aboutsummaryrefslogtreecommitdiffstats
path: root/src/lread.c
diff options
context:
space:
mode:
authorYuan Fu2022-06-14 15:59:46 -0700
committerYuan Fu2022-06-14 15:59:46 -0700
commit98bfb240818bae14cd87a1ffeb8fae7cb7846e05 (patch)
tree16e8ab06875ed54e110cf98ccdbd7e78f15905c6 /src/lread.c
parent184d212042ffa5a4f02c92085d9b6e8346d66e99 (diff)
parent787c4ad8b0776280305a220d6669c956d9ed8a5d (diff)
downloademacs-98bfb240818bae14cd87a1ffeb8fae7cb7846e05.tar.gz
emacs-98bfb240818bae14cd87a1ffeb8fae7cb7846e05.zip
Merge remote-tracking branch 'savannah/master' into feature/tree-sitter
Diffstat (limited to 'src/lread.c')
-rw-r--r--src/lread.c2219
1 files changed, 1211 insertions, 1008 deletions
diff --git a/src/lread.c b/src/lread.c
index f1ffdef04e4..dfabe75113e 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -656,10 +656,6 @@ struct subst
656static Lisp_Object read_internal_start (Lisp_Object, Lisp_Object, 656static Lisp_Object read_internal_start (Lisp_Object, Lisp_Object,
657 Lisp_Object, bool); 657 Lisp_Object, bool);
658static Lisp_Object read0 (Lisp_Object, bool); 658static Lisp_Object read0 (Lisp_Object, bool);
659static Lisp_Object read1 (Lisp_Object, int *, bool, bool);
660
661static Lisp_Object read_list (bool, Lisp_Object, bool);
662static Lisp_Object read_vector (Lisp_Object, bool, bool);
663 659
664static Lisp_Object substitute_object_recurse (struct subst *, Lisp_Object); 660static Lisp_Object substitute_object_recurse (struct subst *, Lisp_Object);
665static void substitute_in_interval (INTERVAL, void *); 661static void substitute_in_interval (INTERVAL, void *);
@@ -940,7 +936,7 @@ lisp_file_lexically_bound_p (Lisp_Object readcharfun)
940 ch = READCHAR; 936 ch = READCHAR;
941 if (ch == '\n') ch = READCHAR; 937 if (ch == '\n') ch = READCHAR;
942 /* It is OK to leave the position after a #! line, since 938 /* It is OK to leave the position after a #! line, since
943 that is what read1 does. */ 939 that is what read0 does. */
944 } 940 }
945 941
946 if (ch != ';') 942 if (ch != ';')
@@ -1248,10 +1244,9 @@ Return t if the file exists and loads successfully. */)
1248 CHECK_STRING (file); 1244 CHECK_STRING (file);
1249 1245
1250 /* If file name is magic, call the handler. */ 1246 /* If file name is magic, call the handler. */
1251 /* This shouldn't be necessary any more now that `openp' handles it right. 1247 handler = Ffind_file_name_handler (file, Qload);
1252 handler = Ffind_file_name_handler (file, Qload); 1248 if (!NILP (handler))
1253 if (!NILP (handler)) 1249 return call5 (handler, Qload, file, noerror, nomessage, nosuffix);
1254 return call5 (handler, Qload, file, noerror, nomessage, nosuffix); */
1255 1250
1256 /* The presence of this call is the result of a historical accident: 1251 /* The presence of this call is the result of a historical accident:
1257 it used to be in every file-operation and when it got removed 1252 it used to be in every file-operation and when it got removed
@@ -2221,7 +2216,7 @@ readevalloop (Lisp_Object readcharfun,
2221 lexical environment, otherwise, turn off lexical binding. */ 2216 lexical environment, otherwise, turn off lexical binding. */
2222 lex_bound = find_symbol_value (Qlexical_binding); 2217 lex_bound = find_symbol_value (Qlexical_binding);
2223 specbind (Qinternal_interpreter_environment, 2218 specbind (Qinternal_interpreter_environment,
2224 (NILP (lex_bound) || EQ (lex_bound, Qunbound) 2219 (NILP (lex_bound) || BASE_EQ (lex_bound, Qunbound)
2225 ? Qnil : list1 (Qt))); 2220 ? Qnil : list1 (Qt)));
2226 specbind (Qmacroexp__dynvars, Vmacroexp__dynvars); 2221 specbind (Qmacroexp__dynvars, Vmacroexp__dynvars);
2227 2222
@@ -2286,6 +2281,7 @@ readevalloop (Lisp_Object readcharfun,
2286 if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r' 2281 if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r'
2287 || c == NO_BREAK_SPACE) 2282 || c == NO_BREAK_SPACE)
2288 goto read_next; 2283 goto read_next;
2284 UNREAD (c);
2289 2285
2290 if (! HASH_TABLE_P (read_objects_map) 2286 if (! HASH_TABLE_P (read_objects_map)
2291 || XHASH_TABLE (read_objects_map)->count) 2287 || XHASH_TABLE (read_objects_map)->count)
@@ -2300,12 +2296,9 @@ readevalloop (Lisp_Object readcharfun,
2300 DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD, 2296 DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD,
2301 Qnil, false); 2297 Qnil, false);
2302 if (!NILP (Vpurify_flag) && c == '(') 2298 if (!NILP (Vpurify_flag) && c == '(')
2303 { 2299 val = read0 (readcharfun, false);
2304 val = read_list (0, readcharfun, false);
2305 }
2306 else 2300 else
2307 { 2301 {
2308 UNREAD (c);
2309 if (!NILP (readfun)) 2302 if (!NILP (readfun))
2310 { 2303 {
2311 val = call1 (readfun, readcharfun); 2304 val = call1 (readfun, readcharfun);
@@ -2349,7 +2342,7 @@ readevalloop (Lisp_Object readcharfun,
2349 { 2342 {
2350 Vvalues = Fcons (val, Vvalues); 2343 Vvalues = Fcons (val, Vvalues);
2351 if (EQ (Vstandard_output, Qt)) 2344 if (EQ (Vstandard_output, Qt))
2352 Fprin1 (val, Qnil); 2345 Fprin1 (val, Qnil, Qnil);
2353 else 2346 else
2354 Fprint (val, Qnil); 2347 Fprint (val, Qnil);
2355 } 2348 }
@@ -2582,24 +2575,6 @@ read_internal_start (Lisp_Object stream, Lisp_Object start, Lisp_Object end,
2582 return retval; 2575 return retval;
2583} 2576}
2584 2577
2585
2586/* Use this for recursive reads, in contexts where internal tokens
2587 are not allowed. */
2588
2589static Lisp_Object
2590read0 (Lisp_Object readcharfun, bool locate_syms)
2591{
2592 register Lisp_Object val;
2593 int c;
2594
2595 val = read1 (readcharfun, &c, 0, locate_syms);
2596 if (!c)
2597 return val;
2598
2599 invalid_syntax_lisp (Fmake_string (make_fixnum (1), make_fixnum (c), Qnil),
2600 readcharfun);
2601}
2602
2603/* Grow a read buffer BUF that contains OFFSET useful bytes of data, 2578/* Grow a read buffer BUF that contains OFFSET useful bytes of data,
2604 by at least MAX_MULTIBYTE_LENGTH bytes. Update *BUF_ADDR and 2579 by at least MAX_MULTIBYTE_LENGTH bytes. Update *BUF_ADDR and
2605 *BUF_SIZE accordingly; 0 <= OFFSET <= *BUF_SIZE. If *BUF_ADDR is 2580 *BUF_SIZE accordingly; 0 <= OFFSET <= *BUF_SIZE. If *BUF_ADDR is
@@ -2658,7 +2633,7 @@ enum { UNICODE_CHARACTER_NAME_LENGTH_BOUND = 200 };
2658 If the escape sequence forces unibyte, return eight-bit char. */ 2633 If the escape sequence forces unibyte, return eight-bit char. */
2659 2634
2660static int 2635static int
2661read_escape (Lisp_Object readcharfun, bool stringp) 2636read_escape (Lisp_Object readcharfun)
2662{ 2637{
2663 int c = READCHAR; 2638 int c = READCHAR;
2664 /* \u allows up to four hex digits, \U up to eight. Default to the 2639 /* \u allows up to four hex digits, \U up to eight. Default to the
@@ -2688,12 +2663,10 @@ read_escape (Lisp_Object readcharfun, bool stringp)
2688 return '\t'; 2663 return '\t';
2689 case 'v': 2664 case 'v':
2690 return '\v'; 2665 return '\v';
2666
2691 case '\n': 2667 case '\n':
2692 return -1; 2668 /* ?\LF is an error; it's probably a user mistake. */
2693 case ' ': 2669 error ("Invalid escape character syntax");
2694 if (stringp)
2695 return -1;
2696 return ' ';
2697 2670
2698 case 'M': 2671 case 'M':
2699 c = READCHAR; 2672 c = READCHAR;
@@ -2701,7 +2674,7 @@ read_escape (Lisp_Object readcharfun, bool stringp)
2701 error ("Invalid escape character syntax"); 2674 error ("Invalid escape character syntax");
2702 c = READCHAR; 2675 c = READCHAR;
2703 if (c == '\\') 2676 if (c == '\\')
2704 c = read_escape (readcharfun, 0); 2677 c = read_escape (readcharfun);
2705 return c | meta_modifier; 2678 return c | meta_modifier;
2706 2679
2707 case 'S': 2680 case 'S':
@@ -2710,7 +2683,7 @@ read_escape (Lisp_Object readcharfun, bool stringp)
2710 error ("Invalid escape character syntax"); 2683 error ("Invalid escape character syntax");
2711 c = READCHAR; 2684 c = READCHAR;
2712 if (c == '\\') 2685 if (c == '\\')
2713 c = read_escape (readcharfun, 0); 2686 c = read_escape (readcharfun);
2714 return c | shift_modifier; 2687 return c | shift_modifier;
2715 2688
2716 case 'H': 2689 case 'H':
@@ -2719,7 +2692,7 @@ read_escape (Lisp_Object readcharfun, bool stringp)
2719 error ("Invalid escape character syntax"); 2692 error ("Invalid escape character syntax");
2720 c = READCHAR; 2693 c = READCHAR;
2721 if (c == '\\') 2694 if (c == '\\')
2722 c = read_escape (readcharfun, 0); 2695 c = read_escape (readcharfun);
2723 return c | hyper_modifier; 2696 return c | hyper_modifier;
2724 2697
2725 case 'A': 2698 case 'A':
@@ -2728,19 +2701,19 @@ read_escape (Lisp_Object readcharfun, bool stringp)
2728 error ("Invalid escape character syntax"); 2701 error ("Invalid escape character syntax");
2729 c = READCHAR; 2702 c = READCHAR;
2730 if (c == '\\') 2703 if (c == '\\')
2731 c = read_escape (readcharfun, 0); 2704 c = read_escape (readcharfun);
2732 return c | alt_modifier; 2705 return c | alt_modifier;
2733 2706
2734 case 's': 2707 case 's':
2735 c = READCHAR; 2708 c = READCHAR;
2736 if (stringp || c != '-') 2709 if (c != '-')
2737 { 2710 {
2738 UNREAD (c); 2711 UNREAD (c);
2739 return ' '; 2712 return ' ';
2740 } 2713 }
2741 c = READCHAR; 2714 c = READCHAR;
2742 if (c == '\\') 2715 if (c == '\\')
2743 c = read_escape (readcharfun, 0); 2716 c = read_escape (readcharfun);
2744 return c | super_modifier; 2717 return c | super_modifier;
2745 2718
2746 case 'C': 2719 case 'C':
@@ -2751,7 +2724,7 @@ read_escape (Lisp_Object readcharfun, bool stringp)
2751 case '^': 2724 case '^':
2752 c = READCHAR; 2725 c = READCHAR;
2753 if (c == '\\') 2726 if (c == '\\')
2754 c = read_escape (readcharfun, 0); 2727 c = read_escape (readcharfun);
2755 if ((c & ~CHAR_MODIFIER_MASK) == '?') 2728 if ((c & ~CHAR_MODIFIER_MASK) == '?')
2756 return 0177 | (c & CHAR_MODIFIER_MASK); 2729 return 0177 | (c & CHAR_MODIFIER_MASK);
2757 else if (! ASCII_CHAR_P ((c & ~CHAR_MODIFIER_MASK))) 2730 else if (! ASCII_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
@@ -2902,8 +2875,8 @@ read_escape (Lisp_Object readcharfun, bool stringp)
2902 invalid_syntax ("Empty character name", readcharfun); 2875 invalid_syntax ("Empty character name", readcharfun);
2903 name[length] = '\0'; 2876 name[length] = '\0';
2904 2877
2905 /* character_name_to_code can invoke read1, recursively. 2878 /* character_name_to_code can invoke read0, recursively.
2906 This is why read1's buffer is not static. */ 2879 This is why read0's buffer is not static. */
2907 return character_name_to_code (name, length, readcharfun); 2880 return character_name_to_code (name, length, readcharfun);
2908 } 2881 }
2909 2882
@@ -2932,20 +2905,17 @@ digit_to_number (int character, int base)
2932 return digit < base ? digit : -1; 2905 return digit < base ? digit : -1;
2933} 2906}
2934 2907
2935static char const invalid_radix_integer_format[] = "integer, radix %"pI"d"; 2908/* Size of the fixed-size buffer used during reading.
2936 2909 It should be at least big enough for `invalid_radix_integer' but
2937/* Small, as read1 is recursive (Bug#31995). But big enough to hold 2910 can usefully be much bigger than that. */
2938 the invalid_radix_integer string. */ 2911enum { stackbufsize = 1024 };
2939enum { stackbufsize = max (64,
2940 (sizeof invalid_radix_integer_format
2941 - sizeof "%"pI"d"
2942 + INT_STRLEN_BOUND (EMACS_INT) + 1)) };
2943 2912
2944static void 2913static void
2945invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)], 2914invalid_radix_integer (EMACS_INT radix, char stackbuf[VLA_ELEMS (stackbufsize)],
2946 Lisp_Object readcharfun) 2915 Lisp_Object readcharfun)
2947{ 2916{
2948 sprintf (stackbuf, invalid_radix_integer_format, radix); 2917 int n = snprintf (stackbuf, stackbufsize, "integer, radix %"pI"d", radix);
2918 eassert (n < stackbufsize);
2949 invalid_syntax (stackbuf, readcharfun); 2919 invalid_syntax (stackbuf, readcharfun);
2950} 2920}
2951 2921
@@ -3011,780 +2981,1110 @@ read_integer (Lisp_Object readcharfun, int radix,
3011 *p = '\0'; 2981 *p = '\0';
3012 return unbind_to (count, string_to_number (read_buffer, radix, NULL)); 2982 return unbind_to (count, string_to_number (read_buffer, radix, NULL));
3013} 2983}
2984
3014 2985
3015/* If the next token is ')' or ']' or '.', we store that character 2986/* Read a character literal (preceded by `?'). */
3016 in *PCH and the return value is not interesting. Else, we store
3017 zero in *PCH and we read and return one lisp object.
3018
3019 FIRST_IN_LIST is true if this is the first element of a list.
3020 LOCATE_SYMS true means read symbol occurrences as symbols with
3021 position. */
3022
3023static Lisp_Object 2987static Lisp_Object
3024read1 (Lisp_Object readcharfun, int *pch, bool first_in_list, bool locate_syms) 2988read_char_literal (Lisp_Object readcharfun)
3025{ 2989{
3026 int c; 2990 int ch = READCHAR;
3027 bool uninterned_symbol = false; 2991 if (ch < 0)
3028 bool skip_shorthand = false; 2992 end_of_file_error ();
3029 bool multibyte;
3030 char stackbuf[stackbufsize];
3031 current_thread->stack_top = stackbuf;
3032 2993
3033 *pch = 0; 2994 /* Accept `single space' syntax like (list ? x) where the
2995 whitespace character is SPC or TAB.
2996 Other literal whitespace like NL, CR, and FF are not accepted,
2997 as there are well-established escape sequences for these. */
2998 if (ch == ' ' || ch == '\t')
2999 return make_fixnum (ch);
3034 3000
3035 retry: 3001 if ( ch == '(' || ch == ')' || ch == '[' || ch == ']'
3002 || ch == '"' || ch == ';')
3003 {
3004 CHECK_LIST (Vlread_unescaped_character_literals);
3005 Lisp_Object char_obj = make_fixed_natnum (ch);
3006 if (NILP (Fmemq (char_obj, Vlread_unescaped_character_literals)))
3007 Vlread_unescaped_character_literals =
3008 Fcons (char_obj, Vlread_unescaped_character_literals);
3009 }
3036 3010
3037 c = READCHAR_REPORT_MULTIBYTE (&multibyte); 3011 if (ch == '\\')
3038 if (c < 0) 3012 ch = read_escape (readcharfun);
3039 end_of_file_error ();
3040 3013
3041 switch (c) 3014 int modifiers = ch & CHAR_MODIFIER_MASK;
3042 { 3015 ch &= ~CHAR_MODIFIER_MASK;
3043 case '(': 3016 if (CHAR_BYTE8_P (ch))
3044 return read_list (0, readcharfun, locate_syms); 3017 ch = CHAR_TO_BYTE8 (ch);
3018 ch |= modifiers;
3045 3019
3046 case '[': 3020 int nch = READCHAR;
3047 return read_vector (readcharfun, 0, locate_syms); 3021 UNREAD (nch);
3022 if (nch <= 32
3023 || nch == '"' || nch == '\'' || nch == ';' || nch == '('
3024 || nch == ')' || nch == '[' || nch == ']' || nch == '#'
3025 || nch == '?' || nch == '`' || nch == ',' || nch == '.')
3026 return make_fixnum (ch);
3048 3027
3049 case ')': 3028 invalid_syntax ("?", readcharfun);
3050 case ']': 3029}
3051 {
3052 *pch = c;
3053 return Qnil;
3054 }
3055 3030
3056 case '#': 3031/* Read a string literal (preceded by '"'). */
3057 c = READCHAR; 3032static Lisp_Object
3058 if (c == 's') 3033read_string_literal (char stackbuf[VLA_ELEMS (stackbufsize)],
3034 Lisp_Object readcharfun)
3035{
3036 char *read_buffer = stackbuf;
3037 ptrdiff_t read_buffer_size = stackbufsize;
3038 specpdl_ref count = SPECPDL_INDEX ();
3039 char *heapbuf = NULL;
3040 char *p = read_buffer;
3041 char *end = read_buffer + read_buffer_size;
3042 /* True if we saw an escape sequence specifying
3043 a multibyte character. */
3044 bool force_multibyte = false;
3045 /* True if we saw an escape sequence specifying
3046 a single-byte character. */
3047 bool force_singlebyte = false;
3048 bool cancel = false;
3049 ptrdiff_t nchars = 0;
3050
3051 int ch;
3052 while ((ch = READCHAR) >= 0 && ch != '\"')
3053 {
3054 if (end - p < MAX_MULTIBYTE_LENGTH)
3059 { 3055 {
3060 c = READCHAR; 3056 ptrdiff_t offset = p - read_buffer;
3061 if (c == '(') 3057 read_buffer = grow_read_buffer (read_buffer, offset,
3058 &heapbuf, &read_buffer_size,
3059 count);
3060 p = read_buffer + offset;
3061 end = read_buffer + read_buffer_size;
3062 }
3063
3064 if (ch == '\\')
3065 {
3066 /* First apply string-specific escape rules: */
3067 ch = READCHAR;
3068 switch (ch)
3062 { 3069 {
3063 /* Accept extended format for hash tables (extensible to 3070 case 's':
3064 other types), e.g. 3071 /* `\s' is always a space in strings. */
3065 #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ 3072 ch = ' ';
3066 Lisp_Object tmp = read_list (0, readcharfun, false); 3073 break;
3067 Lisp_Object head = CAR_SAFE (tmp); 3074 case ' ':
3068 Lisp_Object data = Qnil; 3075 case '\n':
3069 Lisp_Object val = Qnil; 3076 /* `\SPC' and `\LF' generate no characters at all. */
3070 /* The size is 2 * number of allowed keywords to 3077 if (p == read_buffer)
3071 make-hash-table. */ 3078 cancel = true;
3072 Lisp_Object params[12]; 3079 continue;
3073 Lisp_Object ht; 3080 default:
3074 Lisp_Object key = Qnil; 3081 UNREAD (ch);
3075 int param_count = 0; 3082 ch = read_escape (readcharfun);
3076 3083 break;
3077 if (!EQ (head, Qhash_table)) 3084 }
3085
3086 int modifiers = ch & CHAR_MODIFIER_MASK;
3087 ch &= ~CHAR_MODIFIER_MASK;
3088
3089 if (CHAR_BYTE8_P (ch))
3090 force_singlebyte = true;
3091 else if (! ASCII_CHAR_P (ch))
3092 force_multibyte = true;
3093 else /* I.e. ASCII_CHAR_P (ch). */
3094 {
3095 /* Allow `\C-SPC' and `\^SPC'. This is done here because
3096 the literals ?\C-SPC and ?\^SPC (rather inconsistently)
3097 yield (' ' | CHAR_CTL); see bug#55738. */
3098 if (modifiers == CHAR_CTL && ch == ' ')
3099 {
3100 ch = 0;
3101 modifiers = 0;
3102 }
3103 if (modifiers & CHAR_SHIFT)
3078 { 3104 {
3079 ptrdiff_t size = XFIXNUM (Flength (tmp)); 3105 /* Shift modifier is valid only with [A-Za-z]. */
3080 Lisp_Object record = Fmake_record (CAR_SAFE (tmp), 3106 if (ch >= 'A' && ch <= 'Z')
3081 make_fixnum (size - 1), 3107 modifiers &= ~CHAR_SHIFT;
3082 Qnil); 3108 else if (ch >= 'a' && ch <= 'z')
3083 for (int i = 1; i < size; i++)
3084 { 3109 {
3085 tmp = Fcdr (tmp); 3110 ch -= ('a' - 'A');
3086 ASET (record, i, Fcar (tmp)); 3111 modifiers &= ~CHAR_SHIFT;
3087 } 3112 }
3088 return record;
3089 } 3113 }
3090 3114
3091 tmp = CDR_SAFE (tmp); 3115 if (modifiers & CHAR_META)
3116 {
3117 /* Move the meta bit to the right place for a
3118 string. */
3119 modifiers &= ~CHAR_META;
3120 ch = BYTE8_TO_CHAR (ch | 0x80);
3121 force_singlebyte = true;
3122 }
3123 }
3092 3124
3093 /* This is repetitive but fast and simple. */ 3125 /* Any modifiers remaining are invalid. */
3094 params[param_count] = QCsize; 3126 if (modifiers)
3095 params[param_count + 1] = Fplist_get (tmp, Qsize); 3127 invalid_syntax ("Invalid modifier in string", readcharfun);
3096 if (!NILP (params[param_count + 1])) 3128 p += CHAR_STRING (ch, (unsigned char *) p);
3097 param_count += 2; 3129 }
3130 else
3131 {
3132 p += CHAR_STRING (ch, (unsigned char *) p);
3133 if (CHAR_BYTE8_P (ch))
3134 force_singlebyte = true;
3135 else if (! ASCII_CHAR_P (ch))
3136 force_multibyte = true;
3137 }
3138 nchars++;
3139 }
3098 3140
3099 params[param_count] = QCtest; 3141 if (ch < 0)
3100 params[param_count + 1] = Fplist_get (tmp, Qtest); 3142 end_of_file_error ();
3101 if (!NILP (params[param_count + 1]))
3102 param_count += 2;
3103 3143
3104 params[param_count] = QCweakness; 3144 /* If purifying, and string starts with \ newline,
3105 params[param_count + 1] = Fplist_get (tmp, Qweakness); 3145 return zero instead. This is for doc strings
3106 if (!NILP (params[param_count + 1])) 3146 that we are really going to find in etc/DOC.nn.nn. */
3107 param_count += 2; 3147 if (!NILP (Vpurify_flag) && NILP (Vdoc_file_name) && cancel)
3148 {
3149 unbind_to (count, Qnil);
3150 return make_fixnum (0);
3151 }
3108 3152
3109 params[param_count] = QCrehash_size; 3153 if (!force_multibyte && force_singlebyte)
3110 params[param_count + 1] = Fplist_get (tmp, Qrehash_size); 3154 {
3111 if (!NILP (params[param_count + 1])) 3155 /* READ_BUFFER contains raw 8-bit bytes and no multibyte
3112 param_count += 2; 3156 forms. Convert it to unibyte. */
3157 nchars = str_as_unibyte ((unsigned char *) read_buffer,
3158 p - read_buffer);
3159 p = read_buffer + nchars;
3160 }
3113 3161
3114 params[param_count] = QCrehash_threshold; 3162 Lisp_Object obj = make_specified_string (read_buffer, nchars, p - read_buffer,
3115 params[param_count + 1] = Fplist_get (tmp, Qrehash_threshold); 3163 (force_multibyte
3116 if (!NILP (params[param_count + 1])) 3164 || (p - read_buffer != nchars)));
3117 param_count += 2; 3165 return unbind_to (count, obj);
3166}
3118 3167
3119 params[param_count] = QCpurecopy; 3168/* Make a hash table from the constructor plist. */
3120 params[param_count + 1] = Fplist_get (tmp, Qpurecopy); 3169static Lisp_Object
3121 if (!NILP (params[param_count + 1])) 3170hash_table_from_plist (Lisp_Object plist)
3122 param_count += 2; 3171{
3172 Lisp_Object params[12];
3173 Lisp_Object *par = params;
3174
3175 /* This is repetitive but fast and simple. */
3176#define ADDPARAM(name) \
3177 do { \
3178 Lisp_Object val = Fplist_get (plist, Q ## name); \
3179 if (!NILP (val)) \
3180 { \
3181 *par++ = QC ## name; \
3182 *par++ = val; \
3183 } \
3184 } while (0)
3185
3186 ADDPARAM (size);
3187 ADDPARAM (test);
3188 ADDPARAM (weakness);
3189 ADDPARAM (rehash_size);
3190 ADDPARAM (rehash_threshold);
3191 ADDPARAM (purecopy);
3192
3193 Lisp_Object data = Fplist_get (plist, Qdata);
3194
3195 /* Now use params to make a new hash table and fill it. */
3196 Lisp_Object ht = Fmake_hash_table (par - params, params);
3197
3198 Lisp_Object last = data;
3199 FOR_EACH_TAIL_SAFE (data)
3200 {
3201 Lisp_Object key = XCAR (data);
3202 data = XCDR (data);
3203 if (!CONSP (data))
3204 break;
3205 Lisp_Object val = XCAR (data);
3206 last = XCDR (data);
3207 Fputhash (key, val, ht);
3208 }
3209 if (!NILP (last))
3210 error ("Hash table data is not a list of even length");
3123 3211
3124 /* This is the hash table data. */ 3212 return ht;
3125 data = Fplist_get (tmp, Qdata); 3213}
3126 3214
3127 /* Now use params to make a new hash table and fill it. */ 3215static Lisp_Object
3128 ht = Fmake_hash_table (param_count, params); 3216record_from_list (Lisp_Object elems)
3217{
3218 ptrdiff_t size = list_length (elems);
3219 Lisp_Object obj = Fmake_record (XCAR (elems),
3220 make_fixnum (size - 1),
3221 Qnil);
3222 Lisp_Object tl = XCDR (elems);
3223 for (int i = 1; i < size; i++)
3224 {
3225 ASET (obj, i, XCAR (tl));
3226 tl = XCDR (tl);
3227 }
3228 return obj;
3229}
3129 3230
3130 Lisp_Object last = data; 3231/* Turn a reversed list into a vector. */
3131 FOR_EACH_TAIL_SAFE (data) 3232static Lisp_Object
3132 { 3233vector_from_rev_list (Lisp_Object elems)
3133 key = XCAR (data); 3234{
3134 data = XCDR (data); 3235 ptrdiff_t size = list_length (elems);
3135 if (!CONSP (data)) 3236 Lisp_Object obj = make_nil_vector (size);
3136 break; 3237 Lisp_Object *vec = XVECTOR (obj)->contents;
3137 val = XCAR (data); 3238 for (ptrdiff_t i = size - 1; i >= 0; i--)
3138 last = XCDR (data); 3239 {
3139 Fputhash (key, val, ht); 3240 vec[i] = XCAR (elems);
3140 } 3241 Lisp_Object next = XCDR (elems);
3141 if (!NILP (last)) 3242 free_cons (XCONS (elems));
3142 error ("Hash table data is not a list of even length"); 3243 elems = next;
3244 }
3245 return obj;
3246}
3143 3247
3144 return ht; 3248static Lisp_Object
3145 } 3249bytecode_from_rev_list (Lisp_Object elems, Lisp_Object readcharfun)
3146 UNREAD (c); 3250{
3147 invalid_syntax ("#", readcharfun); 3251 Lisp_Object obj = vector_from_rev_list (elems);
3148 } 3252 Lisp_Object *vec = XVECTOR (obj)->contents;
3149 if (c == '^') 3253 ptrdiff_t size = ASIZE (obj);
3150 { 3254
3151 c = READCHAR; 3255 if (!(size >= COMPILED_STACK_DEPTH + 1 && size <= COMPILED_INTERACTIVE + 1
3152 if (c == '[') 3256 && (FIXNUMP (vec[COMPILED_ARGLIST])
3153 { 3257 || CONSP (vec[COMPILED_ARGLIST])
3154 Lisp_Object tmp; 3258 || NILP (vec[COMPILED_ARGLIST]))
3155 tmp = read_vector (readcharfun, 0, false); 3259 && FIXNATP (vec[COMPILED_STACK_DEPTH])))
3156 if (ASIZE (tmp) < CHAR_TABLE_STANDARD_SLOTS) 3260 invalid_syntax ("Invalid byte-code object", readcharfun);
3157 error ("Invalid size char-table"); 3261
3158 XSETPVECTYPE (XVECTOR (tmp), PVEC_CHAR_TABLE); 3262 if (load_force_doc_strings
3159 return tmp; 3263 && NILP (vec[COMPILED_CONSTANTS])
3160 } 3264 && STRINGP (vec[COMPILED_BYTECODE]))
3161 else if (c == '^') 3265 {
3162 { 3266 /* Lazily-loaded bytecode is represented by the constant slot being nil
3163 c = READCHAR; 3267 and the bytecode slot a (lazily loaded) string containing the
3164 if (c == '[') 3268 print representation of (BYTECODE . CONSTANTS). Unpack the
3165 { 3269 pieces by coerceing the string to unibyte and reading the result. */
3166 /* Sub char-table can't be read as a regular 3270 Lisp_Object enc = vec[COMPILED_BYTECODE];
3167 vector because of a two C integer fields. */ 3271 Lisp_Object pair = Fread (Fcons (enc, readcharfun));
3168 Lisp_Object tbl, tmp = read_list (1, readcharfun, false); 3272 if (!CONSP (pair))
3169 ptrdiff_t size = list_length (tmp); 3273 invalid_syntax ("Invalid byte-code object", readcharfun);
3170 int i, depth, min_char; 3274
3171 struct Lisp_Cons *cell; 3275 vec[COMPILED_BYTECODE] = XCAR (pair);
3172 3276 vec[COMPILED_CONSTANTS] = XCDR (pair);
3173 if (size == 0) 3277 }
3174 error ("Zero-sized sub char-table"); 3278
3175 3279 if (!((STRINGP (vec[COMPILED_BYTECODE])
3176 if (! RANGED_FIXNUMP (1, XCAR (tmp), 3)) 3280 && VECTORP (vec[COMPILED_CONSTANTS]))
3177 error ("Invalid depth in sub char-table"); 3281 || CONSP (vec[COMPILED_BYTECODE])))
3178 depth = XFIXNUM (XCAR (tmp)); 3282 invalid_syntax ("Invalid byte-code object", readcharfun);
3179 if (chartab_size[depth] != size - 2) 3283
3180 error ("Invalid size in sub char-table"); 3284 if (STRINGP (vec[COMPILED_BYTECODE]))
3181 cell = XCONS (tmp), tmp = XCDR (tmp), size--; 3285 {
3182 free_cons (cell); 3286 if (STRING_MULTIBYTE (vec[COMPILED_BYTECODE]))
3183
3184 if (! RANGED_FIXNUMP (0, XCAR (tmp), MAX_CHAR))
3185 error ("Invalid minimum character in sub-char-table");
3186 min_char = XFIXNUM (XCAR (tmp));
3187 cell = XCONS (tmp), tmp = XCDR (tmp), size--;
3188 free_cons (cell);
3189
3190 tbl = make_uninit_sub_char_table (depth, min_char);
3191 for (i = 0; i < size; i++)
3192 {
3193 XSUB_CHAR_TABLE (tbl)->contents[i] = XCAR (tmp);
3194 cell = XCONS (tmp), tmp = XCDR (tmp);
3195 free_cons (cell);
3196 }
3197 return tbl;
3198 }
3199 invalid_syntax ("#^^", readcharfun);
3200 }
3201 invalid_syntax ("#^", readcharfun);
3202 }
3203 if (c == '&')
3204 { 3287 {
3205 Lisp_Object length; 3288 /* BYTESTR must have been produced by Emacs 20.2 or earlier
3206 length = read1 (readcharfun, pch, first_in_list, false); 3289 because it produced a raw 8-bit string for byte-code and
3207 c = READCHAR; 3290 now such a byte-code string is loaded as multibyte with
3208 if (c == '"') 3291 raw 8-bit characters converted to multibyte form.
3209 { 3292 Convert them back to the original unibyte form. */
3210 Lisp_Object tmp, val; 3293 vec[COMPILED_BYTECODE] = Fstring_as_unibyte (vec[COMPILED_BYTECODE]);
3211 EMACS_INT size_in_chars = bool_vector_bytes (XFIXNAT (length));
3212 unsigned char *data;
3213
3214 UNREAD (c);
3215 tmp = read1 (readcharfun, pch, first_in_list, false);
3216 if (STRING_MULTIBYTE (tmp)
3217 || (size_in_chars != SCHARS (tmp)
3218 /* We used to print 1 char too many
3219 when the number of bits was a multiple of 8.
3220 Accept such input in case it came from an old
3221 version. */
3222 && ! (XFIXNAT (length)
3223 == (SCHARS (tmp) - 1) * BOOL_VECTOR_BITS_PER_CHAR)))
3224 invalid_syntax ("#&...", readcharfun);
3225
3226 val = make_uninit_bool_vector (XFIXNAT (length));
3227 data = bool_vector_uchar_data (val);
3228 memcpy (data, SDATA (tmp), size_in_chars);
3229 /* Clear the extraneous bits in the last byte. */
3230 if (XFIXNUM (length) != size_in_chars * BOOL_VECTOR_BITS_PER_CHAR)
3231 data[size_in_chars - 1]
3232 &= (1 << (XFIXNUM (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1;
3233 return val;
3234 }
3235 invalid_syntax ("#&...", readcharfun);
3236 } 3294 }
3237 if (c == '[') 3295 // Bytecode must be immovable.
3238 { 3296 pin_string (vec[COMPILED_BYTECODE]);
3239 /* Accept compiled functions at read-time so that we don't have to 3297 }
3240 build them using function calls. */
3241 Lisp_Object tmp;
3242 struct Lisp_Vector *vec;
3243 tmp = read_vector (readcharfun, 1, false);
3244 vec = XVECTOR (tmp);
3245 if (! (COMPILED_STACK_DEPTH < ASIZE (tmp)
3246 && (FIXNUMP (AREF (tmp, COMPILED_ARGLIST))
3247 || CONSP (AREF (tmp, COMPILED_ARGLIST))
3248 || NILP (AREF (tmp, COMPILED_ARGLIST)))
3249 && ((STRINGP (AREF (tmp, COMPILED_BYTECODE))
3250 && VECTORP (AREF (tmp, COMPILED_CONSTANTS)))
3251 || CONSP (AREF (tmp, COMPILED_BYTECODE)))
3252 && FIXNATP (AREF (tmp, COMPILED_STACK_DEPTH))))
3253 invalid_syntax ("Invalid byte-code object", readcharfun);
3254
3255 if (STRINGP (AREF (tmp, COMPILED_BYTECODE)))
3256 {
3257 if (STRING_MULTIBYTE (AREF (tmp, COMPILED_BYTECODE)))
3258 {
3259 /* BYTESTR must have been produced by Emacs 20.2 or earlier
3260 because it produced a raw 8-bit string for byte-code and
3261 now such a byte-code string is loaded as multibyte with
3262 raw 8-bit characters converted to multibyte form.
3263 Convert them back to the original unibyte form. */
3264 ASET (tmp, COMPILED_BYTECODE,
3265 Fstring_as_unibyte (AREF (tmp, COMPILED_BYTECODE)));
3266 }
3267 // Bytecode must be immovable.
3268 pin_string (AREF (tmp, COMPILED_BYTECODE));
3269 }
3270 3298
3271 XSETPVECTYPE (vec, PVEC_COMPILED); 3299 XSETPVECTYPE (XVECTOR (obj), PVEC_COMPILED);
3272 return tmp; 3300 return obj;
3273 } 3301}
3274 if (c == '(')
3275 {
3276 Lisp_Object tmp;
3277 int ch;
3278
3279 /* Read the string itself. */
3280 tmp = read1 (readcharfun, &ch, 0, false);
3281 if (ch != 0 || !STRINGP (tmp))
3282 invalid_syntax ("#", readcharfun);
3283 /* Read the intervals and their properties. */
3284 while (1)
3285 {
3286 Lisp_Object beg, end, plist;
3287 3302
3288 beg = read1 (readcharfun, &ch, 0, false); 3303static Lisp_Object
3289 end = plist = Qnil; 3304char_table_from_rev_list (Lisp_Object elems, Lisp_Object readcharfun)
3290 if (ch == ')') 3305{
3291 break; 3306 Lisp_Object obj = vector_from_rev_list (elems);
3292 if (ch == 0) 3307 if (ASIZE (obj) < CHAR_TABLE_STANDARD_SLOTS)
3293 end = read1 (readcharfun, &ch, 0, false); 3308 invalid_syntax ("Invalid size char-table", readcharfun);
3294 if (ch == 0) 3309 XSETPVECTYPE (XVECTOR (obj), PVEC_CHAR_TABLE);
3295 plist = read1 (readcharfun, &ch, 0, false); 3310 return obj;
3296 if (ch)
3297 invalid_syntax ("Invalid string property list", readcharfun);
3298 Fset_text_properties (beg, end, plist, tmp);
3299 }
3300 3311
3301 return tmp; 3312}
3302 }
3303 3313
3304 /* #@NUMBER is used to skip NUMBER following bytes. 3314static Lisp_Object
3305 That's used in .elc files to skip over doc strings 3315sub_char_table_from_rev_list (Lisp_Object elems, Lisp_Object readcharfun)
3306 and function definitions. */ 3316{
3307 if (c == '@') 3317 /* A sub-char-table can't be read as a regular vector because of two
3318 C integer fields. */
3319 elems = Fnreverse (elems);
3320 ptrdiff_t size = list_length (elems);
3321 if (size < 2)
3322 error ("Invalid size of sub-char-table");
3323
3324 if (!RANGED_FIXNUMP (1, XCAR (elems), 3))
3325 error ("Invalid depth in sub-char-table");
3326 int depth = XFIXNUM (XCAR (elems));
3327
3328 if (chartab_size[depth] != size - 2)
3329 error ("Invalid size in sub-char-table");
3330 elems = XCDR (elems);
3331
3332 if (!RANGED_FIXNUMP (0, XCAR (elems), MAX_CHAR))
3333 error ("Invalid minimum character in sub-char-table");
3334 int min_char = XFIXNUM (XCAR (elems));
3335 elems = XCDR (elems);
3336
3337 Lisp_Object tbl = make_uninit_sub_char_table (depth, min_char);
3338 for (int i = 0; i < size - 2; i++)
3339 {
3340 XSUB_CHAR_TABLE (tbl)->contents[i] = XCAR (elems);
3341 elems = XCDR (elems);
3342 }
3343 return tbl;
3344}
3345
3346static Lisp_Object
3347string_props_from_rev_list (Lisp_Object elems, Lisp_Object readcharfun)
3348{
3349 elems = Fnreverse (elems);
3350 if (NILP (elems) || !STRINGP (XCAR (elems)))
3351 invalid_syntax ("#", readcharfun);
3352 Lisp_Object obj = XCAR (elems);
3353 for (Lisp_Object tl = XCDR (elems); !NILP (tl);)
3354 {
3355 Lisp_Object beg = XCAR (tl);
3356 tl = XCDR (tl);
3357 if (NILP (tl))
3358 invalid_syntax ("Invalid string property list", readcharfun);
3359 Lisp_Object end = XCAR (tl);
3360 tl = XCDR (tl);
3361 if (NILP (tl))
3362 invalid_syntax ("Invalid string property list", readcharfun);
3363 Lisp_Object plist = XCAR (tl);
3364 tl = XCDR (tl);
3365 Fset_text_properties (beg, end, plist, obj);
3366 }
3367 return obj;
3368}
3369
3370/* Read a bool vector (preceded by "#&"). */
3371static Lisp_Object
3372read_bool_vector (char stackbuf[VLA_ELEMS (stackbufsize)],
3373 Lisp_Object readcharfun)
3374{
3375 ptrdiff_t length = 0;
3376 for (;;)
3377 {
3378 int c = READCHAR;
3379 if (c < '0' || c > '9')
3308 { 3380 {
3309 enum { extra = 100 }; 3381 if (c != '"')
3310 ptrdiff_t i, nskip = 0, digits = 0; 3382 invalid_syntax ("#&", readcharfun);
3383 break;
3384 }
3385 if (INT_MULTIPLY_WRAPV (length, 10, &length)
3386 | INT_ADD_WRAPV (length, c - '0', &length))
3387 invalid_syntax ("#&", readcharfun);
3388 }
3311 3389
3312 /* Read a decimal integer. */ 3390 ptrdiff_t size_in_chars = bool_vector_bytes (length);
3313 while ((c = READCHAR) >= 0 3391 Lisp_Object str = read_string_literal (stackbuf, readcharfun);
3314 && c >= '0' && c <= '9') 3392 if (STRING_MULTIBYTE (str)
3315 { 3393 || !(size_in_chars == SCHARS (str)
3316 if ((STRING_BYTES_BOUND - extra) / 10 <= nskip) 3394 /* We used to print 1 char too many when the number of bits
3317 string_overflow (); 3395 was a multiple of 8. Accept such input in case it came
3318 digits++; 3396 from an old version. */
3319 nskip *= 10; 3397 || length == (SCHARS (str) - 1) * BOOL_VECTOR_BITS_PER_CHAR))
3320 nskip += c - '0'; 3398 invalid_syntax ("#&...", readcharfun);
3321 if (digits == 2 && nskip == 0) 3399
3322 { /* We've just seen #@00, which means "skip to end". */ 3400 Lisp_Object obj = make_uninit_bool_vector (length);
3323 skip_dyn_eof (readcharfun); 3401 unsigned char *data = bool_vector_uchar_data (obj);
3324 return Qnil; 3402 memcpy (data, SDATA (str), size_in_chars);
3325 } 3403 /* Clear the extraneous bits in the last byte. */
3326 } 3404 if (length != size_in_chars * BOOL_VECTOR_BITS_PER_CHAR)
3405 data[size_in_chars - 1] &= (1 << (length % BOOL_VECTOR_BITS_PER_CHAR)) - 1;
3406 return obj;
3407}
3408
3409/* Skip (and optionally remember) a lazily-loaded string
3410 preceded by "#@". */
3411static void
3412skip_lazy_string (Lisp_Object readcharfun)
3413{
3414 ptrdiff_t nskip = 0;
3415 ptrdiff_t digits = 0;
3416 for (;;)
3417 {
3418 int c = READCHAR;
3419 if (c < '0' || c > '9')
3420 {
3327 if (nskip > 0) 3421 if (nskip > 0)
3328 /* We can't use UNREAD here, because in the code below we side-step 3422 /* We can't use UNREAD here, because in the code below we side-step
3329 READCHAR. Instead, assume the first char after #@NNN occupies 3423 READCHAR. Instead, assume the first char after #@NNN occupies
3330 a single byte, which is the case normally since it's just 3424 a single byte, which is the case normally since it's just
3331 a space. */ 3425 a space. */
3332 nskip--; 3426 nskip--;
3333 else 3427 else
3334 UNREAD (c); 3428 UNREAD (c);
3335 3429 break;
3336 if (load_force_doc_strings
3337 && (FROM_FILE_P (readcharfun)))
3338 {
3339 /* If we are supposed to force doc strings into core right now,
3340 record the last string that we skipped,
3341 and record where in the file it comes from. */
3342
3343 /* But first exchange saved_doc_string
3344 with prev_saved_doc_string, so we save two strings. */
3345 {
3346 char *temp = saved_doc_string;
3347 ptrdiff_t temp_size = saved_doc_string_size;
3348 file_offset temp_pos = saved_doc_string_position;
3349 ptrdiff_t temp_len = saved_doc_string_length;
3350
3351 saved_doc_string = prev_saved_doc_string;
3352 saved_doc_string_size = prev_saved_doc_string_size;
3353 saved_doc_string_position = prev_saved_doc_string_position;
3354 saved_doc_string_length = prev_saved_doc_string_length;
3355
3356 prev_saved_doc_string = temp;
3357 prev_saved_doc_string_size = temp_size;
3358 prev_saved_doc_string_position = temp_pos;
3359 prev_saved_doc_string_length = temp_len;
3360 }
3361
3362 if (saved_doc_string_size == 0)
3363 {
3364 saved_doc_string = xmalloc (nskip + extra);
3365 saved_doc_string_size = nskip + extra;
3366 }
3367 if (nskip > saved_doc_string_size)
3368 {
3369 saved_doc_string = xrealloc (saved_doc_string, nskip + extra);
3370 saved_doc_string_size = nskip + extra;
3371 }
3372
3373 FILE *instream = infile->stream;
3374 saved_doc_string_position = (file_tell (instream)
3375 - infile->lookahead);
3376
3377 /* Copy that many bytes into saved_doc_string. */
3378 i = 0;
3379 for (int n = min (nskip, infile->lookahead); 0 < n; n--)
3380 saved_doc_string[i++]
3381 = c = infile->buf[--infile->lookahead];
3382 block_input ();
3383 for (; i < nskip && 0 <= c; i++)
3384 saved_doc_string[i] = c = getc (instream);
3385 unblock_input ();
3386
3387 saved_doc_string_length = i;
3388 }
3389 else
3390 /* Skip that many bytes. */
3391 skip_dyn_bytes (readcharfun, nskip);
3392
3393 goto retry;
3394 } 3430 }
3395 if (c == '!') 3431 if (INT_MULTIPLY_WRAPV (nskip, 10, &nskip)
3432 | INT_ADD_WRAPV (nskip, c - '0', &nskip))
3433 invalid_syntax ("#@", readcharfun);
3434 digits++;
3435 if (digits == 2 && nskip == 0)
3396 { 3436 {
3397 /* #! appears at the beginning of an executable file. 3437 /* #@00 means "skip to end" */
3398 Skip the first line. */ 3438 skip_dyn_eof (readcharfun);
3399 while (c != '\n' && c >= 0) 3439 return;
3400 c = READCHAR;
3401 goto retry;
3402 } 3440 }
3403 if (c == '$') 3441 }
3404 return Vload_file_name; 3442
3405 if (c == '\'') 3443 if (load_force_doc_strings && FROM_FILE_P (readcharfun))
3406 return list2 (Qfunction, read0 (readcharfun, locate_syms)); 3444 {
3407 /* #:foo is the uninterned symbol named foo. */ 3445 /* If we are supposed to force doc strings into core right now,
3408 if (c == ':') 3446 record the last string that we skipped,
3447 and record where in the file it comes from. */
3448
3449 /* But first exchange saved_doc_string
3450 with prev_saved_doc_string, so we save two strings. */
3451 {
3452 char *temp = saved_doc_string;
3453 ptrdiff_t temp_size = saved_doc_string_size;
3454 file_offset temp_pos = saved_doc_string_position;
3455 ptrdiff_t temp_len = saved_doc_string_length;
3456
3457 saved_doc_string = prev_saved_doc_string;
3458 saved_doc_string_size = prev_saved_doc_string_size;
3459 saved_doc_string_position = prev_saved_doc_string_position;
3460 saved_doc_string_length = prev_saved_doc_string_length;
3461
3462 prev_saved_doc_string = temp;
3463 prev_saved_doc_string_size = temp_size;
3464 prev_saved_doc_string_position = temp_pos;
3465 prev_saved_doc_string_length = temp_len;
3466 }
3467
3468 enum { extra = 100 };
3469 if (saved_doc_string_size == 0)
3409 { 3470 {
3410 uninterned_symbol = true; 3471 saved_doc_string = xmalloc (nskip + extra);
3411 read_hash_prefixed_symbol: 3472 saved_doc_string_size = nskip + extra;
3412 c = READCHAR;
3413 if (!(c > 040
3414 && c != NO_BREAK_SPACE
3415 && (c >= 0200
3416 || strchr ("\"';()[]#`,", c) == NULL)))
3417 {
3418 /* No symbol character follows, this is the empty
3419 symbol. */
3420 UNREAD (c);
3421 return Fmake_symbol (empty_unibyte_string);
3422 }
3423 goto read_symbol;
3424 } 3473 }
3425 /* #_foo is really the symbol foo, regardless of shorthands */ 3474 if (nskip > saved_doc_string_size)
3426 if (c == '_')
3427 { 3475 {
3428 skip_shorthand = true; 3476 saved_doc_string = xrealloc (saved_doc_string, nskip + extra);
3429 goto read_hash_prefixed_symbol; 3477 saved_doc_string_size = nskip + extra;
3430 } 3478 }
3431 /* ## is the empty symbol. */
3432 if (c == '#')
3433 return Fintern (empty_unibyte_string, Qnil);
3434 3479
3435 if (c >= '0' && c <= '9') 3480 FILE *instream = infile->stream;
3436 { 3481 saved_doc_string_position = (file_tell (instream) - infile->lookahead);
3437 EMACS_INT n = c - '0';
3438 bool overflow = false;
3439 3482
3440 /* Read a non-negative integer. */ 3483 /* Copy that many bytes into saved_doc_string. */
3441 while ('0' <= (c = READCHAR) && c <= '9') 3484 ptrdiff_t i = 0;
3442 { 3485 int c = 0;
3443 overflow |= INT_MULTIPLY_WRAPV (n, 10, &n); 3486 for (int n = min (nskip, infile->lookahead); n > 0; n--)
3444 overflow |= INT_ADD_WRAPV (n, c - '0', &n); 3487 saved_doc_string[i++] = c = infile->buf[--infile->lookahead];
3445 } 3488 block_input ();
3489 for (; i < nskip && c >= 0; i++)
3490 saved_doc_string[i] = c = getc (instream);
3491 unblock_input ();
3446 3492
3447 if (!overflow) 3493 saved_doc_string_length = i;
3448 { 3494 }
3449 if (c == 'r' || c == 'R') 3495 else
3450 { 3496 /* Skip that many bytes. */
3451 if (! (2 <= n && n <= 36)) 3497 skip_dyn_bytes (readcharfun, nskip);
3452 invalid_radix_integer (n, stackbuf, readcharfun); 3498}
3453 return read_integer (readcharfun, n, stackbuf);
3454 }
3455 3499
3456 if (n <= MOST_POSITIVE_FIXNUM && ! NILP (Vread_circle))
3457 {
3458 /* Reader forms that can reuse previously read objects. */
3459 3500
3460 /* #n=object returns object, but associates it with 3501/* Length of prefix only consisting of symbol constituent characters. */
3461 n for #n#. */ 3502static ptrdiff_t
3462 if (c == '=') 3503symbol_char_span (const char *s)
3463 { 3504{
3464 /* Make a placeholder for #n# to use temporarily. */ 3505 const char *p = s;
3465 /* Note: We used to use AUTO_CONS to allocate 3506 while ( *p == '^' || *p == '*' || *p == '+' || *p == '-' || *p == '/'
3466 placeholder, but that is a bad idea, since it 3507 || *p == '<' || *p == '=' || *p == '>' || *p == '_' || *p == '|')
3467 will place a stack-allocated cons cell into 3508 p++;
3468 the list in read_objects_map, which is a 3509 return p - s;
3469 staticpro'd global variable, and thus each of 3510}
3470 its elements is marked during each GC. A
3471 stack-allocated object will become garbled
3472 when its stack slot goes out of scope, and
3473 some other function reuses it for entirely
3474 different purposes, which will cause crashes
3475 in GC. */
3476 Lisp_Object placeholder = Fcons (Qnil, Qnil);
3477 struct Lisp_Hash_Table *h
3478 = XHASH_TABLE (read_objects_map);
3479 Lisp_Object number = make_fixnum (n), hash;
3480
3481 ptrdiff_t i = hash_lookup (h, number, &hash);
3482 if (i >= 0)
3483 /* Not normal, but input could be malformed. */
3484 set_hash_value_slot (h, i, placeholder);
3485 else
3486 hash_put (h, number, placeholder, hash);
3487
3488 /* Read the object itself. */
3489 Lisp_Object tem = read0 (readcharfun, locate_syms);
3490
3491 if (CONSP (tem))
3492 {
3493 if (BASE_EQ (tem, placeholder))
3494 /* Catch silly games like #1=#1# */
3495 invalid_syntax ("nonsensical self-reference",
3496 readcharfun);
3497 3511
3498 /* Optimisation: since the placeholder is already 3512static void
3499 a cons, repurpose it as the actual value. 3513skip_space_and_comments (Lisp_Object readcharfun)
3500 This allows us to skip the substition below, 3514{
3501 since the placeholder is already referenced 3515 int c;
3502 inside TEM at the appropriate places. */ 3516 do
3503 Fsetcar (placeholder, XCAR (tem)); 3517 {
3504 Fsetcdr (placeholder, XCDR (tem)); 3518 c = READCHAR;
3505 3519 if (c == ';')
3506 struct Lisp_Hash_Table *h2 3520 do
3507 = XHASH_TABLE (read_objects_completed); 3521 c = READCHAR;
3508 ptrdiff_t i = hash_lookup (h2, placeholder, &hash); 3522 while (c >= 0 && c != '\n');
3509 eassert (i < 0); 3523 if (c < 0)
3510 hash_put (h2, placeholder, Qnil, hash); 3524 end_of_file_error ();
3511 return placeholder; 3525 }
3512 } 3526 while (c <= 32 || c == NO_BREAK_SPACE);
3513 3527 UNREAD (c);
3514 /* If it can be recursive, remember it for 3528}
3515 future substitutions. */
3516 if (! SYMBOLP (tem)
3517 && ! NUMBERP (tem)
3518 && ! (STRINGP (tem) && !string_intervals (tem)))
3519 {
3520 struct Lisp_Hash_Table *h2
3521 = XHASH_TABLE (read_objects_completed);
3522 i = hash_lookup (h2, tem, &hash);
3523 eassert (i < 0);
3524 hash_put (h2, tem, Qnil, hash);
3525 }
3526
3527 /* Now put it everywhere the placeholder was... */
3528 Flread__substitute_object_in_subtree
3529 (tem, placeholder, read_objects_completed);
3530
3531 /* ...and #n# will use the real value from now on. */
3532 i = hash_lookup (h, number, &hash);
3533 eassert (i >= 0);
3534 set_hash_value_slot (h, i, tem);
3535
3536 return tem;
3537 }
3538 3529
3539 /* #n# returns a previously read object. */ 3530/* When an object is read, the type of the top read stack entry indicates
3540 if (c == '#') 3531 the syntactic context. */
3541 { 3532enum read_entry_type
3542 struct Lisp_Hash_Table *h 3533{
3543 = XHASH_TABLE (read_objects_map); 3534 /* preceding syntactic context */
3544 ptrdiff_t i = hash_lookup (h, make_fixnum (n), NULL); 3535 RE_list_start, /* "(" */
3545 if (i >= 0) 3536
3546 return HASH_VALUE (h, i); 3537 RE_list, /* "(" (+ OBJECT) */
3547 } 3538 RE_list_dot, /* "(" (+ OBJECT) "." */
3548 } 3539
3549 } 3540 RE_vector, /* "[" (* OBJECT) */
3550 /* Fall through to error message. */ 3541 RE_record, /* "#s(" (* OBJECT) */
3542 RE_char_table, /* "#^[" (* OBJECT) */
3543 RE_sub_char_table, /* "#^^[" (* OBJECT) */
3544 RE_byte_code, /* "#[" (* OBJECT) */
3545 RE_string_props, /* "#(" (* OBJECT) */
3546
3547 RE_special, /* "'" | "#'" | "`" | "," | ",@" */
3548
3549 RE_numbered, /* "#" (+ DIGIT) "=" */
3550};
3551
3552struct read_stack_entry
3553{
3554 enum read_entry_type type;
3555 union {
3556 /* RE_list, RE_list_dot */
3557 struct {
3558 Lisp_Object head; /* first cons of list */
3559 Lisp_Object tail; /* last cons of list */
3560 } list;
3561
3562 /* RE_vector, RE_record, RE_char_table, RE_sub_char_table,
3563 RE_byte_code, RE_string_props */
3564 struct {
3565 Lisp_Object elems; /* list of elements in reverse order */
3566 bool old_locate_syms; /* old value of locate_syms */
3567 } vector;
3568
3569 /* RE_special */
3570 struct {
3571 Lisp_Object symbol; /* symbol from special syntax */
3572 } special;
3573
3574 /* RE_numbered */
3575 struct {
3576 Lisp_Object number; /* number as a fixnum */
3577 Lisp_Object placeholder; /* placeholder object */
3578 } numbered;
3579 } u;
3580};
3581
3582struct read_stack
3583{
3584 struct read_stack_entry *stack; /* base of stack */
3585 ptrdiff_t size; /* allocated size in entries */
3586 ptrdiff_t sp; /* current number of entries */
3587};
3588
3589static struct read_stack rdstack = {NULL, 0, 0};
3590
3591void
3592mark_lread (void)
3593{
3594 /* Mark the read stack, which may contain data not otherwise traced */
3595 for (ptrdiff_t i = 0; i < rdstack.sp; i++)
3596 {
3597 struct read_stack_entry *e = &rdstack.stack[i];
3598 switch (e->type)
3599 {
3600 case RE_list_start:
3601 break;
3602 case RE_list:
3603 case RE_list_dot:
3604 mark_object (e->u.list.head);
3605 mark_object (e->u.list.tail);
3606 break;
3607 case RE_vector:
3608 case RE_record:
3609 case RE_char_table:
3610 case RE_sub_char_table:
3611 case RE_byte_code:
3612 case RE_string_props:
3613 mark_object (e->u.vector.elems);
3614 break;
3615 case RE_special:
3616 mark_object (e->u.special.symbol);
3617 break;
3618 case RE_numbered:
3619 mark_object (e->u.numbered.number);
3620 mark_object (e->u.numbered.placeholder);
3621 break;
3551 } 3622 }
3552 else if (c == 'x' || c == 'X') 3623 }
3553 return read_integer (readcharfun, 16, stackbuf); 3624}
3554 else if (c == 'o' || c == 'O')
3555 return read_integer (readcharfun, 8, stackbuf);
3556 else if (c == 'b' || c == 'B')
3557 return read_integer (readcharfun, 2, stackbuf);
3558
3559 char acm_buf[15]; /* FIXME!!! 2021-11-27. */
3560 sprintf (acm_buf, "#%c", c);
3561 invalid_syntax (acm_buf, readcharfun);
3562 UNREAD (c);
3563 invalid_syntax ("#", readcharfun);
3564 3625
3565 case ';': 3626static inline struct read_stack_entry *
3566 while ((c = READCHAR) >= 0 && c != '\n'); 3627read_stack_top (void)
3567 goto retry; 3628{
3629 eassume (rdstack.sp > 0);
3630 return &rdstack.stack[rdstack.sp - 1];
3631}
3568 3632
3569 case '\'': 3633static inline struct read_stack_entry *
3570 return list2 (Qquote, read0 (readcharfun, locate_syms)); 3634read_stack_pop (void)
3635{
3636 eassume (rdstack.sp > 0);
3637 return &rdstack.stack[--rdstack.sp];
3638}
3571 3639
3572 case '`': 3640static inline bool
3573 return list2 (Qbackquote, read0 (readcharfun, locate_syms)); 3641read_stack_empty_p (ptrdiff_t base_sp)
3642{
3643 return rdstack.sp <= base_sp;
3644}
3574 3645
3575 case ',': 3646NO_INLINE static void
3576 { 3647grow_read_stack (void)
3577 Lisp_Object comma_type = Qnil; 3648{
3578 Lisp_Object value; 3649 struct read_stack *rs = &rdstack;
3579 int ch = READCHAR; 3650 eassert (rs->sp == rs->size);
3651 rs->stack = xpalloc (rs->stack, &rs->size, 1, -1, sizeof *rs->stack);
3652 eassert (rs->sp < rs->size);
3653}
3580 3654
3581 if (ch == '@') 3655static inline void
3582 comma_type = Qcomma_at; 3656read_stack_push (struct read_stack_entry e)
3583 else 3657{
3584 { 3658 if (rdstack.sp >= rdstack.size)
3585 if (ch >= 0) UNREAD (ch); 3659 grow_read_stack ();
3586 comma_type = Qcomma; 3660 rdstack.stack[rdstack.sp++] = e;
3587 } 3661}
3588 3662
3589 value = read0 (readcharfun, locate_syms);
3590 return list2 (comma_type, value);
3591 }
3592 case '?':
3593 {
3594 int modifiers;
3595 int next_char;
3596 bool ok;
3597 3663
3598 c = READCHAR; 3664/* Read a Lisp object.
3599 if (c < 0) 3665 If LOCATE_SYMS is true, symbols are read with position. */
3600 end_of_file_error (); 3666static Lisp_Object
3601 3667read0 (Lisp_Object readcharfun, bool locate_syms)
3602 /* Accept `single space' syntax like (list ? x) where the 3668{
3603 whitespace character is SPC or TAB. 3669 char stackbuf[stackbufsize];
3604 Other literal whitespace like NL, CR, and FF are not accepted, 3670 char *read_buffer = stackbuf;
3605 as there are well-established escape sequences for these. */ 3671 ptrdiff_t read_buffer_size = sizeof stackbuf;
3606 if (c == ' ' || c == '\t') 3672 char *heapbuf = NULL;
3607 return make_fixnum (c); 3673 specpdl_ref count = SPECPDL_INDEX ();
3608 3674
3609 if (c == '(' || c == ')' || c == '[' || c == ']' 3675 ptrdiff_t base_sp = rdstack.sp;
3610 || c == '"' || c == ';') 3676
3677 bool uninterned_symbol;
3678 bool skip_shorthand;
3679
3680 /* Read an object into `obj'. */
3681 read_obj: ;
3682 Lisp_Object obj;
3683 bool multibyte;
3684 int c = READCHAR_REPORT_MULTIBYTE (&multibyte);
3685 if (c < 0)
3686 end_of_file_error ();
3687
3688 switch (c)
3689 {
3690 case '(':
3691 read_stack_push ((struct read_stack_entry) {.type = RE_list_start});
3692 goto read_obj;
3693
3694 case ')':
3695 if (read_stack_empty_p (base_sp))
3696 invalid_syntax (")", readcharfun);
3697 switch (read_stack_top ()->type)
3698 {
3699 case RE_list_start:
3700 read_stack_pop ();
3701 obj = Qnil;
3702 break;
3703 case RE_list:
3704 obj = read_stack_pop ()->u.list.head;
3705 break;
3706 case RE_record:
3611 { 3707 {
3612 CHECK_LIST (Vlread_unescaped_character_literals); 3708 locate_syms = read_stack_top ()->u.vector.old_locate_syms;
3613 Lisp_Object char_obj = make_fixed_natnum (c); 3709 Lisp_Object elems = Fnreverse (read_stack_pop ()->u.vector.elems);
3614 if (NILP (Fmemq (char_obj, Vlread_unescaped_character_literals))) 3710 if (NILP (elems))
3615 Vlread_unescaped_character_literals = 3711 invalid_syntax ("#s", readcharfun);
3616 Fcons (char_obj, Vlread_unescaped_character_literals); 3712
3713 if (BASE_EQ (XCAR (elems), Qhash_table))
3714 obj = hash_table_from_plist (XCDR (elems));
3715 else
3716 obj = record_from_list (elems);
3717 break;
3617 } 3718 }
3719 case RE_string_props:
3720 locate_syms = read_stack_top ()->u.vector.old_locate_syms;
3721 obj = string_props_from_rev_list (read_stack_pop () ->u.vector.elems,
3722 readcharfun);
3723 break;
3724 default:
3725 invalid_syntax (")", readcharfun);
3726 }
3727 break;
3618 3728
3619 if (c == '\\') 3729 case '[':
3620 c = read_escape (readcharfun, 0); 3730 read_stack_push ((struct read_stack_entry) {
3621 modifiers = c & CHAR_MODIFIER_MASK; 3731 .type = RE_vector,
3622 c &= ~CHAR_MODIFIER_MASK; 3732 .u.vector.elems = Qnil,
3623 if (CHAR_BYTE8_P (c)) 3733 .u.vector.old_locate_syms = locate_syms,
3624 c = CHAR_TO_BYTE8 (c); 3734 });
3625 c |= modifiers; 3735 /* FIXME: should vectors be read with locate_syms=false? */
3626 3736 goto read_obj;
3627 next_char = READCHAR;
3628 ok = (next_char <= 040
3629 || (next_char < 0200
3630 && strchr ("\"';()[]#?`,.", next_char) != NULL));
3631 UNREAD (next_char);
3632 if (ok)
3633 return make_fixnum (c);
3634
3635 invalid_syntax ("?", readcharfun);
3636 }
3637 3737
3638 case '"': 3738 case ']':
3739 if (read_stack_empty_p (base_sp))
3740 invalid_syntax ("]", readcharfun);
3741 switch (read_stack_top ()->type)
3742 {
3743 case RE_vector:
3744 locate_syms = read_stack_top ()->u.vector.old_locate_syms;
3745 obj = vector_from_rev_list (read_stack_pop ()->u.vector.elems);
3746 break;
3747 case RE_byte_code:
3748 locate_syms = read_stack_top ()->u.vector.old_locate_syms;
3749 obj = bytecode_from_rev_list (read_stack_pop ()->u.vector.elems,
3750 readcharfun);
3751 break;
3752 case RE_char_table:
3753 locate_syms = read_stack_top ()->u.vector.old_locate_syms;
3754 obj = char_table_from_rev_list (read_stack_pop ()->u.vector.elems,
3755 readcharfun);
3756 break;
3757 case RE_sub_char_table:
3758 locate_syms = read_stack_top ()->u.vector.old_locate_syms;
3759 obj = sub_char_table_from_rev_list (read_stack_pop ()->u.vector.elems,
3760 readcharfun);
3761 break;
3762 default:
3763 invalid_syntax ("]", readcharfun);
3764 break;
3765 }
3766 break;
3767
3768 case '#':
3639 { 3769 {
3640 specpdl_ref count = SPECPDL_INDEX (); 3770 int ch = READCHAR;
3641 char *read_buffer = stackbuf; 3771 switch (ch)
3642 ptrdiff_t read_buffer_size = sizeof stackbuf;
3643 char *heapbuf = NULL;
3644 char *p = read_buffer;
3645 char *end = read_buffer + read_buffer_size;
3646 int ch;
3647 /* True if we saw an escape sequence specifying
3648 a multibyte character. */
3649 bool force_multibyte = false;
3650 /* True if we saw an escape sequence specifying
3651 a single-byte character. */
3652 bool force_singlebyte = false;
3653 bool cancel = false;
3654 ptrdiff_t nchars = 0;
3655
3656 while ((ch = READCHAR) >= 0
3657 && ch != '\"')
3658 { 3772 {
3659 if (end - p < MAX_MULTIBYTE_LENGTH) 3773 case '\'':
3774 /* #'X -- special syntax for (function X) */
3775 read_stack_push ((struct read_stack_entry) {
3776 .type = RE_special,
3777 .u.special.symbol = Qfunction,
3778 });
3779 goto read_obj;
3780
3781 case '#':
3782 /* ## -- the empty symbol */
3783 obj = Fintern (empty_unibyte_string, Qnil);
3784 break;
3785
3786 case 's':
3787 /* #s(...) -- a record or hash-table */
3788 ch = READCHAR;
3789 if (ch != '(')
3660 { 3790 {
3661 ptrdiff_t offset = p - read_buffer; 3791 UNREAD (ch);
3662 read_buffer = grow_read_buffer (read_buffer, offset, 3792 invalid_syntax ("#s", readcharfun);
3663 &heapbuf, &read_buffer_size,
3664 count);
3665 p = read_buffer + offset;
3666 end = read_buffer + read_buffer_size;
3667 } 3793 }
3794 read_stack_push ((struct read_stack_entry) {
3795 .type = RE_record,
3796 .u.vector.elems = Qnil,
3797 .u.vector.old_locate_syms = locate_syms,
3798 });
3799 locate_syms = false;
3800 goto read_obj;
3801
3802 case '^':
3803 /* #^[...] -- char-table
3804 #^^[...] -- sub-char-table */
3805 ch = READCHAR;
3806 if (ch == '^')
3807 {
3808 ch = READCHAR;
3809 if (ch == '[')
3810 {
3811 read_stack_push ((struct read_stack_entry) {
3812 .type = RE_sub_char_table,
3813 .u.vector.elems = Qnil,
3814 .u.vector.old_locate_syms = locate_syms,
3815 });
3816 locate_syms = false;
3817 goto read_obj;
3818 }
3819 else
3820 {
3821 UNREAD (ch);
3822 invalid_syntax ("#^^", readcharfun);
3823 }
3824 }
3825 else if (ch == '[')
3826 {
3827 read_stack_push ((struct read_stack_entry) {
3828 .type = RE_char_table,
3829 .u.vector.elems = Qnil,
3830 .u.vector.old_locate_syms = locate_syms,
3831 });
3832 locate_syms = false;
3833 goto read_obj;
3834 }
3835 else
3836 {
3837 UNREAD (ch);
3838 invalid_syntax ("#^", readcharfun);
3839 }
3840
3841 case '(':
3842 /* #(...) -- string with properties */
3843 read_stack_push ((struct read_stack_entry) {
3844 .type = RE_string_props,
3845 .u.vector.elems = Qnil,
3846 .u.vector.old_locate_syms = locate_syms,
3847 });
3848 locate_syms = false;
3849 goto read_obj;
3850
3851 case '[':
3852 /* #[...] -- byte-code */
3853 read_stack_push ((struct read_stack_entry) {
3854 .type = RE_byte_code,
3855 .u.vector.elems = Qnil,
3856 .u.vector.old_locate_syms = locate_syms,
3857 });
3858 locate_syms = false;
3859 goto read_obj;
3860
3861 case '&':
3862 /* #&N"..." -- bool-vector */
3863 obj = read_bool_vector (stackbuf, readcharfun);
3864 break;
3865
3866 case '!':
3867 /* #! appears at the beginning of an executable file.
3868 Skip the rest of the line. */
3869 {
3870 int c;
3871 do
3872 c = READCHAR;
3873 while (c >= 0 && c != '\n');
3874 goto read_obj;
3875 }
3668 3876
3669 if (ch == '\\') 3877 case 'x':
3878 case 'X':
3879 obj = read_integer (readcharfun, 16, stackbuf);
3880 break;
3881
3882 case 'o':
3883 case 'O':
3884 obj = read_integer (readcharfun, 8, stackbuf);
3885 break;
3886
3887 case 'b':
3888 case 'B':
3889 obj = read_integer (readcharfun, 2, stackbuf);
3890 break;
3891
3892 case '@':
3893 /* #@NUMBER is used to skip NUMBER following bytes.
3894 That's used in .elc files to skip over doc strings
3895 and function definitions that can be loaded lazily. */
3896 skip_lazy_string (readcharfun);
3897 goto read_obj;
3898
3899 case '$':
3900 /* #$ -- reference to lazy-loaded string */
3901 obj = Vload_file_name;
3902 break;
3903
3904 case ':':
3905 /* #:X -- uninterned symbol */
3906 c = READCHAR;
3907 if (c <= 32 || c == NO_BREAK_SPACE
3908 || c == '"' || c == '\'' || c == ';' || c == '#'
3909 || c == '(' || c == ')' || c == '[' || c == ']'
3910 || c == '`' || c == ',')
3670 { 3911 {
3671 int modifiers; 3912 /* No symbol character follows: this is the empty symbol. */
3913 UNREAD (c);
3914 obj = Fmake_symbol (empty_unibyte_string);
3915 break;
3916 }
3917 uninterned_symbol = true;
3918 skip_shorthand = false;
3919 goto read_symbol;
3672 3920
3673 ch = read_escape (readcharfun, 1); 3921 case '_':
3922 /* #_X -- symbol without shorthand */
3923 c = READCHAR;
3924 if (c <= 32 || c == NO_BREAK_SPACE
3925 || c == '"' || c == '\'' || c == ';' || c == '#'
3926 || c == '(' || c == ')' || c == '[' || c == ']'
3927 || c == '`' || c == ',')
3928 {
3929 /* No symbol character follows: this is the empty symbol. */
3930 UNREAD (c);
3931 obj = Fintern (empty_unibyte_string, Qnil);
3932 break;
3933 }
3934 uninterned_symbol = false;
3935 skip_shorthand = true;
3936 goto read_symbol;
3674 3937
3675 /* CH is -1 if \ newline or \ space has just been seen. */ 3938 default:
3676 if (ch == -1) 3939 if (ch >= '0' && ch <= '9')
3940 {
3941 /* #N=OBJ or #N# -- first read the number N */
3942 EMACS_INT n = ch - '0';
3943 int c;
3944 for (;;)
3677 { 3945 {
3678 if (p == read_buffer) 3946 c = READCHAR;
3679 cancel = true; 3947 if (c < '0' || c > '9')
3680 continue; 3948 break;
3949 if (INT_MULTIPLY_WRAPV (n, 10, &n)
3950 || INT_ADD_WRAPV (n, c - '0', &n))
3951 invalid_syntax ("#", readcharfun);
3681 } 3952 }
3682 3953 if (c == 'r' || c == 'R')
3683 modifiers = ch & CHAR_MODIFIER_MASK;
3684 ch = ch & ~CHAR_MODIFIER_MASK;
3685
3686 if (CHAR_BYTE8_P (ch))
3687 force_singlebyte = true;
3688 else if (! ASCII_CHAR_P (ch))
3689 force_multibyte = true;
3690 else /* I.e. ASCII_CHAR_P (ch). */
3691 { 3954 {
3692 /* Allow `\C- ' and `\C-?'. */ 3955 /* #NrDIGITS -- radix-N number */
3693 if (modifiers == CHAR_CTL) 3956 if (n < 0 || n > 36)
3694 { 3957 invalid_radix_integer (n, stackbuf, readcharfun);
3695 if (ch == ' ') 3958 obj = read_integer (readcharfun, n, stackbuf);
3696 ch = 0, modifiers = 0; 3959 break;
3697 else if (ch == '?') 3960 }
3698 ch = 127, modifiers = 0; 3961 else if (n <= MOST_POSITIVE_FIXNUM && !NILP (Vread_circle))
3699 } 3962 {
3700 if (modifiers & CHAR_SHIFT) 3963 if (c == '=')
3701 { 3964 {
3702 /* Shift modifier is valid only with [A-Za-z]. */ 3965 /* #N=OBJ -- assign number N to OBJ */
3703 if (ch >= 'A' && ch <= 'Z') 3966 Lisp_Object placeholder = Fcons (Qnil, Qnil);
3704 modifiers &= ~CHAR_SHIFT; 3967
3705 else if (ch >= 'a' && ch <= 'z') 3968 struct Lisp_Hash_Table *h
3706 ch -= ('a' - 'A'), modifiers &= ~CHAR_SHIFT; 3969 = XHASH_TABLE (read_objects_map);
3970 Lisp_Object number = make_fixnum (n);
3971 Lisp_Object hash;
3972 ptrdiff_t i = hash_lookup (h, number, &hash);
3973 if (i >= 0)
3974 /* Not normal, but input could be malformed. */
3975 set_hash_value_slot (h, i, placeholder);
3976 else
3977 hash_put (h, number, placeholder, hash);
3978 read_stack_push ((struct read_stack_entry) {
3979 .type = RE_numbered,
3980 .u.numbered.number = number,
3981 .u.numbered.placeholder = placeholder,
3982 });
3983 goto read_obj;
3707 } 3984 }
3708 3985 else if (c == '#')
3709 if (modifiers & CHAR_META)
3710 { 3986 {
3711 /* Move the meta bit to the right place for a 3987 /* #N# -- reference to numbered object */
3712 string. */ 3988 struct Lisp_Hash_Table *h
3713 modifiers &= ~CHAR_META; 3989 = XHASH_TABLE (read_objects_map);
3714 ch = BYTE8_TO_CHAR (ch | 0x80); 3990 ptrdiff_t i = hash_lookup (h, make_fixnum (n), NULL);
3715 force_singlebyte = true; 3991 if (i < 0)
3992 invalid_syntax ("#", readcharfun);
3993 obj = HASH_VALUE (h, i);
3994 break;
3716 } 3995 }
3996 else
3997 invalid_syntax ("#", readcharfun);
3717 } 3998 }
3718 3999 else
3719 /* Any modifiers remaining are invalid. */ 4000 invalid_syntax ("#", readcharfun);
3720 if (modifiers)
3721 invalid_syntax ("Invalid modifier in string", readcharfun);
3722 p += CHAR_STRING (ch, (unsigned char *) p);
3723 } 4001 }
3724 else 4002 else
3725 { 4003 invalid_syntax ("#", readcharfun);
3726 p += CHAR_STRING (ch, (unsigned char *) p);
3727 if (CHAR_BYTE8_P (ch))
3728 force_singlebyte = true;
3729 else if (! ASCII_CHAR_P (ch))
3730 force_multibyte = true;
3731 }
3732 nchars++;
3733 } 4004 }
4005 break;
4006 }
3734 4007
3735 if (ch < 0) 4008 case '?':
3736 end_of_file_error (); 4009 obj = read_char_literal (readcharfun);
4010 break;
3737 4011
3738 /* If purifying, and string starts with \ newline, 4012 case '"':
3739 return zero instead. This is for doc strings 4013 obj = read_string_literal (stackbuf, readcharfun);
3740 that we are really going to find in etc/DOC.nn.nn. */ 4014 break;
3741 if (!NILP (Vpurify_flag) && NILP (Vdoc_file_name) && cancel) 4015
3742 return unbind_to (count, make_fixnum (0)); 4016 case '\'':
4017 read_stack_push ((struct read_stack_entry) {
4018 .type = RE_special,
4019 .u.special.symbol = Qquote,
4020 });
4021 goto read_obj;
3743 4022
3744 if (! force_multibyte && force_singlebyte) 4023 case '`':
4024 read_stack_push ((struct read_stack_entry) {
4025 .type = RE_special,
4026 .u.special.symbol = Qbackquote,
4027 });
4028 goto read_obj;
4029
4030 case ',':
4031 {
4032 int ch = READCHAR;
4033 Lisp_Object sym;
4034 if (ch == '@')
4035 sym = Qcomma_at;
4036 else
3745 { 4037 {
3746 /* READ_BUFFER contains raw 8-bit bytes and no multibyte 4038 if (ch >= 0)
3747 forms. Convert it to unibyte. */ 4039 UNREAD (ch);
3748 nchars = str_as_unibyte ((unsigned char *) read_buffer, 4040 sym = Qcomma;
3749 p - read_buffer);
3750 p = read_buffer + nchars;
3751 } 4041 }
4042 read_stack_push ((struct read_stack_entry) {
4043 .type = RE_special,
4044 .u.special.symbol = sym,
4045 });
4046 goto read_obj;
4047 }
3752 4048
3753 Lisp_Object result 4049 case ';':
3754 = make_specified_string (read_buffer, nchars, p - read_buffer, 4050 {
3755 (force_multibyte 4051 int c;
3756 || (p - read_buffer != nchars))); 4052 do
3757 return unbind_to (count, result); 4053 c = READCHAR;
4054 while (c >= 0 && c != '\n');
4055 goto read_obj;
3758 } 4056 }
3759 4057
3760 case '.': 4058 case '.':
3761 { 4059 {
3762 int next_char = READCHAR; 4060 int nch = READCHAR;
3763 UNREAD (next_char); 4061 UNREAD (nch);
3764 4062 if (nch <= 32 || nch == NO_BREAK_SPACE
3765 if (next_char <= 040 4063 || nch == '"' || nch == '\'' || nch == ';'
3766 || (next_char < 0200 4064 || nch == '(' || nch == '[' || nch == '#'
3767 && strchr ("\"';([#?`,", next_char) != NULL)) 4065 || nch == '?' || nch == '`' || nch == ',')
3768 { 4066 {
3769 *pch = c; 4067 if (!read_stack_empty_p (base_sp)
3770 return Qnil; 4068 && read_stack_top ()->type == RE_list)
4069 {
4070 read_stack_top ()->type = RE_list_dot;
4071 goto read_obj;
4072 }
4073 invalid_syntax (".", readcharfun);
3771 } 4074 }
3772 } 4075 }
3773 /* The atom-reading loop below will now loop at least once, 4076 /* may be a number or symbol starting with a dot */
3774 assuring that we will not try to UNREAD two characters in a
3775 row. */
3776 FALLTHROUGH; 4077 FALLTHROUGH;
4078
3777 default: 4079 default:
3778 if (c <= 040) goto retry; 4080 if (c <= 32 || c == NO_BREAK_SPACE)
3779 if (c == NO_BREAK_SPACE) 4081 goto read_obj;
3780 goto retry;
3781 4082
4083 uninterned_symbol = false;
4084 skip_shorthand = false;
4085 /* symbol or number */
3782 read_symbol: 4086 read_symbol:
3783 { 4087 {
3784 specpdl_ref count = SPECPDL_INDEX ();
3785 char *read_buffer = stackbuf;
3786 ptrdiff_t read_buffer_size = sizeof stackbuf;
3787 char *heapbuf = NULL;
3788 char *p = read_buffer; 4088 char *p = read_buffer;
3789 char *end = read_buffer + read_buffer_size; 4089 char *end = read_buffer + read_buffer_size;
3790 bool quoted = false; 4090 bool quoted = false;
@@ -3805,7 +4105,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list, bool locate_syms)
3805 if (c == '\\') 4105 if (c == '\\')
3806 { 4106 {
3807 c = READCHAR; 4107 c = READCHAR;
3808 if (c == -1) 4108 if (c < 0)
3809 end_of_file_error (); 4109 end_of_file_error ();
3810 quoted = true; 4110 quoted = true;
3811 } 4111 }
@@ -3816,94 +4116,205 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list, bool locate_syms)
3816 *p++ = c; 4116 *p++ = c;
3817 c = READCHAR; 4117 c = READCHAR;
3818 } 4118 }
3819 while (c > 040 4119 while (c > 32
3820 && c != NO_BREAK_SPACE 4120 && c != NO_BREAK_SPACE
3821 && (c >= 0200 4121 && (c >= 128
3822 || strchr ("\"';()[]#`,", c) == NULL)); 4122 || !( c == '"' || c == '\'' || c == ';' || c == '#'
4123 || c == '(' || c == ')' || c == '[' || c == ']'
4124 || c == '`' || c == ',')));
3823 4125
3824 *p = 0; 4126 *p = 0;
3825 ptrdiff_t nbytes = p - read_buffer; 4127 ptrdiff_t nbytes = p - read_buffer;
3826 UNREAD (c); 4128 UNREAD (c);
3827 4129
3828 if (!quoted && !uninterned_symbol && !skip_shorthand) 4130 /* Only attempt to parse the token as a number if it starts as one. */
4131 char c0 = read_buffer[0];
4132 if (((c0 >= '0' && c0 <= '9') || c0 == '.' || c0 == '-' || c0 == '+')
4133 && !quoted && !uninterned_symbol && !skip_shorthand)
3829 { 4134 {
3830 ptrdiff_t len; 4135 ptrdiff_t len;
3831 Lisp_Object result = string_to_number (read_buffer, 10, &len); 4136 Lisp_Object result = string_to_number (read_buffer, 10, &len);
3832 if (! NILP (result) && len == nbytes) 4137 if (!NILP (result) && len == nbytes)
3833 return unbind_to (count, result); 4138 {
4139 obj = result;
4140 break;
4141 }
3834 } 4142 }
3835 { 4143
3836 Lisp_Object result; 4144 /* symbol, possibly uninterned */
3837 ptrdiff_t nchars 4145 ptrdiff_t nchars
3838 = (multibyte 4146 = (multibyte
3839 ? multibyte_chars_in_text ((unsigned char *) read_buffer, 4147 ? multibyte_chars_in_text ((unsigned char *)read_buffer, nbytes)
3840 nbytes) 4148 : nbytes);
3841 : nbytes); 4149 Lisp_Object result;
3842 4150 if (uninterned_symbol)
3843 if (uninterned_symbol) 4151 {
3844 { 4152 Lisp_Object name
3845 Lisp_Object name 4153 = (!NILP (Vpurify_flag)
3846 = ((! NILP (Vpurify_flag) 4154 ? make_pure_string (read_buffer, nchars, nbytes, multibyte)
3847 ? make_pure_string : make_specified_string) 4155 : make_specified_string (read_buffer, nchars, nbytes,
3848 (read_buffer, nchars, nbytes, multibyte)); 4156 multibyte));
3849 result = Fmake_symbol (name); 4157 result = Fmake_symbol (name);
3850 } 4158 }
3851 else 4159 else
3852 { 4160 {
3853 /* Don't create the string object for the name unless 4161 /* Don't create the string object for the name unless
3854 we're going to retain it in a new symbol. 4162 we're going to retain it in a new symbol.
3855 4163
3856 Like intern_1 but supports multibyte names. */ 4164 Like intern_1 but supports multibyte names. */
3857 Lisp_Object obarray = check_obarray (Vobarray); 4165 Lisp_Object obarray = check_obarray (Vobarray);
3858 4166
3859 char* longhand = NULL; 4167 char *longhand = NULL;
3860 ptrdiff_t longhand_chars = 0; 4168 ptrdiff_t longhand_chars = 0;
3861 ptrdiff_t longhand_bytes = 0; 4169 ptrdiff_t longhand_bytes = 0;
3862 4170
3863 Lisp_Object tem; 4171 Lisp_Object found;
3864 if (skip_shorthand 4172 if (skip_shorthand
3865 /* The following ASCII characters are used in the 4173 /* We exempt characters used in the "core" Emacs Lisp
3866 only "core" Emacs Lisp symbols that are comprised 4174 symbols that are comprised entirely of characters
3867 entirely of characters that have the 'symbol 4175 that have the 'symbol constituent' syntax from
3868 constituent' syntax. We exempt them from 4176 transforming according to shorthands. */
3869 transforming according to shorthands. */ 4177 || symbol_char_span (read_buffer) >= nbytes)
3870 || strspn (read_buffer, "^*+-/<=>_|") >= nbytes) 4178 found = oblookup (obarray, read_buffer, nchars, nbytes);
3871 tem = oblookup (obarray, read_buffer, nchars, nbytes); 4179 else
3872 else 4180 found = oblookup_considering_shorthand (obarray, read_buffer,
3873 tem = oblookup_considering_shorthand (obarray, read_buffer,
3874 nchars, nbytes, &longhand, 4181 nchars, nbytes, &longhand,
3875 &longhand_chars, 4182 &longhand_chars,
3876 &longhand_bytes); 4183 &longhand_bytes);
3877 4184
3878 if (SYMBOLP (tem)) 4185 if (SYMBOLP (found))
3879 result = tem; 4186 result = found;
3880 else if (longhand) 4187 else if (longhand)
3881 { 4188 {
3882 Lisp_Object name 4189 Lisp_Object name = make_specified_string (longhand,
3883 = make_specified_string (longhand, longhand_chars, 4190 longhand_chars,
3884 longhand_bytes, multibyte); 4191 longhand_bytes,
3885 xfree (longhand); 4192 multibyte);
3886 result = intern_driver (name, obarray, tem); 4193 xfree (longhand);
3887 } 4194 result = intern_driver (name, obarray, found);
3888 else 4195 }
3889 { 4196 else
3890 Lisp_Object name 4197 {
3891 = make_specified_string (read_buffer, nchars, nbytes, 4198 Lisp_Object name = make_specified_string (read_buffer, nchars,
3892 multibyte); 4199 nbytes, multibyte);
3893 result = intern_driver (name, obarray, tem); 4200 result = intern_driver (name, obarray, found);
3894 } 4201 }
3895 } 4202 }
3896 if (locate_syms 4203 if (locate_syms && !NILP (result))
3897 && !NILP (result) 4204 result = build_symbol_with_pos (result,
3898 ) 4205 make_fixnum (start_position));
3899 result = build_symbol_with_pos (result,
3900 make_fixnum (start_position));
3901 4206
3902 return unbind_to (count, result); 4207 obj = result;
3903 } 4208 break;
3904 } 4209 }
3905 } 4210 }
4211
4212 /* We have read an object in `obj'. Use the stack to decide what to
4213 do with it. */
4214 while (rdstack.sp > base_sp)
4215 {
4216 struct read_stack_entry *e = read_stack_top ();
4217 switch (e->type)
4218 {
4219 case RE_list_start:
4220 e->type = RE_list;
4221 e->u.list.head = e->u.list.tail = Fcons (obj, Qnil);
4222 goto read_obj;
4223
4224 case RE_list:
4225 {
4226 Lisp_Object tl = Fcons (obj, Qnil);
4227 XSETCDR (e->u.list.tail, tl);
4228 e->u.list.tail = tl;
4229 goto read_obj;
4230 }
4231
4232 case RE_list_dot:
4233 {
4234 skip_space_and_comments (readcharfun);
4235 int ch = READCHAR;
4236 if (ch != ')')
4237 invalid_syntax ("expected )", readcharfun);
4238 XSETCDR (e->u.list.tail, obj);
4239 read_stack_pop ();
4240 obj = e->u.list.head;
4241 break;
4242 }
4243
4244 case RE_vector:
4245 case RE_record:
4246 case RE_char_table:
4247 case RE_sub_char_table:
4248 case RE_byte_code:
4249 case RE_string_props:
4250 e->u.vector.elems = Fcons (obj, e->u.vector.elems);
4251 goto read_obj;
4252
4253 case RE_special:
4254 read_stack_pop ();
4255 obj = list2 (e->u.special.symbol, obj);
4256 break;
4257
4258 case RE_numbered:
4259 {
4260 read_stack_pop ();
4261 Lisp_Object placeholder = e->u.numbered.placeholder;
4262 if (CONSP (obj))
4263 {
4264 if (BASE_EQ (obj, placeholder))
4265 /* Catch silly games like #1=#1# */
4266 invalid_syntax ("nonsensical self-reference", readcharfun);
4267
4268 /* Optimisation: since the placeholder is already
4269 a cons, repurpose it as the actual value.
4270 This allows us to skip the substitution below,
4271 since the placeholder is already referenced
4272 inside OBJ at the appropriate places. */
4273 Fsetcar (placeholder, XCAR (obj));
4274 Fsetcdr (placeholder, XCDR (obj));
4275
4276 struct Lisp_Hash_Table *h2
4277 = XHASH_TABLE (read_objects_completed);
4278 Lisp_Object hash;
4279 ptrdiff_t i = hash_lookup (h2, placeholder, &hash);
4280 eassert (i < 0);
4281 hash_put (h2, placeholder, Qnil, hash);
4282 obj = placeholder;
4283 }
4284 else
4285 {
4286 /* If it can be recursive, remember it for future
4287 substitutions. */
4288 if (!SYMBOLP (obj) && !NUMBERP (obj)
4289 && !(STRINGP (obj) && !string_intervals (obj)))
4290 {
4291 struct Lisp_Hash_Table *h2
4292 = XHASH_TABLE (read_objects_completed);
4293 Lisp_Object hash;
4294 ptrdiff_t i = hash_lookup (h2, obj, &hash);
4295 eassert (i < 0);
4296 hash_put (h2, obj, Qnil, hash);
4297 }
4298
4299 /* Now put it everywhere the placeholder was... */
4300 Flread__substitute_object_in_subtree (obj, placeholder,
4301 read_objects_completed);
4302
4303 /* ...and #n# will use the real value from now on. */
4304 struct Lisp_Hash_Table *h = XHASH_TABLE (read_objects_map);
4305 Lisp_Object hash;
4306 ptrdiff_t i = hash_lookup (h, e->u.numbered.number, &hash);
4307 eassert (i >= 0);
4308 set_hash_value_slot (h, i, obj);
4309 }
4310 break;
4311 }
4312 }
4313 }
4314
4315 return unbind_to (count, obj);
3906} 4316}
4317
3907 4318
3908DEFUN ("lread--substitute-object-in-subtree", 4319DEFUN ("lread--substitute-object-in-subtree",
3909 Flread__substitute_object_in_subtree, 4320 Flread__substitute_object_in_subtree,
@@ -4150,214 +4561,6 @@ string_to_number (char const *string, int base, ptrdiff_t *plen)
4150} 4561}
4151 4562
4152 4563
4153static Lisp_Object
4154read_vector (Lisp_Object readcharfun, bool bytecodeflag, bool locate_syms)
4155{
4156 Lisp_Object tem = read_list (1, readcharfun, locate_syms);
4157 ptrdiff_t size = list_length (tem);
4158 Lisp_Object vector = make_nil_vector (size);
4159
4160 /* Avoid accessing past the end of a vector if the vector is too
4161 small to be valid for bytecode. */
4162 bytecodeflag &= COMPILED_STACK_DEPTH < size;
4163
4164 Lisp_Object *ptr = XVECTOR (vector)->contents;
4165 for (ptrdiff_t i = 0; i < size; i++)
4166 {
4167 Lisp_Object item = Fcar (tem);
4168 /* If `load-force-doc-strings' is t when reading a lazily-loaded
4169 bytecode object, the docstring containing the bytecode and
4170 constants values must be treated as unibyte and passed to
4171 Fread, to get the actual bytecode string and constants vector. */
4172 if (bytecodeflag && load_force_doc_strings)
4173 {
4174 if (i == COMPILED_BYTECODE)
4175 {
4176 if (!STRINGP (item))
4177 error ("Invalid byte code");
4178
4179 /* Delay handling the bytecode slot until we know whether
4180 it is lazily-loaded (we can tell by whether the
4181 constants slot is nil). */
4182 ASET (vector, COMPILED_CONSTANTS, item);
4183 item = Qnil;
4184 }
4185 else if (i == COMPILED_CONSTANTS)
4186 {
4187 Lisp_Object bytestr = ptr[COMPILED_CONSTANTS];
4188
4189 if (NILP (item))
4190 {
4191 /* Coerce string to unibyte (like string-as-unibyte,
4192 but without generating extra garbage and
4193 guaranteeing no change in the contents). */
4194 STRING_SET_CHARS (bytestr, SBYTES (bytestr));
4195 STRING_SET_UNIBYTE (bytestr);
4196
4197 item = Fread (Fcons (bytestr, readcharfun));
4198 if (!CONSP (item))
4199 error ("Invalid byte code");
4200
4201 struct Lisp_Cons *otem = XCONS (item);
4202 bytestr = XCAR (item);
4203 item = XCDR (item);
4204 free_cons (otem);
4205 }
4206
4207 /* Now handle the bytecode slot. */
4208 ASET (vector, COMPILED_BYTECODE, bytestr);
4209 }
4210 else if (i == COMPILED_DOC_STRING
4211 && STRINGP (item)
4212 && ! STRING_MULTIBYTE (item))
4213 {
4214 if (EQ (readcharfun, Qget_emacs_mule_file_char))
4215 item = Fdecode_coding_string (item, Qemacs_mule, Qnil, Qnil);
4216 else
4217 item = Fstring_as_multibyte (item);
4218 }
4219 }
4220 ASET (vector, i, item);
4221 struct Lisp_Cons *otem = XCONS (tem);
4222 tem = Fcdr (tem);
4223 free_cons (otem);
4224 }
4225 return vector;
4226}
4227
4228/* FLAG means check for ']' to terminate rather than ')' and '.'.
4229 LOCATE_SYMS true means read symbol occurrencess as symbols with
4230 position. */
4231
4232static Lisp_Object
4233read_list (bool flag, Lisp_Object readcharfun, bool locate_syms)
4234{
4235 Lisp_Object val, tail;
4236 Lisp_Object elt, tem;
4237 /* 0 is the normal case.
4238 1 means this list is a doc reference; replace it with the number 0.
4239 2 means this list is a doc reference; replace it with the doc string. */
4240 int doc_reference = 0;
4241
4242 /* Initialize this to 1 if we are reading a list. */
4243 bool first_in_list = flag <= 0;
4244
4245 val = Qnil;
4246 tail = Qnil;
4247
4248 while (1)
4249 {
4250 int ch;
4251 elt = read1 (readcharfun, &ch, first_in_list, locate_syms);
4252
4253 first_in_list = 0;
4254
4255 /* While building, if the list starts with #$, treat it specially. */
4256 if (EQ (elt, Vload_file_name)
4257 && ! NILP (elt))
4258 {
4259 if (!NILP (Vpurify_flag))
4260 doc_reference = 0;
4261 else if (load_force_doc_strings)
4262 doc_reference = 2;
4263 }
4264 if (ch)
4265 {
4266 if (flag > 0)
4267 {
4268 if (ch == ']')
4269 return val;
4270 invalid_syntax (") or . in a vector", readcharfun);
4271 }
4272 if (ch == ')')
4273 return val;
4274 if (ch == '.')
4275 {
4276 if (!NILP (tail))
4277 XSETCDR (tail, read0 (readcharfun, locate_syms));
4278 else
4279 val = read0 (readcharfun, locate_syms);
4280 read1 (readcharfun, &ch, 0, locate_syms);
4281
4282 if (ch == ')')
4283 {
4284 if (doc_reference == 2 && FIXNUMP (XCDR (val)))
4285 {
4286 char *saved = NULL;
4287 file_offset saved_position;
4288 /* Get a doc string from the file we are loading.
4289 If it's in saved_doc_string, get it from there.
4290
4291 Here, we don't know if the string is a
4292 bytecode string or a doc string. As a
4293 bytecode string must be unibyte, we always
4294 return a unibyte string. If it is actually a
4295 doc string, caller must make it
4296 multibyte. */
4297
4298 /* Position is negative for user variables. */
4299 EMACS_INT pos = eabs (XFIXNUM (XCDR (val)));
4300 if (pos >= saved_doc_string_position
4301 && pos < (saved_doc_string_position
4302 + saved_doc_string_length))
4303 {
4304 saved = saved_doc_string;
4305 saved_position = saved_doc_string_position;
4306 }
4307 /* Look in prev_saved_doc_string the same way. */
4308 else if (pos >= prev_saved_doc_string_position
4309 && pos < (prev_saved_doc_string_position
4310 + prev_saved_doc_string_length))
4311 {
4312 saved = prev_saved_doc_string;
4313 saved_position = prev_saved_doc_string_position;
4314 }
4315 if (saved)
4316 {
4317 ptrdiff_t start = pos - saved_position;
4318 ptrdiff_t from, to;
4319
4320 /* Process quoting with ^A,
4321 and find the end of the string,
4322 which is marked with ^_ (037). */
4323 for (from = start, to = start;
4324 saved[from] != 037;)
4325 {
4326 int c = saved[from++];
4327 if (c == 1)
4328 {
4329 c = saved[from++];
4330 saved[to++] = (c == 1 ? c
4331 : c == '0' ? 0
4332 : c == '_' ? 037
4333 : c);
4334 }
4335 else
4336 saved[to++] = c;
4337 }
4338
4339 return make_unibyte_string (saved + start,
4340 to - start);
4341 }
4342 else
4343 return get_doc_string (val, 1, 0);
4344 }
4345
4346 return val;
4347 }
4348 invalid_syntax (". in wrong context", readcharfun);
4349 }
4350 invalid_syntax ("] in a list", readcharfun);
4351 }
4352 tem = list1 (elt);
4353 if (!NILP (tail))
4354 XSETCDR (tail, tem);
4355 else
4356 val = tem;
4357 tail = tem;
4358 }
4359}
4360
4361static Lisp_Object initial_obarray; 4564static Lisp_Object initial_obarray;
4362 4565
4363/* `oblookup' stores the bucket number here, for the sake of Funintern. */ 4566/* `oblookup' stores the bucket number here, for the sake of Funintern. */
@@ -4464,7 +4667,7 @@ define_symbol (Lisp_Object sym, char const *str)
4464 4667
4465 /* Qunbound is uninterned, so that it's not confused with any symbol 4668 /* Qunbound is uninterned, so that it's not confused with any symbol
4466 'unbound' created by a Lisp program. */ 4669 'unbound' created by a Lisp program. */
4467 if (! EQ (sym, Qunbound)) 4670 if (! BASE_EQ (sym, Qunbound))
4468 { 4671 {
4469 Lisp_Object bucket = oblookup (initial_obarray, str, len, len); 4672 Lisp_Object bucket = oblookup (initial_obarray, str, len, len);
4470 eassert (FIXNUMP (bucket)); 4673 eassert (FIXNUMP (bucket));