/* CPP Library - charsets
   Copyright (C) 1998-2026 Free Software Foundation, Inc.

   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
Free Software Foundation; either version 3, or (at your option) any
later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "cpplib.h"
#include "internal.h"

/* Character set handling for C-family languages.

   Terminological note: In what follows, "charset" or "character set"
   will be taken to mean both an abstract set of characters and an
   encoding for that set.

   The C99 standard discusses two character sets: source and execution.
   The source character set is used for internal processing in translation
   phases 1 through 4; the execution character set is used thereafter.
   Both are required by 5.2.1.2p1 to be multibyte encodings, not wide
   character encodings (see 3.7.2, 3.7.3 for the standardese meanings
   of these terms).  Furthermore, the "basic character set" (listed in
   5.2.1p3) is to be encoded in each with values one byte wide, and is
   to appear in the initial shift state.

   It is not explicitly mentioned, but there is also a "wide execution
   character set" used to encode wide character constants and wide
   string literals; this is supposed to be the result of applying the
   standard library function mbstowcs() to an equivalent narrow string
   (6.4.5p5).  However, the behavior of hexadecimal and octal
   \-escapes is at odds with this; they are supposed to be translated
   directly to wchar_t values (6.4.4.4p5,6).

   The source character set is not necessarily the character set used
   to encode physical source files on disk; translation phase 1 converts
   from whatever that encoding is to the source character set.

   The presence of universal character names in C99 (6.4.3 et seq.)
   forces the source character set to be isomorphic to ISO 10646,
   that is, Unicode.  There is no such constraint on the execution
   character set; note also that the conversion from source to
   execution character set does not occur for identifiers (5.1.1.2p1#5).

   For convenience of implementation, the source character set's
   encoding of the basic character set should be identical to the
   execution character set OF THE HOST SYSTEM's encoding of the basic
   character set, and it should not be a state-dependent encoding.

   cpplib uses UTF-8 or UTF-EBCDIC for the source character set,
   depending on whether the host is based on ASCII or EBCDIC (see
   respectively Unicode section 2.3/ISO10646 Amendment 2, and Unicode
   Technical Report #16).  With limited exceptions, it relies on the
   system library's iconv() primitive to do charset conversion
   (specified in SUSv2).  */

#if !HAVE_ICONV
/* Make certain that the uses of iconv(), iconv_open(), iconv_close()
   below, which are guarded only by if statements with compile-time
   constant conditions, do not cause link errors.  */
#define iconv_open(x, y) (errno = EINVAL, (iconv_t)-1)
#define iconv(a,b,c,d,e) (errno = EINVAL, (size_t)-1)
#define iconv_close(x)   (void)0
#define ICONV_CONST
#endif

#if HOST_CHARSET == HOST_CHARSET_ASCII
#define SOURCE_CHARSET "UTF-8"
#define LAST_POSSIBLY_BASIC_SOURCE_CHAR 0x7e
#elif HOST_CHARSET == HOST_CHARSET_EBCDIC
#define SOURCE_CHARSET "UTF-EBCDIC"
#define LAST_POSSIBLY_BASIC_SOURCE_CHAR 0xFF
#else
#error "Unrecognized basic host character set"
#endif

#ifndef EILSEQ
#define EILSEQ EINVAL
#endif

/* This structure is used for a resizable string buffer throughout.  */
/* Don't call it strbuf, as that conflicts with unistd.h on systems
   such as DYNIX/ptx where unistd.h includes stropts.h.  */
struct _cpp_strbuf
{
  uchar *text;
  size_t asize;
  size_t len;
};

/* This is enough to hold any string that fits on a single 80-column
   line, even if iconv quadruples its size (e.g. conversion from
   ASCII to UTF-32) rounded up to a power of two.  */
#define OUTBUF_BLOCK_SIZE 256

/* Conversions between UTF-8 and UTF-16/32 are implemented by custom
   logic.  This is because a depressing number of systems lack iconv,
   or have have iconv libraries that do not do these conversions, so
   we need a fallback implementation for them.  To ensure the fallback
   doesn't break due to neglect, it is used on all systems.

   UTF-32 encoding is nice and simple: a four-byte binary number,
   constrained to the range 00000000-7FFFFFFF to avoid questions of
   signedness.  We do have to cope with big- and little-endian
   variants.

   UTF-16 encoding uses two-byte binary numbers, again in big- and
   little-endian variants, for all values in the 00000000-0000FFFF
   range.  Values in the 00010000-0010FFFF range are encoded as pairs
   of two-byte numbers, called "surrogate pairs": given a number S in
   this range, it is mapped to a pair (H, L) as follows:

     H = (S - 0x10000) / 0x400 + 0xD800
     L = (S - 0x10000) % 0x400 + 0xDC00

   Two-byte values in the D800...DFFF range are ill-formed except as a
   component of a surrogate pair.  Even if the encoding within a
   two-byte value is little-endian, the H member of the surrogate pair
   comes first.

   There is no way to encode values in the 00110000-7FFFFFFF range,
   which is not currently a problem as there are no assigned code
   points in that range; however, the author expects that it will
   eventually become necessary to abandon UTF-16 due to this
   limitation.  Note also that, because of these pairs, UTF-16 does
   not meet the requirements of the C standard for a wide character
   encoding (see 3.7.3 and 6.4.4.4p11).

   UTF-8 encoding looks like this:

   value range	       encoded as
   00000000-0000007F   0xxxxxxx
   00000080-000007FF   110xxxxx 10xxxxxx
   00000800-0000FFFF   1110xxxx 10xxxxxx 10xxxxxx
   00010000-001FFFFF   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
   00200000-03FFFFFF   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
   04000000-7FFFFFFF   1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

   Values in the 0000D800 ... 0000DFFF range (surrogates) are invalid,
   which means that three-byte sequences ED xx yy, with A0 <= xx <= BF,
   never occur.  Note also that any value that can be encoded by a
   given row of the table can also be encoded by all successive rows,
   but this is not done; only the shortest possible encoding for any
   given value is valid.  For instance, the character 07C0 could be
   encoded as any of DF 80, E0 9F 80, F0 80 9F 80, F8 80 80 9F 80, or
   FC 80 80 80 9F 80.  Only the first is valid.

   An implementation note: the transformation from UTF-16 to UTF-8, or
   vice versa, is easiest done by using UTF-32 as an intermediary.  */

/* Internal primitives which go from an UTF-8 byte stream to native-endian
   UTF-32 in a cppchar_t, or vice versa; this avoids an extra marshal/unmarshal
   operation in several places below.  */
static inline int
one_utf8_to_cppchar (const uchar **inbufp, size_t *inbytesleftp,
		     cppchar_t *cp)
{
  static const uchar masks[6] = { 0x7F, 0x1F, 0x0F, 0x07, 0x03, 0x01 };
  static const uchar patns[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };

  cppchar_t c;
  const uchar *inbuf = *inbufp;
  size_t nbytes, i;

  if (*inbytesleftp < 1)
    return EINVAL;

  c = *inbuf;
  if (c < 0x80)
    {
      *cp = c;
      *inbytesleftp -= 1;
      *inbufp += 1;
      return 0;
    }

  /* The number of leading 1-bits in the first byte indicates how many
     bytes follow.  */
  for (nbytes = 2; nbytes < 7; nbytes++)
    if ((c & ~masks[nbytes-1]) == patns[nbytes-1])
      goto found;
  return EILSEQ;
 found:

  if (*inbytesleftp < nbytes)
    return EINVAL;

  c = (c & masks[nbytes-1]);
  inbuf++;
  for (i = 1; i < nbytes; i++)
    {
      cppchar_t n = *inbuf++;
      if ((n & 0xC0) != 0x80)
	return EILSEQ;
      c = ((c << 6) + (n & 0x3F));
    }

  /* Make sure the shortest possible encoding was used.  */
  if (c <=      0x7F && nbytes > 1) return EILSEQ;
  if (c <=     0x7FF && nbytes > 2) return EILSEQ;
  if (c <=    0xFFFF && nbytes > 3) return EILSEQ;
  if (c <=  0x1FFFFF && nbytes > 4) return EILSEQ;
  if (c <= 0x3FFFFFF && nbytes > 5) return EILSEQ;

  /* Make sure the character is valid.  */
  if (c > 0x7FFFFFFF || (c >= 0xD800 && c <= 0xDFFF)) return EILSEQ;

  *cp = c;
  *inbufp = inbuf;
  *inbytesleftp -= nbytes;
  return 0;
}

static inline int
one_cppchar_to_utf8 (cppchar_t c, uchar **outbufp, size_t *outbytesleftp)
{
  static const uchar masks[6] =  { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
  static const uchar limits[6] = { 0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
  size_t nbytes;
  uchar buf[6], *p = &buf[6];
  uchar *outbuf = *outbufp;

  nbytes = 1;
  if (c < 0x80)
    *--p = c;
  else
    {
      do
	{
	  *--p = ((c & 0x3F) | 0x80);
	  c >>= 6;
	  nbytes++;
	}
      while (c >= 0x3F || (c & limits[nbytes-1]));
      *--p = (c | masks[nbytes-1]);
    }

  if (*outbytesleftp < nbytes)
    return E2BIG;

  while (p < &buf[6])
    *outbuf++ = *p++;
  *outbytesleftp -= nbytes;
  *outbufp = outbuf;
  return 0;
}

/* The following four functions transform one character between the two
   encodings named in the function name.  All have the signature
   int (*)(iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp,
           uchar **outbufp, size_t *outbytesleftp)

   BIGEND must have the value 0 or 1, coerced to (iconv_t); it is
   interpreted as a boolean indicating whether big-endian or
   little-endian encoding is to be used for the member of the pair
   that is not UTF-8.

   INBUFP, INBYTESLEFTP, OUTBUFP, OUTBYTESLEFTP work exactly as they
   do for iconv.

   The return value is either 0 for success, or an errno value for
   failure, which may be E2BIG (need more space), EILSEQ (ill-formed
   input sequence), ir EINVAL (incomplete input sequence).  */

static inline int
one_utf8_to_utf32 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp,
		   uchar **outbufp, size_t *outbytesleftp)
{
  uchar *outbuf;
  cppchar_t s = 0;
  int rval;

  /* Check for space first, since we know exactly how much we need.  */
  if (*outbytesleftp < 4)
    return E2BIG;

  rval = one_utf8_to_cppchar (inbufp, inbytesleftp, &s);
  if (rval)
    return rval;

  outbuf = *outbufp;
  outbuf[bigend ? 3 : 0] = (s & 0x000000FF);
  outbuf[bigend ? 2 : 1] = (s & 0x0000FF00) >> 8;
  outbuf[bigend ? 1 : 2] = (s & 0x00FF0000) >> 16;
  outbuf[bigend ? 0 : 3] = (s & 0xFF000000) >> 24;

  *outbufp += 4;
  *outbytesleftp -= 4;
  return 0;
}

static inline int
one_utf32_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp,
		   uchar **outbufp, size_t *outbytesleftp)
{
  cppchar_t s;
  int rval;
  const uchar *inbuf;

  if (*inbytesleftp < 4)
    return EINVAL;

  inbuf = *inbufp;

  s  = inbuf[bigend ? 0 : 3] << 24;
  s += inbuf[bigend ? 1 : 2] << 16;
  s += inbuf[bigend ? 2 : 1] << 8;
  s += inbuf[bigend ? 3 : 0];

  if (s >= 0x7FFFFFFF || (s >= 0xD800 && s <= 0xDFFF))
    return EILSEQ;

  rval = one_cppchar_to_utf8 (s, outbufp, outbytesleftp);
  if (rval)
    return rval;

  *inbufp += 4;
  *inbytesleftp -= 4;
  return 0;
}

