From 42ddb571cee384024b7933396e3fbaf9aeab02a9 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 7 Jul 2016 05:59:13 -0400
Subject: [PATCH 15/25] FIXME: unify implementations of convert_hex and
 convert_hex_ranges

---
 libcpp/charset.c | 73 ++++++++++++++++++++++++++------------------------------
 1 file changed, 34 insertions(+), 39 deletions(-)

diff --git a/libcpp/charset.c b/libcpp/charset.c
index ff14538..b9a7c45 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -1285,19 +1285,12 @@ emit_numeric_escape (cpp_reader *pfile, cppchar_t n,
     }
 }
 
-/* Convert a hexadecimal escape, pointed to by FROM, to the execution
-   character set and write it into the string buffer TBUF.  Returns an
-   advanced pointer, and issues diagnostics as necessary.
-   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.  */
 static const uchar *
-convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit,
-	     struct _cpp_strbuf *tbuf, struct cset_converter cvt)//
-#if 0
-	     source_range char_range,
-	     cpp_string_location_reader *loc_reader)
-#endif
+convert_hex_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 c, n = 0, overflow = 0;
   int digits_found = 0;
@@ -1312,7 +1305,8 @@ convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit,
   from++;
 
   /* The 'x' is part of the spelling of this character.  */
-  //char_range.m_finish = loc_reader->get_next ().m_finish;
+  if (loc_reader)
+    char_range.m_finish = loc_reader->get_next ().m_finish;
 
   while (from < limit)
     {
@@ -1320,7 +1314,8 @@ convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit,
       if (! hex_p (c))
 	break;
       from++;
-      //char_range.m_finish = loc_reader->get_next ().m_finish;
+      if (loc_reader)
+	char_range.m_finish = loc_reader->get_next ().m_finish;
       overflow |= n ^ (n << 4 >> 4);
       n = (n << 4) + hex_value (c);
       digits_found = 1;
@@ -1340,39 +1335,38 @@ convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit,
       n &= mask;
     }
 
-  emit_numeric_escape (pfile, n, tbuf, cvt);
+  if (ranges)
+    ranges->add_range (char_range);
+  else
+    emit_numeric_escape (pfile, n, tbuf, cvt);
 
   return from;
 }
 
+/* Convert a hexadecimal escape, pointed to by FROM, to the execution
+   character set and write it into the string buffer TBUF.  Returns an
+   advanced pointer, and issues diagnostics as necessary.
+   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.  */
+static const uchar *
+convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit,
+	     struct _cpp_strbuf *tbuf, struct cset_converter cvt)
+{
+  source_range dummy;
+  return convert_hex_unified (pfile, from, limit, tbuf, cvt,
+			      dummy, NULL, NULL);
+}
+
 static const uchar *
-convert_hex_ranges (const uchar *from, const uchar *limit,
+convert_hex_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 c, n = 0, overflow = 0;
-
-  /* Skip 'x'.  */
-  from++;
-
-  /* The 'x' is part of the spelling of this character.  */
-  char_range.m_finish = loc_reader->get_next ().m_finish;
-
-  while (from < limit)
-    {
-      c = *from;
-      if (! hex_p (c))
-	break;
-      from++;
-      char_range.m_finish = loc_reader->get_next ().m_finish;
-      overflow |= n ^ (n << 4 >> 4);
-      n = (n << 4) + hex_value (c);
-    }
-
-  ranges.add_range (char_range);
-
-  return from;
+  struct cset_converter dummy;
+  return convert_hex_unified (pfile, from, limit, NULL, dummy,
+			      char_range, loc_reader, &ranges);
 }
 
 /* Convert an octal escape, pointed to by FROM, to the execution
@@ -1597,7 +1591,8 @@ convert_escape_ranges (cpp_reader *pfile, const uchar *from, const uchar *limit,
 				 ranges);
 
     case 'x':
-      return convert_hex_ranges (from, limit, char_range, loc_reader, ranges);
+      return convert_hex_ranges (pfile, from, limit, char_range, loc_reader,
+				 ranges);
 
     case '0':  case '1':  case '2':  case '3':
     case '4':  case '5':  case '6':  case '7':
-- 
1.8.5.3

