- /* Find the new binding. */
- tem1 = Fassq (symbol, buf->local_var_alist);
- XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 1;
- XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 0;
-
- if (NILP (tem1))
- {
- /* This buffer still sees the default value. */
-
- /* If the variable is not local_if_set,
- or if this is `let' rather than `set',
- make CURRENT-ALIST-ELEMENT point to itself,
- indicating that we're seeing the default value.
- Likewise if the variable has been let-bound
- in the current buffer. */
- if (bindflag || !XBUFFER_LOCAL_VALUE (valcontents)->local_if_set
- || let_shadows_buffer_binding_p (XSYMBOL (symbol)))
- {
- XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0;
-
- if (XBUFFER_LOCAL_VALUE (valcontents)->check_frame)
- tem1 = Fassq (symbol,
- XFRAME (selected_frame)->param_alist);
-
- if (! NILP (tem1))
- XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 1;
- else
- tem1 = XBUFFER_LOCAL_VALUE (valcontents)->cdr;
- }
- /* If it's a Lisp_Buffer_Local_Value, being set not bound,
- and we're not within a let that was made for this buffer,
- create a new buffer-local binding for the variable.
- That means, give this buffer a new assoc for a local value
- and load that binding. */
- else
- {
- tem1 = Fcons (symbol, XCDR (current_alist_element));
- buf->local_var_alist
- = Fcons (tem1, buf->local_var_alist);
- }
- }
+ start:
+ switch (sym->redirect)
+ {
+ case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
+ case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return;
+ case SYMBOL_LOCALIZED:
+ {
+ struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
+ if (NILP (where))
+ {
+ if (blv->frame_local)
+ where = selected_frame;
+ else
+ XSETBUFFER (where, current_buffer);
+ }
+ /* If the current buffer is not the buffer whose binding is
+ loaded, or if there may be frame-local bindings and the frame
+ isn't the right one, or if it's a Lisp_Buffer_Local_Value and
+ the default binding is loaded, the loaded binding may be the
+ wrong one. */
+ if (!EQ (blv->where, where)
+ /* Also unload a global binding (if the var is local_if_set). */
+ || (EQ (blv->valcell, blv->defcell)))
+ {
+ /* The currently loaded binding is not necessarily valid.
+ We need to unload it, and choose a new binding. */
+
+ /* Write out `realvalue' to the old loaded binding. */
+ if (blv->fwd)
+ SET_BLV_VALUE (blv, do_symval_forwarding (blv->fwd));
+
+ /* Find the new binding. */
+ XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */
+ tem1 = Fassq (symbol,
+ (blv->frame_local
+ ? XFRAME (where)->param_alist
+ : BVAR (XBUFFER (where), local_var_alist)));
+ blv->where = where;
+ blv->found = 1;
+
+ if (NILP (tem1))
+ {
+ /* This buffer still sees the default value. */
+
+ /* If the variable is a Lisp_Some_Buffer_Local_Value,
+ or if this is `let' rather than `set',
+ make CURRENT-ALIST-ELEMENT point to itself,
+ indicating that we're seeing the default value.
+ Likewise if the variable has been let-bound
+ in the current buffer. */
+ if (bindflag || !blv->local_if_set
+ || let_shadows_buffer_binding_p (sym))
+ {
+ blv->found = 0;
+ tem1 = blv->defcell;
+ }
+ /* If it's a local_if_set, being set not bound,
+ and we're not within a let that was made for this buffer,
+ create a new buffer-local binding for the variable.
+ That means, give this buffer a new assoc for a local value
+ and load that binding. */
+ else
+ {
+ /* local_if_set is only supported for buffer-local
+ bindings, not for frame-local bindings. */
+ eassert (!blv->frame_local);
+ tem1 = Fcons (symbol, XCDR (blv->defcell));
+ BVAR (XBUFFER (where), local_var_alist)
+ = Fcons (tem1, BVAR (XBUFFER (where), local_var_alist));
+ }
+ }
+
+ /* Record which binding is now loaded. */
+ blv->valcell = tem1;
+ }