static inline int
one_utf8_to_utf16 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp,
		   uchar **outbufp, size_t *outbytesleftp)
{
  int rval;
  cppchar_t s = 0;
  const uchar *save_inbuf = *inbufp;
  size_t save_inbytesleft = *inbytesleftp;
  uchar *outbuf = *outbufp;

  rval = one_utf8_to_cppchar (inbufp, inbytesleftp, &s);
  if (rval)
    return rval;

  if (s > 0x0010FFFF)
    {
      *inbufp = save_inbuf;
      *inbytesleftp = save_inbytesleft;
      return EILSEQ;
    }

  if (s <= 0xFFFF)
    {
      if (*outbytesleftp < 2)
	{
	  *inbufp = save_inbuf;
	  *inbytesleftp = save_inbytesleft;
	  return E2BIG;
	}
      outbuf[bigend ? 1 : 0] = (s & 0x00FF);
      outbuf[bigend ? 0 : 1] = (s & 0xFF00) >> 8;

      *outbufp += 2;
      *outbytesleftp -= 2;
      return 0;
    }
  else
    {
      cppchar_t hi, lo;

      if (*outbytesleftp < 4)
	{
	  *inbufp = save_inbuf;
	  *inbytesleftp = save_inbytesleft;
	  return E2BIG;
	}

      hi = (s - 0x10000) / 0x400 + 0xD800;
      lo = (s - 0x10000) % 0x400 + 0xDC00;

      /* Even if we are little-endian, put the high surrogate first.
	 ??? Matches practice?  */
      outbuf[bigend ? 1 : 0] = (hi & 0x00FF);
      outbuf[bigend ? 0 : 1] = (hi & 0xFF00) >> 8;
      outbuf[bigend ? 3 : 2] = (lo & 0x00FF);
      outbuf[bigend ? 2 : 3] = (lo & 0xFF00) >> 8;

      *outbufp += 4;
      *outbytesleftp -= 4;
      return 0;
    }
}

static inline int
one_utf16_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp,
		   uchar **outbufp, size_t *outbytesleftp)
{
  cppchar_t s;
  const uchar *inbuf = *inbufp;
  int rval;

  if (*inbytesleftp < 2)
    return EINVAL;
  s  = inbuf[bigend ? 0 : 1] << 8;
  s += inbuf[bigend ? 1 : 0];

  /* Low surrogate without immediately preceding high surrogate is invalid.  */
  if (s >= 0xDC00 && s <= 0xDFFF)
    return EILSEQ;
  /* High surrogate must have a following low surrogate.  */
  else if (s >= 0xD800 && s <= 0xDBFF)
    {
      cppchar_t hi = s, lo;
      if (*inbytesleftp < 4)
	return EINVAL;

      lo  = inbuf[bigend ? 2 : 3] << 8;
      lo += inbuf[bigend ? 3 : 2];

      if (lo < 0xDC00 || lo > 0xDFFF)
	return EILSEQ;

      s = (hi - 0xD800) * 0x400 + (lo - 0xDC00) + 0x10000;
    }

  rval = one_cppchar_to_utf8 (s, outbufp, outbytesleftp);
  if (rval)
    return rval;

  /* Success - update the input pointers (one_cppchar_to_utf8 has done
     the output pointers for us).  */
  if (s <= 0xFFFF)
    {
      *inbufp += 2;
      *inbytesleftp -= 2;
    }
  else
    {
      *inbufp += 4;
      *inbytesleftp -= 4;
    }
  return 0;
}


/* Special routine which just counts number of characters in the
   string, what exactly is stored into the output doesn't matter
   as long as it is one uchar per character.  */

static inline int
one_count_chars (iconv_t, const uchar **inbufp, size_t *inbytesleftp,
		 uchar **outbufp, size_t *outbytesleftp)
{
  cppchar_t s = 0;
  int rval;

  /* Check for space first, since we know exactly how much we need.  */
  if (*outbytesleftp < 1)
    return E2BIG;

#if HOST_CHARSET == HOST_CHARSET_ASCII
  rval = one_utf8_to_cppchar (inbufp, inbytesleftp, &s);
  if (rval)
    return rval;
#else
  if (*inbytesleftp < 1)
    return EINVAL;
  static const uchar utf_ebcdic_map[256] = {
    /* See table 4 in http://unicode.org/reports/tr16/tr16-7.2.html  */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1,
    1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1, 1,
    1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 1,
    9, 9, 9, 9, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
    2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
    2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
    2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 1, 3, 3,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 4,
    1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 5, 5, 5,
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 6, 7, 7, 0
  };
  rval = utf_ebcdic_map[**inbufp];
  if (rval == 9)
    return EILSEQ;
  if (rval == 0)
    rval = 1;
  if (rval >= 2)
    {
      if (*inbytesleftp < rval)
	return EINVAL;
      for (int i = 1; i < rval; ++i)
	if (utf_ebcdic_map[(*inbufp)[i]] != 9)
	  return EILSEQ;
    }
  *inbytesleftp -= rval;
  *inbufp += rval;
#endif

  **outbufp = ' ';

  *outbufp += 1;
  *outbytesleftp -= 1;
  return 0;
}


/* Helper routine for the next few functions.  The 'const' on
   one_conversion means that we promise not to modify what function is
   pointed to, which lets the inliner see through it.  */

static inline bool
conversion_loop (int (*const one_conversion)(iconv_t, const uchar **, size_t *,
					     uchar **, size_t *),
		 iconv_t cd, const uchar *from, size_t flen, struct _cpp_strbuf *to)
{
  const uchar *inbuf;
  uchar *outbuf;
  size_t inbytesleft, outbytesleft;
  int rval;

  inbuf = from;
  inbytesleft = flen;
  outbuf = to->text + to->len;
  outbytesleft = to->asize - to->len;

  for (;;)
    {
      do
	rval = one_conversion (cd, &inbuf, &inbytesleft,
			       &outbuf, &outbytesleft);
      while (inbytesleft && !rval);

      if (__builtin_expect (inbytesleft == 0, 1))
	{
	  to->len = to->asize - outbytesleft;
	  return true;
	}
      if (rval != E2BIG)
	{
	  errno = rval;
	  return false;
	}

      outbytesleft += OUTBUF_BLOCK_SIZE;
      to->asize += OUTBUF_BLOCK_SIZE;
      to->text = XRESIZEVEC (uchar, to->text, to->asize);
      outbuf = to->text + to->asize - outbytesleft;
    }
}


/* These functions convert entire strings between character sets.
   They all have the signature

   bool (*)(iconv_t cd, const uchar *from, size_t flen, struct _cpp_strbuf *to);

   The input string FROM is converted as specified by the function
   name plus the iconv descriptor CD (which may be fake), and the
   result appended to TO.  On any error, false is returned, otherwise true.  */

/* These four use the custom conversion code above.  */
static bool
convert_utf8_utf16 (iconv_t cd, const uchar *from, size_t flen,
		    struct _cpp_strbuf *to)
{
  return conversion_loop (one_utf8_to_utf16, cd, from, flen, to);
}

static bool
convert_utf8_utf32 (iconv_t cd, const uchar *from, size_t flen,
		    struct _cpp_strbuf *to)
{
  return conversion_loop (one_utf8_to_utf32, cd, from, flen, to);
}

static bool
convert_utf16_utf8 (iconv_t cd, const uchar *from, size_t flen,
		    struct _cpp_strbuf *to)
{
  return conversion_loop (one_utf16_to_utf8, cd, from, flen, to);
}

static bool
convert_utf32_utf8 (iconv_t cd, const uchar *from, size_t flen,
		    struct _cpp_strbuf *to)
{
  return conversion_loop (one_utf32_to_utf8, cd, from, flen, to);
}

/* Magic conversion which just counts characters from input, so
   only to->len is significant.  */
static bool
convert_count_chars (iconv_t cd, const uchar *from,
		     size_t flen, struct _cpp_strbuf *to)
{
  return conversion_loop (one_count_chars, cd, from, flen, to);
}

/* Identity conversion, used when we have no alternative.  */
static bool
convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED,
		       const uchar *from, size_t flen, struct _cpp_strbuf *to)
{
  if (to->len + flen > to->asize)
    {
      to->asize = to->len + flen;
      to->asize += to->asize / 4;
      to->text = XRESIZEVEC (uchar, to->text, to->asize);
    }
  memcpy (to->text + to->len, from, flen);
  to->len += flen;
  return true;
}

/* And this one uses the system iconv primitive.  It's a little
   different, since iconv's interface is a little different.  */
#if HAVE_ICONV

#define CONVERT_ICONV_GROW_BUFFER \
  do { \
      outbytesleft += OUTBUF_BLOCK_SIZE; \
      to->asize += OUTBUF_BLOCK_SIZE; \
      to->text = XRESIZEVEC (uchar, to->text, to->asize); \
      outbuf = (char *)to->text + to->asize - outbytesleft; \
  } while (0)

static bool
convert_using_iconv (iconv_t cd, const uchar *from, size_t flen,
		     struct _cpp_strbuf *to)
{
  ICONV_CONST char *inbuf;
  char *outbuf;
  size_t inbytesleft, outbytesleft;

  /* Reset conversion descriptor and check that it is valid.  */
  if (iconv (cd, 0, 0, 0, 0) == (size_t)-1)
    return false;

  inbuf = (ICONV_CONST char *)from;
  inbytesleft = flen;
  outbuf = (char *)to->text + to->len;
  outbytesleft = to->asize - to->len;

  for (;;)
    {
      iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
      if (__builtin_expect (inbytesleft == 0, 1))
	{
	  /* Close out any shift states, returning to the initial state.  */
	  if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1)
	    {
	      if (errno != E2BIG)
		return false;

	      CONVERT_ICONV_GROW_BUFFER;
	      if (iconv (cd, 0, 0, &outbuf, &outbytesleft) == (size_t)-1)
		return false;
	    }

	  to->len = to->asize - outbytesleft;
	  return true;
	}
      if (errno != E2BIG)
	return false;

      CONVERT_ICONV_GROW_BUFFER;
    }
}
#else
#define convert_using_iconv 0 /* prevent undefined symbol error below */
#endif

/* Arrange for the above custom conversion logic to be used automatically
   when conversion between a suitable pair of character sets is requested.  */

#define APPLY_CONVERSION(CONVERTER, FROM, FLEN, TO) \
   CONVERTER.func (CONVERTER.cd, FROM, FLEN, TO)

struct cpp_conversion
{
  const char *pair;
  convert_f func;
  iconv_t fake_cd;
};
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 },
  { "UTF-8/UTF-16BE", convert_utf8_utf16, (iconv_t)1 },
  { "UTF-32LE/UTF-8", convert_utf32_utf8, (iconv_t)0 },
  { "UTF-32BE/UTF-8", convert_utf32_utf8, (iconv_t)1 },
  { "UTF-16LE/UTF-8", convert_utf16_utf8, (iconv_t)0 },
  { "UTF-16BE/UTF-8", convert_utf16_utf8, (iconv_t)1 },
};

