diff options
| author | Noam Postavsky | 2018-06-03 12:55:37 -0400 |
|---|---|---|
| committer | Noam Postavsky | 2018-06-03 12:55:40 -0400 |
| commit | 9a14b4d1ce84e5e0739572729670b8f10d234097 (patch) | |
| tree | 880aa4dab830e5e7699e6eace5c0a1097a091baa | |
| parent | 5fa73a7d98040f749f4cd45cfa40cf3c1c8cc2e3 (diff) | |
| parent | ed962f2b8a2f63c7dbf31ec5df3c915703dd571d (diff) | |
| download | emacs-9a14b4d1ce84e5e0739572729670b8f10d234097.tar.gz emacs-9a14b4d1ce84e5e0739572729670b8f10d234097.zip | |
; Merge: backports from master
| -rw-r--r-- | lisp/emacs-lisp/cl-print.el | 9 | ||||
| -rw-r--r-- | lisp/epa.el | 1 | ||||
| -rw-r--r-- | lisp/eshell/esh-opt.el | 13 | ||||
| -rw-r--r-- | lisp/mail/mail-extr.el | 39 | ||||
| -rw-r--r-- | src/alloc.c | 17 | ||||
| -rw-r--r-- | src/buffer.c | 55 | ||||
| -rw-r--r-- | src/data.c | 36 | ||||
| -rw-r--r-- | src/editfns.c | 6 | ||||
| -rw-r--r-- | src/insdel.c | 4 | ||||
| -rw-r--r-- | src/lisp.h | 23 | ||||
| -rw-r--r-- | src/marker.c | 13 | ||||
| -rw-r--r-- | src/xterm.c | 3 | ||||
| -rw-r--r-- | test/lisp/emacs-lisp/cl-print-tests.el | 10 | ||||
| -rw-r--r-- | test/src/data-tests.el | 19 | ||||
| -rw-r--r-- | test/src/editfns-tests.el | 51 |
15 files changed, 170 insertions, 129 deletions
diff --git a/lisp/emacs-lisp/cl-print.el b/lisp/emacs-lisp/cl-print.el index de41d826713..7c0e81c9349 100644 --- a/lisp/emacs-lisp/cl-print.el +++ b/lisp/emacs-lisp/cl-print.el | |||
| @@ -62,9 +62,12 @@ call other entry points instead, such as `cl-prin1'." | |||
| 62 | (princ "(" stream) | 62 | (princ "(" stream) |
| 63 | (cl-print-object car stream) | 63 | (cl-print-object car stream) |
| 64 | (while (and (consp object) | 64 | (while (and (consp object) |
| 65 | (not (if cl-print--number-table | 65 | (not (cond |
| 66 | (numberp (gethash object cl-print--number-table)) | 66 | (cl-print--number-table |
| 67 | (memq object cl-print--currently-printing)))) | 67 | (numberp (gethash object cl-print--number-table))) |
| 68 | ((memq object cl-print--currently-printing)) | ||
| 69 | (t (push object cl-print--currently-printing) | ||
| 70 | nil)))) | ||
| 68 | (princ " " stream) | 71 | (princ " " stream) |
| 69 | (cl-print-object (pop object) stream)) | 72 | (cl-print-object (pop object) stream)) |
| 70 | (when object | 73 | (when object |
diff --git a/lisp/epa.el b/lisp/epa.el index a84e4f2b854..f2989b314a2 100644 --- a/lisp/epa.el +++ b/lisp/epa.el | |||
| @@ -701,6 +701,7 @@ If you do not specify PLAIN-FILE, this functions prompts for the value to use." | |||
| 701 | #'epa-progress-callback-function | 701 | #'epa-progress-callback-function |
| 702 | (format "Decrypting %s..." | 702 | (format "Decrypting %s..." |
| 703 | (file-name-nondirectory decrypt-file)))) | 703 | (file-name-nondirectory decrypt-file)))) |
| 704 | (setf (epg-context-pinentry-mode context) epa-pinentry-mode) | ||
| 704 | (message "Decrypting %s..." (file-name-nondirectory decrypt-file)) | 705 | (message "Decrypting %s..." (file-name-nondirectory decrypt-file)) |
| 705 | (condition-case error | 706 | (condition-case error |
| 706 | (epg-decrypt-file context decrypt-file plain-file) | 707 | (epg-decrypt-file context decrypt-file plain-file) |
diff --git a/lisp/eshell/esh-opt.el b/lisp/eshell/esh-opt.el index 3af8fd7cacb..7d0b362b4c4 100644 --- a/lisp/eshell/esh-opt.el +++ b/lisp/eshell/esh-opt.el | |||
| @@ -244,26 +244,27 @@ switch is unrecognized." | |||
| 244 | options))) | 244 | options))) |
| 245 | (ai 0) arg | 245 | (ai 0) arg |
| 246 | (eshell--args args)) | 246 | (eshell--args args)) |
| 247 | (while (< ai (length args)) | 247 | (while (< ai (length eshell--args)) |
| 248 | (setq arg (nth ai args)) | 248 | (setq arg (nth ai eshell--args)) |
| 249 | (if (not (and (stringp arg) | 249 | (if (not (and (stringp arg) |
| 250 | (string-match "^-\\(-\\)?\\(.*\\)" arg))) | 250 | (string-match "^-\\(-\\)?\\(.*\\)" arg))) |
| 251 | (setq ai (1+ ai)) | 251 | (setq ai (1+ ai)) |
| 252 | (let* ((dash (match-string 1 arg)) | 252 | (let* ((dash (match-string 1 arg)) |
| 253 | (switch (match-string 2 arg))) | 253 | (switch (match-string 2 arg))) |
| 254 | (if (= ai 0) | 254 | (if (= ai 0) |
| 255 | (setq args (cdr args)) | 255 | (setq eshell--args (cdr eshell--args)) |
| 256 | (setcdr (nthcdr (1- ai) args) (nthcdr (1+ ai) args))) | 256 | (setcdr (nthcdr (1- ai) eshell--args) |
| 257 | (nthcdr (1+ ai) eshell--args))) | ||
| 257 | (if dash | 258 | (if dash |
| 258 | (if (> (length switch) 0) | 259 | (if (> (length switch) 0) |
| 259 | (eshell--process-option name switch 1 ai options opt-vals) | 260 | (eshell--process-option name switch 1 ai options opt-vals) |
| 260 | (setq ai (length args))) | 261 | (setq ai (length eshell--args))) |
| 261 | (let ((len (length switch)) | 262 | (let ((len (length switch)) |
| 262 | (index 0)) | 263 | (index 0)) |
| 263 | (while (< index len) | 264 | (while (< index len) |
| 264 | (eshell--process-option name (aref switch index) | 265 | (eshell--process-option name (aref switch index) |
| 265 | 0 ai options opt-vals) | 266 | 0 ai options opt-vals) |
| 266 | (setq index (1+ index)))))))) | 267 | (setq index (1+ index)))))))) |
| 267 | (nconc (mapcar #'cdr opt-vals) args))) | 268 | (nconc (mapcar #'cdr opt-vals) eshell--args))) |
| 268 | 269 | ||
| 269 | ;;; esh-opt.el ends here | 270 | ;;; esh-opt.el ends here |
diff --git a/lisp/mail/mail-extr.el b/lisp/mail/mail-extr.el index 1e18c6d0553..3e8a41fb24c 100644 --- a/lisp/mail/mail-extr.el +++ b/lisp/mail/mail-extr.el | |||
| @@ -1406,26 +1406,25 @@ consing a string.)" | |||
| 1406 | (insert (upcase mi) ". "))) | 1406 | (insert (upcase mi) ". "))) |
| 1407 | 1407 | ||
| 1408 | ;; Nuke name if it is the same as mailbox name. | 1408 | ;; Nuke name if it is the same as mailbox name. |
| 1409 | (when mail-extr-ignore-single-names | 1409 | (let ((buffer-length (- (point-max) (point-min))) |
| 1410 | (let ((buffer-length (- (point-max) (point-min))) | 1410 | (i 0) |
| 1411 | (i 0) | 1411 | (names-match-flag t)) |
| 1412 | (names-match-flag t)) | 1412 | (when (and (> buffer-length 0) |
| 1413 | (when (and (> buffer-length 0) | 1413 | (eq buffer-length (- mbox-end mbox-beg))) |
| 1414 | (eq buffer-length (- mbox-end mbox-beg))) | 1414 | (goto-char (point-max)) |
| 1415 | (goto-char (point-max)) | 1415 | (insert-buffer-substring canonicalization-buffer |
| 1416 | (insert-buffer-substring canonicalization-buffer | 1416 | mbox-beg mbox-end) |
| 1417 | mbox-beg mbox-end) | 1417 | (while (and names-match-flag |
| 1418 | (while (and names-match-flag | 1418 | (< i buffer-length)) |
| 1419 | (< i buffer-length)) | 1419 | (or (eq (downcase (char-after (+ i (point-min)))) |
| 1420 | (or (eq (downcase (char-after (+ i (point-min)))) | 1420 | (downcase |
| 1421 | (downcase | 1421 | (char-after (+ i buffer-length (point-min))))) |
| 1422 | (char-after (+ i buffer-length (point-min))))) | 1422 | (setq names-match-flag nil)) |
| 1423 | (setq names-match-flag nil)) | 1423 | (setq i (1+ i))) |
| 1424 | (setq i (1+ i))) | 1424 | (delete-region (+ (point-min) buffer-length) (point-max)) |
| 1425 | (delete-region (+ (point-min) buffer-length) (point-max)) | 1425 | (and names-match-flag |
| 1426 | (and names-match-flag | 1426 | mail-extr-ignore-realname-equals-mailbox-name |
| 1427 | mail-extr-ignore-realname-equals-mailbox-name | 1427 | (narrow-to-region (point) (point))))) |
| 1428 | (narrow-to-region (point) (point)))))) | ||
| 1429 | 1428 | ||
| 1430 | ;; Nuke name if it's just one word. | 1429 | ;; Nuke name if it's just one word. |
| 1431 | (goto-char (point-min)) | 1430 | (goto-char (point-min)) |
diff --git a/src/alloc.c b/src/alloc.c index c3f7920ed87..7baaa512c20 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3884,15 +3884,6 @@ build_marker (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t bytepos) | |||
| 3884 | return obj; | 3884 | return obj; |
| 3885 | } | 3885 | } |
| 3886 | 3886 | ||
| 3887 | /* Put MARKER back on the free list after using it temporarily. */ | ||
| 3888 | |||
| 3889 | void | ||
| 3890 | free_marker (Lisp_Object marker) | ||
| 3891 | { | ||
| 3892 | unchain_marker (XMARKER (marker)); | ||
| 3893 | free_misc (marker); | ||
| 3894 | } | ||
| 3895 | |||
| 3896 | 3887 | ||
| 3897 | /* Return a newly created vector or string with specified arguments as | 3888 | /* Return a newly created vector or string with specified arguments as |
| 3898 | elements. If all the arguments are characters that can fit | 3889 | elements. If all the arguments are characters that can fit |
| @@ -6343,12 +6334,8 @@ mark_localized_symbol (struct Lisp_Symbol *ptr) | |||
| 6343 | { | 6334 | { |
| 6344 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr); | 6335 | struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (ptr); |
| 6345 | Lisp_Object where = blv->where; | 6336 | Lisp_Object where = blv->where; |
| 6346 | /* If the value is set up for a killed buffer or deleted | 6337 | /* If the value is set up for a killed buffer restore its global binding. */ |
| 6347 | frame, restore its global binding. If the value is | 6338 | if ((BUFFERP (where) && !BUFFER_LIVE_P (XBUFFER (where)))) |
| 6348 | forwarded to a C variable, either it's not a Lisp_Object | ||
| 6349 | var, or it's staticpro'd already. */ | ||
| 6350 | if ((BUFFERP (where) && !BUFFER_LIVE_P (XBUFFER (where))) | ||
| 6351 | || (FRAMEP (where) && !FRAME_LIVE_P (XFRAME (where)))) | ||
| 6352 | swap_in_global_binding (ptr); | 6339 | swap_in_global_binding (ptr); |
| 6353 | mark_object (blv->where); | 6340 | mark_object (blv->where); |
| 6354 | mark_object (blv->valcell); | 6341 | mark_object (blv->valcell); |
diff --git a/src/buffer.c b/src/buffer.c index 9b54e4b7787..b0cee717036 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -108,7 +108,6 @@ int last_per_buffer_idx; | |||
| 108 | static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, | 108 | static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay, |
| 109 | bool after, Lisp_Object arg1, | 109 | bool after, Lisp_Object arg1, |
| 110 | Lisp_Object arg2, Lisp_Object arg3); | 110 | Lisp_Object arg2, Lisp_Object arg3); |
| 111 | static void swap_out_buffer_local_variables (struct buffer *b); | ||
| 112 | static void reset_buffer_local_variables (struct buffer *, bool); | 111 | static void reset_buffer_local_variables (struct buffer *, bool); |
| 113 | 112 | ||
| 114 | /* Alist of all buffer names vs the buffers. This used to be | 113 | /* Alist of all buffer names vs the buffers. This used to be |
| @@ -991,10 +990,29 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too) | |||
| 991 | else | 990 | else |
| 992 | { | 991 | { |
| 993 | Lisp_Object tmp, last = Qnil; | 992 | Lisp_Object tmp, last = Qnil; |
| 993 | Lisp_Object buffer; | ||
| 994 | XSETBUFFER (buffer, b); | ||
| 995 | |||
| 994 | for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp)) | 996 | for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp)) |
| 995 | { | 997 | { |
| 996 | Lisp_Object local_var = XCAR (XCAR (tmp)); | 998 | Lisp_Object local_var = XCAR (XCAR (tmp)); |
| 997 | Lisp_Object prop = Fget (local_var, Qpermanent_local); | 999 | Lisp_Object prop = Fget (local_var, Qpermanent_local); |
| 1000 | Lisp_Object sym = local_var; | ||
| 1001 | |||
| 1002 | /* Watchers are run *before* modifying the var. */ | ||
| 1003 | if (XSYMBOL (local_var)->u.s.trapped_write == SYMBOL_TRAPPED_WRITE) | ||
| 1004 | notify_variable_watchers (local_var, Qnil, | ||
| 1005 | Qmakunbound, Fcurrent_buffer ()); | ||
| 1006 | |||
| 1007 | eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED); | ||
| 1008 | /* Need not do anything if some other buffer's binding is | ||
| 1009 | now cached. */ | ||
| 1010 | if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) | ||
| 1011 | { | ||
| 1012 | /* Symbol is set up for this buffer's old local value: | ||
| 1013 | swap it out! */ | ||
| 1014 | swap_in_global_binding (XSYMBOL (sym)); | ||
| 1015 | } | ||
| 998 | 1016 | ||
| 999 | if (!NILP (prop)) | 1017 | if (!NILP (prop)) |
| 1000 | { | 1018 | { |
| @@ -1034,10 +1052,6 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too) | |||
| 1034 | bset_local_var_alist (b, XCDR (tmp)); | 1052 | bset_local_var_alist (b, XCDR (tmp)); |
| 1035 | else | 1053 | else |
| 1036 | XSETCDR (last, XCDR (tmp)); | 1054 | XSETCDR (last, XCDR (tmp)); |
| 1037 | |||
| 1038 | if (XSYMBOL (local_var)->u.s.trapped_write == SYMBOL_TRAPPED_WRITE) | ||
| 1039 | notify_variable_watchers (local_var, Qnil, | ||
| 1040 | Qmakunbound, Fcurrent_buffer ()); | ||
| 1041 | } | 1055 | } |
| 1042 | } | 1056 | } |
| 1043 | 1057 | ||
| @@ -1867,7 +1881,6 @@ cleaning up all windows currently displaying the buffer to be killed. */) | |||
| 1867 | won't be protected from GC. They would be protected | 1881 | won't be protected from GC. They would be protected |
| 1868 | if they happened to remain cached in their symbols. | 1882 | if they happened to remain cached in their symbols. |
| 1869 | This gets rid of them for certain. */ | 1883 | This gets rid of them for certain. */ |
| 1870 | swap_out_buffer_local_variables (b); | ||
| 1871 | reset_buffer_local_variables (b, 1); | 1884 | reset_buffer_local_variables (b, 1); |
| 1872 | 1885 | ||
| 1873 | bset_name (b, Qnil); | 1886 | bset_name (b, Qnil); |
| @@ -2737,11 +2750,6 @@ the normal hook `change-major-mode-hook'. */) | |||
| 2737 | { | 2750 | { |
| 2738 | run_hook (Qchange_major_mode_hook); | 2751 | run_hook (Qchange_major_mode_hook); |
| 2739 | 2752 | ||
| 2740 | /* Make sure none of the bindings in local_var_alist | ||
| 2741 | remain swapped in, in their symbols. */ | ||
| 2742 | |||
| 2743 | swap_out_buffer_local_variables (current_buffer); | ||
| 2744 | |||
| 2745 | /* Actually eliminate all local bindings of this buffer. */ | 2753 | /* Actually eliminate all local bindings of this buffer. */ |
| 2746 | 2754 | ||
| 2747 | reset_buffer_local_variables (current_buffer, 0); | 2755 | reset_buffer_local_variables (current_buffer, 0); |
| @@ -2753,31 +2761,6 @@ the normal hook `change-major-mode-hook'. */) | |||
| 2753 | return Qnil; | 2761 | return Qnil; |
| 2754 | } | 2762 | } |
| 2755 | 2763 | ||
| 2756 | /* Make sure no local variables remain set up with buffer B | ||
| 2757 | for their current values. */ | ||
| 2758 | |||
| 2759 | static void | ||
| 2760 | swap_out_buffer_local_variables (struct buffer *b) | ||
| 2761 | { | ||
| 2762 | Lisp_Object oalist, alist, buffer; | ||
| 2763 | |||
| 2764 | XSETBUFFER (buffer, b); | ||
| 2765 | oalist = BVAR (b, local_var_alist); | ||
| 2766 | |||
| 2767 | for (alist = oalist; CONSP (alist); alist = XCDR (alist)) | ||
| 2768 | { | ||
| 2769 | Lisp_Object sym = XCAR (XCAR (alist)); | ||
| 2770 | eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED); | ||
| 2771 | /* Need not do anything if some other buffer's binding is | ||
| 2772 | now cached. */ | ||
| 2773 | if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) | ||
| 2774 | { | ||
| 2775 | /* Symbol is set up for this buffer's old local value: | ||
| 2776 | swap it out! */ | ||
| 2777 | swap_in_global_binding (XSYMBOL (sym)); | ||
| 2778 | } | ||
| 2779 | } | ||
| 2780 | } | ||
| 2781 | 2764 | ||
| 2782 | /* Find all the overlays in the current buffer that contain position POS. | 2765 | /* Find all the overlays in the current buffer that contain position POS. |
| 2783 | Return the number found, and store them in a vector in *VEC_PTR. | 2766 | Return the number found, and store them in a vector in *VEC_PTR. |
diff --git a/src/data.c b/src/data.c index 45b2bf73026..4bee194e296 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -1188,7 +1188,7 @@ swap_in_global_binding (struct Lisp_Symbol *symbol) | |||
| 1188 | 1188 | ||
| 1189 | /* Indicate that the global binding is set up now. */ | 1189 | /* Indicate that the global binding is set up now. */ |
| 1190 | set_blv_where (blv, Qnil); | 1190 | set_blv_where (blv, Qnil); |
| 1191 | set_blv_found (blv, 0); | 1191 | set_blv_found (blv, false); |
| 1192 | } | 1192 | } |
| 1193 | 1193 | ||
| 1194 | /* Set up the buffer-local symbol SYMBOL for validity in the current buffer. | 1194 | /* Set up the buffer-local symbol SYMBOL for validity in the current buffer. |
| @@ -1257,7 +1257,6 @@ find_symbol_value (Lisp_Object symbol) | |||
| 1257 | swap_in_symval_forwarding (sym, blv); | 1257 | swap_in_symval_forwarding (sym, blv); |
| 1258 | return blv->fwd ? do_symval_forwarding (blv->fwd) : blv_value (blv); | 1258 | return blv->fwd ? do_symval_forwarding (blv->fwd) : blv_value (blv); |
| 1259 | } | 1259 | } |
| 1260 | /* FALLTHROUGH */ | ||
| 1261 | case SYMBOL_FORWARDED: | 1260 | case SYMBOL_FORWARDED: |
| 1262 | return do_symval_forwarding (SYMBOL_FWD (sym)); | 1261 | return do_symval_forwarding (SYMBOL_FWD (sym)); |
| 1263 | default: emacs_abort (); | 1262 | default: emacs_abort (); |
| @@ -1366,7 +1365,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1366 | tem1 = assq_no_quit (symbol, | 1365 | tem1 = assq_no_quit (symbol, |
| 1367 | BVAR (XBUFFER (where), local_var_alist)); | 1366 | BVAR (XBUFFER (where), local_var_alist)); |
| 1368 | set_blv_where (blv, where); | 1367 | set_blv_where (blv, where); |
| 1369 | blv->found = 1; | 1368 | blv->found = true; |
| 1370 | 1369 | ||
| 1371 | if (NILP (tem1)) | 1370 | if (NILP (tem1)) |
| 1372 | { | 1371 | { |
| @@ -1381,7 +1380,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1381 | if (bindflag || !blv->local_if_set | 1380 | if (bindflag || !blv->local_if_set |
| 1382 | || let_shadows_buffer_binding_p (sym)) | 1381 | || let_shadows_buffer_binding_p (sym)) |
| 1383 | { | 1382 | { |
| 1384 | blv->found = 0; | 1383 | blv->found = false; |
| 1385 | tem1 = blv->defcell; | 1384 | tem1 = blv->defcell; |
| 1386 | } | 1385 | } |
| 1387 | /* If it's a local_if_set, being set not bound, | 1386 | /* If it's a local_if_set, being set not bound, |
| @@ -1796,7 +1795,7 @@ make_blv (struct Lisp_Symbol *sym, bool forwarded, | |||
| 1796 | blv->local_if_set = 0; | 1795 | blv->local_if_set = 0; |
| 1797 | set_blv_defcell (blv, tem); | 1796 | set_blv_defcell (blv, tem); |
| 1798 | set_blv_valcell (blv, tem); | 1797 | set_blv_valcell (blv, tem); |
| 1799 | set_blv_found (blv, 0); | 1798 | set_blv_found (blv, false); |
| 1800 | return blv; | 1799 | return blv; |
| 1801 | } | 1800 | } |
| 1802 | 1801 | ||
| @@ -1946,30 +1945,17 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) | |||
| 1946 | CALLN (Fmessage, format, SYMBOL_NAME (variable)); | 1945 | CALLN (Fmessage, format, SYMBOL_NAME (variable)); |
| 1947 | } | 1946 | } |
| 1948 | 1947 | ||
| 1949 | /* Swap out any local binding for some other buffer, and make | 1948 | if (BUFFERP (blv->where) && current_buffer == XBUFFER (blv->where)) |
| 1950 | sure the current value is permanently recorded, if it's the | 1949 | /* Make sure the current value is permanently recorded, if it's the |
| 1951 | default value. */ | 1950 | default value. */ |
| 1952 | find_symbol_value (variable); | 1951 | swap_in_global_binding (sym); |
| 1953 | 1952 | ||
| 1954 | bset_local_var_alist | 1953 | bset_local_var_alist |
| 1955 | (current_buffer, | 1954 | (current_buffer, |
| 1956 | Fcons (Fcons (variable, XCDR (blv->defcell)), | 1955 | Fcons (Fcons (variable, XCDR (blv->defcell)), |
| 1957 | BVAR (current_buffer, local_var_alist))); | 1956 | BVAR (current_buffer, local_var_alist))); |
| 1958 | |||
| 1959 | /* Make sure symbol does not think it is set up for this buffer; | ||
| 1960 | force it to look once again for this buffer's value. */ | ||
| 1961 | if (current_buffer == XBUFFER (blv->where)) | ||
| 1962 | set_blv_where (blv, Qnil); | ||
| 1963 | set_blv_found (blv, 0); | ||
| 1964 | } | 1957 | } |
| 1965 | 1958 | ||
| 1966 | /* If the symbol forwards into a C variable, then load the binding | ||
| 1967 | for this buffer now. If C code modifies the variable before we | ||
| 1968 | load the binding in, then that new value will clobber the default | ||
| 1969 | binding the next time we unload it. */ | ||
| 1970 | if (blv->fwd) | ||
| 1971 | swap_in_symval_forwarding (sym, blv); | ||
| 1972 | |||
| 1973 | return variable; | 1959 | return variable; |
| 1974 | } | 1960 | } |
| 1975 | 1961 | ||
| @@ -2031,11 +2017,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */) | |||
| 2031 | { | 2017 | { |
| 2032 | Lisp_Object buf; XSETBUFFER (buf, current_buffer); | 2018 | Lisp_Object buf; XSETBUFFER (buf, current_buffer); |
| 2033 | if (EQ (buf, blv->where)) | 2019 | if (EQ (buf, blv->where)) |
| 2034 | { | 2020 | swap_in_global_binding (sym); |
| 2035 | set_blv_where (blv, Qnil); | ||
| 2036 | blv->found = 0; | ||
| 2037 | find_symbol_value (variable); | ||
| 2038 | } | ||
| 2039 | } | 2021 | } |
| 2040 | 2022 | ||
| 2041 | return variable; | 2023 | return variable; |
diff --git a/src/editfns.c b/src/editfns.c index d0ccdbddc29..b553a213e6c 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -3876,9 +3876,9 @@ save_restriction_restore (Lisp_Object data) | |||
| 3876 | 3876 | ||
| 3877 | buf->clip_changed = 1; /* Remember that the narrowing changed. */ | 3877 | buf->clip_changed = 1; /* Remember that the narrowing changed. */ |
| 3878 | } | 3878 | } |
| 3879 | /* These aren't needed anymore, so don't wait for GC. */ | 3879 | /* Detach the markers, and free the cons instead of waiting for GC. */ |
| 3880 | free_marker (XCAR (data)); | 3880 | detach_marker (XCAR (data)); |
| 3881 | free_marker (XCDR (data)); | 3881 | detach_marker (XCDR (data)); |
| 3882 | free_cons (XCONS (data)); | 3882 | free_cons (XCONS (data)); |
| 3883 | } | 3883 | } |
| 3884 | else | 3884 | else |
diff --git a/src/insdel.c b/src/insdel.c index 02e3f41bc9f..173c2438347 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -2149,9 +2149,9 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int, | |||
| 2149 | } | 2149 | } |
| 2150 | 2150 | ||
| 2151 | if (! NILP (start_marker)) | 2151 | if (! NILP (start_marker)) |
| 2152 | free_marker (start_marker); | 2152 | detach_marker (start_marker); |
| 2153 | if (! NILP (end_marker)) | 2153 | if (! NILP (end_marker)) |
| 2154 | free_marker (end_marker); | 2154 | detach_marker (end_marker); |
| 2155 | RESTORE_VALUE; | 2155 | RESTORE_VALUE; |
| 2156 | 2156 | ||
| 2157 | unbind_to (count, Qnil); | 2157 | unbind_to (count, Qnil); |
diff --git a/src/lisp.h b/src/lisp.h index a8963b7f3c4..56ad8b814b6 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -2587,18 +2587,15 @@ struct Lisp_Buffer_Objfwd | |||
| 2587 | in the buffer structure itself. They are handled differently, | 2587 | in the buffer structure itself. They are handled differently, |
| 2588 | using struct Lisp_Buffer_Objfwd.) | 2588 | using struct Lisp_Buffer_Objfwd.) |
| 2589 | 2589 | ||
| 2590 | The `realvalue' slot holds the variable's current value, or a | 2590 | The `valcell' slot holds the variable's current value (unless `fwd' |
| 2591 | forwarding pointer to where that value is kept. This value is the | 2591 | is set). This value is the one that corresponds to the loaded binding. |
| 2592 | one that corresponds to the loaded binding. To read or set the | 2592 | To read or set the variable, you must first make sure the right binding |
| 2593 | variable, you must first make sure the right binding is loaded; | 2593 | is loaded; then you can access the value in (or through) `valcell'. |
| 2594 | then you can access the value in (or through) `realvalue'. | 2594 | |
| 2595 | 2595 | `where' is the buffer for which the loaded binding was found. | |
| 2596 | `where' is the buffer for which the loaded binding was found. If | 2596 | If it has changed, to make sure the right binding is loaded it is |
| 2597 | it has changed, to make sure the right binding is loaded it is | ||
| 2598 | necessary to find which binding goes with the current buffer, then | 2597 | necessary to find which binding goes with the current buffer, then |
| 2599 | load it. To load it, first unload the previous binding, then copy | 2598 | load it. To load it, first unload the previous binding. |
| 2600 | the value of the new binding into `realvalue' (or through it). | ||
| 2601 | Also update LOADED-BINDING to point to the newly loaded binding. | ||
| 2602 | 2599 | ||
| 2603 | `local_if_set' indicates that merely setting the variable creates a | 2600 | `local_if_set' indicates that merely setting the variable creates a |
| 2604 | local binding for the current buffer. Otherwise the latter, setting | 2601 | local binding for the current buffer. Otherwise the latter, setting |
| @@ -3728,7 +3725,6 @@ extern Lisp_Object make_save_funcptr_ptr_obj (void (*) (void), void *, | |||
| 3728 | extern Lisp_Object make_save_memory (Lisp_Object *, ptrdiff_t); | 3725 | extern Lisp_Object make_save_memory (Lisp_Object *, ptrdiff_t); |
| 3729 | extern void free_save_value (Lisp_Object); | 3726 | extern void free_save_value (Lisp_Object); |
| 3730 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); | 3727 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); |
| 3731 | extern void free_marker (Lisp_Object); | ||
| 3732 | extern void free_cons (struct Lisp_Cons *); | 3728 | extern void free_cons (struct Lisp_Cons *); |
| 3733 | extern void init_alloc_once (void); | 3729 | extern void init_alloc_once (void); |
| 3734 | extern void init_alloc (void); | 3730 | extern void init_alloc (void); |
| @@ -4019,7 +4015,8 @@ extern ptrdiff_t marker_byte_position (Lisp_Object); | |||
| 4019 | extern void clear_charpos_cache (struct buffer *); | 4015 | extern void clear_charpos_cache (struct buffer *); |
| 4020 | extern ptrdiff_t buf_charpos_to_bytepos (struct buffer *, ptrdiff_t); | 4016 | extern ptrdiff_t buf_charpos_to_bytepos (struct buffer *, ptrdiff_t); |
| 4021 | extern ptrdiff_t buf_bytepos_to_charpos (struct buffer *, ptrdiff_t); | 4017 | extern ptrdiff_t buf_bytepos_to_charpos (struct buffer *, ptrdiff_t); |
| 4022 | extern void unchain_marker (struct Lisp_Marker *marker); | 4018 | extern void detach_marker (Lisp_Object); |
| 4019 | extern void unchain_marker (struct Lisp_Marker *); | ||
| 4023 | extern Lisp_Object set_marker_restricted (Lisp_Object, Lisp_Object, Lisp_Object); | 4020 | extern Lisp_Object set_marker_restricted (Lisp_Object, Lisp_Object, Lisp_Object); |
| 4024 | extern Lisp_Object set_marker_both (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); | 4021 | extern Lisp_Object set_marker_both (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); |
| 4025 | extern Lisp_Object set_marker_restricted_both (Lisp_Object, Lisp_Object, | 4022 | extern Lisp_Object set_marker_restricted_both (Lisp_Object, Lisp_Object, |
diff --git a/src/marker.c b/src/marker.c index 7773c4fce0f..432fdd4cbfa 100644 --- a/src/marker.c +++ b/src/marker.c | |||
| @@ -530,7 +530,7 @@ POSITION is nil, makes marker point nowhere so it no longer slows down | |||
| 530 | editing in any buffer. Returns MARKER. */) | 530 | editing in any buffer. Returns MARKER. */) |
| 531 | (Lisp_Object marker, Lisp_Object position, Lisp_Object buffer) | 531 | (Lisp_Object marker, Lisp_Object position, Lisp_Object buffer) |
| 532 | { | 532 | { |
| 533 | return set_marker_internal (marker, position, buffer, 0); | 533 | return set_marker_internal (marker, position, buffer, false); |
| 534 | } | 534 | } |
| 535 | 535 | ||
| 536 | /* Like the above, but won't let the position be outside the visible part. */ | 536 | /* Like the above, but won't let the position be outside the visible part. */ |
| @@ -539,7 +539,7 @@ Lisp_Object | |||
| 539 | set_marker_restricted (Lisp_Object marker, Lisp_Object position, | 539 | set_marker_restricted (Lisp_Object marker, Lisp_Object position, |
| 540 | Lisp_Object buffer) | 540 | Lisp_Object buffer) |
| 541 | { | 541 | { |
| 542 | return set_marker_internal (marker, position, buffer, 1); | 542 | return set_marker_internal (marker, position, buffer, true); |
| 543 | } | 543 | } |
| 544 | 544 | ||
| 545 | /* Set the position of MARKER, specifying both the | 545 | /* Set the position of MARKER, specifying both the |
| @@ -586,6 +586,15 @@ set_marker_restricted_both (Lisp_Object marker, Lisp_Object buffer, | |||
| 586 | return marker; | 586 | return marker; |
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | /* Detach a marker so that it no longer points anywhere and no longer | ||
| 590 | slows down editing. Do not free the marker, though, as a change | ||
| 591 | function could have inserted it into an undo list (Bug#30931). */ | ||
| 592 | void | ||
| 593 | detach_marker (Lisp_Object marker) | ||
| 594 | { | ||
| 595 | Fset_marker (marker, Qnil, Qnil); | ||
| 596 | } | ||
| 597 | |||
| 589 | /* Remove MARKER from the chain of whatever buffer it is in, | 598 | /* Remove MARKER from the chain of whatever buffer it is in, |
| 590 | leaving it points to nowhere. This is called during garbage | 599 | leaving it points to nowhere. This is called during garbage |
| 591 | collection, so we must be careful to ignore and preserve | 600 | collection, so we must be careful to ignore and preserve |
diff --git a/src/xterm.c b/src/xterm.c index f6f2079ec69..496effaf42a 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -11548,7 +11548,8 @@ x_make_frame_visible (struct frame *f) | |||
| 11548 | poll_for_input_1 (); | 11548 | poll_for_input_1 (); |
| 11549 | poll_suppress_count = old_poll_suppress_count; | 11549 | poll_suppress_count = old_poll_suppress_count; |
| 11550 | #endif | 11550 | #endif |
| 11551 | x_wait_for_event (f, MapNotify); | 11551 | if (! FRAME_VISIBLE_P (f)) |
| 11552 | x_wait_for_event (f, MapNotify); | ||
| 11552 | } | 11553 | } |
| 11553 | } | 11554 | } |
| 11554 | 11555 | ||
diff --git a/test/lisp/emacs-lisp/cl-print-tests.el b/test/lisp/emacs-lisp/cl-print-tests.el index 660d5c80692..d986c4015d7 100644 --- a/test/lisp/emacs-lisp/cl-print-tests.el +++ b/test/lisp/emacs-lisp/cl-print-tests.el | |||
| @@ -55,4 +55,14 @@ | |||
| 55 | (let ((print-circle t)) | 55 | (let ((print-circle t)) |
| 56 | (should (equal "(#1=(a . #1#) #1#)" (cl-prin1-to-string x)))))) | 56 | (should (equal "(#1=(a . #1#) #1#)" (cl-prin1-to-string x)))))) |
| 57 | 57 | ||
| 58 | (ert-deftest cl-print-circle-2 () | ||
| 59 | ;; Bug#31146. | ||
| 60 | (let ((x '(0 . #1=(0 . #1#)))) | ||
| 61 | (let ((print-circle nil)) | ||
| 62 | (should (string-match "\\`(0 0 . #[0-9])\\'" | ||
| 63 | (cl-prin1-to-string x)))) | ||
| 64 | (let ((print-circle t)) | ||
| 65 | (should (equal "(0 . #1=(0 . #1#))" (cl-prin1-to-string x)))))) | ||
| 66 | |||
| 67 | |||
| 58 | ;;; cl-print-tests.el ends here. | 68 | ;;; cl-print-tests.el ends here. |
diff --git a/test/src/data-tests.el b/test/src/data-tests.el index dda1278b6d4..91463db113c 100644 --- a/test/src/data-tests.el +++ b/test/src/data-tests.el | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ;;; data-tests.el --- tests for src/data.c | 1 | ;;; data-tests.el --- tests for src/data.c -*- lexical-binding:t -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2013-2018 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2013-2018 Free Software Foundation, Inc. |
| 4 | 4 | ||
| @@ -484,3 +484,20 @@ comparing the subr with a much slower lisp implementation." | |||
| 484 | (remove-variable-watcher 'data-tests-lvar collect-watch-data) | 484 | (remove-variable-watcher 'data-tests-lvar collect-watch-data) |
| 485 | (setq data-tests-lvar 6) | 485 | (setq data-tests-lvar 6) |
| 486 | (should (null watch-data))))) | 486 | (should (null watch-data))))) |
| 487 | |||
| 488 | (ert-deftest data-tests-kill-all-local-variables () ;bug#30846 | ||
| 489 | (with-temp-buffer | ||
| 490 | (setq-local data-tests-foo1 1) | ||
| 491 | (setq-local data-tests-foo2 2) | ||
| 492 | (setq-local data-tests-foo3 3) | ||
| 493 | (let ((oldfoo2 nil)) | ||
| 494 | (add-variable-watcher 'data-tests-foo2 | ||
| 495 | (lambda (&rest _) | ||
| 496 | (setq oldfoo2 (bound-and-true-p data-tests-foo2)))) | ||
| 497 | (kill-all-local-variables) | ||
| 498 | (should (equal oldfoo2 '2)) ;Watcher is run before changing the var. | ||
| 499 | (should (not (or (bound-and-true-p data-tests-foo1) | ||
| 500 | (bound-and-true-p data-tests-foo2) | ||
| 501 | (bound-and-true-p data-tests-foo3))))))) | ||
| 502 | |||
| 503 | ;;; data-tests.el ends here | ||
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el index b72f37d1f01..714e92e5053 100644 --- a/test/src/editfns-tests.el +++ b/test/src/editfns-tests.el | |||
| @@ -247,4 +247,55 @@ | |||
| 247 | (buffer-string) | 247 | (buffer-string) |
| 248 | "foo bar baz qux")))))) | 248 | "foo bar baz qux")))))) |
| 249 | 249 | ||
| 250 | (ert-deftest delete-region-undo-markers-1 () | ||
| 251 | "Make sure we don't end up with freed markers reachable from Lisp." | ||
| 252 | ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=30931#40 | ||
| 253 | (with-temp-buffer | ||
| 254 | (insert "1234567890") | ||
| 255 | (setq buffer-undo-list nil) | ||
| 256 | (narrow-to-region 2 5) | ||
| 257 | ;; `save-restriction' in a narrowed buffer creates two markers | ||
| 258 | ;; representing the current restriction. | ||
| 259 | (save-restriction | ||
| 260 | (widen) | ||
| 261 | ;; Any markers *within* the deleted region are put onto the undo | ||
| 262 | ;; list. | ||
| 263 | (delete-region 1 6)) | ||
| 264 | ;; (princ (format "%S" buffer-undo-list) #'external-debugging-output) | ||
| 265 | ;; `buffer-undo-list' is now | ||
| 266 | ;; (("12345" . 1) (#<temp-marker1> . -1) (#<temp-marker2> . 1)) | ||
| 267 | ;; | ||
| 268 | ;; If temp-marker1 or temp-marker2 are freed prematurely, calling | ||
| 269 | ;; `type-of' on them will cause Emacs to abort. Calling | ||
| 270 | ;; `garbage-collect' will also abort if it finds any reachable | ||
| 271 | ;; freed objects. | ||
| 272 | (should (eq (type-of (car (nth 1 buffer-undo-list))) 'marker)) | ||
| 273 | (should (eq (type-of (car (nth 2 buffer-undo-list))) 'marker)) | ||
| 274 | (garbage-collect))) | ||
| 275 | |||
| 276 | (ert-deftest delete-region-undo-markers-2 () | ||
| 277 | "Make sure we don't end up with freed markers reachable from Lisp." | ||
| 278 | ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=30931#55 | ||
| 279 | (with-temp-buffer | ||
| 280 | (insert "1234567890") | ||
| 281 | (setq buffer-undo-list nil) | ||
| 282 | ;; signal_before_change creates markers delimiting a change | ||
| 283 | ;; region. | ||
| 284 | (let ((before-change-functions | ||
| 285 | (list (lambda (beg end) | ||
| 286 | (delete-region (1- beg) (1+ end)))))) | ||
| 287 | (delete-region 2 5)) | ||
| 288 | ;; (princ (format "%S" buffer-undo-list) #'external-debugging-output) | ||
| 289 | ;; `buffer-undo-list' is now | ||
| 290 | ;; (("678" . 1) ("12345" . 1) (#<marker in no buffer> . -1) | ||
| 291 | ;; (#<temp-marker1> . -1) (#<temp-marker2> . -4)) | ||
| 292 | ;; | ||
| 293 | ;; If temp-marker1 or temp-marker2 are freed prematurely, calling | ||
| 294 | ;; `type-of' on them will cause Emacs to abort. Calling | ||
| 295 | ;; `garbage-collect' will also abort if it finds any reachable | ||
| 296 | ;; freed objects. | ||
| 297 | (should (eq (type-of (car (nth 3 buffer-undo-list))) 'marker)) | ||
| 298 | (should (eq (type-of (car (nth 4 buffer-undo-list))) 'marker)) | ||
| 299 | (garbage-collect))) | ||
| 300 | |||
| 250 | ;;; editfns-tests.el ends here | 301 | ;;; editfns-tests.el ends here |