/* CPP Library - charsets
   Copyright (C) 1998-2023 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);
    }
}

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

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

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

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

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

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



/* cpp_substring_ranges's constructor. */

cpp_substring_ranges::cpp_substring_ranges () :
  m_ranges (NULL),
  m_num_ranges (0),
  m_alloc_ranges (8)
{
  m_ranges = XNEWVEC (source_range, m_alloc_ranges);
}

/* cpp_substring_ranges's destructor. */

cpp_substring_ranges::~cpp_substring_ranges ()
{
  free (m_ranges);
}

/* Add RANGE to the vector of source_range information.  */

void
cpp_substring_ranges::add_range (source_range range)
{
  if (m_num_ranges >= m_alloc_ranges)
    {
      m_alloc_ranges *= 2;
      m_ranges
	= (source_range *)xrealloc (m_ranges,
				    sizeof (source_range) * m_alloc_ranges);
    }
  m_ranges[m_num_ranges++] = range;
}

/* Read NUM ranges from LOC_READER, adding them to the vector of source_range
   information.  */

void
cpp_substring_ranges::add_n_ranges (int num,
				    cpp_string_location_reader &loc_reader)
{
  for (int i = 0; i < num; i++)
    add_range (loc_reader.get_next ());
}



/* Utility routine that computes a mask of the form 0000...111... with
   WIDTH 1-bits.  */
static inline size_t
width_to_mask (size_t width)
{
  width = MIN (width, BITS_PER_CPPCHAR_T);
  if (width >= CHAR_BIT * sizeof (size_t))
    return ~(size_t) 0;
  else
    return ((size_t) 1 << width) - 1;
}

/* A large table of unicode character information.  */
enum {
  /* Valid in a C99 identifier?  */
  C99 = 1,
  /* Valid in a C99 identifier, but not as the first character?  */
  N99 = 2,
  /* Valid in a C++ identifier?  */
  CXX = 4,
  /* Valid in a C11/C++11 identifier?  */
  C11 = 8,
  /* Valid in a C11/C++11 identifier, but not as the first character?  */
  N11 = 16,
  /* Valid in a C++23 identifier?  */
  CXX23 = 32,
  /* Valid in a C++23 identifier, but not as the first character?  */
  NXX23 = 64,
  /* NFC representation is not valid in an identifier?  */
  CID = 128,
  /* Might be valid NFC form?  */
  NFC = 256,
  /* Might be valid NFKC form?  */
  NKC = 512,
  /* Certain preceding characters might make it not valid NFC/NKFC form?  */
  CTX = 1024
};

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

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

#include "uname2c.h"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

  if (c > UCS_LIMIT)
    return 0;

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

  /* When -pedantic, we require the character to have been listed by
     the standard for the current language.  Otherwise, we accept the
     union of the acceptable sets for all supported language versions.  */
  valid_flags = C99 | CXX | C11 | CXX23;
  if (CPP_PEDANTIC (pfile))
    {
      if (CPP_OPTION (pfile, xid_identifiers))
	valid_flags = CXX23;
      else if (CPP_OPTION (pfile, c11_identifiers))
	valid_flags = C11;
      else if (CPP_OPTION (pfile, c99))
	valid_flags = C99;
    }
  if (! (ucnranges[mn].flags & valid_flags))
      return 0;

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

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

  if (!CPP_PEDANTIC (pfile))
    {
      /* If not -pedantic, accept as character that may
	 begin an identifier a union of characters allowed
	 at that position in each of the character sets.  */
      if ((ucnranges[mn].flags & (C99 | N99)) == C99
	  || (ucnranges[mn].flags & CXX) != 0
	  || (ucnranges[mn].flags & (C11 | N11)) == C11
	  || (ucnranges[mn].flags & (CXX23 | NXX23)) == CXX23)
	return 1;
      return 2;
    }

  if (CPP_OPTION (pfile, xid_identifiers))
    invalid_start_flags = NXX23;
  else if (CPP_OPTION (pfile, c11_identifiers))
    invalid_start_flags = N11;
  else if (CPP_OPTION (pfile, c99))
    invalid_start_flags = N99;
  else
    invalid_start_flags = 0;

  /* In C99, UCN digits may not begin identifiers.  In C11 and C++11,
     UCN combining characters may not begin identifiers.  */
  if (ucnranges[mn].flags & invalid_start_flags)
    return 2;

  return 1;
}

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

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

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

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

   If the hexadecimal value is larger than the upper bound of the UCS
   codespace specified in ISO/IEC 10646, a pedantic warning is issued
   in all versions of C and in the C++20 or later versions of C++.

   *PSTR must be preceded by "\u" or "\U"; it is assumed that the
   buffer end is delimited by a non-hex digit.  Returns false if the
   UCN has not been consumed, true otherwise.

   The value of the UCN, whether valid or invalid, is returned in *CP.
   Diagnostics are emitted for invalid values.  PSTR is updated to point
   one beyond the UCN, or to the syntactically invalid character.

   IDENTIFIER_POS is 0 when not in an identifier, 1 for the start of
   an identifier, or 2 otherwise.

   If LOC_READER is non-NULL, then position information is
   read from *LOC_READER and CHAR_RANGE->m_finish is updated accordingly.  */