/* Subroutine of cpp_init_iconv: initialize and return a
   cset_converter structure for conversion from FROM to TO.  If
   iconv_open() fails, issue an error and return an identity
   converter.  Silently return an identity converter if FROM and TO
   are identical.

   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)
{
  struct cset_converter ret;
  char *pair;
  size_t i;

  ret.to = to;
  ret.from = from;

  if (!strcasecmp (to, from))
    {
      ret.func = convert_no_conversion;
      ret.cd = (iconv_t) -1;
      ret.width = -1;
      return ret;
    }

  pair = (char *) alloca(strlen(to) + strlen(from) + 2);

  strcpy(pair, from);
  strcat(pair, "/");
  strcat(pair, to);
  for (i = 0; i < ARRAY_SIZE (conversion_tab); i++)
    if (!strcasecmp (pair, conversion_tab[i].pair))
      {
	ret.func = conversion_tab[i].func;
	ret.cd = conversion_tab[i].fake_cd;
	ret.width = -1;
	return ret;
      }

  /* No custom converter - try iconv.  */
  if (HAVE_ICONV)
    {
      ret.func = convert_using_iconv;
      ret.cd = iconv_open (to, from);
      ret.width = -1;

      if (ret.cd == (iconv_t) -1)
	{
	  if (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
    {
      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;
}

/* If charset conversion is requested, initialize iconv(3) descriptors
   for conversion from the source character set to the execution
   character sets.  If iconv is not present in the C library, and
   conversion is requested, issue an error.  */

void
cpp_init_iconv (cpp_reader *pfile)
{
  const char *ncset = CPP_OPTION (pfile, narrow_charset);
  const char *wcset = CPP_OPTION (pfile, wide_charset);
  const char *default_wcset;

  bool be = CPP_OPTION (pfile, bytes_big_endian);

  if (CPP_OPTION (pfile, wchar_precision) >= 32)
    default_wcset = be ? "UTF-32BE" : "UTF-32LE";
  else if (CPP_OPTION (pfile, wchar_precision) >= 16)
    default_wcset = be ? "UTF-16BE" : "UTF-16LE";
  else
    /* This effectively means that wide strings are not supported,
       so don't do any conversion at all.  */
   default_wcset = SOURCE_CHARSET;

  if (!ncset)
    ncset = SOURCE_CHARSET;
  if (!wcset)
    wcset = default_wcset;

  pfile->narrow_cset_desc = init_iconv_desc (pfile, ncset, SOURCE_CHARSET);
  pfile->narrow_cset_desc.width = CPP_OPTION (pfile, char_precision);
  pfile->utf8_cset_desc = init_iconv_desc (pfile, "UTF-8", SOURCE_CHARSET);
  pfile->utf8_cset_desc.width = CPP_OPTION (pfile, char_precision);
  pfile->char16_cset_desc = init_iconv_desc (pfile,
					     be ? "UTF-16BE" : "UTF-16LE",
					     SOURCE_CHARSET);
  pfile->char16_cset_desc.width = 16;
  pfile->char32_cset_desc = init_iconv_desc (pfile,
					     be ? "UTF-32BE" : "UTF-32LE",
					     SOURCE_CHARSET);
  pfile->char32_cset_desc.width = 32;
  pfile->wide_cset_desc = init_iconv_desc (pfile, wcset, SOURCE_CHARSET);
  pfile->wide_cset_desc.width = CPP_OPTION (pfile, wchar_precision);
}

/* Destroy iconv(3) descriptors set up by cpp_init_iconv, if necessary.  */
void
_cpp_destroy_iconv (cpp_reader *pfile)
{
  if (HAVE_ICONV)
    {
      if (pfile->narrow_cset_desc.func == convert_using_iconv)
	iconv_close (pfile->narrow_cset_desc.cd);
      if (pfile->utf8_cset_desc.func == convert_using_iconv)
	iconv_close (pfile->utf8_cset_desc.cd);
      if (pfile->char16_cset_desc.func == convert_using_iconv)
	iconv_close (pfile->char16_cset_desc.cd);
      if (pfile->char32_cset_desc.func == convert_using_iconv)
	iconv_close (pfile->char32_cset_desc.cd);
      if (pfile->wide_cset_desc.func == convert_using_iconv)
	iconv_close (pfile->wide_cset_desc.cd);
      if (pfile->reverse_narrow_cset_desc.func == convert_using_iconv)
	iconv_close (pfile->narrow_cset_desc.cd);
      if (pfile->reverse_utf8_cset_desc.func == convert_using_iconv)
	iconv_close (pfile->utf8_cset_desc.cd);
    }
}

/* Utility routine for use by a full compiler.  C is a character taken
   from the *basic* source character set, encoded in the host's
   execution encoding.  Convert it to (the target's) execution
   encoding, and return that value.

   Issues an internal error if C's representation in the narrow
   execution character set fails to be a single-byte value (C99
   5.2.1p3: "The representation of each member of the source and
   execution character sets shall fit in a byte.")  May also issue an
   internal error if C fails to be a member of the basic source
   character set (testing this exactly is too hard, especially when
   the host character set is EBCDIC).  */
cppchar_t
cpp_host_to_exec_charset (cpp_reader *pfile, cppchar_t c)
{
  uchar sbuf[1];
  struct _cpp_strbuf tbuf;

  /* This test is merely an approximation, but it suffices to catch
     the most important thing, which is that we don't get handed a
     character outside the unibyte range of the host character set.  */
  if (c > LAST_POSSIBLY_BASIC_SOURCE_CHAR)
    {
      cpp_error (pfile, CPP_DL_ICE,
		 "character 0x%lx is not in the basic source character set",
		 (unsigned long) c);
      return 0;
    }

  /* Being a character in the unibyte range of the host character set,
     we can safely splat it into a one-byte buffer and trust that that
     is a well-formed string.  */
  sbuf[0] = c;

  /* This should never need to reallocate, but just in case... */
  tbuf.asize = 1;
  tbuf.text = XNEWVEC (uchar, tbuf.asize);
  tbuf.len = 0;

  if (!APPLY_CONVERSION (pfile->narrow_cset_desc, sbuf, 1, &tbuf))
    {
      cpp_errno (pfile, CPP_DL_ICE, "converting to execution character set");
      return 0;
    }
  if (tbuf.len != 1)
    {
      cpp_error (pfile, CPP_DL_ICE,
		 "character 0x%lx is not unibyte in execution character set",
		 (unsigned long)c);
      return 0;
    }
  c = tbuf.text[0];
  free(tbuf.text);
  return c;
}



/* 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
width_to_mask (size_t width)
{
  width = MIN (width, BITS_PER_CPPCHAR_T);
  if (width >= CHAR_BIT * sizeof (size_t))
    return ~(size_t) 0;
  else
    return ((size_t) 1 << width) - 1;
}

/* A large table of unicode character information.  */
enum {
  /* Valid in a C99 identifier?  */
  C99 = 1,
  /* Valid in a C99 identifier, but not as the first character?  */
  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 = 128,
  /* Might be valid NFC form?  */
  NFC = 256,
  /* Might be valid NFKC form?  */
  NKC = 512,
  /* Certain preceding characters might make it not valid NFC/NKFC form?  */
  CTX = 1024
};

struct ucnrange {
  /* Bitmap of flags above.  */
  unsigned short flags;
  /* Combining class of the character.  */
  unsigned char combine;
  /* Last character in the range described by this entry.  */
  unsigned int end;
};
#include "ucnid.h"

/* ISO 10646 defines the UCS codespace as the range 0-0x10FFFF inclusive.  */
#define UCS_LIMIT 0x10FFFF

#include "uname2c.h"

static const char hangul_syllables[][4] = {
  /* L */
  "G", "GG", "N", "D", "DD", "R", "M", "B", "BB", "S", "SS", "",
  "J", "JJ", "C", "K", "T", "P", "H",
  /* V */
  "A", "AE", "YA", "YAE", "EO", "E", "YEO", "YE", "O", "WA", "WAE",
  "OE", "YO", "U", "WEO", "WE", "WI", "YU", "EU", "YI", "I",
  /* T */
  "", "G", "GG", "GS", "N", "NJ", "NH", "D", "L", "LG", "LM", "LB",
  "LS", "LT", "LP", "LH", "M", "B", "BS", "S", "SS", "NG", "J", "C",
  "K", "T", "P", "H"
};

static const short hangul_count[6] = { 19, 21, 28 };

/* Used for Unicode loose matching rule UAX44-LM2 matching.  */

struct uname2c_data
{
  char *canon_name;
  char prev_char;
};

/* Map NAME, a Unicode character name or correction/control/alternate
   alias, to a Unicode codepoint, or return (cppchar_t) -1 if
   not found.  This uses a space optimized radix tree precomputed
   by the makeuname2c utility, with binary format documented in its
   source makeuname2c.cc.  */

static cppchar_t
_cpp_uname2c (const char *name, size_t len, const unsigned char *n,
	      struct uname2c_data *data)
{
  do
    {
      char k;
      const char *key;
      size_t key_len, len_adj;
      bool has_value = *n & 0x40;
      bool has_children, no_sibling = false;
      cppchar_t codepoint = -1;
      const unsigned char *child = NULL;
      int ret;

      if (*n & 0x80)
	{
	  k = ' ' + (*n++ & 0x3f);
	  key = &k;
	  key_len = 1;
	}
      else
	{
	  key_len = *n++ & 0x3f;
	  key = &uname2c_dict[*n++];
	  key += (*n++ << 8);
	}
      if (has_value)
	{
	  codepoint = *n + (n[1] << 8) + ((n[2] & 0x1f) << 16);
	  has_children = n[2] & 0x80;
	  no_sibling = n[2] & 0x40;
	  n += 3;
	}
      else
	has_children = true;
      if (has_children)
	{
	  unsigned int shift = 0;
	  size_t child_off = 0;

	  do
	    {
	      child_off |= (*n & 0x7f) << shift;
	      shift += 7;
	    }
	  while ((*n++ & 0x80) != 0);
	  child = n + child_off;
	}
      if (__builtin_expect (data == NULL, 1))
	{
	  ret = memcmp (name, key, len > key_len ? key_len : len);
	  len_adj = key_len;
	}
      else
	{
	  const char *p = name, *q = key;

	  while (1)
	    {
	      if ((size_t) (p - name) == len || (size_t) (q - key) == key_len)
		break;
	      if (*q == ' ')
		{
		  ++q;
		  continue;
		}
	      if (*q == '-')
		{
		  /* This is the hard case.  Only medial hyphens
		     should be removed, where medial means preceded
		     and followed by alnum.  */
		  if (ISALNUM (q == key ? data->prev_char : q[-1]))
		    {
		      if (q + 1 == key + key_len)
			{
			  /* We don't know what the next letter will be.
			     It could be ISALNUM, then we are supposed
			     to omit it, or it could be a space and then
			     we should not omit it and need to compare it.
			     Fortunately the only 3 names with hyphen
			     followed by non-letter are
			     U+0F0A TIBETAN MARK BKA- SHOG YIG MGO
			     U+0FD0 TIBETAN MARK BKA- SHOG GI MGO RGYAN
			     U+0FD0 TIBETAN MARK BSKA- SHOG GI MGO RGYAN
			     Furthermore, prefixes of NR2 generated
			     ranges all end with a hyphen, but the generated
			     part is then followed by alpha-numeric.
			     So, let's just assume that - at the end of
			     key is always followed by alphanumeric and
			     so should be omitted.
			     makeuname2c.cc verifies that this is true.  */
			  ++q;
			  continue;
			}
		      else if (ISALNUM (q[1]))
			{
			  ++q;
			  continue;
			}
		    }
		}
	      if (*p != *q)
		break;
	      ++p;
	      ++q;
	    }
	  len_adj = p - name;
	  /* If we don't consume the whole key, signal a mismatch,
	     but always with ret = 1, so that we keep looking through
	     siblings.  */
	  ret = q < key + key_len;
	}
      if (ret < 0)
	return -1;
      else if (ret == 0)
	{
	  if (len < len_adj)
	    return -1;
	  else if (codepoint >= 0xd800
		   && codepoint < 0xd800 + ARRAY_SIZE (uname2c_generated))
	    {
	      name += len_adj;
	      len -= len_adj;
	      if (codepoint == 0xd800)
		{
		  /* NR1 - Hangul syllables.  */
		  size_t start = 0, end, i, j;
		  int this_len, max_len;
		  char winner[3];

		  for (i = 0; i < 3; ++i)
		    {
		      end = start + hangul_count[i];
		      max_len = -1;
		      winner[i] = -1;
		      for (j = start; j < end; j++)
			{
			  this_len = strlen (hangul_syllables[j]);
			  if (len >= (size_t) this_len
			      && this_len > max_len
			      && memcmp (name, hangul_syllables[j],
					 this_len) == 0)
			    {
			      max_len = this_len;
			      winner[i] = j - start;
			    }
			}
		      if (max_len == -1)
			return -1;
		      name += max_len;
		      len -= max_len;
		      start = end;
		    }
		  if (__builtin_expect (data != NULL, 0))
		    {
		      memcpy (data->canon_name, key, key_len);
		      data->canon_name[key_len] = '\0';
		      for (i = 0, start = 0; i < 3; ++i)
			{
			  strcat (data->canon_name,
				  hangul_syllables[start + winner[i]]);
			  start += hangul_count[i];
			}
		    }
		  return (0xac00 + 21 * 28 * winner[0]
			  + 28 * winner[1] + winner[2]);
		}
	      else
		{
		  /* NR2 - prefix followed by hexadecimal codepoint.  */
		  const cppchar_t *p;
		  size_t i;

		  if (len < 4 || len > 5)
		    return -1;
		  p = uname2c_pairs + uname2c_generated[codepoint - 0xd800];
		  codepoint = 0;
		  for (i = 0; i < len; ++i)
		    {
		      codepoint <<= 4;
		      if (!ISXDIGIT (name[i]))
			return -1;
		      codepoint += hex_value (name[i]);
		    }
		  for (; *p; p += 2)
		    if (codepoint < *p)
		      return -1;
		    else if (codepoint <= p[1])
		      {
			if (__builtin_expect (data != NULL, 0))
			  {
			    memcpy (data->canon_name, key, key_len);
			    memcpy (data->canon_name + key_len, name, len);
			    data->canon_name[key_len + len] = '\0';
			  }
			return codepoint;
		      }
		  return -1;
		}
	    }
	  else if (__builtin_expect (data != NULL, 0))
	    {
	      if (len == len_adj)
		{
		  memcpy (data->canon_name, key, key_len);
		  data->canon_name[key_len] = '\0';
		  return codepoint;
		}
	      if (has_children)
		{
		  struct uname2c_data save = *data;
		  memcpy (data->canon_name, key, key_len);
		  data->canon_name += key_len;
		  data->prev_char = key[key_len - 1];
		  codepoint = _cpp_uname2c (name + len_adj, len - len_adj,
					    child, data);
		  if (codepoint != (cppchar_t) -1)
		    return codepoint;
		  *data = save;
		}
	    }
	  else if (len == len_adj)
	    return codepoint;
	  else if (!has_children)
	    return -1;
	  else
	    {
	      name += len_adj;
	      len -= len_adj;
	      n = child;
	      continue;
	    }
	}
      if (no_sibling || (!has_value && *n == 0xff))
	break;
    }
  while (1);
  return -1;
}

/* Try to do a loose name lookup according to Unicode loose matching rule
   UAX44-LM2.  First ignore medial hyphens, whitespace, underscore
   characters and convert to upper case.  */

static cppchar_t
_cpp_uname2c_uax44_lm2 (const char *name, size_t len, char *canon_name)
{
  char name_after_uax44_lm2[uname2c_max_name_len];
  char *q = name_after_uax44_lm2;
  const char *p;

  for (p = name; p < name + len; p++)
    if (*p == '_' || *p == ' ')
      continue;
    else if (*p == '-' && p != name && ISALNUM (p[-1]) && ISALNUM (p[1]))
      continue;
    else if (q == name_after_uax44_lm2 + uname2c_max_name_len)
      return -1;
    else if (ISLOWER (*p))
      *q++ = TOUPPER (*p);
    else
      *q++ = *p;

  struct uname2c_data data;
  data.canon_name = canon_name;
  data.prev_char = ' ';
  /* Hangul Jungseong O- E after UAX44-LM2 should be HANGULJUNGSEONGO-E
     and so should match U+1180.  */
  if (q - name_after_uax44_lm2 == sizeof ("HANGULJUNGSEONGO-E") - 1
      && memcmp (name_after_uax44_lm2, "HANGULJUNGSEONGO-E",
		 sizeof ("HANGULJUNGSEONGO-E") - 1) == 0)
    {
      name_after_uax44_lm2[sizeof ("HANGULJUNGSEONGO") - 1] = 'E';
      --q;
    }
  cppchar_t result
    = _cpp_uname2c (name_after_uax44_lm2, q - name_after_uax44_lm2,
		    uname2c_tree, &data);

  /* Unicode UAX44-LM2 exception:
     U+116C HANGUL JUNGSEONG OE
     U+1180 HANGUL JUNGSEONG O-E
     We remove all medial hyphens when we shouldn't remote the U+1180 one.
     The U+1180 entry sorts before U+116C lexicographilly, so we get U+1180
     in both cases.  Thus, if result is U+1180, check if user's name doesn't
     have a hyphen there and adjust.  */
  if (result == 0x1180)
    {
      while (p[-1] == ' ' || p[-1] == '_')
	--p;
      gcc_assert (TOUPPER (p[-1]) == 'E');
      --p;
      while (p[-1] == ' ' || p[-1] == '_')
	--p;
      if (p[-1] != '-')
	{
	  result = 0x116c;
	  memcpy (canon_name + sizeof ("HANGUL JUNGSEONG O") - 1, "E", 2);
	}
    }
  return result;
}

/* Returns flags representing the XID properties of the given codepoint.  */
unsigned int
cpp_check_xid_property (cppchar_t c)
{
  // fast path for ASCII
  if (c < 0x80)
    {
      if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))
	return CPP_XID_START | CPP_XID_CONTINUE;
      if (('0' <= c && c <= '9') || c == '_')
	return CPP_XID_CONTINUE;
    }

  if (c > UCS_LIMIT)
    return 0;

  int mn, mx, md;
  mn = 0;
  mx = ARRAY_SIZE (ucnranges) - 1;
  while (mx != mn)
    {
      md = (mn + mx) / 2;
      if (c <= ucnranges[md].end)
	mx = md;
      else
	mn = md + 1;
    }

  unsigned short flags = ucnranges[mn].flags;

  if (flags & CXX23)
    return CPP_XID_START | CPP_XID_CONTINUE;
  if (flags & NXX23)
    return CPP_XID_CONTINUE;
  return 0;
}

/* Returns 1 if C is valid in an identifier, 2 if C is valid except at
   the start of an identifier, and 0 if C is not valid in an
   identifier.  We assume C has already gone through the checks of
   _cpp_valid_ucn.  Also update NST for C if returning nonzero.  The
   algorithm is a simple binary search on the table defined in
   ucnid.h.  */

static int
ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c,
			 struct normalize_state *nst)
{
  int mn, mx, md;
  unsigned short valid_flags, invalid_start_flags;

