diff src/lread.c @ 5247:02d875ebd1ea

Make Lisp reader errors more informative with over-long hex, octal characters src/ChangeLog addition: 2010-08-21 Aidan Kehoe <kehoea@parhasard.net> * lread.c (read_escape): Make error messages better reflect the text that was encountered, when overlong hex character escapes or non-Latin-1 octal character escapes are encountered. man/ChangeLog addition: 2010-08-21 Aidan Kehoe <kehoea@parhasard.net> * lispref/objects.texi (Character Type): Go into more detail here on the specific type of error provoked on overlong hex character escapes and non-Latin-1 octal character escapes; give details of why the latter may be encountered, and what to do with such code.
author Aidan Kehoe <kehoea@parhasard.net>
date Sat, 21 Aug 2010 19:02:44 +0100
parents 808131ba4a57
children c096d8051f89 308d34e9f07d
line wrap: on
line diff
--- a/src/lread.c	Sun Aug 15 15:42:45 2010 +0100
+++ b/src/lread.c	Sat Aug 21 19:02:44 2010 +0100
@@ -1818,8 +1818,12 @@
 	      }
 	  }
 	if (i >= 0400)
-	  syntax_error ("Non-ISO-8859-1 character specified with octal escape",
-			make_int (i));
+	  {
+	    read_syntax_error ((Ascbyte *) emacs_sprintf_malloc
+			       (NULL,
+				"Non-ISO-8859-1 octal character escape, "
+				"?\\%.3o", i));
+	  }
 	return i;
       }
 
@@ -1827,13 +1831,23 @@
       /* A hex escape, as in ANSI C, except that we only allow latin-1
 	 characters to be read this way.  What is "\x4e03" supposed to
 	 mean, anyways, if the internal representation is hidden?
-         This is also consistent with the treatment of octal escapes. */
+         This is also consistent with the treatment of octal escapes.
+
+         Note that we don't accept ?\XAB as specifying the character with
+         numeric value 171; it must be ?\xAB. */
       {
+#define OVERLONG_INFO "Overlong hex character escape, ?\\x"
+
 	REGISTER Ichar i = 0;
 	REGISTER int count = 0;
+	Ascbyte seen[] = OVERLONG_INFO "\0\0\0\0\0";
+	REGISTER Ascbyte *seenp = seen + sizeof (OVERLONG_INFO) - 1;
+
+#undef OVERLONG_INFO
+
 	while (++count <= 2)
 	  {
-	    c = readchar (readcharfun);
+	    c = readchar (readcharfun), *seenp = c, ++seenp;
 	    /* Remember, can't use isdigit(), isalpha() etc. on Ichars */
 	    if      (c >= '0' && c <= '9')  i = (i << 4) + (c - '0');
 	    else if (c >= 'a' && c <= 'f')  i = (i << 4) + (c - 'a') + 10;
@@ -1847,21 +1861,12 @@
 
         if (count == 3)
           {
-            c = readchar (readcharfun);
+            c = readchar (readcharfun), *seenp = c, ++seenp;
             if ((c >= '0' && c <= '9') ||
                 (c >= 'a' && c <= 'f') ||
                 (c >= 'A' && c <= 'F'))
               {
-                Lisp_Object args[2];
-
-                if      (c >= '0' && c <= '9')  i = (i << 4) + (c - '0');
-                else if (c >= 'a' && c <= 'f')  i = (i << 4) + (c - 'a') + 10;
-                else if (c >= 'A' && c <= 'F')  i = (i << 4) + (c - 'A') + 10;
-
-                args[0] = build_ascstring ("?\\x%x");
-                args[1] = make_int (i);
-                syntax_error ("Overlong hex character escape",
-                              Fformat (2, args));
+		read_syntax_error (seen);
               }
             unreadchar (readcharfun, c);
           }