bool
_cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr,
		const uchar *limit, int identifier_pos,
		struct normalize_state *nst, cppchar_t *cp,
		source_range *char_range,
		cpp_string_location_reader *loc_reader)
{
  cppchar_t result, c;
  unsigned int length;
  const uchar *str = *pstr;
  const uchar *base = str - 2;
  bool delimited = false, named = false;

  if (!CPP_OPTION (pfile, cplusplus) && !CPP_OPTION (pfile, c99))
    cpp_error (pfile, CPP_DL_WARNING,
	       "universal character names are only valid in C++ and C99");
  else if (CPP_OPTION (pfile, cpp_warn_c90_c99_compat) > 0
	   && !CPP_OPTION (pfile, cplusplus))
    cpp_error (pfile, CPP_DL_WARNING,
	       "C99's universal character names are incompatible with C90");
  else if (CPP_WTRADITIONAL (pfile) && identifier_pos == 0)
    cpp_warning (pfile, CPP_W_TRADITIONAL,
	         "the meaning of '\\%c' is different in traditional C",
	         (int) str[-1]);

  result = 0;
  if (str[-1] == 'u')
    {
      length = 4;
      if (str < limit
	  && *str == '{'
	  && (!identifier_pos
	      || CPP_OPTION (pfile, delimited_escape_seqs)
	      || !CPP_OPTION (pfile, std)))
	{
	  str++;
	  /* Magic value to indicate no digits seen.  */
	  length = 32;
	  delimited = true;
	  extend_char_range (char_range, loc_reader);
	}
    }
  else if (str[-1] == 'U')
    length = 8;
  else if (str[-1] == 'N')
    {
      length = 4;
      if (identifier_pos
	  && !CPP_OPTION (pfile, delimited_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, delimited_escape_seqs)
		       && CPP_OPTION (pfile, cpp_pedantic))
		cpp_error (pfile, CPP_DL_PEDWARN,
			   "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, delimited_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, delimited_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 == '}')
    {
      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");
      else if (!CPP_OPTION (pfile, delimited_escape_seqs)
	       && CPP_OPTION (pfile, cpp_pedantic))
	cpp_error (pfile, CPP_DL_PEDWARN,
		   "delimited escape sequences are only valid in C++23");
      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;
    }
  /* The C99 standard permits $, @ and ` to be specified as UCNs.  We use
     hex escapes so that this also works with EBCDIC hosts.
     C++0x permits everything below 0xa0 within literals;
     ucn_valid_in_identifier will complain about identifiers.  */
  else if ((result < 0xa0
	    && !CPP_OPTION (pfile, cplusplus)
	    && (result != 0x24 && result != 0x40 && result != 0x60))
	   || (result & 0x80000000)
	   || (result >= 0xD800 && result <= 0xDFFF))
    {
      cpp_error (pfile, CPP_DL_ERROR,
		 "%.*s is not a valid universal character",
		 (int) (str - base), base);
      result = 1;
    }
  else if (identifier_pos && result == 0x24 
	   && CPP_OPTION (pfile, dollars_in_ident))
    {
      if (CPP_OPTION (pfile, warn_dollars) && !pfile->state.skipping)
	{
	  CPP_OPTION (pfile, warn_dollars) = 0;
	  cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number");
	}
      NORMALIZE_STATE_UPDATE_IDNUM (nst, 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 == '}')
    {
      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))
	cpp_error (pfile, CPP_DL_PEDWARN,
		   "delimited escape sequences are only valid in C++23");
      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 == '}')
	{
	  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))
	    cpp_error (pfile, CPP_DL_PEDWARN,
		       "delimited escape sequences are only valid in C++23");
	  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_PEDANTIC (pfile))
	cpp_error (pfile, CPP_DL_PEDWARN,
		   "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_PEDANTIC (pfile))
	cpp_error (pfile, CPP_DL_PEDWARN,
		   "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':
      if (CPP_PEDANTIC (pfile))
	cpp_error (pfile, CPP_DL_PEDWARN,
		   "non-ISO-standard escape sequence, '\\%c'", (int) c);
      c = charconsts[2];
      break;

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

	  /* diagnostic.cc does not support "%03o".  When it does, this
	     code can use %03o directly in the diagnostic again.  */
	  char buf[32];
	  sprintf(buf, "%03o", (int) c);
	  cpp_error_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);
}