  if (c > UCS_LIMIT)
    return 0;

  mn = 0;
  mx = ARRAY_SIZE (ucnranges) - 1;
  while (mx != mn)
    {
      md = (mn + mx) / 2;
      if (c <= ucnranges[md].end)
	mx = md;
      else
	mn = md + 1;
    }

  /* When -pedantic, we require the character to have been listed by
     the standard for the current language.  Otherwise, we accept the
     union of the acceptable sets for all supported language versions.  */
  valid_flags = C99 | CXX | C11 | CXX23;
  if (CPP_PEDANTIC (pfile))
    {
      if (CPP_OPTION (pfile, xid_identifiers))
	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;

  /* Update NST.  */
  if (ucnranges[mn].combine != 0 && ucnranges[mn].combine < nst->prev_class)
    nst->level = normalized_none;
  else if (ucnranges[mn].flags & CTX)
    {
      bool safe;
      cppchar_t p = nst->previous;

      /* For Hangul, characters in the range AC00-D7A3 are NFC/NFKC,
	 and are combined algorithmically from a sequence of the form
	 1100-1112 1161-1175 11A8-11C2
	 (if the third is not present, it is treated as 11A7, which is not
	 really a valid character).
	 Unfortunately, C99 allows (only) the NFC form, but C++ allows
	 only the combining characters.  */
      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)
	{
	  if ((c >= 0x1161 && c <= 0x1175) || (c >= 0x11A8 && c <= 0x11C2))
	    nst->level = MAX (nst->level, normalized_identifier_C);
	  else
	    nst->level = normalized_none;
	}
    }
  else if (ucnranges[mn].flags & NKC)
    ;
  else if (ucnranges[mn].flags & NFC)
    nst->level = MAX (nst->level, normalized_C);
  else if (ucnranges[mn].flags & CID)
    nst->level = MAX (nst->level, normalized_identifier_C);
  else
    nst->level = normalized_none;
  if (ucnranges[mn].combine == 0)
    nst->previous = c;
  nst->prev_class = ucnranges[mn].combine;

  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, xid_identifiers))
    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;
}

/* Increment char_range->m_finish by a single character.  */

static void
extend_char_range (source_range *char_range,
		   cpp_string_location_reader *loc_reader)
{
  if (loc_reader)
    {
      gcc_assert (char_range);
      char_range->m_finish = loc_reader->get_next ().m_finish;
    }
}

