diff options
Diffstat (limited to 'support/cpp/libcpp')
37 files changed, 37935 insertions, 8348 deletions
diff --git a/support/cpp/libcpp/Makefile.in b/support/cpp/libcpp/Makefile.in new file mode 100644 index 000000000..161f4c4b2 --- /dev/null +++ b/support/cpp/libcpp/Makefile.in @@ -0,0 +1,293 @@ +# @configure_input@ +# Makefile for libcpp. Run 'configure' to generate Makefile from Makefile.in + +# Copyright (C) 2004-2022 Free Software Foundation, Inc. + +#This file is part of libcpp. + +#libcpp is free software; you can redistribute it and/or modify +#it under the terms of the GNU General Public License as published by +#the Free Software Foundation; either version 3, or (at your option) +#any later version. + +#libcpp 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 libcpp; see the file COPYING3. If not see +#<http://www.gnu.org/licenses/>. + +@SET_MAKE@ + +srcdir = @srcdir@ +top_builddir = . +VPATH = @srcdir@ +INSTALL = @INSTALL@ +AR = @AR@ +ARFLAGS = cru +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +CATALOGS = $(patsubst %,po/%,@CATALOGS@) +CC = @CC@ +CFLAGS = @CFLAGS@ +WARN_CFLAGS = @warn@ @c_warn@ @WARN_PEDANTIC@ @WERROR@ +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ +WARN_CXXFLAGS = @warn@ @WARN_PEDANTIC@ @WERROR@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +EXEEXT = @EXEEXT@ +GMSGFMT = @GMSGFMT@ +INCINTL = @INCINTL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +SHELL = @SHELL@ +# USED_CATALOGS = @USED_CATALOGS@ +XGETTEXT = @XGETTEXT@ +CCDEPMODE = @CCDEPMODE@ +CXXDEPMODE = @CXXDEPMODE@ +DEPDIR = @DEPDIR@ +NOEXCEPTION_FLAGS = @noexception_flags@ +PICFLAG = @PICFLAG@ +CET_HOST_FLAGS = @CET_HOST_FLAGS@ + +datarootdir = @datarootdir@ +datadir = @datadir@ +exec_prefix = @prefix@ +libdir = @libdir@ +localedir = $(datadir)/locale +prefix = @prefix@ + +MSGMERGE = msgmerge +mkinstalldirs = $(SHELL) $(srcdir)/../mkinstalldirs +depcomp = $(SHELL) $(srcdir)/../depcomp + +INCLUDES = -I$(srcdir) -I. -I$(srcdir)/../include @INCINTL@ \ + -I$(srcdir)/include + +ALL_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(INCLUDES) $(CPPFLAGS) $(PICFLAG) \ + $(CET_HOST_FLAGS) +ALL_CXXFLAGS = $(CXXFLAGS) $(WARN_CXXFLAGS) $(NOEXCEPTION_FLAGS) $(INCLUDES) \ + $(CPPFLAGS) $(PICFLAG) $(CET_HOST_FLAGS) + +# The name of the compiler to use. +COMPILER = $(CXX) +COMPILER_FLAGS = $(ALL_CXXFLAGS) +DEPMODE = depmode=gcc3 # SDCC hack $(CXXDEPMODE) + +# from SDCC +# 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_a_OBJS = charset.o directives.o errors.o \ + expr.o files.o identifiers.o init.o lex.o line-map.o macro.o \ + mkdeps.o pch.o symtab.o traditional.o + +libcpp_a_SOURCES = charset.cc directives.cc errors.cc \ + expr.cc files.cc identifiers.cc init.cc lex.cc line-map.cc macro.cc \ + mkdeps.cc pch.cc symtab.cc traditional.cc + +all: libcpp.a $(USED_CATALOGS) + +.SUFFIXES: +.SUFFIXES: .cc .gmo .o .obj .po .pox + +libcpp.a: $(libcpp_a_OBJS) + -rm -f libcpp.a + $(AR) $(ARFLAGS) libcpp.a $(libcpp_a_OBJS) + $(RANLIB) libcpp.a + +# Rules to rebuild the configuration + +Makefile: $(srcdir)/Makefile.in config.status + $(SHELL) ./config.status Makefile + +config.status: $(srcdir)/configure + $(SHELL) ./config.status --recheck + +$(srcdir)/configure: @MAINT@ $(srcdir)/aclocal.m4 + cd $(srcdir) && $(AUTOCONF) + +$(srcdir)/aclocal.m4: @MAINT@ $(srcdir)/../config/acx.m4 \ + $(srcdir)/../config/gettext-sister.m4 $(srcdir)/../config/iconv.m4 \ + $(srcdir)/../config/codeset.m4 $(srcdir)/../config/lib-ld.m4 \ + $(srcdir)/../config/lib-link.m4 $(srcdir)/../config/lib-prefix.m4 \ + $(srcdir)/../config/override.m4 $(srcdir)/../config/proginstall.m4 \ + $(srcdir)/configure.ac + cd $(srcdir) && $(ACLOCAL) -I ../config + +config.h: stamp-h1 + test -f config.h || (rm -f stamp-h1 && $(MAKE) stamp-h1) + +stamp-h1: $(srcdir)/config.in config.status + -rm -f stamp-h1 + $(SHELL) ./config.status config.h + +$(srcdir)/config.in: @MAINT@ $(srcdir)/configure.ac + cd $(srcdir) && $(AUTOHEADER) + -rm -f stamp-h1 + +# It is not possible to get LOCALEDIR defined in config.h because +# the value it needs to be defined to is only determined in the +# Makefile. Hence we do this instead. +localedir.h: localedir.hs; @true +localedir.hs: Makefile + echo "#define LOCALEDIR \"$(localedir)\"" > localedir.new + $(srcdir)/../move-if-change localedir.new localedir.h + echo timestamp > localedir.hs + +# Installation rules and other phony targets + +# These rule has to look for .gmo modules in both srcdir and +# the cwd, and has to check that we actually have a catalog +# for each language, in case they weren't built or included +# with the distribution. +installdirs: + @$(mkinstalldirs) $(DESTDIR)$(datadir); \ + cats="$(CATALOGS)"; for cat in $$cats; do \ + lang=`basename $$cat | sed 's/\.gmo$$//'`; \ + if [ -f $$cat ] || [ -f $(srcdir)/$$cat ]; then \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkinstalldirs) $(DESTDIR)$$dir || exit 1; \ + fi; \ + done + +install-strip install: all installdirs + cats="$(CATALOGS)"; for cat in $$cats; do \ + lang=`basename $$cat | sed 's/\.gmo$$//'`; \ + if [ -f $$cat ]; then :; \ + elif [ -f $(srcdir)/$$cat ]; then cat=$(srcdir)/$$cat; \ + else continue; \ + fi; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + echo $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/$(PACKAGE).mo; \ + $(INSTALL_DATA) $$cat $(DESTDIR)$$dir/$(PACKAGE).mo; \ + done + +mostlyclean: + -rm -f *.o + +clean: mostlyclean + -rm -rf libcpp.a $(srcdir)/autom4te.cache + +distclean: clean + -rm -f config.h stamp-h1 config.status config.cache config.log \ + configure.lineno configure.status.lineno Makefile localedir.h \ + localedir.hs $(DEPDIR)/*.Po + -rmdir $(DEPDIR) + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -rm -f $(srcdir)/configure $(srcdir)/aclocal.m4 + +check: +installcheck: +dvi: +pdf: +html: +info: +install-info: +install-pdf: +install-dvi: +install-man: +install-html: + +update-po: $(CATALOGS:.gmo=.pox) + +.PHONY: installdirs install install-strip mostlyclean clean distclean \ + maintainer-clean check installcheck dvi pdf html info install-info \ + install-man update-po install-html install-pdf install-dvi + +# Dependency rule. +COMPILE.base = $(COMPILER) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(COMPILER_FLAGS) -c +ifeq ($(DEPMODE),depmode=gcc3) +# Note that we put the dependencies into a .Tpo file, then move them +# into place if the compile succeeds. We need this because gcc does +# not atomically write the dependency output file. +COMPILE = $(COMPILE.base) -o $@ -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Tpo +POSTCOMPILE = @mv $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +else +COMPILE = source='$<' object='$@' libtool=no DEPDIR=$(DEPDIR) $(DEPMODE) \ + $(depcomp) $(COMPILE.base) +# depcomp handles atomicity for us, so we don't need a postcompile +# step. +POSTCOMPILE = +endif + +# Implicit rules and I18N + +.cc.o: + $(COMPILE) $< + $(POSTCOMPILE) + +# BUG +identifiers.o: identifiers.cc +init.o: init.cc + +# N.B. We do not attempt to copy these into $(srcdir). +.po.gmo: + $(mkinstalldirs) po + $(GMSGFMT) --statistics -o $@ $< + +# The new .po has to be gone over by hand, so we deposit it into +# build/po with a different extension. +# If build/po/$(PACKAGE).pot exists, use it (it was just created), +# else use the one in srcdir. +.po.pox: + $(mkinstalldirs) po + $(MSGMERGE) $< `if test -f po/$(PACKAGE).pot; \ + then echo po/$(PACKAGE).pot; \ + else echo $(srcdir)/po/$(PACKAGE).pot; fi` -o $@ + +# Rule for regenerating the message template. +$(PACKAGE).pot: po/$(PACKAGE).pot +po/$(PACKAGE).pot: $(libcpp_a_SOURCES) + $(mkinstalldirs) $(srcdir)/po + $(XGETTEXT) --default-domain=$(PACKAGE) \ + --keyword=_ --keyword=N_ \ + --keyword=cpp_error:3 \ + --keyword=cpp_warning:3 \ + --keyword=cpp_pedwarning:3 \ + --keyword=cpp_warning_syshdr:3 \ + --keyword=cpp_warning_at:4 \ + --keyword=cpp_pedwarning_at:4 \ + --keyword=cpp_error_with_line:5 \ + --keyword=cpp_warning_with_line:5 \ + --keyword=cpp_pedwarning_with_line:5 \ + --keyword=cpp_warning_with_line_syshdr:5 \ + --keyword=cpp_error_at:4 \ + --keyword=cpp_errno:3 \ + --keyword=SYNTAX_ERROR --keyword=SYNTAX_ERROR2 \ + --copyright-holder="Free Software Foundation, Inc." \ + --msgid-bugs-address="https://gcc.gnu.org/bugs/" \ + --language=c -o po/$(PACKAGE).pot.tmp $^ + sed 's:$(srcdir)/::g' <po/$(PACKAGE).pot.tmp >po/$(PACKAGE).pot + rm po/$(PACKAGE).pot.tmp + +ETAGS = @ETAGS@ + +TAGS_SOURCES = $(libcpp_a_SOURCES) internal.h system.h ucnid.h \ + include/cpplib.h include/line-map.h include/mkdeps.h include/symtab.h + +TAGS: $(TAGS_SOURCES) + cd $(srcdir) && $(ETAGS) $(TAGS_SOURCES) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +# Dependencies +-include $(patsubst %.o, $(DEPDIR)/%.Po, $(libcpp_a_OBJS)) + +# Dependencies on generated headers have to be explicit. +init.o: localedir.h diff --git a/support/cpp/libcpp/charset.c b/support/cpp/libcpp/charset.cc index cba19a671..ca8b7cf7a 100644 --- a/support/cpp/libcpp/charset.c +++ b/support/cpp/libcpp/charset.cc @@ -1,8 +1,7 @@ /* CPP Library - charsets - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2008, 2009, - 2010 Free Software Foundation, Inc. + Copyright (C) 1998-2022 Free Software Foundation, Inc. - Broken out of c-lex.c Apr 2003, adding valid C99 UCN ranges. + Broken out of c-lex.cc Apr 2003, adding valid C99 UCN ranges. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -354,7 +353,7 @@ one_utf8_to_utf16 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp, return EILSEQ; } - if (s < 0xFFFF) + if (s <= 0xFFFF) { if (*outbytesleftp < 2) { @@ -538,6 +537,7 @@ convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED, if (to->len + flen > to->asize) { to->asize = to->len + flen; + to->asize += to->asize / 4; to->text = XRESIZEVEC (uchar, to->text, to->asize); } memcpy (to->text + to->len, from, flen); @@ -609,13 +609,13 @@ convert_using_iconv (iconv_t cd, const uchar *from, size_t flen, #define APPLY_CONVERSION(CONVERTER, FROM, FLEN, TO) \ CONVERTER.func (CONVERTER.cd, FROM, FLEN, TO) -struct conversion +struct cpp_conversion { const char *pair; convert_f func; iconv_t fake_cd; }; -static const struct conversion conversion_tab[] = { +static const struct cpp_conversion conversion_tab[] = { { "UTF-8/UTF-32LE", convert_utf8_utf32, (iconv_t)0 }, { "UTF-8/UTF-32BE", convert_utf8_utf32, (iconv_t)1 }, { "UTF-8/UTF-16LE", convert_utf8_utf16, (iconv_t)0 }, @@ -630,7 +630,11 @@ static const struct conversion conversion_tab[] = { cset_converter structure for conversion from FROM to TO. If iconv_open() fails, issue an error and return an identity converter. Silently return an identity converter if FROM and TO - are identical. */ + are identical. + + PFILE is only used for generating diagnostics; setting it to NULL + suppresses diagnostics. */ + static struct cset_converter init_iconv_desc (cpp_reader *pfile, const char *to, const char *from) { @@ -638,6 +642,9 @@ init_iconv_desc (cpp_reader *pfile, const char *to, const char *from) char *pair; size_t i; + ret.to = to; + ret.from = from; + if (!strcasecmp (to, from)) { ret.func = convert_no_conversion; @@ -669,25 +676,31 @@ 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, /* FIXME should be DL_SORRY */ - "conversion from %s to %s not supported by iconv", - from, to); - else - cpp_errno (pfile, CPP_DL_ERROR, "iconv_open"); - + if (pfile) + { + if (errno == EINVAL) + cpp_error (pfile, CPP_DL_ERROR, /* FIXME should be DL_SORRY */ + "conversion from %s to %s not supported by iconv", + from, to); + else + cpp_errno (pfile, CPP_DL_ERROR, "iconv_open"); + } ret.func = convert_no_conversion; } } else { - cpp_error (pfile, CPP_DL_ERROR, /* FIXME: should be DL_SORRY */ - "no iconv implementation, cannot convert from %s to %s", - from, to); + if (pfile) + { + cpp_error (pfile, CPP_DL_ERROR, /* FIXME: should be DL_SORRY */ + "no iconv implementation, cannot convert from %s to %s", + from, to); + } ret.func = convert_no_conversion; ret.cd = (iconv_t) -1; ret.width = -1; } + return ret; } @@ -812,6 +825,51 @@ cpp_host_to_exec_charset (cpp_reader *pfile, cppchar_t c) +/* cpp_substring_ranges's constructor. */ + +cpp_substring_ranges::cpp_substring_ranges () : + m_ranges (NULL), + m_num_ranges (0), + m_alloc_ranges (8) +{ + m_ranges = XNEWVEC (source_range, m_alloc_ranges); +} + +/* cpp_substring_ranges's destructor. */ + +cpp_substring_ranges::~cpp_substring_ranges () +{ + free (m_ranges); +} + +/* Add RANGE to the vector of source_range information. */ + +void +cpp_substring_ranges::add_range (source_range range) +{ + if (m_num_ranges >= m_alloc_ranges) + { + m_alloc_ranges *= 2; + m_ranges + = (source_range *)xrealloc (m_ranges, + sizeof (source_range) * m_alloc_ranges); + } + m_ranges[m_num_ranges++] = range; +} + +/* Read NUM ranges from LOC_READER, adding them to the vector of source_range + information. */ + +void +cpp_substring_ranges::add_n_ranges (int num, + cpp_string_location_reader &loc_reader) +{ + for (int i = 0; i < num; i++) + add_range (loc_reader.get_next ()); +} + + + /* Utility routine that computes a mask of the form 0000...111... with WIDTH 1-bits. */ static inline size_t @@ -829,29 +887,39 @@ enum { /* Valid in a C99 identifier? */ C99 = 1, /* Valid in a C99 identifier, but not as the first character? */ - DIG = 2, + N99 = 2, /* Valid in a C++ identifier? */ CXX = 4, + /* Valid in a C11/C++11 identifier? */ + C11 = 8, + /* Valid in a C11/C++11 identifier, but not as the first character? */ + N11 = 16, + /* Valid in a C++23 identifier? */ + CXX23 = 32, + /* Valid in a C++23 identifier, but not as the first character? */ + NXX23 = 64, /* NFC representation is not valid in an identifier? */ - CID = 8, + CID = 128, /* Might be valid NFC form? */ - NFC = 16, + NFC = 256, /* Might be valid NFKC form? */ - NKC = 32, + NKC = 512, /* Certain preceding characters might make it not valid NFC/NKFC form? */ - CTX = 64 + CTX = 1024 }; -static const struct { +struct ucnrange { /* Bitmap of flags above. */ - unsigned char flags; + unsigned short 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" + unsigned int end; }; +#include "ucnid.h" + +/* ISO 10646 defines the UCS codespace as the range 0-0x10FFFF inclusive. */ +#define UCS_LIMIT 0x10FFFF /* 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 @@ -865,8 +933,9 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, struct normalize_state *nst) { int mn, mx, md; + unsigned short valid_flags, invalid_start_flags; - if (c > 0xFFFF) + if (c > UCS_LIMIT) return 0; mn = 0; @@ -882,16 +951,20 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, /* 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))) + union of the acceptable sets for all supported language versions. */ + valid_flags = C99 | CXX | C11 | CXX23; + if (CPP_PEDANTIC (pfile)) + { + if (CPP_OPTION (pfile, cplusplus)) + valid_flags = CXX23; + else if (CPP_OPTION (pfile, c11_identifiers)) + valid_flags = C11; + else if (CPP_OPTION (pfile, c99)) + valid_flags = C99; + } + if (! (ucnranges[mn].flags & valid_flags)) return 0; - if (CPP_PEDANTIC (pfile) - && ((CPP_OPTION (pfile, c99) && !(ucnranges[mn].flags & C99)) - || (CPP_OPTION (pfile, cplusplus) - && !(ucnranges[mn].flags & CXX)))) - return 0; - /* Update NST. */ if (ucnranges[mn].combine != 0 && ucnranges[mn].combine < nst->prev_class) nst->level = normalized_none; @@ -900,17 +973,6 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, 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 @@ -918,20 +980,19 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, really a valid character). Unfortunately, C99 allows (only) the NFC form, but C++ allows only the combining characters. */ - else if (c >= 0x1161 && c <= 0x1175) + 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 + safe = check_nfc (pfile, c, p); + if (!safe) { - /* 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 ((c >= 0x1161 && c <= 0x1175) || (c >= 0x11A8 && c <= 0x11C2)) + nst->level = MAX (nst->level, normalized_identifier_C); + else + nst->level = normalized_none; } - 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) ; @@ -941,11 +1002,35 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, nst->level = MAX (nst->level, normalized_identifier_C); else nst->level = normalized_none; - nst->previous = c; + if (ucnranges[mn].combine == 0) + nst->previous = c; nst->prev_class = ucnranges[mn].combine; - /* In C99, UCN digits may not begin identifiers. */ - if (CPP_OPTION (pfile, c99) && (ucnranges[mn].flags & DIG)) + if (!CPP_PEDANTIC (pfile)) + { + /* If not -pedantic, accept as character that may + begin an identifier a union of characters allowed + at that position in each of the character sets. */ + if ((ucnranges[mn].flags & (C99 | N99)) == C99 + || (ucnranges[mn].flags & CXX) != 0 + || (ucnranges[mn].flags & (C11 | N11)) == C11 + || (ucnranges[mn].flags & (CXX23 | NXX23)) == CXX23) + return 1; + return 2; + } + + if (CPP_OPTION (pfile, cplusplus)) + invalid_start_flags = NXX23; + else if (CPP_OPTION (pfile, c11_identifiers)) + invalid_start_flags = N11; + else if (CPP_OPTION (pfile, c99)) + invalid_start_flags = N99; + else + invalid_start_flags = 0; + + /* In C99, UCN digits may not begin identifiers. In C11 and C++11, + UCN combining characters may not begin identifiers. */ + if (ucnranges[mn].flags & invalid_start_flags) return 2; return 1; @@ -967,22 +1052,30 @@ ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c, whose short identifier is less than 00A0 other than 0024 ($), 0040 (@), or 0060 (`), nor one in the range D800 through DFFF inclusive. + If the hexadecimal value is larger than the upper bound of the UCS + codespace specified in ISO/IEC 10646, a pedantic warning is issued + in all versions of C and in the C++20 or later versions of C++. + *PSTR must be preceded by "\u" or "\U"; it is assumed that the - buffer end is delimited by a non-hex digit. Returns zero if the - UCN has not been consumed. + buffer end is delimited by a non-hex digit. Returns false if the + UCN has not been consumed, true otherwise. - Otherwise the nonzero value of the UCN, whether valid or invalid, - is returned. Diagnostics are emitted for invalid values. PSTR - is updated to point one beyond the UCN, or to the syntactically - invalid character. + The value of the UCN, whether valid or invalid, is returned in *CP. + Diagnostics are emitted for invalid values. PSTR is updated to point + one beyond the UCN, or to the syntactically invalid character. IDENTIFIER_POS is 0 when not in an identifier, 1 for the start of - an identifier, or 2 otherwise. */ + an identifier, or 2 otherwise. -cppchar_t + If LOC_READER is non-NULL, then position information is + read from *LOC_READER and CHAR_RANGE->m_finish is updated accordingly. */ + +bool _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, const uchar *limit, int identifier_pos, - struct normalize_state *nst) + struct normalize_state *nst, cppchar_t *cp, + source_range *char_range, + cpp_string_location_reader *loc_reader) { cppchar_t result, c; unsigned int length; @@ -992,6 +1085,10 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, if (!CPP_OPTION (pfile, cplusplus) && !CPP_OPTION (pfile, c99)) cpp_error (pfile, CPP_DL_WARNING, "universal character names are only valid in C++ and C99"); + else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0 + && !CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_WARNING, + "C99's universal character names are incompatible with C90"); else if (CPP_WTRADITIONAL (pfile) && identifier_pos == 0) cpp_warning (pfile, CPP_W_TRADITIONAL, "the meaning of '\\%c' is different in traditional C", @@ -1014,6 +1111,11 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, if (!ISXDIGIT (c)) break; str++; + if (loc_reader) + { + gcc_assert (char_range); + char_range->m_finish = loc_reader->get_next ().m_finish; + } result = (result << 4) + hex_value (c); } while (--length && str < limit); @@ -1022,8 +1124,11 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, multiple tokens in identifiers, so we can't give a helpful error message in that case. */ if (length && identifier_pos) - return 0; - + { + *cp = 0; + return false; + } + *pstr = str; if (length) { @@ -1055,7 +1160,7 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, CPP_OPTION (pfile, warn_dollars) = 0; cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number"); } - NORMALIZE_STATE_UPDATE_IDNUM (nst); + NORMALIZE_STATE_UPDATE_IDNUM (nst, result); } else if (identifier_pos) { @@ -1070,19 +1175,30 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr, "universal character %.*s is not valid at the start of an identifier", (int) (str - base), base); } - - if (result == 0) - result = 1; - - return result; + else if (result > UCS_LIMIT + && (!CPP_OPTION (pfile, cplusplus) + || CPP_OPTION (pfile, lang) > CLK_CXX17)) + cpp_error (pfile, CPP_DL_PEDWARN, + "%.*s is outside the UCS codespace", + (int) (str - base), base); + + *cp = result; + return true; } /* 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. */ + it to the execution character set and write the result into TBUF, + if TBUF is non-NULL. + An advanced pointer is returned. Issues all relevant diagnostics. + If LOC_READER is non-NULL, then RANGES must be non-NULL and CHAR_RANGE + contains the location of the character so far: location information + is read from *LOC_READER, and *RANGES is updated accordingly. */ static const uchar * convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, - struct _cpp_strbuf *tbuf, struct cset_converter cvt) + struct _cpp_strbuf *tbuf, struct cset_converter cvt, + source_range char_range, + cpp_string_location_reader *loc_reader, + cpp_substring_ranges *ranges) { cppchar_t ucn; uchar buf[6]; @@ -1091,8 +1207,17 @@ convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, int rval; struct normalize_state nst = INITIAL_NORMALIZE_STATE; + /* loc_reader and ranges must either be both NULL, or both be non-NULL. */ + gcc_assert ((loc_reader != NULL) == (ranges != NULL)); + from++; /* Skip u/U. */ - ucn = _cpp_valid_ucn (pfile, &from, limit, 0, &nst); + + if (loc_reader) + /* The u/U is part of the spelling of this character. */ + char_range.m_finish = loc_reader->get_next ().m_finish; + + _cpp_valid_ucn (pfile, &from, limit, 0, &nst, + &ucn, &char_range, loc_reader); rval = one_cppchar_to_utf8 (ucn, &bufp, &bytesleft); if (rval) @@ -1101,13 +1226,102 @@ convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit, cpp_errno (pfile, CPP_DL_ERROR, "converting UCN to source character set"); } - else if (!APPLY_CONVERSION (cvt, buf, 6 - bytesleft, tbuf)) - cpp_errno (pfile, CPP_DL_ERROR, - "converting UCN to execution character set"); + else + { + if (tbuf) + if (!APPLY_CONVERSION (cvt, buf, 6 - bytesleft, tbuf)) + cpp_errno (pfile, CPP_DL_ERROR, + "converting UCN to execution character set"); + + if (loc_reader) + { + int num_encoded_bytes = 6 - bytesleft; + for (int i = 0; i < num_encoded_bytes; i++) + ranges->add_range (char_range); + } + } return from; } +/* Performs a similar task as _cpp_valid_ucn, but parses UTF-8-encoded + extended characters rather than UCNs. If the return value is TRUE, then a + character was successfully decoded and stored in *CP; *PSTR has been + updated to point one past the valid UTF-8 sequence. Diagnostics may have + been emitted if the character parsed is not allowed in the current context. + If the return value is FALSE, then *PSTR has not been modified and *CP may + equal 0, to indicate that *PSTR does not form a valid UTF-8 sequence, or it + may, when processing an identifier in C mode, equal a codepoint that was + validly encoded but is not allowed to appear in an identifier. In either + case, no diagnostic is emitted, and the return value of FALSE should cause + a new token to be formed. + + Unlike _cpp_valid_ucn, this will never be called when lexing a string; only + a potential identifier, or a CPP_OTHER token. NST is unused in the latter + case. + + As in _cpp_valid_ucn, IDENTIFIER_POS is 0 when not in an identifier, 1 for + the start of an identifier, or 2 otherwise. */ + +extern bool +_cpp_valid_utf8 (cpp_reader *pfile, + const uchar **pstr, + const uchar *limit, + int identifier_pos, + struct normalize_state *nst, + cppchar_t *cp) +{ + const uchar *base = *pstr; + size_t inbytesleft = limit - base; + if (one_utf8_to_cppchar (pstr, &inbytesleft, cp)) + { + /* No diagnostic here as this byte will rather become a + new token. */ + *cp = 0; + return false; + } + + if (identifier_pos) + { + switch (ucn_valid_in_identifier (pfile, *cp, nst)) + { + + case 0: + /* In C++, this is an error for invalid character in an identifier + because logically, the UTF-8 was converted to a UCN during + translation phase 1 (even though we don't physically do it that + way). In C, this byte rather becomes grammatically a separate + token. */ + + if (CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_ERROR, + "extended character %.*s is not valid in an identifier", + (int) (*pstr - base), base); + else + { + *pstr = base; + return false; + } + + break; + + case 2: + if (identifier_pos == 1) + { + /* This is treated the same way in C++ or C99 -- lexed as an + identifier which is then invalid because an identifier is + not allowed to start with this character. */ + cpp_error (pfile, CPP_DL_ERROR, + "extended character %.*s is not valid at the start of an identifier", + (int) (*pstr - base), base); + } + break; + } + } + + return true; +} + /* 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 @@ -1159,31 +1373,48 @@ emit_numeric_escape (cpp_reader *pfile, cppchar_t n, } /* Convert a hexadecimal escape, pointed to by FROM, to the execution - character set and write it into the string buffer TBUF. Returns an - advanced pointer, and issues diagnostics as necessary. + character set and write it into the string buffer TBUF (if non-NULL). + Returns an advanced pointer, and issues diagnostics as necessary. No character set translation occurs; this routine always produces the execution-set character with numeric value equal to the given hex - number. You can, e.g. generate surrogate pairs this way. */ + number. You can, e.g. generate surrogate pairs this way. + If LOC_READER is non-NULL, then RANGES must be non-NULL and CHAR_RANGE + contains the location of the character so far: location information + is read from *LOC_READER, and *RANGES is updated accordingly. */ static const uchar * convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit, - struct _cpp_strbuf *tbuf, struct cset_converter cvt) + struct _cpp_strbuf *tbuf, struct cset_converter cvt, + source_range char_range, + cpp_string_location_reader *loc_reader, + cpp_substring_ranges *ranges) { cppchar_t c, n = 0, overflow = 0; int digits_found = 0; size_t width = cvt.width; size_t mask = width_to_mask (width); + /* loc_reader and ranges must either be both NULL, or both be non-NULL. */ + gcc_assert ((loc_reader != NULL) == (ranges != NULL)); + if (CPP_WTRADITIONAL (pfile)) cpp_warning (pfile, CPP_W_TRADITIONAL, "the meaning of '\\x' is different in traditional C"); - from++; /* Skip 'x'. */ + /* Skip 'x'. */ + from++; + + /* The 'x' is part of the spelling of this character. */ + if (loc_reader) + char_range.m_finish = loc_reader->get_next ().m_finish; + while (from < limit) { c = *from; if (! hex_p (c)) break; from++; + if (loc_reader) + char_range.m_finish = loc_reader->get_next ().m_finish; overflow |= n ^ (n << 4 >> 4); n = (n << 4) + hex_value (c); digits_found = 1; @@ -1203,7 +1434,10 @@ convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit, n &= mask; } - emit_numeric_escape (pfile, n, tbuf, cvt); + if (tbuf) + emit_numeric_escape (pfile, n, tbuf, cvt); + if (ranges) + ranges->add_range (char_range); return from; } @@ -1213,16 +1447,24 @@ convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit, advanced pointer, and issues diagnostics as necessary. No character set translation occurs; this routine always produces the execution-set character with numeric value equal to the given octal - number. */ + number. + If LOC_READER is non-NULL, then RANGES must be non-NULL and CHAR_RANGE + contains the location of the character so far: location information + is read from *LOC_READER, and *RANGES is updated accordingly. */ static const uchar * convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit, - struct _cpp_strbuf *tbuf, struct cset_converter cvt) + struct _cpp_strbuf *tbuf, struct cset_converter cvt, + source_range char_range, + cpp_string_location_reader *loc_reader, + cpp_substring_ranges *ranges) { size_t count = 0; cppchar_t c, n = 0; size_t width = cvt.width; size_t mask = width_to_mask (width); - bool overflow = false; + + /* loc_reader and ranges must either be both NULL, or both be non-NULL. */ + gcc_assert ((loc_reader != NULL) == (ranges != NULL)); while (from < limit && count++ < 3) { @@ -1230,7 +1472,8 @@ convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit, if (c < '0' || c > '7') break; from++; - overflow |= n ^ (n << 3 >> 3); + if (loc_reader) + char_range.m_finish = loc_reader->get_next ().m_finish; n = (n << 3) + c - '0'; } @@ -1241,18 +1484,26 @@ convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit, n &= mask; } - emit_numeric_escape (pfile, n, tbuf, cvt); + if (tbuf) + emit_numeric_escape (pfile, n, tbuf, cvt); + if (ranges) + ranges->add_range (char_range); return from; } /* Convert an escape sequence (pointed to by FROM) to its value on the target, and to the execution character set. Do not scan past - LIMIT. Write the converted value into TBUF. Returns an advanced - pointer. Handles all relevant diagnostics. */ + LIMIT. Write the converted value into TBUF, if TBUF is non-NULL. + Returns an advanced pointer. Handles all relevant diagnostics. + If LOC_READER is non-NULL, then RANGES must be non-NULL: location + information is read from *LOC_READER, and *RANGES is updated + accordingly. */ static const uchar * convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, - struct _cpp_strbuf *tbuf, struct cset_converter cvt) + struct _cpp_strbuf *tbuf, struct cset_converter cvt, + cpp_string_location_reader *loc_reader, + cpp_substring_ranges *ranges) { /* Values of \a \b \e \f \n \r \t \v respectively. */ #if HOST_CHARSET == HOST_CHARSET_ASCII @@ -1265,20 +1516,27 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, uchar c; + /* Record the location of the backslash. */ + source_range char_range; + if (loc_reader) + char_range = loc_reader->get_next (); + c = *from; switch (c) { /* UCNs, hex escapes, and octal escapes are processed separately. */ case 'u': case 'U': - return convert_ucn (pfile, from, limit, tbuf, cvt); + return convert_ucn (pfile, from, limit, tbuf, cvt, + char_range, loc_reader, ranges); case 'x': - return convert_hex (pfile, from, limit, tbuf, cvt); - break; + return convert_hex (pfile, from, limit, tbuf, cvt, + char_range, loc_reader, ranges); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': - return convert_oct (pfile, from, limit, tbuf, cvt); + return convert_oct (pfile, from, limit, tbuf, cvt, + char_range, loc_reader, ranges); /* Various letter escapes. Get the appropriate host-charset value into C. */ @@ -1321,19 +1579,28 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit, "unknown escape sequence: '\\%c'", (int) c); else { - /* diagnostic.c does not support "%03o". When it does, this + encoding_rich_location rich_loc (pfile); + + /* diagnostic.cc 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); + cpp_error_at (pfile, CPP_DL_PEDWARN, &rich_loc, + "unknown escape sequence: '\\%s'", buf); } } - /* Now convert what we have to the execution character set. */ - if (!APPLY_CONVERSION (cvt, &c, 1, tbuf)) - cpp_errno (pfile, CPP_DL_ERROR, - "converting escape sequence to execution character set"); + if (tbuf) + /* Now convert what we have to the execution character set. */ + if (!APPLY_CONVERSION (cvt, &c, 1, tbuf)) + cpp_errno (pfile, CPP_DL_ERROR, + "converting escape sequence to execution character set"); + + if (loc_reader) + { + char_range.m_finish = loc_reader->get_next ().m_finish; + ranges->add_range (char_range); + } return from + 1; } @@ -1347,6 +1614,7 @@ converter_for_type (cpp_reader *pfile, enum cpp_ttype type) { default: return pfile->narrow_cset_desc; + case CPP_UTF8CHAR: case CPP_UTF8STRING: return pfile->utf8_cset_desc; case CPP_CHAR16: @@ -1365,28 +1633,52 @@ converter_for_type (cpp_reader *pfile, enum cpp_ttype type) are to be converted from the source to the execution character set, escape sequences translated, and finally all are to be concatenated. WIDE indicates whether or not to produce a wide - string. The result is written into TO. Returns true for success, - false for failure. */ -bool -cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, - cpp_string *to, enum cpp_ttype type) + string. If TO is non-NULL, the result is written into TO. + If LOC_READERS and OUT are non-NULL, then location information + is read from LOC_READERS (which must be an array of length COUNT), + and location information is written to *RANGES. + + Returns true for success, false for failure. */ + +static bool +cpp_interpret_string_1 (cpp_reader *pfile, const cpp_string *from, size_t count, + cpp_string *to, enum cpp_ttype type, + cpp_string_location_reader *loc_readers, + cpp_substring_ranges *out) { struct _cpp_strbuf tbuf; const uchar *p, *base, *limit; size_t i; struct cset_converter cvt = converter_for_type (pfile, type); - tbuf.asize = MAX (OUTBUF_BLOCK_SIZE, from->len); - tbuf.text = XNEWVEC (uchar, tbuf.asize); - tbuf.len = 0; + /* loc_readers and out must either be both NULL, or both be non-NULL. */ + gcc_assert ((loc_readers != NULL) == (out != NULL)); + if (to) + { + tbuf.asize = MAX (OUTBUF_BLOCK_SIZE, from->len); + tbuf.text = XNEWVEC (uchar, tbuf.asize); + tbuf.len = 0; + } + + cpp_string_location_reader *loc_reader = NULL; for (i = 0; i < count; i++) { + if (loc_readers) + loc_reader = &loc_readers[i]; + p = from[i].text; if (*p == 'u') { - if (*++p == '8') - p++; + p++; + if (loc_reader) + loc_reader->get_next (); + if (*p == '8') + { + p++; + if (loc_reader) + loc_reader->get_next (); + } } else if (*p == 'L' || *p == 'U') p++; if (*p == 'R') @@ -1395,23 +1687,64 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, /* Skip over 'R"'. */ p += 2; + if (loc_reader) + { + loc_reader->get_next (); + loc_reader->get_next (); + } prefix = p; while (*p != '(') - p++; + { + p++; + if (loc_reader) + loc_reader->get_next (); + } p++; + if (loc_reader) + loc_reader->get_next (); limit = from[i].text + from[i].len; if (limit >= p + (p - prefix) + 1) limit -= (p - prefix) + 1; /* Raw strings are all normal characters; these can be fed directly to convert_cset. */ - if (!APPLY_CONVERSION (cvt, p, limit - p, &tbuf)) - goto fail; + if (to) + if (!APPLY_CONVERSION (cvt, p, limit - p, &tbuf)) + goto fail; + + if (loc_reader) + { + /* If generating source ranges, assume we have a 1:1 + correspondence between bytes in the source encoding and bytes + in the execution encoding (e.g. if we have a UTF-8 to UTF-8 + conversion), so that this run of bytes in the source file + corresponds to a run of bytes in the execution string. + This requirement is guaranteed by an early-reject in + cpp_interpret_string_ranges. */ + gcc_assert (cvt.func == convert_no_conversion); + out->add_n_ranges (limit - p, *loc_reader); + } continue; } - p++; /* Skip leading quote. */ + /* If we don't now have a leading quote, something has gone wrong. + This can occur if cpp_interpret_string_ranges is handling a + stringified macro argument, but should not be possible otherwise. */ + if (*p != '"' && *p != '\'') + { + gcc_assert (out != NULL); + cpp_error (pfile, CPP_DL_ERROR, "missing open quote"); + if (to) + free (tbuf.text); + return false; + } + + /* Skip leading quote. */ + p++; + if (loc_reader) + loc_reader->get_next (); + limit = from[i].text + from[i].len - 1; /* Skip trailing quote. */ for (;;) @@ -1423,29 +1756,139 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, { /* We have a run of normal characters; these can be fed directly to convert_cset. */ - if (!APPLY_CONVERSION (cvt, base, p - base, &tbuf)) - goto fail; + if (to) + if (!APPLY_CONVERSION (cvt, base, p - base, &tbuf)) + goto fail; + /* Similar to above: assumes we have a 1:1 correspondence + between bytes in the source encoding and bytes in the + execution encoding. */ + if (loc_reader) + { + gcc_assert (cvt.func == convert_no_conversion); + out->add_n_ranges (p - base, *loc_reader); + } } - if (p == limit) + if (p >= limit) break; - p = convert_escape (pfile, p + 1, limit, &tbuf, cvt); + struct _cpp_strbuf *tbuf_ptr = to ? &tbuf : NULL; + p = convert_escape (pfile, p + 1, limit, tbuf_ptr, cvt, + loc_reader, out); } } - /* NUL-terminate the 'to' buffer and translate it to a cpp_string - structure. */ - emit_numeric_escape (pfile, 0, &tbuf, cvt); - tbuf.text = XRESIZEVEC (uchar, tbuf.text, tbuf.len); - to->text = tbuf.text; - to->len = tbuf.len; + + if (to) + { + /* NUL-terminate the 'to' buffer and translate it to a cpp_string + structure. */ + emit_numeric_escape (pfile, 0, &tbuf, cvt); + tbuf.text = XRESIZEVEC (uchar, tbuf.text, tbuf.len); + to->text = tbuf.text; + to->len = tbuf.len; + } + /* Use the location of the trailing quote as the location of the + NUL-terminator. */ + if (loc_reader) + { + source_range range = loc_reader->get_next (); + out->add_range (range); + } + return true; fail: cpp_errno (pfile, CPP_DL_ERROR, "converting to execution character set"); - free (tbuf.text); + if (to) + free (tbuf.text); return false; } +/* FROM is an array of cpp_string structures of length COUNT. These + are to be converted from the source to the execution character set, + escape sequences translated, and finally all are to be + concatenated. WIDE indicates whether or not to produce a wide + string. The result is written into TO. Returns true for success, + false for failure. */ +bool +cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count, + cpp_string *to, enum cpp_ttype type) +{ + return cpp_interpret_string_1 (pfile, from, count, to, type, NULL, NULL); +} + +/* A "do nothing" diagnostic-handling callback for use by + cpp_interpret_string_ranges, so that it can temporarily suppress + diagnostic-handling. */ + +static bool +noop_diagnostic_cb (cpp_reader *, enum cpp_diagnostic_level, + enum cpp_warning_reason, rich_location *, + const char *, va_list *) +{ + /* no-op. */ + return true; +} + +/* This function mimics the behavior of cpp_interpret_string, but + rather than generating a string in the execution character set, + *OUT is written to with the source code ranges of the characters + in such a string. + FROM and LOC_READERS should both be arrays of length COUNT. + Returns NULL for success, or an error message for failure. */ + +const char * +cpp_interpret_string_ranges (cpp_reader *pfile, const cpp_string *from, + cpp_string_location_reader *loc_readers, + size_t count, + cpp_substring_ranges *out, + enum cpp_ttype type) +{ + /* There are a couple of cases in the range-handling in + cpp_interpret_string_1 that rely on there being a 1:1 correspondence + between bytes in the source encoding and bytes in the execution + encoding, so that each byte in the execution string can correspond + to the location of a byte in the source string. + + This holds for the typical case of a UTF-8 to UTF-8 conversion. + Enforce this requirement by only attempting to track substring + locations if we have source encoding == execution encoding. + + This is a stronger condition than we need, since we could e.g. + have ASCII to EBCDIC (with 1 byte per character before and after), + but it seems to be a reasonable restriction. */ + struct cset_converter cvt = converter_for_type (pfile, type); + if (cvt.func != convert_no_conversion) + return "execution character set != source character set"; + + /* For on-demand strings we have already lexed the strings, so there + should be no diagnostics. However, if we have bogus source location + data (or stringified macro arguments), the attempt to lex the + strings could fail with an diagnostic. Temporarily install an + diagnostic-handler to catch the diagnostic, so that it can lead to this call + failing, rather than being emitted as a user-visible diagnostic. + If an diagnostic does occur, we should see it via the return value of + cpp_interpret_string_1. */ + bool (*saved_diagnostic_handler) (cpp_reader *, enum cpp_diagnostic_level, + enum cpp_warning_reason, rich_location *, + const char *, va_list *) + ATTRIBUTE_FPTR_PRINTF(5,0); + + saved_diagnostic_handler = pfile->cb.diagnostic; + pfile->cb.diagnostic = noop_diagnostic_cb; + + bool result = cpp_interpret_string_1 (pfile, from, count, NULL, type, + loc_readers, out); + + /* Restore the saved diagnostic-handler. */ + pfile->cb.diagnostic = saved_diagnostic_handler; + + if (!result) + return "cpp_interpret_string_1 failed"; + + /* Success. */ + return NULL; +} + /* Subroutine of do_line and do_linemarker. Convert escape sequences in a string, but do not perform character set conversion. */ bool @@ -1470,10 +1913,11 @@ cpp_interpret_string_notranslate (cpp_reader *pfile, const cpp_string *from, /* Subroutine of cpp_interpret_charconst which performs the conversion to a number, for narrow strings. STR is the string structure returned by cpp_interpret_string. PCHARS_SEEN and UNSIGNEDP are as for - cpp_interpret_charconst. */ + cpp_interpret_charconst. TYPE is the token type. */ static cppchar_t narrow_str_to_charconst (cpp_reader *pfile, cpp_string str, - unsigned int *pchars_seen, int *unsignedp) + unsigned int *pchars_seen, int *unsignedp, + enum cpp_ttype type) { size_t width = CPP_OPTION (pfile, char_precision); size_t max_chars = CPP_OPTION (pfile, int_precision) / width; @@ -1502,10 +1946,12 @@ narrow_str_to_charconst (cpp_reader *pfile, cpp_string str, result = c; } + if (type == CPP_UTF8CHAR) + max_chars = 1; if (i > max_chars) { i = max_chars; - cpp_error (pfile, CPP_DL_WARNING, + cpp_error (pfile, type == CPP_UTF8CHAR ? CPP_DL_ERROR : CPP_DL_WARNING, "character constant too long for its type"); } else if (i > 1 && CPP_OPTION (pfile, warn_multichar)) @@ -1514,6 +1960,8 @@ narrow_str_to_charconst (cpp_reader *pfile, cpp_string str, /* Multichar constants are of type int and therefore signed. */ if (i > 1) unsigned_p = 0; + else if (type == CPP_UTF8CHAR && !CPP_OPTION (pfile, cplusplus)) + unsigned_p = 1; else unsigned_p = CPP_OPTION (pfile, unsigned_char); @@ -1554,6 +2002,17 @@ wide_str_to_charconst (cpp_reader *pfile, cpp_string str, size_t off, i; cppchar_t result = 0, c; + if (str.len <= nbwc) + { + /* Error recovery, if no errors have been diagnosed previously, + there should be at least two wide characters. Empty literals + are diagnosed earlier and we can get just the zero terminator + only if there were errors diagnosed during conversion. */ + *pchars_seen = 0; + *unsignedp = 0; + return 0; + } + /* This is finicky because the string is in the target's byte order, which may not be our byte order. Only the last character, ignoring the NUL terminator, is relevant. */ @@ -1569,7 +2028,9 @@ wide_str_to_charconst (cpp_reader *pfile, cpp_string str, character exactly fills a wchar_t, so a multi-character wide character constant is guaranteed to overflow. */ if (str.len > nbwc * 2) - cpp_error (pfile, CPP_DL_WARNING, + cpp_error (pfile, (CPP_OPTION (pfile, cplusplus) + && (type == CPP_CHAR16 || type == CPP_CHAR32)) + ? CPP_DL_ERROR : CPP_DL_WARNING, "character constant too long for its type"); /* Truncate the constant to its natural width, and simultaneously @@ -1603,23 +2064,32 @@ cpp_interpret_charconst (cpp_reader *pfile, const cpp_token *token, unsigned int *pchars_seen, int *unsignedp) { cpp_string str = { 0, 0 }; - bool wide = (token->type != CPP_CHAR); + bool wide = (token->type != CPP_CHAR && token->type != CPP_UTF8CHAR); + int u8 = 2 * int(token->type == CPP_UTF8CHAR); cppchar_t result; - /* an empty constant will appear as L'', u'', U'' or '' */ - if (token->val.str.len == (size_t) (2 + wide)) + /* An empty constant will appear as L'', u'', U'', u8'', or '' */ + if (token->val.str.len == (size_t) (2 + wide + u8)) { cpp_error (pfile, CPP_DL_ERROR, "empty character constant"); + *pchars_seen = 0; + *unsignedp = 0; + return 0; + } + else if (!cpp_interpret_string (pfile, &token->val.str, 1, &str, + token->type)) + { + *pchars_seen = 0; + *unsignedp = 0; return 0; } - else if (!cpp_interpret_string (pfile, &token->val.str, 1, &str, token->type)) - return 0; if (wide) result = wide_str_to_charconst (pfile, str, pchars_seen, unsignedp, token->type); else - result = narrow_str_to_charconst (pfile, str, pchars_seen, unsignedp); + result = narrow_str_to_charconst (pfile, str, pchars_seen, unsignedp, + token->type); if (str.text != token->val.str.text) free ((void *)str.text); @@ -1628,8 +2098,9 @@ cpp_interpret_charconst (cpp_reader *pfile, const cpp_token *token, } /* 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. */ + UCN escapes or UTF-8 multibyte chars, 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) { @@ -1680,6 +2151,25 @@ _cpp_interpret_identifier (cpp_reader *pfile, const uchar *id, size_t len) buf, bufp - buf, HT_ALLOC)); } + +/* Utility to strip a UTF-8 byte order marking from the beginning + of a buffer. Returns the number of bytes to skip, which currently + will be either 0 or 3. */ +int +cpp_check_utf8_bom (const char *data, size_t data_length) +{ + +#if HOST_CHARSET == HOST_CHARSET_ASCII + const unsigned char *udata = (const unsigned char *) data; + if (data_length >= 3 && udata[0] == 0xef && udata[1] == 0xbb + && udata[2] == 0xbf) + return 3; +#endif + + return 0; +} + + /* 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 @@ -1693,7 +2183,11 @@ _cpp_interpret_identifier (cpp_reader *pfile, const uchar *id, size_t len) INPUT is expected to have been allocated with xmalloc. This function will either set *BUFFER_START to INPUT, or free it and set *BUFFER_START to a pointer to another xmalloc-allocated block of - memory. */ + memory. + + PFILE is only used to generate diagnostics; setting it to NULL suppresses + diagnostics, and causes a return of NULL if there was any error instead. */ + uchar * _cpp_convert_input (cpp_reader *pfile, const char *input_charset, uchar *input, size_t size, size_t len, @@ -1716,22 +2210,38 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset, to.text = XNEWVEC (uchar, to.asize); to.len = 0; - if (!APPLY_CONVERSION (input_cset, input, len, &to)) - cpp_error (pfile, CPP_DL_ERROR, - "failure to convert %s to %s", - CPP_OPTION (pfile, input_charset), SOURCE_CHARSET); - + const bool ok = APPLY_CONVERSION (input_cset, input, len, &to); free (input); - } - /* Clean up the mess. */ - if (input_cset.func == convert_using_iconv) - iconv_close (input_cset.cd); + /* Clean up the mess. */ + if (input_cset.func == convert_using_iconv) + iconv_close (input_cset.cd); + + /* Handle conversion failure. */ + if (!ok) + { + if (!pfile) + { + XDELETEVEC (to.text); + *buffer_start = NULL; + *st_size = 0; + return NULL; + } + cpp_error (pfile, CPP_DL_ERROR, "failure to convert %s to %s", + input_charset, SOURCE_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 = XRESIZEVEC (uchar, to.text, to.len + 1); + haven't enough space for the \n-terminator or following + 15 bytes of padding (used to quiet warnings from valgrind or + Address Sanitizer, when the optimized lexer accesses aligned + 16-byte memory chunks, including the bytes after the malloced, + area, and stops lexing on '\n'). */ + if (to.len + 4096 < to.asize || to.len + 16 > to.asize) + to.text = XRESIZEVEC (uchar, to.text, to.len + 16); + + memset (to.text + to.len, '\0', 16); /* 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 @@ -1744,19 +2254,14 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset, buffer = to.text; *st_size = to.len; -#if HOST_CHARSET == HOST_CHARSET_ASCII - /* The HOST_CHARSET test just above ensures that the source charset - is UTF-8. So, ignore a UTF-8 BOM if we see one. Note that - glib'c UTF-8 iconv() provider (as of glibc 2.7) does not ignore a + + /* Ignore a UTF-8 BOM if we see one and the source charset is UTF-8. Note + that glib'c UTF-8 iconv() provider (as of glibc 2.7) does not ignore a BOM -- however, even if it did, we would still need this code due to the 'convert_no_conversion' case. */ - if (to.len >= 3 && to.text[0] == 0xef && to.text[1] == 0xbb - && to.text[2] == 0xbf) - { - *st_size -= 3; - buffer += 3; - } -#endif + const int bom_len = cpp_check_utf8_bom ((const char *) to.text, to.len); + *st_size -= bom_len; + buffer += bom_len; *buffer_start = to.text; return buffer; @@ -1795,3 +2300,211 @@ _cpp_default_encoding (void) return current_encoding; } + +/* Check if the configured input charset requires no conversion, other than + possibly stripping a UTF-8 BOM. */ +bool cpp_input_conversion_is_trivial (const char *input_charset) +{ + return !strcasecmp (input_charset, SOURCE_CHARSET); +} + +/* Implementation of class cpp_string_location_reader. */ + +/* Constructor for cpp_string_location_reader. */ + +cpp_string_location_reader:: +cpp_string_location_reader (location_t src_loc, + line_maps *line_table) +{ + src_loc = get_range_from_loc (line_table, src_loc).m_start; + + /* SRC_LOC might be a macro location. It only makes sense to do + column-by-column calculations on ordinary maps, so get the + corresponding location in an ordinary map. */ + m_loc + = linemap_resolve_location (line_table, src_loc, + LRK_SPELLING_LOCATION, NULL); + + const line_map_ordinary *map + = linemap_check_ordinary (linemap_lookup (line_table, m_loc)); + m_offset_per_column = (1 << map->m_range_bits); +} + +/* Get the range of the next source byte. */ + +source_range +cpp_string_location_reader::get_next () +{ + source_range result; + result.m_start = m_loc; + result.m_finish = m_loc; + if (m_loc <= LINE_MAP_MAX_LOCATION_WITH_COLS) + m_loc += m_offset_per_column; + return result; +} + +cpp_display_width_computation:: +cpp_display_width_computation (const char *data, int data_length, + const cpp_char_column_policy &policy) : + m_begin (data), + m_next (m_begin), + m_bytes_left (data_length), + m_policy (policy), + m_display_cols (0) +{ + gcc_assert (policy.m_tabstop > 0); + gcc_assert (policy.m_width_cb); +} + + +/* The main implementation function for class cpp_display_width_computation. + m_next points on entry to the start of the UTF-8 encoding of the next + character, and is updated to point just after the last byte of the encoding. + m_bytes_left contains on entry the remaining size of the buffer into which + m_next points, and this is also updated accordingly. If m_next does not + point to a valid UTF-8-encoded sequence, then it will be treated as a single + byte with display width 1. m_cur_display_col is the current display column, + relative to which tab stops should be expanded. Returns the display width of + the codepoint just processed. + If OUT is non-NULL, it is populated. */ + +int +cpp_display_width_computation::process_next_codepoint (cpp_decoded_char *out) +{ + cppchar_t c; + int next_width; + + if (out) + out->m_start_byte = m_next; + + if (*m_next == '\t') + { + ++m_next; + --m_bytes_left; + next_width = m_policy.m_tabstop - (m_display_cols % m_policy.m_tabstop); + if (out) + { + out->m_ch = '\t'; + out->m_valid_ch = true; + } + } + else if (one_utf8_to_cppchar ((const uchar **) &m_next, &m_bytes_left, &c) + != 0) + { + /* Input is not convertible to UTF-8. This could be fine, e.g. in a + string literal, so don't complain. Just treat it as if it has a width + of one. */ + ++m_next; + --m_bytes_left; + next_width = m_policy.m_undecoded_byte_width; + if (out) + out->m_valid_ch = false; + } + else + { + /* one_utf8_to_cppchar() has updated m_next and m_bytes_left for us. */ + next_width = m_policy.m_width_cb (c); + if (out) + { + out->m_ch = c; + out->m_valid_ch = true; + } + } + + if (out) + out->m_next_byte = m_next; + + m_display_cols += next_width; + return next_width; +} + +/* Utility to advance the byte stream by the minimum amount needed to consume + N display columns. Returns the number of display columns that were + actually skipped. This could be less than N, if there was not enough data, + or more than N, if the last character to be skipped had a sufficiently large + display width. */ +int +cpp_display_width_computation::advance_display_cols (int n) +{ + const int start = m_display_cols; + const int target = start + n; + while (m_display_cols < target && !done ()) + process_next_codepoint (NULL); + return m_display_cols - start; +} + +/* For the string of length DATA_LENGTH bytes that begins at DATA, compute + how many display columns are occupied by the first COLUMN bytes. COLUMN + may exceed DATA_LENGTH, in which case the phantom bytes at the end are + treated as if they have display width 1. Tabs are expanded to the next tab + stop, relative to the start of DATA, and non-printable-ASCII characters + will be escaped as per POLICY. */ + +int +cpp_byte_column_to_display_column (const char *data, int data_length, + int column, + const cpp_char_column_policy &policy) +{ + const int offset = MAX (0, column - data_length); + cpp_display_width_computation dw (data, column - offset, policy); + while (!dw.done ()) + dw.process_next_codepoint (NULL); + return dw.display_cols_processed () + offset; +} + +/* For the string of length DATA_LENGTH bytes that begins at DATA, compute + the least number of bytes that will result in at least DISPLAY_COL display + columns. The return value may exceed DATA_LENGTH if the entire string does + not occupy enough display columns. Non-printable-ASCII characters + will be escaped as per POLICY. */ + +int +cpp_display_column_to_byte_column (const char *data, int data_length, + int display_col, + const cpp_char_column_policy &policy) +{ + cpp_display_width_computation dw (data, data_length, policy); + const int avail_display = dw.advance_display_cols (display_col); + return dw.bytes_processed () + MAX (0, display_col - avail_display); +} + +/* Our own version of wcwidth(). We don't use the actual wcwidth() in glibc, + because that will inspect the user's locale, and in particular in an ASCII + locale, it will not return anything useful for extended characters. But GCC + in other respects (see e.g. _cpp_default_encoding()) behaves as if + everything is UTF-8. We also make some tweaks that are useful for the way + GCC needs to use this data, e.g. tabs and other control characters should be + treated as having width 1. The lookup tables are generated from + contrib/unicode/gen_wcwidth.py and were made by simply calling glibc + wcwidth() on all codepoints, then applying the small tweaks. These tables + are not highly optimized, but for the present purpose of outputting + diagnostics, they are sufficient. */ + +#include "generated_cpp_wcwidth.h" +int cpp_wcwidth (cppchar_t c) +{ + if (__builtin_expect (c <= wcwidth_range_ends[0], true)) + return wcwidth_widths[0]; + + /* Binary search the tables. */ + int begin = 1; + static const int end + = sizeof wcwidth_range_ends / sizeof (*wcwidth_range_ends); + int len = end - begin; + do + { + int half = len/2; + int middle = begin + half; + if (c > wcwidth_range_ends[middle]) + { + begin = middle + 1; + len -= half + 1; + } + else + len = half; + } while (len); + + if (__builtin_expect (begin != end, true)) + return wcwidth_widths[begin]; + return 1; +} diff --git a/support/cpp/libcpp/config.in b/support/cpp/libcpp/config.in new file mode 100644 index 000000000..9983aee59 --- /dev/null +++ b/support/cpp/libcpp/config.in @@ -0,0 +1,380 @@ +/* config.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to 1 if you want more run-time sanity checks. */ +#undef CHECKING_P + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define if you want assertions enabled. This is a cheap check. */ +#undef ENABLE_ASSERT_CHECKING + +/* Define to enable system headers canonicalization. */ +#undef ENABLE_CANONICAL_SYSTEM_HEADERS + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define to get calls to the valgrind runtime enabled. */ +#undef ENABLE_VALGRIND_ANNOTATIONS + +/* Define if you want to workaround valgrind (a memory checker) warnings about + possible memory leaks because of libcpp use of interior pointers. */ +#undef ENABLE_VALGRIND_CHECKING + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the `clearerr_unlocked' function. */ +#undef HAVE_CLEARERR_UNLOCKED + +/* Define to 1 if you have the declaration of `abort', and to 0 if you don't. + */ +#undef HAVE_DECL_ABORT + +/* Define to 1 if you have the declaration of `asprintf', and to 0 if you + don't. */ +#undef HAVE_DECL_ASPRINTF + +/* Define to 1 if you have the declaration of `basename(char *)', and to 0 if + you don't. */ +#undef HAVE_DECL_BASENAME + +/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_CLEARERR_UNLOCKED + +/* Define to 1 if you have the declaration of `errno', and to 0 if you don't. + */ +#undef HAVE_DECL_ERRNO + +/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_FEOF_UNLOCKED + +/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FERROR_UNLOCKED + +/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FFLUSH_UNLOCKED + +/* Define to 1 if you have the declaration of `fgetc_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FGETC_UNLOCKED + +/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FGETS_UNLOCKED + +/* Define to 1 if you have the declaration of `fileno_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FILENO_UNLOCKED + +/* Define to 1 if you have the declaration of `fprintf_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FPRINTF_UNLOCKED + +/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FPUTC_UNLOCKED + +/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FPUTS_UNLOCKED + +/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FREAD_UNLOCKED + +/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FWRITE_UNLOCKED + +/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_GETCHAR_UNLOCKED + +/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_GETC_UNLOCKED + +/* Define to 1 if you have the declaration of `getopt', and to 0 if you don't. + */ +#undef HAVE_DECL_GETOPT + +/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_PUTCHAR_UNLOCKED + +/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_PUTC_UNLOCKED + +/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you + don't. */ +#undef HAVE_DECL_VASPRINTF + +/* Define to 1 if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `feof_unlocked' function. */ +#undef HAVE_FEOF_UNLOCKED + +/* Define to 1 if you have the `ferror_unlocked' function. */ +#undef HAVE_FERROR_UNLOCKED + +/* Define to 1 if you have the `fflush_unlocked' function. */ +#undef HAVE_FFLUSH_UNLOCKED + +/* Define to 1 if you have the `fgetc_unlocked' function. */ +#undef HAVE_FGETC_UNLOCKED + +/* Define to 1 if you have the `fgets_unlocked' function. */ +#undef HAVE_FGETS_UNLOCKED + +/* Define to 1 if you have the `fileno_unlocked' function. */ +#undef HAVE_FILENO_UNLOCKED + +/* Define to 1 if you have the `fprintf_unlocked' function. */ +#undef HAVE_FPRINTF_UNLOCKED + +/* Define to 1 if you have the `fputc_unlocked' function. */ +#undef HAVE_FPUTC_UNLOCKED + +/* Define to 1 if you have the `fputs_unlocked' function. */ +#undef HAVE_FPUTS_UNLOCKED + +/* Define to 1 if you have the `fread_unlocked' function. */ +#undef HAVE_FREAD_UNLOCKED + +/* Define to 1 if you have the `fwrite_unlocked' function. */ +#undef HAVE_FWRITE_UNLOCKED + +/* Define to 1 if you have the `getchar_unlocked' function. */ +#undef HAVE_GETCHAR_UNLOCKED + +/* Define to 1 if you have the `getc_unlocked' function. */ +#undef HAVE_GETC_UNLOCKED + +/* Define if you have the iconv() function. */ +#undef HAVE_ICONV + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */ +#undef HAVE_LANGINFO_CODESET + +/* Define to 1 if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the <locale.h> header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if libc includes obstacks. */ +#undef HAVE_OBSTACK + +/* Define to 1 if you have the `putchar_unlocked' function. */ +#undef HAVE_PUTCHAR_UNLOCKED + +/* Define to 1 if you have the `putc_unlocked' function. */ +#undef HAVE_PUTC_UNLOCKED + +/* Define to 1 if you can assemble SSE4 insns. */ +#undef HAVE_SSE4 + +/* Define to 1 if you have the <stddef.h> header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the <sys/file.h> header file. */ +#undef HAVE_SYS_FILE_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define if <sys/types.h> defines \`uchar'. */ +#undef HAVE_UCHAR + +/* Define to 1 if the system has the type `uintptr_t'. */ +#undef HAVE_UINTPTR_T + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Define as const if the declaration of iconv() needs const. */ +#undef ICONV_CONST + +/* Define to the name of this package. */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* The size of `dev_t', as computed by sizeof. */ +#undef SIZEOF_DEV_T + +/* The size of `ino_t', as computed by sizeof. */ +#undef SIZEOF_INO_T + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you can safely include both <string.h> and <strings.h>. */ +#undef STRING_WITH_STRINGS + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your <sys/time.h> declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT64_T + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `long int' if <sys/types.h> does not define. */ +#undef off_t + +/* Define to `int' if <sys/types.h> does not define. */ +#undef ptrdiff_t + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t + +/* Define to `int' if <sys/types.h> does not define. */ +#undef ssize_t + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef uint64_t + +/* Define to the type of an unsigned integer type wide enough to hold a + pointer, if such a type exists, and if the system does not define it. */ +#undef uintptr_t diff --git a/support/cpp/libcpp/configure b/support/cpp/libcpp/configure new file mode 100755 index 000000000..751453902 --- /dev/null +++ b/support/cpp/libcpp/configure @@ -0,0 +1,9160 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for cpplib . +# +# Report bugs to <gcc-bugs@gcc.gnu.org>. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: gcc-bugs@gcc.gnu.org about your system, including any +$0: error possibly output before this message. Then install +$0: a modern shell, or manually run the script under such a +$0: shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='cpplib' +PACKAGE_TARNAME='cpplib' +PACKAGE_VERSION=' ' +PACKAGE_STRING='cpplib ' +PACKAGE_BUGREPORT='gcc-bugs@gcc.gnu.org' +PACKAGE_URL='' + +ac_unique_file="ucnid.h" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='LTLIBOBJS +CET_HOST_FLAGS +PICFLAG +MAINT +USED_CATALOGS +PACKAGE +LTLIBICONV +LIBICONV +CATOBJEXT +GENCAT +INSTOBJEXT +DATADIRNAME +CATALOGS +POSUB +GMSGFMT +XGETTEXT +INCINTL +LIBINTL_DEP +LIBINTL +USE_NLS +ALLOCA +LIBOBJS +CXXDEPMODE +DEPDIR +am__leading_dot +WERROR +noexception_flags +WARN_PEDANTIC +c_warn +warn +ETAGS +AUTOHEADER +AUTOCONF +ACLOCAL +EGREP +GREP +CPP +AR +RANLIB +ac_ct_CXX +CXXFLAGS +CXX +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +SET_MAKE +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_largefile +enable_werror_always +with_gnu_ld +enable_rpath +with_libiconv_prefix +with_libiconv_type +enable_maintainer_mode +enable_checking +enable_canonical_system_headers +enable_host_shared +enable_cet +enable_valgrind_annotations +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures cpplib to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/cpplib] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of cpplib :";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-largefile omit support for large files + --enable-werror-always enable -Werror despite compiler version + --disable-rpath do not hardcode runtime library paths + --enable-maintainer-mode enable rules only needed by maintainers + --enable-checking[=LIST] + enable expensive run-time checks. With LIST, enable + only specific categories of checks. Categories are: + yes,no,all,none,release. Flags are: misc,valgrind or + other strings + --enable-canonical-system-headers + enable or disable system headers canonicalization + --enable-host-shared build host code as shared libraries + --enable-cet enable Intel CET in host libraries [default=auto] + --enable-valgrind-annotations + enable valgrind runtime interaction + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld assume the C compiler uses GNU ld default=no + --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib + --without-libiconv-prefix don't search for libiconv in includedir and libdir + --with-libiconv-type=TYPE type of library to search for (auto/static/shared) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to <gcc-bugs@gcc.gnu.org>. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +cpplib configure +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ----------------------------------- ## +## Report this to gcc-bugs@gcc.gnu.org ## +## ----------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_find_uintX_t LINENO BITS VAR +# ------------------------------------ +# Finds an unsigned integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_uintX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 +$as_echo_n "checking for uint$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ + 'unsigned long long int' 'unsigned short int' 'unsigned char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + case $ac_type in #( + uint$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_uintX_t + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include <stdio.h> +#include <stdlib.h> +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 <conftest.val; ac_retval=0 +else + ac_retval=1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.val + + fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_compute_int + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by cpplib $as_me , which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + + +# Checks for programs. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. +set dummy ${ac_tool_prefix}ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="${ac_tool_prefix}ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AR"; then + ac_ct_AR=$AR + # Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="ar" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +else + AR="$ac_cv_prog_AR" +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + +# Check whether --enable-largefile was given. +if test "${enable_largefile+set}" = set; then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } +if ${ac_cv_sys_largefile_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if ${ac_cv_sys_file_offset_bits+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } +if ${ac_cv_sys_large_files+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include <sys/types.h> + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF +;; +esac +rm -rf conftest* + fi + + +fi + + +MISSING=`cd $ac_aux_dir && ${PWDCMD-pwd}`/missing +for ac_prog in aclocal +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ACLOCAL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ACLOCAL"; then + ac_cv_prog_ACLOCAL="$ACLOCAL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ACLOCAL="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ACLOCAL=$ac_cv_prog_ACLOCAL +if test -n "$ACLOCAL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ACLOCAL" >&5 +$as_echo "$ACLOCAL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ACLOCAL" && break +done +test -n "$ACLOCAL" || ACLOCAL="$MISSING aclocal" + +for ac_prog in autoconf +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AUTOCONF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AUTOCONF"; then + ac_cv_prog_AUTOCONF="$AUTOCONF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AUTOCONF="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AUTOCONF=$ac_cv_prog_AUTOCONF +if test -n "$AUTOCONF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AUTOCONF" >&5 +$as_echo "$AUTOCONF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AUTOCONF" && break +done +test -n "$AUTOCONF" || AUTOCONF="$MISSING autoconf" + +for ac_prog in autoheader +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AUTOHEADER+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AUTOHEADER"; then + ac_cv_prog_AUTOHEADER="$AUTOHEADER" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AUTOHEADER="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AUTOHEADER=$ac_cv_prog_AUTOHEADER +if test -n "$AUTOHEADER"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AUTOHEADER" >&5 +$as_echo "$AUTOHEADER" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AUTOHEADER" && break +done +test -n "$AUTOHEADER" || AUTOHEADER="$MISSING autoheader" + + +if test -z "$ETAGS"; then + ETAGS=etags +fi + + +# Figure out what compiler warnings we can enable. +# See config/warnings.m4 for details. + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +warn= +save_CFLAGS="$CFLAGS" +for real_option in -W -Wall -Wno-narrowing -Wwrite-strings \ + -Wmissing-format-attribute; do + # Do the check with the no- prefix removed since gcc silently + # accepts any -Wno-* option on purpose + case $real_option in + -Wno-*) option=-W`expr x$real_option : 'x-Wno-\(.*\)'` ;; + *) option=$real_option ;; + esac + as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh` + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5 +$as_echo_n "checking whether $CC supports $option... " >&6; } +if eval \${$as_acx_Woption+:} false; then : + $as_echo_n "(cached) " >&6 +else + CFLAGS="$option" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_acx_Woption=yes" +else + eval "$as_acx_Woption=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +eval ac_res=\$$as_acx_Woption + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then : + warn="$warn${warn:+ }$real_option" +fi + done +CFLAGS="$save_CFLAGS" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +c_warn= +save_CFLAGS="$CFLAGS" +for real_option in -Wstrict-prototypes -Wmissing-prototypes \ + -Wold-style-definition -Wc++-compat; do + # Do the check with the no- prefix removed since gcc silently + # accepts any -Wno-* option on purpose + case $real_option in + -Wno-*) option=-W`expr x$real_option : 'x-Wno-\(.*\)'` ;; + *) option=$real_option ;; + esac + as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh` + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5 +$as_echo_n "checking whether $CC supports $option... " >&6; } +if eval \${$as_acx_Woption+:} false; then : + $as_echo_n "(cached) " >&6 +else + CFLAGS="$option" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_acx_Woption=yes" +else + eval "$as_acx_Woption=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +eval ac_res=\$$as_acx_Woption + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then : + c_warn="$c_warn${c_warn:+ }$real_option" +fi + done +CFLAGS="$save_CFLAGS" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +WARN_PEDANTIC= +# Do the check with the no- prefix removed from the warning options +# since gcc silently accepts any -Wno-* option on purpose +if test "$GCC" = yes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -pedantic -Wlong-long" >&5 +$as_echo_n "checking whether $CC supports -pedantic -Wlong-long... " >&6; } +if ${acx_cv_prog_cc_pedantic__Wlong_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_CFLAGS="$CFLAGS" +CFLAGS="-pedantic -Wlong-long" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + acx_cv_prog_cc_pedantic__Wlong_long=yes +else + acx_cv_prog_cc_pedantic__Wlong_long=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +CFLAGS="$save_CFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_cv_prog_cc_pedantic__Wlong_long" >&5 +$as_echo "$acx_cv_prog_cc_pedantic__Wlong_long" >&6; } +if test $acx_cv_prog_cc_pedantic__Wlong_long = yes; then : + WARN_PEDANTIC="$WARN_PEDANTIC${WARN_PEDANTIC:+ }-pedantic -Wno-long-long" +fi + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Disable exceptions and RTTI if building with g++ +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +noexception_flags= +save_CFLAGS="$CFLAGS" +for real_option in -fno-exceptions -fno-rtti; do + # Do the check with the no- prefix removed since gcc silently + # accepts any -Wno-* option on purpose + case $real_option in + -Wno-*) option=-W`expr x$real_option : 'x-Wno-\(.*\)'` ;; + *) option=$real_option ;; + esac + as_acx_Woption=`$as_echo "acx_cv_prog_cc_warning_$option" | $as_tr_sh` + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports $option" >&5 +$as_echo_n "checking whether $CC supports $option... " >&6; } +if eval \${$as_acx_Woption+:} false; then : + $as_echo_n "(cached) " >&6 +else + CFLAGS="$option" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_acx_Woption=yes" +else + eval "$as_acx_Woption=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +eval ac_res=\$$as_acx_Woption + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + if test `eval 'as_val=${'$as_acx_Woption'};$as_echo "$as_val"'` = yes; then : + noexception_flags="$noexception_flags${noexception_flags:+ }$real_option" +fi + done +CFLAGS="$save_CFLAGS" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Only enable with --enable-werror-always until existing warnings are +# corrected. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +WERROR= +# Check whether --enable-werror-always was given. +if test "${enable_werror_always+set}" = set; then : + enableval=$enable_werror_always; +else + enable_werror_always=no +fi + +if test $enable_werror_always = yes; then : + WERROR="$WERROR${WERROR:+ }-Werror" +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Dependency checking. +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depdir" + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int i; +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + as_fn_error $? "C++ compiler missing or inoperational" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +am_depcomp=$ac_aux_dir/depcomp +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + if test $depmode = none; then break; fi + + $as_echo "$as_me:$LINENO: trying $depmode" >&5 + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "include sub/conftest.Po" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + depcmd="depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c" + echo "| $depcmd" | sed -e 's/ */ /g' >&5 + if env $depcmd > conftest.err 2>&1 && + grep sub/conftst6.h sub/conftest.Po >>conftest.err 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po >>conftest.err 2>&1 && + ${MAKE-make} -s -f confmf >>conftest.err 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + $as_echo "$as_me:$LINENO: success" >&5 + break + fi + fi + $as_echo "$as_me:$LINENO: failure, diagnostics are:" >&5 + sed -e 's/^/| /' < conftest.err >&5 + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +if test x${am_cv_CXX_dependencies_compiler_type-none} = xnone +then as_fn_error $? "no usable dependency style found" "$LINENO" 5 +else CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + +fi + + +# Checks for header files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <sys/time.h> +#include <time.h> + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether string.h and strings.h may both be included" >&5 +$as_echo_n "checking whether string.h and strings.h may both be included... " >&6; } +if ${gcc_cv_header_string+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> +#include <strings.h> +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gcc_cv_header_string=yes +else + gcc_cv_header_string=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_string" >&5 +$as_echo "$gcc_cv_header_string" >&6; } +if test $gcc_cv_header_string = yes; then + +$as_echo "#define STRING_WITH_STRINGS 1" >>confdefs.h + +fi + + +for ac_header in locale.h fcntl.h limits.h stddef.h \ + stdlib.h strings.h string.h sys/file.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + #include <sys/param.h> + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for obstacks" >&5 +$as_echo_n "checking for obstacks... " >&6; } +if ${ac_cv_func_obstack+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + #include "obstack.h" +int +main () +{ +struct obstack mem; + #define obstack_chunk_alloc malloc + #define obstack_chunk_free free + obstack_init (&mem); + obstack_free (&mem, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_obstack=yes +else + ac_cv_func_obstack=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_obstack" >&5 +$as_echo "$ac_cv_func_obstack" >&6; } +if test $ac_cv_func_obstack = yes; then + +$as_echo "#define HAVE_OBSTACK 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" obstack.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS obstack.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" +if test "x$ac_cv_type_off_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define off_t long int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" +if test "x$ac_cv_type_ssize_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define ssize_t int +_ACEOF + +fi + + + ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" +if test "x$ac_cv_type_uintptr_t" = xyes; then : + +$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h + +else + for ac_type in 'unsigned int' 'unsigned long int' \ + 'unsigned long long int'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +cat >>confdefs.h <<_ACEOF +#define uintptr_t $ac_type +_ACEOF + + ac_type= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test -z "$ac_type" && break + done +fi + + +ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" +if test "x$ac_cv_type_ptrdiff_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define ptrdiff_t int +_ACEOF + +fi + +ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t" +case $ac_cv_c_uint64_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT64_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint64_t $ac_cv_c_uint64_t +_ACEOF +;; + esac + +if test x"$ac_cv_c_uint64_t" = x"no"; then + as_fn_error $? "uint64_t not found" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if ${ac_cv_struct_tm+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <time.h> + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_struct_tm=time.h +else + ac_cv_struct_tm=sys/time.h +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +$as_echo "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h + +fi + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +$as_echo_n "checking size of int... " >&6; } +if ${ac_cv_sizeof_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +$as_echo "$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + +for ac_func in clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +ac_fn_c_check_decl "$LINENO" "abort" "ac_cv_have_decl_abort" "$ac_includes_default" +if test "x$ac_cv_have_decl_abort" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_ABORT $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "asprintf" "ac_cv_have_decl_asprintf" "$ac_includes_default" +if test "x$ac_cv_have_decl_asprintf" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_ASPRINTF $ac_have_decl +_ACEOF +as_ac_Symbol=`$as_echo "ac_cv_have_decl_basename(char *)" | $as_tr_sh` +ac_fn_c_check_decl "$LINENO" "basename(char *)" "$as_ac_Symbol" "$ac_includes_default" +if eval test \"x\$"$as_ac_Symbol"\" = x"yes"; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_BASENAME $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "errno" "ac_cv_have_decl_errno" "$ac_includes_default" +if test "x$ac_cv_have_decl_errno" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_ERRNO $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "getopt" "ac_cv_have_decl_getopt" "$ac_includes_default" +if test "x$ac_cv_have_decl_getopt" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETOPT $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "vasprintf" "ac_cv_have_decl_vasprintf" "$ac_includes_default" +if test "x$ac_cv_have_decl_vasprintf" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_VASPRINTF $ac_have_decl +_ACEOF + +ac_fn_c_check_decl "$LINENO" "clearerr_unlocked" "ac_cv_have_decl_clearerr_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_clearerr_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_CLEARERR_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "feof_unlocked" "ac_cv_have_decl_feof_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_feof_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FEOF_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "ferror_unlocked" "ac_cv_have_decl_ferror_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_ferror_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FERROR_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "fflush_unlocked" "ac_cv_have_decl_fflush_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fflush_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FFLUSH_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "fgetc_unlocked" "ac_cv_have_decl_fgetc_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fgetc_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FGETC_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "fgets_unlocked" "ac_cv_have_decl_fgets_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fgets_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FGETS_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "fileno_unlocked" "ac_cv_have_decl_fileno_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fileno_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FILENO_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "fprintf_unlocked" "ac_cv_have_decl_fprintf_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fprintf_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FPRINTF_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "fputc_unlocked" "ac_cv_have_decl_fputc_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fputc_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FPUTC_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "fputs_unlocked" "ac_cv_have_decl_fputs_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fputs_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FPUTS_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "fread_unlocked" "ac_cv_have_decl_fread_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fread_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FREAD_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "fwrite_unlocked" "ac_cv_have_decl_fwrite_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fwrite_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FWRITE_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "getchar_unlocked" "ac_cv_have_decl_getchar_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_getchar_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETCHAR_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "getc_unlocked" "ac_cv_have_decl_getc_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_getc_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETC_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "putchar_unlocked" "ac_cv_have_decl_putchar_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_putchar_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PUTCHAR_UNLOCKED $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "putc_unlocked" "ac_cv_have_decl_putc_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_putc_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PUTC_UNLOCKED $ac_have_decl +_ACEOF + + +# Checks for library functions. +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 +$as_echo_n "checking for working alloca.h... " >&6; } +if ${ac_cv_working_alloca_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <alloca.h> +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_working_alloca_h=yes +else + ac_cv_working_alloca_h=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 +$as_echo "$ac_cv_working_alloca_h" >&6; } +if test $ac_cv_working_alloca_h = yes; then + +$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 +$as_echo_n "checking for alloca... " >&6; } +if ${ac_cv_func_alloca_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include <malloc.h> +# define alloca _alloca +# else +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +void *alloca (size_t); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + if (p) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_func_alloca_works=yes +else + ac_cv_func_alloca_works=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 +$as_echo "$ac_cv_func_alloca_works" >&6; } + +if test $ac_cv_func_alloca_works = yes; then + +$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=\${LIBOBJDIR}alloca.$ac_objext + +$as_echo "#define C_ALLOCA 1" >>confdefs.h + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 +$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } +if ${ac_cv_os_cray+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined CRAY && ! defined CRAY2 +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then : + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 +$as_echo "$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 +$as_echo_n "checking stack direction for C alloca... " >&6; } +if ${ac_cv_c_stack_direction+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_c_stack_direction=0 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +find_stack_direction (int *addr, int depth) +{ + int dir, dummy = 0; + if (! addr) + addr = &dummy; + *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; + dir = depth ? find_stack_direction (addr, depth - 1) : 0; + return dir + dummy; +} + +int +main (int argc, char **argv) +{ + return find_stack_direction (0, argc + !argv + 20) < 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_stack_direction=1 +else + ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 +$as_echo "$ac_cv_c_stack_direction" >&6; } +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5 +$as_echo_n "checking for nl_langinfo and CODESET... " >&6; } +if ${am_cv_langinfo_codeset+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <langinfo.h> +int +main () +{ +char* cs = nl_langinfo(CODESET); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_langinfo_codeset=yes +else + am_cv_langinfo_codeset=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_langinfo_codeset" >&5 +$as_echo "$am_cv_langinfo_codeset" >&6; } + if test $am_cv_langinfo_codeset = yes; then + +$as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h + + fi + +# If we haven't got the data from the intl directory, +# assume NLS is disabled. +USE_NLS=no +LIBINTL= +LIBINTL_DEP= +INCINTL= +XGETTEXT= +GMSGFMT= +POSUB= + +if test -f ../intl/config.intl; then + . ../intl/config.intl +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 +$as_echo_n "checking whether NLS is requested... " >&6; } +if test x"$USE_NLS" != xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for catalogs to be installed" >&5 +$as_echo_n "checking for catalogs to be installed... " >&6; } + # Look for .po and .gmo files in the source directory. + CATALOGS= + XLINGUAS= + for cat in $srcdir/po/*.gmo $srcdir/po/*.po; do + # If there aren't any .gmo files the shell will give us the + # literal string "../path/to/srcdir/po/*.gmo" which has to be + # weeded out. + case "$cat" in *\**) + continue;; + esac + # The quadruple backslash is collapsed to a double backslash + # by the backticks, then collapsed again by the double quotes, + # leaving us with one backslash in the sed expression (right + # before the dot that mustn't act as a wildcard). + cat=`echo $cat | sed -e "s!$srcdir/po/!!" -e "s!\\\\.po!.gmo!"` + lang=`echo $cat | sed -e "s!\\\\.gmo!!"` + # The user is allowed to set LINGUAS to a list of languages to + # install catalogs for. If it's empty that means "all of them." + if test "x$LINGUAS" = x; then + CATALOGS="$CATALOGS $cat" + XLINGUAS="$XLINGUAS $lang" + else + case "$LINGUAS" in *$lang*) + CATALOGS="$CATALOGS $cat" + XLINGUAS="$XLINGUAS $lang" + ;; + esac + fi + done + LINGUAS="$XLINGUAS" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINGUAS" >&5 +$as_echo "$LINGUAS" >&6; } + + + DATADIRNAME=share + + INSTOBJEXT=.mo + + GENCAT=gencat + + CATOBJEXT=.gmo + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uchar" >&5 +$as_echo_n "checking for uchar... " >&6; } +if ${gcc_cv_type_uchar+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> + +int +main () +{ +if ((uchar *)0) return 0; + if (sizeof(uchar)) return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_uchar=yes +else + ac_cv_type_uchar=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_type_uchar" >&5 +$as_echo "$gcc_cv_type_uchar" >&6; } +if test $ac_cv_type_uchar = yes; then + +$as_echo "#define HAVE_UCHAR 1" >>confdefs.h + +fi + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ino_t" >&5 +$as_echo_n "checking size of ino_t... " >&6; } +if ${ac_cv_sizeof_ino_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (ino_t))" "ac_cv_sizeof_ino_t" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_ino_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (ino_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_ino_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ino_t" >&5 +$as_echo "$ac_cv_sizeof_ino_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INO_T $ac_cv_sizeof_ino_t +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of dev_t" >&5 +$as_echo_n "checking size of dev_t... " >&6; } +if ${ac_cv_sizeof_dev_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (dev_t))" "ac_cv_sizeof_dev_t" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_dev_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (dev_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_dev_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_dev_t" >&5 +$as_echo "$ac_cv_sizeof_dev_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_DEV_T $ac_cv_sizeof_dev_t +_ACEOF + + + +# g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which exposes a different +# iconv() prototype. +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 +$as_echo_n "checking for ld used by GCC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${acl_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$acl_cv_path_LD" +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${acl_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then + acl_cv_prog_gnu_ld=yes +else + acl_cv_prog_gnu_ld=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_prog_gnu_ld" >&5 +$as_echo "$acl_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$acl_cv_prog_gnu_ld + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 +$as_echo_n "checking for shared library run path origin... " >&6; } +if ${acl_cv_rpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 +$as_echo "$acl_cv_rpath" >&6; } + wl="$acl_cv_wl" + libext="$acl_cv_libext" + shlibext="$acl_cv_shlibext" + hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + hardcode_direct="$acl_cv_hardcode_direct" + hardcode_minus_L="$acl_cv_hardcode_minus_L" + # Check whether --enable-rpath was given. +if test "${enable_rpath+set}" = set; then : + enableval=$enable_rpath; : +else + enable_rpath=yes +fi + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libiconv-prefix was given. +if test "${with_libiconv_prefix+set}" = set; then : + withval=$with_libiconv_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi + +fi + + +# Check whether --with-libiconv-type was given. +if test "${with_libiconv_type+set}" = set; then : + withval=$with_libiconv_type; with_libiconv_type=$withval +else + with_libiconv_type=auto +fi + + lib_type=`eval echo \$with_libiconv_type` + + LIBICONV= + LTLIBICONV= + INCICONV= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='iconv ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext" && test x$lib_type != xstatic; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + elif test x$lib_type != xshared; then + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext" && test x$lib_type != xstatic; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + elif test x$lib_type != xshared; then + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$hardcode_direct" = yes; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" + ;; + esac + done + fi + else + if test "x$lib_type" = "xauto" || test "x$lib_type" = "xshared"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l:lib$name.$libext" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l:lib$name.$libext" + fi + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" + done + fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 +$as_echo_n "checking for iconv... " >&6; } +if ${am_cv_func_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + am_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <iconv.h> +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CPPFLAGS="$am_save_CPPFLAGS" + + if test "$am_cv_func_iconv" != yes && test -d ../libiconv; then + for _libs in .libs _libs; do + am_save_CPPFLAGS="$CPPFLAGS" + am_save_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS -I../libiconv/include" + LIBS="$LIBS ../libiconv/lib/$_libs/libiconv.a" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <iconv.h> +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + INCICONV="-I../libiconv/include" + LIBICONV='${top_builddir}'/../libiconv/lib/$_libs/libiconv.a + LTLIBICONV='${top_builddir}'/../libiconv/lib/libiconv.la + am_cv_lib_iconv=yes + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CPPFLAGS="$am_save_CPPFLAGS" + LIBS="$am_save_LIBS" + if test "$am_cv_func_iconv" = "yes"; then + break + fi + done + fi + + if test "$am_cv_func_iconv" != yes; then + am_save_CPPFLAGS="$CPPFLAGS" + am_save_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $INCICONV" + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <iconv.h> +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + am_cv_lib_iconv=yes + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CPPFLAGS="$am_save_CPPFLAGS" + LIBS="$am_save_LIBS" + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 +$as_echo "$am_cv_func_iconv" >&6; } + if test "$am_cv_func_iconv" = yes; then + +$as_echo "#define HAVE_ICONV 1" >>confdefs.h + + fi + if test "$am_cv_lib_iconv" = yes; then + + for element in $INCICONV; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 +$as_echo_n "checking how to link with libiconv... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 +$as_echo "$LIBICONV" >&6; } + else + LIBICONV= + LTLIBICONV= + fi + + + + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv declaration" >&5 +$as_echo_n "checking for iconv declaration... " >&6; } + if ${am_cv_proto_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <stdlib.h> +#include <iconv.h> +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + am_cv_proto_iconv_arg1="" +else + am_cv_proto_iconv_arg1="const" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);" +fi + + am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_t:- + }$am_cv_proto_iconv" >&5 +$as_echo "${ac_t:- + }$am_cv_proto_iconv" >&6; } + +cat >>confdefs.h <<_ACEOF +#define ICONV_CONST $am_cv_proto_iconv_arg1 +_ACEOF + + fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# More defines and substitutions. +PACKAGE="$PACKAGE_TARNAME" + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + + +if test "x$enable_nls" != xno; then + USED_CATALOGS='$(CATALOGS)' +else + USED_CATALOGS= +fi + + +# Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; +else + enable_maintainer_mode=no +fi + + +if test "x$enable_maintainer_mode" = xno; then + MAINT='#' +else + MAINT= +fi + + +# Enable expensive internal checks +is_release= +if test -f $srcdir/../gcc/DEV-PHASE \ + && test x"`cat $srcdir/../gcc/DEV-PHASE`" != xexperimental; then + is_release=yes +fi + +# Check whether --enable-checking was given. +if test "${enable_checking+set}" = set; then : + enableval=$enable_checking; ac_checking_flags="${enableval}" +else + +# Determine the default checks. +if test x$is_release = x ; then + ac_checking_flags=yes +else + ac_checking_flags=release +fi +fi + +IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="$IFS," +for check in release $ac_checking_flags +do + case $check in + # these set all the flags to specific states + yes|all) ac_checking=1 ; ac_assert_checking=1 ; ac_valgrind_checking= ;; + no|none) ac_checking= ; ac_assert_checking= ; ac_valgrind_checking= ;; + release) ac_checking= ; ac_assert_checking=1 ; ac_valgrind_checking= ;; + # these enable particular checks + assert) ac_assert_checking=1 ;; + misc) ac_checking=1 ;; + valgrind) ac_valgrind_checking=1 ;; + # accept + *) ;; + esac +done +IFS="$ac_save_IFS" + +if test x$ac_checking != x ; then + +$as_echo "#define CHECKING_P 1" >>confdefs.h + +else + $as_echo "#define CHECKING_P 0" >>confdefs.h + +fi + +if test x$ac_assert_checking != x ; then + +$as_echo "#define ENABLE_ASSERT_CHECKING 1" >>confdefs.h + +fi + +if test x$ac_valgrind_checking != x ; then + +$as_echo "#define ENABLE_VALGRIND_CHECKING 1" >>confdefs.h + +fi + +# Check whether --enable-canonical-system-headers was given. +if test "${enable_canonical_system_headers+set}" = set; then : + enableval=$enable_canonical_system_headers; +else + enable_canonical_system_headers=yes +fi + +if test $enable_canonical_system_headers != no; then + +$as_echo "#define ENABLE_CANONICAL_SYSTEM_HEADERS 1" >>confdefs.h + +fi + +case $target in + i?86-* | x86_64-*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +asm ("pcmpestri %0, %%xmm0, %%xmm1" : : "i"(0)) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +$as_echo "#define HAVE_SSE4 1" >>confdefs.h + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +esac + +# Enable --enable-host-shared. +# Check whether --enable-host-shared was given. +if test "${enable_host_shared+set}" = set; then : + enableval=$enable_host_shared; PICFLAG=-fPIC +else + PICFLAG= +fi + + + +# Enable Intel CET on Intel CET enabled host if jit is enabled. + # Check whether --enable-cet was given. +if test "${enable_cet+set}" = set; then : + enableval=$enable_cet; + case "$enableval" in + yes|no|auto) ;; + *) as_fn_error $? "Unknown argument to enable/disable cet" "$LINENO" 5 ;; + esac + +else + enable_cet=auto +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CET support" >&5 +$as_echo_n "checking for CET support... " >&6; } + +case "$host" in + i[34567]86-*-linux* | x86_64-*-linux*) + may_have_cet=yes + cet_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fcf-protection" + case "$enable_cet" in + auto) + # Check if target supports multi-byte NOPs + # and if compiler and assembler support CET. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if !defined(__SSE2__) +#error target does not support multi-byte NOPs +#else +asm ("setssbsy"); +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + enable_cet=yes +else + enable_cet=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + yes) + # Check if compiler and assembler support CET. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +asm ("setssbsy"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + support_cet=yes +else + support_cet=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $support_cet = "no"; then + if test x$enable_bootstrap != xno \ + && test -z "${with_build_subdir}" \ + && (test ! -f ../stage_current \ + || test `cat ../stage_current` != "stage1"); then + # Require CET support only for the final GCC build. + as_fn_error $? "compiler and assembler with CET support are required for --enable-cet" "$LINENO" 5 + else + # Don't enable CET without CET support for non-bootstrap + # build, in stage1 nor for build support. + enable_cet=no + fi + fi + ;; + esac + CFLAGS="$cet_save_CFLAGS" + ;; + *) + may_have_cet=no + enable_cet=no + ;; +esac + +cet_save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -fcf-protection=none" +cet_save_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS -Wl,-z,ibt,-z,shstk" +if test x$may_have_cet = xyes; then + # Check whether -fcf-protection=none -Wl,-z,ibt,-z,shstk work. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + may_have_cet=yes +else + may_have_cet=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +if test x$may_have_cet = xyes; then + if test x$cross_compiling = xno; then + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + asm ("endbr32"); + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + have_multi_byte_nop=yes +else + have_multi_byte_nop=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + have_cet=no + if test x$have_multi_byte_nop = xyes; then + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +static void +foo (void) +{ +} + +static void +__attribute__ ((noinline, noclone)) +xxx (void (*f) (void)) +{ + f (); +} + +static void +__attribute__ ((noinline, noclone)) +bar (void) +{ + xxx (foo); +} + +int +main () +{ + bar (); + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + have_cet=no +else + have_cet=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi + if test x$enable_cet = xno -a x$have_cet = xyes; then + as_fn_error $? "Intel CET must be enabled on Intel CET enabled host" "$LINENO" 5 + fi + fi +else + # Enable CET in cross compiler if possible so that it will run on both + # CET and non-CET hosts. + have_cet=yes +fi +if test x$enable_cet = xyes; then + CET_HOST_FLAGS="-fcf-protection" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +CFLAGS="$cet_save_CFLAGS" +LDFLAGS="$cet_save_LDFLAGS" + +case x$enable_languages in +*jit*) + ;; +*) + CET_HOST_FLAGS= + ;; +esac + + +# Check whether --enable-valgrind-annotations was given. +if test "${enable_valgrind_annotations+set}" = set; then : + enableval=$enable_valgrind_annotations; +else + enable_valgrind_annotations=no +fi + +if test x$enable_valgrind_annotations != xno \ + || test x$ac_valgrind_checking != x; then + if (test $have_valgrind_h = no \ + && test $gcc_cv_header_memcheck_h = no \ + && test $gcc_cv_header_valgrind_memcheck_h = no); then + as_fn_error $? "*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h" "$LINENO" 5 + fi + +$as_echo "#define ENABLE_VALGRIND_ANNOTATIONS 1" >>confdefs.h + +fi + +# Output. + +ac_config_headers="$ac_config_headers config.h:config.in" + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by cpplib $as_me , which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to <gcc-bugs@gcc.gnu.org>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +cpplib config.status +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +ac_aux_dir=$ac_aux_dir DEPDIR=$DEPDIR + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depdir") CONFIG_COMMANDS="$CONFIG_COMMANDS depdir" ;; + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config.in" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depdir":C) $SHELL $ac_aux_dir/mkinstalldirs $DEPDIR ;; + "config.h":H) echo timestamp > stamp-h1 ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/support/cpp/libcpp/configure.ac b/support/cpp/libcpp/configure.ac new file mode 100644 index 000000000..9b6042518 --- /dev/null +++ b/support/cpp/libcpp/configure.ac @@ -0,0 +1,248 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_INIT(cpplib, [ ], gcc-bugs@gcc.gnu.org, cpplib) +AC_CONFIG_SRCDIR(ucnid.h) +AC_CONFIG_MACRO_DIR(../config) +AC_CANONICAL_SYSTEM + +# Checks for programs. +AC_PROG_MAKE_SET +AC_PROG_INSTALL +AC_PROG_CC +AC_PROG_CXX +AC_PROG_RANLIB +AC_CHECK_TOOL(AR, ar) + +AC_USE_SYSTEM_EXTENSIONS +AC_SYS_LARGEFILE + +MISSING=`cd $ac_aux_dir && ${PWDCMD-pwd}`/missing +AC_CHECK_PROGS([ACLOCAL], [aclocal], [$MISSING aclocal]) +AC_CHECK_PROGS([AUTOCONF], [autoconf], [$MISSING autoconf]) +AC_CHECK_PROGS([AUTOHEADER], [autoheader], [$MISSING autoheader]) + +if test -z "$ETAGS"; then + ETAGS=etags +fi +AC_SUBST([ETAGS]) + +# Figure out what compiler warnings we can enable. +# See config/warnings.m4 for details. + +ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wno-narrowing -Wwrite-strings \ + -Wmissing-format-attribute], [warn]) +ACX_PROG_CC_WARNING_OPTS([-Wstrict-prototypes -Wmissing-prototypes \ + -Wold-style-definition -Wc++-compat], [c_warn]) +ACX_PROG_CC_WARNING_ALMOST_PEDANTIC([-Wno-long-long]) + +# Disable exceptions and RTTI if building with g++ +ACX_PROG_CC_WARNING_OPTS( + m4_quote(m4_do([-fno-exceptions -fno-rtti])), [noexception_flags]) + +# Only enable with --enable-werror-always until existing warnings are +# corrected. +ACX_PROG_CC_WARNINGS_ARE_ERRORS([manual]) + +# Dependency checking. +ZW_CREATE_DEPDIR +AC_LANG_PUSH([C++]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([int i;])], [], + [AC_MSG_ERROR([C++ compiler missing or inoperational])]) +AC_LANG_POP([C++]) +ZW_PROG_COMPILER_DEPENDENCIES([CXX]) + +# Checks for header files. +AC_HEADER_TIME +ACX_HEADER_STRING + +AC_CHECK_HEADERS(locale.h fcntl.h limits.h stddef.h \ + stdlib.h strings.h string.h sys/file.h unistd.h) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_BIGENDIAN +AC_C_CONST +AC_C_INLINE +AC_FUNC_OBSTACK +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_TYPE_UINTPTR_T +AC_CHECK_TYPE(ptrdiff_t, int) +AC_TYPE_UINT64_T +if test x"$ac_cv_c_uint64_t" = x"no"; then + AC_MSG_ERROR([uint64_t not found]) +fi +AC_STRUCT_TM +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(long) +define(libcpp_UNLOCKED_FUNCS, clearerr_unlocked feof_unlocked dnl + ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked dnl + fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked dnl + fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked dnl + putchar_unlocked putc_unlocked) +AC_CHECK_FUNCS(libcpp_UNLOCKED_FUNCS) +AC_CHECK_DECLS([abort, asprintf, basename(char *), errno, getopt, vasprintf]) +AC_CHECK_DECLS(m4_split(m4_normalize(libcpp_UNLOCKED_FUNCS))) + +# Checks for library functions. +AC_FUNC_ALLOCA +AC_HEADER_STDC +AM_LANGINFO_CODESET +ZW_GNU_GETTEXT_SISTER_DIR + +AC_CACHE_CHECK(for uchar, gcc_cv_type_uchar, +[AC_TRY_COMPILE([ +#include <sys/types.h> +], +[if ((uchar *)0) return 0; + if (sizeof(uchar)) return 0;], +ac_cv_type_uchar=yes, ac_cv_type_uchar=no)]) +if test $ac_cv_type_uchar = yes; then + AC_DEFINE(HAVE_UCHAR, 1, + [Define if <sys/types.h> defines \`uchar'.]) +fi + +AC_CHECK_SIZEOF(ino_t) +AC_CHECK_SIZEOF(dev_t) + +# g++ on Solaris 10+ defines _XOPEN_SOURCE=600, which exposes a different +# iconv() prototype. +AC_LANG_PUSH([C++]) +AM_ICONV +AC_LANG_POP([C++]) + +# More defines and substitutions. +PACKAGE="$PACKAGE_TARNAME" +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Define to the name of this package.]) +AC_SUBST(PACKAGE) + +if test "x$enable_nls" != xno; then + USED_CATALOGS='$(CATALOGS)' +else + USED_CATALOGS= +fi +AC_SUBST(USED_CATALOGS) + +AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable rules only needed by maintainers],, +enable_maintainer_mode=no) + +if test "x$enable_maintainer_mode" = xno; then + MAINT='#' +else + MAINT= +fi +AC_SUBST(MAINT) + +# Enable expensive internal checks +is_release= +if test -f $srcdir/../gcc/DEV-PHASE \ + && test x"`cat $srcdir/../gcc/DEV-PHASE`" != xexperimental; then + is_release=yes +fi + +AC_ARG_ENABLE(checking, +[AS_HELP_STRING([[--enable-checking[=LIST]]], + [enable expensive run-time checks. With LIST, + enable only specific categories of checks. + Categories are: yes,no,all,none,release. + Flags are: misc,valgrind or other strings])], +[ac_checking_flags="${enableval}"],[ +# Determine the default checks. +if test x$is_release = x ; then + ac_checking_flags=yes +else + ac_checking_flags=release +fi]) +IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="$IFS," +for check in release $ac_checking_flags +do + case $check in + # these set all the flags to specific states + yes|all) ac_checking=1 ; ac_assert_checking=1 ; ac_valgrind_checking= ;; + no|none) ac_checking= ; ac_assert_checking= ; ac_valgrind_checking= ;; + release) ac_checking= ; ac_assert_checking=1 ; ac_valgrind_checking= ;; + # these enable particular checks + assert) ac_assert_checking=1 ;; + misc) ac_checking=1 ;; + valgrind) ac_valgrind_checking=1 ;; + # accept + *) ;; + esac +done +IFS="$ac_save_IFS" + +if test x$ac_checking != x ; then + AC_DEFINE(CHECKING_P, 1, +[Define to 1 if you want more run-time sanity checks.]) +else + AC_DEFINE(CHECKING_P, 0) +fi + +if test x$ac_assert_checking != x ; then + AC_DEFINE(ENABLE_ASSERT_CHECKING, 1, +[Define if you want assertions enabled. This is a cheap check.]) +fi + +if test x$ac_valgrind_checking != x ; then + AC_DEFINE(ENABLE_VALGRIND_CHECKING, 1, +[Define if you want to workaround valgrind (a memory checker) warnings about + possible memory leaks because of libcpp use of interior pointers.]) +fi + +AC_ARG_ENABLE(canonical-system-headers, +[ --enable-canonical-system-headers + enable or disable system headers canonicalization], +[], +enable_canonical_system_headers=yes) +if test $enable_canonical_system_headers != no; then + AC_DEFINE(ENABLE_CANONICAL_SYSTEM_HEADERS, + 1, [Define to enable system headers canonicalization.]) +fi + +case $target in + i?86-* | x86_64-*) + AC_TRY_COMPILE([], [asm ("pcmpestri %0, %%xmm0, %%xmm1" : : "i"(0))], + [AC_DEFINE([HAVE_SSE4], [1], + [Define to 1 if you can assemble SSE4 insns.])]) +esac + +# Enable --enable-host-shared. +AC_ARG_ENABLE(host-shared, +[AS_HELP_STRING([--enable-host-shared], + [build host code as shared libraries])], +[PICFLAG=-fPIC], [PICFLAG=]) +AC_SUBST(PICFLAG) + +# Enable Intel CET on Intel CET enabled host if jit is enabled. +GCC_CET_HOST_FLAGS(CET_HOST_FLAGS) +case x$enable_languages in +*jit*) + ;; +*) + CET_HOST_FLAGS= + ;; +esac +AC_SUBST(CET_HOST_FLAGS) + +AC_ARG_ENABLE(valgrind-annotations, +[AS_HELP_STRING([--enable-valgrind-annotations], + [enable valgrind runtime interaction])], [], +[enable_valgrind_annotations=no]) +if test x$enable_valgrind_annotations != xno \ + || test x$ac_valgrind_checking != x; then + if (test $have_valgrind_h = no \ + && test $gcc_cv_header_memcheck_h = no \ + && test $gcc_cv_header_valgrind_memcheck_h = no); then + AC_MSG_ERROR([*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h]) + fi + AC_DEFINE(ENABLE_VALGRIND_ANNOTATIONS, 1, +[Define to get calls to the valgrind runtime enabled.]) +fi + +# Output. + +AC_CONFIG_HEADERS(config.h:config.in, [echo timestamp > stamp-h1]) +AC_CONFIG_FILES(Makefile) +AC_OUTPUT diff --git a/support/cpp/libcpp/directives.c b/support/cpp/libcpp/directives.cc index f244ae5b5..bfeaef9b7 100644 --- a/support/cpp/libcpp/directives.c +++ b/support/cpp/libcpp/directives.cc @@ -1,7 +1,5 @@ /* CPP Library. (Directive handling.) - Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 1986-2022 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 @@ -32,7 +30,7 @@ along with this program; see the file COPYING3. If not see struct if_stack { struct if_stack *next; - linenum_type line; /* Line where condition started. */ + location_t line; /* Line where condition started. */ const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */ bool skip_elses; /* Can future #else / #elif be skipped? */ bool was_skipping; /* If were skipping on entry. */ @@ -58,10 +56,12 @@ struct pragma_entry /* Values for the origin field of struct directive. KANDR directives come from traditional (K&R) C. STDC89 directives come from the - 1989 C standard. EXTENSION directives are extensions. */ + 1989 C standard. STDC2X directives come from the C2X standard. EXTENSION + directives are extensions. */ #define KANDR 0 #define STDC89 1 -#define EXTENSION 2 +#define STDC2X 2 +#define EXTENSION 3 /* Values for the flags field of struct directive. COND indicates a conditional; IF_COND an opening conditional. INCL means to treat @@ -69,13 +69,17 @@ struct pragma_entry means this directive should be handled even if -fpreprocessed is in effect (these are the directives with callback hooks). - EXPAND is set on directives that are always macro-expanded. */ + EXPAND is set on directives that are always macro-expanded. + + ELIFDEF is set on directives that are only handled for standards with the + #elifdef / #elifndef feature. */ #define COND (1 << 0) #define IF_COND (1 << 1) #define INCL (1 << 2) #define IN_I (1 << 3) #define EXPAND (1 << 4) #define DEPRECATED (1 << 5) +#define ELIFDEF (1 << 6) /* Defines one #-directive, including how to handle it. */ typedef void (*directive_handler) (cpp_reader *); @@ -100,11 +104,12 @@ static void directive_diagnostics (cpp_reader *, const directive *, int); static void run_directive (cpp_reader *, int, const char *, size_t); static char *glue_header_name (cpp_reader *); static const char *parse_include (cpp_reader *, int *, const cpp_token ***, - source_location *); + location_t *); static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *); static unsigned int read_flag (cpp_reader *, unsigned int); static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *); -static void do_diagnostic (cpp_reader *, int, int, int); +static void do_diagnostic (cpp_reader *, enum cpp_diagnostic_level code, + enum cpp_warning_reason reason, int); static cpp_hashnode *lex_macro_node (cpp_reader *, bool); static int undefine_macros (cpp_reader *, cpp_hashnode *, void *); static void do_include_common (cpp_reader *, enum include_type); @@ -118,47 +123,48 @@ static void do_pragma_once (cpp_reader *); static void do_pragma_poison (cpp_reader *); static void do_pragma_system_header (cpp_reader *); static void do_pragma_dependency (cpp_reader *); +static void do_pragma_warning_or_error (cpp_reader *, bool error); +static void do_pragma_warning (cpp_reader *); +static void do_pragma_error (cpp_reader *); static void do_linemarker (cpp_reader *); static const cpp_token *get_token_no_padding (cpp_reader *); static const cpp_token *get__Pragma_string (cpp_reader *); -static void destringize_and_run (cpp_reader *, const cpp_string *); -static int parse_answer (cpp_reader *, struct answer **, int, source_location); -static cpp_hashnode *parse_assertion (cpp_reader *, struct answer **, int); -static struct answer ** find_answer (cpp_hashnode *, const struct answer *); +static void destringize_and_run (cpp_reader *, const cpp_string *, + location_t); +static bool parse_answer (cpp_reader *, int, location_t, cpp_macro **); +static cpp_hashnode *parse_assertion (cpp_reader *, int, cpp_macro **); +static cpp_macro **find_answer (cpp_hashnode *, const cpp_macro *); static void handle_assertion (cpp_reader *, const char *, int); static void do_pragma_push_macro (cpp_reader *); static void do_pragma_pop_macro (cpp_reader *); static void cpp_pop_definition (cpp_reader *, struct def_pragma_macro *); -/* This is the table of directive handlers. It is ordered by - frequency of occurrence; the numbers at the end are directive - counts from all the source code I have lying around (egcs and libc - CVS as of 1999-05-18, plus grub-0.5.91, linux-2.2.9, and - pcmcia-cs-3.0.9). This is no longer important as directive lookup - is now O(1). All extensions other than #warning, #include_next, - and #import are deprecated. The name is where the extension - appears to have come from. */ +/* This is the table of directive handlers. All extensions other than + #warning, #include_next, and #import are deprecated. The name is + where the extension appears to have come from. */ #define DIRECTIVE_TABLE \ -D(define, T_DEFINE = 0, KANDR, IN_I) /* 270554 */ \ -D(include, T_INCLUDE, KANDR, INCL | EXPAND) /* 52262 */ \ -D(endif, T_ENDIF, KANDR, COND) /* 45855 */ \ -D(ifdef, T_IFDEF, KANDR, COND | IF_COND) /* 22000 */ \ -D(if, T_IF, KANDR, COND | IF_COND | EXPAND) /* 18162 */ \ -D(else, T_ELSE, KANDR, COND) /* 9863 */ \ -D(ifndef, T_IFNDEF, KANDR, COND | IF_COND) /* 9675 */ \ -D(undef, T_UNDEF, KANDR, IN_I) /* 4837 */ \ -D(line, T_LINE, KANDR, EXPAND) /* 2465 */ \ -D(elif, T_ELIF, STDC89, COND | EXPAND) /* 610 */ \ -D(error, T_ERROR, STDC89, 0) /* 475 */ \ -D(pragma, T_PRAGMA, STDC89, IN_I) /* 195 */ \ -D(warning, T_WARNING, EXTENSION, 0) /* 22 */ \ -D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL | EXPAND) /* 19 */ \ -D(ident, T_IDENT, EXTENSION, IN_I) /* 11 */ \ -D(import, T_IMPORT, EXTENSION, INCL | EXPAND) /* 0 ObjC */ \ -D(assert, T_ASSERT, EXTENSION, DEPRECATED) /* 0 SVR4 */ \ -D(unassert, T_UNASSERT, EXTENSION, DEPRECATED) /* 0 SVR4 */ \ -D(sccs, T_SCCS, EXTENSION, IN_I) /* 0 SVR4? */ + D(define, T_DEFINE = 0, KANDR, IN_I) \ + D(include, T_INCLUDE, KANDR, INCL | EXPAND) \ + D(endif, T_ENDIF, KANDR, COND) \ + D(ifdef, T_IFDEF, KANDR, COND | IF_COND) \ + D(if, T_IF, KANDR, COND | IF_COND | EXPAND) \ + D(else, T_ELSE, KANDR, COND) \ + D(ifndef, T_IFNDEF, KANDR, COND | IF_COND) \ + D(undef, T_UNDEF, KANDR, IN_I) \ + D(line, T_LINE, KANDR, EXPAND) \ + D(elif, T_ELIF, STDC89, COND | EXPAND) \ + D(elifdef, T_ELIFDEF, STDC2X, COND | ELIFDEF) \ + D(elifndef, T_ELIFNDEF, STDC2X, COND | ELIFDEF) \ + D(error, T_ERROR, STDC89, 0) \ + D(pragma, T_PRAGMA, STDC89, IN_I) \ + D(warning, T_WARNING, EXTENSION, 0) \ + D(include_next, T_INCLUDE_NEXT, EXTENSION, INCL | EXPAND) \ + D(ident, T_IDENT, EXTENSION, IN_I) \ + D(import, T_IMPORT, EXTENSION, INCL | EXPAND) /* ObjC */ \ + D(assert, T_ASSERT, EXTENSION, DEPRECATED) /* SVR4 */ \ + D(unassert, T_UNASSERT, EXTENSION, DEPRECATED) /* SVR4 */ \ + D(sccs, T_SCCS, EXTENSION, IN_I) /* SVR4? */ /* #sccs is synonymous with #ident. */ #define do_sccs do_ident @@ -186,6 +192,16 @@ static const directive dtable[] = DIRECTIVE_TABLE }; #undef D + +/* A NULL-terminated array of directive names for use + when suggesting corrections for misspelled directives. */ +#define D(name, t, origin, flags) #name, +static const char * const directive_names[] = { +DIRECTIVE_TABLE + NULL +}; +#undef D + #undef DIRECTIVE_TABLE /* Wrapper struct directive for linemarkers. @@ -196,8 +212,6 @@ static const directive linemarker_dir = do_linemarker, UC"#", 1, KANDR, IN_I }; -#define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF) - /* Skip any remaining tokens in a directive. */ static void skip_rest_of_line (cpp_reader *pfile) @@ -212,16 +226,33 @@ skip_rest_of_line (cpp_reader *pfile) ; } -/* Ensure there are no stray tokens at the end of a directive. If - EXPAND is true, tokens macro-expanding to nothing are allowed. */ +/* Helper function for check_oel. */ + static void -check_eol (cpp_reader *pfile, bool expand) +check_eol_1 (cpp_reader *pfile, bool expand, enum cpp_warning_reason reason) { if (! SEEN_EOL () && (expand ? cpp_get_token (pfile) : _cpp_lex_token (pfile))->type != CPP_EOF) - cpp_error (pfile, CPP_DL_PEDWARN, "extra tokens at end of #%s directive", - pfile->directive->name); + cpp_pedwarning (pfile, reason, "extra tokens at end of #%s directive", + pfile->directive->name); +} + +/* Variant of check_eol used for Wendif-labels warnings. */ + +static void +check_eol_endif_labels (cpp_reader *pfile) +{ + check_eol_1 (pfile, false, CPP_W_ENDIF_LABELS); +} + +/* Ensure there are no stray tokens at the end of a directive. If + EXPAND is true, tokens macro-expanding to nothing are allowed. */ + +static void +check_eol (cpp_reader *pfile, bool expand) +{ + check_eol_1 (pfile, expand, CPP_W_NONE); } /* Ensure there are no stray tokens other than comments at the end of @@ -328,7 +359,7 @@ prepare_directive_trad (cpp_reader *pfile) if (no_expand) pfile->state.prevent_expansion++; - _cpp_scan_out_logical_line (pfile, NULL); + _cpp_scan_out_logical_line (pfile, NULL, false); if (no_expand) pfile->state.prevent_expansion--; @@ -383,13 +414,13 @@ directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented) } } -/* Check if we have a known directive. INDENTED is nonzero if the +/* Check if we have a known directive. INDENTED is true if the '#' of the directive was indented. This function is in this file - to save unnecessarily exporting dtable etc. to lex.c. Returns + to save unnecessarily exporting dtable etc. to lex.cc. Returns nonzero if the line of tokens has been handled, zero if we should continue processing the line. */ int -_cpp_handle_directive (cpp_reader *pfile, int indented) +_cpp_handle_directive (cpp_reader *pfile, bool indented) { const directive *dir = 0; const cpp_token *dname; @@ -414,7 +445,15 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) if (dname->type == CPP_NAME) { if (dname->val.node.node->is_directive) - dir = &dtable[dname->val.node.node->directive_index]; + { + dir = &dtable[dname->val.node.node->directive_index]; + if ((dir->flags & ELIFDEF) + && !CPP_OPTION (pfile, elifdef) + /* For -std=gnu* modes elifdef is supported with + a pedwarn if pedantic. */ + && CPP_OPTION (pfile, std)) + dir = 0; + } } /* We do not recognize the # followed by a number extension in assembler code. */ @@ -441,12 +480,12 @@ _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. macro.c + -fpreprocessed mode only if the # is in column 1. macro.cc puts a space in front of any '#' at the start of a macro. We exclude the -fdirectives-only case because macro expansion has not been performed yet, and block comments can cause spaces - to preceed the directive. */ + to precede the directive. */ if (CPP_OPTION (pfile, preprocessed) && !CPP_OPTION (pfile, directives_only) && (indented || !(dir->flags & IN_I))) @@ -479,8 +518,35 @@ _cpp_handle_directive (cpp_reader *pfile, int indented) if (CPP_OPTION (pfile, lang) == CLK_ASM) skip = 0; else if (!pfile->state.skipping) - cpp_error (pfile, CPP_DL_ERROR, "invalid preprocessing directive #%s", - cpp_token_as_text (pfile, dname)); + { + const char *unrecognized + = (const char *)cpp_token_as_text (pfile, dname); + const char *hint = NULL; + + /* Call back into gcc to get a spelling suggestion. Ideally + we'd just use best_match from gcc/spellcheck.h (and filter + out the uncommon directives), but that requires moving it + to a support library. */ + if (pfile->cb.get_suggestion) + hint = pfile->cb.get_suggestion (pfile, unrecognized, + directive_names); + + if (hint) + { + rich_location richloc (pfile->line_table, dname->src_loc); + source_range misspelled_token_range + = get_range_from_loc (pfile->line_table, dname->src_loc); + richloc.add_fixit_replace (misspelled_token_range, hint); + cpp_error_at (pfile, CPP_DL_ERROR, &richloc, + "invalid preprocessing directive #%s;" + " did you mean #%s?", + unrecognized, hint); + } + else + cpp_error (pfile, CPP_DL_ERROR, + "invalid preprocessing directive #%s", + unrecognized); + } } pfile->directive = dir; @@ -545,9 +611,11 @@ lex_macro_node (cpp_reader *pfile, bool is_def_or_undef) { cpp_hashnode *node = token->val.node.node; - if (is_def_or_undef && node == pfile->spec_nodes.n_defined) + if (is_def_or_undef + && node == pfile->spec_nodes.n_defined) cpp_error (pfile, CPP_DL_ERROR, - "\"defined\" cannot be used as a macro name"); + "\"%s\" cannot be used as a macro name", + NODE_NAME (node)); else if (! (node->flags & NODE_POISONED)) return node; } @@ -564,7 +632,7 @@ lex_macro_node (cpp_reader *pfile, bool is_def_or_undef) return NULL; } -/* Process a #define directive. Most work is done in macro.c. */ +/* Process a #define directive. Most work is done in macro.cc. */ static void do_define (cpp_reader *pfile) { @@ -604,13 +672,19 @@ do_undef (cpp_reader *pfile) /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified identifier is not currently defined as a macro name. */ - if (node->type == NT_MACRO) + if (cpp_macro_p (node)) { if (node->flags & NODE_WARN) cpp_error (pfile, CPP_DL_WARNING, "undefining \"%s\"", NODE_NAME (node)); - - if (CPP_OPTION (pfile, warn_unused_macros)) + else if (cpp_builtin_macro_p (node) + && CPP_OPTION (pfile, warn_builtin_macro_redefined)) + cpp_warning_with_line (pfile, CPP_W_BUILTIN_MACRO_REDEFINED, + pfile->directive_line, 0, + "undefining \"%s\"", NODE_NAME (node)); + + if (node->value.macro + && CPP_OPTION (pfile, warn_unused_macros)) _cpp_warn_if_unused_macro (pfile, node, NULL); _cpp_free_definition (node); @@ -629,7 +703,8 @@ undefine_macros (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *h, /* Body of _cpp_free_definition inlined here for speed. Macros and assertions no longer have anything to free. */ h->type = NT_VOID; - h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED); + h->value.answers = NULL; + h->flags &= ~(NODE_POISONED|NODE_DISABLED|NODE_USED); return 1; } @@ -693,7 +768,7 @@ glue_header_name (cpp_reader *pfile) static const char * parse_include (cpp_reader *pfile, int *pangle_brackets, - const cpp_token ***buf, source_location *location) + const cpp_token ***buf, location_t *location) { char *fname; const cpp_token *header; @@ -751,34 +826,36 @@ do_include_common (cpp_reader *pfile, enum include_type type) const char *fname; int angle_brackets; const cpp_token **buf = NULL; - source_location location; + location_t location; /* Re-enable saving of comments if requested, so that the include callback can dump comments which follow #include. */ pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); + /* Tell the lexer this is an include directive -- we want it to + increment the line number even if this is the last line of a file. */ + pfile->state.in_directive = 2; + fname = parse_include (pfile, &angle_brackets, &buf, &location); if (!fname) - { - if (buf) - XDELETEVEC (buf); - return; - } + goto done; if (!*fname) - { - cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0, - "empty filename in #%s", - pfile->directive->name); - XDELETEVEC (fname); - if (buf) - XDELETEVEC (buf); - return; - } + { + cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0, + "empty filename in #%s", + pfile->directive->name); + goto done; + } /* Prevent #include recursion. */ - if (pfile->line_table->depth >= CPP_STACK_MAX) - cpp_error (pfile, CPP_DL_ERROR, "#include nested too deeply"); + if (pfile->line_table->depth >= CPP_OPTION (pfile, max_include_depth)) + cpp_error (pfile, + CPP_DL_ERROR, + "#include nested depth %u exceeds maximum of %u" + " (use -fmax-include-depth=DEPTH to increase the maximum)", + pfile->line_table->depth, + CPP_OPTION (pfile, max_include_depth)); else { /* Get out of macro context, if we are. */ @@ -789,9 +866,10 @@ do_include_common (cpp_reader *pfile, enum include_type type) pfile->directive->name, fname, angle_brackets, buf); - _cpp_stack_include (pfile, fname, angle_brackets, type); + _cpp_stack_include (pfile, fname, angle_brackets, type, location); } + done: XDELETEVEC (fname); if (buf) XDELETEVEC (buf); @@ -816,7 +894,7 @@ do_include_next (cpp_reader *pfile) /* If this is the primary source file, warn and use the normal search logic. */ - if (cpp_in_primary_file (pfile)) + if (_cpp_in_main_source_file (pfile)) { cpp_error (pfile, CPP_DL_WARNING, "#include_next in primary source file"); @@ -853,25 +931,32 @@ read_flag (cpp_reader *pfile, unsigned int last) /* Subroutine of do_line and do_linemarker. Convert a number in STR, of length LEN, to binary; store it in NUMP, and return false if the number was well-formed, true if not. WRAPPED is set to true if the - number did not fit into 'unsigned long'. */ + number did not fit into 'linenum_type'. */ static bool strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped) { linenum_type reg = 0; - linenum_type reg_prev = 0; uchar c; + bool seen_digit_sep = false; *wrapped = false; while (len--) { c = *str++; + if (!seen_digit_sep && c == '\'' && len) + { + seen_digit_sep = true; + continue; + } if (!ISDIGIT (c)) return true; + seen_digit_sep = false; + if (reg > ((linenum_type) -1) / 10) + *wrapped = true; reg *= 10; - reg += c - '0'; - if (reg < reg_prev) + if (reg > ((linenum_type) -1) - (c - '0')) *wrapped = true; - reg_prev = reg; + reg += c - '0'; } *nump = reg; return false; @@ -879,19 +964,19 @@ strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped) /* Interpret #line command. Note that the filename string (if any) is a true string constant - (escapes are interpreted), unlike in #line. */ + (escapes are interpreted). */ 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]; + class line_maps *line_table = pfile->line_table; + const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (line_table); /* skip_rest_of_line() may cause line table to be realloc()ed so note down sysp right now. */ - unsigned char map_sysp = map->sysp; + unsigned char map_sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (map); const cpp_token *token; - const char *new_file = map->to_file; + const char *new_file = ORDINARY_MAP_FILE_NAME (map); linenum_type new_lineno; /* C99 raised the minimum limit on #line numbers. */ @@ -937,6 +1022,7 @@ do_line (cpp_reader *pfile) skip_rest_of_line (pfile); _cpp_do_file_change (pfile, LC_RENAME_VERBATIM, new_file, new_lineno, map_sysp); + line_table->seen_line_directive = true; } /* Interpret the # 44 "file" [flags] notation, which has slightly @@ -945,12 +1031,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]; + class line_maps *line_table = pfile->line_table; + const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (line_table); const cpp_token *token; - const char *new_file = map->to_file; + const char *new_file = ORDINARY_MAP_FILE_NAME (map); linenum_type new_lineno; - unsigned int new_sysp = map->sysp; + unsigned int new_sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (map); enum lc_reason reason = LC_RENAME_VERBATIM; int flag; bool wrapped; @@ -1016,42 +1102,94 @@ do_linemarker (cpp_reader *pfile) skip_rest_of_line (pfile); + if (reason == LC_LEAVE) + { + /* Reread map since cpp_get_token can invalidate it with a + reallocation. */ + map = LINEMAPS_LAST_ORDINARY_MAP (line_table); + const line_map_ordinary *from + = linemap_included_from_linemap (line_table, map); + + if (!from) + /* Not nested. */; + else if (!new_file[0]) + /* Leaving to "" means fill in the popped-to name. */ + new_file = ORDINARY_MAP_FILE_NAME (from); + else if (filename_cmp (ORDINARY_MAP_FILE_NAME (from), new_file) != 0) + /* It's the wrong name, Grommit! */ + from = NULL; + + if (!from) + { + cpp_warning (pfile, CPP_W_NONE, + "file \"%s\" linemarker ignored due to " + "incorrect nesting", new_file); + return; + } + } + /* Compensate for the increment in linemap_add that occurs in _cpp_do_file_change. We're currently at the start of the line - *following* the #line directive. A separate source_location for this + *following* the #line directive. A separate location_t for this location makes no sense (until we do the LC_LEAVE), and complicates LAST_SOURCE_LINE_LOCATION. */ pfile->line_table->highest_location--; _cpp_do_file_change (pfile, reason, new_file, new_lineno, new_sysp); + line_table->seen_line_directive = true; } -/* Arrange the file_change callback. pfile->line has changed to - FILE_LINE of TO_FILE, for reason REASON. SYSP is 1 for a system - header, 2 for a system header that needs to be extern "C" protected, - and zero otherwise. */ +/* Arrange the file_change callback. Changing to TO_FILE:TO_LINE for + REASON. SYSP is 1 for a system header, 2 for a system header that + needs to be extern "C" protected, and zero otherwise. */ void _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason, - const char *to_file, linenum_type file_line, + const char *to_file, linenum_type to_line, unsigned int sysp) { - const struct line_map *map = linemap_add (pfile->line_table, reason, sysp, - to_file, file_line); - if (map != NULL) - linemap_line_start (pfile->line_table, map->to_line, 127); + linemap_assert (reason != LC_ENTER_MACRO); + + const line_map_ordinary *ord_map = NULL; + if (!to_line && reason == LC_RENAME_VERBATIM) + { + /* A linemarker moving to line zero. If we're on the second + line of the current map, and it also starts at zero, just + rewind -- we're probably reading the builtins of a + preprocessed source. */ + line_map_ordinary *last = LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table); + if (!ORDINARY_MAP_STARTING_LINE_NUMBER (last) + && 0 == filename_cmp (to_file, ORDINARY_MAP_FILE_NAME (last)) + && SOURCE_LINE (last, pfile->line_table->highest_line) == 2) + { + ord_map = last; + pfile->line_table->highest_location + = pfile->line_table->highest_line = MAP_START_LOCATION (last); + } + } + + if (!ord_map) + if (const line_map *map = linemap_add (pfile->line_table, reason, sysp, + to_file, to_line)) + { + ord_map = linemap_check_ordinary (map); + linemap_line_start (pfile->line_table, + ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map), + 127); + } if (pfile->cb.file_change) - pfile->cb.file_change (pfile, map); + pfile->cb.file_change (pfile, ord_map); } /* Report a warning or error detected by the program we are processing. Use the directive's tokens in the error message. */ static void -do_diagnostic (cpp_reader *pfile, int code, int reason, int print_dir) +do_diagnostic (cpp_reader *pfile, enum cpp_diagnostic_level code, + enum cpp_warning_reason reason, int print_dir) { const unsigned char *dir_name; unsigned char *line; - source_location src_loc = pfile->cur_token[-1].src_loc; + location_t src_loc = pfile->cur_token[-1].src_loc; if (print_dir) dir_name = pfile->directive->name; @@ -1073,7 +1211,7 @@ do_diagnostic (cpp_reader *pfile, int code, int reason, int print_dir) static void do_error (cpp_reader *pfile) { - do_diagnostic (pfile, CPP_DL_ERROR, 0, 1); + do_diagnostic (pfile, CPP_DL_ERROR, CPP_W_NONE, 1); } static void @@ -1261,6 +1399,8 @@ _cpp_init_internal_pragmas (cpp_reader *pfile) register_pragma_internal (pfile, "GCC", "system_header", do_pragma_system_header); register_pragma_internal (pfile, "GCC", "dependency", do_pragma_dependency); + register_pragma_internal (pfile, "GCC", "warning", do_pragma_warning); + register_pragma_internal (pfile, "GCC", "error", do_pragma_error); } /* Return the number of registered pragmas in PE. */ @@ -1345,13 +1485,15 @@ static void do_pragma (cpp_reader *pfile) { const struct pragma_entry *p = NULL; - const cpp_token *token, *pragma_token = pfile->cur_token; + const cpp_token *token, *pragma_token; + location_t pragma_token_virt_loc = 0; cpp_token ns_token; unsigned int count = 1; pfile->state.prevent_expansion++; - token = cpp_get_token (pfile); + pragma_token = token = cpp_get_token_with_location (pfile, + &pragma_token_virt_loc); ns_token = *token; if (token->type == CPP_NAME) { @@ -1361,6 +1503,7 @@ do_pragma (cpp_reader *pfile) bool allow_name_expansion = p->allow_expansion; if (allow_name_expansion) pfile->state.prevent_expansion--; + token = cpp_get_token (pfile); if (token->type == CPP_NAME) p = lookup_pragma_entry (p->u.space, token->val.node.node); @@ -1376,7 +1519,7 @@ do_pragma (cpp_reader *pfile) { if (p->is_deferred) { - pfile->directive_result.src_loc = pragma_token->src_loc; + pfile->directive_result.src_loc = pragma_token_virt_loc; pfile->directive_result.type = CPP_PRAGMA; pfile->directive_result.flags = pragma_token->flags; pfile->directive_result.val.pragma = p->u.ident; @@ -1427,7 +1570,7 @@ do_pragma (cpp_reader *pfile) static void do_pragma_once (cpp_reader *pfile) { - if (cpp_in_primary_file (pfile)) + if (_cpp_in_main_source_file (pfile)) cpp_error (pfile, CPP_DL_WARNING, "#pragma once in main file"); check_eol (pfile, false); @@ -1449,7 +1592,7 @@ do_pragma_push_macro (cpp_reader *pfile) txt = get__Pragma_string (pfile); if (!txt) { - source_location src_loc = pfile->cur_token[-1].src_loc; + location_t src_loc = pfile->cur_token[-1].src_loc; cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, "invalid #pragma push_macro directive"); check_eol (pfile, false); @@ -1477,6 +1620,8 @@ do_pragma_push_macro (cpp_reader *pfile) node = _cpp_lex_identifier (pfile, c->name); if (node->type == NT_VOID) c->is_undef = 1; + else if (node->type == NT_BUILTIN_MACRO) + c->is_builtin = 1; else { defn = cpp_macro_definition (pfile, node); @@ -1504,7 +1649,7 @@ do_pragma_pop_macro (cpp_reader *pfile) txt = get__Pragma_string (pfile); if (!txt) { - source_location src_loc = pfile->cur_token[-1].src_loc; + location_t src_loc = pfile->cur_token[-1].src_loc; cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, "invalid #pragma pop_macro directive"); check_eol (pfile, false); @@ -1569,7 +1714,7 @@ do_pragma_poison (cpp_reader *pfile) if (hp->flags & NODE_POISONED) continue; - if (hp->type == NT_MACRO) + if (cpp_macro_p (hp)) cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"", NODE_NAME (hp)); _cpp_free_definition (hp); @@ -1587,7 +1732,7 @@ do_pragma_poison (cpp_reader *pfile) static void do_pragma_system_header (cpp_reader *pfile) { - if (cpp_in_primary_file (pfile)) + if (_cpp_in_main_source_file (pfile)) cpp_error (pfile, CPP_DL_WARNING, "#pragma system_header ignored outside include file"); else @@ -1606,7 +1751,7 @@ do_pragma_dependency (cpp_reader *pfile) { const char *fname; int angle_brackets, ordering; - source_location location; + location_t location; fname = parse_include (pfile, &angle_brackets, NULL, &location); if (!fname) @@ -1622,13 +1767,50 @@ do_pragma_dependency (cpp_reader *pfile) if (cpp_get_token (pfile)->type != CPP_EOF) { _cpp_backup_tokens (pfile, 1); - do_diagnostic (pfile, CPP_DL_WARNING, 0, 0); + do_diagnostic (pfile, CPP_DL_WARNING, CPP_W_NONE, 0); } } free ((void *) fname); } +/* Issue a diagnostic with the message taken from the pragma. If + ERROR is true, the diagnostic is a warning, otherwise, it is an + error. */ +static void +do_pragma_warning_or_error (cpp_reader *pfile, bool error) +{ + const cpp_token *tok = _cpp_lex_token (pfile); + cpp_string str; + if (tok->type != CPP_STRING + || !cpp_interpret_string_notranslate (pfile, &tok->val.str, 1, &str, + CPP_STRING) + || str.len == 0) + { + cpp_error (pfile, CPP_DL_ERROR, "invalid \"#pragma GCC %s\" directive", + error ? "error" : "warning"); + return; + } + cpp_error (pfile, error ? CPP_DL_ERROR : CPP_DL_WARNING, + "%s", str.text); + free ((void *)str.text); +} + +/* Issue a warning diagnostic. */ +static void +do_pragma_warning (cpp_reader *pfile) +{ + do_pragma_warning_or_error (pfile, false); +} + +/* Issue an error diagnostic. */ +static void +do_pragma_error (cpp_reader *pfile) +{ + do_pragma_warning_or_error (pfile, true); +} + + /* Get a token but skip padding. */ static const cpp_token * get_token_no_padding (cpp_reader *pfile) @@ -1675,7 +1857,8 @@ get__Pragma_string (cpp_reader *pfile) /* Destringize IN into a temporary buffer, by removing the first \ of \" and \\ sequences, and process the result as a #pragma directive. */ static void -destringize_and_run (cpp_reader *pfile, const cpp_string *in) +destringize_and_run (cpp_reader *pfile, const cpp_string *in, + location_t expansion_loc) { const unsigned char *src, *limit; char *dest, *result; @@ -1710,10 +1893,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) saved_cur_token = pfile->cur_token; saved_cur_run = pfile->cur_run; - pfile->context = XNEW (cpp_context); - pfile->context->macro = 0; - pfile->context->prev = 0; - pfile->context->next = 0; + pfile->context = XCNEW (cpp_context); /* Inline run_directive, since we need to delay the _cpp_pop_buffer until we've read all of the tokens that we want. */ @@ -1728,6 +1908,8 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) save_directive = pfile->directive; pfile->directive = &dtable[T_PRAGMA]; do_pragma (pfile); + if (pfile->directive_result.type == CPP_PRAGMA) + pfile->directive_result.flags |= PRAGMA_OP; end_directive (pfile, 1); pfile->directive = save_directive; @@ -1758,6 +1940,12 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) toks = XRESIZEVEC (cpp_token, toks, maxcount); } toks[count] = *cpp_get_token (pfile); + /* _Pragma is a builtin, so we're not within a macro-map, and so + the token locations are set to bogus ordinary locations + near to, but after that of the "_Pragma". + Paper over this by setting them equal to the location of the + _Pragma itself (PR preprocessor/69126). */ + toks[count].src_loc = expansion_loc; /* Macros have been already expanded by cpp_get_token if the pragma allowed expansion. */ toks[count++].flags |= NO_EXPAND; @@ -1767,8 +1955,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) else { count = 1; - toks = XNEW (cpp_token); - toks[0] = pfile->directive_result; + toks = &pfile->avoid_paste; /* If we handled the entire pragma internally, make sure we get the line number correct for the next token. */ @@ -1792,14 +1979,14 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in) /* Handle the _Pragma operator. Return 0 on error, 1 if ok. */ int -_cpp_do__Pragma (cpp_reader *pfile) +_cpp_do__Pragma (cpp_reader *pfile, location_t expansion_loc) { const cpp_token *string = get__Pragma_string (pfile); pfile->directive_result.type = CPP_PADDING; if (string) { - destringize_and_run (pfile, &string->val.str); + destringize_and_run (pfile, &string->val.str, expansion_loc); return 1; } cpp_error (pfile, CPP_DL_ERROR, @@ -1819,30 +2006,11 @@ do_ifdef (cpp_reader *pfile) if (node) { - /* Do not treat conditional macros as being defined. This is due to - the powerpc and spu ports using conditional macros for 'vector', - 'bool', and 'pixel' to act as conditional keywords. This messes - up tests like #ifndef bool. */ - skip = (node->type != NT_MACRO - || ((node->flags & NODE_CONDITIONAL) != 0)); + skip = !_cpp_defined_macro_p (node); + if (!_cpp_maybe_notify_macro_use (pfile, node, pfile->directive_line)) + /* It wasn't a macro after all. */ + skip = true; _cpp_mark_macro_used (node); - if (!(node->flags & NODE_USED)) - { - node->flags |= NODE_USED; - if (node->type == NT_MACRO) - { - if ((node->flags & NODE_BUILTIN) - && pfile->cb.user_builtin_macro) - pfile->cb.user_builtin_macro (pfile, node); - if (pfile->cb.used_define) - pfile->cb.used_define (pfile, pfile->directive_line, node); - } - else - { - if (pfile->cb.used_undef) - pfile->cb.used_undef (pfile, pfile->directive_line, node); - } - } if (pfile->cb.used) pfile->cb.used (pfile, pfile->directive_line, node); check_eol (pfile, false); @@ -1865,30 +2033,11 @@ do_ifndef (cpp_reader *pfile) if (node) { - /* Do not treat conditional macros as being defined. This is due to - the powerpc and spu ports using conditional macros for 'vector', - 'bool', and 'pixel' to act as conditional keywords. This messes - up tests like #ifndef bool. */ - skip = (node->type == NT_MACRO - && ((node->flags & NODE_CONDITIONAL) == 0)); + skip = _cpp_defined_macro_p (node); + if (!_cpp_maybe_notify_macro_use (pfile, node, pfile->directive_line)) + /* It wasn't a macro after all. */ + skip = false; _cpp_mark_macro_used (node); - if (!(node->flags & NODE_USED)) - { - node->flags |= NODE_USED; - if (node->type == NT_MACRO) - { - if ((node->flags & NODE_BUILTIN) - && pfile->cb.user_builtin_macro) - pfile->cb.user_builtin_macro (pfile, node); - if (pfile->cb.used_define) - pfile->cb.used_define (pfile, pfile->directive_line, node); - } - else - { - if (pfile->cb.used_undef) - pfile->cb.used_undef (pfile, pfile->directive_line, node); - } - } if (pfile->cb.used) pfile->cb.used (pfile, pfile->directive_line, node); check_eol (pfile, false); @@ -1944,12 +2093,12 @@ do_else (cpp_reader *pfile) /* Only check EOL if was not originally skipping. */ if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels)) - check_eol (pfile, false); + check_eol_endif_labels (pfile); } } -/* Handle a #elif directive by not changing if_stack either. See the - comment above do_else. */ +/* Handle a #elif, #elifdef or #elifndef directive by not changing if_stack + either. See the comment above do_else. */ static void do_elif (cpp_reader *pfile) { @@ -1957,34 +2106,84 @@ do_elif (cpp_reader *pfile) struct if_stack *ifs = buffer->if_stack; if (ifs == NULL) - cpp_error (pfile, CPP_DL_ERROR, "#elif without #if"); + cpp_error (pfile, CPP_DL_ERROR, "#%s without #if", pfile->directive->name); else { if (ifs->type == T_ELSE) { - cpp_error (pfile, CPP_DL_ERROR, "#elif after #else"); + cpp_error (pfile, CPP_DL_ERROR, "#%s after #else", + pfile->directive->name); cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0, "the conditional began here"); } ifs->type = T_ELIF; - if (! ifs->was_skipping) + /* See DR#412: "Only the first group whose control condition + evaluates to true (nonzero) is processed; any following groups + are skipped and their controlling directives are processed as + if they were in a group that is skipped." */ + if (ifs->skip_elses) + { + /* In older GNU standards, #elifdef/#elifndef is supported + as an extension, but pedwarn if -pedantic if the presence + of the directive would be rejected. */ + if (pfile->directive != &dtable[T_ELIF] + && ! CPP_OPTION (pfile, elifdef) + && CPP_PEDANTIC (pfile) + && !pfile->state.skipping) + { + if (CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_PEDWARN, + "#%s before C++23 is a GCC extension", + pfile->directive->name); + else + cpp_error (pfile, CPP_DL_PEDWARN, + "#%s before C2X is a GCC extension", + pfile->directive->name); + } + pfile->state.skipping = 1; + } + else { - bool value; - /* The standard mandates that the expression be parsed even - if we are skipping elses at this point -- the lexical - restrictions on #elif only apply to skipped groups, but - this group is not being skipped. Temporarily set - skipping to false to get lexer warnings. */ - pfile->state.skipping = 0; - value = _cpp_parse_expr (pfile, false); - if (ifs->skip_elses) - pfile->state.skipping = 1; + if (pfile->directive == &dtable[T_ELIF]) + pfile->state.skipping = !_cpp_parse_expr (pfile, false); else { - pfile->state.skipping = ! value; - ifs->skip_elses = value; + cpp_hashnode *node = lex_macro_node (pfile, false); + + if (node) + { + bool macro_defined = _cpp_defined_macro_p (node); + if (!_cpp_maybe_notify_macro_use (pfile, node, + pfile->directive_line)) + /* It wasn't a macro after all. */ + macro_defined = false; + bool skip = (pfile->directive == &dtable[T_ELIFDEF] + ? !macro_defined + : macro_defined); + if (pfile->cb.used) + pfile->cb.used (pfile, pfile->directive_line, node); + check_eol (pfile, false); + /* In older GNU standards, #elifdef/#elifndef is supported + as an extension, but pedwarn if -pedantic if the presence + of the directive would change behavior. */ + if (! CPP_OPTION (pfile, elifdef) + && CPP_PEDANTIC (pfile) + && pfile->state.skipping != skip) + { + if (CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_PEDWARN, + "#%s before C++23 is a GCC extension", + pfile->directive->name); + else + cpp_error (pfile, CPP_DL_PEDWARN, + "#%s before C2X is a GCC extension", + pfile->directive->name); + } + pfile->state.skipping = skip; + } } + ifs->skip_elses = !pfile->state.skipping; } /* Invalidate any controlling macro. */ @@ -1992,6 +2191,20 @@ do_elif (cpp_reader *pfile) } } +/* Handle a #elifdef directive. */ +static void +do_elifdef (cpp_reader *pfile) +{ + do_elif (pfile); +} + +/* Handle a #elifndef directive. */ +static void +do_elifndef (cpp_reader *pfile) +{ + do_elif (pfile); +} + /* #endif pops the if stack and resets pfile->state.skipping. */ static void do_endif (cpp_reader *pfile) @@ -2005,7 +2218,7 @@ do_endif (cpp_reader *pfile) { /* Only check EOL if was not originally skipping. */ if (!ifs->was_skipping && CPP_OPTION (pfile, warn_endif_labels)) - check_eol (pfile, false); + check_eol_endif_labels (pfile); /* If potential control macro, we go back outside again. */ if (ifs->next == 0 && ifs->mi_cmacro) @@ -2052,17 +2265,13 @@ push_conditional (cpp_reader *pfile, int skip, int type, storage, i.e. the #assert case. Returns 0 on success, and sets ANSWERP to point to the answer. PRED_LOC is the location of the predicate. */ -static int -parse_answer (cpp_reader *pfile, struct answer **answerp, int type, - source_location pred_loc) +static bool +parse_answer (cpp_reader *pfile, int type, location_t pred_loc, + cpp_macro **answer_ptr) { - const cpp_token *paren; - struct answer *answer; - unsigned int acount; - /* In a conditional, it is legal to not have an open paren. We should save the following token in this case. */ - paren = cpp_get_token (pfile); + const cpp_token *paren = cpp_get_token (pfile); /* If not a paren, see if we're OK. */ if (paren->type != CPP_OPEN_PAREN) @@ -2072,23 +2281,26 @@ parse_answer (cpp_reader *pfile, struct answer **answerp, int type, if (type == T_IF) { _cpp_backup_tokens (pfile, 1); - return 0; + return true; } /* #unassert with no answer is valid - it removes all answers. */ if (type == T_UNASSERT && paren->type == CPP_EOF) - return 0; + return true; cpp_error_with_line (pfile, CPP_DL_ERROR, pred_loc, 0, "missing '(' after predicate"); - return 1; + return false; } - for (acount = 0;; acount++) + cpp_macro *answer = _cpp_new_macro (pfile, cmk_assert, + _cpp_reserve_room (pfile, 0, + sizeof (cpp_macro))); + answer->parm.next = NULL; + unsigned count = 0; + for (;;) { - size_t room_needed; const cpp_token *token = cpp_get_token (pfile); - cpp_token *dest; if (token->type == CPP_CLOSE_PAREN) break; @@ -2096,57 +2308,52 @@ parse_answer (cpp_reader *pfile, struct answer **answerp, int type, if (token->type == CPP_EOF) { cpp_error (pfile, CPP_DL_ERROR, "missing ')' to complete answer"); - return 1; + return false; } - /* struct answer includes the space for one token. */ - room_needed = (sizeof (struct answer) + acount * sizeof (cpp_token)); - - if (BUFF_ROOM (pfile->a_buff) < room_needed) - _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (struct answer)); - - dest = &((struct answer *) BUFF_FRONT (pfile->a_buff))->first[acount]; - *dest = *token; - - /* Drop whitespace at start, for answer equivalence purposes. */ - if (acount == 0) - dest->flags &= ~PREV_WHITE; + answer = (cpp_macro *)_cpp_reserve_room + (pfile, sizeof (cpp_macro) + count * sizeof (cpp_token), + sizeof (cpp_token)); + answer->exp.tokens[count++] = *token; } - if (acount == 0) + if (!count) { cpp_error (pfile, CPP_DL_ERROR, "predicate's answer is empty"); - return 1; + return false; } - answer = (struct answer *) BUFF_FRONT (pfile->a_buff); - answer->count = acount; - answer->next = NULL; - *answerp = answer; + /* Drop whitespace at start, for answer equivalence purposes. */ + answer->exp.tokens[0].flags &= ~PREV_WHITE; - return 0; + answer->count = count; + *answer_ptr = answer; + + return true; } /* Parses an assertion directive of type TYPE, returning a pointer to - the hash node of the predicate, or 0 on error. If an answer was - supplied, it is placed in ANSWERP, otherwise it is set to 0. */ + the hash node of the predicate, or 0 on error. The node is + guaranteed to be disjoint from the macro namespace, so can only + have type 'NT_VOID'. If an answer was supplied, it is placed in + *ANSWER_PTR, which is otherwise set to 0. */ static cpp_hashnode * -parse_assertion (cpp_reader *pfile, struct answer **answerp, int type) +parse_assertion (cpp_reader *pfile, int type, cpp_macro **answer_ptr) { cpp_hashnode *result = 0; - const cpp_token *predicate; /* We don't expand predicates or answers. */ pfile->state.prevent_expansion++; - *answerp = 0; - predicate = cpp_get_token (pfile); + *answer_ptr = NULL; + + const cpp_token *predicate = cpp_get_token (pfile); if (predicate->type == CPP_EOF) cpp_error (pfile, CPP_DL_ERROR, "assertion without predicate"); else if (predicate->type != CPP_NAME) cpp_error_with_line (pfile, CPP_DL_ERROR, predicate->src_loc, 0, "predicate must be an identifier"); - else if (parse_answer (pfile, answerp, type, predicate->src_loc) == 0) + else if (parse_answer (pfile, type, predicate->src_loc, answer_ptr)) { unsigned int len = NODE_LEN (predicate->val.node.node); unsigned char *sym = (unsigned char *) alloca (len + 1); @@ -2158,25 +2365,27 @@ parse_assertion (cpp_reader *pfile, struct answer **answerp, int type) } pfile->state.prevent_expansion--; + return result; } /* Returns a pointer to the pointer to CANDIDATE in the answer chain, or a pointer to NULL if the answer is not in the chain. */ -static struct answer ** -find_answer (cpp_hashnode *node, const struct answer *candidate) +static cpp_macro ** +find_answer (cpp_hashnode *node, const cpp_macro *candidate) { unsigned int i; - struct answer **result; + cpp_macro **result = NULL; - for (result = &node->value.answers; *result; result = &(*result)->next) + for (result = &node->value.answers; *result; result = &(*result)->parm.next) { - struct answer *answer = *result; + cpp_macro *answer = *result; if (answer->count == candidate->count) { for (i = 0; i < answer->count; i++) - if (! _cpp_equiv_tokens (&answer->first[i], &candidate->first[i])) + if (!_cpp_equiv_tokens (&answer->exp.tokens[i], + &candidate->exp.tokens[i])) break; if (i == answer->count) @@ -2193,18 +2402,18 @@ find_answer (cpp_hashnode *node, const struct answer *candidate) int _cpp_test_assertion (cpp_reader *pfile, unsigned int *value) { - struct answer *answer; - cpp_hashnode *node; - - node = parse_assertion (pfile, &answer, T_IF); + cpp_macro *answer; + cpp_hashnode *node = parse_assertion (pfile, T_IF, &answer); /* For recovery, an erroneous assertion expression is handled as a failing assertion. */ *value = 0; if (node) - *value = (node->type == NT_ASSERTION && - (answer == 0 || *find_answer (node, answer) != 0)); + { + if (node->value.answers) + *value = !answer || *find_answer (node, answer); + } else if (pfile->cur_token[-1].type == CPP_EOF) _cpp_backup_tokens (pfile, 1); @@ -2216,43 +2425,29 @@ _cpp_test_assertion (cpp_reader *pfile, unsigned int *value) static void do_assert (cpp_reader *pfile) { - struct answer *new_answer; - cpp_hashnode *node; + cpp_macro *answer; + cpp_hashnode *node = parse_assertion (pfile, T_ASSERT, &answer); - node = parse_assertion (pfile, &new_answer, T_ASSERT); if (node) { - size_t answer_size; - /* Place the new answer in the answer list. First check there is not a duplicate. */ - new_answer->next = 0; - if (node->type == NT_ASSERTION) + if (*find_answer (node, answer)) { - if (*find_answer (node, new_answer)) - { - cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted", - NODE_NAME (node) + 1); - return; - } - new_answer->next = node->value.answers; + cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted", + NODE_NAME (node) + 1); + return; } - 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; + /* Commit or allocate storage for the answer. */ + answer = (cpp_macro *)_cpp_commit_buff + (pfile, sizeof (cpp_macro) - sizeof (cpp_token) + + sizeof (cpp_token) * answer->count); + + /* Chain into the list. */ + answer->parm.next = node->value.answers; + node->value.answers = answer; - node->type = NT_ASSERTION; - node->value.answers = new_answer; check_eol (pfile, false); } } @@ -2261,25 +2456,19 @@ do_assert (cpp_reader *pfile) static void do_unassert (cpp_reader *pfile) { - cpp_hashnode *node; - struct answer *answer; + cpp_macro *answer; + cpp_hashnode *node = parse_assertion (pfile, T_UNASSERT, &answer); - node = parse_assertion (pfile, &answer, T_UNASSERT); /* It isn't an error to #unassert something that isn't asserted. */ - if (node && node->type == NT_ASSERTION) + if (node) { if (answer) { - struct answer **p = find_answer (node, answer), *temp; - - /* Remove the answer from the list. */ - temp = *p; - if (temp) - *p = temp->next; + cpp_macro **p = find_answer (node, answer); - /* Did we free the last answer? */ - if (node->value.answers == 0) - node->type = NT_VOID; + /* Remove the assert from the list. */ + if (cpp_macro *temp = *p) + *p = temp->parm.next; check_eol (pfile, false); } @@ -2324,6 +2513,15 @@ cpp_define (cpp_reader *pfile, const char *str) run_directive (pfile, T_DEFINE, buf, count); } +/* Like cpp_define, but does not warn about unused macro. */ +void +cpp_define_unused (cpp_reader *pfile, const char *str) +{ + unsigned char warn_unused_macros = CPP_OPTION (pfile, warn_unused_macros); + CPP_OPTION (pfile, warn_unused_macros) = 0; + cpp_define (pfile, str); + CPP_OPTION (pfile, warn_unused_macros) = warn_unused_macros; +} /* Use to build macros to be run through cpp_define() as described above. @@ -2332,17 +2530,31 @@ cpp_define (cpp_reader *pfile, const char *str) void cpp_define_formatted (cpp_reader *pfile, const char *fmt, ...) { - char *ptr = NULL; + char *ptr; va_list ap; va_start (ap, fmt); - vasprintf (&ptr, fmt, ap); + ptr = xvasprintf (fmt, ap); va_end (ap); cpp_define (pfile, ptr); free (ptr); } +/* Like cpp_define_formatted, but does not warn about unused macro. */ +void +cpp_define_formatted_unused (cpp_reader *pfile, const char *fmt, ...) +{ + char *ptr; + + va_list ap; + va_start (ap, fmt); + ptr = xvasprintf (fmt, ap); + va_end (ap); + + cpp_define_unused (pfile, ptr); + free (ptr); +} /* Slight variant of the above for use by initialize_builtins. */ void @@ -2378,18 +2590,23 @@ cpp_pop_definition (cpp_reader *pfile, struct def_pragma_macro *c) if (pfile->cb.before_define) pfile->cb.before_define (pfile); - if (node->type == NT_MACRO) + if (cpp_macro_p (node)) { if (pfile->cb.undef) pfile->cb.undef (pfile, pfile->directive_line, node); if (CPP_OPTION (pfile, warn_unused_macros)) _cpp_warn_if_unused_macro (pfile, node, NULL); + _cpp_free_definition (node); } - if (node->type != NT_VOID) - _cpp_free_definition (node); if (c->is_undef) return; + if (c->is_builtin) + { + _cpp_restore_special_builtin (pfile, c); + return; + } + { size_t namelen; const uchar *dn; @@ -2400,8 +2617,6 @@ cpp_pop_definition (cpp_reader *pfile, struct def_pragma_macro *c) h = cpp_lookup (pfile, c->definition, namelen); dn = c->definition + namelen; - h->type = NT_VOID; - h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED); nbuf = cpp_push_buffer (pfile, dn, ustrchr (dn, '\n') - dn, true); if (nbuf != NULL) { @@ -2477,11 +2692,25 @@ cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb) pfile->cb = *cb; } +/* The narrow character set identifier. */ +const char * +cpp_get_narrow_charset_name (cpp_reader *pfile) +{ + return pfile->narrow_cset_desc.to; +} + +/* The wide character set identifier. */ +const char * +cpp_get_wide_charset_name (cpp_reader *pfile) +{ + return pfile->wide_cset_desc.to; +} + /* The dependencies structure. (Creates one if it hasn't already been.) */ -struct deps * +class mkdeps * cpp_get_deps (cpp_reader *pfile) { - if (!pfile->deps) + if (!pfile->deps && CPP_OPTION (pfile, deps.style) != DEPS_NONE) pfile->deps = deps_init (); return pfile->deps; } @@ -2517,6 +2746,7 @@ _cpp_pop_buffer (cpp_reader *pfile) cpp_buffer *buffer = pfile->buffer; struct _cpp_file *inc = buffer->file; struct if_stack *ifs; + const unsigned char *to_free; /* Walk back up the conditional stack till we reach its level at entry to this file, issuing error messages. */ @@ -2530,6 +2760,7 @@ _cpp_pop_buffer (cpp_reader *pfile) /* _cpp_do_file_change expects pfile->buffer to be the new one. */ pfile->buffer = buffer->prev; + to_free = buffer->to_free; free (buffer->notes); /* Free the buffer object now; we may want to push a new buffer @@ -2538,23 +2769,31 @@ _cpp_pop_buffer (cpp_reader *pfile) if (inc) { - _cpp_pop_file_buffer (pfile, inc); + _cpp_pop_file_buffer (pfile, inc, to_free); _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0); } + else if (to_free) + free ((void *)to_free); } /* Enter all recognized directives in the hash table. */ void _cpp_init_directives (cpp_reader *pfile) { - unsigned int i; - cpp_hashnode *node; - - for (i = 0; i < (unsigned int) N_DIRECTIVES; i++) + for (int i = 0; i < N_DIRECTIVES; i++) { - node = cpp_lookup (pfile, dtable[i].name, dtable[i].length); + cpp_hashnode *node = cpp_lookup (pfile, dtable[i].name, dtable[i].length); node->is_directive = 1; node->directive_index = i; } } + +/* Extract header file from a bracket include. Parsing starts after '<'. + The string is malloced and must be freed by the caller. */ +char * +_cpp_bracket_include(cpp_reader *pfile) +{ + return glue_header_name (pfile); +} + diff --git a/support/cpp/libcpp/errors.c b/support/cpp/libcpp/errors.c deleted file mode 100644 index c586749ab..000000000 --- a/support/cpp/libcpp/errors.c +++ /dev/null @@ -1,238 +0,0 @@ -/* Default error handlers for CPP Library. - Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, 1999, 2000, - 2001, 2002, 2004, 2008, 2009, 2010 Free Software Foundation, Inc. - Written by Per Bothner, 1994. - Based on CCCP program by Paul Rubin, June 1986 - Adapted to ANSI C, Richard Stallman, Jan 1987 - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -#include "config.h" -#include "system.h" -#include "cpplib.h" -#include "internal.h" - -/* Print a diagnostic at the location of the previously lexed token. */ - -ATTRIBUTE_FPTR_PRINTF(4,0) -static bool -cpp_diagnostic (cpp_reader * pfile, int level, int reason, - const char *msgid, va_list *ap) -{ - source_location src_loc; - bool ret; - - if (CPP_OPTION (pfile, traditional)) - { - if (pfile->state.in_directive) - src_loc = pfile->directive_line; - else - src_loc = pfile->line_table->highest_line; - } - /* We don't want to refer to a token before the beginning of the - current run -- that is invalid. */ - else if (pfile->cur_token == pfile->cur_run->base) - { - if (pfile->cur_run->prev != NULL) - src_loc = pfile->cur_run->prev->limit->src_loc; - else - src_loc = 0; - } - else - { - src_loc = pfile->cur_token[-1].src_loc; - } - - if (!pfile->cb.error) - abort (); - ret = pfile->cb.error (pfile, level, reason, src_loc, 0, _(msgid), ap); - - return ret; -} - -/* Print a warning or error, depending on the value of LEVEL. */ - -bool -cpp_error (cpp_reader * pfile, int level, const char *msgid, ...) -{ - va_list ap; - bool ret; - - va_start (ap, msgid); - - ret = cpp_diagnostic (pfile, level, CPP_W_NONE, msgid, &ap); - - va_end (ap); - return ret; -} - -/* Print a warning. The warning reason may be given in REASON. */ - -bool -cpp_warning (cpp_reader * pfile, int reason, const char *msgid, ...) -{ - va_list ap; - bool ret; - - va_start (ap, msgid); - - ret = cpp_diagnostic (pfile, CPP_DL_WARNING, reason, msgid, &ap); - - va_end (ap); - return ret; -} - -/* Print a pedantic warning. The warning reason may be given in REASON. */ - -bool -cpp_pedwarning (cpp_reader * pfile, int reason, const char *msgid, ...) -{ - va_list ap; - bool ret; - - va_start (ap, msgid); - - ret = cpp_diagnostic (pfile, CPP_DL_PEDWARN, reason, msgid, &ap); - - va_end (ap); - return ret; -} - -/* Print a warning, including system headers. The warning reason may be - given in REASON. */ - -bool -cpp_warning_syshdr (cpp_reader * pfile, int reason, const char *msgid, ...) -{ - va_list ap; - bool ret; - - va_start (ap, msgid); - - ret = cpp_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, reason, msgid, &ap); - - va_end (ap); - return ret; -} - -/* Print a diagnostic at a specific location. */ - -ATTRIBUTE_FPTR_PRINTF(6,0) -static bool -cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason, - source_location src_loc, unsigned int column, - const char *msgid, va_list *ap) -{ - bool ret; - - if (!pfile->cb.error) - abort (); - ret = pfile->cb.error (pfile, level, reason, src_loc, column, _(msgid), ap); - - return ret; -} - -/* Print a warning or error, depending on the value of LEVEL. */ - -bool -cpp_error_with_line (cpp_reader *pfile, int level, - source_location src_loc, unsigned int column, - const char *msgid, ...) -{ - va_list ap; - bool ret; - - va_start (ap, msgid); - - ret = cpp_diagnostic_with_line (pfile, level, CPP_W_NONE, src_loc, - column, msgid, &ap); - - va_end (ap); - return ret; -} - -/* Print a warning. The warning reason may be given in REASON. */ - -bool -cpp_warning_with_line (cpp_reader *pfile, int reason, - source_location src_loc, unsigned int column, - const char *msgid, ...) -{ - va_list ap; - bool ret; - - va_start (ap, msgid); - - ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING, reason, src_loc, - column, msgid, &ap); - - va_end (ap); - return ret; -} - -/* Print a pedantic warning. The warning reason may be given in REASON. */ - -bool -cpp_pedwarning_with_line (cpp_reader *pfile, int reason, - source_location src_loc, unsigned int column, - const char *msgid, ...) -{ - va_list ap; - bool ret; - - va_start (ap, msgid); - - ret = cpp_diagnostic_with_line (pfile, CPP_DL_PEDWARN, reason, src_loc, - column, msgid, &ap); - - va_end (ap); - return ret; -} - -/* Print a warning, including system headers. The warning reason may be - given in REASON. */ - -bool -cpp_warning_with_line_syshdr (cpp_reader *pfile, int reason, - source_location src_loc, unsigned int column, - const char *msgid, ...) -{ - va_list ap; - bool ret; - - va_start (ap, msgid); - - ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING_SYSHDR, reason, src_loc, - column, msgid, &ap); - - va_end (ap); - return ret; -} - -/* Print a warning or error, depending on the value of LEVEL. Include - information from errno. */ - -bool -cpp_errno (cpp_reader *pfile, int level, const char *msgid) -{ - if (msgid[0] == '\0') - msgid = _("stdout"); - - return cpp_error (pfile, level, "%s: %s", msgid, xstrerror (errno)); -} diff --git a/support/cpp/libcpp/errors.cc b/support/cpp/libcpp/errors.cc new file mode 100644 index 000000000..df5f8d6fa --- /dev/null +++ b/support/cpp/libcpp/errors.cc @@ -0,0 +1,352 @@ +/* Default error handlers for CPP Library. + Copyright (C) 1986-2022 Free Software Foundation, Inc. + Written by Per Bothner, 1994. + Based on CCCP program by Paul Rubin, June 1986 + Adapted to ANSI C, Richard Stallman, Jan 1987 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" + +/* Get a location_t for the current location in PFILE, + generally that of the previously lexed token. */ + +location_t +cpp_diagnostic_get_current_location (cpp_reader *pfile) +{ + if (CPP_OPTION (pfile, traditional)) + { + if (pfile->state.in_directive) + return pfile->directive_line; + else + return pfile->line_table->highest_line; + } + /* We don't want to refer to a token before the beginning of the + current run -- that is invalid. */ + else if (pfile->cur_token == pfile->cur_run->base) + { + return 0; + } + else + { + return pfile->cur_token[-1].src_loc; + } +} + +/* Print a diagnostic at the given location. */ + +ATTRIBUTE_FPTR_PRINTF(5,0) +static bool +cpp_diagnostic_at (cpp_reader * pfile, enum cpp_diagnostic_level level, + enum cpp_warning_reason reason, rich_location *richloc, + const char *msgid, va_list *ap) +{ + bool ret; + + if (!pfile->cb.diagnostic) + abort (); + ret = pfile->cb.diagnostic (pfile, level, reason, richloc, _(msgid), ap); + + return ret; +} + +/* Print a diagnostic at the location of the previously lexed token. */ + +ATTRIBUTE_FPTR_PRINTF(4,0) +static bool +cpp_diagnostic (cpp_reader * pfile, enum cpp_diagnostic_level level, + enum cpp_warning_reason reason, + const char *msgid, va_list *ap) +{ + location_t src_loc = cpp_diagnostic_get_current_location (pfile); + rich_location richloc (pfile->line_table, src_loc); + return cpp_diagnostic_at (pfile, level, reason, &richloc, msgid, ap); +} + +/* Print a warning or error, depending on the value of LEVEL. */ + +bool +cpp_error (cpp_reader * pfile, enum cpp_diagnostic_level level, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic (pfile, level, CPP_W_NONE, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a warning. The warning reason may be given in REASON. */ + +bool +cpp_warning (cpp_reader * pfile, enum cpp_warning_reason reason, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic (pfile, CPP_DL_WARNING, reason, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a pedantic warning. The warning reason may be given in REASON. */ + +bool +cpp_pedwarning (cpp_reader * pfile, enum cpp_warning_reason reason, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic (pfile, CPP_DL_PEDWARN, reason, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a warning, including system headers. The warning reason may be + given in REASON. */ + +bool +cpp_warning_syshdr (cpp_reader * pfile, enum cpp_warning_reason reason, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, reason, msgid, &ap); + + va_end (ap); + return ret; +} + +/* As cpp_warning above, but use RICHLOC as the location of the diagnostic. */ + +bool cpp_warning_at (cpp_reader *pfile, enum cpp_warning_reason reason, + rich_location *richloc, const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_at (pfile, CPP_DL_WARNING, reason, richloc, + msgid, &ap); + + va_end (ap); + return ret; + +} + +/* As cpp_pedwarning above, but use RICHLOC as the location of the + diagnostic. */ + +bool +cpp_pedwarning_at (cpp_reader * pfile, enum cpp_warning_reason reason, + rich_location *richloc, const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_at (pfile, CPP_DL_PEDWARN, reason, richloc, + msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a diagnostic at a specific location. */ + +ATTRIBUTE_FPTR_PRINTF(6,0) +static bool +cpp_diagnostic_with_line (cpp_reader * pfile, enum cpp_diagnostic_level level, + enum cpp_warning_reason reason, + location_t src_loc, unsigned int column, + const char *msgid, va_list *ap) +{ + bool ret; + + if (!pfile->cb.diagnostic) + abort (); + rich_location richloc (pfile->line_table, src_loc); + if (column) + richloc.override_column (column); + ret = pfile->cb.diagnostic (pfile, level, reason, &richloc, _(msgid), ap); + + return ret; +} + +/* Print a warning or error, depending on the value of LEVEL. */ + +bool +cpp_error_with_line (cpp_reader *pfile, enum cpp_diagnostic_level level, + location_t src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, level, CPP_W_NONE, src_loc, + column, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a warning. The warning reason may be given in REASON. */ + +bool +cpp_warning_with_line (cpp_reader *pfile, enum cpp_warning_reason reason, + location_t src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING, reason, src_loc, + column, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a pedantic warning. The warning reason may be given in REASON. */ + +bool +cpp_pedwarning_with_line (cpp_reader *pfile, enum cpp_warning_reason reason, + location_t src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, CPP_DL_PEDWARN, reason, src_loc, + column, msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a warning, including system headers. The warning reason may be + given in REASON. */ + +bool +cpp_warning_with_line_syshdr (cpp_reader *pfile, enum cpp_warning_reason reason, + location_t src_loc, unsigned int column, + const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING_SYSHDR, reason, src_loc, + column, msgid, &ap); + + va_end (ap); + return ret; +} + +/* As cpp_error, but use SRC_LOC as the location of the error, without + a column override. */ + +bool +cpp_error_at (cpp_reader * pfile, enum cpp_diagnostic_level level, + location_t src_loc, const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + rich_location richloc (pfile->line_table, src_loc); + ret = cpp_diagnostic_at (pfile, level, CPP_W_NONE, &richloc, + msgid, &ap); + + va_end (ap); + return ret; +} + +/* As cpp_error, but use RICHLOC as the location of the error, without + a column override. */ + +bool +cpp_error_at (cpp_reader * pfile, enum cpp_diagnostic_level level, + rich_location *richloc, const char *msgid, ...) +{ + va_list ap; + bool ret; + + va_start (ap, msgid); + + ret = cpp_diagnostic_at (pfile, level, CPP_W_NONE, richloc, + msgid, &ap); + + va_end (ap); + return ret; +} + +/* Print a warning or error, depending on the value of LEVEL. Include + information from errno. */ + +bool +cpp_errno (cpp_reader *pfile, enum cpp_diagnostic_level level, + const char *msgid) +{ + return cpp_error (pfile, level, "%s: %s", _(msgid), xstrerror (errno)); +} + +/* Print a warning or error, depending on the value of LEVEL. Include + information from errno. Unlike cpp_errno, the argument is a filename + that is not localized, but "" is replaced with localized "stdout". */ + +bool +cpp_errno_filename (cpp_reader *pfile, enum cpp_diagnostic_level level, + const char *filename, + location_t loc) +{ + if (filename[0] == '\0') + filename = _("stdout"); + + return cpp_error_at (pfile, level, loc, "%s: %s", filename, + xstrerror (errno)); +} diff --git a/support/cpp/libcpp/expr.c b/support/cpp/libcpp/expr.cc index d9bae17fe..78c5c3eeb 100644 --- a/support/cpp/libcpp/expr.c +++ b/support/cpp/libcpp/expr.cc @@ -1,6 +1,5 @@ /* Parse C expressions for cpplib. - Copyright (C) 1987, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2001, - 2002, 2004, 2008, 2009, 2010 Free Software Foundation. + Copyright (C) 1987-2022 Free Software Foundation, Inc. Contributed by Per Bothner, 1994. This program is free software; you can redistribute it and/or modify it @@ -31,7 +30,7 @@ struct op { const cpp_token *token; /* The token forming op (for diagnostics). */ cpp_num value; /* The value logically "right" of op. */ - source_location loc; /* The location of this value. */ + location_t loc; /* The location of this value. */ enum cpp_ttype op; }; @@ -53,16 +52,16 @@ static cpp_num num_equality_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype); static cpp_num num_mul (cpp_reader *, cpp_num, cpp_num); static cpp_num num_div_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype, - source_location); + location_t); static cpp_num num_lshift (cpp_num, size_t, size_t); static cpp_num num_rshift (cpp_num, size_t, size_t); static cpp_num append_digit (cpp_num, int, int, size_t); static cpp_num parse_defined (cpp_reader *); -static cpp_num eval_token (cpp_reader *, const cpp_token *); +static cpp_num eval_token (cpp_reader *, const cpp_token *, location_t); static struct op *reduce (cpp_reader *, struct op *, enum cpp_ttype); -static unsigned int interpret_float_suffix (const uchar *, size_t); -static unsigned int interpret_int_suffix (const uchar *, size_t); +static unsigned int interpret_float_suffix (cpp_reader *, const uchar *, size_t); +static unsigned int interpret_int_suffix (cpp_reader *, const uchar *, size_t); static void check_promotion (cpp_reader *, const struct op *); /* Token type abuse to create unary plus and minus operators. */ @@ -76,18 +75,63 @@ static void check_promotion (cpp_reader *, const struct op *); #define SYNTAX_ERROR2(msgid, arg) \ do { cpp_error (pfile, CPP_DL_ERROR, msgid, arg); goto syntax_error; } \ while(0) +#define SYNTAX_ERROR_AT(loc, msgid) \ + do { cpp_error_with_line (pfile, CPP_DL_ERROR, (loc), 0, msgid); goto syntax_error; } \ + while(0) +#define SYNTAX_ERROR2_AT(loc, msgid, arg) \ + do { cpp_error_with_line (pfile, CPP_DL_ERROR, (loc), 0, msgid, arg); goto syntax_error; } \ + while(0) /* Subroutine of cpp_classify_number. S points to a float suffix of length LEN, possibly zero. Returns 0 for an invalid suffix, or a - flag vector describing the suffix. */ + flag vector (of CPP_N_* bits) describing the suffix. */ static unsigned int -interpret_float_suffix (const uchar *s, size_t len) +interpret_float_suffix (cpp_reader *pfile, const uchar *s, size_t len) { + size_t orig_len = len; + const uchar *orig_s = s; size_t flags; - size_t f, d, l, w, q, i; + size_t f, d, l, w, q, i, fn, fnx, fn_bits; flags = 0; - f = d = l = w = q = i = 0; + f = d = l = w = q = i = fn = fnx = fn_bits = 0; + + /* The following decimal float suffixes, from TR 24732:2009, TS + 18661-2:2015 and C2X, are supported: + + df, DF - _Decimal32. + dd, DD - _Decimal64. + dl, DL - _Decimal128. + + The dN and DN suffixes for _DecimalN, and dNx and DNx for + _DecimalNx, defined in TS 18661-3:2015, are not supported. + + Fixed-point suffixes, from TR 18037:2008, are supported. They + consist of three parts, in order: + + (i) An optional u or U, for unsigned types. + + (ii) An optional h or H, for short types, or l or L, for long + types, or ll or LL, for long long types. Use of ll or LL is a + GNU extension. + + (iii) r or R, for _Fract types, or k or K, for _Accum types. + + Otherwise the suffix is for a binary or standard floating-point + type. Such a suffix, or the absence of a suffix, may be preceded + or followed by i, I, j or J, to indicate an imaginary number with + the corresponding complex type. The following suffixes for + binary or standard floating-point types are supported: + + f, F - float (ISO C and C++). + l, L - long double (ISO C and C++). + d, D - double, even with the FLOAT_CONST_DECIMAL64 pragma in + operation (from TR 24732:2009; the pragma and the suffix + are not included in TS 18661-2:2015). + w, W - machine-specific type such as __float80 (GNU extension). + q, Q - machine-specific type such as __float128 (GNU extension). + fN, FN - _FloatN (TS 18661-3:2015). + fNx, FNx - _FloatNx (TS 18661-3:2015). */ /* Process decimal float suffixes, which are two letters starting with d or D. Order and case are significant. */ @@ -109,72 +153,139 @@ interpret_float_suffix (const uchar *s, size_t len) } } - /* Recognize a fixed-point suffix. */ - switch (s[len-1]) + if (CPP_OPTION (pfile, ext_numeric_literals)) { - case 'k': case 'K': flags = CPP_N_ACCUM; break; - case 'r': case 'R': flags = CPP_N_FRACT; break; - default: break; - } - - /* Continue processing a fixed-point suffix. The suffix is case - insensitive except for ll or LL. Order is significant. */ - if (flags) - { - if (len == 1) - return flags; - len--; + /* Recognize a fixed-point suffix. */ + if (len != 0) + switch (s[len-1]) + { + case 'k': case 'K': flags = CPP_N_ACCUM; break; + case 'r': case 'R': flags = CPP_N_FRACT; break; + default: break; + } - if (*s == 'u' || *s == 'U') + /* Continue processing a fixed-point suffix. The suffix is case + insensitive except for ll or LL. Order is significant. */ + if (flags) { - flags |= CPP_N_UNSIGNED; if (len == 1) return flags; len--; - s++; - } - switch (*s) - { - case 'h': case 'H': - if (len == 1) - return flags |= CPP_N_SMALL; - break; - case 'l': - if (len == 1) - return flags |= CPP_N_MEDIUM; - if (len == 2 && s[1] == 'l') - return flags |= CPP_N_LARGE; - break; - case 'L': - if (len == 1) - return flags |= CPP_N_MEDIUM; - if (len == 2 && s[1] == 'L') - return flags |= CPP_N_LARGE; - break; - default: - break; - } - /* Anything left at this point is invalid. */ - return 0; + if (*s == 'u' || *s == 'U') + { + flags |= CPP_N_UNSIGNED; + if (len == 1) + return flags; + len--; + s++; + } + + switch (*s) + { + case 'h': case 'H': + if (len == 1) + return flags |= CPP_N_SMALL; + break; + case 'l': + if (len == 1) + return flags |= CPP_N_MEDIUM; + if (len == 2 && s[1] == 'l') + return flags |= CPP_N_LARGE; + break; + case 'L': + if (len == 1) + return flags |= CPP_N_MEDIUM; + if (len == 2 && s[1] == 'L') + return flags |= CPP_N_LARGE; + break; + default: + break; + } + /* Anything left at this point is invalid. */ + return 0; + } } /* In any remaining valid suffix, the case and order don't matter. */ while (len--) - switch (s[len]) - { - case 'f': case 'F': f++; break; - case 'd': case 'D': d++; break; - case 'l': case 'L': l++; break; - case 'w': case 'W': w++; break; - case 'q': case 'Q': q++; break; - case 'i': case 'I': - case 'j': case 'J': i++; break; - default: + { + switch (s[0]) + { + case 'f': case 'F': + f++; + if (len > 0 + && !CPP_OPTION (pfile, cplusplus) + && s[1] >= '1' + && s[1] <= '9' + && fn_bits == 0) + { + f--; + while (len > 0 + && s[1] >= '0' + && s[1] <= '9' + && fn_bits < CPP_FLOATN_MAX) + { + fn_bits = fn_bits * 10 + (s[1] - '0'); + len--; + s++; + } + if (len > 0 && s[1] == 'x') + { + fnx++; + len--; + s++; + } + else + fn++; + } + break; + case 'd': case 'D': d++; break; + case 'l': case 'L': l++; break; + case 'w': case 'W': w++; break; + case 'q': case 'Q': q++; break; + case 'i': case 'I': + case 'j': case 'J': i++; break; + default: + return 0; + } + s++; + } + + /* Reject any case of multiple suffixes specifying types, multiple + suffixes specifying an imaginary constant, _FloatN or _FloatNx + suffixes for invalid values of N, and _FloatN suffixes for values + of N larger than can be represented in the return value. The + caller is responsible for rejecting _FloatN suffixes where + _FloatN is not supported on the chosen target. */ + if (f + d + l + w + q + fn + fnx > 1 || i > 1) + return 0; + if (fn_bits > CPP_FLOATN_MAX) + return 0; + if (fnx && fn_bits != 32 && fn_bits != 64 && fn_bits != 128) + return 0; + if (fn && fn_bits != 16 && fn_bits % 32 != 0) + return 0; + if (fn && fn_bits == 96) + return 0; + + if (i) + { + if (!CPP_OPTION (pfile, ext_numeric_literals)) return 0; - } - if (f + d + l + w + q > 1 || i > 1) + /* In C++14 and up these suffixes are in the standard library, so treat + them as user-defined literals. */ + if (CPP_OPTION (pfile, cplusplus) + && CPP_OPTION (pfile, lang) > CLK_CXX11 + && orig_s[0] == 'i' + && (orig_len == 1 + || (orig_len == 2 + && (orig_s[1] == 'f' || orig_s[1] == 'l')))) + return 0; + } + + if ((w || q) && !CPP_OPTION (pfile, ext_numeric_literals)) return 0; return ((i ? CPP_N_IMAGINARY : 0) @@ -182,22 +293,34 @@ interpret_float_suffix (const uchar *s, size_t len) d ? CPP_N_MEDIUM : l ? CPP_N_LARGE : w ? CPP_N_MD_W : - q ? CPP_N_MD_Q : CPP_N_DEFAULT)); + q ? CPP_N_MD_Q : + fn ? CPP_N_FLOATN | (fn_bits << CPP_FLOATN_SHIFT) : + fnx ? CPP_N_FLOATNX | (fn_bits << CPP_FLOATN_SHIFT) : + CPP_N_DEFAULT)); +} + +/* Return the classification flags for a float suffix. */ +unsigned int +cpp_interpret_float_suffix (cpp_reader *pfile, const char *s, size_t len) +{ + return interpret_float_suffix (pfile, (const unsigned char *)s, len); } /* Subroutine of cpp_classify_number. S points to an integer suffix of length LEN, possibly zero. Returns 0 for an invalid suffix, or a flag vector describing the suffix. */ static unsigned int -interpret_int_suffix (const uchar *s, size_t len) +interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len) { - size_t u, l, i; + size_t orig_len = len; + size_t u, l, i, z; - u = l = i = 0; + u = l = i = z = 0; while (len--) switch (s[len]) { + case 'z': case 'Z': z++; break; case 'u': case 'U': u++; break; case 'i': case 'I': case 'j': case 'J': i++; break; @@ -210,26 +333,197 @@ interpret_int_suffix (const uchar *s, size_t len) return 0; } - if (l > 2 || u > 1 || i > 1) + if (l > 2 || u > 1 || i > 1 || z > 1) return 0; + if (z) + { + if (l > 0 || i > 0) + return 0; + if (!CPP_OPTION (pfile, cplusplus)) + return 0; + } + + if (i) + { + if (!CPP_OPTION (pfile, ext_numeric_literals)) + return 0; + + /* In C++14 and up these suffixes are in the standard library, so treat + them as user-defined literals. */ + if (CPP_OPTION (pfile, cplusplus) + && CPP_OPTION (pfile, lang) > CLK_CXX11 + && s[0] == 'i' + && (orig_len == 1 || (orig_len == 2 && s[1] == 'l'))) + return 0; + } + return ((i ? CPP_N_IMAGINARY : 0) | (u ? CPP_N_UNSIGNED : 0) | ((l == 0) ? CPP_N_SMALL - : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE)); + : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE) + | (z ? CPP_N_SIZE_T : 0)); +} + +/* Return the classification flags for an int suffix. */ +unsigned int +cpp_interpret_int_suffix (cpp_reader *pfile, const char *s, size_t len) +{ + return interpret_int_suffix (pfile, (const unsigned char *)s, len); +} + +/* Return the string type corresponding to the the input user-defined string + literal type. If the input type is not a user-defined string literal + type return the input type. */ +enum cpp_ttype +cpp_userdef_string_remove_type (enum cpp_ttype type) +{ + if (type == CPP_STRING_USERDEF) + return CPP_STRING; + else if (type == CPP_WSTRING_USERDEF) + return CPP_WSTRING; + else if (type == CPP_STRING16_USERDEF) + return CPP_STRING16; + else if (type == CPP_STRING32_USERDEF) + return CPP_STRING32; + else if (type == CPP_UTF8STRING_USERDEF) + return CPP_UTF8STRING; + else + return type; +} + +/* Return the user-defined string literal type corresponding to the input + string type. If the input type is not a string type return the input + type. */ +enum cpp_ttype +cpp_userdef_string_add_type (enum cpp_ttype type) +{ + if (type == CPP_STRING) + return CPP_STRING_USERDEF; + else if (type == CPP_WSTRING) + return CPP_WSTRING_USERDEF; + else if (type == CPP_STRING16) + return CPP_STRING16_USERDEF; + else if (type == CPP_STRING32) + return CPP_STRING32_USERDEF; + else if (type == CPP_UTF8STRING) + return CPP_UTF8STRING_USERDEF; + else + return type; +} + +/* Return the char type corresponding to the the input user-defined char + literal type. If the input type is not a user-defined char literal + type return the input type. */ +enum cpp_ttype +cpp_userdef_char_remove_type (enum cpp_ttype type) +{ + if (type == CPP_CHAR_USERDEF) + return CPP_CHAR; + else if (type == CPP_WCHAR_USERDEF) + return CPP_WCHAR; + else if (type == CPP_CHAR16_USERDEF) + return CPP_CHAR16; + else if (type == CPP_CHAR32_USERDEF) + return CPP_CHAR32; + else if (type == CPP_UTF8CHAR_USERDEF) + return CPP_UTF8CHAR; + else + return type; +} + +/* Return the user-defined char literal type corresponding to the input + char type. If the input type is not a char type return the input + type. */ +enum cpp_ttype +cpp_userdef_char_add_type (enum cpp_ttype type) +{ + if (type == CPP_CHAR) + return CPP_CHAR_USERDEF; + else if (type == CPP_WCHAR) + return CPP_WCHAR_USERDEF; + else if (type == CPP_CHAR16) + return CPP_CHAR16_USERDEF; + else if (type == CPP_CHAR32) + return CPP_CHAR32_USERDEF; + else if (type == CPP_UTF8CHAR) + return CPP_UTF8CHAR_USERDEF; + else + return type; +} + +/* Return true if the token type is a user-defined string literal. */ +bool +cpp_userdef_string_p (enum cpp_ttype type) +{ + if (type == CPP_STRING_USERDEF + || type == CPP_WSTRING_USERDEF + || type == CPP_STRING16_USERDEF + || type == CPP_STRING32_USERDEF + || type == CPP_UTF8STRING_USERDEF) + return true; + else + return false; +} + +/* Return true if the token type is a user-defined char literal. */ +bool +cpp_userdef_char_p (enum cpp_ttype type) +{ + if (type == CPP_CHAR_USERDEF + || type == CPP_WCHAR_USERDEF + || type == CPP_CHAR16_USERDEF + || type == CPP_CHAR32_USERDEF + || type == CPP_UTF8CHAR_USERDEF) + return true; + else + return false; +} + +/* Extract the suffix from a user-defined literal string or char. */ +const char * +cpp_get_userdef_suffix (const cpp_token *tok) +{ + unsigned int len = tok->val.str.len; + const char *text = (const char *)tok->val.str.text; + char delim; + unsigned int i; + for (i = 0; i < len; ++i) + if (text[i] == '\'' || text[i] == '"') + break; + if (i == len) + return text + len; + delim = text[i]; + for (i = len; i > 0; --i) + if (text[i - 1] == delim) + break; + return text + i; } /* Categorize numeric constants according to their field (integer, floating point, or invalid), radix (decimal, octal, hexadecimal), - and type suffixes. */ + and type suffixes. + + TOKEN is the token that represents the numeric constant to + classify. + + In C++0X if UD_SUFFIX is non null it will be assigned + any unrecognized suffix for a user-defined literal. + + VIRTUAL_LOCATION is the virtual location for TOKEN. */ unsigned int -cpp_classify_number (cpp_reader *pfile, const cpp_token *token) +cpp_classify_number (cpp_reader *pfile, const cpp_token *token, + const char **ud_suffix, location_t virtual_location) { const uchar *str = token->val.str.text; const uchar *limit; unsigned int max_digit, result, radix; enum {NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON} float_flag; bool seen_digit; + bool seen_digit_sep; + + if (ud_suffix) + *ud_suffix = NULL; /* If the lexer has done its job, length one can only be a single digit. Fast-path this very common case. */ @@ -241,6 +535,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) max_digit = 0; radix = 10; seen_digit = false; + seen_digit_sep = false; /* First, interpret the radix. */ if (*str == '0') @@ -249,16 +544,27 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) str++; /* Require at least one hex digit to classify it as hex. */ - if ((*str == 'x' || *str == 'X') - && (str[1] == '.' || ISXDIGIT (str[1]))) + if (*str == 'x' || *str == 'X') { - radix = 16; - str++; + if (str[1] == '.' || ISXDIGIT (str[1])) + { + radix = 16; + str++; + } + else if (DIGIT_SEP (str[1])) + SYNTAX_ERROR_AT (virtual_location, + "digit separator after base indicator"); } - else if ((*str == 'b' || *str == 'B') && (str[1] == '0' || str[1] == '1')) + else if (*str == 'b' || *str == 'B') { - radix = 2; - str++; + if (str[1] == '0' || str[1] == '1') + { + radix = 2; + str++; + } + else if (DIGIT_SEP (str[1])) + SYNTAX_ERROR_AT (virtual_location, + "digit separator after base indicator"); } } @@ -269,21 +575,32 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16)) { + seen_digit_sep = false; seen_digit = true; c = hex_value (c); if (c > max_digit) max_digit = c; } + else if (DIGIT_SEP (c)) + seen_digit_sep = true; else if (c == '.') { + if (seen_digit_sep || DIGIT_SEP (*str)) + SYNTAX_ERROR_AT (virtual_location, + "digit separator adjacent to decimal point"); + seen_digit_sep = false; if (float_flag == NOT_FLOAT) float_flag = AFTER_POINT; else - SYNTAX_ERROR ("too many decimal points in number"); + SYNTAX_ERROR_AT (virtual_location, + "too many decimal points in number"); } else if ((radix <= 10 && (c == 'e' || c == 'E')) || (radix == 16 && (c == 'p' || c == 'P'))) { + if (seen_digit_sep || DIGIT_SEP (*str)) + SYNTAX_ERROR_AT (virtual_location, + "digit separator adjacent to exponent"); float_flag = AFTER_EXPON; break; } @@ -295,10 +612,14 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) } } + if (seen_digit_sep && float_flag != AFTER_EXPON) + SYNTAX_ERROR_AT (virtual_location, + "digit separator outside digit sequence"); + /* The suffix may be for decimal fixed-point constants without exponent. */ if (radix != 16 && float_flag == NOT_FLOAT) { - result = interpret_float_suffix (str, limit - str); + result = interpret_float_suffix (pfile, str, limit - str); if ((result & CPP_N_FRACT) || (result & CPP_N_ACCUM)) { result |= CPP_N_FLOATING; @@ -307,8 +628,8 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) radix = 10; if (CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_PEDWARN, - "fixed-point constants are a GCC extension"); + cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, + "fixed-point constants are a GCC extension"); goto syntax_ok; } else @@ -321,26 +642,36 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) if (max_digit >= radix) { if (radix == 2) - SYNTAX_ERROR2 ("invalid digit \"%c\" in binary constant", '0' + max_digit); + SYNTAX_ERROR2_AT (virtual_location, + "invalid digit \"%c\" in binary constant", '0' + max_digit); else - SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit); + SYNTAX_ERROR2_AT (virtual_location, + "invalid digit \"%c\" in octal constant", '0' + max_digit); } if (float_flag != NOT_FLOAT) { if (radix == 2) { - cpp_error (pfile, CPP_DL_ERROR, - "invalid prefix \"0b\" for floating constant"); + cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0, + "invalid prefix \"0b\" for floating constant"); return CPP_N_INVALID; } if (radix == 16 && !seen_digit) - SYNTAX_ERROR ("no digits in hexadecimal floating constant"); + SYNTAX_ERROR_AT (virtual_location, + "no digits in hexadecimal floating constant"); - if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99)) - cpp_error (pfile, CPP_DL_PEDWARN, - "use of C99 hexadecimal floating constant"); + if (radix == 16 && CPP_PEDANTIC (pfile) + && !CPP_OPTION (pfile, extended_numbers)) + { + if (CPP_OPTION (pfile, cplusplus)) + cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, + "use of C++17 hexadecimal floating constant"); + else + cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, + "use of C99 hexadecimal floating constant"); + } if (float_flag == AFTER_EXPON) { @@ -349,67 +680,105 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) /* Exponent is decimal, even if string is a hex float. */ if (!ISDIGIT (*str)) - SYNTAX_ERROR ("exponent has no digits"); - + { + if (DIGIT_SEP (*str)) + SYNTAX_ERROR_AT (virtual_location, + "digit separator adjacent to exponent"); + else + SYNTAX_ERROR_AT (virtual_location, "exponent has no digits"); + } do - str++; - while (ISDIGIT (*str)); + { + seen_digit_sep = DIGIT_SEP (*str); + str++; + } + while (ISDIGIT (*str) || DIGIT_SEP (*str)); } else if (radix == 16) - SYNTAX_ERROR ("hexadecimal floating constants require an exponent"); + SYNTAX_ERROR_AT (virtual_location, + "hexadecimal floating constants require an exponent"); + + if (seen_digit_sep) + SYNTAX_ERROR_AT (virtual_location, + "digit separator outside digit sequence"); - result = interpret_float_suffix (str, limit - str); + result = interpret_float_suffix (pfile, str, limit - str); if (result == 0) { - cpp_error (pfile, CPP_DL_ERROR, - "invalid suffix \"%.*s\" on floating constant", - (int) (limit - str), str); - return CPP_N_INVALID; + if (CPP_OPTION (pfile, user_literals)) + { + if (ud_suffix) + *ud_suffix = (const char *) str; + result = CPP_N_LARGE | CPP_N_USERDEF; + } + else + { + cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0, + "invalid suffix \"%.*s\" on floating constant", + (int) (limit - str), str); + return CPP_N_INVALID; + } } /* Traditional C didn't accept any floating suffixes. */ if (limit != str && CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile)) - cpp_warning (pfile, CPP_W_TRADITIONAL, - "traditional C rejects the \"%.*s\" suffix", - (int) (limit - str), str); + cpp_warning_with_line (pfile, CPP_W_TRADITIONAL, virtual_location, 0, + "traditional C rejects the \"%.*s\" suffix", + (int) (limit - str), str); /* A suffix for double is a GCC extension via decimal float support. If the suffix also specifies an imaginary value we'll catch that later. */ if ((result == CPP_N_MEDIUM) && CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_PEDWARN, - "suffix for double constant is a GCC extension"); + cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, + "suffix for double constant is a GCC extension"); /* Radix must be 10 for decimal floats. */ if ((result & CPP_N_DFLOAT) && radix != 10) { - cpp_error (pfile, CPP_DL_ERROR, - "invalid suffix \"%.*s\" with hexadecimal floating constant", - (int) (limit - str), str); + cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0, + "invalid suffix \"%.*s\" with hexadecimal floating constant", + (int) (limit - str), str); return CPP_N_INVALID; } if ((result & (CPP_N_FRACT | CPP_N_ACCUM)) && CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_PEDWARN, - "fixed-point constants are a GCC extension"); + cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, + "fixed-point constants are a GCC extension"); - if ((result & CPP_N_DFLOAT) && CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_PEDWARN, - "decimal float constants are a GCC extension"); + if (result & CPP_N_DFLOAT) + { + if (CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, dfp_constants)) + cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, + "decimal float constants are a C2X feature"); + else if (CPP_OPTION (pfile, cpp_warn_c11_c2x_compat) > 0) + cpp_warning_with_line (pfile, CPP_W_C11_C2X_COMPAT, + virtual_location, 0, + "decimal float constants are a C2X feature"); + } result |= CPP_N_FLOATING; } else { - result = interpret_int_suffix (str, limit - str); + result = interpret_int_suffix (pfile, str, limit - str); if (result == 0) { - cpp_error (pfile, CPP_DL_ERROR, - "invalid suffix \"%.*s\" on integer constant", - (int) (limit - str), str); - return CPP_N_INVALID; + if (CPP_OPTION (pfile, user_literals)) + { + if (ud_suffix) + *ud_suffix = (const char *) str; + result = CPP_N_UNSIGNED | CPP_N_LARGE | CPP_N_USERDEF; + } + else + { + cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0, + "invalid suffix \"%.*s\" on integer constant", + (int) (limit - str), str); + return CPP_N_INVALID; + } } /* Traditional C only accepted the 'L' suffix. @@ -421,34 +790,59 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token) && CPP_OPTION (pfile, cpp_warn_long_long); if (u_or_i || large) - cpp_warning (pfile, large ? CPP_W_LONG_LONG : CPP_W_TRADITIONAL, - "traditional C rejects the \"%.*s\" suffix", - (int) (limit - str), str); + cpp_warning_with_line (pfile, large ? CPP_W_LONG_LONG : CPP_W_TRADITIONAL, + virtual_location, 0, + "traditional C rejects the \"%.*s\" suffix", + (int) (limit - str), str); } if ((result & CPP_N_WIDTH) == CPP_N_LARGE && CPP_OPTION (pfile, cpp_warn_long_long)) { const char *message = CPP_OPTION (pfile, cplusplus) - ? N_("use of C++0x long long integer constant") + ? N_("use of C++11 long long integer constant") : N_("use of C99 long long integer constant"); if (CPP_OPTION (pfile, c99)) - cpp_warning (pfile, CPP_W_LONG_LONG, "%s", message); + cpp_warning_with_line (pfile, CPP_W_LONG_LONG, virtual_location, + 0, message); else - cpp_pedwarning (pfile, CPP_W_LONG_LONG, "%s", message); + cpp_pedwarning_with_line (pfile, CPP_W_LONG_LONG, + virtual_location, 0, message); } + if ((result & CPP_N_SIZE_T) == CPP_N_SIZE_T + && !CPP_OPTION (pfile, size_t_literals)) + { + const char *message = (result & CPP_N_UNSIGNED) == CPP_N_UNSIGNED + ? N_("use of C++23 %<size_t%> integer constant") + : N_("use of C++23 %<make_signed_t<size_t>%> integer constant"); + cpp_warning_with_line (pfile, CPP_W_SIZE_T_LITERALS, + virtual_location, 0, message); + } + result |= CPP_N_INTEGER; } syntax_ok: if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_PEDWARN, - "imaginary constants are a GCC extension"); - if (radix == 2 && CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_PEDWARN, - "binary constants are a GCC extension"); + cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, + "imaginary constants are a GCC extension"); + if (radix == 2) + { + if (!CPP_OPTION (pfile, binary_constants) + && CPP_PEDANTIC (pfile)) + cpp_error_with_line (pfile, CPP_DL_PEDWARN, virtual_location, 0, + CPP_OPTION (pfile, cplusplus) + ? N_("binary constants are a C++14 feature " + "or GCC extension") + : N_("binary constants are a C2X feature " + "or GCC extension")); + else if (CPP_OPTION (pfile, cpp_warn_c11_c2x_compat) > 0) + cpp_warning_with_line (pfile, CPP_W_C11_C2X_COMPAT, + virtual_location, 0, + "binary constants are a C2X feature"); + } if (radix == 10) result |= CPP_N_DECIMAL; @@ -525,6 +919,8 @@ cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token, if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c))) c = hex_value (c); + else if (DIGIT_SEP (c)) + continue; else break; @@ -539,7 +935,7 @@ cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token, } } - if (overflow) + if (overflow && !(type & CPP_N_USERDEF)) cpp_error (pfile, CPP_DL_PEDWARN, "integer constant is too large for its type"); /* If too big to be signed, consider it unsigned. Only warn for @@ -688,30 +1084,19 @@ parse_defined (cpp_reader *pfile) } } + bool is_defined = false; if (node) { - if (pfile->context != initial_context && CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_WARNING, - "this use of \"defined\" may not be portable"); - + if ((pfile->context != initial_context + || initial_context != &pfile->base_context) + && CPP_OPTION (pfile, warn_expansion_to_defined)) + cpp_pedwarning (pfile, CPP_W_EXPANSION_TO_DEFINED, + "this use of \"defined\" may not be portable"); + is_defined = _cpp_defined_macro_p (node); + if (!_cpp_maybe_notify_macro_use (pfile, node, token->src_loc)) + /* It wasn't a macro after all. */ + is_defined = false; _cpp_mark_macro_used (node); - if (!(node->flags & NODE_USED)) - { - node->flags |= NODE_USED; - if (node->type == NT_MACRO) - { - if ((node->flags & NODE_BUILTIN) - && pfile->cb.user_builtin_macro) - pfile->cb.user_builtin_macro (pfile, node); - if (pfile->cb.used_define) - pfile->cb.used_define (pfile, pfile->directive_line, node); - } - else - { - if (pfile->cb.used_undef) - pfile->cb.used_undef (pfile, pfile->directive_line, node); - } - } /* A possible controlling macro of the form #if !defined (). _cpp_parse_expr checks there was no other junk on the line. */ @@ -721,14 +1106,13 @@ parse_defined (cpp_reader *pfile) pfile->state.prevent_expansion--; /* Do not treat conditional macros as being defined. This is due to the - powerpc and spu ports using conditional macros for 'vector', 'bool', and - 'pixel' to act as conditional keywords. This messes up tests like #ifndef + powerpc port using conditional macros for 'vector', 'bool', and 'pixel' + to act as conditional keywords. This messes up tests like #ifndef bool. */ result.unsignedp = false; result.high = 0; result.overflow = false; - result.low = (node && node->type == NT_MACRO - && (node->flags & NODE_CONDITIONAL) == 0); + result.low = is_defined; return result; } @@ -736,7 +1120,8 @@ parse_defined (cpp_reader *pfile) number or character constant, or the result of the "defined" or "#" operators). */ static cpp_num -eval_token (cpp_reader *pfile, const cpp_token *token) +eval_token (cpp_reader *pfile, const cpp_token *token, + location_t virtual_location) { cpp_num result; unsigned int temp; @@ -748,18 +1133,21 @@ eval_token (cpp_reader *pfile, const cpp_token *token) switch (token->type) { case CPP_NUMBER: - temp = cpp_classify_number (pfile, token); + temp = cpp_classify_number (pfile, token, NULL, virtual_location); + if (temp & CPP_N_USERDEF) + cpp_error (pfile, CPP_DL_ERROR, + "user-defined literal in preprocessor expression"); switch (temp & CPP_N_CATEGORY) { case CPP_N_FLOATING: - cpp_error (pfile, CPP_DL_ERROR, - "floating constant in preprocessor expression"); + cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0, + "floating constant in preprocessor expression"); break; case CPP_N_INTEGER: if (!(temp & CPP_N_IMAGINARY)) return cpp_interpret_integer (pfile, token, temp); - cpp_error (pfile, CPP_DL_ERROR, - "imaginary number in preprocessor expression"); + cpp_error_with_line (pfile, CPP_DL_ERROR, virtual_location, 0, + "imaginary number in preprocessor expression"); break; case CPP_N_INVALID: @@ -773,6 +1161,7 @@ eval_token (cpp_reader *pfile, const cpp_token *token) case CPP_CHAR: case CPP_CHAR16: case CPP_CHAR32: + case CPP_UTF8CHAR: { cppchar_t cc = cpp_interpret_charconst (pfile, token, &temp, &unsignedp); @@ -806,8 +1195,9 @@ eval_token (cpp_reader *pfile, const cpp_token *token) result.high = 0; result.low = 0; if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval) - cpp_warning (pfile, CPP_W_UNDEF, "\"%s\" is not defined", - NODE_NAME (token->val.node.node)); + cpp_warning_with_line (pfile, CPP_W_UNDEF, virtual_location, 0, + "\"%s\" is not defined, evaluates to 0", + NODE_NAME (token->val.node.node)); } break; @@ -817,11 +1207,12 @@ eval_token (cpp_reader *pfile, const cpp_token *token) /* A pedantic warning takes precedence over a deprecated warning here. */ if (CPP_PEDANTIC (pfile)) - cpp_error (pfile, CPP_DL_PEDWARN, - "assertions are a GCC extension"); + cpp_error_with_line (pfile, CPP_DL_PEDWARN, + virtual_location, 0, + "assertions are a GCC extension"); else if (CPP_OPTION (pfile, cpp_warn_deprecated)) - cpp_warning (pfile, CPP_W_DEPRECATED, - "assertions are a deprecated extension"); + cpp_warning_with_line (pfile, CPP_W_DEPRECATED, virtual_location, 0, + "assertions are a deprecated extension"); } _cpp_test_assertion (pfile, &temp); result.high = 0; @@ -923,6 +1314,7 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if) struct op *top = pfile->op_stack; unsigned int lex_count; bool saw_leading_not, want_value = true; + location_t virtual_location = 0; pfile->state.skip_eval = 0; @@ -939,9 +1331,9 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if) struct op op; lex_count++; - op.token = cpp_get_token (pfile); + op.token = cpp_get_token_with_location (pfile, &virtual_location); op.op = op.token->type; - op.loc = op.token->src_loc; + op.loc = virtual_location; switch (op.op) { @@ -951,13 +1343,15 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if) case CPP_WCHAR: case CPP_CHAR16: case CPP_CHAR32: + case CPP_UTF8CHAR: case CPP_NAME: case CPP_HASH: if (!want_value) - SYNTAX_ERROR2 ("missing binary operator before token \"%s\"", - cpp_token_as_text (pfile, op.token)); + SYNTAX_ERROR2_AT (op.loc, + "missing binary operator before token \"%s\"", + cpp_token_as_text (pfile, op.token)); want_value = false; - top->value = eval_token (pfile, op.token); + top->value = eval_token (pfile, op.token, op.loc); continue; case CPP_NOT: @@ -974,8 +1368,9 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if) default: if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ) - SYNTAX_ERROR2 ("token \"%s\" is not valid in preprocessor expressions", - cpp_token_as_text (pfile, op.token)); + SYNTAX_ERROR2_AT (op.loc, + "token \"%s\" is not valid in preprocessor expressions", + cpp_token_as_text (pfile, op.token)); break; } @@ -983,27 +1378,32 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if) if (optab[op.op].flags & NO_L_OPERAND) { if (!want_value) - SYNTAX_ERROR2 ("missing binary operator before token \"%s\"", - cpp_token_as_text (pfile, op.token)); + SYNTAX_ERROR2_AT (op.loc, + "missing binary operator before token \"%s\"", + cpp_token_as_text (pfile, op.token)); } else if (want_value) { /* We want a number (or expression) and haven't got one. Try to emit a specific diagnostic. */ if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN) - SYNTAX_ERROR ("missing expression between '(' and ')'"); + SYNTAX_ERROR_AT (op.loc, + "missing expression between '(' and ')'"); if (op.op == CPP_EOF && top->op == CPP_EOF) - SYNTAX_ERROR2 ("%s with no expression", is_if ? "#if" : "#elif"); + SYNTAX_ERROR2_AT (op.loc, + "%s with no expression", is_if ? "#if" : "#elif"); if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN) - SYNTAX_ERROR2 ("operator '%s' has no right operand", - cpp_token_as_text (pfile, top->token)); + SYNTAX_ERROR2_AT (op.loc, + "operator '%s' has no right operand", + cpp_token_as_text (pfile, top->token)); else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF) /* Complain about missing paren during reduction. */; else - SYNTAX_ERROR2 ("operator '%s' has no left operand", - cpp_token_as_text (pfile, op.token)); + SYNTAX_ERROR2_AT (op.loc, + "operator '%s' has no left operand", + cpp_token_as_text (pfile, op.token)); } top = reduce (pfile, top, op.op); @@ -1028,7 +1428,8 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if) break; case CPP_COLON: if (top->op != CPP_QUERY) - SYNTAX_ERROR (" ':' without preceding '?'"); + SYNTAX_ERROR_AT (op.loc, + " ':' without preceding '?'"); if (!num_zerop (top[-1].value)) /* Was '?' condition true? */ pfile->state.skip_eval++; else @@ -1045,7 +1446,7 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if) top->op = op.op; top->token = op.token; - top->loc = op.token->src_loc; + top->loc = op.loc; } /* The controlling macro expression is only valid if we called lex 3 @@ -1056,8 +1457,9 @@ _cpp_parse_expr (cpp_reader *pfile, bool is_if) if (top != pfile->op_stack) { - cpp_error (pfile, CPP_DL_ICE, "unbalanced stack in %s", - is_if ? "#if" : "#elif"); + cpp_error_with_line (pfile, CPP_DL_ICE, top->loc, 0, + "unbalanced stack in %s", + is_if ? "#if" : "#elif"); syntax_error: return false; /* Return false on syntax error. */ } @@ -1577,7 +1979,22 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) /* Arithmetic. */ case CPP_MINUS: - rhs = num_negate (rhs, precision); + result.low = lhs.low - rhs.low; + result.high = lhs.high - rhs.high; + if (result.low > lhs.low) + result.high--; + result.unsignedp = lhs.unsignedp || rhs.unsignedp; + result.overflow = false; + + result = num_trim (result, precision); + if (!result.unsignedp) + { + bool lhsp = num_positive (lhs, precision); + result.overflow = (lhsp != num_positive (rhs, precision) + && lhsp != num_positive (result, precision)); + } + return result; + case CPP_PLUS: result.low = lhs.low + rhs.low; result.high = lhs.high + rhs.high; @@ -1599,8 +2016,8 @@ num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op) default: /* case CPP_COMMA: */ if (CPP_PEDANTIC (pfile) && (!CPP_OPTION (pfile, c99) || !pfile->state.skip_eval)) - cpp_error (pfile, CPP_DL_PEDWARN, - "comma operator in operand of #if"); + cpp_pedwarning (pfile, CPP_W_PEDANTIC, + "comma operator in operand of #if"); lhs = rhs; break; } @@ -1695,7 +2112,7 @@ num_mul (cpp_reader *pfile, cpp_num lhs, cpp_num rhs) static cpp_num num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op, - source_location location) + location_t location) { cpp_num result, sub; cpp_num_part mask; @@ -1791,3 +2208,4 @@ num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op, return lhs; } + diff --git a/support/cpp/libcpp/files.c b/support/cpp/libcpp/files.cc index 6484be5e7..64ff63547 100644 --- a/support/cpp/libcpp/files.c +++ b/support/cpp/libcpp/files.cc @@ -1,7 +1,5 @@ /* Part of CPP library. File handling. - Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. + Copyright (C) 1986-2022 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 @@ -31,6 +29,7 @@ along with this program; see the file COPYING3. If not see #include "hashtab.h" #include "md5.h" #include <dirent.h> +#include <cassert> /* Variable length record files on VMS will have a stat size that includes record control characters that won't be included in the read size. */ @@ -52,7 +51,7 @@ along with this program; see the file COPYING3. If not see /* 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. */ + cpp_file_hash_entry; at present no reference count is kept. */ struct _cpp_file { /* Filename as given to #include or command line switch. */ @@ -100,16 +99,19 @@ struct _cpp_file unsigned short stack_count; /* If opened with #import or contains #pragma once. */ - bool once_only; + bool once_only : 1; /* If read() failed before. */ - bool dont_read; - - /* If this file is the main file. */ - bool main_file; + bool dont_read : 1; /* If BUFFER above contains the true contents of the file. */ - bool buffer_valid; + bool buffer_valid : 1; + + /* If this file is implicitly preincluded. */ + bool implicit_preinclude : 1; + + /* > 0: Known C++ Module header unit, <0: known not. ==0, unknown */ + int header_unit : 2; }; /* A singly-linked list for all searches for a given file name, with @@ -139,11 +141,11 @@ struct _cpp_file have to do more work re-preprocessing the file, and/or comparing its contents against earlier once-only files. */ -struct file_hash_entry +struct cpp_file_hash_entry { - struct file_hash_entry *next; + struct cpp_file_hash_entry *next; cpp_dir *start_dir; - source_location location; + location_t location; union { _cpp_file *file; @@ -151,10 +153,10 @@ struct file_hash_entry } u; }; -/* Number of entries to put in a file_hash_entry pool. */ +/* Number of entries to put in a cpp_file_hash_entry pool. */ #define FILE_HASH_POOL_SIZE 127 -/* A file hash entry pool. We allocate file_hash_entry object from +/* A file hash entry pool. We allocate cpp_file_hash_entry object from one of these. */ struct file_hash_entry_pool { @@ -163,28 +165,30 @@ struct file_hash_entry_pool /* Next pool in the chain; used when freeing. */ struct file_hash_entry_pool *next; /* The memory pool. */ - struct file_hash_entry pool[FILE_HASH_POOL_SIZE]; + struct cpp_file_hash_entry pool[FILE_HASH_POOL_SIZE]; }; static bool open_file (_cpp_file *file); static bool pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch); static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file, - bool *invalid_pch); -static bool read_file_guts (cpp_reader *pfile, _cpp_file *file); -static bool read_file (cpp_reader *pfile, _cpp_file *file); -static bool should_stack_file (cpp_reader *, _cpp_file *file, bool import); + bool *invalid_pch, location_t loc); +static bool read_file_guts (cpp_reader *pfile, _cpp_file *file, + location_t loc, const char *input_charset); +static bool read_file (cpp_reader *pfile, _cpp_file *file, + location_t loc); static struct cpp_dir *search_path_head (cpp_reader *, const char *fname, int angle_brackets, enum include_type); static const char *dir_name_of_file (_cpp_file *file); -static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int); -static struct file_hash_entry *search_cache (struct file_hash_entry *head, +static void open_file_failed (cpp_reader *pfile, _cpp_file *file, int, + location_t); +static struct cpp_file_hash_entry *search_cache (struct cpp_file_hash_entry *head, const cpp_dir *start_dir); -static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname); +static _cpp_file *make_cpp_file (cpp_dir *, const char *fname); static void destroy_cpp_file (_cpp_file *); static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp); static void allocate_file_hash_entries (cpp_reader *pfile); -static struct file_hash_entry *new_file_hash_entry (cpp_reader *pfile); +static struct cpp_file_hash_entry *new_file_hash_entry (cpp_reader *pfile); static int report_missing_guard (void **slot, void *b); static hashval_t file_hash_hash (const void *p); static int file_hash_eq (const void *p, const void *q); @@ -290,9 +294,13 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) /* If the file is not included as first include from either the toplevel file or the command-line it is not a valid use of PCH. */ - if (pfile->all_files - && pfile->all_files->next_file) - return false; + for (_cpp_file *f = pfile->all_files; f; f = f->next_file) + if (f->implicit_preinclude) + continue; + else if (pfile->main_file == f) + break; + else + return false; flen = strlen (path); len = flen + sizeof (extension); @@ -341,13 +349,34 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) return valid; } +/* Canonicalize the path to FILE. Return the canonical form if it is + shorter, otherwise return NULL. This function does NOT free the + memory pointed by FILE. */ + +static char * +maybe_shorter_path (const char * file) +{ + char * file2 = lrealpath (file); + if (file2 && strlen (file2) < strlen (file)) + { + return file2; + } + else + { + free (file2); + return NULL; + } +} + /* Try to open the path FILE->name appended to FILE->dir. This is where remap and PCH intercept the file lookup process. Return true if the file was found, whether or not the open was successful. - Set *INVALID_PCH to true if a PCH file is found but wasn't valid. */ + Set *INVALID_PCH to true if a PCH file is found but wasn't valid. + Use LOC when emitting any diagnostics. */ static bool -find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) +find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch, + location_t loc) { char *path; @@ -361,10 +390,30 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) if (path) { - hashval_t hv = htab_hash_string (path); + hashval_t hv; char *copy; void **pp; + /* We try to canonicalize system headers. For DOS based file + * system, we always try to shorten non-system headers, as DOS + * has a tighter constraint on max path length. */ + if ((CPP_OPTION (pfile, canonical_system_headers) && file->dir->sysp) +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + || !file->dir->sysp +#endif + ) + { + char * canonical_path = maybe_shorter_path (path); + if (canonical_path) + { + /* The canonical path was newly allocated. Let's free the + non-canonical one. */ + free (path); + path = canonical_path; + } + } + + hv = htab_hash_string (path); if (htab_find_with_hash (pfile->nonexistent_file_hash, path, hv) != NULL) { file->err_no = ENOENT; @@ -380,7 +429,7 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) if (file->err_no != ENOENT) { - open_file_failed (pfile, file, 0); + open_file_failed (pfile, file, 0, loc); return true; } @@ -405,7 +454,7 @@ find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch) return false; } -/* Return tue iff the missing_header callback found the given HEADER. */ +/* Return true iff the missing_header callback found the given HEADER. */ static bool search_path_exhausted (cpp_reader *pfile, const char *header, _cpp_file *file) { @@ -447,12 +496,17 @@ _cpp_find_failed (_cpp_file *file) descriptor. FD can be -1 if the file was found in the cache and had previously been closed. To open it again pass the return value to open_file(). -*/ + + If KIND is _cpp_FFK_PRE_INCLUDE then it is OK for the file to be + missing. If present, it is OK for a precompiled header to be + included after it. + + Use LOC as the location for any errors. */ + _cpp_file * -_cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool fake, int angle_brackets) +_cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, + int angle_brackets, _cpp_find_file_kind kind, location_t loc) { - struct file_hash_entry *entry, **hash_slot; - _cpp_file *file; bool invalid_pch = false; bool saw_bracket_include = false; bool saw_quote_include = false; @@ -460,69 +514,103 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f /* Ensure we get no confusion between cached files and directories. */ if (start_dir == NULL) - cpp_error (pfile, CPP_DL_ICE, "NULL directory in find_file"); + cpp_error_at (pfile, CPP_DL_ICE, loc, "NULL directory in find_file"); - hash_slot = (struct file_hash_entry **) - htab_find_slot_with_hash (pfile->file_hash, fname, - htab_hash_string (fname), - INSERT); + void **hash_slot + = htab_find_slot_with_hash (pfile->file_hash, fname, + htab_hash_string (fname), INSERT); /* First check the cache before we resort to memory allocation. */ - entry = search_cache (*hash_slot, start_dir); + cpp_file_hash_entry *entry + = search_cache ((struct cpp_file_hash_entry *) *hash_slot, start_dir); if (entry) return entry->u.file; - file = make_cpp_file (pfile, start_dir, fname); - - /* Try each path in the include chain. */ - for (; !fake ;) - { - if (find_file_in_dir (pfile, file, &invalid_pch)) - break; + _cpp_file *file = make_cpp_file (start_dir, fname); + file->implicit_preinclude + = (kind == _cpp_FFK_PRE_INCLUDE + || (pfile->buffer && pfile->buffer->file->implicit_preinclude)); - file->dir = file->dir->next; - if (file->dir == NULL) - { - if (search_path_exhausted (pfile, fname, file)) - { - /* Although this file must not go in the cache, because - the file found might depend on things (like the current file) - that aren't represented in the cache, it still has to go in - the list of all files so that #import works. */ - file->next_file = pfile->all_files; - pfile->all_files = file; - return file; - } - - if (invalid_pch) - { - cpp_error (pfile, CPP_DL_ERROR, - "one or more PCH files were found, but they were invalid"); - if (!cpp_get_options (pfile)->warn_invalid_pch) - cpp_error (pfile, CPP_DL_ERROR, - "use -Winvalid-pch for more information"); - } - open_file_failed (pfile, file, angle_brackets); + if (kind != _cpp_FFK_FAKE) + /* Try each path in the include chain. */ + for (;;) + { + if (find_file_in_dir (pfile, file, &invalid_pch, loc)) break; - } - /* Only check the cache for the starting location (done above) - and the quote and bracket chain heads because there are no - other possible starting points for searches. */ - if (file->dir == pfile->bracket_include) - saw_bracket_include = true; - else if (file->dir == pfile->quote_include) - saw_quote_include = true; - else - continue; - - entry = search_cache (*hash_slot, file->dir); - if (entry) - { - found_in_cache = file->dir; - break; - } - } + 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; + if (*hash_slot == NULL) + { + /* If *hash_slot is NULL, the above + htab_find_slot_with_hash call just created the + slot, but we aren't going to store there anything + of use, so need to remove the newly created entry. + htab_clear_slot requires that it is non-NULL, so + store some non-NULL but valid pointer there, + htab_clear_slot will immediately overwrite it. */ + *hash_slot = file; + htab_clear_slot (pfile->file_hash, hash_slot); + } + return file; + } + + if (invalid_pch) + { + cpp_error (pfile, CPP_DL_ERROR, + "one or more PCH files were found," + " but they were invalid"); + if (!cpp_get_options (pfile)->warn_invalid_pch) + cpp_error (pfile, CPP_DL_NOTE, + "use -Winvalid-pch for more information"); + } + + if (kind == _cpp_FFK_PRE_INCLUDE) + { + free ((char *) file->name); + free (file); + if (*hash_slot == NULL) + { + /* See comment on the above htab_clear_slot call. */ + *hash_slot = &hash_slot; + htab_clear_slot (pfile->file_hash, hash_slot); + } + return NULL; + } + + if (kind != _cpp_FFK_HAS_INCLUDE) + open_file_failed (pfile, file, angle_brackets, loc); + break; + } + + /* Only check the cache for the starting location (done above) + and the quote and bracket chain heads because there are no + other possible starting points for searches. */ + if (file->dir == pfile->bracket_include) + saw_bracket_include = true; + else if (file->dir == pfile->quote_include) + saw_quote_include = true; + else + continue; + + entry + = search_cache ((struct cpp_file_hash_entry *) *hash_slot, file->dir); + if (entry) + { + found_in_cache = file->dir; + break; + } + } if (entry) { @@ -540,11 +628,11 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f /* Store this new result in the hash table. */ entry = new_file_hash_entry (pfile); - entry->next = *hash_slot; + entry->next = (struct cpp_file_hash_entry *) *hash_slot; entry->start_dir = start_dir; - entry->location = pfile->line_table->highest_location; + entry->location = loc; entry->u.file = file; - *hash_slot = entry; + *hash_slot = (void *) entry; /* If we passed the quote or bracket chain heads, cache them also. This speeds up processing if there are lots of -I options. */ @@ -553,22 +641,22 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f && found_in_cache != pfile->bracket_include) { entry = new_file_hash_entry (pfile); - entry->next = *hash_slot; + entry->next = (struct cpp_file_hash_entry *) *hash_slot; entry->start_dir = pfile->bracket_include; - entry->location = pfile->line_table->highest_location; + entry->location = loc; entry->u.file = file; - *hash_slot = entry; + *hash_slot = (void *) entry; } if (saw_quote_include && pfile->quote_include != start_dir && found_in_cache != pfile->quote_include) { entry = new_file_hash_entry (pfile); - entry->next = *hash_slot; + entry->next = (struct cpp_file_hash_entry *) *hash_slot; entry->start_dir = pfile->quote_include; - entry->location = pfile->line_table->highest_location; + entry->location = loc; entry->u.file = file; - *hash_slot = entry; + *hash_slot = (void *) entry; } return file; @@ -581,9 +669,14 @@ _cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool f except for plain files and block devices, since there is no reliable portable way of doing this. + Use LOC for any diagnostics. + + PFILE may be NULL. In this case, no diagnostics are issued. + FIXME: Flush file cache and try again if we run out of memory. */ static bool -read_file_guts (cpp_reader *pfile, _cpp_file *file) +read_file_guts (cpp_reader *pfile, _cpp_file *file, location_t loc, + const char *input_charset) { ssize_t size, total, count; uchar *buf; @@ -591,11 +684,13 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file) if (S_ISBLK (file->st.st_mode)) { - cpp_error (pfile, CPP_DL_ERROR, "%s is a block device", file->path); + if (pfile) + cpp_error_at (pfile, CPP_DL_ERROR, loc, + "%s is a block device", file->path); return false; } - regular = S_ISREG (file->st.st_mode); + regular = S_ISREG (file->st.st_mode) != 0; if (regular) { /* off_t might have a wider range than ssize_t - in other words, @@ -608,7 +703,9 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file) does not bite us. */ if (file->st.st_size > INTTYPE_MAXIMUM (ssize_t)) { - cpp_error (pfile, CPP_DL_ERROR, "%s is too large", file->path); + if (pfile) + cpp_error_at (pfile, CPP_DL_ERROR, loc, + "%s is too large", file->path); return false; } @@ -620,7 +717,11 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file) the majority of C source files. */ size = 8 * 1024; - buf = XNEWVEC (uchar, size + 1); + /* The + 16 here is space for the final '\n' and 15 bytes of padding, + used to quiet warnings from valgrind or Address Sanitizer, when the + optimized lexer accesses aligned 16-byte memory chunks, including + the bytes after the malloced, area, and stops lexing on '\n'. */ + buf = XNEWVEC (uchar, size + 16); total = 0; while ((count = read (file->fd, buf + total, size - total)) > 0) { @@ -631,35 +732,37 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file) if (regular) break; size *= 2; - buf = XRESIZEVEC (uchar, buf, size + 1); + buf = XRESIZEVEC (uchar, buf, size + 16); } } if (count < 0) { - cpp_errno (pfile, CPP_DL_ERROR, file->path); + if (pfile) + cpp_errno_filename (pfile, CPP_DL_ERROR, file->path, loc); + free (buf); return false; } - if (regular && total != size && STAT_SIZE_RELIABLE (file->st)) - cpp_error (pfile, CPP_DL_WARNING, + if (pfile && regular && total != size && STAT_SIZE_RELIABLE (file->st)) + cpp_error_at (pfile, CPP_DL_WARNING, loc, "%s is shorter than expected", file->path); file->buffer = _cpp_convert_input (pfile, - CPP_OPTION (pfile, input_charset), - buf, size, total, + input_charset, + buf, size + 16, total, &file->buffer_start, &file->st.st_size); - file->buffer_valid = true; - - return true; + file->buffer_valid = file->buffer; + return file->buffer_valid; } /* Convenience wrapper around read_file_guts that opens the file if necessary and closes the file descriptor after reading. FILE must - have been passed through find_file() at some stage. */ + have been passed through find_file() at some stage. Use LOC for + any diagnostics. Unlike read_file_guts(), PFILE may not be NULL. */ static bool -read_file (cpp_reader *pfile, _cpp_file *file) +read_file (cpp_reader *pfile, _cpp_file *file, location_t loc) { /* If we already have its contents in memory, succeed immediately. */ if (file->buffer_valid) @@ -671,27 +774,26 @@ read_file (cpp_reader *pfile, _cpp_file *file) if (file->fd == -1 && !open_file (file)) { - open_file_failed (pfile, file, 0); + open_file_failed (pfile, file, 0, loc); return false; } - file->dont_read = !read_file_guts (pfile, file); + file->dont_read = !read_file_guts (pfile, file, loc, + CPP_OPTION (pfile, input_charset)); close (file->fd); file->fd = -1; return !file->dont_read; } -/* Returns TRUE if FILE's contents have been successfully placed in - FILE->buffer and the file should be stacked, otherwise false. */ +/* Returns TRUE if FILE is already known to be idempotent, and should + therefore not be read again. */ static bool -should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) +is_known_idempotent_file (cpp_reader *pfile, _cpp_file *file, bool import) { - _cpp_file *f; - /* Skip once-only files. */ if (file->once_only) - return false; + return true; /* We must mark the file once-only if #import now, before header guard checks. Otherwise, undefining the header guard might @@ -702,13 +804,13 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) /* Don't stack files that have been stacked before. */ if (file->stack_count) - return false; + return true; } /* Skip if the file had a header guard and the macro is defined. PCH relies on this appearing before the PCH handler below. */ - if (file->cmacro && file->cmacro->type == NT_MACRO) - return false; + if (file->cmacro && cpp_macro_p (file->cmacro)) + return true; /* Handle PCH files immediately; don't stack them. */ if (file->pchname) @@ -717,12 +819,19 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) file->fd = -1; free ((void *) file->pchname); file->pchname = NULL; - return false; + return true; } - if (!read_file (pfile, file)) - return false; + return false; +} + +/* Return TRUE if file has unique contents, so we should read process + it. The file's contents must already have been read. */ +static bool +has_unique_contents (cpp_reader *pfile, _cpp_file *file, bool import, + location_t loc) +{ /* 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. */ @@ -743,10 +852,10 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) /* We may have read the file under a different name. Look for likely candidates and compare file contents to be sure. */ - for (f = pfile->all_files; f; f = f->next_file) + for (_cpp_file *f = pfile->all_files; f; f = f->next_file) { if (f == file) - continue; + continue; /* It'sa me! */ if ((import || f->once_only) && f->err_no == 0 @@ -754,25 +863,23 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) && f->st.st_size == file->st.st_size) { _cpp_file *ref_file; - bool same_file_p = false; if (f->buffer && !f->buffer_valid) { /* We already have a buffer but it is not valid, because the file is still stacked. Make a new one. */ - ref_file = make_cpp_file (pfile, f->dir, f->name); + ref_file = make_cpp_file (f->dir, f->name); ref_file->path = f->path; } else /* The file is not stacked anymore. We can reuse it. */ ref_file = f; - same_file_p = read_file (pfile, ref_file) - /* Size might have changed in read_file(). */ - && ref_file->st.st_size == file->st.st_size - && !memcmp (ref_file->buffer, - file->buffer, - file->st.st_size); + bool same_file_p = (read_file (pfile, ref_file, loc) + /* Size might have changed in read_file(). */ + && ref_file->st.st_size == file->st.st_size + && !memcmp (ref_file->buffer, file->buffer, + file->st.st_size)); if (f->buffer && !f->buffer_valid) { @@ -781,55 +888,128 @@ should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) } if (same_file_p) - break; + /* Already seen under a different name. */ + return false; } } - return f == NULL; + return true; } /* Place the file referenced by FILE into a new buffer on the buffer - stack if possible. IMPORT is true if this stacking attempt is - because of a #import directive. Returns true if a buffer is - stacked. */ + stack if possible. Returns true if a buffer is stacked. Use LOC + for any diagnostics. */ + bool -_cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import) +_cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type, + location_t loc) { - cpp_buffer *buffer; - int sysp; + if (is_known_idempotent_file (pfile, file, type == IT_IMPORT)) + return false; - if (!should_stack_file (pfile, file, import)) - return false; + int sysp = 0; + char *buf = nullptr; - if (pfile->buffer == NULL || file->dir == NULL) - sysp = 0; - else - sysp = MAX (pfile->buffer->sysp, file->dir->sysp); + /* Check C++ module include translation. */ + if (!file->header_unit && type < IT_HEADER_HWM + /* Do not include translate include-next. */ + && type != IT_INCLUDE_NEXT + && pfile->cb.translate_include) + buf = (pfile->cb.translate_include + (pfile, pfile->line_table, loc, file->path)); - /* Add the file to the dependencies on its first inclusion. */ - if (CPP_OPTION (pfile, deps.style) > !!sysp && !file->stack_count) + if (buf) { - if (!file->main_file || !CPP_OPTION (pfile, deps.ignore_main_file)) - deps_add_dep (pfile->deps, file->path); + /* We don't increment the line number at the end of a buffer, + because we don't usually need that location (we're popping an + include file). However in this case we do want to do the + increment. So push a writable buffer of two newlines to acheive + that. (We also need an extra newline, so this looks like a regular + file, which we do that to to make sure we don't fall off the end in the + middle of a line. */ + static uchar newlines[] = "\n\n\n"; + cpp_push_buffer (pfile, newlines, 2, true); + + size_t len = strlen (buf); + buf[len] = '\n'; /* See above */ + cpp_buffer *buffer + = cpp_push_buffer (pfile, reinterpret_cast<unsigned char *> (buf), + len, true); + buffer->to_free = buffer->buf; + + file->header_unit = +1; + _cpp_mark_file_once_only (pfile, file); } + else + { + /* Not a header unit, and we know it. */ + file->header_unit = -1; + + if (!read_file (pfile, file, loc)) + return false; - /* Clear buffer_valid since _cpp_clean_line messes it up. */ - file->buffer_valid = false; - file->stack_count++; + if (!has_unique_contents (pfile, file, type == IT_IMPORT, loc)) + return false; - /* Stack the buffer. */ - buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size, - CPP_OPTION (pfile, preprocessed) - && !CPP_OPTION (pfile, directives_only)); - buffer->file = file; - buffer->sysp = sysp; + if (pfile->buffer && file->dir) + sysp = MAX (pfile->buffer->sysp, file->dir->sysp); - /* Initialize controlling macro state. */ - pfile->mi_valid = true; - pfile->mi_cmacro = 0; + /* Add the file to the dependencies on its first inclusion. */ + if (CPP_OPTION (pfile, deps.style) > (sysp != 0) + && !file->stack_count + && file->path[0] + && !(pfile->main_file == file + && CPP_OPTION (pfile, deps.ignore_main_file))) + deps_add_dep (pfile->deps, file->path); - /* Generate the call back. */ - _cpp_do_file_change (pfile, LC_ENTER, file->path, 1, sysp); + /* Clear buffer_valid since _cpp_clean_line messes it up. */ + file->buffer_valid = false; + file->stack_count++; + + /* Stack the buffer. */ + cpp_buffer *buffer + = cpp_push_buffer (pfile, file->buffer, file->st.st_size, + CPP_OPTION (pfile, preprocessed) + && !CPP_OPTION (pfile, directives_only)); + buffer->file = file; + buffer->sysp = sysp; + buffer->to_free = file->buffer_start; + + /* Initialize controlling macro state. */ + pfile->mi_valid = true; + pfile->mi_cmacro = 0; + } + + /* In the case of a normal #include, we're now at the start of the + line *following* the #include. A separate location_t for this + location makes no sense, until we do the LC_LEAVE. + + This does not apply if we found a PCH file, we're not a regular + include, or we ran out of locations. */ + bool decrement = (file->pchname == NULL + && type < IT_DIRECTIVE_HWM + && (pfile->line_table->highest_location + != LINE_MAP_MAX_LOCATION - 1)); + if (decrement) + pfile->line_table->highest_location--; + + if (file->header_unit <= 0) + /* Add line map and do callbacks. */ + _cpp_do_file_change (pfile, LC_ENTER, file->path, + /* With preamble injection, start on line zero, + so the preamble doesn't appear to have been + included from line 1. Likewise when + starting preprocessed, we expect an initial + locating line. */ + type == IT_PRE_MAIN ? 0 : 1, sysp); + else if (decrement) + { + /* Adjust the line back one so we appear on the #include line itself. */ + const line_map_ordinary *map + = LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table); + linenum_type line = SOURCE_LINE (map, pfile->line_table->highest_line); + linemap_line_start (pfile->line_table, line - 1, 0); + } return true; } @@ -876,6 +1056,7 @@ search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets, return make_cpp_dir (pfile, dir_name_of_file (file), pfile->buffer ? pfile->buffer->sysp : 0); + assert(dir); if (dir == NULL) cpp_error (pfile, CPP_DL_ERROR, "no include path in which to search for %s", fname); @@ -907,34 +1088,118 @@ dir_name_of_file (_cpp_file *file) Returns true if a buffer was stacked. */ bool _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets, - enum include_type type) + enum include_type type, location_t loc) { - struct cpp_dir *dir; - _cpp_file *file; - - dir = search_path_head (pfile, fname, angle_brackets, type); + /* For -include command-line flags we have type == IT_CMDLINE. + When the first -include file is processed we have the case, where + pfile->cur_token == pfile->cur_run->base, we are directly called up + by the front end. However in the case of the second -include file, + we are called from _cpp_lex_token -> _cpp_get_fresh_line -> + cpp_push_include, with pfile->cur_token != pfile->cur_run->base, + and pfile->cur_token[-1].src_loc not (yet) initialized. + However, when the include file cannot be found, we need src_loc to + be initialized to some safe value: 0 means UNKNOWN_LOCATION. */ + if (type == IT_CMDLINE && pfile->cur_token != pfile->cur_run->base) + pfile->cur_token[-1].src_loc = 0; + + cpp_dir *dir = search_path_head (pfile, fname, angle_brackets, type); if (!dir) return false; - file = _cpp_find_file (pfile, fname, dir, false, angle_brackets); - - /* Compensate for the increment in linemap_add that occurs in - _cpp_stack_file. In the case of a normal #include, we're - currently at the start of the line *following* the #include. A - separate source_location for this location makes no sense (until - we do the LC_LEAVE), and complicates LAST_SOURCE_LINE_LOCATION. - This does not apply if we found a PCH file (in which case - linemap_add is not called) or we were included from the - command-line. */ - if (file->pchname == NULL && file->err_no == 0 && type != IT_CMDLINE) - pfile->line_table->highest_location--; + _cpp_file *file = _cpp_find_file (pfile, fname, dir, angle_brackets, + type == IT_DEFAULT ? _cpp_FFK_PRE_INCLUDE + : _cpp_FFK_NORMAL, loc); + if (type == IT_DEFAULT && file == NULL) + return false; + + return _cpp_stack_file (pfile, file, type, loc); +} + +/* NAME is a header file name, find the _cpp_file, if any. */ + +static _cpp_file * +test_header_unit (cpp_reader *pfile, const char *name, bool angle, + location_t loc) +{ + if (cpp_dir *dir = search_path_head (pfile, name, angle, IT_INCLUDE)) + return _cpp_find_file (pfile, name, dir, angle, _cpp_FFK_NORMAL, loc); + + return nullptr; +} + +/* NAME is a header file name, find the path we'll use to open it and infer that + it is a header-unit. */ + +const char * +_cpp_find_header_unit (cpp_reader *pfile, const char *name, bool angle, + location_t loc) +{ + if (_cpp_file *file = test_header_unit (pfile, name, angle, loc)) + { + if (file->fd > 0) + { + /* Don't leave it open. */ + close (file->fd); + file->fd = 0; + } + + file->header_unit = +1; + _cpp_mark_file_once_only (pfile, file); + + return file->path; + } + + return nullptr; +} + +/* NAME is a header file name, find the path we'll use to open it. But do not + infer it is a header unit. */ + +const char * +cpp_probe_header_unit (cpp_reader *pfile, const char *name, bool angle, + location_t loc) +{ + if (_cpp_file *file = test_header_unit (pfile, name, angle, loc)) + return file->path; - return _cpp_stack_file (pfile, file, type == IT_IMPORT); + return nullptr; +} + +/* Retrofit the just-entered main file asif it was an include. This + will permit correct include_next use, and mark it as a system + header if that's where it resides. We use filesystem-appropriate + prefix matching of the include path to locate the main file. */ +void +cpp_retrofit_as_include (cpp_reader *pfile) +{ + /* We should be the outermost. */ + gcc_assert (!pfile->buffer->prev); + + if (const char *name = pfile->main_file->name) + { + /* Locate name on the include dir path, using a prefix match. */ + size_t name_len = strlen (name); + for (cpp_dir *dir = pfile->quote_include; dir; dir = dir->next) + if (dir->len < name_len + && IS_DIR_SEPARATOR (name[dir->len]) + && !filename_ncmp (name, dir->name, dir->len)) + { + pfile->main_file->dir = dir; + if (dir->sysp) + cpp_make_system_header (pfile, 1, 0); + break; + } + } + + /* Initialize controlling macro state. */ + pfile->mi_valid = true; + pfile->mi_cmacro = 0; } /* Could not open FILE. The complication is dependency output. */ static void -open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets) +open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets, + location_t loc) { 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); @@ -946,7 +1211,9 @@ open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets) /* If the preprocessor output (other than dependency information) is being used, we must also flag an error. */ if (CPP_OPTION (pfile, deps.need_preprocessor_output)) - cpp_errno (pfile, CPP_DL_FATAL, file->path); + cpp_errno_filename (pfile, CPP_DL_FATAL, + file->path ? file->path : file->name, + loc); } else { @@ -960,16 +1227,20 @@ open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets) if (CPP_OPTION (pfile, deps.style) == DEPS_NONE || print_dep || CPP_OPTION (pfile, deps.need_preprocessor_output)) - cpp_errno (pfile, CPP_DL_FATAL, file->path); + cpp_errno_filename (pfile, CPP_DL_FATAL, + file->path ? file->path : file->name, + loc); else - cpp_errno (pfile, CPP_DL_WARNING, file->path); + cpp_errno_filename (pfile, CPP_DL_WARNING, + file->path ? file->path : file->name, + loc); } } /* Search in the chain beginning at HEAD for a file whose search path started at START_DIR != NULL. */ -static struct file_hash_entry * -search_cache (struct file_hash_entry *head, const cpp_dir *start_dir) +static struct cpp_file_hash_entry * +search_cache (struct cpp_file_hash_entry *head, const cpp_dir *start_dir) { while (head && head->start_dir != start_dir) head = head->next; @@ -979,12 +1250,9 @@ search_cache (struct file_hash_entry *head, const cpp_dir *start_dir) /* Allocate a new _cpp_file structure. */ static _cpp_file * -make_cpp_file (cpp_reader *pfile, cpp_dir *dir, const char *fname) +make_cpp_file (cpp_dir *dir, const char *fname) { - _cpp_file *file; - - file = XCNEW (_cpp_file); - file->main_file = !pfile->buffer; + _cpp_file *file = XCNEW (_cpp_file); file->fd = -1; file->dir = dir; file->name = xstrdup (fname); @@ -996,9 +1264,9 @@ make_cpp_file (cpp_reader *pfile, cpp_dir *dir, const char *fname) static void destroy_cpp_file (_cpp_file *file) { - if (file->buffer_start) - free ((void *) file->buffer_start); + free ((void *) file->buffer_start); free ((void *) file->name); + free ((void *) file->path); free (file); } @@ -1025,10 +1293,10 @@ destroy_all_cpp_files (cpp_reader *pfile) static cpp_dir * make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp) { - struct file_hash_entry *entry, **hash_slot; + struct cpp_file_hash_entry *entry, **hash_slot; cpp_dir *dir; - hash_slot = (struct file_hash_entry **) + hash_slot = (struct cpp_file_hash_entry **) htab_find_slot_with_hash (pfile->dir_hash, dir_name, htab_hash_string (dir_name), INSERT); @@ -1067,7 +1335,7 @@ allocate_file_hash_entries (cpp_reader *pfile) } /* Return a new file hash entry. */ -static struct file_hash_entry * +static struct cpp_file_hash_entry * new_file_hash_entry (cpp_reader *pfile) { unsigned int idx; @@ -1097,9 +1365,9 @@ free_file_hash_entries (cpp_reader *pfile) bool cpp_included (cpp_reader *pfile, const char *fname) { - struct file_hash_entry *entry; + struct cpp_file_hash_entry *entry; - entry = (struct file_hash_entry *) + entry = (struct cpp_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)) @@ -1113,12 +1381,14 @@ cpp_included (cpp_reader *pfile, const char *fname) filenames aliased by links or redundant . or .. traversals etc. */ bool cpp_included_before (cpp_reader *pfile, const char *fname, - source_location location) + location_t location) { - struct file_hash_entry *entry; + struct cpp_file_hash_entry *entry + = (struct cpp_file_hash_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)); + if (IS_ADHOC_LOC (location)) + location = get_location_from_adhoc_loc (pfile->line_table, location); while (entry && (entry->start_dir == NULL || entry->u.file->err_no || entry->location > location)) @@ -1132,7 +1402,7 @@ cpp_included_before (cpp_reader *pfile, const char *fname, static hashval_t file_hash_hash (const void *p) { - struct file_hash_entry *entry = (struct file_hash_entry *) p; + struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) p; const char *hname; if (entry->start_dir) hname = entry->u.file->name; @@ -1146,7 +1416,7 @@ file_hash_hash (const void *p) static int file_hash_eq (const void *p, const void *q) { - struct file_hash_entry *entry = (struct file_hash_entry *) p; + struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) p; const char *fname = (const char *) q; const char *hname; @@ -1155,7 +1425,7 @@ file_hash_eq (const void *p, const void *q) else hname = entry->u.dir->name; - return strcmp (hname, fname) == 0; + return filename_cmp (hname, fname) == 0; } /* Compare entries in the nonexistent file hash table. These are just @@ -1163,7 +1433,7 @@ file_hash_eq (const void *p, const void *q) static int nonexistent_file_hash_eq (const void *p, const void *q) { - return strcmp ((const char *) p, (const char *) q) == 0; + return filename_cmp ((const char *) p, (const char *) q) == 0; } /* Initialize everything in this source file. */ @@ -1178,9 +1448,8 @@ _cpp_init_files (cpp_reader *pfile) pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string, nonexistent_file_hash_eq, NULL, xcalloc, free); - _obstack_begin (&pfile->nonexistent_file_ob, 0, 0, - (void *(*) (size_t)) xmalloc, - (void (*) (void *)) free); + obstack_specify_allocation (&pfile->nonexistent_file_ob, 0, 0, + xmalloc, free); } /* Finalize everything in this source file. */ @@ -1210,7 +1479,7 @@ cpp_clear_file_cache (cpp_reader *pfile) void _cpp_fake_include (cpp_reader *pfile, const char *fname) { - _cpp_find_file (pfile, fname, pfile->buffer->file->dir, true, 0); + _cpp_find_file (pfile, fname, pfile->buffer->file->dir, 0, _cpp_FFK_FAKE, 0); } /* Not everyone who wants to set system-header-ness on a buffer can @@ -1220,15 +1489,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]; - + const class line_maps *line_table = pfile->line_table; + const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (line_table); /* 1 = system header, 2 = system header to be treated as C. */ if (syshdr) flags = 1 + (externc != 0); pfile->buffer->sysp = flags; - _cpp_do_file_change (pfile, LC_RENAME, map->to_file, - SOURCE_LINE (map, pfile->line_table->highest_line), flags); + _cpp_do_file_change (pfile, LC_RENAME, ORDINARY_MAP_FILE_NAME (map), + SOURCE_LINE (map, pfile->line_table->highest_line), + flags); } /* Allow the client to change the current file. Used by the front end @@ -1243,6 +1512,7 @@ cpp_change_file (cpp_reader *pfile, enum lc_reason reason, struct report_missing_guard_data { + cpp_reader *pfile; const char **paths; size_t count; }; @@ -1251,7 +1521,7 @@ struct report_missing_guard_data static int report_missing_guard (void **slot, void *d) { - struct file_hash_entry *entry = (struct file_hash_entry *) *slot; + struct cpp_file_hash_entry *entry = (struct cpp_file_hash_entry *) *slot; struct report_missing_guard_data *data = (struct report_missing_guard_data *) d; @@ -1261,8 +1531,10 @@ report_missing_guard (void **slot, void *d) _cpp_file *file = entry->u.file; /* We don't want MI guard advice for the main file. */ - if (!file->once_only && file->cmacro == NULL - && file->stack_count == 1 && !file->main_file) + if (!file->once_only + && file->cmacro == NULL + && file->stack_count == 1 + && data->pfile->main_file != file) { if (data->paths == NULL) { @@ -1292,6 +1564,7 @@ _cpp_report_missing_guards (cpp_reader *pfile) { struct report_missing_guard_data data; + data.pfile = pfile; data.paths = NULL; data.count = htab_elements (pfile->file_hash); htab_traverse (pfile->file_hash, report_missing_guard, &data); @@ -1329,7 +1602,7 @@ _cpp_compare_file_date (cpp_reader *pfile, const char *fname, if (!dir) return -1; - file = _cpp_find_file (pfile, fname, dir, false, angle_brackets); + file = _cpp_find_file (pfile, fname, dir, angle_brackets, _cpp_FFK_NORMAL, 0); if (file->err_no) return -1; @@ -1347,13 +1620,25 @@ _cpp_compare_file_date (cpp_reader *pfile, const char *fname, bool cpp_push_include (cpp_reader *pfile, const char *fname) { - return _cpp_stack_include (pfile, fname, false, IT_CMDLINE); + return _cpp_stack_include (pfile, fname, false, IT_CMDLINE, + pfile->line_table->highest_line); +} + +/* Pushes the given file, implicitly included at the start of a + compilation, onto the buffer stack but without any errors if the + file is not found. Returns nonzero if successful. */ +bool +cpp_push_default_include (cpp_reader *pfile, const char *fname) +{ + return _cpp_stack_include (pfile, fname, true, IT_DEFAULT, + pfile->line_table->highest_line); } /* Do appropriate cleanup when a file INC's buffer is popped off the input stack. */ void -_cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file) +_cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file, + const unsigned char *to_free) { /* Record the inclusion-preventing macro, which could be NULL meaning no controlling macro. */ @@ -1363,15 +1648,25 @@ _cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file) /* Invalidate control macros in the #including file. */ pfile->mi_valid = false; - if (file->buffer_start) + if (to_free) { - free ((void *) file->buffer_start); - file->buffer_start = NULL; - file->buffer = NULL; - file->buffer_valid = false; + if (to_free == file->buffer_start) + { + file->buffer_start = NULL; + file->buffer = NULL; + file->buffer_valid = false; + } + free ((void *) to_free); } } +/* Return the file name associated with FILE. */ +const char * +_cpp_get_file_name (_cpp_file *file) +{ + return file->name; +} + /* Inteface to file statistics record in _cpp_file structure. */ struct stat * _cpp_get_file_stat (_cpp_file *file) @@ -1413,7 +1708,7 @@ append_file_to_dir (const char *fname, cpp_dir *dir) flen = strlen (fname); path = XNEWVEC (char, dlen + 1 + flen + 1); memcpy (path, dir->name, dlen); - if (dlen && path[dlen - 1] != '/') + if (dlen && !IS_DIR_SEPARATOR (path[dlen - 1])) path[dlen++] = '/'; memcpy (&path[dlen], fname, flen + 1); @@ -1461,7 +1756,7 @@ read_name_map (cpp_dir *dir) len = dir->len; name = (char *) alloca (len + sizeof (FILE_NAME_MAP_FILE) + 1); memcpy (name, dir->name, len); - if (len && name[len - 1] != '/') + if (len && !IS_DIR_SEPARATOR (name[len - 1])) name[len++] = '/'; strcpy (name + len, FILE_NAME_MAP_FILE); f = fopen (name, "r"); @@ -1519,7 +1814,7 @@ static char * remap_filename (cpp_reader *pfile, _cpp_file *file) { const char *fname, *p; - char *new_dir; + char *new_dir, *p3; cpp_dir *dir; size_t index, len; @@ -1532,17 +1827,31 @@ remap_filename (cpp_reader *pfile, _cpp_file *file) read_name_map (dir); for (index = 0; dir->name_map[index]; index += 2) - if (!strcmp (dir->name_map[index], fname)) + if (!filename_cmp (dir->name_map[index], fname)) return xstrdup (dir->name_map[index + 1]); - + if (IS_ABSOLUTE_PATH (fname)) + return NULL; p = strchr (fname, '/'); +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + { + const char *p2 = strchr (fname, '\\'); + if (!p || (p > p2)) + p = p2; + } +#endif if (!p || p == fname) return NULL; len = dir->len + (p - fname + 1); - new_dir = XNEWVEC (char, len + 1); + new_dir = XNEWVEC (char, len + 2); + p3 = new_dir + dir->len; memcpy (new_dir, dir->name, dir->len); - memcpy (new_dir + dir->len, fname, p - fname + 1); + if (dir->len && !IS_DIR_SEPARATOR (dir->name[dir->len - 1])) + { + *p3++ = '/'; + len++; + } + memcpy (p3, fname, p - fname + 1); new_dir[len] = '\0'; dir = make_cpp_dir (pfile, new_dir, dir->sysp); @@ -1674,6 +1983,7 @@ _cpp_save_file_entries (cpp_reader *pfile, FILE *fp) struct pchf_data *result; size_t result_size; _cpp_file *f; + bool ret; for (f = pfile->all_files; f; f = f->next_file) ++count; @@ -1712,7 +2022,8 @@ _cpp_save_file_entries (cpp_reader *pfile, FILE *fp) if (!open_file (f)) { - open_file_failed (pfile, f, 0); + open_file_failed (pfile, f, 0, 0); + free (result); return false; } ff = fdopen (f->fd, "rb"); @@ -1729,7 +2040,9 @@ _cpp_save_file_entries (cpp_reader *pfile, FILE *fp) qsort (result->entries, result->count, sizeof (struct pchf_entry), pchf_save_compare); - return fwrite (result, result_size, 1, fp) == 1; + ret = fwrite (result, result_size, 1, fp) == 1; + free (result); + return ret; } /* Read the pchf_data structure from F. */ @@ -1825,3 +2138,39 @@ check_file_against_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, return bsearch (&d, pchf->entries, pchf->count, sizeof (struct pchf_entry), pchf_compare) != NULL; } + +/* Return true if the file FNAME is found in the appropriate include file path + as indicated by ANGLE_BRACKETS. */ + +bool +_cpp_has_header (cpp_reader *pfile, const char *fname, int angle_brackets, + enum include_type type) +{ + cpp_dir *start_dir = search_path_head (pfile, fname, angle_brackets, type); + _cpp_file *file = _cpp_find_file (pfile, fname, start_dir, angle_brackets, + _cpp_FFK_HAS_INCLUDE, 0); + return file->err_no != ENOENT; +} + +/* Read a file and convert to input charset, the same as if it were being read + by a cpp_reader. */ + +cpp_converted_source +cpp_get_converted_source (const char *fname, const char *input_charset) +{ + cpp_converted_source res = {}; + _cpp_file file = {}; + file.fd = -1; + file.name = lbasename (fname); + file.path = fname; + if (!open_file (&file)) + return res; + const bool ok = read_file_guts (NULL, &file, 0, input_charset); + close (file.fd); + if (!ok) + return res; + res.to_free = (char *) file.buffer_start; + res.data = (char *) file.buffer; + res.len = file.st.st_size; + return res; +} diff --git a/support/cpp/libcpp/generated_cpp_wcwidth.h b/support/cpp/libcpp/generated_cpp_wcwidth.h new file mode 100644 index 000000000..abe1be30d --- /dev/null +++ b/support/cpp/libcpp/generated_cpp_wcwidth.h @@ -0,0 +1,162 @@ +/* Generated by contrib/unicode/gen_wcwidth.py, with the help of glibc's + utf8_gen.py, using version 13.0.0 of the Unicode standard. */ + +static const cppchar_t wcwidth_range_ends[] = { + 0x2ff, 0x36f, 0x482, 0x489, 0x590, 0x5bd, 0x5be, 0x5bf, + 0x5c0, 0x5c2, 0x5c3, 0x5c5, 0x5c6, 0x5c7, 0x60f, 0x61a, + 0x61b, 0x61c, 0x64a, 0x65f, 0x66f, 0x670, 0x6d5, 0x6dc, + 0x6de, 0x6e4, 0x6e6, 0x6e8, 0x6e9, 0x6ed, 0x710, 0x711, + 0x72f, 0x74a, 0x7a5, 0x7b0, 0x7ea, 0x7f3, 0x7fc, 0x7fd, + 0x815, 0x819, 0x81a, 0x823, 0x824, 0x827, 0x828, 0x82d, + 0x858, 0x85b, 0x8d2, 0x8e1, 0x8e2, 0x902, 0x939, 0x93a, + 0x93b, 0x93c, 0x940, 0x948, 0x94c, 0x94d, 0x950, 0x957, + 0x961, 0x963, 0x980, 0x981, 0x9bb, 0x9bc, 0x9c0, 0x9c4, + 0x9cc, 0x9cd, 0x9e1, 0x9e3, 0x9fd, 0x9fe, 0xa00, 0xa02, + 0xa3b, 0xa3c, 0xa40, 0xa42, 0xa46, 0xa48, 0xa4a, 0xa4d, + 0xa50, 0xa51, 0xa6f, 0xa71, 0xa74, 0xa75, 0xa80, 0xa82, + 0xabb, 0xabc, 0xac0, 0xac5, 0xac6, 0xac8, 0xacc, 0xacd, + 0xae1, 0xae3, 0xaf9, 0xaff, 0xb00, 0xb01, 0xb3b, 0xb3c, + 0xb3e, 0xb3f, 0xb40, 0xb44, 0xb4c, 0xb4d, 0xb54, 0xb56, + 0xb61, 0xb63, 0xb81, 0xb82, 0xbbf, 0xbc0, 0xbcc, 0xbcd, + 0xbff, 0xc00, 0xc03, 0xc04, 0xc3d, 0xc40, 0xc45, 0xc48, + 0xc49, 0xc4d, 0xc54, 0xc56, 0xc61, 0xc63, 0xc80, 0xc81, + 0xcbb, 0xcbc, 0xcbe, 0xcbf, 0xcc5, 0xcc6, 0xccb, 0xccd, + 0xce1, 0xce3, 0xcff, 0xd01, 0xd3a, 0xd3c, 0xd40, 0xd44, + 0xd4c, 0xd4d, 0xd61, 0xd63, 0xd80, 0xd81, 0xdc9, 0xdca, + 0xdd1, 0xdd4, 0xdd5, 0xdd6, 0xe30, 0xe31, 0xe33, 0xe3a, + 0xe46, 0xe4e, 0xeb0, 0xeb1, 0xeb3, 0xebc, 0xec7, 0xecd, + 0xf17, 0xf19, 0xf34, 0xf35, 0xf36, 0xf37, 0xf38, 0xf39, + 0xf70, 0xf7e, 0xf7f, 0xf84, 0xf85, 0xf87, 0xf8c, 0xf97, + 0xf98, 0xfbc, 0xfc5, 0xfc6, 0x102c, 0x1030, 0x1031, 0x1037, + 0x1038, 0x103a, 0x103c, 0x103e, 0x1057, 0x1059, 0x105d, 0x1060, + 0x1070, 0x1074, 0x1081, 0x1082, 0x1084, 0x1086, 0x108c, 0x108d, + 0x109c, 0x109d, 0x10ff, 0x115f, 0x11ff, 0x135c, 0x135f, 0x1711, + 0x1714, 0x1731, 0x1734, 0x1751, 0x1753, 0x1771, 0x1773, 0x17b3, + 0x17b5, 0x17b6, 0x17bd, 0x17c5, 0x17c6, 0x17c8, 0x17d3, 0x17dc, + 0x17dd, 0x180a, 0x180e, 0x1884, 0x1886, 0x18a8, 0x18a9, 0x191f, + 0x1922, 0x1926, 0x1928, 0x1931, 0x1932, 0x1938, 0x193b, 0x1a16, + 0x1a18, 0x1a1a, 0x1a1b, 0x1a55, 0x1a56, 0x1a57, 0x1a5e, 0x1a5f, + 0x1a60, 0x1a61, 0x1a62, 0x1a64, 0x1a6c, 0x1a72, 0x1a7c, 0x1a7e, + 0x1a7f, 0x1aaf, 0x1ac0, 0x1aff, 0x1b03, 0x1b33, 0x1b34, 0x1b35, + 0x1b3a, 0x1b3b, 0x1b3c, 0x1b41, 0x1b42, 0x1b6a, 0x1b73, 0x1b7f, + 0x1b81, 0x1ba1, 0x1ba5, 0x1ba7, 0x1ba9, 0x1baa, 0x1bad, 0x1be5, + 0x1be6, 0x1be7, 0x1be9, 0x1bec, 0x1bed, 0x1bee, 0x1bf1, 0x1c2b, + 0x1c33, 0x1c35, 0x1c37, 0x1ccf, 0x1cd2, 0x1cd3, 0x1ce0, 0x1ce1, + 0x1ce8, 0x1cec, 0x1ced, 0x1cf3, 0x1cf4, 0x1cf7, 0x1cf9, 0x1dbf, + 0x1df9, 0x1dfa, 0x1dff, 0x200a, 0x200f, 0x2029, 0x202e, 0x205f, + 0x2064, 0x2065, 0x206f, 0x20cf, 0x20f0, 0x2319, 0x231b, 0x2328, + 0x232a, 0x23e8, 0x23ec, 0x23ef, 0x23f0, 0x23f2, 0x23f3, 0x25fc, + 0x25fe, 0x2613, 0x2615, 0x2647, 0x2653, 0x267e, 0x267f, 0x2692, + 0x2693, 0x26a0, 0x26a1, 0x26a9, 0x26ab, 0x26bc, 0x26be, 0x26c3, + 0x26c5, 0x26cd, 0x26ce, 0x26d3, 0x26d4, 0x26e9, 0x26ea, 0x26f1, + 0x26f3, 0x26f4, 0x26f5, 0x26f9, 0x26fa, 0x26fc, 0x26fd, 0x2704, + 0x2705, 0x2709, 0x270b, 0x2727, 0x2728, 0x274b, 0x274c, 0x274d, + 0x274e, 0x2752, 0x2755, 0x2756, 0x2757, 0x2794, 0x2797, 0x27af, + 0x27b0, 0x27be, 0x27bf, 0x2b1a, 0x2b1c, 0x2b4f, 0x2b50, 0x2b54, + 0x2b55, 0x2cee, 0x2cf1, 0x2d7e, 0x2d7f, 0x2ddf, 0x2dff, 0x2e7f, + 0x2e99, 0x2e9a, 0x2ef3, 0x2eff, 0x2fd5, 0x2fef, 0x2ffb, 0x2fff, + 0x3029, 0x302d, 0x303e, 0x3040, 0x3096, 0x3098, 0x309a, 0x30ff, + 0x3104, 0x312f, 0x3130, 0x318e, 0x318f, 0x31e3, 0x31ef, 0x321e, + 0x321f, 0x9ffc, 0x9fff, 0xa48c, 0xa48f, 0xa4c6, 0xa66e, 0xa672, + 0xa673, 0xa67d, 0xa69d, 0xa69f, 0xa6ef, 0xa6f1, 0xa801, 0xa802, + 0xa805, 0xa806, 0xa80a, 0xa80b, 0xa824, 0xa826, 0xa82b, 0xa82c, + 0xa8c3, 0xa8c5, 0xa8df, 0xa8f1, 0xa8fe, 0xa8ff, 0xa925, 0xa92d, + 0xa946, 0xa951, 0xa95f, 0xa97c, 0xa97f, 0xa982, 0xa9b2, 0xa9b3, + 0xa9b5, 0xa9b9, 0xa9bb, 0xa9bd, 0xa9e4, 0xa9e5, 0xaa28, 0xaa2e, + 0xaa30, 0xaa32, 0xaa34, 0xaa36, 0xaa42, 0xaa43, 0xaa4b, 0xaa4c, + 0xaa7b, 0xaa7c, 0xaaaf, 0xaab0, 0xaab1, 0xaab4, 0xaab6, 0xaab8, + 0xaabd, 0xaabf, 0xaac0, 0xaac1, 0xaaeb, 0xaaed, 0xaaf5, 0xaaf6, + 0xabe4, 0xabe5, 0xabe7, 0xabe8, 0xabec, 0xabed, 0xabff, 0xd7a3, + 0xd7af, 0xd7c6, 0xd7ca, 0xd7fb, 0xf8ff, 0xfa6d, 0xfa6f, 0xfad9, + 0xfb1d, 0xfb1e, 0xfdff, 0xfe0f, 0xfe19, 0xfe1f, 0xfe2f, 0xfe52, + 0xfe53, 0xfe66, 0xfe67, 0xfe6b, 0xfefe, 0xfeff, 0xff00, 0xff60, + 0xffdf, 0xffe6, 0xfff8, 0xfffb, 0x101fc, 0x101fd, 0x102df, 0x102e0, + 0x10375, 0x1037a, 0x10a00, 0x10a03, 0x10a04, 0x10a06, 0x10a0b, 0x10a0f, + 0x10a37, 0x10a3a, 0x10a3e, 0x10a3f, 0x10ae4, 0x10ae6, 0x10d23, 0x10d27, + 0x10eaa, 0x10eac, 0x10f45, 0x10f50, 0x11000, 0x11001, 0x11037, 0x11046, + 0x1107e, 0x11081, 0x110b2, 0x110b6, 0x110b8, 0x110ba, 0x110ff, 0x11102, + 0x11126, 0x1112b, 0x1112c, 0x11134, 0x11172, 0x11173, 0x1117f, 0x11181, + 0x111b5, 0x111be, 0x111c8, 0x111cc, 0x111ce, 0x111cf, 0x1122e, 0x11231, + 0x11233, 0x11234, 0x11235, 0x11237, 0x1123d, 0x1123e, 0x112de, 0x112df, + 0x112e2, 0x112ea, 0x112ff, 0x11301, 0x1133a, 0x1133c, 0x1133f, 0x11340, + 0x11365, 0x1136c, 0x1136f, 0x11374, 0x11437, 0x1143f, 0x11441, 0x11444, + 0x11445, 0x11446, 0x1145d, 0x1145e, 0x114b2, 0x114b8, 0x114b9, 0x114ba, + 0x114be, 0x114c0, 0x114c1, 0x114c3, 0x115b1, 0x115b5, 0x115bb, 0x115bd, + 0x115be, 0x115c0, 0x115db, 0x115dd, 0x11632, 0x1163a, 0x1163c, 0x1163d, + 0x1163e, 0x11640, 0x116aa, 0x116ab, 0x116ac, 0x116ad, 0x116af, 0x116b5, + 0x116b6, 0x116b7, 0x1171c, 0x1171f, 0x11721, 0x11725, 0x11726, 0x1172b, + 0x1182e, 0x11837, 0x11838, 0x1183a, 0x1193a, 0x1193c, 0x1193d, 0x1193e, + 0x11942, 0x11943, 0x119d3, 0x119d7, 0x119d9, 0x119db, 0x119df, 0x119e0, + 0x11a00, 0x11a0a, 0x11a32, 0x11a38, 0x11a3a, 0x11a3e, 0x11a46, 0x11a47, + 0x11a50, 0x11a56, 0x11a58, 0x11a5b, 0x11a89, 0x11a96, 0x11a97, 0x11a99, + 0x11c2f, 0x11c36, 0x11c37, 0x11c3d, 0x11c3e, 0x11c3f, 0x11c91, 0x11ca7, + 0x11ca9, 0x11cb0, 0x11cb1, 0x11cb3, 0x11cb4, 0x11cb6, 0x11d30, 0x11d36, + 0x11d39, 0x11d3a, 0x11d3b, 0x11d3d, 0x11d3e, 0x11d45, 0x11d46, 0x11d47, + 0x11d8f, 0x11d91, 0x11d94, 0x11d95, 0x11d96, 0x11d97, 0x11ef2, 0x11ef4, + 0x1342f, 0x13438, 0x16aef, 0x16af4, 0x16b2f, 0x16b36, 0x16f4e, 0x16f4f, + 0x16f8e, 0x16f92, 0x16fdf, 0x16fe3, 0x16fe4, 0x16fef, 0x16ff1, 0x16fff, + 0x187f7, 0x187ff, 0x18cd5, 0x18cff, 0x18d08, 0x1afff, 0x1b11e, 0x1b14f, + 0x1b152, 0x1b163, 0x1b167, 0x1b16f, 0x1b2fb, 0x1bc9c, 0x1bc9e, 0x1bc9f, + 0x1bca3, 0x1d166, 0x1d169, 0x1d172, 0x1d182, 0x1d184, 0x1d18b, 0x1d1a9, + 0x1d1ad, 0x1d241, 0x1d244, 0x1d9ff, 0x1da36, 0x1da3a, 0x1da6c, 0x1da74, + 0x1da75, 0x1da83, 0x1da84, 0x1da9a, 0x1da9f, 0x1daa0, 0x1daaf, 0x1dfff, + 0x1e006, 0x1e007, 0x1e018, 0x1e01a, 0x1e021, 0x1e022, 0x1e024, 0x1e025, + 0x1e02a, 0x1e12f, 0x1e136, 0x1e2eb, 0x1e2ef, 0x1e8cf, 0x1e8d6, 0x1e943, + 0x1e94a, 0x1f003, 0x1f004, 0x1f0ce, 0x1f0cf, 0x1f18d, 0x1f18e, 0x1f190, + 0x1f19a, 0x1f1ff, 0x1f202, 0x1f20f, 0x1f23b, 0x1f23f, 0x1f248, 0x1f24f, + 0x1f251, 0x1f25f, 0x1f265, 0x1f2ff, 0x1f320, 0x1f32c, 0x1f335, 0x1f336, + 0x1f37c, 0x1f37d, 0x1f393, 0x1f39f, 0x1f3ca, 0x1f3ce, 0x1f3d3, 0x1f3df, + 0x1f3f0, 0x1f3f3, 0x1f3f4, 0x1f3f7, 0x1f43e, 0x1f43f, 0x1f440, 0x1f441, + 0x1f4fc, 0x1f4fe, 0x1f53d, 0x1f54a, 0x1f54e, 0x1f54f, 0x1f567, 0x1f579, + 0x1f57a, 0x1f594, 0x1f596, 0x1f5a3, 0x1f5a4, 0x1f5fa, 0x1f64f, 0x1f67f, + 0x1f6c5, 0x1f6cb, 0x1f6cc, 0x1f6cf, 0x1f6d2, 0x1f6d4, 0x1f6d7, 0x1f6ea, + 0x1f6ec, 0x1f6f3, 0x1f6fc, 0x1f7df, 0x1f7eb, 0x1f90b, 0x1f93a, 0x1f93b, + 0x1f945, 0x1f946, 0x1f978, 0x1f979, 0x1f9cb, 0x1f9cc, 0x1f9ff, 0x1fa6f, + 0x1fa74, 0x1fa77, 0x1fa7a, 0x1fa7f, 0x1fa86, 0x1fa8f, 0x1faa8, 0x1faaf, + 0x1fab6, 0x1fabf, 0x1fac2, 0x1facf, 0x1fad6, 0x1ffff, 0x2a6dd, 0x2a6ff, + 0x2b734, 0x2b73f, 0x2b81d, 0x2b81f, 0x2cea1, 0x2ceaf, 0x2ebe0, 0x2f7ff, + 0x2fa1d, 0x2ffff, 0x3134a, 0xe0000, 0xe0001, 0xe001f, 0xe007f, 0xe00ff, + 0xe01ef, +}; + +static const unsigned char wcwidth_widths[] = { + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 0, 2, 1, 2, 1, 0, 2, + 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 1, 0, 1, 0, 1, 2, 1, 2, + 1, 0, 1, 0, 2, 1, 0, 2, 1, 2, 1, 2, 1, 0, 1, 2, 1, 2, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 0, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, + 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 0, 1, 0, 1, + 0, +}; diff --git a/support/cpp/libcpp/identifiers.c b/support/cpp/libcpp/identifiers.cc index 67378df97..89a0490a0 100644 --- a/support/cpp/libcpp/identifiers.c +++ b/support/cpp/libcpp/identifiers.cc @@ -1,6 +1,5 @@ /* Hash tables for the CPP library. - Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998, - 1999, 2000, 2001, 2002, 2007, 2009 Free Software Foundation, Inc. + Copyright (C) 1986-2022 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 @@ -28,12 +27,12 @@ along with this program; see the file COPYING3. If not see #include "cpplib.h" #include "internal.h" -static hashnode alloc_node (hash_table *); +static hashnode alloc_node (cpp_hash_table *); /* Return an identifier node for hashtable.c. Used by cpplib except when integrated with the C front ends. */ static hashnode -alloc_node (hash_table *table) +alloc_node (cpp_hash_table *table) { cpp_hashnode *node; @@ -45,7 +44,7 @@ alloc_node (hash_table *table) /* Set up the identifier hash table. Use TABLE if non-null, otherwise create our own. */ void -_cpp_init_hashtable (cpp_reader *pfile, hash_table *table) +_cpp_init_hashtable (cpp_reader *pfile, cpp_hash_table *table) { struct spec_nodes *s; @@ -55,9 +54,7 @@ _cpp_init_hashtable (cpp_reader *pfile, hash_table *table) table = ht_create (13); /* 8K (=2^13) entries. */ table->alloc_node = alloc_node; - _obstack_begin (&pfile->hash_ob, 0, 0, - (void *(*) (size_t)) xmalloc, - (void (*) (void *)) free); + obstack_specify_allocation (&pfile->hash_ob, 0, 0, xmalloc, free); } table->pfile = pfile; @@ -73,6 +70,13 @@ _cpp_init_hashtable (cpp_reader *pfile, hash_table *table) s->n_false = cpp_lookup (pfile, DSC("false")); s->n__VA_ARGS__ = cpp_lookup (pfile, DSC("__VA_ARGS__")); s->n__VA_ARGS__->flags |= NODE_DIAGNOSTIC; + s->n__VA_OPT__ = cpp_lookup (pfile, DSC("__VA_OPT__")); + s->n__VA_OPT__->flags |= NODE_DIAGNOSTIC; + /* __has_include{,_next} are inited in cpp_init_builtins. */ + + // sdcpp additions + s->n__asm = cpp_lookup (pfile, DSC("__asm")); + s->n__endasm = cpp_lookup (pfile, DSC("__endasm")); } /* Tear down the identifier hash table. */ @@ -103,8 +107,8 @@ cpp_defined (cpp_reader *pfile, const unsigned char *str, int len) node = CPP_HASHNODE (ht_lookup (pfile->hash_table, str, len, HT_NO_INSERT)); - /* If it's of type NT_MACRO, it cannot be poisoned. */ - return node && node->type == NT_MACRO; + /* If it's a macro, it cannot have been poisoned. */ + return node && cpp_macro_p (node); } /* We don't need a proxy since the hash table's identifier comes first diff --git a/support/cpp/libcpp/include/cpplib.h b/support/cpp/libcpp/include/cpplib.h index 6882514d5..dc764a66e 100644 --- a/support/cpp/libcpp/include/cpplib.h +++ b/support/cpp/libcpp/include/cpplib.h @@ -1,7 +1,5 @@ /* Definitions for CPP library. - Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. + Copyright (C) 1995-2022 Free Software Foundation, Inc. Written by Per Bothner, 1994-95. This program is free software; you can redistribute it and/or modify it @@ -38,7 +36,6 @@ typedef struct cpp_macro cpp_macro; typedef struct cpp_callbacks cpp_callbacks; typedef struct cpp_dir cpp_dir; -struct answer; struct _cpp_file; /* The first three groups, apart from '=', can appear in preprocessor @@ -49,7 +46,7 @@ struct _cpp_file; '='. The lexer needs operators ending in '=', like ">>=", to be in the same order as their counterparts without the '=', like ">>". - See the cpp_operator table optab in expr.c if you change the order or + See the cpp_operator table optab in expr.cc if you change the order or add or remove anything in the first group. */ #define TTYPE_TABLE \ @@ -81,6 +78,7 @@ struct _cpp_file; OP(NOT_EQ, "!=") \ OP(GREATER_EQ, ">=") \ OP(LESS_EQ, "<=") \ + OP(SPACESHIP, "<=>") \ \ /* These two are unary + / - in preprocessor expressions. */ \ OP(PLUS_EQ, "+=") /* math */ \ @@ -121,6 +119,7 @@ struct _cpp_file; TK(WCHAR, LITERAL) /* L'char' */ \ TK(CHAR16, LITERAL) /* u'char' */ \ TK(CHAR32, LITERAL) /* U'char' */ \ + TK(UTF8CHAR, LITERAL) /* u8'char' */ \ TK(OTHER, LITERAL) /* stray punctuation */ \ \ TK(STRING, LITERAL) /* "string" */ \ @@ -131,6 +130,17 @@ struct _cpp_file; TK(OBJC_STRING, LITERAL) /* @"string" - Objective-C */ \ TK(HEADER_NAME, LITERAL) /* <stdio.h> in #include */ \ \ + TK(CHAR_USERDEF, LITERAL) /* 'char'_suffix - C++-0x */ \ + TK(WCHAR_USERDEF, LITERAL) /* L'char'_suffix - C++-0x */ \ + TK(CHAR16_USERDEF, LITERAL) /* u'char'_suffix - C++-0x */ \ + TK(CHAR32_USERDEF, LITERAL) /* U'char'_suffix - C++-0x */ \ + TK(UTF8CHAR_USERDEF, LITERAL) /* u8'char'_suffix - C++-0x */ \ + TK(STRING_USERDEF, LITERAL) /* "string"_suffix - C++-0x */ \ + TK(WSTRING_USERDEF, LITERAL) /* L"string"_suffix - C++-0x */ \ + TK(STRING16_USERDEF, LITERAL) /* u"string"_suffix - C++-0x */ \ + TK(STRING32_USERDEF, LITERAL) /* U"string"_suffix - C++-0x */ \ + TK(UTF8STRING_USERDEF,LITERAL) /* u8"string"_suffix - C++-0x */ \ + \ TK(COMMENT, LITERAL) /* Only if output comments. */ \ /* SPELL_LITERAL happens to DTRT. */ \ TK(MACRO_ARG, NONE) /* Macro argument. */ \ @@ -148,6 +158,9 @@ enum cpp_ttype TTYPE_TABLE N_TTYPES, + /* A token type for keywords, as opposed to ordinary identifiers. */ + CPP_KEYWORD, + /* Positions in the table. */ CPP_LAST_EQ = CPP_LSHIFT, CPP_FIRST_DIGRAPH = CPP_HASH, @@ -158,9 +171,13 @@ enum cpp_ttype #undef TK /* C language kind, used when calling cpp_create_reader. */ -enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_GNUC1X, - CLK_STDC89, CLK_STDC94, CLK_STDC99, CLK_STDC1X, - CLK_GNUCXX, CLK_CXX98, CLK_GNUCXX0X, CLK_CXX0X, CLK_ASM}; +enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_GNUC11, CLK_GNUC17, CLK_GNUC2X, + CLK_STDC89, CLK_STDC94, CLK_STDC99, CLK_STDC11, CLK_STDC17, + CLK_STDC2X, + CLK_GNUCXX, CLK_CXX98, CLK_GNUCXX11, CLK_CXX11, + CLK_GNUCXX14, CLK_CXX14, CLK_GNUCXX17, CLK_CXX17, + CLK_GNUCXX20, CLK_CXX20, CLK_GNUCXX23, CLK_CXX23, + CLK_ASM}; /* Payload of a NUMBER, STRING, CHAR or COMMENT token. */ struct GTY(()) cpp_string { @@ -174,17 +191,22 @@ struct GTY(()) cpp_string { #define STRINGIFY_ARG (1 << 2) /* If macro argument to be stringified. */ #define PASTE_LEFT (1 << 3) /* If on LHS of a ## operator. */ #define NAMED_OP (1 << 4) /* C++ named operators. */ -#define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */ +#define PREV_FALLTHROUGH (1 << 5) /* On a token preceeded by FALLTHROUGH + comment. */ #define BOL (1 << 6) /* Token at beginning of line. */ #define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend, - set in c-lex.c. */ + set in c-lex.cc. */ #define SP_DIGRAPH (1 << 8) /* # or ## token was a digraph. */ #define SP_PREV_WHITE (1 << 9) /* If whitespace before a ## operator, or before this token after a # operator. */ -#define PREV_NL (1 <<11) /* If a newline before this token. */ -#define ENTER_ASM (1 <<12) /* enter an __asm __endasm pair. */ -#define EXIT_ASM (1 <<13) /* exit an __asm __endasm pair. */ +#define NO_EXPAND (1 << 10) /* Do not macro-expand this token. */ +#define PRAGMA_OP (1 << 11) /* _Pragma token. */ + +/* sdcc specific */ +#define PREV_NL (1 <<12) /* If a newline before this token. */ +#define ENTER_ASM (1 <<13) /* enter an __asm __endasm pair. */ +#define EXIT_ASM (1 <<14) /* exit an __asm __endasm pair. */ /* Specify which field, if any, of the cpp_token union is used. */ @@ -202,6 +224,12 @@ enum cpp_token_fld_kind { struct GTY(()) cpp_macro_arg { /* Argument number. */ unsigned int arg_no; + /* The original spelling of the macro argument token. */ + 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"))) + spelling; }; /* An identifier in the cpp_token union. */ @@ -212,12 +240,21 @@ struct GTY(()) cpp_identifier { "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL", "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"))) node; + /* The original spelling of the identifier. */ + cpp_hashnode * + GTY ((nested_ptr (union tree_node, + "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL", + "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"))) + spelling; }; /* A preprocessing token. This has been carefully packed and should occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */ struct GTY(()) cpp_token { - source_location src_loc; /* Location of first char of token. */ + + /* Location of first char of token, together with range of full token. */ + location_t src_loc; + ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */ unsigned short flags; /* flags - see above */ @@ -232,7 +269,7 @@ struct GTY(()) cpp_token { /* A string, or number. */ struct cpp_string GTY ((tag ("CPP_TOKEN_FLD_STR"))) str; - /* Argument no. for a CPP_MACRO_ARG. */ + /* Argument no. (and original spelling) for a CPP_MACRO_ARG. */ struct cpp_macro_arg GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) macro_arg; /* Original token no. for a CPP_PASTE (from a sequence of @@ -245,7 +282,7 @@ struct GTY(()) cpp_token { }; /* Say which field is in use. */ -extern enum cpp_token_fld_kind cpp_token_val_index (cpp_token *tok); +extern enum cpp_token_fld_kind cpp_token_val_index (const cpp_token *tok); /* A type wide enough to hold any multibyte source character. cpplib's character constant interpreter requires an unsigned type. @@ -281,13 +318,31 @@ enum cpp_normalize_level { normalized_none }; +enum cpp_main_search +{ + CMS_none, /* A regular source file. */ + CMS_header, /* Is a directly-specified header file (eg PCH or + header-unit). */ + CMS_user, /* Search the user INCLUDE path. */ + CMS_system, /* Search the system INCLUDE path. */ +}; + +/* The possible bidirectional control characters checking levels. */ +enum cpp_bidirectional_level { + /* No checking. */ + bidirectional_none = 0, + /* Only detect unpaired uses of bidirectional control characters. */ + bidirectional_unpaired = 1, + /* Detect any use of bidirectional control characters. */ + bidirectional_any = 2, + /* Also warn about UCNs. */ + bidirectional_ucn = 4 +}; + /* This structure is nested inside struct cpp_reader, and carries all the options visible to the command line. */ struct cpp_options { - /* Characters between tab stops. */ - unsigned int tabstop; - /* The language we're preprocessing. */ enum c_lang lang; @@ -321,6 +376,13 @@ struct cpp_options /* Nonzero means process u/U prefix literals (UTF-16/32). */ unsigned char uliterals; + /* Nonzero means process u8 prefixed character literals (UTF-8). */ + unsigned char utf8_char_literals; + + /* Nonzero means process r/R raw strings. If this is set, uliterals + must be set as well. */ + unsigned char rliterals; + /* Nonzero means print names of header files (-H). */ unsigned char print_include_names; @@ -330,6 +392,9 @@ struct cpp_options /* Nonzero means warn if slash-star appears in a comment. */ unsigned char warn_comments; + /* Nonzero means to warn about __DATA__, __TIME__ and __TIMESTAMP__ usage. */ + unsigned char warn_date_time; + /* Nonzero means warn if a user-supplied include directory does not exist. */ unsigned char warn_missing_include_dirs; @@ -362,6 +427,9 @@ struct cpp_options explicitly undefined. */ unsigned char warn_builtin_macro_redefined; + /* Different -Wimplicit-fallthrough= levels. */ + unsigned char cpp_warn_implicit_fallthrough; + /* Nonzero means we should look for header.gcc files that remap file names. */ unsigned char remap; @@ -379,6 +447,10 @@ struct cpp_options /* Nonzero means warn if undefined identifiers are evaluated in an #if. */ unsigned char warn_undef; + /* Nonzero means warn if "defined" is encountered in a place other than + an #if. */ + unsigned char warn_expansion_to_defined; + /* Nonzero means warn of unused macros from the main file. */ unsigned char warn_unused_macros; @@ -394,6 +466,18 @@ struct cpp_options /* Nonzero means we're looking at already preprocessed code, so don't bother trying to do macro expansion and whatnot. */ unsigned char preprocessed; + + /* Nonzero means we are going to emit debugging logs during + preprocessing. */ + unsigned char debug; + + /* Nonzero means we are tracking locations of tokens involved in + macro expansion. 1 Means we track the location in degraded mode + where we do not track locations of tokens resulting from the + expansion of arguments of function-like macro. 2 Means we do + track all macro expansions. This last option is the one that + consumes the highest amount of memory. */ + unsigned char track_macro_expansion; /* Nonzero means handle C++ alternate operator names. */ unsigned char operator_names; @@ -404,6 +488,45 @@ struct cpp_options /* True for traditional preprocessing. */ unsigned char traditional; + /* Nonzero for C++ 2011 Standard user-defined literals. */ + unsigned char user_literals; + + /* Nonzero means warn when a string or character literal is followed by a + ud-suffix which does not beging with an underscore. */ + unsigned char warn_literal_suffix; + + /* Nonzero means interpret imaginary, fixed-point, or other gnu extension + literal number suffixes as user-defined literal number suffixes. */ + unsigned char ext_numeric_literals; + + /* Nonzero means extended identifiers allow the characters specified + in C11. */ + unsigned char c11_identifiers; + + /* Nonzero for C++ 2014 Standard binary constants. */ + unsigned char binary_constants; + + /* Nonzero for C++ 2014 Standard digit separators. */ + unsigned char digit_separators; + + /* Nonzero for C2X decimal floating-point constants. */ + unsigned char dfp_constants; + + /* Nonzero for C++20 __VA_OPT__ feature. */ + unsigned char va_opt; + + /* Nonzero for the '::' token. */ + unsigned char scope; + + /* Nonzero for the '#elifdef' and '#elifndef' directives. */ + unsigned char elifdef; + + /* Nonzero means tokenize C++20 module directives. */ + unsigned char module_directives; + + /* Nonzero for C++23 size_t literals. */ + unsigned char size_t_literals; + /* Holds the name of the target (execution) character set. */ const char *narrow_charset; @@ -414,8 +537,8 @@ struct cpp_options const char *input_charset; /* The minimum permitted level of normalization before a warning - is generated. */ - enum cpp_normalize_level warn_normalize; + is generated. See enum cpp_normalize_level. */ + int warn_normalize; /* True to warn about precompiled header files we couldn't use. */ bool warn_invalid_pch; @@ -423,6 +546,19 @@ struct cpp_options /* True if dependencies should be restored from a precompiled header. */ bool restore_pch_deps; + /* True if warn about differences between C90 and C99. */ + signed char cpp_warn_c90_c99_compat; + + /* True if warn about differences between C11 and C2X. */ + signed char cpp_warn_c11_c2x_compat; + + /* True if warn about differences between C++98 and C++11. */ + bool cpp_warn_cxx11_compat; + + /* Nonzero if bidirectional control characters checking is on. See enum + cpp_bidirectional_level. */ + unsigned char cpp_warn_bidirectional; + /* SDCC abuse by Kevin: allow naked '#' characters in expanded macros * (see _cpp_create_definition in cppmacro.c) */ @@ -453,6 +589,9 @@ struct cpp_options one. */ bool phony_targets; + /* Generate dependency info for modules. */ + bool modules; + /* If true, no dependency is generated on the main file. */ bool ignore_main_file; @@ -479,6 +618,70 @@ struct cpp_options /* True disables tokenization outside of preprocessing directives. */ bool directives_only; + + /* True enables canonicalization of system header file paths. */ + bool canonical_system_headers; + + /* The maximum depth of the nested #include. */ + unsigned int max_include_depth; + + cpp_main_search main_search : 8; +}; + +/* Diagnostic levels. To get a diagnostic without associating a + position in the translation unit with it, use cpp_error_with_line + with a line number of zero. */ + +enum cpp_diagnostic_level { + /* Warning, an error with -Werror. */ + CPP_DL_WARNING = 0, + /* Same as CPP_DL_WARNING, except it is not suppressed in system headers. */ + CPP_DL_WARNING_SYSHDR, + /* Warning, an error with -pedantic-errors or -Werror. */ + CPP_DL_PEDWARN, + /* An error. */ + CPP_DL_ERROR, + /* An internal consistency check failed. Prints "internal error: ", + otherwise the same as CPP_DL_ERROR. */ + CPP_DL_ICE, + /* An informative note following a warning. */ + CPP_DL_NOTE, + /* A fatal error. */ + CPP_DL_FATAL +}; + +/* Warning reason codes. Use a reason code of CPP_W_NONE for unclassified + warnings and diagnostics that are not warnings. */ + +enum cpp_warning_reason { + CPP_W_NONE = 0, + CPP_W_DEPRECATED, + CPP_W_COMMENTS, + CPP_W_MISSING_INCLUDE_DIRS, + CPP_W_TRIGRAPHS, + CPP_W_MULTICHAR, + CPP_W_TRADITIONAL, + CPP_W_LONG_LONG, + CPP_W_ENDIF_LABELS, + CPP_W_NUM_SIGN_CHANGE, + CPP_W_VARIADIC_MACROS, + CPP_W_BUILTIN_MACRO_REDEFINED, + CPP_W_DOLLARS, + CPP_W_UNDEF, + CPP_W_UNUSED_MACROS, + CPP_W_CXX_OPERATOR_NAMES, + CPP_W_NORMALIZE, + CPP_W_INVALID_PCH, + CPP_W_WARNING_DIRECTIVE, + CPP_W_LITERAL_SUFFIX, + CPP_W_SIZE_T_LITERALS, + CPP_W_DATE_TIME, + CPP_W_PEDANTIC, + CPP_W_C90_C99_COMPAT, + CPP_W_C11_C2X_COMPAT, + CPP_W_CXX11_COMPAT, + CPP_W_EXPANSION_TO_DEFINED, + CPP_W_BIDIRECTIONAL }; /* Callback for header lookup for HEADER, which is the name of a @@ -499,15 +702,15 @@ struct cpp_callbacks The line_map is for the new file. It is NULL if there is no new file. (In C this happens when done with <built-in>+<command line> and also when done with a main file.) This can be used for resource cleanup. */ - void (*file_change) (cpp_reader *, const struct line_map *); + void (*file_change) (cpp_reader *, const line_map_ordinary *); void (*dir_change) (cpp_reader *, const char *); - void (*include) (cpp_reader *, unsigned int, const unsigned char *, + void (*include) (cpp_reader *, location_t, const unsigned char *, const char *, int, const cpp_token **); - void (*define) (cpp_reader *, unsigned int, cpp_hashnode *); - void (*undef) (cpp_reader *, unsigned int, cpp_hashnode *); - void (*ident) (cpp_reader *, unsigned int, const cpp_string *); - void (*def_pragma) (cpp_reader *, unsigned int); + void (*define) (cpp_reader *, location_t, cpp_hashnode *); + void (*undef) (cpp_reader *, location_t, cpp_hashnode *); + void (*ident) (cpp_reader *, location_t, const cpp_string *); + void (*def_pragma) (cpp_reader *, location_t); int (*valid_pch) (cpp_reader *, const char *, int); void (*read_pch) (cpp_reader *, const char *, int, const char *); missing_header_cb missing_header; @@ -518,31 +721,75 @@ struct cpp_callbacks /* Called to emit a diagnostic. This callback receives the translated message. */ - bool (*error) (cpp_reader *, int, int, source_location, unsigned int, - const char *, va_list *) - ATTRIBUTE_FPTR_PRINTF(6,0); + bool (*diagnostic) (cpp_reader *, + enum cpp_diagnostic_level, + enum cpp_warning_reason, + rich_location *, + const char *, va_list *) + ATTRIBUTE_FPTR_PRINTF(5,0); /* Callbacks for when a macro is expanded, or tested (whether defined or not at the time) in #ifdef, #ifndef or "defined". */ - void (*used_define) (cpp_reader *, unsigned int, cpp_hashnode *); - void (*used_undef) (cpp_reader *, unsigned int, cpp_hashnode *); + void (*used_define) (cpp_reader *, location_t, cpp_hashnode *); + void (*used_undef) (cpp_reader *, location_t, cpp_hashnode *); /* Called before #define and #undef or other macro definition changes are processed. */ void (*before_define) (cpp_reader *); /* Called whenever a macro is expanded or tested. Second argument is the location of the start of the current expansion. */ - void (*used) (cpp_reader *, source_location, cpp_hashnode *); + void (*used) (cpp_reader *, location_t, cpp_hashnode *); + + /* Callback to identify whether an attribute exists. */ + int (*has_attribute) (cpp_reader *, bool); + + /* Callback to determine whether a built-in function is recognized. */ + int (*has_builtin) (cpp_reader *); + + /* Callback that can change a user lazy into normal macro. */ + void (*user_lazy_macro) (cpp_reader *, cpp_macro *, unsigned); + + /* Callback to handle deferred cpp_macros. */ + cpp_macro *(*user_deferred_macro) (cpp_reader *, location_t, cpp_hashnode *); - /* Callback that can change a user builtin into normal macro. */ - bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *); + /* Callback to parse SOURCE_DATE_EPOCH from environment. */ + time_t (*get_source_date_epoch) (cpp_reader *); + + /* Callback for providing suggestions for misspelled directives. */ + const char *(*get_suggestion) (cpp_reader *, const char *, const char *const *); + + /* Callback for when a comment is encountered, giving the location + of the opening slash, a pointer to the content (which is not + necessarily 0-terminated), and the length of the content. + The content contains the opening slash-star (or slash-slash), + and for C-style comments contains the closing star-slash. For + C++-style comments it does not include the terminating newline. */ + void (*comment) (cpp_reader *, location_t, const unsigned char *, + size_t); + + /* Callback for filename remapping in __FILE__ and __BASE_FILE__ macro + expansions. */ + const char *(*remap_filename) (const char*); + + /* Maybe translate a #include into something else. Return a + cpp_buffer containing the translation if translating. */ + char *(*translate_include) (cpp_reader *, line_maps *, location_t, + const char *path); }; #ifdef VMS #define INO_T_CPP ino_t ino[3] +#elif defined (_AIX) && SIZEOF_INO_T == 4 +#define INO_T_CPP ino64_t ino #else #define INO_T_CPP ino_t ino #endif +#if defined (_AIX) && SIZEOF_DEV_T == 4 +#define DEV_T_CPP dev64_t dev +#else +#define DEV_T_CPP dev_t dev +#endif + /* Chain of directories to look for include files in. */ struct cpp_dir { @@ -577,17 +824,87 @@ struct cpp_dir /* The C front end uses these to recognize duplicated directories in the search path. */ INO_T_CPP; - dev_t dev; + DEV_T_CPP; +}; + +/* The kind of the cpp_macro. */ +enum cpp_macro_kind { + cmk_macro, /* An ISO macro (token expansion). */ + cmk_assert, /* An assertion. */ + cmk_traditional /* A traditional macro (text expansion). */ +}; + +/* Each macro definition is recorded in a cpp_macro structure. + Variadic macros cannot occur with traditional cpp. */ +struct GTY(()) cpp_macro { + union cpp_parm_u + { + /* Parameters, if any. If parameter names use extended identifiers, + the original spelling of those identifiers, not the canonical + UTF-8 spelling, goes here. */ + cpp_hashnode ** GTY ((tag ("false"), + 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 ("%1.paramc"))) params; + + /* If this is an assertion, the next one in the chain. */ + cpp_macro *GTY ((tag ("true"))) next; + } GTY ((desc ("%1.kind == cmk_assert"))) parm; + + /* Definition line number. */ + location_t line; + + /* Number of tokens in body, or bytes for traditional macros. */ + /* Do we really need 2^32-1 range here? */ + unsigned int count; + + /* Number of parameters. */ + unsigned short paramc; + + /* Non-zero if this is a user-lazy macro, value provided by user. */ + unsigned char lazy; + + /* The kind of this macro (ISO, trad or assert) */ + unsigned kind : 2; + + /* 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 whether the tokens include extra CPP_PASTE tokens at the + end to track invalid redefinitions with consecutive CPP_PASTE + tokens. */ + unsigned int extra_tokens : 1; + + /* Imported C++20 macro (from a header unit). */ + unsigned int imported_p : 1; + + /* 0 bits spare (32-bit). 32 on 64-bit target. */ + + union cpp_exp_u + { + /* Trailing array of replacement tokens (ISO), or assertion body value. */ + cpp_token GTY ((tag ("false"), length ("%1.count"))) tokens[1]; + + /* Pointer to replacement text (traditional). See comment at top + of cpptrad.c for how traditional function-like macros are + encoded. */ + const unsigned char *GTY ((tag ("true"))) text; + } GTY ((desc ("%1.kind == cmk_traditional"))) exp; }; -/* The structure of a node in the hash table. The hash table has - entries for all identifiers: either macros defined by #define - commands (type NT_MACRO), assertions created with #assert - (NT_ASSERTION), or neither of the above (NT_VOID). Builtin macros - like __LINE__ are flagged NODE_BUILTIN. Poisoned identifiers are - flagged NODE_POISONED. NODE_OPERATOR (C++ only) indicates an - identifier that behaves like an operator such as "xor". - NODE_DIAGNOSTIC is for speed in lex_token: it indicates a +/* Poisoned identifiers are flagged NODE_POISONED. NODE_OPERATOR (C++ + only) indicates an identifier that behaves like an operator such as + "xor". NODE_DIAGNOSTIC is for speed in lex_token: it indicates a diagnostic may be required for this node. Currently this only applies to __VA_ARGS__, poisoned identifiers, and -Wc++-compat warnings about NODE_OPERATOR. */ @@ -595,21 +912,22 @@ struct cpp_dir /* Hash node flags. */ #define NODE_OPERATOR (1 << 0) /* C++ named operator. */ #define NODE_POISONED (1 << 1) /* Poisoned identifier. */ -#define NODE_BUILTIN (1 << 2) /* Builtin macro. */ -#define NODE_DIAGNOSTIC (1 << 3) /* Possible diagnostic when lexed. */ -#define NODE_WARN (1 << 4) /* Warn if redefined or undefined. */ -#define NODE_DISABLED (1 << 5) /* A disabled macro. */ -#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */ -#define NODE_USED (1 << 7) /* Dumped with -dU. */ -#define NODE_CONDITIONAL (1 << 8) /* Conditional macro */ -#define NODE_WARN_OPERATOR (1 << 9) /* Warn about C++ named operator. */ +#define NODE_DIAGNOSTIC (1 << 2) /* Possible diagnostic when lexed. */ +#define NODE_WARN (1 << 3) /* Warn if redefined or undefined. */ +#define NODE_DISABLED (1 << 4) /* A disabled macro. */ +#define NODE_USED (1 << 5) /* Dumped with -dU. */ +#define NODE_CONDITIONAL (1 << 6) /* Conditional macro */ +#define NODE_WARN_OPERATOR (1 << 7) /* Warn about C++ named operator. */ +#define NODE_MODULE (1 << 8) /* C++-20 module-related name. */ /* Different flavors of hash node. */ enum node_type { - NT_VOID = 0, /* No definition yet. */ - NT_MACRO, /* A macro of some form. */ - NT_ASSERTION /* Predicate for #assert. */ + NT_VOID = 0, /* Maybe an assert? */ + NT_MACRO_ARG, /* A macro arg. */ + NT_USER_MACRO, /* A user macro. */ + NT_BUILTIN_MACRO, /* A builtin macro. */ + NT_MACRO_MASK = NT_USER_MACRO /* Mask for either macro kind. */ }; /* Different flavors of builtin macro. _Pragma is an operator, but we @@ -619,6 +937,7 @@ enum cpp_builtin_type BT_SPECLINE = 0, /* `__LINE__' */ BT_DATE, /* `__DATE__' */ BT_FILE, /* `__FILE__' */ + BT_FILE_NAME, /* `__FILE_NAME__' */ BT_BASE_FILE, /* `__BASE_FILE__' */ BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ BT_TIME, /* `__TIME__' */ @@ -626,46 +945,35 @@ enum cpp_builtin_type BT_PRAGMA, /* `_Pragma' operator */ BT_TIMESTAMP, /* `__TIMESTAMP__' */ BT_COUNTER, /* `__COUNTER__' */ + BT_HAS_ATTRIBUTE, /* `__has_attribute(x)' */ + BT_HAS_STD_ATTRIBUTE, /* `__has_c_attribute(x)' */ + BT_HAS_BUILTIN, /* `__has_builtin(x)' */ + BT_HAS_INCLUDE, /* `__has_include(x)' */ + BT_HAS_INCLUDE_NEXT, /* `__has_include_next(x)' */ +/* sdcc specific */ BT_FUNCTION, /* `__func__' */ BT_FIRST_USER, /* User defined builtin macros. */ BT_LAST_USER = BT_FIRST_USER + 31 }; #define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE)) -#define HT_NODE(NODE) ((ht_identifier *) (NODE)) -#define NODE_LEN(NODE) HT_LEN (&(NODE)->ident) -#define NODE_NAME(NODE) HT_STR (&(NODE)->ident) - -/* Specify which field, if any, of the union is used. */ - -enum { - NTV_MACRO, - NTV_ANSWER, - NTV_BUILTIN, - NTV_ARGUMENT, - NTV_NONE -}; - -#define CPP_HASHNODE_VALUE_IDX(HNODE) \ - ((HNODE.flags & NODE_MACRO_ARG) ? NTV_ARGUMENT \ - : HNODE.type == NT_MACRO ? ((HNODE.flags & NODE_BUILTIN) \ - ? NTV_BUILTIN : NTV_MACRO) \ - : HNODE.type == NT_ASSERTION ? NTV_ANSWER \ - : NTV_NONE) +#define HT_NODE(NODE) (&(NODE)->ident) +#define NODE_LEN(NODE) HT_LEN (HT_NODE (NODE)) +#define NODE_NAME(NODE) HT_STR (HT_NODE (NODE)) /* The common part of an identifier node shared amongst all 3 C front ends. Also used to store CPP identifiers, which are a superset of identifiers in the grammatical sense. */ union GTY(()) _cpp_hashnode_value { - /* If a macro. */ - cpp_macro * GTY((tag ("NTV_MACRO"))) macro; - /* Answers to an assertion. */ - struct answer * GTY ((tag ("NTV_ANSWER"))) answers; + /* Assert (maybe NULL) */ + cpp_macro * GTY((tag ("NT_VOID"))) answers; + /* Macro (maybe NULL) */ + cpp_macro * GTY((tag ("NT_USER_MACRO"))) macro; /* Code for a builtin macro. */ - enum cpp_builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin; + enum cpp_builtin_type GTY ((tag ("NT_BUILTIN_MACRO"))) builtin; /* Macro argument index. */ - unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index; + unsigned short GTY ((tag ("NT_MACRO_ARG"))) arg_index; }; struct GTY(()) cpp_hashnode { @@ -674,11 +982,63 @@ struct GTY(()) cpp_hashnode { unsigned int directive_index : 7; /* If is_directive, then index into directive table. Otherwise, a NODE_OPERATOR. */ - unsigned char rid_code; /* Rid code - for front ends. */ - ENUM_BITFIELD(node_type) type : 6; /* CPP node type. */ - unsigned int flags : 10; /* CPP flags. */ + unsigned int rid_code : 8; /* Rid code - for front ends. */ + unsigned int flags : 9; /* CPP flags. */ + ENUM_BITFIELD(node_type) type : 2; /* CPP node type. */ + + /* 5 bits spare. */ + + /* The deferred cookie is applicable to NT_USER_MACRO or NT_VOID. + The latter for when a macro had a prevailing undef. + On a 64-bit system there would be 32-bits of padding to the value + field. So placing the deferred index here is not costly. */ + unsigned deferred; /* Deferred cookie */ + + union _cpp_hashnode_value GTY ((desc ("%1.type"))) value; +}; + +/* A class for iterating through the source locations within a + string token (before escapes are interpreted, and before + concatenation). */ - union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value; +class cpp_string_location_reader { + public: + cpp_string_location_reader (location_t src_loc, + line_maps *line_table); + + source_range get_next (); + + private: + location_t m_loc; + int m_offset_per_column; +}; + +/* A class for storing the source ranges of all of the characters within + a string literal, after escapes are interpreted, and after + concatenation. + + This is not GTY-marked, as instances are intended to be temporary. */ + +class cpp_substring_ranges +{ + public: + cpp_substring_ranges (); + ~cpp_substring_ranges (); + + int get_num_ranges () const { return m_num_ranges; } + source_range get_range (int idx) const + { + linemap_assert (idx < m_num_ranges); + return m_ranges[idx]; + } + + void add_range (source_range range); + void add_n_ranges (int num, cpp_string_location_reader &loc_reader); + + private: + source_range *m_ranges; + int m_num_ranges; + int m_alloc_ranges; }; /* Call this first to get a handle to pass to other functions. @@ -688,11 +1048,11 @@ struct GTY(()) cpp_hashnode { that cpplib will share; this technique is used by the C front ends. */ extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *, - struct line_maps *); + class line_maps *); /* Reset the cpp_reader's line_map. This is only used after reading a PCH file. */ -extern void cpp_set_line_map (cpp_reader *, struct line_maps *); +extern void cpp_set_line_map (cpp_reader *, class line_maps *); /* Call this to change the selected language standard (e.g. because of command line options). */ @@ -706,17 +1066,30 @@ extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int); call cpp_finish on that reader. You can either edit the callbacks through the pointer returned from cpp_get_callbacks, or set them with cpp_set_callbacks. */ -extern cpp_options *cpp_get_options (cpp_reader *); -extern cpp_callbacks *cpp_get_callbacks (cpp_reader *); +extern cpp_options *cpp_get_options (cpp_reader *) ATTRIBUTE_PURE; +extern cpp_callbacks *cpp_get_callbacks (cpp_reader *) ATTRIBUTE_PURE; extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *); -extern struct deps *cpp_get_deps (cpp_reader *); +extern class mkdeps *cpp_get_deps (cpp_reader *) ATTRIBUTE_PURE; + +extern const char *cpp_probe_header_unit (cpp_reader *, const char *file, + bool angle_p, location_t); + +/* Call these to get name data about the various compile-time + charsets. */ +extern const char *cpp_get_narrow_charset_name (cpp_reader *) ATTRIBUTE_PURE; +extern const char *cpp_get_wide_charset_name (cpp_reader *) ATTRIBUTE_PURE; /* This function reads the file, but does not start preprocessing. It returns the name of the original file; this is the same as the input file, except for preprocessed input. This will generate at least one file change callback, and possibly a line change callback too. If there was an error opening the file, it returns NULL. */ -extern const char *cpp_read_main_file (cpp_reader *, const char *); +extern const char *cpp_read_main_file (cpp_reader *, const char *, + bool injecting = false); +extern location_t cpp_main_loc (const cpp_reader *); + +/* Adjust for the main file to be an include. */ +extern void cpp_retrofit_as_include (cpp_reader *); /* Set up built-ins with special behavior. Use cpp_init_builtins() instead unless your know what you are doing. */ @@ -753,9 +1126,55 @@ extern int cpp_avoid_paste (cpp_reader *, const cpp_token *, const cpp_token *); extern const cpp_token *cpp_get_token (cpp_reader *); extern const cpp_token *cpp_get_token_with_location (cpp_reader *, - source_location *); -extern const unsigned char *cpp_macro_definition (cpp_reader *, - cpp_hashnode *); + location_t *); +inline bool cpp_user_macro_p (const cpp_hashnode *node) +{ + return node->type == NT_USER_MACRO; +} +inline bool cpp_builtin_macro_p (const cpp_hashnode *node) +{ + return node->type == NT_BUILTIN_MACRO; +} +inline bool cpp_macro_p (const cpp_hashnode *node) +{ + return node->type & NT_MACRO_MASK; +} +inline cpp_macro *cpp_set_deferred_macro (cpp_hashnode *node, + cpp_macro *forced = NULL) +{ + cpp_macro *old = node->value.macro; + + node->value.macro = forced; + node->type = NT_USER_MACRO; + node->flags &= ~NODE_USED; + + return old; +} +cpp_macro *cpp_get_deferred_macro (cpp_reader *, cpp_hashnode *, location_t); + +/* Returns true if NODE is a function-like user macro. */ +inline bool cpp_fun_like_macro_p (cpp_hashnode *node) +{ + return cpp_user_macro_p (node) && node->value.macro->fun_like; +} + +extern const unsigned char *cpp_macro_definition (cpp_reader *, cpp_hashnode *); +extern const unsigned char *cpp_macro_definition (cpp_reader *, cpp_hashnode *, + const cpp_macro *); +inline location_t cpp_macro_definition_location (cpp_hashnode *node) +{ + const cpp_macro *macro = node->value.macro; + return macro ? macro->line : 0; +} +/* Return an idempotent time stamp (possibly from SOURCE_DATE_EPOCH). */ +enum class CPP_time_kind +{ + FIXED = -1, /* Fixed time via source epoch. */ + DYNAMIC = -2, /* Dynamic via time(2). */ + UNKNOWN = -3 /* Wibbly wobbly, timey wimey. */ +}; +extern CPP_time_kind cpp_get_date (cpp_reader *, time_t *); + extern void _cpp_backup_tokens (cpp_reader *, unsigned int); extern const cpp_token *cpp_peek_token (cpp_reader *, int); @@ -766,6 +1185,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 *, enum cpp_ttype); +extern const char *cpp_interpret_string_ranges (cpp_reader *pfile, + const cpp_string *from, + cpp_string_location_reader *, + size_t count, + cpp_substring_ranges *out, + enum cpp_ttype type); extern bool cpp_interpret_string_notranslate (cpp_reader *, const cpp_string *, size_t, cpp_string *, enum cpp_ttype); @@ -776,12 +1201,19 @@ extern cppchar_t cpp_host_to_exec_charset (cpp_reader *, cppchar_t); /* Used to register macros and assertions, perhaps from the command line. The text is the same as the command line argument. */ extern void cpp_define (cpp_reader *, const char *); +extern void cpp_define_unused (cpp_reader *, const char *); extern void cpp_define_formatted (cpp_reader *pfile, const char *fmt, ...) ATTRIBUTE_PRINTF_2; +extern void cpp_define_formatted_unused (cpp_reader *pfile, + const char *fmt, + ...) ATTRIBUTE_PRINTF_2; extern void cpp_assert (cpp_reader *, const char *); extern void cpp_undef (cpp_reader *, const char *); extern void cpp_unassert (cpp_reader *, const char *); +/* Mark a node as a lazily defined macro. */ +extern void cpp_define_lazily (cpp_reader *, cpp_hashnode *node, unsigned N); + /* Undefine all macros and assertions. */ extern void cpp_undef_all (cpp_reader *); @@ -791,7 +1223,10 @@ extern int cpp_defined (cpp_reader *, const unsigned char *, int); /* A preprocessing number. Code assumes that any unused high bits of the double integer are set to zero. */ -typedef unsigned HOST_WIDE_INT cpp_num_part; + +/* This type has to be equal to unsigned HOST_WIDE_INT, see + gcc/c-family/c-lex.cc. */ +typedef uint64_t cpp_num_part; typedef struct cpp_num cpp_num; struct cpp_num { @@ -814,7 +1249,7 @@ struct cpp_num #define CPP_N_FLOATING 0x0002 #define CPP_N_WIDTH 0x00F0 -#define CPP_N_SMALL 0x0010 /* int, float, shrot _Fract/Accum */ +#define CPP_N_SMALL 0x0010 /* int, float, short _Fract/Accum */ #define CPP_N_MEDIUM 0x0020 /* long, double, long _Fract/_Accum. */ #define CPP_N_LARGE 0x0040 /* long long, long double, long long _Fract/Accum. */ @@ -836,100 +1271,105 @@ struct cpp_num #define CPP_N_FRACT 0x100000 /* Fract types. */ #define CPP_N_ACCUM 0x200000 /* Accum types. */ +#define CPP_N_FLOATN 0x400000 /* _FloatN types. */ +#define CPP_N_FLOATNX 0x800000 /* _FloatNx types. */ + +#define CPP_N_USERDEF 0x1000000 /* C++11 user-defined literal. */ + +#define CPP_N_SIZE_T 0x2000000 /* C++23 size_t literal. */ + +#define CPP_N_WIDTH_FLOATN_NX 0xF0000000 /* _FloatN / _FloatNx value + of N, divided by 16. */ +#define CPP_FLOATN_SHIFT 24 +#define CPP_FLOATN_MAX 0xF0 /* Classify a CPP_NUMBER token. The return value is a combination of the flags from the above sets. */ -extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *); +extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *, + const char **, location_t); + +/* Return the classification flags for a float suffix. */ +extern unsigned int cpp_interpret_float_suffix (cpp_reader *, const char *, + size_t); + +/* Return the classification flags for an int suffix. */ +extern unsigned int cpp_interpret_int_suffix (cpp_reader *, const char *, + size_t); /* Evaluate a token classified as category CPP_N_INTEGER. */ extern cpp_num cpp_interpret_integer (cpp_reader *, const cpp_token *, - unsigned int type); + unsigned int); /* Sign extend a number, with PRECISION significant bits and all others assumed clear, to fill out a cpp_num structure. */ cpp_num cpp_num_sign_extend (cpp_num, size_t); -/* Diagnostic levels. To get a diagnostic without associating a - position in the translation unit with it, use cpp_error_with_line - with a line number of zero. */ - -enum { - /* Warning, an error with -Werror. */ - CPP_DL_WARNING = 0, - /* Same as CPP_DL_WARNING, except it is not suppressed in system headers. */ - CPP_DL_WARNING_SYSHDR, - /* Warning, an error with -pedantic-errors or -Werror. */ - CPP_DL_PEDWARN, - /* An error. */ - CPP_DL_ERROR, - /* An internal consistency check failed. Prints "internal error: ", - otherwise the same as CPP_DL_ERROR. */ - CPP_DL_ICE, - /* An informative note following a warning. */ - CPP_DL_NOTE, - /* A fatal error. */ - CPP_DL_FATAL -}; - -/* Warning reason codes. Use a reason code of zero for unclassified warnings - and errors that are not warnings. */ -enum { - CPP_W_NONE = 0, - CPP_W_DEPRECATED, - CPP_W_COMMENTS, - CPP_W_MISSING_INCLUDE_DIRS, - CPP_W_TRIGRAPHS, - CPP_W_MULTICHAR, - CPP_W_TRADITIONAL, - CPP_W_LONG_LONG, - CPP_W_ENDIF_LABELS, - CPP_W_NUM_SIGN_CHANGE, - CPP_W_VARIADIC_MACROS, - CPP_W_BUILTIN_MACRO_REDEFINED, - CPP_W_DOLLARS, - CPP_W_UNDEF, - CPP_W_UNUSED_MACROS, - CPP_W_CXX_OPERATOR_NAMES, - CPP_W_NORMALIZE, - CPP_W_INVALID_PCH, - CPP_W_WARNING_DIRECTIVE -}; - /* Output a diagnostic of some kind. */ -extern bool cpp_error (cpp_reader *, int, const char *msgid, ...) +extern bool cpp_error (cpp_reader *, enum cpp_diagnostic_level, + const char *msgid, ...) ATTRIBUTE_PRINTF_3; -extern bool cpp_warning (cpp_reader *, int, const char *msgid, ...) +extern bool cpp_warning (cpp_reader *, enum cpp_warning_reason, + const char *msgid, ...) ATTRIBUTE_PRINTF_3; -extern bool cpp_pedwarning (cpp_reader *, int, const char *msgid, ...) +extern bool cpp_pedwarning (cpp_reader *, enum cpp_warning_reason, + const char *msgid, ...) ATTRIBUTE_PRINTF_3; -extern bool cpp_warning_syshdr (cpp_reader *, int, const char *msgid, ...) +extern bool cpp_warning_syshdr (cpp_reader *, enum cpp_warning_reason reason, + const char *msgid, ...) ATTRIBUTE_PRINTF_3; +/* As their counterparts above, but use RICHLOC. */ +extern bool cpp_warning_at (cpp_reader *, enum cpp_warning_reason, + rich_location *richloc, const char *msgid, ...) + ATTRIBUTE_PRINTF_4; +extern bool cpp_pedwarning_at (cpp_reader *, enum cpp_warning_reason, + rich_location *richloc, const char *msgid, ...) + ATTRIBUTE_PRINTF_4; + /* Output a diagnostic with "MSGID: " preceding the error string of errno. No location is printed. */ -extern bool cpp_errno (cpp_reader *, int, const char *msgid); +extern bool cpp_errno (cpp_reader *, enum cpp_diagnostic_level, + const char *msgid); +/* Similarly, but with "FILENAME: " instead of "MSGID: ", where + the filename is not localized. */ +extern bool cpp_errno_filename (cpp_reader *, enum cpp_diagnostic_level, + const char *filename, location_t loc); /* Same as cpp_error, except additionally specifies a position as a (translation unit) physical line and physical column. If the line is zero, then no location is printed. */ -extern bool cpp_error_with_line (cpp_reader *, int, source_location, - unsigned, const char *msgid, ...) +extern bool cpp_error_with_line (cpp_reader *, enum cpp_diagnostic_level, + location_t, unsigned, + const char *msgid, ...) ATTRIBUTE_PRINTF_5; -extern bool cpp_warning_with_line (cpp_reader *, int, source_location, - unsigned, const char *msgid, ...) +extern bool cpp_warning_with_line (cpp_reader *, enum cpp_warning_reason, + location_t, unsigned, + const char *msgid, ...) ATTRIBUTE_PRINTF_5; -extern bool cpp_pedwarning_with_line (cpp_reader *, int, source_location, - unsigned, const char *msgid, ...) +extern bool cpp_pedwarning_with_line (cpp_reader *, enum cpp_warning_reason, + location_t, unsigned, + const char *msgid, ...) ATTRIBUTE_PRINTF_5; -extern bool cpp_warning_with_line_syshdr (cpp_reader *, int, source_location, - unsigned, const char *msgid, ...) +extern bool cpp_warning_with_line_syshdr (cpp_reader *, enum cpp_warning_reason, + location_t, unsigned, + const char *msgid, ...) ATTRIBUTE_PRINTF_5; -/* In lex.c */ +extern bool cpp_error_at (cpp_reader * pfile, enum cpp_diagnostic_level, + location_t src_loc, const char *msgid, ...) + ATTRIBUTE_PRINTF_4; + +extern bool cpp_error_at (cpp_reader * pfile, enum cpp_diagnostic_level, + rich_location *richloc, const char *msgid, ...) + ATTRIBUTE_PRINTF_4; + +/* In lex.cc */ extern int cpp_ideq (const cpp_token *, const char *); extern void cpp_output_line (cpp_reader *, FILE *); extern unsigned char *cpp_output_line_to_string (cpp_reader *, const unsigned char *); +extern const unsigned char *cpp_alloc_token_string + (cpp_reader *, const unsigned char *, unsigned); extern void cpp_output_token (const cpp_token *, FILE *); extern const char *cpp_type2name (enum cpp_ttype, unsigned char flags); /* Returns the value of an escape sequence, truncated to the correct @@ -949,7 +1389,7 @@ typedef struct char *comment; /* source location for the given comment. */ - source_location sloc; + location_t sloc; } cpp_comment; /* Structure holding all comments for a given cpp_reader. */ @@ -980,17 +1420,20 @@ extern cpp_hashnode *cpp_lookup (cpp_reader *, const unsigned char *, typedef int (*cpp_cb) (cpp_reader *, cpp_hashnode *, void *); extern void cpp_forall_identifiers (cpp_reader *, cpp_cb, void *); -/* In macro.c */ +/* In macro.cc */ extern void cpp_scan_nooutput (cpp_reader *); extern int cpp_sys_macro_p (cpp_reader *); extern unsigned char *cpp_quote_string (unsigned char *, const unsigned char *, unsigned int); +extern bool cpp_compare_macros (const cpp_macro *macro1, + const cpp_macro *macro2); -/* In files.c */ +/* In files.cc */ extern bool cpp_included (cpp_reader *, const char *); -extern bool cpp_included_before (cpp_reader *, const char *, source_location); +extern bool cpp_included_before (cpp_reader *, const char *, location_t); extern void cpp_make_system_header (cpp_reader *, int, int); extern bool cpp_push_include (cpp_reader *, const char *); +extern bool cpp_push_default_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 *); @@ -999,7 +1442,21 @@ extern struct _cpp_file *cpp_get_file (cpp_buffer *); extern cpp_buffer *cpp_get_prev (cpp_buffer *); extern void cpp_clear_file_cache (cpp_reader *); -/* In pch.c */ +/* cpp_get_converted_source returns the contents of the given file, as it exists + after cpplib has read it and converted it from the input charset to the + source charset. Return struct will be zero-filled if the data could not be + read for any reason. The data starts at the DATA pointer, but the TO_FREE + pointer is what should be passed to free(), as there may be an offset. */ +struct cpp_converted_source +{ + char *to_free; + char *data; + size_t len; +}; +cpp_converted_source cpp_get_converted_source (const char *fname, + const char *input_charset); + +/* In pch.cc */ struct save_macro_data; extern int cpp_save_state (cpp_reader *, FILE *); extern int cpp_write_pch_deps (cpp_reader *, FILE *); @@ -1009,4 +1466,132 @@ extern void cpp_prepare_state (cpp_reader *, struct save_macro_data **); extern int cpp_read_state (cpp_reader *, const char *, FILE *, struct save_macro_data *); +/* In lex.cc */ +extern void cpp_force_token_locations (cpp_reader *, location_t); +extern void cpp_stop_forcing_token_locations (cpp_reader *); +enum CPP_DO_task +{ + CPP_DO_print, + CPP_DO_location, + CPP_DO_token +}; + +extern void cpp_directive_only_process (cpp_reader *pfile, + void *data, + void (*cb) (cpp_reader *, + CPP_DO_task, + void *data, ...)); + +/* In expr.cc */ +extern enum cpp_ttype cpp_userdef_string_remove_type + (enum cpp_ttype type); +extern enum cpp_ttype cpp_userdef_string_add_type + (enum cpp_ttype type); +extern enum cpp_ttype cpp_userdef_char_remove_type + (enum cpp_ttype type); +extern enum cpp_ttype cpp_userdef_char_add_type + (enum cpp_ttype type); +extern bool cpp_userdef_string_p + (enum cpp_ttype type); +extern bool cpp_userdef_char_p + (enum cpp_ttype type); +extern const char * cpp_get_userdef_suffix + (const cpp_token *); + +/* In charset.cc */ + +/* The result of attempting to decode a run of UTF-8 bytes. */ + +struct cpp_decoded_char +{ + const char *m_start_byte; + const char *m_next_byte; + + bool m_valid_ch; + cppchar_t m_ch; +}; + +/* Information for mapping between code points and display columns. + + This is a tabstop value, along with a callback for getting the + widths of characters. Normally this callback is cpp_wcwidth, but we + support other schemes for escaping non-ASCII unicode as a series of + ASCII chars when printing the user's source code in diagnostic-show-locus.cc + + For example, consider: + - the Unicode character U+03C0 "GREEK SMALL LETTER PI" (UTF-8: 0xCF 0x80) + - the Unicode character U+1F642 "SLIGHTLY SMILING FACE" + (UTF-8: 0xF0 0x9F 0x99 0x82) + - the byte 0xBF (a stray trailing byte of a UTF-8 character) + Normally U+03C0 would occupy one display column, U+1F642 + would occupy two display columns, and the stray byte would be + printed verbatim as one display column. + + However when escaping them as unicode code points as "<U+03C0>" + and "<U+1F642>" they occupy 8 and 9 display columns respectively, + and when escaping them as bytes as "<CF><80>" and "<F0><9F><99><82>" + they occupy 8 and 16 display columns respectively. In both cases + the stray byte is escaped to <BF> as 4 display columns. */ + +struct cpp_char_column_policy +{ + cpp_char_column_policy (int tabstop, + int (*width_cb) (cppchar_t c)) + : m_tabstop (tabstop), + m_undecoded_byte_width (1), + m_width_cb (width_cb) + {} + + int m_tabstop; + /* Width in display columns of a stray byte that isn't decodable + as UTF-8. */ + int m_undecoded_byte_width; + int (*m_width_cb) (cppchar_t c); +}; + +/* A class to manage the state while converting a UTF-8 sequence to cppchar_t + and computing the display width one character at a time. */ +class cpp_display_width_computation { + public: + cpp_display_width_computation (const char *data, int data_length, + const cpp_char_column_policy &policy); + const char *next_byte () const { return m_next; } + int bytes_processed () const { return m_next - m_begin; } + int bytes_left () const { return m_bytes_left; } + bool done () const { return !bytes_left (); } + int display_cols_processed () const { return m_display_cols; } + + int process_next_codepoint (cpp_decoded_char *out); + int advance_display_cols (int n); + + private: + const char *const m_begin; + const char *m_next; + size_t m_bytes_left; + const cpp_char_column_policy &m_policy; + int m_display_cols; +}; + +/* Convenience functions that are simple use cases for class + cpp_display_width_computation. Tab characters will be expanded to spaces + as determined by POLICY.m_tabstop, and non-printable-ASCII characters + will be escaped as per POLICY. */ + +int cpp_byte_column_to_display_column (const char *data, int data_length, + int column, + const cpp_char_column_policy &policy); +inline int cpp_display_width (const char *data, int data_length, + const cpp_char_column_policy &policy) +{ + return cpp_byte_column_to_display_column (data, data_length, data_length, + policy); +} +int cpp_display_column_to_byte_column (const char *data, int data_length, + int display_col, + const cpp_char_column_policy &policy); +int cpp_wcwidth (cppchar_t c); + +bool cpp_input_conversion_is_trivial (const char *input_charset); +int cpp_check_utf8_bom (const char *data, size_t data_length); + #endif /* ! LIBCPP_CPPLIB_H */ diff --git a/support/cpp/libcpp/include/filenames.h b/support/cpp/libcpp/include/filenames.h new file mode 100644 index 000000000..6c72c422e --- /dev/null +++ b/support/cpp/libcpp/include/filenames.h @@ -0,0 +1,100 @@ +/* Macros for taking apart, interpreting and processing file names. + + These are here because some non-Posix (a.k.a. DOSish) systems have + drive letter brain-damage at the beginning of an absolute file name, + use forward- and back-slash in path names interchangeably, and + some of them have case-insensitive file names. + + Copyright (C) 2000-2022 Free Software Foundation, Inc. + +This file is part of BFD, the Binary File Descriptor library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef FILENAMES_H +#define FILENAMES_H + +#include "hashtab.h" /* for hashval_t */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__MSDOS__) || (defined(_WIN32) && ! defined(__CYGWIN__)) || \ + defined(__OS2__) +# ifndef HAVE_DOS_BASED_FILE_SYSTEM +# define HAVE_DOS_BASED_FILE_SYSTEM 1 +# endif +# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM +# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1 +# endif +# define HAS_DRIVE_SPEC(f) HAS_DOS_DRIVE_SPEC (f) +# define IS_DIR_SEPARATOR(c) IS_DOS_DIR_SEPARATOR (c) +# define IS_ABSOLUTE_PATH(f) IS_DOS_ABSOLUTE_PATH (f) +#else /* not DOSish */ +# if defined(__APPLE__) +# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM +# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1 +# endif +# endif /* __APPLE__ */ +# define HAS_DRIVE_SPEC(f) (0) +# define IS_DIR_SEPARATOR(c) IS_UNIX_DIR_SEPARATOR (c) +# define IS_ABSOLUTE_PATH(f) IS_UNIX_ABSOLUTE_PATH (f) +#endif + +#define IS_DIR_SEPARATOR_1(dos_based, c) \ + (((c) == '/') \ + || (((c) == '\\') && (dos_based))) + +#define HAS_DRIVE_SPEC_1(dos_based, f) \ + ((f)[0] && ((f)[1] == ':') && (dos_based)) + +/* Remove the drive spec from F, assuming HAS_DRIVE_SPEC (f). + The result is a pointer to the remainder of F. */ +#define STRIP_DRIVE_SPEC(f) ((f) + 2) + +#define IS_DOS_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (1, c) +#define IS_DOS_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (1, f) +#define HAS_DOS_DRIVE_SPEC(f) HAS_DRIVE_SPEC_1 (1, f) + +#define IS_UNIX_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (0, c) +#define IS_UNIX_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (0, f) + +/* Note that when DOS_BASED is true, IS_ABSOLUTE_PATH accepts d:foo as + well, although it is only semi-absolute. This is because the users + of IS_ABSOLUTE_PATH want to know whether to prepend the current + working directory to a file name, which should not be done with a + name like d:foo. */ +#define IS_ABSOLUTE_PATH_1(dos_based, f) \ + (IS_DIR_SEPARATOR_1 (dos_based, (f)[0]) \ + || HAS_DRIVE_SPEC_1 (dos_based, f)) + +extern int filename_cmp (const char *s1, const char *s2); +#define FILENAME_CMP(s1, s2) filename_cmp(s1, s2) + +extern int filename_ncmp (const char *s1, const char *s2, + size_t n); + +extern hashval_t filename_hash (const void *s); + +extern int filename_eq (const void *s1, const void *s2); + +extern int canonical_filename_eq (const char *a, const char *b); + +#ifdef __cplusplus +} +#endif + +#endif /* FILENAMES_H */ diff --git a/support/cpp/libcpp/include/hashtab.h b/support/cpp/libcpp/include/hashtab.h new file mode 100644 index 000000000..7117eee2a --- /dev/null +++ b/support/cpp/libcpp/include/hashtab.h @@ -0,0 +1,207 @@ +/* An expandable hash tables datatype. + Copyright (C) 1999-2022 Free Software Foundation, Inc. + Contributed by Vladimir Makarov (vmakarov@cygnus.com). + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This package implements basic hash table functionality. It is possible + to search for an entry, create an entry and destroy an entry. + + Elements in the table are generic pointers. + + The size of the table is not fixed; if the occupancy of the table + grows too high the hash table will be expanded. + + The abstract data implementation is based on generalized Algorithm D + from Knuth's book "The art of computer programming". Hash table is + expanded by creation of new hash table and transferring elements from + the old table to the new table. */ + +#ifndef __HASHTAB_H__ +#define __HASHTAB_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ansidecl.h" + +/* The type for a hash code. */ +typedef unsigned int hashval_t; + +/* Callback function pointer types. */ + +/* Calculate hash of a table entry. */ +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) (const void *, const void *); + +/* Cleanup function called whenever a live element is removed from + the hash table. */ +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) (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 void *(*htab_alloc) (size_t, size_t); + +/* We also need a free() routine. */ +typedef void (*htab_free) (void *); + +/* Memory allocation and deallocation; variants which take an extra + argument. */ +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 + tables. All work with hash table should be executed only through + functions mentioned below. The size of this structure is subject to + change. */ + +struct htab { + /* Pointer to hash function. */ + htab_hash hash_f; + + /* Pointer to comparison function. */ + htab_eq eq_f; + + /* Pointer to cleanup function. */ + htab_del del_f; + + /* Table itself. */ + void **entries; + + /* Current size (in entries) of the hash table. */ + size_t size; + + /* Current number of elements including also deleted elements. */ + size_t n_elements; + + /* Current number of deleted elements in the table. */ + size_t n_deleted; + + /* The following member is used for debugging. Its value is number + of all calls of `htab_find_slot' for the hash table. */ + unsigned int searches; + + /* The following member is used for debugging. Its value is number + of collisions fixed for time of work with the hash table. */ + unsigned int collisions; + + /* Pointers to allocate/free functions. */ + htab_alloc alloc_f; + htab_free free_f; + + /* Alternate allocate/free functions, which take an extra argument. */ + void *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; + +/* An enum saying whether we insert into the hash table or not. */ +enum insert_option {NO_INSERT, INSERT}; + +/* The prototypes of the package functions. */ + +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 (size_t, htab_hash, + htab_eq, htab_del, + void *, htab_alloc_with_arg, + htab_free_with_arg); + +extern htab_t htab_create_typed_alloc (size_t, htab_hash, htab_eq, htab_del, + htab_alloc, htab_alloc, htab_free); + +/* Backward-compatibility functions. */ +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, const void *); +extern void htab_remove_elt_with_hash (htab_t, const 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; + +/* An equality function for pointers. */ +extern htab_eq htab_eq_pointer; + +/* A hash function for null-terminated strings. */ +extern hashval_t htab_hash_string (const void *); + +/* An equality function for null-terminated strings. */ +extern int htab_eq_string (const void *, const void *); + +/* An iterative hash function for arbitrary data. */ +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) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __HASHTAB_H */ diff --git a/support/cpp/libcpp/include/libiberty.h b/support/cpp/libcpp/include/libiberty.h new file mode 100644 index 000000000..a65ced9c8 --- /dev/null +++ b/support/cpp/libcpp/include/libiberty.h @@ -0,0 +1,761 @@ +/* Function declarations for libiberty. + + Copyright (C) 1997-2022 Free Software Foundation, Inc. + + Note - certain prototypes declared in this header file are for + functions whoes implementation copyright does not belong to the + FSF. Those prototypes are present in this file for reference + purposes only and their presence in this file should not construed + as an indication of ownership by the FSF of the implementation of + those functions in any way or form whatsoever. + + 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 Cygnus Support, 1994. + + The libiberty library provides a number of functions which are + missing on some operating systems. We do not declare those here, + to avoid conflicts with the system header files on operating + systems that do support those functions. In this file we only + declare those functions which are specific to libiberty. */ + +#ifndef LIBIBERTY_H +#define LIBIBERTY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ansidecl.h" + +/* Get a definition for size_t. */ +#include <stddef.h> +/* Get a definition for va_list. */ +#include <stdarg.h> + +#include <stdio.h> + +/* If the OS supports it, ensure that the supplied stream is setup to + avoid any multi-threaded locking. Otherwise leave the FILE pointer + unchanged. If the stream is NULL do nothing. */ + +extern void unlock_stream (FILE *); + +/* If the OS supports it, ensure that the standard I/O streams, stdin, + stdout and stderr are setup to avoid any multi-threaded locking. + Otherwise do nothing. */ + +extern void unlock_std_streams (void); + +/* Open and return a FILE pointer. If the OS supports it, ensure that + the stream is setup to avoid any multi-threaded locking. Otherwise + return the FILE pointer unchanged. */ + +extern FILE *fopen_unlocked (const char *, const char *); +extern FILE *fdopen_unlocked (int, const char *); +extern FILE *freopen_unlocked (const char *, const char *, FILE *); + +/* Build an argument vector from a string. Allocates memory using + malloc. Use freeargv to free the vector. */ + +extern char **buildargv (const char *) ATTRIBUTE_MALLOC; + +/* Free a vector returned by buildargv. */ + +extern void freeargv (char **); + +/* Duplicate an argument vector. Allocates memory using malloc. Use + freeargv to free the vector. */ + +extern char **dupargv (char * const *) ATTRIBUTE_MALLOC; + +/* Expand "@file" arguments in argv. */ + +extern void expandargv (int *, char ***); + +/* Write argv to an @-file, inserting necessary quoting. */ + +extern int writeargv (char * const *, FILE *); + +/* Return the number of elements in argv. */ + +extern int countargv (char * const *); + +/* Return the last component of a path name. Note that we can't use a + prototype here because the parameter is declared inconsistently + across different systems, sometimes as "char *" and sometimes as + "const char *" */ + +/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is + undefined, we haven't run the autoconf check so provide the + declaration without arguments. If it is 0, we checked and failed + to find the declaration so provide a fully prototyped one. If it + is 1, we found it so don't provide any declaration at all. */ +#if !HAVE_DECL_BASENAME +#if defined (__GNU_LIBRARY__ ) || defined (__linux__) \ + || defined (__FreeBSD__) || defined (__OpenBSD__) || defined (__NetBSD__) \ + || defined (__CYGWIN__) || defined (__CYGWIN32__) || defined (__MINGW32__) \ + || defined (__DragonFly__) || defined (HAVE_DECL_BASENAME) +extern char *basename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1); +#else +/* Do not allow basename to be used if there is no prototype seen. We + either need to use the above prototype or have one from + autoconf which would result in HAVE_DECL_BASENAME being set. */ +#define basename basename_cannot_be_used_without_a_prototype +#endif +#endif + +/* A well-defined basename () that is always compiled in. */ + +extern const char *lbasename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1); + +/* Same, but assumes DOS semantics (drive name, backslash is also a + dir separator) regardless of host. */ + +extern const char *dos_lbasename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1); + +/* Same, but assumes Unix semantics (absolute paths always start with + a slash, only forward slash is accepted as dir separator) + regardless of host. */ + +extern const char *unix_lbasename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1); + +/* A well-defined realpath () that is always compiled in. */ + +extern char *lrealpath (const char *); + +/* Return true when FD file descriptor exists. */ + +extern int is_valid_fd (int fd); + +/* Concatenate an arbitrary number of strings. You must pass NULL as + the last argument of this function, to terminate the list of + strings. Allocates memory using xmalloc. */ + +extern char *concat (const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_SENTINEL; + +/* Concatenate an arbitrary number of strings. You must pass NULL as + the last argument of this function, to terminate the list of + strings. Allocates memory using xmalloc. The first argument is + not one of the strings to be concatenated, but if not NULL is a + pointer to be freed after the new string is created, similar to the + way xrealloc works. */ + +extern char *reconcat (char *, const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_SENTINEL; + +/* Determine the length of concatenating an arbitrary number of + strings. You must pass NULL as the last argument of this function, + to terminate the list of strings. */ + +extern unsigned long concat_length (const char *, ...) ATTRIBUTE_SENTINEL; + +/* Concatenate an arbitrary number of strings into a SUPPLIED area of + memory. You must pass NULL as the last argument of this function, + to terminate the list of strings. The supplied memory is assumed + to be large enough. */ + +extern char *concat_copy (char *, const char *, ...) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_NONNULL(1) ATTRIBUTE_SENTINEL; + +/* Concatenate an arbitrary number of strings into a GLOBAL area of + memory. You must pass NULL as the last argument of this function, + to terminate the list of strings. The supplied memory is assumed + to be large enough. */ + +extern char *concat_copy2 (const char *, ...) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_SENTINEL; + +/* This is the global area used by concat_copy2. */ + +extern char *libiberty_concat_ptr; + +/* Concatenate an arbitrary number of strings. You must pass NULL as + the last argument of this function, to terminate the list of + strings. Allocates memory using alloca. The arguments are + evaluated twice! */ +#define ACONCAT(ACONCAT_PARAMS) \ + (libiberty_concat_ptr = (char *) alloca (concat_length ACONCAT_PARAMS + 1), \ + concat_copy2 ACONCAT_PARAMS) + +/* Check whether two file descriptors refer to the same file. */ + +extern int fdmatch (int fd1, int fd2); + +/* Return the position of the first bit set in the argument. */ +/* Prototypes vary from system to system, so we only provide a + prototype on systems where we know that we need it. */ +#if defined (HAVE_DECL_FFS) && !HAVE_DECL_FFS +extern int ffs(int); +#endif + +/* Get the working directory. The result is cached, so don't call + chdir() between calls to getpwd(). */ + +extern char * getpwd (void); + +/* Get the current time. */ +/* Prototypes vary from system to system, so we only provide a + prototype on systems where we know that we need it. */ +#ifdef __MINGW32__ +/* Forward declaration to avoid #include <sys/time.h>. */ +struct timeval; +extern int gettimeofday (struct timeval *, void *); +#endif + +/* Get the amount of time the process has run, in microseconds. */ + +extern long get_run_time (void); + +/* Generate a relocated path to some installation directory. Allocates + return value using malloc. */ + +extern char *make_relative_prefix (const char *, const char *, + const char *) ATTRIBUTE_MALLOC; + +/* Generate a relocated path to some installation directory without + attempting to follow any soft links. Allocates + return value using malloc. */ + +extern char *make_relative_prefix_ignore_links (const char *, const char *, + const char *) ATTRIBUTE_MALLOC; + +/* Returns a pointer to a directory path suitable for creating temporary + files in. */ + +extern const char *choose_tmpdir (void) ATTRIBUTE_RETURNS_NONNULL; + +/* Choose a temporary directory to use for scratch files. */ + +extern char *choose_temp_base (void) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL; + +/* Return a temporary file name or NULL if unable to create one. */ + +extern char *make_temp_file (const char *) ATTRIBUTE_MALLOC; + +/* Return a temporary file name with given PREFIX and SUFFIX + or NULL if unable to create one. */ + +extern char *make_temp_file_with_prefix (const char *, const char *) ATTRIBUTE_MALLOC; + +/* Remove a link to a file unless it is special. */ + +extern int unlink_if_ordinary (const char *); + +/* Allocate memory filled with spaces. Allocates using malloc. */ + +extern const char *spaces (int count); + +/* Return the maximum error number for which strerror will return a + string. */ + +extern int errno_max (void); + +/* Return the name of an errno value (e.g., strerrno (EINVAL) returns + "EINVAL"). */ + +extern const char *strerrno (int); + +/* Given the name of an errno value, return the value. */ + +extern int strtoerrno (const char *); + +/* ANSI's strerror(), but more robust. */ + +extern char *xstrerror (int) ATTRIBUTE_RETURNS_NONNULL; + +/* Return the maximum signal number for which strsignal will return a + string. */ + +extern int signo_max (void); + +/* Return a signal message string for a signal number + (e.g., strsignal (SIGHUP) returns something like "Hangup"). */ +/* This is commented out as it can conflict with one in system headers. + We still document its existence though. */ + +/*extern const char *strsignal (int);*/ + +/* Return the name of a signal number (e.g., strsigno (SIGHUP) returns + "SIGHUP"). */ + +extern const char *strsigno (int); + +/* Given the name of a signal, return its number. */ + +extern int strtosigno (const char *); + +/* Register a function to be run by xexit. Returns 0 on success. */ + +extern int xatexit (void (*fn) (void)); + +/* Exit, calling all the functions registered with xatexit. */ + +extern void xexit (int status) ATTRIBUTE_NORETURN; + +/* Set the program name used by xmalloc. */ + +extern void xmalloc_set_program_name (const char *); + +/* Report an allocation failure. */ +extern void xmalloc_failed (size_t) ATTRIBUTE_NORETURN; + +/* Allocate memory without fail. If malloc fails, this will print a + message to stderr (using the name set by xmalloc_set_program_name, + if any) and then call xexit. */ + +extern void *xmalloc (size_t) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_RESULT_SIZE_1 ATTRIBUTE_WARN_UNUSED_RESULT; + +/* Reallocate memory without fail. This works like xmalloc. Note, + realloc type functions are not suitable for attribute malloc since + they may return the same address across multiple calls. */ + +extern void *xrealloc (void *, size_t) ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_RESULT_SIZE_2 ATTRIBUTE_WARN_UNUSED_RESULT; + +/* Allocate memory without fail and set it to zero. This works like + xmalloc. */ + +extern void *xcalloc (size_t, size_t) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_RESULT_SIZE_1_2 ATTRIBUTE_WARN_UNUSED_RESULT; + +/* Copy a string into a memory buffer without fail. */ + +extern char *xstrdup (const char *) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_WARN_UNUSED_RESULT; + +/* Copy at most N characters from string into a buffer without fail. */ + +extern char *xstrndup (const char *, size_t) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_WARN_UNUSED_RESULT; + +/* Copy an existing memory buffer to a new memory buffer without fail. */ + +extern void *xmemdup (const void *, size_t, size_t) ATTRIBUTE_MALLOC ATTRIBUTE_RETURNS_NONNULL ATTRIBUTE_WARN_UNUSED_RESULT; + +/* Physical memory routines. Return values are in BYTES. */ +extern double physmem_total (void); +extern double physmem_available (void); + +/* Compute the 32-bit CRC of a block of memory. */ +extern unsigned int xcrc32 (const unsigned char *, int, unsigned int); + +/* These macros provide a K&R/C89/C++-friendly way of allocating structures + with nice encapsulation. The XDELETE*() macros are technically + superfluous, but provided here for symmetry. Using them consistently + makes it easier to update client code to use different allocators such + as new/delete and new[]/delete[]. */ + +/* Scalar allocators. */ + +#define XALLOCA(T) ((T *) alloca (sizeof (T))) +#define XNEW(T) ((T *) xmalloc (sizeof (T))) +#define XCNEW(T) ((T *) xcalloc (1, sizeof (T))) +#define XDUP(T, P) ((T *) xmemdup ((P), sizeof (T), sizeof (T))) +#define XDELETE(P) free ((void*) (P)) + +/* Array allocators. */ + +#define XALLOCAVEC(T, N) ((T *) alloca (sizeof (T) * (N))) +#define XNEWVEC(T, N) ((T *) xmalloc (sizeof (T) * (N))) +#define XCNEWVEC(T, N) ((T *) xcalloc ((N), sizeof (T))) +#define XDUPVEC(T, P, N) ((T *) xmemdup ((P), sizeof (T) * (N), sizeof (T) * (N))) +#define XRESIZEVEC(T, P, N) ((T *) xrealloc ((void *) (P), sizeof (T) * (N))) +#define XDELETEVEC(P) free ((void*) (P)) + +/* Allocators for variable-sized structures and raw buffers. */ + +#define XALLOCAVAR(T, S) ((T *) alloca ((S))) +#define XNEWVAR(T, S) ((T *) xmalloc ((S))) +#define XCNEWVAR(T, S) ((T *) xcalloc (1, (S))) +#define XDUPVAR(T, P, S1, S2) ((T *) xmemdup ((P), (S1), (S2))) +#define XRESIZEVAR(T, P, S) ((T *) xrealloc ((P), (S))) + +/* Type-safe obstack allocator. */ + +#define XOBNEW(O, T) ((T *) obstack_alloc ((O), sizeof (T))) +#define XOBNEWVEC(O, T, N) ((T *) obstack_alloc ((O), sizeof (T) * (N))) +#define XOBNEWVAR(O, T, S) ((T *) obstack_alloc ((O), (S))) +#define XOBFINISH(O, T) ((T) obstack_finish ((O))) + +/* hex character manipulation routines */ + +#define _hex_array_size 256 +#define _hex_bad 99 +extern const unsigned char _hex_value[_hex_array_size]; +extern void hex_init (void); +#define hex_p(c) (hex_value (c) != _hex_bad) +/* If you change this, note well: Some code relies on side effects in + the argument being performed exactly once. */ +#define hex_value(c) ((unsigned int) _hex_value[(unsigned char) (c)]) + +/* Flags for pex_init. These are bits to be or'ed together. */ + +/* Record subprocess times, if possible. */ +#define PEX_RECORD_TIMES 0x1 + +/* Use pipes for communication between processes, if possible. */ +#define PEX_USE_PIPES 0x2 + +/* Save files used for communication between processes. */ +#define PEX_SAVE_TEMPS 0x4 + +/* Max number of alloca bytes per call before we must switch to malloc. + + ?? Swiped from gnulib's regex_internal.h header. Is this actually + the case? This number seems arbitrary, though sane. + + The OS usually guarantees only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + allocate anything larger than 4096 bytes. Also care for the possibility + of a few compiler-allocated temporary stack slots. */ +#define MAX_ALLOCA_SIZE 4032 + +/* Prepare to execute one or more programs, with standard output of + each program fed to standard input of the next. + FLAGS As above. + PNAME The name of the program to report in error messages. + TEMPBASE A base name to use for temporary files; may be NULL to + use a random name. + Returns NULL on error. */ + +extern struct pex_obj *pex_init (int flags, const char *pname, + const char *tempbase) ATTRIBUTE_RETURNS_NONNULL; + +/* Flags for pex_run. These are bits to be or'ed together. */ + +/* Last program in pipeline. Standard output of program goes to + OUTNAME, or, if OUTNAME is NULL, to standard output of caller. Do + not set this if you want to call pex_read_output. After this is + set, pex_run may no longer be called with the same struct + pex_obj. */ +#define PEX_LAST 0x1 + +/* Search for program in executable search path. */ +#define PEX_SEARCH 0x2 + +/* OUTNAME is a suffix. */ +#define PEX_SUFFIX 0x4 + +/* Send program's standard error to standard output. */ +#define PEX_STDERR_TO_STDOUT 0x8 + +/* Input file should be opened in binary mode. This flag is ignored + on Unix. */ +#define PEX_BINARY_INPUT 0x10 + +/* Output file should be opened in binary mode. This flag is ignored + on Unix. For proper behaviour PEX_BINARY_INPUT and + PEX_BINARY_OUTPUT have to match appropriately--i.e., a call using + PEX_BINARY_OUTPUT should be followed by a call using + PEX_BINARY_INPUT. */ +#define PEX_BINARY_OUTPUT 0x20 + +/* Capture stderr to a pipe. The output can be read by + calling pex_read_err and reading from the returned + FILE object. This flag may be specified only for + the last program in a pipeline. + + This flag is supported only on Unix and Windows. */ +#define PEX_STDERR_TO_PIPE 0x40 + +/* Capture stderr in binary mode. This flag is ignored + on Unix. */ +#define PEX_BINARY_ERROR 0x80 + +/* Append stdout to existing file instead of truncating it. */ +#define PEX_STDOUT_APPEND 0x100 + +/* Thes same as PEX_STDOUT_APPEND, but for STDERR. */ +#define PEX_STDERR_APPEND 0x200 + +/* Execute one program. Returns NULL on success. On error returns an + error string (typically just the name of a system call); the error + string is statically allocated. + + OBJ Returned by pex_init. + + FLAGS As above. + + EXECUTABLE The program to execute. + + ARGV NULL terminated array of arguments to pass to the program. + + OUTNAME Sets the output file name as follows: + + PEX_SUFFIX set (OUTNAME may not be NULL): + TEMPBASE parameter to pex_init not NULL: + Output file name is the concatenation of TEMPBASE + and OUTNAME. + TEMPBASE is NULL: + Output file name is a random file name ending in + OUTNAME. + PEX_SUFFIX not set: + OUTNAME not NULL: + Output file name is OUTNAME. + OUTNAME NULL, TEMPBASE not NULL: + Output file name is randomly chosen using + TEMPBASE. + OUTNAME NULL, TEMPBASE NULL: + Output file name is randomly chosen. + + If PEX_LAST is not set, the output file name is the + name to use for a temporary file holding stdout, if + any (there will not be a file if PEX_USE_PIPES is set + and the system supports pipes). If a file is used, it + will be removed when no longer needed unless + PEX_SAVE_TEMPS is set. + + If PEX_LAST is set, and OUTNAME is not NULL, standard + output is written to the output file name. The file + will not be removed. If PEX_LAST and PEX_SUFFIX are + both set, TEMPBASE may not be NULL. + + ERRNAME If not NULL, this is the name of a file to which + standard error is written. If NULL, standard error of + the program is standard error of the caller. + + ERR On an error return, *ERR is set to an errno value, or + to 0 if there is no relevant errno. +*/ + +extern const char *pex_run (struct pex_obj *obj, int flags, + const char *executable, char * const *argv, + const char *outname, const char *errname, + int *err); + +/* As for pex_run (), but takes an extra parameter to enable the + environment for the child process to be specified. + + ENV The environment for the child process, specified as + an array of character pointers. Each element of the + array should point to a string of the form VAR=VALUE, + with the exception of the last element which must be + a null pointer. +*/ + +extern const char *pex_run_in_environment (struct pex_obj *obj, int flags, + const char *executable, + char * const *argv, + char * const *env, + const char *outname, + const char *errname, int *err); + +/* Return a stream for a temporary file to pass to the first program + in the pipeline as input. The file name is chosen as for pex_run. + pex_run closes the file automatically; don't close it yourself. */ + +extern FILE *pex_input_file (struct pex_obj *obj, int flags, + const char *in_name); + +/* Return a stream for a pipe connected to the standard input of the + first program in the pipeline. You must have passed + `PEX_USE_PIPES' to `pex_init'. Close the returned stream + yourself. */ + +extern FILE *pex_input_pipe (struct pex_obj *obj, int binary); + +/* Read the standard output of the last program to be executed. + pex_run cannot be called after this. BINARY should be non-zero if + the file should be opened in binary mode; this is ignored on Unix. + Returns NULL on error. Don't call fclose on the returned FILE; it + will be closed by pex_free. */ + +extern FILE *pex_read_output (struct pex_obj *, int binary); + +/* Read the standard error of the last program to be executed. + pex_run cannot be called after this. BINARY should be non-zero if + the file should be opened in binary mode; this is ignored on Unix. + Returns NULL on error. Don't call fclose on the returned FILE; it + will be closed by pex_free. */ + +extern FILE *pex_read_err (struct pex_obj *, int binary); + +/* Return exit status of all programs in VECTOR. COUNT indicates the + size of VECTOR. The status codes in the vector are in the order of + the calls to pex_run. Returns 0 on error, 1 on success. */ + +extern int pex_get_status (struct pex_obj *, int count, int *vector); + +/* Return times of all programs in VECTOR. COUNT indicates the size + of VECTOR. struct pex_time is really just struct timeval, but that + is not portable to all systems. Returns 0 on error, 1 on + success. */ + +struct pex_time +{ + unsigned long user_seconds; + unsigned long user_microseconds; + unsigned long system_seconds; + unsigned long system_microseconds; +}; + +extern int pex_get_times (struct pex_obj *, int count, + struct pex_time *vector); + +/* Clean up a pex_obj. If you have not called pex_get_times or + pex_get_status, this will try to kill the subprocesses. */ + +extern void pex_free (struct pex_obj *); + +/* Just execute one program. Return value is as for pex_run. + FLAGS Combination of PEX_SEARCH and PEX_STDERR_TO_STDOUT. + EXECUTABLE As for pex_run. + ARGV As for pex_run. + PNAME As for pex_init. + OUTNAME As for pex_run when PEX_LAST is set. + ERRNAME As for pex_run. + STATUS Set to exit status on success. + ERR As for pex_run. +*/ + +extern const char *pex_one (int flags, const char *executable, + char * const *argv, const char *pname, + const char *outname, const char *errname, + int *status, int *err); + +/* pexecute and pwait are the old pexecute interface, still here for + backward compatibility. Don't use these for new code. Instead, + use pex_init/pex_run/pex_get_status/pex_free, or pex_one. */ + +/* Definitions used by the pexecute routine. */ + +#define PEXECUTE_FIRST 1 +#define PEXECUTE_LAST 2 +#define PEXECUTE_ONE (PEXECUTE_FIRST + PEXECUTE_LAST) +#define PEXECUTE_SEARCH 4 +#define PEXECUTE_VERBOSE 8 + +/* Execute a program. */ + +extern int pexecute (const char *, char * const *, const char *, + const char *, char **, char **, int); + +/* Wait for pexecute to finish. */ + +extern int pwait (int, int *, int); + +/* Like bsearch, but takes and passes on an argument like qsort_r. */ + +extern void *bsearch_r (const void *, const void *, + size_t, size_t, + int (*)(const void *, const void *, void *), + void *); + +#if defined(HAVE_DECL_ASPRINTF) && !HAVE_DECL_ASPRINTF +/* Like sprintf but provides a pointer to malloc'd storage, which must + be freed by the caller. */ + +extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2; +#endif + +/* Like asprintf but allocates memory without fail. This works like + xmalloc. */ + +extern char *xasprintf (const char *, ...) ATTRIBUTE_MALLOC ATTRIBUTE_PRINTF_1; + +#if defined(HAVE_DECL_VASPRINTF) && !HAVE_DECL_VASPRINTF +/* Like vsprintf but provides a pointer to malloc'd storage, which + must be freed by the caller. */ + +extern int vasprintf (char **, const char *, va_list) ATTRIBUTE_PRINTF(2,0); +#endif + +/* Like vasprintf but allocates memory without fail. This works like + xmalloc. */ + +extern char *xvasprintf (const char *, va_list) ATTRIBUTE_MALLOC ATTRIBUTE_PRINTF(1,0); + +#if defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF +/* Like sprintf but prints at most N characters. */ +extern int snprintf (char *, size_t, const char *, ...) ATTRIBUTE_PRINTF_3; +#endif + +#if defined(HAVE_DECL_VSNPRINTF) && !HAVE_DECL_VSNPRINTF +/* Like vsprintf but prints at most N characters. */ +extern int vsnprintf (char *, size_t, const char *, va_list) ATTRIBUTE_PRINTF(3,0); +#endif + +#if defined (HAVE_DECL_STRNLEN) && !HAVE_DECL_STRNLEN +extern size_t strnlen (const char *, size_t); +#endif + +#if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP +/* Compare version strings. */ +extern int strverscmp (const char *, const char *); +#endif + +#if defined(HAVE_DECL_STRTOL) && !HAVE_DECL_STRTOL +extern long int strtol (const char *nptr, + char **endptr, int base); +#endif + +#if defined(HAVE_DECL_STRTOUL) && !HAVE_DECL_STRTOUL +extern unsigned long int strtoul (const char *nptr, + char **endptr, int base); +#endif + +#if defined(HAVE_LONG_LONG) && defined(HAVE_DECL_STRTOLL) && !HAVE_DECL_STRTOLL +__extension__ +extern long long int strtoll (const char *nptr, + char **endptr, int base); +#endif + +#if defined(HAVE_LONG_LONG) && defined(HAVE_DECL_STRTOULL) && !HAVE_DECL_STRTOULL +__extension__ +extern unsigned long long int strtoull (const char *nptr, + char **endptr, int base); +#endif + +/* Set the title of a process */ +extern void setproctitle (const char *name, ...); + +/* Increase stack limit if possible. */ +extern void stack_limit_increase (unsigned long); + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +/* Drastically simplified alloca configurator. If we're using GCC, + we use __builtin_alloca; otherwise we use the C alloca. The C + alloca is always available. You can override GCC by defining + USE_C_ALLOCA yourself. The canonical autoconf macro C_ALLOCA is + also set/unset as it is often used to indicate whether code needs + to call alloca(0). */ +extern void *C_alloca (size_t) ATTRIBUTE_MALLOC; +#undef alloca +#if GCC_VERSION >= 2000 && !defined USE_C_ALLOCA +# define alloca(x) __builtin_alloca(x) +# undef C_ALLOCA +# define ASTRDUP(X) \ + (__extension__ ({ const char *const libiberty_optr = (X); \ + const unsigned long libiberty_len = strlen (libiberty_optr) + 1; \ + char *const libiberty_nptr = (char *) alloca (libiberty_len); \ + (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len); })) +#else +# define alloca(x) C_alloca(x) +# undef USE_C_ALLOCA +# define USE_C_ALLOCA 1 +# undef C_ALLOCA +# define C_ALLOCA 1 +extern const char *libiberty_optr; +extern char *libiberty_nptr; +extern unsigned long libiberty_len; +# define ASTRDUP(X) \ + (libiberty_optr = (X), \ + libiberty_len = strlen (libiberty_optr) + 1, \ + libiberty_nptr = (char *) alloca (libiberty_len), \ + (char *) memcpy (libiberty_nptr, libiberty_optr, libiberty_len)) +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* ! defined (LIBIBERTY_H) */ diff --git a/support/cpp/libcpp/include/line-map.h b/support/cpp/libcpp/include/line-map.h index 3234423ff..80335721e 100644 --- a/support/cpp/libcpp/include/line-map.h +++ b/support/cpp/libcpp/include/line-map.h @@ -1,6 +1,5 @@ -/* Map logical line numbers to (source file, line number) pairs. - Copyright (C) 2001, 2003, 2004, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. +/* Map (unsigned int) keys to (source file, line, column) triples. + Copyright (C) 2001-2022 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 @@ -27,59 +26,765 @@ along with this program; see the file COPYING3. If not see #define GTY(x) /* nothing */ #endif -/* Reason for adding a line change with add_line_map (). LC_ENTER is - when including a new file, e.g. a #include directive in C. - LC_LEAVE is when reaching a file's end. LC_RENAME is when a file - name or line number changes for neither of the above reasons - (e.g. a #line directive in C); LC_RENAME_VERBATIM is like LC_RENAME - but a filename of "" is not specially interpreted as standard input. */ -enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME, LC_RENAME_VERBATIM}; +/* Both gcc and emacs number source *lines* starting at 1, but + they have differing conventions for *columns*. + + GCC uses a 1-based convention for source columns, + whereas Emacs's M-x column-number-mode uses a 0-based convention. + + For example, an error in the initial, left-hand + column of source line 3 is reported by GCC as: + + some-file.c:3:1: error: ...etc... + + On navigating to the location of that error in Emacs + (e.g. via "next-error"), + the locus is reported in the Mode Line + (assuming M-x column-number-mode) as: + + some-file.c 10% (3, 0) + + i.e. "3:1:" in GCC corresponds to "(3, 0)" in Emacs. */ /* The type of line numbers. */ typedef unsigned int linenum_type; -/* A logical line/column number, i.e. an "index" into a line_map. */ -typedef unsigned int source_location; +/* A type for doing arithmetic on line numbers. */ +typedef long long linenum_arith_t; + +/* A function for for use by qsort for comparing line numbers. */ + +inline int compare (linenum_type lhs, linenum_type rhs) +{ + /* Avoid truncation issues by using linenum_arith_t for the comparison, + and only consider the sign of the result. */ + linenum_arith_t diff = (linenum_arith_t)lhs - (linenum_arith_t)rhs; + if (diff) + return diff > 0 ? 1 : -1; + return 0; +} + +/* Reason for creating a new line map with linemap_add. */ +enum lc_reason +{ + LC_ENTER = 0, /* Begin #include. */ + LC_LEAVE, /* Return to including file. */ + LC_RENAME, /* Other reason for name change. */ + LC_RENAME_VERBATIM, /* Likewise, but "" != stdin. */ + LC_ENTER_MACRO, /* Begin macro expansion. */ + LC_MODULE, /* A (C++) Module. */ + /* FIXME: add support for stringize and paste. */ + LC_HWM /* High Water Mark. */ +}; + +/* The typedef "location_t" is a key within the location database, + identifying a source location or macro expansion, along with range + information, and (optionally) a pointer for use by gcc. + + This key only has meaning in relation to a line_maps instance. Within + gcc there is a single line_maps instance: "line_table", declared in + gcc/input.h and defined in gcc/input.cc. + + The values of the keys are intended to be internal to libcpp, + but for ease-of-understanding the implementation, they are currently + assigned as follows: + + Actual | Value | Meaning + -----------+-------------------------------+------------------------------- + 0x00000000 | UNKNOWN_LOCATION (gcc/input.h)| Unknown/invalid location. + -----------+-------------------------------+------------------------------- + 0x00000001 | BUILTINS_LOCATION | The location for declarations + | (gcc/input.h) | in "<built-in>" + -----------+-------------------------------+------------------------------- + 0x00000002 | RESERVED_LOCATION_COUNT | The first location to be + | (also | handed out, and the + | ordmap[0]->start_location) | first line in ordmap 0 + -----------+-------------------------------+------------------------------- + | ordmap[1]->start_location | First line in ordmap 1 + | ordmap[1]->start_location+32 | First column in that line + | (assuming range_bits == 5) | + | ordmap[1]->start_location+64 | 2nd column in that line + | ordmap[1]->start_location+4096| Second line in ordmap 1 + | (assuming column_bits == 12) + | + | Subsequent lines are offset by (1 << column_bits), + | e.g. 4096 for 12 bits, with a column value of 0 representing + | "the whole line". + | + | Within a line, the low "range_bits" (typically 5) are used for + | storing short ranges, so that there's an offset of + | (1 << range_bits) between individual columns within a line, + | typically 32. + | The low range_bits store the offset of the end point from the + | start point, and the start point is found by masking away + | the range bits. + | + | For example: + | ordmap[1]->start_location+64 "2nd column in that line" + | above means a caret at that location, with a range + | starting and finishing at the same place (the range bits + | are 0), a range of length 1. + | + | By contrast: + | ordmap[1]->start_location+68 + | has range bits 0x4, meaning a caret with a range starting at + | that location, but with endpoint 4 columns further on: a range + | of length 5. + | + | Ranges that have caret != start, or have an endpoint too + | far away to fit in range_bits are instead stored as ad-hoc + | locations. Hence for range_bits == 5 we can compactly store + | tokens of length <= 32 without needing to use the ad-hoc + | table. + | + | This packing scheme means we effectively have + | (column_bits - range_bits) + | of bits for the columns, typically (12 - 5) = 7, for 128 + | columns; longer line widths are accomodated by starting a + | new ordmap with a higher column_bits. + | + | ordmap[2]->start_location-1 | Final location in ordmap 1 + -----------+-------------------------------+------------------------------- + | ordmap[2]->start_location | First line in ordmap 2 + | ordmap[3]->start_location-1 | Final location in ordmap 2 + -----------+-------------------------------+------------------------------- + | | (etc) + -----------+-------------------------------+------------------------------- + | ordmap[n-1]->start_location | First line in final ord map + | | (etc) + | set->highest_location - 1 | Final location in that ordmap + -----------+-------------------------------+------------------------------- + | set->highest_location | Location of the where the next + | | ordinary linemap would start + -----------+-------------------------------+------------------------------- + | | + | VVVVVVVVVVVVVVVVVVVVVVVVVVV + | Ordinary maps grow this way + | + | (unallocated integers) + | + 0x60000000 | LINE_MAP_MAX_LOCATION_WITH_COLS + | Beyond this point, ordinary linemaps have 0 bits per column: + | each increment of the value corresponds to a new source line. + | + 0x70000000 | LINE_MAP_MAX_LOCATION + | Beyond the point, we give up on ordinary maps; attempts to + | create locations in them lead to UNKNOWN_LOCATION (0). + | + | (unallocated integers) + | + | Macro maps grow this way + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | | + -----------+-------------------------------+------------------------------- + | LINEMAPS_MACRO_LOWEST_LOCATION| Locations within macro maps + | macromap[m-1]->start_location | Start of last macro map + | | + -----------+-------------------------------+------------------------------- + | macromap[m-2]->start_location | Start of penultimate macro map + -----------+-------------------------------+------------------------------- + | macromap[1]->start_location | Start of macro map 1 + -----------+-------------------------------+------------------------------- + | macromap[0]->start_location | Start of macro map 0 + 0x7fffffff | MAX_LOCATION_T | Also used as a mask for + | | accessing the ad-hoc data table + -----------+-------------------------------+------------------------------- + 0x80000000 | Start of ad-hoc values; the lower 31 bits are used as an index + ... | into the line_table->location_adhoc_data_map.data array. + 0xffffffff | UINT_MAX | + -----------+-------------------------------+------------------------------- + + Examples of location encoding. + + Packed ranges + ============= + + Consider encoding the location of a token "foo", seen underlined here + on line 523, within an ordinary line_map that starts at line 500: + + 11111111112 + 12345678901234567890 + 522 + 523 return foo + bar; + ^~~ + 524 + + The location's caret and start are both at line 523, column 11; the + location's finish is on the same line, at column 13 (an offset of 2 + columns, for length 3). + + Line 523 is offset 23 from the starting line of the ordinary line_map. + + caret == start, and the offset of the finish fits within 5 bits, so + this can be stored as a packed range. + + This is encoded as: + ordmap->start + + (line_offset << ordmap->m_column_and_range_bits) + + (column << ordmap->m_range_bits) + + (range_offset); + i.e. (for line offset 23, column 11, range offset 2): + ordmap->start + + (23 << 12) + + (11 << 5) + + 2; + i.e.: + ordmap->start + 0x17162 + assuming that the line_map uses the default of 7 bits for columns and + 5 bits for packed range (giving 12 bits for m_column_and_range_bits). + + + "Pure" locations + ================ + + These are a special case of the above, where + caret == start == finish + They are stored as packed ranges with offset == 0. + For example, the location of the "f" of "foo" could be stored + as above, but with range offset 0, giving: + ordmap->start + + (23 << 12) + + (11 << 5) + + 0; + i.e.: + ordmap->start + 0x17160 + + + Unoptimized ranges + ================== + + Consider encoding the location of the binary expression + below: + + 11111111112 + 12345678901234567890 + 522 + 523 return foo + bar; + ~~~~^~~~~ + 524 + + The location's caret is at the "+", line 523 column 15, but starts + earlier, at the "f" of "foo" at column 11. The finish is at the "r" + of "bar" at column 19. + + This can't be stored as a packed range since start != caret. + Hence it is stored as an ad-hoc location e.g. 0x80000003. + + Stripping off the top bit gives us an index into the ad-hoc + lookaside table: + + line_table->location_adhoc_data_map.data[0x3] + + from which the caret, start and finish can be looked up, + encoded as "pure" locations: + + start == ordmap->start + (23 << 12) + (11 << 5) + == ordmap->start + 0x17160 (as above; the "f" of "foo") + + caret == ordmap->start + (23 << 12) + (15 << 5) + == ordmap->start + 0x171e0 + + finish == ordmap->start + (23 << 12) + (19 << 5) + == ordmap->start + 0x17260 + + To further see how location_t works in practice, see the + worked example in libcpp/location-example.txt. */ +typedef unsigned int location_t; + +/* Do not track column numbers higher than this one. As a result, the + range of column_bits is [12, 18] (or 0 if column numbers are + disabled). */ +const unsigned int LINE_MAP_MAX_COLUMN_NUMBER = (1U << 12); + +/* Do not pack ranges if locations get higher than this. + If you change this, update: + gcc.dg/plugin/location-overflow-test-*.c. */ +const location_t LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES = 0x50000000; + +/* Do not track column numbers if locations get higher than this. + If you change this, update: + gcc.dg/plugin/location-overflow-test-*.c. */ +const location_t LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000; + +/* Highest possible source location encoded within an ordinary map. */ +const location_t LINE_MAP_MAX_LOCATION = 0x70000000; + +/* A range of source locations. + + Ranges are closed: + m_start is the first location within the range, + m_finish is the last location within the range. + + We may need a more compact way to store these, but for now, + let's do it the simple way, as a pair. */ +struct GTY(()) source_range +{ + location_t m_start; + location_t m_finish; + + /* We avoid using constructors, since various structs that + don't yet have constructors will embed instances of + source_range. */ + + /* Make a source_range from a location_t. */ + static source_range from_location (location_t loc) + { + source_range result; + result.m_start = loc; + result.m_finish = loc; + return result; + } + + /* Make a source_range from a pair of location_t. */ + static source_range from_locations (location_t start, + location_t finish) + { + source_range result; + result.m_start = start; + result.m_finish = finish; + return result; + } +}; /* Memory allocation function typedef. Works like xrealloc. */ typedef void *(*line_map_realloc) (void *, size_t); -/* Physical source file TO_FILE at line TO_LINE at column 0 is represented +/* Memory allocator function that returns the actual allocated size, + for a given requested allocation. */ +typedef size_t (*line_map_round_alloc_size_func) (size_t); + +/* A line_map encodes a sequence of locations. + There are two kinds of maps. Ordinary maps and macro expansion + maps, a.k.a macro maps. + + A macro map encodes source locations of tokens that are part of a + macro replacement-list, at a macro expansion point. E.g, in: + + #define PLUS(A,B) A + B + + No macro map is going to be created there, because we are not at a + macro expansion point. We are at a macro /definition/ point. So the + locations of the tokens of the macro replacement-list (i.e, A + B) + will be locations in an ordinary map, not a macro map. + + On the other hand, if we later do: + + int a = PLUS (1,2); + + The invocation of PLUS here is a macro expansion. So we are at a + macro expansion point. The preprocessor expands PLUS (1,2) and + replaces it with the tokens of its replacement-list: 1 + 2. A macro + map is going to be created to hold (or rather to map, haha ...) the + locations of the tokens 1, + and 2. The macro map also records the + location of the expansion point of PLUS. That location is mapped in + the map that is active right before the location of the invocation + of PLUS. */ + +/* This contains GTY mark-up to support precompiled headers. + line_map is an abstract class, only derived objects exist. */ +struct GTY((tag ("0"), desc ("MAP_ORDINARY_P (&%h) ? 1 : 2"))) line_map { + location_t start_location; + + /* Size and alignment is (usually) 4 bytes. */ +}; + +/* An ordinary line map encodes physical source locations. Those + physical source locations are called "spelling locations". + + Physical source file TO_FILE at line TO_LINE at column 0 is represented by the logical START_LOCATION. TO_LINE+L at column C is represented by - START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits), - and the result_location is less than the next line_map's start_location. + START_LOCATION+(L*(1<<m_column_and_range_bits))+(C*1<<m_range_bits), as + long as C<(1<<effective range bits), and the result_location is less than + the next line_map's start_location. (The top line is line 1 and the leftmost column is column 1; line/column 0 means "entire file/line" or "unknown line/column" or "not applicable".) - INCLUDED_FROM is an index into the set that gives the line mapping - at whose end the current one was included. File(s) at the bottom - of the include stack have this set to -1. REASON is the reason for - creation of this line map, SYSP is one for a system header, two for - a C system header file that therefore needs to be extern "C" - protected in C++, and zero otherwise. */ -struct GTY(()) line_map { + + The highest possible source location is MAX_LOCATION_T. */ +struct GTY((tag ("1"))) line_map_ordinary : public line_map { + /* Base class is 4 bytes. */ + + /* 4 bytes of integers, each 1 byte for easy extraction/insertion. */ + + /* The reason for creation of this line map. */ + ENUM_BITFIELD (lc_reason) reason : 8; + + /* 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. This field isn't really needed now that it's in + cpp_buffer. */ + unsigned char sysp; + + /* Number of the low-order location_t bits used for column numbers + and ranges. */ + unsigned int m_column_and_range_bits : 8; + + /* Number of the low-order "column" bits used for storing short ranges + inline, rather than in the ad-hoc table. + MSB LSB + 31 0 + +-------------------------+-------------------------------------------+ + | |<---map->column_and_range_bits (e.g. 12)-->| + +-------------------------+-----------------------+-------------------+ + | | column_and_range_bits | map->range_bits | + | | - range_bits | | + +-------------------------+-----------------------+-------------------+ + | row bits | effective column bits | short range bits | + | | (e.g. 7) | (e.g. 5) | + +-------------------------+-----------------------+-------------------+ */ + unsigned int m_range_bits : 8; + + /* Pointer alignment boundary on both 32 and 64-bit systems. */ + const char *to_file; linenum_type to_line; - source_location start_location; - int included_from; - ENUM_BITFIELD (lc_reason) reason : CHAR_BIT; - /* The sysp field isn't really needed now that it's in cpp_buffer. */ - unsigned char sysp; - /* Number of the low-order source_location bits used for a column number. */ - unsigned int column_bits : 8; + + /* Location from whence this line map was included. For regular + #includes, this location will be the last location of a map. For + outermost file, this is 0. For modules it could be anywhere + within a map. */ + location_t included_from; + + /* Size is 20 or 24 bytes, no padding */ }; -/* A set of chronological line_map structures. */ -struct GTY(()) line_maps { - struct line_map * GTY ((length ("%h.used"))) maps; +/* This is the highest possible source location encoded within an + ordinary or macro map. */ +const location_t MAX_LOCATION_T = 0x7FFFFFFF; + +struct cpp_hashnode; + +/* A macro line map encodes location of tokens coming from a macro + expansion. + + The offset from START_LOCATION is used to index into + MACRO_LOCATIONS; this holds the original location of the token. */ +struct GTY((tag ("2"))) line_map_macro : public line_map { + /* Base is 4 bytes. */ + + /* The number of tokens inside the replacement-list of MACRO. */ + unsigned int n_tokens; + + /* Pointer alignment boundary. */ + + /* The cpp macro whose expansion gave birth to this macro map. */ + struct 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"))) + macro; + + /* This array of location is actually an array of pairs of + locations. The elements inside it thus look like: + + x0,y0, x1,y1, x2,y2, ...., xn,yn. + + where n == n_tokens; + + Remember that these xI,yI are collected when libcpp is about to + expand a given macro. + + yI is the location in the macro definition, either of the token + itself or of a macro parameter that it replaces. + + Imagine this: + + #define PLUS(A, B) A + B <--- #1 + + int a = PLUS (1,2); <--- #2 + + There is a macro map for the expansion of PLUS in #2. PLUS is + expanded into its expansion-list. The expansion-list is the + replacement-list of PLUS where the macro parameters are replaced + with their arguments. So the replacement-list of PLUS is made of + the tokens: + + A, +, B + + and the expansion-list is made of the tokens: + + 1, +, 2 + + Let's consider the case of token "+". Its y1 [yI for I == 1] is + its spelling location in #1. + + y0 (thus for token "1") is the spelling location of A in #1. + + And y2 (of token "2") is the spelling location of B in #1. + + When the token is /not/ an argument for a macro, xI is the same + location as yI. Otherwise, xI is the location of the token + outside this macro expansion. If this macro was expanded from + another macro expansion, xI is a virtual location representing + the token in that macro expansion; otherwise, it is the spelling + location of the token. + + Note that a virtual location is a location returned by + linemap_add_macro_token. It encodes the relevant locations (x,y + pairs) of that token across the macro expansions from which it + (the token) might come from. + + In the example above x1 (for token "+") is going to be the same + as y1. x0 is the spelling location for the argument token "1", + and x2 is the spelling location for the argument token "2". */ + location_t * GTY((atomic)) macro_locations; + + /* This is the location of the expansion point of the current macro + map. It's the location of the macro name. That location is held + by the map that was current right before the current one. It + could have been either a macro or an ordinary map, depending on + if we are in a nested expansion context not. */ + location_t expansion; + + /* Size is 20 or 32 (4 bytes padding on 64-bit). */ +}; + +#if CHECKING_P && (GCC_VERSION >= 2007) + +/* Assertion macro to be used in line-map code. */ +#define linemap_assert(EXPR) \ + do { \ + if (! (EXPR)) \ + abort (); \ + } while (0) + +/* Assert that becomes a conditional expression when checking is disabled at + compilation time. Use this for conditions that should not happen but if + they happen, it is better to handle them gracefully rather than crash + randomly later. + Usage: + + if (linemap_assert_fails(EXPR)) handle_error(); */ +#define linemap_assert_fails(EXPR) __extension__ \ + ({linemap_assert (EXPR); false;}) + +#else +/* Include EXPR, so that unused variable warnings do not occur. */ +#define linemap_assert(EXPR) ((void)(0 && (EXPR))) +#define linemap_assert_fails(EXPR) (! (EXPR)) +#endif + +/* Get whether location LOC is an ordinary location. */ + +inline bool +IS_ORDINARY_LOC (location_t loc) +{ + return loc < LINE_MAP_MAX_LOCATION; +} + +/* Get whether location LOC is an ad-hoc location. */ + +inline bool +IS_ADHOC_LOC (location_t loc) +{ + return loc > MAX_LOCATION_T; +} + +/* Categorize line map kinds. */ + +inline bool +MAP_ORDINARY_P (const line_map *map) +{ + return IS_ORDINARY_LOC (map->start_location); +} + +/* Return TRUE if MAP encodes locations coming from a macro + replacement-list at macro expansion point. */ +bool +linemap_macro_expansion_map_p (const line_map *); + +/* Assert that MAP encodes locations of tokens that are not part of + the replacement-list of a macro expansion, downcasting from + line_map * to line_map_ordinary *. */ + +inline line_map_ordinary * +linemap_check_ordinary (line_map *map) +{ + linemap_assert (MAP_ORDINARY_P (map)); + return (line_map_ordinary *)map; +} + +/* Assert that MAP encodes locations of tokens that are not part of + the replacement-list of a macro expansion, downcasting from + const line_map * to const line_map_ordinary *. */ + +inline const line_map_ordinary * +linemap_check_ordinary (const line_map *map) +{ + linemap_assert (MAP_ORDINARY_P (map)); + return (const line_map_ordinary *)map; +} + +/* Assert that MAP is a macro expansion and downcast to the appropriate + subclass. */ + +inline line_map_macro *linemap_check_macro (line_map *map) +{ + linemap_assert (!MAP_ORDINARY_P (map)); + return (line_map_macro *)map; +} + +/* Assert that MAP is a macro expansion and downcast to the appropriate + subclass. */ + +inline const line_map_macro * +linemap_check_macro (const line_map *map) +{ + linemap_assert (!MAP_ORDINARY_P (map)); + return (const line_map_macro *)map; +} + +/* Read the start location of MAP. */ + +inline location_t +MAP_START_LOCATION (const line_map *map) +{ + return map->start_location; +} + +/* Get the starting line number of ordinary map MAP. */ + +inline linenum_type +ORDINARY_MAP_STARTING_LINE_NUMBER (const line_map_ordinary *ord_map) +{ + return ord_map->to_line; +} + +/* Return a positive value if map encodes locations from a system + header, 0 otherwise. Returns 1 if ordinary map MAP encodes locations + in a system header and 2 if it encodes locations in a C system header + that therefore needs to be extern "C" protected in C++. */ + +inline unsigned char +ORDINARY_MAP_IN_SYSTEM_HEADER_P (const line_map_ordinary *ord_map) +{ + return ord_map->sysp; +} + +/* TRUE if this line map is for a module (not a source file). */ + +inline bool +MAP_MODULE_P (const line_map *map) +{ + return (MAP_ORDINARY_P (map) + && linemap_check_ordinary (map)->reason == LC_MODULE); +} + +/* Get the filename of ordinary map MAP. */ + +inline const char * +ORDINARY_MAP_FILE_NAME (const line_map_ordinary *ord_map) +{ + return ord_map->to_file; +} + +/* Get the cpp macro whose expansion gave birth to macro map MAP. */ + +inline cpp_hashnode * +MACRO_MAP_MACRO (const line_map_macro *macro_map) +{ + return macro_map->macro; +} + +/* Get the number of tokens inside the replacement-list of the macro + that led to macro map MAP. */ + +inline unsigned int +MACRO_MAP_NUM_MACRO_TOKENS (const line_map_macro *macro_map) +{ + return macro_map->n_tokens; +} + +/* Get the array of pairs of locations within macro map MAP. + See the declaration of line_map_macro for more information. */ + +inline location_t * +MACRO_MAP_LOCATIONS (const line_map_macro *macro_map) +{ + return macro_map->macro_locations; +} + +/* Get the location of the expansion point of the macro map MAP. */ + +inline location_t +MACRO_MAP_EXPANSION_POINT_LOCATION (const line_map_macro *macro_map) +{ + return macro_map->expansion; +} + +/* The abstraction of a set of location maps. There can be several + types of location maps. This abstraction contains the attributes + that are independent from the type of the map. + + Essentially this is just a vector of T_linemap_subclass, + which can only ever grow in size. */ + +struct GTY(()) maps_info_ordinary { + /* This array contains the "ordinary" line maps, for all + events other than macro expansion + (e.g. when a new preprocessing unit starts or ends). */ + line_map_ordinary * GTY ((length ("%h.used"))) maps; + + /* The total number of allocated maps. */ unsigned int allocated; + + /* The number of elements used in maps. This number is smaller + or equal to ALLOCATED. */ unsigned int used; - unsigned int cache; + mutable unsigned int cache; +}; + +struct GTY(()) maps_info_macro { + /* This array contains the macro line maps. + A macro line map is created whenever a macro expansion occurs. */ + line_map_macro * GTY ((length ("%h.used"))) maps; + + /* The total number of allocated maps. */ + unsigned int allocated; + + /* The number of elements used in maps. This number is smaller + or equal to ALLOCATED. */ + unsigned int used; - /* The most recently listed include stack, if any, starts with - LAST_LISTED as the topmost including file. -1 indicates nothing - has been listed yet. */ - int last_listed; + mutable unsigned int cache; +}; + +/* Data structure to associate a source_range together with an arbitrary + data pointer with a source location. */ +struct GTY(()) location_adhoc_data { + location_t locus; + source_range src_range; + void * GTY((skip)) data; +}; + +struct htab; + +/* The following data structure encodes a location with some adhoc data + and maps it to a new unsigned integer (called an adhoc location) + that replaces the original location to represent the mapping. + + The new adhoc_loc uses the highest bit as the enabling bit, i.e. if the + highest bit is 1, then the number is adhoc_loc. Otherwise, it serves as + the original location. Once identified as the adhoc_loc, the lower 31 + bits of the integer is used to index the location_adhoc_data array, + in which the locus and associated data is stored. */ + +struct GTY(()) location_adhoc_data_map { + struct htab * GTY((skip)) htab; + location_t curr_loc; + unsigned int allocated; + struct location_adhoc_data GTY((length ("%h.allocated"))) *data; +}; + +/* A set of chronological line_map structures. */ +class GTY(()) line_maps { +public: + + ~line_maps (); + + maps_info_ordinary info_ordinary; + + maps_info_macro info_macro; /* Depth of the include stack, including the current file. */ unsigned int depth; @@ -87,107 +792,1326 @@ struct GTY(()) line_maps { /* If true, prints an include trace a la -H. */ bool trace_includes; - /* Highest source_location "given out". */ - source_location highest_location; + /* True if we've seen a #line or # 44 "file" directive. */ + bool seen_line_directive; + + /* Highest location_t "given out". */ + location_t highest_location; - /* Start of line of highest source_location "given out". */ - source_location highest_line; + /* Start of line of highest location_t "given out". */ + location_t highest_line; /* The maximum column number we can quickly allocate. Higher numbers may require allocating a new line_map. */ unsigned int max_column_hint; - /* If non-null, the allocator to use when resizing 'maps'. If null, - xrealloc is used. */ - line_map_realloc reallocator; + /* The allocator to use when resizing 'maps', defaults to xrealloc. */ + line_map_realloc GTY((callback)) reallocator; + + /* The allocators' function used to know the actual size it + allocated, for a certain allocation size requested. */ + line_map_round_alloc_size_func GTY((callback)) round_alloc_size; + + struct location_adhoc_data_map location_adhoc_data_map; + + /* The special location value that is used as spelling location for + built-in tokens. */ + location_t builtin_location; + + /* The default value of range_bits in ordinary line maps. */ + unsigned int default_range_bits; + + unsigned int num_optimized_ranges; + unsigned int num_unoptimized_ranges; }; -/* Initialize a line map set. */ -extern void linemap_init (struct line_maps *); +/* Returns the number of allocated maps so far. MAP_KIND shall be TRUE + if we are interested in macro maps, FALSE otherwise. */ +inline unsigned int +LINEMAPS_ALLOCATED (const line_maps *set, bool map_kind) +{ + if (map_kind) + return set->info_macro.allocated; + else + return set->info_ordinary.allocated; +} + +/* As above, but by reference (e.g. as an lvalue). */ + +inline unsigned int & +LINEMAPS_ALLOCATED (line_maps *set, bool map_kind) +{ + if (map_kind) + return set->info_macro.allocated; + else + return set->info_ordinary.allocated; +} + +/* Returns the number of used maps so far. MAP_KIND shall be TRUE if + we are interested in macro maps, FALSE otherwise.*/ +inline unsigned int +LINEMAPS_USED (const line_maps *set, bool map_kind) +{ + if (map_kind) + return set->info_macro.used; + else + return set->info_ordinary.used; +} + +/* As above, but by reference (e.g. as an lvalue). */ + +inline unsigned int & +LINEMAPS_USED (line_maps *set, bool map_kind) +{ + if (map_kind) + return set->info_macro.used; + else + return set->info_ordinary.used; +} + +/* Returns the index of the last map that was looked up with + linemap_lookup. MAP_KIND shall be TRUE if we are interested in + macro maps, FALSE otherwise. */ +inline unsigned int & +LINEMAPS_CACHE (const line_maps *set, bool map_kind) +{ + if (map_kind) + return set->info_macro.cache; + else + return set->info_ordinary.cache; +} + +/* Return the map at a given index. */ +inline line_map * +LINEMAPS_MAP_AT (const line_maps *set, bool map_kind, int index) +{ + if (map_kind) + return &set->info_macro.maps[index]; + else + return &set->info_ordinary.maps[index]; +} + +/* Returns the last map used in the line table SET. MAP_KIND + shall be TRUE if we are interested in macro maps, FALSE + otherwise.*/ +inline line_map * +LINEMAPS_LAST_MAP (const line_maps *set, bool map_kind) +{ + return LINEMAPS_MAP_AT (set, map_kind, + LINEMAPS_USED (set, map_kind) - 1); +} + +/* Returns the last map that was allocated in the line table SET. + MAP_KIND shall be TRUE if we are interested in macro maps, FALSE + otherwise.*/ +inline line_map * +LINEMAPS_LAST_ALLOCATED_MAP (const line_maps *set, bool map_kind) +{ + return LINEMAPS_MAP_AT (set, map_kind, + LINEMAPS_ALLOCATED (set, map_kind) - 1); +} + +/* Returns a pointer to the memory region where ordinary maps are + allocated in the line table SET. */ +inline line_map_ordinary * +LINEMAPS_ORDINARY_MAPS (const line_maps *set) +{ + return set->info_ordinary.maps; +} + +/* Returns the INDEXth ordinary map. */ +inline line_map_ordinary * +LINEMAPS_ORDINARY_MAP_AT (const line_maps *set, int index) +{ + linemap_assert (index >= 0 + && (unsigned int)index < LINEMAPS_USED (set, false)); + return (line_map_ordinary *)LINEMAPS_MAP_AT (set, false, index); +} + +/* Return the number of ordinary maps allocated in the line table + SET. */ +inline unsigned int +LINEMAPS_ORDINARY_ALLOCATED (const line_maps *set) +{ + return LINEMAPS_ALLOCATED (set, false); +} + +/* Return the number of ordinary maps used in the line table SET. */ +inline unsigned int +LINEMAPS_ORDINARY_USED (const line_maps *set) +{ + return LINEMAPS_USED (set, false); +} + +/* Return the index of the last ordinary map that was looked up with + linemap_lookup. */ +inline unsigned int & +LINEMAPS_ORDINARY_CACHE (const line_maps *set) +{ + return LINEMAPS_CACHE (set, false); +} + +/* Returns a pointer to the last ordinary map used in the line table + SET. */ +inline line_map_ordinary * +LINEMAPS_LAST_ORDINARY_MAP (const line_maps *set) +{ + return (line_map_ordinary *)LINEMAPS_LAST_MAP (set, false); +} + +/* Returns a pointer to the last ordinary map allocated the line table + SET. */ +inline line_map_ordinary * +LINEMAPS_LAST_ALLOCATED_ORDINARY_MAP (const line_maps *set) +{ + return (line_map_ordinary *)LINEMAPS_LAST_ALLOCATED_MAP (set, false); +} + +/* Returns a pointer to the beginning of the region where macro maps + are allocated. */ +inline line_map_macro * +LINEMAPS_MACRO_MAPS (const line_maps *set) +{ + return set->info_macro.maps; +} + +/* Returns the INDEXth macro map. */ +inline line_map_macro * +LINEMAPS_MACRO_MAP_AT (const line_maps *set, int index) +{ + linemap_assert (index >= 0 + && (unsigned int)index < LINEMAPS_USED (set, true)); + return (line_map_macro *)LINEMAPS_MAP_AT (set, true, index); +} + +/* Returns the number of macro maps that were allocated in the line + table SET. */ +inline unsigned int +LINEMAPS_MACRO_ALLOCATED (const line_maps *set) +{ + return LINEMAPS_ALLOCATED (set, true); +} + +/* Returns the number of macro maps used in the line table SET. */ +inline unsigned int +LINEMAPS_MACRO_USED (const line_maps *set) +{ + return LINEMAPS_USED (set, true); +} + +/* Return the index of the last macro map that was looked up with + linemap_lookup. */ +inline unsigned int & +LINEMAPS_MACRO_CACHE (const line_maps *set) +{ + return LINEMAPS_CACHE (set, true); +} + +/* Returns the last macro map used in the line table SET. */ +inline line_map_macro * +LINEMAPS_LAST_MACRO_MAP (const line_maps *set) +{ + return (line_map_macro *)LINEMAPS_LAST_MAP (set, true); +} + +/* Returns the lowest location [of a token resulting from macro + expansion] encoded in this line table. */ +inline location_t +LINEMAPS_MACRO_LOWEST_LOCATION (const line_maps *set) +{ + return LINEMAPS_MACRO_USED (set) + ? MAP_START_LOCATION (LINEMAPS_LAST_MACRO_MAP (set)) + : MAX_LOCATION_T + 1; +} + +/* Returns the last macro map allocated in the line table SET. */ +inline line_map_macro * +LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set) +{ + return (line_map_macro *)LINEMAPS_LAST_ALLOCATED_MAP (set, true); +} + +extern location_t get_combined_adhoc_loc (line_maps *, location_t, + source_range, void *); +extern void *get_data_from_adhoc_loc (const line_maps *, location_t); +extern location_t get_location_from_adhoc_loc (const line_maps *, + location_t); + +extern source_range get_range_from_loc (line_maps *set, location_t loc); + +/* Get whether location LOC is a "pure" location, or + whether it is an ad-hoc location, or embeds range information. */ + +bool +pure_location_p (line_maps *set, location_t loc); + +/* Given location LOC within SET, strip away any packed range information + or ad-hoc information. */ + +extern location_t get_pure_location (line_maps *set, location_t loc); + +/* Combine LOC and BLOCK, giving a combined adhoc location. */ -/* Free a line map set. */ -extern void linemap_free (struct line_maps *); +inline location_t +COMBINE_LOCATION_DATA (class line_maps *set, + location_t loc, + source_range src_range, + void *block) +{ + return get_combined_adhoc_loc (set, loc, src_range, block); +} + +extern void rebuild_location_adhoc_htab (class line_maps *); + +/* Initialize a line map set. SET is the line map set to initialize + and BUILTIN_LOCATION is the special location value to be used as + spelling location for built-in tokens. This BUILTIN_LOCATION has + to be strictly less than RESERVED_LOCATION_COUNT. */ +extern void linemap_init (class line_maps *set, + location_t builtin_location); /* Check for and warn about line_maps entered but not exited. */ -extern void linemap_check_files_exited (struct line_maps *); +extern void linemap_check_files_exited (class line_maps *); -/* Return a source_location for the start (i.e. column==0) of +/* Return a location_t for the start (i.e. column==0) of (physical) line TO_LINE in the current source file (as in the most recent linemap_add). MAX_COLUMN_HINT is the highest column number we expect to use in this line (but it does not change the highest_location). */ -extern source_location linemap_line_start -(struct line_maps *set, linenum_type to_line, unsigned int max_column_hint); +extern location_t linemap_line_start +(class line_maps *set, linenum_type to_line, unsigned int max_column_hint); + +/* Allocate a raw block of line maps, zero initialized. */ +extern line_map *line_map_new_raw (line_maps *, bool, unsigned); /* Add a mapping of logical source line to physical source file and - line number. + line number. This function creates an "ordinary map", which is a + map that records locations of tokens that are not part of macro + replacement-lists present at a macro expansion point. The text pointed to by TO_FILE must have a lifetime - at least as long as the final call to lookup_line (). An empty + at least as long as the lifetime of SET. An empty TO_FILE means standard input. If reason is LC_LEAVE, and TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their natural values considering the file we are returning to. A call to this function can relocate the previous set of maps, so any stored line_map pointers should not be used. */ -extern const struct line_map *linemap_add - (struct line_maps *, enum lc_reason, unsigned int sysp, +extern const line_map *linemap_add + (class line_maps *, enum lc_reason, unsigned int sysp, const char *to_file, linenum_type to_line); -/* Given a logical line, returns the map from which the corresponding - (source file, line) pair can be deduced. */ -extern const struct line_map *linemap_lookup - (struct line_maps *, source_location); +/* Create a macro map. A macro map encodes source locations of tokens + that are part of a macro replacement-list, at a macro expansion + point. See the extensive comments of struct line_map and struct + line_map_macro, in line-map.h. + + This map shall be created when the macro is expanded. The map + encodes the source location of the expansion point of the macro as + well as the "original" source location of each token that is part + of the macro replacement-list. If a macro is defined but never + expanded, it has no macro map. SET is the set of maps the macro + map should be part of. MACRO_NODE is the macro which the new macro + map should encode source locations for. EXPANSION is the location + of the expansion point of MACRO. For function-like macros + invocations, it's best to make it point to the closing parenthesis + of the macro, rather than the the location of the first character + of the macro. NUM_TOKENS is the number of tokens that are part of + the replacement-list of MACRO. */ +const line_map_macro *linemap_enter_macro (line_maps *, cpp_hashnode *, + location_t, unsigned int); + +/* Create a source location for a module. The creator must either do + this after the TU is tokenized, or deal with saving and restoring + map state. */ + +extern location_t linemap_module_loc + (line_maps *, location_t from, const char *name); +extern void linemap_module_reparent + (line_maps *, location_t loc, location_t new_parent); + +/* Restore the linemap state such that the map at LWM-1 continues. + Return start location of the new map. */ +extern unsigned linemap_module_restore + (line_maps *, unsigned lwm); + +/* Given a logical source location, returns the map which the + corresponding (source file, line, column) triplet can be deduced + from. Since the set is built chronologically, the logical lines are + monotonic increasing, and so the list is sorted and we can use a + binary search. If no line map have been allocated yet, this + function returns NULL. */ +extern const line_map *linemap_lookup + (const line_maps *, location_t); + +unsigned linemap_lookup_macro_index (const line_maps *, location_t); + +/* Returns TRUE if the line table set tracks token locations across + macro expansion, FALSE otherwise. */ +bool linemap_tracks_macro_expansion_locs_p (class line_maps *); + +/* Return the name of the macro associated to MACRO_MAP. */ +const char* linemap_map_get_macro_name (const line_map_macro *); + +/* Return a positive value if LOCATION is the locus of a token that is + located in a system header, O otherwise. It returns 1 if LOCATION + is the locus of a token that is located in a system header, and 2 + if LOCATION is the locus of a token located in a C system header + that therefore needs to be extern "C" protected in C++. + + Note that this function returns 1 if LOCATION belongs to a token + that is part of a macro replacement-list defined in a system + header, but expanded in a non-system file. */ +int linemap_location_in_system_header_p (class line_maps *, + location_t); -/* source_location values from 0 to RESERVED_LOCATION_COUNT-1 will +/* Return TRUE if LOCATION is a source code location of a token that is part of + a macro expansion, FALSE otherwise. */ +bool linemap_location_from_macro_expansion_p (const line_maps *, + location_t); + +/* TRUE if LOCATION is a source code location of a token that is part of the + definition of a macro, FALSE otherwise. */ +bool linemap_location_from_macro_definition_p (class line_maps *, + location_t); + +/* With the precondition that LOCATION is the locus of a token that is + an argument of a function-like macro MACRO_MAP and appears in the + expansion of MACRO_MAP, return the locus of that argument in the + context of the caller of MACRO_MAP. */ + +extern location_t linemap_macro_map_loc_unwind_toward_spelling + (line_maps *set, const line_map_macro *macro_map, location_t location); + +/* location_t values from 0 to RESERVED_LOCATION_COUNT-1 will be reserved for libcpp user as special values, no token from libcpp will contain any of those locations. */ -#define RESERVED_LOCATION_COUNT 2 - -/* Converts a map and a source_location to source line. */ -#define SOURCE_LINE(MAP, LOC) \ - ((((LOC) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line) - -#define SOURCE_COLUMN(MAP, LOC) \ - (((LOC) - (MAP)->start_location) & ((1 << (MAP)->column_bits) - 1)) - -/* Returns the last source line within a map. This is the (last) line - of the #include, or other directive, that caused a map change. */ -#define LAST_SOURCE_LINE(MAP) \ - SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP)) -#define LAST_SOURCE_COLUMN(MAP) \ - SOURCE_COLUMN (MAP, LAST_SOURCE_LINE_LOCATION (MAP)) -#define LAST_SOURCE_LINE_LOCATION(MAP) \ - ((((MAP)[1].start_location - 1 - (MAP)->start_location) \ - & ~((1 << (MAP)->column_bits) - 1)) \ - + (MAP)->start_location) - -/* Returns the map a given map was included from. */ -#define INCLUDED_FROM(SET, MAP) (&(SET)->maps[(MAP)->included_from]) - -/* Nonzero if the map is at the bottom of the include stack. */ -#define MAIN_FILE_P(MAP) ((MAP)->included_from < 0) - -/* Set LOC to a source position that is the same line as the most recent - linemap_line_start, but with the specified TO_COLUMN column number. */ - -#define LINEMAP_POSITION_FOR_COLUMN(LOC, SET, TO_COLUMN) do { \ - unsigned int to_column = (TO_COLUMN); \ - struct line_maps *set = (SET); \ - if (__builtin_expect (to_column >= set->max_column_hint, 0)) \ - (LOC) = linemap_position_for_column (set, to_column); \ - else { \ - source_location r = set->highest_line; \ - r = r + to_column; \ - if (r >= set->highest_location) \ - set->highest_location = r; \ - (LOC) = r; \ - }} while (0) - - -extern source_location -linemap_position_for_column (struct line_maps *set, unsigned int to_column); +const location_t RESERVED_LOCATION_COUNT = 2; + +/* Converts a map and a location_t to source line. */ +inline linenum_type +SOURCE_LINE (const line_map_ordinary *ord_map, location_t loc) +{ + return ((loc - ord_map->start_location) + >> ord_map->m_column_and_range_bits) + ord_map->to_line; +} + +/* Convert a map and location_t to source column number. */ +inline linenum_type +SOURCE_COLUMN (const line_map_ordinary *ord_map, location_t loc) +{ + return ((loc - ord_map->start_location) + & ((1 << ord_map->m_column_and_range_bits) - 1)) >> ord_map->m_range_bits; +} + + +inline location_t +linemap_included_from (const line_map_ordinary *ord_map) +{ + return ord_map->included_from; +} + +/* The linemap containing the included-from location of MAP. */ +const line_map_ordinary *linemap_included_from_linemap + (line_maps *set, const line_map_ordinary *map); + +/* True if the map is at the bottom of the include stack. */ + +inline bool +MAIN_FILE_P (const line_map_ordinary *ord_map) +{ + return ord_map->included_from == 0; +} + +/* Encode and return a location_t from a column number. The + source line considered is the last source line used to call + linemap_line_start, i.e, the last source line which a location was + encoded from. */ +extern location_t +linemap_position_for_column (class line_maps *, unsigned int); + +/* Encode and return a source location from a given line and + column. */ +location_t +linemap_position_for_line_and_column (line_maps *set, + const line_map_ordinary *, + linenum_type, unsigned int); + +/* Encode and return a location_t starting from location LOC and + shifting it by OFFSET columns. This function does not support + virtual locations. */ +location_t +linemap_position_for_loc_and_offset (class line_maps *set, + location_t loc, + unsigned int offset); + +/* Return the file this map is for. */ +inline const char * +LINEMAP_FILE (const line_map_ordinary *ord_map) +{ + return ord_map->to_file; +} + +/* Return the line number this map started encoding location from. */ +inline linenum_type +LINEMAP_LINE (const line_map_ordinary *ord_map) +{ + return ord_map->to_line; +} + +/* Return a positive value if map encodes locations from a system + header, 0 otherwise. Returns 1 if MAP encodes locations in a + system header and 2 if it encodes locations in a C system header + that therefore needs to be extern "C" protected in C++. */ +inline unsigned char +LINEMAP_SYSP (const line_map_ordinary *ord_map) +{ + return ord_map->sysp; +} + +const struct line_map *first_map_in_common (line_maps *set, + location_t loc0, + location_t loc1, + location_t *res_loc0, + location_t *res_loc1); + +/* Return a positive value if PRE denotes the location of a token that + comes before the token of POST, 0 if PRE denotes the location of + the same token as the token for POST, and a negative value + otherwise. */ +int linemap_compare_locations (class line_maps *set, + location_t pre, + location_t post); + +/* Return TRUE if LOC_A denotes the location a token that comes + topogically before the token denoted by location LOC_B, or if they + are equal. */ +inline bool +linemap_location_before_p (class line_maps *set, + location_t loc_a, + location_t loc_b) +{ + return linemap_compare_locations (set, loc_a, loc_b) >= 0; +} + +typedef struct +{ + /* The name of the source file involved. */ + const char *file; + + /* The line-location in the source file. */ + int line; + + int column; + + void *data; + + /* In a system header?. */ + bool sysp; +} expanded_location; + +class range_label; + +/* A hint to diagnostic_show_locus on how to print a source range within a + rich_location. + + Typically this is SHOW_RANGE_WITH_CARET for the 0th range, and + SHOW_RANGE_WITHOUT_CARET for subsequent ranges, + but the Fortran frontend uses SHOW_RANGE_WITH_CARET repeatedly for + printing things like: + + x = x + y + 1 2 + Error: Shapes for operands at (1) and (2) are not conformable + + where "1" and "2" are notionally carets. */ + +enum range_display_kind +{ + /* Show the pertinent source line(s), the caret, and underline(s). */ + SHOW_RANGE_WITH_CARET, + + /* Show the pertinent source line(s) and underline(s), but don't + show the caret (just an underline). */ + SHOW_RANGE_WITHOUT_CARET, + + /* Just show the source lines; don't show the range itself. + This is for use when displaying some line-insertion fix-it hints (for + showing the user context on the change, for when it doesn't make sense + to highlight the first column on the next line). */ + SHOW_LINES_WITHOUT_RANGE +}; + +/* A location within a rich_location: a caret&range, with + the caret potentially flagged for display, and an optional + label. */ + +struct location_range +{ + location_t m_loc; + + enum range_display_kind m_range_display_kind; + + /* If non-NULL, the label for this range. */ + const range_label *m_label; +}; + +/* A partially-embedded vec for use within rich_location for storing + ranges and fix-it hints. + + Elements [0..NUM_EMBEDDED) are allocated within m_embed, after + that they are within the dynamically-allocated m_extra. + + This allows for static allocation in the common case, whilst + supporting the rarer case of an arbitrary number of elements. + + Dynamic allocation is not performed unless it's needed. */ + +template <typename T, int NUM_EMBEDDED> +class semi_embedded_vec +{ + public: + semi_embedded_vec (); + ~semi_embedded_vec (); + + unsigned int count () const { return m_num; } + T& operator[] (int idx); + const T& operator[] (int idx) const; + + void push (const T&); + void truncate (int len); + + private: + int m_num; + T m_embedded[NUM_EMBEDDED]; + int m_alloc; + T *m_extra; +}; + +/* Constructor for semi_embedded_vec. In particular, no dynamic allocation + is done. */ + +template <typename T, int NUM_EMBEDDED> +semi_embedded_vec<T, NUM_EMBEDDED>::semi_embedded_vec () +: m_num (0), m_alloc (0), m_extra (NULL) +{ +} + +/* semi_embedded_vec's dtor. Release any dynamically-allocated memory. */ + +template <typename T, int NUM_EMBEDDED> +semi_embedded_vec<T, NUM_EMBEDDED>::~semi_embedded_vec () +{ + XDELETEVEC (m_extra); +} + +/* Look up element IDX, mutably. */ + +template <typename T, int NUM_EMBEDDED> +T& +semi_embedded_vec<T, NUM_EMBEDDED>::operator[] (int idx) +{ + linemap_assert (idx < m_num); + if (idx < NUM_EMBEDDED) + return m_embedded[idx]; + else + { + linemap_assert (m_extra != NULL); + return m_extra[idx - NUM_EMBEDDED]; + } +} + +/* Look up element IDX (const). */ + +template <typename T, int NUM_EMBEDDED> +const T& +semi_embedded_vec<T, NUM_EMBEDDED>::operator[] (int idx) const +{ + linemap_assert (idx < m_num); + if (idx < NUM_EMBEDDED) + return m_embedded[idx]; + else + { + linemap_assert (m_extra != NULL); + return m_extra[idx - NUM_EMBEDDED]; + } +} + +/* Append VALUE to the end of the semi_embedded_vec. */ + +template <typename T, int NUM_EMBEDDED> +void +semi_embedded_vec<T, NUM_EMBEDDED>::push (const T& value) +{ + int idx = m_num++; + if (idx < NUM_EMBEDDED) + m_embedded[idx] = value; + else + { + /* Offset "idx" to be an index within m_extra. */ + idx -= NUM_EMBEDDED; + if (NULL == m_extra) + { + linemap_assert (m_alloc == 0); + m_alloc = 16; + m_extra = XNEWVEC (T, m_alloc); + } + else if (idx >= m_alloc) + { + linemap_assert (m_alloc > 0); + m_alloc *= 2; + m_extra = XRESIZEVEC (T, m_extra, m_alloc); + } + linemap_assert (m_extra); + linemap_assert (idx < m_alloc); + m_extra[idx] = value; + } +} + +/* Truncate to length LEN. No deallocation is performed. */ + +template <typename T, int NUM_EMBEDDED> +void +semi_embedded_vec<T, NUM_EMBEDDED>::truncate (int len) +{ + linemap_assert (len <= m_num); + m_num = len; +} + +class fixit_hint; +class diagnostic_path; + +/* A "rich" source code location, for use when printing diagnostics. + A rich_location has one or more carets&ranges, where the carets + are optional. These are referred to as "ranges" from here. + Typically the zeroth range has a caret; other ranges sometimes + have carets. + + The "primary" location of a rich_location is the caret of range 0, + used for determining the line/column when printing diagnostic + text, such as: + + some-file.c:3:1: error: ...etc... + + Additional ranges may be added to help the user identify other + pertinent clauses in a diagnostic. + + Ranges can (optionally) be given labels via class range_label. + + rich_location instances are intended to be allocated on the stack + when generating diagnostics, and to be short-lived. + + Examples of rich locations + -------------------------- + + Example A + ********* + int i = "foo"; + ^ + This "rich" location is simply a single range (range 0), with + caret = start = finish at the given point. + + Example B + ********* + a = (foo && bar) + ~~~~~^~~~~~~ + This rich location has a single range (range 0), with the caret + at the first "&", and the start/finish at the parentheses. + Compare with example C below. + + Example C + ********* + a = (foo && bar) + ~~~ ^~ ~~~ + This rich location has three ranges: + - Range 0 has its caret and start location at the first "&" and + end at the second "&. + - Range 1 has its start and finish at the "f" and "o" of "foo"; + the caret is not flagged for display, but is perhaps at the "f" + of "foo". + - Similarly, range 2 has its start and finish at the "b" and "r" of + "bar"; the caret is not flagged for display, but is perhaps at the + "b" of "bar". + Compare with example B above. + + Example D (Fortran frontend) + **************************** + x = x + y + 1 2 + This rich location has range 0 at "1", and range 1 at "2". + Both are flagged for caret display. Both ranges have start/finish + equal to their caret point. The frontend overrides the diagnostic + context's default caret character for these ranges. + + Example E (range labels) + ************************ + printf ("arg0: %i arg1: %s arg2: %i", + ^~ + | + const char * + 100, 101, 102); + ~~~ + | + int + This rich location has two ranges: + - range 0 is at the "%s" with start = caret = "%" and finish at + the "s". It has a range_label ("const char *"). + - range 1 has start/finish covering the "101" and is not flagged for + caret printing. The caret is at the start of "101", where its + range_label is printed ("int"). + + Fix-it hints + ------------ + + Rich locations can also contain "fix-it hints", giving suggestions + for the user on how to edit their code to fix a problem. These + can be expressed as insertions, replacements, and removals of text. + The edits by default are relative to the zeroth range within the + rich_location, but optionally they can be expressed relative to + other locations (using various overloaded methods of the form + rich_location::add_fixit_*). + + For example: + + Example F: fix-it hint: insert_before + ************************************* + ptr = arr[0]; + ^~~~~~ + & + This rich location has a single range (range 0) covering "arr[0]", + with the caret at the start. The rich location has a single + insertion fix-it hint, inserted before range 0, added via + richloc.add_fixit_insert_before ("&"); + + Example G: multiple fix-it hints: insert_before and insert_after + **************************************************************** + #define FN(ARG0, ARG1, ARG2) fn(ARG0, ARG1, ARG2) + ^~~~ ^~~~ ^~~~ + ( ) ( ) ( ) + This rich location has three ranges, covering "arg0", "arg1", + and "arg2", all with caret-printing enabled. + The rich location has 6 insertion fix-it hints: each arg + has a pair of insertion fix-it hints, suggesting wrapping + them with parentheses: one a '(' inserted before, + the other a ')' inserted after, added via + richloc.add_fixit_insert_before (LOC, "("); + and + richloc.add_fixit_insert_after (LOC, ")"); + + Example H: fix-it hint: removal + ******************************* + struct s {int i};; + ^ + - + This rich location has a single range at the stray trailing + semicolon, along with a single removal fix-it hint, covering + the same range, added via: + richloc.add_fixit_remove (); + + Example I: fix-it hint: replace + ******************************* + c = s.colour; + ^~~~~~ + color + This rich location has a single range (range 0) covering "colour", + and a single "replace" fix-it hint, covering the same range, + added via + richloc.add_fixit_replace ("color"); + + Example J: fix-it hint: line insertion + ************************************** + + 3 | #include <stddef.h> + + |+#include <stdio.h> + 4 | int the_next_line; + + This rich location has a single range at line 4 column 1, marked + with SHOW_LINES_WITHOUT_RANGE (to avoid printing a meaningless caret + on the "i" of int). It has a insertion fix-it hint of the string + "#include <stdio.h>\n". + + Adding a fix-it hint can fail: for example, attempts to insert content + at the transition between two line maps may fail due to there being no + location_t value to express the new location. + + Attempts to add a fix-it hint within a macro expansion will fail. + + There is only limited support for newline characters in fix-it hints: + only hints with newlines which insert an entire new line are permitted, + inserting at the start of a line, and finishing with a newline + (with no interior newline characters). Other attempts to add + fix-it hints containing newline characters will fail. + Similarly, attempts to delete or replace a range *affecting* multiple + lines will fail. + + The rich_location API handles these failures gracefully, so that + diagnostics can attempt to add fix-it hints without each needing + extensive checking. + + Fix-it hints within a rich_location are "atomic": if any hints can't + be applied, none of them will be (tracked by the m_seen_impossible_fixit + flag), and no fix-its hints will be displayed for that rich_location. + This implies that diagnostic messages need to be worded in such a way + that they make sense whether or not the fix-it hints are displayed, + or that richloc.seen_impossible_fixit_p () should be checked before + issuing the diagnostics. */ + +class rich_location +{ + public: + /* Constructors. */ + + /* Constructing from a location. */ + rich_location (line_maps *set, location_t loc, + const range_label *label = NULL); + + /* Destructor. */ + ~rich_location (); + + /* The class manages the memory pointed to by the elements of + the M_FIXIT_HINTS vector and is not meant to be copied or + assigned. */ + rich_location (const rich_location &) = delete; + void operator= (const rich_location &) = delete; + + /* Accessors. */ + location_t get_loc () const { return get_loc (0); } + location_t get_loc (unsigned int idx) const; + + void + add_range (location_t loc, + enum range_display_kind range_display_kind + = SHOW_RANGE_WITHOUT_CARET, + const range_label *label = NULL); + + void + set_range (unsigned int idx, location_t loc, + enum range_display_kind range_display_kind); + + unsigned int get_num_locations () const { return m_ranges.count (); } + + const location_range *get_range (unsigned int idx) const; + location_range *get_range (unsigned int idx); + + expanded_location get_expanded_location (unsigned int idx); + + void + override_column (int column); + + /* Fix-it hints. */ + + /* Methods for adding insertion fix-it hints. */ + + /* Suggest inserting NEW_CONTENT immediately before the primary + range's start. */ + void + add_fixit_insert_before (const char *new_content); + + /* Suggest inserting NEW_CONTENT immediately before the start of WHERE. */ + void + add_fixit_insert_before (location_t where, + const char *new_content); + + /* Suggest inserting NEW_CONTENT immediately after the end of the primary + range. */ + void + add_fixit_insert_after (const char *new_content); + + /* Suggest inserting NEW_CONTENT immediately after the end of WHERE. */ + void + add_fixit_insert_after (location_t where, + const char *new_content); + + /* Methods for adding removal fix-it hints. */ + + /* Suggest removing the content covered by range 0. */ + void + add_fixit_remove (); + + /* Suggest removing the content covered between the start and finish + of WHERE. */ + void + add_fixit_remove (location_t where); + + /* Suggest removing the content covered by SRC_RANGE. */ + void + add_fixit_remove (source_range src_range); + + /* Methods for adding "replace" fix-it hints. */ + + /* Suggest replacing the content covered by range 0 with NEW_CONTENT. */ + void + add_fixit_replace (const char *new_content); + + /* Suggest replacing the content between the start and finish of + WHERE with NEW_CONTENT. */ + void + add_fixit_replace (location_t where, + const char *new_content); + + /* Suggest replacing the content covered by SRC_RANGE with + NEW_CONTENT. */ + void + add_fixit_replace (source_range src_range, + const char *new_content); + + unsigned int get_num_fixit_hints () const { return m_fixit_hints.count (); } + fixit_hint *get_fixit_hint (int idx) const { return m_fixit_hints[idx]; } + fixit_hint *get_last_fixit_hint () const; + bool seen_impossible_fixit_p () const { return m_seen_impossible_fixit; } + + /* Set this if the fix-it hints are not suitable to be + automatically applied. + + For example, if you are suggesting more than one + mutually exclusive solution to a problem, then + it doesn't make sense to apply all of the solutions; + manual intervention is required. + + If set, then the fix-it hints in the rich_location will + be printed, but will not be added to generated patches, + or affect the modified version of the file. */ + void fixits_cannot_be_auto_applied () + { + m_fixits_cannot_be_auto_applied = true; + } + + bool fixits_can_be_auto_applied_p () const + { + return !m_fixits_cannot_be_auto_applied; + } + + /* An optional path through the code. */ + const diagnostic_path *get_path () const { return m_path; } + void set_path (const diagnostic_path *path) { m_path = path; } + + /* A flag for hinting that the diagnostic involves character encoding + issues, and thus that it will be helpful to the user if we show some + representation of how the characters in the pertinent source lines + are encoded. + The default is false (i.e. do not escape). + When set to true, non-ASCII bytes in the pertinent source lines will + be escaped in a manner controlled by the user-supplied option + -fdiagnostics-escape-format=, so that the user can better understand + what's going on with the encoding in their source file. */ + bool escape_on_output_p () const { return m_escape_on_output; } + void set_escape_on_output (bool flag) { m_escape_on_output = flag; } + +private: + bool reject_impossible_fixit (location_t where); + void stop_supporting_fixits (); + void maybe_add_fixit (location_t start, + location_t next_loc, + const char *new_content); + +public: + static const int STATICALLY_ALLOCATED_RANGES = 3; + +protected: + line_maps *m_line_table; + semi_embedded_vec <location_range, STATICALLY_ALLOCATED_RANGES> m_ranges; + + int m_column_override; + + bool m_have_expanded_location; + bool m_seen_impossible_fixit; + bool m_fixits_cannot_be_auto_applied; + bool m_escape_on_output; + + expanded_location m_expanded_location; + + static const int MAX_STATIC_FIXIT_HINTS = 2; + semi_embedded_vec <fixit_hint *, MAX_STATIC_FIXIT_HINTS> m_fixit_hints; + + const diagnostic_path *m_path; +}; + +/* A struct for the result of range_label::get_text: a NUL-terminated buffer + of localized text, and a flag to determine if the caller should "free" the + buffer. */ + +class label_text +{ +public: + label_text () + : m_buffer (NULL), m_caller_owned (false) + {} + + void maybe_free () + { + if (m_caller_owned) + free (m_buffer); + } + + /* Create a label_text instance that borrows BUFFER from a + longer-lived owner. */ + static label_text borrow (const char *buffer) + { + return label_text (const_cast <char *> (buffer), false); + } + + /* Create a label_text instance that takes ownership of BUFFER. */ + static label_text take (char *buffer) + { + return label_text (buffer, true); + } + + /* Take ownership of the buffer, copying if necessary. */ + char *take_or_copy () + { + if (m_caller_owned) + return m_buffer; + else + return xstrdup (m_buffer); + } + + char *m_buffer; + bool m_caller_owned; + +private: + label_text (char *buffer, bool owned) + : m_buffer (buffer), m_caller_owned (owned) + {} +}; + +/* Abstract base class for labelling a range within a rich_location + (e.g. for labelling expressions with their type). + + Generating the text could require non-trivial work, so this work + is delayed (via the "get_text" virtual function) until the diagnostic + printing code "knows" it needs it, thus avoiding doing it e.g. for + warnings that are filtered by command-line flags. This virtual + function also isolates libcpp and the diagnostics subsystem from + the front-end and middle-end-specific code for generating the text + for the labels. + + Like the rich_location instances they annotate, range_label instances + are intended to be allocated on the stack when generating diagnostics, + and to be short-lived. */ + +class range_label +{ + public: + virtual ~range_label () {} + + /* Get localized text for the label. + The RANGE_IDX is provided, allowing for range_label instances to be + shared by multiple ranges if need be (the "flyweight" design pattern). */ + virtual label_text get_text (unsigned range_idx) const = 0; +}; + +/* A fix-it hint: a suggested insertion, replacement, or deletion of text. + We handle these three types of edit with one class, by representing + them as replacement of a half-open range: + [start, next_loc) + Insertions have start == next_loc: "replace" the empty string at the + start location with the new string. + Deletions are replacement with the empty string. + + There is only limited support for newline characters in fix-it hints + as noted above in the comment for class rich_location. + A fixit_hint instance can have at most one newline character; if + present, the newline character must be the final character of + the content (preventing e.g. fix-its that split a pre-existing line). */ + +class fixit_hint +{ + public: + fixit_hint (location_t start, + location_t next_loc, + const char *new_content); + ~fixit_hint () { free (m_bytes); } + + bool affects_line_p (const char *file, int line) const; + location_t get_start_loc () const { return m_start; } + location_t get_next_loc () const { return m_next_loc; } + bool maybe_append (location_t start, + location_t next_loc, + const char *new_content); + + const char *get_string () const { return m_bytes; } + size_t get_length () const { return m_len; } + + bool insertion_p () const { return m_start == m_next_loc; } + + bool ends_with_newline_p () const; + + private: + /* We don't use source_range here since, unlike most places, + this is a half-open/half-closed range: + [start, next_loc) + so that we can support insertion via start == next_loc. */ + location_t m_start; + location_t m_next_loc; + char *m_bytes; + size_t m_len; +}; + + +/* This is enum is used by the function linemap_resolve_location + below. The meaning of the values is explained in the comment of + that function. */ +enum location_resolution_kind +{ + LRK_MACRO_EXPANSION_POINT, + LRK_SPELLING_LOCATION, + LRK_MACRO_DEFINITION_LOCATION +}; + +/* Resolve a virtual location into either a spelling location, an + expansion point location or a token argument replacement point + location. Return the map that encodes the virtual location as well + as the resolved location. + + If LOC is *NOT* the location of a token resulting from the + expansion of a macro, then the parameter LRK (which stands for + Location Resolution Kind) is ignored and the resulting location + just equals the one given in argument. + + Now if LOC *IS* the location of a token resulting from the + expansion of a macro, this is what happens. + + * If LRK is set to LRK_MACRO_EXPANSION_POINT + ------------------------------- + + The virtual location is resolved to the first macro expansion point + that led to this macro expansion. + + * If LRK is set to LRK_SPELLING_LOCATION + ------------------------------------- + + The virtual location is resolved to the locus where the token has + been spelled in the source. This can follow through all the macro + expansions that led to the token. + + * If LRK is set to LRK_MACRO_DEFINITION_LOCATION + -------------------------------------- + + The virtual location is resolved to the locus of the token in the + context of the macro definition. + + If LOC is the locus of a token that is an argument of a + function-like macro [replacing a parameter in the replacement list + of the macro] the virtual location is resolved to the locus of the + parameter that is replaced, in the context of the definition of the + macro. + + If LOC is the locus of a token that is not an argument of a + function-like macro, then the function behaves as if LRK was set to + LRK_SPELLING_LOCATION. + + If LOC_MAP is not NULL, *LOC_MAP is set to the map encoding the + returned location. Note that if the returned location wasn't originally + encoded by a map, the *MAP is set to NULL. This can happen if LOC + resolves to a location reserved for the client code, like + UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */ + +location_t linemap_resolve_location (class line_maps *, + location_t loc, + enum location_resolution_kind lrk, + const line_map_ordinary **loc_map); + +/* Suppose that LOC is the virtual location of a token coming from the + expansion of a macro M. This function then steps up to get the + location L of the point where M got expanded. If L is a spelling + location inside a macro expansion M', then this function returns + the point where M' was expanded. LOC_MAP is an output parameter. + When non-NULL, *LOC_MAP is set to the map of the returned + location. */ +location_t linemap_unwind_toward_expansion (class line_maps *, + location_t loc, + const line_map **loc_map); + +/* If LOC is the virtual location of a token coming from the expansion + of a macro M and if its spelling location is reserved (e.g, a + location for a built-in token), then this function unwinds (using + linemap_unwind_toward_expansion) the location until a location that + is not reserved and is not in a system header is reached. In other + words, this unwinds the reserved location until a location that is + in real source code is reached. + + Otherwise, if the spelling location for LOC is not reserved or if + LOC doesn't come from the expansion of a macro, the function + returns LOC as is and *MAP is not touched. + + *MAP is set to the map of the returned location if the later is + different from LOC. */ +location_t linemap_unwind_to_first_non_reserved_loc (class line_maps *, + location_t loc, + const line_map **map); + +/* Expand source code location LOC and return a user readable source + code location. LOC must be a spelling (non-virtual) location. If + it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source + location is returned. */ +expanded_location linemap_expand_location (class line_maps *, + const line_map *, + location_t loc); + +/* Statistics about maps allocation and usage as returned by + linemap_get_statistics. */ +struct linemap_stats +{ + long num_ordinary_maps_allocated; + long num_ordinary_maps_used; + long ordinary_maps_allocated_size; + long ordinary_maps_used_size; + long num_expanded_macros; + long num_macro_tokens; + long num_macro_maps_used; + long macro_maps_allocated_size; + long macro_maps_used_size; + long macro_maps_locations_size; + long duplicated_macro_maps_locations_size; + long adhoc_table_size; + long adhoc_table_entries_used; +}; + +/* Return the highest location emitted for a given file for which + there is a line map in SET. FILE_NAME is the file name to + consider. If the function returns TRUE, *LOC is set to the highest + location emitted for that file. */ +bool linemap_get_file_highest_location (class line_maps * set, + const char *file_name, + location_t *loc); + +/* Compute and return statistics about the memory consumption of some + parts of the line table SET. */ +void linemap_get_statistics (line_maps *, struct linemap_stats *); + +/* Dump debugging information about source location LOC into the file + stream STREAM. SET is the line map set LOC comes from. */ +void linemap_dump_location (line_maps *, location_t, FILE *); + +/* Dump line map at index IX in line table SET to STREAM. If STREAM + is NULL, use stderr. IS_MACRO is true if the caller wants to + dump a macro map, false otherwise. */ +void linemap_dump (FILE *, line_maps *, unsigned, bool); + +/* Dump line table SET to STREAM. If STREAM is NULL, stderr is used. + NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO + specifies how many macro maps to dump. */ +void line_table_dump (FILE *, line_maps *, unsigned int, unsigned int); + +/* An enum for distinguishing the various parts within a location_t. */ + +enum location_aspect +{ + LOCATION_ASPECT_CARET, + LOCATION_ASPECT_START, + LOCATION_ASPECT_FINISH +}; + +/* The rich_location class requires a way to expand location_t instances. + We would directly use expand_location_to_spelling_point, which is + implemented in gcc/input.cc, but we also need to use it for rich_location + within genmatch.cc. + Hence we require client code of libcpp to implement the following + symbol. */ +extern expanded_location +linemap_client_expand_location_to_spelling_point (location_t, + enum location_aspect); #endif /* !LIBCPP_LINE_MAP_H */ diff --git a/support/cpp/libcpp/include/mkdeps.h b/support/cpp/libcpp/include/mkdeps.h index f743ee72d..dbcd9417c 100644 --- a/support/cpp/libcpp/include/mkdeps.h +++ b/support/cpp/libcpp/include/mkdeps.h @@ -1,5 +1,5 @@ /* Dependency generator for Makefile fragments. - Copyright (C) 2000, 2001, 2003, 2009 Free Software Foundation, Inc. + Copyright (C) 2000-2022 Free Software Foundation, Inc. Contributed by Zack Weinberg, Mar 2000 This program is free software; you can redistribute it and/or modify it @@ -23,58 +23,60 @@ along with this program; see the file COPYING3. If not see #ifndef LIBCPP_MKDEPS_H #define LIBCPP_MKDEPS_H -/* This is the data structure used by all the functions in mkdeps.c. +#include "cpplib.h" + +/* This is the data structure used by all the functions in mkdeps.cc. It's quite straightforward, but should be treated as opaque. */ -struct deps; -struct cpp_reader; +class mkdeps; /* Create a deps buffer. */ -extern struct deps *deps_init (void); +extern class mkdeps *deps_init (void); /* Destroy a deps buffer. */ -extern void deps_free (struct deps *); +extern void deps_free (class mkdeps *); /* 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 *); +extern void deps_add_vpath (class mkdeps *, 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); +extern void deps_add_target (class mkdeps *, const char *, int); /* Sets the default target if none has been given already. An empty string as the default target is interpreted as stdin. */ -extern void deps_add_default_target (struct cpp_reader *, const char *); +extern void deps_add_default_target (const cpp_reader *, class mkdeps *, const char *); + +/* Adds a module target. The module name and cmi name are copied. */ +extern void deps_add_module_target (struct mkdeps *, const char *module, + const char *cmi, bool is_header); + +/* Adds a module dependency. The module name is copied. */ +extern void deps_add_module_dep (struct mkdeps *, const char *module); /* Add a dependency (appears on the right side of the colon) to the deps list. Dependencies will be printed in the order that they were entered with this function. By convention, the first dependency entered should be the primary source file. */ -extern void deps_add_dep (struct deps *, const char *); +extern void deps_add_dep (class mkdeps *, const char *); -/* Write out a deps buffer to a specified file. The third argument +/* Write out a deps buffer to a specified file. The last argument is the number of columns to word-wrap at (0 means don't wrap). */ -extern void deps_write (const struct deps *, FILE *, unsigned int); +extern void deps_write (const cpp_reader *, FILE *, unsigned int); /* Write out a deps buffer to a file, in a form that can be read back with deps_restore. Returns nonzero on error, in which case the error number will be in errno. */ -extern int deps_save (struct deps *, FILE *); +extern int deps_save (class mkdeps *, FILE *); /* Read back dependency information written with deps_save into the deps buffer. The third argument may be NULL, in which case the dependency information is just skipped, or it may be a filename, in which case that filename is skipped. */ -extern int deps_restore (struct deps *, FILE *, const char *); - -/* For each dependency *except the first*, emit a dummy rule for that - file, causing it to depend on nothing. This is used to work around - the intermediate-file deletion misfeature in Make, in some - automatic dependency schemes. */ -extern void deps_phony_targets (const struct deps *, FILE *); +extern int deps_restore (class mkdeps *, FILE *, const char *); #endif /* ! LIBCPP_MKDEPS_H */ diff --git a/support/cpp/libcpp/include/safe-ctype.h b/support/cpp/libcpp/include/safe-ctype.h new file mode 100644 index 000000000..82f0aa77b --- /dev/null +++ b/support/cpp/libcpp/include/safe-ctype.h @@ -0,0 +1,150 @@ +/* <ctype.h> replacement macros. + + Copyright (C) 2000-2022 Free Software Foundation, Inc. + Contributed by Zack Weinberg <zackw@stanford.edu>. + +This file is part of the libiberty library. +Libiberty is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +Libiberty is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with libiberty; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ + +/* This is a compatible replacement of the standard C library's <ctype.h> + with the following properties: + + - Implements all isxxx() macros required by C99. + - Also implements some character classes useful when + parsing C-like languages. + - Does not change behavior depending on the current locale. + - Behaves properly for all values in the range of a signed or + unsigned char. + + To avoid conflicts, this header defines the isxxx functions in upper + case, e.g. ISALPHA not isalpha. */ + +#ifndef SAFE_CTYPE_H +#define SAFE_CTYPE_H + +/* Determine host character set. */ +#define HOST_CHARSET_UNKNOWN 0 +#define HOST_CHARSET_ASCII 1 +#define HOST_CHARSET_EBCDIC 2 + +#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \ + && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 +# define HOST_CHARSET HOST_CHARSET_ASCII +#else +# if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \ + && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A +# define HOST_CHARSET HOST_CHARSET_EBCDIC +# else +# define HOST_CHARSET HOST_CHARSET_UNKNOWN +# endif +#endif + +/* Categories. */ + +enum { + /* In C99 */ + _sch_isblank = 0x0001, /* space \t */ + _sch_iscntrl = 0x0002, /* nonprinting characters */ + _sch_isdigit = 0x0004, /* 0-9 */ + _sch_islower = 0x0008, /* a-z */ + _sch_isprint = 0x0010, /* any printing character including ' ' */ + _sch_ispunct = 0x0020, /* all punctuation */ + _sch_isspace = 0x0040, /* space \t \n \r \f \v */ + _sch_isupper = 0x0080, /* A-Z */ + _sch_isxdigit = 0x0100, /* 0-9A-Fa-f */ + + /* Extra categories useful to cpplib. */ + _sch_isidst = 0x0200, /* A-Za-z_ */ + _sch_isvsp = 0x0400, /* \n \r */ + _sch_isnvsp = 0x0800, /* space \t \f \v \0 */ + + /* Combinations of the above. */ + _sch_isalpha = _sch_isupper|_sch_islower, /* A-Za-z */ + _sch_isalnum = _sch_isalpha|_sch_isdigit, /* A-Za-z0-9 */ + _sch_isidnum = _sch_isidst|_sch_isdigit, /* A-Za-z0-9_ */ + _sch_isgraph = _sch_isalnum|_sch_ispunct, /* isprint and not space */ + _sch_iscppsp = _sch_isvsp|_sch_isnvsp, /* isspace + \0 */ + _sch_isbasic = _sch_isprint|_sch_iscppsp /* basic charset of ISO C + (plus ` and @) */ +}; + +/* Character classification. */ +extern const unsigned short _sch_istable[256]; + +#define _sch_test(c, bit) (_sch_istable[(c) & 0xff] & (unsigned short)(bit)) + +#define ISALPHA(c) _sch_test(c, _sch_isalpha) +#define ISALNUM(c) _sch_test(c, _sch_isalnum) +#define ISBLANK(c) _sch_test(c, _sch_isblank) +#define ISCNTRL(c) _sch_test(c, _sch_iscntrl) +#define ISDIGIT(c) _sch_test(c, _sch_isdigit) +#define ISGRAPH(c) _sch_test(c, _sch_isgraph) +#define ISLOWER(c) _sch_test(c, _sch_islower) +#define ISPRINT(c) _sch_test(c, _sch_isprint) +#define ISPUNCT(c) _sch_test(c, _sch_ispunct) +#define ISSPACE(c) _sch_test(c, _sch_isspace) +#define ISUPPER(c) _sch_test(c, _sch_isupper) +#define ISXDIGIT(c) _sch_test(c, _sch_isxdigit) + +#define ISIDNUM(c) _sch_test(c, _sch_isidnum) +#define ISIDST(c) _sch_test(c, _sch_isidst) +#define IS_ISOBASIC(c) _sch_test(c, _sch_isbasic) +#define IS_VSPACE(c) _sch_test(c, _sch_isvsp) +#define IS_NVSPACE(c) _sch_test(c, _sch_isnvsp) +#define IS_SPACE_OR_NUL(c) _sch_test(c, _sch_iscppsp) + +/* Character transformation. */ +extern const unsigned char _sch_toupper[256]; +extern const unsigned char _sch_tolower[256]; +#define TOUPPER(c) _sch_toupper[(c) & 0xff] +#define TOLOWER(c) _sch_tolower[(c) & 0xff] + +/* Prevent the users of safe-ctype.h from accidently using the routines + from ctype.h. Initially, the approach was to produce an error when + detecting that ctype.h has been included. But this was causing + trouble as ctype.h might get indirectly included as a result of + including another system header (for instance gnulib's stdint.h). + So we include ctype.h here and then immediately redefine its macros. */ + +#include <ctype.h> +#undef isalpha +#define isalpha(c) do_not_use_isalpha_with_safe_ctype +#undef isalnum +#define isalnum(c) do_not_use_isalnum_with_safe_ctype +#undef iscntrl +#define iscntrl(c) do_not_use_iscntrl_with_safe_ctype +#undef isdigit +#define isdigit(c) do_not_use_isdigit_with_safe_ctype +#undef isgraph +#define isgraph(c) do_not_use_isgraph_with_safe_ctype +#undef islower +#define islower(c) do_not_use_islower_with_safe_ctype +#undef isprint +#define isprint(c) do_not_use_isprint_with_safe_ctype +#undef ispunct +#define ispunct(c) do_not_use_ispunct_with_safe_ctype +#undef isspace +#define isspace(c) do_not_use_isspace_with_safe_ctype +#undef isupper +#define isupper(c) do_not_use_isupper_with_safe_ctype +#undef isxdigit +#define isxdigit(c) do_not_use_isxdigit_with_safe_ctype +#undef toupper +#define toupper(c) do_not_use_toupper_with_safe_ctype +#undef tolower +#define tolower(c) do_not_use_tolower_with_safe_ctype + +#endif /* SAFE_CTYPE_H */ diff --git a/support/cpp/libcpp/include/symtab.h b/support/cpp/libcpp/include/symtab.h index 4107a6f8a..53efe6c39 100644 --- a/support/cpp/libcpp/include/symtab.h +++ b/support/cpp/libcpp/include/symtab.h @@ -1,6 +1,5 @@ /* Hash tables. - Copyright (C) 2000, 2001, 2003, 2004, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. + Copyright (C) 2000-2022 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 @@ -38,7 +37,7 @@ struct GTY(()) ht_identifier { #define HT_LEN(NODE) ((NODE)->len) #define HT_STR(NODE) ((NODE)->str) -typedef struct ht hash_table; +typedef struct ht cpp_hash_table; typedef struct ht_identifier *hashnode; enum ht_lookup_option {HT_NO_INSERT = 0, HT_ALLOC}; @@ -51,7 +50,7 @@ struct ht hashnode *entries; /* Call back, allocate a node. */ - hashnode (*alloc_node) (hash_table *); + hashnode (*alloc_node) (cpp_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); @@ -71,14 +70,14 @@ struct ht }; /* Initialize the hashtable with 2 ^ order entries. */ -extern hash_table *ht_create (unsigned int order); +extern cpp_hash_table *ht_create (unsigned int order); /* Frees all memory associated with a hash table. */ -extern void ht_destroy (hash_table *); +extern void ht_destroy (cpp_hash_table *); -extern hashnode ht_lookup (hash_table *, const unsigned char *, +extern hashnode ht_lookup (cpp_hash_table *, const unsigned char *, size_t, enum ht_lookup_option); -extern hashnode ht_lookup_with_hash (hash_table *, const unsigned char *, +extern hashnode ht_lookup_with_hash (cpp_hash_table *, const unsigned char *, size_t, unsigned int, enum ht_lookup_option); #define HT_HASHSTEP(r, c) ((r) * 67 + ((c) - 113)); @@ -88,17 +87,17 @@ extern hashnode ht_lookup_with_hash (hash_table *, const unsigned char *, TABLE->PFILE, the node, and a PTR, and the callback sequence stops if the callback returns zero. */ typedef int (*ht_cb) (struct cpp_reader *, hashnode, const void *); -extern void ht_forall (hash_table *, ht_cb, const void *); +extern void ht_forall (cpp_hash_table *, ht_cb, const void *); /* For all nodes in TABLE, call the callback. If the callback returns a nonzero value, the node is removed from the table. */ -extern void ht_purge (hash_table *, ht_cb, const void *); +extern void ht_purge (cpp_hash_table *, ht_cb, const void *); /* Restore the hash table. */ -extern void ht_load (hash_table *ht, hashnode *entries, +extern void ht_load (cpp_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 *); +extern void ht_dump_statistics (cpp_hash_table *); #endif /* LIBCPP_SYMTAB_H */ diff --git a/support/cpp/libcpp/init.c b/support/cpp/libcpp/init.cc index 8a3254904..19bef848e 100644 --- a/support/cpp/libcpp/init.c +++ b/support/cpp/libcpp/init.cc @@ -1,7 +1,5 @@ /* CPP Library. - Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, - 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 1986-2022 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 @@ -25,13 +23,20 @@ along with this program; see the file COPYING3. If not see #include "cpplib.h" #include "internal.h" #include "mkdeps.h" -#ifdef ENABLE_NLS #include "localedir.h" +#include "filenames.h" + +#ifndef ENABLE_CANONICAL_SYSTEM_HEADERS +#ifdef HAVE_DOS_BASED_FILE_SYSTEM +#define ENABLE_CANONICAL_SYSTEM_HEADERS 1 +#else +#define ENABLE_CANONICAL_SYSTEM_HEADERS 0 +#endif #endif static void init_library (void); static void mark_named_operators (cpp_reader *, int); -static void read_original_filename (cpp_reader *); +static bool read_original_filename (cpp_reader *); static void read_original_directory (cpp_reader *); static void post_options (cpp_reader *); @@ -76,30 +81,49 @@ struct lang_flags char cplusplus; char extended_numbers; char extended_identifiers; + char c11_identifiers; char std; - char cplusplus_comments; char digraphs; char uliterals; + char rliterals; + char user_literals; + char binary_constants; + char digit_separators; + char trigraphs; + char utf8_char_literals; + char va_opt; + char scope; + char dfp_constants; + char size_t_literals; + char elifdef; }; static const struct lang_flags lang_defaults[] = -{ /* c99 c++ xnum xid std // digr ulit */ - /* GNUC89 */ { 0, 0, 1, 0, 0, 1, 1, 0 }, - /* GNUC99 */ { 1, 0, 1, 0, 0, 1, 1, 1 }, - /* GNUC1X */ { 1, 0, 1, 0, 0, 1, 1, 1 }, - /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0 }, - /* STDC94 */ { 0, 0, 0, 0, 1, 0, 1, 0 }, - /* STDC99 */ { 1, 0, 1, 0, 1, 1, 1, 0 }, - /* STDC1X */ { 1, 0, 1, 0, 1, 1, 1, 0 }, - /* GNUCXX */ { 0, 1, 1, 0, 0, 1, 1, 0 }, - /* CXX98 */ { 0, 1, 1, 0, 1, 1, 1, 0 }, - /* GNUCXX0X */ { 1, 1, 1, 0, 0, 1, 1, 1 }, - /* CXX0X */ { 1, 1, 1, 0, 1, 1, 1, 1 }, - /* ASM */ { 0, 0, 1, 0, 0, 1, 0, 0 } - /* xid should be 1 for GNUC99, STDC99, GNUCXX, CXX98, GNUCXX0X, and - CXX0X when no longer experimental (when all uses of identifiers - in the compiler have been audited for correct handling of - extended identifiers). */ +{ /* c99 c++ xnum xid c11 std digr ulit rlit udlit bincst digsep trig u8chlit vaopt scope dfp szlit elifdef */ + /* GNUC89 */ { 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 }, + /* GNUC99 */ { 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 }, + /* GNUC11 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 }, + /* GNUC17 */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 }, + /* GNUC2X */ { 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1 }, + /* STDC89 */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, + /* STDC94 */ { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, + /* STDC99 */ { 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, + /* STDC11 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, + /* STDC17 */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, + /* STDC2X */ { 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1 }, + /* GNUCXX */ { 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 }, + /* CXX98 */ { 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0 }, + /* GNUCXX11 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0 }, + /* CXX11 */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0 }, + /* GNUCXX14 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0 }, + /* CXX14 */ { 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0 }, + /* GNUCXX17 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0 }, + /* CXX17 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0 }, + /* GNUCXX20 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0 }, + /* CXX20 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0 }, + /* GNUCXX23 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1 }, + /* CXX23 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1 }, + /* ASM */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; /* Sets internal flags correctly for a given language. */ @@ -114,12 +138,21 @@ cpp_set_lang (cpp_reader *pfile, enum c_lang lang) 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, c11_identifiers) = l->c11_identifiers; CPP_OPTION (pfile, std) = l->std; - /* Trigraphs processing is always enabled in sdcpp */ - CPP_OPTION (pfile, trigraphs) = 1; - CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; CPP_OPTION (pfile, digraphs) = l->digraphs; CPP_OPTION (pfile, uliterals) = l->uliterals; + CPP_OPTION (pfile, rliterals) = l->rliterals; + CPP_OPTION (pfile, user_literals) = l->user_literals; + CPP_OPTION (pfile, binary_constants) = l->binary_constants; + CPP_OPTION (pfile, digit_separators) = l->digit_separators; + CPP_OPTION (pfile, trigraphs) = l->trigraphs; + CPP_OPTION (pfile, utf8_char_literals) = l->utf8_char_literals; + CPP_OPTION (pfile, va_opt) = l->va_opt; + CPP_OPTION (pfile, scope) = l->scope; + CPP_OPTION (pfile, dfp_constants) = l->dfp_constants; + CPP_OPTION (pfile, size_t_literals) = l->size_t_literals; + CPP_OPTION (pfile, elifdef) = l->elifdef; } /* Initialize library global state. */ @@ -132,6 +165,8 @@ init_library (void) { initialized = 1; + _cpp_init_lexer (); + /* Set up the trigraph map. This doesn't need to do anything if we were compiled with a compiler that supports C99 designated initializers. */ @@ -145,8 +180,8 @@ init_library (void) /* Initialize a cpp_reader structure. */ cpp_reader * -cpp_create_reader (enum c_lang lang, hash_table *table, - struct line_maps *line_table) +cpp_create_reader (enum c_lang lang, cpp_hash_table *table, + class line_maps *line_table) { cpp_reader *pfile; @@ -154,23 +189,39 @@ cpp_create_reader (enum c_lang lang, hash_table *table, init_library (); pfile = XCNEW (cpp_reader); + memset (&pfile->base_context, 0, sizeof (pfile->base_context)); cpp_set_lang (pfile, lang); CPP_OPTION (pfile, warn_multichar) = 1; CPP_OPTION (pfile, discard_comments) = 1; CPP_OPTION (pfile, discard_comments_in_macro_exp) = 1; - CPP_OPTION (pfile, tabstop) = 8; + CPP_OPTION (pfile, max_include_depth) = 200; CPP_OPTION (pfile, operator_names) = 1; - /* Trigraphs wrning is always enabled in sdcpp */ - CPP_OPTION (pfile, warn_trigraphs) = 1; + CPP_OPTION (pfile, warn_trigraphs) = 2; CPP_OPTION (pfile, warn_endif_labels) = 1; + CPP_OPTION (pfile, cpp_warn_c90_c99_compat) = -1; + CPP_OPTION (pfile, cpp_warn_c11_c2x_compat) = -1; + CPP_OPTION (pfile, cpp_warn_cxx11_compat) = 0; CPP_OPTION (pfile, cpp_warn_deprecated) = 1; CPP_OPTION (pfile, cpp_warn_long_long) = 0; CPP_OPTION (pfile, dollars_in_ident) = 1; CPP_OPTION (pfile, warn_dollars) = 1; CPP_OPTION (pfile, warn_variadic_macros) = 1; CPP_OPTION (pfile, warn_builtin_macro_redefined) = 1; + CPP_OPTION (pfile, cpp_warn_implicit_fallthrough) = 0; + /* By default, track locations of tokens resulting from macro + expansion. The '2' means, track the locations with the highest + accuracy. Read the comments for struct + cpp_options::track_macro_expansion to learn about the other + values. */ + CPP_OPTION (pfile, track_macro_expansion) = 2; CPP_OPTION (pfile, warn_normalize) = normalized_C; + CPP_OPTION (pfile, warn_literal_suffix) = 1; + CPP_OPTION (pfile, canonical_system_headers) + = ENABLE_CANONICAL_SYSTEM_HEADERS; + CPP_OPTION (pfile, ext_numeric_literals) = 1; + CPP_OPTION (pfile, warn_date_time) = 0; + CPP_OPTION (pfile, cpp_warn_bidirectional) = bidirectional_unpaired; /* Default CPP arithmetic to something sensible for the host for the benefit of dumb users like fix-header. */ @@ -204,8 +255,10 @@ cpp_create_reader (enum c_lang lang, hash_table *table, /* Set up static tokens. */ pfile->avoid_paste.type = CPP_PADDING; pfile->avoid_paste.val.source = NULL; - pfile->eof.type = CPP_EOF; - pfile->eof.flags = 0; + pfile->avoid_paste.src_loc = 0; + pfile->endarg.type = CPP_EOF; + pfile->endarg.flags = 0; + pfile->endarg.src_loc = 0; /* Create a token buffer for the lexer. */ _cpp_init_tokenrun (&pfile->base_run, 250); @@ -214,7 +267,7 @@ cpp_create_reader (enum c_lang lang, hash_table *table, /* Initialize the base context. */ pfile->context = &pfile->base_context; - pfile->base_context.macro = 0; + pfile->base_context.c.macro = 0; pfile->base_context.prev = pfile->base_context.next = 0; /* Aligned and unaligned storage. */ @@ -224,16 +277,22 @@ cpp_create_reader (enum c_lang lang, hash_table *table, /* Initialize table for push_macro/pop_macro. */ pfile->pushed_macros = 0; + /* Do not force token locations by default. */ + pfile->forced_token_location = 0; + + /* Note the timestamp is unset. */ + pfile->time_stamp = time_t (-1); + pfile->time_stamp_kind = 0; + /* The expression parser stack. */ _cpp_expand_op_stack (pfile); /* Initialize the buffer obstack. */ - _obstack_begin (&pfile->buffer_ob, 0, 0, - (void *(*) (size_t)) xmalloc, - (void (*) (void *)) free); + obstack_specify_allocation (&pfile->buffer_ob, 0, 0, xmalloc, free); _cpp_init_files (pfile); + // sdcc hack not reached?! _cpp_init_hashtable (pfile, table); return pfile; @@ -242,7 +301,7 @@ cpp_create_reader (enum c_lang lang, hash_table *table, /* Set the line_table entry in PFILE. This is called after reading a PCH file, as the old line_table will be incorrect. */ void -cpp_set_line_map (cpp_reader *pfile, struct line_maps *line_table) +cpp_set_line_map (cpp_reader *pfile, class line_maps *line_table) { pfile->line_table = line_table; } @@ -262,8 +321,7 @@ cpp_destroy (cpp_reader *pfile) while (CPP_BUFFER (pfile) != NULL) _cpp_pop_buffer (pfile); - if (pfile->out.base) - free (pfile->out.base); + free (pfile->out.base); if (pfile->macro_buffer) { @@ -325,7 +383,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 - macro.c. Builtin is somewhat of a misnomer -- the property of + macro.cc. Builtin is somewhat of a misnomer -- the property of interest is that these macros require special code to compute their expansions. The value is a "cpp_builtin_type" enumerator. @@ -349,10 +407,20 @@ static const struct builtin_macro builtin_array[] = B("__TIME__", BT_TIME, false), B("__DATE__", BT_DATE, false), B("__FILE__", BT_FILE, false), + B("__FILE_NAME__", BT_FILE_NAME, false), B("__BASE_FILE__", BT_BASE_FILE, false), B("__LINE__", BT_SPECLINE, true), B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL, true), B("__COUNTER__", BT_COUNTER, true), + /* Make sure to update the list of built-in + function-like macros in traditional.cc: + fun_like_macro() when adding more following */ + B("__has_attribute", BT_HAS_ATTRIBUTE, true), + B("__has_c_attribute", BT_HAS_STD_ATTRIBUTE, true), + B("__has_cpp_attribute", BT_HAS_ATTRIBUTE, true), + B("__has_builtin", BT_HAS_BUILTIN, true), + B("__has_include", BT_HAS_INCLUDE, true), + B("__has_include_next",BT_HAS_INCLUDE_NEXT, true), /* Keep builtins not used for -traditional-cpp at the end, and update init_builtins() if any more are added. */ B("_Pragma", BT_PRAGMA, true), @@ -433,16 +501,39 @@ cpp_init_special_builtins (cpp_reader *pfile) for (b = builtin_array; b < builtin_array + n; b++) { + if ((b->value == BT_HAS_ATTRIBUTE + || b->value == BT_HAS_STD_ATTRIBUTE + || b->value == BT_HAS_BUILTIN) + && (CPP_OPTION (pfile, lang) == CLK_ASM + || pfile->cb.has_attribute == NULL)) + continue; cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len); - hp->type = NT_MACRO; - hp->flags |= NODE_BUILTIN; - if (b->always_warn_if_redefined - || CPP_OPTION (pfile, warn_builtin_macro_redefined)) + hp->type = NT_BUILTIN_MACRO; + if (b->always_warn_if_redefined) hp->flags |= NODE_WARN; hp->value.builtin = (enum cpp_builtin_type) b->value; } } +/* Restore macro C to builtin macro definition. */ + +void +_cpp_restore_special_builtin (cpp_reader *pfile, struct def_pragma_macro *c) +{ + size_t len = strlen (c->name); + + for (const struct builtin_macro *b = builtin_array; + b < builtin_array + ARRAY_SIZE (builtin_array); b++) + if (b->len == len && memcmp (c->name, b->name, len + 1) == 0) + { + cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len); + hp->type = NT_BUILTIN_MACRO; + if (b->always_warn_if_redefined) + hp->flags |= NODE_WARN; + hp->value.builtin = (enum cpp_builtin_type) b->value; + } +} + /* Read the builtins table above and enter them, and language-specific macros, into the hash table. HOSTED is true if this is a hosted environment. */ @@ -457,17 +548,52 @@ cpp_init_builtins (cpp_reader *pfile, int hosted) _cpp_define_builtin (pfile, "__STDC__ 1"); if (CPP_OPTION (pfile, cplusplus)) - _cpp_define_builtin (pfile, "__cplusplus 1"); + { + /* C++23 is not yet a standard. For now, use an invalid + * year/month, 202100L, which is larger than 202002L. */ + if (CPP_OPTION (pfile, lang) == CLK_CXX23 + || CPP_OPTION (pfile, lang) == CLK_GNUCXX23) + _cpp_define_builtin (pfile, "__cplusplus 202100L"); + else if (CPP_OPTION (pfile, lang) == CLK_CXX20 + || CPP_OPTION (pfile, lang) == CLK_GNUCXX20) + _cpp_define_builtin (pfile, "__cplusplus 202002L"); + else if (CPP_OPTION (pfile, lang) == CLK_CXX17 + || CPP_OPTION (pfile, lang) == CLK_GNUCXX17) + _cpp_define_builtin (pfile, "__cplusplus 201703L"); + else if (CPP_OPTION (pfile, lang) == CLK_CXX14 + || CPP_OPTION (pfile, lang) == CLK_GNUCXX14) + _cpp_define_builtin (pfile, "__cplusplus 201402L"); + else if (CPP_OPTION (pfile, lang) == CLK_CXX11 + || CPP_OPTION (pfile, lang) == CLK_GNUCXX11) + _cpp_define_builtin (pfile, "__cplusplus 201103L"); + else + _cpp_define_builtin (pfile, "__cplusplus 199711L"); + } else if (CPP_OPTION (pfile, lang) == CLK_ASM) _cpp_define_builtin (pfile, "__ASSEMBLER__ 1"); else if (CPP_OPTION (pfile, lang) == CLK_STDC94) _cpp_define_builtin (pfile, "__STDC_VERSION__ 199409L"); - else if (CPP_OPTION (pfile, lang) == CLK_STDC1X - || CPP_OPTION (pfile, lang) == CLK_GNUC1X) + else if (CPP_OPTION (pfile, lang) == CLK_STDC2X + || CPP_OPTION (pfile, lang) == CLK_GNUC2X) + _cpp_define_builtin (pfile, "__STDC_VERSION__ 202000L"); + else if (CPP_OPTION (pfile, lang) == CLK_STDC17 + || CPP_OPTION (pfile, lang) == CLK_GNUC17) + _cpp_define_builtin (pfile, "__STDC_VERSION__ 201710L"); + else if (CPP_OPTION (pfile, lang) == CLK_STDC11 + || CPP_OPTION (pfile, lang) == CLK_GNUC11) _cpp_define_builtin (pfile, "__STDC_VERSION__ 201112L"); else if (CPP_OPTION (pfile, c99)) _cpp_define_builtin (pfile, "__STDC_VERSION__ 199901L"); + if (CPP_OPTION (pfile, uliterals) + && !(CPP_OPTION (pfile, cplusplus) + && (CPP_OPTION (pfile, lang) == CLK_GNUCXX + || CPP_OPTION (pfile, lang) == CLK_CXX98))) + { + _cpp_define_builtin (pfile, "__STDC_UTF_16__ 1"); + _cpp_define_builtin (pfile, "__STDC_UTF_32__ 1"); + } + if (hosted) _cpp_define_builtin (pfile, "__STDC_HOSTED__ 1"); else @@ -478,8 +604,8 @@ cpp_init_builtins (cpp_reader *pfile, int hosted) } /* Sanity-checks are dependent on command-line options, so it is - called as a subroutine of cpp_read_main_file (). */ -#if ENABLE_CHECKING + called as a subroutine of cpp_read_main_file. */ +#if CHECKING_P static void sanity_checks (cpp_reader *); static void sanity_checks (cpp_reader *pfile) { @@ -552,115 +678,163 @@ cpp_post_options (cpp_reader *pfile) } /* Setup for processing input from the file named FNAME, or stdin if - it is the empty string. Return the original filename - on success (e.g. foo.i->foo.c), or NULL on failure. */ + it is the empty string. Return the original filename on success + (e.g. foo.i->foo.c), or NULL on failure. INJECTING is true if + there may be injected headers before line 1 of the main file. */ const char * -cpp_read_main_file (cpp_reader *pfile, const char *fname) +cpp_read_main_file (cpp_reader *pfile, const char *fname, bool injecting) { - if (CPP_OPTION (pfile, deps.style) != DEPS_NONE) - { - if (!pfile->deps) - pfile->deps = deps_init (); - - /* Set the default target (if there is none already). */ - deps_add_default_target (pfile, fname); - } + if (mkdeps *deps = cpp_get_deps (pfile)) + /* Set the default target (if there is none already). */ + deps_add_default_target (pfile /*sdcpp*/, deps, fname); pfile->main_file - = _cpp_find_file (pfile, fname, &pfile->no_search_path, false, 0); + = _cpp_find_file (pfile, fname, + CPP_OPTION (pfile, preprocessed) ? &pfile->no_search_path + : CPP_OPTION (pfile, main_search) == CMS_user + ? pfile->quote_include + : CPP_OPTION (pfile, main_search) == CMS_system + ? pfile->bracket_include : &pfile->no_search_path, + /*angle=*/0, _cpp_FFK_NORMAL, 0); + if (_cpp_find_failed (pfile->main_file)) return NULL; - _cpp_stack_file (pfile, pfile->main_file, false); + _cpp_stack_file (pfile, pfile->main_file, + injecting || CPP_OPTION (pfile, preprocessed) + ? IT_PRE_MAIN : IT_MAIN, 0); /* For foo.i, read the original filename foo.c now, for the benefit of the front ends. */ if (CPP_OPTION (pfile, preprocessed)) - { - read_original_filename (pfile); - fname = pfile->line_table->maps[pfile->line_table->used-1].to_file; - } - return fname; + if (!read_original_filename (pfile)) + { + /* We're on line 1 after all. */ + auto *last = linemap_check_ordinary + (LINEMAPS_LAST_MAP (pfile->line_table, false)); + last->to_line = 1; + /* Inform of as-if a file change. */ + _cpp_do_file_change (pfile, LC_RENAME_VERBATIM, LINEMAP_FILE (last), + LINEMAP_LINE (last), LINEMAP_SYSP (last)); + } + + auto *map = LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table); + pfile->main_loc = MAP_START_LOCATION (map); + + return ORDINARY_MAP_FILE_NAME (map); } -/* For preprocessed files, if the first tokens are of the form # NUM. - handle the directive so we know the original file name. This will - generate file_change callbacks, which the front ends must handle - appropriately given their state of initialization. */ -static void -read_original_filename (cpp_reader *pfile) +location_t +cpp_main_loc (const cpp_reader *pfile) { - const cpp_token *token, *token1; + return pfile->main_loc; +} - /* Lex ahead; if the first tokens are of the form # NUM, then - process the directive, otherwise back up. */ - token = _cpp_lex_direct (pfile); - if (token->type == CPP_HASH) +/* For preprocessed files, if the very first characters are + '#<SPACE>[01]<SPACE>', then handle a line directive so we know the + original file name. This will generate file_change callbacks, + which the front ends must handle appropriately given their state of + initialization. We peek directly into the character buffer, so + that we're not confused by otherwise-skipped white space & + comments. We can be very picky, because this should have been + machine-generated text (by us, no less). This way we do not + interfere with the module directive state machine. */ + +static bool +read_original_filename (cpp_reader *pfile) +{ + auto *buf = pfile->buffer->next_line; + + if (pfile->buffer->rlimit - buf > 4 + && buf[0] == '#' + && buf[1] == ' ' + // Also permit '1', as that's what used to be here + && (buf[2] == '0' || buf[2] == '1') + && buf[3] == ' ') { - pfile->state.in_directive = 1; - token1 = _cpp_lex_direct (pfile); - _cpp_backup_tokens (pfile, 1); - pfile->state.in_directive = 0; - - /* If it's a #line directive, handle it. */ - if (token1->type == CPP_NUMBER - && _cpp_handle_directive (pfile, token->flags & PREV_WHITE)) + const cpp_token *token = _cpp_lex_direct (pfile); + gcc_checking_assert (token->type == CPP_HASH); + if (_cpp_handle_directive (pfile, token->flags & PREV_WHITE)) { read_original_directory (pfile); - return; + + auto *penult = &linemap_check_ordinary + (LINEMAPS_LAST_MAP (pfile->line_table, false))[-1]; + if (penult[1].reason == LC_RENAME_VERBATIM) + { + /* Expunge any evidence of the original linemap. */ + pfile->line_table->highest_location + = pfile->line_table->highest_line + = penult[0].start_location; + + penult[1].start_location = penult[0].start_location; + penult[1].reason = penult[0].reason; + penult[0] = penult[1]; + pfile->line_table->info_ordinary.used--; + pfile->line_table->info_ordinary.cache = 0; + } + + return true; } } - /* Backup as if nothing happened. */ - _cpp_backup_tokens (pfile, 1); + return false; } /* For preprocessed files, if the tokens following the first filename line is of the form # <line> "/path/name//", handle the - directive so we know the original current directory. */ + directive so we know the original current directory. + + As with the first line peeking, we can do this without lexing by + being picky. */ static void read_original_directory (cpp_reader *pfile) { - const cpp_token *hash, *token; - - /* Lex ahead; if the first tokens are of the form # NUM, then - process the directive, otherwise back up. */ - hash = _cpp_lex_direct (pfile); - if (hash->type != CPP_HASH) + auto *buf = pfile->buffer->next_line; + + if (pfile->buffer->rlimit - buf > 4 + && buf[0] == '#' + && buf[1] == ' ' + // Also permit '1', as that's what used to be here + && (buf[2] == '0' || buf[2] == '1') + && buf[3] == ' ') { - _cpp_backup_tokens (pfile, 1); - return; - } - - token = _cpp_lex_direct (pfile); + const cpp_token *hash = _cpp_lex_direct (pfile); + gcc_checking_assert (hash->type == CPP_HASH); + pfile->state.in_directive = 1; + const cpp_token *number = _cpp_lex_direct (pfile); + gcc_checking_assert (number->type == CPP_NUMBER); + const cpp_token *string = _cpp_lex_direct (pfile); + pfile->state.in_directive = 0; - if (token->type != CPP_NUMBER) - { - _cpp_backup_tokens (pfile, 2); - return; - } + const unsigned char *text = nullptr; + size_t len = 0; + if (string->type == CPP_STRING) + { + /* The string value includes the quotes. */ + text = string->val.str.text; + len = string->val.str.len; + } + if (len < 5 + || !IS_DIR_SEPARATOR (text[len - 2]) + || !IS_DIR_SEPARATOR (text[len - 3])) + { + /* That didn't work out, back out. */ + _cpp_backup_tokens (pfile, 3); + return; + } - token = _cpp_lex_direct (pfile); + if (pfile->cb.dir_change) + { + /* Smash the string directly, it's dead at this point */ + char *smashy = (char *)text; + smashy[len - 3] = 0; + + pfile->cb.dir_change (pfile, smashy + 1); + } - if (token->type != CPP_STRING - || ! (token->val.str.len >= 5 - && token->val.str.text[token->val.str.len-2] == '/' - && token->val.str.text[token->val.str.len-3] == '/')) - { - _cpp_backup_tokens (pfile, 3); - return; + /* We should be at EOL. */ } - - if (pfile->cb.dir_change) - { - char *debugdir = (char *) alloca (token->val.str.len - 3); - - memcpy (debugdir, (const char *) token->val.str.text + 1, - token->val.str.len - 4); - debugdir[token->val.str.len - 4] = '\0'; - - pfile->cb.dir_change (pfile, debugdir); - } } /* This is called at the end of preprocessing. It pops the last @@ -675,7 +849,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); - /* lex.c leaves the final buffer on the stack. This it so that + /* lex.cc 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 @@ -683,14 +857,8 @@ cpp_finish (cpp_reader *pfile, FILE *deps_stream) while (pfile->buffer) _cpp_pop_buffer (pfile); - if (CPP_OPTION (pfile, deps.style) != DEPS_NONE - && deps_stream) - { - deps_write (pfile->deps, deps_stream, 72); - - if (CPP_OPTION (pfile, deps.phony_targets)) - deps_phony_targets (pfile->deps, deps_stream); - } + if (deps_stream) + deps_write (pfile, deps_stream, 72); /* Report on headers that could use multiple include guards. */ if (CPP_OPTION (pfile, print_include_names)) @@ -713,8 +881,35 @@ post_options (cpp_reader *pfile) CPP_OPTION (pfile, traditional) = 0; } + if (CPP_OPTION (pfile, warn_trigraphs) == 2) + CPP_OPTION (pfile, warn_trigraphs) = !CPP_OPTION (pfile, trigraphs); + if (CPP_OPTION (pfile, traditional)) { - CPP_OPTION (pfile, cplusplus_comments) = 0; + CPP_OPTION (pfile, trigraphs) = 0; + CPP_OPTION (pfile, warn_trigraphs) = 0; + } + + if (CPP_OPTION (pfile, module_directives)) + { + /* These unspellable tokens have a leading space. */ + const char *const inits[spec_nodes::M_HWM] + = {"export ", "module ", "import ", "__import"}; + + for (int ix = 0; ix != spec_nodes::M_HWM; ix++) + { + cpp_hashnode *node = cpp_lookup (pfile, UC (inits[ix]), + strlen (inits[ix])); + + /* Token we pass to the compiler. */ + pfile->spec_nodes.n_modules[ix][1] = node; + + if (ix != spec_nodes::M__IMPORT) + /* Token we recognize when lexing, drop the trailing ' '. */ + node = cpp_lookup (pfile, NODE_NAME (node), NODE_LEN (node) - 1); + + node->flags |= NODE_MODULE; + pfile->spec_nodes.n_modules[ix][0] = node; + } } } diff --git a/support/cpp/libcpp/internal.h b/support/cpp/libcpp/internal.h index eeed29d39..9ece76155 100644 --- a/support/cpp/libcpp/internal.h +++ b/support/cpp/libcpp/internal.h @@ -1,6 +1,5 @@ /* Part of CPP library. - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, - 2008, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 1997-2022 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 @@ -24,7 +23,7 @@ along with this program; see the file COPYING3. If not see #define LIBCPP_INTERNAL_H #include "symtab.h" -#include "cpp-id-data.h" +#include "cpplib.h" #if HAVE_ICONV #include <iconv.h> @@ -49,6 +48,8 @@ struct cset_converter convert_f func; iconv_t cd; int width; + const char* from; + const char* to; }; #define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t)) @@ -60,22 +61,21 @@ struct cset_converter || (((prevc) == 'p' || (prevc) == 'P') \ && CPP_OPTION (pfile, extended_numbers)))) +#define DIGIT_SEP(c) ((c) == '\'' && CPP_OPTION (pfile, digit_separators)) + #define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION) #define CPP_BUFFER(PFILE) ((PFILE)->buffer) #define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base) #define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur) #define CPP_INCREMENT_LINE(PFILE, COLS_HINT) do { \ - const struct line_maps *line_table = PFILE->line_table; \ - const struct line_map *map = &line_table->maps[line_table->used-1]; \ + const class line_maps *line_table = PFILE->line_table; \ + const struct line_map_ordinary *map = \ + LINEMAPS_LAST_ORDINARY_MAP (line_table); \ linenum_type line = SOURCE_LINE (map, line_table->highest_line); \ linemap_line_start (PFILE->line_table, line + 1, COLS_HINT); \ } while (0) -/* Maximum nesting of cpp_buffers. We use a static limit, partly for - efficiency, and partly to limit runaway recursion. */ -#define CPP_STACK_MAX 200 - /* Host alignment handling. */ struct dummy { @@ -91,9 +91,8 @@ struct dummy #define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1)) #define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT) -#define _cpp_mark_macro_used(NODE) do { \ - if ((NODE)->type == NT_MACRO && !((NODE)->flags & NODE_BUILTIN)) \ - (NODE)->value.macro->used = 1; } while (0) +#define _cpp_mark_macro_used(NODE) \ + (cpp_user_macro_p (NODE) ? (NODE)->value.macro->used = 1 : 0) /* A generic memory buffer, and operations on it. */ typedef struct _cpp_buff _cpp_buff; @@ -116,7 +115,23 @@ extern unsigned char *_cpp_unaligned_alloc (cpp_reader *, size_t); #define BUFF_LIMIT(BUFF) ((BUFF)->limit) /* #include types. */ -enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE}; +enum include_type + { + /* Directive-based including mechanisms. */ + IT_INCLUDE, /* #include */ + IT_INCLUDE_NEXT, /* #include_next */ + IT_IMPORT, /* #import */ + + /* Non-directive including mechanisms. */ + IT_CMDLINE, /* -include */ + IT_DEFAULT, /* forced header */ + IT_MAIN, /* main, start on line 1 */ + IT_PRE_MAIN, /* main, but there will be a preamble before line + 1 */ + + IT_DIRECTIVE_HWM = IT_IMPORT + 1, /* Directives below this. */ + IT_HEADER_HWM = IT_DEFAULT + 1 /* Header files below this. */ + }; union utoken { @@ -138,6 +153,40 @@ struct tokenrun #define CUR(c) ((c)->u.trad.cur) #define RLIMIT(c) ((c)->u.trad.rlimit) +/* This describes some additional data that is added to the macro + token context of type cpp_context, when -ftrack-macro-expansion is + on. */ +typedef struct +{ + /* The node of the macro we are referring to. */ + cpp_hashnode *macro_node; + /* This buffer contains an array of virtual locations. The virtual + location at index 0 is the virtual location of the token at index + 0 in the current instance of cpp_context; similarly for all the + other virtual locations. */ + location_t *virt_locs; + /* This is a pointer to the current virtual location. This is used + to iterate over the virtual locations while we iterate over the + tokens they belong to. */ + location_t *cur_virt_loc; +} macro_context; + +/* The kind of tokens carried by a cpp_context. */ +enum context_tokens_kind { + /* This is the value of cpp_context::tokens_kind if u.iso.first + contains an instance of cpp_token **. */ + TOKENS_KIND_INDIRECT, + /* This is the value of cpp_context::tokens_kind if u.iso.first + contains an instance of cpp_token *. */ + TOKENS_KIND_DIRECT, + /* This is the value of cpp_context::tokens_kind when the token + context contains tokens resulting from macro expansion. In that + case struct cpp_context::macro points to an instance of struct + macro_context. This is used only when the + -ftrack-macro-expansion flag is on. */ + TOKENS_KIND_EXTENDED +}; + typedef struct cpp_context cpp_context; struct cpp_context { @@ -167,16 +216,30 @@ struct cpp_context When the context is popped, the buffer is released. */ _cpp_buff *buff; - /* For a macro context, the macro node, otherwise NULL. */ - cpp_hashnode *macro; + /* If tokens_kind is TOKEN_KIND_EXTENDED, then (as we thus are in a + macro context) this is a pointer to an instance of macro_context. + Otherwise if tokens_kind is *not* TOKEN_KIND_EXTENDED, then, if + we are in a macro context, this is a pointer to an instance of + cpp_hashnode, representing the name of the macro this context is + for. If we are not in a macro context, then this is just NULL. + Note that when tokens_kind is TOKEN_KIND_EXTENDED, the memory + used by the instance of macro_context pointed to by this member + is de-allocated upon de-allocation of the instance of struct + cpp_context. */ + union + { + macro_context *mc; + cpp_hashnode *macro; + } c; - /* True if utoken element is token, else ptoken. */ - bool direct_p; + /* This determines the type of tokens held by this context. */ + enum context_tokens_kind tokens_kind; }; struct lexer_state { - /* Nonzero if first token on line is CPP_HASH. */ + /* 1 if we're handling a directive. 2 if it's an include-like + directive. */ unsigned char in_directive; /* Nonzero if in a directive that will handle padding tokens itself. @@ -197,7 +260,7 @@ struct lexer_state all directives apart from #define. */ unsigned char save_comments; - /* Nonzero if lexing __VA_ARGS__ is valid. */ + /* Nonzero if lexing __VA_ARGS__ and __VA_OPT__ are valid. */ unsigned char va_args_ok; /* Nonzero if lexing poisoned identifiers is valid. */ @@ -216,11 +279,17 @@ struct lexer_state /* Nonzero to skip evaluating part of an expression. */ unsigned int skip_eval; - /* Nonzero when handling a deferred pragma. */ + /* Nonzero when tokenizing a deferred pragma. */ unsigned char in_deferred_pragma; + /* Count to token that is a header-name. */ + unsigned char directive_file_token; + /* Nonzero if the deferred pragma being handled allows macro expansion. */ unsigned char pragma_allow_expansion; + + /* Nonzero if _Pragma should not be interpreted. */ + unsigned char ignore__Pragma; }; /* Special nodes - identifiers with predefined significance. */ @@ -230,6 +299,14 @@ struct spec_nodes cpp_hashnode *n_true; /* C++ keyword true */ cpp_hashnode *n_false; /* C++ keyword false */ cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */ + cpp_hashnode *n__VA_OPT__; /* C++ vararg macros */ + + enum {M_EXPORT, M_MODULE, M_IMPORT, M__IMPORT, M_HWM}; + + /* C++20 modules, only set when module_directives is in effect. + incoming variants [0], outgoing ones [1] */ + cpp_hashnode *n_modules[M_HWM][2]; + /* SDCC _asm specific */ cpp_hashnode *n__asm; /* __asm ... __endasm ; */ cpp_hashnode *n__endasm; /* __asm ... __endasm ; */ @@ -257,6 +334,8 @@ struct cpp_buffer const unsigned char *buf; /* Entire character buffer. */ const unsigned char *rlimit; /* Writable byte at end of file. */ + const unsigned char *to_free; /* Pointer that should be freed when + popping the buffer. */ _cpp_line_note *notes; /* Array of notes. */ unsigned int cur_note; /* Next note to process. */ @@ -278,23 +357,23 @@ struct cpp_buffer struct if_stack *if_stack; /* True if we need to get the next clean line. */ - bool need_line; + bool need_line : 1; /* True if we have already warned about C++ comments in this file. The warning happens only for C89 extended mode with -pedantic on, or for -Wtraditional, and only once per file (otherwise it would be far too noisy). */ - unsigned int warned_cplusplus_comments : 1; + bool warned_cplusplus_comments : 1; /* True if we don't process trigraphs and escaped newlines. True for preprocessed input, command line directives, and _Pragma buffers. */ - unsigned int from_stage3 : 1; + bool 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; + bool 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. */ @@ -319,7 +398,7 @@ struct def_pragma_macro { unsigned char *definition; /* Definition line number. */ - source_location line; + location_t line; /* If macro defined in system header. */ unsigned int syshdr : 1; /* Nonzero if it has been expanded or had its existence tested. */ @@ -327,6 +406,8 @@ struct def_pragma_macro { /* Mark if we save an undefined macro. */ unsigned int is_undef : 1; + /* Nonzero if it was a builtin macro. */ + unsigned int is_builtin : 1; }; /* A cpp_reader encapsulates the "state" of a pre-processor run. @@ -344,10 +425,10 @@ struct cpp_reader struct lexer_state state; /* Source line tracking. */ - struct line_maps *line_table; + class line_maps *line_table; /* The line of the '#' of the current directive. */ - source_location directive_line; + location_t directive_line; /* Memory buffers. */ _cpp_buff *a_buff; /* Aligned permanent storage. */ @@ -366,11 +447,20 @@ struct cpp_reader /* When expanding a macro at top-level, this is the location of the macro invocation. */ - source_location invocation_location; + location_t invocation_location; + + /* This is the node representing the macro being expanded at + top-level. The value of this data member is valid iff + cpp_in_macro_expansion_p() returns TRUE. */ + cpp_hashnode *top_most_macro_node; - /* True if this call to cpp_get_token should consider setting - invocation_location. */ - bool set_invocation_location; + /* Nonzero if we are about to expand a macro. Note that if we are + really expanding a macro, the function macro_of_context returns + the macro being expanded and this flag is set to false. Client + code should use the function cpp_in_macro_expansion_p to know if we + are either about to expand a macro, or are actually expanding + one. */ + bool about_to_expand_macro_p; /* Search paths for include files. */ struct cpp_dir *quote_include; /* "" */ @@ -440,19 +530,23 @@ struct cpp_reader const unsigned char *date; const unsigned char *time; - /* EOF token, and a token forcing paste avoidance. */ + /* Time stamp, set idempotently lazily. */ + time_t time_stamp; + int time_stamp_kind; /* Or errno. */ + + /* A token forcing paste avoidance, and one demarking macro arguments. */ cpp_token avoid_paste; - cpp_token eof; + cpp_token endarg; - /* Opaque handle to the dependencies of mkdeps.c. */ - struct deps *deps; + /* Opaque handle to the dependencies of mkdeps.cc. */ + class mkdeps *deps; /* Obstack holding all macro hash nodes. This never shrinks. - See identifiers.c */ + See identifiers.cc */ struct obstack hash_ob; /* Obstack holding buffer and conditional structures. This is a - real stack. See directives.c. */ + real stack. See directives.cc. */ struct obstack buffer_ob; /* Pragma table - dynamic, because a library user can add to the @@ -484,10 +578,10 @@ struct cpp_reader unsigned char *base; unsigned char *limit; unsigned char *cur; - source_location first_line; + location_t first_line; } out; - /* Used for buffer overlays by traditional.c. */ + /* Used for buffer overlays by traditional.cc. */ const unsigned char *saved_cur, *saved_rlimit, *saved_line_base; /* A saved list of the defined macros, for dependency checking @@ -502,6 +596,22 @@ struct cpp_reader /* List of saved macros by push_macro. */ struct def_pragma_macro *pushed_macros; + + /* If non-zero, the lexer will use this location for the next token + instead of getting a location from the linemap. */ + location_t forced_token_location; + + /* Location identifying the main source file -- intended to be line + zero of said file. */ + location_t main_loc; + + /* Returns true iff we should warn about UTF-8 bidirectional control + characters. */ + bool warn_bidi_p () const + { + return (CPP_OPTION (this, cpp_warn_bidirectional) + & (bidirectional_unpaired|bidirectional_any)); + } }; /* Character classes. Based on the more primitive macros in safe-ctype.h. @@ -509,7 +619,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 lex.c must be + the set is_vspace, the macro handle_newline() in lex.cc must be updated. */ #define _dollar_ok(x) ((x) == '$' && CPP_OPTION (pfile, dollars_in_ident)) @@ -522,6 +632,8 @@ struct cpp_reader #define is_nvspace(x) IS_NVSPACE(x) #define is_space(x) IS_SPACE_OR_NUL(x) +#define SEEN_EOL() (pfile->cur_token[-1].type == CPP_EOF) + /* This table is constant if it can be initialized at compile time, which is the case if cpp was compiled with GCC >=2.7, or another compiler that supports C99. */ @@ -531,121 +643,166 @@ extern const unsigned char _cpp_trigraph_map[UCHAR_MAX + 1]; extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1]; #endif -/* Macros. */ +#if defined (IN_GCC) +#elif defined (HAVE_UCHAR) +#else +typedef unsigned char uchar; +#endif -static inline int cpp_in_system_header (cpp_reader *); -static inline int -cpp_in_system_header (cpp_reader *pfile) +#define UC (const uchar *) /* Intended use: UC"string" */ + +/* Accessors. */ + +inline int +_cpp_in_system_header (cpp_reader *pfile) { return pfile->buffer ? pfile->buffer->sysp : 0; } #define CPP_PEDANTIC(PF) CPP_OPTION (PF, cpp_pedantic) #define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, cpp_warn_traditional) -static inline int cpp_in_primary_file (cpp_reader *); -static inline int -cpp_in_primary_file (cpp_reader *pfile) +/* Return true if we're in the main file (unless it's considered to be + an include file in its own right. */ +inline int +_cpp_in_main_source_file (cpp_reader *pfile) +{ + return (!CPP_OPTION (pfile, main_search) + && pfile->buffer->file == pfile->main_file); +} + +/* True if NODE is a macro for the purposes of ifdef, defined etc. */ +inline bool _cpp_defined_macro_p (cpp_hashnode *node) { - return pfile->line_table->depth == 1; + /* Do not treat conditional macros as being defined. This is due to + the powerpc port using conditional macros for 'vector', 'bool', + and 'pixel' to act as conditional keywords. This messes up tests + like #ifndef bool. */ + return cpp_macro_p (node) && !(node->flags & NODE_CONDITIONAL); } -/* In macro.c */ +/* In macro.cc */ +extern bool _cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node, + location_t); +inline bool _cpp_maybe_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node, + location_t loc) +{ + if (!(node->flags & NODE_USED)) + return _cpp_notify_macro_use (pfile, node, loc); + return true; +} +extern cpp_macro *_cpp_new_macro (cpp_reader *, cpp_macro_kind, void *); extern void _cpp_free_definition (cpp_hashnode *); extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *); extern void _cpp_pop_context (cpp_reader *); extern void _cpp_push_text_context (cpp_reader *, cpp_hashnode *, const unsigned char *, size_t); -extern bool _cpp_save_parameter (cpp_reader *, cpp_macro *, cpp_hashnode *); +extern bool _cpp_save_parameter (cpp_reader *, unsigned, cpp_hashnode *, + cpp_hashnode *); +extern void _cpp_unsave_parameters (cpp_reader *, unsigned); extern bool _cpp_arguments_ok (cpp_reader *, cpp_macro *, const cpp_hashnode *, unsigned int); extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *, - cpp_hashnode *); + cpp_hashnode *, + location_t = 0); extern int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *); extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *, const cpp_token *, unsigned int); extern void _cpp_backup_tokens_direct (cpp_reader *, unsigned int); -/* In identifiers.c */ -extern void _cpp_init_hashtable (cpp_reader *, hash_table *); +/* In identifiers.cc */ +extern void _cpp_init_hashtable (cpp_reader *, cpp_hash_table *); extern void _cpp_destroy_hashtable (cpp_reader *); -/* In files.c */ -typedef struct _cpp_file _cpp_file; +/* In files.cc */ +enum _cpp_find_file_kind + { _cpp_FFK_NORMAL, _cpp_FFK_FAKE, _cpp_FFK_PRE_INCLUDE, _cpp_FFK_HAS_INCLUDE }; extern _cpp_file *_cpp_find_file (cpp_reader *, const char *, cpp_dir *, - bool, int); + int angle, _cpp_find_file_kind, location_t); extern bool _cpp_find_failed (_cpp_file *); extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *); +extern const char *_cpp_find_header_unit (cpp_reader *, const char *file, + bool angle_p, location_t); extern void _cpp_fake_include (cpp_reader *, const char *); -extern bool _cpp_stack_file (cpp_reader *, _cpp_file*, bool); +extern bool _cpp_stack_file (cpp_reader *, _cpp_file*, include_type, location_t); extern bool _cpp_stack_include (cpp_reader *, const char *, int, - enum include_type); + enum include_type, location_t); extern int _cpp_compare_file_date (cpp_reader *, const char *, int); extern void _cpp_report_missing_guards (cpp_reader *); extern void _cpp_init_files (cpp_reader *); extern void _cpp_cleanup_files (cpp_reader *); -extern void _cpp_pop_file_buffer (cpp_reader *, struct _cpp_file *); +extern void _cpp_pop_file_buffer (cpp_reader *, struct _cpp_file *, + const unsigned char *); extern bool _cpp_save_file_entries (cpp_reader *pfile, FILE *f); extern bool _cpp_read_file_entries (cpp_reader *, FILE *); +extern const char *_cpp_get_file_name (_cpp_file *); extern struct stat *_cpp_get_file_stat (_cpp_file *); +extern bool _cpp_has_header (cpp_reader *, const char *, int, + enum include_type); -/* In expr.c */ +/* In expr.cc */ extern bool _cpp_parse_expr (cpp_reader *, bool); extern struct op *_cpp_expand_op_stack (cpp_reader *); -/* In lex.c */ -extern int _cpp_process_line_notes (cpp_reader *, int); +/* In lex.cc */ +extern int /* HACK */ _cpp_process_line_notes (cpp_reader *, int); extern void _cpp_clean_line (cpp_reader *); extern bool _cpp_get_fresh_line (cpp_reader *); extern bool _cpp_skip_block_comment (cpp_reader *); extern cpp_token *_cpp_temp_token (cpp_reader *); extern const cpp_token *_cpp_lex_token (cpp_reader *); extern cpp_token *_cpp_lex_direct (cpp_reader *); +extern unsigned char *_cpp_spell_ident_ucns (unsigned char *, cpp_hashnode *); extern int _cpp_equiv_tokens (const cpp_token *, const cpp_token *); extern void _cpp_init_tokenrun (tokenrun *, unsigned int); extern cpp_hashnode *_cpp_lex_identifier (cpp_reader *, const char *); +extern int _cpp_remaining_tokens_num_in_context (cpp_context *); +extern void _cpp_init_lexer (void); +static inline void *_cpp_reserve_room (cpp_reader *pfile, size_t have, + size_t extra) +{ + if (BUFF_ROOM (pfile->a_buff) < (have + extra)) + _cpp_extend_buff (pfile, &pfile->a_buff, extra); + return BUFF_FRONT (pfile->a_buff); +} +extern void *_cpp_commit_buff (cpp_reader *pfile, size_t size); -/* In init.c. */ +/* In init.cc. */ extern void _cpp_maybe_push_include_file (cpp_reader *); extern const char *cpp_named_operator2name (enum cpp_ttype type); +extern void _cpp_restore_special_builtin (cpp_reader *pfile, + struct def_pragma_macro *); -/* In directives.c */ +/* In directives.cc */ extern int _cpp_test_assertion (cpp_reader *, unsigned int *); -extern int _cpp_handle_directive (cpp_reader *, int); +extern int _cpp_handle_directive (cpp_reader *, bool); extern void _cpp_define_builtin (cpp_reader *, const char *); extern char ** _cpp_save_pragma_names (cpp_reader *); extern void _cpp_restore_pragma_names (cpp_reader *, char **); -extern int _cpp_do__Pragma (cpp_reader *); +extern int _cpp_do__Pragma (cpp_reader *, location_t); extern void _cpp_init_directives (cpp_reader *); extern void _cpp_init_internal_pragmas (cpp_reader *); extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *, linenum_type, unsigned int); extern void _cpp_pop_buffer (cpp_reader *); +extern char *_cpp_bracket_include (cpp_reader *); -/* In directives.c */ -struct _cpp_dir_only_callbacks -{ - /* Called to print a block of lines. */ - void (*print_lines) (int, const void *, size_t); - void (*maybe_print_line) (source_location); -}; +/* In errors.cc */ +extern location_t cpp_diagnostic_get_current_location (cpp_reader *); -extern void _cpp_preprocess_dir_only (cpp_reader *, - const struct _cpp_dir_only_callbacks *); - -/* In traditional.c. */ -extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *); +/* In traditional.cc. */ +extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *, bool); extern bool _cpp_read_logical_line_trad (cpp_reader *); extern void _cpp_overlay_buffer (cpp_reader *pfile, const unsigned char *, size_t); extern void _cpp_remove_overlay (cpp_reader *); -extern bool _cpp_create_trad_definition (cpp_reader *, cpp_macro *); +extern cpp_macro *_cpp_create_trad_definition (cpp_reader *); extern bool _cpp_expansions_different_trad (const cpp_macro *, const cpp_macro *); extern unsigned char *_cpp_copy_replacement_text (const cpp_macro *, unsigned char *); extern size_t _cpp_replacement_text_len (const cpp_macro *); -/* In charset.c. */ +/* In charset.cc. */ /* The normalization state at this point in the sequence. It starts initialized to all zeros, and at the end @@ -653,9 +810,10 @@ extern size_t _cpp_replacement_text_len (const cpp_macro *); struct normalize_state { - /* The previous character. */ + /* The previous starter character. */ cppchar_t previous; - /* The combining class of the previous character. */ + /* The combining class of the previous character (whether or not a + starter). */ unsigned char prev_class; /* The lowest normalization level so far. */ enum cpp_normalize_level level; @@ -663,14 +821,25 @@ struct normalize_state #define INITIAL_NORMALIZE_STATE { 0, 0, normalized_KC } #define NORMALIZE_STATE_RESULT(st) ((st)->level) -/* We saw a character that matches ISIDNUM(), update a +/* We saw a character C that matches ISIDNUM(), update a normalize_state appropriately. */ -#define NORMALIZE_STATE_UPDATE_IDNUM(st) \ - ((st)->previous = 0, (st)->prev_class = 0) +#define NORMALIZE_STATE_UPDATE_IDNUM(st, c) \ + ((st)->previous = (c), (st)->prev_class = 0) + +extern bool _cpp_valid_ucn (cpp_reader *, const unsigned char **, + const unsigned char *, int, + struct normalize_state *state, + cppchar_t *, + source_range *char_range, + cpp_string_location_reader *loc_reader); + +extern bool _cpp_valid_utf8 (cpp_reader *pfile, + const uchar **pstr, + const uchar *limit, + int identifier_pos, + struct normalize_state *nst, + cppchar_t *cp); -extern cppchar_t _cpp_valid_ucn (cpp_reader *, const unsigned char **, - const unsigned char *, int, - struct normalize_state *state); extern void _cpp_destroy_iconv (cpp_reader *); extern unsigned char *_cpp_convert_input (cpp_reader *, const char *, unsigned char *, size_t, size_t, @@ -689,8 +858,8 @@ 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 const unsigned char *uxstrdup (const unsigned char *); +static inline const 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. */ @@ -720,16 +889,16 @@ ustrlen (const unsigned char *s1) return strlen ((const char *)s1); } -static inline unsigned char * +static inline const unsigned char * uxstrdup (const unsigned char *s1) { - return (unsigned char *) xstrdup ((const char *)s1); + return (const unsigned char *) xstrdup ((const char *)s1); } -static inline unsigned char * +static inline const unsigned char * ustrchr (const unsigned char *s1, int c) { - return (unsigned char *) strchr ((const char *)s1, c); + return (const unsigned char *) strchr ((const char *)s1, c); } static inline int @@ -738,6 +907,74 @@ ufputs (const unsigned char *s, FILE *f) return fputs ((const char *)s, f); } +/* In line-map.cc. */ + +/* Create and return a virtual location for a token that is part of a + macro expansion-list at a macro expansion point. See the comment + inside struct line_map_macro to see what an expansion-list exactly + is. + + A call to this function must come after a call to + linemap_enter_macro. + + MAP is the map into which the source location is created. TOKEN_NO + is the index of the token in the macro replacement-list, starting + at number 0. + + ORIG_LOC is the location of the token outside of this macro + expansion. If the token comes originally from the macro + definition, it is the locus in the macro definition; otherwise it + is a location in the context of the caller of this macro expansion + (which is a virtual location or a source location if the caller is + itself a macro expansion or not). + + MACRO_DEFINITION_LOC is the location in the macro definition, + either of the token itself or of a macro parameter that it + replaces. */ +location_t linemap_add_macro_token (const line_map_macro *, + unsigned int, + location_t, + location_t); + +/* Return the source line number corresponding to source location + LOCATION. SET is the line map set LOCATION comes from. If + LOCATION is the location of token that is part of the + expansion-list of a macro expansion return the line number of the + macro expansion point. */ +int linemap_get_expansion_line (class line_maps *, + location_t); + +/* Return the path of the file corresponding to source code location + LOCATION. + + If LOCATION is the location of a token that is part of the + replacement-list of a macro expansion return the file path of the + macro expansion point. + + SET is the line map set LOCATION comes from. */ +const char* linemap_get_expansion_filename (class line_maps *, + location_t); + +/* A subclass of rich_location for emitting a diagnostic + at the current location of the reader, but flagging + it with set_escape_on_output (true). */ +class encoding_rich_location : public rich_location +{ + public: + encoding_rich_location (cpp_reader *pfile) + : rich_location (pfile->line_table, + cpp_diagnostic_get_current_location (pfile)) + { + set_escape_on_output (true); + } + + encoding_rich_location (cpp_reader *pfile, location_t loc) + : rich_location (pfile->line_table, loc) + { + set_escape_on_output (true); + } +}; + #ifdef __cplusplus } #endif diff --git a/support/cpp/libcpp/lex.c b/support/cpp/libcpp/lex.c deleted file mode 100644 index ccb4b0fe0..000000000 --- a/support/cpp/libcpp/lex.c +++ /dev/null @@ -1,2906 +0,0 @@ -/* CPP Library - lexical analysis. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - Contributed by Per Bothner, 1994-95. - Based on CCCP program by Paul Rubin, June 1986 - Adapted to ANSI C, Richard Stallman, Jan 1987 - Broken out to separate file, Zack Weinberg, Mar 2000 - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -#include "config.h" -#include "system.h" -#include "cpplib.h" -#include "internal.h" -#include <assert.h> - -enum spell_type -{ - SPELL_OPERATOR = 0, - SPELL_IDENT, - SPELL_LITERAL, - SPELL_NONE -}; - -struct token_spelling -{ - enum spell_type category; - const unsigned char *name; -}; - -static const unsigned char *const digraph_spellings[] = -{ UC"%:", UC"%:%:", UC"<:", UC":>", UC"<%", UC"%>" }; - -#define OP(e, s) { SPELL_OPERATOR, UC s }, -#define TK(e, s) { SPELL_ ## s, UC #e }, -static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE }; -#undef OP -#undef TK - -#define TOKEN_SPELL(token) (token_spellings[(token)->type].category) -#define TOKEN_NAME(token) (token_spellings[(token)->type].name) - -static void add_line_note (cpp_buffer *, const uchar *, unsigned int); -static int skip_line_comment (cpp_reader *); -static void skip_whitespace (cpp_reader *, cppchar_t); -static void lex_string (cpp_reader *, cpp_token *, const uchar *); -static void save_comment (cpp_reader *, cpp_token *, const uchar *, cppchar_t); -static void store_comment (cpp_reader *, cpp_token *); -static void create_literal (cpp_reader *, cpp_token *, const uchar *, - unsigned int, enum cpp_ttype); -static bool warn_in_comment (cpp_reader *, _cpp_line_note *); -static int name_p (cpp_reader *, const cpp_string *); -static tokenrun *next_tokenrun (tokenrun *); - -static _cpp_buff *new_buff (size_t); - -int in_asm = 0; - -/* Utility routine: - - Compares, the token TOKEN to the NUL-terminated string STRING. - TOKEN must be a CPP_NAME. Returns 1 for equal, 0 for unequal. */ -int -cpp_ideq (const cpp_token *token, const char *string) -{ - if (token->type != CPP_NAME) - return 0; - - return !ustrcmp (NODE_NAME (token->val.node.node), (const uchar *) string); -} - -/* Record a note TYPE at byte POS into the current cleaned logical - line. */ -static void -add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type) -{ - if (buffer->notes_used == buffer->notes_cap) - { - buffer->notes_cap = buffer->notes_cap * 2 + 200; - buffer->notes = XRESIZEVEC (_cpp_line_note, buffer->notes, - buffer->notes_cap); - } - - buffer->notes[buffer->notes_used].pos = pos; - buffer->notes[buffer->notes_used].type = type; - buffer->notes_used++; -} - - -/* Fast path to find line special characters using optimized character - scanning algorithms. Anything complicated falls back to the slow - path below. Since this loop is very hot it's worth doing these kinds - of optimizations. - - One of the paths through the ifdefs should provide - - const uchar *search_line_fast (const uchar *s, const uchar *end); - - Between S and END, search for \n, \r, \\, ?. Return a pointer to - the found character. - - Note that the last character of the buffer is *always* a newline, - as forced by _cpp_convert_input. This fact can be used to avoid - explicitly looking for the end of the buffer. */ - -/* Configure gives us an ifdef test. */ -#ifndef WORDS_BIGENDIAN -#define WORDS_BIGENDIAN 0 -#endif - -/* We'd like the largest integer that fits into a register. There's nothing - in <stdint.h> that gives us that. For most hosts this is unsigned long, - but MS decided on an LLP64 model. Thankfully when building with GCC we - can get the "real" word size. */ -#ifdef __GNUC__ -typedef unsigned int word_type __attribute__((__mode__(__word__))); -#else -typedef unsigned long word_type; -#endif - -/* The code below is only expecting sizes 4 or 8. - Die at compile-time if this expectation is violated. */ -typedef char check_word_type_size - [(sizeof(word_type) == 8 || sizeof(word_type) == 4) * 2 - 1]; - -/* Return X with the first N bytes forced to values that won't match one - of the interesting characters. Note that NUL is not interesting. */ - -static inline word_type -acc_char_mask_misalign (word_type val, unsigned int n) -{ - word_type mask = -1; - if (WORDS_BIGENDIAN) - mask >>= n * 8; - else - mask <<= n * 8; - return val & mask; -} - -/* Return X replicated to all byte positions within WORD_TYPE. */ - -static inline word_type -acc_char_replicate (uchar x) -{ - word_type ret; - - ret = (x << 24) | (x << 16) | (x << 8) | x; - if (sizeof(word_type) == 8) - ret = (ret << 16 << 16) | ret; - return ret; -} - -/* Return non-zero if some byte of VAL is (probably) C. */ - -static inline word_type -acc_char_cmp (word_type val, word_type c) -{ -#if defined(__GNUC__) && defined(__alpha__) - /* We can get exact results using a compare-bytes instruction. - Get (val == c) via (0 >= (val ^ c)). */ - return __builtin_alpha_cmpbge (0, val ^ c); -#else - word_type magic = 0x7efefefeU; - if (sizeof(word_type) == 8) - magic = (magic << 16 << 16) | 0xfefefefeU; - magic |= 1; - - val ^= c; - return ((val + magic) ^ ~val) & ~magic; -#endif -} - -/* Given the result of acc_char_cmp is non-zero, return the index of - the found character. If this was a false positive, return -1. */ - -static inline int -acc_char_index (word_type cmp ATTRIBUTE_UNUSED, - word_type val ATTRIBUTE_UNUSED) -{ -#if defined(__GNUC__) && defined(__alpha__) && !WORDS_BIGENDIAN - /* The cmpbge instruction sets *bits* of the result corresponding to - matches in the bytes with no false positives. */ - return __builtin_ctzl (cmp); -#else - unsigned int i; - - /* ??? It would be nice to force unrolling here, - and have all of these constants folded. */ - for (i = 0; i < sizeof(word_type); ++i) - { - uchar c; - if (WORDS_BIGENDIAN) - c = (val >> (sizeof(word_type) - i - 1) * 8) & 0xff; - else - c = (val >> i * 8) & 0xff; - - if (c == '\n' || c == '\r' || c == '\\' || c == '?') - return i; - } - - return -1; -#endif -} - -/* A version of the fast scanner using bit fiddling techniques. - - For 32-bit words, one would normally perform 16 comparisons and - 16 branches. With this algorithm one performs 24 arithmetic - operations and one branch. Whether this is faster with a 32-bit - word size is going to be somewhat system dependent. - - For 64-bit words, we eliminate twice the number of comparisons - and branches without increasing the number of arithmetic operations. - It's almost certainly going to be a win with 64-bit word size. */ - -static const uchar * search_line_acc_char (const uchar *, const uchar *) - ATTRIBUTE_UNUSED; - -static const uchar * -search_line_acc_char (const uchar *s, const uchar *end ATTRIBUTE_UNUSED) -{ - const word_type repl_nl = acc_char_replicate ('\n'); - const word_type repl_cr = acc_char_replicate ('\r'); - const word_type repl_bs = acc_char_replicate ('\\'); - const word_type repl_qm = acc_char_replicate ('?'); - - unsigned int misalign; - const word_type *p; - word_type val, t; - - /* Align the buffer. Mask out any bytes from before the beginning. */ - p = (word_type *)((uintptr_t)s & -sizeof(word_type)); - val = *p; - misalign = (uintptr_t)s & (sizeof(word_type) - 1); - if (misalign) - val = acc_char_mask_misalign (val, misalign); - - /* Main loop. */ - while (1) - { - t = acc_char_cmp (val, repl_nl); - t |= acc_char_cmp (val, repl_cr); - t |= acc_char_cmp (val, repl_bs); - t |= acc_char_cmp (val, repl_qm); - - if (__builtin_expect (t != 0, 0)) - { - int i = acc_char_index (t, val); - if (i >= 0) - return (const uchar *)p + i; - } - - val = *++p; - } -} - -#define search_line_fast search_line_acc_char - -/* Returns with a logical line that contains no escaped newlines or - trigraphs. This is a time-critical inner loop. */ -void -_cpp_clean_line (cpp_reader *pfile) -{ - cpp_buffer *buffer; - const uchar *s; - uchar c, *d, *p; - - buffer = pfile->buffer; - buffer->cur_note = buffer->notes_used = 0; - buffer->cur = buffer->line_base = buffer->next_line; - buffer->need_line = false; - s = buffer->next_line; - - if (!buffer->from_stage3) - { - const uchar *pbackslash = NULL; - - /* Fast path. This is the common case of an un-escaped line with - no trigraphs. The primary win here is by not writing any - data back to memory until we have to. */ - while (1) - { - /* Perform an optimized search for \n, \r, \\, ?. */ - s = search_line_fast (s, buffer->rlimit); - - c = *s; - if (c == '\\') - { - /* Record the location of the backslash and continue. */ - pbackslash = s++; - } - else if (__builtin_expect (c == '?', 0)) - { - if (__builtin_expect (s[1] == '?', false) - && _cpp_trigraph_map[s[2]]) - { - /* Have a trigraph. We may or may not have to convert - it. Add a line note regardless, for -Wtrigraphs. */ - add_line_note (buffer, s, s[2]); - if (CPP_OPTION (pfile, trigraphs)) - { - /* We do, and that means we have to switch to the - slow path. */ - d = (uchar *) s; - *d = _cpp_trigraph_map[s[2]]; - s += 2; - goto slow_path; - } - } - /* Not a trigraph. Continue on fast-path. */ - s++; - } - else - break; - } - - /* This must be \r or \n. We're either done, or we'll be forced - to write back to the buffer and continue on the slow path. */ - d = (uchar *) s; - - if (__builtin_expect (s == buffer->rlimit, false)) - goto done; - - /* DOS line ending? */ - if (__builtin_expect (c == '\r', false) && s[1] == '\n') - { - s++; - if (s == buffer->rlimit) - goto done; - } - - if (__builtin_expect (pbackslash == NULL, true)) - goto done; - - /* Check for escaped newline. */ - p = d; - while (is_nvspace (p[-1])) - p--; - if (p - 1 != pbackslash) - goto done; - - /* Have an escaped newline; process it and proceed to - the slow path. */ - add_line_note (buffer, p - 1, p != d ? ' ' : '\\'); - d = p - 2; - buffer->next_line = p - 1; - - slow_path: - while (1) - { - c = *++s; - *++d = c; - - if (c == '\n' || c == '\r') - { - /* Handle DOS line endings. */ - if (c == '\r' && s != buffer->rlimit && s[1] == '\n') - s++; - if (s == buffer->rlimit) - break; - - /* Escaped? */ - p = d; - while (p != buffer->next_line && is_nvspace (p[-1])) - p--; - if (p == buffer->next_line || p[-1] != '\\') - break; - - add_line_note (buffer, p - 1, p != d ? ' ': '\\'); - d = p - 2; - buffer->next_line = p - 1; - } - else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]]) - { - /* Add a note regardless, for the benefit of -Wtrigraphs. */ - add_line_note (buffer, d, s[2]); - if (CPP_OPTION (pfile, trigraphs)) - { - *d = _cpp_trigraph_map[s[2]]; - s += 2; - } - } - } - } - else - { - while (*s != '\n' && *s != '\r') - s++; - d = (uchar *) s; - - /* Handle DOS line endings. */ - if (*s == '\r' && s != buffer->rlimit && s[1] == '\n') - s++; - } - - done: - *d = '\n'; - /* A sentinel note that should never be processed. */ - add_line_note (buffer, d + 1, '\n'); - buffer->next_line = s + 1; -} - -/* Return true if the trigraph indicated by NOTE should be warned - about in a comment. */ -static bool -warn_in_comment (cpp_reader *pfile, _cpp_line_note *note) -{ - const uchar *p; - - /* Within comments we don't warn about trigraphs, unless the - trigraph forms an escaped newline, as that may change - behavior. */ - if (note->type != '/') - return false; - - /* If -trigraphs, then this was an escaped newline iff the next note - is coincident. */ - if (CPP_OPTION (pfile, trigraphs)) - return note[1].pos == note->pos; - - /* Otherwise, see if this forms an escaped newline. */ - p = note->pos + 3; - while (is_nvspace (*p)) - p++; - - /* There might have been escaped newlines between the trigraph and the - newline we found. Hence the position test. */ - return (*p == '\n' && p < note[1].pos); -} - -/* Process the notes created by add_line_note as far as the current - location. */ -int -_cpp_process_line_notes (cpp_reader *pfile, int in_comment) -{ - int ret = 0; - cpp_buffer *buffer = pfile->buffer; - - for (;;) - { - _cpp_line_note *note = &buffer->notes[buffer->cur_note]; - unsigned int col; - - if (note->pos > buffer->cur) - break; - - buffer->cur_note++; - col = CPP_BUF_COLUMN (buffer, note->pos + 1); - - if (note->type == '\\' || note->type == ' ') - { - if (note->type == ' ' && !in_comment) - cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, - "backslash and newline separated by space"); - - if (buffer->next_line > buffer->rlimit) - { - cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, col, - "backslash-newline at end of file"); - /* Prevent "no newline at end of file" warning. */ - buffer->next_line = buffer->rlimit; - } - - ret = PREV_NL; - - buffer->line_base = note->pos; - CPP_INCREMENT_LINE (pfile, 0); - } - else if (_cpp_trigraph_map[note->type]) - { - if (CPP_OPTION (pfile, warn_trigraphs) - && (!in_comment || warn_in_comment (pfile, note))) - { - if (CPP_OPTION (pfile, trigraphs)) - cpp_warning_with_line (pfile, CPP_W_TRIGRAPHS, - pfile->line_table->highest_line, col, - "trigraph ??%c converted to %c", - note->type, - (int) _cpp_trigraph_map[note->type]); - else - { - cpp_warning_with_line - (pfile, CPP_W_TRIGRAPHS, - pfile->line_table->highest_line, col, - "trigraph ??%c ignored, use -trigraphs to enable", - note->type); - } - } - } - else if (note->type == 0) - /* Already processed in lex_raw_string. */; - else - abort (); - } - return ret; -} - -/* SDCC __asm specific */ -/* Skip an __asm ... __endasm block. We find the end of the comment by - seeing __endasm. Returns non-zero if _asm terminated by EOF, zero - otherwise. */ -static int -_sdcpp_skip_asm_block (cpp_reader *pfile) -{ -#define ENDASM_STR "endasm" -#define ENDASM_LEN ((sizeof ENDASM_STR) - 1) - - cpp_buffer *buffer = pfile->buffer; - uchar c = EOF; - int prev_space = false; - - while (buffer->cur != buffer->rlimit) - { - prev_space = is_space(c); - c = *buffer->cur++; - - if (prev_space && c == '_' && *buffer->cur == '_') - { - /* check if it is __endasm */ - ++buffer->cur; - if (buffer->cur + ENDASM_LEN <= buffer->rlimit && - strncmp((const char *)buffer->cur, ENDASM_STR, ENDASM_LEN) == 0) - { - buffer->cur += ENDASM_LEN; - break; - } - } - else if (c == '\n') - { - unsigned int cols; - --buffer->cur; - _cpp_process_line_notes (pfile, true); - if (buffer->next_line >= buffer->rlimit) - return true; - _cpp_clean_line (pfile); - - cols = buffer->next_line - buffer->line_base; - CPP_INCREMENT_LINE (pfile, cols); - } - } - - _cpp_process_line_notes (pfile, true); - return false; -} - -/* Skip a C-style block comment. We find the end of the comment by - seeing if an asterisk is before every '/' we encounter. Returns - nonzero if comment terminated by EOF, zero otherwise. - - Buffer->cur points to the initial asterisk of the comment. */ -bool -_cpp_skip_block_comment (cpp_reader *pfile) -{ - cpp_buffer *buffer = pfile->buffer; - const uchar *cur = buffer->cur; - uchar c; - - cur++; - if (*cur == '/') - cur++; - - for (;;) - { - /* People like decorating comments with '*', so check for '/' - instead for efficiency. */ - c = *cur++; - - if (c == '/') - { - if (cur[-2] == '*') - break; - - /* Warn about potential nested comments, but not if the '/' - comes immediately before the true comment delimiter. - Don't bother to get it right across escaped newlines. */ - if (CPP_OPTION (pfile, warn_comments) - && cur[0] == '*' && cur[1] != '/') - { - buffer->cur = cur; - cpp_warning_with_line (pfile, CPP_W_COMMENTS, - pfile->line_table->highest_line, - CPP_BUF_COL (buffer), - "\"/*\" within comment"); - } - } - else if (c == '\n') - { - unsigned int cols; - buffer->cur = cur - 1; - _cpp_process_line_notes (pfile, true); - if (buffer->next_line >= buffer->rlimit) - return true; - _cpp_clean_line (pfile); - - cols = buffer->next_line - buffer->line_base; - CPP_INCREMENT_LINE (pfile, cols); - - cur = buffer->cur; - } - } - - buffer->cur = cur; - _cpp_process_line_notes (pfile, true); - return false; -} - -/* Skip a C++ line comment, leaving buffer->cur pointing to the - terminating newline. Handles escaped newlines. Returns nonzero - if a multiline comment. */ -static int -skip_line_comment (cpp_reader *pfile) -{ - cpp_buffer *buffer = pfile->buffer; - source_location orig_line = pfile->line_table->highest_line; - - while (*buffer->cur != '\n') - buffer->cur++; - - _cpp_process_line_notes (pfile, true); - return orig_line != pfile->line_table->highest_line; -} - -/* Skips whitespace, saving the next non-whitespace character. */ -static void -skip_whitespace (cpp_reader *pfile, cppchar_t c) -{ - cpp_buffer *buffer = pfile->buffer; - bool saw_NUL = false; - - do - { - /* Horizontal space always OK. */ - if (c == ' ' || c == '\t') - ; - /* Just \f \v or \0 left. */ - else if (c == '\0') - saw_NUL = true; - else if (pfile->state.in_directive && CPP_PEDANTIC (pfile)) - cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, - CPP_BUF_COL (buffer), - "%s in preprocessing directive", - c == '\f' ? "form feed" : "vertical tab"); - - c = *buffer->cur++; - } - /* We only want non-vertical space, i.e. ' ' \t \f \v \0. */ - while (is_nvspace (c)); - - if (saw_NUL) - cpp_error (pfile, CPP_DL_WARNING, "null character(s) ignored"); - - buffer->cur--; -} - -/* See if the characters of a number token are valid in a name (no - '.', '+' or '-'). */ -static int -name_p (cpp_reader *pfile, const cpp_string *string) -{ - unsigned int i; - - for (i = 0; i < string->len; i++) - if (!is_idchar (string->text[i])) - return 0; - - return 1; -} - -/* After parsing an identifier or other sequence, produce a warning about - sequences not in NFC/NFKC. */ -static void -warn_about_normalization (cpp_reader *pfile, - const cpp_token *token, - const struct normalize_state *s) -{ - if (CPP_OPTION (pfile, warn_normalize) < NORMALIZE_STATE_RESULT (s) - && !pfile->state.skipping) - { - /* Make sure that the token is printed using UCNs, even - if we'd otherwise happily print UTF-8. */ - unsigned char *buf = XNEWVEC (unsigned char, cpp_token_len (token)); - size_t sz; - - sz = cpp_spell_token (pfile, token, buf, false) - buf; - if (NORMALIZE_STATE_RESULT (s) == normalized_C) - cpp_warning_with_line (pfile, CPP_W_NORMALIZE, token->src_loc, 0, - "`%.*s' is not in NFKC", (int) sz, buf); - else - cpp_warning_with_line (pfile, CPP_W_NORMALIZE, token->src_loc, 0, - "`%.*s' is not in NFC", (int) sz, buf); - } -} - -/* Returns TRUE if the sequence starting at buffer->cur is invalid in - an identifier. FIRST is TRUE if this starts an identifier. */ -static bool -forms_identifier_p (cpp_reader *pfile, int first, - struct normalize_state *state) -{ - cpp_buffer *buffer = pfile->buffer; - - if (*buffer->cur == '$') - { - if (!CPP_OPTION (pfile, dollars_in_ident)) - return false; - - buffer->cur++; - if (CPP_OPTION (pfile, warn_dollars) && !pfile->state.skipping) - { - CPP_OPTION (pfile, warn_dollars) = 0; - cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number"); - } - - return true; - } - - /* Is this a syntactically valid UCN? */ - if (CPP_OPTION (pfile, extended_identifiers) - && *buffer->cur == '\\' - && (buffer->cur[1] == 'u' || buffer->cur[1] == 'U')) - { - buffer->cur += 2; - if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first, - state)) - return true; - buffer->cur -= 2; - } - - return false; -} - -/* Helper function to get the cpp_hashnode of the identifier BASE. */ -static cpp_hashnode * -lex_identifier_intern (cpp_reader *pfile, const uchar *base) -{ - cpp_hashnode *result; - const uchar *cur; - unsigned int len; - unsigned int hash = HT_HASHSTEP (0, *base); - - cur = base + 1; - while (ISIDNUM (*cur)) - { - hash = HT_HASHSTEP (hash, *cur); - cur++; - } - len = cur - base; - hash = HT_HASHFINISH (hash, len); - result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, - base, len, hash, HT_ALLOC)); - - /* Rarely, identifiers require diagnostics when lexed. */ - if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC) - && !pfile->state.skipping, 0)) - { - /* It is allowed to poison the same identifier twice. */ - if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) - cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"", - NODE_NAME (result)); - - /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the - replacement list of a variadic macro. */ - if (result == pfile->spec_nodes.n__VA_ARGS__ - && !pfile->state.va_args_ok) - cpp_error (pfile, CPP_DL_PEDWARN, - "__VA_ARGS__ can only appear in the expansion" - " of a C99 variadic macro"); - - /* For -Wc++-compat, warn about use of C++ named operators. */ - if (result->flags & NODE_WARN_OPERATOR) - cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, - "identifier \"%s\" is a special operator name in C++", - NODE_NAME (result)); - } - - return result; -} - -/* Get the cpp_hashnode of an identifier specified by NAME in - the current cpp_reader object. If none is found, NULL is returned. */ -cpp_hashnode * -_cpp_lex_identifier (cpp_reader *pfile, const char *name) -{ - cpp_hashnode *result; - result = lex_identifier_intern (pfile, (uchar *) name); - return result; -} - -/* Lex an identifier starting at BUFFER->CUR - 1. */ -static cpp_hashnode * -lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn, - struct normalize_state *nst) -{ - cpp_hashnode *result; - const uchar *cur; - unsigned int len; - unsigned int hash = HT_HASHSTEP (0, *base); - - cur = pfile->buffer->cur; - if (! starts_ucn) - while (ISIDNUM (*cur)) - { - hash = HT_HASHSTEP (hash, *cur); - cur++; - } - pfile->buffer->cur = cur; - if (starts_ucn || forms_identifier_p (pfile, false, nst)) - { - /* Slower version for identifiers containing UCNs (or $). */ - do { - while (ISIDNUM (*pfile->buffer->cur)) - { - pfile->buffer->cur++; - NORMALIZE_STATE_UPDATE_IDNUM (nst); - } - } while (forms_identifier_p (pfile, false, nst)); - result = _cpp_interpret_identifier (pfile, base, - pfile->buffer->cur - base); - } - else - { - len = cur - base; - hash = HT_HASHFINISH (hash, len); - - result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, - base, len, hash, HT_ALLOC)); - } - - /* Rarely, identifiers require diagnostics when lexed. */ - if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC) - && !pfile->state.skipping, 0)) - { - /* It is allowed to poison the same identifier twice. */ - if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) - cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"", - NODE_NAME (result)); - - /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the - replacement list of a variadic macro. */ - if (result == pfile->spec_nodes.n__VA_ARGS__ - && !pfile->state.va_args_ok) - cpp_error (pfile, CPP_DL_PEDWARN, - "__VA_ARGS__ can only appear in the expansion" - " of a C99 variadic macro"); - - /* For -Wc++-compat, warn about use of C++ named operators. */ - if (result->flags & NODE_WARN_OPERATOR) - cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, - "identifier \"%s\" is a special operator name in C++", - NODE_NAME (result)); - } - - return result; -} - -/* sdpcc specific */ -/* Pedantic parse a number, beginning with character C, skipping embedded - backslash-newlines. LEADING_PERIOD is nonzero if there was a "." - before C. Place the result in NUMBER. */ -static void -pedantic_lex_number (cpp_reader *pfile, cpp_string *number) -{ -#define get_effective_char(pfile) (*pfile->buffer->cur++) -#define BACKUP() (--pfile->buffer->cur) - - enum num_type_e { NT_DEC, NT_HEX, NT_BIN } num_type = NT_DEC; - enum num_part_e { NP_WHOLE, NP_FRACT, NP_EXP, NP_INT_SUFFIX, NP_FLOAT_SUFFIX } num_part = NP_WHOLE; - - uchar c = *(pfile->buffer->cur - 1); - struct obstack *stack = &pfile->hash_table->stack; - int len = 0; - int has_whole = 0; - int has_fract = 0; - - if ('.' == c) - { - num_part = NP_FRACT; - ++len; - obstack_1grow (stack, '.'); - c = get_effective_char (pfile); - } - else - { - if ('0' == c) - { - has_whole = 1; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - - switch (c) - { - case 'X': - case 'x': - num_type = NT_HEX; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - break; - - case 'B': - case 'b': - if (!CPP_OPTION (pfile, std)) - { - num_type = NT_BIN; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - break; - - case '.': - num_part = NP_FRACT; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - break; - } - } - } - - for (; ; ) - { - switch (num_part) - { - case NP_WHOLE: - if (NT_DEC == num_type) - { - while (ISDIGIT (c)) - { - has_whole = 1; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - - if ('.' == c) - { - num_part = NP_FRACT; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - continue; - } - else if ('E' == c || 'e' == c) - { - if (has_whole || has_fract) - { - num_part = NP_EXP; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - continue; - } - else - break; - } - } - else if (NT_HEX == num_type) - { - while (ISXDIGIT (c)) - { - has_whole = 1; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - - if ('.' == c) - { - num_part = NP_FRACT; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - continue; - } - else if ('P' == c || 'p' == c) - { - if (has_whole || has_fract) - { - num_part = NP_EXP; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - continue; - } - else - break; - } - } - else /* (NT_BIN == num_type) */ - { - while ((c=='0') || (c=='1')) - { - has_whole = 1; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - - if ('.' == c) - { - num_part = NP_FRACT; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - continue; - } - else if ('P' == c || 'p' == c) - { - if (has_whole || has_fract) - { - num_part = NP_EXP; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - continue; - } - else - break; - } - } - num_part = NP_INT_SUFFIX; - continue; - - case NP_FRACT: - if (NT_DEC == num_type) - { - while (ISDIGIT (c)) - { - has_fract = 1; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - - if ('E' == c || 'e' == c) - { - if (has_whole || has_fract) - { - num_part = NP_EXP; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - continue; - } - } - } - else - { - while (ISXDIGIT (c)) - { - has_fract = 1; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - - if ('P' == c || 'p' == c) - { - if (has_whole || has_fract) - { - num_part = NP_EXP; - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - continue; - } - } - } - num_part = NP_FLOAT_SUFFIX; - continue; - - case NP_EXP: - if ('+' == c || '-' == c) - { - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - - while (ISDIGIT (c)) - { - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - - num_part = NP_FLOAT_SUFFIX; - continue; - - case NP_INT_SUFFIX: - if ('L' == c || 'l' == c) - { - uchar prevc = c; - - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - - if (c == prevc) - { - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - } - else if ('U' == c || 'u' == c) - { - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - break; - - case NP_FLOAT_SUFFIX: - if ('F' == c || 'f' == c) - { - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - else if ('L' == c || 'l' == c) - { - ++len; - obstack_1grow (stack, c); - c = get_effective_char (pfile); - } - break; - } - break; - } - - /* Step back over the unwanted char. */ - BACKUP (); - - number->text = obstack_finish (stack); - number->len = len; -} - -/* Lex a number to NUMBER starting at BUFFER->CUR - 1. */ -static void -lex_number (cpp_reader *pfile, cpp_string *number, - struct normalize_state *nst) -{ - const uchar *cur; - const uchar *base; - uchar *dest; - - base = pfile->buffer->cur - 1; - do - { - cur = pfile->buffer->cur; - - /* N.B. ISIDNUM does not include $. */ - while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1])) - { - cur++; - NORMALIZE_STATE_UPDATE_IDNUM (nst); - } - - pfile->buffer->cur = cur; - } - while (forms_identifier_p (pfile, false, nst)); - - number->len = cur - base; - dest = _cpp_unaligned_alloc (pfile, number->len + 1); - memcpy (dest, base, number->len); - dest[number->len] = '\0'; - number->text = dest; -} - -/* Create a token of type TYPE with a literal spelling. */ -static void -create_literal (cpp_reader *pfile, cpp_token *token, const uchar *base, - unsigned int len, enum cpp_ttype type) -{ - uchar *dest = _cpp_unaligned_alloc (pfile, len + 1); - - memcpy (dest, base, len); - dest[len] = '\0'; - token->type = type; - token->val.str.len = len; - token->val.str.text = dest; -} - -/* Subroutine of lex_raw_string: Append LEN chars from BASE to the buffer - sequence from *FIRST_BUFF_P to LAST_BUFF_P. */ - -static void -bufring_append (cpp_reader *pfile, const uchar *base, size_t len, - _cpp_buff **first_buff_p, _cpp_buff **last_buff_p) -{ - _cpp_buff *first_buff = *first_buff_p; - _cpp_buff *last_buff = *last_buff_p; - - if (first_buff == NULL) - first_buff = last_buff = _cpp_get_buff (pfile, len); - else if (len > BUFF_ROOM (last_buff)) - { - size_t room = BUFF_ROOM (last_buff); - memcpy (BUFF_FRONT (last_buff), base, room); - BUFF_FRONT (last_buff) += room; - base += room; - len -= room; - last_buff = _cpp_append_extend_buff (pfile, last_buff, len); - } - - memcpy (BUFF_FRONT (last_buff), base, len); - BUFF_FRONT (last_buff) += len; - - *first_buff_p = first_buff; - *last_buff_p = last_buff; -} - -/* Lexes a raw string. The stored string contains the spelling, including - double quotes, delimiter string, '(' and ')', any leading - 'L', 'u', 'U' or 'u8' and 'R' modifier. It returns the type of the - literal, or CPP_OTHER if it was not properly terminated. - - The spelling is NUL-terminated, but it is not guaranteed that this - is the first NUL since embedded NULs are preserved. */ - -static void -lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base, - const uchar *cur) -{ - source_location saw_NUL = 0; - const uchar *raw_prefix; - unsigned int raw_prefix_len = 0; - enum cpp_ttype type; - size_t total_len = 0; - _cpp_buff *first_buff = NULL, *last_buff = NULL; - _cpp_line_note *note = &pfile->buffer->notes[pfile->buffer->cur_note]; - - type = (*base == 'L' ? CPP_WSTRING : - *base == 'U' ? CPP_STRING32 : - *base == 'u' ? (base[1] == '8' ? CPP_UTF8STRING : CPP_STRING16) - : CPP_STRING); - - raw_prefix = cur + 1; - while (raw_prefix_len < 16) - { - switch (raw_prefix[raw_prefix_len]) - { - case ' ': case '(': case ')': case '\\': case '\t': - case '\v': case '\f': case '\n': default: - break; - /* Basic source charset except the above chars. */ - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': - case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': - case 's': case 't': case 'u': case 'v': case 'w': case 'x': - case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': - case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': - case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': - case '0': case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - case '_': case '{': case '}': case '#': case '[': case ']': - case '<': case '>': case '%': case ':': case ';': case '.': - case '?': case '*': case '+': case '-': case '/': case '^': - case '&': case '|': case '~': case '!': case '=': case ',': - case '"': case '\'': - raw_prefix_len++; - continue; - } - break; - } - - if (raw_prefix[raw_prefix_len] != '(') - { - int col = CPP_BUF_COLUMN (pfile->buffer, raw_prefix + raw_prefix_len) - + 1; - if (raw_prefix_len == 16) - cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, col, - "raw string delimiter longer than 16 characters"); - else - cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, col, - "invalid character '%c' in raw string delimiter", - (int) raw_prefix[raw_prefix_len]); - pfile->buffer->cur = raw_prefix - 1; - create_literal (pfile, token, base, raw_prefix - 1 - base, CPP_OTHER); - return; - } - - cur = raw_prefix + raw_prefix_len + 1; - for (;;) - { -#define BUF_APPEND(STR,LEN) \ - do { \ - bufring_append (pfile, (const uchar *)(STR), (LEN), \ - &first_buff, &last_buff); \ - total_len += (LEN); \ - } while (0); - - cppchar_t c; - - /* If we previously performed any trigraph or line splicing - transformations, undo them within the body of the raw string. */ - while (note->pos < cur) - ++note; - for (; note->pos == cur; ++note) - { - switch (note->type) - { - case '\\': - case ' ': - /* Restore backslash followed by newline. */ - BUF_APPEND (base, cur - base); - base = cur; - BUF_APPEND ("\\", 1); - after_backslash: - if (note->type == ' ') - { - /* GNU backslash whitespace newline extension. FIXME - could be any sequence of non-vertical space. When we - can properly restore any such sequence, we should mark - this note as handled so _cpp_process_line_notes - doesn't warn. */ - BUF_APPEND (" ", 1); - } - - BUF_APPEND ("\n", 1); - break; - - case 0: - /* Already handled. */ - break; - - default: - if (_cpp_trigraph_map[note->type]) - { - /* Don't warn about this trigraph in - _cpp_process_line_notes, since trigraphs show up as - trigraphs in raw strings. */ - uchar type = note->type; - note->type = 0; - - if (!CPP_OPTION (pfile, trigraphs)) - /* If we didn't convert the trigraph in the first - place, don't do anything now either. */ - break; - - BUF_APPEND (base, cur - base); - base = cur; - BUF_APPEND ("??", 2); - - /* ??/ followed by newline gets two line notes, one for - the trigraph and one for the backslash/newline. */ - if (type == '/' && note[1].pos == cur) - { - if (note[1].type != '\\' - && note[1].type != ' ') - abort (); - BUF_APPEND ("/", 1); - ++note; - goto after_backslash; - } - /* The ) from ??) could be part of the suffix. */ - else if (type == ')' - && strncmp ((const char *) cur+1, - (const char *) raw_prefix, - raw_prefix_len) == 0 - && cur[raw_prefix_len+1] == '"') - { - BUF_APPEND (")", 1); - base++; - cur += raw_prefix_len + 2; - goto break_outer_loop; - } - else - { - /* Skip the replacement character. */ - base = ++cur; - BUF_APPEND (&type, 1); - } - } - else - abort (); - break; - } - } - c = *cur++; - - if (c == ')' - && strncmp ((const char *) cur, (const char *) raw_prefix, - raw_prefix_len) == 0 - && cur[raw_prefix_len] == '"') - { - cur += raw_prefix_len + 1; - break; - } - else if (c == '\n') - { - if (pfile->state.in_directive - || pfile->state.parsing_args - || pfile->state.in_deferred_pragma) - { - cur--; - type = CPP_OTHER; - cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, 0, - "unterminated raw string"); - break; - } - - BUF_APPEND (base, cur - base); - - if (pfile->buffer->cur < pfile->buffer->rlimit) - CPP_INCREMENT_LINE (pfile, 0); - pfile->buffer->need_line = true; - - pfile->buffer->cur = cur-1; - _cpp_process_line_notes (pfile, false); - if (!_cpp_get_fresh_line (pfile)) - { - source_location src_loc = token->src_loc; - token->type = CPP_EOF; - /* Tell the compiler the line number of the EOF token. */ - token->src_loc = pfile->line_table->highest_line; - token->flags = BOL; - if (first_buff != NULL) - _cpp_release_buff (pfile, first_buff); - cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, - "unterminated raw string"); - return; - } - - cur = base = pfile->buffer->cur; - note = &pfile->buffer->notes[pfile->buffer->cur_note]; - } - else if (c == '\0' && !saw_NUL) - LINEMAP_POSITION_FOR_COLUMN (saw_NUL, pfile->line_table, - CPP_BUF_COLUMN (pfile->buffer, cur)); - } - break_outer_loop: - - if (saw_NUL && !pfile->state.skipping) - cpp_error_with_line (pfile, CPP_DL_WARNING, saw_NUL, 0, - "null character(s) preserved in literal"); - - pfile->buffer->cur = cur; - if (first_buff == NULL) - create_literal (pfile, token, base, cur - base, type); - else - { - uchar *dest = _cpp_unaligned_alloc (pfile, total_len + (cur - base) + 1); - - token->type = type; - token->val.str.len = total_len + (cur - base); - token->val.str.text = dest; - last_buff = first_buff; - while (last_buff != NULL) - { - memcpy (dest, last_buff->base, - BUFF_FRONT (last_buff) - last_buff->base); - dest += BUFF_FRONT (last_buff) - last_buff->base; - last_buff = last_buff->next; - } - _cpp_release_buff (pfile, first_buff); - memcpy (dest, base, cur - base); - dest[cur - base] = '\0'; - } -} - -/* Lexes a string, character constant, or angle-bracketed header file - name. The stored string contains the spelling, including opening - quote and any leading 'L', 'u', 'U' or 'u8' and optional - 'R' modifier. It returns the type of the literal, or CPP_OTHER - if it was not properly terminated, or CPP_LESS for an unterminated - header name which must be relexed as normal tokens. - - The spelling is NUL-terminated, but it is not guaranteed that this - is the first NUL since embedded NULs are preserved. */ -static void -lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base) -{ - bool saw_NUL = false; - const uchar *cur; - cppchar_t terminator; - enum cpp_ttype type; - - cur = base; - terminator = *cur++; - if (terminator == 'L' || terminator == 'U') - terminator = *cur++; - else if (terminator == 'u') - { - terminator = *cur++; - if (terminator == '8') - terminator = *cur++; - } - if (terminator == 'R') - { - lex_raw_string (pfile, token, base, cur); - return; - } - if (terminator == '"') - type = (*base == 'L' ? CPP_WSTRING : - *base == 'U' ? CPP_STRING32 : - *base == 'u' ? (base[1] == '8' ? CPP_UTF8STRING : CPP_STRING16) - : CPP_STRING); - else if (terminator == '\'') - type = (*base == 'L' ? CPP_WCHAR : - *base == 'U' ? CPP_CHAR32 : - *base == 'u' ? CPP_CHAR16 : CPP_CHAR); - else - terminator = '>', type = CPP_HEADER_NAME; - - for (;;) - { - cppchar_t c = *cur++; - - /* In #include-style directives, terminators are not escapable. */ - if (c == '\\' && !pfile->state.angled_headers && *cur != '\n') - cur++; - else if (c == terminator) - break; - else if (c == '\n') - { - cur--; - /* Unmatched quotes always yield undefined behavior, but - greedy lexing means that what appears to be an unterminated - header name may actually be a legitimate sequence of tokens. */ - if (terminator == '>') - { - token->type = CPP_LESS; - return; - } - type = CPP_OTHER; - break; - } - else if (c == '\0') - saw_NUL = true; - } - - if (saw_NUL && !pfile->state.skipping) - cpp_error (pfile, CPP_DL_WARNING, - "null character(s) preserved in literal"); - - if (type == CPP_OTHER && CPP_OPTION (pfile, lang) != CLK_ASM) - cpp_error (pfile, CPP_DL_PEDWARN, "missing terminating %c character", - (int) terminator); - - pfile->buffer->cur = cur; - create_literal (pfile, token, base, cur - base, type); -} - -/* sdcpp specific */ -/* Fixed _WIN32 problem with CR-CR-LF sequences when outputting - comment blocks (when executed with -C option) and - _asm (SDCPP specific) blocks */ - -/* Count and copy characters from src to dest, excluding CRs: - CRs are automatically generated, because the output is - opened in TEXT mode. If dest == NULL, only count chars */ -static unsigned int -copy_text_chars (unsigned char *dest, const unsigned char *src, unsigned int len) -{ - unsigned int n = 0; - const unsigned char *p; - - for (p = src; p != src + len; ++p) - { - assert(*p != '\0'); - - if (*p != '\r') - { - if (dest != NULL) - *dest++ = *p; - ++n; - } - } - - return n; -} - -/* SDCC _asm specific */ -/* The stored comment includes the comment start and any terminator. */ -static void -_sdcpp_save_asm (cpp_reader *pfile, cpp_token *token, const unsigned char *from, int is_asm) -{ -#define _ASM_STR "__asm" -#define _ASM_LEN ((sizeof _ASM_STR) - 1) -#define _ASM_STR1 "_asm" -#define _ASM_LEN1 ((sizeof _ASM_STR1) - 1) - - unsigned char *buffer; - unsigned int text_len, len; - unsigned int asm_len = is_asm ? _ASM_LEN : _ASM_LEN1; - const char *asm_str = is_asm ? _ASM_STR : _ASM_STR1; - - len = pfile->buffer->cur - from; - /* + asm_len for the initial '_asm'. */ - text_len = copy_text_chars (NULL, from, len) + asm_len; - buffer = _cpp_unaligned_alloc (pfile, text_len); - - - token->type = CPP_ASM; - token->val.str.len = text_len; - token->val.str.text = buffer; - - memcpy (buffer, asm_str, asm_len); - copy_text_chars (buffer + asm_len, from, len); -} - -/* Return the comment table. The client may not make any assumption - about the ordering of the table. */ -cpp_comment_table * -cpp_get_comments (cpp_reader *pfile) -{ - return &pfile->comments; -} - -/* Append a comment to the end of the comment table. */ -static void -store_comment (cpp_reader *pfile, cpp_token *token) -{ - int len; - - if (pfile->comments.allocated == 0) - { - pfile->comments.allocated = 256; - pfile->comments.entries = (cpp_comment *) xmalloc - (pfile->comments.allocated * sizeof (cpp_comment)); - } - - if (pfile->comments.count == pfile->comments.allocated) - { - pfile->comments.allocated *= 2; - pfile->comments.entries = (cpp_comment *) xrealloc - (pfile->comments.entries, - pfile->comments.allocated * sizeof (cpp_comment)); - } - - len = token->val.str.len; - - /* Copy comment. Note, token may not be NULL terminated. */ - pfile->comments.entries[pfile->comments.count].comment = - (char *) xmalloc (sizeof (char) * (len + 1)); - memcpy (pfile->comments.entries[pfile->comments.count].comment, - token->val.str.text, len); - pfile->comments.entries[pfile->comments.count].comment[len] = '\0'; - - /* Set source location. */ - pfile->comments.entries[pfile->comments.count].sloc = token->src_loc; - - /* Increment the count of entries in the comment table. */ - pfile->comments.count++; -} - -/* The stored comment includes the comment start and any terminator. */ -static void -save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from, - cppchar_t type) -{ - unsigned char *buffer; - unsigned int len, clen, i; - - len = pfile->buffer->cur - from + 1; /* + 1 for the initial '/'. */ - - /* C++ comments probably (not definitely) have moved past a new - line, which we don't want to save in the comment. */ - if (is_vspace (pfile->buffer->cur[-1])) - len--; - - /* If we are currently in a directive or in argument parsing, then - we need to store all C++ comments as C comments internally, and - so we need to allocate a little extra space in that case. - - Note that the only time we encounter a directive here is - when we are saving comments in a "#define". */ - clen = ((pfile->state.in_directive || pfile->state.parsing_args) - && type == '/') ? len + 2 : len; - - buffer = _cpp_unaligned_alloc (pfile, clen); - - token->type = CPP_COMMENT; - token->val.str.len = clen; - token->val.str.text = buffer; - - buffer[0] = '/'; - /* sdcpp specific */ - copy_text_chars (buffer + 1, from, len); - - /* Finish conversion to a C comment, if necessary. */ - if ((pfile->state.in_directive || pfile->state.parsing_args) && type == '/') - { - buffer[1] = '*'; - buffer[clen - 2] = '*'; - buffer[clen - 1] = '/'; - /* As there can be in a C++ comments illegal sequences for C comments - we need to filter them out. */ - for (i = 2; i < (clen - 2); i++) - if (buffer[i] == '/' && (buffer[i - 1] == '*' || buffer[i + 1] == '*')) - buffer[i] = '|'; - } - - /* Finally store this comment for use by clients of libcpp. */ - store_comment (pfile, token); -} - -/* Allocate COUNT tokens for RUN. */ -void -_cpp_init_tokenrun (tokenrun *run, unsigned int count) -{ - run->base = XNEWVEC (cpp_token, count); - run->limit = run->base + count; - run->next = NULL; -} - -/* Returns the next tokenrun, or creates one if there is none. */ -static tokenrun * -next_tokenrun (tokenrun *run) -{ - if (run->next == NULL) - { - run->next = XNEW (tokenrun); - run->next->prev = run; - _cpp_init_tokenrun (run->next, 250); - } - - return run->next; -} - -/* Look ahead in the input stream. */ -const cpp_token * -cpp_peek_token (cpp_reader *pfile, int index) -{ - cpp_context *context = pfile->context; - const cpp_token *peektok; - int count; - - /* First, scan through any pending cpp_context objects. */ - while (context->prev) - { - ptrdiff_t sz = (context->direct_p - ? LAST (context).token - FIRST (context).token - : LAST (context).ptoken - FIRST (context).ptoken); - - if (index < (int) sz) - return (context->direct_p - ? FIRST (context).token + index - : *(FIRST (context).ptoken + index)); - - index -= (int) sz; - context = context->prev; - } - - /* We will have to read some new tokens after all (and do so - without invalidating preceding tokens). */ - count = index; - pfile->keep_tokens++; - - do - { - peektok = _cpp_lex_token (pfile); - if (peektok->type == CPP_EOF) - return peektok; - } - while (index--); - - _cpp_backup_tokens_direct (pfile, count + 1); - pfile->keep_tokens--; - - return peektok; -} - -/* Allocate a single token that is invalidated at the same time as the - rest of the tokens on the line. Has its line and col set to the - same as the last lexed token, so that diagnostics appear in the - right place. */ -cpp_token * -_cpp_temp_token (cpp_reader *pfile) -{ - cpp_token *old, *result; - ptrdiff_t sz = pfile->cur_run->limit - pfile->cur_token; - ptrdiff_t la = (ptrdiff_t) pfile->lookaheads; - - old = pfile->cur_token - 1; - /* Any pre-existing lookaheads must not be clobbered. */ - if (la) - { - if (sz <= la) - { - tokenrun *next = next_tokenrun (pfile->cur_run); - - if (sz < la) - memmove (next->base + 1, next->base, - (la - sz) * sizeof (cpp_token)); - - next->base[0] = pfile->cur_run->limit[-1]; - } - - if (sz > 1) - memmove (pfile->cur_token + 1, pfile->cur_token, - MIN (la, sz - 1) * sizeof (cpp_token)); - } - - if (!sz && pfile->cur_token == pfile->cur_run->limit) - { - pfile->cur_run = next_tokenrun (pfile->cur_run); - pfile->cur_token = pfile->cur_run->base; - } - - result = pfile->cur_token++; - result->src_loc = old->src_loc; - return result; -} - -/* Lex a token into RESULT (external interface). Takes care of issues - like directive handling, token lookahead, multiple include - optimization and skipping. */ -const cpp_token * -_cpp_lex_token (cpp_reader *pfile) -{ - cpp_token *result; - - for (;;) - { - if (pfile->cur_token == pfile->cur_run->limit) - { - pfile->cur_run = next_tokenrun (pfile->cur_run); - pfile->cur_token = pfile->cur_run->base; - } - /* We assume that the current token is somewhere in the current - run. */ - if (pfile->cur_token < pfile->cur_run->base - || pfile->cur_token >= pfile->cur_run->limit) - abort (); - - if (pfile->lookaheads) - { - pfile->lookaheads--; - result = pfile->cur_token++; - } - else - result = _cpp_lex_direct (pfile); - - if (result->flags & BOL) - { - /* Is this a directive. If _cpp_handle_directive returns - false, it is an assembler #. */ - if (result->type == CPP_HASH - /* 6.10.3 p 11: Directives in a list of macro arguments - gives undefined behavior. This implementation - handles the directive as normal. */ - && pfile->state.parsing_args != 1) - { - if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE)) - { - if (pfile->directive_result.type == CPP_PADDING) - continue; - result = &pfile->directive_result; - } - } - else if (pfile->state.in_deferred_pragma) - result = &pfile->directive_result; - - if (pfile->cb.line_change && !pfile->state.skipping) - pfile->cb.line_change (pfile, result, pfile->state.parsing_args); - } - - /* We don't skip tokens in directives. */ - if (pfile->state.in_directive || pfile->state.in_deferred_pragma) - break; - - /* Outside a directive, invalidate controlling macros. At file - EOF, _cpp_lex_direct takes care of popping the buffer, so we never - get here and MI optimization works. */ - pfile->mi_valid = false; - - if (!pfile->state.skipping || result->type == CPP_EOF) - break; - } - - return result; -} - -/* Returns true if a fresh line has been loaded. */ -bool -_cpp_get_fresh_line (cpp_reader *pfile) -{ - int return_at_eof; - - /* We can't get a new line until we leave the current directive. */ - if (pfile->state.in_directive) - return false; - - for (;;) - { - cpp_buffer *buffer = pfile->buffer; - - if (!buffer->need_line) - return true; - - if (buffer->next_line < buffer->rlimit) - { - _cpp_clean_line (pfile); - return true; - } - - /* First, get out of parsing arguments state. */ - if (pfile->state.parsing_args) - return false; - - /* End of buffer. Non-empty files should end in a newline. */ - if (buffer->buf != buffer->rlimit - && buffer->next_line > buffer->rlimit - && !buffer->from_stage3) - { - /* Clip to buffer size. */ - buffer->next_line = buffer->rlimit; - } - - return_at_eof = buffer->return_at_eof; - _cpp_pop_buffer (pfile); - if (pfile->buffer == NULL || return_at_eof) - return false; - } -} - -#define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE) \ - do \ - { \ - result->type = ELSE_TYPE; \ - if (*buffer->cur == CHAR) \ - buffer->cur++, result->type = THEN_TYPE; \ - } \ - while (0) - -/* Lex a token into pfile->cur_token, which is also incremented, to - get diagnostics pointing to the correct location. - - Does not handle issues such as token lookahead, multiple-include - optimization, directives, skipping etc. This function is only - suitable for use by _cpp_lex_token, and in special cases like - lex_expansion_token which doesn't care for any of these issues. - - When meeting a newline, returns CPP_EOF if parsing a directive, - otherwise returns to the start of the token buffer if permissible. - Returns the location of the lexed token. */ -cpp_token * -_cpp_lex_direct (cpp_reader *pfile) -{ - cppchar_t c; - cpp_buffer *buffer; - const unsigned char *comment_start; - cpp_token *result = pfile->cur_token++; - - fresh_line: - result->flags = 0; - buffer = pfile->buffer; - if (buffer->need_line) - { - if (pfile->state.in_deferred_pragma) - { - result->type = CPP_PRAGMA_EOL; - pfile->state.in_deferred_pragma = false; - if (!pfile->state.pragma_allow_expansion) - pfile->state.prevent_expansion--; - return result; - } - if (!_cpp_get_fresh_line (pfile)) - { - result->type = CPP_EOF; - if (!pfile->state.in_directive) - { - /* Tell the compiler the line number of the EOF token. */ - result->src_loc = pfile->line_table->highest_line; - result->flags = BOL; - } - return result; - } - if (!pfile->keep_tokens) - { - pfile->cur_run = &pfile->base_run; - result = pfile->base_run.base; - pfile->cur_token = result + 1; - } - result->flags = BOL; - if (pfile->state.parsing_args == 2) - result->flags |= PREV_WHITE; - } - buffer = pfile->buffer; - update_tokens_line: - result->src_loc = pfile->line_table->highest_line; - - skipped_white: - if (buffer->cur >= buffer->notes[buffer->cur_note].pos - && !pfile->overlaid_buffer) - { - result->flags |= _cpp_process_line_notes (pfile, false); - result->src_loc = pfile->line_table->highest_line; - } - c = *buffer->cur++; - - LINEMAP_POSITION_FOR_COLUMN (result->src_loc, pfile->line_table, - CPP_BUF_COLUMN (buffer, buffer->cur)); - - switch (c) - { - case ' ': case '\t': case '\f': case '\v': case '\0': - result->flags |= PREV_WHITE; - skip_whitespace (pfile, c); - goto skipped_white; - - case '\n': - if (buffer->cur < buffer->rlimit) - CPP_INCREMENT_LINE (pfile, 0); - buffer->need_line = true; - goto fresh_line; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - struct normalize_state nst = INITIAL_NORMALIZE_STATE; - result->type = CPP_NUMBER; - /* sdcpp specific */ - if (CPP_OPTION (pfile, pedantic_parse_number)) - pedantic_lex_number (pfile, &result->val.str); - else - lex_number (pfile, &result->val.str, &nst); - warn_about_normalization (pfile, result, &nst); - break; - } - - case 'L': - case 'u': - case 'U': - case 'R': - /* 'L', 'u', 'U', 'u8' or 'R' may introduce wide characters, - wide strings or raw strings. */ - if (c == 'L' || CPP_OPTION (pfile, uliterals)) - { - if ((*buffer->cur == '\'' && c != 'R') - || *buffer->cur == '"' - || (*buffer->cur == 'R' - && c != 'R' - && buffer->cur[1] == '"' - && CPP_OPTION (pfile, uliterals)) - || (*buffer->cur == '8' - && c == 'u' - && (buffer->cur[1] == '"' - || (buffer->cur[1] == 'R' && buffer->cur[2] == '"')))) - { - lex_string (pfile, result, buffer->cur - 1); - break; - } - } - /* Fall through. */ - - case '_': - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': - case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': - case 's': case 't': case 'v': case 'w': case 'x': - case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - case 'G': case 'H': case 'I': case 'J': case 'K': - case 'M': case 'N': case 'O': case 'P': case 'Q': - case 'S': case 'T': case 'V': case 'W': case 'X': - case 'Y': case 'Z': - result->type = CPP_NAME; - { - struct normalize_state nst = INITIAL_NORMALIZE_STATE; - result->val.node.node = lex_identifier (pfile, buffer->cur - 1, false, - &nst); - warn_about_normalization (pfile, result, &nst); - } - - /* SDCC __asm specific */ - /* handle __asm ... __endasm ; */ - if (result->val.node.node == pfile->spec_nodes.n__asm) - { - if (CPP_OPTION (pfile, preproc_asm) == 0) - { - comment_start = buffer->cur; - result->type = CPP_ASM; - _sdcpp_skip_asm_block (pfile); - /* Save the __asm block as a token in its own right. */ - _sdcpp_save_asm (pfile, result, comment_start, result->val.node.node == pfile->spec_nodes.n__asm); - } - result->flags |= ENTER_ASM; - } - else if (result->val.node.node == pfile->spec_nodes.n__endasm) - { - result->flags |= EXIT_ASM; - } - /* Convert named operators to their proper types. */ - else if (result->val.node.node->flags & NODE_OPERATOR) - { - result->flags |= NAMED_OP; - result->type = (enum cpp_ttype) result->val.node.node->directive_index; - } - break; - - case '\'': - case '"': - lex_string (pfile, result, buffer->cur - 1); - break; - - case '/': - /* A potential block or line comment. */ - comment_start = buffer->cur; - c = *buffer->cur; - - if (c == '*') - { - if (_cpp_skip_block_comment (pfile)) - cpp_error (pfile, CPP_DL_ERROR, "unterminated comment"); - } - else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments) - || cpp_in_system_header (pfile))) - { - /* Warn about comments only if pedantically GNUC89, and not - in system headers. */ - if (CPP_OPTION (pfile, lang) == CLK_GNUC89 && CPP_PEDANTIC (pfile) - && ! buffer->warned_cplusplus_comments) - { - cpp_error (pfile, CPP_DL_PEDWARN, - "C++ style comments are not allowed in ISO C90"); - cpp_error (pfile, CPP_DL_PEDWARN, - "(this will be reported only once per input file)"); - buffer->warned_cplusplus_comments = 1; - } - - if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments)) - cpp_warning (pfile, CPP_W_COMMENTS, "multi-line comment"); - } - else if (c == '=') - { - buffer->cur++; - result->type = CPP_DIV_EQ; - break; - } - else - { - result->type = CPP_DIV; - break; - } - - if (!pfile->state.save_comments) - { - result->flags |= PREV_WHITE; - goto update_tokens_line; - } - - /* Save the comment as a token in its own right. */ - save_comment (pfile, result, comment_start, c); - break; - - case '<': - if (pfile->state.angled_headers) - { - lex_string (pfile, result, buffer->cur - 1); - if (result->type != CPP_LESS) - break; - } - - result->type = CPP_LESS; - if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_LESS_EQ; - else if (*buffer->cur == '<') - { - buffer->cur++; - IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT); - } - else if (CPP_OPTION (pfile, digraphs)) - { - if (*buffer->cur == ':') - { - buffer->cur++; - result->flags |= DIGRAPH; - result->type = CPP_OPEN_SQUARE; - } - else if (*buffer->cur == '%') - { - buffer->cur++; - result->flags |= DIGRAPH; - result->type = CPP_OPEN_BRACE; - } - } - break; - - case '>': - result->type = CPP_GREATER; - if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_GREATER_EQ; - else if (*buffer->cur == '>') - { - buffer->cur++; - IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT); - } - break; - - case '%': - result->type = CPP_MOD; - if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_MOD_EQ; - else if (CPP_OPTION (pfile, digraphs)) - { - if (*buffer->cur == ':') - { - buffer->cur++; - result->flags |= DIGRAPH; - result->type = CPP_HASH; - if (*buffer->cur == '%' && buffer->cur[1] == ':') - buffer->cur += 2, result->type = CPP_PASTE, result->val.token_no = 0; - } - else if (*buffer->cur == '>') - { - buffer->cur++; - result->flags |= DIGRAPH; - result->type = CPP_CLOSE_BRACE; - } - } - break; - - case '.': - result->type = CPP_DOT; - if (ISDIGIT (*buffer->cur)) - { - struct normalize_state nst = INITIAL_NORMALIZE_STATE; - result->type = CPP_NUMBER; - /* sdcpp specific */ - if (CPP_OPTION (pfile, pedantic_parse_number)) - pedantic_lex_number (pfile, &result->val.str); - else - lex_number (pfile, &result->val.str, &nst); - warn_about_normalization (pfile, result, &nst); - } - else if (*buffer->cur == '.' && buffer->cur[1] == '.') - buffer->cur += 2, result->type = CPP_ELLIPSIS; - else if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus)) - buffer->cur++, result->type = CPP_DOT_STAR; - break; - - case '+': - result->type = CPP_PLUS; - if (*buffer->cur == '+') - buffer->cur++, result->type = CPP_PLUS_PLUS; - else if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_PLUS_EQ; - break; - - case '-': - result->type = CPP_MINUS; - if (*buffer->cur == '>') - { - buffer->cur++; - result->type = CPP_DEREF; - if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus)) - buffer->cur++, result->type = CPP_DEREF_STAR; - } - else if (*buffer->cur == '-') - buffer->cur++, result->type = CPP_MINUS_MINUS; - else if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_MINUS_EQ; - break; - - case '&': - result->type = CPP_AND; - if (*buffer->cur == '&') - buffer->cur++, result->type = CPP_AND_AND; - else if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_AND_EQ; - break; - - case '|': - result->type = CPP_OR; - if (*buffer->cur == '|') - buffer->cur++, result->type = CPP_OR_OR; - else if (*buffer->cur == '=') - buffer->cur++, result->type = CPP_OR_EQ; - break; - - case ':': - result->type = CPP_COLON; - if (*buffer->cur == ':' && CPP_OPTION (pfile, cplusplus)) - buffer->cur++, result->type = CPP_SCOPE; - else if (*buffer->cur == '>' && CPP_OPTION (pfile, digraphs)) - { - buffer->cur++; - result->flags |= DIGRAPH; - result->type = CPP_CLOSE_SQUARE; - } - break; - - case '*': IF_NEXT_IS ('=', CPP_MULT_EQ, CPP_MULT); break; - case '=': IF_NEXT_IS ('=', CPP_EQ_EQ, CPP_EQ); break; - case '!': IF_NEXT_IS ('=', CPP_NOT_EQ, CPP_NOT); break; - case '^': IF_NEXT_IS ('=', CPP_XOR_EQ, CPP_XOR); break; - case '#': IF_NEXT_IS ('#', CPP_PASTE, CPP_HASH); result->val.token_no = 0; break; - - case '?': result->type = CPP_QUERY; break; - case '~': result->type = CPP_COMPL; break; - case ',': result->type = CPP_COMMA; break; - case '(': result->type = CPP_OPEN_PAREN; break; - case ')': result->type = CPP_CLOSE_PAREN; break; - case '[': result->type = CPP_OPEN_SQUARE; break; - case ']': result->type = CPP_CLOSE_SQUARE; break; - case '{': result->type = CPP_OPEN_BRACE; break; - case '}': result->type = CPP_CLOSE_BRACE; break; - case ';': result->type = CPP_SEMICOLON; break; - - /* @ is a punctuator in Objective-C. */ - case '@': result->type = CPP_ATSIGN; break; - - case '$': - case '\\': - { - const uchar *base = --buffer->cur; - struct normalize_state nst = INITIAL_NORMALIZE_STATE; - - if (forms_identifier_p (pfile, true, &nst)) - { - result->type = CPP_NAME; - result->val.node.node = lex_identifier (pfile, base, true, &nst); - warn_about_normalization (pfile, result, &nst); - break; - } - buffer->cur++; - } - - default: - create_literal (pfile, result, buffer->cur - 1, 1, CPP_OTHER); - break; - } - - return result; -} - -/* An upper bound on the number of bytes needed to spell TOKEN. - Does not include preceding whitespace. */ -unsigned int -cpp_token_len (const cpp_token *token) -{ - unsigned int len; - - switch (TOKEN_SPELL (token)) - { - default: len = 6; break; - case SPELL_LITERAL: len = token->val.str.len; break; - case SPELL_IDENT: len = NODE_LEN (token->val.node.node) * 10; break; - } - - return len; -} - -/* Parse UTF-8 out of NAMEP and place a \U escape in BUFFER. - Return the number of bytes read out of NAME. (There are always - 10 bytes written to BUFFER.) */ - -static size_t -utf8_to_ucn (unsigned char *buffer, const unsigned char *name) -{ - int j; - int ucn_len = 0; - int ucn_len_c; - unsigned t; - unsigned long utf32; - - /* Compute the length of the UTF-8 sequence. */ - for (t = *name; t & 0x80; t <<= 1) - ucn_len++; - - utf32 = *name & (0x7F >> ucn_len); - for (ucn_len_c = 1; ucn_len_c < ucn_len; ucn_len_c++) - { - utf32 = (utf32 << 6) | (*++name & 0x3F); - - /* Ill-formed UTF-8. */ - if ((*name & ~0x3F) != 0x80) - abort (); - } - - *buffer++ = '\\'; - *buffer++ = 'U'; - for (j = 7; j >= 0; j--) - *buffer++ = "0123456789abcdef"[(utf32 >> (4 * j)) & 0xF]; - return ucn_len; -} - -/* Given a token TYPE corresponding to a digraph, return a pointer to - the spelling of the digraph. */ -static const unsigned char * -cpp_digraph2name (enum cpp_ttype type) -{ - return digraph_spellings[(int) type - (int) CPP_FIRST_DIGRAPH]; -} - -/* Write the spelling of a token TOKEN to BUFFER. The buffer must - already contain the enough space to hold the token's spelling. - Returns a pointer to the character after the last character written. - FORSTRING is true if this is to be the spelling after translation - phase 1 (this is different for UCNs). - FIXME: Would be nice if we didn't need the PFILE argument. */ -unsigned char * -cpp_spell_token (cpp_reader *pfile, const cpp_token *token, - unsigned char *buffer, bool forstring) -{ - switch (TOKEN_SPELL (token)) - { - case SPELL_OPERATOR: - { - const unsigned char *spelling; - unsigned char c; - - if (token->flags & DIGRAPH) - spelling = cpp_digraph2name (token->type); - else if (token->flags & NAMED_OP) - goto spell_ident; - else - spelling = TOKEN_NAME (token); - - while ((c = *spelling++) != '\0') - *buffer++ = c; - } - break; - - spell_ident: - case SPELL_IDENT: - if (forstring) - { - memcpy (buffer, NODE_NAME (token->val.node.node), - NODE_LEN (token->val.node.node)); - buffer += NODE_LEN (token->val.node.node); - } - else - { - size_t i; - const unsigned char * name = NODE_NAME (token->val.node.node); - - for (i = 0; i < NODE_LEN (token->val.node.node); i++) - if (name[i] & ~0x7F) - { - i += utf8_to_ucn (buffer, name + i) - 1; - buffer += 10; - } - else - *buffer++ = NODE_NAME (token->val.node.node)[i]; - } - break; - - case SPELL_LITERAL: - memcpy (buffer, token->val.str.text, token->val.str.len); - buffer += token->val.str.len; - break; - - case SPELL_NONE: - cpp_error (pfile, CPP_DL_ICE, - "unspellable token %s", TOKEN_NAME (token)); - break; - } - - return buffer; -} - -/* Returns TOKEN spelt as a null-terminated string. The string is - freed when the reader is destroyed. Useful for diagnostics. */ -unsigned char * -cpp_token_as_text (cpp_reader *pfile, const cpp_token *token) -{ - unsigned int len = cpp_token_len (token) + 1; - unsigned char *start = _cpp_unaligned_alloc (pfile, len), *end; - - end = cpp_spell_token (pfile, token, start, false); - end[0] = '\0'; - - return start; -} - -/* Returns a pointer to a string which spells the token defined by - TYPE and FLAGS. Used by C front ends, which really should move to - using cpp_token_as_text. */ -const char * -cpp_type2name (enum cpp_ttype type, unsigned char flags) -{ - if (flags & DIGRAPH) - return (const char *) cpp_digraph2name (type); - else if (flags & NAMED_OP) - return cpp_named_operator2name (type); - - return (const char *) token_spellings[type].name; -} - -/* Writes the spelling of token to FP, without any preceding space. - Separated from cpp_spell_token for efficiency - to avoid stdio - double-buffering. */ -void -cpp_output_token (const cpp_token *token, FILE *fp) -{ - if (token->flags & ENTER_ASM) - in_asm++; - if (token->flags & EXIT_ASM) - in_asm--; - - switch (TOKEN_SPELL (token)) - { - case SPELL_OPERATOR: - { - const unsigned char *spelling; - int c; - - if (token->flags & DIGRAPH) - spelling = cpp_digraph2name (token->type); - else if (token->flags & NAMED_OP) - goto spell_ident; - else - spelling = TOKEN_NAME (token); - - c = *spelling; - do - putc (c, fp); - while ((c = *++spelling) != '\0'); - } - break; - - spell_ident: - case SPELL_IDENT: - { - size_t i; - const unsigned char * name = NODE_NAME (token->val.node.node); - - for (i = 0; i < NODE_LEN (token->val.node.node); i++) - if (name[i] & ~0x7F) - { - unsigned char buffer[10]; - i += utf8_to_ucn (buffer, name + i) - 1; - fwrite (buffer, 1, 10, fp); - } - else - fputc (NODE_NAME (token->val.node.node)[i], fp); - } - break; - - case SPELL_LITERAL: - fwrite (token->val.str.text, 1, token->val.str.len, fp); - break; - - case SPELL_NONE: - /* An error, most probably. */ - break; - } -} - -/* Compare two tokens. */ -int -_cpp_equiv_tokens (const cpp_token *a, const cpp_token *b) -{ - if (a->type == b->type && a->flags == b->flags) - switch (TOKEN_SPELL (a)) - { - default: /* Keep compiler happy. */ - case SPELL_OPERATOR: - /* token_no is used to track where multiple consecutive ## - tokens were originally located. */ - return (a->type != CPP_PASTE || a->val.token_no == b->val.token_no); - case SPELL_NONE: - return (a->type != CPP_MACRO_ARG - || a->val.macro_arg.arg_no == b->val.macro_arg.arg_no); - case SPELL_IDENT: - return a->val.node.node == b->val.node.node; - case SPELL_LITERAL: - return (a->val.str.len == b->val.str.len - && !memcmp (a->val.str.text, b->val.str.text, - a->val.str.len)); - } - - return 0; -} - -/* Returns nonzero if a space should be inserted to avoid an - accidental token paste for output. For simplicity, it is - conservative, and occasionally advises a space where one is not - needed, e.g. "." and ".2". */ -int -cpp_avoid_paste (cpp_reader *pfile, const cpp_token *token1, - const cpp_token *token2) -{ - enum cpp_ttype a = token1->type, b = token2->type; - cppchar_t c; - - if (token1->flags & NAMED_OP) - a = CPP_NAME; - if (token2->flags & NAMED_OP) - b = CPP_NAME; - - c = EOF; - if (token2->flags & DIGRAPH) - c = digraph_spellings[(int) b - (int) CPP_FIRST_DIGRAPH][0]; - else if (token_spellings[b].category == SPELL_OPERATOR) - c = token_spellings[b].name[0]; - - /* Quickly get everything that can paste with an '='. */ - if ((int) a <= (int) CPP_LAST_EQ && c == '=') - return 1; - - switch (a) - { - case CPP_GREATER: return c == '>'; - case CPP_LESS: return c == '<' || c == '%' || c == ':'; - case CPP_PLUS: return c == '+'; - case CPP_MINUS: return c == '-' || c == '>'; - case CPP_DIV: return c == '/' || c == '*'; /* Comments. */ - case CPP_MOD: return c == ':' || c == '>'; - case CPP_AND: return c == '&'; - case CPP_OR: return c == '|'; - case CPP_COLON: return c == ':' || c == '>'; - case CPP_DEREF: return c == '*'; - case CPP_DOT: return c == '.' || c == '%' || b == CPP_NUMBER; - case CPP_HASH: return c == '#' || c == '%'; /* Digraph form. */ - case CPP_NAME: return ((b == CPP_NUMBER - && name_p (pfile, &token2->val.str)) - || b == CPP_NAME - || b == CPP_CHAR || b == CPP_STRING); /* L */ - case CPP_NUMBER: return (b == CPP_NUMBER || b == CPP_NAME - || c == '.' || c == '+' || c == '-'); - /* UCNs */ - case CPP_OTHER: return ((token1->val.str.text[0] == '\\' - && b == CPP_NAME) - || (CPP_OPTION (pfile, objc) - && token1->val.str.text[0] == '@' - && (b == CPP_NAME || b == CPP_STRING))); - default: break; - } - - return 0; -} - -/* Output all the remaining tokens on the current line, and a newline - character, to FP. Leading whitespace is removed. If there are - macros, special token padding is not performed. */ -void -cpp_output_line (cpp_reader *pfile, FILE *fp) -{ - const cpp_token *token; - - token = cpp_get_token (pfile); - while (token->type != CPP_EOF) - { - cpp_output_token (token, fp); - token = cpp_get_token (pfile); - if (token->flags & PREV_WHITE) - putc (' ', fp); - if (in_asm && token->flags & PREV_NL) - fputs ("\x87 ", fp); - } - - putc ('\n', fp); -} - -/* Return a string representation of all the remaining tokens on the - current line. The result is allocated using xmalloc and must be - freed by the caller. */ -unsigned char * -cpp_output_line_to_string (cpp_reader *pfile, const unsigned char *dir_name) -{ - const cpp_token *token; - unsigned int out = dir_name ? ustrlen (dir_name) : 0; - unsigned int alloced = 120 + out; - unsigned char *result = (unsigned char *) xmalloc (alloced); - - /* If DIR_NAME is empty, there are no initial contents. */ - if (dir_name) - { - sprintf ((char *) result, "#%s ", dir_name); - out += 2; - } - - token = cpp_get_token (pfile); - while (token->type != CPP_EOF) - { - unsigned char *last; - /* Include room for a possible space and the terminating nul. */ - unsigned int len = cpp_token_len (token) + 2; - - if (out + len > alloced) - { - alloced *= 2; - if (out + len > alloced) - alloced = out + len; - result = (unsigned char *) xrealloc (result, alloced); - } - - last = cpp_spell_token (pfile, token, &result[out], 0); - out = last - result; - - token = cpp_get_token (pfile); - if (token->flags & PREV_WHITE) - result[out++] = ' '; - } - - result[out] = '\0'; - return result; -} - -/* Memory buffers. Changing these three constants can have a dramatic - effect on performance. The values here are reasonable defaults, - but might be tuned. If you adjust them, be sure to test across a - range of uses of cpplib, including heavy nested function-like macro - expansion. Also check the change in peak memory usage (NJAMD is a - good tool for this). */ -#define MIN_BUFF_SIZE 8000 -#define BUFF_SIZE_UPPER_BOUND(MIN_SIZE) (MIN_BUFF_SIZE + (MIN_SIZE) * 3 / 2) -#define EXTENDED_BUFF_SIZE(BUFF, MIN_EXTRA) \ - (MIN_EXTRA + ((BUFF)->limit - (BUFF)->cur) * 2) - -#if MIN_BUFF_SIZE > BUFF_SIZE_UPPER_BOUND (0) - #error BUFF_SIZE_UPPER_BOUND must be at least as large as MIN_BUFF_SIZE! -#endif - -/* Create a new allocation buffer. Place the control block at the end - of the buffer, so that buffer overflows will cause immediate chaos. */ -static _cpp_buff * -new_buff (size_t len) -{ - _cpp_buff *result; - unsigned char *base; - - if (len < MIN_BUFF_SIZE) - len = MIN_BUFF_SIZE; - len = CPP_ALIGN (len); - - base = XNEWVEC (unsigned char, len + sizeof (_cpp_buff)); - result = (_cpp_buff *) (base + len); - result->base = base; - result->cur = base; - result->limit = base + len; - result->next = NULL; - return result; -} - -/* Place a chain of unwanted allocation buffers on the free list. */ -void -_cpp_release_buff (cpp_reader *pfile, _cpp_buff *buff) -{ - _cpp_buff *end = buff; - - while (end->next) - end = end->next; - end->next = pfile->free_buffs; - pfile->free_buffs = buff; -} - -/* Return a free buffer of size at least MIN_SIZE. */ -_cpp_buff * -_cpp_get_buff (cpp_reader *pfile, size_t min_size) -{ - _cpp_buff *result, **p; - - for (p = &pfile->free_buffs;; p = &(*p)->next) - { - size_t size; - - if (*p == NULL) - return new_buff (min_size); - result = *p; - size = result->limit - result->base; - /* Return a buffer that's big enough, but don't waste one that's - way too big. */ - if (size >= min_size && size <= BUFF_SIZE_UPPER_BOUND (min_size)) - break; - } - - *p = result->next; - result->next = NULL; - result->cur = result->base; - return result; -} - -/* Creates a new buffer with enough space to hold the uncommitted - remaining bytes of BUFF, and at least MIN_EXTRA more bytes. Copies - the excess bytes to the new buffer. Chains the new buffer after - BUFF, and returns the new buffer. */ -_cpp_buff * -_cpp_append_extend_buff (cpp_reader *pfile, _cpp_buff *buff, size_t min_extra) -{ - size_t size = EXTENDED_BUFF_SIZE (buff, min_extra); - _cpp_buff *new_buff = _cpp_get_buff (pfile, size); - - buff->next = new_buff; - memcpy (new_buff->base, buff->cur, BUFF_ROOM (buff)); - return new_buff; -} - -/* Creates a new buffer with enough space to hold the uncommitted - remaining bytes of the buffer pointed to by BUFF, and at least - MIN_EXTRA more bytes. Copies the excess bytes to the new buffer. - Chains the new buffer before the buffer pointed to by BUFF, and - updates the pointer to point to the new buffer. */ -void -_cpp_extend_buff (cpp_reader *pfile, _cpp_buff **pbuff, size_t min_extra) -{ - _cpp_buff *new_buff, *old_buff = *pbuff; - size_t size = EXTENDED_BUFF_SIZE (old_buff, min_extra); - - new_buff = _cpp_get_buff (pfile, size); - memcpy (new_buff->base, old_buff->cur, BUFF_ROOM (old_buff)); - new_buff->next = old_buff; - *pbuff = new_buff; -} - -/* Free a chain of buffers starting at BUFF. */ -void -_cpp_free_buff (_cpp_buff *buff) -{ - _cpp_buff *next; - - for (; buff; buff = next) - { - next = buff->next; - free (buff->base); - } -} - -/* Allocate permanent, unaligned storage of length LEN. */ -unsigned char * -_cpp_unaligned_alloc (cpp_reader *pfile, size_t len) -{ - _cpp_buff *buff = pfile->u_buff; - unsigned char *result = buff->cur; - - if (len > (size_t) (buff->limit - result)) - { - buff = _cpp_get_buff (pfile, len); - buff->next = pfile->u_buff; - pfile->u_buff = buff; - result = buff->cur; - } - - buff->cur = result + len; - return result; -} - -/* Allocate permanent, unaligned storage of length LEN from a_buff. - That buffer is used for growing allocations when saving macro - replacement lists in a #define, and when parsing an answer to an - assertion in #assert, #unassert or #if (and therefore possibly - whilst expanding macros). It therefore must not be used by any - code that they might call: specifically the lexer and the guts of - the macro expander. - - All existing other uses clearly fit this restriction: storing - registered pragmas during initialization. */ -unsigned char * -_cpp_aligned_alloc (cpp_reader *pfile, size_t len) -{ - _cpp_buff *buff = pfile->a_buff; - unsigned char *result = buff->cur; - - if (len > (size_t) (buff->limit - result)) - { - buff = _cpp_get_buff (pfile, len); - buff->next = pfile->a_buff; - pfile->a_buff = buff; - result = buff->cur; - } - - buff->cur = result + len; - return result; -} - -/* Say which field of TOK is in use. */ - -enum cpp_token_fld_kind -cpp_token_val_index (cpp_token *tok) -{ - switch (TOKEN_SPELL (tok)) - { - case SPELL_IDENT: - return CPP_TOKEN_FLD_NODE; - case SPELL_LITERAL: - return CPP_TOKEN_FLD_STR; - case SPELL_OPERATOR: - if (tok->type == CPP_PASTE) - return CPP_TOKEN_FLD_TOKEN_NO; - else - return CPP_TOKEN_FLD_NONE; - case SPELL_NONE: - if (tok->type == CPP_MACRO_ARG) - return CPP_TOKEN_FLD_ARG_NO; - else if (tok->type == CPP_PADDING) - return CPP_TOKEN_FLD_SOURCE; - else if (tok->type == CPP_PRAGMA) - return CPP_TOKEN_FLD_PRAGMA; - /* else fall through */ - default: - return CPP_TOKEN_FLD_NONE; - } -} diff --git a/support/cpp/libcpp/lex.cc b/support/cpp/libcpp/lex.cc new file mode 100644 index 000000000..38d05545e --- /dev/null +++ b/support/cpp/libcpp/lex.cc @@ -0,0 +1,5560 @@ +/* CPP Library - lexical analysis. + Copyright (C) 2000-2022 Free Software Foundation, Inc. + Contributed by Per Bothner, 1994-95. + Based on CCCP program by Paul Rubin, June 1986 + Adapted to ANSI C, Richard Stallman, Jan 1987 + Broken out to separate file, Zack Weinberg, Mar 2000 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include <map> // BUG +#include <iostream> // BUG +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" +#include <cassert> + +#define untested() ( std::cerr << "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \ + <<":" << __func__ << "\n" ) + +enum spell_type +{ + SPELL_OPERATOR = 0, + SPELL_IDENT, + SPELL_LITERAL, + SPELL_NONE +}; + +struct token_spelling +{ + enum spell_type category; + const unsigned char *name; +}; + +static const unsigned char *const digraph_spellings[] = +{ UC"%:", UC"%:%:", UC"<:", UC":>", UC"<%", UC"%>" }; + +#define OP(e, s) { SPELL_OPERATOR, UC s }, +#define TK(e, s) { SPELL_ ## s, UC #e }, +static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE }; +#undef OP +#undef TK + +#define TOKEN_SPELL(token) (token_spellings[(token)->type].category) +#define TOKEN_NAME(token) (token_spellings[(token)->type].name) + +static void add_line_note (cpp_buffer *, const uchar *, unsigned int); +static int skip_line_comment (cpp_reader *); +static void skip_whitespace (cpp_reader *, cppchar_t); +static void lex_string (cpp_reader *, cpp_token *, const uchar *); +static void save_comment (cpp_reader *, cpp_token *, const uchar *, cppchar_t); +static void store_comment (cpp_reader *, cpp_token *); +static void create_literal (cpp_reader *, cpp_token *, const uchar *, + unsigned int, enum cpp_ttype); +static bool warn_in_comment (cpp_reader *, _cpp_line_note *); +static int name_p (cpp_reader *, const cpp_string *); +static tokenrun *next_tokenrun (tokenrun *); + +static _cpp_buff *new_buff (size_t); + +int _in_asm = 0; +bool in_asm() +{ + return _in_asm; +} + +/* Utility routine: + + Compares, the token TOKEN to the NUL-terminated string STRING. + TOKEN must be a CPP_NAME. Returns 1 for equal, 0 for unequal. */ +int +cpp_ideq (const cpp_token *token, const char *string) +{ + if (token->type != CPP_NAME) + return 0; + + return !ustrcmp (NODE_NAME (token->val.node.node), (const uchar *) string); +} + +/* Record a note TYPE at byte POS into the current cleaned logical + line. */ +static void +add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type) +{ + if (buffer->notes_used == buffer->notes_cap) + { + buffer->notes_cap = buffer->notes_cap * 2 + 200; + buffer->notes = XRESIZEVEC (_cpp_line_note, buffer->notes, + buffer->notes_cap); + } + + buffer->notes[buffer->notes_used].pos = pos; + buffer->notes[buffer->notes_used].type = type; + buffer->notes_used++; +} + + +/* Fast path to find line special characters using optimized character + scanning algorithms. Anything complicated falls back to the slow + path below. Since this loop is very hot it's worth doing these kinds + of optimizations. + + One of the paths through the ifdefs should provide + + const uchar *search_line_fast (const uchar *s, const uchar *end); + + Between S and END, search for \n, \r, \\, ?. Return a pointer to + the found character. + + Note that the last character of the buffer is *always* a newline, + as forced by _cpp_convert_input. This fact can be used to avoid + explicitly looking for the end of the buffer. */ + +/* Configure gives us an ifdef test. */ +#ifndef WORDS_BIGENDIAN +#define WORDS_BIGENDIAN 0 +#endif + +/* We'd like the largest integer that fits into a register. There's nothing + in <stdint.h> that gives us that. For most hosts this is unsigned long, + but MS decided on an LLP64 model. Thankfully when building with GCC we + can get the "real" word size. */ +#ifdef __GNUC__ +typedef unsigned int word_type __attribute__((__mode__(__word__))); +#else +typedef unsigned long word_type; +#endif + +/* The code below is only expecting sizes 4 or 8. + Die at compile-time if this expectation is violated. */ +typedef char check_word_type_size + [(sizeof(word_type) == 8 || sizeof(word_type) == 4) * 2 - 1]; + +/* Return X with the first N bytes forced to values that won't match one + of the interesting characters. Note that NUL is not interesting. */ + +static inline word_type +acc_char_mask_misalign (word_type val, unsigned int n) +{ + word_type mask = -1; + if (WORDS_BIGENDIAN) + mask >>= n * 8; + else + mask <<= n * 8; + return val & mask; +} + +/* Return X replicated to all byte positions within WORD_TYPE. */ + +static inline word_type +acc_char_replicate (uchar x) +{ + word_type ret; + + ret = (x << 24) | (x << 16) | (x << 8) | x; + if (sizeof(word_type) == 8) + ret = (ret << 16 << 16) | ret; + return ret; +} + +/* Return non-zero if some byte of VAL is (probably) C. */ + +static inline word_type +acc_char_cmp (word_type val, word_type c) +{ +#if defined(__GNUC__) && defined(__alpha__) + /* We can get exact results using a compare-bytes instruction. + Get (val == c) via (0 >= (val ^ c)). */ + return __builtin_alpha_cmpbge (0, val ^ c); +#else + word_type magic = 0x7efefefeU; + if (sizeof(word_type) == 8) + magic = (magic << 16 << 16) | 0xfefefefeU; + magic |= 1; + + val ^= c; + return ((val + magic) ^ ~val) & ~magic; +#endif +} + +/* Given the result of acc_char_cmp is non-zero, return the index of + the found character. If this was a false positive, return -1. */ + +static inline int +acc_char_index (word_type cmp ATTRIBUTE_UNUSED, + word_type val ATTRIBUTE_UNUSED) +{ +#if defined(__GNUC__) && defined(__alpha__) && !WORDS_BIGENDIAN + /* The cmpbge instruction sets *bits* of the result corresponding to + matches in the bytes with no false positives. */ + return __builtin_ctzl (cmp); +#else + unsigned int i; + + /* ??? It would be nice to force unrolling here, + and have all of these constants folded. */ + for (i = 0; i < sizeof(word_type); ++i) + { + uchar c; + if (WORDS_BIGENDIAN) + c = (val >> (sizeof(word_type) - i - 1) * 8) & 0xff; + else + c = (val >> i * 8) & 0xff; + + if (c == '\n' || c == '\r' || c == '\\' || c == '?') + return i; + } + + return -1; +#endif +} + +/* A version of the fast scanner using bit fiddling techniques. + + For 32-bit words, one would normally perform 16 comparisons and + 16 branches. With this algorithm one performs 24 arithmetic + operations and one branch. Whether this is faster with a 32-bit + word size is going to be somewhat system dependent. + + For 64-bit words, we eliminate twice the number of comparisons + and branches without increasing the number of arithmetic operations. + It's almost certainly going to be a win with 64-bit word size. */ + +static const uchar * search_line_acc_char (const uchar *, const uchar *) + ATTRIBUTE_UNUSED; + +static const uchar * +search_line_acc_char (const uchar *s, const uchar *end ATTRIBUTE_UNUSED) +{ + const word_type repl_nl = acc_char_replicate ('\n'); + const word_type repl_cr = acc_char_replicate ('\r'); + const word_type repl_bs = acc_char_replicate ('\\'); + const word_type repl_qm = acc_char_replicate ('?'); + + unsigned int misalign; + const word_type *p; + word_type val, t; + + /* Align the buffer. Mask out any bytes from before the beginning. */ + p = (word_type *)((uintptr_t)s & -sizeof(word_type)); + val = *p; + misalign = (uintptr_t)s & (sizeof(word_type) - 1); + if (misalign) + val = acc_char_mask_misalign (val, misalign); + + /* Main loop. */ + while (1) + { + t = acc_char_cmp (val, repl_nl); + t |= acc_char_cmp (val, repl_cr); + t |= acc_char_cmp (val, repl_bs); + t |= acc_char_cmp (val, repl_qm); + + if (__builtin_expect (t != 0, 0)) + { + int i = acc_char_index (t, val); + if (i >= 0) + return (const uchar *)p + i; + } + + val = *++p; + } +} + +/* Disable on Solaris 2/x86 until the following problem can be properly + autoconfed: + + The Solaris 10+ assembler tags objects with the instruction set + extensions used, so SSE4.2 executables cannot run on machines that + don't support that extension. */ + +#if (GCC_VERSION >= 4005) && (__GNUC__ >= 5 || !defined(__PIC__)) && (defined(__i386__) || defined(__x86_64__)) && !(defined(__sun__) && defined(__svr4__)) + +/* Replicated character data to be shared between implementations. + Recall that outside of a context with vector support we can't + define compatible vector types, therefore these are all defined + in terms of raw characters. */ +static const char repl_chars[4][16] __attribute__((aligned(16))) = { + { '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n', + '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n' }, + { '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r', + '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r' }, + { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', + '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' }, + { '?', '?', '?', '?', '?', '?', '?', '?', + '?', '?', '?', '?', '?', '?', '?', '?' }, +}; + +/* A version of the fast scanner using MMX vectorized byte compare insns. + + This uses the PMOVMSKB instruction which was introduced with "MMX2", + which was packaged into SSE1; it is also present in the AMD MMX + extension. Mark the function as using "sse" so that we emit a real + "emms" instruction, rather than the 3dNOW "femms" instruction. */ + +static const uchar * +#ifndef __SSE__ +__attribute__((__target__("sse"))) +#endif +search_line_mmx (const uchar *s, const uchar *end ATTRIBUTE_UNUSED) +{ + typedef char v8qi __attribute__ ((__vector_size__ (8))); + typedef int __m64 __attribute__ ((__vector_size__ (8), __may_alias__)); + + const v8qi repl_nl = *(const v8qi *)repl_chars[0]; + const v8qi repl_cr = *(const v8qi *)repl_chars[1]; + const v8qi repl_bs = *(const v8qi *)repl_chars[2]; + const v8qi repl_qm = *(const v8qi *)repl_chars[3]; + + unsigned int misalign, found, mask; + const v8qi *p; + v8qi data, t, c; + + /* Align the source pointer. While MMX doesn't generate unaligned data + faults, this allows us to safely scan to the end of the buffer without + reading beyond the end of the last page. */ + misalign = (uintptr_t)s & 7; + p = (const v8qi *)((uintptr_t)s & -8); + data = *p; + + /* Create a mask for the bytes that are valid within the first + 16-byte block. The Idea here is that the AND with the mask + within the loop is "free", since we need some AND or TEST + insn in order to set the flags for the branch anyway. */ + mask = -1u << misalign; + + /* Main loop processing 8 bytes at a time. */ + goto start; + do + { + data = *++p; + mask = -1; + + start: + t = __builtin_ia32_pcmpeqb(data, repl_nl); + c = __builtin_ia32_pcmpeqb(data, repl_cr); + t = (v8qi) __builtin_ia32_por ((__m64)t, (__m64)c); + c = __builtin_ia32_pcmpeqb(data, repl_bs); + t = (v8qi) __builtin_ia32_por ((__m64)t, (__m64)c); + c = __builtin_ia32_pcmpeqb(data, repl_qm); + t = (v8qi) __builtin_ia32_por ((__m64)t, (__m64)c); + found = __builtin_ia32_pmovmskb (t); + found &= mask; + } + while (!found); + + __builtin_ia32_emms (); + + /* FOUND contains 1 in bits for which we matched a relevant + character. Conversion to the byte index is trivial. */ + found = __builtin_ctz(found); + return (const uchar *)p + found; +} + +/* A version of the fast scanner using SSE2 vectorized byte compare insns. */ + +static const uchar * +#ifndef __SSE2__ +__attribute__((__target__("sse2"))) +#endif +search_line_sse2 (const uchar *s, const uchar *end ATTRIBUTE_UNUSED) +{ + typedef char v16qi __attribute__ ((__vector_size__ (16))); + + const v16qi repl_nl = *(const v16qi *)repl_chars[0]; + const v16qi repl_cr = *(const v16qi *)repl_chars[1]; + const v16qi repl_bs = *(const v16qi *)repl_chars[2]; + const v16qi repl_qm = *(const v16qi *)repl_chars[3]; + + unsigned int misalign, found, mask; + const v16qi *p; + v16qi data, t; + + /* Align the source pointer. */ + misalign = (uintptr_t)s & 15; + p = (const v16qi *)((uintptr_t)s & -16); + data = *p; + + /* Create a mask for the bytes that are valid within the first + 16-byte block. The Idea here is that the AND with the mask + within the loop is "free", since we need some AND or TEST + insn in order to set the flags for the branch anyway. */ + mask = -1u << misalign; + + /* Main loop processing 16 bytes at a time. */ + goto start; + do + { + data = *++p; + mask = -1; + + start: + t = data == repl_nl; + t |= data == repl_cr; + t |= data == repl_bs; + t |= data == repl_qm; + found = __builtin_ia32_pmovmskb128 (t); + found &= mask; + } + while (!found); + + /* FOUND contains 1 in bits for which we matched a relevant + character. Conversion to the byte index is trivial. */ + found = __builtin_ctz(found); + return (const uchar *)p + found; +} + +#ifdef HAVE_SSE4 +/* A version of the fast scanner using SSE 4.2 vectorized string insns. */ + +static const uchar * +#ifndef __SSE4_2__ +__attribute__((__target__("sse4.2"))) +#endif +search_line_sse42 (const uchar *s, const uchar *end) +{ + typedef char v16qi __attribute__ ((__vector_size__ (16))); + static const v16qi search = { '\n', '\r', '?', '\\' }; + + uintptr_t si = (uintptr_t)s; + uintptr_t index; + + /* Check for unaligned input. */ + if (si & 15) + { + v16qi sv; + + if (__builtin_expect (end - s < 16, 0) + && __builtin_expect ((si & 0xfff) > 0xff0, 0)) + { + /* There are less than 16 bytes left in the buffer, and less + than 16 bytes left on the page. Reading 16 bytes at this + point might generate a spurious page fault. Defer to the + SSE2 implementation, which already handles alignment. */ + return search_line_sse2 (s, end); + } + + /* ??? The builtin doesn't understand that the PCMPESTRI read from + memory need not be aligned. */ + sv = __builtin_ia32_loaddqu ((const char *) s); + index = __builtin_ia32_pcmpestri128 (search, 4, sv, 16, 0); + + if (__builtin_expect (index < 16, 0)) + goto found; + + /* Advance the pointer to an aligned address. We will re-scan a + few bytes, but we no longer need care for reading past the + end of a page, since we're guaranteed a match. */ + s = (const uchar *)((si + 15) & -16); + } + + /* Main loop, processing 16 bytes at a time. */ +#ifdef __GCC_ASM_FLAG_OUTPUTS__ + while (1) + { + char f; + + /* By using inline assembly instead of the builtin, + we can use the result, as well as the flags set. */ + __asm ("%vpcmpestri\t$0, %2, %3" + : "=c"(index), "=@ccc"(f) + : "m"(*s), "x"(search), "a"(4), "d"(16)); + if (f) + break; + + s += 16; + } +#else + s -= 16; + /* By doing the whole loop in inline assembly, + we can make proper use of the flags set. */ + __asm ( ".balign 16\n" + "0: add $16, %1\n" + " %vpcmpestri\t$0, (%1), %2\n" + " jnc 0b" + : "=&c"(index), "+r"(s) + : "x"(search), "a"(4), "d"(16)); +#endif + + found: + return s + index; +} + +#else +/* Work around out-dated assemblers without sse4 support. */ +#define search_line_sse42 search_line_sse2 +#endif + +/* Check the CPU capabilities. */ + +#include "../gcc/config/i386/cpuid.h" + +typedef const uchar * (*search_line_fast_type) (const uchar *, const uchar *); +static search_line_fast_type search_line_fast; + +#define HAVE_init_vectorized_lexer 1 +static inline void +init_vectorized_lexer (void) +{ + unsigned dummy, ecx = 0, edx = 0; + search_line_fast_type impl = search_line_acc_char; + int minimum = 0; + +#if defined(__SSE4_2__) + minimum = 3; +#elif defined(__SSE2__) + minimum = 2; +#elif defined(__SSE__) + minimum = 1; +#endif + + if (minimum == 3) + impl = search_line_sse42; + else if (__get_cpuid (1, &dummy, &dummy, &ecx, &edx) || minimum == 2) + { + if (minimum == 3 || (ecx & bit_SSE4_2)) + impl = search_line_sse42; + else if (minimum == 2 || (edx & bit_SSE2)) + impl = search_line_sse2; + else if (minimum == 1 || (edx & bit_SSE)) + impl = search_line_mmx; + } + else if (__get_cpuid (0x80000001, &dummy, &dummy, &dummy, &edx)) + { + if (minimum == 1 + || (edx & (bit_MMXEXT | bit_CMOV)) == (bit_MMXEXT | bit_CMOV)) + impl = search_line_mmx; + } + + search_line_fast = impl; +} + +#elif (GCC_VERSION >= 4005) && defined(_ARCH_PWR8) && defined(__ALTIVEC__) + +/* A vection of the fast scanner using AltiVec vectorized byte compares + and VSX unaligned loads (when VSX is available). This is otherwise + the same as the AltiVec version. */ + +ATTRIBUTE_NO_SANITIZE_UNDEFINED +static const uchar * +search_line_fast (const uchar *s, const uchar *end ATTRIBUTE_UNUSED) +{ + typedef __attribute__((altivec(vector))) unsigned char vc; + + const vc repl_nl = { + '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n', + '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n' + }; + const vc repl_cr = { + '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r', + '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r' + }; + const vc repl_bs = { + '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', + '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' + }; + const vc repl_qm = { + '?', '?', '?', '?', '?', '?', '?', '?', + '?', '?', '?', '?', '?', '?', '?', '?', + }; + const vc zero = { 0 }; + + vc data, t; + + /* Main loop processing 16 bytes at a time. */ + do + { + vc m_nl, m_cr, m_bs, m_qm; + + data = __builtin_vec_vsx_ld (0, s); + s += 16; + + m_nl = (vc) __builtin_vec_cmpeq(data, repl_nl); + m_cr = (vc) __builtin_vec_cmpeq(data, repl_cr); + m_bs = (vc) __builtin_vec_cmpeq(data, repl_bs); + m_qm = (vc) __builtin_vec_cmpeq(data, repl_qm); + t = (m_nl | m_cr) | (m_bs | m_qm); + + /* T now contains 0xff in bytes for which we matched one of the relevant + characters. We want to exit the loop if any byte in T is non-zero. + Below is the expansion of vec_any_ne(t, zero). */ + } + while (!__builtin_vec_vcmpeq_p(/*__CR6_LT_REV*/3, t, zero)); + + /* Restore s to to point to the 16 bytes we just processed. */ + s -= 16; + + { +#define N (sizeof(vc) / sizeof(long)) + + union { + vc v; + /* Statically assert that N is 2 or 4. */ + unsigned long l[(N == 2 || N == 4) ? N : -1]; + } u; + unsigned long l, i = 0; + + u.v = t; + + /* Find the first word of T that is non-zero. */ + switch (N) + { + case 4: + l = u.l[i++]; + if (l != 0) + break; + s += sizeof(unsigned long); + l = u.l[i++]; + if (l != 0) + break; + s += sizeof(unsigned long); + /* FALLTHRU */ + case 2: + l = u.l[i++]; + if (l != 0) + break; + s += sizeof(unsigned long); + l = u.l[i]; + } + + /* L now contains 0xff in bytes for which we matched one of the + relevant characters. We can find the byte index by finding + its bit index and dividing by 8. */ +#ifdef __BIG_ENDIAN__ + l = __builtin_clzl(l) >> 3; +#else + l = __builtin_ctzl(l) >> 3; +#endif + return s + l; + +#undef N + } +} + +#elif (GCC_VERSION >= 4005) && defined(__ALTIVEC__) && defined (__BIG_ENDIAN__) + +/* A vection of the fast scanner using AltiVec vectorized byte compares. + This cannot be used for little endian because vec_lvsl/lvsr are + deprecated for little endian and the code won't work properly. */ +/* ??? Unfortunately, attribute(target("altivec")) is not yet supported, + so we can't compile this function without -maltivec on the command line + (or implied by some other switch). */ + +static const uchar * +search_line_fast (const uchar *s, const uchar *end ATTRIBUTE_UNUSED) +{ + typedef __attribute__((altivec(vector))) unsigned char vc; + + const vc repl_nl = { + '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n', + '\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n' + }; + const vc repl_cr = { + '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r', + '\r', '\r', '\r', '\r', '\r', '\r', '\r', '\r' + }; + const vc repl_bs = { + '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', + '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' + }; + const vc repl_qm = { + '?', '?', '?', '?', '?', '?', '?', '?', + '?', '?', '?', '?', '?', '?', '?', '?', + }; + const vc ones = { + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + }; + const vc zero = { 0 }; + + vc data, mask, t; + + /* Altivec loads automatically mask addresses with -16. This lets us + issue the first load as early as possible. */ + data = __builtin_vec_ld(0, (const vc *)s); + + /* Discard bytes before the beginning of the buffer. Do this by + beginning with all ones and shifting in zeros according to the + mis-alignment. The LVSR instruction pulls the exact shift we + want from the address. */ + mask = __builtin_vec_lvsr(0, s); + mask = __builtin_vec_perm(zero, ones, mask); + data &= mask; + + /* While altivec loads mask addresses, we still need to align S so + that the offset we compute at the end is correct. */ + s = (const uchar *)((uintptr_t)s & -16); + + /* Main loop processing 16 bytes at a time. */ + goto start; + do + { + vc m_nl, m_cr, m_bs, m_qm; + + s += 16; + data = __builtin_vec_ld(0, (const vc *)s); + + start: + m_nl = (vc) __builtin_vec_cmpeq(data, repl_nl); + m_cr = (vc) __builtin_vec_cmpeq(data, repl_cr); + m_bs = (vc) __builtin_vec_cmpeq(data, repl_bs); + m_qm = (vc) __builtin_vec_cmpeq(data, repl_qm); + t = (m_nl | m_cr) | (m_bs | m_qm); + + /* T now contains 0xff in bytes for which we matched one of the relevant + characters. We want to exit the loop if any byte in T is non-zero. + Below is the expansion of vec_any_ne(t, zero). */ + } + while (!__builtin_vec_vcmpeq_p(/*__CR6_LT_REV*/3, t, zero)); + + { +#define N (sizeof(vc) / sizeof(long)) + + union { + vc v; + /* Statically assert that N is 2 or 4. */ + unsigned long l[(N == 2 || N == 4) ? N : -1]; + } u; + unsigned long l, i = 0; + + u.v = t; + + /* Find the first word of T that is non-zero. */ + switch (N) + { + case 4: + l = u.l[i++]; + if (l != 0) + break; + s += sizeof(unsigned long); + l = u.l[i++]; + if (l != 0) + break; + s += sizeof(unsigned long); + /* FALLTHROUGH */ + case 2: + l = u.l[i++]; + if (l != 0) + break; + s += sizeof(unsigned long); + l = u.l[i]; + } + + /* L now contains 0xff in bytes for which we matched one of the + relevant characters. We can find the byte index by finding + its bit index and dividing by 8. */ + l = __builtin_clzl(l) >> 3; + return s + l; + +#undef N + } +} + +#elif defined (__ARM_NEON) && defined (__ARM_64BIT_STATE) +#include "arm_neon.h" + +/* This doesn't have to be the exact page size, but no system may use + a size smaller than this. ARMv8 requires a minimum page size of + 4k. The impact of being conservative here is a small number of + cases will take the slightly slower entry path into the main + loop. */ + +#define AARCH64_MIN_PAGE_SIZE 4096 + +static const uchar * +search_line_fast (const uchar *s, const uchar *end ATTRIBUTE_UNUSED) +{ + const uint8x16_t repl_nl = vdupq_n_u8 ('\n'); + const uint8x16_t repl_cr = vdupq_n_u8 ('\r'); + const uint8x16_t repl_bs = vdupq_n_u8 ('\\'); + const uint8x16_t repl_qm = vdupq_n_u8 ('?'); + const uint8x16_t xmask = (uint8x16_t) vdupq_n_u64 (0x8040201008040201ULL); + +#ifdef __ARM_BIG_ENDIAN + const int16x8_t shift = {8, 8, 8, 8, 0, 0, 0, 0}; +#else + const int16x8_t shift = {0, 0, 0, 0, 8, 8, 8, 8}; +#endif + + unsigned int found; + const uint8_t *p; + uint8x16_t data; + uint8x16_t t; + uint16x8_t m; + uint8x16_t u, v, w; + + /* Align the source pointer. */ + p = (const uint8_t *)((uintptr_t)s & -16); + + /* Assuming random string start positions, with a 4k page size we'll take + the slow path about 0.37% of the time. */ + if (__builtin_expect ((AARCH64_MIN_PAGE_SIZE + - (((uintptr_t) s) & (AARCH64_MIN_PAGE_SIZE - 1))) + < 16, 0)) + { + /* Slow path: the string starts near a possible page boundary. */ + uint32_t misalign, mask; + + misalign = (uintptr_t)s & 15; + mask = (-1u << misalign) & 0xffff; + data = vld1q_u8 (p); + t = vceqq_u8 (data, repl_nl); + u = vceqq_u8 (data, repl_cr); + v = vorrq_u8 (t, vceqq_u8 (data, repl_bs)); + w = vorrq_u8 (u, vceqq_u8 (data, repl_qm)); + t = vorrq_u8 (v, w); + t = vandq_u8 (t, xmask); + m = vpaddlq_u8 (t); + m = vshlq_u16 (m, shift); + found = vaddvq_u16 (m); + found &= mask; + if (found) + return (const uchar*)p + __builtin_ctz (found); + } + else + { + data = vld1q_u8 ((const uint8_t *) s); + t = vceqq_u8 (data, repl_nl); + u = vceqq_u8 (data, repl_cr); + v = vorrq_u8 (t, vceqq_u8 (data, repl_bs)); + w = vorrq_u8 (u, vceqq_u8 (data, repl_qm)); + t = vorrq_u8 (v, w); + if (__builtin_expect (vpaddd_u64 ((uint64x2_t)t) != 0, 0)) + goto done; + } + + do + { + p += 16; + data = vld1q_u8 (p); + t = vceqq_u8 (data, repl_nl); + u = vceqq_u8 (data, repl_cr); + v = vorrq_u8 (t, vceqq_u8 (data, repl_bs)); + w = vorrq_u8 (u, vceqq_u8 (data, repl_qm)); + t = vorrq_u8 (v, w); + } while (!vpaddd_u64 ((uint64x2_t)t)); + +done: + /* Now that we've found the terminating substring, work out precisely where + we need to stop. */ + t = vandq_u8 (t, xmask); + m = vpaddlq_u8 (t); + m = vshlq_u16 (m, shift); + found = vaddvq_u16 (m); + return (((((uintptr_t) p) < (uintptr_t) s) ? s : (const uchar *)p) + + __builtin_ctz (found)); +} + +#elif defined (__ARM_NEON) +#include "arm_neon.h" + +static const uchar * +search_line_fast (const uchar *s, const uchar *end ATTRIBUTE_UNUSED) +{ + const uint8x16_t repl_nl = vdupq_n_u8 ('\n'); + const uint8x16_t repl_cr = vdupq_n_u8 ('\r'); + const uint8x16_t repl_bs = vdupq_n_u8 ('\\'); + const uint8x16_t repl_qm = vdupq_n_u8 ('?'); + const uint8x16_t xmask = (uint8x16_t) vdupq_n_u64 (0x8040201008040201ULL); + + unsigned int misalign, found, mask; + const uint8_t *p; + uint8x16_t data; + + /* Align the source pointer. */ + misalign = (uintptr_t)s & 15; + p = (const uint8_t *)((uintptr_t)s & -16); + data = vld1q_u8 (p); + + /* Create a mask for the bytes that are valid within the first + 16-byte block. The Idea here is that the AND with the mask + within the loop is "free", since we need some AND or TEST + insn in order to set the flags for the branch anyway. */ + mask = (-1u << misalign) & 0xffff; + + /* Main loop, processing 16 bytes at a time. */ + goto start; + + do + { + uint8x8_t l; + uint16x4_t m; + uint32x2_t n; + uint8x16_t t, u, v, w; + + p += 16; + data = vld1q_u8 (p); + mask = 0xffff; + + start: + t = vceqq_u8 (data, repl_nl); + u = vceqq_u8 (data, repl_cr); + v = vorrq_u8 (t, vceqq_u8 (data, repl_bs)); + w = vorrq_u8 (u, vceqq_u8 (data, repl_qm)); + t = vandq_u8 (vorrq_u8 (v, w), xmask); + l = vpadd_u8 (vget_low_u8 (t), vget_high_u8 (t)); + m = vpaddl_u8 (l); + n = vpaddl_u16 (m); + + found = vget_lane_u32 ((uint32x2_t) vorr_u64 ((uint64x1_t) n, + vshr_n_u64 ((uint64x1_t) n, 24)), 0); + found &= mask; + } + while (!found); + + /* FOUND contains 1 in bits for which we matched a relevant + character. Conversion to the byte index is trivial. */ + found = __builtin_ctz (found); + return (const uchar *)p + found; +} + +#else + +/* We only have one accelerated alternative. Use a direct call so that + we encourage inlining. */ + +#define search_line_fast search_line_acc_char + +#endif + +/* Initialize the lexer if needed. */ + +void +_cpp_init_lexer (void) +{ +#ifdef HAVE_init_vectorized_lexer + init_vectorized_lexer (); +#endif +} + +/* Returns with a logical line that contains no escaped newlines or + trigraphs. This is a time-critical inner loop. */ +void +_cpp_clean_line (cpp_reader *pfile) +{ + cpp_buffer *buffer; + const uchar *s; + uchar c, *d, *p; + + buffer = pfile->buffer; + buffer->cur_note = buffer->notes_used = 0; + buffer->cur = buffer->line_base = buffer->next_line; + buffer->need_line = false; + s = buffer->next_line; + + if (!buffer->from_stage3) + { + const uchar *pbackslash = NULL; + + /* Fast path. This is the common case of an un-escaped line with + no trigraphs. The primary win here is by not writing any + data back to memory until we have to. */ + while (1) + { + /* Perform an optimized search for \n, \r, \\, ?. */ + s = search_line_fast (s, buffer->rlimit); + + c = *s; + if (c == '\\') + { + /* Record the location of the backslash and continue. */ + pbackslash = s++; + } + else if (__builtin_expect (c == '?', 0)) + { + if (__builtin_expect (s[1] == '?', false) + && _cpp_trigraph_map[s[2]]) + { + /* Have a trigraph. We may or may not have to convert + it. Add a line note regardless, for -Wtrigraphs. */ + add_line_note (buffer, s, s[2]); + if (CPP_OPTION (pfile, trigraphs)) + { + /* We do, and that means we have to switch to the + slow path. */ + d = (uchar *) s; + *d = _cpp_trigraph_map[s[2]]; + s += 2; + goto slow_path; + } + } + /* Not a trigraph. Continue on fast-path. */ + s++; + } + else + break; + } + + /* This must be \r or \n. We're either done, or we'll be forced + to write back to the buffer and continue on the slow path. */ + d = (uchar *) s; + + if (__builtin_expect (s == buffer->rlimit, false)) + goto done; + + /* DOS line ending? */ + if (__builtin_expect (c == '\r', false) && s[1] == '\n') + { + s++; + if (s == buffer->rlimit) + goto done; + } + + if (__builtin_expect (pbackslash == NULL, true)) + goto done; + + /* Check for escaped newline. */ + p = d; + while (is_nvspace (p[-1])) + p--; + if (p - 1 != pbackslash) + goto done; + + /* Have an escaped newline; process it and proceed to + the slow path. */ + add_line_note (buffer, p - 1, p != d ? ' ' : '\\'); + d = p - 2; + buffer->next_line = p - 1; + + slow_path: + while (1) + { + c = *++s; + *++d = c; + + if (c == '\n' || c == '\r') + { + /* Handle DOS line endings. */ + if (c == '\r' && s != buffer->rlimit && s[1] == '\n') + s++; + if (s == buffer->rlimit) + break; + + /* Escaped? */ + p = d; + while (p != buffer->next_line && is_nvspace (p[-1])) + p--; + if (p == buffer->next_line || p[-1] != '\\') + break; + + add_line_note (buffer, p - 1, p != d ? ' ': '\\'); + d = p - 2; + buffer->next_line = p - 1; + } + else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]]) + { + /* Add a note regardless, for the benefit of -Wtrigraphs. */ + add_line_note (buffer, d, s[2]); + if (CPP_OPTION (pfile, trigraphs)) + { + *d = _cpp_trigraph_map[s[2]]; + s += 2; + } + } + } + } + else + { + while (*s != '\n' && *s != '\r') + s++; + d = (uchar *) s; + + /* Handle DOS line endings. */ + if (*s == '\r' && s + 1 != buffer->rlimit && s[1] == '\n') + s++; + } + + done: + *d = '\n'; + /* A sentinel note that should never be processed. */ + add_line_note (buffer, d + 1, '\n'); + buffer->next_line = s + 1; +} + +/* Return true if the trigraph indicated by NOTE should be warned + about in a comment. */ +static bool +warn_in_comment (cpp_reader *pfile, _cpp_line_note *note) +{ + const uchar *p; + + /* Within comments we don't warn about trigraphs, unless the + trigraph forms an escaped newline, as that may change + behavior. */ + if (note->type != '/') + return false; + + /* If -trigraphs, then this was an escaped newline iff the next note + is coincident. */ + if (CPP_OPTION (pfile, trigraphs)) + return note[1].pos == note->pos; + + /* Otherwise, see if this forms an escaped newline. */ + p = note->pos + 3; + while (is_nvspace (*p)) + p++; + + /* There might have been escaped newlines between the trigraph and the + newline we found. Hence the position test. */ + return (*p == '\n' && p < note[1].pos); +} + +/* Process the notes created by add_line_note as far as the current + location. */ +int /*hack*/ +_cpp_process_line_notes (cpp_reader *pfile, int in_comment) +{ + int ret=0; + cpp_buffer *buffer = pfile->buffer; + + for (;;) + { + _cpp_line_note *note = &buffer->notes[buffer->cur_note]; + unsigned int col; + + if (note->pos > buffer->cur) + break; + + buffer->cur_note++; + col = CPP_BUF_COLUMN (buffer, note->pos + 1); + + if (note->type == '\\' || note->type == ' ') + { + if (note->type == ' ' && !in_comment) + cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col, + "backslash and newline separated by space"); + + if (buffer->next_line > buffer->rlimit) + { + cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, col, + "backslash-newline at end of file"); + /* Prevent "no newline at end of file" warning. */ + buffer->next_line = buffer->rlimit; + } + // sdcc hack? + ret = PREV_NL; + + buffer->line_base = note->pos; + CPP_INCREMENT_LINE (pfile, 0); + } + else if (_cpp_trigraph_map[note->type]) + { + if (CPP_OPTION (pfile, warn_trigraphs) + && (!in_comment || warn_in_comment (pfile, note))) + { + if (CPP_OPTION (pfile, trigraphs)) + cpp_warning_with_line (pfile, CPP_W_TRIGRAPHS, + pfile->line_table->highest_line, col, + "trigraph ??%c converted to %c", + note->type, + (int) _cpp_trigraph_map[note->type]); + else + { + cpp_warning_with_line + (pfile, CPP_W_TRIGRAPHS, + pfile->line_table->highest_line, col, + "trigraph ??%c ignored, use -trigraphs to enable", + note->type); + } + } + } + else if (note->type == 0) + /* Already processed in lex_raw_string. */; + else + abort (); + } + return ret; // sdcc hack +} + +namespace bidi { + enum class kind { + NONE, LRE, RLE, LRO, RLO, LRI, RLI, FSI, PDF, PDI, LTR, RTL + }; + + /* All the UTF-8 encodings of bidi characters start with E2. */ + constexpr uchar utf8_start = 0xe2; + + struct context + { + context () {} + context (location_t loc, kind k, bool pdf, bool ucn) + : m_loc (loc), m_kind (k), m_pdf (pdf), m_ucn (ucn) + { + } + + kind get_pop_kind () const + { + return m_pdf ? kind::PDF : kind::PDI; + } + bool ucn_p () const + { + return m_ucn; + } + + location_t m_loc; + kind m_kind; + unsigned m_pdf : 1; + unsigned m_ucn : 1; + }; + + /* A vector holding currently open bidi contexts. We use a char for + each context, its LSB is 1 if it represents a PDF context, 0 if it + represents a PDI context. The next bit is 1 if this context was open + by a bidi character written as a UCN, and 0 when it was UTF-8. */ + semi_embedded_vec <context, 16> vec; + + /* Close the whole comment/identifier/string literal/character constant + context. */ + void on_close () + { + vec.truncate (0); + } + + /* Pop the last element in the vector. */ + void pop () + { + unsigned int len = vec.count (); + gcc_checking_assert (len > 0); + vec.truncate (len - 1); + } + + /* Return the pop kind of the context of the Ith element. */ + kind pop_kind_at (unsigned int i) + { + return vec[i].get_pop_kind (); + } + + /* Return the pop kind of the context that is currently opened. */ + kind current_ctx () + { + unsigned int len = vec.count (); + if (len == 0) + return kind::NONE; + return vec[len - 1].get_pop_kind (); + } + + /* Return true if the current context comes from a UCN origin, that is, + the bidi char which started this bidi context was written as a UCN. */ + bool current_ctx_ucn_p () + { + unsigned int len = vec.count (); + gcc_checking_assert (len > 0); + return vec[len - 1].m_ucn; + } + + location_t current_ctx_loc () + { + unsigned int len = vec.count (); + gcc_checking_assert (len > 0); + return vec[len - 1].m_loc; + } + + /* We've read a bidi char, update the current vector as necessary. + LOC is only valid when K is not kind::NONE. */ + void on_char (kind k, bool ucn_p, location_t loc) + { + switch (k) + { + case kind::LRE: + case kind::RLE: + case kind::LRO: + case kind::RLO: + vec.push (context (loc, k, true, ucn_p)); + break; + case kind::LRI: + case kind::RLI: + case kind::FSI: + vec.push (context (loc, k, false, ucn_p)); + break; + /* PDF terminates the scope of the last LRE, RLE, LRO, or RLO + whose scope has not yet been terminated. */ + case kind::PDF: + if (current_ctx () == kind::PDF) + pop (); + break; + /* PDI terminates the scope of the last LRI, RLI, or FSI whose + scope has not yet been terminated, as well as the scopes of + any subsequent LREs, RLEs, LROs, or RLOs whose scopes have not + yet been terminated. */ + case kind::PDI: + for (int i = vec.count () - 1; i >= 0; --i) + if (pop_kind_at (i) == kind::PDI) + { + vec.truncate (i); + break; + } + break; + case kind::LTR: + case kind::RTL: + /* These aren't popped by a PDF/PDI. */ + break; + ATTR_LIKELY case kind::NONE: + break; + default: + abort (); + } + } + + /* Return a descriptive string for K. */ + const char *to_str (kind k) + { + switch (k) + { + case kind::LRE: + return "U+202A (LEFT-TO-RIGHT EMBEDDING)"; + case kind::RLE: + return "U+202B (RIGHT-TO-LEFT EMBEDDING)"; + case kind::LRO: + return "U+202D (LEFT-TO-RIGHT OVERRIDE)"; + case kind::RLO: + return "U+202E (RIGHT-TO-LEFT OVERRIDE)"; + case kind::LRI: + return "U+2066 (LEFT-TO-RIGHT ISOLATE)"; + case kind::RLI: + return "U+2067 (RIGHT-TO-LEFT ISOLATE)"; + case kind::FSI: + return "U+2068 (FIRST STRONG ISOLATE)"; + case kind::PDF: + return "U+202C (POP DIRECTIONAL FORMATTING)"; + case kind::PDI: + return "U+2069 (POP DIRECTIONAL ISOLATE)"; + case kind::LTR: + return "U+200E (LEFT-TO-RIGHT MARK)"; + case kind::RTL: + return "U+200F (RIGHT-TO-LEFT MARK)"; + default: + abort (); + } + } +} + +/* Get location_t for the range of bytes [START, START + NUM_BYTES) + within the current line in FILE, with the caret at START. */ + +static location_t +get_location_for_byte_range_in_cur_line (cpp_reader *pfile, + const unsigned char *const start, + size_t num_bytes) +{ + gcc_checking_assert (num_bytes > 0); + + /* CPP_BUF_COLUMN and linemap_position_for_column both refer + to offsets in bytes, but CPP_BUF_COLUMN is 0-based, + whereas linemap_position_for_column is 1-based. */ + + /* Get 0-based offsets within the line. */ + size_t start_offset = CPP_BUF_COLUMN (pfile->buffer, start); + size_t end_offset = start_offset + num_bytes - 1; + + /* Now convert to location_t, where "columns" are 1-based byte offsets. */ + location_t start_loc = linemap_position_for_column (pfile->line_table, + start_offset + 1); + location_t end_loc = linemap_position_for_column (pfile->line_table, + end_offset + 1); + + if (start_loc == end_loc) + return start_loc; + + source_range src_range; + src_range.m_start = start_loc; + src_range.m_finish = end_loc; + location_t combined_loc = COMBINE_LOCATION_DATA (pfile->line_table, + start_loc, + src_range, + NULL); + return combined_loc; +} + +/* Parse a sequence of 3 bytes starting with P and return its bidi code. */ + +static bidi::kind +get_bidi_utf8_1 (const unsigned char *const p) +{ + gcc_checking_assert (p[0] == bidi::utf8_start); + + if (p[1] == 0x80) + switch (p[2]) + { + case 0xaa: + return bidi::kind::LRE; + case 0xab: + return bidi::kind::RLE; + case 0xac: + return bidi::kind::PDF; + case 0xad: + return bidi::kind::LRO; + case 0xae: + return bidi::kind::RLO; + case 0x8e: + return bidi::kind::LTR; + case 0x8f: + return bidi::kind::RTL; + default: + break; + } + else if (p[1] == 0x81) + switch (p[2]) + { + case 0xa6: + return bidi::kind::LRI; + case 0xa7: + return bidi::kind::RLI; + case 0xa8: + return bidi::kind::FSI; + case 0xa9: + return bidi::kind::PDI; + default: + break; + } + + return bidi::kind::NONE; +} + +/* Parse a sequence of 3 bytes starting with P and return its bidi code. + If the kind is not NONE, write the location to *OUT.*/ + +static bidi::kind +get_bidi_utf8 (cpp_reader *pfile, const unsigned char *const p, location_t *out) +{ + bidi::kind result = get_bidi_utf8_1 (p); + if (result != bidi::kind::NONE) + { + /* We have a sequence of 3 bytes starting at P. */ + *out = get_location_for_byte_range_in_cur_line (pfile, p, 3); + } + return result; +} + +/* Parse a UCN where P points just past \u or \U and return its bidi code. */ + +static bidi::kind +get_bidi_ucn_1 (const unsigned char *p, bool is_U) +{ + /* 6.4.3 Universal Character Names + \u hex-quad + \U hex-quad hex-quad + where \unnnn means \U0000nnnn. */ + + if (is_U) + { + if (p[0] != '0' || p[1] != '0' || p[2] != '0' || p[3] != '0') + return bidi::kind::NONE; + /* Skip 4B so we can treat \u and \U the same below. */ + p += 4; + } + + /* All code points we are looking for start with 20xx. */ + if (p[0] != '2' || p[1] != '0') + return bidi::kind::NONE; + else if (p[2] == '2') + switch (p[3]) + { + case 'a': + case 'A': + return bidi::kind::LRE; + case 'b': + case 'B': + return bidi::kind::RLE; + case 'c': + case 'C': + return bidi::kind::PDF; + case 'd': + case 'D': + return bidi::kind::LRO; + case 'e': + case 'E': + return bidi::kind::RLO; + default: + break; + } + else if (p[2] == '6') + switch (p[3]) + { + case '6': + return bidi::kind::LRI; + case '7': + return bidi::kind::RLI; + case '8': + return bidi::kind::FSI; + case '9': + return bidi::kind::PDI; + default: + break; + } + else if (p[2] == '0') + switch (p[3]) + { + case 'e': + case 'E': + return bidi::kind::LTR; + case 'f': + case 'F': + return bidi::kind::RTL; + default: + break; + } + + return bidi::kind::NONE; +} + +/* Parse a UCN where P points just past \u or \U and return its bidi code. + If the kind is not NONE, write the location to *OUT.*/ + +static bidi::kind +get_bidi_ucn (cpp_reader *pfile, const unsigned char *p, bool is_U, + location_t *out) +{ + bidi::kind result = get_bidi_ucn_1 (p, is_U); + if (result != bidi::kind::NONE) + { + const unsigned char *start = p - 2; + size_t num_bytes = 2 + (is_U ? 8 : 4); + *out = get_location_for_byte_range_in_cur_line (pfile, start, num_bytes); + } + return result; +} + +/* Subclass of rich_location for reporting on unpaired UTF-8 + bidirectional control character(s). + Escape the source lines on output, and show all unclosed + bidi context, labelling everything. */ + +class unpaired_bidi_rich_location : public rich_location +{ + public: + class custom_range_label : public range_label + { + public: + label_text get_text (unsigned range_idx) const FINAL OVERRIDE + { + /* range 0 is the primary location; each subsequent range i + 1 + is for bidi::vec[i]. */ + if (range_idx > 0) + { + const bidi::context &ctxt (bidi::vec[range_idx - 1]); + return label_text::borrow (bidi::to_str (ctxt.m_kind)); + } + else + return label_text::borrow (_("end of bidirectional context")); + } + }; + + unpaired_bidi_rich_location (cpp_reader *pfile, location_t loc) + : rich_location (pfile->line_table, loc, &m_custom_label) + { + set_escape_on_output (true); + for (unsigned i = 0; i < bidi::vec.count (); i++) + add_range (bidi::vec[i].m_loc, + SHOW_RANGE_WITHOUT_CARET, + &m_custom_label); + } + + private: + custom_range_label m_custom_label; +}; + +/* We're closing a bidi context, that is, we've encountered a newline, + are closing a C-style comment, or are at the end of a string literal, + character constant, or identifier. Warn if this context was not + properly terminated by a PDI or PDF. P points to the last character + in this context. */ + +static void +maybe_warn_bidi_on_close (cpp_reader *pfile, const uchar *p) +{ + const auto warn_bidi = CPP_OPTION (pfile, cpp_warn_bidirectional); + if (bidi::vec.count () > 0 + && (warn_bidi & bidirectional_unpaired + && (!bidi::current_ctx_ucn_p () + || (warn_bidi & bidirectional_ucn)))) + { + const location_t loc + = linemap_position_for_column (pfile->line_table, + CPP_BUF_COLUMN (pfile->buffer, p)); + unpaired_bidi_rich_location rich_loc (pfile, loc); + /* cpp_callbacks doesn't yet have a way to handle singular vs plural + forms of a diagnostic, so fake it for now. */ + if (bidi::vec.count () > 1) + cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc, + "unpaired UTF-8 bidirectional control characters " + "detected"); + else + cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc, + "unpaired UTF-8 bidirectional control character " + "detected"); + } + /* We're done with this context. */ + bidi::on_close (); +} + +/* We're at the beginning or in the middle of an identifier/comment/string + literal/character constant. Warn if we've encountered a bidi character. + KIND says which bidi control character it was; UCN_P is true iff this bidi + control character was written as a UCN. LOC is the location of the + character, but is only valid if KIND != bidi::kind::NONE. */ + +static void +maybe_warn_bidi_on_char (cpp_reader *pfile, bidi::kind kind, + bool ucn_p, location_t loc) +{ + if (__builtin_expect (kind == bidi::kind::NONE, 1)) + return; + + const auto warn_bidi = CPP_OPTION (pfile, cpp_warn_bidirectional); + + if (warn_bidi & (bidirectional_unpaired|bidirectional_any)) + { + rich_location rich_loc (pfile->line_table, loc); + rich_loc.set_escape_on_output (true); + + /* It seems excessive to warn about a PDI/PDF that is closing + an opened context because we've already warned about the + opening character. Except warn when we have a UCN x UTF-8 + mismatch, if UCN checking is enabled. */ + if (kind == bidi::current_ctx ()) + { + if (warn_bidi == (bidirectional_unpaired|bidirectional_ucn) + && bidi::current_ctx_ucn_p () != ucn_p) + { + rich_loc.add_range (bidi::current_ctx_loc ()); + cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc, + "UTF-8 vs UCN mismatch when closing " + "a context by \"%s\"", bidi::to_str (kind)); + } + } + else if (warn_bidi & bidirectional_any + && (!ucn_p || (warn_bidi & bidirectional_ucn))) + { + if (kind == bidi::kind::PDF || kind == bidi::kind::PDI) + cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc, + "\"%s\" is closing an unopened context", + bidi::to_str (kind)); + else + cpp_warning_at (pfile, CPP_W_BIDIRECTIONAL, &rich_loc, + "found problematic Unicode character \"%s\"", + bidi::to_str (kind)); + } + } + /* We're done with this context. */ + bidi::on_char (kind, ucn_p, loc); +} + +/* SDCC __asm specific */ +/* Skip an __asm ... __endasm block. We find the end of the comment by + seeing __endasm. Returns non-zero if _asm terminated by EOF, zero + otherwise. */ +static int +_sdcpp_skip_asm_block (cpp_reader *pfile) +{ untested(); +#define ENDASM_STR "endasm" +#define ENDASM_LEN ((sizeof ENDASM_STR) - 1) + + cpp_buffer *buffer = pfile->buffer; + uchar c = EOF; + int prev_space = false; + + while (buffer->cur != buffer->rlimit) + { + prev_space = is_space(c); + c = *buffer->cur++; + + if (prev_space && c == '_' && *buffer->cur == '_') + { + /* check if it is __endasm */ + ++buffer->cur; + if (buffer->cur + ENDASM_LEN <= buffer->rlimit && + strncmp((const char *)buffer->cur, ENDASM_STR, ENDASM_LEN) == 0) + { + buffer->cur += ENDASM_LEN; + break; + } + } + else if (c == '\n') + { + unsigned int cols; + --buffer->cur; + _cpp_process_line_notes (pfile, true); + if (buffer->next_line >= buffer->rlimit) + return true; + _cpp_clean_line (pfile); + + cols = buffer->next_line - buffer->line_base; + CPP_INCREMENT_LINE (pfile, cols); + } + } + + _cpp_process_line_notes (pfile, true); + return false; +} + +/* Skip a C-style block comment. We find the end of the comment by + seeing if an asterisk is before every '/' we encounter. Returns + nonzero if comment terminated by EOF, zero otherwise. + + Buffer->cur points to the initial asterisk of the comment. */ +bool +_cpp_skip_block_comment (cpp_reader *pfile) +{ + cpp_buffer *buffer = pfile->buffer; + const uchar *cur = buffer->cur; + uchar c; + const bool warn_bidi_p = pfile->warn_bidi_p (); + + cur++; + if (*cur == '/') + cur++; + + for (;;) + { + /* People like decorating comments with '*', so check for '/' + instead for efficiency. */ + c = *cur++; + + if (c == '/') + { + if (cur[-2] == '*') + { + if (warn_bidi_p) + maybe_warn_bidi_on_close (pfile, cur); + break; + } + + /* Warn about potential nested comments, but not if the '/' + comes immediately before the true comment delimiter. + Don't bother to get it right across escaped newlines. */ + if (CPP_OPTION (pfile, warn_comments) + && cur[0] == '*' && cur[1] != '/') + { + buffer->cur = cur; + cpp_warning_with_line (pfile, CPP_W_COMMENTS, + pfile->line_table->highest_line, + CPP_BUF_COL (buffer), + "\"/*\" within comment"); + } + } + else if (c == '\n') + { + unsigned int cols; + buffer->cur = cur - 1; + if (warn_bidi_p) + maybe_warn_bidi_on_close (pfile, cur); + _cpp_process_line_notes (pfile, true); + if (buffer->next_line >= buffer->rlimit) + return true; + _cpp_clean_line (pfile); + + cols = buffer->next_line - buffer->line_base; + CPP_INCREMENT_LINE (pfile, cols); + + cur = buffer->cur; + } + /* If this is a beginning of a UTF-8 encoding, it might be + a bidirectional control character. */ + else if (__builtin_expect (c == bidi::utf8_start, 0) && warn_bidi_p) + { + location_t loc; + bidi::kind kind = get_bidi_utf8 (pfile, cur - 1, &loc); + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc); + } + } + + buffer->cur = cur; + _cpp_process_line_notes (pfile, true); + return false; +} + +/* Skip a C++ line comment, leaving buffer->cur pointing to the + terminating newline. Handles escaped newlines. Returns nonzero + if a multiline comment. */ +static int +skip_line_comment (cpp_reader *pfile) +{ + cpp_buffer *buffer = pfile->buffer; + location_t orig_line = pfile->line_table->highest_line; + const bool warn_bidi_p = pfile->warn_bidi_p (); + + if (!warn_bidi_p) + while (*buffer->cur != '\n') + buffer->cur++; + else + { + while (*buffer->cur != '\n' + && *buffer->cur != bidi::utf8_start) + buffer->cur++; + if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0)) + { + while (*buffer->cur != '\n') + { + if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0)) + { + location_t loc; + bidi::kind kind = get_bidi_utf8 (pfile, buffer->cur, &loc); + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc); + } + buffer->cur++; + } + maybe_warn_bidi_on_close (pfile, buffer->cur); + } + } + + _cpp_process_line_notes (pfile, true); + return orig_line != pfile->line_table->highest_line; +} + +/* Skips whitespace, saving the next non-whitespace character. */ +static void +skip_whitespace (cpp_reader *pfile, cppchar_t c) +{ + cpp_buffer *buffer = pfile->buffer; + bool saw_NUL = false; + + do + { + /* Horizontal space always OK. */ + if (c == ' ' || c == '\t') + ; + /* Just \f \v or \0 left. */ + else if (c == '\0') + saw_NUL = true; + else if (pfile->state.in_directive && CPP_PEDANTIC (pfile)) + cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line_table->highest_line, + CPP_BUF_COL (buffer), + "%s in preprocessing directive", + c == '\f' ? "form feed" : "vertical tab"); + + c = *buffer->cur++; + } + /* We only want non-vertical space, i.e. ' ' \t \f \v \0. */ + while (is_nvspace (c)); + + if (saw_NUL) + { + encoding_rich_location rich_loc (pfile); + cpp_error_at (pfile, CPP_DL_WARNING, &rich_loc, + "null character(s) ignored"); + } + + buffer->cur--; +} + +/* See if the characters of a number token are valid in a name (no + '.', '+' or '-'). */ +static int +name_p (cpp_reader *pfile, const cpp_string *string) +{ + unsigned int i; + + for (i = 0; i < string->len; i++) + if (!is_idchar (string->text[i])) + return 0; + + return 1; +} + +/* After parsing an identifier or other sequence, produce a warning about + sequences not in NFC/NFKC. */ +static void +warn_about_normalization (cpp_reader *pfile, + const cpp_token *token, + const struct normalize_state *s) +{ + if (CPP_OPTION (pfile, warn_normalize) < NORMALIZE_STATE_RESULT (s) + && !pfile->state.skipping) + { + location_t loc = token->src_loc; + + /* If possible, create a location range for the token. */ + if (loc >= RESERVED_LOCATION_COUNT + && token->type != CPP_EOF + /* There must be no line notes to process. */ + && (!(pfile->buffer->cur + >= pfile->buffer->notes[pfile->buffer->cur_note].pos + && !pfile->overlaid_buffer))) + { + source_range tok_range; + tok_range.m_start = loc; + tok_range.m_finish + = linemap_position_for_column (pfile->line_table, + CPP_BUF_COLUMN (pfile->buffer, + pfile->buffer->cur)); + loc = COMBINE_LOCATION_DATA (pfile->line_table, + loc, tok_range, NULL); + } + + encoding_rich_location rich_loc (pfile, loc); + + /* Make sure that the token is printed using UCNs, even + if we'd otherwise happily print UTF-8. */ + unsigned char *buf = XNEWVEC (unsigned char, cpp_token_len (token)); + size_t sz; + + sz = cpp_spell_token (pfile, token, buf, false) - buf; + if (NORMALIZE_STATE_RESULT (s) == normalized_C) + cpp_warning_at (pfile, CPP_W_NORMALIZE, &rich_loc, + "`%.*s' is not in NFKC", (int) sz, buf); + else if (CPP_OPTION (pfile, cplusplus)) + cpp_pedwarning_at (pfile, CPP_W_NORMALIZE, &rich_loc, + "`%.*s' is not in NFC", (int) sz, buf); + else + cpp_warning_at (pfile, CPP_W_NORMALIZE, &rich_loc, + "`%.*s' is not in NFC", (int) sz, buf); + free (buf); + } +} + +static const cppchar_t utf8_signifier = 0xC0; + +/* Returns TRUE if the sequence starting at buffer->cur is valid in + an identifier. FIRST is TRUE if this starts an identifier. */ + +static bool +forms_identifier_p (cpp_reader *pfile, int first, + struct normalize_state *state) +{ + cpp_buffer *buffer = pfile->buffer; + const bool warn_bidi_p = pfile->warn_bidi_p (); + + if (*buffer->cur == '$') + { + if (!CPP_OPTION (pfile, dollars_in_ident)) + return false; + + buffer->cur++; + if (CPP_OPTION (pfile, warn_dollars) && !pfile->state.skipping) + { + CPP_OPTION (pfile, warn_dollars) = 0; + cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number"); + } + + return true; + } + + /* Is this a syntactically valid UCN or a valid UTF-8 char? */ + if (CPP_OPTION (pfile, extended_identifiers)) + { + cppchar_t s; + if (*buffer->cur >= utf8_signifier) + { + if (__builtin_expect (*buffer->cur == bidi::utf8_start, 0) + && warn_bidi_p) + { + location_t loc; + bidi::kind kind = get_bidi_utf8 (pfile, buffer->cur, &loc); + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc); + } + if (_cpp_valid_utf8 (pfile, &buffer->cur, buffer->rlimit, 1 + !first, + state, &s)) + return true; + } + else if (*buffer->cur == '\\' + && (buffer->cur[1] == 'u' || buffer->cur[1] == 'U')) + { + buffer->cur += 2; + if (warn_bidi_p) + { + location_t loc; + bidi::kind kind = get_bidi_ucn (pfile, + buffer->cur, + buffer->cur[-1] == 'U', + &loc); + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/true, loc); + } + if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first, + state, &s, NULL, NULL)) + return true; + buffer->cur -= 2; + } + } + + return false; +} + +/* Helper function to issue error about improper __VA_OPT__ use. */ +static void +maybe_va_opt_error (cpp_reader *pfile) +{ + if (CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, va_opt)) + { + /* __VA_OPT__ should not be accepted at all, but allow it in + system headers. */ + if (!_cpp_in_system_header (pfile)) + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_OPT__ is not available until C++20"); + } + else if (!pfile->state.va_args_ok) + { + /* __VA_OPT__ should only appear in the replacement list of a + variadic macro. */ + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_OPT__ can only appear in the expansion" + " of a C++20 variadic macro"); + } +} + +/* Helper function to get the cpp_hashnode of the identifier BASE. */ +static cpp_hashnode * +lex_identifier_intern (cpp_reader *pfile, const uchar *base) +{ + cpp_hashnode *result; + const uchar *cur; + unsigned int len; + unsigned int hash = HT_HASHSTEP (0, *base); + + cur = base + 1; + while (ISIDNUM (*cur)) + { + hash = HT_HASHSTEP (hash, *cur); + cur++; + } + len = cur - base; + hash = HT_HASHFINISH (hash, len); + result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, + base, len, hash, HT_ALLOC)); + + /* Rarely, identifiers require diagnostics when lexed. */ + if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC) + && !pfile->state.skipping, 0)) + { + /* It is allowed to poison the same identifier twice. */ + if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) + cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"", + NODE_NAME (result)); + + /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the + replacement list of a variadic macro. */ + if (result == pfile->spec_nodes.n__VA_ARGS__ + && !pfile->state.va_args_ok) + { + if (CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_ARGS__ can only appear in the expansion" + " of a C++11 variadic macro"); + else + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_ARGS__ can only appear in the expansion" + " of a C99 variadic macro"); + } + + if (result == pfile->spec_nodes.n__VA_OPT__) + maybe_va_opt_error (pfile); + + /* For -Wc++-compat, warn about use of C++ named operators. */ + if (result->flags & NODE_WARN_OPERATOR) + cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, + "identifier \"%s\" is a special operator name in C++", + NODE_NAME (result)); + } + + return result; +} + +/* Get the cpp_hashnode of an identifier specified by NAME in + the current cpp_reader object. If none is found, NULL is returned. */ +cpp_hashnode * +_cpp_lex_identifier (cpp_reader *pfile, const char *name) +{ + cpp_hashnode *result; + result = lex_identifier_intern (pfile, (uchar *) name); + return result; +} + +/* Lex an identifier starting at BUFFER->CUR - 1. */ +static cpp_hashnode * +lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn, + struct normalize_state *nst, cpp_hashnode **spelling) +{ + cpp_hashnode *result; + const uchar *cur; + unsigned int len; + unsigned int hash = HT_HASHSTEP (0, *base); + const bool warn_bidi_p = pfile->warn_bidi_p (); + + cur = pfile->buffer->cur; + if (! starts_ucn) + { + while (ISIDNUM (*cur)) + { + hash = HT_HASHSTEP (hash, *cur); + cur++; + } + NORMALIZE_STATE_UPDATE_IDNUM (nst, *(cur - 1)); + } + pfile->buffer->cur = cur; + if (starts_ucn || forms_identifier_p (pfile, false, nst)) + { + /* Slower version for identifiers containing UCNs + or extended chars (including $). */ + do { + while (ISIDNUM (*pfile->buffer->cur)) + { + NORMALIZE_STATE_UPDATE_IDNUM (nst, *pfile->buffer->cur); + pfile->buffer->cur++; + } + } while (forms_identifier_p (pfile, false, nst)); + if (warn_bidi_p) + maybe_warn_bidi_on_close (pfile, pfile->buffer->cur); + result = _cpp_interpret_identifier (pfile, base, + pfile->buffer->cur - base); + *spelling = cpp_lookup (pfile, base, pfile->buffer->cur - base); + } + else + { + len = cur - base; + hash = HT_HASHFINISH (hash, len); + + result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, + base, len, hash, HT_ALLOC)); + *spelling = result; + } + + /* Rarely, identifiers require diagnostics when lexed. */ + if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC) + && !pfile->state.skipping, 0)) + { + /* It is allowed to poison the same identifier twice. */ + if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok) + cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"", + NODE_NAME (result)); + + /* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the + replacement list of a variadic macro. */ + if (result == pfile->spec_nodes.n__VA_ARGS__ + && !pfile->state.va_args_ok) + { + if (CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_ARGS__ can only appear in the expansion" + " of a C++11 variadic macro"); + else + cpp_error (pfile, CPP_DL_PEDWARN, + "__VA_ARGS__ can only appear in the expansion" + " of a C99 variadic macro"); + } + + /* __VA_OPT__ should only appear in the replacement list of a + variadic macro. */ + if (result == pfile->spec_nodes.n__VA_OPT__) + maybe_va_opt_error (pfile); + + /* For -Wc++-compat, warn about use of C++ named operators. */ + if (result->flags & NODE_WARN_OPERATOR) + cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES, + "identifier \"%s\" is a special operator name in C++", + NODE_NAME (result)); + } + + return result; +} + +/* Lex a number to NUMBER starting at BUFFER->CUR - 1. */ +static void +lex_number (cpp_reader *pfile, cpp_string *number, + struct normalize_state *nst) +{ + const uchar *cur; + const uchar *base; + uchar *dest; + + base = pfile->buffer->cur - 1; + do + { + const uchar *adj_digit_sep = NULL; + cur = pfile->buffer->cur; + + /* N.B. ISIDNUM does not include $. */ + while (ISIDNUM (*cur) + || (*cur == '.' && !DIGIT_SEP (cur[-1])) + || DIGIT_SEP (*cur) + || (VALID_SIGN (*cur, cur[-1]) && !DIGIT_SEP (cur[-2]))) + { + NORMALIZE_STATE_UPDATE_IDNUM (nst, *cur); + /* Adjacent digit separators do not form part of the pp-number syntax. + However, they can safely be diagnosed here as an error, since '' is + not a valid preprocessing token. */ + if (DIGIT_SEP (*cur) && DIGIT_SEP (cur[-1]) && !adj_digit_sep) + adj_digit_sep = cur; + cur++; + } + /* A number can't end with a digit separator. */ + while (cur > pfile->buffer->cur && DIGIT_SEP (cur[-1])) + --cur; + if (adj_digit_sep && adj_digit_sep < cur) + cpp_error (pfile, CPP_DL_ERROR, "adjacent digit separators"); + + pfile->buffer->cur = cur; + } + while (forms_identifier_p (pfile, false, nst)); + + number->len = cur - base; + dest = _cpp_unaligned_alloc (pfile, number->len + 1); + memcpy (dest, base, number->len); + dest[number->len] = '\0'; + number->text = dest; +} + +/* Create a token of type TYPE with a literal spelling. */ +static void +create_literal (cpp_reader *pfile, cpp_token *token, const uchar *base, + unsigned int len, enum cpp_ttype type) +{ + token->type = type; + token->val.str.len = len; + token->val.str.text = cpp_alloc_token_string (pfile, base, len); +} + +const uchar * +cpp_alloc_token_string (cpp_reader *pfile, + const unsigned char *ptr, unsigned len) +{ + uchar *dest = _cpp_unaligned_alloc (pfile, len + 1); + + dest[len] = 0; + memcpy (dest, ptr, len); + return dest; +} + +/* A pair of raw buffer pointers. The currently open one is [1], the + first one is [0]. Used for string literal lexing. */ +struct lit_accum { + _cpp_buff *first; + _cpp_buff *last; + const uchar *rpos; + size_t accum; + + lit_accum () + : first (NULL), last (NULL), rpos (0), accum (0) + { + } + + void append (cpp_reader *, const uchar *, size_t); + + void read_begin (cpp_reader *); + bool reading_p () const + { + return rpos != NULL; + } + char read_char () + { + char c = *rpos++; + if (rpos == BUFF_FRONT (last)) + rpos = NULL; + return c; + } +}; + +/* Subroutine of lex_raw_string: Append LEN chars from BASE to the buffer + sequence from *FIRST_BUFF_P to LAST_BUFF_P. */ + +void +lit_accum::append (cpp_reader *pfile, const uchar *base, size_t len) +{ + if (!last) + /* Starting. */ + first = last = _cpp_get_buff (pfile, len); + else if (len > BUFF_ROOM (last)) + { + /* There is insufficient room in the buffer. Copy what we can, + and then either extend or create a new one. */ + size_t room = BUFF_ROOM (last); + memcpy (BUFF_FRONT (last), base, room); + BUFF_FRONT (last) += room; + base += room; + len -= room; + accum += room; + + gcc_checking_assert (!rpos); + + last = _cpp_append_extend_buff (pfile, last, len); + } + + memcpy (BUFF_FRONT (last), base, len); + BUFF_FRONT (last) += len; + accum += len; +} + +void +lit_accum::read_begin (cpp_reader *pfile) +{ + /* We never accumulate more than 4 chars to read. */ + if (BUFF_ROOM (last) < 4) + + last = _cpp_append_extend_buff (pfile, last, 4); + rpos = BUFF_FRONT (last); +} + +/* Returns true if a macro has been defined. + This might not work if compile with -save-temps, + or preprocess separately from compilation. */ + +static bool +is_macro(cpp_reader *pfile, const uchar *base) +{ + const uchar *cur = base; + if (! ISIDST (*cur)) + return false; + unsigned int hash = HT_HASHSTEP (0, *cur); + ++cur; + while (ISIDNUM (*cur)) + { + hash = HT_HASHSTEP (hash, *cur); + ++cur; + } + hash = HT_HASHFINISH (hash, cur - base); + + cpp_hashnode *result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table, + base, cur - base, hash, HT_NO_INSERT)); + + return result && cpp_macro_p (result); +} + +/* Returns true if a literal suffix does not have the expected form + and is defined as a macro. */ + +static bool +is_macro_not_literal_suffix(cpp_reader *pfile, const uchar *base) +{ + /* User-defined literals outside of namespace std must start with a single + underscore, so assume anything of that form really is a UDL suffix. + We don't need to worry about UDLs defined inside namespace std because + their names are reserved, so cannot be used as macro names in valid + programs. */ + if (base[0] == '_' && base[1] != '_') + return false; + return is_macro (pfile, base); +} + +/* Lexes a raw string. The stored string contains the spelling, + including double quotes, delimiter string, '(' and ')', any leading + 'L', 'u', 'U' or 'u8' and 'R' modifier. The created token contains + the type of the literal, or CPP_OTHER if it was not properly + terminated. + + BASE is the start of the token. Updates pfile->buffer->cur to just + after the lexed string. + + The spelling is NUL-terminated, but it is not guaranteed that this + is the first NUL since embedded NULs are preserved. */ + +static void +lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base) +{ + const uchar *pos = base; + const bool warn_bidi_p = pfile->warn_bidi_p (); + + /* 'tis a pity this information isn't passed down from the lexer's + initial categorization of the token. */ + enum cpp_ttype type = CPP_STRING; + + if (*pos == 'L') + { + type = CPP_WSTRING; + pos++; + } + else if (*pos == 'U') + { + type = CPP_STRING32; + pos++; + } + else if (*pos == 'u') + { + if (pos[1] == '8') + { + type = CPP_UTF8STRING; + pos++; + } + else + type = CPP_STRING16; + pos++; + } + + gcc_checking_assert (pos[0] == 'R' && pos[1] == '"'); + pos += 2; + + _cpp_line_note *note = &pfile->buffer->notes[pfile->buffer->cur_note]; + + /* Skip notes before the ". */ + while (note->pos < pos) + ++note; + + lit_accum accum; + + uchar prefix[17]; + unsigned prefix_len = 0; + enum Phase + { + PHASE_PREFIX = -2, + PHASE_NONE = -1, + PHASE_SUFFIX = 0 + } phase = PHASE_PREFIX; + + for (;;) + { + gcc_checking_assert (note->pos >= pos); + + /* Undo any escaped newlines and trigraphs. */ + if (!accum.reading_p () && note->pos == pos) + switch (note->type) + { + case '\\': + case ' ': + /* Restore backslash followed by newline. */ + accum.append (pfile, base, pos - base); + base = pos; + accum.read_begin (pfile); + accum.append (pfile, UC"\\", 1); + + after_backslash: + if (note->type == ' ') + /* GNU backslash whitespace newline extension. FIXME + could be any sequence of non-vertical space. When we + can properly restore any such sequence, we should + mark this note as handled so _cpp_process_line_notes + doesn't warn. */ + accum.append (pfile, UC" ", 1); + + accum.append (pfile, UC"\n", 1); + note++; + break; + + case '\n': + /* This can happen for ??/<NEWLINE> when trigraphs are not + being interpretted. */ + gcc_checking_assert (!CPP_OPTION (pfile, trigraphs)); + note->type = 0; + note++; + break; + + default: + gcc_checking_assert (_cpp_trigraph_map[note->type]); + + /* Don't warn about this trigraph in + _cpp_process_line_notes, since trigraphs show up as + trigraphs in raw strings. */ + uchar type = note->type; + note->type = 0; + + if (CPP_OPTION (pfile, trigraphs)) + { + accum.append (pfile, base, pos - base); + base = pos; + accum.read_begin (pfile); + accum.append (pfile, UC"??", 2); + accum.append (pfile, &type, 1); + + /* ??/ followed by newline gets two line notes, one for + the trigraph and one for the backslash/newline. */ + if (type == '/' && note[1].pos == pos) + { + note++; + gcc_assert (note->type == '\\' || note->type == ' '); + goto after_backslash; + } + /* Skip the replacement character. */ + base = ++pos; + } + + note++; + break; + } + + /* Now get a char to process. Either from an expanded note, or + from the line buffer. */ + bool read_note = accum.reading_p (); + char c = read_note ? accum.read_char () : *pos++; + + if (phase == PHASE_PREFIX) + { + if (c == '(') + { + /* Done. */ + phase = PHASE_NONE; + prefix[prefix_len++] = '"'; + } + else if (prefix_len < 16 + /* Prefix chars are any of the basic character set, + [lex.charset] except for ' + ()\\\t\v\f\n'. Optimized for a contiguous + alphabet. */ + /* Unlike a switch, this collapses down to one or + two shift and bitmask operations on an ASCII + system, with an outlier or two. */ + && (('Z' - 'A' == 25 + ? ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + : ISIDST (c)) + || (c >= '0' && c <= '9') + || c == '_' || c == '{' || c == '}' + || c == '[' || c == ']' || c == '#' + || c == '<' || c == '>' || c == '%' + || c == ':' || c == ';' || c == '.' || c == '?' + || c == '*' || c == '+' || c == '-' || c == '/' + || c == '^' || c == '&' || c == '|' || c == '~' + || c == '!' || c == '=' || c == ',' + || c == '"' || c == '\'')) + prefix[prefix_len++] = c; + else + { + /* Something is wrong. */ + int col = CPP_BUF_COLUMN (pfile->buffer, pos) + read_note; + if (prefix_len == 16) + cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, + col, "raw string delimiter longer " + "than 16 characters"); + else if (c == '\n') + cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, + col, "invalid new-line in raw " + "string delimiter"); + else + cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, + col, "invalid character '%c' in " + "raw string delimiter", c); + type = CPP_OTHER; + phase = PHASE_NONE; + /* Continue until we get a close quote, that's probably + the best failure mode. */ + prefix_len = 0; + } + if (c != '\n') + continue; + } + + if (phase != PHASE_NONE) + { + if (prefix[phase] != c) + phase = PHASE_NONE; + else if (unsigned (phase + 1) == prefix_len) + break; + else + { + phase = Phase (phase + 1); + continue; + } + } + + if (!prefix_len && c == '"') + /* Failure mode lexing. */ + goto out; + else if (prefix_len && c == ')') + phase = PHASE_SUFFIX; + else if (!read_note && c == '\n') + { + pos--; + pfile->buffer->cur = pos; + if (pfile->state.in_directive + || (pfile->state.parsing_args + && pfile->buffer->next_line >= pfile->buffer->rlimit)) + { + cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, 0, + "unterminated raw string"); + type = CPP_OTHER; + goto out; + } + + accum.append (pfile, base, pos - base + 1); + _cpp_process_line_notes (pfile, false); + + if (pfile->buffer->next_line < pfile->buffer->rlimit) + CPP_INCREMENT_LINE (pfile, 0); + pfile->buffer->need_line = true; + + if (!_cpp_get_fresh_line (pfile)) + { + /* We ran out of file and failed to get a line. */ + location_t src_loc = token->src_loc; + token->type = CPP_EOF; + /* Tell the compiler the line number of the EOF token. */ + token->src_loc = pfile->line_table->highest_line; + token->flags = BOL; + if (accum.first) + _cpp_release_buff (pfile, accum.first); + cpp_error_with_line (pfile, CPP_DL_ERROR, src_loc, 0, + "unterminated raw string"); + /* Now pop the buffer that _cpp_get_fresh_line did not. */ + _cpp_pop_buffer (pfile); + return; + } + + pos = base = pfile->buffer->cur; + note = &pfile->buffer->notes[pfile->buffer->cur_note]; + } + else if (__builtin_expect ((unsigned char) c == bidi::utf8_start, 0) + && warn_bidi_p) + { + location_t loc; + bidi::kind kind = get_bidi_utf8 (pfile, pos - 1, &loc); + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc); + } + } + + if (warn_bidi_p) + maybe_warn_bidi_on_close (pfile, pos); + + if (CPP_OPTION (pfile, user_literals)) + { + /* If a string format macro, say from inttypes.h, is placed touching + a string literal it could be parsed as a C++11 user-defined string + literal thus breaking the program. */ + if (is_macro_not_literal_suffix (pfile, pos)) + { + /* Raise a warning, but do not consume subsequent tokens. */ + if (CPP_OPTION (pfile, warn_literal_suffix) && !pfile->state.skipping) + cpp_warning_with_line (pfile, CPP_W_LITERAL_SUFFIX, + token->src_loc, 0, + "invalid suffix on literal; C++11 requires " + "a space between literal and string macro"); + } + /* Grab user defined literal suffix. */ + else if (ISIDST (*pos)) + { + type = cpp_userdef_string_add_type (type); + ++pos; + + while (ISIDNUM (*pos)) + ++pos; + } + } + + out: + pfile->buffer->cur = pos; + if (!accum.accum) + create_literal (pfile, token, base, pos - base, type); + else + { + size_t extra_len = pos - base; + uchar *dest = _cpp_unaligned_alloc (pfile, accum.accum + extra_len + 1); + + token->type = type; + token->val.str.len = accum.accum + extra_len; + token->val.str.text = dest; + for (_cpp_buff *buf = accum.first; buf; buf = buf->next) + { + size_t len = BUFF_FRONT (buf) - buf->base; + memcpy (dest, buf->base, len); + dest += len; + } + _cpp_release_buff (pfile, accum.first); + memcpy (dest, base, extra_len); + dest[extra_len] = '\0'; + } +} + +/* Lexes a string, character constant, or angle-bracketed header file + name. The stored string contains the spelling, including opening + quote and any leading 'L', 'u', 'U' or 'u8' and optional + 'R' modifier. It returns the type of the literal, or CPP_OTHER + if it was not properly terminated, or CPP_LESS for an unterminated + header name which must be relexed as normal tokens. + + The spelling is NUL-terminated, but it is not guaranteed that this + is the first NUL since embedded NULs are preserved. */ +static void +lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base) +{ + bool saw_NUL = false; + const uchar *cur; + cppchar_t terminator; + enum cpp_ttype type; + + cur = base; + terminator = *cur++; + if (terminator == 'L' || terminator == 'U') + terminator = *cur++; + else if (terminator == 'u') + { + terminator = *cur++; + if (terminator == '8') + terminator = *cur++; + } + if (terminator == 'R') + { + lex_raw_string (pfile, token, base); + return; + } + if (terminator == '"') + type = (*base == 'L' ? CPP_WSTRING : + *base == 'U' ? CPP_STRING32 : + *base == 'u' ? (base[1] == '8' ? CPP_UTF8STRING : CPP_STRING16) + : CPP_STRING); + else if (terminator == '\'') + type = (*base == 'L' ? CPP_WCHAR : + *base == 'U' ? CPP_CHAR32 : + *base == 'u' ? (base[1] == '8' ? CPP_UTF8CHAR : CPP_CHAR16) + : CPP_CHAR); + else + terminator = '>', type = CPP_HEADER_NAME; + + const bool warn_bidi_p = pfile->warn_bidi_p (); + for (;;) + { + cppchar_t c = *cur++; + + /* In #include-style directives, terminators are not escapable. */ + if (c == '\\' && !pfile->state.angled_headers && *cur != '\n') + { + if ((cur[0] == 'u' || cur[0] == 'U') && warn_bidi_p) + { + location_t loc; + bidi::kind kind = get_bidi_ucn (pfile, cur + 1, cur[0] == 'U', + &loc); + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/true, loc); + } + cur++; + } + else if (c == terminator) + { + if (warn_bidi_p) + maybe_warn_bidi_on_close (pfile, cur - 1); + break; + } + else if (c == '\n') + { + cur--; + /* Unmatched quotes always yield undefined behavior, but + greedy lexing means that what appears to be an unterminated + header name may actually be a legitimate sequence of tokens. */ + if (terminator == '>') + { + token->type = CPP_LESS; + return; + } + type = CPP_OTHER; + break; + } + else if (c == '\0') + saw_NUL = true; + else if (__builtin_expect (c == bidi::utf8_start, 0) && warn_bidi_p) + { + location_t loc; + bidi::kind kind = get_bidi_utf8 (pfile, cur - 1, &loc); + maybe_warn_bidi_on_char (pfile, kind, /*ucn_p=*/false, loc); + } + } + + if (saw_NUL && !pfile->state.skipping) + cpp_error (pfile, CPP_DL_WARNING, + "null character(s) preserved in literal"); + + if (type == CPP_OTHER && CPP_OPTION (pfile, lang) != CLK_ASM) + cpp_error (pfile, CPP_DL_PEDWARN, "missing terminating %c character", + (int) terminator); + + if (CPP_OPTION (pfile, user_literals)) + { + /* If a string format macro, say from inttypes.h, is placed touching + a string literal it could be parsed as a C++11 user-defined string + literal thus breaking the program. */ + if (is_macro_not_literal_suffix (pfile, cur)) + { + /* Raise a warning, but do not consume subsequent tokens. */ + if (CPP_OPTION (pfile, warn_literal_suffix) && !pfile->state.skipping) + cpp_warning_with_line (pfile, CPP_W_LITERAL_SUFFIX, + token->src_loc, 0, + "invalid suffix on literal; C++11 requires " + "a space between literal and string macro"); + } + /* Grab user defined literal suffix. */ + else if (ISIDST (*cur)) + { + type = cpp_userdef_char_add_type (type); + type = cpp_userdef_string_add_type (type); + ++cur; + + while (ISIDNUM (*cur)) + ++cur; + } + } + else if (CPP_OPTION (pfile, cpp_warn_cxx11_compat) + && is_macro (pfile, cur) + && !pfile->state.skipping) + cpp_warning_with_line (pfile, CPP_W_CXX11_COMPAT, + token->src_loc, 0, "C++11 requires a space " + "between string literal and macro"); + + pfile->buffer->cur = cur; + create_literal (pfile, token, base, cur - base, type); +} + +/* sdcpp specific */ +/* Fixed _WIN32 problem with CR-CR-LF sequences when outputting + comment blocks (when executed with -C option) and + _asm (SDCPP specific) blocks */ + +/* Count and copy characters from src to dest, excluding CRs: + CRs are automatically generated, because the output is + opened in TEXT mode. If dest == NULL, only count chars */ +static unsigned int +copy_text_chars (unsigned char *dest, const unsigned char *src, unsigned int len) +{ + unsigned int n = 0; + const unsigned char *p; + + for (p = src; p != src + len; ++p) + { + assert(*p != '\0'); + + if (*p != '\r') + { + if (dest != NULL) + *dest++ = *p; + ++n; + } + } + + return n; +} + + +/* SDCC _asm specific */ +/* The stored comment includes the comment start and any terminator. */ +static void +_sdcpp_save_asm (cpp_reader *pfile, cpp_token *token, const unsigned char *from, int is_asm) +{ untested(); +#define _ASM_STR "__asm" +#define _ASM_LEN ((sizeof _ASM_STR) - 1) +#define _ASM_STR1 "_asm" +#define _ASM_LEN1 ((sizeof _ASM_STR1) - 1) + + unsigned char *buffer; + unsigned int text_len, len; + unsigned int asm_len = is_asm ? _ASM_LEN : _ASM_LEN1; + const char *asm_str = is_asm ? _ASM_STR : _ASM_STR1; + + { untested(); + len = pfile->buffer->cur - from; + /* + asm_len for the initial '_asm'. */ + text_len = copy_text_chars (NULL, from, len) + asm_len; + buffer = _cpp_unaligned_alloc (pfile, text_len); + } + + + { untested(); + token->type = CPP_ASM; + token->val.str.len = text_len; + token->val.str.text = buffer; + } + + { untested(); + memcpy (buffer, asm_str, asm_len); + copy_text_chars (buffer + asm_len, from, len); + } +} + +/* Return the comment table. The client may not make any assumption + about the ordering of the table. */ +cpp_comment_table * +cpp_get_comments (cpp_reader *pfile) +{ + return &pfile->comments; +} + +/* Append a comment to the end of the comment table. */ +static void +store_comment (cpp_reader *pfile, cpp_token *token) +{ + int len; + + if (pfile->comments.allocated == 0) + { + pfile->comments.allocated = 256; + pfile->comments.entries = (cpp_comment *) xmalloc + (pfile->comments.allocated * sizeof (cpp_comment)); + } + + if (pfile->comments.count == pfile->comments.allocated) + { + pfile->comments.allocated *= 2; + pfile->comments.entries = (cpp_comment *) xrealloc + (pfile->comments.entries, + pfile->comments.allocated * sizeof (cpp_comment)); + } + + len = token->val.str.len; + + /* Copy comment. Note, token may not be NULL terminated. */ + pfile->comments.entries[pfile->comments.count].comment = + (char *) xmalloc (sizeof (char) * (len + 1)); + memcpy (pfile->comments.entries[pfile->comments.count].comment, + token->val.str.text, len); + pfile->comments.entries[pfile->comments.count].comment[len] = '\0'; + + /* Set source location. */ + pfile->comments.entries[pfile->comments.count].sloc = token->src_loc; + + /* Increment the count of entries in the comment table. */ + pfile->comments.count++; +} + +/* The stored comment includes the comment start and any terminator. */ +static void +save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from, + cppchar_t type) +{ + unsigned char *buffer; + unsigned int len, clen, i; + + len = pfile->buffer->cur - from + 1; /* + 1 for the initial '/'. */ + + /* C++ comments probably (not definitely) have moved past a new + line, which we don't want to save in the comment. */ + if (is_vspace (pfile->buffer->cur[-1])) + len--; + + /* If we are currently in a directive or in argument parsing, then + we need to store all C++ comments as C comments internally, and + so we need to allocate a little extra space in that case. + + Note that the only time we encounter a directive here is + when we are saving comments in a "#define". */ + clen = ((pfile->state.in_directive || pfile->state.parsing_args) + && type == '/') ? len + 2 : len; + + buffer = _cpp_unaligned_alloc (pfile, clen); + + token->type = CPP_COMMENT; + token->val.str.len = clen; + token->val.str.text = buffer; + + buffer[0] = '/'; + memcpy (buffer + 1, from, len - 1); + + /* Finish conversion to a C comment, if necessary. */ + if ((pfile->state.in_directive || pfile->state.parsing_args) && type == '/') + { + buffer[1] = '*'; + buffer[clen - 2] = '*'; + buffer[clen - 1] = '/'; + /* As there can be in a C++ comments illegal sequences for C comments + we need to filter them out. */ + for (i = 2; i < (clen - 2); i++) + if (buffer[i] == '/' && (buffer[i - 1] == '*' || buffer[i + 1] == '*')) + buffer[i] = '|'; + } + + /* Finally store this comment for use by clients of libcpp. */ + store_comment (pfile, token); +} + +/* Returns true if comment at COMMENT_START is a recognized FALLTHROUGH + comment. */ + +static bool +fallthrough_comment_p (cpp_reader *pfile, const unsigned char *comment_start) +{ + const unsigned char *from = comment_start + 1; + + switch (CPP_OPTION (pfile, cpp_warn_implicit_fallthrough)) + { + /* For both -Wimplicit-fallthrough=0 and -Wimplicit-fallthrough=5 we + don't recognize any comments. The latter only checks attributes, + the former doesn't warn. */ + case 0: + default: + return false; + /* -Wimplicit-fallthrough=1 considers any comment, no matter what + content it has. */ + case 1: + return true; + case 2: + /* -Wimplicit-fallthrough=2 looks for (case insensitive) + .*falls?[ \t-]*thr(u|ough).* regex. */ + for (; (size_t) (pfile->buffer->cur - from) >= sizeof "fallthru" - 1; + from++) + { + /* Is there anything like strpbrk with upper boundary, or + memchr looking for 2 characters rather than just one? */ + if (from[0] != 'f' && from[0] != 'F') + continue; + if (from[1] != 'a' && from[1] != 'A') + continue; + if (from[2] != 'l' && from[2] != 'L') + continue; + if (from[3] != 'l' && from[3] != 'L') + continue; + from += sizeof "fall" - 1; + if (from[0] == 's' || from[0] == 'S') + from++; + while (*from == ' ' || *from == '\t' || *from == '-') + from++; + if (from[0] != 't' && from[0] != 'T') + continue; + if (from[1] != 'h' && from[1] != 'H') + continue; + if (from[2] != 'r' && from[2] != 'R') + continue; + if (from[3] == 'u' || from[3] == 'U') + return true; + if (from[3] != 'o' && from[3] != 'O') + continue; + if (from[4] != 'u' && from[4] != 'U') + continue; + if (from[5] != 'g' && from[5] != 'G') + continue; + if (from[6] != 'h' && from[6] != 'H') + continue; + return true; + } + return false; + case 3: + case 4: + break; + } + + /* Whole comment contents: + -fallthrough + @fallthrough@ + */ + if (*from == '-' || *from == '@') + { + size_t len = sizeof "fallthrough" - 1; + if ((size_t) (pfile->buffer->cur - from - 1) < len) + return false; + if (memcmp (from + 1, "fallthrough", len)) + return false; + if (*from == '@') + { + if (from[len + 1] != '@') + return false; + len++; + } + from += 1 + len; + } + /* Whole comment contents (regex): + lint -fallthrough[ \t]* + */ + else if (*from == 'l') + { + size_t len = sizeof "int -fallthrough" - 1; + if ((size_t) (pfile->buffer->cur - from - 1) < len) + return false; + if (memcmp (from + 1, "int -fallthrough", len)) + return false; + from += 1 + len; + while (*from == ' ' || *from == '\t') + from++; + } + /* Whole comment contents (regex): + [ \t]*FALLTHR(U|OUGH)[ \t]* + */ + else if (CPP_OPTION (pfile, cpp_warn_implicit_fallthrough) == 4) + { + while (*from == ' ' || *from == '\t') + from++; + if ((size_t) (pfile->buffer->cur - from) < sizeof "FALLTHRU" - 1) + return false; + if (memcmp (from, "FALLTHR", sizeof "FALLTHR" - 1)) + return false; + from += sizeof "FALLTHR" - 1; + if (*from == 'U') + from++; + else if ((size_t) (pfile->buffer->cur - from) < sizeof "OUGH" - 1) + return false; + else if (memcmp (from, "OUGH", sizeof "OUGH" - 1)) + return false; + else + from += sizeof "OUGH" - 1; + while (*from == ' ' || *from == '\t') + from++; + } + /* Whole comment contents (regex): + [ \t.!]*(ELSE,? |INTENTIONAL(LY)? )?FALL(S | |-)?THR(OUGH|U)[ \t.!]*(-[^\n\r]*)? + [ \t.!]*(Else,? |Intentional(ly)? )?Fall((s | |-)[Tt]|t)hr(ough|u)[ \t.!]*(-[^\n\r]*)? + [ \t.!]*([Ee]lse,? |[Ii]ntentional(ly)? )?fall(s | |-)?thr(ough|u)[ \t.!]*(-[^\n\r]*)? + */ + else + { + while (*from == ' ' || *from == '\t' || *from == '.' || *from == '!') + from++; + unsigned char f = *from; + bool all_upper = false; + if (f == 'E' || f == 'e') + { + if ((size_t) (pfile->buffer->cur - from) + < sizeof "else fallthru" - 1) + return false; + if (f == 'E' && memcmp (from + 1, "LSE", sizeof "LSE" - 1) == 0) + all_upper = true; + else if (memcmp (from + 1, "lse", sizeof "lse" - 1)) + return false; + from += sizeof "else" - 1; + if (*from == ',') + from++; + if (*from != ' ') + return false; + from++; + if (all_upper && *from == 'f') + return false; + if (f == 'e' && *from == 'F') + return false; + f = *from; + } + else if (f == 'I' || f == 'i') + { + if ((size_t) (pfile->buffer->cur - from) + < sizeof "intentional fallthru" - 1) + return false; + if (f == 'I' && memcmp (from + 1, "NTENTIONAL", + sizeof "NTENTIONAL" - 1) == 0) + all_upper = true; + else if (memcmp (from + 1, "ntentional", + sizeof "ntentional" - 1)) + return false; + from += sizeof "intentional" - 1; + if (*from == ' ') + { + from++; + if (all_upper && *from == 'f') + return false; + } + else if (all_upper) + { + if (memcmp (from, "LY F", sizeof "LY F" - 1)) + return false; + from += sizeof "LY " - 1; + } + else + { + if (memcmp (from, "ly ", sizeof "ly " - 1)) + return false; + from += sizeof "ly " - 1; + } + if (f == 'i' && *from == 'F') + return false; + f = *from; + } + if (f != 'F' && f != 'f') + return false; + if ((size_t) (pfile->buffer->cur - from) < sizeof "fallthru" - 1) + return false; + if (f == 'F' && memcmp (from + 1, "ALL", sizeof "ALL" - 1) == 0) + all_upper = true; + else if (all_upper) + return false; + else if (memcmp (from + 1, "all", sizeof "all" - 1)) + return false; + from += sizeof "fall" - 1; + if (*from == (all_upper ? 'S' : 's') && from[1] == ' ') + from += 2; + else if (*from == ' ' || *from == '-') + from++; + else if (*from != (all_upper ? 'T' : 't')) + return false; + if ((f == 'f' || *from != 'T') && (all_upper || *from != 't')) + return false; + if ((size_t) (pfile->buffer->cur - from) < sizeof "thru" - 1) + return false; + if (memcmp (from + 1, all_upper ? "HRU" : "hru", sizeof "hru" - 1)) + { + if ((size_t) (pfile->buffer->cur - from) < sizeof "through" - 1) + return false; + if (memcmp (from + 1, all_upper ? "HROUGH" : "hrough", + sizeof "hrough" - 1)) + return false; + from += sizeof "through" - 1; + } + else + from += sizeof "thru" - 1; + while (*from == ' ' || *from == '\t' || *from == '.' || *from == '!') + from++; + if (*from == '-') + { + from++; + if (*comment_start == '*') + { + do + { + while (*from && *from != '*' + && *from != '\n' && *from != '\r') + from++; + if (*from != '*' || from[1] == '/') + break; + from++; + } + while (1); + } + else + while (*from && *from != '\n' && *from != '\r') + from++; + } + } + /* C block comment. */ + if (*comment_start == '*') + { + if (*from != '*' || from[1] != '/') + return false; + } + /* C++ line comment. */ + else if (*from != '\n') + return false; + + return true; +} + +/* Allocate COUNT tokens for RUN. */ +void +_cpp_init_tokenrun (tokenrun *run, unsigned int count) +{ + run->base = XNEWVEC (cpp_token, count); + run->limit = run->base + count; + run->next = NULL; +} + +/* Returns the next tokenrun, or creates one if there is none. */ +static tokenrun * +next_tokenrun (tokenrun *run) +{ + if (run->next == NULL) + { + run->next = XNEW (tokenrun); + run->next->prev = run; + _cpp_init_tokenrun (run->next, 250); + } + + return run->next; +} + +/* Return the number of not yet processed token in a given + context. */ +int +_cpp_remaining_tokens_num_in_context (cpp_context *context) +{ + if (context->tokens_kind == TOKENS_KIND_DIRECT) + return (LAST (context).token - FIRST (context).token); + else if (context->tokens_kind == TOKENS_KIND_INDIRECT + || context->tokens_kind == TOKENS_KIND_EXTENDED) + return (LAST (context).ptoken - FIRST (context).ptoken); + else + abort (); +} + +/* Returns the token present at index INDEX in a given context. If + INDEX is zero, the next token to be processed is returned. */ +static const cpp_token* +_cpp_token_from_context_at (cpp_context *context, int index) +{ + if (context->tokens_kind == TOKENS_KIND_DIRECT) + return &(FIRST (context).token[index]); + else if (context->tokens_kind == TOKENS_KIND_INDIRECT + || context->tokens_kind == TOKENS_KIND_EXTENDED) + return FIRST (context).ptoken[index]; + else + abort (); +} + +/* Look ahead in the input stream. */ +const cpp_token * +cpp_peek_token (cpp_reader *pfile, int index) +{ + cpp_context *context = pfile->context; + const cpp_token *peektok; + int count; + + /* First, scan through any pending cpp_context objects. */ + while (context->prev) + { + ptrdiff_t sz = _cpp_remaining_tokens_num_in_context (context); + + if (index < (int) sz) + return _cpp_token_from_context_at (context, index); + index -= (int) sz; + context = context->prev; + } + + /* We will have to read some new tokens after all (and do so + without invalidating preceding tokens). */ + count = index; + pfile->keep_tokens++; + + /* For peeked tokens temporarily disable line_change reporting, + until the tokens are parsed for real. */ + void (*line_change) (cpp_reader *, const cpp_token *, int) + = pfile->cb.line_change; + pfile->cb.line_change = NULL; + + do + { + peektok = _cpp_lex_token (pfile); + if (peektok->type == CPP_EOF) + { + index--; + break; + } + else if (peektok->type == CPP_PRAGMA) + { + /* Don't peek past a pragma. */ + if (peektok == &pfile->directive_result) + /* Save the pragma in the buffer. */ + *pfile->cur_token++ = *peektok; + index--; + break; + } + } + while (index--); + + _cpp_backup_tokens_direct (pfile, count - index); + pfile->keep_tokens--; + pfile->cb.line_change = line_change; + + return peektok; +} + +/* Allocate a single token that is invalidated at the same time as the + rest of the tokens on the line. Has its line and col set to the + same as the last lexed token, so that diagnostics appear in the + right place. */ +cpp_token * +_cpp_temp_token (cpp_reader *pfile) +{ + cpp_token *old, *result; + ptrdiff_t sz = pfile->cur_run->limit - pfile->cur_token; + ptrdiff_t la = (ptrdiff_t) pfile->lookaheads; + + old = pfile->cur_token - 1; + /* Any pre-existing lookaheads must not be clobbered. */ + if (la) + { + if (sz <= la) + { + tokenrun *next = next_tokenrun (pfile->cur_run); + + if (sz < la) + memmove (next->base + 1, next->base, + (la - sz) * sizeof (cpp_token)); + + next->base[0] = pfile->cur_run->limit[-1]; + } + + if (sz > 1) + memmove (pfile->cur_token + 1, pfile->cur_token, + MIN (la, sz - 1) * sizeof (cpp_token)); + } + + if (!sz && pfile->cur_token == pfile->cur_run->limit) + { + pfile->cur_run = next_tokenrun (pfile->cur_run); + pfile->cur_token = pfile->cur_run->base; + } + + result = pfile->cur_token++; + result->src_loc = old->src_loc; + return result; +} + +/* We're at the beginning of a logical line (so not in + directives-mode) and RESULT is a CPP_NAME with NODE_MODULE set. See + if we should enter deferred_pragma mode to tokenize the rest of the + line as a module control-line. */ + +static void +cpp_maybe_module_directive (cpp_reader *pfile, cpp_token *result) +{ + unsigned backup = 0; /* Tokens we peeked. */ + cpp_hashnode *node = result->val.node.node; + cpp_token *peek = result; + cpp_token *keyword = peek; + cpp_hashnode *(&n_modules)[spec_nodes::M_HWM][2] = pfile->spec_nodes.n_modules; + int header_count = 0; + + /* Make sure the incoming state is as we expect it. This way we + can restore it using constants. */ + gcc_checking_assert (!pfile->state.in_deferred_pragma + && !pfile->state.skipping + && !pfile->state.parsing_args + && !pfile->state.angled_headers + && (pfile->state.save_comments + == !CPP_OPTION (pfile, discard_comments))); + + /* Enter directives mode sufficiently for peeking. We don't have + to actually set in_directive. */ + pfile->state.in_deferred_pragma = true; + + /* These two fields are needed to process tokenization in deferred + pragma mode. They are not used outside deferred pragma mode or + directives mode. */ + pfile->state.pragma_allow_expansion = true; + pfile->directive_line = result->src_loc; + + /* Saving comments is incompatible with directives mode. */ + pfile->state.save_comments = 0; + + if (node == n_modules[spec_nodes::M_EXPORT][0]) + { + peek = _cpp_lex_direct (pfile); + keyword = peek; + backup++; + if (keyword->type != CPP_NAME) + goto not_module; + node = keyword->val.node.node; + if (!(node->flags & NODE_MODULE)) + goto not_module; + } + + if (node == n_modules[spec_nodes::M__IMPORT][0]) + /* __import */ + header_count = backup + 2 + 16; + else if (node == n_modules[spec_nodes::M_IMPORT][0]) + /* import */ + header_count = backup + 2 + (CPP_OPTION (pfile, preprocessed) ? 16 : 0); + else if (node == n_modules[spec_nodes::M_MODULE][0]) + ; /* module */ + else + goto not_module; + + /* We've seen [export] {module|import|__import}. Check the next token. */ + if (header_count) + /* After '{,__}import' a header name may appear. */ + pfile->state.angled_headers = true; + peek = _cpp_lex_direct (pfile); + backup++; + + /* ... import followed by identifier, ':', '<' or + header-name preprocessing tokens, or module + followed by cpp-identifier, ':' or ';' preprocessing + tokens. C++ keywords are not yet relevant. */ + if (peek->type == CPP_NAME + || peek->type == CPP_COLON + || (header_count + ? (peek->type == CPP_LESS + || (peek->type == CPP_STRING && peek->val.str.text[0] != 'R') + || peek->type == CPP_HEADER_NAME) + : peek->type == CPP_SEMICOLON)) + { + pfile->state.pragma_allow_expansion = !CPP_OPTION (pfile, preprocessed); + if (!pfile->state.pragma_allow_expansion) + pfile->state.prevent_expansion++; + + if (!header_count && linemap_included_from + (LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table))) + cpp_error_with_line (pfile, CPP_DL_ERROR, keyword->src_loc, 0, + "module control-line cannot be in included file"); + + /* The first one or two tokens cannot be macro names. */ + for (int ix = backup; ix--;) + { + cpp_token *tok = ix ? keyword : result; + cpp_hashnode *node = tok->val.node.node; + + /* Don't attempt to expand the token. */ + tok->flags |= NO_EXPAND; + if (_cpp_defined_macro_p (node) + && _cpp_maybe_notify_macro_use (pfile, node, tok->src_loc) + && !cpp_fun_like_macro_p (node)) + cpp_error_with_line (pfile, CPP_DL_ERROR, tok->src_loc, 0, + "module control-line \"%s\" cannot be" + " an object-like macro", + NODE_NAME (node)); + } + + /* Map to underbar variants. */ + keyword->val.node.node = n_modules[header_count + ? spec_nodes::M_IMPORT + : spec_nodes::M_MODULE][1]; + if (backup != 1) + result->val.node.node = n_modules[spec_nodes::M_EXPORT][1]; + + /* Maybe tell the tokenizer we expect a header-name down the + road. */ + pfile->state.directive_file_token = header_count; + } + else + { + not_module: + /* Drop out of directive mode. */ + /* We aaserted save_comments had this value upon entry. */ + pfile->state.save_comments + = !CPP_OPTION (pfile, discard_comments); + pfile->state.in_deferred_pragma = false; + /* Do not let this remain on. */ + pfile->state.angled_headers = false; + } + + /* In either case we want to backup the peeked tokens. */ + if (backup) + { + /* If we saw EOL, we should drop it, because this isn't a module + control-line after all. */ + bool eol = peek->type == CPP_PRAGMA_EOL; + if (!eol || backup > 1) + { + /* Put put the peeked tokens back */ + _cpp_backup_tokens_direct (pfile, backup); + /* But if the last one was an EOL, forget it. */ + if (eol) + pfile->lookaheads--; + } + } +} + +/* Lex a token into RESULT (external interface). Takes care of issues + like directive handling, token lookahead, multiple include + optimization and skipping. */ +const cpp_token * +_cpp_lex_token (cpp_reader *pfile) +{ + cpp_token *result; + + for (;;) + { + if (pfile->cur_token == pfile->cur_run->limit) + { + pfile->cur_run = next_tokenrun (pfile->cur_run); + pfile->cur_token = pfile->cur_run->base; + } + /* We assume that the current token is somewhere in the current + run. */ + if (pfile->cur_token < pfile->cur_run->base + || pfile->cur_token >= pfile->cur_run->limit) + abort (); + + if (pfile->lookaheads) + { + pfile->lookaheads--; + result = pfile->cur_token++; + } + else + result = _cpp_lex_direct (pfile); + + if (result->flags & BOL) + { + /* Is this a directive. If _cpp_handle_directive returns + false, it is an assembler #. */ + if (result->type == CPP_HASH + /* 6.10.3 p 11: Directives in a list of macro arguments + gives undefined behavior. This implementation + handles the directive as normal. */ + && pfile->state.parsing_args != 1) + { + if (_cpp_handle_directive (pfile, result->flags & PREV_WHITE)) + { + if (pfile->directive_result.type == CPP_PADDING) + continue; + result = &pfile->directive_result; + } + } + else if (pfile->state.in_deferred_pragma) + { untested(); + result = &pfile->directive_result; + } + else if (result->type == CPP_NAME + && (result->val.node.node->flags & NODE_MODULE) + && !pfile->state.skipping + /* Unlike regular directives, we do not deal with + tokenizing module directives as macro arguments. + That's not permitted. */ + && !pfile->state.parsing_args) + { untested(); + /* P1857. Before macro expansion, At start of logical + line ... */ + /* We don't have to consider lookaheads at this point. */ + gcc_checking_assert (!pfile->lookaheads); + + cpp_maybe_module_directive (pfile, result); + } + else + { + } + + if (pfile->cb.line_change && !pfile->state.skipping) + pfile->cb.line_change (pfile, result, pfile->state.parsing_args); + } + + /* We don't skip tokens in directives. */ + if (pfile->state.in_directive || pfile->state.in_deferred_pragma) + break; + + /* Outside a directive, invalidate controlling macros. At file + EOF, _cpp_lex_direct takes care of popping the buffer, so we never + get here and MI optimization works. */ + pfile->mi_valid = false; + + if (!pfile->state.skipping || result->type == CPP_EOF) + break; + } + + return result; +} + +/* Returns true if a fresh line has been loaded. */ +bool +_cpp_get_fresh_line (cpp_reader *pfile) +{ + /* We can't get a new line until we leave the current directive. */ + if (pfile->state.in_directive) + return false; + + for (;;) + { + cpp_buffer *buffer = pfile->buffer; + + if (!buffer->need_line) + return true; + + if (buffer->next_line < buffer->rlimit) + { + _cpp_clean_line (pfile); + return true; + } + + /* First, get out of parsing arguments state. */ + if (pfile->state.parsing_args) + return false; + + /* End of buffer. Non-empty files should end in a newline. */ + if (buffer->buf != buffer->rlimit + && buffer->next_line > buffer->rlimit + && !buffer->from_stage3) + { + /* Clip to buffer size. */ + buffer->next_line = buffer->rlimit; + } + + if (buffer->prev && !buffer->return_at_eof) + _cpp_pop_buffer (pfile); + else + { + /* End of translation. Do not pop the buffer yet. Increment + line number so that the EOF token is on a line of its own + (_cpp_lex_direct doesn't increment in that case, because + it's hard for it to distinguish this special case). */ + CPP_INCREMENT_LINE (pfile, 0); + return false; + } + } +} + +#define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE) \ + do \ + { \ + result->type = ELSE_TYPE; \ + if (*buffer->cur == CHAR) \ + buffer->cur++, result->type = THEN_TYPE; \ + } \ + while (0) + +/* Lex a token into pfile->cur_token, which is also incremented, to + get diagnostics pointing to the correct location. + + Does not handle issues such as token lookahead, multiple-include + optimization, directives, skipping etc. This function is only + suitable for use by _cpp_lex_token, and in special cases like + lex_expansion_token which doesn't care for any of these issues. + + When meeting a newline, returns CPP_EOF if parsing a directive, + otherwise returns to the start of the token buffer if permissible. + Returns the location of the lexed token. */ +cpp_token * +_cpp_lex_direct (cpp_reader *pfile) +{ + cppchar_t c; + cpp_buffer *buffer; + const unsigned char *comment_start; + bool fallthrough_comment = false; + cpp_token *result = pfile->cur_token++; + + fresh_line: + result->flags = 0; + buffer = pfile->buffer; + if (buffer->need_line) + { + if (pfile->state.in_deferred_pragma) + { + /* This can happen in cases like: + #define loop(x) whatever + #pragma omp loop + where when trying to expand loop we need to peek + next token after loop, but aren't still in_deferred_pragma + mode but are in in_directive mode, so buffer->need_line + is set, a CPP_EOF is peeked. */ + result->type = CPP_PRAGMA_EOL; + pfile->state.in_deferred_pragma = false; + if (!pfile->state.pragma_allow_expansion) + pfile->state.prevent_expansion--; + return result; + } + if (!_cpp_get_fresh_line (pfile)) + { + result->type = CPP_EOF; + /* Not a real EOF in a directive or arg parsing -- we refuse + to advance to the next file now, and will once we're out + of those modes. */ + if (!pfile->state.in_directive && !pfile->state.parsing_args) + { + /* Tell the compiler the line number of the EOF token. */ + result->src_loc = pfile->line_table->highest_line; + result->flags = BOL; + /* Now pop the buffer that _cpp_get_fresh_line did not. */ + _cpp_pop_buffer (pfile); + } + return result; + } + if (buffer != pfile->buffer) + fallthrough_comment = false; + if (!pfile->keep_tokens) + { + pfile->cur_run = &pfile->base_run; + result = pfile->base_run.base; + pfile->cur_token = result + 1; + } + result->flags = BOL; + if (pfile->state.parsing_args == 2) + result->flags |= PREV_WHITE; + } + buffer = pfile->buffer; + update_tokens_line: + result->src_loc = pfile->line_table->highest_line; + + skipped_white: + if (buffer->cur >= buffer->notes[buffer->cur_note].pos + && !pfile->overlaid_buffer) + { + // sdcc hack // + result->flags |=_cpp_process_line_notes (pfile, false); + result->src_loc = pfile->line_table->highest_line; + } + c = *buffer->cur++; + + if (pfile->forced_token_location) + result->src_loc = pfile->forced_token_location; + else + result->src_loc = linemap_position_for_column (pfile->line_table, + CPP_BUF_COLUMN (buffer, buffer->cur)); + + switch (c) + { + case ' ': case '\t': case '\f': case '\v': case '\0': + result->flags |= PREV_WHITE; + skip_whitespace (pfile, c); + goto skipped_white; + + case '\n': + /* Increment the line, unless this is the last line ... */ + if (buffer->cur < buffer->rlimit + /* ... or this is a #include, (where _cpp_stack_file needs to + unwind by one line) ... */ + || (pfile->state.in_directive > 1 + /* ... except traditional-cpp increments this elsewhere. */ + && !CPP_OPTION (pfile, traditional))) + CPP_INCREMENT_LINE (pfile, 0); + buffer->need_line = true; + if (pfile->state.in_deferred_pragma) + { + /* Produce the PRAGMA_EOL on this line. File reading + ensures there is always a \n at end of the buffer, thus + in a deferred pragma we always see CPP_PRAGMA_EOL before + any CPP_EOF. */ + result->type = CPP_PRAGMA_EOL; + result->flags &= ~PREV_WHITE; + pfile->state.in_deferred_pragma = false; + if (!pfile->state.pragma_allow_expansion) + pfile->state.prevent_expansion--; + return result; + } + goto fresh_line; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->type = CPP_NUMBER; + lex_number (pfile, &result->val.str, &nst); + warn_about_normalization (pfile, result, &nst); + break; + } + + case 'L': + case 'u': + case 'U': + case 'R': + /* 'L', 'u', 'U', 'u8' or 'R' may introduce wide characters, + wide strings or raw strings. */ + if (c == 'L' || CPP_OPTION (pfile, rliterals) + || (c != 'R' && CPP_OPTION (pfile, uliterals))) + { + if ((*buffer->cur == '\'' && c != 'R') + || *buffer->cur == '"' + || (*buffer->cur == 'R' + && c != 'R' + && buffer->cur[1] == '"' + && CPP_OPTION (pfile, rliterals)) + || (*buffer->cur == '8' + && c == 'u' + && ((buffer->cur[1] == '"' || (buffer->cur[1] == '\'' + && CPP_OPTION (pfile, utf8_char_literals))) + || (buffer->cur[1] == 'R' && buffer->cur[2] == '"' + && CPP_OPTION (pfile, rliterals))))) + { + lex_string (pfile, result, buffer->cur - 1); + break; + } + } + /* Fall through. */ + + case '_': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'v': case 'w': case 'x': + case 'y': case 'z': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': + case 'M': case 'N': case 'O': case 'P': case 'Q': + case 'S': case 'T': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + result->type = CPP_NAME; + { + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->val.node.node = lex_identifier (pfile, buffer->cur - 1, false, + &nst, + &result->val.node.spelling); + warn_about_normalization (pfile, result, &nst); + } + + /* SDCC __asm specific */ + /* handle __asm ... __endasm ; */ + if (result->val.node.node == pfile->spec_nodes.n__asm) + { + if (CPP_OPTION (pfile, preproc_asm)) + { + // ignore, go on. + }else{ + comment_start = buffer->cur; + result->type = CPP_ASM; + _sdcpp_skip_asm_block (pfile); + /* Save the __asm block as a token in its own right. */ + _sdcpp_save_asm (pfile, result, comment_start, result->val.node.node == pfile->spec_nodes.n__asm); + } + result->flags |= ENTER_ASM; + } + else if (result->val.node.node == pfile->spec_nodes.n__endasm) + { + result->flags |= EXIT_ASM; + } + else + + /* Convert named operators to their proper types. */ + if (result->val.node.node->flags & NODE_OPERATOR) + { untested(); + result->flags |= NAMED_OP; + result->type = (enum cpp_ttype) result->val.node.node->directive_index; + }else{ + } + + /* Signal FALLTHROUGH comment followed by another token. */ + if (fallthrough_comment) + result->flags |= PREV_FALLTHROUGH; + break; + + case '\'': + case '"': + lex_string (pfile, result, buffer->cur - 1); + break; + + case '/': + /* A potential block or line comment. */ + comment_start = buffer->cur; + c = *buffer->cur; + + if (c == '*') + { + if (_cpp_skip_block_comment (pfile)) + cpp_error (pfile, CPP_DL_ERROR, "unterminated comment"); + } + else if (c == '/' && ! CPP_OPTION (pfile, traditional)) + { + /* Don't warn for system headers. */ + if (_cpp_in_system_header (pfile)) + ; + /* Warn about comments if pedantically GNUC89, and not + in system headers. */ + else if (CPP_OPTION (pfile, lang) == CLK_GNUC89 + && CPP_PEDANTIC (pfile) + && ! buffer->warned_cplusplus_comments) + { + if (cpp_error (pfile, CPP_DL_PEDWARN, + "C++ style comments are not allowed in ISO C90")) + cpp_error (pfile, CPP_DL_NOTE, + "(this will be reported only once per input file)"); + buffer->warned_cplusplus_comments = 1; + } + /* Or if specifically desired via -Wc90-c99-compat. */ + else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0 + && ! CPP_OPTION (pfile, cplusplus) + && ! buffer->warned_cplusplus_comments) + { + if (cpp_error (pfile, CPP_DL_WARNING, + "C++ style comments are incompatible with C90")) + cpp_error (pfile, CPP_DL_NOTE, + "(this will be reported only once per input file)"); + buffer->warned_cplusplus_comments = 1; + } + /* In C89/C94, C++ style comments are forbidden. */ + else if ((CPP_OPTION (pfile, lang) == CLK_STDC89 + || CPP_OPTION (pfile, lang) == CLK_STDC94)) + { + /* But don't be confused about valid code such as + - // immediately followed by *, + - // in a preprocessing directive, + - // in an #if 0 block. */ + if (buffer->cur[1] == '*' + || pfile->state.in_directive + || pfile->state.skipping) + { + result->type = CPP_DIV; + break; + } + else if (! buffer->warned_cplusplus_comments) + { + if (cpp_error (pfile, CPP_DL_ERROR, + "C++ style comments are not allowed in " + "ISO C90")) + cpp_error (pfile, CPP_DL_NOTE, + "(this will be reported only once per input " + "file)"); + buffer->warned_cplusplus_comments = 1; + } + } + if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments)) + cpp_warning (pfile, CPP_W_COMMENTS, "multi-line comment"); + } + else if (c == '=') + { + buffer->cur++; + result->type = CPP_DIV_EQ; + break; + } + else + { + result->type = CPP_DIV; + break; + } + + if (fallthrough_comment_p (pfile, comment_start)) + fallthrough_comment = true; + + if (pfile->cb.comment) + { + size_t len = pfile->buffer->cur - comment_start; + pfile->cb.comment (pfile, result->src_loc, comment_start - 1, + len + 1); + } + + if (!pfile->state.save_comments) + { + result->flags |= PREV_WHITE; + goto update_tokens_line; + } + + if (fallthrough_comment) + result->flags |= PREV_FALLTHROUGH; + + /* Save the comment as a token in its own right. */ + save_comment (pfile, result, comment_start, c); + break; + + case '<': + if (pfile->state.angled_headers) + { + lex_string (pfile, result, buffer->cur - 1); + if (result->type != CPP_LESS) + break; + } + + result->type = CPP_LESS; + if (*buffer->cur == '=') + { + buffer->cur++, result->type = CPP_LESS_EQ; + if (*buffer->cur == '>' + && CPP_OPTION (pfile, cplusplus) + && CPP_OPTION (pfile, lang) >= CLK_GNUCXX20) + buffer->cur++, result->type = CPP_SPACESHIP; + } + else if (*buffer->cur == '<') + { + buffer->cur++; + IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT); + } + else if (CPP_OPTION (pfile, digraphs)) + { + if (*buffer->cur == ':') + { + /* C++11 [2.5/3 lex.pptoken], "Otherwise, if the next + three characters are <:: and the subsequent character + is neither : nor >, the < is treated as a preprocessor + token by itself". */ + if (CPP_OPTION (pfile, cplusplus) + && CPP_OPTION (pfile, lang) != CLK_CXX98 + && CPP_OPTION (pfile, lang) != CLK_GNUCXX + && buffer->cur[1] == ':' + && buffer->cur[2] != ':' && buffer->cur[2] != '>') + break; + + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_OPEN_SQUARE; + } + else if (*buffer->cur == '%') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_OPEN_BRACE; + } + } + break; + + case '>': + result->type = CPP_GREATER; + if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_GREATER_EQ; + else if (*buffer->cur == '>') + { + buffer->cur++; + IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT); + } + break; + + case '%': + result->type = CPP_MOD; + if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_MOD_EQ; + else if (CPP_OPTION (pfile, digraphs)) + { + if (*buffer->cur == ':') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_HASH; + if (*buffer->cur == '%' && buffer->cur[1] == ':') + buffer->cur += 2, result->type = CPP_PASTE, result->val.token_no = 0; + } + else if (*buffer->cur == '>') + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_CLOSE_BRACE; + } + } + break; + + case '.': + result->type = CPP_DOT; + if (ISDIGIT (*buffer->cur)) + { + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + result->type = CPP_NUMBER; + lex_number (pfile, &result->val.str, &nst); + warn_about_normalization (pfile, result, &nst); + } + else if (*buffer->cur == '.' && buffer->cur[1] == '.') + buffer->cur += 2, result->type = CPP_ELLIPSIS; + else if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus)) + buffer->cur++, result->type = CPP_DOT_STAR; + break; + + case '+': + result->type = CPP_PLUS; + if (*buffer->cur == '+') + buffer->cur++, result->type = CPP_PLUS_PLUS; + else if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_PLUS_EQ; + break; + + case '-': + result->type = CPP_MINUS; + if (*buffer->cur == '>') + { + buffer->cur++; + result->type = CPP_DEREF; + if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus)) + buffer->cur++, result->type = CPP_DEREF_STAR; + } + else if (*buffer->cur == '-') + buffer->cur++, result->type = CPP_MINUS_MINUS; + else if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_MINUS_EQ; + break; + + case '&': + result->type = CPP_AND; + if (*buffer->cur == '&') + buffer->cur++, result->type = CPP_AND_AND; + else if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_AND_EQ; + break; + + case '|': + result->type = CPP_OR; + if (*buffer->cur == '|') + buffer->cur++, result->type = CPP_OR_OR; + else if (*buffer->cur == '=') + buffer->cur++, result->type = CPP_OR_EQ; + break; + + case ':': + result->type = CPP_COLON; + if (*buffer->cur == ':' && CPP_OPTION (pfile, scope)) + buffer->cur++, result->type = CPP_SCOPE; + else if (*buffer->cur == '>' && CPP_OPTION (pfile, digraphs)) + { + buffer->cur++; + result->flags |= DIGRAPH; + result->type = CPP_CLOSE_SQUARE; + } + break; + + case '*': IF_NEXT_IS ('=', CPP_MULT_EQ, CPP_MULT); break; + case '=': IF_NEXT_IS ('=', CPP_EQ_EQ, CPP_EQ); break; + case '!': IF_NEXT_IS ('=', CPP_NOT_EQ, CPP_NOT); break; + case '^': IF_NEXT_IS ('=', CPP_XOR_EQ, CPP_XOR); break; + case '#': IF_NEXT_IS ('#', CPP_PASTE, CPP_HASH); result->val.token_no = 0; break; + + case '?': result->type = CPP_QUERY; break; + case '~': result->type = CPP_COMPL; break; + case ',': result->type = CPP_COMMA; break; + case '(': result->type = CPP_OPEN_PAREN; break; + case ')': result->type = CPP_CLOSE_PAREN; break; + case '[': result->type = CPP_OPEN_SQUARE; break; + case ']': result->type = CPP_CLOSE_SQUARE; break; + case '{': result->type = CPP_OPEN_BRACE; break; + case '}': result->type = CPP_CLOSE_BRACE; break; + case ';': result->type = CPP_SEMICOLON; break; + + /* @ is a punctuator in Objective-C. */ + case '@': result->type = CPP_ATSIGN; break; + + default: + { + const uchar *base = --buffer->cur; + + /* Check for an extended identifier ($ or UCN or UTF-8). */ + struct normalize_state nst = INITIAL_NORMALIZE_STATE; + if (forms_identifier_p (pfile, true, &nst)) + { + result->type = CPP_NAME; + result->val.node.node = lex_identifier (pfile, base, true, &nst, + &result->val.node.spelling); + warn_about_normalization (pfile, result, &nst); + break; + } + + /* Otherwise this will form a CPP_OTHER token. Parse valid UTF-8 as a + single token. */ + buffer->cur++; + if (c >= utf8_signifier) + { + const uchar *pstr = base; + cppchar_t s; + if (_cpp_valid_utf8 (pfile, &pstr, buffer->rlimit, 0, NULL, &s)) + buffer->cur = pstr; + } + create_literal (pfile, result, base, buffer->cur - base, CPP_OTHER); + break; + } + + } + + /* Potentially convert the location of the token to a range. */ + if (result->src_loc >= RESERVED_LOCATION_COUNT + && result->type != CPP_EOF) + { + /* Ensure that any line notes are processed, so that we have the + correct physical line/column for the end-point of the token even + when a logical line is split via one or more backslashes. */ + if (buffer->cur >= buffer->notes[buffer->cur_note].pos + && !pfile->overlaid_buffer) + _cpp_process_line_notes (pfile, false); + + source_range tok_range; + tok_range.m_start = result->src_loc; + tok_range.m_finish + = linemap_position_for_column (pfile->line_table, + CPP_BUF_COLUMN (buffer, buffer->cur)); + + result->src_loc = COMBINE_LOCATION_DATA (pfile->line_table, + result->src_loc, + tok_range, NULL); + } + + return result; +} + +/* An upper bound on the number of bytes needed to spell TOKEN. + Does not include preceding whitespace. */ +unsigned int +cpp_token_len (const cpp_token *token) +{ + unsigned int len; + + switch (TOKEN_SPELL (token)) + { + default: len = 6; break; + case SPELL_LITERAL: len = token->val.str.len; break; + case SPELL_IDENT: len = NODE_LEN (token->val.node.node) * 10; break; + } + + return len; +} + +/* Parse UTF-8 out of NAMEP and place a \U escape in BUFFER. + Return the number of bytes read out of NAME. (There are always + 10 bytes written to BUFFER.) */ + +static size_t +utf8_to_ucn (unsigned char *buffer, const unsigned char *name) +{ + int j; + int ucn_len = 0; + int ucn_len_c; + unsigned t; + unsigned long utf32; + + /* Compute the length of the UTF-8 sequence. */ + for (t = *name; t & 0x80; t <<= 1) + ucn_len++; + + utf32 = *name & (0x7F >> ucn_len); + for (ucn_len_c = 1; ucn_len_c < ucn_len; ucn_len_c++) + { + utf32 = (utf32 << 6) | (*++name & 0x3F); + + /* Ill-formed UTF-8. */ + if ((*name & ~0x3F) != 0x80) + abort (); + } + + *buffer++ = '\\'; + *buffer++ = 'U'; + for (j = 7; j >= 0; j--) + *buffer++ = "0123456789abcdef"[(utf32 >> (4 * j)) & 0xF]; + return ucn_len; +} + +/* Given a token TYPE corresponding to a digraph, return a pointer to + the spelling of the digraph. */ +static const unsigned char * +cpp_digraph2name (enum cpp_ttype type) +{ + return digraph_spellings[(int) type - (int) CPP_FIRST_DIGRAPH]; +} + +/* Write the spelling of an identifier IDENT, using UCNs, to BUFFER. + The buffer must already contain the enough space to hold the + token's spelling. Returns a pointer to the character after the + last character written. */ +unsigned char * +_cpp_spell_ident_ucns (unsigned char *buffer, cpp_hashnode *ident) +{ + size_t i; + const unsigned char *name = NODE_NAME (ident); + + for (i = 0; i < NODE_LEN (ident); i++) + if (name[i] & ~0x7F) + { + i += utf8_to_ucn (buffer, name + i) - 1; + buffer += 10; + } + else + *buffer++ = name[i]; + + return buffer; +} + +/* 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 (with the original spelling of extended identifiers), false + if extended identifiers should always be written using UCNs (there is + no option for always writing them in the internal UTF-8 form). + FIXME: Would be nice if we didn't need the PFILE argument. */ +unsigned char * +cpp_spell_token (cpp_reader *pfile, const cpp_token *token, + unsigned char *buffer, bool forstring) +{ + switch (TOKEN_SPELL (token)) + { + case SPELL_OPERATOR: + { + const unsigned char *spelling; + unsigned char c; + + if (token->flags & DIGRAPH) + spelling = cpp_digraph2name (token->type); + else if (token->flags & NAMED_OP) + goto spell_ident; + else + spelling = TOKEN_NAME (token); + + while ((c = *spelling++) != '\0') + *buffer++ = c; + } + break; + + spell_ident: + case SPELL_IDENT: + if (forstring) + { + memcpy (buffer, NODE_NAME (token->val.node.spelling), + NODE_LEN (token->val.node.spelling)); + buffer += NODE_LEN (token->val.node.spelling); + } + else + buffer = _cpp_spell_ident_ucns (buffer, token->val.node.node); + break; + + case SPELL_LITERAL: + memcpy (buffer, token->val.str.text, token->val.str.len); + buffer += token->val.str.len; + break; + + case SPELL_NONE: + cpp_error (pfile, CPP_DL_ICE, + "unspellable token %s", TOKEN_NAME (token)); + break; + } + + return buffer; +} + +/* Returns TOKEN spelt as a null-terminated string. The string is + freed when the reader is destroyed. Useful for diagnostics. */ +unsigned char * +cpp_token_as_text (cpp_reader *pfile, const cpp_token *token) +{ + unsigned int len = cpp_token_len (token) + 1; + unsigned char *start = _cpp_unaligned_alloc (pfile, len), *end; + + end = cpp_spell_token (pfile, token, start, false); + end[0] = '\0'; + + return start; +} + +/* Returns a pointer to a string which spells the token defined by + TYPE and FLAGS. Used by C front ends, which really should move to + using cpp_token_as_text. */ +const char * +cpp_type2name (enum cpp_ttype type, unsigned char flags) +{ + if (flags & DIGRAPH) + return (const char *) cpp_digraph2name (type); + else if (flags & NAMED_OP) + return cpp_named_operator2name (type); + + return (const char *) token_spellings[type].name; +} + +/* Writes the spelling of token to FP, without any preceding space. + Separated from cpp_spell_token for efficiency - to avoid stdio + double-buffering. */ +void +cpp_output_token (const cpp_token *token, FILE *fp) +{ + if (token->flags & ENTER_ASM){ + _in_asm++; + }else{ + } + if (token->flags & EXIT_ASM){ + _in_asm--; + }else{ + } + + switch (TOKEN_SPELL (token)) + { + case SPELL_OPERATOR: + { + const unsigned char *spelling; + int c; + + if (token->flags & DIGRAPH) + spelling = cpp_digraph2name (token->type); + else if (token->flags & NAMED_OP) + goto spell_ident; + else + spelling = TOKEN_NAME (token); + + c = *spelling; + do + putc (c, fp); + while ((c = *++spelling) != '\0'); + } + break; + + spell_ident: + case SPELL_IDENT: + { + size_t i; + const unsigned char * name = NODE_NAME (token->val.node.node); + + for (i = 0; i < NODE_LEN (token->val.node.node); i++) + if (name[i] & ~0x7F) + { + unsigned char buffer[10]; + i += utf8_to_ucn (buffer, name + i) - 1; + fwrite (buffer, 1, 10, fp); + } + else + fputc (NODE_NAME (token->val.node.node)[i], fp); + } + break; + + case SPELL_LITERAL: + if (token->type == CPP_HEADER_NAME) + fputc ('"', fp); + fwrite (token->val.str.text, 1, token->val.str.len, fp); + if (token->type == CPP_HEADER_NAME) + fputc ('"', fp); + break; + + case SPELL_NONE: + /* An error, most probably. */ + break; + } +} + +/* Compare two tokens. */ +int +_cpp_equiv_tokens (const cpp_token *a, const cpp_token *b) +{ + if (a->type == b->type && a->flags == b->flags) + switch (TOKEN_SPELL (a)) + { + default: /* Keep compiler happy. */ + case SPELL_OPERATOR: + /* token_no is used to track where multiple consecutive ## + tokens were originally located. */ + return (a->type != CPP_PASTE || a->val.token_no == b->val.token_no); + case SPELL_NONE: + return (a->type != CPP_MACRO_ARG + || (a->val.macro_arg.arg_no == b->val.macro_arg.arg_no + && a->val.macro_arg.spelling == b->val.macro_arg.spelling)); + case SPELL_IDENT: + return (a->val.node.node == b->val.node.node + && a->val.node.spelling == b->val.node.spelling); + case SPELL_LITERAL: + return (a->val.str.len == b->val.str.len + && !memcmp (a->val.str.text, b->val.str.text, + a->val.str.len)); + } + + return 0; +} + +/* Returns nonzero if a space should be inserted to avoid an + accidental token paste for output. For simplicity, it is + conservative, and occasionally advises a space where one is not + needed, e.g. "." and ".2". */ +int +cpp_avoid_paste (cpp_reader *pfile, const cpp_token *token1, + const cpp_token *token2) +{ + enum cpp_ttype a = token1->type, b = token2->type; + cppchar_t c; + + if (token1->flags & NAMED_OP) + a = CPP_NAME; + if (token2->flags & NAMED_OP) + b = CPP_NAME; + + c = EOF; + if (token2->flags & DIGRAPH) + c = digraph_spellings[(int) b - (int) CPP_FIRST_DIGRAPH][0]; + else if (token_spellings[b].category == SPELL_OPERATOR) + c = token_spellings[b].name[0]; + + /* Quickly get everything that can paste with an '='. */ + if ((int) a <= (int) CPP_LAST_EQ && c == '=') + return 1; + + switch (a) + { + case CPP_GREATER: return c == '>'; + case CPP_LESS: return c == '<' || c == '%' || c == ':'; + case CPP_PLUS: return c == '+'; + case CPP_MINUS: return c == '-' || c == '>'; + case CPP_DIV: return c == '/' || c == '*'; /* Comments. */ + case CPP_MOD: return c == ':' || c == '>'; + case CPP_AND: return c == '&'; + case CPP_OR: return c == '|'; + case CPP_COLON: return c == ':' || c == '>'; + case CPP_DEREF: return c == '*'; + case CPP_DOT: return c == '.' || c == '%' || b == CPP_NUMBER; + case CPP_HASH: return c == '#' || c == '%'; /* Digraph form. */ + case CPP_PRAGMA: + case CPP_NAME: return ((b == CPP_NUMBER + && name_p (pfile, &token2->val.str)) + || b == CPP_NAME + || b == CPP_CHAR || b == CPP_STRING); /* L */ + case CPP_NUMBER: return (b == CPP_NUMBER || b == CPP_NAME + || b == CPP_CHAR + || c == '.' || c == '+' || c == '-'); + /* UCNs */ + case CPP_OTHER: return ((token1->val.str.text[0] == '\\' + && b == CPP_NAME) + || (CPP_OPTION (pfile, objc) + && token1->val.str.text[0] == '@' + && (b == CPP_NAME || b == CPP_STRING))); + case CPP_LESS_EQ: return c == '>'; + case CPP_STRING: + case CPP_WSTRING: + case CPP_UTF8STRING: + case CPP_STRING16: + case CPP_STRING32: return (CPP_OPTION (pfile, user_literals) + && (b == CPP_NAME + || (TOKEN_SPELL (token2) == SPELL_LITERAL + && ISIDST (token2->val.str.text[0])))); + + default: break; + } + + return 0; +} + +/* Output all the remaining tokens on the current line, and a newline + character, to FP. Leading whitespace is removed. If there are + macros, special token padding is not performed. */ +void +cpp_output_line (cpp_reader *pfile, FILE *fp) +{ + const cpp_token *token; + + token = cpp_get_token (pfile); + while (token->type != CPP_EOF) + { + cpp_output_token (token, fp); + token = cpp_get_token (pfile); + if (token->flags & PREV_WHITE) + putc (' ', fp); + if (_in_asm && token->flags & PREV_NL) + fputs ("\x87 ", fp); + } + + putc ('\n', fp); +} +/* Return a string representation of all the remaining tokens on the + current line. The result is allocated using xmalloc and must be + freed by the caller. */ +unsigned char * +cpp_output_line_to_string (cpp_reader *pfile, const unsigned char *dir_name) +{ + const cpp_token *token; + unsigned int out = dir_name ? ustrlen (dir_name) : 0; + unsigned int alloced = 120 + out; + unsigned char *result = (unsigned char *) xmalloc (alloced); + + /* If DIR_NAME is empty, there are no initial contents. */ + if (dir_name) + { + sprintf ((char *) result, "#%s ", dir_name); + out += 2; + } + + token = cpp_get_token (pfile); + while (token->type != CPP_EOF) + { + unsigned char *last; + /* Include room for a possible space and the terminating nul. */ + unsigned int len = cpp_token_len (token) + 2; + + if (out + len > alloced) + { + alloced *= 2; + if (out + len > alloced) + alloced = out + len; + result = (unsigned char *) xrealloc (result, alloced); + } + + last = cpp_spell_token (pfile, token, &result[out], 0); + out = last - result; + + token = cpp_get_token (pfile); + if (token->flags & PREV_WHITE) + result[out++] = ' '; + } + + result[out] = '\0'; + return result; +} + +/* Memory buffers. Changing these three constants can have a dramatic + effect on performance. The values here are reasonable defaults, + but might be tuned. If you adjust them, be sure to test across a + range of uses of cpplib, including heavy nested function-like macro + expansion. Also check the change in peak memory usage (NJAMD is a + good tool for this). */ +#define MIN_BUFF_SIZE 8000 +#define BUFF_SIZE_UPPER_BOUND(MIN_SIZE) (MIN_BUFF_SIZE + (MIN_SIZE) * 3 / 2) +#define EXTENDED_BUFF_SIZE(BUFF, MIN_EXTRA) \ + (MIN_EXTRA + ((BUFF)->limit - (BUFF)->cur) * 2) + +#if MIN_BUFF_SIZE > BUFF_SIZE_UPPER_BOUND (0) + #error BUFF_SIZE_UPPER_BOUND must be at least as large as MIN_BUFF_SIZE! +#endif + +/* Create a new allocation buffer. Place the control block at the end + of the buffer, so that buffer overflows will cause immediate chaos. */ +static _cpp_buff * +new_buff (size_t len) +{ + _cpp_buff *result; + unsigned char *base; + + if (len < MIN_BUFF_SIZE) + len = MIN_BUFF_SIZE; + len = CPP_ALIGN (len); + +#ifdef ENABLE_VALGRIND_ANNOTATIONS + /* Valgrind warns about uses of interior pointers, so put _cpp_buff + struct first. */ + size_t slen = CPP_ALIGN2 (sizeof (_cpp_buff), 2 * DEFAULT_ALIGNMENT); + base = XNEWVEC (unsigned char, len + slen); + result = (_cpp_buff *) base; + base += slen; +#else + base = XNEWVEC (unsigned char, len + sizeof (_cpp_buff)); + result = (_cpp_buff *) (base + len); +#endif + result->base = base; + result->cur = base; + result->limit = base + len; + result->next = NULL; + return result; +} + +/* Place a chain of unwanted allocation buffers on the free list. */ +void +_cpp_release_buff (cpp_reader *pfile, _cpp_buff *buff) +{ + _cpp_buff *end = buff; + + while (end->next) + end = end->next; + end->next = pfile->free_buffs; + pfile->free_buffs = buff; +} + +/* Return a free buffer of size at least MIN_SIZE. */ +_cpp_buff * +_cpp_get_buff (cpp_reader *pfile, size_t min_size) +{ + _cpp_buff *result, **p; + + for (p = &pfile->free_buffs;; p = &(*p)->next) + { + size_t size; + + if (*p == NULL) + return new_buff (min_size); + result = *p; + size = result->limit - result->base; + /* Return a buffer that's big enough, but don't waste one that's + way too big. */ + if (size >= min_size && size <= BUFF_SIZE_UPPER_BOUND (min_size)) + break; + } + + *p = result->next; + result->next = NULL; + result->cur = result->base; + return result; +} + +/* Creates a new buffer with enough space to hold the uncommitted + remaining bytes of BUFF, and at least MIN_EXTRA more bytes. Copies + the excess bytes to the new buffer. Chains the new buffer after + BUFF, and returns the new buffer. */ +_cpp_buff * +_cpp_append_extend_buff (cpp_reader *pfile, _cpp_buff *buff, size_t min_extra) +{ + size_t size = EXTENDED_BUFF_SIZE (buff, min_extra); + _cpp_buff *new_buff = _cpp_get_buff (pfile, size); + + buff->next = new_buff; + memcpy (new_buff->base, buff->cur, BUFF_ROOM (buff)); + return new_buff; +} + +/* Creates a new buffer with enough space to hold the uncommitted + remaining bytes of the buffer pointed to by BUFF, and at least + MIN_EXTRA more bytes. Copies the excess bytes to the new buffer. + Chains the new buffer before the buffer pointed to by BUFF, and + updates the pointer to point to the new buffer. */ +void +_cpp_extend_buff (cpp_reader *pfile, _cpp_buff **pbuff, size_t min_extra) +{ + _cpp_buff *new_buff, *old_buff = *pbuff; + size_t size = EXTENDED_BUFF_SIZE (old_buff, min_extra); + + new_buff = _cpp_get_buff (pfile, size); + memcpy (new_buff->base, old_buff->cur, BUFF_ROOM (old_buff)); + new_buff->next = old_buff; + *pbuff = new_buff; +} + +/* Free a chain of buffers starting at BUFF. */ +void +_cpp_free_buff (_cpp_buff *buff) +{ + _cpp_buff *next; + + for (; buff; buff = next) + { + next = buff->next; +#ifdef ENABLE_VALGRIND_ANNOTATIONS + free (buff); +#else + free (buff->base); +#endif + } +} + +/* Allocate permanent, unaligned storage of length LEN. */ +unsigned char * +_cpp_unaligned_alloc (cpp_reader *pfile, size_t len) +{ + _cpp_buff *buff = pfile->u_buff; + unsigned char *result = buff->cur; + + if (len > (size_t) (buff->limit - result)) + { + buff = _cpp_get_buff (pfile, len); + buff->next = pfile->u_buff; + pfile->u_buff = buff; + result = buff->cur; + } + + buff->cur = result + len; + return result; +} + +/* Allocate permanent, unaligned storage of length LEN from a_buff. + That buffer is used for growing allocations when saving macro + replacement lists in a #define, and when parsing an answer to an + assertion in #assert, #unassert or #if (and therefore possibly + whilst expanding macros). It therefore must not be used by any + code that they might call: specifically the lexer and the guts of + the macro expander. + + All existing other uses clearly fit this restriction: storing + registered pragmas during initialization. */ +unsigned char * +_cpp_aligned_alloc (cpp_reader *pfile, size_t len) +{ + _cpp_buff *buff = pfile->a_buff; + unsigned char *result = buff->cur; + + if (len > (size_t) (buff->limit - result)) + { + buff = _cpp_get_buff (pfile, len); + buff->next = pfile->a_buff; + pfile->a_buff = buff; + result = buff->cur; + } + + buff->cur = result + len; + return result; +} + +/* Commit or allocate storage from a buffer. */ + +void * +_cpp_commit_buff (cpp_reader *pfile, size_t size) +{ + void *ptr = BUFF_FRONT (pfile->a_buff); + + if (pfile->hash_table->alloc_subobject) + { + void *copy = pfile->hash_table->alloc_subobject (size); + memcpy (copy, ptr, size); + ptr = copy; + } + else + BUFF_FRONT (pfile->a_buff) += size; + + return ptr; +} + +/* Say which field of TOK is in use. */ + +enum cpp_token_fld_kind +cpp_token_val_index (const cpp_token *tok) +{ + switch (TOKEN_SPELL (tok)) + { + case SPELL_IDENT: + return CPP_TOKEN_FLD_NODE; + case SPELL_LITERAL: + return CPP_TOKEN_FLD_STR; + case SPELL_OPERATOR: + /* Operands which were originally spelled as ident keep around + the node for the exact spelling. */ + if (tok->flags & NAMED_OP) + return CPP_TOKEN_FLD_NODE; + else if (tok->type == CPP_PASTE) + return CPP_TOKEN_FLD_TOKEN_NO; + else + return CPP_TOKEN_FLD_NONE; + case SPELL_NONE: + if (tok->type == CPP_MACRO_ARG) + return CPP_TOKEN_FLD_ARG_NO; + else if (tok->type == CPP_PADDING) + return CPP_TOKEN_FLD_SOURCE; + else if (tok->type == CPP_PRAGMA) + return CPP_TOKEN_FLD_PRAGMA; + /* fall through */ + default: + return CPP_TOKEN_FLD_NONE; + } +} + +/* All tokens lexed in R after calling this function will be forced to + have their location_t to be P, until + cpp_stop_forcing_token_locations is called for R. */ + +void +cpp_force_token_locations (cpp_reader *r, location_t loc) +{ + r->forced_token_location = loc; +} + +/* Go back to assigning locations naturally for lexed tokens. */ + +void +cpp_stop_forcing_token_locations (cpp_reader *r) +{ + r->forced_token_location = 0; +} + +/* We're looking at \, if it's escaping EOL, look past it. If at + LIMIT, don't advance. */ + +static const unsigned char * +do_peek_backslash (const unsigned char *peek, const unsigned char *limit) +{ + const unsigned char *probe = peek; + + if (__builtin_expect (peek[1] == '\n', true)) + { + eol: + probe += 2; + if (__builtin_expect (probe < limit, true)) + { + peek = probe; + if (*peek == '\\') + /* The user might be perverse. */ + return do_peek_backslash (peek, limit); + } + } + else if (__builtin_expect (peek[1] == '\r', false)) + { + if (probe[2] == '\n') + probe++; + goto eol; + } + + return peek; +} + +static const unsigned char * +do_peek_next (const unsigned char *peek, const unsigned char *limit) +{ + if (__builtin_expect (*peek == '\\', false)) + peek = do_peek_backslash (peek, limit); + return peek; +} + +static const unsigned char * +do_peek_prev (const unsigned char *peek, const unsigned char *bound) +{ + if (peek == bound) + return NULL; + + unsigned char c = *--peek; + if (__builtin_expect (c == '\n', false) + || __builtin_expect (c == 'r', false)) + { + if (peek == bound) + return peek; + int ix = -1; + if (c == '\n' && peek[ix] == '\r') + { + if (peek + ix == bound) + return peek; + ix--; + } + + if (peek[ix] == '\\') + return do_peek_prev (peek + ix, bound); + + return peek; + } + else + return peek; +} + +/* If PEEK[-1] is identifier MATCH, scan past it and trailing white + space. Otherwise return NULL. */ + +static const unsigned char * +do_peek_ident (const char *match, const unsigned char *peek, + const unsigned char *limit) +{ + for (; *++match; peek++) + if (*peek != *match) + { + peek = do_peek_next (peek, limit); + if (*peek != *match) + return NULL; + } + + /* Must now not be looking at an identifier char. */ + peek = do_peek_next (peek, limit); + if (ISIDNUM (*peek)) + return NULL; + + /* Skip control-line whitespace. */ + ws: + while (*peek == ' ' || *peek == '\t') + peek++; + if (__builtin_expect (*peek == '\\', false)) + { + peek = do_peek_backslash (peek, limit); + if (*peek != '\\') + goto ws; + } + + return peek; +} + +/* Are we looking at a module control line starting as PEEK - 1? */ + +static bool +do_peek_module (cpp_reader *pfile, unsigned char c, + const unsigned char *peek, const unsigned char *limit) +{ + bool import = false; + + if (__builtin_expect (c == 'e', false)) + { + if (!((peek[0] == 'x' || peek[0] == '\\') + && (peek = do_peek_ident ("export", peek, limit)))) + return false; + + /* export, peek for import or module. No need to peek __import + here. */ + if (peek[0] == 'i') + { + if (!((peek[1] == 'm' || peek[1] == '\\') + && (peek = do_peek_ident ("import", peek + 1, limit)))) + return false; + import = true; + } + else if (peek[0] == 'm') + { + if (!((peek[1] == 'o' || peek[1] == '\\') + && (peek = do_peek_ident ("module", peek + 1, limit)))) + return false; + } + else + return false; + } + else if (__builtin_expect (c == 'i', false)) + { + if (!((peek[0] == 'm' || peek[0] == '\\') + && (peek = do_peek_ident ("import", peek, limit)))) + return false; + import = true; + } + else if (__builtin_expect (c == '_', false)) + { + /* Needed for translated includes. */ + if (!((peek[0] == '_' || peek[0] == '\\') + && (peek = do_peek_ident ("__import", peek, limit)))) + return false; + import = true; + } + else if (__builtin_expect (c == 'm', false)) + { + if (!((peek[0] == 'o' || peek[0] == '\\') + && (peek = do_peek_ident ("module", peek, limit)))) + return false; + } + else + return false; + + /* Peek the next character to see if it's good enough. We'll be at + the first non-whitespace char, including skipping an escaped + newline. */ + /* ... import followed by identifier, ':', '<' or header-name + preprocessing tokens, or module followed by identifier, ':' or + ';' preprocessing tokens. */ + unsigned char p = *peek++; + + /* A character literal is ... single quotes, ... optionally preceded + by u8, u, U, or L */ + /* A string-literal is a ... double quotes, optionally prefixed by + R, u8, u8R, u, uR, U, UR, L, or LR */ + if (p == 'u') + { + peek = do_peek_next (peek, limit); + if (*peek == '8') + { + peek++; + goto peek_u8; + } + goto peek_u; + } + else if (p == 'U' || p == 'L') + { + peek_u8: + peek = do_peek_next (peek, limit); + peek_u: + if (*peek == '\"' || *peek == '\'') + return false; + + if (*peek == 'R') + goto peek_R; + /* Identifier. Ok. */ + } + else if (p == 'R') + { + peek_R: + if (CPP_OPTION (pfile, rliterals)) + { + peek = do_peek_next (peek, limit); + if (*peek == '\"') + return false; + } + /* Identifier. Ok. */ + } + else if ('Z' - 'A' == 25 + ? ((p >= 'A' && p <= 'Z') || (p >= 'a' && p <= 'z') || p == '_') + : ISIDST (p)) + { + /* Identifier. Ok. */ + } + else if (p == '<') + { + /* Maybe angle header, ok for import. Reject + '<=', '<<' digraph:'<:'. */ + if (!import) + return false; + peek = do_peek_next (peek, limit); + if (*peek == '=' || *peek == '<' + || (*peek == ':' && CPP_OPTION (pfile, digraphs))) + return false; + } + else if (p == ';') + { + /* SEMICOLON, ok for module. */ + if (import) + return false; + } + else if (p == '"') + { + /* STRING, ok for import. */ + if (!import) + return false; + } + else if (p == ':') + { + /* Maybe COLON, ok. Reject '::', digraph:':>'. */ + peek = do_peek_next (peek, limit); + if (*peek == ':' || (*peek == '>' && CPP_OPTION (pfile, digraphs))) + return false; + } + else + /* FIXME: Detect a unicode character, excluding those not + permitted as the initial character. [lex.name]/1. I presume + we need to check the \[uU] spellings, and directly using + Unicode in say UTF8 form? Or perhaps we do the phase-1 + conversion of UTF8 to universal-character-names? */ + return false; + + return true; +} + +/* Directives-only scanning. Somewhat more relaxed than correct + parsing -- some ill-formed programs will not be rejected. */ + +void +cpp_directive_only_process (cpp_reader *pfile, + void *data, + void (*cb) (cpp_reader *, CPP_DO_task, void *, ...)) +{ + bool module_p = CPP_OPTION (pfile, module_directives); + + do + { + restart: + /* Buffer initialization, but no line cleaning. */ + cpp_buffer *buffer = pfile->buffer; + buffer->cur_note = buffer->notes_used = 0; + buffer->cur = buffer->line_base = buffer->next_line; + buffer->need_line = false; + /* Files always end in a newline or carriage return. We rely on this for + character peeking safety. */ + gcc_assert (buffer->rlimit[0] == '\n' || buffer->rlimit[0] == '\r'); + + const unsigned char *base = buffer->cur; + unsigned line_count = 0; + const unsigned char *line_start = base; + + bool bol = true; + bool raw = false; + + const unsigned char *lwm = base; + for (const unsigned char *pos = base, *limit = buffer->rlimit; + pos < limit;) + { + unsigned char c = *pos++; + /* This matches the switch in _cpp_lex_direct. */ + switch (c) + { + case ' ': case '\t': case '\f': case '\v': + /* Whitespace, do nothing. */ + break; + + case '\r': /* MAC line ending, or Windows \r\n */ + if (*pos == '\n') + pos++; + /* FALLTHROUGH */ + + case '\n': + bol = true; + + next_line: + CPP_INCREMENT_LINE (pfile, 0); + line_count++; + line_start = pos; + break; + + case '\\': + /* <backslash><newline> is removed, and doesn't undo any + preceeding escape or whatnot. */ + if (*pos == '\n') + { + pos++; + goto next_line; + } + else if (*pos == '\r') + { + if (pos[1] == '\n') + pos++; + pos++; + goto next_line; + } + goto dflt; + + case '#': + if (bol) + { + /* Line directive. */ + if (pos - 1 > base && !pfile->state.skipping) + cb (pfile, CPP_DO_print, data, + line_count, base, pos - 1 - base); + + /* Prep things for directive handling. */ + buffer->next_line = pos; + buffer->need_line = true; + bool ok = _cpp_get_fresh_line (pfile); + gcc_checking_assert (ok); + + /* Ensure proper column numbering for generated + error messages. */ + buffer->line_base -= pos - line_start; + + _cpp_handle_directive (pfile, line_start + 1 != pos); + + /* Sanitize the line settings. Duplicate #include's can + mess things up. */ + // FIXME: Necessary? + pfile->line_table->highest_location + = pfile->line_table->highest_line; + + if (!pfile->state.skipping + && pfile->buffer->next_line < pfile->buffer->rlimit) + cb (pfile, CPP_DO_location, data, + pfile->line_table->highest_line); + + goto restart; + } + goto dflt; + + case '/': + { + const unsigned char *peek = do_peek_next (pos, limit); + if (!(*peek == '/' || *peek == '*')) + goto dflt; + + /* Line or block comment */ + bool is_block = *peek == '*'; + bool star = false; + bool esc = false; + location_t sloc + = linemap_position_for_column (pfile->line_table, + pos - line_start); + + while (pos < limit) + { + char c = *pos++; + switch (c) + { + case '\\': + esc = true; + break; + + case '\r': + if (*pos == '\n') + pos++; + /* FALLTHROUGH */ + + case '\n': + { + CPP_INCREMENT_LINE (pfile, 0); + line_count++; + line_start = pos; + if (!esc && !is_block) + { + bol = true; + goto done_comment; + } + } + if (!esc) + star = false; + esc = false; + break; + + case '*': + if (pos > peek) + star = is_block; + esc = false; + break; + + case '/': + if (star) + goto done_comment; + /* FALLTHROUGH */ + + default: + star = false; + esc = false; + break; + } + } + if (pos < limit || is_block) + cpp_error_with_line (pfile, CPP_DL_ERROR, sloc, 0, + "unterminated comment"); + done_comment: + lwm = pos; + break; + } + + case '\'': + if (!CPP_OPTION (pfile, digit_separators)) + goto delimited_string; + + /* Possibly a number punctuator. */ + if (!ISIDNUM (*do_peek_next (pos, limit))) + goto delimited_string; + + goto quote_peek; + + case '\"': + if (!CPP_OPTION (pfile, rliterals)) + goto delimited_string; + + quote_peek: + { + /* For ' see if it's a number punctuator + \.?<digit>(<digit>|<identifier-nondigit> + |'<digit>|'<nondigit>|[eEpP]<sign>|\.)* */ + /* For " see if it's a raw string + {U,L,u,u8}R. This includes CPP_NUMBER detection, + because that could be 0e+R. */ + const unsigned char *peek = pos - 1; + bool quote_first = c == '"'; + bool quote_eight = false; + bool maybe_number_start = false; + bool want_number = false; + + while ((peek = do_peek_prev (peek, lwm))) + { + unsigned char p = *peek; + if (quote_first) + { + if (!raw) + { + if (p != 'R') + break; + raw = true; + continue; + } + + quote_first = false; + if (p == 'L' || p == 'U' || p == 'u') + ; + else if (p == '8') + quote_eight = true; + else + goto second_raw; + } + else if (quote_eight) + { + if (p != 'u') + { + raw = false; + break; + } + quote_eight = false; + } + else if (c == '"') + { + second_raw:; + if (!want_number && ISIDNUM (p)) + { + raw = false; + break; + } + } + + if (ISDIGIT (p)) + maybe_number_start = true; + else if (p == '.') + want_number = true; + else if (ISIDNUM (p)) + maybe_number_start = false; + else if (p == '+' || p == '-') + { + if (const unsigned char *peek_prev + = do_peek_prev (peek, lwm)) + { + p = *peek_prev; + if (p == 'e' || p == 'E' + || p == 'p' || p == 'P') + { + want_number = true; + maybe_number_start = false; + } + else + break; + } + else + break; + } + else if (p == '\'' || p == '\"') + { + /* If this is lwm, this must be the end of a + previous string. So this is a trailing + literal type, (a) if those are allowed, + and (b) maybe_start is false. Otherwise + this must be a CPP_NUMBER because we've + met another ', and we'd have checked that + in its own right. */ + if (peek == lwm && CPP_OPTION (pfile, uliterals)) + { + if (!maybe_number_start && !want_number) + /* Must be a literal type. */ + raw = false; + } + else if (p == '\'' + && CPP_OPTION (pfile, digit_separators)) + maybe_number_start = true; + break; + } + else if (c == '\'') + break; + else if (!quote_first && !quote_eight) + break; + } + + if (maybe_number_start) + { + if (c == '\'') + /* A CPP NUMBER. */ + goto dflt; + raw = false; + } + + goto delimited_string; + } + + delimited_string: + { + /* (Possibly raw) string or char literal. */ + unsigned char end = c; + int delim_len = -1; + const unsigned char *delim = NULL; + location_t sloc = linemap_position_for_column (pfile->line_table, + pos - line_start); + int esc = 0; + + if (raw) + { + /* There can be no line breaks in the delimiter. */ + delim = pos; + for (delim_len = 0; (c = *pos++) != '('; delim_len++) + { + if (delim_len == 16) + { + cpp_error_with_line (pfile, CPP_DL_ERROR, + sloc, 0, + "raw string delimiter" + " longer than %d" + " characters", + delim_len); + raw = false; + pos = delim; + break; + } + if (strchr (") \\\t\v\f\n", c)) + { + cpp_error_with_line (pfile, CPP_DL_ERROR, + sloc, 0, + "invalid character '%c'" + " in raw string" + " delimiter", c); + raw = false; + pos = delim; + break; + } + if (pos >= limit) + goto bad_string; + } + } + + while (pos < limit) + { + char c = *pos++; + switch (c) + { + case '\\': + if (!raw) + esc++; + break; + + case '\r': + if (*pos == '\n') + pos++; + /* FALLTHROUGH */ + + case '\n': + { + CPP_INCREMENT_LINE (pfile, 0); + line_count++; + line_start = pos; + } + if (esc) + esc--; + break; + + case ')': + if (raw + && pos + delim_len + 1 < limit + && pos[delim_len] == end + && !memcmp (delim, pos, delim_len)) + { + pos += delim_len + 1; + raw = false; + goto done_string; + } + break; + + default: + if (!raw && !(esc & 1) && c == end) + goto done_string; + esc = 0; + break; + } + } + bad_string: + cpp_error_with_line (pfile, CPP_DL_ERROR, sloc, 0, + "unterminated literal"); + + done_string: + raw = false; + lwm = pos - 1; + } + goto dflt; + + case '_': + case 'e': + case 'i': + case 'm': + if (bol && module_p && !pfile->state.skipping + && do_peek_module (pfile, c, pos, limit)) + { + /* We've seen the start of a module control line. + Start up the tokenizer. */ + pos--; /* Backup over the first character. */ + + /* Backup over whitespace to start of line. */ + while (pos > line_start + && (pos[-1] == ' ' || pos[-1] == '\t')) + pos--; + + if (pos > base) + cb (pfile, CPP_DO_print, data, line_count, base, pos - base); + + /* Prep things for directive handling. */ + buffer->next_line = pos; + buffer->need_line = true; + + /* Now get tokens until the PRAGMA_EOL. */ + do + { + location_t spelling; + const cpp_token *tok + = cpp_get_token_with_location (pfile, &spelling); + + gcc_assert (pfile->state.in_deferred_pragma + || tok->type == CPP_PRAGMA_EOL); + cb (pfile, CPP_DO_token, data, tok, spelling); + } + while (pfile->state.in_deferred_pragma); + + if (pfile->buffer->next_line < pfile->buffer->rlimit) + cb (pfile, CPP_DO_location, data, + pfile->line_table->highest_line); + + pfile->mi_valid = false; + goto restart; + } + goto dflt; + + default: + dflt: + bol = false; + pfile->mi_valid = false; + break; + } + } + + if (buffer->rlimit > base && !pfile->state.skipping) + { + const unsigned char *limit = buffer->rlimit; + /* If the file was not newline terminated, add rlimit, which is + guaranteed to point to a newline, to the end of our range. */ + if (limit[-1] != '\n') + { + limit++; + CPP_INCREMENT_LINE (pfile, 0); + line_count++; + } + cb (pfile, CPP_DO_print, data, line_count, base, limit - base); + } + + _cpp_pop_buffer (pfile); + } + while (pfile->buffer); +} diff --git a/support/cpp/libcpp/line-map.c b/support/cpp/libcpp/line-map.c deleted file mode 100644 index a82c4286f..000000000 --- a/support/cpp/libcpp/line-map.c +++ /dev/null @@ -1,319 +0,0 @@ -/* Map logical line numbers to (source file, line number) pairs. - Copyright (C) 2001, 2003, 2004, 2007, 2008, 2009 - Free Software Foundation, Inc. - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -#include "config.h" -#include "system.h" -#include "line-map.h" - -static void trace_include (const struct line_maps *, const struct line_map *); - -/* Initialize a line map set. */ - -void -linemap_init (struct line_maps *set) -{ - set->maps = NULL; - set->allocated = 0; - set->used = 0; - set->last_listed = -1; - set->trace_includes = false; - set->depth = 0; - set->cache = 0; - set->highest_location = RESERVED_LOCATION_COUNT - 1; - set->highest_line = RESERVED_LOCATION_COUNT - 1; - set->max_column_hint = 0; - set->reallocator = 0; -} - -/* Check for and warn about line_maps entered but not exited. */ - -void -linemap_check_files_exited (struct line_maps *set) -{ - struct line_map *map; - /* Depending upon whether we are handling preprocessed input or - not, this can be a user error or an ICE. */ - for (map = &set->maps[set->used - 1]; ! MAIN_FILE_P (map); - map = INCLUDED_FROM (set, map)) - fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n", - map->to_file); -} - -/* Free a line map set. */ - -void -linemap_free (struct line_maps *set) -{ - if (set->maps) - { - linemap_check_files_exited (set); - - free (set->maps); - } -} - -/* Add a mapping of logical source line to physical source file and - line number. - - The text pointed to by TO_FILE must have a lifetime - at least as long as the final call to lookup_line (). An empty - TO_FILE means standard input. If reason is LC_LEAVE, and - TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their - natural values considering the file we are returning to. - - FROM_LINE should be monotonic increasing across calls to this - function. A call to this function can relocate the previous set of - maps, so any stored line_map pointers should not be used. */ - -const struct line_map * -linemap_add (struct line_maps *set, enum lc_reason reason, - unsigned int sysp, const char *to_file, linenum_type to_line) -{ - struct line_map *map; - source_location start_location = set->highest_location + 1; - - if (set->used && start_location < set->maps[set->used - 1].start_location) - abort (); - - if (set->used == set->allocated) - { - line_map_realloc reallocator - = set->reallocator ? set->reallocator : xrealloc; - set->allocated = 2 * set->allocated + 256; - set->maps - = (struct line_map *) (*reallocator) (set->maps, - set->allocated - * sizeof (struct line_map)); - memset (&set->maps[set->used], 0, ((set->allocated - set->used) - * sizeof (struct line_map))); - } - - map = &set->maps[set->used]; - - if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM) - to_file = "<stdin>"; - - if (reason == LC_RENAME_VERBATIM) - reason = LC_RENAME; - - /* If we don't keep our line maps consistent, we can easily - segfault. Don't rely on the client to do it for us. */ - if (set->depth == 0) - reason = LC_ENTER; - else if (reason == LC_LEAVE) - { - struct line_map *from; - bool error; - - if (MAIN_FILE_P (map - 1)) - { - if (to_file == NULL) - { - set->depth--; - return NULL; - } - error = true; - reason = LC_RENAME; - from = map - 1; - } - else - { - from = INCLUDED_FROM (set, map - 1); - error = to_file && strcmp (from->to_file, to_file); - } - - /* Depending upon whether we are handling preprocessed input or - not, this can be a user error or an ICE. */ - if (error) - fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n", - to_file); - - /* A TO_FILE of NULL is special - we use the natural values. */ - if (error || to_file == NULL) - { - to_file = from->to_file; - to_line = SOURCE_LINE (from, from[1].start_location); - sysp = from->sysp; - } - } - - map->reason = reason; - map->sysp = sysp; - map->start_location = start_location; - map->to_file = to_file; - map->to_line = to_line; - set->cache = set->used++; - map->column_bits = 0; - set->highest_location = start_location; - set->highest_line = start_location; - set->max_column_hint = 0; - - if (reason == LC_ENTER) - { - map->included_from = set->depth == 0 ? -1 : (int) (set->used - 2); - set->depth++; - if (set->trace_includes) - trace_include (set, map); - } - else if (reason == LC_RENAME) - map->included_from = map[-1].included_from; - else if (reason == LC_LEAVE) - { - set->depth--; - map->included_from = INCLUDED_FROM (set, map - 1)->included_from; - } - - return map; -} - -source_location -linemap_line_start (struct line_maps *set, linenum_type to_line, - unsigned int max_column_hint) -{ - struct line_map *map = &set->maps[set->used - 1]; - source_location highest = set->highest_location; - source_location r; - linenum_type last_line = SOURCE_LINE (map, set->highest_line); - int line_delta = to_line - last_line; - bool add_map = false; - if (line_delta < 0 - || (line_delta > 10 && line_delta * map->column_bits > 1000) - || (max_column_hint >= (1U << map->column_bits)) - || (max_column_hint <= 80 && map->column_bits >= 10)) - { - add_map = true; - } - else - max_column_hint = set->max_column_hint; - if (add_map) - { - int column_bits; - if (max_column_hint > 100000 || highest > 0xC0000000) - { - /* If the column number is ridiculous or we've allocated a huge - number of source_locations, give up on column numbers. */ - max_column_hint = 0; - if (highest >0xF0000000) - return 0; - column_bits = 0; - } - else - { - column_bits = 7; - while (max_column_hint >= (1U << column_bits)) - column_bits++; - max_column_hint = 1U << column_bits; - } - /* Allocate the new line_map. However, if the current map only has a - single line we can sometimes just increase its column_bits instead. */ - if (line_delta < 0 - || last_line != map->to_line - || SOURCE_COLUMN (map, highest) >= (1U << column_bits)) - map = (struct line_map *) linemap_add (set, LC_RENAME, map->sysp, - map->to_file, to_line); - map->column_bits = column_bits; - r = map->start_location + ((to_line - map->to_line) << column_bits); - } - else - r = highest - SOURCE_COLUMN (map, highest) - + (line_delta << map->column_bits); - set->highest_line = r; - if (r > set->highest_location) - set->highest_location = r; - set->max_column_hint = max_column_hint; - return r; -} - -source_location -linemap_position_for_column (struct line_maps *set, unsigned int to_column) -{ - source_location r = set->highest_line; - if (to_column >= set->max_column_hint) - { - if (r >= 0xC000000 || to_column > 100000) - { - /* Running low on source_locations - disable column numbers. */ - return r; - } - else - { - struct line_map *map = &set->maps[set->used - 1]; - r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50); - } - } - r = r + to_column; - if (r >= set->highest_location) - set->highest_location = r; - return r; -} - -/* Given a logical line, returns the map from which the corresponding - (source file, line) pair can be deduced. Since the set is built - chronologically, the logical lines are monotonic increasing, and so - the list is sorted and we can use a binary search. */ - -const struct line_map * -linemap_lookup (struct line_maps *set, source_location line) -{ - unsigned int md, mn, mx; - const struct line_map *cached; - - mn = set->cache; - mx = set->used; - - cached = &set->maps[mn]; - /* We should get a segfault if no line_maps have been added yet. */ - if (line >= cached->start_location) - { - if (mn + 1 == mx || line < cached[1].start_location) - return cached; - } - else - { - mx = mn; - mn = 0; - } - - while (mx - mn > 1) - { - md = (mn + mx) / 2; - if (set->maps[md].start_location > line) - mx = md; - else - mn = md; - } - - set->cache = mn; - return &set->maps[mn]; -} - -/* Print an include trace, for e.g. the -H option of the preprocessor. */ - -static void -trace_include (const struct line_maps *set, const struct line_map *map) -{ - unsigned int i = set->depth; - - while (--i) - putc ('.', stderr); - fprintf (stderr, " %s\n", map->to_file); -} diff --git a/support/cpp/libcpp/line-map.cc b/support/cpp/libcpp/line-map.cc new file mode 100644 index 000000000..62077c385 --- /dev/null +++ b/support/cpp/libcpp/line-map.cc @@ -0,0 +1,2555 @@ +/* Map (unsigned int) keys to (source file, line, column) triples. + Copyright (C) 2001-2022 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! */ + +#include "config.h" +#include "system.h" +#include "line-map.h" +#include "cpplib.h" +#include "internal.h" +#include "hashtab.h" + +static void trace_include (const line_maps *, const line_map_ordinary *); +static const line_map_ordinary * linemap_ordinary_map_lookup (const line_maps *, + location_t); +static const line_map_macro* linemap_macro_map_lookup (const line_maps *, + location_t); +static location_t linemap_macro_map_loc_to_def_point +(const line_map_macro *, location_t); +static location_t linemap_macro_map_loc_to_exp_point +(const line_map_macro *, location_t); +static location_t linemap_macro_loc_to_spelling_point +(line_maps *, location_t, const line_map_ordinary **); +static location_t linemap_macro_loc_to_def_point (line_maps *, + location_t, + const line_map_ordinary **); +static location_t linemap_macro_loc_to_exp_point (line_maps *, + location_t, + const line_map_ordinary **); + +/* Counters defined in macro.cc. */ +extern unsigned num_expanded_macros_counter; +extern unsigned num_macro_tokens_counter; + +/* Destructor for class line_maps. + Ensure non-GC-managed memory is released. */ + +line_maps::~line_maps () +{ + if (location_adhoc_data_map.htab) + htab_delete (location_adhoc_data_map.htab); +} + +/* Hash function for location_adhoc_data hashtable. */ + +static hashval_t +location_adhoc_data_hash (const void *l) +{ + const struct location_adhoc_data *lb = + (const struct location_adhoc_data *) l; + return ((hashval_t) lb->locus + + (hashval_t) lb->src_range.m_start + + (hashval_t) lb->src_range.m_finish + + (size_t) lb->data); +} + +/* Compare function for location_adhoc_data hashtable. */ + +static int +location_adhoc_data_eq (const void *l1, const void *l2) +{ + const struct location_adhoc_data *lb1 = + (const struct location_adhoc_data *) l1; + const struct location_adhoc_data *lb2 = + (const struct location_adhoc_data *) l2; + return (lb1->locus == lb2->locus + && lb1->src_range.m_start == lb2->src_range.m_start + && lb1->src_range.m_finish == lb2->src_range.m_finish + && lb1->data == lb2->data); +} + +/* Update the hashtable when location_adhoc_data is reallocated. */ + +static int +location_adhoc_data_update (void **slot, void *data) +{ + *((char **) slot) + = (char *) ((uintptr_t) *((char **) slot) + *((ptrdiff_t *) data)); + return 1; +} + +/* Rebuild the hash table from the location adhoc data. */ + +void +rebuild_location_adhoc_htab (line_maps *set) +{ + unsigned i; + set->location_adhoc_data_map.htab = + htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL); + for (i = 0; i < set->location_adhoc_data_map.curr_loc; i++) + htab_find_slot (set->location_adhoc_data_map.htab, + set->location_adhoc_data_map.data + i, INSERT); +} + +/* Helper function for get_combined_adhoc_loc. + Can the given LOCUS + SRC_RANGE and DATA pointer be stored compactly + within a location_t, without needing to use an ad-hoc location. */ + +static bool +can_be_stored_compactly_p (line_maps *set, + location_t locus, + source_range src_range, + void *data) +{ + /* If there's an ad-hoc pointer, we can't store it directly in the + location_t, we need the lookaside. */ + if (data) + return false; + + /* We only store ranges that begin at the locus and that are sufficiently + "sane". */ + if (src_range.m_start != locus) + return false; + + if (src_range.m_finish < src_range.m_start) + return false; + + if (src_range.m_start < RESERVED_LOCATION_COUNT) + return false; + + if (locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES) + return false; + + /* All 3 locations must be within ordinary maps, typically, the same + ordinary map. */ + location_t lowest_macro_loc = LINEMAPS_MACRO_LOWEST_LOCATION (set); + if (locus >= lowest_macro_loc) + return false; + if (src_range.m_start >= lowest_macro_loc) + return false; + if (src_range.m_finish >= lowest_macro_loc) + return false; + + /* Passed all tests. */ + return true; +} + +/* Combine LOCUS and DATA to a combined adhoc loc. */ + +location_t +get_combined_adhoc_loc (line_maps *set, + location_t locus, + source_range src_range, + void *data) +{ + struct location_adhoc_data lb; + struct location_adhoc_data **slot; + + if (IS_ADHOC_LOC (locus)) + locus = get_location_from_adhoc_loc (set, locus); + if (locus == 0 && data == NULL) + return 0; + + /* Any ordinary locations ought to be "pure" at this point: no + compressed ranges. */ + linemap_assert (locus < RESERVED_LOCATION_COUNT + || locus >= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES + || locus >= LINEMAPS_MACRO_LOWEST_LOCATION (set) + || pure_location_p (set, locus)); + + /* Consider short-range optimization. */ + if (can_be_stored_compactly_p (set, locus, src_range, data)) + { + /* The low bits ought to be clear. */ + linemap_assert (pure_location_p (set, locus)); + const line_map *map = linemap_lookup (set, locus); + const line_map_ordinary *ordmap = linemap_check_ordinary (map); + unsigned int int_diff = src_range.m_finish - src_range.m_start; + unsigned int col_diff = (int_diff >> ordmap->m_range_bits); + if (col_diff < (1U << ordmap->m_range_bits)) + { + location_t packed = locus | col_diff; + set->num_optimized_ranges++; + return packed; + } + } + + /* We can also compactly store locations + when locus == start == finish (and data is NULL). */ + if (locus == src_range.m_start + && locus == src_range.m_finish + && !data) + return locus; + + if (!data) + set->num_unoptimized_ranges++; + + lb.locus = locus; + lb.src_range = src_range; + lb.data = data; + slot = (struct location_adhoc_data **) + htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT); + if (*slot == NULL) + { + if (set->location_adhoc_data_map.curr_loc >= + set->location_adhoc_data_map.allocated) + { + char *orig_data = (char *) set->location_adhoc_data_map.data; + ptrdiff_t offset; + /* Cast away extern "C" from the type of xrealloc. */ + line_map_realloc reallocator = (set->reallocator + ? set->reallocator + : (line_map_realloc) xrealloc); + + if (set->location_adhoc_data_map.allocated == 0) + set->location_adhoc_data_map.allocated = 128; + else + set->location_adhoc_data_map.allocated *= 2; + set->location_adhoc_data_map.data = (struct location_adhoc_data *) + reallocator (set->location_adhoc_data_map.data, + set->location_adhoc_data_map.allocated + * sizeof (struct location_adhoc_data)); + offset = (char *) (set->location_adhoc_data_map.data) - orig_data; + if (set->location_adhoc_data_map.allocated > 128) + htab_traverse (set->location_adhoc_data_map.htab, + location_adhoc_data_update, &offset); + } + *slot = set->location_adhoc_data_map.data + + set->location_adhoc_data_map.curr_loc; + set->location_adhoc_data_map.data[set->location_adhoc_data_map.curr_loc++] + = lb; + } + return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000; +} + +/* Return the data for the adhoc loc. */ + +void * +get_data_from_adhoc_loc (const class line_maps *set, location_t loc) +{ + linemap_assert (IS_ADHOC_LOC (loc)); + return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].data; +} + +/* Return the location for the adhoc loc. */ + +location_t +get_location_from_adhoc_loc (const class line_maps *set, location_t loc) +{ + linemap_assert (IS_ADHOC_LOC (loc)); + return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus; +} + +/* Return the source_range for adhoc location LOC. */ + +static source_range +get_range_from_adhoc_loc (const class line_maps *set, location_t loc) +{ + linemap_assert (IS_ADHOC_LOC (loc)); + return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].src_range; +} + +/* Get the source_range of location LOC, either from the ad-hoc + lookaside table, or embedded inside LOC itself. */ + +source_range +get_range_from_loc (line_maps *set, + location_t loc) +{ + if (IS_ADHOC_LOC (loc)) + return get_range_from_adhoc_loc (set, loc); + + /* For ordinary maps, extract packed range. */ + if (loc >= RESERVED_LOCATION_COUNT + && loc < LINEMAPS_MACRO_LOWEST_LOCATION (set) + && loc <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES) + { + const line_map *map = linemap_lookup (set, loc); + const line_map_ordinary *ordmap = linemap_check_ordinary (map); + source_range result; + int offset = loc & ((1 << ordmap->m_range_bits) - 1); + result.m_start = loc - offset; + result.m_finish = result.m_start + (offset << ordmap->m_range_bits); + return result; + } + + return source_range::from_location (loc); +} + +/* Get whether location LOC is a "pure" location, or + whether it is an ad-hoc location, or embeds range information. */ + +bool +pure_location_p (line_maps *set, location_t loc) +{ + if (IS_ADHOC_LOC (loc)) + return false; + + const line_map *map = linemap_lookup (set, loc); + if (map == NULL) + return true; + const line_map_ordinary *ordmap = linemap_check_ordinary (map); + + if (loc & ((1U << ordmap->m_range_bits) - 1)) + return false; + + return true; +} + +/* Given location LOC within SET, strip away any packed range information + or ad-hoc information. */ + +location_t +get_pure_location (line_maps *set, location_t loc) +{ + if (IS_ADHOC_LOC (loc)) + loc = get_location_from_adhoc_loc (set, loc); + + if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (set)) + return loc; + + if (loc < RESERVED_LOCATION_COUNT) + return loc; + + const line_map *map = linemap_lookup (set, loc); + const line_map_ordinary *ordmap = linemap_check_ordinary (map); + + return loc & ~((1 << ordmap->m_range_bits) - 1); +} + +/* Initialize a line map set. */ + +void +linemap_init (line_maps *set, + location_t builtin_location) +{ +#if __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined (__clang__) + /* PR33916, needed to fix PR82939. */ + memset (set, 0, sizeof (line_maps)); +#else + new (set) line_maps(); +#endif + /* Set default reallocator (used for initial alloc too). */ + set->reallocator = xrealloc; + set->highest_location = RESERVED_LOCATION_COUNT - 1; + set->highest_line = RESERVED_LOCATION_COUNT - 1; + set->location_adhoc_data_map.htab = + htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL); + set->builtin_location = builtin_location; +} + +/* Return the ordinary line map from whence MAP was included. Returns + NULL if MAP was not an include. */ + +const line_map_ordinary * +linemap_included_from_linemap (line_maps *set, const line_map_ordinary *map) +{ + return linemap_ordinary_map_lookup (set, linemap_included_from (map)); +} + +/* Check for and warn about line_maps entered but not exited. */ + +void +linemap_check_files_exited (line_maps *set) +{ + /* Depending upon whether we are handling preprocessed input or + not, this can be a user error or an ICE. */ + for (const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set); + ! MAIN_FILE_P (map); + map = linemap_included_from_linemap (set, map)) + fprintf (stderr, "line-map.cc: file \"%s\" entered but not left\n", + ORDINARY_MAP_FILE_NAME (map)); +} + +/* Create NUM zero-initialized maps of type MACRO_P. */ + +line_map * +line_map_new_raw (line_maps *set, bool macro_p, unsigned num) +{ + unsigned num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p); + unsigned num_maps_used = LINEMAPS_USED (set, macro_p); + + if (num > num_maps_allocated - num_maps_used) + { + /* We need more space! */ + if (!num_maps_allocated) + num_maps_allocated = 128; + if (num_maps_allocated < num_maps_used + num) + num_maps_allocated = num_maps_used + num; + num_maps_allocated *= 2; + + size_t size_of_a_map; + void *buffer; + if (macro_p) + { + size_of_a_map = sizeof (line_map_macro); + buffer = set->info_macro.maps; + } + else + { + size_of_a_map = sizeof (line_map_ordinary); + buffer = set->info_ordinary.maps; + } + + /* We are going to execute some dance to try to reduce the + overhead of the memory allocator, in case we are using the + ggc-page.cc one. + + The actual size of memory we are going to get back from the + allocator may well be larger than what we ask for. Use this + hook to find what that size is. */ + size_t alloc_size + = set->round_alloc_size (num_maps_allocated * size_of_a_map); + + /* Now alloc_size contains the exact memory size we would get if + we have asked for the initial alloc_size amount of memory. + Let's get back to the number of map that amounts to. */ + unsigned num_maps = alloc_size / size_of_a_map; + buffer = set->reallocator (buffer, num_maps * size_of_a_map); + memset ((char *)buffer + num_maps_used * size_of_a_map, 0, + (num_maps - num_maps_used) * size_of_a_map); + if (macro_p) + set->info_macro.maps = (line_map_macro *)buffer; + else + set->info_ordinary.maps = (line_map_ordinary *)buffer; + LINEMAPS_ALLOCATED (set, macro_p) = num_maps; + } + + line_map *result = (macro_p ? (line_map *)&set->info_macro.maps[num_maps_used] + : (line_map *)&set->info_ordinary.maps[num_maps_used]); + LINEMAPS_USED (set, macro_p) += num; + + return result; +} + +/* Create a new line map in the line map set SET, and return it. + REASON is the reason of creating the map. It determines the type + of map created (ordinary or macro map). Note that ordinary maps and + macro maps are allocated in different memory location. */ + +static struct line_map * +new_linemap (line_maps *set, location_t start_location) +{ + line_map *result = line_map_new_raw (set, + start_location >= LINE_MAP_MAX_LOCATION, + 1); + + result->start_location = start_location; + + return result; +} + +/* Return the location of the last source line within an ordinary + map. */ +inline location_t +LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map) +{ + return (((map[1].start_location - 1 + - map->start_location) + & ~((1 << map->m_column_and_range_bits) - 1)) + + map->start_location); +} + +/* Add a mapping of logical source line to physical source file and + line number. + + The text pointed to by TO_FILE must have a lifetime + at least as long as the final call to lookup_line (). An empty + TO_FILE means standard input. If reason is LC_LEAVE, and + TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their + natural values considering the file we are returning to. + + FROM_LINE should be monotonic increasing across calls to this + function. A call to this function can relocate the previous set of + maps, so any stored line_map pointers should not be used. */ + +const struct line_map * +linemap_add (line_maps *set, enum lc_reason reason, + unsigned int sysp, const char *to_file, linenum_type to_line) +{ + /* Generate a start_location above the current highest_location. + If possible, make the low range bits be zero. */ + location_t start_location = set->highest_location + 1; + unsigned range_bits = 0; + if (start_location < LINE_MAP_MAX_LOCATION_WITH_COLS) + range_bits = set->default_range_bits; + start_location += (1 << range_bits) - 1; + start_location &= ~((1 << range_bits) - 1); + + linemap_assert (!LINEMAPS_ORDINARY_USED (set) + || (start_location + >= MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (set)))); + + /* When we enter the file for the first time reason cannot be + LC_RENAME. */ + linemap_assert (!(set->depth == 0 && reason == LC_RENAME)); + + /* If we are leaving the main file, return a NULL map. */ + if (reason == LC_LEAVE + && MAIN_FILE_P (LINEMAPS_LAST_ORDINARY_MAP (set)) + && to_file == NULL) + { + set->depth--; + return NULL; + } + + linemap_assert (reason != LC_ENTER_MACRO); + + if (start_location >= LINE_MAP_MAX_LOCATION) + /* We ran out of line map space. */ + start_location = 0; + + line_map_ordinary *map + = linemap_check_ordinary (new_linemap (set, start_location)); + map->reason = reason; + + if (to_file && *to_file == '\0' && reason != LC_RENAME_VERBATIM) + to_file = "<stdin>"; + + if (reason == LC_RENAME_VERBATIM) + reason = LC_RENAME; + + const line_map_ordinary *from = NULL; + if (reason == LC_LEAVE) + { + /* When we are just leaving an "included" file, and jump to the next + location inside the "includer" right after the #include + "included", this variable points the map in use right before the + #include "included", inside the same "includer" file. */ + + linemap_assert (!MAIN_FILE_P (map - 1)); + /* (MAP - 1) points to the map we are leaving. The + map from which (MAP - 1) got included should be the map + that comes right before MAP in the same file. */ + from = linemap_included_from_linemap (set, map - 1); + + /* A TO_FILE of NULL is special - we use the natural values. */ + if (to_file == NULL) + { + to_file = ORDINARY_MAP_FILE_NAME (from); + to_line = SOURCE_LINE (from, from[1].start_location); + sysp = ORDINARY_MAP_IN_SYSTEM_HEADER_P (from); + } + else + linemap_assert (filename_cmp (ORDINARY_MAP_FILE_NAME (from), + to_file) == 0); + } + + map->sysp = sysp; + map->to_file = to_file; + map->to_line = to_line; + LINEMAPS_ORDINARY_CACHE (set) = LINEMAPS_ORDINARY_USED (set) - 1; + /* Do not store range_bits here. That's readjusted in + linemap_line_start. */ + map->m_range_bits = map->m_column_and_range_bits = 0; + set->highest_location = start_location; + set->highest_line = start_location; + set->max_column_hint = 0; + + /* This assertion is placed after set->highest_location has + been updated, since the latter affects + linemap_location_from_macro_expansion_p, which ultimately affects + pure_location_p. */ + linemap_assert (pure_location_p (set, start_location)); + + if (reason == LC_ENTER) + { + if (set->depth == 0) + map->included_from = 0; + else + /* The location of the end of the just-closed map. */ + map->included_from + = (((map[0].start_location - 1 - map[-1].start_location) + & ~((1 << map[-1].m_column_and_range_bits) - 1)) + + map[-1].start_location); + set->depth++; + if (set->trace_includes) + trace_include (set, map); + } + else if (reason == LC_RENAME) + map->included_from = linemap_included_from (&map[-1]); + else if (reason == LC_LEAVE) + { + set->depth--; + map->included_from = linemap_included_from (from); + } + + return map; +} + +/* Create a location for a module NAME imported at FROM. */ + +location_t +linemap_module_loc (line_maps *set, location_t from, const char *name) +{ + const line_map_ordinary *map + = linemap_check_ordinary (linemap_add (set, LC_MODULE, false, name, 0)); + const_cast <line_map_ordinary *> (map)->included_from = from; + + location_t loc = linemap_line_start (set, 0, 0); + + return loc; +} + +/* The linemap containing LOC is being reparented to be + imported/included from ADOPTOR. This can happen when an + indirectly imported module is then directly imported, or when + partitions are involved. */ + +void +linemap_module_reparent (line_maps *set, location_t loc, location_t adoptor) +{ + const line_map_ordinary *map = linemap_ordinary_map_lookup (set, loc); + const_cast<line_map_ordinary *> (map)->included_from = adoptor; +} + +/* A linemap at LWM-1 was interrupted to insert module locations & imports. + Append a new map, continuing the interrupted one. Return the start location + of the new map, or 0 if failed (because we ran out of locations. */ + +unsigned +linemap_module_restore (line_maps *set, unsigned lwm) +{ + linemap_assert (lwm); + + const line_map_ordinary *pre_map + = linemap_check_ordinary (LINEMAPS_MAP_AT (set, false, lwm - 1)); + unsigned src_line = SOURCE_LINE (pre_map, LAST_SOURCE_LINE_LOCATION (pre_map)); + location_t inc_at = pre_map->included_from; + if (const line_map_ordinary *post_map + = (linemap_check_ordinary + (linemap_add (set, LC_RENAME_VERBATIM, + ORDINARY_MAP_IN_SYSTEM_HEADER_P (pre_map), + ORDINARY_MAP_FILE_NAME (pre_map), src_line)))) + { + /* linemap_add will think we were included from the same as the preceeding + map. */ + const_cast <line_map_ordinary *> (post_map)->included_from = inc_at; + + return post_map->start_location; + } + + return 0; +} + +/* Returns TRUE if the line table set tracks token locations across + macro expansion, FALSE otherwise. */ + +bool +linemap_tracks_macro_expansion_locs_p (line_maps *set) +{ + return LINEMAPS_MACRO_MAPS (set) != NULL; +} + +/* Create a macro map. A macro map encodes source locations of tokens + that are part of a macro replacement-list, at a macro expansion + point. See the extensive comments of struct line_map and struct + line_map_macro, in line-map.h. + + This map shall be created when the macro is expanded. The map + encodes the source location of the expansion point of the macro as + well as the "original" source location of each token that is part + of the macro replacement-list. If a macro is defined but never + expanded, it has no macro map. SET is the set of maps the macro + map should be part of. MACRO_NODE is the macro which the new macro + map should encode source locations for. EXPANSION is the location + of the expansion point of MACRO. For function-like macros + invocations, it's best to make it point to the closing parenthesis + of the macro, rather than the the location of the first character + of the macro. NUM_TOKENS is the number of tokens that are part of + the replacement-list of MACRO. + + Note that when we run out of the integer space available for source + locations, this function returns NULL. In that case, callers of + this function cannot encode {line,column} pairs into locations of + macro tokens anymore. */ + +const line_map_macro * +linemap_enter_macro (class line_maps *set, struct cpp_hashnode *macro_node, + location_t expansion, unsigned int num_tokens) +{ + location_t start_location + = LINEMAPS_MACRO_LOWEST_LOCATION (set) - num_tokens; + + if (start_location < LINE_MAP_MAX_LOCATION) + /* We ran out of macro map space. */ + return NULL; + + line_map_macro *map = linemap_check_macro (new_linemap (set, start_location)); + + map->macro = macro_node; + map->n_tokens = num_tokens; + map->macro_locations + = (location_t*) set->reallocator (NULL, + 2 * num_tokens + * sizeof (location_t)); + map->expansion = expansion; + memset (MACRO_MAP_LOCATIONS (map), 0, + 2 * num_tokens * sizeof (location_t)); + + LINEMAPS_MACRO_CACHE (set) = LINEMAPS_MACRO_USED (set) - 1; + + return map; +} + +/* Create and return a virtual location for a token that is part of a + macro expansion-list at a macro expansion point. See the comment + inside struct line_map_macro to see what an expansion-list exactly + is. + + A call to this function must come after a call to + linemap_enter_macro. + + MAP is the map into which the source location is created. TOKEN_NO + is the index of the token in the macro replacement-list, starting + at number 0. + + ORIG_LOC is the location of the token outside of this macro + expansion. If the token comes originally from the macro + definition, it is the locus in the macro definition; otherwise it + is a location in the context of the caller of this macro expansion + (which is a virtual location or a source location if the caller is + itself a macro expansion or not). + + ORIG_PARM_REPLACEMENT_LOC is the location in the macro definition, + either of the token itself or of a macro parameter that it + replaces. */ + +location_t +linemap_add_macro_token (const line_map_macro *map, + unsigned int token_no, + location_t orig_loc, + location_t orig_parm_replacement_loc) +{ + location_t result; + + linemap_assert (linemap_macro_expansion_map_p (map)); + linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map)); + + MACRO_MAP_LOCATIONS (map)[2 * token_no] = orig_loc; + MACRO_MAP_LOCATIONS (map)[2 * token_no + 1] = orig_parm_replacement_loc; + + result = MAP_START_LOCATION (map) + token_no; + return result; +} + +/* Return a location_t for the start (i.e. column==0) of + (physical) line TO_LINE in the current source file (as in the + most recent linemap_add). MAX_COLUMN_HINT is the highest column + number we expect to use in this line (but it does not change + the highest_location). */ + +location_t +linemap_line_start (line_maps *set, linenum_type to_line, + unsigned int max_column_hint) +{ + line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set); + location_t highest = set->highest_location; + location_t r; + linenum_type last_line = + SOURCE_LINE (map, set->highest_line); + int line_delta = to_line - last_line; + bool add_map = false; + linemap_assert (map->m_column_and_range_bits >= map->m_range_bits); + int effective_column_bits = map->m_column_and_range_bits - map->m_range_bits; + + if (line_delta < 0 + || (line_delta > 10 + && line_delta * map->m_column_and_range_bits > 1000) + || (max_column_hint >= (1U << effective_column_bits)) + || (max_column_hint <= 80 && effective_column_bits >= 10) + || (highest > LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES + && map->m_range_bits > 0) + || (highest > LINE_MAP_MAX_LOCATION_WITH_COLS + && (set->max_column_hint || highest >= LINE_MAP_MAX_LOCATION))) + add_map = true; + else + max_column_hint = set->max_column_hint; + if (add_map) + { + int column_bits; + int range_bits; + if (max_column_hint > LINE_MAP_MAX_COLUMN_NUMBER + || highest > LINE_MAP_MAX_LOCATION_WITH_COLS) + { + /* If the column number is ridiculous or we've allocated a huge + number of location_ts, give up on column numbers + (and on packed ranges). */ + max_column_hint = 1; + column_bits = 0; + range_bits = 0; + if (highest >= LINE_MAP_MAX_LOCATION) + goto overflowed; + } + else + { + column_bits = 7; + if (highest <= LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES) + range_bits = set->default_range_bits; + else + range_bits = 0; + while (max_column_hint >= (1U << column_bits)) + column_bits++; + max_column_hint = 1U << column_bits; + column_bits += range_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 != ORDINARY_MAP_STARTING_LINE_NUMBER (map) + || SOURCE_COLUMN (map, highest) >= (1U << (column_bits - range_bits)) + || ( /* We can't reuse the map if the line offset is sufficiently + large to cause overflow when computing location_t values. */ + (to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map)) + >= (((uint64_t) 1) + << (CHAR_BIT * sizeof (linenum_type) - column_bits))) + || range_bits < map->m_range_bits) + map = linemap_check_ordinary + (const_cast <line_map *> + (linemap_add (set, LC_RENAME, + ORDINARY_MAP_IN_SYSTEM_HEADER_P (map), + ORDINARY_MAP_FILE_NAME (map), + to_line))); + map->m_column_and_range_bits = column_bits; + map->m_range_bits = range_bits; + r = (MAP_START_LOCATION (map) + + ((to_line - ORDINARY_MAP_STARTING_LINE_NUMBER (map)) + << column_bits)); + } + else + r = set->highest_line + (line_delta << map->m_column_and_range_bits); + + /* Locations of ordinary tokens are always lower than locations of + macro tokens. */ + if (r >= LINE_MAP_MAX_LOCATION) + { + overflowed: + /* Remember we overflowed. */ + set->highest_line = set->highest_location = LINE_MAP_MAX_LOCATION - 1; + /* No column numbers! */ + set->max_column_hint = 1; + return 0; + } + + set->highest_line = r; + if (r > set->highest_location) + set->highest_location = r; + set->max_column_hint = max_column_hint; + + /* At this point, we expect one of: + (a) the normal case: a "pure" location with 0 range bits, or + (b) we've gone past LINE_MAP_MAX_LOCATION_WITH_COLS so can't track + columns anymore (or ranges), or + (c) we're in a region with a column hint exceeding + LINE_MAP_MAX_COLUMN_NUMBER, so column-tracking is off, + with column_bits == 0. */ + linemap_assert (pure_location_p (set, r) + || r >= LINE_MAP_MAX_LOCATION_WITH_COLS + || map->m_column_and_range_bits == 0); + linemap_assert (SOURCE_LINE (map, r) == to_line); + return r; +} + +/* Encode and return a location_t from a column number. The + source line considered is the last source line used to call + linemap_line_start, i.e, the last source line which a location was + encoded from. */ + +location_t +linemap_position_for_column (line_maps *set, unsigned int to_column) +{ + location_t r = set->highest_line; + + linemap_assert + (!linemap_macro_expansion_map_p (LINEMAPS_LAST_ORDINARY_MAP (set))); + + if (to_column >= set->max_column_hint) + { + if (r > LINE_MAP_MAX_LOCATION_WITH_COLS + || to_column > LINE_MAP_MAX_COLUMN_NUMBER) + { + /* Running low on location_ts - disable column numbers. */ + return r; + } + else + { + /* Otherwise, attempt to start a new line that can hold TO_COLUMN, + with some space to spare. This may or may not lead to a new + linemap being created. */ + line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set); + r = linemap_line_start (set, SOURCE_LINE (map, r), to_column + 50); + map = LINEMAPS_LAST_ORDINARY_MAP (set); + if (map->m_column_and_range_bits == 0) + { + /* ...then the linemap has column-tracking disabled, + presumably due to exceeding either + LINE_MAP_MAX_LOCATION_WITH_COLS (overall) or + LINE_MAP_MAX_COLUMN_NUMBER (within this line). + Return the start of the linemap, which encodes column 0, for + the whole line. */ + return r; + } + } + } + line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set); + r = r + (to_column << map->m_range_bits); + if (r >= set->highest_location) + set->highest_location = r; + return r; +} + +/* Encode and return a source location from a given line and + column. */ + +location_t +linemap_position_for_line_and_column (line_maps *set, + const line_map_ordinary *ord_map, + linenum_type line, + unsigned column) +{ + linemap_assert (ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map) <= line); + + location_t r = MAP_START_LOCATION (ord_map); + r += ((line - ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map)) + << ord_map->m_column_and_range_bits); + if (r <= LINE_MAP_MAX_LOCATION_WITH_COLS) + r += ((column & ((1 << ord_map->m_column_and_range_bits) - 1)) + << ord_map->m_range_bits); + location_t upper_limit = LINEMAPS_MACRO_LOWEST_LOCATION (set); + if (r >= upper_limit) + r = upper_limit - 1; + if (r > set->highest_location) + set->highest_location = r; + return r; +} + +/* Encode and return a location_t starting from location LOC and + shifting it by COLUMN_OFFSET columns. This function does not support + virtual locations. */ + +location_t +linemap_position_for_loc_and_offset (line_maps *set, + location_t loc, + unsigned int column_offset) +{ + const line_map_ordinary * map = NULL; + + if (IS_ADHOC_LOC (loc)) + loc = get_location_from_adhoc_loc (set, loc); + + /* This function does not support virtual locations yet. */ + if (linemap_location_from_macro_expansion_p (set, loc)) + return loc; + + if (column_offset == 0 + /* Adding an offset to a reserved location (like + UNKNOWN_LOCATION for the C/C++ FEs) does not really make + sense. So let's leave the location intact in that case. */ + || loc < RESERVED_LOCATION_COUNT) + return loc; + + /* We find the real location and shift it. */ + loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map); + /* The new location (loc + offset) should be higher than the first + location encoded by MAP. This can fail if the line information + is messed up because of line directives (see PR66415). */ + if (MAP_START_LOCATION (map) >= loc + (column_offset << map->m_range_bits)) + return loc; + + linenum_type line = SOURCE_LINE (map, loc); + unsigned int column = SOURCE_COLUMN (map, loc); + + /* If MAP is not the last line map of its set, then the new location + (loc + offset) should be less than the first location encoded by + the next line map of the set. Otherwise, we try to encode the + location in the next map. */ + for (; map != LINEMAPS_LAST_ORDINARY_MAP (set) + && (loc + (column_offset << map->m_range_bits) + >= MAP_START_LOCATION (map + 1)); map++) + /* If the next map is a different file, or starts in a higher line, we + cannot encode the location there. */ + if ((map + 1)->reason != LC_RENAME + || line < ORDINARY_MAP_STARTING_LINE_NUMBER (map + 1) + || 0 != strcmp (LINEMAP_FILE (map + 1), LINEMAP_FILE (map))) + return loc; + + column += column_offset; + + /* Bail out if the column is not representable within the existing + linemap. */ + if (column >= (1u << (map->m_column_and_range_bits - map->m_range_bits))) + return loc; + + location_t r = + linemap_position_for_line_and_column (set, map, line, column); + if (linemap_assert_fails (r <= set->highest_location) + || linemap_assert_fails (map == linemap_lookup (set, r))) + return loc; + + return r; +} + +/* Given a virtual source location yielded by a map (either an + ordinary or a macro map), returns that map. */ + +const struct line_map* +linemap_lookup (const line_maps *set, location_t line) +{ + if (IS_ADHOC_LOC (line)) + line = get_location_from_adhoc_loc (set, line); + if (linemap_location_from_macro_expansion_p (set, line)) + return linemap_macro_map_lookup (set, line); + return linemap_ordinary_map_lookup (set, line); +} + +/* Given a source location yielded by an ordinary map, returns that + map. Since the set is built chronologically, the logical lines are + monotonic increasing, and so the list is sorted and we can use a + binary search. */ + +static const line_map_ordinary * +linemap_ordinary_map_lookup (const line_maps *set, location_t line) +{ + if (IS_ADHOC_LOC (line)) + line = get_location_from_adhoc_loc (set, line); + + if (set == NULL || line < RESERVED_LOCATION_COUNT) + return NULL; + + unsigned mn = LINEMAPS_ORDINARY_CACHE (set); + unsigned mx = LINEMAPS_ORDINARY_USED (set); + + const line_map_ordinary *cached = LINEMAPS_ORDINARY_MAP_AT (set, mn); + /* We should get a segfault if no line_maps have been added yet. */ + if (line >= MAP_START_LOCATION (cached)) + { + if (mn + 1 == mx || line < MAP_START_LOCATION (&cached[1])) + return cached; + } + else + { + mx = mn; + mn = 0; + } + + while (mx - mn > 1) + { + unsigned md = (mn + mx) / 2; + if (MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (set, md)) > line) + mx = md; + else + mn = md; + } + + LINEMAPS_ORDINARY_CACHE (set) = mn; + const line_map_ordinary *result = LINEMAPS_ORDINARY_MAP_AT (set, mn); + linemap_assert (line >= MAP_START_LOCATION (result)); + return result; +} + +/* Given a source location yielded by a macro map, returns that map. + Since the set is built chronologically, the logical lines are + monotonic decreasing, and so the list is sorted and we can use a + binary search. */ + +static const line_map_macro * +linemap_macro_map_lookup (const line_maps *set, location_t line) +{ + if (IS_ADHOC_LOC (line)) + line = get_location_from_adhoc_loc (set, line); + + linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set)); + + if (set == NULL) + return NULL; + + unsigned ix = linemap_lookup_macro_index (set, line); + const struct line_map_macro *result = LINEMAPS_MACRO_MAP_AT (set, ix); + linemap_assert (MAP_START_LOCATION (result) <= line); + + return result; +} + +unsigned +linemap_lookup_macro_index (const line_maps *set, location_t line) +{ + unsigned mn = LINEMAPS_MACRO_CACHE (set); + unsigned mx = LINEMAPS_MACRO_USED (set); + const struct line_map_macro *cached = LINEMAPS_MACRO_MAP_AT (set, mn); + + if (line >= MAP_START_LOCATION (cached)) + { + if (line < (MAP_START_LOCATION (cached) + + MACRO_MAP_NUM_MACRO_TOKENS (cached))) + return mn; + mx = mn - 1; + mn = 0; + } + + while (mn < mx) + { + unsigned md = (mx + mn) / 2; + if (MAP_START_LOCATION (LINEMAPS_MACRO_MAP_AT (set, md)) > line) + mn = md + 1; + else + mx = md; + } + + LINEMAPS_MACRO_CACHE (set) = mx; + return mx; +} + +/* Return TRUE if MAP encodes locations coming from a macro + replacement-list at macro expansion point. */ + +bool +linemap_macro_expansion_map_p (const struct line_map *map) +{ + return map && !MAP_ORDINARY_P (map); +} + +/* If LOCATION is the locus of a token in a replacement-list of a + macro expansion return the location of the macro expansion point. + + Read the comments of struct line_map and struct line_map_macro in + line-map.h to understand what a macro expansion point is. */ + +static location_t +linemap_macro_map_loc_to_exp_point (const line_map_macro *map, + location_t location ATTRIBUTE_UNUSED) +{ + linemap_assert (linemap_macro_expansion_map_p (map) + && location >= MAP_START_LOCATION (map)); + + /* Make sure LOCATION is correct. */ + linemap_assert ((location - MAP_START_LOCATION (map)) + < MACRO_MAP_NUM_MACRO_TOKENS (map)); + + return MACRO_MAP_EXPANSION_POINT_LOCATION (map); +} + +/* LOCATION is the source location of a token that belongs to a macro + replacement-list as part of the macro expansion denoted by MAP. + + Return the location of the token at the definition point of the + macro. */ + +static location_t +linemap_macro_map_loc_to_def_point (const line_map_macro *map, + location_t location) +{ + unsigned token_no; + + linemap_assert (linemap_macro_expansion_map_p (map) + && location >= MAP_START_LOCATION (map)); + linemap_assert (location >= RESERVED_LOCATION_COUNT); + + token_no = location - MAP_START_LOCATION (map); + linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map)); + + location = MACRO_MAP_LOCATIONS (map)[2 * token_no + 1]; + + return location; +} + +/* If LOCATION is the locus of a token that is an argument of a + function-like macro M and appears in the expansion of M, return the + locus of that argument in the context of the caller of M. + + In other words, this returns the xI location presented in the + comments of line_map_macro above. */ +location_t +linemap_macro_map_loc_unwind_toward_spelling (line_maps *set, + const line_map_macro* map, + location_t location) +{ + unsigned token_no; + + if (IS_ADHOC_LOC (location)) + location = get_location_from_adhoc_loc (set, location); + + linemap_assert (linemap_macro_expansion_map_p (map) + && location >= MAP_START_LOCATION (map)); + linemap_assert (location >= RESERVED_LOCATION_COUNT); + linemap_assert (!IS_ADHOC_LOC (location)); + + token_no = location - MAP_START_LOCATION (map); + linemap_assert (token_no < MACRO_MAP_NUM_MACRO_TOKENS (map)); + + location = MACRO_MAP_LOCATIONS (map)[2 * token_no]; + + return location; +} + +/* Return the source line number corresponding to source location + LOCATION. SET is the line map set LOCATION comes from. If + LOCATION is the source location of token that is part of the + replacement-list of a macro expansion return the line number of the + macro expansion point. */ + +int +linemap_get_expansion_line (line_maps *set, + location_t location) +{ + const line_map_ordinary *map = NULL; + + if (IS_ADHOC_LOC (location)) + location = get_location_from_adhoc_loc (set, location); + + if (location < RESERVED_LOCATION_COUNT) + return 0; + + location = + linemap_macro_loc_to_exp_point (set, location, &map); + + return SOURCE_LINE (map, location); +} + +/* Return the path of the file corresponding to source code location + LOCATION. + + If LOCATION is the source location of token that is part of the + replacement-list of a macro expansion return the file path of the + macro expansion point. + + SET is the line map set LOCATION comes from. */ + +const char* +linemap_get_expansion_filename (line_maps *set, + location_t location) +{ + const struct line_map_ordinary *map = NULL; + + if (IS_ADHOC_LOC (location)) + location = get_location_from_adhoc_loc (set, location); + + if (location < RESERVED_LOCATION_COUNT) + return NULL; + + linemap_macro_loc_to_exp_point (set, location, &map); + + return LINEMAP_FILE (map); +} + +/* Return the name of the macro associated to MACRO_MAP. */ + +const char* +linemap_map_get_macro_name (const line_map_macro *macro_map) +{ + linemap_assert (macro_map && linemap_macro_expansion_map_p (macro_map)); + return (const char*) NODE_NAME (MACRO_MAP_MACRO (macro_map)); +} + +/* Return a positive value if LOCATION is the locus of a token that is + located in a system header, O otherwise. It returns 1 if LOCATION + is the locus of a token that is located in a system header, and 2 + if LOCATION is the locus of a token located in a C system header + that therefore needs to be extern "C" protected in C++. + + Note that this function returns 1 if LOCATION belongs to a token + that is part of a macro replacement-list defined in a system + header, but expanded in a non-system file. */ + +int +linemap_location_in_system_header_p (line_maps *set, + location_t location) +{ + const struct line_map *map = NULL; + + if (IS_ADHOC_LOC (location)) + location = get_location_from_adhoc_loc (set, location); + + if (location < RESERVED_LOCATION_COUNT) + return false; + + /* Let's look at where the token for LOCATION comes from. */ + while (true) + { + map = linemap_lookup (set, location); + if (map != NULL) + { + if (!linemap_macro_expansion_map_p (map)) + /* It's a normal token. */ + return LINEMAP_SYSP (linemap_check_ordinary (map)); + else + { + const line_map_macro *macro_map = linemap_check_macro (map); + + /* It's a token resulting from a macro expansion. */ + location_t loc = + linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, location); + if (loc < RESERVED_LOCATION_COUNT) + /* This token might come from a built-in macro. Let's + look at where that macro got expanded. */ + location = linemap_macro_map_loc_to_exp_point (macro_map, location); + else + location = loc; + } + } + else + break; + } + return false; +} + +/* Return TRUE if LOCATION is a source code location of a token that is part of + a macro expansion, FALSE otherwise. */ + +bool +linemap_location_from_macro_expansion_p (const class line_maps *set, + location_t location) +{ + if (IS_ADHOC_LOC (location)) + location = get_location_from_adhoc_loc (set, location); + + return location >= LINEMAPS_MACRO_LOWEST_LOCATION (set); +} + +/* Given two virtual locations *LOC0 and *LOC1, return the first + common macro map in their macro expansion histories. Return NULL + if no common macro was found. *LOC0 (resp. *LOC1) is set to the + virtual location of the token inside the resulting macro. */ + +static const struct line_map* +first_map_in_common_1 (line_maps *set, + location_t *loc0, + location_t *loc1) +{ + location_t l0 = *loc0, l1 = *loc1; + const struct line_map *map0 = linemap_lookup (set, l0); + if (IS_ADHOC_LOC (l0)) + l0 = get_location_from_adhoc_loc (set, l0); + + const struct line_map *map1 = linemap_lookup (set, l1); + if (IS_ADHOC_LOC (l1)) + l1 = get_location_from_adhoc_loc (set, l1); + + while (linemap_macro_expansion_map_p (map0) + && linemap_macro_expansion_map_p (map1) + && (map0 != map1)) + { + if (MAP_START_LOCATION (map0) < MAP_START_LOCATION (map1)) + { + l0 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map0), + l0); + map0 = linemap_lookup (set, l0); + } + else + { + l1 = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map1), + l1); + map1 = linemap_lookup (set, l1); + } + } + + if (map0 == map1) + { + *loc0 = l0; + *loc1 = l1; + return map0; + } + return NULL; +} + +/* Given two virtual locations LOC0 and LOC1, return the first common + macro map in their macro expansion histories. Return NULL if no + common macro was found. *RES_LOC0 (resp. *RES_LOC1) is set to the + virtual location of the token inside the resulting macro, upon + return of a non-NULL result. */ + +const struct line_map* +first_map_in_common (line_maps *set, + location_t loc0, + location_t loc1, + location_t *res_loc0, + location_t *res_loc1) +{ + *res_loc0 = loc0; + *res_loc1 = loc1; + + return first_map_in_common_1 (set, res_loc0, res_loc1); +} + +/* Return a positive value if PRE denotes the location of a token that + comes before the token of POST, 0 if PRE denotes the location of + the same token as the token for POST, and a negative value + otherwise. */ + +int +linemap_compare_locations (line_maps *set, + location_t pre, + location_t post) +{ + bool pre_virtual_p, post_virtual_p; + location_t l0 = pre, l1 = post; + + if (IS_ADHOC_LOC (l0)) + l0 = get_location_from_adhoc_loc (set, l0); + if (IS_ADHOC_LOC (l1)) + l1 = get_location_from_adhoc_loc (set, l1); + + if (l0 == l1) + return 0; + + if ((pre_virtual_p = linemap_location_from_macro_expansion_p (set, l0))) + l0 = linemap_resolve_location (set, l0, + LRK_MACRO_EXPANSION_POINT, + NULL); + + if ((post_virtual_p = linemap_location_from_macro_expansion_p (set, l1))) + l1 = linemap_resolve_location (set, l1, + LRK_MACRO_EXPANSION_POINT, + NULL); + + if (l0 == l1 + && pre_virtual_p + && post_virtual_p) + { + /* So pre and post represent two tokens that are present in a + same macro expansion. Let's see if the token for pre was + before the token for post in that expansion. */ + const struct line_map *map = + first_map_in_common (set, pre, post, &l0, &l1); + + if (map == NULL) + /* This should not be possible while we have column information, but if + we don't, the tokens could be from separate macro expansions on the + same line. */ + gcc_assert (l0 > LINE_MAP_MAX_LOCATION_WITH_COLS); + else + { + unsigned i0 = l0 - MAP_START_LOCATION (map); + unsigned i1 = l1 - MAP_START_LOCATION (map); + return i1 - i0; + } + } + + if (IS_ADHOC_LOC (l0)) + l0 = get_location_from_adhoc_loc (set, l0); + if (IS_ADHOC_LOC (l1)) + l1 = get_location_from_adhoc_loc (set, l1); + + return l1 - l0; +} + +/* Print an include trace, for e.g. the -H option of the preprocessor. */ + +static void +trace_include (const class line_maps *set, const line_map_ordinary *map) +{ + unsigned int i = set->depth; + + while (--i) + putc ('.', stderr); + + fprintf (stderr, " %s\n", ORDINARY_MAP_FILE_NAME (map)); +} + +/* Return the spelling location of the token wherever it comes from, + whether part of a macro definition or not. + + This is a subroutine for linemap_resolve_location. */ + +static location_t +linemap_macro_loc_to_spelling_point (line_maps *set, + location_t location, + const line_map_ordinary **original_map) +{ + linemap_assert (set && location >= RESERVED_LOCATION_COUNT); + + while (true) + { + const struct line_map *map = linemap_lookup (set, location); + if (!map || MAP_ORDINARY_P (map)) + { + if (original_map) + *original_map = (const line_map_ordinary *)map; + break; + } + + location = linemap_macro_map_loc_unwind_toward_spelling + (set, linemap_check_macro (map), location); + } + + return location; +} + +/* If LOCATION is the source location of a token that belongs to a + macro replacement-list -- as part of a macro expansion -- then + return the location of the token at the definition point of the + macro. Otherwise, return LOCATION. SET is the set of maps + location come from. ORIGINAL_MAP is an output parm. If non NULL, + the function sets *ORIGINAL_MAP to the ordinary (non-macro) map the + returned location comes from. + + This is a subroutine of linemap_resolve_location. */ + +static location_t +linemap_macro_loc_to_def_point (line_maps *set, + location_t location, + const line_map_ordinary **original_map) +{ + linemap_assert (set && location >= RESERVED_LOCATION_COUNT); + + for (;;) + { + location_t caret_loc = location; + if (IS_ADHOC_LOC (caret_loc)) + caret_loc = get_location_from_adhoc_loc (set, caret_loc); + + const line_map *map = linemap_lookup (set, caret_loc); + if (!map || MAP_ORDINARY_P (map)) + { + if (original_map) + *original_map = (const line_map_ordinary *)map; + break; + } + + location = linemap_macro_map_loc_to_def_point + (linemap_check_macro (map), caret_loc); + } + + return location; +} + +/* If LOCATION is the source location of a token that belongs to a + macro replacement-list -- at a macro expansion point -- then return + the location of the topmost expansion point of the macro. We say + topmost because if we are in the context of a nested macro + expansion, the function returns the source location of the first + macro expansion that triggered the nested expansions. + + Otherwise, return LOCATION. SET is the set of maps location come + from. ORIGINAL_MAP is an output parm. If non NULL, the function + sets *ORIGINAL_MAP to the ordinary (non-macro) map the returned + location comes from. + + This is a subroutine of linemap_resolve_location. */ + +static location_t +linemap_macro_loc_to_exp_point (line_maps *set, + location_t location, + const line_map_ordinary **original_map) +{ + struct line_map *map; + + if (IS_ADHOC_LOC (location)) + location = get_location_from_adhoc_loc (set, location); + + linemap_assert (set && location >= RESERVED_LOCATION_COUNT); + + while (true) + { + map = const_cast <line_map *> (linemap_lookup (set, location)); + if (!linemap_macro_expansion_map_p (map)) + break; + location = linemap_macro_map_loc_to_exp_point (linemap_check_macro (map), + location); + } + + if (original_map) + *original_map = linemap_check_ordinary (map); + return location; +} + +/* Resolve a virtual location into either a spelling location, an + expansion point location or a token argument replacement point + location. Return the map that encodes the virtual location as well + as the resolved location. + + If LOC is *NOT* the location of a token resulting from the + expansion of a macro, then the parameter LRK (which stands for + Location Resolution Kind) is ignored and the resulting location + just equals the one given in argument. + + Now if LOC *IS* the location of a token resulting from the + expansion of a macro, this is what happens. + + * If LRK is set to LRK_MACRO_EXPANSION_POINT + ------------------------------- + + The virtual location is resolved to the first macro expansion point + that led to this macro expansion. + + * If LRK is set to LRK_SPELLING_LOCATION + ------------------------------------- + + The virtual location is resolved to the locus where the token has + been spelled in the source. This can follow through all the macro + expansions that led to the token. + + * If LRK is set to LRK_MACRO_DEFINITION_LOCATION + -------------------------------------- + + The virtual location is resolved to the locus of the token in the + context of the macro definition. + + If LOC is the locus of a token that is an argument of a + function-like macro [replacing a parameter in the replacement list + of the macro] the virtual location is resolved to the locus of the + parameter that is replaced, in the context of the definition of the + macro. + + If LOC is the locus of a token that is not an argument of a + function-like macro, then the function behaves as if LRK was set to + LRK_SPELLING_LOCATION. + + If MAP is not NULL, *MAP is set to the map encoding the + returned location. Note that if the returned location wasn't originally + encoded by a map, then *MAP is set to NULL. This can happen if LOC + resolves to a location reserved for the client code, like + UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */ + +location_t +linemap_resolve_location (line_maps *set, + location_t loc, + enum location_resolution_kind lrk, + const line_map_ordinary **map) +{ + location_t locus = loc; + if (IS_ADHOC_LOC (loc)) + locus = get_location_from_adhoc_loc (set, loc); + + if (locus < RESERVED_LOCATION_COUNT) + { + /* A reserved location wasn't encoded in a map. Let's return a + NULL map here, just like what linemap_ordinary_map_lookup + does. */ + if (map) + *map = NULL; + return loc; + } + + switch (lrk) + { + case LRK_MACRO_EXPANSION_POINT: + loc = linemap_macro_loc_to_exp_point (set, loc, map); + break; + case LRK_SPELLING_LOCATION: + loc = linemap_macro_loc_to_spelling_point (set, loc, map); + break; + case LRK_MACRO_DEFINITION_LOCATION: + loc = linemap_macro_loc_to_def_point (set, loc, map); + break; + default: + abort (); + } + return loc; +} + +/* TRUE if LOCATION is a source code location of a token that is part of the + definition of a macro, FALSE otherwise. */ + +bool +linemap_location_from_macro_definition_p (line_maps *set, + location_t loc) +{ + if (IS_ADHOC_LOC (loc)) + loc = get_location_from_adhoc_loc (set, loc); + + if (!linemap_location_from_macro_expansion_p (set, loc)) + return false; + + while (true) + { + const struct line_map_macro *map + = linemap_check_macro (linemap_lookup (set, loc)); + + location_t s_loc + = linemap_macro_map_loc_unwind_toward_spelling (set, map, loc); + if (linemap_location_from_macro_expansion_p (set, s_loc)) + loc = s_loc; + else + { + location_t def_loc + = linemap_macro_map_loc_to_def_point (map, loc); + return s_loc == def_loc; + } + } +} + +/* + Suppose that LOC is the virtual location of a token T coming from + the expansion of a macro M. This function then steps up to get the + location L of the point where M got expanded. If L is a spelling + location inside a macro expansion M', then this function returns + the locus of the point where M' was expanded. Said otherwise, this + function returns the location of T in the context that triggered + the expansion of M. + + *LOC_MAP must be set to the map of LOC. This function then sets it + to the map of the returned location. */ + +location_t +linemap_unwind_toward_expansion (line_maps *set, + location_t loc, + const struct line_map **map) +{ + location_t resolved_location; + const line_map_macro *macro_map = linemap_check_macro (*map); + const struct line_map *resolved_map; + + if (IS_ADHOC_LOC (loc)) + loc = get_location_from_adhoc_loc (set, loc); + + resolved_location = + linemap_macro_map_loc_unwind_toward_spelling (set, macro_map, loc); + resolved_map = linemap_lookup (set, resolved_location); + + if (!linemap_macro_expansion_map_p (resolved_map)) + { + resolved_location = linemap_macro_map_loc_to_exp_point (macro_map, loc); + resolved_map = linemap_lookup (set, resolved_location); + } + + *map = resolved_map; + return resolved_location; +} + +/* If LOC is the virtual location of a token coming from the expansion + of a macro M and if its spelling location is reserved (e.g, a + location for a built-in token), then this function unwinds (using + linemap_unwind_toward_expansion) the location until a location that + is not reserved and is not in a system header is reached. In other + words, this unwinds the reserved location until a location that is + in real source code is reached. + + Otherwise, if the spelling location for LOC is not reserved or if + LOC doesn't come from the expansion of a macro, the function + returns LOC as is and *MAP is not touched. + + *MAP is set to the map of the returned location if the later is + different from LOC. */ +location_t +linemap_unwind_to_first_non_reserved_loc (line_maps *set, + location_t loc, + const struct line_map **map) +{ + location_t resolved_loc; + const struct line_map *map0 = NULL; + const line_map_ordinary *map1 = NULL; + + if (IS_ADHOC_LOC (loc)) + loc = get_location_from_adhoc_loc (set, loc); + + map0 = linemap_lookup (set, loc); + if (!linemap_macro_expansion_map_p (map0)) + return loc; + + resolved_loc = linemap_resolve_location (set, loc, + LRK_SPELLING_LOCATION, + &map1); + + if (resolved_loc >= RESERVED_LOCATION_COUNT + && !LINEMAP_SYSP (map1)) + return loc; + + while (linemap_macro_expansion_map_p (map0) + && (resolved_loc < RESERVED_LOCATION_COUNT + || LINEMAP_SYSP (map1))) + { + loc = linemap_unwind_toward_expansion (set, loc, &map0); + resolved_loc = linemap_resolve_location (set, loc, + LRK_SPELLING_LOCATION, + &map1); + } + + if (map != NULL) + *map = map0; + return loc; +} + +/* Expand source code location LOC and return a user readable source + code location. LOC must be a spelling (non-virtual) location. If + it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source + location is returned. */ + +expanded_location +linemap_expand_location (line_maps *set, + const struct line_map *map, + location_t loc) + +{ + expanded_location xloc; + + memset (&xloc, 0, sizeof (xloc)); + if (IS_ADHOC_LOC (loc)) + { + xloc.data = get_data_from_adhoc_loc (set, loc); + loc = get_location_from_adhoc_loc (set, loc); + } + + if (loc < RESERVED_LOCATION_COUNT) + /* The location for this token wasn't generated from a line map. + It was probably a location for a builtin token, chosen by some + client code. Let's not try to expand the location in that + case. */; + else if (map == NULL) + /* We shouldn't be getting a NULL map with a location that is not + reserved by the client code. */ + abort (); + else + { + /* MAP must be an ordinary map and LOC must be non-virtual, + encoded into this map, obviously; the accessors used on MAP + below ensure it is ordinary. Let's just assert the + non-virtualness of LOC here. */ + if (linemap_location_from_macro_expansion_p (set, loc)) + abort (); + + const line_map_ordinary *ord_map = linemap_check_ordinary (map); + + xloc.file = LINEMAP_FILE (ord_map); + xloc.line = SOURCE_LINE (ord_map, loc); + xloc.column = SOURCE_COLUMN (ord_map, loc); + xloc.sysp = LINEMAP_SYSP (ord_map) != 0; + } + + return xloc; +} + + +/* Dump line map at index IX in line table SET to STREAM. If STREAM + is NULL, use stderr. IS_MACRO is true if the caller wants to + dump a macro map, false otherwise. */ + +void +linemap_dump (FILE *stream, class line_maps *set, unsigned ix, bool is_macro) +{ + const char *const lc_reasons_v[LC_HWM] + = { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM", + "LC_ENTER_MACRO", "LC_MODULE" }; + const line_map *map; + unsigned reason; + + if (stream == NULL) + stream = stderr; + + if (!is_macro) + { + map = LINEMAPS_ORDINARY_MAP_AT (set, ix); + reason = linemap_check_ordinary (map)->reason; + } + else + { + map = LINEMAPS_MACRO_MAP_AT (set, ix); + reason = LC_ENTER_MACRO; + } + + fprintf (stream, "Map #%u [%p] - LOC: %u - REASON: %s - SYSP: %s\n", + ix, (void *) map, map->start_location, + reason < LC_HWM ? lc_reasons_v[reason] : "???", + ((!is_macro + && ORDINARY_MAP_IN_SYSTEM_HEADER_P (linemap_check_ordinary (map))) + ? "yes" : "no")); + if (!is_macro) + { + const line_map_ordinary *ord_map = linemap_check_ordinary (map); + const line_map_ordinary *includer_map + = linemap_included_from_linemap (set, ord_map); + + fprintf (stream, "File: %s:%d\n", ORDINARY_MAP_FILE_NAME (ord_map), + ORDINARY_MAP_STARTING_LINE_NUMBER (ord_map)); + fprintf (stream, "Included from: [%d] %s\n", + includer_map ? int (includer_map - set->info_ordinary.maps) : -1, + includer_map ? ORDINARY_MAP_FILE_NAME (includer_map) : "None"); + } + else + { + const line_map_macro *macro_map = linemap_check_macro (map); + fprintf (stream, "Macro: %s (%u tokens)\n", + linemap_map_get_macro_name (macro_map), + MACRO_MAP_NUM_MACRO_TOKENS (macro_map)); + } + + fprintf (stream, "\n"); +} + + +/* Dump debugging information about source location LOC into the file + stream STREAM. SET is the line map set LOC comes from. */ + +void +linemap_dump_location (line_maps *set, + location_t loc, + FILE *stream) +{ + const line_map_ordinary *map; + location_t location; + const char *path = "", *from = ""; + int l = -1, c = -1, s = -1, e = -1; + + if (IS_ADHOC_LOC (loc)) + loc = get_location_from_adhoc_loc (set, loc); + + if (loc == 0) + return; + + location = + linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map); + + if (map == NULL) + /* Only reserved locations can be tolerated in this case. */ + linemap_assert (location < RESERVED_LOCATION_COUNT); + else + { + path = LINEMAP_FILE (map); + l = SOURCE_LINE (map, location); + c = SOURCE_COLUMN (map, location); + s = LINEMAP_SYSP (map) != 0; + e = location != loc; + if (e) + from = "N/A"; + else + { + const line_map_ordinary *from_map + = linemap_included_from_linemap (set, map); + from = from_map ? LINEMAP_FILE (from_map) : "<NULL>"; + } + } + + /* P: path, L: line, C: column, S: in-system-header, M: map address, + E: macro expansion?, LOC: original location, R: resolved location */ + fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}", + path, from, l, c, s, (void*)map, e, loc, location); +} + +/* Return the highest location emitted for a given file for which + there is a line map in SET. FILE_NAME is the file name to + consider. If the function returns TRUE, *LOC is set to the highest + location emitted for that file. */ + +bool +linemap_get_file_highest_location (line_maps *set, + const char *file_name, + location_t *loc) +{ + /* If the set is empty or no ordinary map has been created then + there is no file to look for ... */ + if (set == NULL || set->info_ordinary.used == 0) + return false; + + /* Now look for the last ordinary map created for FILE_NAME. */ + int i; + for (i = set->info_ordinary.used - 1; i >= 0; --i) + { + const char *fname = set->info_ordinary.maps[i].to_file; + if (fname && !filename_cmp (fname, file_name)) + break; + } + + if (i < 0) + return false; + + /* The highest location for a given map is either the starting + location of the next map minus one, or -- if the map is the + latest one -- the highest location of the set. */ + location_t result; + if (i == (int) set->info_ordinary.used - 1) + result = set->highest_location; + else + result = set->info_ordinary.maps[i + 1].start_location - 1; + + *loc = result; + return true; +} + +/* Compute and return statistics about the memory consumption of some + parts of the line table SET. */ + +void +linemap_get_statistics (line_maps *set, + struct linemap_stats *s) +{ + long ordinary_maps_allocated_size, ordinary_maps_used_size, + macro_maps_allocated_size, macro_maps_used_size, + macro_maps_locations_size = 0, duplicated_macro_maps_locations_size = 0; + + const line_map_macro *cur_map; + + ordinary_maps_allocated_size = + LINEMAPS_ORDINARY_ALLOCATED (set) * sizeof (struct line_map_ordinary); + + ordinary_maps_used_size = + LINEMAPS_ORDINARY_USED (set) * sizeof (struct line_map_ordinary); + + macro_maps_allocated_size = + LINEMAPS_MACRO_ALLOCATED (set) * sizeof (struct line_map_macro); + + for (cur_map = LINEMAPS_MACRO_MAPS (set); + cur_map && cur_map <= LINEMAPS_LAST_MACRO_MAP (set); + ++cur_map) + { + unsigned i; + + linemap_assert (linemap_macro_expansion_map_p (cur_map)); + + macro_maps_locations_size += + 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map) * sizeof (location_t); + + for (i = 0; i < 2 * MACRO_MAP_NUM_MACRO_TOKENS (cur_map); i += 2) + { + if (MACRO_MAP_LOCATIONS (cur_map)[i] == + MACRO_MAP_LOCATIONS (cur_map)[i + 1]) + duplicated_macro_maps_locations_size += + sizeof (location_t); + } + } + + macro_maps_used_size = + LINEMAPS_MACRO_USED (set) * sizeof (struct line_map_macro); + + s->num_ordinary_maps_allocated = LINEMAPS_ORDINARY_ALLOCATED (set); + s->num_ordinary_maps_used = LINEMAPS_ORDINARY_USED (set); + s->ordinary_maps_allocated_size = ordinary_maps_allocated_size; + s->ordinary_maps_used_size = ordinary_maps_used_size; + s->num_expanded_macros = num_expanded_macros_counter; + s->num_macro_tokens = num_macro_tokens_counter; + s->num_macro_maps_used = LINEMAPS_MACRO_USED (set); + s->macro_maps_allocated_size = macro_maps_allocated_size; + s->macro_maps_locations_size = macro_maps_locations_size; + s->macro_maps_used_size = macro_maps_used_size; + s->duplicated_macro_maps_locations_size = + duplicated_macro_maps_locations_size; + s->adhoc_table_size = (set->location_adhoc_data_map.allocated + * sizeof (struct location_adhoc_data)); + s->adhoc_table_entries_used = set->location_adhoc_data_map.curr_loc; +} + + +/* Dump line table SET to STREAM. If STREAM is NULL, stderr is used. + NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO + specifies how many macro maps to dump. */ + +void +line_table_dump (FILE *stream, class line_maps *set, unsigned int num_ordinary, + unsigned int num_macro) +{ + unsigned int i; + + if (set == NULL) + return; + + if (stream == NULL) + stream = stderr; + + fprintf (stream, "# of ordinary maps: %d\n", LINEMAPS_ORDINARY_USED (set)); + fprintf (stream, "# of macro maps: %d\n", LINEMAPS_MACRO_USED (set)); + fprintf (stream, "Include stack depth: %d\n", set->depth); + fprintf (stream, "Highest location: %u\n", set->highest_location); + + if (num_ordinary) + { + fprintf (stream, "\nOrdinary line maps\n"); + for (i = 0; i < num_ordinary && i < LINEMAPS_ORDINARY_USED (set); i++) + linemap_dump (stream, set, i, false); + fprintf (stream, "\n"); + } + + if (num_macro) + { + fprintf (stream, "\nMacro line maps\n"); + for (i = 0; i < num_macro && i < LINEMAPS_MACRO_USED (set); i++) + linemap_dump (stream, set, i, true); + fprintf (stream, "\n"); + } +} + +/* class rich_location. */ + +/* Construct a rich_location with location LOC as its initial range. */ + +rich_location::rich_location (line_maps *set, location_t loc, + const range_label *label) : + m_line_table (set), + m_ranges (), + m_column_override (0), + m_have_expanded_location (false), + m_seen_impossible_fixit (false), + m_fixits_cannot_be_auto_applied (false), + m_escape_on_output (false), + m_fixit_hints (), + m_path (NULL) +{ + add_range (loc, SHOW_RANGE_WITH_CARET, label); +} + +/* The destructor for class rich_location. */ + +rich_location::~rich_location () +{ + for (unsigned int i = 0; i < m_fixit_hints.count (); i++) + delete get_fixit_hint (i); +} + +/* Get location IDX within this rich_location. */ + +location_t +rich_location::get_loc (unsigned int idx) const +{ + const location_range *locrange = get_range (idx); + return locrange->m_loc; +} + +/* Get range IDX within this rich_location. */ + +const location_range * +rich_location::get_range (unsigned int idx) const +{ + return &m_ranges[idx]; +} + +/* Mutable access to range IDX within this rich_location. */ + +location_range * +rich_location::get_range (unsigned int idx) +{ + return &m_ranges[idx]; +} + +/* Expand location IDX within this rich_location. */ +/* Get an expanded_location for this rich_location's primary + location. */ + +expanded_location +rich_location::get_expanded_location (unsigned int idx) +{ + if (idx == 0) + { + /* Cache the expansion of the primary location. */ + if (!m_have_expanded_location) + { + m_expanded_location + = linemap_client_expand_location_to_spelling_point + (get_loc (0), LOCATION_ASPECT_CARET); + if (m_column_override) + m_expanded_location.column = m_column_override; + m_have_expanded_location = true; + } + + return m_expanded_location; + } + else + return linemap_client_expand_location_to_spelling_point + (get_loc (idx), LOCATION_ASPECT_CARET); +} + +/* Set the column of the primary location, with 0 meaning + "don't override it". */ + +void +rich_location::override_column (int column) +{ + m_column_override = column; + m_have_expanded_location = false; +} + +/* Add the given range. */ + +void +rich_location::add_range (location_t loc, + enum range_display_kind range_display_kind, + const range_label *label) +{ + location_range range; + range.m_loc = loc; + range.m_range_display_kind = range_display_kind; + range.m_label = label; + m_ranges.push (range); +} + +/* Add or overwrite the location given by IDX, setting its location to LOC, + and setting its m_range_display_kind to RANGE_DISPLAY_KIND. + + It must either overwrite an existing location, or add one *exactly* on + the end of the array. + + This is primarily for use by gcc when implementing diagnostic format + decoders e.g. + - the "+" in the C/C++ frontends, for handling format codes like "%q+D" + (which writes the source location of a tree back into location 0 of + the rich_location), and + - the "%C" and "%L" format codes in the Fortran frontend. */ + +void +rich_location::set_range (unsigned int idx, location_t loc, + enum range_display_kind range_display_kind) +{ + /* We can either overwrite an existing range, or add one exactly + on the end of the array. */ + linemap_assert (idx <= m_ranges.count ()); + + if (idx == m_ranges.count ()) + add_range (loc, range_display_kind); + else + { + location_range *locrange = get_range (idx); + locrange->m_loc = loc; + locrange->m_range_display_kind = range_display_kind; + } + + if (idx == 0) + /* Mark any cached value here as dirty. */ + m_have_expanded_location = false; +} + +/* Methods for adding insertion fix-it hints. */ + +/* Add a fixit-hint, suggesting insertion of NEW_CONTENT + immediately before the primary range's start location. */ + +void +rich_location::add_fixit_insert_before (const char *new_content) +{ + add_fixit_insert_before (get_loc (), new_content); +} + +/* Add a fixit-hint, suggesting insertion of NEW_CONTENT + immediately before the start of WHERE. */ + +void +rich_location::add_fixit_insert_before (location_t where, + const char *new_content) +{ + location_t start = get_range_from_loc (m_line_table, where).m_start; + maybe_add_fixit (start, start, new_content); +} + +/* Add a fixit-hint, suggesting insertion of NEW_CONTENT + immediately after the primary range's end-point. */ + +void +rich_location::add_fixit_insert_after (const char *new_content) +{ + add_fixit_insert_after (get_loc (), new_content); +} + +/* Add a fixit-hint, suggesting insertion of NEW_CONTENT + immediately after the end-point of WHERE. */ + +void +rich_location::add_fixit_insert_after (location_t where, + const char *new_content) +{ + location_t finish = get_range_from_loc (m_line_table, where).m_finish; + location_t next_loc + = linemap_position_for_loc_and_offset (m_line_table, finish, 1); + + /* linemap_position_for_loc_and_offset can fail, if so, it returns + its input value. */ + if (next_loc == finish) + { + stop_supporting_fixits (); + return; + } + + maybe_add_fixit (next_loc, next_loc, new_content); +} + +/* Methods for adding removal fix-it hints. */ + +/* Add a fixit-hint, suggesting removal of the content covered + by range 0. */ + +void +rich_location::add_fixit_remove () +{ + add_fixit_remove (get_loc ()); +} + +/* Add a fixit-hint, suggesting removal of the content between + the start and finish of WHERE. */ + +void +rich_location::add_fixit_remove (location_t where) +{ + source_range range = get_range_from_loc (m_line_table, where); + add_fixit_remove (range); +} + +/* Add a fixit-hint, suggesting removal of the content at + SRC_RANGE. */ + +void +rich_location::add_fixit_remove (source_range src_range) +{ + add_fixit_replace (src_range, ""); +} + +/* Add a fixit-hint, suggesting replacement of the content covered + by range 0 with NEW_CONTENT. */ + +void +rich_location::add_fixit_replace (const char *new_content) +{ + add_fixit_replace (get_loc (), new_content); +} + +/* Methods for adding "replace" fix-it hints. */ + +/* Add a fixit-hint, suggesting replacement of the content between + the start and finish of WHERE with NEW_CONTENT. */ + +void +rich_location::add_fixit_replace (location_t where, + const char *new_content) +{ + source_range range = get_range_from_loc (m_line_table, where); + add_fixit_replace (range, new_content); +} + +/* Add a fixit-hint, suggesting replacement of the content at + SRC_RANGE with NEW_CONTENT. */ + +void +rich_location::add_fixit_replace (source_range src_range, + const char *new_content) +{ + location_t start = get_pure_location (m_line_table, src_range.m_start); + location_t finish = get_pure_location (m_line_table, src_range.m_finish); + + /* Fix-it hints use half-closed ranges, so attempt to offset the endpoint. */ + location_t next_loc + = linemap_position_for_loc_and_offset (m_line_table, finish, 1); + /* linemap_position_for_loc_and_offset can fail, if so, it returns + its input value. */ + if (next_loc == finish) + { + stop_supporting_fixits (); + return; + } + finish = next_loc; + + maybe_add_fixit (start, finish, new_content); +} + +/* Get the last fix-it hint within this rich_location, or NULL if none. */ + +fixit_hint * +rich_location::get_last_fixit_hint () const +{ + if (m_fixit_hints.count () > 0) + return get_fixit_hint (m_fixit_hints.count () - 1); + else + return NULL; +} + +/* If WHERE is an "awkward" location, then mark this rich_location as not + supporting fixits, purging any thay were already added, and return true. + + Otherwise (the common case), return false. */ + +bool +rich_location::reject_impossible_fixit (location_t where) +{ + /* Fix-its within a rich_location should either all be suggested, or + none of them should be suggested. + Once we've rejected a fixit, we reject any more, even those + with reasonable locations. */ + if (m_seen_impossible_fixit) + return true; + + if (where <= LINE_MAP_MAX_LOCATION_WITH_COLS) + /* WHERE is a reasonable location for a fix-it; don't reject it. */ + return false; + + /* Otherwise we have an attempt to add a fix-it with an "awkward" + location: either one that we can't obtain column information + for (within an ordinary map), or one within a macro expansion. */ + stop_supporting_fixits (); + return true; +} + +/* Mark this rich_location as not supporting fixits, purging any that were + already added. */ + +void +rich_location::stop_supporting_fixits () +{ + m_seen_impossible_fixit = true; + + /* Purge the rich_location of any fix-its that were already added. */ + for (unsigned int i = 0; i < m_fixit_hints.count (); i++) + delete get_fixit_hint (i); + m_fixit_hints.truncate (0); +} + +/* Add HINT to the fix-it hints in this rich_location, + consolidating into the prior fixit if possible. */ + +void +rich_location::maybe_add_fixit (location_t start, + location_t next_loc, + const char *new_content) +{ + if (reject_impossible_fixit (start)) + return; + if (reject_impossible_fixit (next_loc)) + return; + + /* Only allow fix-it hints that affect a single line in one file. + Compare the end-points. */ + expanded_location exploc_start + = linemap_client_expand_location_to_spelling_point (start, + LOCATION_ASPECT_START); + expanded_location exploc_next_loc + = linemap_client_expand_location_to_spelling_point (next_loc, + LOCATION_ASPECT_START); + /* They must be within the same file... */ + if (exploc_start.file != exploc_next_loc.file) + { + stop_supporting_fixits (); + return; + } + /* ...and on the same line. */ + if (exploc_start.line != exploc_next_loc.line) + { + stop_supporting_fixits (); + return; + } + /* The columns must be in the correct order. This can fail if the + endpoints straddle the boundary for which the linemap can represent + columns (PR c/82050). */ + if (exploc_start.column > exploc_next_loc.column) + { + stop_supporting_fixits (); + return; + } + /* If we have very long lines, tokens will eventually fall back to + having column == 0. + We can't handle fix-it hints that use such locations. */ + if (exploc_start.column == 0 || exploc_next_loc.column == 0) + { + stop_supporting_fixits (); + return; + } + + const char *newline = strchr (new_content, '\n'); + if (newline) + { + /* For now, we can only support insertion of whole lines + i.e. starts at start of line, and the newline is at the end of + the insertion point. */ + + /* It must be an insertion, not a replacement/deletion. */ + if (start != next_loc) + { + stop_supporting_fixits (); + return; + } + + /* The insertion must be at the start of a line. */ + if (exploc_start.column != 1) + { + stop_supporting_fixits (); + return; + } + + /* The newline must be at end of NEW_CONTENT. + We could eventually split up fix-its at newlines if we wanted + to allow more generality (e.g. to allow adding multiple lines + with one add_fixit call. */ + if (newline[1] != '\0') + { + stop_supporting_fixits (); + return; + } + } + + /* Consolidate neighboring fixits. + Don't consolidate into newline-insertion fixits. */ + fixit_hint *prev = get_last_fixit_hint (); + if (prev && !prev->ends_with_newline_p ()) + if (prev->maybe_append (start, next_loc, new_content)) + return; + + m_fixit_hints.push (new fixit_hint (start, next_loc, new_content)); +} + +/* class fixit_hint. */ + +fixit_hint::fixit_hint (location_t start, + location_t next_loc, + const char *new_content) +: m_start (start), + m_next_loc (next_loc), + m_bytes (xstrdup (new_content)), + m_len (strlen (new_content)) +{ +} + +/* Does this fix-it hint affect the given line? */ + +bool +fixit_hint::affects_line_p (const char *file, int line) const +{ + expanded_location exploc_start + = linemap_client_expand_location_to_spelling_point (m_start, + LOCATION_ASPECT_START); + if (file != exploc_start.file) + return false; + if (line < exploc_start.line) + return false; + expanded_location exploc_next_loc + = linemap_client_expand_location_to_spelling_point (m_next_loc, + LOCATION_ASPECT_START); + if (file != exploc_next_loc.file) + return false; + if (line > exploc_next_loc.line) + return false; + return true; +} + +/* Method for consolidating fix-it hints, for use by + rich_location::maybe_add_fixit. + If possible, merge a pending fix-it hint with the given params + into this one and return true. + Otherwise return false. */ + +bool +fixit_hint::maybe_append (location_t start, + location_t next_loc, + const char *new_content) +{ + /* For consolidation to be possible, START must be at this hint's + m_next_loc. */ + if (start != m_next_loc) + return false; + + /* If so, we have neighboring replacements; merge them. */ + m_next_loc = next_loc; + size_t extra_len = strlen (new_content); + m_bytes = (char *)xrealloc (m_bytes, m_len + extra_len + 1); + memcpy (m_bytes + m_len, new_content, extra_len); + m_len += extra_len; + m_bytes[m_len] = '\0'; + return true; +} + +/* Return true iff this hint's content ends with a newline. */ + +bool +fixit_hint::ends_with_newline_p () const +{ + if (m_len == 0) + return false; + return m_bytes[m_len - 1] == '\n'; +} diff --git a/support/cpp/libcpp/macro.c b/support/cpp/libcpp/macro.c deleted file mode 100644 index 1d990d206..000000000 --- a/support/cpp/libcpp/macro.c +++ /dev/null @@ -1,2126 +0,0 @@ -/* Part of CPP library. (Macro and #define handling.) - Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. - Written by Per Bothner, 1994. - Based on CCCP program by Paul Rubin, June 1986 - Adapted to ANSI C, Richard Stallman, Jan 1987 - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -#include "config.h" -#include "system.h" -#include "cpplib.h" -#include "internal.h" - -typedef struct macro_arg macro_arg; -struct macro_arg -{ - const cpp_token **first; /* First token in unexpanded argument. */ - const cpp_token **expanded; /* Macro-expanded argument. */ - const cpp_token *stringified; /* Stringified argument. */ - unsigned int count; /* # of tokens in argument. */ - unsigned int expanded_count; /* # of tokens in expanded argument. */ -}; - -/* Macro expansion. */ - -static int enter_macro_context (cpp_reader *, cpp_hashnode *, - const cpp_token *); -static int builtin_macro (cpp_reader *, cpp_hashnode *); -static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *, - const cpp_token **, unsigned int); -static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *, - _cpp_buff **); -static cpp_context *next_context (cpp_reader *); -static const cpp_token *padding_token (cpp_reader *, const cpp_token *); -static void expand_arg (cpp_reader *, macro_arg *); -static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int); -static const cpp_token *stringify_arg (cpp_reader *, macro_arg *); -static void paste_all_tokens (cpp_reader *, const cpp_token *); -static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *); -static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *, - macro_arg *); -static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *, - _cpp_buff **); -static bool create_iso_definition (cpp_reader *, cpp_macro *); - -/* #define directive parsing and handling. */ - -static cpp_token *alloc_expansion_token (cpp_reader *, cpp_macro *); -static cpp_token *lex_expansion_token (cpp_reader *, cpp_macro *); -static bool warn_of_redefinition (cpp_reader *, cpp_hashnode *, - const cpp_macro *); -static bool parse_params (cpp_reader *, cpp_macro *); -static void check_trad_stringification (cpp_reader *, const cpp_macro *, - const cpp_string *); - -/* Emits a warning if NODE is a macro defined in the main file that - has not been used. */ -int -_cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node, - void *v ATTRIBUTE_UNUSED) -{ - if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) - { - cpp_macro *macro = node->value.macro; - - if (!macro->used - && MAIN_FILE_P (linemap_lookup (pfile->line_table, macro->line))) - cpp_warning_with_line (pfile, CPP_W_UNUSED_MACROS, macro->line, 0, - "macro \"%s\" is not used", NODE_NAME (node)); - } - - return 1; -} - -/* Allocates and returns a CPP_STRING token, containing TEXT of length - LEN, after null-terminating it. TEXT must be in permanent storage. */ -static const cpp_token * -new_string_token (cpp_reader *pfile, unsigned char *text, unsigned int len) -{ - cpp_token *token = _cpp_temp_token (pfile); - - text[len] = '\0'; - token->type = CPP_STRING; - token->val.str.len = len; - token->val.str.text = text; - token->flags = 0; - return token; -} - -static const char * const monthnames[] = -{ - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -/* Helper function for builtin_macro. Returns the text generated by - a builtin macro. */ -const uchar * -_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node) -{ - const struct line_map *map; - const uchar *result = NULL; - linenum_type number = 1; - - switch (node->value.builtin) - { - default: - cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"", - NODE_NAME (node)); - break; - - case BT_TIMESTAMP: - { - cpp_buffer *pbuffer = cpp_get_buffer (pfile); - if (pbuffer->timestamp == NULL) - { - /* Initialize timestamp value of the assotiated file. */ - struct _cpp_file *file = cpp_get_file (pbuffer); - if (file) - { - /* Generate __TIMESTAMP__ string, that represents - the date and time of the last modification - of the current source file. The string constant - looks like "Sun Sep 16 01:03:52 1973". */ - struct tm *tb = NULL; - struct stat *st = _cpp_get_file_stat (file); - if (st) - tb = localtime (&st->st_mtime); - if (tb) - { - char *str = asctime (tb); - size_t len = strlen (str); - unsigned char *buf = _cpp_unaligned_alloc (pfile, len + 2); - buf[0] = '"'; - strcpy ((char *) buf + 1, str); - buf[len] = '"'; - pbuffer->timestamp = buf; - } - else - { - cpp_errno (pfile, CPP_DL_WARNING, - "could not determine file timestamp"); - pbuffer->timestamp = UC"\"??? ??? ?? ??:??:?? ????\""; - } - } - } - result = pbuffer->timestamp; - } - break; - case BT_FILE: - case BT_BASE_FILE: - { - unsigned int len; - const char *name; - uchar *buf; - map = linemap_lookup (pfile->line_table, pfile->line_table->highest_line); - - if (node->value.builtin == BT_BASE_FILE) - while (! MAIN_FILE_P (map)) - map = INCLUDED_FROM (pfile->line_table, map); - - name = map->to_file; - len = strlen (name); - buf = _cpp_unaligned_alloc (pfile, len * 2 + 3); - result = buf; - *buf = '"'; - buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len); - *buf++ = '"'; - *buf = '\0'; - } - break; - - case BT_INCLUDE_LEVEL: - /* The line map depth counts the primary source as level 1, but - historically __INCLUDE_DEPTH__ has called the primary source - level 0. */ - number = pfile->line_table->depth - 1; - break; - - case BT_SPECLINE: - map = &pfile->line_table->maps[pfile->line_table->used-1]; - /* If __LINE__ is embedded in a macro, it must expand to the - line of the macro's invocation, not its definition. - Otherwise things like assert() will not work properly. */ - number = SOURCE_LINE (map, - CPP_OPTION (pfile, traditional) - ? pfile->line_table->highest_line - : pfile->cur_token[-1].src_loc); - break; - - /* __STDC__ has the value 1 under normal circumstances. - However, if (a) we are in a system header, (b) the option - stdc_0_in_system_headers is true (set by target config), and - (c) we are not in strictly conforming mode, then it has the - value 0. (b) and (c) are already checked in cpp_init_builtins. */ - case BT_STDC: - if (cpp_in_system_header (pfile)) - number = 0; - else - number = 1; - break; - - case BT_DATE: - case BT_TIME: - if (pfile->date == NULL) - { - /* Allocate __DATE__ and __TIME__ strings from permanent - storage. We only do this once, and don't generate them - at init time, because time() and localtime() are very - slow on some systems. */ - time_t tt; - struct tm *tb = NULL; - - /* (time_t) -1 is a legitimate value for "number of seconds - since the Epoch", so we have to do a little dance to - distinguish that from a genuine error. */ - errno = 0; - tt = time(NULL); - if (tt != (time_t)-1 || errno == 0) - tb = localtime (&tt); - - if (tb) - { - pfile->date = _cpp_unaligned_alloc (pfile, - sizeof ("\"Oct 11 1347\"")); - sprintf ((char *) pfile->date, "\"%s %2d %4d\"", - monthnames[tb->tm_mon], tb->tm_mday, - tb->tm_year + 1900); - - pfile->time = _cpp_unaligned_alloc (pfile, - sizeof ("\"12:34:56\"")); - sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"", - tb->tm_hour, tb->tm_min, tb->tm_sec); - } - else - { - cpp_errno (pfile, CPP_DL_WARNING, - "could not determine date and time"); - - pfile->date = UC"\"??? ?? ????\""; - pfile->time = UC"\"??:??:??\""; - } - } - - if (node->value.builtin == BT_DATE) - result = pfile->date; - else - result = pfile->time; - break; - - case BT_COUNTER: - if (CPP_OPTION (pfile, directives_only) && pfile->state.in_directive) - cpp_error (pfile, CPP_DL_ERROR, - "__COUNTER__ expanded inside directive with -fdirectives-only"); - number = pfile->counter++; - break; - } - - if (result == NULL) - { - /* 21 bytes holds all NUL-terminated unsigned 64-bit numbers. */ - result = _cpp_unaligned_alloc (pfile, 21); - sprintf ((char *) result, "%u", number); - } - - return result; -} - -/* Convert builtin macros like __FILE__ to a token and push it on the - context stack. Also handles _Pragma, for which a new token may not - be created. Returns 1 if it generates a new token context, 0 to - return the token to the caller. */ -static int -builtin_macro (cpp_reader *pfile, cpp_hashnode *node) -{ - const uchar *buf; - size_t len; - char *nbuf; - - if (node->value.builtin == BT_PRAGMA) - { - /* Don't interpret _Pragma within directives. The standard is - not clear on this, but to me this makes most sense. */ - if (pfile->state.in_directive) - return 0; - - return _cpp_do__Pragma (pfile); - } - - buf = _cpp_builtin_macro_text (pfile, node); - len = ustrlen (buf); - nbuf = (char *) alloca (len + 1); - memcpy (nbuf, buf, len); - nbuf[len]='\n'; - - cpp_push_buffer (pfile, (uchar *) nbuf, len, /* from_stage3 */ true); - _cpp_clean_line (pfile); - - /* Set pfile->cur_token as required by _cpp_lex_direct. */ - pfile->cur_token = _cpp_temp_token (pfile); - _cpp_push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1); - if (pfile->buffer->cur != pfile->buffer->rlimit) - cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"", - NODE_NAME (node)); - _cpp_pop_buffer (pfile); - - return 1; -} - -/* Copies SRC, of length LEN, to DEST, adding backslashes before all - backslashes and double quotes. DEST must be of sufficient size. - Returns a pointer to the end of the string. */ -uchar * -cpp_quote_string (uchar *dest, const uchar *src, unsigned int len) -{ - while (len--) - { - uchar c = *src++; - - if (c == '\\' || c == '"') - { - *dest++ = '\\'; - *dest++ = c; - } - else - *dest++ = c; - } - - return dest; -} - -/* Convert a token sequence ARG to a single string token according to - the rules of the ISO C #-operator. */ -static const cpp_token * -stringify_arg (cpp_reader *pfile, macro_arg *arg) -{ - unsigned char *dest; - unsigned int i, escape_it, backslash_count = 0; - const cpp_token *source = NULL; - size_t len; - - if (BUFF_ROOM (pfile->u_buff) < 3) - _cpp_extend_buff (pfile, &pfile->u_buff, 3); - dest = BUFF_FRONT (pfile->u_buff); - *dest++ = '"'; - - /* Loop, reading in the argument's tokens. */ - for (i = 0; i < arg->count; i++) - { - const cpp_token *token = arg->first[i]; - - if (token->type == CPP_PADDING) - { - if (source == NULL - || (!(source->flags & PREV_WHITE) - && token->val.source == NULL)) - source = token->val.source; - continue; - } - - escape_it = (token->type == CPP_STRING || token->type == CPP_CHAR - || token->type == CPP_WSTRING || token->type == CPP_WCHAR - || token->type == CPP_STRING32 || token->type == CPP_CHAR32 - || token->type == CPP_STRING16 || token->type == CPP_CHAR16 - || token->type == CPP_UTF8STRING); - - /* Room for each char being written in octal, initial space and - final quote and NUL. */ - len = cpp_token_len (token); - if (escape_it) - len *= 4; - len += 3; - - if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len) - { - size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff); - _cpp_extend_buff (pfile, &pfile->u_buff, len); - dest = BUFF_FRONT (pfile->u_buff) + len_so_far; - } - - /* Leading white space? */ - if (dest - 1 != BUFF_FRONT (pfile->u_buff)) - { - if (source == NULL) - source = token; - if (source->flags & PREV_WHITE) - *dest++ = ' '; - } - source = NULL; - - if (escape_it) - { - _cpp_buff *buff = _cpp_get_buff (pfile, len); - unsigned char *buf = BUFF_FRONT (buff); - len = cpp_spell_token (pfile, token, buf, true) - buf; - dest = cpp_quote_string (dest, buf, len); - _cpp_release_buff (pfile, buff); - } - else - dest = cpp_spell_token (pfile, token, dest, true); - - if (token->type == CPP_OTHER && token->val.str.text[0] == '\\') - backslash_count++; - else - backslash_count = 0; - } - - /* Ignore the final \ of invalid string literals. */ - if (backslash_count & 1) - { - cpp_error (pfile, CPP_DL_WARNING, - "invalid string literal, ignoring final '\\'"); - dest--; - } - - /* Commit the memory, including NUL, and return the token. */ - *dest++ = '"'; - len = dest - BUFF_FRONT (pfile->u_buff); - BUFF_FRONT (pfile->u_buff) = dest + 1; - return new_string_token (pfile, dest - len, len); -} - -/* Try to paste two tokens. On success, return nonzero. In any - case, PLHS is updated to point to the pasted token, which is - guaranteed to not have the PASTE_LEFT flag set. */ -static bool -paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs) -{ - unsigned char *buf, *end, *lhsend; - cpp_token *lhs; - unsigned int len; - - len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 1; - buf = (unsigned char *) alloca (len); - end = lhsend = cpp_spell_token (pfile, *plhs, buf, false); - - /* Avoid comment headers, since they are still processed in stage 3. - It is simpler to insert a space here, rather than modifying the - lexer to ignore comments in some circumstances. Simply returning - false doesn't work, since we want to clear the PASTE_LEFT flag. */ - if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ) - *end++ = ' '; - /* In one obscure case we might see padding here. */ - if (rhs->type != CPP_PADDING) - end = cpp_spell_token (pfile, rhs, end, false); - *end = '\n'; - - cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true); - _cpp_clean_line (pfile); - - /* Set pfile->cur_token as required by _cpp_lex_direct. */ - pfile->cur_token = _cpp_temp_token (pfile); - lhs = _cpp_lex_direct (pfile); - if (pfile->buffer->cur != pfile->buffer->rlimit) - { - source_location saved_loc = lhs->src_loc; - - _cpp_pop_buffer (pfile); - _cpp_backup_tokens (pfile, 1); - *lhsend = '\0'; - - /* We have to remove the PASTE_LEFT flag from the old lhs, but - we want to keep the new location. */ - *lhs = **plhs; - *plhs = lhs; - lhs->src_loc = saved_loc; - lhs->flags &= ~PASTE_LEFT; - - /* Mandatory error for all apart from assembler. */ - if (CPP_OPTION (pfile, lang) != CLK_ASM) - cpp_error (pfile, CPP_DL_ERROR, - "pasting \"%s\" and \"%s\" does not give a valid preprocessing token", - buf, cpp_token_as_text (pfile, rhs)); - return false; - } - - *plhs = lhs; - _cpp_pop_buffer (pfile); - return true; -} - -/* Handles an arbitrarily long sequence of ## operators, with initial - operand LHS. This implementation is left-associative, - non-recursive, and finishes a paste before handling succeeding - ones. If a paste fails, we back up to the RHS of the failing ## - operator before pushing the context containing the result of prior - successful pastes, with the effect that the RHS appears in the - output stream after the pasted LHS normally. */ -static void -paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs) -{ - const cpp_token *rhs; - cpp_context *context = pfile->context; - - do - { - /* Take the token directly from the current context. We can do - this, because we are in the replacement list of either an - object-like macro, or a function-like macro with arguments - inserted. In either case, the constraints to #define - guarantee we have at least one more token. */ - if (context->direct_p) - rhs = FIRST (context).token++; - else - rhs = *FIRST (context).ptoken++; - - if (rhs->type == CPP_PADDING) - { - if (rhs->flags & PASTE_LEFT) - abort (); - } - if (!paste_tokens (pfile, &lhs, rhs)) - break; - } - while (rhs->flags & PASTE_LEFT); - - /* Put the resulting token in its own context. */ - _cpp_push_token_context (pfile, NULL, lhs, 1); -} - -/* Returns TRUE if the number of arguments ARGC supplied in an - invocation of the MACRO referenced by NODE is valid. An empty - invocation to a macro with no parameters should pass ARGC as zero. - - Note that MACRO cannot necessarily be deduced from NODE, in case - NODE was redefined whilst collecting arguments. */ -bool -_cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node, unsigned int argc) -{ - if (argc == macro->paramc) - return true; - - if (argc < macro->paramc) - { - /* As an extension, a rest argument is allowed to not appear in - the invocation at all. - e.g. #define debug(format, args...) something - debug("string"); - - This is exactly the same as if there had been an empty rest - argument - debug("string", ). */ - - if (argc + 1 == macro->paramc && macro->variadic) - { - if (CPP_PEDANTIC (pfile) && ! macro->syshdr) - cpp_error (pfile, CPP_DL_PEDWARN, - "ISO C99 requires rest arguments to be used"); - return true; - } - - cpp_error (pfile, CPP_DL_ERROR, - "macro \"%s\" requires %u arguments, but only %u given", - NODE_NAME (node), macro->paramc, argc); - } - else - cpp_error (pfile, CPP_DL_ERROR, - "macro \"%s\" passed %u arguments, but takes just %u", - NODE_NAME (node), argc, macro->paramc); - - return false; -} - -/* Reads and returns the arguments to a function-like macro - invocation. Assumes the opening parenthesis has been processed. - If there is an error, emits an appropriate diagnostic and returns - NULL. Each argument is terminated by a CPP_EOF token, for the - future benefit of expand_arg(). If there are any deferred - #pragma directives among macro arguments, store pointers to the - CPP_PRAGMA ... CPP_PRAGMA_EOL tokens into *PRAGMA_BUFF buffer. */ -static _cpp_buff * -collect_args (cpp_reader *pfile, const cpp_hashnode *node, - _cpp_buff **pragma_buff) -{ - _cpp_buff *buff, *base_buff; - cpp_macro *macro; - macro_arg *args, *arg; - const cpp_token *token; - unsigned int argc; - - macro = node->value.macro; - if (macro->paramc) - argc = macro->paramc; - else - argc = 1; - buff = _cpp_get_buff (pfile, argc * (50 * sizeof (cpp_token *) - + sizeof (macro_arg))); - base_buff = buff; - args = (macro_arg *) buff->base; - memset (args, 0, argc * sizeof (macro_arg)); - buff->cur = (unsigned char *) &args[argc]; - arg = args, argc = 0; - - /* Collect the tokens making up each argument. We don't yet know - how many arguments have been supplied, whether too many or too - few. Hence the slightly bizarre usage of "argc" and "arg". */ - do - { - unsigned int paren_depth = 0; - unsigned int ntokens = 0; - - argc++; - arg->first = (const cpp_token **) buff->cur; - - for (;;) - { - /* Require space for 2 new tokens (including a CPP_EOF). */ - if ((unsigned char *) &arg->first[ntokens + 2] > buff->limit) - { - buff = _cpp_append_extend_buff (pfile, buff, - 1000 * sizeof (cpp_token *)); - arg->first = (const cpp_token **) buff->cur; - } - - token = cpp_get_token (pfile); - - if (token->type == CPP_PADDING) - { - /* Drop leading padding. */ - if (ntokens == 0) - continue; - } - else if (token->type == CPP_OPEN_PAREN) - paren_depth++; - else if (token->type == CPP_CLOSE_PAREN) - { - if (paren_depth-- == 0) - break; - } - else if (token->type == CPP_COMMA) - { - /* A comma does not terminate an argument within - parentheses or as part of a variable argument. */ - if (paren_depth == 0 - && ! (macro->variadic && argc == macro->paramc)) - break; - } - else if (token->type == CPP_EOF - || (token->type == CPP_HASH && token->flags & BOL)) - break; - else if (token->type == CPP_PRAGMA) - { - cpp_token *newtok = _cpp_temp_token (pfile); - - /* CPP_PRAGMA token lives in directive_result, which will - be overwritten on the next directive. */ - *newtok = *token; - token = newtok; - do - { - if (*pragma_buff == NULL - || BUFF_ROOM (*pragma_buff) < sizeof (cpp_token *)) - { - _cpp_buff *next; - if (*pragma_buff == NULL) - *pragma_buff - = _cpp_get_buff (pfile, 32 * sizeof (cpp_token *)); - else - { - next = *pragma_buff; - *pragma_buff - = _cpp_get_buff (pfile, - (BUFF_FRONT (*pragma_buff) - - (*pragma_buff)->base) * 2); - (*pragma_buff)->next = next; - } - } - *(const cpp_token **) BUFF_FRONT (*pragma_buff) = token; - BUFF_FRONT (*pragma_buff) += sizeof (cpp_token *); - if (token->type == CPP_PRAGMA_EOL) - break; - token = cpp_get_token (pfile); - } - while (token->type != CPP_EOF); - - /* In deferred pragmas parsing_args and prevent_expansion - had been changed, reset it. */ - pfile->state.parsing_args = 2; - pfile->state.prevent_expansion = 1; - - if (token->type == CPP_EOF) - break; - else - continue; - } - - arg->first[ntokens++] = token; - } - - /* Drop trailing padding. */ - while (ntokens > 0 && arg->first[ntokens - 1]->type == CPP_PADDING) - ntokens--; - - arg->count = ntokens; - arg->first[ntokens] = &pfile->eof; - - /* Terminate the argument. Excess arguments loop back and - overwrite the final legitimate argument, before failing. */ - if (argc <= macro->paramc) - { - buff->cur = (unsigned char *) &arg->first[ntokens + 1]; - if (argc != macro->paramc) - arg++; - } - } - while (token->type != CPP_CLOSE_PAREN && token->type != CPP_EOF); - - if (token->type == CPP_EOF) - { - /* We still need the CPP_EOF to end directives, and to end - pre-expansion of a macro argument. Step back is not - unconditional, since we don't want to return a CPP_EOF to our - callers at the end of an -include-d file. */ - if (pfile->context->prev || pfile->state.in_directive) - _cpp_backup_tokens (pfile, 1); - cpp_error (pfile, CPP_DL_ERROR, - "unterminated argument list invoking macro \"%s\"", - NODE_NAME (node)); - } - else - { - /* A single empty argument is counted as no argument. */ - if (argc == 1 && macro->paramc == 0 && args[0].count == 0) - argc = 0; - if (_cpp_arguments_ok (pfile, macro, node, argc)) - { - /* GCC has special semantics for , ## b where b is a varargs - parameter: we remove the comma if b was omitted entirely. - If b was merely an empty argument, the comma is retained. - If the macro takes just one (varargs) parameter, then we - retain the comma only if we are standards conforming. - - If FIRST is NULL replace_args () swallows the comma. */ - if (macro->variadic && (argc < macro->paramc - || (argc == 1 && args[0].count == 0 - && !CPP_OPTION (pfile, std)))) - args[macro->paramc - 1].first = NULL; - return base_buff; - } - } - - /* An error occurred. */ - _cpp_release_buff (pfile, base_buff); - return NULL; -} - -/* Search for an opening parenthesis to the macro of NODE, in such a - way that, if none is found, we don't lose the information in any - intervening padding tokens. If we find the parenthesis, collect - the arguments and return the buffer containing them. PRAGMA_BUFF - argument is the same as in collect_args. */ -static _cpp_buff * -funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node, - _cpp_buff **pragma_buff) -{ - const cpp_token *token, *padding = NULL; - - for (;;) - { - token = cpp_get_token (pfile); - if (token->type != CPP_PADDING) - break; - if (padding == NULL - || (!(padding->flags & PREV_WHITE) && token->val.source == NULL)) - padding = token; - } - - if (token->type == CPP_OPEN_PAREN) - { - pfile->state.parsing_args = 2; - return collect_args (pfile, node, pragma_buff); - } - - /* CPP_EOF can be the end of macro arguments, or the end of the - file. We mustn't back up over the latter. Ugh. */ - if (token->type != CPP_EOF || token == &pfile->eof) - { - /* Back up. We may have skipped padding, in which case backing - up more than one token when expanding macros is in general - too difficult. We re-insert it in its own context. */ - _cpp_backup_tokens (pfile, 1); - if (padding) - _cpp_push_token_context (pfile, NULL, padding, 1); - } - - return NULL; -} - -/* Return the real number of tokens in the expansion of MACRO. */ -static inline unsigned int -macro_real_token_count (const cpp_macro *macro) -{ - unsigned int i; - if (__builtin_expect (!macro->extra_tokens, true)) - return macro->count; - for (i = 0; i < macro->count; i++) - if (macro->exp.tokens[i].type == CPP_PASTE) - return i; - abort (); - return 0; //makes compiler happy -} - -/* Push the context of a macro with hash entry NODE onto the context - stack. If we can successfully expand the macro, we push a context - containing its yet-to-be-rescanned replacement list and return one. - If there were additionally any unexpanded deferred #pragma directives - among macro arguments, push another context containing the - pragma tokens before the yet-to-be-rescanned replacement list - and return two. Otherwise, we don't push a context and return zero. */ -static int -enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, - const cpp_token *result) -{ - /* The presence of a macro invalidates a file's controlling macro. */ - pfile->mi_valid = false; - - pfile->state.angled_headers = false; - - if ((node->flags & NODE_BUILTIN) && !(node->flags & NODE_USED)) - { - node->flags |= NODE_USED; - if ((!pfile->cb.user_builtin_macro - || !pfile->cb.user_builtin_macro (pfile, node)) - && pfile->cb.used_define) - pfile->cb.used_define (pfile, pfile->directive_line, node); - } - - /* Handle standard macros. */ - if (! (node->flags & NODE_BUILTIN)) - { - cpp_macro *macro = node->value.macro; - _cpp_buff *pragma_buff = NULL; - - if (macro->fun_like) - { - _cpp_buff *buff; - - pfile->state.prevent_expansion++; - pfile->keep_tokens++; - pfile->state.parsing_args = 1; - buff = funlike_invocation_p (pfile, node, &pragma_buff); - pfile->state.parsing_args = 0; - pfile->keep_tokens--; - pfile->state.prevent_expansion--; - - if (buff == NULL) - { - if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr) - cpp_warning (pfile, CPP_W_TRADITIONAL, - "function-like macro \"%s\" must be used with arguments in traditional C", - NODE_NAME (node)); - - if (pragma_buff) - _cpp_release_buff (pfile, pragma_buff); - - return 0; - } - - if (macro->paramc > 0) - replace_args (pfile, node, macro, (macro_arg *) buff->base); - _cpp_release_buff (pfile, buff); - } - - /* Disable the macro within its expansion. */ - node->flags |= NODE_DISABLED; - - if (!(node->flags & NODE_USED)) - { - node->flags |= NODE_USED; - if (pfile->cb.used_define) - pfile->cb.used_define (pfile, pfile->directive_line, node); - } - - if (pfile->cb.used) - pfile->cb.used (pfile, result->src_loc, node); - - macro->used = 1; - - if (macro->paramc == 0) - _cpp_push_token_context (pfile, node, macro->exp.tokens, - macro_real_token_count (macro)); - - if (pragma_buff) - { - if (!pfile->state.in_directive) - _cpp_push_token_context (pfile, NULL, - padding_token (pfile, result), 1); - do - { - _cpp_buff *tail = pragma_buff->next; - pragma_buff->next = NULL; - push_ptoken_context (pfile, NULL, pragma_buff, - (const cpp_token **) pragma_buff->base, - ((const cpp_token **) BUFF_FRONT (pragma_buff) - - (const cpp_token **) pragma_buff->base)); - pragma_buff = tail; - } - while (pragma_buff != NULL); - return 2; - } - - return 1; - } - - /* Handle built-in macros and the _Pragma operator. */ - return builtin_macro (pfile, node); -} - -/* Replace the parameters in a function-like macro of NODE with the - actual ARGS, and place the result in a newly pushed token context. - Expand each argument before replacing, unless it is operated upon - by the # or ## operators. */ -static void -replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg *args) -{ - unsigned int i, total; - const cpp_token *src, *limit; - const cpp_token **dest, **first; - macro_arg *arg; - _cpp_buff *buff; - unsigned int count; - - /* First, fully macro-expand arguments, calculating the number of - tokens in the final expansion as we go. The ordering of the if - statements below is subtle; we must handle stringification before - pasting. */ - count = macro_real_token_count (macro); - total = count; - limit = macro->exp.tokens + count; - - for (src = macro->exp.tokens; src < limit; src++) - if (src->type == CPP_MACRO_ARG) - { - /* Leading and trailing padding tokens. */ - total += 2; - - /* We have an argument. If it is not being stringified or - pasted it is macro-replaced before insertion. */ - arg = &args[src->val.macro_arg.arg_no - 1]; - - if (src->flags & STRINGIFY_ARG) - { - if (!arg->stringified) - arg->stringified = stringify_arg (pfile, arg); - } - else if ((src->flags & PASTE_LEFT) - || (src > macro->exp.tokens && (src[-1].flags & PASTE_LEFT))) - total += arg->count - 1; - else - { - if (!arg->expanded) - expand_arg (pfile, arg); - total += arg->expanded_count - 1; - } - } - - /* Now allocate space for the expansion, copy the tokens and replace - the arguments. */ - buff = _cpp_get_buff (pfile, total * sizeof (cpp_token *)); - first = (const cpp_token **) buff->base; - dest = first; - - for (src = macro->exp.tokens; src < limit; src++) - { - unsigned int count; - const cpp_token **from, **paste_flag; - - if (src->type != CPP_MACRO_ARG) - { - *dest++ = src; - continue; - } - - paste_flag = 0; - arg = &args[src->val.macro_arg.arg_no - 1]; - if (src->flags & STRINGIFY_ARG) - count = 1, from = &arg->stringified; - else if (src->flags & PASTE_LEFT) - count = arg->count, from = arg->first; - else if (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT)) - { - count = arg->count, from = arg->first; - if (dest != first) - { - if (dest[-1]->type == CPP_COMMA - && macro->variadic - && src->val.macro_arg.arg_no == macro->paramc) - { - /* Swallow a pasted comma if from == NULL, otherwise - drop the paste flag. */ - if (from == NULL) - dest--; - else - paste_flag = dest - 1; - } - /* Remove the paste flag if the RHS is a placemarker. */ - else if (count == 0) - paste_flag = dest - 1; - } - } - else - count = arg->expanded_count, from = arg->expanded; - - /* Padding on the left of an argument (unless RHS of ##). */ - if ((!pfile->state.in_directive || pfile->state.directive_wants_padding) - && src != macro->exp.tokens && !(src[-1].flags & PASTE_LEFT)) - *dest++ = padding_token (pfile, src); - - if (count) - { - memcpy (dest, from, count * sizeof (cpp_token *)); - dest += count; - - /* With a non-empty argument on the LHS of ##, the last - token should be flagged PASTE_LEFT. */ - if (src->flags & PASTE_LEFT) - paste_flag = dest - 1; - } - else if (CPP_PEDANTIC (pfile) && ! macro->syshdr - && ! CPP_OPTION (pfile, c99) - && ! cpp_in_system_header (pfile)) - { - cpp_error (pfile, CPP_DL_PEDWARN, - "invoking macro %s argument %d: " - "empty macro arguments are undefined" - " in ISO C90 and ISO C++98", - NODE_NAME (node), - src->val.macro_arg.arg_no); - } - - /* Avoid paste on RHS (even case count == 0). */ - if (!pfile->state.in_directive && !(src->flags & PASTE_LEFT)) - *dest++ = &pfile->avoid_paste; - - /* Add a new paste flag, or remove an unwanted one. */ - if (paste_flag) - { - cpp_token *token = _cpp_temp_token (pfile); - token->type = (*paste_flag)->type; - token->val = (*paste_flag)->val; - if (src->flags & PASTE_LEFT) - token->flags = (*paste_flag)->flags | PASTE_LEFT; - else - token->flags = (*paste_flag)->flags & ~PASTE_LEFT; - *paste_flag = token; - } - } - - /* Free the expanded arguments. */ - for (i = 0; i < macro->paramc; i++) - if (args[i].expanded) - free (args[i].expanded); - - push_ptoken_context (pfile, node, buff, first, dest - first); -} - -/* Return a special padding token, with padding inherited from SOURCE. */ -static const cpp_token * -padding_token (cpp_reader *pfile, const cpp_token *source) -{ - cpp_token *result = _cpp_temp_token (pfile); - - result->type = CPP_PADDING; - - /* Data in GCed data structures cannot be made const so far, so we - need a cast here. */ - result->val.source = (cpp_token *) source; - result->flags = 0; - return result; -} - -/* Get a new uninitialized context. Create a new one if we cannot - re-use an old one. */ -static cpp_context * -next_context (cpp_reader *pfile) -{ - cpp_context *result = pfile->context->next; - - if (result == 0) - { - result = XNEW (cpp_context); - result->prev = pfile->context; - result->next = 0; - pfile->context->next = result; - } - - pfile->context = result; - return result; -} - -/* Push a list of pointers to tokens. */ -static void -push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff, - const cpp_token **first, unsigned int count) -{ - cpp_context *context = next_context (pfile); - - context->direct_p = false; - context->macro = macro; - context->buff = buff; - FIRST (context).ptoken = first; - LAST (context).ptoken = first + count; -} - -/* Push a list of tokens. */ -void -_cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro, - const cpp_token *first, unsigned int count) -{ - cpp_context *context = next_context (pfile); - - context->direct_p = true; - context->macro = macro; - context->buff = NULL; - FIRST (context).token = first; - LAST (context).token = first + count; -} - -/* Push a traditional macro's replacement text. */ -void -_cpp_push_text_context (cpp_reader *pfile, cpp_hashnode *macro, - const uchar *start, size_t len) -{ - cpp_context *context = next_context (pfile); - - context->direct_p = true; - context->macro = macro; - context->buff = NULL; - CUR (context) = start; - RLIMIT (context) = start + len; - macro->flags |= NODE_DISABLED; -} - -/* Expand an argument ARG before replacing parameters in a - function-like macro. This works by pushing a context with the - argument's tokens, and then expanding that into a temporary buffer - as if it were a normal part of the token stream. collect_args() - has terminated the argument's tokens with a CPP_EOF so that we know - when we have fully expanded the argument. */ -static void -expand_arg (cpp_reader *pfile, macro_arg *arg) -{ - unsigned int capacity; - bool saved_warn_trad; - - if (arg->count == 0) - return; - - /* Don't warn about funlike macros when pre-expanding. */ - saved_warn_trad = CPP_WTRADITIONAL (pfile); - CPP_WTRADITIONAL (pfile) = 0; - - /* Loop, reading in the arguments. */ - capacity = 256; - arg->expanded = XNEWVEC (const cpp_token *, capacity); - - push_ptoken_context (pfile, NULL, NULL, arg->first, arg->count + 1); - for (;;) - { - const cpp_token *token; - - if (arg->expanded_count + 1 >= capacity) - { - capacity *= 2; - arg->expanded = XRESIZEVEC (const cpp_token *, arg->expanded, - capacity); - } - - token = cpp_get_token (pfile); - - if (token->type == CPP_EOF) - break; - - arg->expanded[arg->expanded_count++] = token; - } - - _cpp_pop_context (pfile); - - CPP_WTRADITIONAL (pfile) = saved_warn_trad; -} - -/* Pop the current context off the stack, re-enabling the macro if the - context represented a macro's replacement list. The context - structure is not freed so that we can re-use it later. */ -void -_cpp_pop_context (cpp_reader *pfile) -{ - cpp_context *context = pfile->context; - - if (context->macro) - context->macro->flags &= ~NODE_DISABLED; - - if (context->buff) - _cpp_release_buff (pfile, context->buff); - - pfile->context = context->prev; -} - -/* External routine to get a token. Also used nearly everywhere - internally, except for places where we know we can safely call - _cpp_lex_token directly, such as lexing a directive name. - - Macro expansions and directives are transparently handled, - including entering included files. Thus tokens are post-macro - expansion, and after any intervening directives. External callers - see CPP_EOF only at EOF. Internal callers also see it when meeting - a directive inside a macro call, when at the end of a directive and - state.in_directive is still 1, and at the end of argument - pre-expansion. */ -const cpp_token * -cpp_get_token (cpp_reader *pfile) -{ - const cpp_token *result; - bool can_set = pfile->set_invocation_location; - pfile->set_invocation_location = false; - - for (;;) - { - cpp_hashnode *node; - cpp_context *context = pfile->context; - - /* Context->prev == 0 <=> base context. */ - if (!context->prev) - result = _cpp_lex_token (pfile); - else if (FIRST (context).token != LAST (context).token) - { - if (context->direct_p) - result = FIRST (context).token++; - else - result = *FIRST (context).ptoken++; - - if (result->flags & PASTE_LEFT) - { - paste_all_tokens (pfile, result); - if (pfile->state.in_directive) - continue; - return padding_token (pfile, result); - } - } - else - { - _cpp_pop_context (pfile); - if (pfile->state.in_directive) - continue; - return &pfile->avoid_paste; - } - - if (pfile->state.in_directive && result->type == CPP_COMMENT) - continue; - - if (result->type != CPP_NAME) - break; - - node = result->val.node.node; - - if (node->type != NT_MACRO || (result->flags & NO_EXPAND)) - break; - - if (!(node->flags & NODE_DISABLED)) - { - int ret = 0; - /* If not in a macro context, and we're going to start an - expansion, record the location. */ - if (can_set && !context->macro) - pfile->invocation_location = result->src_loc; - if (pfile->state.prevent_expansion) - break; - - /* Conditional macros require that a predicate be evaluated - first. */ - if ((node->flags & NODE_CONDITIONAL) != 0) - { - if (pfile->cb.macro_to_expand) - { - bool whitespace_after; - const cpp_token *peek_tok = cpp_peek_token (pfile, 0); - - whitespace_after = (peek_tok->type == CPP_PADDING - || (peek_tok->flags & PREV_WHITE)); - node = pfile->cb.macro_to_expand (pfile, result); - if (node) - ret = enter_macro_context (pfile, node, result); - else if (whitespace_after) - { - /* If macro_to_expand hook returned NULL and it - ate some tokens, see if we don't need to add - a padding token in between this and the - next token. */ - peek_tok = cpp_peek_token (pfile, 0); - if (peek_tok->type != CPP_PADDING - && (peek_tok->flags & PREV_WHITE) == 0) - _cpp_push_token_context (pfile, NULL, - padding_token (pfile, - peek_tok), 1); - } - } - } - else - ret = enter_macro_context (pfile, node, result); - if (ret) - { - if (pfile->state.in_directive || ret == 2) - continue; - return padding_token (pfile, result); - } - } - else - { - /* Flag this token as always unexpandable. FIXME: move this - to collect_args()?. */ - cpp_token *t = _cpp_temp_token (pfile); - t->type = result->type; - t->flags = result->flags | NO_EXPAND; - t->val = result->val; - result = t; - } - - break; - } - - return result; -} - -/* Like cpp_get_token, but also returns a location separate from the - one provided by the returned token. LOC is an out parameter; *LOC - is set to the location "as expected by the user". This matters - when a token results from macro expansion -- the token's location - will indicate where the macro is defined, but *LOC will be the - location of the start of the expansion. */ -const cpp_token * -cpp_get_token_with_location (cpp_reader *pfile, source_location *loc) -{ - const cpp_token *result; - - pfile->set_invocation_location = true; - result = cpp_get_token (pfile); - if (pfile->context->macro) - *loc = pfile->invocation_location; - else - *loc = result->src_loc; - - return result; -} - -/* Returns true if we're expanding an object-like macro that was - defined in a system header. Just checks the macro at the top of - the stack. Used for diagnostic suppression. */ -int -cpp_sys_macro_p (cpp_reader *pfile) -{ - cpp_hashnode *node = pfile->context->macro; - - return node && node->value.macro && node->value.macro->syshdr; -} - -/* Read each token in, until end of the current file. Directives are - transparently processed. */ -void -cpp_scan_nooutput (cpp_reader *pfile) -{ - /* Request a CPP_EOF token at the end of this file, rather than - transparently continuing with the including file. */ - pfile->buffer->return_at_eof = true; - - pfile->state.discarding_output++; - pfile->state.prevent_expansion++; - - if (CPP_OPTION (pfile, traditional)) - while (_cpp_read_logical_line_trad (pfile)) - ; - else - while (cpp_get_token (pfile)->type != CPP_EOF) - ; - - pfile->state.discarding_output--; - pfile->state.prevent_expansion--; -} - -/* Step back one or more tokens obtained from the lexer. */ -void -_cpp_backup_tokens_direct (cpp_reader *pfile, unsigned int count) -{ - pfile->lookaheads += count; - while (count--) - { - pfile->cur_token--; - if (pfile->cur_token == pfile->cur_run->base - /* Possible with -fpreprocessed and no leading #line. */ - && pfile->cur_run->prev != NULL) - { - pfile->cur_run = pfile->cur_run->prev; - pfile->cur_token = pfile->cur_run->limit; - } - } -} - -/* Step back one (or more) tokens. Can only step back more than 1 if - they are from the lexer, and not from macro expansion. */ -void -_cpp_backup_tokens (cpp_reader *pfile, unsigned int count) -{ - if (pfile->context->prev == NULL) - _cpp_backup_tokens_direct (pfile, count); - else - { - if (count != 1) - abort (); - if (pfile->context->direct_p) - FIRST (pfile->context).token--; - else - FIRST (pfile->context).ptoken--; - } -} - -/* #define directive parsing and handling. */ - -/* Returns nonzero if a macro redefinition warning is required. */ -static bool -warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node, - const cpp_macro *macro2) -{ - const cpp_macro *macro1; - unsigned int i; - - /* Some redefinitions need to be warned about regardless. */ - if (node->flags & NODE_WARN) - return true; - - /* Suppress warnings for builtins that lack the NODE_WARN flag. */ - if (node->flags & NODE_BUILTIN) - { - if (!pfile->cb.user_builtin_macro - || !pfile->cb.user_builtin_macro (pfile, node)) - return false; - } - - /* Redefinitions of conditional (context-sensitive) macros, on - the other hand, must be allowed silently. */ - if (node->flags & NODE_CONDITIONAL) - return false; - - /* Redefinition of a macro is allowed if and only if the old and new - definitions are the same. (6.10.3 paragraph 2). */ - macro1 = node->value.macro; - - /* Don't check count here as it can be different in valid - traditional redefinitions with just whitespace differences. */ - if (macro1->paramc != macro2->paramc - || macro1->fun_like != macro2->fun_like - || macro1->variadic != macro2->variadic) - return true; - - /* Check parameter spellings. */ - for (i = 0; i < macro1->paramc; i++) - if (macro1->params[i] != macro2->params[i]) - return true; - - /* Check the replacement text or tokens. */ - if (CPP_OPTION (pfile, traditional)) - return _cpp_expansions_different_trad (macro1, macro2); - - if (macro1->count != macro2->count) - return true; - - for (i = 0; i < macro1->count; i++) - if (!_cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i])) - return true; - - return false; -} - -/* Free the definition of hashnode H. */ -void -_cpp_free_definition (cpp_hashnode *h) -{ - /* Macros and assertions no longer have anything to free. */ - h->type = NT_VOID; - /* Clear builtin flag in case of redefinition. */ - h->flags &= ~(NODE_BUILTIN | NODE_DISABLED | NODE_USED); -} - -/* Save parameter NODE to the parameter list of macro MACRO. Returns - zero on success, nonzero if the parameter is a duplicate. */ -bool -_cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node) -{ - unsigned int len; - /* Constraint 6.10.3.6 - duplicate parameter names. */ - if (node->flags & NODE_MACRO_ARG) - { - cpp_error (pfile, CPP_DL_ERROR, "duplicate macro parameter \"%s\"", - NODE_NAME (node)); - return true; - } - - if (BUFF_ROOM (pfile->a_buff) - < (macro->paramc + 1) * sizeof (cpp_hashnode *)) - _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *)); - - ((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[macro->paramc++] = node; - node->flags |= NODE_MACRO_ARG; - len = macro->paramc * sizeof (union _cpp_hashnode_value); - if (len > pfile->macro_buffer_len) - { - pfile->macro_buffer = XRESIZEVEC (unsigned char, pfile->macro_buffer, - len); - pfile->macro_buffer_len = len; - } - ((union _cpp_hashnode_value *) pfile->macro_buffer)[macro->paramc - 1] - = node->value; - - node->value.arg_index = macro->paramc; - return false; -} - -/* Check the syntax of the parameters in a MACRO definition. Returns - false if an error occurs. */ -static bool -parse_params (cpp_reader *pfile, cpp_macro *macro) -{ - unsigned int prev_ident = 0; - - for (;;) - { - const cpp_token *token = _cpp_lex_token (pfile); - - switch (token->type) - { - default: - /* Allow/ignore comments in parameter lists if we are - preserving comments in macro expansions. */ - if (token->type == CPP_COMMENT - && ! CPP_OPTION (pfile, discard_comments_in_macro_exp)) - continue; - - cpp_error (pfile, CPP_DL_ERROR, - "\"%s\" may not appear in macro parameter list", - cpp_token_as_text (pfile, token)); - return false; - - case CPP_NAME: - if (prev_ident) - { - cpp_error (pfile, CPP_DL_ERROR, - "macro parameters must be comma-separated"); - return false; - } - prev_ident = 1; - - if (_cpp_save_parameter (pfile, macro, token->val.node.node)) - return false; - continue; - - case CPP_CLOSE_PAREN: - if (prev_ident || macro->paramc == 0) - return true; - - /* Fall through to pick up the error. */ - case CPP_COMMA: - if (!prev_ident) - { - cpp_error (pfile, CPP_DL_ERROR, "parameter name missing"); - return false; - } - prev_ident = 0; - continue; - - case CPP_ELLIPSIS: - macro->variadic = 1; - if (!prev_ident) - { - _cpp_save_parameter (pfile, macro, - pfile->spec_nodes.n__VA_ARGS__); - pfile->state.va_args_ok = 1; - if (! CPP_OPTION (pfile, c99) - && CPP_OPTION (pfile, cpp_pedantic) - && CPP_OPTION (pfile, warn_variadic_macros)) - cpp_pedwarning - (pfile, CPP_W_VARIADIC_MACROS, - "anonymous variadic macros were introduced in C99"); - } - else if (CPP_OPTION (pfile, cpp_pedantic) - && CPP_OPTION (pfile, warn_variadic_macros)) - cpp_pedwarning (pfile, CPP_W_VARIADIC_MACROS, - "ISO C does not permit named variadic macros"); - - /* We're at the end, and just expect a closing parenthesis. */ - token = _cpp_lex_token (pfile); - if (token->type == CPP_CLOSE_PAREN) - return true; - /* Fall through. */ - - case CPP_EOF: - cpp_error (pfile, CPP_DL_ERROR, "missing ')' in macro parameter list"); - return false; - } - } -} - -/* Allocate room for a token from a macro's replacement list. */ -static cpp_token * -alloc_expansion_token (cpp_reader *pfile, cpp_macro *macro) -{ - if (BUFF_ROOM (pfile->a_buff) < (macro->count + 1) * sizeof (cpp_token)) - _cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_token)); - - return &((cpp_token *) BUFF_FRONT (pfile->a_buff))[macro->count++]; -} - -/* Lex a token from the expansion of MACRO, but mark parameters as we - find them and warn of traditional stringification. */ -static cpp_token * -lex_expansion_token (cpp_reader *pfile, cpp_macro *macro) -{ - cpp_token *token, *saved_cur_token; - - saved_cur_token = pfile->cur_token; - pfile->cur_token = alloc_expansion_token (pfile, macro); - token = _cpp_lex_direct (pfile); - pfile->cur_token = saved_cur_token; - - /* Is this a parameter? */ - if (token->type == CPP_NAME - && (token->val.node.node->flags & NODE_MACRO_ARG) != 0) - { - token->type = CPP_MACRO_ARG; - token->val.macro_arg.arg_no = token->val.node.node->value.arg_index; - } - else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0 - && (token->type == CPP_STRING || token->type == CPP_CHAR)) - check_trad_stringification (pfile, macro, &token->val.str); - - return token; -} - -static bool -create_iso_definition (cpp_reader *pfile, cpp_macro *macro) -{ - cpp_token *token; - const cpp_token *ctoken; - bool following_paste_op = false; - #define paste_op_error_msg \ - N_("'##' cannot appear at either end of a macro expansion") - unsigned int num_extra_tokens = 0; - - /* Get the first token of the expansion (or the '(' of a - function-like macro). */ - ctoken = _cpp_lex_token (pfile); - - if (ctoken->type == CPP_OPEN_PAREN && !(ctoken->flags & PREV_WHITE)) - { - bool ok = parse_params (pfile, macro); - macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff); - if (!ok) - return false; - - /* Success. Commit or allocate the parameter array. */ - if (pfile->hash_table->alloc_subobject) - { - cpp_hashnode **params = - (cpp_hashnode **) pfile->hash_table->alloc_subobject - (sizeof (cpp_hashnode *) * macro->paramc); - memcpy (params, macro->params, - sizeof (cpp_hashnode *) * macro->paramc); - macro->params = params; - } - else - BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; - macro->fun_like = 1; - } - else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE)) - { - /* While ISO C99 requires whitespace before replacement text - in a macro definition, ISO C90 with TC1 allows there characters - from the basic source character set. */ - if (CPP_OPTION (pfile, c99)) - cpp_error (pfile, CPP_DL_PEDWARN, - "ISO C99 requires whitespace after the macro name"); - else - { - int warntype = CPP_DL_WARNING; - switch (ctoken->type) - { - case CPP_ATSIGN: - case CPP_AT_NAME: - case CPP_OBJC_STRING: - /* '@' is not in basic character set. */ - warntype = CPP_DL_PEDWARN; - break; - case CPP_OTHER: - /* Basic character set sans letters, digits and _. */ - if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~", - ctoken->val.str.text[0]) == NULL) - warntype = CPP_DL_PEDWARN; - break; - default: - /* All other tokens start with a character from basic - character set. */ - break; - } - cpp_error (pfile, warntype, - "missing whitespace after the macro name"); - } - } - - if (macro->fun_like) - token = lex_expansion_token (pfile, macro); - else - { - token = alloc_expansion_token (pfile, macro); - *token = *ctoken; - } - - for (;;) - { - /* Check the stringifying # constraint 6.10.3.2.1 of - function-like macros when lexing the subsequent token. */ - if (macro->count > 1 && token[-1].type == CPP_HASH && macro->fun_like) - { - if (token->type == CPP_MACRO_ARG) - { - if (token->flags & PREV_WHITE) - token->flags |= SP_PREV_WHITE; - if (token[-1].flags & DIGRAPH) - token->flags |= SP_DIGRAPH; - token->flags &= ~PREV_WHITE; - token->flags |= STRINGIFY_ARG; - token->flags |= token[-1].flags & PREV_WHITE; - token[-1] = token[0]; - macro->count--; - } - /* Let assembler get away with murder. */ - /* sdcpp specific: don't complain abuout naked hash */ - else if ((CPP_OPTION (pfile, lang) != CLK_ASM) - && (!CPP_OPTION(pfile, allow_naked_hash))) - { - cpp_error (pfile, CPP_DL_ERROR, - "'#' is not followed by a macro parameter"); - return false; - } - } - - if (token->type == CPP_EOF) - { - /* Paste operator constraint 6.10.3.3.1: - Token-paste ##, can appear in both object-like and - function-like macros, but not at the end. */ - if (following_paste_op) - { - cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); - return false; - } - break; - } - - /* Paste operator constraint 6.10.3.3.1. */ - if (token->type == CPP_PASTE) - { - /* Token-paste ##, can appear in both object-like and - function-like macros, but not at the beginning. */ - if (macro->count == 1) - { - cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); - return false; - } - - if (token[-1].flags & PASTE_LEFT) - { - macro->extra_tokens = 1; - num_extra_tokens++; - token->val.token_no = macro->count - 1; - } - else - { - --macro->count; - token[-1].flags |= PASTE_LEFT; - if (token->flags & DIGRAPH) - token[-1].flags |= SP_DIGRAPH; - if (token->flags & PREV_WHITE) - token[-1].flags |= SP_PREV_WHITE; - } - } - - following_paste_op = (token->type == CPP_PASTE); - token = lex_expansion_token (pfile, macro); - } - - macro->exp.tokens = (cpp_token *) BUFF_FRONT (pfile->a_buff); - macro->traditional = 0; - - /* Don't count the CPP_EOF. */ - macro->count--; - - /* Clear whitespace on first token for warn_of_redefinition(). */ - if (macro->count) - macro->exp.tokens[0].flags &= ~PREV_WHITE; - - /* Commit or allocate the memory. */ - if (pfile->hash_table->alloc_subobject) - { - cpp_token *tokns = - (cpp_token *) pfile->hash_table->alloc_subobject (sizeof (cpp_token) - * macro->count); - if (num_extra_tokens) - { - /* Place second and subsequent ## or %:%: tokens in - sequences of consecutive such tokens at the end of the - list to preserve information about where they appear, how - they are spelt and whether they are preceded by - whitespace without otherwise interfering with macro - expansion. */ - cpp_token *normal_dest = tokns; - cpp_token *extra_dest = tokns + macro->count - num_extra_tokens; - unsigned int i; - for (i = 0; i < macro->count; i++) - { - if (macro->exp.tokens[i].type == CPP_PASTE) - *extra_dest++ = macro->exp.tokens[i]; - else - *normal_dest++ = macro->exp.tokens[i]; - } - } - else - memcpy (tokns, macro->exp.tokens, sizeof (cpp_token) * macro->count); - macro->exp.tokens = tokns; - } - else - BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->exp.tokens[macro->count]; - - return true; -} - -/* Parse a macro and save its expansion. Returns nonzero on success. */ -bool -_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) -{ - cpp_macro *macro; - unsigned int i; - bool ok; - - if (pfile->hash_table->alloc_subobject) - macro = (cpp_macro *) pfile->hash_table->alloc_subobject - (sizeof (cpp_macro)); - else - macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro)); - macro->line = pfile->directive_line; - macro->params = 0; - macro->paramc = 0; - macro->variadic = 0; - macro->used = !CPP_OPTION (pfile, warn_unused_macros); - macro->count = 0; - macro->fun_like = 0; - macro->extra_tokens = 0; - /* To suppress some diagnostics. */ - macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0; - - if (CPP_OPTION (pfile, traditional)) - ok = _cpp_create_trad_definition (pfile, macro); - else - { - ok = create_iso_definition (pfile, macro); - - /* We set the type for SEEN_EOL() in directives.c. - - Longer term we should lex the whole line before coming here, - and just copy the expansion. */ - - /* Stop the lexer accepting __VA_ARGS__. */ - pfile->state.va_args_ok = 0; - } - - /* Clear the fast argument lookup indices. */ - for (i = macro->paramc; i-- > 0; ) - { - struct cpp_hashnode *node = macro->params[i]; - node->flags &= ~ NODE_MACRO_ARG; - node->value = ((union _cpp_hashnode_value *) pfile->macro_buffer)[i]; - } - - if (!ok) - return ok; - - if (node->type == NT_MACRO) - { - if (CPP_OPTION (pfile, warn_unused_macros)) - _cpp_warn_if_unused_macro (pfile, node, NULL); - - if (warn_of_redefinition (pfile, node, macro)) - { - const int reason = (node->flags & NODE_BUILTIN) - ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE; - bool warned; - - warned = cpp_pedwarning_with_line (pfile, reason, - pfile->directive_line, 0, - "\"%s\" redefined", - NODE_NAME (node)); - - if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) - cpp_error_with_line (pfile, CPP_DL_NOTE, - node->value.macro->line, 0, - "this is the location of the previous definition"); - } - } - - if (node->type != NT_VOID) - _cpp_free_definition (node); - - /* Enter definition in hash table. */ - node->type = NT_MACRO; - node->value.macro = macro; - if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")) - && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_FORMAT_MACROS") - /* __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS are mentioned - in the C standard, as something that one must use in C++. - However DR#593 indicates that these aren't actually mentioned - in the C++ standard. We special-case them anyway. */ - && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_LIMIT_MACROS") - && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_CONSTANT_MACROS")) - node->flags |= NODE_WARN; - - /* If user defines one of the conditional macros, remove the - conditional flag */ - node->flags &= ~NODE_CONDITIONAL; - - return ok; -} - -/* Warn if a token in STRING matches one of a function-like MACRO's - parameters. */ -static void -check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro, - const cpp_string *string) -{ - unsigned int i, len; - const uchar *p, *q, *limit; - - /* Loop over the string. */ - limit = string->text + string->len - 1; - for (p = string->text + 1; p < limit; p = q) - { - /* Find the start of an identifier. */ - while (p < limit && !is_idstart (*p)) - p++; - - /* Find the end of the identifier. */ - q = p; - while (q < limit && is_idchar (*q)) - q++; - - len = q - p; - - /* Loop over the function macro arguments to see if the - identifier inside the string matches one of them. */ - for (i = 0; i < macro->paramc; i++) - { - const cpp_hashnode *node = macro->params[i]; - - if (NODE_LEN (node) == len - && !memcmp (p, NODE_NAME (node), len)) - { - cpp_error (pfile, CPP_DL_WARNING, - "macro argument \"%s\" would be stringified in traditional C", - NODE_NAME (node)); - break; - } - } - } -} - -/* Returns the name, arguments and expansion of a macro, in a format - suitable to be read back in again, and therefore also for DWARF 2 - debugging info. e.g. "PASTE(X, Y) X ## Y", or "MACNAME EXPANSION". - Caller is expected to generate the "#define" bit if needed. The - returned text is temporary, and automatically freed later. */ -const unsigned char * -cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node) -{ - unsigned int i, len; - const cpp_macro *macro; - unsigned char *buffer; - - if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN)) - { - if (node->type != NT_MACRO - || !pfile->cb.user_builtin_macro - || !pfile->cb.user_builtin_macro (pfile, node)) - { - cpp_error (pfile, CPP_DL_ICE, - "invalid hash type %d in cpp_macro_definition", - node->type); - return 0; - } - } - - macro = node->value.macro; - /* Calculate length. */ - len = NODE_LEN (node) + 2; /* ' ' and NUL. */ - if (macro->fun_like) - { - len += 4; /* "()" plus possible final ".." of named - varargs (we have + 1 below). */ - for (i = 0; i < macro->paramc; i++) - len += NODE_LEN (macro->params[i]) + 1; /* "," */ - } - - /* This should match below where we fill in the buffer. */ - if (CPP_OPTION (pfile, traditional)) - len += _cpp_replacement_text_len (macro); - else - { - unsigned int count = macro_real_token_count (macro); - for (i = 0; i < count; i++) - { - cpp_token *token = ¯o->exp.tokens[i]; - - if (token->type == CPP_MACRO_ARG) - len += NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]); - else - len += cpp_token_len (token); - - if (token->flags & STRINGIFY_ARG) - len++; /* "#" */ - if (token->flags & PASTE_LEFT) - len += 3; /* " ##" */ - if (token->flags & PREV_WHITE) - len++; /* " " */ - } - } - - if (len > pfile->macro_buffer_len) - { - pfile->macro_buffer = XRESIZEVEC (unsigned char, - pfile->macro_buffer, len); - pfile->macro_buffer_len = len; - } - - /* Fill in the buffer. Start with the macro name. */ - buffer = pfile->macro_buffer; - memcpy (buffer, NODE_NAME (node), NODE_LEN (node)); - buffer += NODE_LEN (node); - - /* Parameter names. */ - if (macro->fun_like) - { - *buffer++ = '('; - for (i = 0; i < macro->paramc; i++) - { - cpp_hashnode *param = macro->params[i]; - - if (param != pfile->spec_nodes.n__VA_ARGS__) - { - memcpy (buffer, NODE_NAME (param), NODE_LEN (param)); - buffer += NODE_LEN (param); - } - - if (i + 1 < macro->paramc) - /* Don't emit a space after the comma here; we're trying - to emit a Dwarf-friendly definition, and the Dwarf spec - forbids spaces in the argument list. */ - *buffer++ = ','; - else if (macro->variadic) - *buffer++ = '.', *buffer++ = '.', *buffer++ = '.'; - } - *buffer++ = ')'; - } - - /* The Dwarf spec requires a space after the macro name, even if the - definition is the empty string. */ - *buffer++ = ' '; - - if (CPP_OPTION (pfile, traditional)) - buffer = _cpp_copy_replacement_text (macro, buffer); - else if (macro->count) - /* Expansion tokens. */ - { - unsigned int count = macro_real_token_count (macro); - for (i = 0; i < count; i++) - { - cpp_token *token = ¯o->exp.tokens[i]; - - if (token->flags & PREV_WHITE) - *buffer++ = ' '; - if (token->flags & STRINGIFY_ARG) - *buffer++ = '#'; - - if (token->type == CPP_MACRO_ARG) - { - memcpy (buffer, - NODE_NAME (macro->params[token->val.macro_arg.arg_no - 1]), - NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1])); - buffer += NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]); - } - else - buffer = cpp_spell_token (pfile, token, buffer, false); - - if (token->flags & PASTE_LEFT) - { - *buffer++ = ' '; - *buffer++ = '#'; - *buffer++ = '#'; - /* Next has PREV_WHITE; see _cpp_create_definition. */ - } - } - } - - *buffer = '\0'; - return pfile->macro_buffer; -} diff --git a/support/cpp/libcpp/macro.cc b/support/cpp/libcpp/macro.cc new file mode 100644 index 000000000..8ebf360c0 --- /dev/null +++ b/support/cpp/libcpp/macro.cc @@ -0,0 +1,4131 @@ +/* Part of CPP library. (Macro and #define handling.) + Copyright (C) 1986-2022 Free Software Foundation, Inc. + Written by Per Bothner, 1994. + Based on CCCP program by Paul Rubin, June 1986 + Adapted to ANSI C, Richard Stallman, Jan 1987 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" + +typedef struct macro_arg macro_arg; +/* This structure represents the tokens of a macro argument. These + tokens can be macro themselves, in which case they can be either + expanded or unexpanded. When they are expanded, this data + structure keeps both the expanded and unexpanded forms. */ +struct macro_arg +{ + const cpp_token **first; /* First token in unexpanded argument. */ + const cpp_token **expanded; /* Macro-expanded argument. */ + const cpp_token *stringified; /* Stringified argument. */ + unsigned int count; /* # of tokens in argument. */ + unsigned int expanded_count; /* # of tokens in expanded argument. */ + location_t *virt_locs; /* Where virtual locations for + unexpanded tokens are stored. */ + location_t *expanded_virt_locs; /* Where virtual locations for + expanded tokens are + stored. */ +}; + +/* The kind of macro tokens which the instance of + macro_arg_token_iter is supposed to iterate over. */ +enum macro_arg_token_kind { + MACRO_ARG_TOKEN_NORMAL, + /* This is a macro argument token that got transformed into a string + literal, e.g. #foo. */ + MACRO_ARG_TOKEN_STRINGIFIED, + /* This is a token resulting from the expansion of a macro + argument that was itself a macro. */ + MACRO_ARG_TOKEN_EXPANDED +}; + +/* An iterator over tokens coming from a function-like macro + argument. */ +typedef struct macro_arg_token_iter macro_arg_token_iter; +struct macro_arg_token_iter +{ + /* Whether or not -ftrack-macro-expansion is used. */ + bool track_macro_exp_p; + /* The kind of token over which we are supposed to iterate. */ + enum macro_arg_token_kind kind; + /* A pointer to the current token pointed to by the iterator. */ + const cpp_token **token_ptr; + /* A pointer to the "full" location of the current token. If + -ftrack-macro-expansion is used this location tracks loci across + macro expansion. */ + const location_t *location_ptr; +#if CHECKING_P + /* The number of times the iterator went forward. This useful only + when checking is enabled. */ + size_t num_forwards; +#endif +}; + +/* Saved data about an identifier being used as a macro argument + name. */ +struct macro_arg_saved_data { + /* The canonical (UTF-8) spelling of this identifier. */ + cpp_hashnode *canonical_node; + /* The previous value & type of this identifier. */ + union _cpp_hashnode_value value; + node_type type; +}; + +static const char *vaopt_paste_error = + N_("'##' cannot appear at either end of __VA_OPT__"); + +static void expand_arg (cpp_reader *, macro_arg *); + +/* A class for tracking __VA_OPT__ state while iterating over a + sequence of tokens. This is used during both macro definition and + expansion. */ +class vaopt_state { + + public: + + enum update_type + { + ERROR, + DROP, + INCLUDE, + BEGIN, + END + }; + + /* Initialize the state tracker. ANY_ARGS is true if variable + arguments were provided to the macro invocation. */ + vaopt_state (cpp_reader *pfile, bool is_variadic, macro_arg *arg) + : m_pfile (pfile), + m_arg (arg), + m_variadic (is_variadic), + m_last_was_paste (false), + m_stringify (false), + m_state (0), + m_paste_location (0), + m_location (0), + m_update (ERROR) + { + } + + /* Given a token, update the state of this tracker and return a + boolean indicating whether the token should be be included in the + expansion. */ + update_type update (const cpp_token *token) + { + /* If the macro isn't variadic, just don't bother. */ + if (!m_variadic) + return INCLUDE; + + if (token->type == CPP_NAME + && token->val.node.node == m_pfile->spec_nodes.n__VA_OPT__) + { + if (m_state > 0) + { + cpp_error_at (m_pfile, CPP_DL_ERROR, token->src_loc, + "__VA_OPT__ may not appear in a __VA_OPT__"); + return ERROR; + } + ++m_state; + m_location = token->src_loc; + m_stringify = (token->flags & STRINGIFY_ARG) != 0; + return BEGIN; + } + else if (m_state == 1) + { + if (token->type != CPP_OPEN_PAREN) + { + cpp_error_at (m_pfile, CPP_DL_ERROR, m_location, + "__VA_OPT__ must be followed by an " + "open parenthesis"); + return ERROR; + } + ++m_state; + if (m_update == ERROR) + { + if (m_arg == NULL) + m_update = INCLUDE; + else + { + m_update = DROP; + if (!m_arg->expanded) + expand_arg (m_pfile, m_arg); + for (unsigned idx = 0; idx < m_arg->expanded_count; ++idx) + if (m_arg->expanded[idx]->type != CPP_PADDING) + { + m_update = INCLUDE; + break; + } + } + } + return DROP; + } + else if (m_state >= 2) + { + if (m_state == 2 && token->type == CPP_PASTE) + { + cpp_error_at (m_pfile, CPP_DL_ERROR, token->src_loc, + vaopt_paste_error); + return ERROR; + } + /* Advance states before further considering this token, in + case we see a close paren immediately after the open + paren. */ + if (m_state == 2) + ++m_state; + + bool was_paste = m_last_was_paste; + m_last_was_paste = false; + if (token->type == CPP_PASTE) + { + m_last_was_paste = true; + m_paste_location = token->src_loc; + } + else if (token->type == CPP_OPEN_PAREN) + ++m_state; + else if (token->type == CPP_CLOSE_PAREN) + { + --m_state; + if (m_state == 2) + { + /* Saw the final paren. */ + m_state = 0; + + if (was_paste) + { + cpp_error_at (m_pfile, CPP_DL_ERROR, token->src_loc, + vaopt_paste_error); + return ERROR; + } + + return END; + } + } + return m_update; + } + + /* Nothing to do with __VA_OPT__. */ + return INCLUDE; + } + + /* Ensure that any __VA_OPT__ was completed. If ok, return true. + Otherwise, issue an error and return false. */ + bool completed () + { + if (m_variadic && m_state != 0) + cpp_error_at (m_pfile, CPP_DL_ERROR, m_location, + "unterminated __VA_OPT__"); + return m_state == 0; + } + + /* Return true for # __VA_OPT__. */ + bool stringify () const + { + return m_stringify; + } + + private: + + /* The cpp_reader. */ + cpp_reader *m_pfile; + + /* The __VA_ARGS__ argument. */ + macro_arg *m_arg; + + /* True if the macro is variadic. */ + bool m_variadic; + /* If true, the previous token was ##. This is used to detect when + a paste occurs at the end of the sequence. */ + bool m_last_was_paste; + /* True for #__VA_OPT__. */ + bool m_stringify; + + /* The state variable: + 0 means not parsing + 1 means __VA_OPT__ seen, looking for "(" + 2 means "(" seen (so the next token can't be "##") + >= 3 means looking for ")", the number encodes the paren depth. */ + int m_state; + + /* The location of the paste token. */ + location_t m_paste_location; + + /* Location of the __VA_OPT__ token. */ + location_t m_location; + + /* If __VA_ARGS__ substitutes to no preprocessing tokens, + INCLUDE, otherwise DROP. ERROR when unknown yet. */ + update_type m_update; +}; + +/* Macro expansion. */ + +static cpp_macro *get_deferred_or_lazy_macro (cpp_reader *, cpp_hashnode *, + location_t); +static int enter_macro_context (cpp_reader *, cpp_hashnode *, + const cpp_token *, location_t); +static int builtin_macro (cpp_reader *, cpp_hashnode *, + location_t, location_t); +static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *, + const cpp_token **, unsigned int); +static void push_extended_tokens_context (cpp_reader *, cpp_hashnode *, + _cpp_buff *, location_t *, + const cpp_token **, unsigned int); +static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *, + _cpp_buff **, unsigned *); +static cpp_context *next_context (cpp_reader *); +static const cpp_token *padding_token (cpp_reader *, const cpp_token *); +static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int); +static const cpp_token *stringify_arg (cpp_reader *, const cpp_token **, + unsigned int); +static void paste_all_tokens (cpp_reader *, const cpp_token *); +static bool paste_tokens (cpp_reader *, location_t, + const cpp_token **, const cpp_token *); +static void alloc_expanded_arg_mem (cpp_reader *, macro_arg *, size_t); +static void ensure_expanded_arg_room (cpp_reader *, macro_arg *, size_t, size_t *); +static void delete_macro_args (_cpp_buff*, unsigned num_args); +static void set_arg_token (macro_arg *, const cpp_token *, + location_t, size_t, + enum macro_arg_token_kind, + bool); +static const location_t *get_arg_token_location (const macro_arg *, + enum macro_arg_token_kind); +static const cpp_token **arg_token_ptr_at (const macro_arg *, + size_t, + enum macro_arg_token_kind, + location_t **virt_location); + +static void macro_arg_token_iter_init (macro_arg_token_iter *, bool, + enum macro_arg_token_kind, + const macro_arg *, + const cpp_token **); +static const cpp_token *macro_arg_token_iter_get_token +(const macro_arg_token_iter *it); +static location_t macro_arg_token_iter_get_location +(const macro_arg_token_iter *); +static void macro_arg_token_iter_forward (macro_arg_token_iter *); +static _cpp_buff *tokens_buff_new (cpp_reader *, size_t, + location_t **); +static size_t tokens_buff_count (_cpp_buff *); +static const cpp_token **tokens_buff_last_token_ptr (_cpp_buff *); +static inline const cpp_token **tokens_buff_put_token_to (const cpp_token **, + location_t *, + const cpp_token *, + location_t, + location_t, + const line_map_macro *, + unsigned int); + +static const cpp_token **tokens_buff_add_token (_cpp_buff *, + location_t *, + const cpp_token *, + location_t, + location_t, + const line_map_macro *, + unsigned int); +static inline void tokens_buff_remove_last_token (_cpp_buff *); +static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *, + macro_arg *, location_t); +static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *, + _cpp_buff **, unsigned *); +static cpp_macro *create_iso_definition (cpp_reader *); + +/* #define directive parsing and handling. */ + +static cpp_macro *lex_expansion_token (cpp_reader *, cpp_macro *); +static bool parse_params (cpp_reader *, unsigned *, bool *); +static void check_trad_stringification (cpp_reader *, const cpp_macro *, + const cpp_string *); +static bool reached_end_of_context (cpp_context *); +static void consume_next_token_from_context (cpp_reader *pfile, + const cpp_token **, + location_t *); +static const cpp_token* cpp_get_token_1 (cpp_reader *, location_t *); + +static cpp_hashnode* macro_of_context (cpp_context *context); + +/* Statistical counter tracking the number of macros that got + expanded. */ +unsigned num_expanded_macros_counter = 0; +/* Statistical counter tracking the total number tokens resulting + from macro expansion. */ +unsigned num_macro_tokens_counter = 0; + +/* Wrapper around cpp_get_token to skip CPP_PADDING tokens + and not consume CPP_EOF. */ +static const cpp_token * +cpp_get_token_no_padding (cpp_reader *pfile) +{ + for (;;) + { + const cpp_token *ret = cpp_peek_token (pfile, 0); + if (ret->type == CPP_EOF) + return ret; + ret = cpp_get_token (pfile); + if (ret->type != CPP_PADDING) + return ret; + } +} + +/* Handle meeting "__has_include" builtin macro. */ + +static int +builtin_has_include (cpp_reader *pfile, cpp_hashnode *op, bool has_next) +{ + int result = 0; + + if (!pfile->state.in_directive) + cpp_error (pfile, CPP_DL_ERROR, + "\"%s\" used outside of preprocessing directive", + NODE_NAME (op)); + + pfile->state.angled_headers = true; + const cpp_token *token = cpp_get_token_no_padding (pfile); + bool paren = token->type == CPP_OPEN_PAREN; + if (paren) + token = cpp_get_token_no_padding (pfile); + else + cpp_error (pfile, CPP_DL_ERROR, + "missing '(' before \"%s\" operand", NODE_NAME (op)); + pfile->state.angled_headers = false; + + bool bracket = token->type != CPP_STRING; + char *fname = NULL; + if (token->type == CPP_STRING || token->type == CPP_HEADER_NAME) + { + fname = XNEWVEC (char, token->val.str.len - 1); + memcpy (fname, token->val.str.text + 1, token->val.str.len - 2); + fname[token->val.str.len - 2] = '\0'; + } + else if (token->type == CPP_LESS) + fname = _cpp_bracket_include (pfile); + else + cpp_error (pfile, CPP_DL_ERROR, + "operator \"%s\" requires a header-name", NODE_NAME (op)); + + if (fname) + { + /* Do not do the lookup if we're skipping, that's unnecessary + IO. */ + if (!pfile->state.skip_eval + && _cpp_has_header (pfile, fname, bracket, + has_next ? IT_INCLUDE_NEXT : IT_INCLUDE)) + result = 1; + + XDELETEVEC (fname); + } + + if (paren + && cpp_get_token_no_padding (pfile)->type != CPP_CLOSE_PAREN) + cpp_error (pfile, CPP_DL_ERROR, + "missing ')' after \"%s\" operand", NODE_NAME (op)); + + return result; +} + +/* Emits a warning if NODE is a macro defined in the main file that + has not been used. */ +int +_cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node, + void *v ATTRIBUTE_UNUSED) +{ + if (cpp_user_macro_p (node)) + { + cpp_macro *macro = node->value.macro; + + if (!macro->used + && MAIN_FILE_P (linemap_check_ordinary + (linemap_lookup (pfile->line_table, + macro->line)))) + cpp_warning_with_line (pfile, CPP_W_UNUSED_MACROS, macro->line, 0, + "macro \"%s\" is not used", NODE_NAME (node)); + } + + return 1; +} + +/* Allocates and returns a CPP_STRING token, containing TEXT of length + LEN, after null-terminating it. TEXT must be in permanent storage. */ +static const cpp_token * +new_string_token (cpp_reader *pfile, unsigned char *text, unsigned int len) +{ + cpp_token *token = _cpp_temp_token (pfile); + + text[len] = '\0'; + token->type = CPP_STRING; + token->val.str.len = len; + token->val.str.text = text; + token->flags = 0; + return token; +} + +static const char * const monthnames[] = +{ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +/* Helper function for builtin_macro. Returns the text generated by + a builtin macro. */ +const uchar * +_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node, + location_t loc) +{ + const uchar *result = NULL; + linenum_type number = 1; + + switch (node->value.builtin) + { + default: + cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"", + NODE_NAME (node)); + break; + + case BT_TIMESTAMP: + { + if (CPP_OPTION (pfile, warn_date_time)) + cpp_warning (pfile, CPP_W_DATE_TIME, "macro \"%s\" might prevent " + "reproducible builds", NODE_NAME (node)); + + cpp_buffer *pbuffer = cpp_get_buffer (pfile); + if (pbuffer->timestamp == NULL) + { + /* Initialize timestamp value of the assotiated file. */ + struct _cpp_file *file = cpp_get_file (pbuffer); + if (file) + { + /* Generate __TIMESTAMP__ string, that represents + the date and time of the last modification + of the current source file. The string constant + looks like "Sun Sep 16 01:03:52 1973". */ + struct tm *tb = NULL; + struct stat *st = _cpp_get_file_stat (file); + if (st) + tb = localtime (&st->st_mtime); + if (tb) + { + char *str = asctime (tb); + size_t len = strlen (str); + unsigned char *buf = _cpp_unaligned_alloc (pfile, len + 2); + buf[0] = '"'; + strcpy ((char *) buf + 1, str); + buf[len] = '"'; + pbuffer->timestamp = buf; + } + else + { + cpp_errno (pfile, CPP_DL_WARNING, + "could not determine file timestamp"); + pbuffer->timestamp = UC"\"??? ??? ?? ??:??:?? ????\""; + } + } + } + result = pbuffer->timestamp; + } + break; + case BT_FILE: + case BT_FILE_NAME: + case BT_BASE_FILE: + { + unsigned int len; + const char *name; + uchar *buf; + + if (node->value.builtin == BT_FILE + || node->value.builtin == BT_FILE_NAME) + { + name = linemap_get_expansion_filename (pfile->line_table, + pfile->line_table->highest_line); + if ((node->value.builtin == BT_FILE_NAME) && name) + name = lbasename (name); + } + else + { + name = _cpp_get_file_name (pfile->main_file); + if (!name) + abort (); + } + if (pfile->cb.remap_filename) + name = pfile->cb.remap_filename (name); + len = strlen (name); + buf = _cpp_unaligned_alloc (pfile, len * 2 + 3); + result = buf; + *buf = '"'; + buf = cpp_quote_string (buf + 1, (const unsigned char *) name, len); + *buf++ = '"'; + *buf = '\0'; + } + break; + + case BT_INCLUDE_LEVEL: + /* The line map depth counts the primary source as level 1, but + historically __INCLUDE_DEPTH__ has called the primary source + level 0. */ + number = pfile->line_table->depth - 1; + break; + + case BT_SPECLINE: + /* 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. + See WG14 N1911, WG21 N4220 sec 6.5, and PR 61861. */ + if (CPP_OPTION (pfile, traditional)) + loc = pfile->line_table->highest_line; + else + loc = linemap_resolve_location (pfile->line_table, loc, + LRK_MACRO_EXPANSION_POINT, NULL); + number = linemap_get_expansion_line (pfile->line_table, loc); + break; + + /* __STDC__ has the value 1 under normal circumstances. + However, if (a) we are in a system header, (b) the option + stdc_0_in_system_headers is true (set by target config), and + (c) we are not in strictly conforming mode, then it has the + value 0. (b) and (c) are already checked in cpp_init_builtins. */ + case BT_STDC: + if (_cpp_in_system_header (pfile)) + number = 0; + else + number = 1; + break; + + case BT_DATE: + case BT_TIME: + if (CPP_OPTION (pfile, warn_date_time)) + cpp_warning (pfile, CPP_W_DATE_TIME, "macro \"%s\" might prevent " + "reproducible builds", NODE_NAME (node)); + if (pfile->date == NULL) + { + /* Allocate __DATE__ and __TIME__ strings from permanent + storage. We only do this once, and don't generate them + at init time, because time() and localtime() are very + slow on some systems. */ + time_t tt; + auto kind = cpp_get_date (pfile, &tt); + + if (kind == CPP_time_kind::UNKNOWN) + { + cpp_errno (pfile, CPP_DL_WARNING, + "could not determine date and time"); + + pfile->date = UC"\"??? ?? ????\""; + pfile->time = UC"\"??:??:??\""; + } + else + { + struct tm *tb = (kind == CPP_time_kind::FIXED + ? gmtime : localtime) (&tt); + + pfile->date = _cpp_unaligned_alloc (pfile, + sizeof ("\"Oct 11 1347\"")); + sprintf ((char *) pfile->date, "\"%s %2d %4d\"", + monthnames[tb->tm_mon], tb->tm_mday, + tb->tm_year + 1900); + + pfile->time = _cpp_unaligned_alloc (pfile, + sizeof ("\"12:34:56\"")); + sprintf ((char *) pfile->time, "\"%02d:%02d:%02d\"", + tb->tm_hour, tb->tm_min, tb->tm_sec); + } + } + + if (node->value.builtin == BT_DATE) + result = pfile->date; + else + result = pfile->time; + break; + + case BT_COUNTER: + if (CPP_OPTION (pfile, directives_only) && pfile->state.in_directive) + cpp_error (pfile, CPP_DL_ERROR, + "__COUNTER__ expanded inside directive with -fdirectives-only"); + number = pfile->counter++; + break; + + case BT_HAS_ATTRIBUTE: + number = pfile->cb.has_attribute (pfile, false); + break; + + case BT_HAS_STD_ATTRIBUTE: + number = pfile->cb.has_attribute (pfile, true); + break; + + case BT_HAS_BUILTIN: + number = pfile->cb.has_builtin (pfile); + break; + + case BT_HAS_INCLUDE: + case BT_HAS_INCLUDE_NEXT: + number = builtin_has_include (pfile, node, + node->value.builtin == BT_HAS_INCLUDE_NEXT); + break; + } + + if (result == NULL) + { + /* 21 bytes holds all NUL-terminated unsigned 64-bit numbers. */ + result = _cpp_unaligned_alloc (pfile, 21); + sprintf ((char *) result, "%u", number); + } + + return result; +} + +/* Get an idempotent date. Either the cached value, the value from + source epoch, or failing that, the value from time(2). Use this + during compilation so that every time stamp is the same. */ +CPP_time_kind +cpp_get_date (cpp_reader *pfile, time_t *result) +{ + if (!pfile->time_stamp_kind) + { + int kind = 0; + if (pfile->cb.get_source_date_epoch) + { + /* Try reading the fixed epoch. */ + pfile->time_stamp = pfile->cb.get_source_date_epoch (pfile); + if (pfile->time_stamp != time_t (-1)) + kind = int (CPP_time_kind::FIXED); + } + + if (!kind) + { + /* Pedantically time_t (-1) is a legitimate value for + "number of seconds since the Epoch". It is a silly + time. */ + errno = 0; + pfile->time_stamp = time (nullptr); + /* Annoyingly a library could legally set errno and return a + valid time! Bad library! */ + if (pfile->time_stamp == time_t (-1) && errno) + kind = errno; + else + kind = int (CPP_time_kind::DYNAMIC); + } + + pfile->time_stamp_kind = kind; + } + + *result = pfile->time_stamp; + if (pfile->time_stamp_kind >= 0) + { + errno = pfile->time_stamp_kind; + return CPP_time_kind::UNKNOWN; + } + + return CPP_time_kind (pfile->time_stamp_kind); +} + +/* Convert builtin macros like __FILE__ to a token and push it on the + context stack. Also handles _Pragma, for which a new token may not + be created. Returns 1 if it generates a new token context, 0 to + return the token to the caller. LOC is the location of the expansion + point of the macro. */ +static int +builtin_macro (cpp_reader *pfile, cpp_hashnode *node, + location_t loc, location_t expand_loc) +{ + const uchar *buf; + size_t len; + char *nbuf; + + if (node->value.builtin == BT_PRAGMA) + { + /* Don't interpret _Pragma within directives. The standard is + not clear on this, but to me this makes most sense. + Similarly, don't interpret _Pragma inside expand_args, we might + need to stringize it later on. */ + if (pfile->state.in_directive || pfile->state.ignore__Pragma) + return 0; + + return _cpp_do__Pragma (pfile, loc); + } + + buf = _cpp_builtin_macro_text (pfile, node, expand_loc); + len = ustrlen (buf); + nbuf = (char *) alloca (len + 1); + memcpy (nbuf, buf, len); + nbuf[len]='\n'; + + cpp_push_buffer (pfile, (uchar *) nbuf, len, /* from_stage3 */ true); + _cpp_clean_line (pfile); + + /* Set pfile->cur_token as required by _cpp_lex_direct. */ + pfile->cur_token = _cpp_temp_token (pfile); + cpp_token *token = _cpp_lex_direct (pfile); + /* We should point to the expansion point of the builtin macro. */ + token->src_loc = loc; + if (pfile->context->tokens_kind == TOKENS_KIND_EXTENDED) + { + /* We are tracking tokens resulting from macro expansion. + Create a macro line map and generate a virtual location for + the token resulting from the expansion of the built-in + macro. */ + location_t *virt_locs = NULL; + _cpp_buff *token_buf = tokens_buff_new (pfile, 1, &virt_locs); + const line_map_macro * map = + linemap_enter_macro (pfile->line_table, node, loc, 1); + tokens_buff_add_token (token_buf, virt_locs, token, + pfile->line_table->builtin_location, + pfile->line_table->builtin_location, + map, /*macro_token_index=*/0); + push_extended_tokens_context (pfile, node, token_buf, virt_locs, + (const cpp_token **)token_buf->base, + 1); + } + else + _cpp_push_token_context (pfile, NULL, token, 1); + if (pfile->buffer->cur != pfile->buffer->rlimit) + cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"", + NODE_NAME (node)); + _cpp_pop_buffer (pfile); + + return 1; +} + +/* Copies SRC, of length LEN, to DEST, adding backslashes before all + backslashes and double quotes. DEST must be of sufficient size. + Returns a pointer to the end of the string. */ +uchar * +cpp_quote_string (uchar *dest, const uchar *src, unsigned int len) +{ + while (len--) + { + uchar c = *src++; + + switch (c) + { + case '\n': + /* Naked LF can appear in raw string literals */ + c = 'n'; + /* FALLTHROUGH */ + + case '\\': + case '"': + *dest++ = '\\'; + /* FALLTHROUGH */ + + default: + *dest++ = c; + } + } + + return dest; +} + +/* Convert a token sequence FIRST to FIRST+COUNT-1 to a single string token + according to the rules of the ISO C #-operator. */ +static const cpp_token * +stringify_arg (cpp_reader *pfile, const cpp_token **first, unsigned int count) +{ + unsigned char *dest; + unsigned int i, escape_it, backslash_count = 0; + const cpp_token *source = NULL; + size_t len; + + if (BUFF_ROOM (pfile->u_buff) < 3) + _cpp_extend_buff (pfile, &pfile->u_buff, 3); + dest = BUFF_FRONT (pfile->u_buff); + *dest++ = '"'; + + /* Loop, reading in the argument's tokens. */ + for (i = 0; i < count; i++) + { + const cpp_token *token = first[i]; + + if (token->type == CPP_PADDING) + { + if (source == NULL + || (!(source->flags & PREV_WHITE) + && token->val.source == NULL)) + source = token->val.source; + continue; + } + + escape_it = (token->type == CPP_STRING || token->type == CPP_CHAR + || token->type == CPP_WSTRING || token->type == CPP_WCHAR + || token->type == CPP_STRING32 || token->type == CPP_CHAR32 + || token->type == CPP_STRING16 || token->type == CPP_CHAR16 + || token->type == CPP_UTF8STRING || token->type == CPP_UTF8CHAR + || cpp_userdef_string_p (token->type) + || cpp_userdef_char_p (token->type)); + + /* Room for each char being written in octal, initial space and + final quote and NUL. */ + len = cpp_token_len (token); + if (escape_it) + len *= 4; + len += 3; + + if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len) + { + size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff); + _cpp_extend_buff (pfile, &pfile->u_buff, len); + dest = BUFF_FRONT (pfile->u_buff) + len_so_far; + } + + /* Leading white space? */ + if (dest - 1 != BUFF_FRONT (pfile->u_buff)) + { + if (source == NULL) + source = token; + if (source->flags & PREV_WHITE) + *dest++ = ' '; + } + source = NULL; + + if (escape_it) + { + _cpp_buff *buff = _cpp_get_buff (pfile, len); + unsigned char *buf = BUFF_FRONT (buff); + len = cpp_spell_token (pfile, token, buf, true) - buf; + dest = cpp_quote_string (dest, buf, len); + _cpp_release_buff (pfile, buff); + } + else + dest = cpp_spell_token (pfile, token, dest, true); + + if (token->type == CPP_OTHER && token->val.str.text[0] == '\\') + backslash_count++; + else + backslash_count = 0; + } + + /* Ignore the final \ of invalid string literals. */ + if (backslash_count & 1) + { + cpp_error (pfile, CPP_DL_WARNING, + "invalid string literal, ignoring final '\\'"); + dest--; + } + + /* Commit the memory, including NUL, and return the token. */ + *dest++ = '"'; + len = dest - BUFF_FRONT (pfile->u_buff); + BUFF_FRONT (pfile->u_buff) = dest + 1; + return new_string_token (pfile, dest - len, len); +} + +/* Try to paste two tokens. On success, return nonzero. In any + case, PLHS is updated to point to the pasted token, which is + guaranteed to not have the PASTE_LEFT flag set. LOCATION is + the virtual location used for error reporting. */ +static bool +paste_tokens (cpp_reader *pfile, location_t location, + const cpp_token **plhs, const cpp_token *rhs) +{ + unsigned char *buf, *end, *lhsend; + cpp_token *lhs; + unsigned int len; + + len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 2; + buf = (unsigned char *) alloca (len); + end = lhsend = cpp_spell_token (pfile, *plhs, buf, true); + + /* Avoid comment headers, since they are still processed in stage 3. + It is simpler to insert a space here, rather than modifying the + lexer to ignore comments in some circumstances. Simply returning + false doesn't work, since we want to clear the PASTE_LEFT flag. */ + if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ) + *end++ = ' '; + /* In one obscure case we might see padding here. */ + if (rhs->type != CPP_PADDING) + end = cpp_spell_token (pfile, rhs, end, true); + *end = '\n'; + + cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true); + _cpp_clean_line (pfile); + + /* Set pfile->cur_token as required by _cpp_lex_direct. */ + pfile->cur_token = _cpp_temp_token (pfile); + lhs = _cpp_lex_direct (pfile); + if (pfile->buffer->cur != pfile->buffer->rlimit) + { + location_t saved_loc = lhs->src_loc; + + _cpp_pop_buffer (pfile); + + unsigned char *rhsstart = lhsend; + if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ) + rhsstart++; + + /* We have to remove the PASTE_LEFT flag from the old lhs, but + we want to keep the new location. */ + *lhs = **plhs; + *plhs = lhs; + lhs->src_loc = saved_loc; + lhs->flags &= ~PASTE_LEFT; + + /* Mandatory error for all apart from assembler. */ + if (CPP_OPTION (pfile, lang) != CLK_ASM) + cpp_error_with_line (pfile, CPP_DL_ERROR, location, 0, + "pasting \"%.*s\" and \"%.*s\" does not give " + "a valid preprocessing token", + (int) (lhsend - buf), buf, + (int) (end - rhsstart), rhsstart); + return false; + } + + lhs->flags |= (*plhs)->flags & (PREV_WHITE | PREV_FALLTHROUGH); + *plhs = lhs; + _cpp_pop_buffer (pfile); + return true; +} + +/* Handles an arbitrarily long sequence of ## operators, with initial + operand LHS. This implementation is left-associative, + non-recursive, and finishes a paste before handling succeeding + ones. If a paste fails, we back up to the RHS of the failing ## + operator before pushing the context containing the result of prior + successful pastes, with the effect that the RHS appears in the + output stream after the pasted LHS normally. */ +static void +paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs) +{ + const cpp_token *rhs = NULL; + cpp_context *context = pfile->context; + location_t virt_loc = 0; + + /* We are expanding a macro and we must have been called on a token + that appears at the left hand side of a ## operator. */ + if (macro_of_context (pfile->context) == NULL + || (!(lhs->flags & PASTE_LEFT))) + abort (); + + if (context->tokens_kind == TOKENS_KIND_EXTENDED) + /* The caller must have called consume_next_token_from_context + right before calling us. That has incremented the pointer to + the current virtual location. So it now points to the location + of the token that comes right after *LHS. We want the + resulting pasted token to have the location of the current + *LHS, though. */ + virt_loc = context->c.mc->cur_virt_loc[-1]; + else + /* We are not tracking macro expansion. So the best virtual + location we can get here is the expansion point of the macro we + are currently expanding. */ + virt_loc = pfile->invocation_location; + + do + { + /* Take the token directly from the current context. We can do + this, because we are in the replacement list of either an + object-like macro, or a function-like macro with arguments + inserted. In either case, the constraints to #define + guarantee we have at least one more token. */ + if (context->tokens_kind == TOKENS_KIND_DIRECT) + rhs = FIRST (context).token++; + else if (context->tokens_kind == TOKENS_KIND_INDIRECT) + rhs = *FIRST (context).ptoken++; + else if (context->tokens_kind == TOKENS_KIND_EXTENDED) + { + /* So we are in presence of an extended token context, which + means that each token in this context has a virtual + location attached to it. So let's not forget to update + the pointer to the current virtual location of the + current token when we update the pointer to the current + token */ + + rhs = *FIRST (context).ptoken++; + /* context->c.mc must be non-null, as if we were not in a + macro context, context->tokens_kind could not be equal to + TOKENS_KIND_EXTENDED. */ + context->c.mc->cur_virt_loc++; + } + + if (rhs->type == CPP_PADDING) + { + if (rhs->flags & PASTE_LEFT) + abort (); + } + if (!paste_tokens (pfile, virt_loc, &lhs, rhs)) + { + _cpp_backup_tokens (pfile, 1); + break; + } + } + while (rhs->flags & PASTE_LEFT); + + /* Put the resulting token in its own context. */ + if (context->tokens_kind == TOKENS_KIND_EXTENDED) + { + location_t *virt_locs = NULL; + _cpp_buff *token_buf = tokens_buff_new (pfile, 1, &virt_locs); + tokens_buff_add_token (token_buf, virt_locs, lhs, + virt_loc, 0, NULL, 0); + push_extended_tokens_context (pfile, context->c.mc->macro_node, + token_buf, virt_locs, + (const cpp_token **)token_buf->base, 1); + } + else + _cpp_push_token_context (pfile, NULL, lhs, 1); +} + +/* Returns TRUE if the number of arguments ARGC supplied in an + invocation of the MACRO referenced by NODE is valid. An empty + invocation to a macro with no parameters should pass ARGC as zero. + + Note that MACRO cannot necessarily be deduced from NODE, in case + NODE was redefined whilst collecting arguments. */ +bool +_cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node, unsigned int argc) +{ + if (argc == macro->paramc) + return true; + + if (argc < macro->paramc) + { + /* In C++20 (here the va_opt flag is used), and also as a GNU + extension, variadic arguments are allowed to not appear in + the invocation at all. + e.g. #define debug(format, args...) something + debug("string"); + + This is exactly the same as if an empty variadic list had been + supplied - debug("string", ). */ + + if (argc + 1 == macro->paramc && macro->variadic) + { + if (CPP_PEDANTIC (pfile) && ! macro->syshdr + && ! CPP_OPTION (pfile, va_opt)) + { + if (CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_PEDWARN, + "ISO C++11 requires at least one argument " + "for the \"...\" in a variadic macro"); + else + cpp_error (pfile, CPP_DL_PEDWARN, + "ISO C99 requires at least one argument " + "for the \"...\" in a variadic macro"); + } + return true; + } + + cpp_error (pfile, CPP_DL_ERROR, + "macro \"%s\" requires %u arguments, but only %u given", + NODE_NAME (node), macro->paramc, argc); + } + else + cpp_error (pfile, CPP_DL_ERROR, + "macro \"%s\" passed %u arguments, but takes just %u", + NODE_NAME (node), argc, macro->paramc); + + if (macro->line > RESERVED_LOCATION_COUNT) + cpp_error_at (pfile, CPP_DL_NOTE, macro->line, "macro \"%s\" defined here", + NODE_NAME (node)); + + return false; +} + +/* Reads and returns the arguments to a function-like macro + invocation. Assumes the opening parenthesis has been processed. + If there is an error, emits an appropriate diagnostic and returns + NULL. Each argument is terminated by a CPP_EOF token, for the + future benefit of expand_arg(). If there are any deferred + #pragma directives among macro arguments, store pointers to the + CPP_PRAGMA ... CPP_PRAGMA_EOL tokens into *PRAGMA_BUFF buffer. + + What is returned is the buffer that contains the memory allocated + to hold the macro arguments. NODE is the name of the macro this + function is dealing with. If NUM_ARGS is non-NULL, *NUM_ARGS is + set to the actual number of macro arguments allocated in the + returned buffer. */ +static _cpp_buff * +collect_args (cpp_reader *pfile, const cpp_hashnode *node, + _cpp_buff **pragma_buff, unsigned *num_args) +{ + _cpp_buff *buff, *base_buff; + cpp_macro *macro; + macro_arg *args, *arg; + const cpp_token *token; + unsigned int argc; + location_t virt_loc; + bool track_macro_expansion_p = CPP_OPTION (pfile, track_macro_expansion); + unsigned num_args_alloced = 0; + + macro = node->value.macro; + if (macro->paramc) + argc = macro->paramc; + else + argc = 1; + +#define DEFAULT_NUM_TOKENS_PER_MACRO_ARG 50 +#define ARG_TOKENS_EXTENT 1000 + + buff = _cpp_get_buff (pfile, argc * (DEFAULT_NUM_TOKENS_PER_MACRO_ARG + * sizeof (cpp_token *) + + sizeof (macro_arg))); + base_buff = buff; + args = (macro_arg *) buff->base; + memset (args, 0, argc * sizeof (macro_arg)); + buff->cur = (unsigned char *) &args[argc]; + arg = args, argc = 0; + + /* Collect the tokens making up each argument. We don't yet know + how many arguments have been supplied, whether too many or too + few. Hence the slightly bizarre usage of "argc" and "arg". */ + do + { + unsigned int paren_depth = 0; + unsigned int ntokens = 0; + unsigned virt_locs_capacity = DEFAULT_NUM_TOKENS_PER_MACRO_ARG; + num_args_alloced++; + + argc++; + arg->first = (const cpp_token **) buff->cur; + if (track_macro_expansion_p) + { + virt_locs_capacity = DEFAULT_NUM_TOKENS_PER_MACRO_ARG; + arg->virt_locs = XNEWVEC (location_t, + virt_locs_capacity); + } + + for (;;) + { + /* Require space for 2 new tokens (including a CPP_EOF). */ + if ((unsigned char *) &arg->first[ntokens + 2] > buff->limit) + { + buff = _cpp_append_extend_buff (pfile, buff, + ARG_TOKENS_EXTENT + * sizeof (cpp_token *)); + arg->first = (const cpp_token **) buff->cur; + } + if (track_macro_expansion_p + && (ntokens + 2 > virt_locs_capacity)) + { + virt_locs_capacity += ARG_TOKENS_EXTENT; + arg->virt_locs = XRESIZEVEC (location_t, + arg->virt_locs, + virt_locs_capacity); + } + + token = cpp_get_token_1 (pfile, &virt_loc); + + if (token->type == CPP_PADDING) + { + /* Drop leading padding. */ + if (ntokens == 0) + continue; + } + else if (token->type == CPP_OPEN_PAREN) + paren_depth++; + else if (token->type == CPP_CLOSE_PAREN) + { + if (paren_depth-- == 0) + break; + } + else if (token->type == CPP_COMMA) + { + /* A comma does not terminate an argument within + parentheses or as part of a variable argument. */ + if (paren_depth == 0 + && ! (macro->variadic && argc == macro->paramc)) + break; + } + else if (token->type == CPP_EOF + || (token->type == CPP_HASH && token->flags & BOL)) + break; + else if (token->type == CPP_PRAGMA && !(token->flags & PRAGMA_OP)) + { + cpp_token *newtok = _cpp_temp_token (pfile); + + /* CPP_PRAGMA token lives in directive_result, which will + be overwritten on the next directive. */ + *newtok = *token; + token = newtok; + do + { + if (*pragma_buff == NULL + || BUFF_ROOM (*pragma_buff) < sizeof (cpp_token *)) + { + _cpp_buff *next; + if (*pragma_buff == NULL) + *pragma_buff + = _cpp_get_buff (pfile, 32 * sizeof (cpp_token *)); + else + { + next = *pragma_buff; + *pragma_buff + = _cpp_get_buff (pfile, + (BUFF_FRONT (*pragma_buff) + - (*pragma_buff)->base) * 2); + (*pragma_buff)->next = next; + } + } + *(const cpp_token **) BUFF_FRONT (*pragma_buff) = token; + BUFF_FRONT (*pragma_buff) += sizeof (cpp_token *); + if (token->type == CPP_PRAGMA_EOL) + break; + token = cpp_get_token_1 (pfile, &virt_loc); + } + while (token->type != CPP_EOF); + + /* In deferred pragmas parsing_args and prevent_expansion + had been changed, reset it. */ + pfile->state.parsing_args = 2; + pfile->state.prevent_expansion = 1; + + if (token->type == CPP_EOF) + break; + else + continue; + } + set_arg_token (arg, token, virt_loc, + ntokens, MACRO_ARG_TOKEN_NORMAL, + CPP_OPTION (pfile, track_macro_expansion)); + ntokens++; + } + + /* Drop trailing padding. */ + while (ntokens > 0 && arg->first[ntokens - 1]->type == CPP_PADDING) + ntokens--; + + arg->count = ntokens; + /* Append an EOF to mark end-of-argument. */ + set_arg_token (arg, &pfile->endarg, token->src_loc, + ntokens, MACRO_ARG_TOKEN_NORMAL, + CPP_OPTION (pfile, track_macro_expansion)); + + /* Terminate the argument. Excess arguments loop back and + overwrite the final legitimate argument, before failing. */ + if (argc <= macro->paramc) + { + buff->cur = (unsigned char *) &arg->first[ntokens + 1]; + if (argc != macro->paramc) + arg++; + } + } + while (token->type != CPP_CLOSE_PAREN && token->type != CPP_EOF); + + if (token->type == CPP_EOF) + { + /* Unless the EOF is marking the end of an argument, it's a fake + one from the end of a file that _cpp_clean_line will not have + advanced past. */ + if (token == &pfile->endarg) + _cpp_backup_tokens (pfile, 1); + cpp_error (pfile, CPP_DL_ERROR, + "unterminated argument list invoking macro \"%s\"", + NODE_NAME (node)); + } + else + { + /* A single empty argument is counted as no argument. */ + if (argc == 1 && macro->paramc == 0 && args[0].count == 0) + argc = 0; + if (_cpp_arguments_ok (pfile, macro, node, argc)) + { + /* GCC has special semantics for , ## b where b is a varargs + parameter: we remove the comma if b was omitted entirely. + If b was merely an empty argument, the comma is retained. + If the macro takes just one (varargs) parameter, then we + retain the comma only if we are standards conforming. + + If FIRST is NULL replace_args () swallows the comma. */ + if (macro->variadic && (argc < macro->paramc + || (argc == 1 && args[0].count == 0 + && !CPP_OPTION (pfile, std)))) + args[macro->paramc - 1].first = NULL; + if (num_args) + *num_args = num_args_alloced; + return base_buff; + } + } + + /* An error occurred. */ + _cpp_release_buff (pfile, base_buff); + return NULL; +} + +/* Search for an opening parenthesis to the macro of NODE, in such a + way that, if none is found, we don't lose the information in any + intervening padding tokens. If we find the parenthesis, collect + the arguments and return the buffer containing them. PRAGMA_BUFF + argument is the same as in collect_args. If NUM_ARGS is non-NULL, + *NUM_ARGS is set to the number of arguments contained in the + returned buffer. */ +static _cpp_buff * +funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node, + _cpp_buff **pragma_buff, unsigned *num_args) +{ + const cpp_token *token, *padding = NULL; + + for (;;) + { + token = cpp_get_token (pfile); + if (token->type != CPP_PADDING) + break; + gcc_assert ((token->flags & PREV_WHITE) == 0); + if (padding == NULL + || padding->val.source == NULL + || (!(padding->val.source->flags & PREV_WHITE) + && token->val.source == NULL)) + padding = token; + } + + if (token->type == CPP_OPEN_PAREN) + { + pfile->state.parsing_args = 2; + return collect_args (pfile, node, pragma_buff, num_args); + } + + /* Back up. A CPP_EOF is either an EOF from an argument we're + expanding, or a fake one from lex_direct. We want to backup the + former, but not the latter. We may have skipped padding, in + which case backing up more than one token when expanding macros + is in general too difficult. We re-insert it in its own + context. */ + if (token->type != CPP_EOF || token == &pfile->endarg) + { + _cpp_backup_tokens (pfile, 1); + if (padding) + _cpp_push_token_context (pfile, NULL, padding, 1); + } + + return NULL; +} + +/* Return the real number of tokens in the expansion of MACRO. */ +static inline unsigned int +macro_real_token_count (const cpp_macro *macro) +{ + if (__builtin_expect (!macro->extra_tokens, true)) + return macro->count; + + for (unsigned i = macro->count; i--;) + if (macro->exp.tokens[i].type != CPP_PASTE) + return i + 1; + + return 0; +} + +/* Push the context of a macro with hash entry NODE onto the context + stack. If we can successfully expand the macro, we push a context + containing its yet-to-be-rescanned replacement list and return one. + If there were additionally any unexpanded deferred #pragma + directives among macro arguments, push another context containing + the pragma tokens before the yet-to-be-rescanned replacement list + and return two. Otherwise, we don't push a context and return + zero. LOCATION is the location of the expansion point of the + macro. */ +static int +enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, + const cpp_token *result, location_t location) +{ + /* The presence of a macro invalidates a file's controlling macro. */ + pfile->mi_valid = false; + + pfile->state.angled_headers = false; + + /* From here to when we push the context for the macro later down + this function, we need to flag the fact that we are about to + expand a macro. This is useful when -ftrack-macro-expansion is + turned off. In that case, we need to record the location of the + expansion point of the top-most macro we are about to to expand, + into pfile->invocation_location. But we must not record any such + location once the process of expanding the macro starts; that is, + we must not do that recording between now and later down this + function where set this flag to FALSE. */ + pfile->about_to_expand_macro_p = true; + + if (cpp_user_macro_p (node)) + { + cpp_macro *macro = node->value.macro; + _cpp_buff *pragma_buff = NULL; + + if (macro->fun_like) + { + _cpp_buff *buff; + unsigned num_args = 0; + + pfile->state.prevent_expansion++; + pfile->keep_tokens++; + pfile->state.parsing_args = 1; + buff = funlike_invocation_p (pfile, node, &pragma_buff, + &num_args); + pfile->state.parsing_args = 0; + pfile->keep_tokens--; + pfile->state.prevent_expansion--; + + if (buff == NULL) + { + if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr) + cpp_warning (pfile, CPP_W_TRADITIONAL, + "function-like macro \"%s\" must be used with arguments in traditional C", + NODE_NAME (node)); + + if (pragma_buff) + _cpp_release_buff (pfile, pragma_buff); + + pfile->about_to_expand_macro_p = false; + return 0; + } + + if (macro->paramc > 0) + replace_args (pfile, node, macro, + (macro_arg *) buff->base, + location); + /* Free the memory used by the arguments of this + function-like macro. This memory has been allocated by + funlike_invocation_p and by replace_args. */ + delete_macro_args (buff, num_args); + } + + /* Disable the macro within its expansion. */ + node->flags |= NODE_DISABLED; + + /* Laziness can only affect the expansion tokens of the macro, + not its fun-likeness or parameters. */ + _cpp_maybe_notify_macro_use (pfile, node, location); + if (pfile->cb.used) + pfile->cb.used (pfile, location, node); + + macro->used = 1; + + if (macro->paramc == 0) + { + unsigned tokens_count = macro_real_token_count (macro); + if (CPP_OPTION (pfile, track_macro_expansion)) + { + unsigned int i; + const cpp_token *src = macro->exp.tokens; + const line_map_macro *map; + location_t *virt_locs = NULL; + _cpp_buff *macro_tokens + = tokens_buff_new (pfile, tokens_count, &virt_locs); + + /* Create a macro map to record the locations of the + tokens that are involved in the expansion. LOCATION + is the location of the macro expansion point. */ + map = linemap_enter_macro (pfile->line_table, + node, location, tokens_count); + for (i = 0; i < tokens_count; ++i) + { + tokens_buff_add_token (macro_tokens, virt_locs, + src, src->src_loc, + src->src_loc, map, i); + ++src; + } + push_extended_tokens_context (pfile, node, + macro_tokens, + virt_locs, + (const cpp_token **) + macro_tokens->base, + tokens_count); + } + else + _cpp_push_token_context (pfile, node, macro->exp.tokens, + tokens_count); + num_macro_tokens_counter += tokens_count; + } + + if (pragma_buff) + { + if (!pfile->state.in_directive) + _cpp_push_token_context (pfile, NULL, + padding_token (pfile, result), 1); + do + { + unsigned tokens_count; + _cpp_buff *tail = pragma_buff->next; + pragma_buff->next = NULL; + tokens_count = ((const cpp_token **) BUFF_FRONT (pragma_buff) + - (const cpp_token **) pragma_buff->base); + push_ptoken_context (pfile, NULL, pragma_buff, + (const cpp_token **) pragma_buff->base, + tokens_count); + pragma_buff = tail; + if (!CPP_OPTION (pfile, track_macro_expansion)) + num_macro_tokens_counter += tokens_count; + + } + while (pragma_buff != NULL); + pfile->about_to_expand_macro_p = false; + return 2; + } + + pfile->about_to_expand_macro_p = false; + return 1; + } + + pfile->about_to_expand_macro_p = false; + /* Handle built-in macros and the _Pragma operator. */ + { + location_t expand_loc; + + if (/* The top-level macro invocation that triggered the expansion + we are looking at is with a function-like user macro ... */ + cpp_fun_like_macro_p (pfile->top_most_macro_node) + /* ... and we are tracking the macro expansion. */ + && CPP_OPTION (pfile, track_macro_expansion)) + /* Then the location of the end of the macro invocation is the + location of the expansion point of this macro. */ + expand_loc = location; + else + /* Otherwise, the location of the end of the macro invocation is + the location of the expansion point of that top-level macro + invocation. */ + expand_loc = pfile->invocation_location; + + return builtin_macro (pfile, node, location, expand_loc); + } +} + +/* De-allocate the memory used by BUFF which is an array of instances + of macro_arg. NUM_ARGS is the number of instances of macro_arg + present in BUFF. */ +static void +delete_macro_args (_cpp_buff *buff, unsigned num_args) +{ + macro_arg *macro_args; + unsigned i; + + if (buff == NULL) + return; + + macro_args = (macro_arg *) buff->base; + + /* Walk instances of macro_arg to free their expanded tokens as well + as their macro_arg::virt_locs members. */ + for (i = 0; i < num_args; ++i) + { + if (macro_args[i].expanded) + { + free (macro_args[i].expanded); + macro_args[i].expanded = NULL; + } + if (macro_args[i].virt_locs) + { + free (macro_args[i].virt_locs); + macro_args[i].virt_locs = NULL; + } + if (macro_args[i].expanded_virt_locs) + { + free (macro_args[i].expanded_virt_locs); + macro_args[i].expanded_virt_locs = NULL; + } + } + _cpp_free_buff (buff); +} + +/* Set the INDEXth token of the macro argument ARG. TOKEN is the token + to set, LOCATION is its virtual location. "Virtual" location means + the location that encodes loci across macro expansion. Otherwise + it has to be TOKEN->SRC_LOC. KIND is the kind of tokens the + argument ARG is supposed to contain. Note that ARG must be + tailored so that it has enough room to contain INDEX + 1 numbers of + tokens, at least. */ +static void +set_arg_token (macro_arg *arg, const cpp_token *token, + location_t location, size_t index, + enum macro_arg_token_kind kind, + bool track_macro_exp_p) +{ + const cpp_token **token_ptr; + location_t *loc = NULL; + + token_ptr = + arg_token_ptr_at (arg, index, kind, + track_macro_exp_p ? &loc : NULL); + *token_ptr = token; + + if (loc != NULL) + { + /* We can't set the location of a stringified argument + token and we can't set any location if we aren't tracking + macro expansion locations. */ + gcc_checking_assert (kind != MACRO_ARG_TOKEN_STRINGIFIED + && track_macro_exp_p); + *loc = location; + } +} + +/* Get the pointer to the location of the argument token of the + function-like macro argument ARG. This function must be called + only when we -ftrack-macro-expansion is on. */ +static const location_t * +get_arg_token_location (const macro_arg *arg, + enum macro_arg_token_kind kind) +{ + const location_t *loc = NULL; + const cpp_token **token_ptr = + arg_token_ptr_at (arg, 0, kind, (location_t **) &loc); + + if (token_ptr == NULL) + return NULL; + + return loc; +} + +/* Return the pointer to the INDEXth token of the macro argument ARG. + KIND specifies the kind of token the macro argument ARG contains. + If VIRT_LOCATION is non NULL, *VIRT_LOCATION is set to the address + of the virtual location of the returned token if the + -ftrack-macro-expansion flag is on; otherwise, it's set to the + spelling location of the returned token. */ +static const cpp_token ** +arg_token_ptr_at (const macro_arg *arg, size_t index, + enum macro_arg_token_kind kind, + location_t **virt_location) +{ + const cpp_token **tokens_ptr = NULL; + + switch (kind) + { + case MACRO_ARG_TOKEN_NORMAL: + tokens_ptr = arg->first; + break; + case MACRO_ARG_TOKEN_STRINGIFIED: + tokens_ptr = (const cpp_token **) &arg->stringified; + break; + case MACRO_ARG_TOKEN_EXPANDED: + tokens_ptr = arg->expanded; + break; + } + + if (tokens_ptr == NULL) + /* This can happen for e.g, an empty token argument to a + funtion-like macro. */ + return tokens_ptr; + + if (virt_location) + { + if (kind == MACRO_ARG_TOKEN_NORMAL) + *virt_location = &arg->virt_locs[index]; + else if (kind == MACRO_ARG_TOKEN_EXPANDED) + *virt_location = &arg->expanded_virt_locs[index]; + else if (kind == MACRO_ARG_TOKEN_STRINGIFIED) + *virt_location = + (location_t *) &tokens_ptr[index]->src_loc; + } + return &tokens_ptr[index]; +} + +/* Initialize an iterator so that it iterates over the tokens of a + function-like macro argument. KIND is the kind of tokens we want + ITER to iterate over. TOKEN_PTR points the first token ITER will + iterate over. */ +static void +macro_arg_token_iter_init (macro_arg_token_iter *iter, + bool track_macro_exp_p, + enum macro_arg_token_kind kind, + const macro_arg *arg, + const cpp_token **token_ptr) +{ + iter->track_macro_exp_p = track_macro_exp_p; + iter->kind = kind; + iter->token_ptr = token_ptr; + /* Unconditionally initialize this so that the compiler doesn't warn + about iter->location_ptr being possibly uninitialized later after + this code has been inlined somewhere. */ + iter->location_ptr = NULL; + if (track_macro_exp_p) + iter->location_ptr = get_arg_token_location (arg, kind); +#if CHECKING_P + iter->num_forwards = 0; + if (track_macro_exp_p + && token_ptr != NULL + && iter->location_ptr == NULL) + abort (); +#endif +} + +/* Move the iterator one token forward. Note that if IT was + initialized on an argument that has a stringified token, moving it + forward doesn't make sense as a stringified token is essentially one + string. */ +static void +macro_arg_token_iter_forward (macro_arg_token_iter *it) +{ + switch (it->kind) + { + case MACRO_ARG_TOKEN_NORMAL: + case MACRO_ARG_TOKEN_EXPANDED: + it->token_ptr++; + if (it->track_macro_exp_p) + it->location_ptr++; + break; + case MACRO_ARG_TOKEN_STRINGIFIED: +#if CHECKING_P + if (it->num_forwards > 0) + abort (); +#endif + break; + } + +#if CHECKING_P + it->num_forwards++; +#endif +} + +/* Return the token pointed to by the iterator. */ +static const cpp_token * +macro_arg_token_iter_get_token (const macro_arg_token_iter *it) +{ +#if CHECKING_P + if (it->kind == MACRO_ARG_TOKEN_STRINGIFIED + && it->num_forwards > 0) + abort (); +#endif + if (it->token_ptr == NULL) + return NULL; + return *it->token_ptr; +} + +/* Return the location of the token pointed to by the iterator.*/ +static location_t +macro_arg_token_iter_get_location (const macro_arg_token_iter *it) +{ +#if CHECKING_P + if (it->kind == MACRO_ARG_TOKEN_STRINGIFIED + && it->num_forwards > 0) + abort (); +#endif + if (it->track_macro_exp_p) + return *it->location_ptr; + else + return (*it->token_ptr)->src_loc; +} + +/* Return the index of a token [resulting from macro expansion] inside + the total list of tokens resulting from a given macro + expansion. The index can be different depending on whether if we + want each tokens resulting from function-like macro arguments + expansion to have a different location or not. + + E.g, consider this function-like macro: + + #define M(x) x - 3 + + Then consider us "calling" it (and thus expanding it) like: + + M(1+4) + + It will be expanded into: + + 1+4-3 + + Let's consider the case of the token '4'. + + Its index can be 2 (it's the third token of the set of tokens + resulting from the expansion) or it can be 0 if we consider that + all tokens resulting from the expansion of the argument "1+2" have + the same index, which is 0. In this later case, the index of token + '-' would then be 1 and the index of token '3' would be 2. + + The later case is useful to use less memory e.g, for the case of + the user using the option -ftrack-macro-expansion=1. + + ABSOLUTE_TOKEN_INDEX is the index of the macro argument token we + are interested in. CUR_REPLACEMENT_TOKEN is the token of the macro + parameter (inside the macro replacement list) that corresponds to + the macro argument for which ABSOLUTE_TOKEN_INDEX is a token index + of. + + If we refer to the example above, for the '4' argument token, + ABSOLUTE_TOKEN_INDEX would be set to 2, and CUR_REPLACEMENT_TOKEN + would be set to the token 'x', in the replacement list "x - 3" of + macro M. + + This is a subroutine of replace_args. */ +inline static unsigned +expanded_token_index (cpp_reader *pfile, cpp_macro *macro, + const cpp_token *cur_replacement_token, + unsigned absolute_token_index) +{ + if (CPP_OPTION (pfile, track_macro_expansion) > 1) + return absolute_token_index; + return cur_replacement_token - macro->exp.tokens; +} + +/* Copy whether PASTE_LEFT is set from SRC to *PASTE_FLAG. */ + +static void +copy_paste_flag (cpp_reader *pfile, const cpp_token **paste_flag, + const cpp_token *src) +{ + cpp_token *token = _cpp_temp_token (pfile); + token->type = (*paste_flag)->type; + token->val = (*paste_flag)->val; + if (src->flags & PASTE_LEFT) + token->flags = (*paste_flag)->flags | PASTE_LEFT; + else + token->flags = (*paste_flag)->flags & ~PASTE_LEFT; + *paste_flag = token; +} + +/* True IFF the last token emitted into BUFF (if any) is PTR. */ + +static bool +last_token_is (_cpp_buff *buff, const cpp_token **ptr) +{ + return (ptr && tokens_buff_last_token_ptr (buff) == ptr); +} + +/* Replace the parameters in a function-like macro of NODE with the + actual ARGS, and place the result in a newly pushed token context. + Expand each argument before replacing, unless it is operated upon + by the # or ## operators. EXPANSION_POINT_LOC is the location of + the expansion point of the macro. E.g, the location of the + function-like macro invocation. */ +static void +replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, + macro_arg *args, location_t expansion_point_loc) +{ + unsigned int i, total; + const cpp_token *src, *limit; + const cpp_token **first = NULL; + macro_arg *arg; + _cpp_buff *buff = NULL; + location_t *virt_locs = NULL; + unsigned int exp_count; + const line_map_macro *map = NULL; + int track_macro_exp; + + /* First, fully macro-expand arguments, calculating the number of + tokens in the final expansion as we go. The ordering of the if + statements below is subtle; we must handle stringification before + pasting. */ + + /* EXP_COUNT is the number of tokens in the macro replacement + list. TOTAL is the number of tokens /after/ macro parameters + have been replaced by their arguments. */ + exp_count = macro_real_token_count (macro); + total = exp_count; + limit = macro->exp.tokens + exp_count; + + for (src = macro->exp.tokens; src < limit; src++) + if (src->type == CPP_MACRO_ARG) + { + /* Leading and trailing padding tokens. */ + total += 2; + /* Account for leading and padding tokens in exp_count too. + This is going to be important later down this function, + when we want to handle the case of (track_macro_exp < + 2). */ + exp_count += 2; + + /* We have an argument. If it is not being stringified or + pasted it is macro-replaced before insertion. */ + arg = &args[src->val.macro_arg.arg_no - 1]; + + if (src->flags & STRINGIFY_ARG) + { + if (!arg->stringified) + arg->stringified = stringify_arg (pfile, arg->first, arg->count); + } + else if ((src->flags & PASTE_LEFT) + || (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT))) + total += arg->count - 1; + else + { + if (!arg->expanded) + expand_arg (pfile, arg); + total += arg->expanded_count - 1; + } + } + + /* When the compiler is called with the -ftrack-macro-expansion + flag, we need to keep track of the location of each token that + results from macro expansion. + + A token resulting from macro expansion is not a new token. It is + simply the same token as the token coming from the macro + definition. The new things that are allocated are the buffer + that holds the tokens resulting from macro expansion and a new + location that records many things like the locus of the expansion + point as well as the original locus inside the definition of the + macro. This location is called a virtual location. + + So the buffer BUFF holds a set of cpp_token*, and the buffer + VIRT_LOCS holds the virtual locations of the tokens held by BUFF. + + Both of these two buffers are going to be hung off of the macro + context, when the latter is pushed. The memory allocated to + store the tokens and their locations is going to be freed once + the context of macro expansion is popped. + + As far as tokens are concerned, the memory overhead of + -ftrack-macro-expansion is proportional to the number of + macros that get expanded multiplied by sizeof (location_t). + The good news is that extra memory gets freed when the macro + context is freed, i.e shortly after the macro got expanded. */ + + /* Is the -ftrack-macro-expansion flag in effect? */ + track_macro_exp = CPP_OPTION (pfile, track_macro_expansion); + + /* Now allocate memory space for tokens and locations resulting from + the macro expansion, copy the tokens and replace the arguments. + This memory must be freed when the context of the macro MACRO is + popped. */ + buff = tokens_buff_new (pfile, total, track_macro_exp ? &virt_locs : NULL); + + first = (const cpp_token **) buff->base; + + /* Create a macro map to record the locations of the tokens that are + involved in the expansion. Note that the expansion point is set + to the location of the closing parenthesis. Otherwise, the + subsequent map created for the first token that comes after the + macro map might have a wrong line number. That would lead to + tokens with wrong line numbers after the macro expansion. This + adds up to the memory overhead of the -ftrack-macro-expansion + flag; for every macro that is expanded, a "macro map" is + created. */ + if (track_macro_exp) + { + int num_macro_tokens = total; + if (track_macro_exp < 2) + /* Then the number of macro tokens won't take in account the + fact that function-like macro arguments can expand to + multiple tokens. This is to save memory at the expense of + accuracy. + + Suppose we have #define SQUARE(A) A * A + + And then we do SQUARE(2+3) + + Then the tokens 2, +, 3, will have the same location, + saying they come from the expansion of the argument A. */ + num_macro_tokens = exp_count; + map = linemap_enter_macro (pfile->line_table, node, + expansion_point_loc, + num_macro_tokens); + } + i = 0; + vaopt_state vaopt_tracker (pfile, macro->variadic, &args[macro->paramc - 1]); + const cpp_token **vaopt_start = NULL; + for (src = macro->exp.tokens; src < limit; src++) + { + unsigned int arg_tokens_count; + macro_arg_token_iter from; + const cpp_token **paste_flag = NULL; + const cpp_token **tmp_token_ptr; + + /* __VA_OPT__ handling. */ + vaopt_state::update_type vostate = vaopt_tracker.update (src); + if (__builtin_expect (vostate != vaopt_state::INCLUDE, false)) + { + if (vostate == vaopt_state::BEGIN) + { + /* Padding on the left of __VA_OPT__ (unless RHS of ##). */ + if (src != macro->exp.tokens && !(src[-1].flags & PASTE_LEFT)) + { + const cpp_token *t = padding_token (pfile, src); + unsigned index = expanded_token_index (pfile, macro, src, i); + /* Allocate a virtual location for the padding token and + append the token and its location to BUFF and + VIRT_LOCS. */ + tokens_buff_add_token (buff, virt_locs, t, + t->src_loc, t->src_loc, + map, index); + } + vaopt_start = tokens_buff_last_token_ptr (buff); + } + else if (vostate == vaopt_state::END) + { + const cpp_token **start = vaopt_start; + vaopt_start = NULL; + + paste_flag = tokens_buff_last_token_ptr (buff); + + if (vaopt_tracker.stringify ()) + { + unsigned int count + = start ? paste_flag - start : tokens_buff_count (buff); + const cpp_token **first + = start ? start + 1 + : (const cpp_token **) (buff->base); + unsigned int i, j; + + /* Paste any tokens that need to be pasted before calling + stringify_arg, because stringify_arg uses pfile->u_buff + which paste_tokens can use as well. */ + for (i = 0, j = 0; i < count; i++, j++) + { + const cpp_token *token = first[i]; + + if (token->flags & PASTE_LEFT) + { + location_t virt_loc = pfile->invocation_location; + const cpp_token *rhs; + do + { + if (i == count) + abort (); + rhs = first[++i]; + if (!paste_tokens (pfile, virt_loc, &token, rhs)) + { + --i; + break; + } + } + while (rhs->flags & PASTE_LEFT); + } + + first[j] = token; + } + if (j != i) + { + while (i-- != j) + tokens_buff_remove_last_token (buff); + count = j; + } + + const cpp_token *t = stringify_arg (pfile, first, count); + while (count--) + tokens_buff_remove_last_token (buff); + if (src->flags & PASTE_LEFT) + copy_paste_flag (pfile, &t, src); + tokens_buff_add_token (buff, virt_locs, + t, t->src_loc, t->src_loc, + NULL, 0); + continue; + } + if (start && paste_flag == start && (*start)->flags & PASTE_LEFT) + /* If __VA_OPT__ expands to nothing (either because __VA_ARGS__ + is empty or because it is __VA_OPT__() ), drop PASTE_LEFT + flag from previous token. */ + copy_paste_flag (pfile, start, &pfile->avoid_paste); + if (src->flags & PASTE_LEFT) + { + /* Don't avoid paste after all. */ + while (paste_flag && paste_flag != start + && *paste_flag == &pfile->avoid_paste) + { + tokens_buff_remove_last_token (buff); + paste_flag = tokens_buff_last_token_ptr (buff); + } + + /* With a non-empty __VA_OPT__ on the LHS of ##, the last + token should be flagged PASTE_LEFT. */ + if (paste_flag && (*paste_flag)->type != CPP_PADDING) + copy_paste_flag (pfile, paste_flag, src); + } + else + { + /* Otherwise, avoid paste on RHS, __VA_OPT__(c)d or + __VA_OPT__(c)__VA_OPT__(d). */ + const cpp_token *t = &pfile->avoid_paste; + tokens_buff_add_token (buff, virt_locs, + t, t->src_loc, t->src_loc, + NULL, 0); + } + } + continue; + } + + if (src->type != CPP_MACRO_ARG) + { + /* Allocate a virtual location for token SRC, and add that + token and its virtual location into the buffers BUFF and + VIRT_LOCS. */ + unsigned index = expanded_token_index (pfile, macro, src, i); + tokens_buff_add_token (buff, virt_locs, src, + src->src_loc, src->src_loc, + map, index); + i += 1; + continue; + } + + paste_flag = 0; + arg = &args[src->val.macro_arg.arg_no - 1]; + /* SRC is a macro parameter that we need to replace with its + corresponding argument. So at some point we'll need to + iterate over the tokens of the macro argument and copy them + into the "place" now holding the correspondig macro + parameter. We are going to use the iterator type + macro_argo_token_iter to handle that iterating. The 'if' + below is to initialize the iterator depending on the type of + tokens the macro argument has. It also does some adjustment + related to padding tokens and some pasting corner cases. */ + if (src->flags & STRINGIFY_ARG) + { + arg_tokens_count = 1; + macro_arg_token_iter_init (&from, + CPP_OPTION (pfile, + track_macro_expansion), + MACRO_ARG_TOKEN_STRINGIFIED, + arg, &arg->stringified); + } + else if (src->flags & PASTE_LEFT) + { + arg_tokens_count = arg->count; + macro_arg_token_iter_init (&from, + CPP_OPTION (pfile, + track_macro_expansion), + MACRO_ARG_TOKEN_NORMAL, + arg, arg->first); + } + else if (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT)) + { + int num_toks; + arg_tokens_count = arg->count; + macro_arg_token_iter_init (&from, + CPP_OPTION (pfile, + track_macro_expansion), + MACRO_ARG_TOKEN_NORMAL, + arg, arg->first); + + num_toks = tokens_buff_count (buff); + + if (num_toks != 0) + { + /* So the current parameter token is pasted to the previous + token in the replacement list. Let's look at what + we have as previous and current arguments. */ + + /* This is the previous argument's token ... */ + tmp_token_ptr = tokens_buff_last_token_ptr (buff); + + if ((*tmp_token_ptr)->type == CPP_COMMA + && macro->variadic + && src->val.macro_arg.arg_no == macro->paramc) + { + /* ... which is a comma; and the current parameter + is the last parameter of a variadic function-like + macro. If the argument to the current last + parameter is NULL, then swallow the comma, + otherwise drop the paste flag. */ + if (macro_arg_token_iter_get_token (&from) == NULL) + tokens_buff_remove_last_token (buff); + else + paste_flag = tmp_token_ptr; + } + /* Remove the paste flag if the RHS is a placemarker. */ + else if (arg_tokens_count == 0) + paste_flag = tmp_token_ptr; + } + } + else + { + arg_tokens_count = arg->expanded_count; + macro_arg_token_iter_init (&from, + CPP_OPTION (pfile, + track_macro_expansion), + MACRO_ARG_TOKEN_EXPANDED, + arg, arg->expanded); + + if (last_token_is (buff, vaopt_start)) + { + /* We're expanding an arg at the beginning of __VA_OPT__. + Skip padding. */ + while (arg_tokens_count) + { + const cpp_token *t = macro_arg_token_iter_get_token (&from); + if (t->type != CPP_PADDING) + break; + macro_arg_token_iter_forward (&from); + --arg_tokens_count; + } + } + } + + /* Padding on the left of an argument (unless RHS of ##). */ + if ((!pfile->state.in_directive || pfile->state.directive_wants_padding) + && src != macro->exp.tokens + && !(src[-1].flags & PASTE_LEFT) + && !last_token_is (buff, vaopt_start)) + { + const cpp_token *t = padding_token (pfile, src); + unsigned index = expanded_token_index (pfile, macro, src, i); + /* Allocate a virtual location for the padding token and + append the token and its location to BUFF and + VIRT_LOCS. */ + tokens_buff_add_token (buff, virt_locs, t, + t->src_loc, t->src_loc, + map, index); + } + + if (arg_tokens_count) + { + /* So now we've got the number of tokens that make up the + argument that is going to replace the current parameter + in the macro's replacement list. */ + unsigned int j; + for (j = 0; j < arg_tokens_count; ++j) + { + /* So if track_macro_exp is < 2, the user wants to + save extra memory while tracking macro expansion + locations. So in that case here is what we do: + + Suppose we have #define SQUARE(A) A * A + + And then we do SQUARE(2+3) + + Then the tokens 2, +, 3, will have the same location, + saying they come from the expansion of the argument + A. + + So that means we are going to ignore the COUNT tokens + resulting from the expansion of the current macro + argument. In other words all the ARG_TOKENS_COUNT tokens + resulting from the expansion of the macro argument will + have the index I. Normally, each of those tokens should + have index I+J. */ + unsigned token_index = i; + unsigned index; + if (track_macro_exp > 1) + token_index += j; + + index = expanded_token_index (pfile, macro, src, token_index); + const cpp_token *tok = macro_arg_token_iter_get_token (&from); + tokens_buff_add_token (buff, virt_locs, tok, + macro_arg_token_iter_get_location (&from), + src->src_loc, map, index); + macro_arg_token_iter_forward (&from); + } + + /* With a non-empty argument on the LHS of ##, the last + token should be flagged PASTE_LEFT. */ + if (src->flags & PASTE_LEFT) + paste_flag + = (const cpp_token **) tokens_buff_last_token_ptr (buff); + } + else if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, c99) + && ! macro->syshdr && ! _cpp_in_system_header (pfile)) + { + if (CPP_OPTION (pfile, cplusplus)) + cpp_pedwarning (pfile, CPP_W_PEDANTIC, + "invoking macro %s argument %d: " + "empty macro arguments are undefined" + " in ISO C++98", + NODE_NAME (node), src->val.macro_arg.arg_no); + else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat)) + cpp_pedwarning (pfile, + CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0 + ? CPP_W_C90_C99_COMPAT : CPP_W_PEDANTIC, + "invoking macro %s argument %d: " + "empty macro arguments are undefined" + " in ISO C90", + NODE_NAME (node), src->val.macro_arg.arg_no); + } + else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0 + && ! CPP_OPTION (pfile, cplusplus) + && ! macro->syshdr && ! _cpp_in_system_header (pfile)) + cpp_warning (pfile, CPP_W_C90_C99_COMPAT, + "invoking macro %s argument %d: " + "empty macro arguments are undefined" + " in ISO C90", + NODE_NAME (node), src->val.macro_arg.arg_no); + + /* Avoid paste on RHS (even case count == 0). */ + if (!pfile->state.in_directive && !(src->flags & PASTE_LEFT)) + { + const cpp_token *t = &pfile->avoid_paste; + tokens_buff_add_token (buff, virt_locs, + t, t->src_loc, t->src_loc, + NULL, 0); + } + + /* Add a new paste flag, or remove an unwanted one. */ + if (paste_flag) + copy_paste_flag (pfile, paste_flag, src); + + i += arg_tokens_count; + } + + if (track_macro_exp) + push_extended_tokens_context (pfile, node, buff, virt_locs, first, + tokens_buff_count (buff)); + else + push_ptoken_context (pfile, node, buff, first, + tokens_buff_count (buff)); + + num_macro_tokens_counter += tokens_buff_count (buff); +} + +/* Return a special padding token, with padding inherited from SOURCE. */ +static const cpp_token * +padding_token (cpp_reader *pfile, const cpp_token *source) +{ + cpp_token *result = _cpp_temp_token (pfile); + + result->type = CPP_PADDING; + + /* Data in GCed data structures cannot be made const so far, so we + need a cast here. */ + result->val.source = (cpp_token *) source; + result->flags = 0; + return result; +} + +/* Get a new uninitialized context. Create a new one if we cannot + re-use an old one. */ +static cpp_context * +next_context (cpp_reader *pfile) +{ + cpp_context *result = pfile->context->next; + + if (result == 0) + { + result = XNEW (cpp_context); + memset (result, 0, sizeof (cpp_context)); + result->prev = pfile->context; + result->next = 0; + pfile->context->next = result; + } + + pfile->context = result; + return result; +} + +/* Push a list of pointers to tokens. */ +static void +push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff, + const cpp_token **first, unsigned int count) +{ + cpp_context *context = next_context (pfile); + + context->tokens_kind = TOKENS_KIND_INDIRECT; + context->c.macro = macro; + context->buff = buff; + FIRST (context).ptoken = first; + LAST (context).ptoken = first + count; +} + +/* Push a list of tokens. + + A NULL macro means that we should continue the current macro + expansion, in essence. That means that if we are currently in a + macro expansion context, we'll make the new pfile->context refer to + the current macro. */ +void +_cpp_push_token_context (cpp_reader *pfile, cpp_hashnode *macro, + const cpp_token *first, unsigned int count) +{ + cpp_context *context; + + if (macro == NULL) + macro = macro_of_context (pfile->context); + + context = next_context (pfile); + context->tokens_kind = TOKENS_KIND_DIRECT; + context->c.macro = macro; + context->buff = NULL; + FIRST (context).token = first; + LAST (context).token = first + count; +} + +/* Build a context containing a list of tokens as well as their + virtual locations and push it. TOKENS_BUFF is the buffer that + contains the tokens pointed to by FIRST. If TOKENS_BUFF is + non-NULL, it means that the context owns it, meaning that + _cpp_pop_context will free it as well as VIRT_LOCS_BUFF that + contains the virtual locations. + + A NULL macro means that we should continue the current macro + expansion, in essence. That means that if we are currently in a + macro expansion context, we'll make the new pfile->context refer to + the current macro. */ +static void +push_extended_tokens_context (cpp_reader *pfile, + cpp_hashnode *macro, + _cpp_buff *token_buff, + location_t *virt_locs, + const cpp_token **first, + unsigned int count) +{ + cpp_context *context; + macro_context *m; + + if (macro == NULL) + macro = macro_of_context (pfile->context); + + context = next_context (pfile); + context->tokens_kind = TOKENS_KIND_EXTENDED; + context->buff = token_buff; + + m = XNEW (macro_context); + m->macro_node = macro; + m->virt_locs = virt_locs; + m->cur_virt_loc = virt_locs; + context->c.mc = m; + FIRST (context).ptoken = first; + LAST (context).ptoken = first + count; +} + +/* Push a traditional macro's replacement text. */ +void +_cpp_push_text_context (cpp_reader *pfile, cpp_hashnode *macro, + const uchar *start, size_t len) +{ + cpp_context *context = next_context (pfile); + + context->tokens_kind = TOKENS_KIND_DIRECT; + context->c.macro = macro; + context->buff = NULL; + CUR (context) = start; + RLIMIT (context) = start + len; + macro->flags |= NODE_DISABLED; +} + +/* Creates a buffer that holds tokens a.k.a "token buffer", usually + for the purpose of storing them on a cpp_context. If VIRT_LOCS is + non-null (which means that -ftrack-macro-expansion is on), + *VIRT_LOCS is set to a newly allocated buffer that is supposed to + hold the virtual locations of the tokens resulting from macro + expansion. */ +static _cpp_buff* +tokens_buff_new (cpp_reader *pfile, size_t len, + location_t **virt_locs) +{ + size_t tokens_size = len * sizeof (cpp_token *); + size_t locs_size = len * sizeof (location_t); + + if (virt_locs != NULL) + *virt_locs = XNEWVEC (location_t, locs_size); + return _cpp_get_buff (pfile, tokens_size); +} + +/* Returns the number of tokens contained in a token buffer. The + buffer holds a set of cpp_token*. */ +static size_t +tokens_buff_count (_cpp_buff *buff) +{ + return (BUFF_FRONT (buff) - buff->base) / sizeof (cpp_token *); +} + +/* Return a pointer to the last token contained in the token buffer + BUFF. */ +static const cpp_token ** +tokens_buff_last_token_ptr (_cpp_buff *buff) +{ + if (BUFF_FRONT (buff) == buff->base) + return NULL; + return &((const cpp_token **) BUFF_FRONT (buff))[-1]; +} + +/* Remove the last token contained in the token buffer TOKENS_BUFF. + If VIRT_LOCS_BUFF is non-NULL, it should point at the buffer + containing the virtual locations of the tokens in TOKENS_BUFF; in + which case the function updates that buffer as well. */ +static inline void +tokens_buff_remove_last_token (_cpp_buff *tokens_buff) + +{ + if (BUFF_FRONT (tokens_buff) > tokens_buff->base) + BUFF_FRONT (tokens_buff) = + (unsigned char *) &((cpp_token **) BUFF_FRONT (tokens_buff))[-1]; +} + +/* Insert a token into the token buffer at the position pointed to by + DEST. Note that the buffer is not enlarged so the previous token + that was at *DEST is overwritten. VIRT_LOC_DEST, if non-null, + means -ftrack-macro-expansion is effect; it then points to where to + insert the virtual location of TOKEN. TOKEN is the token to + insert. VIRT_LOC is the virtual location of the token, i.e, the + location possibly encoding its locus across macro expansion. If + TOKEN is an argument of a function-like macro (inside a macro + replacement list), PARM_DEF_LOC is the spelling location of the + macro parameter that TOKEN is replacing, in the replacement list of + the macro. If TOKEN is not an argument of a function-like macro or + if it doesn't come from a macro expansion, then VIRT_LOC can just + be set to the same value as PARM_DEF_LOC. If MAP is non null, it + means TOKEN comes from a macro expansion and MAP is the macro map + associated to the macro. MACRO_TOKEN_INDEX points to the index of + the token in the macro map; it is not considered if MAP is NULL. + + Upon successful completion this function returns the a pointer to + the position of the token coming right after the insertion + point. */ +static inline const cpp_token ** +tokens_buff_put_token_to (const cpp_token **dest, + location_t *virt_loc_dest, + const cpp_token *token, + location_t virt_loc, + location_t parm_def_loc, + const line_map_macro *map, + unsigned int macro_token_index) +{ + location_t macro_loc = virt_loc; + const cpp_token **result; + + if (virt_loc_dest) + { + /* -ftrack-macro-expansion is on. */ + if (map) + macro_loc = linemap_add_macro_token (map, macro_token_index, + virt_loc, parm_def_loc); + *virt_loc_dest = macro_loc; + } + *dest = token; + result = &dest[1]; + + return result; +} + +/* Adds a token at the end of the tokens contained in BUFFER. Note + that this function doesn't enlarge BUFFER when the number of tokens + reaches BUFFER's size; it aborts in that situation. + + TOKEN is the token to append. VIRT_LOC is the virtual location of + the token, i.e, the location possibly encoding its locus across + macro expansion. If TOKEN is an argument of a function-like macro + (inside a macro replacement list), PARM_DEF_LOC is the location of + the macro parameter that TOKEN is replacing. If TOKEN doesn't come + from a macro expansion, then VIRT_LOC can just be set to the same + value as PARM_DEF_LOC. If MAP is non null, it means TOKEN comes + from a macro expansion and MAP is the macro map associated to the + macro. MACRO_TOKEN_INDEX points to the index of the token in the + macro map; It is not considered if MAP is NULL. If VIRT_LOCS is + non-null, it means -ftrack-macro-expansion is on; in which case + this function adds the virtual location DEF_LOC to the VIRT_LOCS + array, at the same index as the one of TOKEN in BUFFER. Upon + successful completion this function returns the a pointer to the + position of the token coming right after the insertion point. */ +static const cpp_token ** +tokens_buff_add_token (_cpp_buff *buffer, + location_t *virt_locs, + const cpp_token *token, + location_t virt_loc, + location_t parm_def_loc, + const line_map_macro *map, + unsigned int macro_token_index) +{ + const cpp_token **result; + location_t *virt_loc_dest = NULL; + unsigned token_index = + (BUFF_FRONT (buffer) - buffer->base) / sizeof (cpp_token *); + + /* Abort if we pass the end the buffer. */ + if (BUFF_FRONT (buffer) > BUFF_LIMIT (buffer)) + abort (); + + if (virt_locs != NULL) + virt_loc_dest = &virt_locs[token_index]; + + result = + tokens_buff_put_token_to ((const cpp_token **) BUFF_FRONT (buffer), + virt_loc_dest, token, virt_loc, parm_def_loc, + map, macro_token_index); + + BUFF_FRONT (buffer) = (unsigned char *) result; + return result; +} + +/* Allocate space for the function-like macro argument ARG to store + the tokens resulting from the macro-expansion of the tokens that + make up ARG itself. That space is allocated in ARG->expanded and + needs to be freed using free. */ +static void +alloc_expanded_arg_mem (cpp_reader *pfile, macro_arg *arg, size_t capacity) +{ + gcc_checking_assert (arg->expanded == NULL + && arg->expanded_virt_locs == NULL); + + arg->expanded = XNEWVEC (const cpp_token *, capacity); + if (CPP_OPTION (pfile, track_macro_expansion)) + arg->expanded_virt_locs = XNEWVEC (location_t, capacity); + +} + +/* If necessary, enlarge ARG->expanded to so that it can contain SIZE + tokens. */ +static void +ensure_expanded_arg_room (cpp_reader *pfile, macro_arg *arg, + size_t size, size_t *expanded_capacity) +{ + if (size <= *expanded_capacity) + return; + + size *= 2; + + arg->expanded = + XRESIZEVEC (const cpp_token *, arg->expanded, size); + *expanded_capacity = size; + + if (CPP_OPTION (pfile, track_macro_expansion)) + { + if (arg->expanded_virt_locs == NULL) + arg->expanded_virt_locs = XNEWVEC (location_t, size); + else + arg->expanded_virt_locs = XRESIZEVEC (location_t, + arg->expanded_virt_locs, + size); + } +} + +/* Expand an argument ARG before replacing parameters in a + function-like macro. This works by pushing a context with the + argument's tokens, and then expanding that into a temporary buffer + as if it were a normal part of the token stream. collect_args() + has terminated the argument's tokens with a CPP_EOF so that we know + when we have fully expanded the argument. */ +static void +expand_arg (cpp_reader *pfile, macro_arg *arg) +{ + size_t capacity; + bool saved_warn_trad; + bool track_macro_exp_p = CPP_OPTION (pfile, track_macro_expansion); + bool saved_ignore__Pragma; + + if (arg->count == 0 + || arg->expanded != NULL) + return; + + /* Don't warn about funlike macros when pre-expanding. */ + saved_warn_trad = CPP_WTRADITIONAL (pfile); + CPP_WTRADITIONAL (pfile) = 0; + + /* Loop, reading in the tokens of the argument. */ + capacity = 256; + alloc_expanded_arg_mem (pfile, arg, capacity); + + if (track_macro_exp_p) + push_extended_tokens_context (pfile, NULL, NULL, + arg->virt_locs, + arg->first, + arg->count + 1); + else + push_ptoken_context (pfile, NULL, NULL, + arg->first, arg->count + 1); + + saved_ignore__Pragma = pfile->state.ignore__Pragma; + pfile->state.ignore__Pragma = 1; + + for (;;) + { + const cpp_token *token; + location_t location; + + ensure_expanded_arg_room (pfile, arg, arg->expanded_count + 1, + &capacity); + + token = cpp_get_token_1 (pfile, &location); + + if (token->type == CPP_EOF) + break; + + set_arg_token (arg, token, location, + arg->expanded_count, MACRO_ARG_TOKEN_EXPANDED, + CPP_OPTION (pfile, track_macro_expansion)); + arg->expanded_count++; + } + + _cpp_pop_context (pfile); + + CPP_WTRADITIONAL (pfile) = saved_warn_trad; + pfile->state.ignore__Pragma = saved_ignore__Pragma; +} + +/* Returns the macro associated to the current context if we are in + the context a macro expansion, NULL otherwise. */ +static cpp_hashnode* +macro_of_context (cpp_context *context) +{ + if (context == NULL) + return NULL; + + return (context->tokens_kind == TOKENS_KIND_EXTENDED) + ? context->c.mc->macro_node + : context->c.macro; +} + +/* Return TRUE iff we are expanding a macro or are about to start + expanding one. If we are effectively expanding a macro, the + function macro_of_context returns a pointer to the macro being + expanded. */ +static bool +in_macro_expansion_p (cpp_reader *pfile) +{ + if (pfile == NULL) + return false; + + return (pfile->about_to_expand_macro_p + || macro_of_context (pfile->context)); +} + +/* Pop the current context off the stack, re-enabling the macro if the + context represented a macro's replacement list. Initially the + context structure was not freed so that we can re-use it later, but + now we do free it to reduce peak memory consumption. */ +void +_cpp_pop_context (cpp_reader *pfile) +{ + cpp_context *context = pfile->context; + + /* We should not be popping the base context. */ + gcc_assert (context != &pfile->base_context); + + if (context->c.macro) + { + cpp_hashnode *macro; + if (context->tokens_kind == TOKENS_KIND_EXTENDED) + { + macro_context *mc = context->c.mc; + macro = mc->macro_node; + /* If context->buff is set, it means the life time of tokens + is bound to the life time of this context; so we must + free the tokens; that means we must free the virtual + locations of these tokens too. */ + if (context->buff && mc->virt_locs) + { + free (mc->virt_locs); + mc->virt_locs = NULL; + } + free (mc); + context->c.mc = NULL; + } + else + macro = context->c.macro; + + /* Beware that MACRO can be NULL in cases like when we are + called from expand_arg. In those cases, a dummy context with + tokens is pushed just for the purpose of walking them using + cpp_get_token_1. In that case, no 'macro' field is set into + the dummy context. */ + if (macro != NULL + /* Several contiguous macro expansion contexts can be + associated to the same macro; that means it's the same + macro expansion that spans across all these (sub) + contexts. So we should re-enable an expansion-disabled + macro only when we are sure we are really out of that + macro expansion. */ + && macro_of_context (context->prev) != macro) + macro->flags &= ~NODE_DISABLED; + + if (macro == pfile->top_most_macro_node && context->prev == NULL) + /* We are popping the context of the top-most macro node. */ + pfile->top_most_macro_node = NULL; + } + + if (context->buff) + { + /* Decrease memory peak consumption by freeing the memory used + by the context. */ + _cpp_free_buff (context->buff); + } + + pfile->context = context->prev; + /* decrease peak memory consumption by feeing the context. */ + pfile->context->next = NULL; + free (context); +} + +/* Return TRUE if we reached the end of the set of tokens stored in + CONTEXT, FALSE otherwise. */ +static inline bool +reached_end_of_context (cpp_context *context) +{ + if (context->tokens_kind == TOKENS_KIND_DIRECT) + return FIRST (context).token == LAST (context).token; + else if (context->tokens_kind == TOKENS_KIND_INDIRECT + || context->tokens_kind == TOKENS_KIND_EXTENDED) + return FIRST (context).ptoken == LAST (context).ptoken; + else + abort (); +} + +/* Consume the next token contained in the current context of PFILE, + and return it in *TOKEN. It's "full location" is returned in + *LOCATION. If -ftrack-macro-location is in effeect, fFull location" + means the location encoding the locus of the token across macro + expansion; otherwise it's just is the "normal" location of the + token which (*TOKEN)->src_loc. */ +static inline void +consume_next_token_from_context (cpp_reader *pfile, + const cpp_token ** token, + location_t *location) +{ + cpp_context *c = pfile->context; + + if ((c)->tokens_kind == TOKENS_KIND_DIRECT) + { + *token = FIRST (c).token; + *location = (*token)->src_loc; + FIRST (c).token++; + } + else if ((c)->tokens_kind == TOKENS_KIND_INDIRECT) + { + *token = *FIRST (c).ptoken; + *location = (*token)->src_loc; + FIRST (c).ptoken++; + } + else if ((c)->tokens_kind == TOKENS_KIND_EXTENDED) + { + macro_context *m = c->c.mc; + *token = *FIRST (c).ptoken; + if (m->virt_locs) + { + *location = *m->cur_virt_loc; + m->cur_virt_loc++; + } + else + *location = (*token)->src_loc; + FIRST (c).ptoken++; + } + else + abort (); +} + +/* In the traditional mode of the preprocessor, if we are currently in + a directive, the location of a token must be the location of the + start of the directive line. This function returns the proper + location if we are in the traditional mode, and just returns + LOCATION otherwise. */ + +static inline location_t +maybe_adjust_loc_for_trad_cpp (cpp_reader *pfile, location_t location) +{ + if (CPP_OPTION (pfile, traditional)) + { + if (pfile->state.in_directive) + return pfile->directive_line; + } + return location; +} + +/* Routine to get a token as well as its location. + + Macro expansions and directives are transparently handled, + including entering included files. Thus tokens are post-macro + expansion, and after any intervening directives. External callers + see CPP_EOF only at EOF. Internal callers also see it when meeting + a directive inside a macro call, when at the end of a directive and + state.in_directive is still 1, and at the end of argument + pre-expansion. + + LOC is an out parameter; *LOC is set to the location "as expected + by the user". Please read the comment of + cpp_get_token_with_location to learn more about the meaning of this + location. */ +static const cpp_token* +cpp_get_token_1 (cpp_reader *pfile, location_t *location) +{ + const cpp_token *result; + /* This token is a virtual token that either encodes a location + related to macro expansion or a spelling location. */ + location_t virt_loc = 0; + /* pfile->about_to_expand_macro_p can be overriden by indirect calls + to functions that push macro contexts. So let's save it so that + we can restore it when we are about to leave this routine. */ + bool saved_about_to_expand_macro = pfile->about_to_expand_macro_p; + + for (;;) + { + cpp_hashnode *node; + cpp_context *context = pfile->context; + + /* Context->prev == 0 <=> base context. */ + if (!context->prev) + { + result = _cpp_lex_token (pfile); + virt_loc = result->src_loc; + } + else if (!reached_end_of_context (context)) + { + consume_next_token_from_context (pfile, &result, + &virt_loc); + if (result->flags & PASTE_LEFT) + { + paste_all_tokens (pfile, result); + if (pfile->state.in_directive) + continue; + result = padding_token (pfile, result); + goto out; + } + } + else + { + if (pfile->context->c.macro) + ++num_expanded_macros_counter; + _cpp_pop_context (pfile); + if (pfile->state.in_directive) + continue; + result = &pfile->avoid_paste; + goto out; + } + + if (pfile->state.in_directive && result->type == CPP_COMMENT) + continue; + + if (result->type != CPP_NAME) + break; + + node = result->val.node.node; + + if (node->type == NT_VOID || (result->flags & NO_EXPAND)) + break; + + if (!(node->flags & NODE_USED) + && node->type == NT_USER_MACRO + && !node->value.macro + && !cpp_get_deferred_macro (pfile, node, result->src_loc)) + break; + + if (!(node->flags & NODE_DISABLED)) + { + int ret = 0; + /* If not in a macro context, and we're going to start an + expansion, record the location and the top level macro + about to be expanded. */ + if (!in_macro_expansion_p (pfile)) + { + pfile->invocation_location = result->src_loc; + pfile->top_most_macro_node = node; + } + if (pfile->state.prevent_expansion) + break; + + /* Conditional macros require that a predicate be evaluated + first. */ + if ((node->flags & NODE_CONDITIONAL) != 0) + { + if (pfile->cb.macro_to_expand) + { + bool whitespace_after; + const cpp_token *peek_tok = cpp_peek_token (pfile, 0); + + whitespace_after = (peek_tok->type == CPP_PADDING + || (peek_tok->flags & PREV_WHITE)); + node = pfile->cb.macro_to_expand (pfile, result); + if (node) + ret = enter_macro_context (pfile, node, result, virt_loc); + else if (whitespace_after) + { + /* If macro_to_expand hook returned NULL and it + ate some tokens, see if we don't need to add + a padding token in between this and the + next token. */ + peek_tok = cpp_peek_token (pfile, 0); + if (peek_tok->type != CPP_PADDING + && (peek_tok->flags & PREV_WHITE) == 0) + _cpp_push_token_context (pfile, NULL, + padding_token (pfile, + peek_tok), 1); + } + } + } + else + ret = enter_macro_context (pfile, node, result, virt_loc); + if (ret) + { + if (pfile->state.in_directive || ret == 2) + continue; + result = padding_token (pfile, result); + goto out; + } + } + else + { + /* Flag this token as always unexpandable. FIXME: move this + to collect_args()?. */ + cpp_token *t = _cpp_temp_token (pfile); + t->type = result->type; + t->flags = result->flags | NO_EXPAND; + t->val = result->val; + result = t; + } + + break; + } + + out: + if (location != NULL) + { + if (virt_loc == 0) + virt_loc = result->src_loc; + *location = virt_loc; + + if (!CPP_OPTION (pfile, track_macro_expansion) + && macro_of_context (pfile->context) != NULL) + /* We are in a macro expansion context, are not tracking + virtual location, but were asked to report the location + of the expansion point of the macro being expanded. */ + *location = pfile->invocation_location; + + *location = maybe_adjust_loc_for_trad_cpp (pfile, *location); + } + + pfile->about_to_expand_macro_p = saved_about_to_expand_macro; + + if (pfile->state.directive_file_token + && !pfile->state.parsing_args + && !(result->type == CPP_PADDING || result->type == CPP_COMMENT) + && !(15 & --pfile->state.directive_file_token)) + { + /* Do header-name frobbery. Concatenate < ... > as approprate. + Do header search if needed, and finally drop the outer <> or + "". */ + pfile->state.angled_headers = false; + + /* Do angle-header reconstitution. Then do include searching. + We'll always end up with a ""-quoted header-name in that + case. If searching finds nothing, we emit a diagnostic and + an empty string. */ + size_t len = 0; + char *fname = NULL; + + cpp_token *tmp = _cpp_temp_token (pfile); + *tmp = *result; + + tmp->type = CPP_HEADER_NAME; + bool need_search = !pfile->state.directive_file_token; + pfile->state.directive_file_token = 0; + + bool angle = result->type != CPP_STRING; + if (result->type == CPP_HEADER_NAME + || (result->type == CPP_STRING && result->val.str.text[0] != 'R')) + { + len = result->val.str.len - 2; + fname = XNEWVEC (char, len + 1); + memcpy (fname, result->val.str.text + 1, len); + fname[len] = 0; + } + else if (result->type == CPP_LESS) + fname = _cpp_bracket_include (pfile); + + if (fname) + { + /* We have a header-name. Look it up. This will emit an + unfound diagnostic. Canonicalize the found name. */ + const char *found = fname; + + if (need_search) + { + found = _cpp_find_header_unit (pfile, fname, angle, tmp->src_loc); + if (!found) + found = ""; + len = strlen (found); + } + /* Force a leading './' if it's not absolute. */ + bool dotme = (found[0] == '.' ? !IS_DIR_SEPARATOR (found[1]) + : found[0] && !IS_ABSOLUTE_PATH (found)); + + if (BUFF_ROOM (pfile->u_buff) < len + 1 + dotme * 2) + _cpp_extend_buff (pfile, &pfile->u_buff, len + 1 + dotme * 2); + unsigned char *buf = BUFF_FRONT (pfile->u_buff); + size_t pos = 0; + + if (dotme) + { + buf[pos++] = '.'; + /* Apparently '/' is unconditional. */ + buf[pos++] = '/'; + } + memcpy (&buf[pos], found, len); + pos += len; + buf[pos] = 0; + + tmp->val.str.len = pos; + tmp->val.str.text = buf; + + tmp->type = CPP_HEADER_NAME; + XDELETEVEC (fname); + + result = tmp; + } + } + + return result; +} + +/* External routine to get a token. Also used nearly everywhere + internally, except for places where we know we can safely call + _cpp_lex_token directly, such as lexing a directive name. + + Macro expansions and directives are transparently handled, + including entering included files. Thus tokens are post-macro + expansion, and after any intervening directives. External callers + see CPP_EOF only at EOF. Internal callers also see it when meeting + a directive inside a macro call, when at the end of a directive and + state.in_directive is still 1, and at the end of argument + pre-expansion. */ +const cpp_token * +cpp_get_token (cpp_reader *pfile) +{ + return cpp_get_token_1 (pfile, NULL); +} + +/* Like cpp_get_token, but also returns a virtual token location + separate from the spelling location carried by the returned token. + + LOC is an out parameter; *LOC is set to the location "as expected + by the user". This matters when a token results from macro + expansion; in that case the token's spelling location indicates the + locus of the token in the definition of the macro but *LOC + virtually encodes all the other meaningful locuses associated to + the token. + + What? virtual location? Yes, virtual location. + + If the token results from macro expansion and if macro expansion + location tracking is enabled its virtual location encodes (at the + same time): + + - the spelling location of the token + + - the locus of the macro expansion point + + - the locus of the point where the token got instantiated as part + of the macro expansion process. + + You have to use the linemap API to get the locus you are interested + in from a given virtual location. + + Note however that virtual locations are not necessarily ordered for + relations '<' and '>'. One must use the function + linemap_location_before_p instead of using the relational operator + '<'. + + If macro expansion tracking is off and if the token results from + macro expansion the virtual location is the expansion point of the + macro that got expanded. + + When the token doesn't result from macro expansion, the virtual + location is just the same thing as its spelling location. */ + +const cpp_token * +cpp_get_token_with_location (cpp_reader *pfile, location_t *loc) +{ + return cpp_get_token_1 (pfile, loc); +} + +/* Returns true if we're expanding an object-like macro that was + defined in a system header. Just checks the macro at the top of + the stack. Used for diagnostic suppression. + Also return true for builtin macros. */ +int +cpp_sys_macro_p (cpp_reader *pfile) +{ + cpp_hashnode *node = NULL; + + if (pfile->context->tokens_kind == TOKENS_KIND_EXTENDED) + node = pfile->context->c.mc->macro_node; + else + node = pfile->context->c.macro; + + if (!node) + return false; + if (cpp_builtin_macro_p (node)) + return true; + return node->value.macro && node->value.macro->syshdr; +} + +/* Read each token in, until end of the current file. Directives are + transparently processed. */ +void +cpp_scan_nooutput (cpp_reader *pfile) +{ + /* Request a CPP_EOF token at the end of this file, rather than + transparently continuing with the including file. */ + pfile->buffer->return_at_eof = true; + + pfile->state.discarding_output++; + pfile->state.prevent_expansion++; + + if (CPP_OPTION (pfile, traditional)) + while (_cpp_read_logical_line_trad (pfile)) + ; + else + while (cpp_get_token (pfile)->type != CPP_EOF) + ; + + pfile->state.discarding_output--; + pfile->state.prevent_expansion--; +} + +/* Step back one or more tokens obtained from the lexer. */ +void +_cpp_backup_tokens_direct (cpp_reader *pfile, unsigned int count) +{ + pfile->lookaheads += count; + while (count--) + { + pfile->cur_token--; + if (pfile->cur_token == pfile->cur_run->base + /* Possible with -fpreprocessed and no leading #line. */ + && pfile->cur_run->prev != NULL) + { + pfile->cur_run = pfile->cur_run->prev; + pfile->cur_token = pfile->cur_run->limit; + } + } +} + +/* Step back one (or more) tokens. Can only step back more than 1 if + they are from the lexer, and not from macro expansion. */ +void +_cpp_backup_tokens (cpp_reader *pfile, unsigned int count) +{ + if (pfile->context->prev == NULL) + _cpp_backup_tokens_direct (pfile, count); + else + { + if (count != 1) + abort (); + if (pfile->context->tokens_kind == TOKENS_KIND_DIRECT) + FIRST (pfile->context).token--; + else if (pfile->context->tokens_kind == TOKENS_KIND_INDIRECT) + FIRST (pfile->context).ptoken--; + else if (pfile->context->tokens_kind == TOKENS_KIND_EXTENDED) + { + FIRST (pfile->context).ptoken--; + if (pfile->context->c.macro) + { + macro_context *m = pfile->context->c.mc; + m->cur_virt_loc--; + gcc_checking_assert (m->cur_virt_loc >= m->virt_locs); + } + else + abort (); + } + else + abort (); + } +} + +/* #define directive parsing and handling. */ + +/* Returns true if a macro redefinition warning is required. */ +static bool +warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node, + const cpp_macro *macro2) +{ + /* Some redefinitions need to be warned about regardless. */ + if (node->flags & NODE_WARN) + return true; + + /* Suppress warnings for builtins that lack the NODE_WARN flag, + unless Wbuiltin-macro-redefined. */ + if (cpp_builtin_macro_p (node)) + return CPP_OPTION (pfile, warn_builtin_macro_redefined); + + /* Redefinitions of conditional (context-sensitive) macros, on + the other hand, must be allowed silently. */ + if (node->flags & NODE_CONDITIONAL) + return false; + + if (cpp_macro *macro1 = get_deferred_or_lazy_macro (pfile, node, macro2->line)) + return cpp_compare_macros (macro1, macro2); + return false; +} + +/* Return TRUE if MACRO1 and MACRO2 differ. */ + +bool +cpp_compare_macros (const cpp_macro *macro1, const cpp_macro *macro2) +{ + /* Redefinition of a macro is allowed if and only if the old and new + definitions are the same. (6.10.3 paragraph 2). */ + + /* Don't check count here as it can be different in valid + traditional redefinitions with just whitespace differences. */ + if (macro1->paramc != macro2->paramc + || macro1->fun_like != macro2->fun_like + || macro1->variadic != macro2->variadic) + return true; + + /* Check parameter spellings. */ + for (unsigned i = macro1->paramc; i--; ) + if (macro1->parm.params[i] != macro2->parm.params[i]) + return true; + + /* Check the replacement text or tokens. */ + if (macro1->kind == cmk_traditional) + return _cpp_expansions_different_trad (macro1, macro2); + + if (macro1->count != macro2->count) + return true; + + for (unsigned i= macro1->count; i--; ) + if (!_cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i])) + return true; + + return false; +} + +/* Free the definition of hashnode H. */ +void +_cpp_free_definition (cpp_hashnode *h) +{ + /* Macros and assertions no longer have anything to free. */ + h->type = NT_VOID; + h->value.answers = NULL; + h->flags &= ~(NODE_DISABLED | NODE_USED); +} + +/* Save parameter NODE (spelling SPELLING) to the parameter list of + macro MACRO. Returns true on success, false on failure. */ +bool +_cpp_save_parameter (cpp_reader *pfile, unsigned n, cpp_hashnode *node, + cpp_hashnode *spelling) +{ + /* Constraint 6.10.3.6 - duplicate parameter names. */ + if (node->type == NT_MACRO_ARG) + { + cpp_error (pfile, CPP_DL_ERROR, "duplicate macro parameter \"%s\"", + NODE_NAME (node)); + return false; + } + + unsigned len = (n + 1) * sizeof (struct macro_arg_saved_data); + if (len > pfile->macro_buffer_len) + { + pfile->macro_buffer + = XRESIZEVEC (unsigned char, pfile->macro_buffer, len); + pfile->macro_buffer_len = len; + } + + macro_arg_saved_data *saved = (macro_arg_saved_data *)pfile->macro_buffer; + saved[n].canonical_node = node; + saved[n].value = node->value; + saved[n].type = node->type; + + void *base = _cpp_reserve_room (pfile, n * sizeof (cpp_hashnode *), + sizeof (cpp_hashnode *)); + ((cpp_hashnode **)base)[n] = spelling; + + /* Morph into a macro arg. */ + node->type = NT_MACRO_ARG; + /* Index is 1 based. */ + node->value.arg_index = n + 1; + + return true; +} + +/* Restore the parameters to their previous state. */ +void +_cpp_unsave_parameters (cpp_reader *pfile, unsigned n) +{ + /* Clear the fast argument lookup indices. */ + while (n--) + { + struct macro_arg_saved_data *save = + &((struct macro_arg_saved_data *) pfile->macro_buffer)[n]; + + struct cpp_hashnode *node = save->canonical_node; + node->type = save->type; + node->value = save->value; + } +} + +/* Check the syntax of the parameters in a MACRO definition. Return + false on failure. Set *N_PTR and *VARADIC_PTR as appropriate. + '(' ')' + '(' parm-list ',' last-parm ')' + '(' last-parm ')' + parm-list: name + | parm-list, name + last-parm: name + | name '...' + | '...' +*/ + +static bool +parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *varadic_ptr) +{ + unsigned nparms = 0; + bool ok = false; + + for (bool prev_ident = false;;) + { + const cpp_token *token = _cpp_lex_token (pfile); + + switch (token->type) + { + case CPP_COMMENT: + /* Allow/ignore comments in parameter lists if we are + preserving comments in macro expansions. */ + if (!CPP_OPTION (pfile, discard_comments_in_macro_exp)) + break; + + /* FALLTHRU */ + default: + bad: + { + const char *const msgs[5] = + { + N_("expected parameter name, found \"%s\""), + N_("expected ',' or ')', found \"%s\""), + N_("expected parameter name before end of line"), + N_("expected ')' before end of line"), + N_("expected ')' after \"...\"") + }; + unsigned ix = prev_ident; + const unsigned char *as_text = NULL; + if (*varadic_ptr) + ix = 4; + else if (token->type == CPP_EOF) + ix += 2; + else + as_text = cpp_token_as_text (pfile, token); + cpp_error (pfile, CPP_DL_ERROR, msgs[ix], as_text); + } + goto out; + + case CPP_NAME: + if (prev_ident || *varadic_ptr) + goto bad; + prev_ident = true; + + if (!_cpp_save_parameter (pfile, nparms, token->val.node.node, + token->val.node.spelling)) + goto out; + nparms++; + break; + + case CPP_CLOSE_PAREN: + if (prev_ident || !nparms || *varadic_ptr) + { + ok = true; + goto out; + } + + /* FALLTHRU */ + case CPP_COMMA: + if (!prev_ident || *varadic_ptr) + goto bad; + prev_ident = false; + break; + + case CPP_ELLIPSIS: + if (*varadic_ptr) + goto bad; + *varadic_ptr = true; + if (!prev_ident) + { + /* An ISO bare ellipsis. */ + _cpp_save_parameter (pfile, nparms, + pfile->spec_nodes.n__VA_ARGS__, + pfile->spec_nodes.n__VA_ARGS__); + nparms++; + pfile->state.va_args_ok = 1; + if (! CPP_OPTION (pfile, c99) + && CPP_OPTION (pfile, cpp_pedantic) + && CPP_OPTION (pfile, warn_variadic_macros)) + cpp_pedwarning + (pfile, CPP_W_VARIADIC_MACROS, + CPP_OPTION (pfile, cplusplus) + ? N_("anonymous variadic macros were introduced in C++11") + : N_("anonymous variadic macros were introduced in C99")); + else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0 + && ! CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_WARNING, + "anonymous variadic macros were introduced in C99"); + } + else if (CPP_OPTION (pfile, cpp_pedantic) + && CPP_OPTION (pfile, warn_variadic_macros)) + cpp_pedwarning (pfile, CPP_W_VARIADIC_MACROS, + CPP_OPTION (pfile, cplusplus) + ? N_("ISO C++ does not permit named variadic macros") + : N_("ISO C does not permit named variadic macros")); + break; + } + } + + out: + *n_ptr = nparms; + + return ok; +} + +/* Lex a token from the expansion of MACRO, but mark parameters as we + find them and warn of traditional stringification. */ +static cpp_macro * +lex_expansion_token (cpp_reader *pfile, cpp_macro *macro) +{ + macro = (cpp_macro *)_cpp_reserve_room (pfile, + sizeof (cpp_macro) - sizeof (cpp_token) + + macro->count * sizeof (cpp_token), + sizeof (cpp_token)); + cpp_token *saved_cur_token = pfile->cur_token; + pfile->cur_token = ¯o->exp.tokens[macro->count]; + cpp_token *token = _cpp_lex_direct (pfile); + pfile->cur_token = saved_cur_token; + + /* Is this a parameter? */ + if (token->type == CPP_NAME && token->val.node.node->type == NT_MACRO_ARG) + { + /* Morph into a parameter reference. */ + cpp_hashnode *spelling = token->val.node.spelling; + token->type = CPP_MACRO_ARG; + token->val.macro_arg.arg_no = token->val.node.node->value.arg_index; + token->val.macro_arg.spelling = spelling; + } + else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0 + && (token->type == CPP_STRING || token->type == CPP_CHAR)) + check_trad_stringification (pfile, macro, &token->val.str); + + return macro; +} + +static cpp_macro * +create_iso_definition (cpp_reader *pfile) +{ + bool following_paste_op = false; + const char *paste_op_error_msg = + N_("'##' cannot appear at either end of a macro expansion"); + unsigned int num_extra_tokens = 0; + unsigned nparms = 0; + cpp_hashnode **params = NULL; + bool varadic = false; + bool ok = false; + cpp_macro *macro = NULL; + + /* Look at the first token, to see if this is a function-like + macro. */ + cpp_token first; + cpp_token *saved_cur_token = pfile->cur_token; + pfile->cur_token = &first; + cpp_token *token = _cpp_lex_direct (pfile); + pfile->cur_token = saved_cur_token; + + if (token->flags & PREV_WHITE) + /* Preceeded by space, must be part of expansion. */; + else if (token->type == CPP_OPEN_PAREN) + { + /* An open-paren, get a parameter list. */ + if (!parse_params (pfile, &nparms, &varadic)) + goto out; + + params = (cpp_hashnode **)_cpp_commit_buff + (pfile, sizeof (cpp_hashnode *) * nparms); + token = NULL; + } + else if (token->type != CPP_EOF + && !(token->type == CPP_COMMENT + && ! CPP_OPTION (pfile, discard_comments_in_macro_exp))) + { + /* While ISO C99 requires whitespace before replacement text + in a macro definition, ISO C90 with TC1 allows characters + from the basic source character set there. */ + if (CPP_OPTION (pfile, c99)) + cpp_error (pfile, CPP_DL_PEDWARN, + CPP_OPTION (pfile, cplusplus) + ? N_("ISO C++11 requires whitespace after the macro name") + : N_("ISO C99 requires whitespace after the macro name")); + else + { + enum cpp_diagnostic_level warntype = CPP_DL_WARNING; + switch (token->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 ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~", + token->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"); + } + } + + macro = _cpp_new_macro (pfile, cmk_macro, + _cpp_reserve_room (pfile, 0, sizeof (cpp_macro))); + + if (!token) + { + macro->variadic = varadic; + macro->paramc = nparms; + macro->parm.params = params; + macro->fun_like = true; + } + else + { + /* Preserve the token we peeked, there is already a single slot for it. */ + macro->exp.tokens[0] = *token; + token = ¯o->exp.tokens[0]; + macro->count = 1; + } + + for (vaopt_state vaopt_tracker (pfile, macro->variadic, NULL);; token = NULL) + { + if (!token) + { + macro = lex_expansion_token (pfile, macro); + token = ¯o->exp.tokens[macro->count++]; + } + + /* Check the stringifying # constraint 6.10.3.2.1 of + function-like macros when lexing the subsequent token. */ + if (macro->count > 1 && token[-1].type == CPP_HASH && macro->fun_like) + { + if (token->type == CPP_MACRO_ARG + || (macro->variadic + && token->type == CPP_NAME + && token->val.node.node == pfile->spec_nodes.n__VA_OPT__)) + { + if (token->flags & PREV_WHITE) + token->flags |= SP_PREV_WHITE; + if (token[-1].flags & DIGRAPH) + token->flags |= SP_DIGRAPH; + token->flags &= ~PREV_WHITE; + token->flags |= STRINGIFY_ARG; + token->flags |= token[-1].flags & PREV_WHITE; + token[-1] = token[0]; + macro->count--; + } + /* Let assembler get away with murder. */ + else if (CPP_OPTION (pfile, lang) != CLK_ASM) + { + cpp_error (pfile, CPP_DL_ERROR, + "'#' is not followed by a macro parameter"); + goto out; + } + } + + if (token->type == CPP_EOF) + { + /* Paste operator constraint 6.10.3.3.1: + Token-paste ##, can appear in both object-like and + function-like macros, but not at the end. */ + if (following_paste_op) + { + cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); + goto out; + } + if (!vaopt_tracker.completed ()) + goto out; + break; + } + + /* Paste operator constraint 6.10.3.3.1. */ + if (token->type == CPP_PASTE) + { + /* Token-paste ##, can appear in both object-like and + function-like macros, but not at the beginning. */ + if (macro->count == 1) + { + cpp_error (pfile, CPP_DL_ERROR, paste_op_error_msg); + goto out; + } + + if (following_paste_op) + { + /* Consecutive paste operators. This one will be moved + to the end. */ + num_extra_tokens++; + token->val.token_no = macro->count - 1; + } + else + { + /* Drop the paste operator. */ + --macro->count; + token[-1].flags |= PASTE_LEFT; + if (token->flags & DIGRAPH) + token[-1].flags |= SP_DIGRAPH; + if (token->flags & PREV_WHITE) + token[-1].flags |= SP_PREV_WHITE; + } + following_paste_op = true; + } + else + following_paste_op = false; + + if (vaopt_tracker.update (token) == vaopt_state::ERROR) + goto out; + } + + /* We're committed to winning now. */ + ok = true; + + /* Don't count the CPP_EOF. */ + macro->count--; + + macro = (cpp_macro *)_cpp_commit_buff + (pfile, sizeof (cpp_macro) - sizeof (cpp_token) + + sizeof (cpp_token) * macro->count); + + /* Clear whitespace on first token. */ + if (macro->count) + macro->exp.tokens[0].flags &= ~PREV_WHITE; + + if (num_extra_tokens) + { + /* Place second and subsequent ## or %:%: tokens in sequences of + consecutive such tokens at the end of the list to preserve + information about where they appear, how they are spelt and + whether they are preceded by whitespace without otherwise + interfering with macro expansion. Remember, this is + extremely rare, so efficiency is not a priority. */ + cpp_token *temp = (cpp_token *)_cpp_reserve_room + (pfile, 0, num_extra_tokens * sizeof (cpp_token)); + unsigned extra_ix = 0, norm_ix = 0; + cpp_token *exp = macro->exp.tokens; + for (unsigned ix = 0; ix != macro->count; ix++) + if (exp[ix].type == CPP_PASTE) + temp[extra_ix++] = exp[ix]; + else + exp[norm_ix++] = exp[ix]; + memcpy (&exp[norm_ix], temp, num_extra_tokens * sizeof (cpp_token)); + + /* Record there are extra tokens. */ + macro->extra_tokens = 1; + } + + out: + pfile->state.va_args_ok = 0; + _cpp_unsave_parameters (pfile, nparms); + + return ok ? macro : NULL; +} + +cpp_macro * +_cpp_new_macro (cpp_reader *pfile, cpp_macro_kind kind, void *placement) +{ + cpp_macro *macro = (cpp_macro *) placement; + + /* Zero init all the fields. This'll tell the compiler know all the + following inits are writing a virgin object. */ + memset (macro, 0, offsetof (cpp_macro, exp)); + + macro->line = pfile->directive_line; + macro->parm.params = 0; + macro->lazy = 0; + macro->paramc = 0; + macro->variadic = 0; + macro->used = !CPP_OPTION (pfile, warn_unused_macros); + macro->count = 0; + macro->fun_like = 0; + macro->imported_p = false; + macro->extra_tokens = 0; + /* To suppress some diagnostics. */ + macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0; + + macro->kind = kind; + + return macro; +} + +/* Parse a macro and save its expansion. Returns nonzero on success. */ +bool +_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) +{ + cpp_macro *macro; + + if (CPP_OPTION (pfile, traditional)) + macro = _cpp_create_trad_definition (pfile); + else + macro = create_iso_definition (pfile); + + if (!macro) + return false; + + if (cpp_macro_p (node)) + { + if (CPP_OPTION (pfile, warn_unused_macros)) + _cpp_warn_if_unused_macro (pfile, node, NULL); + + if (warn_of_redefinition (pfile, node, macro)) + { + const enum cpp_warning_reason reason + = (cpp_builtin_macro_p (node) && !(node->flags & NODE_WARN)) + ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE; + + bool warned = + cpp_pedwarning_with_line (pfile, reason, + pfile->directive_line, 0, + "\"%s\" redefined", NODE_NAME (node)); + + if (warned && cpp_user_macro_p (node)) + cpp_error_with_line (pfile, CPP_DL_NOTE, + node->value.macro->line, 0, + "this is the location of the previous definition"); + } + _cpp_free_definition (node); + } + + /* Enter definition in hash table. */ + node->type = NT_USER_MACRO; + node->value.macro = macro; + if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_")) + && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_FORMAT_MACROS") + /* __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS are mentioned + in the C standard, as something that one must use in C++. + However DR#593 and C++11 indicate that they play no role in C++. + We special-case them anyway. */ + && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_LIMIT_MACROS") + && ustrcmp (NODE_NAME (node), (const uchar *) "__STDC_CONSTANT_MACROS")) + node->flags |= NODE_WARN; + + /* If user defines one of the conditional macros, remove the + conditional flag */ + node->flags &= ~NODE_CONDITIONAL; + + return true; +} + +extern void +cpp_define_lazily (cpp_reader *pfile, cpp_hashnode *node, unsigned num) +{ + cpp_macro *macro = node->value.macro; + + gcc_checking_assert (pfile->cb.user_lazy_macro && macro && num < UCHAR_MAX); + + macro->lazy = num + 1; +} + +/* NODE is a deferred macro, resolve it, returning the definition + (which may be NULL). */ +cpp_macro * +cpp_get_deferred_macro (cpp_reader *pfile, cpp_hashnode *node, + location_t loc) +{ + gcc_checking_assert (node->type == NT_USER_MACRO); + + node->value.macro = pfile->cb.user_deferred_macro (pfile, loc, node); + + if (!node->value.macro) + node->type = NT_VOID; + + return node->value.macro; +} + +static cpp_macro * +get_deferred_or_lazy_macro (cpp_reader *pfile, cpp_hashnode *node, + location_t loc) +{ + cpp_macro *macro = node->value.macro; + if (!macro) + { + macro = cpp_get_deferred_macro (pfile, node, loc); + gcc_checking_assert (!macro || !macro->lazy); + } + else if (macro->lazy) + { + pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1); + macro->lazy = 0; + } + + return macro; +} + +/* Notify the use of NODE in a macro-aware context (i.e. expanding it, + or testing its existance). Also applies any lazy definition. + Return FALSE if the macro isn't really there. */ + +extern bool +_cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node, + location_t loc) +{ + node->flags |= NODE_USED; + switch (node->type) + { + case NT_USER_MACRO: + if (!get_deferred_or_lazy_macro (pfile, node, loc)) + return false; + /* FALLTHROUGH. */ + + case NT_BUILTIN_MACRO: + if (pfile->cb.used_define) + pfile->cb.used_define (pfile, loc, node); + break; + + case NT_VOID: + if (pfile->cb.used_undef) + pfile->cb.used_undef (pfile, loc, node); + break; + + default: + abort (); + } + + return true; +} + +/* Warn if a token in STRING matches one of a function-like MACRO's + parameters. */ +static void +check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro, + const cpp_string *string) +{ + unsigned int i, len; + const uchar *p, *q, *limit; + + /* Loop over the string. */ + limit = string->text + string->len - 1; + for (p = string->text + 1; p < limit; p = q) + { + /* Find the start of an identifier. */ + while (p < limit && !is_idstart (*p)) + p++; + + /* Find the end of the identifier. */ + q = p; + while (q < limit && is_idchar (*q)) + q++; + + len = q - p; + + /* Loop over the function macro arguments to see if the + identifier inside the string matches one of them. */ + for (i = 0; i < macro->paramc; i++) + { + const cpp_hashnode *node = macro->parm.params[i]; + + if (NODE_LEN (node) == len + && !memcmp (p, NODE_NAME (node), len)) + { + cpp_warning (pfile, CPP_W_TRADITIONAL, + "macro argument \"%s\" would be stringified in traditional C", + NODE_NAME (node)); + break; + } + } + } +} + +/* Returns the name, arguments and expansion of a macro, in a format + suitable to be read back in again, and therefore also for DWARF 2 + debugging info. e.g. "PASTE(X, Y) X ## Y", or "MACNAME EXPANSION". + Caller is expected to generate the "#define" bit if needed. The + returned text is temporary, and automatically freed later. */ +const unsigned char * +cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node) +{ + gcc_checking_assert (cpp_user_macro_p (node)); + + if (const cpp_macro *macro = get_deferred_or_lazy_macro (pfile, node, 0)) + return cpp_macro_definition (pfile, node, macro); + return NULL; +} + +const unsigned char * +cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node, + const cpp_macro *macro) +{ + unsigned int i, len; + unsigned char *buffer; + + /* Calculate length. */ + len = NODE_LEN (node) * 10 + 2; /* ' ' and NUL. */ + if (macro->fun_like) + { + len += 4; /* "()" plus possible final ".." of named + varargs (we have + 1 below). */ + for (i = 0; i < macro->paramc; i++) + len += NODE_LEN (macro->parm.params[i]) + 1; /* "," */ + } + + /* This should match below where we fill in the buffer. */ + if (CPP_OPTION (pfile, traditional)) + len += _cpp_replacement_text_len (macro); + else + { + unsigned int count = macro_real_token_count (macro); + for (i = 0; i < count; i++) + { + const cpp_token *token = ¯o->exp.tokens[i]; + + if (token->type == CPP_MACRO_ARG) + len += NODE_LEN (token->val.macro_arg.spelling); + else + len += cpp_token_len (token); + + if (token->flags & STRINGIFY_ARG) + len++; /* "#" */ + if (token->flags & PASTE_LEFT) + len += 3; /* " ##" */ + if (token->flags & PREV_WHITE) + len++; /* " " */ + } + } + + if (len > pfile->macro_buffer_len) + { + pfile->macro_buffer = XRESIZEVEC (unsigned char, + pfile->macro_buffer, len); + pfile->macro_buffer_len = len; + } + + /* Fill in the buffer. Start with the macro name. */ + buffer = pfile->macro_buffer; + buffer = _cpp_spell_ident_ucns (buffer, node); + + /* Parameter names. */ + if (macro->fun_like) + { + *buffer++ = '('; + for (i = 0; i < macro->paramc; i++) + { + cpp_hashnode *param = macro->parm.params[i]; + + if (param != pfile->spec_nodes.n__VA_ARGS__) + { + memcpy (buffer, NODE_NAME (param), NODE_LEN (param)); + buffer += NODE_LEN (param); + } + + if (i + 1 < macro->paramc) + /* Don't emit a space after the comma here; we're trying + to emit a Dwarf-friendly definition, and the Dwarf spec + forbids spaces in the argument list. */ + *buffer++ = ','; + else if (macro->variadic) + *buffer++ = '.', *buffer++ = '.', *buffer++ = '.'; + } + *buffer++ = ')'; + } + + /* The Dwarf spec requires a space after the macro name, even if the + definition is the empty string. */ + *buffer++ = ' '; + + if (CPP_OPTION (pfile, traditional)) + buffer = _cpp_copy_replacement_text (macro, buffer); + else if (macro->count) + /* Expansion tokens. */ + { + unsigned int count = macro_real_token_count (macro); + for (i = 0; i < count; i++) + { + const cpp_token *token = ¯o->exp.tokens[i]; + + if (token->flags & PREV_WHITE) + *buffer++ = ' '; + if (token->flags & STRINGIFY_ARG) + *buffer++ = '#'; + + if (token->type == CPP_MACRO_ARG) + { + memcpy (buffer, + NODE_NAME (token->val.macro_arg.spelling), + NODE_LEN (token->val.macro_arg.spelling)); + buffer += NODE_LEN (token->val.macro_arg.spelling); + } + else + buffer = cpp_spell_token (pfile, token, buffer, true); + + if (token->flags & PASTE_LEFT) + { + *buffer++ = ' '; + *buffer++ = '#'; + *buffer++ = '#'; + /* Next has PREV_WHITE; see _cpp_create_definition. */ + } + } + } + + *buffer = '\0'; + return pfile->macro_buffer; +} diff --git a/support/cpp/libcpp/makeucnid.cc b/support/cpp/libcpp/makeucnid.cc new file mode 100644 index 000000000..57c3beb4a --- /dev/null +++ b/support/cpp/libcpp/makeucnid.cc @@ -0,0 +1,525 @@ +/* Make ucnid.h from various sources. + Copyright (C) 2005-2022 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +/* Run this program as + ./makeucnid ucnid.tab UnicodeData.txt DerivedNormalizationProps.txt \ + DerivedCoreProperties.txt > ucnid.h +*/ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <stdbool.h> +#include <stdlib.h> + +enum { + C99 = 1, + CXX = 2, + N99 = 4, + C11 = 8, + N11 = 16, + CXX23 = 32, + NXX23 = 64, + all_languages = C99 | CXX | C11 | CXX23 | NXX23, + not_NFC = 128, + not_NFKC = 256, + maybe_not_NFC = 512 +}; + +#define NUM_CODE_POINTS 0x110000 +#define MAX_CODE_POINT 0x10ffff + +static unsigned flags[NUM_CODE_POINTS]; +static unsigned int all_decomp[NUM_CODE_POINTS][2]; +static unsigned int decomp[NUM_CODE_POINTS][2]; +static unsigned char combining_value[NUM_CODE_POINTS]; + +/* Die! */ + +static void +fail (const char *s) +{ + fprintf (stderr, "%s\n", s); + exit (1); +} + +/* Read ucnid.tab and set the flags for language versions in header[]. */ + +static void +read_ucnid (const char *fname) +{ + FILE *f = fopen (fname, "r"); + unsigned fl = 0; + + if (!f) + fail ("opening ucnid.tab"); + for (;;) + { + char line[256]; + + if (!fgets (line, sizeof (line), f)) + break; + if (strcmp (line, "[C99]\n") == 0) + fl = C99; + else if (strcmp (line, "[C99DIG]\n") == 0) + fl = C99|N99; + else if (strcmp (line, "[CXX]\n") == 0) + fl = CXX; + else if (strcmp (line, "[C11]\n") == 0) + fl = C11; + else if (strcmp (line, "[C11NOSTART]\n") == 0) + fl = C11|N11; + else if (isxdigit (line[0])) + { + char *l = line; + while (*l) + { + unsigned long start, end; + char *endptr; + start = strtoul (l, &endptr, 16); + if (endptr == l || (*endptr != '-' && ! isspace (*endptr))) + fail ("parsing ucnid.tab [1]"); + l = endptr; + if (*l != '-') + end = start; + else + { + end = strtoul (l + 1, &endptr, 16); + if (end < start) + fail ("parsing ucnid.tab, end before start"); + l = endptr; + if (! isspace (*l)) + fail ("parsing ucnid.tab, junk after range"); + } + while (isspace (*l)) + l++; + if (end > MAX_CODE_POINT) + fail ("parsing ucnid.tab, end too large"); + while (start <= end) + flags[start++] |= fl; + } + } + } + if (ferror (f)) + fail ("reading ucnid.tab"); + fclose (f); +} + +/* Read UnicodeData.txt and fill in the 'decomp' table to be the + decompositions of characters for which both the character + decomposed and all the code points in the decomposition are valid + for some supported language version, and the 'all_decomp' table to + be the decompositions of all characters without those + constraints. */ + +static void +read_table (char *fname) +{ + FILE * f = fopen (fname, "r"); + + if (!f) + fail ("opening UnicodeData.txt"); + for (;;) + { + char line[256]; + unsigned long codepoint, this_decomp[4]; + char *l; + int i, j; + int decomp_useful; + + if (!fgets (line, sizeof (line), f)) + break; + codepoint = strtoul (line, &l, 16); + if (l == line || *l != ';') + fail ("parsing UnicodeData.txt, reading code point"); + if (codepoint > MAX_CODE_POINT) + fail ("parsing UnicodeData.txt, code point too large"); + + do { + l++; + } while (*l != ';'); + /* Category value. */ + do { + l++; + } while (*l != ';'); + /* Canonical combining class; in NFC/NFKC, they must be increasing + (or zero). */ + if (! isdigit (*++l)) + fail ("parsing UnicodeData.txt, combining class not number"); + combining_value[codepoint] = strtoul (l, &l, 10); + if (*l++ != ';') + fail ("parsing UnicodeData.txt, junk after combining class"); + + /* Skip over bidi value. */ + do { + l++; + } while (*l != ';'); + + /* Decomposition mapping. */ + decomp_useful = flags[codepoint]; + if (*++l == '<') /* Compatibility mapping. */ + continue; + for (i = 0; i < 4; i++) + { + if (*l == ';') + break; + if (!isxdigit (*l)) + fail ("parsing UnicodeData.txt, decomposition format"); + this_decomp[i] = strtoul (l, &l, 16); + decomp_useful &= flags[this_decomp[i]]; + while (isspace (*l)) + l++; + } + if (i > 2) /* Decomposition too long. */ + fail ("parsing UnicodeData.txt, decomposition too long"); + for (j = 0; j < i; j++) + all_decomp[codepoint][j] = this_decomp[j]; + if ((flags[codepoint] & all_languages) && decomp_useful) + while (--i >= 0) + decomp[codepoint][i] = this_decomp[i]; + } + if (ferror (f)) + fail ("reading UnicodeData.txt"); + fclose (f); +} + +/* Read DerivedNormalizationProps.txt and set the flags that say whether + a character is in NFC, NFKC, or is context-dependent. */ + +static void +read_derived (const char *fname) +{ + FILE * f = fopen (fname, "r"); + + if (!f) + fail ("opening DerivedNormalizationProps.txt"); + for (;;) + { + char line[256]; + unsigned long start, end; + char *l; + bool not_NFC_p, not_NFKC_p, maybe_not_NFC_p; + + if (!fgets (line, sizeof (line), f)) + break; + not_NFC_p = (strstr (line, "; NFC_QC; N") != NULL); + not_NFKC_p = (strstr (line, "; NFKC_QC; N") != NULL); + maybe_not_NFC_p = (strstr (line, "; NFC_QC; M") != NULL); + if (! not_NFC_p && ! not_NFKC_p && ! maybe_not_NFC_p) + continue; + + start = strtoul (line, &l, 16); + if (l == line) + fail ("parsing DerivedNormalizationProps.txt, reading start"); + if (start > MAX_CODE_POINT) + fail ("parsing DerivedNormalizationProps.txt, code point too large"); + if (*l == '.' && l[1] == '.') + end = strtoul (l + 2, &l, 16); + else + end = start; + + while (start <= end) + flags[start++] |= ((not_NFC_p ? not_NFC : 0) + | (not_NFKC_p ? not_NFKC : 0) + | (maybe_not_NFC_p ? maybe_not_NFC : 0) + ); + } + if (ferror (f)) + fail ("reading DerivedNormalizationProps.txt"); + fclose (f); +} + +/* Read DerivedCoreProperties.txt and fill in languages version in + flags from the XID_Start and XID_Continue properties. */ + +static void +read_derivedcore (char *fname) +{ + FILE * f = fopen (fname, "r"); + + if (!f) + fail ("opening DerivedCoreProperties.txt"); + for (;;) + { + char line[256]; + unsigned long codepoint_start, codepoint_end; + char *l; + int i, j; + + if (!fgets (line, sizeof (line), f)) + break; + if (line[0] == '#' || line[0] == '\n' || line[0] == '\r') + continue; + codepoint_start = strtoul (line, &l, 16); + if (l == line) + fail ("parsing DerivedCoreProperties.txt, reading code point"); + if (codepoint_start > MAX_CODE_POINT) + fail ("parsing DerivedCoreProperties.txt, code point too large"); + + if (*l == '.' && l[1] == '.') + { + char *l2 = l + 2; + codepoint_end = strtoul (l + 2, &l, 16); + if (l == l2 || codepoint_end < codepoint_start) + fail ("parsing DerivedCoreProperties.txt, reading code point"); + if (codepoint_end > MAX_CODE_POINT) + fail ("parsing DerivedCoreProperties.txt, code point too large"); + } + else + codepoint_end = codepoint_start; + + while (*l == ' ') + l++; + if (*l++ != ';') + fail ("parsing DerivedCoreProperties.txt, reading code point"); + + while (*l == ' ') + l++; + + if (codepoint_end < 0x80) + continue; + + if (strncmp (l, "XID_Start ", 10) == 0) + { + for (; codepoint_start <= codepoint_end; codepoint_start++) + flags[codepoint_start] + = (flags[codepoint_start] | CXX23) & ~NXX23; + } + else if (strncmp (l, "XID_Continue ", 13) == 0) + { + for (; codepoint_start <= codepoint_end; codepoint_start++) + if ((flags[codepoint_start] & CXX23) == 0) + flags[codepoint_start] |= CXX23 | NXX23; + } + } + if (ferror (f)) + fail ("reading DerivedCoreProperties.txt"); + fclose (f); +} + +/* Write out the table. + The table consists of two words per entry. The first word is the flags + for the unicode code points up to and including the second word. */ + +static void +write_table (void) +{ + unsigned i; + unsigned last_flag = flags[0]; + bool really_safe = decomp[0][0] == 0; + unsigned char last_combine = combining_value[0]; + + printf ("static const struct ucnrange ucnranges[] = {\n"); + + for (i = 1; i <= NUM_CODE_POINTS; i++) + if (i == NUM_CODE_POINTS + || (flags[i] != last_flag && ((flags[i] | last_flag) & all_languages)) + || really_safe != (decomp[i][0] == 0) + || combining_value[i] != last_combine) + { + printf ("{ %s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s, %3d, %#06x },\n", + last_flag & C99 ? "C99" : " 0", + last_flag & N99 ? "N99" : " 0", + last_flag & CXX ? "CXX" : " 0", + last_flag & C11 ? "C11" : " 0", + last_flag & N11 ? "N11" : " 0", + last_flag & CXX23 ? "CXX23" : " 0", + last_flag & NXX23 ? "NXX23" : " 0", + really_safe ? "CID" : " 0", + last_flag & not_NFC ? " 0" : "NFC", + last_flag & not_NFKC ? " 0" : "NKC", + last_flag & maybe_not_NFC ? "CTX" : " 0", + combining_value[i - 1], + i - 1); + last_flag = flags[i]; + last_combine = combining_value[i]; + really_safe = decomp[i][0] == 0; + } + + printf ("};\n"); +} + +/* Return whether a given character is valid in an identifier for some + supported language, either as itself or as a UCN. */ + +static bool +char_id_valid (unsigned int c) +{ + return ((flags[c] & all_languages) + || (c == 0x24) + || (c >= 0x30 && c <= 0x39) + || (c >= 0x41 && c <= 0x5a) + || (c >= 0x61 && c <= 0x7a)); +} + +/* Write out the switch statement over characters for which it is + context-dependent whether they are in NFC. */ + +static void +write_context_switch (void) +{ + unsigned i; + printf ("static bool\n" + "check_nfc (cpp_reader *pfile, cppchar_t c, cppchar_t p)\n" + "{\n" + " switch (c)\n" + " {\n"); + for (i = 0; i < NUM_CODE_POINTS; i++) + { + bool found_case = false; + unsigned j; + if (!(flags[i] & all_languages) || !(flags[i] & maybe_not_NFC)) + continue; + if ((i >= 0x1161 && i <= 0x1175) || (i >= 0x11A8 && i <= 0x11C2)) + continue; /* Hangul handled algorithmically. */ + printf (" case %#06x:\n" + " switch (p)\n" + "\t{\n", i); + /* If an NFC starter character decomposes with this character I + as the second character and an NFC starter character S as the + first character, that latter character as a previous + character means this character is not NFC. Furthermore, any + NFC starter character K made by a series of compositions of S + with combining characters whose combining class is greater + than that of I also means this character is not NFC. */ + for (j = 0; j < NUM_CODE_POINTS; j++) + { + unsigned s, k; + if (all_decomp[j][1] != i) + continue; + s = all_decomp[j][0]; + if (combining_value[s] != 0 || (flags[s] & not_NFC) != 0) + continue; + if (char_id_valid (s)) + { + found_case = true; + printf ("\tcase %#06x:\n", s); + } + for (k = 0; k < NUM_CODE_POINTS; k++) + { + unsigned t = k; + if (k == s || !char_id_valid (k)) + continue; + while (all_decomp[t][1] != 0 + && combining_value[all_decomp[t][1]] > combining_value[i]) + { + if (combining_value[t] != 0 || (flags[t] & not_NFC) != 0) + break; + t = all_decomp[t][0]; + } + if (t == s) + { + found_case = true; + printf ("\tcase %#06x:\n", k); + } + } + } + if (found_case) + printf ("\t return false;\n"); + else + printf ("\t/* Non-NFC cases not applicable to C/C++. */\n"); + printf ("\tdefault:\n" + "\t return true;\n" + "\t}\n\n"); + } + printf (" default:\n" + " cpp_error (pfile, CPP_DL_ICE, \"Character %%x might not be NFKC\", c);\n" + " return true;\n" + " }\n" + "}\n"); +} + +/* Print out the huge copyright notice. */ + +static void +write_copyright (void) +{ + static const char copyright[] = "\ +/* Unicode characters and various properties.\n\ + Copyright (C) 2003-2022 Free Software Foundation, Inc.\n\ +\n\ + This program is free software; you can redistribute it and/or modify it\n\ + under the terms of the GNU General Public License as published by the\n\ + Free Software Foundation; either version 3, or (at your option) any\n\ + later version.\n\ +\n\ + This program is distributed in the hope that it will be useful,\n\ + but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ + GNU General Public License for more details.\n\ +\n\ + You should have received a copy of the GNU General Public License\n\ + along with this program; see the file COPYING3. If not see\n\ + <http://www.gnu.org/licenses/>.\n\ +\n\ +\n\ + Copyright (C) 1991-2005 Unicode, Inc. All rights reserved.\n\ + Distributed under the Terms of Use in\n\ + http://www.unicode.org/copyright.html.\n\ +\n\ + Permission is hereby granted, free of charge, to any person\n\ + obtaining a copy of the Unicode data files and any associated\n\ + documentation (the \"Data Files\") or Unicode software and any\n\ + associated documentation (the \"Software\") to deal in the Data Files\n\ + or Software without restriction, including without limitation the\n\ + rights to use, copy, modify, merge, publish, distribute, and/or\n\ + sell copies of the Data Files or Software, and to permit persons to\n\ + whom the Data Files or Software are furnished to do so, provided\n\ + that (a) the above copyright notice(s) and this permission notice\n\ + appear with all copies of the Data Files or Software, (b) both the\n\ + above copyright notice(s) and this permission notice appear in\n\ + associated documentation, and (c) there is clear notice in each\n\ + modified Data File or in the Software as well as in the\n\ + documentation associated with the Data File(s) or Software that the\n\ + data or software has been modified.\n\ +\n\ + THE DATA FILES AND SOFTWARE ARE PROVIDED \"AS IS\", WITHOUT WARRANTY\n\ + OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n\ + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n\ + NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE\n\ + COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR\n\ + ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY\n\ + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,\n\ + WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\n\ + ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE\n\ + OF THE DATA FILES OR SOFTWARE.\n\ +\n\ + Except as contained in this notice, the name of a copyright holder\n\ + shall not be used in advertising or otherwise to promote the sale,\n\ + use or other dealings in these Data Files or Software without prior\n\ + written authorization of the copyright holder. */\n"; + + puts (copyright); +} + +/* Main program. */ + +int +main(int argc, char ** argv) +{ + if (argc != 5) + fail ("too few arguments to makeucn"); + read_ucnid (argv[1]); + read_table (argv[2]); + read_derived (argv[3]); + read_derivedcore (argv[4]); + + write_copyright (); + write_table (); + write_context_switch (); + return 0; +} diff --git a/support/cpp/libcpp/md5.h b/support/cpp/libcpp/md5.h new file mode 100644 index 000000000..b823943da --- /dev/null +++ b/support/cpp/libcpp/md5.h @@ -0,0 +1,154 @@ +/* md5.h - Declaration of functions and data types used for MD5 sum + computing library functions. + Copyright 1995, 1996, 2000 Free Software Foundation, Inc. + NOTE: The canonical source of this file is maintained with the GNU C + Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _MD5_H +#define _MD5_H 1 + +#include <stdio.h> + +#if defined HAVE_LIMITS_H || _LIBC +# include <limits.h> +#endif + +#include "ansidecl.h" + +/* The following contortions are an attempt to use the C preprocessor + to determine an unsigned integral type that is 32 bits wide. An + alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but + doing that would require that the configure script compile and *run* + the resulting executable. Locally running cross-compiled executables + is usually not possible. */ + +#ifdef _LIBC +# include <sys/types.h> +typedef u_int32_t md5_uint32; +typedef uintptr_t md5_uintptr; +#else +# define INT_MAX_32_BITS 2147483647 + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + This should be valid for all systems GNU cares about because + that doesn't include 16-bit systems, and only modern systems + (that certainly have <limits.h>) have 64+-bit integral types. */ + +# ifndef INT_MAX +# define INT_MAX INT_MAX_32_BITS +# endif + +# if INT_MAX == INT_MAX_32_BITS + typedef unsigned int md5_uint32; +# else +# if SHRT_MAX == INT_MAX_32_BITS + typedef unsigned short md5_uint32; +# else +# if LONG_MAX == INT_MAX_32_BITS + typedef unsigned long md5_uint32; +# else + /* The following line is intended to evoke an error. + Using #error is not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +# endif +# ifdef _WIN32 +# include <stdint.h> + typedef uintptr_t md5_uintptr; +# else + /* We have to make a guess about the integer type equivalent in size + to pointers which should always be correct. */ + typedef unsigned long int md5_uintptr; +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure to save state of computation between the single steps. */ +struct md5_ctx +{ + md5_uint32 A; + md5_uint32 B; + md5_uint32 C; + md5_uint32 D; + + md5_uint32 total[2]; + md5_uint32 buflen; + char buffer[128] ATTRIBUTE_ALIGNED_ALIGNOF(md5_uint32); +}; + +/* + * The following three functions are build up the low level used in + * the functions `md5_stream' and `md5_buffer'. + */ + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +extern void md5_init_ctx (struct md5_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void md5_process_block (const void *buffer, size_t len, + struct md5_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void md5_process_bytes (const void *buffer, size_t len, + struct md5_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *md5_finish_ctx (struct md5_ctx *ctx, void *resbuf); + + +/* Put result from CTX in first 16 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *md5_read_ctx (const struct md5_ctx *ctx, void *resbuf); + + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int md5_stream (FILE *stream, void *resblock); + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *md5_buffer (const char *buffer, size_t len, void *resblock); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/support/cpp/libcpp/mkdeps.c b/support/cpp/libcpp/mkdeps.c deleted file mode 100644 index 144f0d1f5..000000000 --- a/support/cpp/libcpp/mkdeps.c +++ /dev/null @@ -1,447 +0,0 @@ -/* Dependency generator for Makefile fragments. - Copyright (C) 2000, 2001, 2003, 2007, 2008, 2009 - Free Software Foundation, Inc. - Contributed by Zack Weinberg, Mar 2000 - -This program is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 3, or (at your option) any -later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; see the file COPYING3. If not see -<http://www.gnu.org/licenses/>. - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -#include "config.h" -#include "system.h" -#include "mkdeps.h" -#include "internal.h" - -/* Keep this structure local to this file, so clients don't find it - easy to start making assumptions. */ -struct deps -{ - const char **targetv; - unsigned int ntargets; /* number of slots actually occupied */ - unsigned int targets_size; /* amt of allocated space - in words */ - - const char **depv; - unsigned int ndeps; - unsigned int deps_size; - - const char **vpathv; - size_t *vpathlv; - unsigned int nvpaths; - unsigned int vpaths_size; -}; - -static const char *munge (const char *); - -/* Given a filename, quote characters in that filename which are - significant to Make. Note that it's not possible to quote all such - characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are - not properly handled. It isn't possible to get this right in any - current version of Make. (??? Still true? Old comment referred to - 3.76.1.) */ - -static const char * -munge (const char *filename) -{ - int len; - const char *p, *q; - char *dst, *buffer; - - for (p = filename, len = 0; *p; p++, len++) - { - switch (*p) - { - case ' ': - case '\t': - /* GNU make uses a weird quoting scheme for white space. - A space or tab preceded by 2N+1 backslashes represents - N backslashes followed by space; a space or tab - preceded by 2N backslashes represents N backslashes at - the end of a file name; and backslashes in other - contexts should not be doubled. */ - for (q = p - 1; filename <= q && *q == '\\'; q--) - len++; - len++; - break; - - case '$': - /* '$' is quoted by doubling it. */ - len++; - break; - - case '#': - /* '#' is quoted with a backslash. */ - len++; - break; - } - } - - /* Now we know how big to make the buffer. */ - buffer = XNEWVEC (char, len + 1); - - for (p = filename, dst = buffer; *p; p++, dst++) - { - switch (*p) - { - case ' ': - case '\t': - for (q = p - 1; filename <= q && *q == '\\'; q--) - *dst++ = '\\'; - *dst++ = '\\'; - break; - - case '$': - *dst++ = '$'; - break; - - case '#': - *dst++ = '\\'; - break; - - default: - /* nothing */; - } - *dst = *p; - } - - *dst = '\0'; - return buffer; -} - -/* If T begins with any of the partial pathnames listed in d->vpathv, - then advance T to point beyond that pathname. */ -static const char * -apply_vpath (struct deps *d, const char *t) -{ - if (d->vpathv) - { - unsigned int i; - for (i = 0; i < d->nvpaths; i++) - { - if (!strncmp (d->vpathv[i], t, d->vpathlv[i])) - { - const char *p = t + d->vpathlv[i]; - if (!IS_DIR_SEPARATOR (*p)) - goto not_this_one; - - /* Do not simplify $(vpath)/../whatever. ??? Might not - be necessary. */ - if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3])) - goto not_this_one; - - /* found a match */ - t = t + d->vpathlv[i] + 1; - break; - } - not_this_one:; - } - } - - /* Remove leading ./ in any case. */ - while (t[0] == '.' && IS_DIR_SEPARATOR (t[1])) - { - t += 2; - /* If we removed a leading ./, then also remove any /s after the - first. */ - while (IS_DIR_SEPARATOR (t[0])) - ++t; - } - - return t; -} - -/* Public routines. */ - -struct deps * -deps_init (void) -{ - return XCNEW (struct deps); -} - -void -deps_free (struct deps *d) -{ - unsigned int i; - - if (d->targetv) - { - for (i = 0; i < d->ntargets; i++) - free ((void *) d->targetv[i]); - free (d->targetv); - } - - if (d->depv) - { - for (i = 0; i < d->ndeps; i++) - free ((void *) d->depv[i]); - free (d->depv); - } - - if (d->vpathv) - { - for (i = 0; i < d->nvpaths; i++) - free ((void *) d->vpathv[i]); - free (d->vpathv); - free (d->vpathlv); - } - - free (d); -} - -/* Adds a target T. We make a copy, so it need not be a permanent - string. QUOTE is true if the string should be quoted. */ -void -deps_add_target (struct deps *d, const char *t, int quote) -{ - if (d->ntargets == d->targets_size) - { - d->targets_size = d->targets_size * 2 + 4; - d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size); - } - - t = apply_vpath (d, t); - if (quote) - t = munge (t); /* Also makes permanent copy. */ - else - t = xstrdup (t); - - d->targetv[d->ntargets++] = t; -} - -/* Sets the default target if none has been given already. An empty - string as the default target in interpreted as stdin. The string - is quoted for MAKE. */ -void -deps_add_default_target (cpp_reader *pfile, const char *tgt) -{ - struct deps *d = pfile->deps; - - /* Only if we have no targets. */ - if (d->ntargets) - return; - - if (tgt[0] == '\0') - deps_add_target (d, "-", 1); - else - { -#ifndef TARGET_OBJECT_SUFFIX -# define TARGET_OBJECT_SUFFIX ".o" -#endif - const char *start = lbasename (tgt); - char *o; - - char *suffix; - const char *obj_ext; - - if (NULL == CPP_OPTION (pfile, obj_ext)) - obj_ext = TARGET_OBJECT_SUFFIX; - else if (CPP_OPTION (pfile, obj_ext)[0] != '.') - { - char *t = alloca (strlen (CPP_OPTION (pfile, obj_ext)) + 2); - t[0] = '.'; - strcpy (&t[1], CPP_OPTION (pfile, obj_ext)); - obj_ext = t; - } - else - obj_ext = CPP_OPTION (pfile, obj_ext); - - o = (char *) alloca (strlen (start) + strlen (obj_ext) + 1); - strcpy (o, start); - - suffix = strrchr (o, '.'); - if (!suffix) - suffix = o + strlen (o); - strcpy (suffix, obj_ext); - - deps_add_target (d, o, 1); - } -} - -void -deps_add_dep (struct deps *d, const char *t) -{ - t = munge (apply_vpath (d, t)); /* Also makes permanent copy. */ - - if (d->ndeps == d->deps_size) - { - d->deps_size = d->deps_size * 2 + 8; - d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size); - } - d->depv[d->ndeps++] = t; -} - -void -deps_add_vpath (struct deps *d, const char *vpath) -{ - const char *elem, *p; - char *copy; - size_t len; - - for (elem = vpath; *elem; elem = p) - { - for (p = elem; *p && *p != ':'; p++); - len = p - elem; - copy = XNEWVEC (char, len + 1); - memcpy (copy, elem, len); - copy[len] = '\0'; - if (*p == ':') - p++; - - if (d->nvpaths == d->vpaths_size) - { - d->vpaths_size = d->vpaths_size * 2 + 8; - d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size); - d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size); - } - d->vpathv[d->nvpaths] = copy; - d->vpathlv[d->nvpaths] = len; - d->nvpaths++; - } -} - -void -deps_write (const struct deps *d, FILE *fp, unsigned int colmax) -{ - unsigned int size, i, column; - - column = 0; - if (colmax && colmax < 34) - colmax = 34; - - for (i = 0; i < d->ntargets; i++) - { - size = strlen (d->targetv[i]); - column += size; - if (i) - { - if (colmax && column > colmax) - { - fputs (" \\\n ", fp); - column = 1 + size; - } - else - { - putc (' ', fp); - column++; - } - } - fputs (d->targetv[i], fp); - } - - putc (':', fp); - column++; - - for (i = 0; i < d->ndeps; i++) - { - size = strlen (d->depv[i]); - column += size; - if (colmax && column > colmax) - { - fputs (" \\\n ", fp); - column = 1 + size; - } - else - { - putc (' ', fp); - column++; - } - fputs (d->depv[i], fp); - } - putc ('\n', fp); -} - -void -deps_phony_targets (const struct deps *d, FILE *fp) -{ - unsigned int i; - - for (i = 1; i < d->ndeps; i++) - { - putc ('\n', fp); - fputs (d->depv[i], fp); - putc (':', fp); - putc ('\n', fp); - } -} - -/* Write out a deps buffer to a file, in a form that can be read back - with deps_restore. Returns nonzero on error, in which case the - error number will be in errno. */ - -int -deps_save (struct deps *deps, FILE *f) -{ - unsigned int i; - - /* The cppreader structure contains makefile dependences. Write out this - structure. */ - - /* The number of dependences. */ - if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1) - return -1; - /* The length of each dependence followed by the string. */ - for (i = 0; i < deps->ndeps; i++) - { - size_t num_to_write = strlen (deps->depv[i]); - if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1) - return -1; - if (fwrite (deps->depv[i], num_to_write, 1, f) != 1) - return -1; - } - - return 0; -} - -/* Read back dependency information written with deps_save into - the deps buffer. The third argument may be NULL, in which case - the dependency information is just skipped, or it may be a filename, - in which case that filename is skipped. */ - -int -deps_restore (struct deps *deps, FILE *fd, const char *self) -{ - unsigned int i, count; - size_t num_to_read; - size_t buf_size = 512; - char *buf = XNEWVEC (char, buf_size); - - /* Number of dependences. */ - if (fread (&count, 1, sizeof (count), fd) != sizeof (count)) - return -1; - - /* The length of each dependence string, followed by the string. */ - for (i = 0; i < count; i++) - { - /* Read in # bytes in string. */ - if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t)) - return -1; - if (buf_size < num_to_read + 1) - { - buf_size = num_to_read + 1 + 127; - buf = XRESIZEVEC (char, buf, buf_size); - } - if (fread (buf, 1, num_to_read, fd) != num_to_read) - return -1; - buf[num_to_read] = '\0'; - - /* Generate makefile dependencies from .pch if -nopch-deps. */ - if (self != NULL && strcmp (buf, self) != 0) - deps_add_dep (deps, buf); - } - - free (buf); - return 0; -} diff --git a/support/cpp/libcpp/mkdeps.cc b/support/cpp/libcpp/mkdeps.cc new file mode 100644 index 000000000..226a4811d --- /dev/null +++ b/support/cpp/libcpp/mkdeps.cc @@ -0,0 +1,578 @@ +/* Dependency generator for Makefile fragments. + Copyright (C) 2000-2022 Free Software Foundation, Inc. + Contributed by Zack Weinberg, Mar 2000 + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! */ + +#include <iostream> +#define untested() ( std::cerr << "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \ + <<":" << __func__ << "\n" ) + +#include "config.h" +#include "system.h" +#include "mkdeps.h" +#include "internal.h" + +/* Not set up to just include std::vector et al, here's a simple + implementation. */ + +/* Keep this structure local to this file, so clients don't find it + easy to start making assumptions. */ +class mkdeps +{ +public: + /* T has trivial cctor & dtor. */ + template <typename T> + class vec + { + private: + T *ary; + unsigned num; + unsigned alloc; + + public: + vec () + : ary (NULL), num (0), alloc (0) + {} + ~vec () + { + XDELETEVEC (ary); + } + + public: + unsigned size () const + { + return num; + } + const T &operator[] (unsigned ix) const + { + return ary[ix]; + } + T &operator[] (unsigned ix) + { + return ary[ix]; + } + void push (const T &elt) + { + if (num == alloc) + { + alloc = alloc ? alloc * 2 : 16; + ary = XRESIZEVEC (T, ary, alloc); + } + ary[num++] = elt; + } + }; + struct velt + { + const char *str; + size_t len; + }; + + mkdeps () + : module_name (NULL), cmi_name (NULL), is_header_unit (false), quote_lwm (0) + { + } + ~mkdeps () + { + unsigned int i; + + for (i = targets.size (); i--;) + free (const_cast <char *> (targets[i])); + for (i = deps.size (); i--;) + free (const_cast <char *> (deps[i])); + for (i = vpath.size (); i--;) + XDELETEVEC (vpath[i].str); + for (i = modules.size (); i--;) + XDELETEVEC (modules[i]); + XDELETEVEC (module_name); + free (const_cast <char *> (cmi_name)); + } + +public: + vec<const char *> targets; + vec<const char *> deps; + vec<velt> vpath; + vec<const char *> modules; + +public: + const char *module_name; + const char *cmi_name; + bool is_header_unit; + unsigned short quote_lwm; +}; + +/* Apply Make quoting to STR, TRAIL. Note that it's not possible to + quote all such characters - e.g. \n, %, *, ?, [, \ (in some + contexts), and ~ are not properly handled. It isn't possible to + get this right in any current version of Make. (??? Still true? + Old comment referred to 3.76.1.) */ + +static const char * +munge (const char *str, const char *trail = nullptr) +{ + static unsigned alloc; + static char *buf; + unsigned dst = 0; + + for (; str; str = trail, trail = nullptr) + { + unsigned slashes = 0; + char c; + for (const char *probe = str; (c = *probe++);) + { + if (alloc < dst + 4 + slashes) + { + alloc = alloc * 2 + 32; + buf = XRESIZEVEC (char, buf, alloc); + } + + switch (c) + { + case '\\': + slashes++; + break; + + case '$': + buf[dst++] = '$'; + goto def; + + case ' ': + case '\t': + /* GNU make uses a weird quoting scheme for white space. + A space or tab preceded by 2N+1 backslashes + represents N backslashes followed by space; a space + or tab preceded by 2N backslashes represents N + backslashes at the end of a file name; and + backslashes in other contexts should not be + doubled. */ + while (slashes--) + buf[dst++] = '\\'; + /* FALLTHROUGH */ + + case '#': + buf[dst++] = '\\'; + /* FALLTHROUGH */ + + default: + def: + slashes = 0; + break; + } + + buf[dst++] = c; + } + } + + buf[dst] = 0; + return buf; +} + +/* If T begins with any of the partial pathnames listed in d->vpathv, + then advance T to point beyond that pathname. */ +static const char * +apply_vpath (class mkdeps *d, const char *t) +{ + if (unsigned len = d->vpath.size ()) + for (unsigned i = len; i--;) + { + if (!filename_ncmp (d->vpath[i].str, t, d->vpath[i].len)) + { + const char *p = t + d->vpath[i].len; + if (!IS_DIR_SEPARATOR (*p)) + goto not_this_one; + + /* Do not simplify $(vpath)/../whatever. ??? Might not + be necessary. */ + if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3])) + goto not_this_one; + + /* found a match */ + t = t + d->vpath[i].len + 1; + break; + } + not_this_one:; + } + + /* Remove leading ./ in any case. */ + while (t[0] == '.' && IS_DIR_SEPARATOR (t[1])) + { + t += 2; + /* If we removed a leading ./, then also remove any /s after the + first. */ + while (IS_DIR_SEPARATOR (t[0])) + ++t; + } + + return t; +} + +/* Public routines. */ + +class mkdeps * +deps_init (void) +{ + return new mkdeps (); +} + +void +deps_free (class mkdeps *d) +{ + delete d; +} + +/* Adds a target T. We make a copy, so it need not be a permanent + string. QUOTE is true if the string should be quoted. */ +void +deps_add_target (class mkdeps *d, const char *t, int quote) +{ + t = xstrdup (apply_vpath (d, t)); + + if (!quote) + { + /* Sometimes unquoted items are added after quoted ones. + Swap out the lowest quoted. */ + if (d->quote_lwm != d->targets.size ()) + { + const char *lowest = d->targets[d->quote_lwm]; + d->targets[d->quote_lwm] = t; + t = lowest; + } + d->quote_lwm++; + } + + d->targets.push (t); +} + +/* Sets the default target if none has been given already. An empty + string as the default target in interpreted as stdin. The string + is quoted for MAKE. */ +void +deps_add_default_target (const class cpp_reader *pfile, class mkdeps *d, const char *tgt) +{ + /* Only if we have no targets. */ + if (d->targets.size ()) + return; + + if (tgt[0] == '\0') + { untested(); + d->targets.push (xstrdup ("-")); + } + else + { +#ifndef TARGET_OBJECT_SUFFIX +# define TARGET_OBJECT_SUFFIX ".o" +#endif + const char *start = lbasename (tgt); + + char *suffix; + const char *obj_ext; + + if (NULL == CPP_OPTION (pfile, obj_ext)) + { + obj_ext = TARGET_OBJECT_SUFFIX; + } + else if (CPP_OPTION (pfile, obj_ext)[0] != '.') + { untested(); + char *t = (char*) alloca (strlen (CPP_OPTION (pfile, obj_ext)) + 2); + t[0] = '.'; + strcpy (&t[1], CPP_OPTION (pfile, obj_ext)); + obj_ext = t; + } + else + { + obj_ext = CPP_OPTION (pfile, obj_ext); + } + + // if obj_ext != ".o": + // fprintf(stderr, "custom objext %s, deprecate this?\n", obj_ext); + + char *o = (char *) alloca (strlen (start) + strlen (obj_ext) + 1); + + strcpy (o, start); + + suffix = strrchr (o, '.'); + if (!suffix){ untested(); + suffix = o + strlen (o); + }else{ + } + strcpy (suffix, obj_ext); + + deps_add_target (d, o, 1); + } +} + +void +deps_add_dep (class mkdeps *d, const char *t) +{ + gcc_assert (*t); + + t = apply_vpath (d, t); + + d->deps.push (xstrdup (t)); +} + +void +deps_add_vpath (class mkdeps *d, const char *vpath) +{ + const char *elem, *p; + + for (elem = vpath; *elem; elem = p) + { + for (p = elem; *p && *p != ':'; p++) + continue; + mkdeps::velt elt; + elt.len = p - elem; + char *str = XNEWVEC (char, elt.len + 1); + elt.str = str; + memcpy (str, elem, elt.len); + str[elt.len] = '\0'; + if (*p == ':') + p++; + + d->vpath.push (elt); + } +} + +/* Add a new module target (there can only be one). M is the module + name. */ + +void +deps_add_module_target (struct mkdeps *d, const char *m, + const char *cmi, bool is_header_unit) +{ + gcc_assert (!d->module_name); + + d->module_name = xstrdup (m); + d->is_header_unit = is_header_unit; + d->cmi_name = xstrdup (cmi); +} + +/* Add a new module dependency. M is the module name. */ + +void +deps_add_module_dep (struct mkdeps *d, const char *m) +{ + d->modules.push (xstrdup (m)); +} + +/* Write NAME, with a leading space to FP, a Makefile. Advance COL as + appropriate, wrap at COLMAX, returning new column number. Iff + QUOTE apply quoting. Append TRAIL. */ + +static unsigned +make_write_name (const char *name, FILE *fp, unsigned col, unsigned colmax, + bool quote = true, const char *trail = NULL) +{ + if (quote) + name = munge (name, trail); + unsigned size = strlen (name); + + if (col) + { + if (colmax && col + size> colmax) + { + fputs (" \\\n", fp); + col = 0; + } + col++; + fputs (" ", fp); + } + + col += size; + fputs (name, fp); + + return col; +} + +/* Write all the names in VEC via make_write_name. */ + +static unsigned +make_write_vec (const mkdeps::vec<const char *> &vec, FILE *fp, + unsigned col, unsigned colmax, unsigned quote_lwm = 0, + const char *trail = NULL) +{ + for (unsigned ix = 0; ix != vec.size (); ix++) + col = make_write_name (vec[ix], fp, col, colmax, ix >= quote_lwm, trail); + return col; +} + +/* Write the dependencies to a Makefile. If PHONY is true, add + .PHONY targets for all the dependencies too. */ + +static void +make_write (const cpp_reader *pfile, FILE *fp, unsigned int colmax) +{ + const mkdeps *d = pfile->deps; + + unsigned column = 0; + if (colmax && colmax < 34) + colmax = 34; + + if (d->deps.size ()) + { + column = make_write_vec (d->targets, fp, 0, colmax, d->quote_lwm); + if (CPP_OPTION (pfile, deps.modules) && d->cmi_name) + column = make_write_name (d->cmi_name, fp, column, colmax); + fputs (":", fp); + column++; + make_write_vec (d->deps, fp, column, colmax); + fputs ("\n", fp); + if (CPP_OPTION (pfile, deps.phony_targets)) + for (unsigned i = 1; i < d->deps.size (); i++) + fprintf (fp, "%s:\n", munge (d->deps[i])); + } + + if (!CPP_OPTION (pfile, deps.modules)) + return; + + if (d->modules.size ()) + { + column = make_write_vec (d->targets, fp, 0, colmax, d->quote_lwm); + if (d->cmi_name) + column = make_write_name (d->cmi_name, fp, column, colmax); + fputs (":", fp); + column++; + column = make_write_vec (d->modules, fp, column, colmax, 0, ".c++m"); + fputs ("\n", fp); + } + + if (d->module_name) + { + if (d->cmi_name) + { + /* module-name : cmi-name */ + column = make_write_name (d->module_name, fp, 0, colmax, + true, ".c++m"); + fputs (":", fp); + column++; + column = make_write_name (d->cmi_name, fp, column, colmax); + fputs ("\n", fp); + + column = fprintf (fp, ".PHONY:"); + column = make_write_name (d->module_name, fp, column, colmax, + true, ".c++m"); + fputs ("\n", fp); + } + + if (d->cmi_name && !d->is_header_unit) + { + /* An order-only dependency. + cmi-name :| first-target + We can probably drop this this in favour of Make-4.3's grouped + targets '&:' */ + column = make_write_name (d->cmi_name, fp, 0, colmax); + fputs (":|", fp); + column++; + column = make_write_name (d->targets[0], fp, column, colmax); + fputs ("\n", fp); + } + } + + if (d->modules.size ()) + { + column = fprintf (fp, "CXX_IMPORTS +="); + make_write_vec (d->modules, fp, column, colmax, 0, ".c++m"); + fputs ("\n", fp); + } +} + +/* Write out dependencies according to the selected format (which is + only Make at the moment). */ +/* Really we should be opening fp here. */ + +void +deps_write (const cpp_reader *pfile, FILE *fp, unsigned int colmax) +{ + make_write (pfile, fp, colmax); +} + +/* Write out a deps buffer to a file, in a form that can be read back + with deps_restore. Returns nonzero on error, in which case the + error number will be in errno. */ + +int +deps_save (class mkdeps *deps, FILE *f) +{ + unsigned int i; + size_t size; + + /* The cppreader structure contains makefile dependences. Write out this + structure. */ + + /* The number of dependences. */ + size = deps->deps.size (); + if (fwrite (&size, sizeof (size), 1, f) != 1) + return -1; + + /* The length of each dependence followed by the string. */ + for (i = 0; i < deps->deps.size (); i++) + { + size = strlen (deps->deps[i]); + if (fwrite (&size, sizeof (size), 1, f) != 1) + return -1; + if (fwrite (deps->deps[i], size, 1, f) != 1) + return -1; + } + + return 0; +} + +/* Read back dependency information written with deps_save into + the deps sizefer. The third argument may be NULL, in which case + the dependency information is just skipped, or it may be a filename, + in which case that filename is skipped. */ + +int +deps_restore (class mkdeps *deps, FILE *fd, const char *self) +{ + size_t size; + char *buf = NULL; + size_t buf_size = 0; + + /* Number of dependences. */ + if (fread (&size, sizeof (size), 1, fd) != 1) + return -1; + + /* The length of each dependence string, followed by the string. */ + for (unsigned i = size; i--;) + { + /* Read in # bytes in string. */ + if (fread (&size, sizeof (size), 1, fd) != 1) + return -1; + + if (size >= buf_size) + { + buf_size = size + 512; + buf = XRESIZEVEC (char, buf, buf_size); + } + if (fread (buf, 1, size, fd) != size) + { + XDELETEVEC (buf); + return -1; + } + buf[size] = 0; + + /* Generate makefile dependencies from .pch if -nopch-deps. */ + if (self != NULL && filename_cmp (buf, self) != 0) + deps_add_dep (deps, buf); + } + + XDELETEVEC (buf); + return 0; +} diff --git a/support/cpp/libcpp/pch.cc b/support/cpp/libcpp/pch.cc new file mode 100644 index 000000000..9aa589a04 --- /dev/null +++ b/support/cpp/libcpp/pch.cc @@ -0,0 +1,878 @@ +/* Part of CPP library. (Precompiled header reading/writing.) + Copyright (C) 2000-2022 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "cpplib.h" +#include "internal.h" +#include "hashtab.h" +#include "mkdeps.h" + +static int write_macdef (cpp_reader *, cpp_hashnode *, void *); +static int save_idents (cpp_reader *, cpp_hashnode *, void *); +static hashval_t hashmem (const void *, size_t); +static hashval_t cpp_string_hash (const void *); +static int cpp_string_eq (const void *, const void *); +static int count_defs (cpp_reader *, cpp_hashnode *, void *); +static int comp_hashnodes (const void *, const void *); +static int collect_ht_nodes (cpp_reader *, cpp_hashnode *, void *); +static int write_defs (cpp_reader *, cpp_hashnode *, void *); +static int save_macros (cpp_reader *, cpp_hashnode *, void *); +static int _cpp_save_pushed_macros (cpp_reader *, FILE *); +static int _cpp_restore_pushed_macros (cpp_reader *, FILE *); + +/* This structure represents a macro definition on disk. */ +struct macrodef_struct +{ + unsigned int definition_length; + unsigned short name_length; + unsigned short flags; +}; + +/* This is how we write out a macro definition. + Suitable for being called by cpp_forall_identifiers. */ + +static int +write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) +{ + FILE *f = (FILE *) file_p; + bool is_void = false; + switch (hn->type) + { + case NT_VOID: + if (! (hn->flags & NODE_POISONED)) + return 1; + is_void = true; + goto poisoned; + + case NT_BUILTIN_MACRO: + return 1; + + case NT_USER_MACRO: + if (hn->value.macro->kind != cmk_assert) + { + poisoned: + struct macrodef_struct s; + const unsigned char *defn; + + s.name_length = NODE_LEN (hn); + s.flags = hn->flags & NODE_POISONED; + + if (is_void) + { + defn = NODE_NAME (hn); + s.definition_length = s.name_length; + } + else + { + defn = cpp_macro_definition (pfile, hn); + s.definition_length = ustrlen (defn); + } + + if (fwrite (&s, sizeof (s), 1, f) != 1 + || fwrite (defn, 1, s.definition_length, f) != s.definition_length) + { + cpp_errno (pfile, CPP_DL_ERROR, + "while writing precompiled header"); + return 0; + } + } + return 1; + + default: + abort (); + } +} + +/* This structure records the names of the defined macros. + It's also used as a callback structure for size_initial_idents + and save_idents. */ + +struct cpp_savedstate +{ + /* A hash table of the defined identifiers. */ + htab_t definedhash; + /* The size of the definitions of those identifiers (the size of + 'definedstrs'). */ + size_t hashsize; + /* Number of definitions */ + size_t n_defs; + /* Array of definitions. In cpp_write_pch_deps it is used for sorting. */ + cpp_hashnode **defs; + /* Space for the next definition. Definitions are null-terminated + strings. */ + unsigned char *definedstrs; +}; + +/* Save this identifier into the state: put it in the hash table, + put the definition in 'definedstrs'. */ + +static int +save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) +{ + struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; + + if (hn->type != NT_VOID) + { + struct cpp_string news; + void **slot; + + news.len = NODE_LEN (hn); + news.text= NODE_NAME (hn); + slot = htab_find_slot (ss->definedhash, &news, INSERT); + if (*slot == NULL) + { + struct cpp_string *sp; + unsigned char *text; + + sp = XNEW (struct cpp_string); + *slot = sp; + + sp->len = NODE_LEN (hn); + sp->text = text = XNEWVEC (unsigned char, NODE_LEN (hn)); + memcpy (text, NODE_NAME (hn), NODE_LEN (hn)); + } + } + + return 1; +} + +/* Hash some memory in a generic way. */ + +static hashval_t +hashmem (const void *p_p, size_t sz) +{ + const unsigned char *p = (const unsigned char *)p_p; + size_t i; + hashval_t h; + + h = 0; + for (i = 0; i < sz; i++) + h = h * 67 - (*p++ - 113); + return h; +} + +/* Hash a cpp string for the hashtable machinery. */ + +static hashval_t +cpp_string_hash (const void *a_p) +{ + const struct cpp_string *a = (const struct cpp_string *) a_p; + return hashmem (a->text, a->len); +} + +/* Compare two cpp strings for the hashtable machinery. */ + +static int +cpp_string_eq (const void *a_p, const void *b_p) +{ + const struct cpp_string *a = (const struct cpp_string *) a_p; + const struct cpp_string *b = (const struct cpp_string *) b_p; + return (a->len == b->len + && memcmp (a->text, b->text, a->len) == 0); +} + +/* Free memory associated with cpp_string. */ + +static void +cpp_string_free (void *a_p) +{ + struct cpp_string *a = (struct cpp_string *) a_p; + free ((void *) a->text); + free (a); +} + +/* Save the current definitions of the cpp_reader for dependency + checking purposes. When writing a precompiled header, this should + be called at the same point in the compilation as cpp_valid_state + would be called when reading the precompiled header back in. */ + +int +cpp_save_state (cpp_reader *r, FILE *f) +{ + /* Save the list of non-void identifiers for the dependency checking. */ + r->savedstate = XNEW (struct cpp_savedstate); + r->savedstate->definedhash = htab_create (100, cpp_string_hash, + cpp_string_eq, cpp_string_free); + cpp_forall_identifiers (r, save_idents, r->savedstate); + + /* Write out the list of defined identifiers. */ + cpp_forall_identifiers (r, write_macdef, f); + + return 0; +} + +/* Calculate the 'hashsize' field of the saved state. */ + +static int +count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) +{ + struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; + + switch (hn->type) + { + case NT_BUILTIN_MACRO: + return 1; + + case NT_USER_MACRO: + if (hn->value.macro->kind == cmk_assert) + return 1; + + /* fall through. */ + + case NT_VOID: + { + struct cpp_string news; + void **slot; + + news.len = NODE_LEN (hn); + news.text = NODE_NAME (hn); + slot = (void **) htab_find (ss->definedhash, &news); + if (slot == NULL) + { + ss->hashsize += NODE_LEN (hn) + 1; + ss->n_defs += 1; + } + } + return 1; + + default: + abort (); + } +} + +/* Collect the identifiers into the state's string table. */ +static int +write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p) +{ + struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p; + + switch (hn->type) + { + case NT_BUILTIN_MACRO: + return 1; + + case NT_USER_MACRO: + if (hn->value.macro->kind == cmk_assert) + return 1; + + /* fall through. */ + + case NT_VOID: + { + struct cpp_string news; + void **slot; + + news.len = NODE_LEN (hn); + news.text = NODE_NAME (hn); + slot = (void **) htab_find (ss->definedhash, &news); + if (slot == NULL) + { + ss->defs[ss->n_defs] = hn; + ss->n_defs += 1; + } + } + return 1; + + default: + abort (); + } +} + +/* Comparison function for qsort. The arguments point to pointers of + type ht_hashnode *. */ +static int +comp_hashnodes (const void *px, const void *py) +{ + cpp_hashnode *x = *(cpp_hashnode **) px; + cpp_hashnode *y = *(cpp_hashnode **) py; + return ustrcmp (NODE_NAME (x), NODE_NAME (y)); +} + +/* Write out the remainder of the dependency information. This should be + called after the PCH is ready to be saved. */ + +int +cpp_write_pch_deps (cpp_reader *r, FILE *f) +{ + struct macrodef_struct z; + struct cpp_savedstate *const ss = r->savedstate; + unsigned char *definedstrs; + size_t i; + + /* Collect the list of identifiers which have been seen and + weren't defined to anything previously. */ + ss->hashsize = 0; + ss->n_defs = 0; + cpp_forall_identifiers (r, count_defs, ss); + + ss->defs = XNEWVEC (cpp_hashnode *, ss->n_defs); + ss->n_defs = 0; + cpp_forall_identifiers (r, write_defs, ss); + + /* Sort the list, copy it into a buffer, and write it out. */ + qsort (ss->defs, ss->n_defs, sizeof (cpp_hashnode *), &comp_hashnodes); + definedstrs = ss->definedstrs = XNEWVEC (unsigned char, ss->hashsize); + for (i = 0; i < ss->n_defs; ++i) + { + size_t len = NODE_LEN (ss->defs[i]); + memcpy (definedstrs, NODE_NAME (ss->defs[i]), len + 1); + definedstrs += len + 1; + } + + memset (&z, 0, sizeof (z)); + z.definition_length = ss->hashsize; + if (fwrite (&z, sizeof (z), 1, f) != 1 + || fwrite (ss->definedstrs, ss->hashsize, 1, f) != 1) + { + cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); + return -1; + } + free (ss->definedstrs); + free (ss->defs); + htab_delete (ss->definedhash); + + /* Free the saved state. */ + free (ss); + r->savedstate = NULL; + + /* Save the next value of __COUNTER__. */ + if (fwrite (&r->counter, sizeof (r->counter), 1, f) != 1) + { + cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); + return -1; + } + + return 0; +} + +/* Write out the definitions of the preprocessor, in a form suitable for + cpp_read_state. */ + +int +cpp_write_pch_state (cpp_reader *r, FILE *f) +{ + if (!r->deps) + r->deps = deps_init (); + + if (deps_save (r->deps, f) != 0) + { + cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); + return -1; + } + + if (! _cpp_save_file_entries (r, f)) + { + cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); + return -1; + } + + /* Save the next __COUNTER__ value. When we include a precompiled header, + we need to start at the offset we would have if the header had been + included normally. */ + if (fwrite (&r->counter, sizeof (r->counter), 1, f) != 1) + { + cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); + return -1; + } + + /* Write saved macros. */ + if (! _cpp_save_pushed_macros (r, f)) + { + cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header"); + return -1; + } + + return 0; +} + +static int +_cpp_restore_pushed_macros (cpp_reader *r, FILE *f) +{ + size_t count_saved = 0; + size_t i; + struct def_pragma_macro *p; + size_t nlen; + uchar *defn; + size_t defnlen; + + if (fread (&count_saved, sizeof (count_saved), 1, f) != 1) + return 0; + if (! count_saved) + return 1; + for (i = 0; i < count_saved; i++) + { + if (fread (&nlen, sizeof (nlen), 1, f) != 1) + return 0; + p = XNEW (struct def_pragma_macro); + memset (p, 0, sizeof (struct def_pragma_macro)); + p->name = XNEWVAR (char, nlen + 1); + p->name[nlen] = 0; + if (fread (p->name, nlen, 1, f) != 1) + return 0; + if (fread (&defnlen, sizeof (defnlen), 1, f) != 1) + return 0; + if (defnlen == 0) + p->is_undef = 1; + else + { + defn = XNEWVEC (uchar, defnlen + 1); + defn[defnlen] = 0; + + if (fread (defn, defnlen, 1, f) != 1) + return 0; + + p->definition = defn; + if (fread (&(p->line), sizeof (location_t), 1, f) != 1) + return 0; + defnlen = 0; + if (fread (&defnlen, sizeof (defnlen), 1, f) != 1) + return 0; + p->syshdr = ((defnlen & 1) != 0 ? 1 : 0); + p->used = ((defnlen & 2) != 0 ? 1 : 0); + } + + p->next = r->pushed_macros; + r->pushed_macros = p; + } + return 1; +} + +static int +_cpp_save_pushed_macros (cpp_reader *r, FILE *f) +{ + size_t count_saved = 0; + size_t i; + struct def_pragma_macro *p,**pp; + size_t defnlen; + + /* Get count. */ + p = r->pushed_macros; + while (p != NULL) + { + count_saved++; + p = p->next; + } + if (fwrite (&count_saved, sizeof (count_saved), 1, f) != 1) + return 0; + if (!count_saved) + return 1; + + pp = (struct def_pragma_macro **) alloca (sizeof (struct def_pragma_macro *) + * count_saved); + /* Store them in reverse order. */ + p = r->pushed_macros; + i = count_saved; + while (p != NULL) + { + --i; + pp[i] = p; + p = p->next; + } + for (i = 0; i < count_saved; i++) + { + defnlen = strlen (pp[i]->name); + if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1 + || fwrite (pp[i]->name, defnlen, 1, f) != 1) + return 0; + if (pp[i]->is_undef) + { + defnlen = 0; + if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1) + return 0; + } + else + { + defnlen = ustrlen (pp[i]->definition); + if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1 + || fwrite (pp[i]->definition, defnlen, 1, f) != 1) + return 0; + if (fwrite (&(pp[i]->line), sizeof (location_t), 1, f) != 1) + return 0; + defnlen = 0; + defnlen |= (pp[i]->syshdr != 0 ? 1 : 0); + defnlen |= (pp[i]->used != 0 ? 2 : 0); + if (fwrite (&defnlen, sizeof (defnlen), 1, f) != 1) + return 0; + } + } + return 1; +} + + +/* Data structure to transform hash table nodes into a sorted list */ + +struct ht_node_list +{ + /* Array of nodes */ + cpp_hashnode **defs; + /* Number of nodes in the array */ + size_t n_defs; + /* Size of the allocated array */ + size_t asize; +}; + +/* Callback for collecting identifiers from hash table */ + +static int +collect_ht_nodes (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, + void *nl_p) +{ + struct ht_node_list *const nl = (struct ht_node_list *)nl_p; + + if (hn->type != NT_VOID || hn->flags & NODE_POISONED) + { + if (nl->n_defs == nl->asize) + { + nl->asize *= 2; + nl->defs = XRESIZEVEC (cpp_hashnode *, nl->defs, nl->asize); + } + + nl->defs[nl->n_defs] = hn; + ++nl->n_defs; + } + return 1; +} + + +/* Return nonzero if FD is a precompiled header which is consistent + with the preprocessor's current definitions. It will be consistent + when: + + - anything that was defined just before the PCH was generated + is defined the same way now; and + - anything that was not defined then, but is defined now, was not + used by the PCH. + + NAME is used to print warnings if `warn_invalid_pch' is set in the + reader's flags. +*/ + +int +cpp_valid_state (cpp_reader *r, const char *name, int fd) +{ + struct macrodef_struct m; + size_t namebufsz = 256; + unsigned char *namebuf = XNEWVEC (unsigned char, namebufsz); + unsigned char *undeftab = NULL; + struct ht_node_list nl = { 0, 0, 0 }; + unsigned char *first, *last; + unsigned int i; + unsigned int counter; + + /* Read in the list of identifiers that must be defined + Check that they are defined in the same way. */ + for (;;) + { + cpp_hashnode *h; + const unsigned char *newdefn; + + if (read (fd, &m, sizeof (m)) != sizeof (m)) + goto error; + + if (m.name_length == 0) + break; + + /* If this file is already preprocessed, there won't be any + macros defined, and that's OK. */ + if (CPP_OPTION (r, preprocessed)) + { + if (lseek (fd, m.definition_length, SEEK_CUR) == -1) + goto error; + continue; + } + + if (m.definition_length > namebufsz) + { + free (namebuf); + namebufsz = m.definition_length + 256; + namebuf = XNEWVEC (unsigned char, namebufsz); + } + + if ((size_t)read (fd, namebuf, m.definition_length) + != m.definition_length) + goto error; + + h = cpp_lookup (r, namebuf, m.name_length); + if (m.flags & NODE_POISONED + || h->flags & NODE_POISONED) + { + if (CPP_OPTION (r, warn_invalid_pch)) + cpp_warning_syshdr (r, CPP_W_INVALID_PCH, + "%s: not used because `%.*s' is poisoned", + name, m.name_length, namebuf); + goto fail; + } + + if (h->type == NT_VOID) + { + /* It's ok if __GCC_HAVE_DWARF2_CFI_ASM becomes undefined, + as in, when the PCH file is created with -g and we're + attempting to use it without -g. Restoring the PCH file + is supposed to bring in this definition *and* enable the + generation of call frame information, so that precompiled + definitions that take this macro into account, to decide + what asm to emit, won't issue .cfi directives when the + compiler doesn't. */ + if (!(h->flags & NODE_USED) + && m.name_length == sizeof ("__GCC_HAVE_DWARF2_CFI_ASM") - 1 + && !memcmp (namebuf, "__GCC_HAVE_DWARF2_CFI_ASM", m.name_length)) + continue; + + if (CPP_OPTION (r, warn_invalid_pch)) + cpp_warning_syshdr (r, CPP_W_INVALID_PCH, + "%s: not used because `%.*s' not defined", + name, m.name_length, namebuf); + goto fail; + } + + newdefn = cpp_macro_definition (r, h); + + if (m.definition_length != ustrlen (newdefn) + || memcmp (namebuf, newdefn, m.definition_length) != 0) + { + if (CPP_OPTION (r, warn_invalid_pch)) + cpp_warning_syshdr (r, CPP_W_INVALID_PCH, + "%s: not used because `%.*s' defined as `%s' not `%.*s'", + name, m.name_length, namebuf, newdefn + m.name_length, + m.definition_length - m.name_length, + namebuf + m.name_length); + goto fail; + } + } + free (namebuf); + namebuf = NULL; + + /* Read in the list of identifiers that must not be defined. + Check that they really aren't. */ + undeftab = XNEWVEC (unsigned char, m.definition_length); + if ((size_t) read (fd, undeftab, m.definition_length) != m.definition_length) + goto error; + + /* Collect identifiers from the current hash table. */ + nl.n_defs = 0; + nl.asize = 10; + nl.defs = XNEWVEC (cpp_hashnode *, nl.asize); + cpp_forall_identifiers (r, &collect_ht_nodes, &nl); + qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes); + + /* Loop through nl.defs and undeftab, both of which are sorted lists. + There should be no matches. */ + first = undeftab; + last = undeftab + m.definition_length; + i = 0; + + while (first < last && i < nl.n_defs) + { + int cmp = ustrcmp (first, NODE_NAME (nl.defs[i])); + + if (cmp < 0) + first += ustrlen (first) + 1; + else if (cmp > 0) + ++i; + else + { + if (CPP_OPTION (r, warn_invalid_pch)) + cpp_warning_syshdr (r, CPP_W_INVALID_PCH, + "%s: not used because `%s' is defined", + name, first); + goto fail; + } + } + + free(nl.defs); + nl.defs = NULL; + free (undeftab); + undeftab = NULL; + + /* Read in the next value of __COUNTER__. + Check that (a) __COUNTER__ was not used in the pch or (b) __COUNTER__ + has not been used in this translation unit. */ + if (read (fd, &counter, sizeof (counter)) != sizeof (counter)) + goto error; + if (counter && r->counter) + { + if (CPP_OPTION (r, warn_invalid_pch)) + cpp_warning_syshdr (r, CPP_W_INVALID_PCH, + "%s: not used because `__COUNTER__' is invalid", + name); + goto fail; + } + + /* We win! */ + return 0; + + error: + cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header"); + + fail: + free (namebuf); + free (undeftab); + free (nl.defs); + return 1; +} + +/* Save all the existing macros. */ + +struct save_macro_data +{ + uchar **defns; + size_t count; + size_t array_size; + char **saved_pragmas; +}; + +/* Save the definition of a single macro, so that it will persist + across a PCH restore. Because macro data is in GCed memory, which + will be blown away by PCH, it must be temporarily copied to + malloced memory. (The macros will refer to identifier nodes which + are also GCed and so on, so the copying is done by turning them + into self-contained strings.) The assumption is that most macro + definitions will come from the PCH file, not from the compilation + before the PCH file is loaded, so it doesn't matter that this is + a little expensive. + + It would reduce the cost even further if macros defined in the PCH + file were not saved in this way, but this is not done (yet), except + for builtins, and for #assert by default. */ + +static int +save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) +{ + struct save_macro_data *data = (struct save_macro_data *)data_p; + + if (cpp_user_macro_p (h)) + { + if (data->count == data->array_size) + { + data->array_size *= 2; + data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size)); + } + + const uchar * defn = cpp_macro_definition (r, h); + size_t defnlen = ustrlen (defn); + + data->defns[data->count] = (uchar *) xmemdup (defn, defnlen, defnlen + 2); + data->defns[data->count][defnlen] = '\n'; + data->count++; + } + + return 1; +} + +/* Prepare to restore the state, by saving the currently-defined + macros in 'data'. */ + +void +cpp_prepare_state (cpp_reader *r, struct save_macro_data **data) +{ + struct save_macro_data *d = XNEW (struct save_macro_data); + + d->array_size = 512; + d->defns = XNEWVEC (uchar *, d->array_size); + d->count = 0; + cpp_forall_identifiers (r, save_macros, d); + d->saved_pragmas = _cpp_save_pragma_names (r); + *data = d; +} + +/* Given a precompiled header that was previously determined to be valid, + apply all its definitions (and undefinitions) to the current state. + DEPNAME is passed to deps_restore. */ + +int +cpp_read_state (cpp_reader *r, const char *name, FILE *f, + struct save_macro_data *data) +{ + size_t i; + struct lexer_state old_state; + unsigned int counter; + + /* Restore spec_nodes, which will be full of references to the old + hashtable entries and so will now be invalid. */ + { + struct spec_nodes *s = &r->spec_nodes; + s->n_defined = cpp_lookup (r, DSC("defined")); + s->n_true = cpp_lookup (r, DSC("true")); + s->n_false = cpp_lookup (r, DSC("false")); + s->n__VA_ARGS__ = cpp_lookup (r, DSC("__VA_ARGS__")); + s->n__VA_OPT__ = cpp_lookup (r, DSC("__VA_OPT__")); + } + + old_state = r->state; + r->state.in_directive = 1; + r->state.prevent_expansion = 1; + r->state.angled_headers = 0; + + /* Run through the carefully-saved macros, insert them. */ + for (i = 0; i < data->count; i++) + { + cpp_hashnode *h; + size_t namelen; + uchar *defn; + + namelen = ustrcspn (data->defns[i], "( \n"); + h = cpp_lookup (r, data->defns[i], namelen); + defn = data->defns[i] + namelen; + + /* The PCH file is valid, so we know that if there is a definition + from the PCH file it must be the same as the one we had + originally, and so do not need to restore it. */ + if (h->type == NT_VOID) + { + if (cpp_push_buffer (r, defn, ustrchr (defn, '\n') - defn, true) + != NULL) + { + _cpp_clean_line (r); + if (!_cpp_create_definition (r, h)) + abort (); + _cpp_pop_buffer (r); + } + else + abort (); + } + + free (data->defns[i]); + } + r->state = old_state; + + _cpp_restore_pragma_names (r, data->saved_pragmas); + + free (data); + + if (deps_restore (r->deps, f, CPP_OPTION (r, restore_pch_deps) ? name : NULL) + != 0) + goto error; + + if (! _cpp_read_file_entries (r, f)) + goto error; + + if (fread (&counter, sizeof (counter), 1, f) != 1) + goto error; + + if (!r->counter) + r->counter = counter; + + /* Read pushed macros. */ + if (! _cpp_restore_pushed_macros (r, f)) + goto error; + return 0; + + error: + cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header"); + return -1; +} diff --git a/support/cpp/libcpp/symtab.c b/support/cpp/libcpp/symtab.cc index 18be40d12..a05921485 100644 --- a/support/cpp/libcpp/symtab.c +++ b/support/cpp/libcpp/symtab.cc @@ -1,6 +1,5 @@ /* Hash tables. - Copyright (C) 2000, 2001, 2003, 2004, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 2000-2022 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 @@ -31,7 +30,7 @@ along with this program; see the file COPYING3. If not see existing entry with a potential new one. */ static unsigned int calc_hash (const unsigned char *, size_t); -static void ht_expand (hash_table *); +static void ht_expand (cpp_hash_table *); static double approx_sqrt (double); /* A deleted entry. */ @@ -53,18 +52,16 @@ calc_hash (const unsigned char *str, size_t len) /* Initialize an identifier hashtable. */ -hash_table * +cpp_hash_table * ht_create (unsigned int order) { unsigned int nslots = 1 << order; - hash_table *table; + cpp_hash_table *table; - table = XCNEW (hash_table); + table = XCNEW (cpp_hash_table); /* Strings need no alignment. */ - _obstack_begin (&table->stack, 0, 0, - (void *(*) (size_t)) xmalloc, - (void (*) (void *)) free); + obstack_specify_allocation (&table->stack, 0, 0, xmalloc, free); obstack_alignment_mask (&table->stack) = 0; @@ -77,7 +74,7 @@ ht_create (unsigned int order) /* Frees all memory associated with a hash table. */ void -ht_destroy (hash_table *table) +ht_destroy (cpp_hash_table *table) { obstack_free (&table->stack, NULL); if (table->entries_owned) @@ -91,7 +88,7 @@ ht_destroy (hash_table *table) returns NULL. Otherwise insert and returns a new entry. A new string is allocated. */ hashnode -ht_lookup (hash_table *table, const unsigned char *str, size_t len, +ht_lookup (cpp_hash_table *table, const unsigned char *str, size_t len, enum ht_lookup_option insert) { return ht_lookup_with_hash (table, str, len, calc_hash (str, len), @@ -99,7 +96,7 @@ ht_lookup (hash_table *table, const unsigned char *str, size_t len, } hashnode -ht_lookup_with_hash (hash_table *table, const unsigned char *str, +ht_lookup_with_hash (cpp_hash_table *table, const unsigned char *str, size_t len, unsigned int hash, enum ht_lookup_option insert) { @@ -182,7 +179,7 @@ ht_lookup_with_hash (hash_table *table, const unsigned char *str, /* Double the size of a hash table, re-hashing existing entries. */ static void -ht_expand (hash_table *table) +ht_expand (cpp_hash_table *table) { hashnode *nentries, *p, *limit; unsigned int size, sizemask; @@ -224,7 +221,7 @@ ht_expand (hash_table *table) /* For all nodes in TABLE, callback CB with parameters TABLE->PFILE, the node, and V. */ void -ht_forall (hash_table *table, ht_cb cb, const void *v) +ht_forall (cpp_hash_table *table, ht_cb cb, const void *v) { hashnode *p, *limit; @@ -242,7 +239,7 @@ ht_forall (hash_table *table, ht_cb cb, const void *v) /* Like ht_forall, but a nonzero return from the callback means that the entry should be removed from the table. */ void -ht_purge (hash_table *table, ht_cb cb, const void *v) +ht_purge (cpp_hash_table *table, ht_cb cb, const void *v) { hashnode *p, *limit; @@ -259,7 +256,7 @@ ht_purge (hash_table *table, ht_cb cb, const void *v) /* Restore the hash table. */ void -ht_load (hash_table *ht, hashnode *entries, +ht_load (cpp_hash_table *ht, hashnode *entries, unsigned int nslots, unsigned int nelements, bool own) { @@ -274,7 +271,7 @@ ht_load (hash_table *ht, hashnode *entries, /* Dump allocation statistics to stderr. */ void -ht_dump_statistics (hash_table *table) +ht_dump_statistics (cpp_hash_table *table) { size_t nelts, nids, overhead, headers; size_t total_bytes, longest, deleted = 0; @@ -307,34 +304,43 @@ ht_dump_statistics (hash_table *table) while (++p < limit); nelts = table->nelements; - overhead = obstack_memory_used (&table->stack) - total_bytes; headers = table->nslots * sizeof (hashnode); - fprintf (stderr, "\nString pool\nentries\t\t%lu\n", + fprintf (stderr, "\nString pool\n%-32s%lu\n", "entries:", (unsigned long) nelts); - fprintf (stderr, "identifiers\t%lu (%.2f%%)\n", + fprintf (stderr, "%-32s%lu (%.2f%%)\n", "identifiers:", (unsigned long) nids, nids * 100.0 / nelts); - fprintf (stderr, "slots\t\t%lu\n", + fprintf (stderr, "%-32s%lu\n", "slots:", (unsigned long) table->nslots); - fprintf (stderr, "deleted\t\t%lu\n", + fprintf (stderr, "%-32s%lu\n", "deleted:", (unsigned long) deleted); - fprintf (stderr, "bytes\t\t%lu%c (%lu%c overhead)\n", - SCALE (total_bytes), LABEL (total_bytes), - SCALE (overhead), LABEL (overhead)); - fprintf (stderr, "table size\t%lu%c\n", + + if (table->alloc_subobject) + fprintf (stderr, "%-32s%lu%c\n", "GGC bytes:", + SCALE (total_bytes), LABEL (total_bytes)); + else + { + overhead = obstack_memory_used (&table->stack) - total_bytes; + fprintf (stderr, "%-32s%lu%c (%lu%c overhead)\n", + "obstack bytes:", + SCALE (total_bytes), LABEL (total_bytes), + SCALE (overhead), LABEL (overhead)); + } + fprintf (stderr, "%-32s%lu%c\n", "table size:", SCALE (headers), LABEL (headers)); exp_len = (double)total_bytes / (double)nelts; exp2_len = exp_len * exp_len; exp_len2 = (double) sum_of_squares / (double) nelts; - fprintf (stderr, "coll/search\t%.4f\n", + fprintf (stderr, "%-32s%.4f\n", "coll/search:", (double) table->collisions / (double) table->searches); - fprintf (stderr, "ins/search\t%.4f\n", + fprintf (stderr, "%-32s%.4f\n", "ins/search:", (double) nelts / (double) table->searches); - fprintf (stderr, "avg. entry\t%.2f bytes (+/- %.2f)\n", + fprintf (stderr, "%-32s%.2f bytes (+/- %.2f)\n", + "avg. entry:", exp_len, approx_sqrt (exp_len2 - exp2_len)); - fprintf (stderr, "longest entry\t%lu\n", + fprintf (stderr, "%-32s%lu\n", "longest entry:", (unsigned long) longest); #undef SCALE #undef LABEL diff --git a/support/cpp/libcpp/system.h b/support/cpp/libcpp/system.h index 9dc83e66c..5a62ba029 100644 --- a/support/cpp/libcpp/system.h +++ b/support/cpp/libcpp/system.h @@ -1,6 +1,6 @@ /* Get common system includes and various definitions and declarations based on autoconf macros. - Copyright (C) 1998-2014 Free Software Foundation, Inc. + Copyright (C) 1998-2022 Free Software Foundation, Inc. This file is part of GCC. @@ -37,6 +37,10 @@ along with GCC; see the file COPYING3. If not see #include <stdio.h> +#ifdef __cplusplus +#include <new> +#endif + /* Define a generic NULL if one hasn't already been defined. */ #ifndef NULL #define NULL 0 @@ -230,7 +234,7 @@ extern int errno; /* 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)) + ? (t) 1 << (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. */ @@ -375,9 +379,12 @@ extern void abort (void); ??? C99 designated initializers are not supported by most C++ compilers, including G++. -- gdr, 2005-05-18 */ #if !defined(HAVE_DESIGNATED_INITIALIZERS) +#ifdef __cplusplus +#define HAVE_DESIGNATED_INITIALIZERS 0 +#else #define HAVE_DESIGNATED_INITIALIZERS \ - (!defined(__cplusplus) \ - && ((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L))) + ((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)) +#endif #endif #ifndef offsetof @@ -391,25 +398,41 @@ extern void abort (void); #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 +/* Redefine abort to report an internal error w/o coredump, and + reporting the location of the error in the source file. */ +extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; +#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__) + +/* Use gcc_assert(EXPR) to test invariants. */ +#if ENABLE_ASSERT_CHECKING +#define gcc_assert(EXPR) \ + ((void)(!(EXPR) ? fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0 : 0)) +#elif (GCC_VERSION >= 4005) +#define gcc_assert(EXPR) \ + ((void)(__builtin_expect (!(EXPR), 0) ? __builtin_unreachable (), 0 : 0)) +#else +/* Include EXPR, so that unused variable warnings do not occur. */ +#define gcc_assert(EXPR) ((void)(0 && (EXPR))) +#endif -#ifndef __cplusplus -#define bool unsigned char +#if CHECKING_P +#define gcc_checking_assert(EXPR) gcc_assert (EXPR) +#else +/* N.B.: in release build EXPR is not evaluated. */ +#define gcc_checking_assert(EXPR) ((void)(0 && (EXPR))) #endif -#define true 1 -#define false 0 -/* Some compilers do not allow the use of unsigned char in bitfields. */ -#define BOOL_BITFIELD unsigned int +#ifdef __has_cpp_attribute +# if __has_cpp_attribute(likely) +# define ATTR_LIKELY [[likely]] +# elif __has_cpp_attribute(__likely__) +# define ATTR_LIKELY [[__likely__]] +# else +# define ATTR_LIKELY +# endif +#else +# define ATTR_LIKELY +#endif /* Poison identifiers we do not want to use. */ #if (GCC_VERSION >= 3000) @@ -443,6 +466,6 @@ extern void abort (void); #endif /* GCC >= 3.0 */ /* SDCC specific */ -#include "sdcpp.h" +// #include "sdcpp.h" #endif /* ! LIBCPP_SYSTEM_H */ diff --git a/support/cpp/libcpp/traditional.c b/support/cpp/libcpp/traditional.cc index 7ff11bb20..d02ea48db 100644 --- a/support/cpp/libcpp/traditional.c +++ b/support/cpp/libcpp/traditional.cc @@ -1,6 +1,5 @@ /* CPP Library - traditional lexical analysis and macro expansion. - Copyright (C) 2002, 2004, 2005, 2007, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 2002-2022 Free Software Foundation, Inc. Contributed by Neil Booth, May 2002 This program is free software; you can redistribute it and/or modify it @@ -61,7 +60,10 @@ struct fun_macro size_t offset; /* The line the macro name appeared on. */ - source_location line; + location_t line; + + /* Number of parameters. */ + unsigned int paramc; /* Zero-based index of argument being currently lexed. */ unsigned int argc; @@ -75,9 +77,10 @@ enum ls {ls_none = 0, /* Normal state. */ ls_defined_close, /* Looking for ')' of defined(). */ ls_hash, /* After # in preprocessor conditional. */ ls_predicate, /* After the predicate, maybe paren? */ - ls_answer}; /* In answer to predicate. */ + ls_answer /* In answer to predicate. */ +}; -/* Lexing TODO: Maybe handle space in escaped newlines. Stop lex.c +/* Lexing TODO: Maybe handle space in escaped newlines. Stop lex.cc from recognizing comments and directives during its lexing pass. */ static const uchar *skip_whitespace (cpp_reader *, const uchar *, int); @@ -85,7 +88,7 @@ static cpp_hashnode *lex_identifier (cpp_reader *, const uchar *); static const uchar *copy_comment (cpp_reader *, const uchar *, int); static void check_output_buffer (cpp_reader *, size_t); static void push_replacement_text (cpp_reader *, cpp_hashnode *); -static bool scan_parameters (cpp_reader *, cpp_macro *); +static bool scan_parameters (cpp_reader *, unsigned *); static bool recursive_macro (cpp_reader *, cpp_hashnode *); static void save_replacement_text (cpp_reader *, cpp_macro *, unsigned int); static void maybe_start_funlike (cpp_reader *, cpp_hashnode *, const uchar *, @@ -115,8 +118,11 @@ check_output_buffer (cpp_reader *pfile, size_t n) } /* Skip a C-style block comment in a macro as a result of -CC. - Buffer->cur points to the initial asterisk of the comment. */ -static void + PFILE->buffer->cur points to the initial asterisk of the comment, + change it to point to after the '*' and '/' characters that terminate it. + Return true if the macro has not been termined, in that case set + PFILE->buffer->cur to the end of the buffer. */ +static bool skip_macro_block_comment (cpp_reader *pfile) { const uchar *cur = pfile->buffer->cur; @@ -127,10 +133,15 @@ skip_macro_block_comment (cpp_reader *pfile) /* People like decorating comments with '*', so check for '/' instead for efficiency. */ - while(! (*cur++ == '/' && cur[-2] == '*') ) - ; + while (! (*cur++ == '/' && cur[-2] == '*')) + if (cur[-1] == '\n') + { + pfile->buffer->cur = cur - 1; + return true; + } pfile->buffer->cur = cur; + return false; } /* CUR points to the asterisk introducing a comment in the current @@ -149,12 +160,12 @@ static const uchar * copy_comment (cpp_reader *pfile, const uchar *cur, int in_define) { bool unterminated, copy = false; - source_location src_loc = pfile->line_table->highest_line; + location_t src_loc = pfile->line_table->highest_line; cpp_buffer *buffer = pfile->buffer; buffer->cur = cur; if (pfile->context->prev) - unterminated = false, skip_macro_block_comment (pfile); + unterminated = skip_macro_block_comment (pfile); else unterminated = _cpp_skip_block_comment (pfile); @@ -301,26 +312,50 @@ _cpp_read_logical_line_trad (cpp_reader *pfile) do { if (pfile->buffer->need_line && !_cpp_get_fresh_line (pfile)) - return false; + { + /* Now pop the buffer that _cpp_get_fresh_line did not. */ + _cpp_pop_buffer (pfile); + return false; + } } - while (!_cpp_scan_out_logical_line (pfile, NULL) || pfile->state.skipping); + while (!_cpp_scan_out_logical_line (pfile, NULL, false) + || pfile->state.skipping); return pfile->buffer != NULL; } +/* Return true if NODE is a fun_like macro. */ +static inline bool +fun_like_macro (cpp_hashnode *node) +{ + if (cpp_builtin_macro_p (node)) + return (node->value.builtin == BT_HAS_ATTRIBUTE + || node->value.builtin == BT_HAS_STD_ATTRIBUTE + || node->value.builtin == BT_HAS_BUILTIN + || node->value.builtin == BT_HAS_INCLUDE + || node->value.builtin == BT_HAS_INCLUDE_NEXT); + return node->value.macro->fun_like; +} + /* Set up state for finding the opening '(' of a function-like macro. */ static void -maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar *start, struct fun_macro *macro) +maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar *start, + struct fun_macro *macro) { - unsigned int n = node->value.macro->paramc + 1; + unsigned int n; + if (cpp_builtin_macro_p (node)) + n = 1; + else + n = node->value.macro->paramc; if (macro->buff) _cpp_release_buff (pfile, macro->buff); - macro->buff = _cpp_get_buff (pfile, n * sizeof (size_t)); + macro->buff = _cpp_get_buff (pfile, (n + 1) * sizeof (size_t)); macro->args = (size_t *) BUFF_FRONT (macro->buff); macro->node = node; macro->offset = start - pfile->out.base; + macro->paramc = n; macro->argc = 0; } @@ -329,7 +364,7 @@ static void save_argument (struct fun_macro *macro, size_t offset) { macro->argc++; - if (macro->argc <= macro->node->value.macro->paramc) + if (macro->argc <= macro->paramc) macro->args[macro->argc] = offset; } @@ -339,9 +374,13 @@ save_argument (struct fun_macro *macro, size_t offset) If MACRO is non-NULL, then we are scanning the replacement list of MACRO, and we call save_replacement_text() every time we meet an - argument. */ + argument. + + If BUILTIN_MACRO_ARG is true, this is called to macro expand + arguments of builtin function-like macros. */ bool -_cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) +_cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro, + bool builtin_macro_arg) { bool result = true; cpp_context *context; @@ -358,14 +397,18 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) fmacro.node = NULL; fmacro.offset = 0; fmacro.line = 0; + fmacro.paramc = 0; fmacro.argc = 0; quote = 0; header_ok = pfile->state.angled_headers; CUR (pfile->context) = pfile->buffer->cur; RLIMIT (pfile->context) = pfile->buffer->rlimit; - pfile->out.cur = pfile->out.base; - pfile->out.first_line = pfile->line_table->highest_line; + if (!builtin_macro_arg) + { + pfile->out.cur = pfile->out.base; + pfile->out.first_line = pfile->line_table->highest_line; + } /* start_of_input_line is needed to make sure that directives really, really start at the first character of the line. */ start_of_input_line = pfile->buffer->cur; @@ -378,6 +421,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) for (;;) { if (!context->prev + && !builtin_macro_arg && cur >= pfile->buffer->notes[pfile->buffer->cur_note].pos) { pfile->buffer->cur = cur; @@ -409,6 +453,8 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) /* Omit the newline from the output buffer. */ pfile->out.cur = out - 1; pfile->buffer->cur = cur; + if (builtin_macro_arg) + goto done; pfile->buffer->need_line = true; CPP_INCREMENT_LINE (pfile, 0); @@ -481,15 +527,14 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) out = pfile->out.cur; cur = CUR (context); - if (node->type == NT_MACRO + if (cpp_macro_p (node) /* Should we expand for ls_answer? */ && (lex_state == ls_none || lex_state == ls_fun_open) && !pfile->state.prevent_expansion) { /* Macros invalidate MI optimization. */ pfile->mi_valid = false; - if (! (node->flags & NODE_BUILTIN) - && node->value.macro->fun_like) + if (fun_like_macro (node)) { maybe_start_funlike (pfile, node, out_start, &fmacro); lex_state = ls_fun_open; @@ -506,7 +551,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) goto new_context; } } - else if (macro && (node->flags & NODE_MACRO_ARG) != 0) + else if (macro && node->type == NT_MACRO_ARG) { /* Found a parameter in the replacement text of a #define. Remove its name from the output. */ @@ -562,6 +607,103 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) paren_depth--; if (lex_state == ls_fun_close && paren_depth == 0) { + if (cpp_builtin_macro_p (fmacro.node)) + { + /* Handle builtin function-like macros like + __has_attribute. The already parsed arguments + are put into a buffer, which is then preprocessed + and the result is fed to _cpp_push_text_context + with disabled expansion, where the ISO preprocessor + parses it. While in traditional preprocessing + macro arguments aren't immediately expanded, they in + the end are because the macro with replaced arguments + is preprocessed again. For the builtin function-like + macros we need the argument immediately though, + if we don't preprocess them, they would behave + very differently from ISO preprocessor handling + of those builtin macros. So, this handling is + more similar to traditional preprocessing of + #if directives, where we also keep preprocessing + until everything is expanded, and then feed the + result with disabled expansion to ISO preprocessor + for handling the directives. */ + lex_state = ls_none; + save_argument (&fmacro, out - pfile->out.base); + cpp_macro m; + memset (&m, '\0', sizeof (m)); + m.paramc = fmacro.paramc; + if (_cpp_arguments_ok (pfile, &m, fmacro.node, + fmacro.argc)) + { + size_t len = fmacro.args[1] - fmacro.args[0]; + uchar *buf; + + /* Remove the macro's invocation from the + output, and push its replacement text. */ + pfile->out.cur = pfile->out.base + fmacro.offset; + CUR (context) = cur; + buf = _cpp_unaligned_alloc (pfile, len + 2); + buf[0] = '('; + memcpy (buf + 1, pfile->out.base + fmacro.args[0], + len); + buf[len + 1] = '\n'; + + const unsigned char *ctx_rlimit = RLIMIT (context); + const unsigned char *saved_cur = pfile->buffer->cur; + const unsigned char *saved_rlimit + = pfile->buffer->rlimit; + const unsigned char *saved_line_base + = pfile->buffer->line_base; + bool saved_need_line = pfile->buffer->need_line; + cpp_buffer *saved_overlaid_buffer + = pfile->overlaid_buffer; + pfile->buffer->cur = buf; + pfile->buffer->line_base = buf; + pfile->buffer->rlimit = buf + len + 1; + pfile->buffer->need_line = false; + pfile->overlaid_buffer = pfile->buffer; + bool saved_in_directive = pfile->state.in_directive; + pfile->state.in_directive = true; + cpp_context *saved_prev_context = context->prev; + context->prev = NULL; + + _cpp_scan_out_logical_line (pfile, NULL, true); + + pfile->state.in_directive = saved_in_directive; + check_output_buffer (pfile, 1); + *pfile->out.cur = '\n'; + pfile->buffer->cur = pfile->out.base + fmacro.offset; + pfile->buffer->line_base = pfile->buffer->cur; + pfile->buffer->rlimit = pfile->out.cur; + CUR (context) = pfile->buffer->cur; + RLIMIT (context) = pfile->buffer->rlimit; + + pfile->state.prevent_expansion++; + const uchar *text + = _cpp_builtin_macro_text (pfile, fmacro.node); + pfile->state.prevent_expansion--; + + context->prev = saved_prev_context; + pfile->buffer->cur = saved_cur; + pfile->buffer->rlimit = saved_rlimit; + pfile->buffer->line_base = saved_line_base; + pfile->buffer->need_line = saved_need_line; + pfile->overlaid_buffer = saved_overlaid_buffer; + pfile->out.cur = pfile->out.base + fmacro.offset; + CUR (context) = cur; + RLIMIT (context) = ctx_rlimit; + len = ustrlen (text); + buf = _cpp_unaligned_alloc (pfile, len + 1); + memcpy (buf, text, len); + buf[len] = '\n'; + text = buf; + _cpp_push_text_context (pfile, fmacro.node, + text, len); + goto new_context; + } + break; + } + cpp_macro *m = fmacro.node->value.macro; m->used = 1; @@ -578,8 +720,7 @@ _cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro) { /* Remove the macro's invocation from the output, and push its replacement text. */ - pfile->out.cur = (pfile->out.base - + fmacro.offset); + pfile->out.cur = pfile->out.base + fmacro.offset; CUR (context) = cur; replace_args_and_push (pfile, &fmacro); goto new_context; @@ -693,13 +834,13 @@ push_replacement_text (cpp_reader *pfile, cpp_hashnode *node) const uchar *text; uchar *buf; - if (node->flags & NODE_BUILTIN) + if (cpp_builtin_macro_p (node)) { text = _cpp_builtin_macro_text (pfile, node); len = ustrlen (text); buf = _cpp_unaligned_alloc (pfile, len + 1); memcpy (buf, text, len); - buf[len]='\n'; + buf[len] = '\n'; text = buf; } else @@ -707,7 +848,6 @@ 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; } @@ -730,7 +870,7 @@ recursive_macro (cpp_reader *pfile, cpp_hashnode *node) detect true recursion; instead we assume any expansion more than 20 deep since the first invocation of this macro must be recursing. */ - if (recursing && node->value.macro->fun_like) + if (recursing && fun_like_macro (node)) { size_t depth = 0; cpp_context *context = pfile->context; @@ -738,7 +878,7 @@ recursive_macro (cpp_reader *pfile, cpp_hashnode *node) do { depth++; - if (context->macro == node && depth > 20) + if (context->c.macro == node && depth > 20) break; context = context->prev; } @@ -773,7 +913,7 @@ _cpp_replacement_text_len (const cpp_macro *macro) len += b->text_len; if (b->arg_index == 0) break; - len += NODE_LEN (macro->params[b->arg_index - 1]); + len += NODE_LEN (macro->parm.params[b->arg_index - 1]); exp += BLOCK_LEN (b->text_len); } } @@ -802,7 +942,7 @@ _cpp_copy_replacement_text (const cpp_macro *macro, uchar *dest) dest += b->text_len; if (b->arg_index == 0) break; - param = macro->params[b->arg_index - 1]; + param = macro->parm.params[b->arg_index - 1]; memcpy (dest, NODE_NAME (param), NODE_LEN (param)); dest += NODE_LEN (param); exp += BLOCK_LEN (b->text_len); @@ -936,20 +1076,23 @@ replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro) duplicate parameter). On success, CUR (pfile->context) is just past the closing parenthesis. */ static bool -scan_parameters (cpp_reader *pfile, cpp_macro *macro) +scan_parameters (cpp_reader *pfile, unsigned *n_ptr) { const uchar *cur = CUR (pfile->context) + 1; bool ok; + unsigned nparms = 0; for (;;) { cur = skip_whitespace (pfile, cur, true /* skip_comments */); if (is_idstart (*cur)) { + struct cpp_hashnode *id = lex_identifier (pfile, cur); ok = false; - if (_cpp_save_parameter (pfile, macro, lex_identifier (pfile, cur))) + if (!_cpp_save_parameter (pfile, nparms, id, id)) break; + nparms++; cur = skip_whitespace (pfile, CUR (pfile->context), true /* skip_comments */); if (*cur == ',') @@ -961,10 +1104,12 @@ scan_parameters (cpp_reader *pfile, cpp_macro *macro) break; } - ok = (*cur == ')' && macro->paramc == 0); + ok = (*cur == ')' && !nparms); break; } + *n_ptr = nparms; + if (!ok) cpp_error (pfile, CPP_DL_ERROR, "syntax error in macro parameter list"); @@ -992,7 +1137,6 @@ 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 @@ -1008,7 +1152,6 @@ 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; @@ -1028,12 +1171,15 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro, /* Analyze and save the replacement text of a macro. Returns true on success. */ -bool -_cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro) +cpp_macro * +_cpp_create_trad_definition (cpp_reader *pfile) { const uchar *cur; uchar *limit; cpp_context *context = pfile->context; + unsigned nparms = 0; + int fun_like = 0; + cpp_hashnode **params = NULL; /* The context has not been set up for command line defines, and CUR has not been updated for the macro name for in-file defines. */ @@ -1045,20 +1191,23 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro) /* Is this a function-like macro? */ if (* CUR (context) == '(') { - bool ok = scan_parameters (pfile, macro); + fun_like = +1; + if (scan_parameters (pfile, &nparms)) + params = (cpp_hashnode **)_cpp_commit_buff + (pfile, sizeof (cpp_hashnode *) * nparms); + else + fun_like = -1; + } - /* Remember the params so we can clear NODE_MACRO_ARG flags. */ - macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff); + cpp_macro *macro = NULL; - /* Setting macro to NULL indicates an error occurred, and - prevents unnecessary work in _cpp_scan_out_logical_line. */ - if (!ok) - macro = NULL; - else - { - BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; - macro->fun_like = 1; - } + if (fun_like >= 0) + { + macro = _cpp_new_macro (pfile, cmk_traditional, + _cpp_aligned_alloc (pfile, sizeof (cpp_macro))); + macro->parm.params = params; + macro->paramc = nparms; + macro->fun_like = fun_like != 0; } /* Skip leading whitespace in the replacement text. */ @@ -1067,21 +1216,23 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro) CPP_OPTION (pfile, discard_comments_in_macro_exp)); pfile->state.prevent_expansion++; - _cpp_scan_out_logical_line (pfile, macro); + _cpp_scan_out_logical_line (pfile, macro, false); pfile->state.prevent_expansion--; - if (!macro) - return false; + _cpp_unsave_parameters (pfile, nparms); - /* Skip trailing white space. */ - cur = pfile->out.base; - limit = pfile->out.cur; - while (limit > cur && is_space (limit[-1])) - limit--; - pfile->out.cur = limit; - save_replacement_text (pfile, macro, 0); + if (macro) + { + /* Skip trailing white space. */ + cur = pfile->out.base; + limit = pfile->out.cur; + while (limit > cur && is_space (limit[-1])) + limit--; + pfile->out.cur = limit; + save_replacement_text (pfile, macro, 0); + } - return true; + return macro; } /* Copy SRC of length LEN to DEST, but convert all contiguous diff --git a/support/cpp/libcpp/ucnid.h b/support/cpp/libcpp/ucnid.h index e5690b223..b15c12366 100644 --- a/support/cpp/libcpp/ucnid.h +++ b/support/cpp/libcpp/ucnid.h @@ -1,5 +1,5 @@ /* Unicode characters and various properties. - Copyright (C) 2003, 2005, 2009 Free Software Foundation, Inc. + Copyright (C) 2003-2022 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 @@ -52,750 +52,5334 @@ 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 }, +static const struct ucnrange ucnranges[] = { +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00a7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x00a8 }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00a9 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x00aa }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00ac }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00ad }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00ae }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x00af }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00b1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x00b4 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x00b5 }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00b6 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x00b7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x00b9 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x00ba }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00bb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x00be }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00bf }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x00d6 }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00d7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x00f6 }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x00f7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0131 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x0133 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x013e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x0140 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0148 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x0149 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x017e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x017f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x01c3 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x01cc }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x01d4 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x01dc }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x01dd }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x01e3 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x01eb }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x01ef }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x01f0 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x01f3 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x01f5 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x01f9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x01ff }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0217 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0229 }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x022d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x022f }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0231 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x024f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x02a8 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x02af }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x02b8 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x02ba }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x02bb }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x02bc }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x02c1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02c5 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x02cf }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x02d1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02d7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x02dd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02df }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x02e4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02eb }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x02ec }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02ed }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x02ee }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x02ff }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 230, 0x0304 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0305 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 230, 0x030c }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x030e }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 230, 0x030f }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0310 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 230, 0x0311 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0312 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 230, 0x0314 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 232, 0x0315 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0319 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 232, 0x031a }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 216, 0x031b }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0320 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 202, 0x0322 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 220, 0x0326 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 202, 0x0328 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x032c }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 220, 0x032e }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x032f }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 220, 0x0331 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0333 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x0337 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 1, 0x0338 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x033c }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x033f }, +{ 0| 0| 0|C11|N11|CXX23|NXX23| 0| 0| 0| 0, 230, 0x0341 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 230, 0x0342 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23| 0| 0| 0| 0, 230, 0x0344 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC|CTX, 240, 0x0345 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0346 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0349 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x034c }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x034e }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x034f }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0352 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0356 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0357 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 232, 0x0358 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x035a }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x035b }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 233, 0x035c }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 234, 0x035e }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 233, 0x035f }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 234, 0x0361 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 233, 0x0362 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x036f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0373 }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0374 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0375 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0377 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0379 }, +{ C99| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x037a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x037d }, +{ 0| 0| 0|C11| 0| 0| 0|CID| 0| 0| 0, 0, 0x037e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x037f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0383 }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x0384 }, +{ 0| 0| 0|C11| 0| 0| 0| 0|NFC| 0| 0, 0, 0x0385 }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0386 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0387 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x038a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x038b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x038c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x038d }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0390 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03a1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03a2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03a9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x03b0 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03c9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x03ce }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03cf }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x03d2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC| 0| 0, 0, 0x03d4 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x03d6 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03d9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03da }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03db }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03dc }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03dd }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03de }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03df }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03e0 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03e1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03ef }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x03f2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03f3 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x03f5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x03f6 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03f8 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x03f9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x03ff }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0400 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0401 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0402 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0403 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0406 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0407 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x040b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x040c }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x040d }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x040e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0418 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0419 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0438 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0439 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x044f }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0450 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0451 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0452 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0453 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0456 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0457 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x045b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x045c }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x045d }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x045e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0475 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0477 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0481 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0482 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0487 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0489 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x048f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04c0 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x04c2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04c4 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04c6 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04c8 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04ca }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04cc }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04cf }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x04d3 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04d5 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x04d7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04d9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x04df }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04e1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x04e7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04e9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x04eb }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x04ed }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x04f5 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x04f7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x04f9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x052f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0530 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0556 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0558 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0559 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x055f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0560 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0586 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x0587 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0588 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0590 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0591 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0595 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0596 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0599 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 222, 0x059a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x059b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x05a1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x05a7 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x05a9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x05aa }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x05ac }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 222, 0x05ad }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 228, 0x05ae }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x05af }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 10, 0x05b0 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 11, 0x05b1 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 12, 0x05b2 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 13, 0x05b3 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 14, 0x05b4 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 15, 0x05b5 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 16, 0x05b6 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 17, 0x05b7 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 18, 0x05b8 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 19, 0x05b9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 19, 0x05ba }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 20, 0x05bb }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 21, 0x05bc }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 22, 0x05bd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05be }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 23, 0x05bf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05c0 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 24, 0x05c1 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 25, 0x05c2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05c3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x05c4 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x05c5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05c6 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 18, 0x05c7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05cf }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x05ea }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05ee }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x05ef }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x05f2 }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x05f4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x060f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0617 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 30, 0x0618 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 31, 0x0619 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 32, 0x061a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x061f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0620 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0621 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0626 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x063a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x063f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x064a }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 27, 0x064b }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 28, 0x064c }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 29, 0x064d }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 30, 0x064e }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 31, 0x064f }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 32, 0x0650 }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 33, 0x0651 }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 34, 0x0652 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 230, 0x0654 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 220, 0x0655 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0656 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x065b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x065c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x065e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x065f }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0669 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x066d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x066f }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 35, 0x0670 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0674 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x0678 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06b7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06b9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06be }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06bf }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x06c0 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06c1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x06c2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06ce }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06cf }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06d2 }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x06d3 }, +{ C99| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06d4 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06d5 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x06dc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06de }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x06e2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x06e3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x06e4 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06e6 }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x06e7 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x06e8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06e9 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x06ea }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x06ec }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x06ed }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06ef }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x06f9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06fc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x06fe }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x06ff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x070f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0710 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 36, 0x0711 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x072f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0730 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0731 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0733 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0734 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0736 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0739 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x073a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x073c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x073d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x073e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0741 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0742 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0743 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0744 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0745 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0746 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0747 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0748 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x074a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x074c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x07a5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x07b0 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x07b1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x07bf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x07c9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x07ea }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x07f1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x07f2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x07f3 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x07f5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x07f9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x07fa }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x07fc }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x07fd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x07ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0815 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0819 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x081a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0823 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0824 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0827 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0828 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x082d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x083f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0858 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x085b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x085f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x086a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x089f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x08b4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x08b5 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x08c7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x08d2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x08d3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x08e1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x08e2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x08e3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x08e5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x08e6 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x08e8 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x08e9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x08ec }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x08ef }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 27, 0x08f0 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 28, 0x08f1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 29, 0x08f2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x08f5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x08f6 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x08f8 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x08fa }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x08ff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0900 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0903 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0904 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0928 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0929 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0930 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0931 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0933 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0934 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0939 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x093b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 7, 0x093c }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x093d }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x094c }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x094d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x094f }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0950 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0951 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0952 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0954 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0957 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x095f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0961 }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0962 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0963 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0965 }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x096f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0970 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0980 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0983 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0984 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x098c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x098e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0990 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0992 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x09a8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09a9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x09b0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09b1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x09b2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09b5 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x09b9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09bb }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x09bc }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x09bd }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x09be }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x09c4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09c6 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x09c8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09ca }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x09cc }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x09cd }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x09ce }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09d6 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x09d7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09db }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x09dd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09de }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x09df }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x09e1 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x09e3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09e5 }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x09ef }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x09f1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09fb }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x09fc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x09fd }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x09fe }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a00 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a01 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a02 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a03 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a04 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a0a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a0e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a10 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a12 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a28 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a29 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a30 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a31 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a32 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0a33 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a34 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a35 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0a36 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a37 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a39 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a3b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x0a3c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a3d }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a42 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a46 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a48 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a4a }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a4c }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0a4d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a50 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a51 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a58 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0a5b }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a5c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a5d }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0a5e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a65 }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a6f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a71 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a73 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a74 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a75 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a80 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0a83 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a84 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a8b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a8c }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a8d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a8e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0a91 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0a92 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0aa8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0aa9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ab0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ab1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ab3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ab4 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ab9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0abb }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x0abc }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0abd }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0ac5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ac6 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0ac9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0aca }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0acc }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0acd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0acf }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ad0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0adf }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ae0 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ae1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0ae3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ae5 }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0aef }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0af8 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0af9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0aff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b00 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0b03 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b04 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b0c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b0e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b10 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b12 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b28 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b29 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b30 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b31 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b33 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b34 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b35 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b39 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b3b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x0b3c }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b3d }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x0b3e }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0b43 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0b44 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b46 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0b47 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x0b48 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b4a }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x0b4c }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0b4d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b54 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0b55 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x0b57 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b5b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0b5d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b5e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b61 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0b63 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b65 }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0b6f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b70 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b71 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b81 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0b82 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b83 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b84 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b8a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b8d }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b90 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b91 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b93 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x0b94 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b95 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b98 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b9a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b9b }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b9c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0b9d }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0b9f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ba2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ba4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ba7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0baa }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bad }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0bb5 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0bb6 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0bb9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bbd }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x0bbe }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0bc2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bc5 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0bc8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bc9 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x0bcc }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0bcd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bcf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0bd0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bd6 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x0bd7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0be5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0be6 }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0bef }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0bff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0c00 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0c03 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0c04 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c0c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c0d }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c10 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c11 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c28 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c29 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c33 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c34 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c39 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c3c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c3d }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0c44 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c45 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0c47 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x0c48 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c49 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0c4c }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0c4d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c54 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 84, 0x0c55 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 91, 0x0c56 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c57 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c5a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c5f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c61 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0c63 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c65 }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0c6f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c7f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c80 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0c81 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0c83 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c84 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c8c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c8d }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0c90 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0c91 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ca8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ca9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0cb3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cb4 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0cb9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cbb }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x0cbc }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0cbd }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0cbf }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x0cc0 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0cc1 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x0cc2 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0cc4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc5 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0cc6 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x0cc8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cc9 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x0ccb }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0ccc }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0ccd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cd4 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x0cd6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cdd }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0cde }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cdf }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ce1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0ce3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ce5 }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0cef }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cf0 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0cf2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0cff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0d01 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0d03 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d04 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d0c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d0d }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d10 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d11 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d28 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d29 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d39 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d3a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0d3c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d3d }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x0d3e }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0d43 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0d44 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d45 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0d48 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d49 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x0d4c }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0d4d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d4e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d53 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d56 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x0d57 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d5e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d5f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d61 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0d63 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d65 }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0d6f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d79 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d7f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d80 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0d83 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d84 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0d96 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0d99 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0db1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0db2 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0dbb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0dbc }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0dbd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0dbf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0dc6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0dc9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 9, 0x0dca }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0dce }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x0dcf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0dd4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0dd5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0dd6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0dd7 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0dd9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x0dda }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0ddb }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x0dde }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x0ddf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0de5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0def }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0df1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0df3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e00 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e30 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0e31 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e32 }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0x0e33 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0e37 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 103, 0x0e39 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0e3a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e3f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e46 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0e47 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 107, 0x0e49 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 107, 0x0e4b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0e4e }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e4f }, +{ C99|N99|CXX|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0e59 }, +{ C99| 0|CXX|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e5b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e80 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e82 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e83 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e84 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e85 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e86 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e88 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e89 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e8a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0e8b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e8c }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e8d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e93 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e97 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e98 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0e9f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ea0 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ea3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ea4 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ea5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ea6 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ea7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ea9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0eab }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0eac }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0eae }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0eaf }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0eb0 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0eb1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0eb2 }, +{ C99| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0x0eb3 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0eb7 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 118, 0x0eb9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0eba }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0ebc }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ebd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ebf }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ec4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ec5 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0ec6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ec7 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 122, 0x0ecb }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0ecd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0ecf }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0ed9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0edb }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x0edd }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0edf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0eff }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f00 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f0b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x0f0c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f17 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0f19 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f1f }, +{ C99|N99| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0f29 }, +{ C99|N99| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f33 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f34 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0f35 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f36 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0f37 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f38 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 216, 0x0f39 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f3d }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0f3f }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f42 }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0f43 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f47 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f48 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f4c }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0f4d }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f51 }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0f52 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f56 }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0f57 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f5b }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0f5c }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f68 }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x0f69 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f6c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f70 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 129, 0x0f71 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 130, 0x0f72 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0f73 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 132, 0x0f74 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0f76 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0x0f77 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0f78 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0x0f79 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 130, 0x0f7d }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0f7f }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 130, 0x0f80 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0f81 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0f83 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x0f84 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f85 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x0f87 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f8b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x0f8c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0f8f }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0f92 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0f93 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0f95 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0f96 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0f97 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0f98 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0f9c }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0f9d }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0fa1 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0fa2 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0fa6 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0fa7 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0fab }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0fac }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0fad }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0fb0 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0fb7 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0fb8 }, +{ C99| 0| 0|C11| 0|CXX23|NXX23| 0| 0| 0| 0, 0, 0x0fb9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x0fbc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0fc5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x0fc6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x0fff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1025 }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1026 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x102a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x102d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x102e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1036 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x1037 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1038 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x103a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x103e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x103f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1049 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x104f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1055 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1059 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x105d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1060 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1061 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1064 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1066 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x106d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1070 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1074 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1081 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x108c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x108d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x108e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x109d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x109f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10c5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10c6 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10c7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10cc }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10cd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10cf }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10f6 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10fa }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10fb }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x10fc }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10ff }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1159 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1160 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC|CTX, 0, 0x1175 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11a2 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11a7 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC|CTX, 0, 0x11c2 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11f9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1248 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1249 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x124d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x124f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1256 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1257 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1258 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1259 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x125d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x125f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1288 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1289 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x128d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x128f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x12b0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x12b1 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x12b5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x12b7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x12be }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x12bf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x12c0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x12c1 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x12c5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x12c7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x12d6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x12d7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1310 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1311 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1315 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1317 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x135a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x135c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x135f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1368 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1371 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x137f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x138f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x139f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x13f5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x13f7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x13fd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1400 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x166c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x166e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x167f }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1680 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x169a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x169f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16ea }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16ed }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16f8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x170c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x170d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1711 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1713 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1714 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x171f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1731 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1733 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1734 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x173f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1751 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1753 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x175f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x176c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x176d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1770 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1771 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1773 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x177f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x17b3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x17d1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x17d2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x17d3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x17d6 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x17d7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x17db }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x17dc }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x17dd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x17df }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x17e9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x180a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x180d }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x180e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x180f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1819 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x181f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1878 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x187f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x18a8 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 228, 0x18a9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x18aa }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x18af }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x18f5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x18ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x191e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x191f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x192b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x192f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1938 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 222, 0x1939 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x193a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x193b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1945 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x194f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x196d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x196f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1974 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x197f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x19ab }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x19af }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x19c9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x19cf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x19da }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x19ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1a16 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1a17 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1a18 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1a1b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1a1f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1a54 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1a5e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1a5f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1a60 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1a74 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1a7c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1a7e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1a7f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1a89 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1a8f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1a99 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1aa6 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1aa7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1aaf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1ab4 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1aba }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1abc }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1abd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1abe }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1ac0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1aff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1b04 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b05 }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1b06 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b07 }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1b08 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b09 }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1b0a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b0b }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1b0c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b0d }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1b0e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b11 }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1b12 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b33 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x1b34 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x1b35 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1b3a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x1b3b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1b3c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x1b3d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1b3f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x1b41 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1b42 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x1b43 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1b44 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b4b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1b4f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1b59 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1b6a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1b6b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1b6c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1b73 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1b7f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1b82 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1ba0 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1ba9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1bab }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1bad }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1baf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1bb9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1be5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x1be6 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1bf1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1bf3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1bff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1c23 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1c36 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x1c37 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1c3f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1c49 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1c4c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1c4f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1c59 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1c7d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1c7f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1c88 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1c8f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1cba }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1cbc }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1cbf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ccf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1cd2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1cd3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x1cd4 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1cd9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1cdb }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1cdf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1ce0 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1ce1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x1ce8 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1cec }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1ced }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1cf3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1cf4 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1cf6 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1cf7 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1cf9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1cfa }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1cff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1d2b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d2e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1d2f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d3a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1d3b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d4d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1d4e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d6a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1d77 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d78 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1d9a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1dbf }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1dc1 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1dc2 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1dc9 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1dca }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1dcc }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 234, 0x1dcd }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 214, 0x1dce }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1dcf }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 202, 0x1dd0 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1df5 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 232, 0x1df6 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 228, 0x1df8 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1df9 }, +{ 0| 0| 0|C11|N11| 0| 0|CID|NFC|NKC| 0, 0, 0x1dfa }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1dfb }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 233, 0x1dfc }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1dfd }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1dfe }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1dff }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e07 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1e09 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e13 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1e17 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e1b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1e1d }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e2d }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1e2f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e37 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1e39 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e4b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1e53 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e5b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1e5d }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e63 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1e69 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e77 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1e7b }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e99 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1e9a }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0|NFC| 0| 0, 0, 0x1e9b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e9f }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1ea3 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1eb7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1ebd }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1ec7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1ecf }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1ee3 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1ee7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1ef1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1ef9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1eff }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f15 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f17 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f1d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f1f }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f45 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f47 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f4d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f4f }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f57 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f58 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f59 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f5a }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f5b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f5c }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f5d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f5e }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f70 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1f71 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f72 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1f73 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f74 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1f75 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f76 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1f77 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f78 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1f79 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f7a }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1f7b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1f7c }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1f7d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f7f }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fb4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fb5 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fba }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1fbb }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fbc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1fbd }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1fbe }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1fc0 }, +{ 0| 0| 0|C11| 0| 0| 0| 0|NFC| 0| 0, 0, 0x1fc1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fc4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fc5 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fc8 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1fc9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fca }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1fcb }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fcc }, +{ 0| 0| 0|C11| 0| 0| 0| 0|NFC| 0| 0, 0, 0x1fcf }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fd2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1fd3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fd5 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fda }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1fdb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fdc }, +{ 0| 0| 0|C11| 0| 0| 0| 0|NFC| 0| 0, 0, 0x1fdf }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fe2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1fe3 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fea }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1feb }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1fec }, +{ 0| 0| 0|C11| 0| 0| 0| 0|NFC| 0| 0, 0, 0x1fed }, +{ 0| 0| 0|C11| 0| 0| 0| 0| 0| 0| 0, 0, 0x1fee }, +{ 0| 0| 0|C11| 0| 0| 0|CID| 0| 0| 0, 0, 0x1fef }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ff1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1ff4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ff5 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1ff8 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1ff9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1ffa }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x1ffb }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1ffc }, +{ 0| 0| 0|C11| 0| 0| 0| 0| 0| 0| 0, 0, 0x1ffd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1ffe }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fff }, +{ 0| 0| 0| 0| 0| 0| 0|CID| 0| 0| 0, 0, 0x200a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x200d }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2029 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x202e }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC| 0| 0, 0, 0x203e }, +{ C99| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x2040 }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2053 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x2054 }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x205f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x206f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2070 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2071 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2073 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x207e }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x207f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x208e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x208f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x209c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x20a7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x20a8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x20cf }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x20d1 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x20d3 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x20d7 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x20da }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x20dc }, +{ 0| 0| 0|C11|N11| 0| 0|CID|NFC|NKC| 0, 0, 0x20e0 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x20e1 }, +{ 0| 0| 0|C11|N11| 0| 0|CID|NFC|NKC| 0, 0, 0x20e4 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x20e6 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x20e7 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x20e8 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x20e9 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x20eb }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x20ef }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x20f0 }, +{ 0| 0| 0|C11|N11| 0| 0|CID|NFC|NKC| 0, 0, 0x20ff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2101 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2102 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2103 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2104 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2106 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2107 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2108 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2109 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2113 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2114 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2115 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2116 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2117 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2118 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x211d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x211f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2122 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2123 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2124 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2125 }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x2126 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2127 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2128 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2129 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID| 0| 0| 0, 0, 0x212a }, +{ C99| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x212b }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x212d }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x212e }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2131 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2132 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2138 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2139 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x213a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x213b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x213f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2140 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2144 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2149 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x214d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x214e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x214f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x215f }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x217f }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2182 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2188 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2189 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x218f }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x245f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x24ea }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x24ff }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2775 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2793 }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2bff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2c2e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2c2f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2c5e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2c5f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2c7b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2c7d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2ce4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2cea }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2cee }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x2cf1 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2cf3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2cff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2d25 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2d26 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2d27 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2d2c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2d2d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2d2f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2d67 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2d6e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x2d6f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2d7e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x2d7f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2d96 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2d9f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2da6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2da7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2dae }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2daf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2db6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2db7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2dbe }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2dbf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2dc6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2dc7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2dce }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2dcf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2dd6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2dd7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2dde }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2ddf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x2dff }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2e7f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2e9e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2e9f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2ef2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2ef3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2eff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x2fd5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2fff }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC| 0| 0, 0, 0x3003 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3004 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3007 }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3020 }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3029 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 218, 0x302a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 228, 0x302b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 232, 0x302c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 222, 0x302d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 224, 0x302f }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3030 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3035 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x3036 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3037 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x303a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x303c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3040 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x304b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x304c }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x304d }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x304e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x304f }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3050 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3051 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3052 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3053 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3054 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3055 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3056 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3057 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3058 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3059 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x305a }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x305b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x305c }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x305d }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x305e }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x305f }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3060 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3061 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3062 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3064 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3065 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3066 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3067 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3068 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3069 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x306f }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3071 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3072 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3074 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3075 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3077 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3078 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x307a }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x307b }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x307d }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3093 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x3094 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3096 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3098 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 8, 0x309a }, +{ C99| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x309c }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x309d }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x309e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x309f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x30a0 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30ab }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30ac }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30ad }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30ae }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30af }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30b0 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30b1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30b2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30b3 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30b4 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30b5 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30b6 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30b7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30b8 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30b9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30ba }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30bb }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30bc }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30bd }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30be }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30bf }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30c0 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30c1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30c2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30c4 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30c5 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30c6 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30c7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30c8 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30c9 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30cf }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30d1 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30d2 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30d4 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30d5 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30d7 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30d8 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30da }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30db }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30dd }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30f3 }, +{ C99| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30f4 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30f6 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30fa }, +{ C99| 0|CXX|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x30fb }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30fc }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x30fd }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x30fe }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x30ff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3104 }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x312c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x312f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3130 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x318e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3191 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x319f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x31bf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x31ef }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x31ff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x321e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x321f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x3247 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x324f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x327e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x327f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x33ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x4dbf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x4dff }, +{ C99| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x9fa5 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x9ffc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x9fff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa48c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa4cf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa4fd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa4ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa60c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa60f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa61f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa629 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa62b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa63f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa66e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xa66f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa673 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xa67d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa67e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa69b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xa69d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xa69f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa6ef }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xa6f1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa716 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa71f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa721 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa76f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xa770 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa788 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa78a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa7bf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa7c1 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa7ca }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa7f4 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa7f7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xa7f9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa801 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa802 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa805 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0xa806 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa80a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa80b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa822 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa827 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa82b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0xa82c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa83f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa873 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa87f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa881 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa8b3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa8c3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0xa8c4 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa8c5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa8cf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa8d9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa8df }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xa8f1 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa8f7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa8fa }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa8fb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa8fc }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa8fe }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa909 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa925 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa92a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0xa92d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa92f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa946 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa952 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0xa953 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa95f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa97c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa97f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa983 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa9b2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0xa9b3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa9bf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0xa9c0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa9ce }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa9cf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa9d9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa9df }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa9e4 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa9e5 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa9ef }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xa9f9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xa9fe }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xa9ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaa28 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xaa36 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xaa3f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaa42 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xaa43 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaa4b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xaa4d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xaa4f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xaa59 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xaa5f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaa76 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xaa79 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaa7a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xaa7d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaaaf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xaab0 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaab1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xaab3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0xaab4 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaab6 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xaab8 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaabd }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xaabf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaac0 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xaac1 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaac2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xaada }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaadd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xaadf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaaea }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xaaef }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xaaf1 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xaaf4 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xaaf5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0xaaf6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xab00 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xab06 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xab08 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xab0e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xab10 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xab16 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xab1f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xab26 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xab27 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xab2e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xab2f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xab5a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xab5b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xab5f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xab68 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xab69 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xab6f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xabe2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xabea }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xabeb }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xabec }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0xabed }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xabef }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xabf9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xabff }, +{ C99| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xd7a3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xd7af }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xd7c6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xd7ca }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xd7fb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xd7ff }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xf8ff }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfa0d }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xfa0f }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfa10 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xfa11 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfa12 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xfa14 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfa1e }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xfa1f }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfa20 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xfa21 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfa22 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xfa24 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfa26 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xfa29 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfa2d }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfa6d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfa6f }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfad9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfaff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfb06 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb12 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfb17 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb1c }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfb1d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 26, 0xfb1e }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfb1f }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfb28 }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfb29 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfb36 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb37 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfb3c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb3d }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfb3e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb3f }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfb41 }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb42 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfb44 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfb45 }, +{ 0| 0|CXX|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0xfb4e }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfbb1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfbd2 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfc5d }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfc63 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfd3d }, +{ 0| 0|CXX| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfd3f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfd4f }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfd8f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfd91 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfdc7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfdcf }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfdef }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfdf9 }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfdfb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfdfc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfdff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xfe0f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe19 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe1f }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xfe26 }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0xfe2d }, +{ 0| 0| 0|C11|N11|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0xfe2f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe32 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0xfe34 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe44 }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe46 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe4c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0xfe4f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe52 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe53 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe66 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe67 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe6b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe6f }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe70 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfe71 }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe72 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0xfe73 }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe74 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfe75 }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe76 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfe77 }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe78 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfe79 }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe7a }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfe7b }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe7c }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfe7d }, +{ 0| 0|CXX|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xfe7e }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xfefc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xff00 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xff0f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0xff19 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xff20 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xff3a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xff3e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0xff3f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xff40 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xff5a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xff65 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xff9d }, +{ 0| 0|CXX|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0xff9f }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xffbe }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffc1 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xffc7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffc9 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xffcf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffd1 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xffd7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffd9 }, +{ 0| 0|CXX|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0xffdc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffdf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xffe6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffe7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0xffee }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xfffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xffff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1000b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1000c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10026 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10027 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1003a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1003b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1003d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1003e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1004d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1004f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1005d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1007f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x100fa }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1013f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10174 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x101fc }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x101fd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1027f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1029c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1029f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x102d0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x102df }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x102e0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x102ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1031f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1032c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1034a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1034f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10375 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1037a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1037f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1039d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1039f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x103c3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x103c7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x103cf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x103d0 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x103d5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x103ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1049d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1049f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x104a9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x104af }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x104d3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x104d7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x104fb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x104ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10527 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1052f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10563 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x105ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10736 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1073f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10755 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1075f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10767 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x107ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10805 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10807 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10808 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10809 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10835 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10836 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10838 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1083b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1083c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1083e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10855 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1085f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10876 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1087f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1089e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x108df }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x108f2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x108f3 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x108f5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x108ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10915 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1091f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10939 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1097f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x109b7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x109bd }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x109bf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x109ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10a00 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x10a03 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10a04 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x10a06 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10a0b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x10a0c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x10a0d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x10a0e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x10a0f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10a13 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10a14 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10a17 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10a18 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10a35 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10a37 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x10a38 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x10a39 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x10a3a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10a3e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x10a3f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10a5f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10a7c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10a7f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10a9c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10abf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10ac7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10ac8 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10ae4 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x10ae5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x10ae6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10aff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10b35 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10b3f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10b55 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10b5f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10b72 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10b7f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10b91 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10bff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10c48 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10c7f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10cb2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10cbf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10cf2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10cff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10d23 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x10d27 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10d2f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x10d39 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10e7f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10ea9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10eaa }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x10eac }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10eaf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10eb1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10eff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10f1c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10f26 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10f27 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10f2f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10f45 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x10f47 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x10f4a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x10f4b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x10f4c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x10f50 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10faf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10fc4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10fdf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x10ff6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10fff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11002 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11037 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11045 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11046 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11065 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1106f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1107e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1107f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11082 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11099 }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1109a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1109b }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x1109c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x110aa }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0|NFC|NKC| 0, 0, 0x110ab }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x110af }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x110b8 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x110b9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 7, 0x110ba }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x110cf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x110e8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x110ef }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x110f9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x110ff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x11102 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11126 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x11127 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1112d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x1112f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11132 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11134 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11135 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1113f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11143 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11144 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11146 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11147 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1114f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11172 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x11173 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11175 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11176 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1117f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11182 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x111b2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x111bf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x111c0 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x111c4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x111c8 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x111c9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x111ca }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x111cc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x111cd }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x111d9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x111da }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x111db }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x111dc }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x111ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11211 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11212 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1122b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11234 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11235 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x11236 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11237 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1123d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1123e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1127f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11286 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11287 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11288 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11289 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1128d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1128e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1129d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1129e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x112a8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x112af }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x112de }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x112e8 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x112e9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x112ea }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x112ef }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x112f9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x112ff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11303 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11304 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1130c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1130e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11310 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11312 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11328 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11329 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11330 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11331 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11333 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11334 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11339 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1133a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x1133c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1133d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x1133e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11344 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11346 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11348 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1134a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x1134c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1134d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1134f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11350 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11356 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x11357 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1135c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11361 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11363 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11365 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1136c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1136f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x11374 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x113ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11434 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11441 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11442 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11445 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x11446 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1144a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1144f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11459 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1145d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1145e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11461 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1147f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x114af }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x114b0 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x114b9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x114ba }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x114bc }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x114bd }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x114be }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x114c1 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x114c2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x114c3 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x114c5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x114c6 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x114c7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x114cf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x114d9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1157f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x115ae }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x115af }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x115b5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x115b7 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x115b9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x115bb }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x115be }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x115bf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x115c0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x115d7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x115db }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x115dd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x115ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1162f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1163e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1163f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11640 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11643 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11644 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1164f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11659 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1167f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x116aa }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x116b5 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x116b6 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x116b7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x116b8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x116bf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x116c9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x116ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1171a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1171c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1172a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1172b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1172f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11739 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x117ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1182b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11838 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11839 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x1183a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1189f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x118df }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x118e9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x118fe }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11906 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11908 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11909 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1190b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11913 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11914 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11916 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11917 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1192f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC|CTX, 0, 0x11930 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11935 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11936 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11937 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23| 0|NFC|NKC| 0, 0, 0x11938 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1193a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1193c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x1193e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1193f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11940 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11941 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11942 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x11943 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1194f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11959 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1199f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x119a7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x119a9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x119d0 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x119d7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x119d9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x119df }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x119e0 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x119e1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x119e2 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x119e3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x119e4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x119ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11a00 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11a0a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11a32 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11a33 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11a34 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11a39 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11a3a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11a3e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11a46 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11a47 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11a4f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11a50 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11a5b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11a89 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11a98 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11a99 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11a9c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11a9d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11abf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11af8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11bff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11c08 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11c09 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11c2e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11c36 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11c37 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11c3e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11c3f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11c40 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11c4f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11c59 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11c71 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11c8f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11c91 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11ca7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11ca8 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11cb6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11cff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11d06 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d07 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11d09 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d0a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11d30 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11d36 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d39 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11d3a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d3b }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11d3d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d3e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11d41 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x11d42 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11d43 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11d45 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11d46 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11d47 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d4f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11d59 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d5f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11d65 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d66 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11d68 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d69 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11d89 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11d8e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d8f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11d91 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d92 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11d96 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 9, 0x11d97 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11d98 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11d9f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11da9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11edf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11ef2 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x11ef6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11faf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x11fb0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x11fff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x12399 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x123ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1246e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1247f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x12543 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x12fff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1342e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x143ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x14646 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x167ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16a38 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16a3f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16a5e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16a5f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x16a69 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16acf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16aed }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16aef }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x16af4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16aff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16b2f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x16b36 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16b3f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16b43 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16b4f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x16b59 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16b62 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16b77 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16b7c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16b8f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16e3f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16e7f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16eff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16f4a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16f4e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x16f4f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16f50 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x16f87 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16f8e }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x16f92 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16f9f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16fdf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16fe1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16fe2 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x16fe3 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x16fe4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16fef }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 6, 0x16ff1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x16fff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x187f7 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x187ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x18cd5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x18cff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x18d08 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1afff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b11e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1b14f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b152 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1b163 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b167 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1b16f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1b2fb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1bbff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1bc6a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1bc6f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1bc7c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1bc7f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1bc88 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1bc8f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1bc99 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1bc9c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1bc9d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x1bc9e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d15d }, +{ 0| 0| 0|C11| 0| 0| 0| 0| 0| 0| 0, 0, 0x1d164 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 216, 0x1d166 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 1, 0x1d169 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d16c }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 226, 0x1d16d }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 216, 0x1d172 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d17a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1d182 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d184 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1d189 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1d18b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d1a9 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1d1ad }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d1ba }, +{ 0| 0| 0|C11| 0| 0| 0| 0| 0| 0| 0, 0, 0x1d1c0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d241 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1d244 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d3ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d454 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d455 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d49c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d49d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d49f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d4a1 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d4a2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d4a4 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d4a6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d4a8 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d4ac }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d4ad }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d4b9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d4ba }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d4bb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d4bc }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d4c3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d4c4 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d505 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d506 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d50a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d50c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d514 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d515 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d51c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d51d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d539 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d53a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d53e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d53f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d544 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d545 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d546 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d549 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d550 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d551 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d6a5 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d6a7 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d6c0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1d6c1 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d6da }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1d6db }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d6fa }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1d6fb }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d714 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1d715 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d734 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1d735 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d74e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1d74f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d76e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1d76f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d788 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1d789 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d7a8 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1d7a9 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d7c2 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1d7c3 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1d7cb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d7cd }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0x1d7ff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1d9ff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1da36 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1da3a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1da6c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1da74 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1da75 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1da83 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1da84 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1da9a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1da9f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1daa0 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1daaf }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1dfff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1e006 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e007 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1e018 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e01a }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1e021 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e022 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1e024 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e025 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1e02a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e0ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e12c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e12f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1e136 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e13d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e13f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1e149 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e14d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e14e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e2bf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e2eb }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1e2ef }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1e2f9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e7ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e8c4 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e8cf }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 220, 0x1e8d6 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e8ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e943 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 230, 0x1e949 }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 7, 0x1e94a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x1e94b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1e94f }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0x1e959 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1edff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee03 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee04 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee1f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee20 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee22 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee23 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee24 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee26 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee27 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee28 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee32 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee33 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee37 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee38 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee39 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee3a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee3b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee41 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee42 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee46 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee47 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee48 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee49 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee4a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee4b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee4c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee4f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee50 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee52 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee53 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee54 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee56 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee57 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee58 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee59 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee5a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee5b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee5c }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee5d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee5e }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee5f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee60 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee62 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee63 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee64 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee66 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee6a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee6b }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee72 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee73 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee77 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee78 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee7c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee7d }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee7e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee7f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee89 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ee8a }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1ee9b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1eea0 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1eea3 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1eea4 }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1eea9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1eeaa }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC| 0| 0, 0, 0x1eebb }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f0ff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1f10a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f10f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1f12e }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f12f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1f14f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f169 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1f16c }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f18f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1f190 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f1ff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1f202 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f20f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1f23b }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f23f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1f248 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1f24f }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC| 0| 0, 0, 0x1f251 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fbef }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC| 0| 0, 0, 0x1fbf9 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1fffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x1ffff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2a6dd }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2a6ff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2b734 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2b73f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2b81d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2b81f }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2cea1 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2ceaf }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x2ebe0 }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2f7ff }, +{ 0| 0| 0|C11| 0|CXX23| 0| 0| 0| 0| 0, 0, 0x2fa1d }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2fffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x2ffff }, +{ 0| 0| 0|C11| 0|CXX23| 0|CID|NFC|NKC| 0, 0, 0x3134a }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3fffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x3ffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x4fffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x4ffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x5fffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x5ffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x6fffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x6ffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x7fffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x7ffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x8fffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x8ffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x9fffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x9ffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xafffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xaffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xbfffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xbffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xcfffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xcffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xdfffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xdffff }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xe00ff }, +{ 0| 0| 0|C11| 0|CXX23|NXX23|CID|NFC|NKC| 0, 0, 0xe01ef }, +{ 0| 0| 0|C11| 0| 0| 0|CID|NFC|NKC| 0, 0, 0xefffd }, +{ 0| 0| 0| 0| 0| 0| 0|CID|NFC|NKC| 0, 0, 0x10ffff }, +}; +static bool +check_nfc (cpp_reader *pfile, cppchar_t c, cppchar_t p) +{ + switch (c) + { + case 0x0300: + switch (p) + { + case 0x0041: + case 0x0045: + case 0x0049: + case 0x004f: + case 0x0055: + case 0x0061: + case 0x0065: + case 0x0069: + case 0x006f: + case 0x0075: + case 0x00dc: + case 0x00fc: + case 0x004e: + case 0x006e: + case 0x0415: + case 0x0418: + case 0x0435: + case 0x0438: + case 0x0112: + case 0x0113: + case 0x014c: + case 0x014d: + case 0x0057: + case 0x0077: + case 0x00c2: + case 0x00e2: + case 0x0102: + case 0x0103: + case 0x00ca: + case 0x00ea: + case 0x00d4: + case 0x00f4: + case 0x01a0: + case 0x01a1: + case 0x01af: + case 0x01b0: + case 0x0059: + case 0x0079: + case 0x1f00: + case 0x1f80: + case 0x1f01: + case 0x1f81: + case 0x1f08: + case 0x1f88: + case 0x1f09: + case 0x1f89: + case 0x1f10: + case 0x1f11: + case 0x1f18: + case 0x1f19: + case 0x1f20: + case 0x1f90: + case 0x1f21: + case 0x1f91: + case 0x1f28: + case 0x1f98: + case 0x1f29: + case 0x1f99: + case 0x1f30: + case 0x1f31: + case 0x1f38: + case 0x1f39: + case 0x1f40: + case 0x1f41: + case 0x1f48: + case 0x1f49: + case 0x1f50: + case 0x1f51: + case 0x1f59: + case 0x1f60: + case 0x1fa0: + case 0x1f61: + case 0x1fa1: + case 0x1f68: + case 0x1fa8: + case 0x1f69: + case 0x1fa9: + case 0x03b1: + case 0x1fb3: + case 0x03b5: + case 0x03b7: + case 0x1fc3: + case 0x03b9: + case 0x03bf: + case 0x03c5: + case 0x03c9: + case 0x1ff3: + case 0x0391: + case 0x1fbc: + case 0x0395: + case 0x0397: + case 0x1fcc: + case 0x1fbf: + case 0x03ca: + case 0x0399: + case 0x1ffe: + case 0x03cb: + case 0x03a5: + case 0x00a8: + case 0x039f: + case 0x03a9: + case 0x1ffc: + return false; + default: + return true; + } + + case 0x0301: + switch (p) + { + case 0x0041: + case 0x0045: + case 0x0049: + case 0x004f: + case 0x0055: + case 0x0059: + case 0x0061: + case 0x0065: + case 0x0069: + case 0x006f: + case 0x0075: + case 0x0079: + case 0x0043: + case 0x0063: + case 0x004c: + case 0x006c: + case 0x004e: + case 0x006e: + case 0x0052: + case 0x0072: + case 0x0053: + case 0x0073: + case 0x005a: + case 0x007a: + case 0x00dc: + case 0x00fc: + case 0x0047: + case 0x0067: + case 0x00c5: + case 0x00e5: + case 0x00c6: + case 0x00e6: + case 0x00d8: + case 0x00f8: + case 0x00a8: + case 0x0391: + case 0x1fbc: + case 0x0395: + case 0x0397: + case 0x1fcc: + case 0x0399: + case 0x039f: + case 0x03a5: + case 0x03a9: + case 0x1ffc: + case 0x03ca: + case 0x03b1: + case 0x1fb3: + case 0x03b5: + case 0x03b7: + case 0x1fc3: + case 0x03b9: + case 0x03cb: + case 0x03bf: + case 0x03c5: + case 0x03c9: + case 0x1ff3: + case 0x03d2: + case 0x0413: + case 0x041a: + case 0x0433: + case 0x043a: + case 0x00c7: + case 0x00e7: + case 0x0112: + case 0x0113: + case 0x00cf: + case 0x00ef: + case 0x004b: + case 0x006b: + case 0x004d: + case 0x006d: + case 0x00d5: + case 0x00f5: + case 0x014c: + case 0x014d: + case 0x0050: + case 0x0070: + case 0x0168: + case 0x0169: + case 0x0057: + case 0x0077: + case 0x00c2: + case 0x00e2: + case 0x0102: + case 0x0103: + case 0x00ca: + case 0x00ea: + case 0x00d4: + case 0x00f4: + case 0x01a0: + case 0x01a1: + case 0x01af: + case 0x01b0: + case 0x1f00: + case 0x1f80: + case 0x1f01: + case 0x1f81: + case 0x1f08: + case 0x1f88: + case 0x1f09: + case 0x1f89: + case 0x1f10: + case 0x1f11: + case 0x1f18: + case 0x1f19: + case 0x1f20: + case 0x1f90: + case 0x1f21: + case 0x1f91: + case 0x1f28: + case 0x1f98: + case 0x1f29: + case 0x1f99: + case 0x1f30: + case 0x1f31: + case 0x1f38: + case 0x1f39: + case 0x1f40: + case 0x1f41: + case 0x1f48: + case 0x1f49: + case 0x1f50: + case 0x1f51: + case 0x1f59: + case 0x1f60: + case 0x1fa0: + case 0x1f61: + case 0x1fa1: + case 0x1f68: + case 0x1fa8: + case 0x1f69: + case 0x1fa9: + case 0x1fbf: + case 0x1ffe: + return false; + default: + return true; + } + + case 0x0302: + switch (p) + { + case 0x0041: + case 0x0045: + case 0x0049: + case 0x004f: + case 0x0055: + case 0x0061: + case 0x0065: + case 0x0069: + case 0x006f: + case 0x0075: + case 0x0043: + case 0x0063: + case 0x0047: + case 0x0067: + case 0x0048: + case 0x0068: + case 0x004a: + case 0x006a: + case 0x0053: + case 0x0073: + case 0x0057: + case 0x0077: + case 0x0059: + case 0x0079: + case 0x005a: + case 0x007a: + case 0x1ea0: + case 0x1ea1: + case 0x1eb8: + case 0x1eb9: + case 0x1ecc: + case 0x1ecd: + return false; + default: + return true; + } + + case 0x0303: + switch (p) + { + case 0x0041: + case 0x004e: + case 0x004f: + case 0x0061: + case 0x006e: + case 0x006f: + case 0x0049: + case 0x0069: + case 0x0055: + case 0x0075: + case 0x0056: + case 0x0076: + case 0x00c2: + case 0x00e2: + case 0x0102: + case 0x0103: + case 0x0045: + case 0x0065: + case 0x00ca: + case 0x00ea: + case 0x00d4: + case 0x00f4: + case 0x01a0: + case 0x01a1: + case 0x01af: + case 0x01b0: + case 0x0059: + case 0x0079: + return false; + default: + return true; + } + + case 0x0304: + switch (p) + { + case 0x0041: + case 0x0061: + case 0x0045: + case 0x0065: + case 0x0049: + case 0x0069: + case 0x004f: + case 0x006f: + case 0x0055: + case 0x0075: + case 0x00dc: + case 0x00fc: + case 0x00c4: + case 0x00e4: + case 0x0226: + case 0x0227: + case 0x00c6: + case 0x00e6: + case 0x01ea: + case 0x01eb: + case 0x00d6: + case 0x00f6: + case 0x00d5: + case 0x00f5: + case 0x022e: + case 0x022f: + case 0x0059: + case 0x0079: + case 0x0418: + case 0x0438: + case 0x0423: + case 0x0443: + case 0x0047: + case 0x0067: + case 0x1e36: + case 0x1e37: + case 0x1e5a: + case 0x1e5b: + case 0x03b1: + case 0x1fb3: + case 0x0391: + case 0x1fbc: + case 0x03b9: + case 0x0399: + case 0x03c5: + case 0x03a5: + return false; + default: + return true; + } + + case 0x0306: + switch (p) + { + case 0x0041: + case 0x0061: + case 0x0045: + case 0x0065: + case 0x0047: + case 0x0067: + case 0x0049: + case 0x0069: + case 0x004f: + case 0x006f: + case 0x0055: + case 0x0075: + case 0x0423: + case 0x0418: + case 0x0438: + case 0x0443: + case 0x0416: + case 0x0436: + case 0x0410: + case 0x0430: + case 0x0415: + case 0x0435: + case 0x0228: + case 0x0229: + case 0x1ea0: + case 0x1ea1: + case 0x03b1: + case 0x1fb3: + case 0x0391: + case 0x1fbc: + case 0x03b9: + case 0x0399: + case 0x03c5: + case 0x03a5: + return false; + default: + return true; + } + + case 0x0307: + switch (p) + { + case 0x0043: + case 0x0063: + case 0x0045: + case 0x0065: + case 0x0047: + case 0x0067: + case 0x0049: + case 0x005a: + case 0x007a: + case 0x0041: + case 0x0061: + case 0x004f: + case 0x006f: + case 0x0042: + case 0x0062: + case 0x0044: + case 0x0064: + case 0x0046: + case 0x0066: + case 0x0048: + case 0x0068: + case 0x004d: + case 0x006d: + case 0x004e: + case 0x006e: + case 0x0050: + case 0x0070: + case 0x0052: + case 0x0072: + case 0x0053: + case 0x0073: + case 0x015a: + case 0x015b: + case 0x0160: + case 0x0161: + case 0x1e62: + case 0x1e63: + case 0x0054: + case 0x0074: + case 0x0057: + case 0x0077: + case 0x0058: + case 0x0078: + case 0x0059: + case 0x0079: + case 0x017f: + return false; + default: + return true; + } + + case 0x0308: + switch (p) + { + case 0x0041: + case 0x0045: + case 0x0049: + case 0x004f: + case 0x0055: + case 0x0061: + case 0x0065: + case 0x0069: + case 0x006f: + case 0x0075: + case 0x0079: + case 0x0059: + case 0x0399: + case 0x03a5: + case 0x03b9: + case 0x03c5: + case 0x03d2: + case 0x0415: + case 0x0406: + case 0x0435: + case 0x0456: + case 0x0410: + case 0x0430: + case 0x04d8: + case 0x04d9: + case 0x0416: + case 0x0436: + case 0x0417: + case 0x0437: + case 0x0418: + case 0x0438: + case 0x041e: + case 0x043e: + case 0x04e8: + case 0x04e9: + case 0x042d: + case 0x044d: + case 0x0423: + case 0x0443: + case 0x0427: + case 0x0447: + case 0x042b: + case 0x044b: + case 0x0048: + case 0x0068: + case 0x00d5: + case 0x00f5: + case 0x016a: + case 0x016b: + case 0x0057: + case 0x0077: + case 0x0058: + case 0x0078: + case 0x0074: + return false; + default: + return true; + } + + case 0x0309: + switch (p) + { + case 0x0041: + case 0x0061: + case 0x00c2: + case 0x00e2: + case 0x0102: + case 0x0103: + case 0x0045: + case 0x0065: + case 0x00ca: + case 0x00ea: + case 0x0049: + case 0x0069: + case 0x004f: + case 0x006f: + case 0x00d4: + case 0x00f4: + case 0x01a0: + case 0x01a1: + case 0x0055: + case 0x0075: + case 0x01af: + case 0x01b0: + case 0x0059: + case 0x0079: + return false; + default: + return true; + } + + case 0x030a: + switch (p) + { + case 0x0041: + case 0x0061: + case 0x0055: + case 0x0075: + case 0x0077: + case 0x0079: + return false; + default: + return true; + } + + case 0x030b: + switch (p) + { + case 0x004f: + case 0x006f: + case 0x0055: + case 0x0075: + case 0x0423: + case 0x0443: + return false; + default: + return true; + } + + case 0x030c: + switch (p) + { + case 0x0043: + case 0x0063: + case 0x0044: + case 0x0064: + case 0x0045: + case 0x0065: + case 0x004c: + case 0x006c: + case 0x004e: + case 0x006e: + case 0x0052: + case 0x0072: + case 0x0053: + case 0x0073: + case 0x0054: + case 0x0074: + case 0x005a: + case 0x007a: + case 0x0041: + case 0x0061: + case 0x0049: + case 0x0069: + case 0x004f: + case 0x006f: + case 0x0055: + case 0x0075: + case 0x00dc: + case 0x00fc: + case 0x0047: + case 0x0067: + case 0x004b: + case 0x006b: + case 0x01b7: + case 0x0292: + case 0x006a: + case 0x0048: + case 0x0068: + return false; + default: + return true; + } + + case 0x030f: + switch (p) + { + case 0x0041: + case 0x0061: + case 0x0045: + case 0x0065: + case 0x0049: + case 0x0069: + case 0x004f: + case 0x006f: + case 0x0052: + case 0x0072: + case 0x0055: + case 0x0075: + case 0x0474: + case 0x0475: + return false; + default: + return true; + } + + case 0x0311: + switch (p) + { + case 0x0041: + case 0x0061: + case 0x0045: + case 0x0065: + case 0x0049: + case 0x0069: + case 0x004f: + case 0x006f: + case 0x0052: + case 0x0072: + case 0x0055: + case 0x0075: + return false; + default: + return true; + } + + case 0x0313: + switch (p) + { + case 0x03b1: + case 0x1fb3: + case 0x0391: + case 0x1fbc: + case 0x03b5: + case 0x0395: + case 0x03b7: + case 0x1fc3: + case 0x0397: + case 0x1fcc: + case 0x03b9: + case 0x0399: + case 0x03bf: + case 0x039f: + case 0x03c5: + case 0x03c9: + case 0x1ff3: + case 0x03a9: + case 0x1ffc: + case 0x03c1: + return false; + default: + return true; + } + + case 0x0314: + switch (p) + { + case 0x03b1: + case 0x1fb3: + case 0x0391: + case 0x1fbc: + case 0x03b5: + case 0x0395: + case 0x03b7: + case 0x1fc3: + case 0x0397: + case 0x1fcc: + case 0x03b9: + case 0x0399: + case 0x03bf: + case 0x039f: + case 0x03c5: + case 0x03a5: + case 0x03c9: + case 0x1ff3: + case 0x03a9: + case 0x1ffc: + case 0x03c1: + case 0x03a1: + return false; + default: + return true; + } + + case 0x031b: + switch (p) + { + case 0x004f: + case 0x00d2: + case 0x00d3: + case 0x00d4: + case 0x00d5: + case 0x00d6: + case 0x014c: + case 0x014e: + case 0x0150: + case 0x01d1: + case 0x020c: + case 0x020e: + case 0x022a: + case 0x022c: + case 0x022e: + case 0x0230: + case 0x1e4c: + case 0x1e4e: + case 0x1e50: + case 0x1e52: + case 0x1ecc: + case 0x1ece: + case 0x1ed0: + case 0x1ed2: + case 0x1ed4: + case 0x1ed6: + case 0x1ed8: + case 0x006f: + case 0x00f2: + case 0x00f3: + case 0x00f4: + case 0x00f5: + case 0x00f6: + case 0x014d: + case 0x014f: + case 0x0151: + case 0x01d2: + case 0x020d: + case 0x020f: + case 0x022b: + case 0x022d: + case 0x022f: + case 0x0231: + case 0x1e4d: + case 0x1e4f: + case 0x1e51: + case 0x1e53: + case 0x1ecd: + case 0x1ecf: + case 0x1ed1: + case 0x1ed3: + case 0x1ed5: + case 0x1ed7: + case 0x1ed9: + case 0x0055: + case 0x00d9: + case 0x00da: + case 0x00db: + case 0x00dc: + case 0x0168: + case 0x016a: + case 0x016c: + case 0x016e: + case 0x0170: + case 0x01d3: + case 0x01d5: + case 0x01d7: + case 0x01d9: + case 0x01db: + case 0x0214: + case 0x0216: + case 0x1e72: + case 0x1e74: + case 0x1e76: + case 0x1e78: + case 0x1e7a: + case 0x1ee4: + case 0x1ee6: + case 0x0075: + case 0x00f9: + case 0x00fa: + case 0x00fb: + case 0x00fc: + case 0x0169: + case 0x016b: + case 0x016d: + case 0x016f: + case 0x0171: + case 0x01d4: + case 0x01d6: + case 0x01d8: + case 0x01da: + case 0x01dc: + case 0x0215: + case 0x0217: + case 0x1e73: + case 0x1e75: + case 0x1e77: + case 0x1e79: + case 0x1e7b: + case 0x1ee5: + case 0x1ee7: + return false; + default: + return true; + } + + case 0x0323: + switch (p) + { + case 0x0042: + case 0x1e02: + case 0x0062: + case 0x1e03: + case 0x0044: + case 0x010e: + case 0x1e0a: + case 0x0064: + case 0x010f: + case 0x1e0b: + case 0x0048: + case 0x0124: + case 0x021e: + case 0x1e22: + case 0x1e26: + case 0x0068: + case 0x0125: + case 0x021f: + case 0x1e23: + case 0x1e27: + case 0x004b: + case 0x01e8: + case 0x1e30: + case 0x006b: + case 0x01e9: + case 0x1e31: + case 0x004c: + case 0x0139: + case 0x013d: + case 0x006c: + case 0x013a: + case 0x013e: + case 0x004d: + case 0x1e3e: + case 0x1e40: + case 0x006d: + case 0x1e3f: + case 0x1e41: + case 0x004e: + case 0x00d1: + case 0x0143: + case 0x0147: + case 0x01f8: + case 0x1e44: + case 0x006e: + case 0x00f1: + case 0x0144: + case 0x0148: + case 0x01f9: + case 0x1e45: + case 0x0052: + case 0x0154: + case 0x0158: + case 0x0210: + case 0x0212: + case 0x1e58: + case 0x0072: + case 0x0155: + case 0x0159: + case 0x0211: + case 0x0213: + case 0x1e59: + case 0x0053: + case 0x015a: + case 0x015c: + case 0x0160: + case 0x1e60: + case 0x1e64: + case 0x1e66: + case 0x0073: + case 0x015b: + case 0x015d: + case 0x0161: + case 0x1e61: + case 0x1e65: + case 0x1e67: + case 0x0054: + case 0x0164: + case 0x1e6a: + case 0x0074: + case 0x0165: + case 0x1e6b: + case 0x1e97: + case 0x0056: + case 0x1e7c: + case 0x0076: + case 0x1e7d: + case 0x0057: + case 0x0174: + case 0x1e80: + case 0x1e82: + case 0x1e84: + case 0x1e86: + case 0x0077: + case 0x0175: + case 0x1e81: + case 0x1e83: + case 0x1e85: + case 0x1e87: + case 0x1e98: + case 0x005a: + case 0x0179: + case 0x017b: + case 0x017d: + case 0x1e90: + case 0x007a: + case 0x017a: + case 0x017c: + case 0x017e: + case 0x1e91: + case 0x0041: + case 0x00c0: + case 0x00c1: + case 0x00c2: + case 0x00c3: + case 0x00c4: + case 0x00c5: + case 0x0100: + case 0x0102: + case 0x01cd: + case 0x01de: + case 0x01e0: + case 0x01fa: + case 0x0200: + case 0x0202: + case 0x0226: + case 0x1ea2: + case 0x1ea4: + case 0x1ea6: + case 0x1ea8: + case 0x1eaa: + case 0x1eae: + case 0x1eb0: + case 0x1eb2: + case 0x1eb4: + case 0x0061: + case 0x00e0: + case 0x00e1: + case 0x00e2: + case 0x00e3: + case 0x00e4: + case 0x00e5: + case 0x0101: + case 0x0103: + case 0x01ce: + case 0x01df: + case 0x01e1: + case 0x01fb: + case 0x0201: + case 0x0203: + case 0x0227: + case 0x1ea3: + case 0x1ea5: + case 0x1ea7: + case 0x1ea9: + case 0x1eab: + case 0x1eaf: + case 0x1eb1: + case 0x1eb3: + case 0x1eb5: + case 0x0045: + case 0x00c8: + case 0x00c9: + case 0x00ca: + case 0x00cb: + case 0x0112: + case 0x0114: + case 0x0116: + case 0x011a: + case 0x0204: + case 0x0206: + case 0x1e14: + case 0x1e16: + case 0x1eba: + case 0x1ebc: + case 0x1ebe: + case 0x1ec0: + case 0x1ec2: + case 0x1ec4: + case 0x0065: + case 0x00e8: + case 0x00e9: + case 0x00ea: + case 0x00eb: + case 0x0113: + case 0x0115: + case 0x0117: + case 0x011b: + case 0x0205: + case 0x0207: + case 0x1e15: + case 0x1e17: + case 0x1ebb: + case 0x1ebd: + case 0x1ebf: + case 0x1ec1: + case 0x1ec3: + case 0x1ec5: + case 0x0049: + case 0x00cc: + case 0x00cd: + case 0x00ce: + case 0x00cf: + case 0x0128: + case 0x012a: + case 0x012c: + case 0x0130: + case 0x01cf: + case 0x0208: + case 0x020a: + case 0x1e2e: + case 0x1ec8: + case 0x0069: + case 0x00ec: + case 0x00ed: + case 0x00ee: + case 0x00ef: + case 0x0129: + case 0x012b: + case 0x012d: + case 0x01d0: + case 0x0209: + case 0x020b: + case 0x1e2f: + case 0x1ec9: + case 0x004f: + case 0x00d2: + case 0x00d3: + case 0x00d4: + case 0x00d5: + case 0x00d6: + case 0x014c: + case 0x014e: + case 0x0150: + case 0x01d1: + case 0x020c: + case 0x020e: + case 0x022a: + case 0x022c: + case 0x022e: + case 0x0230: + case 0x1e4c: + case 0x1e4e: + case 0x1e50: + case 0x1e52: + case 0x1ece: + case 0x1ed0: + case 0x1ed2: + case 0x1ed4: + case 0x1ed6: + case 0x006f: + case 0x00f2: + case 0x00f3: + case 0x00f4: + case 0x00f5: + case 0x00f6: + case 0x014d: + case 0x014f: + case 0x0151: + case 0x01d2: + case 0x020d: + case 0x020f: + case 0x022b: + case 0x022d: + case 0x022f: + case 0x0231: + case 0x1e4d: + case 0x1e4f: + case 0x1e51: + case 0x1e53: + case 0x1ecf: + case 0x1ed1: + case 0x1ed3: + case 0x1ed5: + case 0x1ed7: + case 0x01a0: + case 0x1eda: + case 0x1edc: + case 0x1ede: + case 0x1ee0: + case 0x01a1: + case 0x1edb: + case 0x1edd: + case 0x1edf: + case 0x1ee1: + case 0x0055: + case 0x00d9: + case 0x00da: + case 0x00db: + case 0x00dc: + case 0x0168: + case 0x016a: + case 0x016c: + case 0x016e: + case 0x0170: + case 0x01d3: + case 0x01d5: + case 0x01d7: + case 0x01d9: + case 0x01db: + case 0x0214: + case 0x0216: + case 0x1e78: + case 0x1e7a: + case 0x1ee6: + case 0x0075: + case 0x00f9: + case 0x00fa: + case 0x00fb: + case 0x00fc: + case 0x0169: + case 0x016b: + case 0x016d: + case 0x016f: + case 0x0171: + case 0x01d4: + case 0x01d6: + case 0x01d8: + case 0x01da: + case 0x01dc: + case 0x0215: + case 0x0217: + case 0x1e79: + case 0x1e7b: + case 0x1ee7: + case 0x01af: + case 0x1ee8: + case 0x1eea: + case 0x1eec: + case 0x1eee: + case 0x01b0: + case 0x1ee9: + case 0x1eeb: + case 0x1eed: + case 0x1eef: + case 0x0059: + case 0x00dd: + case 0x0176: + case 0x0178: + case 0x0232: + case 0x1e8e: + case 0x1ef2: + case 0x1ef6: + case 0x1ef8: + case 0x0079: + case 0x00fd: + case 0x00ff: + case 0x0177: + case 0x0233: + case 0x1e8f: + case 0x1e99: + case 0x1ef3: + case 0x1ef7: + case 0x1ef9: + return false; + default: + return true; + } + + case 0x0324: + switch (p) + { + case 0x0055: + case 0x00d9: + case 0x00da: + case 0x00db: + case 0x00dc: + case 0x0168: + case 0x016a: + case 0x016c: + case 0x016e: + case 0x0170: + case 0x01d3: + case 0x01d5: + case 0x01d7: + case 0x01d9: + case 0x01db: + case 0x0214: + case 0x0216: + case 0x1e78: + case 0x1e7a: + case 0x1ee6: + case 0x0075: + case 0x00f9: + case 0x00fa: + case 0x00fb: + case 0x00fc: + case 0x0169: + case 0x016b: + case 0x016d: + case 0x016f: + case 0x0171: + case 0x01d4: + case 0x01d6: + case 0x01d8: + case 0x01da: + case 0x01dc: + case 0x0215: + case 0x0217: + case 0x1e79: + case 0x1e7b: + case 0x1ee7: + return false; + default: + return true; + } + + case 0x0325: + switch (p) + { + case 0x0041: + case 0x00c0: + case 0x00c1: + case 0x00c2: + case 0x00c3: + case 0x00c4: + case 0x00c5: + case 0x0100: + case 0x0102: + case 0x01cd: + case 0x01de: + case 0x01e0: + case 0x01fa: + case 0x0200: + case 0x0202: + case 0x0226: + case 0x1ea2: + case 0x1ea4: + case 0x1ea6: + case 0x1ea8: + case 0x1eaa: + case 0x1eae: + case 0x1eb0: + case 0x1eb2: + case 0x1eb4: + case 0x0061: + case 0x00e0: + case 0x00e1: + case 0x00e2: + case 0x00e3: + case 0x00e4: + case 0x00e5: + case 0x0101: + case 0x0103: + case 0x01ce: + case 0x01df: + case 0x01e1: + case 0x01fb: + case 0x0201: + case 0x0203: + case 0x0227: + case 0x1ea3: + case 0x1ea5: + case 0x1ea7: + case 0x1ea9: + case 0x1eab: + case 0x1eaf: + case 0x1eb1: + case 0x1eb3: + case 0x1eb5: + return false; + default: + return true; + } + + case 0x0326: + switch (p) + { + case 0x0053: + case 0x015a: + case 0x015c: + case 0x0160: + case 0x1e60: + case 0x1e64: + case 0x1e66: + case 0x0073: + case 0x015b: + case 0x015d: + case 0x0161: + case 0x1e61: + case 0x1e65: + case 0x1e67: + case 0x0054: + case 0x0164: + case 0x1e6a: + case 0x0074: + case 0x0165: + case 0x1e6b: + case 0x1e97: + return false; + default: + return true; + } + + case 0x0327: + switch (p) + { + case 0x0043: + case 0x0106: + case 0x0108: + case 0x010a: + case 0x010c: + case 0x0063: + case 0x0107: + case 0x0109: + case 0x010b: + case 0x010d: + case 0x0047: + case 0x011c: + case 0x011e: + case 0x0120: + case 0x01e6: + case 0x01f4: + case 0x1e20: + case 0x0067: + case 0x011d: + case 0x011f: + case 0x0121: + case 0x01e7: + case 0x01f5: + case 0x1e21: + case 0x004b: + case 0x01e8: + case 0x1e30: + case 0x1e32: + case 0x1e34: + case 0x006b: + case 0x01e9: + case 0x1e31: + case 0x1e33: + case 0x1e35: + case 0x004c: + case 0x0139: + case 0x013d: + case 0x1e36: + case 0x1e38: + case 0x1e3a: + case 0x1e3c: + case 0x006c: + case 0x013a: + case 0x013e: + case 0x1e37: + case 0x1e39: + case 0x1e3b: + case 0x1e3d: + case 0x004e: + case 0x00d1: + case 0x0143: + case 0x0147: + case 0x01f8: + case 0x1e44: + case 0x1e46: + case 0x1e48: + case 0x1e4a: + case 0x006e: + case 0x00f1: + case 0x0144: + case 0x0148: + case 0x01f9: + case 0x1e45: + case 0x1e47: + case 0x1e49: + case 0x1e4b: + case 0x0052: + case 0x0154: + case 0x0158: + case 0x0210: + case 0x0212: + case 0x1e58: + case 0x1e5a: + case 0x1e5c: + case 0x1e5e: + case 0x0072: + case 0x0155: + case 0x0159: + case 0x0211: + case 0x0213: + case 0x1e59: + case 0x1e5b: + case 0x1e5d: + case 0x1e5f: + case 0x0053: + case 0x015a: + case 0x015c: + case 0x0160: + case 0x0218: + case 0x1e60: + case 0x1e62: + case 0x1e64: + case 0x1e66: + case 0x1e68: + case 0x0073: + case 0x015b: + case 0x015d: + case 0x0161: + case 0x0219: + case 0x1e61: + case 0x1e63: + case 0x1e65: + case 0x1e67: + case 0x1e69: + case 0x0054: + case 0x0164: + case 0x021a: + case 0x1e6a: + case 0x1e6c: + case 0x1e6e: + case 0x1e70: + case 0x0074: + case 0x0165: + case 0x021b: + case 0x1e6b: + case 0x1e6d: + case 0x1e6f: + case 0x1e71: + case 0x1e97: + case 0x0045: + case 0x00c8: + case 0x00c9: + case 0x00ca: + case 0x00cb: + case 0x0112: + case 0x0114: + case 0x0116: + case 0x011a: + case 0x0204: + case 0x0206: + case 0x1e14: + case 0x1e16: + case 0x1e18: + case 0x1e1a: + case 0x1eb8: + case 0x1eba: + case 0x1ebc: + case 0x1ebe: + case 0x1ec0: + case 0x1ec2: + case 0x1ec4: + case 0x1ec6: + case 0x0065: + case 0x00e8: + case 0x00e9: + case 0x00ea: + case 0x00eb: + case 0x0113: + case 0x0115: + case 0x0117: + case 0x011b: + case 0x0205: + case 0x0207: + case 0x1e15: + case 0x1e17: + case 0x1e19: + case 0x1e1b: + case 0x1eb9: + case 0x1ebb: + case 0x1ebd: + case 0x1ebf: + case 0x1ec1: + case 0x1ec3: + case 0x1ec5: + case 0x1ec7: + case 0x0044: + case 0x010e: + case 0x1e0a: + case 0x1e0c: + case 0x1e0e: + case 0x1e12: + case 0x0064: + case 0x010f: + case 0x1e0b: + case 0x1e0d: + case 0x1e0f: + case 0x1e13: + case 0x0048: + case 0x0124: + case 0x021e: + case 0x1e22: + case 0x1e24: + case 0x1e26: + case 0x1e2a: + case 0x0068: + case 0x0125: + case 0x021f: + case 0x1e23: + case 0x1e25: + case 0x1e27: + case 0x1e2b: + case 0x1e96: + return false; + default: + return true; + } + + case 0x0328: + switch (p) + { + case 0x0041: + case 0x00c0: + case 0x00c1: + case 0x00c2: + case 0x00c3: + case 0x00c4: + case 0x00c5: + case 0x0100: + case 0x0102: + case 0x01cd: + case 0x01de: + case 0x01e0: + case 0x01fa: + case 0x0200: + case 0x0202: + case 0x0226: + case 0x1e00: + case 0x1ea0: + case 0x1ea2: + case 0x1ea4: + case 0x1ea6: + case 0x1ea8: + case 0x1eaa: + case 0x1eac: + case 0x1eae: + case 0x1eb0: + case 0x1eb2: + case 0x1eb4: + case 0x1eb6: + case 0x0061: + case 0x00e0: + case 0x00e1: + case 0x00e2: + case 0x00e3: + case 0x00e4: + case 0x00e5: + case 0x0101: + case 0x0103: + case 0x01ce: + case 0x01df: + case 0x01e1: + case 0x01fb: + case 0x0201: + case 0x0203: + case 0x0227: + case 0x1e01: + case 0x1ea1: + case 0x1ea3: + case 0x1ea5: + case 0x1ea7: + case 0x1ea9: + case 0x1eab: + case 0x1ead: + case 0x1eaf: + case 0x1eb1: + case 0x1eb3: + case 0x1eb5: + case 0x1eb7: + case 0x0045: + case 0x00c8: + case 0x00c9: + case 0x00ca: + case 0x00cb: + case 0x0112: + case 0x0114: + case 0x0116: + case 0x011a: + case 0x0204: + case 0x0206: + case 0x1e14: + case 0x1e16: + case 0x1e18: + case 0x1e1a: + case 0x1eb8: + case 0x1eba: + case 0x1ebc: + case 0x1ebe: + case 0x1ec0: + case 0x1ec2: + case 0x1ec4: + case 0x1ec6: + case 0x0065: + case 0x00e8: + case 0x00e9: + case 0x00ea: + case 0x00eb: + case 0x0113: + case 0x0115: + case 0x0117: + case 0x011b: + case 0x0205: + case 0x0207: + case 0x1e15: + case 0x1e17: + case 0x1e19: + case 0x1e1b: + case 0x1eb9: + case 0x1ebb: + case 0x1ebd: + case 0x1ebf: + case 0x1ec1: + case 0x1ec3: + case 0x1ec5: + case 0x1ec7: + case 0x0049: + case 0x00cc: + case 0x00cd: + case 0x00ce: + case 0x00cf: + case 0x0128: + case 0x012a: + case 0x012c: + case 0x0130: + case 0x01cf: + case 0x0208: + case 0x020a: + case 0x1e2c: + case 0x1e2e: + case 0x1ec8: + case 0x1eca: + case 0x0069: + case 0x00ec: + case 0x00ed: + case 0x00ee: + case 0x00ef: + case 0x0129: + case 0x012b: + case 0x012d: + case 0x01d0: + case 0x0209: + case 0x020b: + case 0x1e2d: + case 0x1e2f: + case 0x1ec9: + case 0x1ecb: + case 0x0055: + case 0x00d9: + case 0x00da: + case 0x00db: + case 0x00dc: + case 0x0168: + case 0x016a: + case 0x016c: + case 0x016e: + case 0x0170: + case 0x01af: + case 0x01d3: + case 0x01d5: + case 0x01d7: + case 0x01d9: + case 0x01db: + case 0x0214: + case 0x0216: + case 0x1e72: + case 0x1e74: + case 0x1e76: + case 0x1e78: + case 0x1e7a: + case 0x1ee4: + case 0x1ee6: + case 0x1ee8: + case 0x1eea: + case 0x1eec: + case 0x1eee: + case 0x1ef0: + case 0x0075: + case 0x00f9: + case 0x00fa: + case 0x00fb: + case 0x00fc: + case 0x0169: + case 0x016b: + case 0x016d: + case 0x016f: + case 0x0171: + case 0x01b0: + case 0x01d4: + case 0x01d6: + case 0x01d8: + case 0x01da: + case 0x01dc: + case 0x0215: + case 0x0217: + case 0x1e73: + case 0x1e75: + case 0x1e77: + case 0x1e79: + case 0x1e7b: + case 0x1ee5: + case 0x1ee7: + case 0x1ee9: + case 0x1eeb: + case 0x1eed: + case 0x1eef: + case 0x1ef1: + case 0x004f: + case 0x00d2: + case 0x00d3: + case 0x00d4: + case 0x00d5: + case 0x00d6: + case 0x014c: + case 0x014e: + case 0x0150: + case 0x01a0: + case 0x01d1: + case 0x020c: + case 0x020e: + case 0x022a: + case 0x022c: + case 0x022e: + case 0x0230: + case 0x1e4c: + case 0x1e4e: + case 0x1e50: + case 0x1e52: + case 0x1ecc: + case 0x1ece: + case 0x1ed0: + case 0x1ed2: + case 0x1ed4: + case 0x1ed6: + case 0x1ed8: + case 0x1eda: + case 0x1edc: + case 0x1ede: + case 0x1ee0: + case 0x1ee2: + case 0x006f: + case 0x00f2: + case 0x00f3: + case 0x00f4: + case 0x00f5: + case 0x00f6: + case 0x014d: + case 0x014f: + case 0x0151: + case 0x01a1: + case 0x01d2: + case 0x020d: + case 0x020f: + case 0x022b: + case 0x022d: + case 0x022f: + case 0x0231: + case 0x1e4d: + case 0x1e4f: + case 0x1e51: + case 0x1e53: + case 0x1ecd: + case 0x1ecf: + case 0x1ed1: + case 0x1ed3: + case 0x1ed5: + case 0x1ed7: + case 0x1ed9: + case 0x1edb: + case 0x1edd: + case 0x1edf: + case 0x1ee1: + case 0x1ee3: + return false; + default: + return true; + } + + case 0x032d: + switch (p) + { + case 0x0044: + case 0x010e: + case 0x1e0a: + case 0x0064: + case 0x010f: + case 0x1e0b: + case 0x0045: + case 0x00c8: + case 0x00c9: + case 0x00ca: + case 0x00cb: + case 0x0112: + case 0x0114: + case 0x0116: + case 0x011a: + case 0x0204: + case 0x0206: + case 0x1e14: + case 0x1e16: + case 0x1eba: + case 0x1ebc: + case 0x1ebe: + case 0x1ec0: + case 0x1ec2: + case 0x1ec4: + case 0x0065: + case 0x00e8: + case 0x00e9: + case 0x00ea: + case 0x00eb: + case 0x0113: + case 0x0115: + case 0x0117: + case 0x011b: + case 0x0205: + case 0x0207: + case 0x1e15: + case 0x1e17: + case 0x1ebb: + case 0x1ebd: + case 0x1ebf: + case 0x1ec1: + case 0x1ec3: + case 0x1ec5: + case 0x004c: + case 0x0139: + case 0x013d: + case 0x006c: + case 0x013a: + case 0x013e: + case 0x004e: + case 0x00d1: + case 0x0143: + case 0x0147: + case 0x01f8: + case 0x1e44: + case 0x006e: + case 0x00f1: + case 0x0144: + case 0x0148: + case 0x01f9: + case 0x1e45: + case 0x0054: + case 0x0164: + case 0x1e6a: + case 0x0074: + case 0x0165: + case 0x1e6b: + case 0x1e97: + case 0x0055: + case 0x00d9: + case 0x00da: + case 0x00db: + case 0x00dc: + case 0x0168: + case 0x016a: + case 0x016c: + case 0x016e: + case 0x0170: + case 0x01d3: + case 0x01d5: + case 0x01d7: + case 0x01d9: + case 0x01db: + case 0x0214: + case 0x0216: + case 0x1e78: + case 0x1e7a: + case 0x1ee6: + case 0x0075: + case 0x00f9: + case 0x00fa: + case 0x00fb: + case 0x00fc: + case 0x0169: + case 0x016b: + case 0x016d: + case 0x016f: + case 0x0171: + case 0x01d4: + case 0x01d6: + case 0x01d8: + case 0x01da: + case 0x01dc: + case 0x0215: + case 0x0217: + case 0x1e79: + case 0x1e7b: + case 0x1ee7: + return false; + default: + return true; + } + + case 0x032e: + switch (p) + { + case 0x0048: + case 0x0124: + case 0x021e: + case 0x1e22: + case 0x1e26: + case 0x0068: + case 0x0125: + case 0x021f: + case 0x1e23: + case 0x1e27: + return false; + default: + return true; + } + + case 0x0330: + switch (p) + { + case 0x0045: + case 0x00c8: + case 0x00c9: + case 0x00ca: + case 0x00cb: + case 0x0112: + case 0x0114: + case 0x0116: + case 0x011a: + case 0x0204: + case 0x0206: + case 0x1e14: + case 0x1e16: + case 0x1eba: + case 0x1ebc: + case 0x1ebe: + case 0x1ec0: + case 0x1ec2: + case 0x1ec4: + case 0x0065: + case 0x00e8: + case 0x00e9: + case 0x00ea: + case 0x00eb: + case 0x0113: + case 0x0115: + case 0x0117: + case 0x011b: + case 0x0205: + case 0x0207: + case 0x1e15: + case 0x1e17: + case 0x1ebb: + case 0x1ebd: + case 0x1ebf: + case 0x1ec1: + case 0x1ec3: + case 0x1ec5: + case 0x0049: + case 0x00cc: + case 0x00cd: + case 0x00ce: + case 0x00cf: + case 0x0128: + case 0x012a: + case 0x012c: + case 0x0130: + case 0x01cf: + case 0x0208: + case 0x020a: + case 0x1e2e: + case 0x1ec8: + case 0x0069: + case 0x00ec: + case 0x00ed: + case 0x00ee: + case 0x00ef: + case 0x0129: + case 0x012b: + case 0x012d: + case 0x01d0: + case 0x0209: + case 0x020b: + case 0x1e2f: + case 0x1ec9: + case 0x0055: + case 0x00d9: + case 0x00da: + case 0x00db: + case 0x00dc: + case 0x0168: + case 0x016a: + case 0x016c: + case 0x016e: + case 0x0170: + case 0x01d3: + case 0x01d5: + case 0x01d7: + case 0x01d9: + case 0x01db: + case 0x0214: + case 0x0216: + case 0x1e78: + case 0x1e7a: + case 0x1ee6: + case 0x0075: + case 0x00f9: + case 0x00fa: + case 0x00fb: + case 0x00fc: + case 0x0169: + case 0x016b: + case 0x016d: + case 0x016f: + case 0x0171: + case 0x01d4: + case 0x01d6: + case 0x01d8: + case 0x01da: + case 0x01dc: + case 0x0215: + case 0x0217: + case 0x1e79: + case 0x1e7b: + case 0x1ee7: + return false; + default: + return true; + } + + case 0x0331: + switch (p) + { + case 0x0042: + case 0x1e02: + case 0x0062: + case 0x1e03: + case 0x0044: + case 0x010e: + case 0x1e0a: + case 0x0064: + case 0x010f: + case 0x1e0b: + case 0x004b: + case 0x01e8: + case 0x1e30: + case 0x006b: + case 0x01e9: + case 0x1e31: + case 0x004c: + case 0x0139: + case 0x013d: + case 0x006c: + case 0x013a: + case 0x013e: + case 0x004e: + case 0x00d1: + case 0x0143: + case 0x0147: + case 0x01f8: + case 0x1e44: + case 0x006e: + case 0x00f1: + case 0x0144: + case 0x0148: + case 0x01f9: + case 0x1e45: + case 0x0052: + case 0x0154: + case 0x0158: + case 0x0210: + case 0x0212: + case 0x1e58: + case 0x0072: + case 0x0155: + case 0x0159: + case 0x0211: + case 0x0213: + case 0x1e59: + case 0x0054: + case 0x0164: + case 0x1e6a: + case 0x0074: + case 0x0165: + case 0x1e6b: + case 0x1e97: + case 0x005a: + case 0x0179: + case 0x017b: + case 0x017d: + case 0x1e90: + case 0x007a: + case 0x017a: + case 0x017c: + case 0x017e: + case 0x1e91: + case 0x0068: + case 0x0125: + case 0x021f: + case 0x1e23: + case 0x1e27: + return false; + default: + return true; + } + + case 0x0338: + switch (p) + { + /* Non-NFC cases not applicable to C/C++. */ + default: + return true; + } + + case 0x0342: + switch (p) + { + case 0x1f00: + case 0x1f80: + case 0x1f01: + case 0x1f81: + case 0x1f08: + case 0x1f88: + case 0x1f09: + case 0x1f89: + case 0x1f20: + case 0x1f90: + case 0x1f21: + case 0x1f91: + case 0x1f28: + case 0x1f98: + case 0x1f29: + case 0x1f99: + case 0x1f30: + case 0x1f31: + case 0x1f38: + case 0x1f39: + case 0x1f50: + case 0x1f51: + case 0x1f59: + case 0x1f60: + case 0x1fa0: + case 0x1f61: + case 0x1fa1: + case 0x1f68: + case 0x1fa8: + case 0x1f69: + case 0x1fa9: + case 0x03b1: + case 0x1fb3: + case 0x00a8: + case 0x03b7: + case 0x1fc3: + case 0x1fbf: + case 0x03b9: + case 0x03ca: + case 0x1ffe: + case 0x03c5: + case 0x03cb: + case 0x03c9: + case 0x1ff3: + return false; + default: + return true; + } + + case 0x0345: + switch (p) + { + case 0x1f00: + case 0x1f01: + case 0x1f02: + case 0x1f03: + case 0x1f04: + case 0x1f05: + case 0x1f06: + case 0x1f07: + case 0x1f08: + case 0x1f09: + case 0x1f0a: + case 0x1f0b: + case 0x1f0c: + case 0x1f0d: + case 0x1f0e: + case 0x1f0f: + case 0x1f20: + case 0x1f21: + case 0x1f22: + case 0x1f23: + case 0x1f24: + case 0x1f25: + case 0x1f26: + case 0x1f27: + case 0x1f28: + case 0x1f29: + case 0x1f2a: + case 0x1f2b: + case 0x1f2c: + case 0x1f2d: + case 0x1f2e: + case 0x1f2f: + case 0x1f60: + case 0x1f61: + case 0x1f62: + case 0x1f63: + case 0x1f64: + case 0x1f65: + case 0x1f66: + case 0x1f67: + case 0x1f68: + case 0x1f69: + case 0x1f6a: + case 0x1f6b: + case 0x1f6c: + case 0x1f6d: + case 0x1f6e: + case 0x1f6f: + case 0x1f70: + case 0x03b1: + case 0x03ac: + case 0x1fb6: + case 0x0391: + case 0x1f74: + case 0x03b7: + case 0x03ae: + case 0x1fc6: + case 0x0397: + case 0x1f7c: + case 0x03c9: + case 0x03ce: + case 0x1ff6: + case 0x03a9: + return false; + default: + return true; + } + + case 0x0653: + switch (p) + { + case 0x0627: + return false; + default: + return true; + } + + case 0x0654: + switch (p) + { + case 0x0627: + case 0x0648: + case 0x064a: + case 0x06d5: + case 0x06c1: + case 0x06d2: + return false; + default: + return true; + } + + case 0x0655: + switch (p) + { + case 0x0627: + case 0x0622: + case 0x0623: + return false; + default: + return true; + } + + case 0x093c: + switch (p) + { + case 0x0928: + case 0x0930: + case 0x0933: + case 0x0915: + case 0x0916: + case 0x0917: + case 0x091c: + case 0x0921: + case 0x0922: + case 0x092b: + case 0x092f: + return false; + default: + return true; + } + + case 0x09be: + switch (p) + { + case 0x09c7: + return false; + default: + return true; + } + + case 0x09d7: + switch (p) + { + case 0x09c7: + return false; + default: + return true; + } + + case 0x0b3e: + switch (p) + { + case 0x0b47: + return false; + default: + return true; + } + + case 0x0b56: + switch (p) + { + case 0x0b47: + return false; + default: + return true; + } + + case 0x0b57: + switch (p) + { + case 0x0b47: + return false; + default: + return true; + } + + case 0x0bbe: + switch (p) + { + case 0x0bc6: + case 0x0bc7: + return false; + default: + return true; + } + + case 0x0bd7: + switch (p) + { + case 0x0b92: + case 0x0bc6: + return false; + default: + return true; + } + + case 0x0c56: + switch (p) + { + case 0x0c46: + return false; + default: + return true; + } + + case 0x0cc2: + switch (p) + { + case 0x0cc6: + return false; + default: + return true; + } + + case 0x0cd5: + switch (p) + { + case 0x0cbf: + case 0x0cc6: + case 0x0cca: + return false; + default: + return true; + } + + case 0x0cd6: + switch (p) + { + case 0x0cc6: + return false; + default: + return true; + } + + case 0x0d3e: + switch (p) + { + case 0x0d46: + case 0x0d47: + return false; + default: + return true; + } + + case 0x0d57: + switch (p) + { + case 0x0d46: + return false; + default: + return true; + } + + case 0x0dca: + switch (p) + { + case 0x0dd9: + case 0x0ddc: + return false; + default: + return true; + } + + case 0x0dcf: + switch (p) + { + case 0x0dd9: + case 0x0dda: + return false; + default: + return true; + } + + case 0x0ddf: + switch (p) + { + case 0x0dd9: + case 0x0dda: + return false; + default: + return true; + } + + case 0x102e: + switch (p) + { + case 0x1025: + return false; + default: + return true; + } + + case 0x1b35: + switch (p) + { + case 0x1b05: + case 0x1b07: + case 0x1b09: + case 0x1b0b: + case 0x1b0d: + case 0x1b11: + case 0x1b3a: + case 0x1b3c: + case 0x1b3e: + case 0x1b3f: + case 0x1b42: + return false; + default: + return true; + } + + case 0x3099: + switch (p) + { + case 0x304b: + case 0x304d: + case 0x304f: + case 0x3051: + case 0x3053: + case 0x3055: + case 0x3057: + case 0x3059: + case 0x305b: + case 0x305d: + case 0x305f: + case 0x3061: + case 0x3064: + case 0x3066: + case 0x3068: + case 0x306f: + case 0x3072: + case 0x3075: + case 0x3078: + case 0x307b: + case 0x3046: + case 0x309d: + case 0x30ab: + case 0x30ad: + case 0x30af: + case 0x30b1: + case 0x30b3: + case 0x30b5: + case 0x30b7: + case 0x30b9: + case 0x30bb: + case 0x30bd: + case 0x30bf: + case 0x30c1: + case 0x30c4: + case 0x30c6: + case 0x30c8: + case 0x30cf: + case 0x30d2: + case 0x30d5: + case 0x30d8: + case 0x30db: + case 0x30a6: + case 0x30ef: + case 0x30f0: + case 0x30f1: + case 0x30f2: + case 0x30fd: + return false; + default: + return true; + } + + case 0x309a: + switch (p) + { + case 0x306f: + case 0x3072: + case 0x3075: + case 0x3078: + case 0x307b: + case 0x30cf: + case 0x30d2: + case 0x30d5: + case 0x30d8: + case 0x30db: + return false; + default: + return true; + } + + case 0x110ba: + switch (p) + { + case 0x11099: + case 0x1109b: + case 0x110a5: + return false; + default: + return true; + } + + case 0x11127: + switch (p) + { + case 0x11131: + case 0x11132: + return false; + default: + return true; + } + + case 0x1133e: + switch (p) + { + case 0x11347: + return false; + default: + return true; + } + + case 0x11357: + switch (p) + { + case 0x11347: + return false; + default: + return true; + } + + case 0x114b0: + switch (p) + { + case 0x114b9: + return false; + default: + return true; + } + + case 0x114ba: + switch (p) + { + case 0x114b9: + return false; + default: + return true; + } + + case 0x114bd: + switch (p) + { + case 0x114b9: + return false; + default: + return true; + } + + case 0x115af: + switch (p) + { + case 0x115b8: + case 0x115b9: + return false; + default: + return true; + } + + case 0x11930: + switch (p) + { + case 0x11935: + return false; + default: + return true; + } + + default: + cpp_error (pfile, CPP_DL_ICE, "Character %x might not be NFKC", c); + return true; + } +} |