/* 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->reverse_narrow_cset_desc.cd);
      if (pfile->reverse_utf8_cset_desc.func == convert_using_iconv)
	iconv_close (pfile->reverse_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,
  /* Valid in C++23 but not in C23.  Set only when CXX23 is also set.  */
  NONC = 2048
};

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 & NONC)
    return 0;
  if ((flags & (CXX23 | NXX23)) == CXX23)
    return CPP_XID_START | CPP_XID_CONTINUE;
  if ((flags & (CXX23 | NXX23)) == (CXX23 | 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;
	  if (!CPP_OPTION (pfile, cplusplus)
	      && (ucnranges[mn].flags & NONC))
	    return 0;
	}
      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);
}