/* [lex.charset]: The character designated by the universal character
   name \UNNNNNNNN is that character whose character short name in
   ISO/IEC 10646 is NNNNNNNN; the character designated by the
   universal character name \uNNNN is that character whose character
   short name in ISO/IEC 10646 is 0000NNNN.  If the hexadecimal value
   for a universal character name corresponds to a surrogate code point
   (in the range 0xD800-0xDFFF, inclusive), the program is ill-formed.
   Additionally, if the hexadecimal value for a universal-character-name
   outside a character or string literal corresponds to a control character
   (in either of the ranges 0x00-0x1F or 0x7F-0x9F, both inclusive) or to a
   character in the basic source character set, the program is ill-formed.

   C99 6.4.3: A universal character name shall not specify a character
   whose short identifier is less than 00A0 other than 0024 ($), 0040 (@),
   or 0060 (`), nor one in the range D800 through DFFF inclusive.

   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 false if the
   UCN has not been consumed, true otherwise.

   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.

   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, cppchar_t *cp,
		source_range *char_range,
		cpp_string_location_reader *loc_reader)
{
  cppchar_t result, c;
  unsigned int length;
  const uchar *str = *pstr;
  const uchar *base = str - 2;
  bool delimited = false, named = false;

  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",
	         (int) str[-1]);

  result = 0;
  if (str[-1] == 'u')
    {
      length = 4;
      if (str < limit
	  && *str == '{'
	  && (!identifier_pos
	      || CPP_OPTION (pfile, delimited_escape_seqs)
	      || !CPP_OPTION (pfile, std)))
	{
	  str++;
	  /* Magic value to indicate no digits seen.  */
	  length = 32;
	  delimited = true;
	  extend_char_range (char_range, loc_reader);
	}
    }
  else if (str[-1] == 'U')
    length = 8;
  else if (str[-1] == 'N')
    {
      length = 4;
      if (identifier_pos
	  && !CPP_OPTION (pfile, named_uc_escape_seqs)
	  && CPP_OPTION (pfile, std))
	{
	  *cp = 0;
	  return false;
	}
      if (str == limit || *str != '{')
	{
	  if (identifier_pos)
	    {
	      *cp = 0;
	      return false;
	    }
	  cpp_error (pfile, CPP_DL_ERROR, "%<\\N%> not followed by %<{%>");
	}
      else
	{
	  str++;
	  named = true;
	  extend_char_range (char_range, loc_reader);
	  length = 0;
	  const uchar *name = str;
	  bool strict = true;

	  do
	    {
	      if (str == limit)
		break;
	      c = *str;
	      if (!ISIDNUM (c) && c != ' ' && c != '-')
		break;
	      if (ISLOWER (c) || c == '_')
		strict = false;
	      str++;
	      extend_char_range (char_range, loc_reader);
	    }
	  while (1);

	  if (str < limit && *str == '}')
	    {
	      if (identifier_pos && name == str)
		{
		  cpp_warning (pfile, CPP_W_UNICODE,
			       "empty named universal character escape "
			       "sequence; treating it as separate tokens");
		  *cp = 0;
		  return false;
		}
	      if (name == str)
		cpp_error (pfile, CPP_DL_ERROR,
			   "empty named universal character escape sequence");
	      else if ((!identifier_pos || strict)
		       && !CPP_OPTION (pfile, named_uc_escape_seqs)
		       && CPP_OPTION (pfile, cpp_pedantic))
		cpp_pedwarning (pfile,
				CPP_OPTION (pfile, cplusplus)
				? CPP_W_CXX23_EXTENSIONS : CPP_W_PEDANTIC,
				"named universal character escapes are only "
				"valid in C++23");
	      if (name == str)
		result = 0x40;
	      else
		{
		  /* If the name is longer than maximum length of a Unicode
		     name, it can't be strictly valid.  */
		  if ((size_t) (str - name) > uname2c_max_name_len || !strict)
		    result = -1;
		  else
		    result = _cpp_uname2c ((const char *) name, str - name,
					   uname2c_tree, NULL);
		  if (result == (cppchar_t) -1)
		    {
		      bool ret = true;
		      if (identifier_pos
			  && (!CPP_OPTION (pfile, named_uc_escape_seqs)
			      || !strict))
			ret = cpp_warning (pfile, CPP_W_UNICODE,
					   "%<\\N{%.*s}%> is not a valid "
					   "universal character; treating it "
					   "as separate tokens",
					   (int) (str - name), name);
		      else
			cpp_error (pfile, CPP_DL_ERROR,
				   "%<\\N{%.*s}%> is not a valid universal "
				   "character", (int) (str - name), name);

		      /* Try to do a loose name lookup according to
			 Unicode loose matching rule UAX44-LM2.  */
		      char canon_name[uname2c_max_name_len + 1];
		      result = _cpp_uname2c_uax44_lm2 ((const char *) name,
						       str - name, canon_name);
		      if (result != (cppchar_t) -1 && ret)
			cpp_error (pfile, CPP_DL_NOTE,
				   "did you mean %<\\N{%s}%>?", canon_name);
		      else
			result = 0xC0;
		      if (identifier_pos
			  && (!CPP_OPTION (pfile, named_uc_escape_seqs)
			      || !strict))
			{
			  *cp = 0;
			  return false;
			}
		    }
		}
	      str++;
	      extend_char_range (char_range, loc_reader);
	    }
	  else if (identifier_pos)
	    {
	      cpp_warning (pfile, CPP_W_UNICODE,
			   "%<\\N{%> not terminated with %<}%> after %.*s; "
			   "treating it as separate tokens",
			   (int) (str - base), base);
	      *cp = 0;
	      return false;
	    }
	  else
	    {
	      cpp_error (pfile, CPP_DL_ERROR,
			 "%<\\N{%> not terminated with %<}%> after %.*s",
			 (int) (str - base), base);
	      result = 1;
	    }
	}
    }
  else
    {
      cpp_error (pfile, CPP_DL_ICE, "in %<_cpp_valid_ucn%> but not a UCN");
      length = 4;
    }

  if (!named)
    do
      {
	if (str == limit)
	  break;
	c = *str;
	if (!ISXDIGIT (c))
	  break;
	str++;
	extend_char_range (char_range, loc_reader);
	if (delimited)
	  {
	    if (!result)
	      /* Accept arbitrary number of leading zeros.
		 16 is another magic value, smaller than 32 above
		 and bigger than 8, so that upon encountering first
		 non-zero digit we can count 8 digits and after that
		 or in overflow bit and ensure length doesn't decrease
		 to 0, as delimited escape sequence doesn't have upper
		 bound on the number of hex digits.  */
	      length = 16;
	    else if (length == 16 - 8)
	      {
		/* Make sure we detect overflows.  */
		result |= 0x8000000;
		++length;
	      }
	  }

	result = (result << 4) + hex_value (c);
      }
    while (--length);

  if (delimited && str < limit && *str == '}')
    {
      bool warned = false;
      if (length == 32 && identifier_pos)
	{
	  cpp_warning (pfile, CPP_W_UNICODE,
		       "empty delimited escape sequence; "
		       "treating it as separate tokens");
	  *cp = 0;
	  return false;
	}
      else if (length == 32)
	{
	  cpp_error (pfile, CPP_DL_ERROR, "empty delimited escape sequence");
	  warned = true;
	}
      else if (!CPP_OPTION (pfile, delimited_escape_seqs)
	       && CPP_OPTION (pfile, cpp_pedantic))
	{
	  if (CPP_OPTION (pfile, cplusplus))
	    warned
	      = cpp_pedwarning (pfile, CPP_W_CXX23_EXTENSIONS,
				"delimited escape sequences are only valid "
				"in C++23");
	  else
	    warned
	      = cpp_pedwarning (pfile, CPP_W_PEDANTIC,
				"delimited escape sequences are only valid "
				"in C2Y");
	}
      if (!warned && CPP_OPTION (pfile, cpp_warn_c23_c2y_compat) > 0)
	cpp_warning (pfile, CPP_W_C11_C23_COMPAT,
		     "delimited escape sequences are only valid in C2Y");

      str++;
      length = 0;
      delimited = false;
      extend_char_range (char_range, loc_reader);
    }

  /* Partial UCNs are not valid in strings, but decompose into
     multiple tokens in identifiers, so we can't give a helpful
     error message in that case.  */
  if (length && identifier_pos)
    {
      if (delimited)
	cpp_warning (pfile, CPP_W_UNICODE,
		     "%<\\u{%> not terminated with %<}%> after %.*s; "
		     "treating it as separate tokens",
		     (int) (str - base), base);
      *cp = 0;
      return false;
    }

  *pstr = str;
  if (length)
    {
      if (!delimited)
	cpp_error (pfile, CPP_DL_ERROR,
		   "incomplete universal character name %.*s",
		   (int) (str - base), base);
      else
	cpp_error (pfile, CPP_DL_ERROR,
		   "%<\\u{%> not terminated with %<}%> after %.*s",
		   (int) (str - base), base);
      result = 1;
    }
  else if ((result & 0x80000000)
	   || (result >= 0xD800 && result <= 0xDFFF))
    {
      cpp_error (pfile, CPP_DL_ERROR,
		 "%.*s is not a valid universal character",
		 (int) (str - base), base);
      result = 1;
    }
  /* The C99 standard permits $, @ and ` to be specified as UCNs.  We use
     hex escapes so that this also works with EBCDIC hosts.
     C++0x permits everything below 0xa0 within literals, as does C23;
     ucn_valid_in_identifier will complain about identifiers.  */
  else if (result < 0xa0
	   && !identifier_pos
	   && !CPP_OPTION (pfile, cplusplus)
	   && (result != 0x24 && result != 0x40 && result != 0x60))
    {
      bool warned = false;
      if (!CPP_OPTION (pfile, low_ucns) && CPP_OPTION (pfile, cpp_pedantic))
	warned = cpp_pedwarning (pfile, CPP_W_PEDANTIC,
				 "%.*s is not a valid universal character"
				 " name before C23", (int) (str - base), base);
      if (!warned && CPP_OPTION (pfile, cpp_warn_c11_c23_compat) > 0)
	warned = cpp_warning (pfile, CPP_W_C11_C23_COMPAT,
			      "%.*s is not a valid universal character"
			      " name before C23", (int) (str - base), base);
    }
  else if (identifier_pos && result == 0x24
	   && CPP_OPTION (pfile, dollars_in_ident)
	   /* In C++26 when dollars are allowed in identifiers,
	      we should still reject \u0024 as $ is part of the basic
	      character set.  C23 also does not allow \u0024 in
	      identifiers.  */
	   && !(CPP_OPTION (pfile, cplusplus)
		? CPP_OPTION (pfile, lang) > CLK_CXX23
		: CPP_OPTION (pfile, low_ucns)))
    {
      if (CPP_OPTION (pfile, warn_dollars) && !pfile->state.skipping)
	{
	  CPP_OPTION (pfile, warn_dollars) = 0;
	  cpp_error (pfile, CPP_DL_PEDWARN, "%<$%> in identifier or number");
	}
      NORMALIZE_STATE_UPDATE_IDNUM (nst, result);
    }
  else if (identifier_pos)
    {
      int validity = ucn_valid_in_identifier (pfile, result, nst);

      if (validity == 0)
	cpp_error (pfile, CPP_DL_ERROR,
		   "universal character %.*s is not valid in an identifier",
		   (int) (str - base), base);
      else if (validity == 2 && identifier_pos == 1)
	cpp_error (pfile, CPP_DL_ERROR,
   "universal character %.*s is not valid at the start of an identifier",
		   (int) (str - base), base);
    }
  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,
   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,
	     source_range char_range,
	     cpp_string_location_reader *loc_reader,
	     cpp_substring_ranges *ranges)
{
  cppchar_t ucn;
  uchar buf[6];
  uchar *bufp = buf;
  size_t bytesleft = 6;
  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/N.  */

  /* The u/U is part of the spelling of this character.  */
  extend_char_range (&char_range, loc_reader);

  _cpp_valid_ucn (pfile, &from, limit, 0, &nst,
		  &ucn, &char_range, loc_reader);

  rval = one_cppchar_to_utf8 (ucn, &bufp, &bytesleft);
  if (rval)
    {
      errno = rval;
      cpp_errno (pfile, CPP_DL_ERROR,
		 "converting UCN to source character set");
    }
  else
    {
      if (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.

    _cpp_valid_utf8 can be called when lexing a potential identifier, or a
    CPP_OTHER token or for the purposes of -Winvalid-utf8 warning in string or
    character literals.  NST is unused when not in a potential identifier.

    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;
}

/* Return true iff BUFFER of size NUM_BYTES is validly-encoded UTF-8.  */

extern bool
cpp_valid_utf8_p (const char *buffer, size_t num_bytes)
{
  const uchar *iter = (const uchar *)buffer;
  size_t bytesleft = num_bytes;
  while (bytesleft > 0)
    {
      /* one_utf8_to_cppchar implements 5-byte and 6 byte sequences as per
	 RFC 2279, but this has been superceded by RFC 3629, which
	 restricts UTF-8 to 1-byte through 4-byte sequences, and
	 states "the octet values C0, C1, F5 to FF never appear".

	 Reject such values.  */
      if (*iter >= 0xf4)
	return false;

      cppchar_t cp;
      int err = one_utf8_to_cppchar (&iter, &bytesleft, &cp);
      if (err)
	return false;

      /* Additionally, Unicode declares that all codepoints above 0010FFFF are
	 invalid because they cannot be represented in UTF-16.

	 Reject such values.*/
      if (cp > UCS_LIMIT)
	return false;
    }
  /* No problems encountered.  */
  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
   is true if it's a wide string that's being assembled in TBUF.  This
   function issues no diagnostics and never fails.  */
static void
emit_numeric_escape (cpp_reader *pfile, cppchar_t n,
		     struct _cpp_strbuf *tbuf, struct cset_converter cvt)
{
  size_t width = cvt.width;

  if (width != CPP_OPTION (pfile, char_precision))
    {
      /* We have to render this into the target byte order, which may not
	 be our byte order.  */
      bool bigend = CPP_OPTION (pfile, bytes_big_endian);
      size_t cwidth = CPP_OPTION (pfile, char_precision);
      size_t cmask = width_to_mask (cwidth);
      size_t nbwc = width / cwidth;
      size_t i;
      size_t off = tbuf->len;
      cppchar_t c;

      if (tbuf->len + nbwc > tbuf->asize)
	{
	  tbuf->asize += OUTBUF_BLOCK_SIZE;
	  tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize);
	}

      for (i = 0; i < nbwc; i++)
	{
	  c = n & cmask;
	  n >>= cwidth;
	  tbuf->text[off + (bigend ? nbwc - i - 1 : i)] = c;
	}
      tbuf->len += nbwc;
    }
  else
    {
      /* Note: this code does not handle the case where the target
	 and host have a different number of bits in a byte.  */
      if (tbuf->len + 1 > tbuf->asize)
	{
	  tbuf->asize += OUTBUF_BLOCK_SIZE;
	  tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize);
	}
      tbuf->text[tbuf->len++] = n;
    }
}

/* Convert a hexadecimal escape, pointed to by FROM, to the execution
   character set and write it into the string buffer TBUF (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.
   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,
	     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);
  bool delimited = false;
  const uchar *base = from - 1;

  /* 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");

  /* Skip 'x'.  */
  from++;

  /* The 'x' is part of the spelling of this character.  */
  extend_char_range (&char_range, loc_reader);

  if (from < limit && *from == '{')
    {
      delimited = true;
      from++;
      extend_char_range (&char_range, loc_reader);
    }

  while (from < limit)
    {
      c = *from;
      if (! hex_p (c))
	break;
      from++;
      extend_char_range (&char_range, loc_reader);
      overflow |= n ^ (n << 4 >> 4);
      n = (n << 4) + hex_value (c);
      digits_found = 1;
    }

  if (delimited && from < limit && *from == '}')
    {
      bool warned = false;
      from++;
      if (!digits_found)
	{
	  cpp_error (pfile, CPP_DL_ERROR,
		     "empty delimited escape sequence");
	  return from;
	}
      else if (!CPP_OPTION (pfile, delimited_escape_seqs)
	       && CPP_OPTION (pfile, cpp_pedantic))
	{
	  if (CPP_OPTION (pfile, cplusplus))
	    warned
	      = cpp_pedwarning (pfile, CPP_W_CXX23_EXTENSIONS,
				"delimited escape sequences are only valid "
				"in C++23");
	  else
	    warned
	      = cpp_pedwarning (pfile, CPP_W_PEDANTIC,
				"delimited escape sequences are only valid "
				"in C2Y");
	}
      if (!warned && CPP_OPTION (pfile, cpp_warn_c23_c2y_compat) > 0)
	cpp_warning (pfile, CPP_W_C11_C23_COMPAT,
		     "delimited escape sequences are only valid in C2Y");
      delimited = false;
      extend_char_range (&char_range, loc_reader);
    }

  if (!digits_found)
    {
      cpp_error (pfile, CPP_DL_ERROR,
		 "%<\\x%> used with no following hex digits");
      return from;
    }
  else if (delimited)
    {
      cpp_error (pfile, CPP_DL_ERROR,
		 "%<\\x{%> not terminated with %<}%> after %.*s",
		 (int) (from - base), base);
      return from;
    }

  if (overflow | (n != (n & mask)))
    {
      cpp_error (pfile, CPP_DL_PEDWARN,
		 "hex escape sequence out of range");
      n &= mask;
    }

  if (tbuf)
    emit_numeric_escape (pfile, n, tbuf, cvt);
  if (ranges)
    ranges->add_range (char_range);

  return from;
}

