}
+/* Signal Qinvalid_read_syntax error.
+ S is error string of length N (if > 0) */
+
+static AVOID
+invalid_syntax_lisp (Lisp_Object s, Lisp_Object readcharfun)
+{
+ if (BUFFERP (readcharfun))
+ {
+ xsignal1 (Qinvalid_read_syntax,
+ CALLN (Fformat, build_string ("%s (line %d, column %d)"),
+ s,
+ /* We should already be in the readcharfun
+ buffer when this error is called, so no need
+ to switch to it first. */
+ make_fixnum (count_lines (BEGV_BYTE, PT_BYTE) + 1),
+ make_fixnum (current_column ())));
+ }
+ else
+ xsignal1 (Qinvalid_read_syntax, s);
+}
+
+static AVOID
+invalid_syntax (const char *s, Lisp_Object readcharfun)
+{
+ invalid_syntax_lisp (build_string (s), readcharfun);
+}
+
+
/* Read one non-ASCII character from INFILE. The character is
encoded in `emacs-mule' and the first byte is already read in
C. */
}
c = DECODE_CHAR (charset, code);
if (c < 0)
- Fsignal (Qinvalid_read_syntax,
- list1 (build_string ("invalid multibyte form")));
+ invalid_syntax ("invalid multibyte form", readcharfun);
return c;
}
}
\f
-/* Signal Qinvalid_read_syntax error.
- S is error string of length N (if > 0) */
-
-static AVOID
-invalid_syntax (const char *s)
-{
- xsignal1 (Qinvalid_read_syntax, build_string (s));
-}
-
-
/* Use this for recursive reads, in contexts where internal tokens
are not allowed. */
if (!c)
return val;
- xsignal1 (Qinvalid_read_syntax,
- Fmake_string (make_fixnum (1), make_fixnum (c), Qnil));
+ invalid_syntax_lisp (Fmake_string (make_fixnum (1), make_fixnum (c), Qnil),
+ readcharfun);
}
\f
/* Grow a read buffer BUF that contains OFFSET useful bytes of data,
/* Return the scalar value that has the Unicode character name NAME.
Raise 'invalid-read-syntax' if there is no such character. */
static int
-character_name_to_code (char const *name, ptrdiff_t name_len)
+character_name_to_code (char const *name, ptrdiff_t name_len,
+ Lisp_Object readcharfun)
{
/* For "U+XXXX", pass the leading '+' to string_to_number to reject
monstrosities like "U+-0000". */
{
AUTO_STRING (format, "\\N{%s}");
AUTO_STRING_WITH_LEN (namestr, name, name_len);
- xsignal1 (Qinvalid_read_syntax, CALLN (Fformat, format, namestr));
+ invalid_syntax_lisp (CALLN (Fformat, format, namestr), readcharfun);
}
return XFIXNUM (code);
{
c = READCHAR;
if (c != '{')
- invalid_syntax ("Expected opening brace after \\N");
+ invalid_syntax ("Expected opening brace after \\N", readcharfun);
char name[UNICODE_CHARACTER_NAME_LENGTH_BOUND + 1];
bool whitespace = false;
ptrdiff_t length = 0;
{
AUTO_STRING (format,
"Invalid character U+%04X in character name");
- xsignal1 (Qinvalid_read_syntax,
- CALLN (Fformat, format, make_fixed_natnum (c)));
+ invalid_syntax_lisp (CALLN (Fformat, format,
+ make_fixed_natnum (c)),
+ readcharfun);
}
/* Treat multiple adjacent whitespace characters as a
single space character. This makes it easier to use
whitespace = false;
name[length++] = c;
if (length >= sizeof name)
- invalid_syntax ("Character name too long");
+ invalid_syntax ("Character name too long", readcharfun);
}
if (length == 0)
- invalid_syntax ("Empty character name");
+ invalid_syntax ("Empty character name", readcharfun);
name[length] = '\0';
/* character_name_to_code can invoke read1, recursively.
This is why read1's buffer is not static. */
- return character_name_to_code (name, length);
+ return character_name_to_code (name, length, readcharfun);
}
default:
+ INT_STRLEN_BOUND (EMACS_INT) + 1)) };
static void
-invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)])
+invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)],
+ Lisp_Object readcharfun)
{
sprintf (stackbuf, invalid_radix_integer_format, radix);
- invalid_syntax (stackbuf);
+ invalid_syntax (stackbuf, readcharfun);
}
/* Read an integer in radix RADIX using READCHARFUN to read
UNREAD (c);
if (valid != 1)
- invalid_radix_integer (radix, stackbuf);
+ invalid_radix_integer (radix, stackbuf, readcharfun);
*p = '\0';
return unbind_to (count, string_to_number (read_buffer, radix, NULL));
return ht;
}
UNREAD (c);
- invalid_syntax ("#");
+ invalid_syntax ("#", readcharfun);
}
if (c == '^')
{
}
return tbl;
}
- invalid_syntax ("#^^");
+ invalid_syntax ("#^^", readcharfun);
}
- invalid_syntax ("#^");
+ invalid_syntax ("#^", readcharfun);
}
if (c == '&')
{
version. */
&& ! (XFIXNAT (length)
== (SCHARS (tmp) - 1) * BOOL_VECTOR_BITS_PER_CHAR)))
- invalid_syntax ("#&...");
+ invalid_syntax ("#&...", readcharfun);
val = make_uninit_bool_vector (XFIXNAT (length));
data = bool_vector_uchar_data (val);
&= (1 << (XFIXNUM (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1;
return val;
}
- invalid_syntax ("#&...");
+ invalid_syntax ("#&...", readcharfun);
}
if (c == '[')
{
&& VECTORP (AREF (tmp, COMPILED_CONSTANTS)))
|| CONSP (AREF (tmp, COMPILED_BYTECODE)))
&& FIXNATP (AREF (tmp, COMPILED_STACK_DEPTH))))
- invalid_syntax ("Invalid byte-code object");
+ invalid_syntax ("Invalid byte-code object", readcharfun);
if (STRINGP (AREF (tmp, COMPILED_BYTECODE))
&& STRING_MULTIBYTE (AREF (tmp, COMPILED_BYTECODE)))
/* Read the string itself. */
tmp = read1 (readcharfun, &ch, 0);
if (ch != 0 || !STRINGP (tmp))
- invalid_syntax ("#");
+ invalid_syntax ("#", readcharfun);
/* Read the intervals and their properties. */
while (1)
{
if (ch == 0)
plist = read1 (readcharfun, &ch, 0);
if (ch)
- invalid_syntax ("Invalid string property list");
+ invalid_syntax ("Invalid string property list", readcharfun);
Fset_text_properties (beg, end, plist, tmp);
}
if (c == 'r' || c == 'R')
{
if (! (2 <= n && n <= 36))
- invalid_radix_integer (n, stackbuf);
+ invalid_radix_integer (n, stackbuf, readcharfun);
return read_integer (readcharfun, n, stackbuf);
}
return read_integer (readcharfun, 2, stackbuf);
UNREAD (c);
- invalid_syntax ("#");
+ invalid_syntax ("#", readcharfun);
case ';':
while ((c = READCHAR) >= 0 && c != '\n');
if (ok)
return make_fixnum (c);
- invalid_syntax ("?");
+ invalid_syntax ("?", readcharfun);
}
case '"':
/* Any modifiers remaining are invalid. */
if (modifiers)
- invalid_syntax ("Invalid modifier in string");
+ invalid_syntax ("Invalid modifier in string", readcharfun);
p += CHAR_STRING (ch, (unsigned char *) p);
}
else
{
if (ch == ']')
return val;
- invalid_syntax (") or . in a vector");
+ invalid_syntax (") or . in a vector", readcharfun);
}
if (ch == ')')
return val;
return val;
}
- invalid_syntax (". in wrong context");
+ invalid_syntax (". in wrong context", readcharfun);
}
- invalid_syntax ("] in a list");
+ invalid_syntax ("] in a list", readcharfun);
}
tem = list1 (elt);
if (!NILP (tail))