aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c1225
1 files changed, 697 insertions, 528 deletions
diff --git a/src/data.c b/src/data.c
index bdba3a9bb36..a56b112196d 100644
--- a/src/data.c
+++ b/src/data.c
@@ -91,7 +91,7 @@ Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
91 91
92Lisp_Object Qinteractive_form; 92Lisp_Object Qinteractive_form;
93 93
94static Lisp_Object swap_in_symval_forwarding P_ ((Lisp_Object, Lisp_Object)); 94static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *);
95 95
96Lisp_Object Vmost_positive_fixnum, Vmost_negative_fixnum; 96Lisp_Object Vmost_positive_fixnum, Vmost_negative_fixnum;
97 97
@@ -582,12 +582,35 @@ DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0,
582 register Lisp_Object symbol; 582 register Lisp_Object symbol;
583{ 583{
584 Lisp_Object valcontents; 584 Lisp_Object valcontents;
585 struct Lisp_Symbol *sym;
585 CHECK_SYMBOL (symbol); 586 CHECK_SYMBOL (symbol);
587 sym = XSYMBOL (symbol);
586 588
587 valcontents = SYMBOL_VALUE (symbol); 589 start:
588 590 switch (sym->redirect)
589 if (BUFFER_LOCAL_VALUEP (valcontents)) 591 {
590 valcontents = swap_in_symval_forwarding (symbol, valcontents); 592 case SYMBOL_PLAINVAL: valcontents = SYMBOL_VAL (sym); break;
593 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
594 case SYMBOL_LOCALIZED:
595 {
596 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
597 if (blv->fwd)
598 /* In set_internal, we un-forward vars when their value is
599 set to Qunbound. */
600 return Qt;
601 else
602 {
603 swap_in_symval_forwarding (sym, blv);
604 valcontents = BLV_VALUE (blv);
605 }
606 break;
607 }
608 case SYMBOL_FORWARDED:
609 /* In set_internal, we un-forward vars when their value is
610 set to Qunbound. */
611 return Qt;
612 default: abort ();
613 }
591 614
592 return (EQ (valcontents, Qunbound) ? Qnil : Qt); 615 return (EQ (valcontents, Qunbound) ? Qnil : Qt);
593} 616}
@@ -824,14 +847,14 @@ indirect_variable (symbol)
824 847
825 hare = tortoise = symbol; 848 hare = tortoise = symbol;
826 849
827 while (hare->indirect_variable) 850 while (hare->redirect == SYMBOL_VARALIAS)
828 { 851 {
829 hare = XSYMBOL (hare->value); 852 hare = SYMBOL_ALIAS (hare);
830 if (!hare->indirect_variable) 853 if (hare->redirect != SYMBOL_VARALIAS)
831 break; 854 break;
832 855
833 hare = XSYMBOL (hare->value); 856 hare = SYMBOL_ALIAS (hare);
834 tortoise = XSYMBOL (tortoise->value); 857 tortoise = SYMBOL_ALIAS (tortoise);
835 858
836 if (hare == tortoise) 859 if (hare == tortoise)
837 { 860 {
@@ -865,44 +888,46 @@ variable chain of symbols. */)
865 This does not handle buffer-local variables; use 888 This does not handle buffer-local variables; use
866 swap_in_symval_forwarding for that. */ 889 swap_in_symval_forwarding for that. */
867 890
891#define do_blv_forwarding(blv) \
892 ((blv)->forwarded ? do_symval_forwarding (BLV_FWD (blv)) : BLV_VALUE (blv))
893
868Lisp_Object 894Lisp_Object
869do_symval_forwarding (valcontents) 895do_symval_forwarding (valcontents)
870 register Lisp_Object valcontents; 896 register union Lisp_Fwd *valcontents;
871{ 897{
872 register Lisp_Object val; 898 register Lisp_Object val;
873 if (MISCP (valcontents)) 899 switch (XFWDTYPE (valcontents))
874 switch (XMISCTYPE (valcontents)) 900 {
875 { 901 case Lisp_Fwd_Int:
876 case Lisp_Misc_Intfwd: 902 XSETINT (val, *XINTFWD (valcontents)->intvar);
877 XSETINT (val, *XINTFWD (valcontents)->intvar); 903 return val;
878 return val; 904
879 905 case Lisp_Fwd_Bool:
880 case Lisp_Misc_Boolfwd: 906 return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil);
881 return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil); 907
882 908 case Lisp_Fwd_Obj:
883 case Lisp_Misc_Objfwd: 909 return *XOBJFWD (valcontents)->objvar;
884 return *XOBJFWD (valcontents)->objvar; 910
885 911 case Lisp_Fwd_Buffer_Obj:
886 case Lisp_Misc_Buffer_Objfwd: 912 return PER_BUFFER_VALUE (current_buffer,
887 return PER_BUFFER_VALUE (current_buffer, 913 XBUFFER_OBJFWD (valcontents)->offset);
888 XBUFFER_OBJFWD (valcontents)->offset); 914
889 915 case Lisp_Fwd_Kboard_Obj:
890 case Lisp_Misc_Kboard_Objfwd: 916 /* We used to simply use current_kboard here, but from Lisp
891 /* We used to simply use current_kboard here, but from Lisp 917 code, it's value is often unexpected. It seems nicer to
892 code, it's value is often unexpected. It seems nicer to 918 allow constructions like this to work as intuitively expected:
893 allow constructions like this to work as intuitively expected: 919
894 920 (with-selected-frame frame
895 (with-selected-frame frame 921 (define-key local-function-map "\eOP" [f1]))
896 (define-key local-function-map "\eOP" [f1])) 922
897 923 On the other hand, this affects the semantics of
898 On the other hand, this affects the semantics of 924 last-command and real-last-command, and people may rely on
899 last-command and real-last-command, and people may rely on 925 that. I took a quick look at the Lisp codebase, and I
900 that. I took a quick look at the Lisp codebase, and I 926 don't think anything will break. --lorentey */
901 don't think anything will break. --lorentey */ 927 return *(Lisp_Object *)(XKBOARD_OBJFWD (valcontents)->offset
902 return *(Lisp_Object *)(XKBOARD_OBJFWD (valcontents)->offset 928 + (char *)FRAME_KBOARD (SELECTED_FRAME ()));
903 + (char *)FRAME_KBOARD (SELECTED_FRAME ())); 929 default: abort ();
904 } 930 }
905 return valcontents;
906} 931}
907 932
908/* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell 933/* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell
@@ -913,102 +938,93 @@ do_symval_forwarding (valcontents)
913 BUF non-zero means set the value in buffer BUF instead of the 938 BUF non-zero means set the value in buffer BUF instead of the
914 current buffer. This only plays a role for per-buffer variables. */ 939 current buffer. This only plays a role for per-buffer variables. */
915 940
916void 941#define store_blv_forwarding(blv, newval, buf) \
917store_symval_forwarding (symbol, valcontents, newval, buf) 942 do { \
918 Lisp_Object symbol; 943 if ((blv)->forwarded) \
919 register Lisp_Object valcontents, newval; 944 store_symval_forwarding (BLV_FWD (blv), (newval), (buf)); \
945 else \
946 SET_BLV_VALUE (blv, newval); \
947 } while (0)
948
949static void
950store_symval_forwarding (/* symbol, */ valcontents, newval, buf)
951 /* struct Lisp_Symbol *symbol; */
952 union Lisp_Fwd *valcontents;
953 register Lisp_Object newval;
920 struct buffer *buf; 954 struct buffer *buf;
921{ 955{
922 switch (SWITCH_ENUM_CAST (XTYPE (valcontents))) 956 switch (XFWDTYPE (valcontents))
923 { 957 {
924 case Lisp_Misc: 958 case Lisp_Fwd_Int:
925 switch (XMISCTYPE (valcontents)) 959 CHECK_NUMBER (newval);
960 *XINTFWD (valcontents)->intvar = XINT (newval);
961 break;
962
963 case Lisp_Fwd_Bool:
964 *XBOOLFWD (valcontents)->boolvar = !NILP (newval);
965 break;
966
967 case Lisp_Fwd_Obj:
968 *XOBJFWD (valcontents)->objvar = newval;
969
970 /* If this variable is a default for something stored
971 in the buffer itself, such as default-fill-column,
972 find the buffers that don't have local values for it
973 and update them. */
974 if (XOBJFWD (valcontents)->objvar > (Lisp_Object *) &buffer_defaults
975 && XOBJFWD (valcontents)->objvar < (Lisp_Object *) (&buffer_defaults + 1))
926 { 976 {
927 case Lisp_Misc_Intfwd: 977 int offset = ((char *) XOBJFWD (valcontents)->objvar
928 CHECK_NUMBER (newval); 978 - (char *) &buffer_defaults);
929 *XINTFWD (valcontents)->intvar = XINT (newval); 979 int idx = PER_BUFFER_IDX (offset);
930 /* This can never happen since intvar points to an EMACS_INT 980
931 which is at least large enough to hold a Lisp_Object. 981 Lisp_Object tail;
932 if (*XINTFWD (valcontents)->intvar != XINT (newval)) 982
933 error ("Value out of range for variable `%s'", 983 if (idx <= 0)
934 SDATA (SYMBOL_NAME (symbol))); */ 984 break;
935 break; 985
936 986 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
937 case Lisp_Misc_Boolfwd:
938 *XBOOLFWD (valcontents)->boolvar = !NILP (newval);
939 break;
940
941 case Lisp_Misc_Objfwd:
942 *XOBJFWD (valcontents)->objvar = newval;
943
944 /* If this variable is a default for something stored
945 in the buffer itself, such as default-fill-column,
946 find the buffers that don't have local values for it
947 and update them. */
948 if (XOBJFWD (valcontents)->objvar > (Lisp_Object *) &buffer_defaults
949 && XOBJFWD (valcontents)->objvar < (Lisp_Object *) (&buffer_defaults + 1))
950 { 987 {
951 int offset = ((char *) XOBJFWD (valcontents)->objvar 988 Lisp_Object buf;
952 - (char *) &buffer_defaults); 989 struct buffer *b;
953 int idx = PER_BUFFER_IDX (offset);
954 990
955 Lisp_Object tail; 991 buf = Fcdr (XCAR (tail));
992 if (!BUFFERP (buf)) continue;
993 b = XBUFFER (buf);
956 994
957 if (idx <= 0) 995 if (! PER_BUFFER_VALUE_P (b, idx))
958 break; 996 PER_BUFFER_VALUE (b, offset) = newval;
959
960 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
961 {
962 Lisp_Object buf;
963 struct buffer *b;
964
965 buf = Fcdr (XCAR (tail));
966 if (!BUFFERP (buf)) continue;
967 b = XBUFFER (buf);
968
969 if (! PER_BUFFER_VALUE_P (b, idx))
970 PER_BUFFER_VALUE (b, offset) = newval;
971 }
972 } 997 }
973 break; 998 }
974 999 break;
975 case Lisp_Misc_Buffer_Objfwd:
976 {
977 int offset = XBUFFER_OBJFWD (valcontents)->offset;
978 Lisp_Object type = XBUFFER_OBJFWD (valcontents)->slottype;
979
980 if (!(NILP (type) || NILP (newval)
981 || (XINT (type) == LISP_INT_TAG
982 ? INTEGERP (newval)
983 : XTYPE (newval) == XINT (type))))
984 buffer_slot_type_mismatch (newval, XINT (type));
985
986 if (buf == NULL)
987 buf = current_buffer;
988 PER_BUFFER_VALUE (buf, offset) = newval;
989 }
990 break;
991 1000
992 case Lisp_Misc_Kboard_Objfwd: 1001 case Lisp_Fwd_Buffer_Obj:
993 { 1002 {
994 char *base = (char *) FRAME_KBOARD (SELECTED_FRAME ()); 1003 int offset = XBUFFER_OBJFWD (valcontents)->offset;
995 char *p = base + XKBOARD_OBJFWD (valcontents)->offset; 1004 Lisp_Object type = XBUFFER_OBJFWD (valcontents)->slottype;
996 *(Lisp_Object *) p = newval; 1005
997 } 1006 if (!(NILP (type) || NILP (newval)
998 break; 1007 || (XINT (type) == LISP_INT_TAG
1008 ? INTEGERP (newval)
1009 : XTYPE (newval) == XINT (type))))
1010 buffer_slot_type_mismatch (newval, XINT (type));
1011
1012 if (buf == NULL)
1013 buf = current_buffer;
1014 PER_BUFFER_VALUE (buf, offset) = newval;
1015 }
1016 break;
999 1017
1000 default: 1018 case Lisp_Fwd_Kboard_Obj:
1001 goto def; 1019 {
1002 } 1020 char *base = (char *) FRAME_KBOARD (SELECTED_FRAME ());
1021 char *p = base + XKBOARD_OBJFWD (valcontents)->offset;
1022 *(Lisp_Object *) p = newval;
1023 }
1003 break; 1024 break;
1004 1025
1005 default: 1026 default:
1006 def: 1027 abort (); /* goto def; */
1007 valcontents = SYMBOL_VALUE (symbol);
1008 if (BUFFER_LOCAL_VALUEP (valcontents))
1009 XBUFFER_LOCAL_VALUE (valcontents)->realvalue = newval;
1010 else
1011 SET_SYMBOL_VALUE (symbol, newval);
1012 } 1028 }
1013} 1029}
1014 1030
@@ -1017,25 +1033,22 @@ store_symval_forwarding (symbol, valcontents, newval, buf)
1017 1033
1018void 1034void
1019swap_in_global_binding (symbol) 1035swap_in_global_binding (symbol)
1020 Lisp_Object symbol; 1036 struct Lisp_Symbol *symbol;
1021{ 1037{
1022 Lisp_Object valcontents = SYMBOL_VALUE (symbol); 1038 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (symbol);
1023 struct Lisp_Buffer_Local_Value *blv = XBUFFER_LOCAL_VALUE (valcontents);
1024 Lisp_Object cdr = blv->cdr;
1025 1039
1026 /* Unload the previously loaded binding. */ 1040 /* Unload the previously loaded binding. */
1027 Fsetcdr (XCAR (cdr), 1041 if (blv->fwd)
1028 do_symval_forwarding (blv->realvalue)); 1042 SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd));
1029 1043
1030 /* Select the global binding in the symbol. */ 1044 /* Select the global binding in the symbol. */
1031 XSETCAR (cdr, cdr); 1045 blv->valcell = blv->defcell;
1032 store_symval_forwarding (symbol, blv->realvalue, XCDR (cdr), NULL); 1046 if (blv->fwd)
1047 store_symval_forwarding (blv->fwd, XCDR (blv->defcell), NULL);
1033 1048
1034 /* Indicate that the global binding is set up now. */ 1049 /* Indicate that the global binding is set up now. */
1035 blv->frame = Qnil; 1050 blv->where = Qnil;
1036 blv->buffer = Qnil; 1051 SET_BLV_FOUND (blv, 0);
1037 blv->found_for_frame = 0;
1038 blv->found_for_buffer = 0;
1039} 1052}
1040 1053
1041/* Set up the buffer-local symbol SYMBOL for validity in the current buffer. 1054/* Set up the buffer-local symbol SYMBOL for validity in the current buffer.
@@ -1045,55 +1058,50 @@ swap_in_global_binding (symbol)
1045 Return the value forwarded one step past the buffer-local stage. 1058 Return the value forwarded one step past the buffer-local stage.
1046 This could be another forwarding pointer. */ 1059 This could be another forwarding pointer. */
1047 1060
1048static Lisp_Object 1061static void
1049swap_in_symval_forwarding (symbol, valcontents) 1062swap_in_symval_forwarding (symbol, blv)
1050 Lisp_Object symbol, valcontents; 1063 struct Lisp_Symbol *symbol;
1064 struct Lisp_Buffer_Local_Value *blv;
1051{ 1065{
1052 register Lisp_Object tem1; 1066 register Lisp_Object tem1;
1053 1067
1054 tem1 = XBUFFER_LOCAL_VALUE (valcontents)->buffer; 1068 eassert (blv == SYMBOL_BLV (symbol));
1069
1070 tem1 = blv->where;
1055 1071
1056 if (NILP (tem1) 1072 if (NILP (tem1)
1057 || current_buffer != XBUFFER (tem1) 1073 || (blv->frame_local
1058 || (XBUFFER_LOCAL_VALUE (valcontents)->check_frame 1074 ? !EQ (selected_frame, tem1)
1059 && ! EQ (selected_frame, XBUFFER_LOCAL_VALUE (valcontents)->frame))) 1075 : current_buffer != XBUFFER (tem1)))
1060 { 1076 {
1061 struct Lisp_Symbol *sym = XSYMBOL (symbol);
1062 if (sym->indirect_variable)
1063 {
1064 sym = indirect_variable (sym);
1065 XSETSYMBOL (symbol, sym);
1066 }
1067 1077
1068 /* Unload the previously loaded binding. */ 1078 /* Unload the previously loaded binding. */
1069 tem1 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); 1079 tem1 = blv->valcell;
1070 Fsetcdr (tem1, 1080 if (blv->fwd)
1071 do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue)); 1081 SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd));
1072 /* Choose the new binding. */ 1082 /* Choose the new binding. */
1073 tem1 = assq_no_quit (symbol, current_buffer->local_var_alist); 1083 {
1074 XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 0; 1084 Lisp_Object var;
1075 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0; 1085 XSETSYMBOL (var, symbol);
1076 if (NILP (tem1)) 1086 if (blv->frame_local)
1077 { 1087 {
1078 if (XBUFFER_LOCAL_VALUE (valcontents)->check_frame) 1088 tem1 = assq_no_quit (var, XFRAME (selected_frame)->param_alist);
1079 tem1 = assq_no_quit (symbol, XFRAME (selected_frame)->param_alist); 1089 blv->where = selected_frame;
1080 if (! NILP (tem1)) 1090 }
1081 XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 1; 1091 else
1082 else 1092 {
1083 tem1 = XBUFFER_LOCAL_VALUE (valcontents)->cdr; 1093 tem1 = assq_no_quit (var, current_buffer->local_var_alist);
1084 } 1094 XSETBUFFER (blv->where, current_buffer);
1085 else 1095 }
1086 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 1; 1096 }
1097 if (!(blv->found = !NILP (tem1)))
1098 tem1 = blv->defcell;
1087 1099
1088 /* Load the new binding. */ 1100 /* Load the new binding. */
1089 XSETCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, tem1); 1101 blv->valcell = tem1;
1090 XSETBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer, current_buffer); 1102 if (blv->fwd)
1091 XBUFFER_LOCAL_VALUE (valcontents)->frame = selected_frame; 1103 store_symval_forwarding (blv->fwd, BLV_VALUE (blv), NULL);
1092 store_symval_forwarding (symbol,
1093 XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
1094 Fcdr (tem1), NULL);
1095 } 1104 }
1096 return XBUFFER_LOCAL_VALUE (valcontents)->realvalue;
1097} 1105}
1098 1106
1099/* Find the value of a symbol, returning Qunbound if it's not bound. 1107/* Find the value of a symbol, returning Qunbound if it's not bound.
@@ -1106,16 +1114,27 @@ Lisp_Object
1106find_symbol_value (symbol) 1114find_symbol_value (symbol)
1107 Lisp_Object symbol; 1115 Lisp_Object symbol;
1108{ 1116{
1109 register Lisp_Object valcontents; 1117 struct Lisp_Symbol *sym;
1110 register Lisp_Object val;
1111 1118
1112 CHECK_SYMBOL (symbol); 1119 CHECK_SYMBOL (symbol);
1113 valcontents = SYMBOL_VALUE (symbol); 1120 sym = XSYMBOL (symbol);
1114
1115 if (BUFFER_LOCAL_VALUEP (valcontents))
1116 valcontents = swap_in_symval_forwarding (symbol, valcontents);
1117 1121
1118 return do_symval_forwarding (valcontents); 1122 start:
1123 switch (sym->redirect)
1124 {
1125 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1126 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym);
1127 case SYMBOL_LOCALIZED:
1128 {
1129 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1130 swap_in_symval_forwarding (sym, blv);
1131 return blv->fwd ? do_symval_forwarding (blv->fwd) : BLV_VALUE (blv);
1132 }
1133 /* FALLTHROUGH */
1134 case SYMBOL_FORWARDED:
1135 return do_symval_forwarding (SYMBOL_FWD (sym));
1136 default: abort ();
1137 }
1119} 1138}
1120 1139
1121DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0, 1140DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0,
@@ -1137,26 +1156,25 @@ DEFUN ("set", Fset, Sset, 2, 2, 0,
1137 (symbol, newval) 1156 (symbol, newval)
1138 register Lisp_Object symbol, newval; 1157 register Lisp_Object symbol, newval;
1139{ 1158{
1140 return set_internal (symbol, newval, current_buffer, 0); 1159 set_internal (symbol, newval, current_buffer, 0);
1160 return newval;
1141} 1161}
1142 1162
1143/* Return 1 if SYMBOL currently has a let-binding 1163/* Return 1 if SYMBOL currently has a let-binding
1144 which was made in the buffer that is now current. */ 1164 which was made in the buffer that is now current. */
1145 1165
1146static int 1166static int
1147let_shadows_buffer_binding_p (symbol) 1167let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol)
1148 struct Lisp_Symbol *symbol;
1149{ 1168{
1150 volatile struct specbinding *p; 1169 struct specbinding *p;
1151 1170
1152 for (p = specpdl_ptr - 1; p >= specpdl; p--) 1171 for (p = specpdl_ptr - 1; p >= specpdl; p--)
1153 if (p->func == NULL 1172 if (p->func == NULL
1154 && CONSP (p->symbol)) 1173 && CONSP (p->symbol))
1155 { 1174 {
1156 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (XCAR (p->symbol)); 1175 struct Lisp_Symbol *let_bound_symbol = XSYMBOL (XCAR (p->symbol));
1157 if ((symbol == let_bound_symbol 1176 eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS);
1158 || (let_bound_symbol->indirect_variable 1177 if (symbol == let_bound_symbol
1159 && symbol == indirect_variable (let_bound_symbol)))
1160 && XBUFFER (XCDR (XCDR (p->symbol))) == current_buffer) 1178 && XBUFFER (XCDR (XCDR (p->symbol))) == current_buffer)
1161 break; 1179 break;
1162 } 1180 }
@@ -1164,6 +1182,19 @@ let_shadows_buffer_binding_p (symbol)
1164 return p >= specpdl; 1182 return p >= specpdl;
1165} 1183}
1166 1184
1185static int
1186let_shadows_global_binding_p (symbol)
1187 Lisp_Object symbol;
1188{
1189 struct specbinding *p;
1190
1191 for (p = specpdl_ptr - 1; p >= specpdl; p--)
1192 if (p->func == NULL && EQ (p->symbol, symbol))
1193 break;
1194
1195 return p >= specpdl;
1196}
1197
1167/* Store the value NEWVAL into SYMBOL. 1198/* Store the value NEWVAL into SYMBOL.
1168 If buffer-locality is an issue, BUF specifies which buffer to use. 1199 If buffer-locality is an issue, BUF specifies which buffer to use.
1169 (0 stands for the current buffer.) 1200 (0 stands for the current buffer.)
@@ -1172,133 +1203,155 @@ let_shadows_buffer_binding_p (symbol)
1172 local in every buffer where it is set, then we make it local. 1203 local in every buffer where it is set, then we make it local.
1173 If BINDFLAG is nonzero, we don't do that. */ 1204 If BINDFLAG is nonzero, we don't do that. */
1174 1205
1175Lisp_Object 1206void
1176set_internal (symbol, newval, buf, bindflag) 1207set_internal (symbol, newval, buf, bindflag)
1177 register Lisp_Object symbol, newval; 1208 register Lisp_Object symbol, newval;
1178 struct buffer *buf; 1209 struct buffer *buf;
1179 int bindflag; 1210 int bindflag;
1180{ 1211{
1181 int voide = EQ (newval, Qunbound); 1212 int voide = EQ (newval, Qunbound);
1182 1213 struct Lisp_Symbol *sym;
1183 register Lisp_Object valcontents, innercontents, tem1, current_alist_element; 1214 Lisp_Object tem1;
1184 1215
1185 if (buf == 0) 1216 if (buf == 0)
1186 buf = current_buffer; 1217 buf = current_buffer;
1187 1218
1188 /* If restoring in a dead buffer, do nothing. */ 1219 /* If restoring in a dead buffer, do nothing. */
1189 if (NILP (buf->name)) 1220 if (NILP (buf->name))
1190 return newval; 1221 return;
1191 1222
1192 CHECK_SYMBOL (symbol); 1223 CHECK_SYMBOL (symbol);
1193 if (SYMBOL_CONSTANT_P (symbol) 1224 if (SYMBOL_CONSTANT_P (symbol))
1194 && (NILP (Fkeywordp (symbol))
1195 || !EQ (newval, SYMBOL_VALUE (symbol))))
1196 xsignal1 (Qsetting_constant, symbol);
1197
1198 innercontents = valcontents = SYMBOL_VALUE (symbol);
1199
1200 if (BUFFER_OBJFWDP (valcontents))
1201 { 1225 {
1202 int offset = XBUFFER_OBJFWD (valcontents)->offset; 1226 if (NILP (Fkeywordp (symbol))
1203 int idx = PER_BUFFER_IDX (offset); 1227 || !EQ (newval, Fsymbol_value (symbol)))
1204 if (idx > 0 1228 xsignal1 (Qsetting_constant, symbol);
1205 && !bindflag 1229 else
1206 && !let_shadows_buffer_binding_p (XSYMBOL (symbol))) 1230 /* Allow setting keywords to their own value. */
1207 SET_PER_BUFFER_VALUE_P (buf, idx, 1); 1231 return;
1208 } 1232 }
1209 else if (BUFFER_LOCAL_VALUEP (valcontents))
1210 {
1211 /* valcontents is a struct Lisp_Buffer_Local_Value. */
1212 if (XSYMBOL (symbol)->indirect_variable)
1213 XSETSYMBOL (symbol, indirect_variable (XSYMBOL (symbol)));
1214
1215 /* What binding is loaded right now? */
1216 current_alist_element
1217 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
1218
1219 /* If the current buffer is not the buffer whose binding is
1220 loaded, or if there may be frame-local bindings and the frame
1221 isn't the right one, or if it's a Lisp_Buffer_Local_Value and
1222 the default binding is loaded, the loaded binding may be the
1223 wrong one. */
1224 if (!BUFFERP (XBUFFER_LOCAL_VALUE (valcontents)->buffer)
1225 || buf != XBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer)
1226 || (XBUFFER_LOCAL_VALUE (valcontents)->check_frame
1227 && !EQ (selected_frame, XBUFFER_LOCAL_VALUE (valcontents)->frame))
1228 /* Also unload a global binding (if the var is local_if_set). */
1229 || (EQ (XCAR (current_alist_element),
1230 current_alist_element)))
1231 {
1232 /* The currently loaded binding is not necessarily valid.
1233 We need to unload it, and choose a new binding. */
1234 1233
1235 /* Write out `realvalue' to the old loaded binding. */ 1234 sym = XSYMBOL (symbol);
1236 Fsetcdr (current_alist_element,
1237 do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue));
1238 1235
1239 /* Find the new binding. */ 1236 start:
1240 tem1 = Fassq (symbol, buf->local_var_alist); 1237 switch (sym->redirect)
1241 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 1; 1238 {
1242 XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 0; 1239 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1240 case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return;
1241 case SYMBOL_LOCALIZED:
1242 {
1243 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1244 Lisp_Object tmp; XSETBUFFER (tmp, buf);
1245
1246 /* If the current buffer is not the buffer whose binding is
1247 loaded, or if there may be frame-local bindings and the frame
1248 isn't the right one, or if it's a Lisp_Buffer_Local_Value and
1249 the default binding is loaded, the loaded binding may be the
1250 wrong one. */
1251 if (!EQ (blv->where,
1252 blv->frame_local ? selected_frame : tmp)
1253 /* Also unload a global binding (if the var is local_if_set). */
1254 || (EQ (blv->valcell, blv->defcell)))
1255 {
1256 /* The currently loaded binding is not necessarily valid.
1257 We need to unload it, and choose a new binding. */
1258
1259 /* Write out `realvalue' to the old loaded binding. */
1260 if (blv->fwd)
1261 SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd));
1243 1262
1244 if (NILP (tem1)) 1263 /* Find the new binding. */
1245 { 1264 {
1246 /* This buffer still sees the default value. */ 1265 XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */
1247 1266 if (blv->frame_local)
1248 /* If the variable is not local_if_set,
1249 or if this is `let' rather than `set',
1250 make CURRENT-ALIST-ELEMENT point to itself,
1251 indicating that we're seeing the default value.
1252 Likewise if the variable has been let-bound
1253 in the current buffer. */
1254 if (bindflag || !XBUFFER_LOCAL_VALUE (valcontents)->local_if_set
1255 || let_shadows_buffer_binding_p (XSYMBOL (symbol)))
1256 { 1267 {
1257 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0; 1268 tem1 = Fassq (symbol, XFRAME (selected_frame)->param_alist);
1258 1269 blv->where = selected_frame;
1259 if (XBUFFER_LOCAL_VALUE (valcontents)->check_frame)
1260 tem1 = Fassq (symbol,
1261 XFRAME (selected_frame)->param_alist);
1262
1263 if (! NILP (tem1))
1264 XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 1;
1265 else
1266 tem1 = XBUFFER_LOCAL_VALUE (valcontents)->cdr;
1267 } 1270 }
1268 /* If it's a Lisp_Buffer_Local_Value, being set not bound,
1269 and we're not within a let that was made for this buffer,
1270 create a new buffer-local binding for the variable.
1271 That means, give this buffer a new assoc for a local value
1272 and load that binding. */
1273 else 1271 else
1274 { 1272 {
1275 tem1 = Fcons (symbol, XCDR (current_alist_element)); 1273 tem1 = Fassq (symbol, buf->local_var_alist);
1276 buf->local_var_alist 1274 blv->where = tmp;
1277 = Fcons (tem1, buf->local_var_alist);
1278 } 1275 }
1279 } 1276 }
1277 blv->found = 1;
1278
1279 if (NILP (tem1))
1280 {
1281 /* This buffer still sees the default value. */
1282
1283 /* If the variable is a Lisp_Some_Buffer_Local_Value,
1284 or if this is `let' rather than `set',
1285 make CURRENT-ALIST-ELEMENT point to itself,
1286 indicating that we're seeing the default value.
1287 Likewise if the variable has been let-bound
1288 in the current buffer. */
1289 if (bindflag || !blv->local_if_set
1290 || let_shadows_buffer_binding_p (sym))
1291 {
1292 blv->found = 0;
1293 tem1 = blv->defcell;
1294 }
1295 /* If it's a local_if_set, being set not bound,
1296 and we're not within a let that was made for this buffer,
1297 create a new buffer-local binding for the variable.
1298 That means, give this buffer a new assoc for a local value
1299 and load that binding. */
1300 else
1301 {
1302 /* local_if_set is only supported for buffer-local
1303 bindings, not for frame-local bindings. */
1304 eassert (!blv->frame_local);
1305 tem1 = Fcons (symbol, XCDR (blv->defcell));
1306 buf->local_var_alist
1307 = Fcons (tem1, buf->local_var_alist);
1308 }
1309 }
1310
1311 /* Record which binding is now loaded. */
1312 blv->valcell = tem1;
1313 }
1280 1314
1281 /* Record which binding is now loaded. */ 1315 /* Store the new value in the cons cell. */
1282 XSETCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, tem1); 1316 SET_BLV_VALUE (blv, newval);
1283 1317
1284 /* Set `buffer' and `frame' slots for the binding now loaded. */ 1318 if (blv->fwd)
1285 XSETBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer, buf); 1319 {
1286 XBUFFER_LOCAL_VALUE (valcontents)->frame = selected_frame; 1320 if (voide)
1287 } 1321 /* If storing void (making the symbol void), forward only through
1288 innercontents = XBUFFER_LOCAL_VALUE (valcontents)->realvalue; 1322 buffer-local indicator, not through Lisp_Objfwd, etc. */
1323 blv->fwd = NULL;
1324 else
1325 store_symval_forwarding (blv->fwd, newval, buf);
1326 }
1327 break;
1328 }
1329 case SYMBOL_FORWARDED:
1330 {
1331 union Lisp_Fwd *innercontents = SYMBOL_FWD (sym);
1332 if (BUFFER_OBJFWDP (innercontents))
1333 {
1334 int offset = XBUFFER_OBJFWD (innercontents)->offset;
1335 int idx = PER_BUFFER_IDX (offset);
1336 if (idx > 0
1337 && !bindflag
1338 && !let_shadows_buffer_binding_p (sym))
1339 SET_PER_BUFFER_VALUE_P (buf, idx, 1);
1340 }
1289 1341
1290 /* Store the new value in the cons-cell. */ 1342 if (voide)
1291 XSETCDR (XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr), newval); 1343 { /* If storing void (making the symbol void), forward only through
1344 buffer-local indicator, not through Lisp_Objfwd, etc. */
1345 sym->redirect = SYMBOL_PLAINVAL;
1346 SET_SYMBOL_VAL (sym, newval);
1347 }
1348 else
1349 store_symval_forwarding (/* sym, */ innercontents, newval, buf);
1350 break;
1351 }
1352 default: abort ();
1292 } 1353 }
1293 1354 return;
1294 /* If storing void (making the symbol void), forward only through
1295 buffer-local indicator, not through Lisp_Objfwd, etc. */
1296 if (voide)
1297 store_symval_forwarding (symbol, Qnil, newval, buf);
1298 else
1299 store_symval_forwarding (symbol, innercontents, newval, buf);
1300
1301 return newval;
1302} 1355}
1303 1356
1304/* Access or set a buffer-local symbol's default value. */ 1357/* Access or set a buffer-local symbol's default value. */
@@ -1310,38 +1363,46 @@ Lisp_Object
1310default_value (symbol) 1363default_value (symbol)
1311 Lisp_Object symbol; 1364 Lisp_Object symbol;
1312{ 1365{
1313 register Lisp_Object valcontents; 1366 struct Lisp_Symbol *sym;
1314 1367
1315 CHECK_SYMBOL (symbol); 1368 CHECK_SYMBOL (symbol);
1316 valcontents = SYMBOL_VALUE (symbol); 1369 sym = XSYMBOL (symbol);
1317 1370
1318 /* For a built-in buffer-local variable, get the default value 1371 start:
1319 rather than letting do_symval_forwarding get the current value. */ 1372 switch (sym->redirect)
1320 if (BUFFER_OBJFWDP (valcontents))
1321 { 1373 {
1322 int offset = XBUFFER_OBJFWD (valcontents)->offset; 1374 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1323 if (PER_BUFFER_IDX (offset) != 0) 1375 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym);
1324 return PER_BUFFER_DEFAULT (offset); 1376 case SYMBOL_LOCALIZED:
1325 } 1377 {
1378 /* If var is set up for a buffer that lacks a local value for it,
1379 the current value is nominally the default value.
1380 But the `realvalue' slot may be more up to date, since
1381 ordinary setq stores just that slot. So use that. */
1382 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1383 if (blv->fwd && EQ (blv->valcell, blv->defcell))
1384 return do_symval_forwarding (blv->fwd);
1385 else
1386 return XCDR (blv->defcell);
1387 }
1388 case SYMBOL_FORWARDED:
1389 {
1390 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
1326 1391
1327 /* Handle user-created local variables. */ 1392 /* For a built-in buffer-local variable, get the default value
1328 if (BUFFER_LOCAL_VALUEP (valcontents)) 1393 rather than letting do_symval_forwarding get the current value. */
1329 { 1394 if (BUFFER_OBJFWDP (valcontents))
1330 /* If var is set up for a buffer that lacks a local value for it, 1395 {
1331 the current value is nominally the default value. 1396 int offset = XBUFFER_OBJFWD (valcontents)->offset;
1332 But the `realvalue' slot may be more up to date, since 1397 if (PER_BUFFER_IDX (offset) != 0)
1333 ordinary setq stores just that slot. So use that. */ 1398 return PER_BUFFER_DEFAULT (offset);
1334 Lisp_Object current_alist_element, alist_element_car; 1399 }
1335 current_alist_element 1400
1336 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); 1401 /* For other variables, get the current value. */
1337 alist_element_car = XCAR (current_alist_element); 1402 return do_symval_forwarding (valcontents);
1338 if (EQ (alist_element_car, current_alist_element)) 1403 }
1339 return do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue); 1404 default: abort ();
1340 else
1341 return XCDR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
1342 } 1405 }
1343 /* For other variables, get the current value. */
1344 return do_symval_forwarding (valcontents);
1345} 1406}
1346 1407
1347DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0, 1408DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0,
@@ -1381,50 +1442,68 @@ for this variable. */)
1381 (symbol, value) 1442 (symbol, value)
1382 Lisp_Object symbol, value; 1443 Lisp_Object symbol, value;
1383{ 1444{
1384 register Lisp_Object valcontents, current_alist_element, alist_element_buffer; 1445 struct Lisp_Symbol *sym;
1385 1446
1386 CHECK_SYMBOL (symbol); 1447 CHECK_SYMBOL (symbol);
1387 valcontents = SYMBOL_VALUE (symbol); 1448 if (SYMBOL_CONSTANT_P (symbol))
1388
1389 /* Handle variables like case-fold-search that have special slots
1390 in the buffer. Make them work apparently like Lisp_Buffer_Local_Value
1391 variables. */
1392 if (BUFFER_OBJFWDP (valcontents))
1393 { 1449 {
1394 int offset = XBUFFER_OBJFWD (valcontents)->offset; 1450 if (NILP (Fkeywordp (symbol))
1395 int idx = PER_BUFFER_IDX (offset); 1451 || !EQ (value, Fdefault_value (symbol)))
1452 xsignal1 (Qsetting_constant, symbol);
1453 else
1454 /* Allow setting keywords to their own value. */
1455 return value;
1456 }
1457 sym = XSYMBOL (symbol);
1396 1458
1397 PER_BUFFER_DEFAULT (offset) = value; 1459 start:
1460 switch (sym->redirect)
1461 {
1462 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1463 case SYMBOL_PLAINVAL: return Fset (symbol, value);
1464 case SYMBOL_LOCALIZED:
1465 {
1466 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1398 1467
1399 /* If this variable is not always local in all buffers, 1468 /* Store new value into the DEFAULT-VALUE slot. */
1400 set it in the buffers that don't nominally have a local value. */ 1469 XSETCDR (blv->defcell, value);
1401 if (idx > 0)
1402 {
1403 struct buffer *b;
1404 1470
1405 for (b = all_buffers; b; b = b->next) 1471 /* If the default binding is now loaded, set the REALVALUE slot too. */
1406 if (!PER_BUFFER_VALUE_P (b, idx)) 1472 if (blv->fwd && EQ (blv->defcell, blv->valcell))
1407 PER_BUFFER_VALUE (b, offset) = value; 1473 store_symval_forwarding (blv->fwd, value, NULL);
1408 } 1474 return value;
1409 return value; 1475 }
1410 } 1476 case SYMBOL_FORWARDED:
1477 {
1478 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
1411 1479
1412 if (!BUFFER_LOCAL_VALUEP (valcontents)) 1480 /* Handle variables like case-fold-search that have special slots
1413 return Fset (symbol, value); 1481 in the buffer.
1482 Make them work apparently like Lisp_Buffer_Local_Value variables. */
1483 if (BUFFER_OBJFWDP (valcontents))
1484 {
1485 int offset = XBUFFER_OBJFWD (valcontents)->offset;
1486 int idx = PER_BUFFER_IDX (offset);
1414 1487
1415 /* Store new value into the DEFAULT-VALUE slot. */ 1488 PER_BUFFER_DEFAULT (offset) = value;
1416 XSETCDR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, value);
1417 1489
1418 /* If the default binding is now loaded, set the REALVALUE slot too. */ 1490 /* If this variable is not always local in all buffers,
1419 current_alist_element 1491 set it in the buffers that don't nominally have a local value. */
1420 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr); 1492 if (idx > 0)
1421 alist_element_buffer = Fcar (current_alist_element); 1493 {
1422 if (EQ (alist_element_buffer, current_alist_element)) 1494 struct buffer *b;
1423 store_symval_forwarding (symbol,
1424 XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
1425 value, NULL);
1426 1495
1427 return value; 1496 for (b = all_buffers; b; b = b->next)
1497 if (!PER_BUFFER_VALUE_P (b, idx))
1498 PER_BUFFER_VALUE (b, offset) = value;
1499 }
1500 return value;
1501 }
1502 else
1503 return Fset (symbol, value);
1504 }
1505 default: abort ();
1506 }
1428} 1507}
1429 1508
1430DEFUN ("setq-default", Fsetq_default, Ssetq_default, 0, UNEVALLED, 0, 1509DEFUN ("setq-default", Fsetq_default, Ssetq_default, 0, UNEVALLED, 0,
@@ -1468,6 +1547,35 @@ usage: (setq-default [VAR VALUE]...) */)
1468 1547
1469/* Lisp functions for creating and removing buffer-local variables. */ 1548/* Lisp functions for creating and removing buffer-local variables. */
1470 1549
1550union Lisp_Val_Fwd
1551 {
1552 Lisp_Object value;
1553 union Lisp_Fwd *fwd;
1554 };
1555
1556static struct Lisp_Buffer_Local_Value *
1557make_blv (struct Lisp_Symbol *sym, int forwarded, union Lisp_Val_Fwd valcontents)
1558{
1559 struct Lisp_Buffer_Local_Value *blv
1560 = xmalloc (sizeof (struct Lisp_Buffer_Local_Value));
1561 Lisp_Object symbol; XSETSYMBOL (symbol, sym);
1562 Lisp_Object tem = Fcons (symbol, (forwarded
1563 ? do_symval_forwarding (valcontents.fwd)
1564 : valcontents.value));
1565 /* Buffer_Local_Values cannot have as realval a buffer-local
1566 or keyboard-local forwarding. */
1567 eassert (!(forwarded && BUFFER_OBJFWDP (valcontents.fwd)));
1568 eassert (!(forwarded && KBOARD_OBJFWDP (valcontents.fwd)));
1569 blv->fwd = forwarded ? valcontents.fwd : NULL;
1570 blv->where = Qnil;
1571 blv->frame_local = 0;
1572 blv->local_if_set = 0;
1573 blv->defcell = tem;
1574 blv->valcell = tem;
1575 SET_BLV_FOUND (blv, 0);
1576 return blv;
1577}
1578
1471DEFUN ("make-variable-buffer-local", Fmake_variable_buffer_local, Smake_variable_buffer_local, 1579DEFUN ("make-variable-buffer-local", Fmake_variable_buffer_local, Smake_variable_buffer_local,
1472 1, 1, "vMake Variable Buffer Local: ", 1580 1, 1, "vMake Variable Buffer Local: ",
1473 doc: /* Make VARIABLE become buffer-local whenever it is set. 1581 doc: /* Make VARIABLE become buffer-local whenever it is set.
@@ -1485,42 +1593,58 @@ The function `default-value' gets the default value and `set-default' sets it.
1485 (variable) 1593 (variable)
1486 register Lisp_Object variable; 1594 register Lisp_Object variable;
1487{ 1595{
1488 register Lisp_Object tem, valcontents, newval;
1489 struct Lisp_Symbol *sym; 1596 struct Lisp_Symbol *sym;
1597 struct Lisp_Buffer_Local_Value *blv = NULL;
1598 union Lisp_Val_Fwd valcontents;
1599 int forwarded;
1490 1600
1491 CHECK_SYMBOL (variable); 1601 CHECK_SYMBOL (variable);
1492 sym = indirect_variable (XSYMBOL (variable)); 1602 sym = XSYMBOL (variable);
1493
1494 valcontents = sym->value;
1495 if (sym->constant || KBOARD_OBJFWDP (valcontents))
1496 error ("Symbol %s may not be buffer-local", SDATA (sym->xname));
1497 1603
1498 if (BUFFER_OBJFWDP (valcontents)) 1604 start:
1499 return variable; 1605 switch (sym->redirect)
1500 else if (BUFFER_LOCAL_VALUEP (valcontents))
1501 { 1606 {
1502 if (XBUFFER_LOCAL_VALUE (valcontents)->check_frame) 1607 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1503 error ("Symbol %s may not be buffer-local", SDATA (sym->xname)); 1608 case SYMBOL_PLAINVAL:
1504 newval = valcontents; 1609 forwarded = 0; valcontents.value = SYMBOL_VAL (sym);
1610 if (EQ (valcontents.value, Qunbound))
1611 valcontents.value = Qnil;
1612 break;
1613 case SYMBOL_LOCALIZED:
1614 blv = SYMBOL_BLV (sym);
1615 if (blv->frame_local)
1616 error ("Symbol %s may not be buffer-local",
1617 SDATA (SYMBOL_NAME (variable)));
1618 break;
1619 case SYMBOL_FORWARDED:
1620 forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym);
1621 if (KBOARD_OBJFWDP (valcontents.fwd))
1622 error ("Symbol %s may not be buffer-local",
1623 SDATA (SYMBOL_NAME (variable)));
1624 else if (BUFFER_OBJFWDP (valcontents.fwd))
1625 return variable;
1626 break;
1627 default: abort ();
1505 } 1628 }
1506 else 1629
1630 if (sym->constant)
1631 error ("Symbol %s may not be buffer-local", SDATA (SYMBOL_NAME (variable)));
1632
1633 if (!blv)
1507 { 1634 {
1508 if (EQ (valcontents, Qunbound)) 1635 blv = make_blv (sym, forwarded, valcontents);
1509 sym->value = Qnil; 1636 sym->redirect = SYMBOL_LOCALIZED;
1510 tem = Fcons (Qnil, Fsymbol_value (variable)); 1637 SET_SYMBOL_BLV (sym, blv);
1511 XSETCAR (tem, tem); 1638 {
1512 newval = allocate_misc (); 1639 Lisp_Object symbol;
1513 XMISCTYPE (newval) = Lisp_Misc_Buffer_Local_Value; 1640 XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */
1514 XBUFFER_LOCAL_VALUE (newval)->realvalue = sym->value; 1641 if (let_shadows_global_binding_p (symbol))
1515 XBUFFER_LOCAL_VALUE (newval)->buffer = Fcurrent_buffer (); 1642 error ("Making %s buffer-local while let-bound!",
1516 XBUFFER_LOCAL_VALUE (newval)->frame = Qnil; 1643 SDATA (SYMBOL_NAME (variable)));
1517 XBUFFER_LOCAL_VALUE (newval)->found_for_buffer = 0; 1644 }
1518 XBUFFER_LOCAL_VALUE (newval)->found_for_frame = 0;
1519 XBUFFER_LOCAL_VALUE (newval)->check_frame = 0;
1520 XBUFFER_LOCAL_VALUE (newval)->cdr = tem;
1521 sym->value = newval;
1522 } 1645 }
1523 XBUFFER_LOCAL_VALUE (newval)->local_if_set = 1; 1646
1647 blv->local_if_set = 1;
1524 return variable; 1648 return variable;
1525} 1649}
1526 1650
@@ -1547,82 +1671,95 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
1547 (variable) 1671 (variable)
1548 register Lisp_Object variable; 1672 register Lisp_Object variable;
1549{ 1673{
1550 register Lisp_Object tem, valcontents; 1674 register Lisp_Object tem;
1675 int forwarded;
1676 union Lisp_Val_Fwd valcontents;
1551 struct Lisp_Symbol *sym; 1677 struct Lisp_Symbol *sym;
1678 struct Lisp_Buffer_Local_Value *blv = NULL;
1552 1679
1553 CHECK_SYMBOL (variable); 1680 CHECK_SYMBOL (variable);
1554 sym = indirect_variable (XSYMBOL (variable)); 1681 sym = XSYMBOL (variable);
1555 1682
1556 valcontents = sym->value; 1683 start:
1557 if (sym->constant || KBOARD_OBJFWDP (valcontents) 1684 switch (sym->redirect)
1558 || (BUFFER_LOCAL_VALUEP (valcontents) 1685 {
1559 && (XBUFFER_LOCAL_VALUE (valcontents)->check_frame))) 1686 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1560 error ("Symbol %s may not be buffer-local", SDATA (sym->xname)); 1687 case SYMBOL_PLAINVAL:
1688 forwarded = 0; valcontents.value = SYMBOL_VAL (sym); break;
1689 case SYMBOL_LOCALIZED:
1690 blv = SYMBOL_BLV (sym);
1691 if (blv->frame_local)
1692 error ("Symbol %s may not be buffer-local",
1693 SDATA (SYMBOL_NAME (variable)));
1694 break;
1695 case SYMBOL_FORWARDED:
1696 forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym);
1697 if (KBOARD_OBJFWDP (valcontents.fwd))
1698 error ("Symbol %s may not be buffer-local",
1699 SDATA (SYMBOL_NAME (variable)));
1700 break;
1701 default: abort ();
1702 }
1561 1703
1562 if ((BUFFER_LOCAL_VALUEP (valcontents) 1704 if (sym->constant)
1563 && XBUFFER_LOCAL_VALUE (valcontents)->local_if_set) 1705 error ("Symbol %s may not be buffer-local", SDATA (SYMBOL_NAME (variable)));
1564 || BUFFER_OBJFWDP (valcontents)) 1706
1707 if (blv ? blv->local_if_set
1708 : (forwarded && BUFFER_OBJFWDP (valcontents.fwd)))
1565 { 1709 {
1566 tem = Fboundp (variable); 1710 tem = Fboundp (variable);
1567
1568 /* Make sure the symbol has a local value in this particular buffer, 1711 /* Make sure the symbol has a local value in this particular buffer,
1569 by setting it to the same value it already has. */ 1712 by setting it to the same value it already has. */
1570 Fset (variable, (EQ (tem, Qt) ? Fsymbol_value (variable) : Qunbound)); 1713 Fset (variable, (EQ (tem, Qt) ? Fsymbol_value (variable) : Qunbound));
1571 return variable; 1714 return variable;
1572 } 1715 }
1573 /* Make sure symbol is set up to hold per-buffer values. */ 1716 if (!blv)
1574 if (!BUFFER_LOCAL_VALUEP (valcontents))
1575 { 1717 {
1576 Lisp_Object newval; 1718 blv = make_blv (sym, forwarded, valcontents);
1577 tem = Fcons (Qnil, do_symval_forwarding (valcontents)); 1719 sym->redirect = SYMBOL_LOCALIZED;
1578 XSETCAR (tem, tem); 1720 SET_SYMBOL_BLV (sym, blv);
1579 newval = allocate_misc (); 1721 {
1580 XMISCTYPE (newval) = Lisp_Misc_Buffer_Local_Value; 1722 Lisp_Object symbol;
1581 XBUFFER_LOCAL_VALUE (newval)->realvalue = sym->value; 1723 XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */
1582 XBUFFER_LOCAL_VALUE (newval)->buffer = Qnil; 1724 if (let_shadows_global_binding_p (symbol))
1583 XBUFFER_LOCAL_VALUE (newval)->frame = Qnil; 1725 error ("Making %s local to %s while let-bound!",
1584 XBUFFER_LOCAL_VALUE (newval)->local_if_set = 0; 1726 SDATA (SYMBOL_NAME (variable)), SDATA (current_buffer->name));
1585 XBUFFER_LOCAL_VALUE (newval)->found_for_buffer = 0; 1727 }
1586 XBUFFER_LOCAL_VALUE (newval)->found_for_frame = 0;
1587 XBUFFER_LOCAL_VALUE (newval)->check_frame = 0;
1588 XBUFFER_LOCAL_VALUE (newval)->cdr = tem;
1589 sym->value = newval;
1590 } 1728 }
1729
1591 /* Make sure this buffer has its own value of symbol. */ 1730 /* Make sure this buffer has its own value of symbol. */
1592 XSETSYMBOL (variable, sym); /* Propagate variable indirections. */ 1731 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
1593 tem = Fassq (variable, current_buffer->local_var_alist); 1732 tem = Fassq (variable, current_buffer->local_var_alist);
1594 if (NILP (tem)) 1733 if (NILP (tem))
1595 { 1734 {
1735 if (let_shadows_buffer_binding_p (sym))
1736 message ("Making %s buffer-local while locally let-bound!",
1737 SDATA (SYMBOL_NAME (variable)));
1738
1596 /* Swap out any local binding for some other buffer, and make 1739 /* Swap out any local binding for some other buffer, and make
1597 sure the current value is permanently recorded, if it's the 1740 sure the current value is permanently recorded, if it's the
1598 default value. */ 1741 default value. */
1599 find_symbol_value (variable); 1742 find_symbol_value (variable);
1600 1743
1601 current_buffer->local_var_alist 1744 current_buffer->local_var_alist
1602 = Fcons (Fcons (variable, XCDR (XBUFFER_LOCAL_VALUE (sym->value)->cdr)), 1745 = Fcons (Fcons (variable, XCDR (blv->defcell)),
1603 current_buffer->local_var_alist); 1746 current_buffer->local_var_alist);
1604 1747
1605 /* Make sure symbol does not think it is set up for this buffer; 1748 /* Make sure symbol does not think it is set up for this buffer;
1606 force it to look once again for this buffer's value. */ 1749 force it to look once again for this buffer's value. */
1607 { 1750 if (current_buffer == XBUFFER (blv->where))
1608 Lisp_Object *pvalbuf; 1751 blv->where = Qnil;
1609 1752 /* blv->valcell = blv->defcell;
1610 valcontents = sym->value; 1753 * SET_BLV_FOUND (blv, 0); */
1611 1754 blv->found = 0;
1612 pvalbuf = &XBUFFER_LOCAL_VALUE (valcontents)->buffer;
1613 if (current_buffer == XBUFFER (*pvalbuf))
1614 *pvalbuf = Qnil;
1615 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0;
1616 }
1617 } 1755 }
1618 1756
1619 /* If the symbol forwards into a C variable, then load the binding 1757 /* If the symbol forwards into a C variable, then load the binding
1620 for this buffer now. If C code modifies the variable before we 1758 for this buffer now. If C code modifies the variable before we
1621 load the binding in, then that new value will clobber the default 1759 load the binding in, then that new value will clobber the default
1622 binding the next time we unload it. */ 1760 binding the next time we unload it. */
1623 valcontents = XBUFFER_LOCAL_VALUE (sym->value)->realvalue; 1761 if (blv->fwd)
1624 if (INTFWDP (valcontents) || BOOLFWDP (valcontents) || OBJFWDP (valcontents)) 1762 swap_in_symval_forwarding (sym, blv);
1625 swap_in_symval_forwarding (variable, sym->value);
1626 1763
1627 return variable; 1764 return variable;
1628} 1765}
@@ -1634,31 +1771,43 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
1634 (variable) 1771 (variable)
1635 register Lisp_Object variable; 1772 register Lisp_Object variable;
1636{ 1773{
1637 register Lisp_Object tem, valcontents; 1774 register Lisp_Object tem;
1775 struct Lisp_Buffer_Local_Value *blv;
1638 struct Lisp_Symbol *sym; 1776 struct Lisp_Symbol *sym;
1639 1777
1640 CHECK_SYMBOL (variable); 1778 CHECK_SYMBOL (variable);
1641 sym = indirect_variable (XSYMBOL (variable)); 1779 sym = XSYMBOL (variable);
1642
1643 valcontents = sym->value;
1644 1780
1645 if (BUFFER_OBJFWDP (valcontents)) 1781 start:
1782 switch (sym->redirect)
1646 { 1783 {
1647 int offset = XBUFFER_OBJFWD (valcontents)->offset; 1784 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1648 int idx = PER_BUFFER_IDX (offset); 1785 case SYMBOL_PLAINVAL: return variable;
1649 1786 case SYMBOL_FORWARDED:
1650 if (idx > 0) 1787 {
1651 { 1788 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
1652 SET_PER_BUFFER_VALUE_P (current_buffer, idx, 0); 1789 if (BUFFER_OBJFWDP (valcontents))
1653 PER_BUFFER_VALUE (current_buffer, offset) 1790 {
1654 = PER_BUFFER_DEFAULT (offset); 1791 int offset = XBUFFER_OBJFWD (valcontents)->offset;
1655 } 1792 int idx = PER_BUFFER_IDX (offset);
1656 return variable; 1793
1794 if (idx > 0)
1795 {
1796 SET_PER_BUFFER_VALUE_P (current_buffer, idx, 0);
1797 PER_BUFFER_VALUE (current_buffer, offset)
1798 = PER_BUFFER_DEFAULT (offset);
1799 }
1800 }
1801 return variable;
1802 }
1803 case SYMBOL_LOCALIZED:
1804 blv = SYMBOL_BLV (sym);
1805 if (blv->frame_local)
1806 return variable;
1807 break;
1808 default: abort ();
1657 } 1809 }
1658 1810
1659 if (!BUFFER_LOCAL_VALUEP (valcontents))
1660 return variable;
1661
1662 /* Get rid of this buffer's alist element, if any. */ 1811 /* Get rid of this buffer's alist element, if any. */
1663 XSETSYMBOL (variable, sym); /* Propagate variable indirection. */ 1812 XSETSYMBOL (variable, sym); /* Propagate variable indirection. */
1664 tem = Fassq (variable, current_buffer->local_var_alist); 1813 tem = Fassq (variable, current_buffer->local_var_alist);
@@ -1670,14 +1819,13 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
1670 loaded, recompute its value. We have to do it now, or else 1819 loaded, recompute its value. We have to do it now, or else
1671 forwarded objects won't work right. */ 1820 forwarded objects won't work right. */
1672 { 1821 {
1673 Lisp_Object *pvalbuf, buf; 1822 Lisp_Object buf; XSETBUFFER (buf, current_buffer);
1674 valcontents = sym->value; 1823 if (EQ (buf, blv->where))
1675 pvalbuf = &XBUFFER_LOCAL_VALUE (valcontents)->buffer;
1676 XSETBUFFER (buf, current_buffer);
1677 if (EQ (buf, *pvalbuf))
1678 { 1824 {
1679 *pvalbuf = Qnil; 1825 blv->where = Qnil;
1680 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0; 1826 /* blv->valcell = blv->defcell;
1827 * SET_BLV_FOUND (blv, 0); */
1828 blv->found = 0;
1681 find_symbol_value (variable); 1829 find_symbol_value (variable);
1682 } 1830 }
1683 } 1831 }
@@ -1712,39 +1860,45 @@ frame-local bindings). */)
1712 (variable) 1860 (variable)
1713 register Lisp_Object variable; 1861 register Lisp_Object variable;
1714{ 1862{
1715 register Lisp_Object tem, valcontents, newval; 1863 int forwarded;
1864 union Lisp_Val_Fwd valcontents;
1716 struct Lisp_Symbol *sym; 1865 struct Lisp_Symbol *sym;
1866 struct Lisp_Buffer_Local_Value *blv = NULL;
1717 1867
1718 CHECK_SYMBOL (variable); 1868 CHECK_SYMBOL (variable);
1719 sym = indirect_variable (XSYMBOL (variable)); 1869 sym = XSYMBOL (variable);
1720
1721 valcontents = sym->value;
1722 if (sym->constant || KBOARD_OBJFWDP (valcontents)
1723 || BUFFER_OBJFWDP (valcontents))
1724 error ("Symbol %s may not be frame-local", SDATA (sym->xname));
1725 1870
1726 if (BUFFER_LOCAL_VALUEP (valcontents)) 1871 start:
1872 switch (sym->redirect)
1727 { 1873 {
1728 if (!XBUFFER_LOCAL_VALUE (valcontents)->check_frame) 1874 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1729 error ("Symbol %s may not be frame-local", SDATA (sym->xname)); 1875 case SYMBOL_PLAINVAL:
1730 return variable; 1876 forwarded = 0; valcontents.value = SYMBOL_VAL (sym);
1877 if (EQ (valcontents.value, Qunbound))
1878 valcontents.value = Qnil;
1879 break;
1880 case SYMBOL_LOCALIZED:
1881 if (SYMBOL_BLV (sym)->frame_local)
1882 return variable;
1883 else
1884 error ("Symbol %s may not be frame-local",
1885 SDATA (SYMBOL_NAME (variable)));
1886 case SYMBOL_FORWARDED:
1887 forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym);
1888 if (KBOARD_OBJFWDP (valcontents.fwd) || BUFFER_OBJFWDP (valcontents.fwd))
1889 error ("Symbol %s may not be frame-local",
1890 SDATA (SYMBOL_NAME (variable)));
1891 break;
1892 default: abort ();
1731 } 1893 }
1732 1894
1733 if (EQ (valcontents, Qunbound)) 1895 if (sym->constant)
1734 sym->value = Qnil; 1896 error ("Symbol %s may not be frame-local", SDATA (SYMBOL_NAME (variable)));
1735 tem = Fcons (Qnil, Fsymbol_value (variable)); 1897
1736 XSETCAR (tem, tem); 1898 blv = make_blv (sym, forwarded, valcontents);
1737 newval = allocate_misc (); 1899 blv->frame_local = 1;
1738 XMISCTYPE (newval) = Lisp_Misc_Buffer_Local_Value; 1900 sym->redirect = SYMBOL_LOCALIZED;
1739 XBUFFER_LOCAL_VALUE (newval)->realvalue = sym->value; 1901 SET_SYMBOL_BLV (sym, blv);
1740 XBUFFER_LOCAL_VALUE (newval)->buffer = Qnil;
1741 XBUFFER_LOCAL_VALUE (newval)->frame = Qnil;
1742 XBUFFER_LOCAL_VALUE (newval)->local_if_set = 0;
1743 XBUFFER_LOCAL_VALUE (newval)->found_for_buffer = 0;
1744 XBUFFER_LOCAL_VALUE (newval)->found_for_frame = 0;
1745 XBUFFER_LOCAL_VALUE (newval)->check_frame = 1;
1746 XBUFFER_LOCAL_VALUE (newval)->cdr = tem;
1747 sym->value = newval;
1748 return variable; 1902 return variable;
1749} 1903}
1750 1904
@@ -1755,7 +1909,6 @@ BUFFER defaults to the current buffer. */)
1755 (variable, buffer) 1909 (variable, buffer)
1756 register Lisp_Object variable, buffer; 1910 register Lisp_Object variable, buffer;
1757{ 1911{
1758 Lisp_Object valcontents;
1759 register struct buffer *buf; 1912 register struct buffer *buf;
1760 struct Lisp_Symbol *sym; 1913 struct Lisp_Symbol *sym;
1761 1914
@@ -1768,29 +1921,46 @@ BUFFER defaults to the current buffer. */)
1768 } 1921 }
1769 1922
1770 CHECK_SYMBOL (variable); 1923 CHECK_SYMBOL (variable);
1771 sym = indirect_variable (XSYMBOL (variable)); 1924 sym = XSYMBOL (variable);
1772 XSETSYMBOL (variable, sym);
1773
1774 valcontents = sym->value;
1775 if (BUFFER_LOCAL_VALUEP (valcontents))
1776 {
1777 Lisp_Object tail, elt;
1778 1925
1779 for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail)) 1926 start:
1780 { 1927 switch (sym->redirect)
1781 elt = XCAR (tail);
1782 if (EQ (variable, XCAR (elt)))
1783 return Qt;
1784 }
1785 }
1786 if (BUFFER_OBJFWDP (valcontents))
1787 { 1928 {
1788 int offset = XBUFFER_OBJFWD (valcontents)->offset; 1929 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1789 int idx = PER_BUFFER_IDX (offset); 1930 case SYMBOL_PLAINVAL: return Qnil;
1790 if (idx == -1 || PER_BUFFER_VALUE_P (buf, idx)) 1931 case SYMBOL_LOCALIZED:
1791 return Qt; 1932 {
1933 Lisp_Object tail, elt, tmp;
1934 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1935 XSETBUFFER (tmp, buf);
1936
1937 for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
1938 {
1939 elt = XCAR (tail);
1940 if (EQ (variable, XCAR (elt)))
1941 {
1942 eassert (!blv->frame_local);
1943 eassert (BLV_FOUND (blv) || !EQ (blv->where, tmp));
1944 return Qt;
1945 }
1946 }
1947 eassert (!BLV_FOUND (blv) || !EQ (blv->where, tmp));
1948 return Qnil;
1949 }
1950 case SYMBOL_FORWARDED:
1951 {
1952 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
1953 if (BUFFER_OBJFWDP (valcontents))
1954 {
1955 int offset = XBUFFER_OBJFWD (valcontents)->offset;
1956 int idx = PER_BUFFER_IDX (offset);
1957 if (idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
1958 return Qt;
1959 }
1960 return Qnil;
1961 }
1962 default: abort ();
1792 } 1963 }
1793 return Qnil;
1794} 1964}
1795 1965
1796DEFUN ("local-variable-if-set-p", Flocal_variable_if_set_p, Slocal_variable_if_set_p, 1966DEFUN ("local-variable-if-set-p", Flocal_variable_if_set_p, Slocal_variable_if_set_p,
@@ -1804,40 +1974,29 @@ BUFFER defaults to the current buffer. */)
1804 (variable, buffer) 1974 (variable, buffer)
1805 register Lisp_Object variable, buffer; 1975 register Lisp_Object variable, buffer;
1806{ 1976{
1807 Lisp_Object valcontents;
1808 register struct buffer *buf;
1809 struct Lisp_Symbol *sym; 1977 struct Lisp_Symbol *sym;
1810 1978
1811 if (NILP (buffer))
1812 buf = current_buffer;
1813 else
1814 {
1815 CHECK_BUFFER (buffer);
1816 buf = XBUFFER (buffer);
1817 }
1818
1819 CHECK_SYMBOL (variable); 1979 CHECK_SYMBOL (variable);
1820 sym = indirect_variable (XSYMBOL (variable)); 1980 sym = XSYMBOL (variable);
1821 XSETSYMBOL (variable, sym);
1822
1823 valcontents = sym->value;
1824 1981
1825 if (BUFFER_OBJFWDP (valcontents)) 1982 start:
1826 /* All these slots become local if they are set. */ 1983 switch (sym->redirect)
1827 return Qt;
1828 else if (BUFFER_LOCAL_VALUEP (valcontents))
1829 { 1984 {
1830 Lisp_Object tail, elt; 1985 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1831 if (XBUFFER_LOCAL_VALUE (valcontents)->local_if_set) 1986 case SYMBOL_PLAINVAL: return Qnil;
1832 return Qt; 1987 case SYMBOL_LOCALIZED:
1833 for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail)) 1988 {
1834 { 1989 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1835 elt = XCAR (tail); 1990 if (blv->local_if_set)
1836 if (EQ (variable, XCAR (elt))) 1991 return Qt;
1837 return Qt; 1992 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
1838 } 1993 return Flocal_variable_p (variable, buffer);
1994 }
1995 case SYMBOL_FORWARDED:
1996 /* All BUFFER_OBJFWD slots become local if they are set. */
1997 return (BUFFER_OBJFWDP (SYMBOL_FWD (sym)) ? Qt : Qnil);
1998 default: abort ();
1839 } 1999 }
1840 return Qnil;
1841} 2000}
1842 2001
1843DEFUN ("variable-binding-locus", Fvariable_binding_locus, Svariable_binding_locus, 2002DEFUN ("variable-binding-locus", Fvariable_binding_locus, Svariable_binding_locus,
@@ -1849,30 +2008,40 @@ If the current binding is global (the default), the value is nil. */)
1849 (variable) 2008 (variable)
1850 register Lisp_Object variable; 2009 register Lisp_Object variable;
1851{ 2010{
1852 Lisp_Object valcontents;
1853 struct Lisp_Symbol *sym; 2011 struct Lisp_Symbol *sym;
1854 2012
1855 CHECK_SYMBOL (variable); 2013 CHECK_SYMBOL (variable);
1856 sym = indirect_variable (XSYMBOL (variable)); 2014 sym = XSYMBOL (variable);
1857 2015
1858 /* Make sure the current binding is actually swapped in. */ 2016 /* Make sure the current binding is actually swapped in. */
1859 find_symbol_value (variable); 2017 find_symbol_value (variable);
1860 2018
1861 valcontents = sym->value; 2019 start:
1862 2020 switch (sym->redirect)
1863 if (BUFFER_LOCAL_VALUEP (valcontents)
1864 || BUFFER_OBJFWDP (valcontents))
1865 { 2021 {
2022 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
2023 case SYMBOL_PLAINVAL: return Qnil;
2024 case SYMBOL_FORWARDED:
2025 {
2026 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
2027 if (KBOARD_OBJFWDP (valcontents))
2028 return Fframe_terminal (Fselected_frame ());
2029 else if (!BUFFER_OBJFWDP (valcontents))
2030 return Qnil;
2031 }
2032 /* FALLTHROUGH */
2033 case SYMBOL_LOCALIZED:
1866 /* For a local variable, record both the symbol and which 2034 /* For a local variable, record both the symbol and which
1867 buffer's or frame's value we are saving. */ 2035 buffer's or frame's value we are saving. */
1868 if (!NILP (Flocal_variable_p (variable, Qnil))) 2036 if (!NILP (Flocal_variable_p (variable, Qnil)))
1869 return Fcurrent_buffer (); 2037 return Fcurrent_buffer ();
1870 else if (BUFFER_LOCAL_VALUEP (valcontents) 2038 else if (sym->redirect == SYMBOL_LOCALIZED
1871 && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame) 2039 && BLV_FOUND (SYMBOL_BLV (sym)))
1872 return XBUFFER_LOCAL_VALUE (valcontents)->frame; 2040 return SYMBOL_BLV (sym)->where;
2041 else
2042 return Qnil;
2043 default: abort ();
1873 } 2044 }
1874
1875 return Qnil;
1876} 2045}
1877 2046
1878/* This code is disabled now that we use the selected frame to return 2047/* This code is disabled now that we use the selected frame to return