/* Convert an octal escape, pointed to by FROM, to the execution
   character set and write it into the string buffer TBUF.  Returns an
   advanced pointer, and issues diagnostics as necessary.
   No character set translation occurs; this routine always produces the
   execution-set character with numeric value equal to the given octal
   number.
   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,
	     source_range char_range,
	     cpp_string_location_reader *loc_reader,
	     cpp_substring_ranges *ranges)
{
  size_t count = 0;
  cppchar_t c, n = 0, overflow = 0;
  size_t width = cvt.width;
  size_t mask = width_to_mask (width);
  bool delimited = false;
  const uchar *base = from - 1;

  /* loc_reader and ranges must either be both NULL, or both be non-NULL.  */
  gcc_assert ((loc_reader != NULL) == (ranges != NULL));

  if (from < limit && *from == 'o')
    {
      from++;
      extend_char_range (&char_range, loc_reader);
      if (from == limit || *from != '{')
	cpp_error (pfile, CPP_DL_ERROR, "%<\\o%> not followed by %<{%>");
      else
	{
	  from++;
	  extend_char_range (&char_range, loc_reader);
	  delimited = true;
	}
    }

  while (from < limit && count++ < 3)
    {
      c = *from;
      if (c < '0' || c > '7')
	break;
      from++;
      extend_char_range (&char_range, loc_reader);
      if (delimited)
	{
	  count = 2;
	  overflow |= n ^ (n << 3 >> 3);
	}
      n = (n << 3) + c - '0';
    }

  if (delimited)
    {
      if (from < limit && *from == '}')
	{
	  bool warned = false;
	  from++;
	  if (count == 1)
	    {
	      cpp_error (pfile, CPP_DL_ERROR,
			 "empty delimited escape sequence");
	      return from;
	    }
	  else if (!CPP_OPTION (pfile, delimited_escape_seqs)
		   && CPP_OPTION (pfile, cpp_pedantic))
	    {
	      if (CPP_OPTION (pfile, cplusplus))
		warned
		  = cpp_pedwarning (pfile, CPP_W_CXX23_EXTENSIONS,
				    "delimited escape sequences are only "
				    "valid in C++23");
	      else
		warned
		  = cpp_pedwarning (pfile, CPP_W_PEDANTIC,
				    "delimited escape sequences are only "
				    "valid in C2Y");
	    }
	  if (!warned && CPP_OPTION (pfile, cpp_warn_c23_c2y_compat) > 0)
	    cpp_warning (pfile, CPP_W_C11_C23_COMPAT,
			 "delimited escape sequences are only valid in C2Y");
	  extend_char_range (&char_range, loc_reader);
	}
      else
	{
	  cpp_error (pfile, CPP_DL_ERROR,
		     "%<\\o{%> not terminated with %<}%> after %.*s",
		     (int) (from - base), base);
	  return from;
	}
    }

  if (overflow | (n != (n & mask)))
    {
      cpp_error (pfile, CPP_DL_PEDWARN,
		 "octal escape sequence out of range");
      n &= mask;
    }

  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, 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,
		cpp_string_location_reader *loc_reader,
		cpp_substring_ranges *ranges, bool uneval)
{
  /* Values of \a \b \e \f \n \r \t \v respectively.  */
#if HOST_CHARSET == HOST_CHARSET_ASCII
  static const uchar charconsts[] = {  7,  8, 27, 12, 10, 13,  9, 11 };
#elif HOST_CHARSET == HOST_CHARSET_EBCDIC
  static const uchar charconsts[] = { 47, 22, 39, 12, 21, 13,  5, 11 };
#else
#error "unknown host character set"
#endif

  uchar c;

  /* 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': case 'N':
      return convert_ucn (pfile, from, limit, tbuf, cvt,
			  char_range, loc_reader, ranges);

    case 'x':
      if (uneval)
	cpp_pedwarning (pfile, CPP_W_PEDANTIC,
			"numeric escape sequence in unevaluated string: "
			"%<\\%c%>", (int) c);
      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':
    case 'o':
      if (uneval)
	cpp_pedwarning (pfile, CPP_W_PEDANTIC,
			"numeric escape sequence in unevaluated string: "
			"%<\\%c%>", (int) c);
      return convert_oct (pfile, from, limit, tbuf, cvt,
			  char_range, loc_reader, ranges);

      /* Various letter escapes.  Get the appropriate host-charset
	 value into C.  */
    case '\\': case '\'': case '"': case '?': break;

    case '(': case '{': case '[': case '%':
      /* '\(', etc, can be used at the beginning of a line in a long
	 string split onto multiple lines with \-newline, to prevent
	 Emacs or other text editors from getting confused.  '\%' can
	 be used to prevent SCCS from mangling printf format strings.  */
      if (CPP_PEDANTIC (pfile))
	goto unknown;
      break;

    case 'b': c = charconsts[1];  break;
    case 'f': c = charconsts[3];  break;
    case 'n': c = charconsts[4];  break;
    case 'r': c = charconsts[5];  break;
    case 't': c = charconsts[6];  break;
    case 'v': c = charconsts[7];  break;

    case 'a':
      if (CPP_WTRADITIONAL (pfile))
	cpp_warning (pfile, CPP_W_TRADITIONAL,
		     "the meaning of %<\\a%> is different in traditional C");
      c = charconsts[0];
      break;

    case 'e': case 'E':
      cpp_pedwarning (pfile, CPP_W_PEDANTIC,
		      "non-ISO-standard escape sequence, %<\\%c%>", (int) c);
      c = charconsts[2];
      break;

    default:
    unknown:
      if (ISGRAPH (c))
	cpp_error (pfile, CPP_DL_PEDWARN,
		   "unknown escape sequence: %<\\%c%>", (int) c);
      else
	{
	  encoding_rich_location rich_loc (pfile);

	  /* pretty-print.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_at (pfile, CPP_DL_PEDWARN, &rich_loc,
			"unknown escape sequence: %<\\%s%>", buf);
	}
    }

  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;
}

/* TYPE is a token type.  The return value is the conversion needed to
   convert from source to execution character set for the given type. */
static struct cset_converter
converter_for_type (cpp_reader *pfile, enum cpp_ttype type)
{
  switch (type)
    {
    default:
	return pfile->narrow_cset_desc;
    case CPP_UTF8CHAR:
    case CPP_UTF8STRING:
	return pfile->utf8_cset_desc;
    case CPP_CHAR16:
    case CPP_STRING16:
	return pfile->char16_cset_desc;
    case CPP_CHAR32:
    case CPP_STRING32:
	return pfile->char32_cset_desc;
    case CPP_WCHAR:
    case CPP_WSTRING:
	return pfile->wide_cset_desc;
    }
}

/* FROM is an array of cpp_string structures of length COUNT.  These
   are to be converted from the source to the execution character set,
   escape sequences translated, and finally all are to be
   concatenated.  WIDE indicates whether or not to produce a wide
   string.  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);

  /* 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')
	{
	  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')
	{
	  const uchar *prefix;

	  /* Skip over 'R"'.  */
	  p += 2;
	  if (loc_reader)
	    {
	      loc_reader->get_next ();
	      loc_reader->get_next ();
	    }
	  prefix = p;
	  while (*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 (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;
	}

      /* 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 (;;)
	{
	  base = p;
	  while (p < limit && *p != '\\')
	    p++;
	  if (p > base)
	    {
	      /* We have a run of normal characters; these can be fed
		 directly to convert_cset.  */
	      if (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)
	    break;

	  struct _cpp_strbuf *tbuf_ptr = to ? &tbuf : NULL;
	  p = convert_escape (pfile, p + 1, limit, tbuf_ptr, cvt,
			      loc_reader, out, type == CPP_UNEVAL_STRING);
	}
    }

  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");
  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);
}

