From 7d281e264403ee3283c7b2e61e8e306eab5f8b13 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 7 Jul 2016 06:15:05 -0400
Subject: [PATCH 17/25] FIXME: unify convert_escape and convert_escape_ranges

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

diff --git a/libcpp/charset.c b/libcpp/charset.c
index a17825c..7cfe798 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -1215,6 +1215,7 @@ convert_ucn_unified (cpp_reader *pfile, const uchar *from, const uchar *limit,
 /* 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.  */
+#if 0
 static const uchar *
 convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit,
 	     struct _cpp_strbuf *tbuf, struct cset_converter cvt)
@@ -1234,6 +1235,7 @@ convert_ucn_ranges (cpp_reader *pfile, const uchar *from, const uchar *limit,
   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
@@ -1349,6 +1351,7 @@ convert_hex_unified (cpp_reader *pfile, const uchar *from, const uchar *limit,
    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 0
 static const uchar *
 convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit,
 	     struct _cpp_strbuf *tbuf, struct cset_converter cvt)
@@ -1368,6 +1371,7 @@ convert_hex_ranges (cpp_reader *pfile, const uchar *from, const uchar *limit,
   return convert_hex_unified (pfile, from, limit, NULL, dummy,
 			      char_range, loc_reader, &ranges);
 }
+#endif
 
 static const uchar *
 convert_oct_unified (cpp_reader *pfile, const uchar *from, const uchar *limit,
@@ -1415,6 +1419,7 @@ convert_oct_unified (cpp_reader *pfile, const uchar *from, const uchar *limit,
    No character set translation occurs; this routine always produces the
    execution-set character with numeric value equal to the given octal
    number.  */
+#if 0
 static const uchar *
 convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit,
 	     struct _cpp_strbuf *tbuf, struct cset_converter cvt)
@@ -1434,15 +1439,14 @@ convert_oct_ranges (cpp_reader *pfile, const uchar *from, const uchar *limit,
   return convert_oct_unified (pfile, from, limit, NULL, dummy,
 			      char_range, loc_reader, &ranges);
 }
+#endif
 
-/* 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.  Returns an advanced
-   pointer.  Handles all relevant diagnostics.  */
 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)
+convert_escape_unified (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)
 {
   /* Values of \a \b \e \f \n \r \t \v respectively.  */
 #if HOST_CHARSET == HOST_CHARSET_ASCII
@@ -1456,27 +1460,27 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit,
   uchar c;
 
   /* Record the location of the backslash.  */
-#if 0
-  source_range char_range = loc_reader->get_next ();
-#endif
+  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':
-      return convert_ucn (pfile, from, limit, tbuf, cvt);
-      //char_range, loc_reader);
+      return convert_ucn_unified (pfile, from, limit, tbuf, cvt,
+				  char_range, loc_reader, ranges);
 
     case 'x':
-      return convert_hex (pfile, from, limit, tbuf, cvt);
-      //char_range, loc_reader);
+      return convert_hex_unified (pfile, from, limit, tbuf, cvt,
+				  char_range, loc_reader, ranges);
       break;
 
     case '0':  case '1':  case '2':  case '3':
     case '4':  case '5':  case '6':  case '7':
-      return convert_oct (pfile, from, limit, tbuf, cvt);
-      //char_range, loc_reader);
+      return convert_oct_unified (pfile, from, limit, tbuf, cvt,
+				  char_range, loc_reader, ranges);
 
       /* Various letter escapes.  Get the appropriate host-charset
 	 value into C.  */
@@ -1528,111 +1532,35 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit,
 	}
     }
 
-  /* Now convert what we have to the execution character set.  */
-  if (!APPLY_CONVERSION (cvt, &c, 1, tbuf))//, loc_reader, true))
-    cpp_errno (pfile, CPP_DL_ERROR,
-	       "converting escape sequence to execution character set");
+  if (!loc_reader)
+    /* Now convert what we have to the execution character set.  */
+    if (!APPLY_CONVERSION (cvt, &c, 1, tbuf))//, loc_reader, true))
+      cpp_errno (pfile, CPP_DL_ERROR,
+		 "converting escape sequence to execution character set");
 
   return from + 1;
 }
 
-#if 1
+/* 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.  Returns an advanced
+   pointer.  Handles all relevant diagnostics.  */
+static const uchar *
+convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit,
+		struct _cpp_strbuf *tbuf, struct cset_converter cvt)
+{
+  return convert_escape_unified (pfile, from, limit, tbuf, cvt, NULL, NULL);
+}
+
 static const uchar *
 convert_escape_ranges (cpp_reader *pfile, const uchar *from, const uchar *limit,
 		       cpp_string_location_reader *loc_reader,
 		       cpp_substring_ranges &ranges)
 {
-  /* 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 = loc_reader->get_next ();
-
-  c = *from;
-  switch (c)
-    {
-      /* UCNs, hex escapes, and octal escapes are processed separately.  */
-    case 'u': case 'U':
-      return convert_ucn_ranges (pfile, from, limit, char_range, loc_reader,
-				 ranges);
-
-    case 'x':
-      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':
-      return convert_oct_ranges (pfile, from, limit, 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
-	{
-	  /* diagnostic.c 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 (pfile, CPP_DL_PEDWARN,
-		     "unknown escape sequence: '\\%s'", buf);
-	}
-    }
-
-#if 0
-  /* Now convert what we have to the execution character set.  */
-  if (!APPLY_CONVERSION (cvt, &c, 1, tbuf))//, loc_reader, true))
-    cpp_errno (pfile, CPP_DL_ERROR,
-	       "converting escape sequence to execution character set");
-#endif
-
-  return from + 1;
+  struct cset_converter dummy;
+  return convert_escape_unified (pfile, from, limit, NULL, dummy,
+				 loc_reader, &ranges);
 }
-#endif
 
 
 /* TYPE is a token type.  The return value is the conversion needed to
-- 
1.8.5.3

