aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Ingebrigtsen2021-02-01 17:04:17 +0100
committerLars Ingebrigtsen2021-02-01 17:04:17 +0100
commite38e7b7bc121b96649518e5e986bba23697abc2d (patch)
tree01229b2db2fe4617a2894919e6d09bffa8ef5ba8 /src
parent3990716a97f48adc0a77250cdf5a2853f3f7f7e0 (diff)
downloademacs-e38e7b7bc121b96649518e5e986bba23697abc2d.tar.gz
emacs-e38e7b7bc121b96649518e5e986bba23697abc2d.zip
Make syntax errors say the line/column they appear at
* src/lisp.h: Add count_lines prototype. * src/lread.c (invalid_syntax_lisp): New function (bug#36970). (invalid_syntax): Extend function to take a readcharfun parameter. (read_emacs_mule_char, character_name_to_code): Pass in. (read_escape, invalid_radix_integer, read1): Ditto. * src/xdisp.c (count_lines): Add a more succinct shim over display_count_lines.
Diffstat (limited to 'src')
-rw-r--r--src/lisp.h1
-rw-r--r--src/lread.c100
-rw-r--r--src/xdisp.c9
3 files changed, 70 insertions, 40 deletions
diff --git a/src/lisp.h b/src/lisp.h
index f6588685443..409a1e70608 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3734,6 +3734,7 @@ extern void message_log_maybe_newline (void);
3734extern void update_echo_area (void); 3734extern void update_echo_area (void);
3735extern void truncate_echo_area (ptrdiff_t); 3735extern void truncate_echo_area (ptrdiff_t);
3736extern void redisplay (void); 3736extern void redisplay (void);
3737extern ptrdiff_t count_lines (ptrdiff_t start_byte, ptrdiff_t end_byte);
3737 3738
3738void set_frame_cursor_types (struct frame *, Lisp_Object); 3739void set_frame_cursor_types (struct frame *, Lisp_Object);
3739extern void syms_of_xdisp (void); 3740extern void syms_of_xdisp (void);
diff --git a/src/lread.c b/src/lread.c
index 72b68df6631..5d1676b0c9c 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -537,6 +537,34 @@ readbyte_from_string (int c, Lisp_Object readcharfun)
537} 537}
538 538
539 539
540/* Signal Qinvalid_read_syntax error.
541 S is error string of length N (if > 0) */
542
543static AVOID
544invalid_syntax_lisp (Lisp_Object s, Lisp_Object readcharfun)
545{
546 if (BUFFERP (readcharfun))
547 {
548 xsignal1 (Qinvalid_read_syntax,
549 CALLN (Fformat, build_string ("%s (line %d, column %d)"),
550 s,
551 /* We should already be in the readcharfun
552 buffer when this error is called, so no need
553 to switch to it first. */
554 make_fixnum (count_lines (BEGV_BYTE, PT_BYTE) + 1),
555 make_fixnum (current_column ())));
556 }
557 else
558 xsignal1 (Qinvalid_read_syntax, s);
559}
560
561static AVOID
562invalid_syntax (const char *s, Lisp_Object readcharfun)
563{
564 invalid_syntax_lisp (build_string (s), readcharfun);
565}
566
567
540/* Read one non-ASCII character from INFILE. The character is 568/* Read one non-ASCII character from INFILE. The character is
541 encoded in `emacs-mule' and the first byte is already read in 569 encoded in `emacs-mule' and the first byte is already read in
542 C. */ 570 C. */
@@ -594,8 +622,7 @@ read_emacs_mule_char (int c, int (*readbyte) (int, Lisp_Object), Lisp_Object rea
594 } 622 }
595 c = DECODE_CHAR (charset, code); 623 c = DECODE_CHAR (charset, code);
596 if (c < 0) 624 if (c < 0)
597 Fsignal (Qinvalid_read_syntax, 625 invalid_syntax ("invalid multibyte form", readcharfun);
598 list1 (build_string ("invalid multibyte form")));
599 return c; 626 return c;
600} 627}
601 628
@@ -2330,16 +2357,6 @@ read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end)
2330} 2357}
2331 2358
2332 2359
2333/* Signal Qinvalid_read_syntax error.
2334 S is error string of length N (if > 0) */
2335
2336static AVOID
2337invalid_syntax (const char *s)
2338{
2339 xsignal1 (Qinvalid_read_syntax, build_string (s));
2340}
2341
2342
2343/* Use this for recursive reads, in contexts where internal tokens 2360/* Use this for recursive reads, in contexts where internal tokens
2344 are not allowed. */ 2361 are not allowed. */
2345 2362
@@ -2353,8 +2370,8 @@ read0 (Lisp_Object readcharfun)
2353 if (!c) 2370 if (!c)
2354 return val; 2371 return val;
2355 2372
2356 xsignal1 (Qinvalid_read_syntax, 2373 invalid_syntax_lisp (Fmake_string (make_fixnum (1), make_fixnum (c), Qnil),
2357 Fmake_string (make_fixnum (1), make_fixnum (c), Qnil)); 2374 readcharfun);
2358} 2375}
2359 2376
2360/* Grow a read buffer BUF that contains OFFSET useful bytes of data, 2377/* Grow a read buffer BUF that contains OFFSET useful bytes of data,
@@ -2384,7 +2401,8 @@ grow_read_buffer (char *buf, ptrdiff_t offset,
2384/* Return the scalar value that has the Unicode character name NAME. 2401/* Return the scalar value that has the Unicode character name NAME.
2385 Raise 'invalid-read-syntax' if there is no such character. */ 2402 Raise 'invalid-read-syntax' if there is no such character. */
2386static int 2403static int
2387character_name_to_code (char const *name, ptrdiff_t name_len) 2404character_name_to_code (char const *name, ptrdiff_t name_len,
2405 Lisp_Object readcharfun)
2388{ 2406{
2389 /* For "U+XXXX", pass the leading '+' to string_to_number to reject 2407 /* For "U+XXXX", pass the leading '+' to string_to_number to reject
2390 monstrosities like "U+-0000". */ 2408 monstrosities like "U+-0000". */
@@ -2400,7 +2418,7 @@ character_name_to_code (char const *name, ptrdiff_t name_len)
2400 { 2418 {
2401 AUTO_STRING (format, "\\N{%s}"); 2419 AUTO_STRING (format, "\\N{%s}");
2402 AUTO_STRING_WITH_LEN (namestr, name, name_len); 2420 AUTO_STRING_WITH_LEN (namestr, name, name_len);
2403 xsignal1 (Qinvalid_read_syntax, CALLN (Fformat, format, namestr)); 2421 invalid_syntax_lisp (CALLN (Fformat, format, namestr), readcharfun);
2404 } 2422 }
2405 2423
2406 return XFIXNUM (code); 2424 return XFIXNUM (code);
@@ -2619,7 +2637,7 @@ read_escape (Lisp_Object readcharfun, bool stringp)
2619 { 2637 {
2620 c = READCHAR; 2638 c = READCHAR;
2621 if (c != '{') 2639 if (c != '{')
2622 invalid_syntax ("Expected opening brace after \\N"); 2640 invalid_syntax ("Expected opening brace after \\N", readcharfun);
2623 char name[UNICODE_CHARACTER_NAME_LENGTH_BOUND + 1]; 2641 char name[UNICODE_CHARACTER_NAME_LENGTH_BOUND + 1];
2624 bool whitespace = false; 2642 bool whitespace = false;
2625 ptrdiff_t length = 0; 2643 ptrdiff_t length = 0;
@@ -2634,8 +2652,9 @@ read_escape (Lisp_Object readcharfun, bool stringp)
2634 { 2652 {
2635 AUTO_STRING (format, 2653 AUTO_STRING (format,
2636 "Invalid character U+%04X in character name"); 2654 "Invalid character U+%04X in character name");
2637 xsignal1 (Qinvalid_read_syntax, 2655 invalid_syntax_lisp (CALLN (Fformat, format,
2638 CALLN (Fformat, format, make_fixed_natnum (c))); 2656 make_fixed_natnum (c)),
2657 readcharfun);
2639 } 2658 }
2640 /* Treat multiple adjacent whitespace characters as a 2659 /* Treat multiple adjacent whitespace characters as a
2641 single space character. This makes it easier to use 2660 single space character. This makes it easier to use
@@ -2651,15 +2670,15 @@ read_escape (Lisp_Object readcharfun, bool stringp)
2651 whitespace = false; 2670 whitespace = false;
2652 name[length++] = c; 2671 name[length++] = c;
2653 if (length >= sizeof name) 2672 if (length >= sizeof name)
2654 invalid_syntax ("Character name too long"); 2673 invalid_syntax ("Character name too long", readcharfun);
2655 } 2674 }
2656 if (length == 0) 2675 if (length == 0)
2657 invalid_syntax ("Empty character name"); 2676 invalid_syntax ("Empty character name", readcharfun);
2658 name[length] = '\0'; 2677 name[length] = '\0';
2659 2678
2660 /* character_name_to_code can invoke read1, recursively. 2679 /* character_name_to_code can invoke read1, recursively.
2661 This is why read1's buffer is not static. */ 2680 This is why read1's buffer is not static. */
2662 return character_name_to_code (name, length); 2681 return character_name_to_code (name, length, readcharfun);
2663 } 2682 }
2664 2683
2665 default: 2684 default:
@@ -2697,10 +2716,11 @@ enum { stackbufsize = max (64,
2697 + INT_STRLEN_BOUND (EMACS_INT) + 1)) }; 2716 + INT_STRLEN_BOUND (EMACS_INT) + 1)) };
2698 2717
2699static void 2718static void
2700invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)]) 2719invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)],
2720 Lisp_Object readcharfun)
2701{ 2721{
2702 sprintf (stackbuf, invalid_radix_integer_format, radix); 2722 sprintf (stackbuf, invalid_radix_integer_format, radix);
2703 invalid_syntax (stackbuf); 2723 invalid_syntax (stackbuf, readcharfun);
2704} 2724}
2705 2725
2706/* Read an integer in radix RADIX using READCHARFUN to read 2726/* Read an integer in radix RADIX using READCHARFUN to read
@@ -2760,7 +2780,7 @@ read_integer (Lisp_Object readcharfun, int radix,
2760 UNREAD (c); 2780 UNREAD (c);
2761 2781
2762 if (valid != 1) 2782 if (valid != 1)
2763 invalid_radix_integer (radix, stackbuf); 2783 invalid_radix_integer (radix, stackbuf, readcharfun);
2764 2784
2765 *p = '\0'; 2785 *p = '\0';
2766 return unbind_to (count, string_to_number (read_buffer, radix, NULL)); 2786 return unbind_to (count, string_to_number (read_buffer, radix, NULL));
@@ -2896,7 +2916,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2896 return ht; 2916 return ht;
2897 } 2917 }
2898 UNREAD (c); 2918 UNREAD (c);
2899 invalid_syntax ("#"); 2919 invalid_syntax ("#", readcharfun);
2900 } 2920 }
2901 if (c == '^') 2921 if (c == '^')
2902 { 2922 {
@@ -2948,9 +2968,9 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2948 } 2968 }
2949 return tbl; 2969 return tbl;
2950 } 2970 }
2951 invalid_syntax ("#^^"); 2971 invalid_syntax ("#^^", readcharfun);
2952 } 2972 }
2953 invalid_syntax ("#^"); 2973 invalid_syntax ("#^", readcharfun);
2954 } 2974 }
2955 if (c == '&') 2975 if (c == '&')
2956 { 2976 {
@@ -2973,7 +2993,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2973 version. */ 2993 version. */
2974 && ! (XFIXNAT (length) 2994 && ! (XFIXNAT (length)
2975 == (SCHARS (tmp) - 1) * BOOL_VECTOR_BITS_PER_CHAR))) 2995 == (SCHARS (tmp) - 1) * BOOL_VECTOR_BITS_PER_CHAR)))
2976 invalid_syntax ("#&..."); 2996 invalid_syntax ("#&...", readcharfun);
2977 2997
2978 val = make_uninit_bool_vector (XFIXNAT (length)); 2998 val = make_uninit_bool_vector (XFIXNAT (length));
2979 data = bool_vector_uchar_data (val); 2999 data = bool_vector_uchar_data (val);
@@ -2984,7 +3004,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2984 &= (1 << (XFIXNUM (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1; 3004 &= (1 << (XFIXNUM (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1;
2985 return val; 3005 return val;
2986 } 3006 }
2987 invalid_syntax ("#&..."); 3007 invalid_syntax ("#&...", readcharfun);
2988 } 3008 }
2989 if (c == '[') 3009 if (c == '[')
2990 { 3010 {
@@ -3002,7 +3022,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
3002 && VECTORP (AREF (tmp, COMPILED_CONSTANTS))) 3022 && VECTORP (AREF (tmp, COMPILED_CONSTANTS)))
3003 || CONSP (AREF (tmp, COMPILED_BYTECODE))) 3023 || CONSP (AREF (tmp, COMPILED_BYTECODE)))
3004 && FIXNATP (AREF (tmp, COMPILED_STACK_DEPTH)))) 3024 && FIXNATP (AREF (tmp, COMPILED_STACK_DEPTH))))
3005 invalid_syntax ("Invalid byte-code object"); 3025 invalid_syntax ("Invalid byte-code object", readcharfun);
3006 3026
3007 if (STRINGP (AREF (tmp, COMPILED_BYTECODE)) 3027 if (STRINGP (AREF (tmp, COMPILED_BYTECODE))
3008 && STRING_MULTIBYTE (AREF (tmp, COMPILED_BYTECODE))) 3028 && STRING_MULTIBYTE (AREF (tmp, COMPILED_BYTECODE)))
@@ -3044,7 +3064,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
3044 /* Read the string itself. */ 3064 /* Read the string itself. */
3045 tmp = read1 (readcharfun, &ch, 0); 3065 tmp = read1 (readcharfun, &ch, 0);
3046 if (ch != 0 || !STRINGP (tmp)) 3066 if (ch != 0 || !STRINGP (tmp))
3047 invalid_syntax ("#"); 3067 invalid_syntax ("#", readcharfun);
3048 /* Read the intervals and their properties. */ 3068 /* Read the intervals and their properties. */
3049 while (1) 3069 while (1)
3050 { 3070 {
@@ -3059,7 +3079,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
3059 if (ch == 0) 3079 if (ch == 0)
3060 plist = read1 (readcharfun, &ch, 0); 3080 plist = read1 (readcharfun, &ch, 0);
3061 if (ch) 3081 if (ch)
3062 invalid_syntax ("Invalid string property list"); 3082 invalid_syntax ("Invalid string property list", readcharfun);
3063 Fset_text_properties (beg, end, plist, tmp); 3083 Fset_text_properties (beg, end, plist, tmp);
3064 } 3084 }
3065 3085
@@ -3207,7 +3227,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
3207 if (c == 'r' || c == 'R') 3227 if (c == 'r' || c == 'R')
3208 { 3228 {
3209 if (! (2 <= n && n <= 36)) 3229 if (! (2 <= n && n <= 36))
3210 invalid_radix_integer (n, stackbuf); 3230 invalid_radix_integer (n, stackbuf, readcharfun);
3211 return read_integer (readcharfun, n, stackbuf); 3231 return read_integer (readcharfun, n, stackbuf);
3212 } 3232 }
3213 3233
@@ -3301,7 +3321,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
3301 return read_integer (readcharfun, 2, stackbuf); 3321 return read_integer (readcharfun, 2, stackbuf);
3302 3322
3303 UNREAD (c); 3323 UNREAD (c);
3304 invalid_syntax ("#"); 3324 invalid_syntax ("#", readcharfun);
3305 3325
3306 case ';': 3326 case ';':
3307 while ((c = READCHAR) >= 0 && c != '\n'); 3327 while ((c = READCHAR) >= 0 && c != '\n');
@@ -3373,7 +3393,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
3373 if (ok) 3393 if (ok)
3374 return make_fixnum (c); 3394 return make_fixnum (c);
3375 3395
3376 invalid_syntax ("?"); 3396 invalid_syntax ("?", readcharfun);
3377 } 3397 }
3378 3398
3379 case '"': 3399 case '"':
@@ -3459,7 +3479,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
3459 3479
3460 /* Any modifiers remaining are invalid. */ 3480 /* Any modifiers remaining are invalid. */
3461 if (modifiers) 3481 if (modifiers)
3462 invalid_syntax ("Invalid modifier in string"); 3482 invalid_syntax ("Invalid modifier in string", readcharfun);
3463 p += CHAR_STRING (ch, (unsigned char *) p); 3483 p += CHAR_STRING (ch, (unsigned char *) p);
3464 } 3484 }
3465 else 3485 else
@@ -3999,7 +4019,7 @@ read_list (bool flag, Lisp_Object readcharfun)
3999 { 4019 {
4000 if (ch == ']') 4020 if (ch == ']')
4001 return val; 4021 return val;
4002 invalid_syntax (") or . in a vector"); 4022 invalid_syntax (") or . in a vector", readcharfun);
4003 } 4023 }
4004 if (ch == ')') 4024 if (ch == ')')
4005 return val; 4025 return val;
@@ -4079,9 +4099,9 @@ read_list (bool flag, Lisp_Object readcharfun)
4079 4099
4080 return val; 4100 return val;
4081 } 4101 }
4082 invalid_syntax (". in wrong context"); 4102 invalid_syntax (". in wrong context", readcharfun);
4083 } 4103 }
4084 invalid_syntax ("] in a list"); 4104 invalid_syntax ("] in a list", readcharfun);
4085 } 4105 }
4086 tem = list1 (elt); 4106 tem = list1 (elt);
4087 if (!NILP (tail)) 4107 if (!NILP (tail))
diff --git a/src/xdisp.c b/src/xdisp.c
index 32b359098aa..efca6f641fb 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -26969,6 +26969,15 @@ decode_mode_spec (struct window *w, register int c, int field_width,
26969 return ""; 26969 return "";
26970} 26970}
26971 26971
26972/* Return the number of lines between start_byte and end_byte in the
26973 current buffer. */
26974
26975ptrdiff_t
26976count_lines (ptrdiff_t start_byte, ptrdiff_t end_byte)
26977{
26978 ptrdiff_t ignored;
26979 return display_count_lines (start_byte, end_byte, ZV, &ignored);
26980}
26972 26981
26973/* Count up to COUNT lines starting from START_BYTE. COUNT negative 26982/* Count up to COUNT lines starting from START_BYTE. COUNT negative
26974 means count lines back from START_BYTE. But don't go beyond 26983 means count lines back from START_BYTE. But don't go beyond