/* 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.  */
  cpp_auto_suppress_diagnostics suppress {pfile};
  bool result = cpp_interpret_string_1 (pfile, from, count, NULL, type,
					loc_readers, out);
  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
cpp_interpret_string_notranslate (cpp_reader *pfile, const cpp_string *from,
				  size_t count,	cpp_string *to,
				  enum cpp_ttype type)
{
  struct cset_converter save_narrow_cset_desc = pfile->narrow_cset_desc;
  bool retval;

  pfile->narrow_cset_desc.func = convert_no_conversion;
  pfile->narrow_cset_desc.cd = (iconv_t) -1;
  pfile->narrow_cset_desc.width = CPP_OPTION (pfile, char_precision);

  retval = cpp_interpret_string (pfile, from, count, to,
				 type == CPP_UNEVAL_STRING
				 ? CPP_UNEVAL_STRING : CPP_STRING);

  pfile->narrow_cset_desc = save_narrow_cset_desc;
  return retval;
}

/* Convert a string FROM to TO, without handling of any UCNs etc., just
   pure character set conversion.  If !REVERSE, convert from SOURCE_CHARSET
   to execution charset corresponding to TYPE, if REVERSE, convert from the
   execution charset corresponding to TYPE to SOURCE_CHARSET.  Return false
   on error.  */

bool
cpp_translate_string (cpp_reader *pfile, const cpp_string *from,
		      cpp_string *to, enum cpp_ttype type, bool reverse)
{
  struct cset_converter cvt = converter_for_type (pfile, type);
  struct _cpp_strbuf tbuf;
  if (reverse)
    {
      struct cset_converter *pcvt;
      switch (type)
	{
	default:
	  pcvt = &pfile->reverse_narrow_cset_desc;
	  break;
	case CPP_UTF8CHAR:
	case CPP_UTF8STRING:
	  pcvt = &pfile->reverse_utf8_cset_desc;
	  break;
	case CPP_CHAR16:
	case CPP_STRING16:
	case CPP_CHAR32:
	case CPP_STRING32:
	case CPP_WCHAR:
	case CPP_WSTRING:
	  return false;
	}
      if (pcvt->func == NULL)
	{
	  *pcvt = init_iconv_desc (pfile, cvt.from, cvt.to);
	  pcvt->width = cvt.width;
	}
      cvt = *pcvt;
    }
  tbuf.asize = MAX (OUTBUF_BLOCK_SIZE, from->len);
  tbuf.text = XNEWVEC (uchar, tbuf.asize);
  tbuf.len = 0;
  if (!APPLY_CONVERSION (cvt, from->text, from->len, &tbuf))
    {
      XDELETEVEC (tbuf.text);
      return false;
    }
  tbuf.text = XRESIZEVEC (uchar, tbuf.text, tbuf.len);
  to->text = tbuf.text;
  to->len = tbuf.len;
  return true;
}

/* Return true if ID is a valid identifier, false otherwise.  Without any
   diagnostics.  */

bool
cpp_valid_identifier (cpp_reader *pfile, const unsigned char *id)
{
  normalize_state nst = INITIAL_NORMALIZE_STATE;
  const unsigned char *p = id;
  if (*p == '\0')
    return false;
  const unsigned char *limit
    = (const unsigned char *) strchr ((const char *) p, '\0');
  static const cppchar_t utf8_signifier = 0xC0;
  if (ISIDST (*p))
    {
      NORMALIZE_STATE_UPDATE_IDNUM (&nst, *p);
      ++p;
    }
  while (*p)
    {
      if (p != id && ISIDNUM (*p))
	{
	  while (ISIDNUM (*p))
	    ++p;
	  NORMALIZE_STATE_UPDATE_IDNUM (&nst, *(p - 1));
	  continue;
	}
      if (CPP_OPTION (pfile, extended_identifiers) && *p >= utf8_signifier)
	{
	  const unsigned char *base = p;
	  size_t inbytesleft = limit - p;
	  cppchar_t c;
	  if (one_utf8_to_cppchar (&p, &inbytesleft, &c))
	    return false;
	  switch (ucn_valid_in_identifier (pfile, c, &nst))
	    {
	    default:
	      return false;
	    case 1:
	      continue;
	    case 2:
	      if (base == id)
		return false;
	      continue;
	    }
	}
      return false;
    }
  return true;
}


/* Return number of source characters in STR.  */
static unsigned
count_source_chars (cpp_reader *pfile, cpp_string str, cpp_ttype type)
{
  cpp_string str2 = { 0, 0 };
  cpp_auto_suppress_diagnostics suppress {pfile};
  convert_f save_func = pfile->narrow_cset_desc.func;
  pfile->narrow_cset_desc.func = convert_count_chars;
  bool ret = cpp_interpret_string (pfile, &str, 1, &str2, type);
  pfile->narrow_cset_desc.func = save_func;
  if (ret)
    {
      if (str2.text != str.text)
	free ((void *)str2.text);
      return str2.len;
    }
  else
    return 0;
}

/* 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.  TOKEN is the token.  */
static cppchar_t
narrow_str_to_charconst (cpp_reader *pfile, cpp_string str,
			 unsigned int *pchars_seen, int *unsignedp,
			 const cpp_token *token)
{
  enum cpp_ttype type = token->type;
  size_t width = CPP_OPTION (pfile, char_precision);
  size_t max_chars = CPP_OPTION (pfile, int_precision) / width;
  size_t mask = width_to_mask (width);
  size_t i;
  cppchar_t result, c;
  bool unsigned_p;
  bool diagnosed = false;

  /* The value of a multi-character character constant, or a
     single-character character constant whose representation in the
     execution character set is more than one byte long, is
     implementation defined.  This implementation defines it to be the
     number formed by interpreting the byte sequence in memory as a
     big-endian binary number.  If overflow occurs, the high bytes are
     lost, and a warning is issued.

     We don't want to process the NUL terminator handed back by
     cpp_interpret_string.  */
  result = 0;
  for (i = 0; i < str.len - 1; i++)
    {
      c = str.text[i] & mask;
      if (width < BITS_PER_CPPCHAR_T)
	result = (result << width) | c;
      else
	result = c;
    }

  if (type == CPP_UTF8CHAR)
    max_chars = 1;
  else if (i > 1 && CPP_OPTION (pfile, cplusplus))
    {
      /* C++ as a DR since
	 P1854R4 - Making non-encodable string literals ill-formed
	 makes multi-character narrow character literals if any of the
	 characters in the literal isn't encodable in char/unsigned char
	 ill-formed.  We need to count the number of c-chars and compare
	 that to str.len.  */
      unsigned src_chars = count_source_chars (pfile, token->val.str, type);

      if (src_chars)
	{
	  if (str.len > src_chars)
	    {
	      if (src_chars <= 2)
		diagnosed
		  = cpp_pedwarning (pfile, CPP_W_PEDANTIC,
				    "character not encodable in a single "
				    "execution character code unit");
	      else
		diagnosed
		  = cpp_pedwarning (pfile, CPP_W_PEDANTIC,
				    "at least one character in a multi-"
				    "character literal not encodable in a "
				    "single execution character code unit");
	      if (diagnosed && i > max_chars)
		i = max_chars;
	    }
	}
    }
  if (diagnosed)
    /* Already diagnosed above.  */;
  else if (i > max_chars)
    {
      unsigned src_chars
	= count_source_chars (pfile, token->val.str,
			      type == CPP_UTF8CHAR ? CPP_CHAR : type);

      if (type != CPP_UTF8CHAR)
	cpp_error (pfile, CPP_DL_WARNING,
		   "multi-character literal with %ld characters exceeds "
		   "%<int%> size of %ld bytes", (long) i, (long) max_chars);
      else if (src_chars > 2)
	cpp_error (pfile, CPP_DL_ERROR,
		   "multi-character literal cannot have an encoding prefix");
      else
	cpp_error (pfile, CPP_DL_ERROR,
		   "character not encodable in a single code unit");
      i = max_chars;
    }
  else if (i > 1 && CPP_OPTION (pfile, warn_multichar))
    cpp_warning (pfile, CPP_W_MULTICHAR, "multi-character character constant");

  /* Multichar constants are of type int and therefore signed.  */
  if (i > 1)
    unsigned_p = 0;
  else if (type == CPP_UTF8CHAR)
    unsigned_p = CPP_OPTION (pfile, unsigned_utf8char);
  else
    unsigned_p = CPP_OPTION (pfile, unsigned_char);

  /* Truncate the constant to its natural width, and simultaneously
     sign- or zero-extend to the full width of cppchar_t.
     For single-character constants, the value is WIDTH bits wide.
     For multi-character constants, the value is INT_PRECISION bits wide.  */
  if (i > 1)
    width = CPP_OPTION (pfile, int_precision);
  if (width < BITS_PER_CPPCHAR_T)
    {
      mask = ((cppchar_t) 1 << width) - 1;
      if (unsigned_p || !(result & (1 << (width - 1))))
	result &= mask;
      else
	result |= ~mask;
    }
  *pchars_seen = i;
  *unsignedp = unsigned_p;
  return result;
}

