diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval.c | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/src/eval.c b/src/eval.c index e000ea622c5..6ee3d89cb3f 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -2923,35 +2923,42 @@ specbind (symbol, value) | |||
| 2923 | } | 2923 | } |
| 2924 | else | 2924 | else |
| 2925 | { | 2925 | { |
| 2926 | Lisp_Object valcontents; | ||
| 2927 | |||
| 2926 | ovalue = find_symbol_value (symbol); | 2928 | ovalue = find_symbol_value (symbol); |
| 2927 | specpdl_ptr->func = 0; | 2929 | specpdl_ptr->func = 0; |
| 2928 | specpdl_ptr->old_value = ovalue; | 2930 | specpdl_ptr->old_value = ovalue; |
| 2929 | 2931 | ||
| 2930 | if (BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) | 2932 | valcontents = XSYMBOL (symbol)->value; |
| 2931 | || SOME_BUFFER_LOCAL_VALUEP (XSYMBOL (symbol)->value) | 2933 | |
| 2932 | || BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) | 2934 | if (BUFFER_LOCAL_VALUEP (valcontents) |
| 2935 | || SOME_BUFFER_LOCAL_VALUEP (valcontents) | ||
| 2936 | || BUFFER_OBJFWDP (valcontents)) | ||
| 2933 | { | 2937 | { |
| 2934 | Lisp_Object current_buffer, binding_buffer; | 2938 | Lisp_Object where; |
| 2935 | 2939 | ||
| 2936 | /* For a local variable, record both the symbol and which | 2940 | /* For a local variable, record both the symbol and which |
| 2937 | buffer's value we are saving. */ | 2941 | buffer's or frame's value we are saving. */ |
| 2938 | current_buffer = Fcurrent_buffer (); | 2942 | if (!NILP (Flocal_variable_p (symbol, Qnil))) |
| 2939 | binding_buffer = current_buffer; | 2943 | where = Fcurrent_buffer (); |
| 2940 | 2944 | else if (!BUFFER_OBJFWDP (valcontents) | |
| 2941 | /* If the variable is not local in this buffer, | 2945 | && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame) |
| 2942 | we are saving the global value, so restore that. */ | 2946 | where = XBUFFER_LOCAL_VALUE (valcontents)->frame; |
| 2943 | if (NILP (Flocal_variable_p (symbol, binding_buffer))) | 2947 | else |
| 2944 | binding_buffer = Qnil; | 2948 | where = Qnil; |
| 2945 | specpdl_ptr->symbol | 2949 | |
| 2946 | = Fcons (symbol, Fcons (binding_buffer, current_buffer)); | 2950 | /* We're not using the `unused' slot in the specbinding |
| 2951 | structure because this would mean we have to do more | ||
| 2952 | work for simple variables. */ | ||
| 2953 | specpdl_ptr->symbol = Fcons (symbol, where); | ||
| 2947 | 2954 | ||
| 2948 | /* If SYMBOL is a per-buffer variable which doesn't have a | 2955 | /* If SYMBOL is a per-buffer variable which doesn't have a |
| 2949 | buffer-local value here, make the `let' change the global | 2956 | buffer-local value here, make the `let' change the global |
| 2950 | value by changing the value of SYMBOL in all buffers not | 2957 | value by changing the value of SYMBOL in all buffers not |
| 2951 | having their own value. This is consistent with what | 2958 | having their own value. This is consistent with what |
| 2952 | happens with other buffer-local variables. */ | 2959 | happens with other buffer-local variables. */ |
| 2953 | if (NILP (binding_buffer) | 2960 | if (NILP (where) |
| 2954 | && BUFFER_OBJFWDP (XSYMBOL (symbol)->value)) | 2961 | && BUFFER_OBJFWDP (valcontents)) |
| 2955 | { | 2962 | { |
| 2956 | ++specpdl_ptr; | 2963 | ++specpdl_ptr; |
| 2957 | Fset_default (symbol, value); | 2964 | Fset_default (symbol, value); |
| @@ -2996,30 +3003,31 @@ unbind_to (count, value) | |||
| 2996 | while (specpdl_ptr != specpdl + count) | 3003 | while (specpdl_ptr != specpdl + count) |
| 2997 | { | 3004 | { |
| 2998 | --specpdl_ptr; | 3005 | --specpdl_ptr; |
| 2999 | 3006 | ||
| 3000 | if (specpdl_ptr->func != 0) | 3007 | if (specpdl_ptr->func != 0) |
| 3001 | (*specpdl_ptr->func) (specpdl_ptr->old_value); | 3008 | (*specpdl_ptr->func) (specpdl_ptr->old_value); |
| 3002 | /* Note that a "binding" of nil is really an unwind protect, | 3009 | /* Note that a "binding" of nil is really an unwind protect, |
| 3003 | so in that case the "old value" is a list of forms to evaluate. */ | 3010 | so in that case the "old value" is a list of forms to evaluate. */ |
| 3004 | else if (NILP (specpdl_ptr->symbol)) | 3011 | else if (NILP (specpdl_ptr->symbol)) |
| 3005 | Fprogn (specpdl_ptr->old_value); | 3012 | Fprogn (specpdl_ptr->old_value); |
| 3006 | /* If the symbol is a list, it is really (SYMBOL BINDING_BUFFER | 3013 | /* If the symbol is a list, it is really (SYMBOL . WHERE) where |
| 3007 | . CURRENT_BUFFER) and it indicates we bound a variable that | 3014 | WHERE is either nil, a buffer, or a frame. If WHERE is a |
| 3008 | has buffer-local bindings. BINDING_BUFFER nil means that the | 3015 | buffer or frame, this indicates we bound a variable that had |
| 3009 | variable had the default value when it was bound. */ | 3016 | a buffer-local or frmae-local binding.. WHERE nil means that |
| 3017 | the variable had the default value when it was bound. */ | ||
| 3010 | else if (CONSP (specpdl_ptr->symbol)) | 3018 | else if (CONSP (specpdl_ptr->symbol)) |
| 3011 | { | 3019 | { |
| 3012 | Lisp_Object symbol, buffer; | 3020 | Lisp_Object symbol, where; |
| 3013 | 3021 | ||
| 3014 | symbol = XCAR (specpdl_ptr->symbol); | 3022 | symbol = XCAR (specpdl_ptr->symbol); |
| 3015 | buffer = XCAR (XCDR (specpdl_ptr->symbol)); | 3023 | where = XCDR (specpdl_ptr->symbol); |
| 3016 | 3024 | ||
| 3017 | /* Handle restoring a default value. */ | 3025 | if (NILP (where)) |
| 3018 | if (NILP (buffer)) | ||
| 3019 | Fset_default (symbol, specpdl_ptr->old_value); | 3026 | Fset_default (symbol, specpdl_ptr->old_value); |
| 3020 | /* Handle restoring a value saved from a live buffer. */ | 3027 | else if (BUFFERP (where)) |
| 3021 | else | 3028 | set_internal (symbol, specpdl_ptr->old_value, XBUFFER (where), 1); |
| 3022 | set_internal (symbol, specpdl_ptr->old_value, XBUFFER (buffer), 1); | 3029 | else |
| 3030 | set_internal (symbol, specpdl_ptr->old_value, NULL, 1); | ||
| 3023 | } | 3031 | } |
| 3024 | else | 3032 | else |
| 3025 | { | 3033 | { |