From d66f7a1d4001a8ba24301c6b4a8a26cbb9d927ec Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 7 Jul 2016 05:33:40 -0400
Subject: [PATCH 13/25] FIXME: unify implementations of convert_ucn and
 convert_ucn_ranges

---
 libcpp/charset.c | 79 +++++++++++++++++++++++++++-----------------------------
 1 file changed, 38 insertions(+), 41 deletions(-)

diff --git a/libcpp/charset.c b/libcpp/charset.c
index afc5abe..ff14538 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -1097,7 +1097,7 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr,
       if (!ISXDIGIT (c))
 	break;
       str++;
-      if (char_range)
+      if (loc_reader)
 	char_range->m_finish = loc_reader->get_next ().m_finish;
       result = (result << 4) + hex_value (c);
     }
@@ -1163,14 +1163,12 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr,
   return true;
 }
 
-/* Convert an UCN, pointed to by FROM, to UTF-8 encoding, then translate
-   it to the execution character set and write the result into TBUF.
-   An advanced pointer is returned.  Issues all relevant diagnostics.  */
 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)
+convert_ucn_unified (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];
@@ -1181,8 +1179,12 @@ convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit,
 
   from++;  /* Skip u/U.  */
 
+  if (loc_reader)
+    /* The u/U is part of the spelling of this character.  */
+    char_range.m_finish = loc_reader->get_next ().m_finish;
+
   _cpp_valid_ucn (pfile, &from, limit, 0, &nst,
-		  &ucn, NULL, NULL);
+		  &ucn, &char_range, loc_reader);
 
   rval = one_cppchar_to_utf8 (ucn, &bufp, &bytesleft);
   if (rval)
@@ -1193,50 +1195,45 @@ convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit,
     }
   else
     {
-      /* Set up a cpp_string_location_reader to supply a
-	 location for the single character, covering all of
-	 char_range.  */
-      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);
+	}
+      else
+	{
+	  if (!APPLY_CONVERSION (cvt, buf, 6 - bytesleft, tbuf))
+	    cpp_errno (pfile, CPP_DL_ERROR,
+		       "converting UCN to execution character set");
+	}
     }
 
   return from;
 }
 
-#if 1
+/* Convert an UCN, pointed to by FROM, to UTF-8 encoding, then translate
+   it to the execution character set and write the result into TBUF.
+   An advanced pointer is returned.  Issues all relevant diagnostics.  */
+static const uchar *
+convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit,
+	     struct _cpp_strbuf *tbuf, struct cset_converter cvt)
+{
+  source_range dummy;
+  return convert_ucn_unified (pfile, from, limit, tbuf, cvt,
+			      dummy, NULL, NULL);
+}
+
 static const uchar *
 convert_ucn_ranges (cpp_reader *pfile, const uchar *from, const uchar *limit,
 		    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;
-
-  from++;  /* Skip u/U.  */
-
-  /* The u/U is part of the spelling of this character.  */
-  char_range.m_finish = loc_reader->get_next ().m_finish;
-
-  _cpp_valid_ucn (pfile, &from, limit, 0, &nst,
-		  &ucn, &char_range, loc_reader);
-
-  rval = one_cppchar_to_utf8 (ucn, &bufp, &bytesleft);
-  if (!rval)
-    {
-      int num_encoded_bytes = 6 - bytesleft;
-      for (int i = 0; i < num_encoded_bytes; i++)
-	ranges.add_range (char_range);
-    }
-
-  return from;
+  struct cset_converter dummy;
+  return convert_ucn_unified (pfile, from, limit, NULL, dummy,
+			      char_range, loc_reader, &ranges);
 }
-#endif
 
 /* Subroutine of convert_hex and convert_oct.  N is the representation
    in the execution character set of a numeric escape; write it into the
-- 
1.8.5.3