/* Subroutine of cpp_interpret_charconst which performs the conversion
   to a number, for wide strings.  STR is the string structure returned
   by cpp_interpret_string.  PCHARS_SEEN and UNSIGNEDP are as for
   cpp_interpret_charconst.  TOKEN is the token.  */
static cppchar_t
wide_str_to_charconst (cpp_reader *pfile, cpp_string str,
		       unsigned int *pchars_seen, int *unsignedp,
		       const cpp_token *token)
{
  enum cpp_ttype type = token->type;
  bool bigend = CPP_OPTION (pfile, bytes_big_endian);
  size_t width = converter_for_type (pfile, type).width;
  size_t cwidth = CPP_OPTION (pfile, char_precision);
  size_t mask = width_to_mask (width);
  size_t cmask = width_to_mask (cwidth);
  size_t nbwc = width / cwidth;
  size_t off, i;
  cppchar_t result = 0, c;

  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.  */
  off = str.len - (nbwc * 2);
  result = 0;
  for (i = 0; i < nbwc; i++)
    {
      c = bigend ? str.text[off + i] : str.text[off + nbwc - i - 1];
      result = (result << cwidth) | (c & cmask);
    }

  /* Wide character constants have type wchar_t, and a single
     character exactly fills a wchar_t, so a multi-character wide
     character constant is guaranteed to overflow.  */
  if (str.len > nbwc * 2)
    {
      cpp_diagnostic_level level = CPP_DL_WARNING;
      unsigned src_chars
	= count_source_chars (pfile, token->val.str, CPP_CHAR);

      if (CPP_OPTION (pfile, cplusplus)
	  && (type == CPP_CHAR16
	      || type == CPP_CHAR32
	      /* In C++23 this is error even for L'ab'.  */
	      || (type == CPP_WCHAR
		  && CPP_OPTION (pfile, size_t_literals))))
	level = CPP_DL_ERROR;
      if (src_chars > 2)
	cpp_error (pfile, level,
		   "multi-character literal cannot have an encoding prefix");
      else
	cpp_error (pfile, level,
		   "character not encodable in a single code unit");
    }

  /* Truncate the constant to its natural width, and simultaneously
     sign- or zero-extend to the full width of cppchar_t.  */
  if (width < BITS_PER_CPPCHAR_T)
    {
      if (type == CPP_CHAR16 || type == CPP_CHAR32
	  || CPP_OPTION (pfile, unsigned_wchar)
	  || !(result & (1 << (width - 1))))
	result &= mask;
      else
	result |= ~mask;
    }

  if (type == CPP_CHAR16 || type == CPP_CHAR32
      || CPP_OPTION (pfile, unsigned_wchar))
    *unsignedp = 1;
  else
    *unsignedp = 0;

  *pchars_seen = 1;
  return result;
}

/* Interpret a (possibly wide) character constant in TOKEN.
   PCHARS_SEEN points to a variable that is filled in with the number
   of characters seen, and UNSIGNEDP to a variable that indicates
   whether the result has signed type.  */
cppchar_t
cpp_interpret_charconst (cpp_reader *pfile, const cpp_token *token,
			 unsigned int *pchars_seen, int *unsignedp)
{
  cpp_string str = { 0, 0 };
  bool wide = (token->type != CPP_CHAR && token->type != CPP_UTF8CHAR);
  int u8 = 2 * int(token->type == CPP_UTF8CHAR);
  cppchar_t result;

  /* 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;
    }

  if (wide)
    result = wide_str_to_charconst (pfile, str, pchars_seen, unsignedp,
				    token);
  else
    result = narrow_str_to_charconst (pfile, str, pchars_seen, unsignedp,
				      token);

  if (str.text != token->val.str.text)
    free ((void *)str.text);

  return result;
}

/* Convert an identifier denoted by ID and LEN, which might contain
   UCN escapes 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)
{
  /* It turns out that a UCN escape always turns into fewer characters
     than the escape itself, so we can allocate a temporary in advance.  */
  uchar * buf = (uchar *) alloca (len + 1);
  uchar * bufp = buf;
  size_t idp;

  for (idp = 0; idp < len; idp++)
    if (id[idp] != '\\')
      *bufp++ = id[idp];
    else
      {
	unsigned length = id[idp + 1] == 'u' ? 4 : 8;
	cppchar_t value = 0;
	size_t bufleft = len - (bufp - buf);
	int rval;
	bool delimited = false;

	idp += 2;
	if (id[idp - 1] == 'N' && id[idp] == '{')
	  {
	    idp++;
	    const uchar *name = &id[idp];
	    while (idp < len
		   && (ISIDNUM (id[idp]) || id[idp] == ' ' || id[idp] == '-'))
	      idp++;
	    if (id[idp] == '}')
	      {
		value = _cpp_uname2c ((const char *) name, &id[idp] - name,
				      uname2c_tree, NULL);
		if (value == (cppchar_t) -1)
		  value = 1;
	      }
	    else
	      idp--;
	  }
	else
	  {
	    if (length == 4 && id[idp] == '{')
	      {
		delimited = true;
		idp++;
	      }
	    while (length && idp < len && ISXDIGIT (id[idp]))
	      {
		value = (value << 4) + hex_value (id[idp]);
		idp++;
		if (!delimited)
		  length--;
	      }
	    if (!delimited || id[idp] != '}')
	      idp--;
	  }

	/* Special case for EBCDIC: if the identifier contains
	   a '$' specified using a UCN, translate it to EBCDIC.  */
	if (value == 0x24)
	  {
	    *bufp++ = '$';
	    continue;
	  }

	rval = one_cppchar_to_utf8 (value, &bufp, &bufleft);
	if (rval)
	  {
	    errno = rval;
	    cpp_errno (pfile, CPP_DL_ERROR,
		       "converting UCN to source character set");
	    break;
	  }
      }

  return CPP_HASHNODE (ht_lookup (pfile->hash_table,
				  buf, bufp - buf, HT_ALLOC));
}


/* 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
   the length of the meaningful data within the buffer.  The
   translated buffer is returned, *ST_SIZE is set to the length of
   the meaningful data within the translated buffer, and *BUFFER_START
   is set to the start of the returned buffer.  *BUFFER_START may
   differ from the return value in the case of a BOM or other ignored
   marker information.

   INPUT is expected to have been allocated with xmalloc.  This
   function will either set *BUFFER_START to INPUT, or free it and set
   *BUFFER_START to a pointer to another xmalloc-allocated block of
   memory.

   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,
		    const unsigned char **buffer_start, off_t *st_size)
{
  struct cset_converter input_cset;
  struct _cpp_strbuf to;
  unsigned char *buffer;
  size_t pad = CPP_BUFFER_PADDING;

  input_cset = init_iconv_desc (pfile, SOURCE_CHARSET, input_charset);
  if (input_cset.func == convert_no_conversion)
    {
      to.text = input;
      to.asize = size;
      to.len = len;
    }
  else
    {
      to.asize = MAX (65536, len);
      to.text = XNEWVEC (uchar, to.asize);
      to.len = 0;

      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);

      /* 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
     don't have enough space for the following padding, which allows
     search_line_fast to use (possibly misaligned) vector loads.  */
  if (to.len + 4096 < to.asize || to.len + pad > to.asize)
    to.text = XRESIZEVEC (uchar, to.text, to.len + pad);

  memset (to.text + to.len, '\0', pad);

  /* If the file is using old-school Mac line endings (\r only),
     terminate with another \r, not an \n, so that we do not mistake
     the \r\n sequence for a single DOS line ending and erroneously
     issue the "No newline at end of file" diagnostic.  */
  if (to.len && to.text[to.len - 1] == '\r')
    to.text[to.len] = '\r';
  else
    to.text[to.len] = '\n';

  buffer = to.text;
  *st_size = to.len;

  /* 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.  */
  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;
}

/* Decide on the default encoding to assume for input files.  */
const char *
_cpp_default_encoding (void)
{
  const char *current_encoding = NULL;

  /* We disable this because the default codeset is 7-bit ASCII on
     most platforms, and this causes conversion failures on every
     file in GCC that happens to have one of the upper 128 characters
     in it -- most likely, as part of the name of a contributor.
     We should definitely recognize in-band markers of file encoding,
     like:
     - the appropriate Unicode byte-order mark (FE FF) to recognize
       UTF16 and UCS4 (in both big-endian and little-endian flavors)
       and UTF8
     - a "#i", "#d", "/ *", "//", " #p" or "#p" (for #pragma) to
       distinguish ASCII and EBCDIC.
     - now we can parse something like "#pragma GCC encoding <xyz>
       on the first line, or even Emacs/VIM's mode line tags (there's
       a problem here in that VIM uses the last line, and Emacs has
       its more elaborate "local variables" convention).
     - investigate whether Java has another common convention, which
       would be friendly to support.
     (Zack Weinberg and Paolo Bonzini, May 20th 2004)  */
#if defined (HAVE_LOCALE_H) && defined (HAVE_LANGINFO_CODESET) && 0
  setlocale (LC_CTYPE, "");
  current_encoding = nl_langinfo (CODESET);
#endif
  if (current_encoding == NULL || *current_encoding == '\0')
    current_encoding = SOURCE_CHARSET;

  return current_encoding;
}

/* 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);
}

template <typename PropertyType>
PropertyType
get_cppchar_property (cppchar_t c,
		      const cppchar_t *range_ends,
		      const PropertyType *range_values,
		      size_t num_ranges,
		      PropertyType default_value)
{
  if (__builtin_expect (c <= range_ends[0], true))
    return range_values[0];

  /* Binary search the tables.  */
  int begin = 1;
  static const int end = num_ranges;
  int len = end - begin;
  do
    {
      int half = len/2;
      int middle = begin + half;
      if (c > range_ends[middle])
	{
	  begin = middle + 1;
	  len -= half + 1;
	}
      else
	len = half;
    } while (len);

  if (__builtin_expect (begin != end, true))
    return range_values[begin];

  return default_value;
}

/* 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)
{
  const size_t num_ranges
    = sizeof wcwidth_range_ends / sizeof (*wcwidth_range_ends);
  return get_cppchar_property<unsigned char > (c,
					       &wcwidth_range_ends[0],
					       &wcwidth_widths[0],
					       num_ranges,
					       1);
}

#include "combining-chars.inc"

bool
cpp_is_combining_char (cppchar_t c)
{
  const size_t num_ranges
    = sizeof combining_range_ends / sizeof (*combining_range_ends);
  return get_cppchar_property<bool> (c,
				     &combining_range_ends[0],
				     &is_combining[0],
				     num_ranges,
				     false);
}

#include "printable-chars.inc"

bool
cpp_is_printable_char (cppchar_t c)
{
  const size_t num_ranges
    = sizeof printable_range_ends / sizeof (*printable_range_ends);
  return get_cppchar_property<bool> (c,
				     &printable_range_ends[0],
				     &is_printable[0],
				     num_ranges,
				     false);
}