/* A "do nothing" diagnostic-handling callback for use by
   cpp_interpret_string_ranges, so that it can temporarily suppress
   diagnostic-handling.  */

static bool
noop_diagnostic_cb (cpp_reader *, enum cpp_diagnostic_level,
		    enum cpp_warning_reason, rich_location *,
		    const char *, va_list *)
{
  /* no-op.  */
  return true;
}

/* This function mimics the behavior of cpp_interpret_string, but
   rather than generating a string in the execution character set,
   *OUT is written to with the source code ranges of the characters
   in such a string.
   FROM and LOC_READERS should both be arrays of length COUNT.
   Returns NULL for success, or an error message for failure.  */

const char *
cpp_interpret_string_ranges (cpp_reader *pfile, const cpp_string *from,
			     cpp_string_location_reader *loc_readers,
			     size_t count,
			     cpp_substring_ranges *out,
			     enum cpp_ttype type)
{
  /* There are a couple of cases in the range-handling in
     cpp_interpret_string_1 that rely on there being a 1:1 correspondence
     between bytes in the source encoding and bytes in the execution
     encoding, so that each byte in the execution string can correspond
     to the location of a byte in the source string.

     This holds for the typical case of a UTF-8 to UTF-8 conversion.
     Enforce this requirement by only attempting to track substring
     locations if we have source encoding == execution encoding.

     This is a stronger condition than we need, since we could e.g.
     have ASCII to EBCDIC (with 1 byte per character before and after),
     but it seems to be a reasonable restriction.  */
  struct cset_converter cvt = converter_for_type (pfile, type);
  if (cvt.func != convert_no_conversion)
    return "execution character set != source character set";

  /* For on-demand strings we have already lexed the strings, so there
     should be no diagnostics.  However, if we have bogus source location
     data (or stringified macro arguments), the attempt to lex the
     strings could fail with an diagnostic.  Temporarily install an
     diagnostic-handler to catch the diagnostic, so that it can lead to this call
     failing, rather than being emitted as a user-visible diagnostic.
     If an diagnostic does occur, we should see it via the return value of
     cpp_interpret_string_1.  */
  bool (*saved_diagnostic_handler) (cpp_reader *, enum cpp_diagnostic_level,
				    enum cpp_warning_reason, rich_location *,
				    const char *, va_list *)
    ATTRIBUTE_FPTR_PRINTF(5,0);

  saved_diagnostic_handler = pfile->cb.diagnostic;
  pfile->cb.diagnostic = noop_diagnostic_cb;

  bool result = cpp_interpret_string_1 (pfile, from, count, NULL, type,
					loc_readers, out);

  /* Restore the saved diagnostic-handler.  */
  pfile->cb.diagnostic = saved_diagnostic_handler;

  if (!result)
    return "cpp_interpret_string_1 failed";

  /* Success.  */
  return NULL;
}

/* Subroutine of do_line and do_linemarker.  Convert escape sequences
   in a string, but do not perform character set conversion.  */
bool
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;
}


/* 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 };
  bool (*saved_diagnostic_handler) (cpp_reader *, enum cpp_diagnostic_level,
				    enum cpp_warning_reason, rich_location *,
				    const char *, va_list *)
    ATTRIBUTE_FPTR_PRINTF(5,0);
  saved_diagnostic_handler = pfile->cb.diagnostic;
  pfile->cb.diagnostic = noop_diagnostic_cb;
  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;
  pfile->cb.diagnostic = saved_diagnostic_handler;
  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) && CPP_PEDANTIC (pfile))
    {
      /* 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_error (pfile, CPP_DL_PEDWARN,
			       "character not encodable in a single execution "
			       "character code unit");
	      else
		diagnosed
		  = cpp_error (pfile, CPP_DL_PEDWARN,
			       "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;

  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
     haven't enough space for the \n-terminator or following
     15 bytes of padding (used to quiet warnings from valgrind or
     Address Sanitizer, when the optimized lexer accesses aligned
     16-byte memory chunks, including the bytes after the malloced,
     area, and stops lexing on '\n').  */
  if (to.len + 4096 < to.asize || to.len + 16 > to.asize)
    to.text = XRESIZEVEC (uchar, to.text, to.len + 16);

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

  /* If the file is using old-school Mac line endings (\r only),
     terminate with another \r, not an \n, so that we do not mistake
     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);
}
