------------------------------------------------------------ revno: 117488 fixes bug: http://debbugs.gnu.org/17829 committer: Juri Linkov branch nick: trunk timestamp: Tue 2014-07-08 11:27:46 +0300 message: * lisp/simple.el (transpose-chars): Don't move point into read-only area. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-07-08 08:02:50 +0000 +++ lisp/ChangeLog 2014-07-08 08:27:46 +0000 @@ -1,5 +1,10 @@ 2014-07-08 Juri Linkov + * simple.el (transpose-chars): Don't move point into read-only area. + (Bug#17829) + +2014-07-08 Juri Linkov + * window.el (with-displayed-buffer-window): New macro. (with-temp-buffer-window, with-current-buffer-window): Use `macroexp-let2' to evaluate and bind variables === modified file 'lisp/simple.el' --- lisp/simple.el 2014-07-01 18:13:28 +0000 +++ lisp/simple.el 2014-07-08 08:27:46 +0000 @@ -5934,7 +5934,9 @@ and drag it forward past ARG other characters (backward if ARG negative). If no argument and at end of line, the previous two chars are exchanged." (interactive "*P") - (and (null arg) (eolp) (forward-char -1)) + (when (and (null arg) (eolp) (not (bobp)) + (not (get-text-property (1- (point)) 'read-only))) + (forward-char -1)) (transpose-subr 'forward-char (prefix-numeric-value arg))) (defun transpose-words (arg) ------------------------------------------------------------ revno: 117487 fixes bug: http://debbugs.gnu.org/17809 committer: Juri Linkov branch nick: trunk timestamp: Tue 2014-07-08 11:02:50 +0300 message: * lisp/window.el (with-displayed-buffer-window): New macro. (with-temp-buffer-window, with-current-buffer-window): Use `macroexp-let2' to evaluate and bind variables in the same order as macro arguments. (display-buffer--action-function-custom-type): Add `display-buffer-below-selected' and `display-buffer-at-bottom'. * lisp/minibuffer.el (minibuffer-completion-help): Replace `with-output-to-temp-buffer' with `with-displayed-buffer-window' with actions that display *Completions* at-bottom when called from the minibuffer, or below-selected in a normal buffer. Associate `window-height' with `fit-window-to-buffer'. Let-bind `pop-up-windows' to nil. * lisp/dired.el (dired-mark-pop-up): Use `with-displayed-buffer-window' instead of `with-current-buffer-window'. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-07-08 01:52:48 +0000 +++ lisp/ChangeLog 2014-07-08 08:02:50 +0000 @@ -1,3 +1,22 @@ +2014-07-08 Juri Linkov + + * window.el (with-displayed-buffer-window): New macro. + (with-temp-buffer-window, with-current-buffer-window): + Use `macroexp-let2' to evaluate and bind variables + in the same order as macro arguments. + (display-buffer--action-function-custom-type): Add + `display-buffer-below-selected' and `display-buffer-at-bottom'. + + * minibuffer.el (minibuffer-completion-help): Replace + `with-output-to-temp-buffer' with `with-displayed-buffer-window' + with actions that display *Completions* at-bottom when called + from the minibuffer, or below-selected in a normal buffer. + Associate `window-height' with `fit-window-to-buffer'. + Let-bind `pop-up-windows' to nil. + + * dired.el (dired-mark-pop-up): Use `with-displayed-buffer-window' + instead of `with-current-buffer-window'. (Bug#17809) + 2014-07-07 Luke Lee * progmodes/hideif.el (hide-ifdef-env): Change to global. === modified file 'lisp/dired.el' --- lisp/dired.el 2014-06-21 19:45:59 +0000 +++ lisp/dired.el 2014-07-08 08:02:50 +0000 @@ -3103,20 +3103,20 @@ ;; Mark *Marked Files* window as softly-dedicated, to prevent ;; other buffers e.g. *Completions* from reusing it (bug#17554). (display-buffer-mark-dedicated 'soft)) - (with-current-buffer buffer - (with-current-buffer-window - buffer - (cons 'display-buffer-below-selected - '((window-height . fit-window-to-buffer))) - #'(lambda (window _value) - (with-selected-window window - (unwind-protect - (apply function args) - (when (window-live-p window) - (quit-restore-window window 'kill))))) - ;; Handle (t FILE) just like (FILE), here. That value is - ;; used (only in some cases), to mean just one file that was - ;; marked, rather than the current line file. + (with-displayed-buffer-window + buffer + (cons 'display-buffer-below-selected + '((window-height . fit-window-to-buffer))) + #'(lambda (window _value) + (with-selected-window window + (unwind-protect + (apply function args) + (when (window-live-p window) + (quit-restore-window window 'kill))))) + ;; Handle (t FILE) just like (FILE), here. That value is + ;; used (only in some cases), to mean just one file that was + ;; marked, rather than the current line file. + (with-current-buffer buffer (dired-format-columns-of-files (if (eq (car files) t) (cdr files) files)) (remove-text-properties (point-min) (point-max) === modified file 'lisp/minibuffer.el' --- lisp/minibuffer.el 2014-06-25 10:36:51 +0000 +++ lisp/minibuffer.el 2014-07-08 08:02:50 +0000 @@ -1794,8 +1794,29 @@ ;; window, mark it as softly-dedicated, so bury-buffer in ;; minibuffer-hide-completions will know whether to ;; delete the window or not. - (display-buffer-mark-dedicated 'soft)) - (with-output-to-temp-buffer "*Completions*" + (display-buffer-mark-dedicated 'soft) + ;; Disable `pop-up-windows' temporarily to allow + ;; `display-buffer--maybe-pop-up-frame-or-window' + ;; in the display actions below to pop up a frame + ;; if `pop-up-frames' is non-nil, but not to pop up a window. + (pop-up-windows nil)) + (with-displayed-buffer-window + "*Completions*" + ;; This is a copy of `display-buffer-fallback-action' + ;; where `display-buffer-use-some-window' is replaced + ;; with `display-buffer-at-bottom'. + `((display-buffer--maybe-same-window + display-buffer-reuse-window + display-buffer--maybe-pop-up-frame-or-window + ;; Use `display-buffer-below-selected' for inline completions, + ;; but not in the minibuffer (e.g. in `eval-expression') + ;; for which `display-buffer-at-bottom' is used. + ,(if (and completion-in-region-mode-predicate + (not (minibuffer-selected-window))) + 'display-buffer-below-selected + 'display-buffer-at-bottom)) + (window-height . fit-window-to-buffer)) + nil ;; Remove the base-size tail because `sort' requires a properly ;; nil-terminated list. (when last (setcdr last nil)) === modified file 'lisp/window.el' --- lisp/window.el 2014-06-18 07:57:27 +0000 +++ lisp/window.el 2014-07-08 08:02:50 +0000 @@ -185,16 +185,19 @@ (let ((buffer (make-symbol "buffer")) (window (make-symbol "window")) (value (make-symbol "value"))) - `(let* ((,buffer (temp-buffer-window-setup ,buffer-or-name)) - (standard-output ,buffer) - ,window ,value) - (setq ,value (progn ,@body)) - (with-current-buffer ,buffer - (setq ,window (temp-buffer-window-show ,buffer ,action))) + (macroexp-let2 nil vbuffer-or-name buffer-or-name + (macroexp-let2 nil vaction action + (macroexp-let2 nil vquit-function quit-function + `(let* ((,buffer (temp-buffer-window-setup ,vbuffer-or-name)) + (standard-output ,buffer) + ,window ,value) + (setq ,value (progn ,@body)) + (with-current-buffer ,buffer + (setq ,window (temp-buffer-window-show ,buffer ,vaction))) - (if (functionp ,quit-function) - (funcall ,quit-function ,window ,value) - ,value)))) + (if (functionp ,vquit-function) + (funcall ,vquit-function ,window ,value) + ,value))))))) (defmacro with-current-buffer-window (buffer-or-name action quit-function &rest body) "Evaluate BODY with a buffer BUFFER-OR-NAME current and show that buffer. @@ -205,16 +208,50 @@ (let ((buffer (make-symbol "buffer")) (window (make-symbol "window")) (value (make-symbol "value"))) - `(let* ((,buffer (temp-buffer-window-setup ,buffer-or-name)) - (standard-output ,buffer) - ,window ,value) - (with-current-buffer ,buffer - (setq ,value (progn ,@body)) - (setq ,window (temp-buffer-window-show ,buffer ,action))) - - (if (functionp ,quit-function) - (funcall ,quit-function ,window ,value) - ,value)))) + (macroexp-let2 nil vbuffer-or-name buffer-or-name + (macroexp-let2 nil vaction action + (macroexp-let2 nil vquit-function quit-function + `(let* ((,buffer (temp-buffer-window-setup ,vbuffer-or-name)) + (standard-output ,buffer) + ,window ,value) + (with-current-buffer ,buffer + (setq ,value (progn ,@body)) + (setq ,window (temp-buffer-window-show ,buffer ,vaction))) + + (if (functionp ,vquit-function) + (funcall ,vquit-function ,window ,value) + ,value))))))) + +(defmacro with-displayed-buffer-window (buffer-or-name action quit-function &rest body) + "Show a buffer BUFFER-OR-NAME and evaluate BODY in that buffer. +This construct is like `with-current-buffer-window' but unlike that +displays the buffer specified by BUFFER-OR-NAME before running BODY." + (declare (debug t)) + (let ((buffer (make-symbol "buffer")) + (window (make-symbol "window")) + (value (make-symbol "value"))) + (macroexp-let2 nil vbuffer-or-name buffer-or-name + (macroexp-let2 nil vaction action + (macroexp-let2 nil vquit-function quit-function + `(let* ((,buffer (temp-buffer-window-setup ,vbuffer-or-name)) + (standard-output ,buffer) + ,window ,value) + (with-current-buffer ,buffer + (setq ,window (temp-buffer-window-show ,buffer ,vaction))) + + (let ((inhibit-read-only t) + (inhibit-modification-hooks t)) + (setq ,value (progn ,@body))) + + (set-window-point ,window (point-min)) + + (when (functionp (cdr (assq 'window-height (cdr ,vaction)))) + (ignore-errors + (funcall (cdr (assq 'window-height (cdr ,vaction))) ,window))) + + (if (functionp ,vquit-function) + (funcall ,vquit-function ,window ,value) + ,value))))))) ;; The following two functions are like `window-next-sibling' and ;; `window-prev-sibling' but the WINDOW argument is _not_ optional (so @@ -5980,6 +6017,8 @@ (const display-buffer-pop-up-window) (const display-buffer-same-window) (const display-buffer-pop-up-frame) + (const display-buffer-below-selected) + (const display-buffer-at-bottom) (const display-buffer-in-previous-window) (const display-buffer-use-some-window) (function :tag "Other function")) ------------------------------------------------------------ revno: 117486 committer: Dmitry Antipov branch nick: trunk timestamp: Tue 2014-07-08 11:17:04 +0400 message: * chartab.c (char_table_translate): Move to... * character.h (char_table_translate): ... inline function here. Avoid Faref and assume that args are always valid. This helps to speedup search, which is especially important for a huge buffers. * lisp.h (char_table_translate): Remove prototype. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-07-08 06:24:07 +0000 +++ src/ChangeLog 2014-07-08 07:17:04 +0000 @@ -1,3 +1,11 @@ +2014-07-08 Dmitry Antipov + + * chartab.c (char_table_translate): Move to... + * character.h (char_table_translate): ... inline function here. + Avoid Faref and assume that args are always valid. This helps to + speedup search, which is especially important for a huge buffers. + * lisp.h (char_table_translate): Remove prototype. + 2014-07-08 Paul Eggert * process.c: Add sanity checks for file descriptors (Bug#17844). === modified file 'src/character.h' --- src/character.h 2014-06-23 04:11:29 +0000 +++ src/character.h 2014-07-08 07:17:04 +0000 @@ -667,6 +667,20 @@ #define GET_TRANSLATION_TABLE(id) \ (XCDR (XVECTOR (Vtranslation_table_vector)->contents[(id)])) +/* Look up the element in char table OBJ at index CH, and return it as + an integer. If the element is not a character, return CH itself. */ + +INLINE int +char_table_translate (Lisp_Object obj, int ch) +{ + /* This internal function is expected to be called with valid arguments, + so there is a eassert instead of CHECK_xxx for the sake of speed. */ + eassert (CHAR_VALID_P (ch)); + eassert (CHAR_TABLE_P (obj)); + obj = CHAR_TABLE_REF (obj, ch); + return CHARACTERP (obj) ? XINT (obj) : ch; +} + INLINE_HEADER_END #endif /* EMACS_CHARACTER_H */ === modified file 'src/chartab.c' --- src/chartab.c 2014-07-02 03:26:19 +0000 +++ src/chartab.c 2014-07-08 07:17:04 +0000 @@ -663,19 +663,6 @@ return value; } -/* Look up the element in TABLE at index CH, and return it as an - integer. If the element is not a character, return CH itself. */ - -int -char_table_translate (Lisp_Object table, int ch) -{ - Lisp_Object value; - value = Faref (table, make_number (ch)); - if (! CHARACTERP (value)) - return ch; - return XINT (value); -} - static Lisp_Object optimize_sub_char_table (Lisp_Object table, Lisp_Object test) { === modified file 'src/lisp.h' --- src/lisp.h 2014-07-02 15:22:49 +0000 +++ src/lisp.h 2014-07-08 07:17:04 +0000 @@ -823,7 +823,6 @@ /* Defined in chartab.c. */ extern Lisp_Object char_table_ref (Lisp_Object, int); extern void char_table_set (Lisp_Object, int, Lisp_Object); -extern int char_table_translate (Lisp_Object, int); /* Defined in data.c. */ extern Lisp_Object Qarrayp, Qbufferp, Qbuffer_or_string_p, Qchar_table_p; ------------------------------------------------------------ revno: 117485 fixes bug: http://debbugs.gnu.org/17844 committer: Paul Eggert branch nick: trunk timestamp: Mon 2014-07-07 23:24:07 -0700 message: * process.c: Add sanity checks for file descriptors. (wait_reading_process_output, Fprocess_filter_multibyte_p): Check that infd is nonnegative before using it as an fd. (read_and_dispose_of_process_output, Fprocess_send_eof): Likewise, for outfd. (wait_reading_process_output): Omit unnecessary check of infd. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-07-07 23:33:05 +0000 +++ src/ChangeLog 2014-07-08 06:24:07 +0000 @@ -1,3 +1,12 @@ +2014-07-08 Paul Eggert + + * process.c: Add sanity checks for file descriptors (Bug#17844). + (wait_reading_process_output, Fprocess_filter_multibyte_p): + Check that infd is nonnegative before using it as an fd. + (read_and_dispose_of_process_output, Fprocess_send_eof): + Likewise, for outfd. + (wait_reading_process_output): Omit unnecessary check of infd. + 2014-07-07 Paul Eggert Minor fixups related to usage of the 'long' type. === modified file 'src/process.c' --- src/process.c 2014-06-24 08:10:48 +0000 +++ src/process.c 2014-07-08 06:24:07 +0000 @@ -4462,6 +4462,7 @@ if (wait_proc && wait_proc->raw_status_new) update_status (wait_proc); if (wait_proc + && wait_proc->infd >= 0 && ! EQ (wait_proc->status, Qrun) && ! EQ (wait_proc->status, Qconnect)) { @@ -4471,7 +4472,7 @@ XSETPROCESS (proc, wait_proc); /* Read data from the process, until we exhaust it. */ - while (wait_proc->infd >= 0) + while (true) { int nread = read_process_output (proc, wait_proc->infd); if (nread < 0) @@ -4642,6 +4643,7 @@ > 0)) { nfds = 1; + eassert (0 <= wait_proc->infd); /* Set to Available. */ FD_SET (wait_proc->infd, &Available); } @@ -4909,7 +4911,8 @@ status_notify to do it later, it will read input from the process before calling the sentinel. */ exec_sentinel (proc, build_string ("open\n")); - if (!EQ (p->filter, Qt) && !EQ (p->command, Qt)) + if (0 <= p->infd && !EQ (p->filter, Qt) + && !EQ (p->command, Qt)) { FD_SET (p->infd, &input_wait_mask); FD_SET (p->infd, &non_keyboard_wait_mask); @@ -5131,7 +5134,7 @@ proc_encode_coding_system[p->outfd] surely points to a valid memory because p->outfd will be changed once EOF is sent to the process. */ - if (NILP (p->encode_coding_system) + if (NILP (p->encode_coding_system) && p->outfd && proc_encode_coding_system[p->outfd]) { pset_encode_coding_system @@ -6071,8 +6074,8 @@ for communication with the subprocess, call shutdown to cause EOF. (In some old system, shutdown to socketpair doesn't work. Then we just can't win.) */ - if (EQ (p->type, Qnetwork) - || p->infd == old_outfd) + if (0 <= old_outfd + && (EQ (p->type, Qnetwork) || p->infd == old_outfd)) shutdown (old_outfd, 1); #endif close_process_fd (&p->open_fd[WRITE_TO_SUBPROCESS]); @@ -6546,6 +6549,8 @@ CHECK_PROCESS (process); p = XPROCESS (process); + if (p->infd < 0) + return Qnil; coding = proc_decode_coding_system[p->infd]; return (CODING_FOR_UNIBYTE (coding) ? Qnil : Qt); } ------------------------------------------------------------ revno: 117484 committer: Luke Lee branch nick: trunk timestamp: Tue 2014-07-08 09:52:48 +0800 message: ChangeLog fix: correcting file path. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-07-07 08:59:32 +0000 +++ lisp/ChangeLog 2014-07-08 01:52:48 +0000 @@ -1,6 +1,6 @@ 2014-07-07 Luke Lee - * lisp/progmodes/hideif.el (hide-ifdef-env): Change to global. + * progmodes/hideif.el (hide-ifdef-env): Change to global. (hide-ifdef-env-backup): New variable. (hide-ifdef-expand-reinclusion-protection, hide-ifdef-header-regexp): New customizable variables. ------------------------------------------------------------ revno: 117483 author: Paul Eggert committer: Paul Eggert branch nick: trunk timestamp: Mon 2014-07-07 16:33:05 -0700 message: Minor fixups related to usage of the 'long' type. * gnutls.c (emacs_gnutls_handshake): * xfaces.c (dump_realized_face): Work even if 'long' is narrower than 'void *'. * termcap.c (scan_file): * xselect.c (x_decline_selection_request) (x_reply_selection_request, x_get_window_property): * xterm.c (x_set_frame_alpha): Remove unnecessary 'L' suffixes of integer constants. * xfns.c (hack_wm_protocols): * xselect.c (x_fill_property_data): * xterm.c (x_set_offset, x_set_window_size_1, x_make_frame_invisible): Remove unnecessary casts to 'long'. (set_machine_and_pid_properties): Don't assume pid_t fits in 32 bits. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-07-07 23:25:13 +0000 +++ src/ChangeLog 2014-07-07 23:33:05 +0000 @@ -1,5 +1,20 @@ 2014-07-07 Paul Eggert + Minor fixups related to usage of the 'long' type. + * gnutls.c (emacs_gnutls_handshake): + * xfaces.c (dump_realized_face): + Work even if 'long' is narrower than 'void *'. + * termcap.c (scan_file): + * xselect.c (x_decline_selection_request) + (x_reply_selection_request, x_get_window_property): + * xterm.c (x_set_frame_alpha): + Remove unnecessary 'L' suffixes of integer constants. + * xfns.c (hack_wm_protocols): + * xselect.c (x_fill_property_data): + * xterm.c (x_set_offset, x_set_window_size_1, x_make_frame_invisible): + Remove unnecessary casts to 'long'. + (set_machine_and_pid_properties): Don't assume pid_t fits in 32 bits. + Minor ImageMagick safety fixes. * image.c (imagemagick_compute_animated_image): Remove useless assignment to local. Avoid problems if dest_width is 0. === modified file 'src/gnutls.c' --- src/gnutls.c 2014-04-05 19:30:36 +0000 +++ src/gnutls.c 2014-07-07 23:33:05 +0000 @@ -336,8 +336,8 @@ in. For an Emacs process socket, infd and outfd are the same but we use this two-argument version for clarity. */ fn_gnutls_transport_set_ptr2 (state, - (gnutls_transport_ptr_t) (long) proc->infd, - (gnutls_transport_ptr_t) (long) proc->outfd); + (void *) (intptr_t) proc->infd, + (void *) (intptr_t) proc->outfd); #endif proc->gnutls_initstage = GNUTLS_STAGE_TRANSPORT_POINTERS_SET; === modified file 'src/termcap.c' --- src/termcap.c 2014-01-01 07:43:34 +0000 +++ src/termcap.c 2014-07-07 23:33:05 +0000 @@ -520,7 +520,7 @@ bufp->ateof = 0; *bufp->ptr = '\0'; - lseek (fd, 0L, 0); + lseek (fd, 0, 0); while (!bufp->ateof) { === modified file 'src/xfaces.c' --- src/xfaces.c 2014-07-03 06:00:53 +0000 +++ src/xfaces.c 2014-07-07 23:33:05 +0000 @@ -6299,7 +6299,7 @@ { fprintf (stderr, "ID: %d\n", face->id); #ifdef HAVE_X_WINDOWS - fprintf (stderr, "gc: %ld\n", (long) face->gc); + fprintf (stderr, "gc: %p\n", face->gc); #endif fprintf (stderr, "foreground: 0x%lx (%s)\n", face->foreground, === modified file 'src/xfns.c' --- src/xfns.c 2014-06-29 16:12:08 +0000 +++ src/xfns.c 2014-07-07 23:33:05 +0000 @@ -1595,7 +1595,7 @@ if ((XGetWindowProperty (dpy, w, FRAME_DISPLAY_INFO (f)->Xatom_wm_protocols, - (long)0, (long)100, False, XA_ATOM, + 0, 100, False, XA_ATOM, &type, &format, &nitems, &bytes_after, &catoms) == Success) @@ -2853,18 +2853,21 @@ static void set_machine_and_pid_properties (struct frame *f) { - long pid = (long) getpid (); - /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME. */ XSetWMProperties (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), NULL, NULL, NULL, 0, NULL, NULL, NULL); - XChangeProperty (FRAME_X_DISPLAY (f), - FRAME_OUTER_WINDOW (f), - XInternAtom (FRAME_X_DISPLAY (f), - "_NET_WM_PID", - False), - XA_CARDINAL, 32, PropModeReplace, - (unsigned char *) &pid, 1); + pid_t pid = getpid (); + if (pid <= 0xffffffffu) + { + unsigned long xpid = pid; + XChangeProperty (FRAME_X_DISPLAY (f), + FRAME_OUTER_WINDOW (f), + XInternAtom (FRAME_X_DISPLAY (f), + "_NET_WM_PID", + False), + XA_CARDINAL, 32, PropModeReplace, + (unsigned char *) &xpid, 1); + } } DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, === modified file 'src/xselect.c' --- src/xselect.c 2014-07-04 02:28:54 +0000 +++ src/xselect.c 2014-07-07 23:33:05 +0000 @@ -458,7 +458,7 @@ died in the meantime. Handle that case. */ block_input (); x_catch_errors (reply->display); - XSendEvent (reply->display, reply->requestor, False, 0L, &reply_base); + XSendEvent (reply->display, reply->requestor, False, 0, &reply_base); XFlush (reply->display); x_uncatch_errors (); unblock_input (); @@ -632,7 +632,7 @@ } /* Now issue the SelectionNotify event. */ - XSendEvent (display, window, False, 0L, &reply_base); + XSendEvent (display, window, False, 0, &reply_base); XFlush (display); #ifdef TRACE_SELECTION @@ -710,7 +710,7 @@ requestor that we're done. */ block_input (); if (! waiting_for_other_props_on_window (display, window)) - XSelectInput (display, window, 0L); + XSelectInput (display, window, 0); TRACE1 ("Set %s to a 0-length chunk to indicate EOF", XGetAtomName (display, cs->property)); @@ -1283,7 +1283,7 @@ /* First probe the thing to find out how big it is. */ result = XGetWindowProperty (display, window, property, - 0L, 0L, False, AnyPropertyType, + 0, 0, False, AnyPropertyType, actual_type_ret, actual_format_ret, actual_size_ret, &bytes_remaining, &tmp_data); @@ -2314,7 +2314,7 @@ else if (STRINGP (o)) { block_input (); - val = (long) XInternAtom (dpy, SSDATA (o), False); + val = XInternAtom (dpy, SSDATA (o), False); unblock_input (); } else === modified file 'src/xterm.c' --- src/xterm.c 2014-06-23 04:11:29 +0000 +++ src/xterm.c 2014-07-07 23:33:05 +0000 @@ -410,7 +410,7 @@ if (parent != None) XChangeProperty (dpy, parent, dpyinfo->Xatom_net_wm_window_opacity, XA_CARDINAL, 32, PropModeReplace, - (unsigned char *) &opac, 1L); + (unsigned char *) &opac, 1); /* return unless necessary */ { @@ -420,7 +420,7 @@ unsigned long n, left; rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity, - 0L, 1L, False, XA_CARDINAL, + 0, 1, False, XA_CARDINAL, &actual, &format, &n, &left, &data); @@ -438,7 +438,7 @@ XChangeProperty (dpy, win, dpyinfo->Xatom_net_wm_window_opacity, XA_CARDINAL, 32, PropModeReplace, - (unsigned char *) &opac, 1L); + (unsigned char *) &opac, 1); x_uncatch_errors (); } @@ -8094,7 +8094,7 @@ x_calc_absolute_position (f); block_input (); - x_wm_set_size_hint (f, (long) 0, 0); + x_wm_set_size_hint (f, 0, 0); modified_left = f->left_pos; modified_top = f->top_pos; @@ -8639,7 +8639,7 @@ + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f)); if (change_gravity) f->win_gravity = NorthWestGravity; - x_wm_set_size_hint (f, (long) 0, 0); + x_wm_set_size_hint (f, 0, 0); XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), pixelwidth, pixelheight); @@ -9046,7 +9046,7 @@ program-specified, so that when the window is mapped again, it will be placed at the same location, without forcing the user to position it by hand again (they have already done that once for this window.) */ - x_wm_set_size_hint (f, (long) 0, 1); + x_wm_set_size_hint (f, 0, 1); #ifdef USE_GTK if (FRAME_GTK_OUTER_WIDGET (f)) ------------------------------------------------------------ revno: 117482 committer: Paul Eggert branch nick: trunk timestamp: Mon 2014-07-07 16:25:13 -0700 message: Minor ImageMagick safety fixes. * image.c (imagemagick_compute_animated_image): Remove useless assignment to local. Avoid problems if dest_width is 0. (imagemagick_load_image): Use int for pixel counts that can't exceed INT_MAX. Avoid problem if PixelGetNextIteratorRow returns a row width greater than the image width (or greater than LONG_MAX!). diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-07-05 14:07:57 +0000 +++ src/ChangeLog 2014-07-07 23:25:13 +0000 @@ -1,3 +1,12 @@ +2014-07-07 Paul Eggert + + Minor ImageMagick safety fixes. + * image.c (imagemagick_compute_animated_image): + Remove useless assignment to local. Avoid problems if dest_width is 0. + (imagemagick_load_image): Use int for pixel counts that can't + exceed INT_MAX. Avoid problem if PixelGetNextIteratorRow returns + a row width greater than the image width (or greater than LONG_MAX!). + 2014-07-04 K. Handa * coding.c (MIN_CHARBUF_SIZE): Delete it. === modified file 'src/image.c' --- src/image.c 2014-06-24 08:10:48 +0000 +++ src/image.c 2014-07-07 23:25:13 +0000 @@ -8059,7 +8059,6 @@ else composite_wand = cache->wand; - dest_width = MagickGetImageWidth (composite_wand); dest_height = MagickGetImageHeight (composite_wand); for (i = max (1, cache->index + 1); i <= ino; i++) @@ -8128,13 +8127,12 @@ { /* Sanity check. This shouldn't happen, but apparently also does in some pictures. */ - if (x + source_left > dest_width - 1) + if (x + source_left >= dest_width) break; /* Normally we only copy over non-transparent pixels, but if the disposal method is "Background", then we copy over all pixels. */ - if (dispose == BackgroundDispose || - PixelGetAlpha (source[x])) + if (dispose == BackgroundDispose || PixelGetAlpha (source[x])) { PixelGetMagickColor (source[x], &pixel); PixelSetMagickColor (dest[x + source_left], &pixel); @@ -8174,7 +8172,8 @@ unsigned char *contents, unsigned int size, char *filename) { - size_t width, height; + int width, height; + size_t image_width, image_height; MagickBooleanType status; XImagePtr ximg; int x, y; @@ -8344,16 +8343,19 @@ /* Finally we are done manipulating the image. Figure out the resulting width/height and transfer ownership to Emacs. */ - height = MagickGetImageHeight (image_wand); - width = MagickGetImageWidth (image_wand); + image_height = MagickGetImageHeight (image_wand); + image_width = MagickGetImageWidth (image_wand); - if (! (width <= INT_MAX && height <= INT_MAX - && check_image_size (f, width, height))) + if (! (image_width <= INT_MAX && image_height <= INT_MAX + && check_image_size (f, image_width, image_height))) { image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); goto imagemagick_error; } + width = image_width; + height = image_height; + /* We can now get a valid pixel buffer from the imagemagick file, if all went ok. */ @@ -8438,10 +8440,12 @@ image_height = MagickGetImageHeight (image_wand); for (y = 0; y < image_height; y++) { - pixels = PixelGetNextIteratorRow (iterator, &width); + size_t row_width; + pixels = PixelGetNextIteratorRow (iterator, &row_width); if (! pixels) break; - for (x = 0; x < (long) width; x++) + int xlim = min (row_width, width); + for (x = 0; x < xlim; x++) { PixelGetMagickColor (pixels[x], &pixel); XPutPixel (ximg, x, y, ------------------------------------------------------------ revno: 117481 committer: Luke Lee branch nick: trunk timestamp: Mon 2014-07-07 16:59:32 +0800 message: HideIfDef mode bug fixes and enhancements. This is #3 of 3 patches based on the completed work posted on http://www.emacswiki.org/emacs/HideIfDef. - Add macro evaluation function and key binding for a marked region. - Merge continuous "..." lines into one. - Fix old hideif bugs that fail to hide the correct #elif regions - Support hide/show commands in a marked region. - Expand top level for .h files to prevent re-inclusion protection. - Change maintainer. * lisp/progmodes/hideif.el (hide-ifdef-env): Change to global. (hide-ifdef-env-backup): New variable. (hide-ifdef-expand-reinclusion-protection, hide-ifdef-header-regexp): New customizable variables. (hif-clear-all-ifdef-defined): New defun. (hif-merge-ifdef-region, hide-ifdef-region-internal, hide-ifdef-region) (hif-show-ifdef-region): Merge hidden regions to prevent continuous "...". (hif-tokenize): Fix for MS-DOS/Win EOL style. (hif-endif-to-ifdef, hif-make-range, hif-find-range, hif-possibly-hide): Fix bug to hide the correct #elif region(s). (hif-range-elif): New defun. (hif-recurse-level): New var. (hif-evaluate-region, hif-evaluate-macro): New defun. (hide-ifdef-guts): Prevent reinclusion protected C/C++ headers from fully hidden. (hide-ifdef-define, hide-ifdefs, hide-ifdef-block, show-ifdef-block): Better interaction. diff: === modified file 'etc/NEWS' --- etc/NEWS 2014-06-30 19:58:56 +0000 +++ etc/NEWS 2014-07-07 08:59:32 +0000 @@ -119,6 +119,16 @@ fitting for use in money calculations; factorial works with non-integer inputs. +** HideIfDef mode now support full C/C++ expressions, argumented macro expansions +, interactive macro evaluation and automatic scanning of #defined symbols. + +*** New custom variable `hide-ifdef-header-regexp' to define C/C++ header file +name patterns. Default case-insensitive .h, .hh, .hpp and .hxx. +*** New custom variable `hide-ifdef-expand-reinclusion-protection' to prevent +reinclusion protected header files from being fully hidden. +*** New custom variable `hide-ifdef-exclude-define-regexp' to define symbol +name patterns (e.x. all "FOR_DOXYGEN_ONLY_*") to be excluded. + ** Obsolete packages --- === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-07-04 10:03:14 +0000 +++ lisp/ChangeLog 2014-07-07 08:59:32 +0000 @@ -1,3 +1,23 @@ +2014-07-07 Luke Lee + + * lisp/progmodes/hideif.el (hide-ifdef-env): Change to global. + (hide-ifdef-env-backup): New variable. + (hide-ifdef-expand-reinclusion-protection, hide-ifdef-header-regexp): + New customizable variables. + (hif-clear-all-ifdef-defined): New defun. + (hif-merge-ifdef-region, hide-ifdef-region-internal, hide-ifdef-region) + (hif-show-ifdef-region): Merge hidden regions to prevent continuous "...". + (hif-tokenize): Fix for MS-DOS/Win EOL style. + (hif-endif-to-ifdef, hif-make-range, hif-find-range, hif-possibly-hide): + Fix bug to hide the correct #elif region(s). + (hif-range-elif): New defun. + (hif-recurse-level): New var. + (hif-evaluate-region, hif-evaluate-macro): New defun. + (hide-ifdef-guts): Prevent reinclusion protected C/C++ headers from + fully hidden. + (hide-ifdef-define, hide-ifdefs, hide-ifdef-block, show-ifdef-block): + Better interaction. + 2014-07-04 Michael Albinus * net/dbus.el (dbus-peer-handler): New defun. === modified file 'lisp/progmodes/hideif.el' --- lisp/progmodes/hideif.el 2014-07-02 04:25:21 +0000 +++ lisp/progmodes/hideif.el 2014-07-07 08:59:32 +0000 @@ -4,7 +4,7 @@ ;; Author: Brian Marick ;; Daniel LaLiberte -;; Maintainer: emacs-devel@gnu.org +;; Maintainer: Luke Lee ;; Keywords: c, outlines ;; This file is part of GNU Emacs. @@ -141,6 +141,36 @@ :type 'string :version "24.5") +(defcustom hide-ifdef-expand-reinclusion-protection t + "Non-nil means don't hide an entire header file enclosed by #ifndef...#endif. +Most C/C++ headers are usually wrapped with ifdefs to prevent re-inclusion: + + ----- beginning of file ----- + #ifndef _XXX_HEADER_FILE_INCLUDED_ + #define _XXX_HEADER_FILE_INCLUDED_ + xxx + xxx + xxx... + #endif + ----- end of file ----- + +The first time we visit such a file, _XXX_HEADER_FILE_INCLUDED_ is +undefined, and so nothing is hidden. The next time we visit it, everything will +be hidden. + +This behavior is generally undesirable. If this option is non-nil, the outermost +#if is always visible." + :type 'boolean + :version "24.5") + +(defcustom hide-ifdef-header-regexp + "\\.h\\(h\\|xx\\|pp\\)?\\'" + "C/C++ header file name patterns to determine if current buffer is a header. +Effective only if `hide-ifdef-expand-reinclusion-protection' is t." + :type 'string + :group 'hide-ifdef + :version "24.5") + (defvar hide-ifdef-mode-submap ;; Set up the submap that goes after the prefix key. (let ((map (make-sparse-keymap))) @@ -153,6 +183,8 @@ (define-key map "s" 'show-ifdefs) (define-key map "\C-d" 'hide-ifdef-block) (define-key map "\C-s" 'show-ifdef-block) + (define-key map "e" 'hif-evaluate-macro) + (define-key map "C" 'hif-clear-all-ifdef-defined) (define-key map "\C-q" 'hide-ifdef-toggle-read-only) (define-key map "\C-w" 'hide-ifdef-toggle-shadowing) @@ -217,6 +249,11 @@ (defvar hide-ifdef-env nil "An alist of defined symbols and their values.") +(defvar hide-ifdef-env-backup nil + "This variable is a backup of the previously cleared `hide-ifdef-env'. +This backup prevents any accidental clearance of `hide-fidef-env' by +`hif-clear-all-ifdef-defined'.") + (defvar hif-outside-read-only nil "Internal variable. Saves the value of `buffer-read-only' while hiding.") @@ -233,53 +270,75 @@ Several variables affect how the hiding is done: `hide-ifdef-env' - An association list of defined and undefined symbols for the - current buffer. Initially, the global value of `hide-ifdef-env' - is used. + An association list of defined and undefined symbols for the + current project. Initially, the global value of `hide-ifdef-env' + is used. This variable was a buffer-local variable, which limits + hideif to parse only one C/C++ file at a time. We've extended + hideif to support parsing a C/C++ project containing multiple C/C++ + source files opened simultaneously in different buffers. Therefore + `hide-ifdef-env' can no longer be buffer local but must be global. `hide-ifdef-define-alist' - An association list of defined symbol lists. + An association list of defined symbol lists. Use `hide-ifdef-set-define-alist' to save the current `hide-ifdef-env' and `hide-ifdef-use-define-alist' to set the current `hide-ifdef-env' from one of the lists in `hide-ifdef-define-alist'. `hide-ifdef-lines' - Set to non-nil to not show #if, #ifdef, #ifndef, #else, and - #endif lines when hiding. + Set to non-nil to not show #if, #ifdef, #ifndef, #else, and + #endif lines when hiding. `hide-ifdef-initially' - Indicates whether `hide-ifdefs' should be called when Hide-Ifdef mode - is activated. + Indicates whether `hide-ifdefs' should be called when Hide-Ifdef mode + is activated. `hide-ifdef-read-only' - Set to non-nil if you want to make buffers read only while hiding. - After `show-ifdefs', read-only status is restored to previous value. + Set to non-nil if you want to make buffers read only while hiding. + After `show-ifdefs', read-only status is restored to previous value. \\{hide-ifdef-mode-map}" :group 'hide-ifdef :lighter " Ifdef" (if hide-ifdef-mode (progn - ;; inherit global values - (set (make-local-variable 'hide-ifdef-env) - (default-value 'hide-ifdef-env)) - (set (make-local-variable 'hide-ifdef-hiding) - (default-value 'hide-ifdef-hiding)) - (set (make-local-variable 'hif-outside-read-only) buffer-read-only) - (set (make-local-variable 'line-move-ignore-invisible) t) - (add-hook 'change-major-mode-hook - (lambda () (hide-ifdef-mode -1)) nil t) - - (add-to-invisibility-spec '(hide-ifdef . t)) - - (if hide-ifdef-initially - (hide-ifdefs) - (show-ifdefs))) + ;; inherit global values + + ;; `hide-ifdef-env' is now a global variable. + ;; We can still simulate the behavior of older hideif versions (i.e. + ;; `hide-ifdef-env' being buffer local) by clearing this variable + ;; (C-c @ C) everytime before hiding current buffer. +;; (set (make-local-variable 'hide-ifdef-env) +;; (default-value 'hide-ifdef-env)) + (set 'hide-ifdef-env (default-value 'hide-ifdef-env)) + ;; Some C/C++ headers might have other ways to prevent reinclusion and + ;; thus would like `hide-ifdef-expand-reinclusion-protection' to be nil. + (set (make-local-variable 'hide-ifdef-expand-reinclusion-protection) + (default-value 'hide-ifdef-expand-reinclusion-protection)) + (set (make-local-variable 'hide-ifdef-hiding) + (default-value 'hide-ifdef-hiding)) + (set (make-local-variable 'hif-outside-read-only) buffer-read-only) + (set (make-local-variable 'line-move-ignore-invisible) t) + (add-hook 'change-major-mode-hook + (lambda () (hide-ifdef-mode -1)) nil t) + + (add-to-invisibility-spec '(hide-ifdef . t)) + + (if hide-ifdef-initially + (hide-ifdefs) + (show-ifdefs))) ;; else end hide-ifdef-mode (kill-local-variable 'line-move-ignore-invisible) (remove-from-invisibility-spec '(hide-ifdef . t)) (when hide-ifdef-hiding (show-ifdefs)))) +(defun hif-clear-all-ifdef-defined () + "Clears all symbols defined in `hide-ifdef-env'. +It will backup this variable to `hide-ifdef-env-backup' before clearing to +prevent accidental clearance." + (interactive) + (when (y-or-n-p "Clear all #defined symbols? ") + (setq hide-ifdef-env-backup hide-ifdef-env) + (setq hide-ifdef-env nil))) (defun hif-show-all () "Show all of the text in the current buffer." @@ -299,16 +358,64 @@ (while (= (logand 1 (skip-chars-backward "\\\\")) 1) (end-of-line 2))) +(defun hif-merge-ifdef-region (start end) + "This function merges nearby ifdef regions to form a bigger overlay. +The region is defined by START and END. This will decrease the number of +overlays created." + ;; Generally there is no need to call itself recursively since there should + ;; originally exists no un-merged regions; however, if a part of the file is + ;; hidden with `hide-ifdef-lines' equals to nil while another part with 't, + ;; this case happens. + ;; TODO: Should we merge? or just create a container overlay? -- this can + ;; prevent `hideif-show-ifdef' expanding too many hidden contents since there + ;; is only a big overlay exists there without any smaller overlays. + (save-restriction + (widen) ; Otherwise `point-min' and `point-max' will be restricted and thus + ; fail to find neighbor overlays + (let ((begovrs (overlays-in + (max (- start 2) (point-min)) + (max (- start 1) (point-min)))) + (endovrs (overlays-in + (min (+ end 1) (point-max)) + (min (+ end 2) (point-max)))) + (ob nil) + (oe nil) + b e) + ;; Merge overlays before START + (dolist (o begovrs) + (when (overlay-get o 'hide-ifdef) + (setq b (min start (overlay-start o)) + e (max end (overlay-end o))) + (move-overlay o b e) + (hif-merge-ifdef-region b e) + (setq ob o))) + ;; Merge overlays after END + (dolist (o endovrs) + (when (overlay-get o 'hide-ifdef) + (setq b (min start (overlay-start o)) + e (max end (overlay-end o))) + (move-overlay o b e) + (hif-merge-ifdef-region b e) + (setf oe o))) + ;; If both START and END merging happens, merge into bigger one + (when (and ob oe) + (let ((b (min (overlay-start ob) (overlay-start oe))) + (e (max (overlay-end ob) (overlay-end oe)))) + (delete-overlay oe) + (move-overlay ob b e) + (hif-merge-ifdef-region b e))) + (or ob oe)))) + (defun hide-ifdef-region-internal (start end) - (remove-overlays start end 'hide-ifdef t) + (unless (hif-merge-ifdef-region start end) (let ((o (make-overlay start end))) (overlay-put o 'hide-ifdef t) (if hide-ifdef-shadow - (overlay-put o 'face 'hide-ifdef-shadow) - (overlay-put o 'invisible 'hide-ifdef)))) + (overlay-put o 'face 'hide-ifdef-shadow) + (overlay-put o 'invisible 'hide-ifdef))))) (defun hide-ifdef-region (start end) - "START is the start of a #if or #else form. END is the ending part. + "START is the start of a #if, #elif, or #else form. END is the ending part. Everything including these lines is made invisible." (save-excursion (goto-char start) (hif-end-of-line) (setq start (point)) @@ -317,7 +424,9 @@ (defun hif-show-ifdef-region (start end) "Everything between START and END is made visible." - (remove-overlays start end 'hide-ifdef t)) + (let ((onum (length (overlays-in start end)))) + (remove-overlays start end 'hide-ifdef t) + (/= onum (length (overlays-in start end))))) ;;===%%SF%% evaluation (Start) === @@ -342,11 +451,11 @@ (defun hif-lookup (var) (or (when (bound-and-true-p semantic-c-takeover-hideif) - (semantic-c-hideif-lookup var)) + (semantic-c-hideif-lookup var)) (let ((val (assoc var hide-ifdef-env))) - (if val - (cdr val) - hif-undefined-symbol)))) + (if val + (cdr val) + hif-undefined-symbol)))) (defun hif-defined (var) (cond @@ -362,24 +471,22 @@ ;;===%%SF%% parsing (Start) === ;;; The code that understands what ifs and ifdef in files look like. -(defconst hif-cpp-prefix "\\(^\\|\r\\)[ \t]*#[ \t]*") -(defconst hif-ifxdef-regexp (concat hif-cpp-prefix "if\\(n\\)?def")) -(defconst hif-ifndef-regexp (concat hif-cpp-prefix "ifndef")) -(defconst hif-ifx-regexp (concat hif-cpp-prefix "if\\(n?def\\)?[ \t]+")) -(defconst hif-elif-regexp (concat hif-cpp-prefix "elif")) -(defconst hif-else-regexp (concat hif-cpp-prefix "else")) -(defconst hif-endif-regexp (concat hif-cpp-prefix "endif")) +(defconst hif-cpp-prefix "\\(^\\|\r\\)[ \t]*#[ \t]*") +(defconst hif-ifxdef-regexp (concat hif-cpp-prefix "if\\(n\\)?def")) +(defconst hif-ifndef-regexp (concat hif-cpp-prefix "ifndef")) +(defconst hif-ifx-regexp (concat hif-cpp-prefix "if\\(n?def\\)?[ \t]+")) +(defconst hif-elif-regexp (concat hif-cpp-prefix "elif")) +(defconst hif-else-regexp (concat hif-cpp-prefix "else")) +(defconst hif-endif-regexp (concat hif-cpp-prefix "endif")) (defconst hif-ifx-else-endif-regexp (concat hif-ifx-regexp "\\|" hif-elif-regexp "\\|" hif-else-regexp "\\|" hif-endif-regexp)) (defconst hif-macro-expr-prefix-regexp (concat hif-cpp-prefix "\\(if\\(n?def\\)?\\|elif\\|define\\)[ \t]+")) -(defconst hif-white-regexp "[ \t]*") -(defconst hif-define-regexp - (concat hif-cpp-prefix "\\(define\\|undef\\)")) -(defconst hif-id-regexp - (concat "[[:alpha:]_][[:alnum:]_]*")) +(defconst hif-white-regexp "[ \t]*") +(defconst hif-define-regexp (concat hif-cpp-prefix "\\(define\\|undef\\)")) +(defconst hif-id-regexp (concat "[[:alpha:]_][[:alnum:]_]*")) (defconst hif-macroref-regexp (concat hif-white-regexp "\\(" hif-id-regexp "\\)" hif-white-regexp "\\(" @@ -398,9 +505,9 @@ (defconst hif-token-alist '(("||" . hif-or) ("&&" . hif-and) - ("|" . hif-logior) + ("|" . hif-logior) ("^" . hif-logxor) - ("&" . hif-logand) + ("&" . hif-logand) ("<<" . hif-shiftleft) (">>" . hif-shiftright) ("==" . hif-equal) @@ -408,22 +515,22 @@ ;; expression syntax, because they are still relevant for the tokenizer, ;; especially in conjunction with ##. ("=" . hif-assign) - ("!=" . hif-notequal) + ("!=" . hif-notequal) ("##" . hif-token-concat) ("!" . hif-not) ("~" . hif-lognot) ("(" . hif-lparen) (")" . hif-rparen) - (">" . hif-greater) - ("<" . hif-less) - (">=" . hif-greater-equal) - ("<=" . hif-less-equal) - ("+" . hif-plus) - ("-" . hif-minus) + (">" . hif-greater) + ("<" . hif-less) + (">=" . hif-greater-equal) + ("<=" . hif-less-equal) + ("+" . hif-plus) + ("-" . hif-minus) ("*" . hif-multiply) ("/" . hif-divide) ("%" . hif-modulo) - ("?" . hif-conditional) + ("?" . hif-conditional) (":" . hif-colon) ("," . hif-comma) ("#" . hif-stringify) @@ -465,23 +572,23 @@ (setq hif-simple-token-only t) (with-syntax-table hide-ifdef-syntax-table (save-excursion - (goto-char start) - (while (progn (forward-comment (point-max)) (< (point) end)) - ;; (message "expr-start = %d" expr-start) (sit-for 1) - (cond - ((looking-at "\\\\\n") - (forward-char 2)) + (goto-char start) + (while (progn (forward-comment (point-max)) (< (point) end)) + ;; (message "expr-start = %d" expr-start) (sit-for 1) + (cond + ((looking-at "\\\\\n") + (forward-char 2)) ((looking-at hif-string-literal-regexp) (push (substring-no-properties (match-string 1)) token-list) (goto-char (match-end 0))) - ((looking-at hif-token-regexp) + ((looking-at hif-token-regexp) (let ((token (buffer-substring-no-properties (point) (match-end 0)))) - (goto-char (match-end 0)) - ;; (message "token: %s" token) (sit-for 1) - (push + (goto-char (match-end 0)) + ;; (message "token: %s" token) (sit-for 1) + (push (or (cdr (assoc token hif-token-alist)) (if (string-equal token "defined") 'hif-defined) ;; TODO: @@ -500,7 +607,9 @@ (setq hif-simple-token-only nil))) token-list))) - (t (error "Bad #if expression: %s" (buffer-string))))))) + ((looking-at "\r") ; Sometimes MS-Windows user will leave CR in + (forward-char 1)) ; the source code. Let's not get stuck here. + (t (error "Bad #if expression: %s" (buffer-string))))))) (nreverse token-list))) @@ -573,7 +682,7 @@ (defun hif-expand-token-list (tokens &optional macroname expand_list) "Perform expansion on TOKENS till everything expanded. Self-reference (directly or indirectly) tokens are not expanded. -EXPAND_LIST is the list of macro names currently being expanded, use for +EXPAND_LIST is the list of macro names currently being expanded, used for detecting self-reference." (catch 'self-referencing (let ((expanded nil) @@ -657,28 +766,28 @@ "Parse an exprlist: expr { ',' expr}." (let ((result (hif-expr))) (if (eq hif-token 'hif-comma) - (let ((temp (list result))) - (while - (progn - (hif-nexttoken) - (push (hif-expr) temp) - (eq hif-token 'hif-comma))) - (cons 'hif-comma (nreverse temp))) + (let ((temp (list result))) + (while + (progn + (hif-nexttoken) + (push (hif-expr) temp) + (eq hif-token 'hif-comma))) + (cons 'hif-comma (nreverse temp))) result))) (defun hif-expr () "Parse an expression as found in #if. - expr : or-expr | or-expr '?' expr ':' expr." +expr : or-expr | or-expr '?' expr ':' expr." (let ((result (hif-or-expr)) - middle) + middle) (while (eq hif-token 'hif-conditional) (hif-nexttoken) (setq middle (hif-expr)) (if (eq hif-token 'hif-colon) - (progn - (hif-nexttoken) - (setq result (list 'hif-conditional result middle (hif-expr)))) - (error "Error: unexpected token: %s" hif-token))) + (progn + (hif-nexttoken) + (setq result (list 'hif-conditional result middle (hif-expr)))) + (error "Error: unexpected token: %s" hif-token))) result)) (defun hif-or-expr () @@ -767,7 +876,7 @@ "Parse an expression with *,/,%. muldiv : factor | muldiv '*|/|%' factor." (let ((result (hif-factor)) - (math-op nil)) + (math-op nil)) (while (memq hif-token '(hif-multiply hif-divide hif-modulo)) (setq math-op hif-token) (hif-nexttoken) @@ -791,20 +900,20 @@ (hif-nexttoken) (let ((result (hif-exprlist))) (if (not (eq hif-token 'hif-rparen)) - (error "Bad token in parenthesized expression: %s" hif-token) - (hif-nexttoken) - result))) + (error "Bad token in parenthesized expression: %s" hif-token) + (hif-nexttoken) + result))) ((eq hif-token 'hif-defined) (hif-nexttoken) (let ((paren (when (eq hif-token 'hif-lparen) (hif-nexttoken) t)) - (ident hif-token)) + (ident hif-token)) (if (memq hif-token '(or and not hif-defined hif-lparen hif-rparen)) - (error "Error: unexpected token: %s" hif-token)) + (error "Error: unexpected token: %s" hif-token)) (when paren - (hif-nexttoken) + (hif-nexttoken) (unless (eq hif-token 'hif-rparen) - (error "Error: expected \")\" after identifier"))) + (error "Error: expected \")\" after identifier"))) (hif-nexttoken) `(hif-defined (quote ,ident)))) @@ -817,7 +926,7 @@ ((memq hif-token '(hif-minus hif-plus)) (list (prog1 hif-token (hif-nexttoken)) 0 (hif-factor))) - (t ; identifier + (t ; identifier (let ((ident hif-token)) (hif-nexttoken) (if (eq hif-token 'hif-lparen) @@ -994,7 +1103,7 @@ (setq prev (hif-token-concat prev (cadr l))) (setq l (cddr l))) (if prev - (setq result (append result (list prev)))) + (setq result (append result (list prev)))) (setq prev (car l) l (cdr l))) (if prev @@ -1068,11 +1177,11 @@ (defun hif-invoke (macro-name actual-parms) "Invoke a macro by expanding it, reparse macro-body and finally invoke it." - ;; Reparse the macro body and evaluate it - (funcall hide-ifdef-evaluator - (hif-parse-exp - (hif-macro-supply-arguments macro-name actual-parms) - macro-name))) + ;; Reparse the macro body and evaluate it + (funcall hide-ifdef-evaluator + (hif-parse-exp + (hif-macro-supply-arguments macro-name actual-parms) + macro-name))) ;;;----------- end of parser ----------------------- @@ -1158,12 +1267,12 @@ (hif-ifdef-to-endif)) ; Find outer endif or else ((hif-looking-at-elif) (hif-ifdef-to-endif)) - ((hif-looking-at-else) + ((hif-looking-at-else) (hif-ifdef-to-endif)) ; Find endif following else - ((hif-looking-at-endif) - 'done) - (t - (error "Mismatched #ifdef #endif pair")))) + ((hif-looking-at-endif) + 'done) + (t + (error "Mismatched #ifdef #endif pair")))) (defun hif-endif-to-ifdef () @@ -1172,15 +1281,18 @@ (let ((start (point))) (hif-find-previous-relevant) (if (= start (point)) - (error "Mismatched #ifdef #endif pair"))) + (error "Mismatched #ifdef #endif pair"))) (cond ((hif-looking-at-endif) - (hif-endif-to-ifdef) ; find beginning of nested if - (hif-endif-to-ifdef)) ; find beginning of outer if or else - ((hif-looking-at-else) - (hif-endif-to-ifdef)) - ((hif-looking-at-ifX) - 'done) - (t))) ; never gets here + (hif-endif-to-ifdef) ; Find beginning of nested if + (hif-endif-to-ifdef)) ; Find beginning of outer if or else + ((hif-looking-at-elif) + (hif-endif-to-ifdef)) + ((hif-looking-at-else) + (hif-endif-to-ifdef)) + ((hif-looking-at-ifX) + 'done) + (t + (error "Mismatched #endif")))) ; never gets here (defun forward-ifdef (&optional arg) @@ -1274,26 +1386,25 @@ ;;===%%SF%% hide-ifdef-hiding (Start) === -;;; A range is a structure with four components: -;;; ELSE-P True if there was an else clause for the ifdef. -;;; START The start of the range. (beginning of line) -;;; ELSE The else marker (beginning of line) -;;; Only valid if ELSE-P is true. -;;; END The end of the range. (beginning of line) +;; A range is a structure with four components: +;; START The start of the range. (beginning of line) +;; ELSE The else marker (beginning of line) +;; END The end of the range. (beginning of line) +;; ELIF A sequence of #elif markers (beginning of line) -(defsubst hif-make-range (start end &optional else) - (list start else end)) +(defsubst hif-make-range (start end &optional else elif) + (list start else end elif)) (defsubst hif-range-start (range) (elt range 0)) (defsubst hif-range-else (range) (elt range 1)) (defsubst hif-range-end (range) (elt range 2)) - - - -;;; Find-Range -;;; The workhorse, it delimits the #if region. Reasonably simple: -;;; Skip until an #else or #endif is found, remembering positions. If -;;; an #else was found, skip some more, looking for the true #endif. +(defsubst hif-range-elif (range) (elt range 3)) + + +;; Find-Range +;; The workhorse, it delimits the #if region. Reasonably simple: +;; Skip until an #else or #endif is found, remembering positions. If +;; an #else was found, skip some more, looking for the true #endif. (defun hif-find-range () "Return a Range structure describing the current #if region. @@ -1302,29 +1413,33 @@ (save-excursion (beginning-of-line) (let ((start (point)) - (else nil) - (end nil)) - ;; Part one. Look for either #endif or #else. + (elif nil) + (else nil) + (end nil)) + ;; Part one. Look for either #elif, #else or #endif. ;; This loop-and-a-half dedicated to E. Dijkstra. - (while (progn - (hif-find-next-relevant) - (hif-looking-at-ifX)) ; Skip nested ifdef - (hif-ifdef-to-endif)) - ;; Found either a #else or an #endif. - (cond ((hif-looking-at-else) - (setq else (point))) - (t - (setq end (point)))) ; (line-end-position) + (while (and (not else) (not end)) + (while (progn + (hif-find-next-relevant) + (hif-looking-at-ifX)) ; Skip nested ifdef + (hif-ifdef-to-endif)) + ;; Found either a #else, #elif, or an #endif. + (cond ((hif-looking-at-elif) + (setq elif (nconc elif (list (point))))) + ((hif-looking-at-else) + (setq else (point))) + (t + (setq end (point))))) ;; If found #else, look for #endif. (when else - (while (progn - (hif-find-next-relevant) - (hif-looking-at-ifX)) ; Skip nested ifdef - (hif-ifdef-to-endif)) - (if (hif-looking-at-else) - (error "Found two elses in a row? Broken!")) - (setq end (point))) ; (line-end-position) - (hif-make-range start end else)))) + (while (progn + (hif-find-next-relevant) + (hif-looking-at-ifX)) ; Skip nested ifdef + (hif-ifdef-to-endif)) + (if (hif-looking-at-else) + (error "Found two elses in a row? Broken!")) + (setq end (point))) ; (line-end-position) + (hif-make-range start end else elif)))) ;; A bit slimy. @@ -1339,70 +1454,180 @@ (line-beginning-position) (progn (hif-end-of-line) (point)))))) -;;; Hif-Possibly-Hide -;;; There are four cases. The #ifX expression is "taken" if it -;;; the hide-ifdef-evaluator returns T. Presumably, this means the code -;;; inside the #ifdef would be included when the program was -;;; compiled. -;;; -;;; Case 1: #ifX taken, and there's an #else. -;;; The #else part must be hidden. The #if (then) part must be -;;; processed for nested #ifX's. -;;; Case 2: #ifX taken, and there's no #else. -;;; The #if part must be processed for nested #ifX's. -;;; Case 3: #ifX not taken, and there's an #else. -;;; The #if part must be hidden. The #else part must be processed -;;; for nested #ifs. -;;; Case 4: #ifX not taken, and there's no #else. -;;; The #ifX part must be hidden. -;;; -;;; Further processing is done by narrowing to the relevant region -;;; and just recursively calling hide-ifdef-guts. -;;; -;;; When hif-possibly-hide returns, point is at the end of the -;;; possibly-hidden range. - -(defun hif-recurse-on (start end) +;; Hif-Possibly-Hide +;; There are four cases. The #ifX expression is "taken" if it +;; the hide-ifdef-evaluator returns T. Presumably, this means the code +;; inside the #ifdef would be included when the program was +;; compiled. +;; +;; Case 1: #ifX taken, and there's an #else. +;; The #else part must be hidden. The #if (then) part must be +;; processed for nested #ifX's. +;; Case 2: #ifX taken, and there's no #else. +;; The #if part must be processed for nested #ifX's. +;; Case 3: #ifX not taken, and there's an #elif +;; The #if part must be hidden, and then evaluate +;; the #elif condition like a new #ifX. +;; Case 4: #ifX not taken, and there's just an #else. +;; The #if part must be hidden. The #else part must be processed +;; for nested #ifs. +;; Case 5: #ifX not taken, and there's no #else. +;; The #ifX part must be hidden. +;; +;; Further processing is done by narrowing to the relevant region +;; and just recursively calling hide-ifdef-guts. +;; +;; When hif-possibly-hide returns, point is at the end of the +;; possibly-hidden range. + +(defvar hif-recurse-level 0) + +(defun hif-recurse-on (start end &optional dont-go-eol) "Call `hide-ifdef-guts' after narrowing to end of START line and END line." (save-excursion (save-restriction (goto-char start) - (end-of-line) + (unless dont-go-eol + (end-of-line)) (narrow-to-region (point) end) - (hide-ifdef-guts)))) + (let ((hif-recurse-level (1+ hif-recurse-level))) + (hide-ifdef-guts))))) -(defun hif-possibly-hide () +(defun hif-possibly-hide (expand-reinclusion) "Called at #ifX expression, this hides those parts that should be hidden. -It uses the judgment of `hide-ifdef-evaluator'." +It uses the judgment of `hide-ifdef-evaluator'. EXPAND-REINCLUSION is a flag +indicating that we should expand the #ifdef even if it should be hidden. +Refer to `hide-ifdef-expand-reinclusion-protection' for more details." ;; (message "hif-possibly-hide") (sit-for 1) - (let ((test (hif-canonicalize hif-ifx-regexp)) - (range (hif-find-range))) + (let* ((case-fold-search nil) + (test (hif-canonicalize hif-ifx-regexp)) + (range (hif-find-range)) + (elifs (hif-range-elif range)) + (if-part t) ; Everytime we start from if-part + (complete nil)) ;; (message "test = %s" test) (sit-for 1) (hif-hide-line (hif-range-end range)) - (if (not (hif-not (funcall hide-ifdef-evaluator test))) - (cond ((hif-range-else range) ; case 1 - (hif-hide-line (hif-range-else range)) - (hide-ifdef-region (hif-range-else range) - (1- (hif-range-end range))) - (hif-recurse-on (hif-range-start range) - (hif-range-else range))) - (t ; case 2 - (hif-recurse-on (hif-range-start range) - (hif-range-end range)))) - (cond ((hif-range-else range) ; case 3 - (hif-hide-line (hif-range-else range)) - (hide-ifdef-region (hif-range-start range) - (1- (hif-range-else range))) - (hif-recurse-on (hif-range-else range) - (hif-range-end range))) - (t ; case 4 - (hide-ifdef-region (point) - (1- (hif-range-end range)))))) + (while (not complete) + (if (and (not (and expand-reinclusion if-part)) + (hif-not (funcall hide-ifdef-evaluator test))) + ;; ifX/elif is FALSE + (if elifs + ;; Case 3 - Hide the #ifX and eval #elif + (let ((newstart (car elifs))) + (hif-hide-line (hif-range-start range)) + (hide-ifdef-region (hif-range-start range) + (1- newstart)) + (setcar range newstart) + (goto-char newstart) + (setq elifs (cdr elifs)) + (setq test (hif-canonicalize hif-elif-regexp))) + + ;; Check for #else + (cond ((hif-range-else range) + ;; Case 4 - #else block visible + (hif-hide-line (hif-range-else range)) + (hide-ifdef-region (hif-range-start range) + (1- (hif-range-else range))) + (hif-recurse-on (hif-range-else range) + (hif-range-end range))) + (t + ;; Case 5 - No #else block, hide #ifX + (hide-ifdef-region (point) + (1- (hif-range-end range))))) + (setq complete t)) + + ;; ifX/elif is TRUE + (cond (elifs + ;; Luke fix: distinguish from #elif..#elif to #elif..#else + (let ((elif (car elifs))) + ;; hide all elifs + (hif-hide-line elif) + (hide-ifdef-region elif (1- (hif-range-end range))) + (hif-recurse-on (hif-range-start range) + elif))) + ((hif-range-else range) + ;; Case 1 - Hide #elif and #else blocks, recurse #ifX + (hif-hide-line (hif-range-else range)) + (hide-ifdef-region (hif-range-else range) + (1- (hif-range-end range))) + (hif-recurse-on (hif-range-start range) + (hif-range-else range))) + (t + ;; Case 2 - No #else, just recurse #ifX + (hif-recurse-on (hif-range-start range) + (hif-range-end range)))) + (setq complete t)) + (setq if-part nil)) + + ;; complete = t (hif-hide-line (hif-range-start range)) ; Always hide start. (goto-char (hif-range-end range)) (end-of-line))) +(defun hif-evaluate-region (start end) + (let* ((tokens (ignore-errors ; Prevent C statement things like + ; 'do { ... } while (0)' + (hif-tokenize start end))) + (expr (and tokens + (condition-case nil + (hif-parse-exp tokens) + (error + tokens)))) + (result (funcall hide-ifdef-evaluator expr))) + result)) + +(defun hif-evaluate-macro (rstart rend) + "Evaluate the macro expansion result for a region. +If no region active, find the current #ifdefs and evaluate the result. +Currently it supports only math calculations, strings or argumented macros can +not be expanded." + (interactive "r") + (let ((case-fold-search nil)) + (save-excursion + (unless mark-active + (setq rstart nil rend nil) + (beginning-of-line) + (when (and (re-search-forward hif-macro-expr-prefix-regexp nil t) + (string= "define" (match-string 2))) + (re-search-forward hif-macroref-regexp nil t))) + (let* ((start (or rstart (point))) + (end (or rend (progn (hif-end-of-line) (point)))) + (defined nil) + (simple 't) + (tokens (ignore-errors ; Prevent C statement things like + ; 'do { ... } while (0)' + (hif-tokenize start end))) + (expr (or (and (<= (length tokens) 1) ; Simple token + (setq defined (assoc (car tokens) hide-ifdef-env)) + (setq simple (atom (hif-lookup (car tokens)))) + (hif-lookup (car tokens))) + (and tokens + (condition-case nil + (hif-parse-exp tokens) + (error + nil))))) + (result (funcall hide-ifdef-evaluator expr)) + (exprstring (replace-regexp-in-string + ;; Trim off leading/trailing whites + "^[ \t]*\\([^ \t]+\\)[ \t]*" "\\1" + (replace-regexp-in-string + "\\(//.*\\)" "" ; Trim off end-of-line comments + (buffer-substring-no-properties start end))))) + (cond + ((and (<= (length tokens) 1) simple) ; Simple token + (if defined + (message "%S <= `%s'" result exprstring) + (message "`%s' is not defined" exprstring))) + ((integerp result) + (if (or (= 0 result) (= 1 result)) + (message "%S <= `%s'" result exprstring) + (message "%S (0x%x) <= `%s'" result result exprstring))) + ((null result) (message "%S <= `%s'" 'false exprstring)) + ((eq t result) (message "%S <= `%s'" 'true exprstring)) + (t (message "%S <= `%s'" result exprstring))) + result)))) + (defun hif-parse-macro-arglist (str) "Parse argument list formatted as '( arg1 [ , argn] [...] )'. The '...' is also included. Return a list of the arguments, if '...' exists the @@ -1410,7 +1635,7 @@ (let* ((hif-simple-token-only nil) ; Dynamic binding var for `hif-tokenize' (tokenlist (cdr (hif-tokenize - (- (point) (length str)) (point)))) ; Remove `hif-lparen' + (- (point) (length str)) (point)))) ; Remove `hif-lparen' etc result token) (while (not (eq (setq token (pop tokenlist)) 'hif-rparen)) (cond @@ -1530,15 +1755,20 @@ It does not do the work that's pointless to redo on a recursive entry." ;; (message "hide-ifdef-guts") (save-excursion - (let ((case-fold-search nil) - min max) + (let* ((case-fold-search t) ; Ignore case for `hide-ifdef-header-regexp' + (expand-header (and hide-ifdef-expand-reinclusion-protection + (string-match hide-ifdef-header-regexp + (buffer-file-name)) + (zerop hif-recurse-level))) + (case-fold-search nil) + min max) (goto-char (point-min)) (setf min (point)) (cl-loop do (setf max (hif-find-any-ifX)) (hif-add-new-defines min max) (if max - (hif-possibly-hide)) + (hif-possibly-hide expand-header)) (setf min (point)) while max)))) @@ -1585,17 +1815,30 @@ (overlay-put overlay 'face nil) (overlay-put overlay 'invisible 'hide-ifdef)))))) -(defun hide-ifdef-define (var) - "Define a VAR so that #ifdef VAR would be included." - (interactive "SDefine what? ") - (hif-set-var var 1) +(defun hide-ifdef-define (var &optional val) + "Define a VAR to VAL (default 1) in `hide-ifdef-env'. +This allows #ifdef VAR to be hidden." + (interactive + (let* ((default (save-excursion + (beginning-of-line) + (cond ((looking-at hif-ifx-else-endif-regexp) + (forward-word 2) + (current-word 'strict)) + (t + nil)))) + (var (read-minibuffer "Define what? " default)) + (val (read-from-minibuffer (format "Set %s to? (default 1): " var) + nil nil t nil "1"))) + (list var val))) + (hif-set-var var (or val 1)) + (message "%s set to %s" var (or val 1)) + (sleep-for 1) (if hide-ifdef-hiding (hide-ifdefs))) (defun hif-undefine-symbol (var) (setq hide-ifdef-env (delete (assoc var hide-ifdef-env) hide-ifdef-env))) - (defun hide-ifdef-undef (start end) "Undefine a VAR so that #ifdef VAR would not be included." (interactive "r") @@ -1616,20 +1859,23 @@ Assume that defined symbols have been added to `hide-ifdef-env'. The text hidden is the text that would not be included by the C preprocessor if it were given the file with those symbols defined. +With prefix command presents it will also hide the #ifdefs themselves. Turn off hiding by calling `show-ifdefs'." (interactive) - (message "Hiding...") - (setq hif-outside-read-only buffer-read-only) - (unless hide-ifdef-mode (hide-ifdef-mode 1)) ; turn on hide-ifdef-mode - (if hide-ifdef-hiding - (show-ifdefs)) ; Otherwise, deep confusion. - (setq hide-ifdef-hiding t) - (hide-ifdef-guts) - (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only)) - (or nomsg - (message "Hiding done"))) + (let ((hide-ifdef-lines current-prefix-arg)) + (or nomsg + (message "Hiding...")) + (setq hif-outside-read-only buffer-read-only) + (unless hide-ifdef-mode (hide-ifdef-mode 1)) ; Turn on hide-ifdef-mode + (if hide-ifdef-hiding + (show-ifdefs)) ; Otherwise, deep confusion. + (setq hide-ifdef-hiding t) + (hide-ifdef-guts) + (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only)) + (or nomsg + (message "Hiding done")))) (defun show-ifdefs () @@ -1645,46 +1891,74 @@ Return as (TOP . BOTTOM) the extent of ifdef block." (let (max-bottom) (cons (save-excursion - (beginning-of-line) - (unless (or (hif-looking-at-else) (hif-looking-at-ifX)) - (up-ifdef)) - (prog1 (point) - (hif-ifdef-to-endif) - (setq max-bottom (1- (point))))) - (save-excursion - (beginning-of-line) - (unless (hif-looking-at-endif) - (hif-find-next-relevant)) - (while (hif-looking-at-ifX) - (hif-ifdef-to-endif) - (hif-find-next-relevant)) - (min max-bottom (1- (point))))))) - - -(defun hide-ifdef-block () - "Hide the ifdef block (true or false part) enclosing or before the cursor." - (interactive) - (unless hide-ifdef-mode (hide-ifdef-mode 1)) - (let ((top-bottom (hif-find-ifdef-block))) - (hide-ifdef-region (car top-bottom) (cdr top-bottom)) - (when hide-ifdef-lines - (hif-hide-line (car top-bottom)) - (hif-hide-line (1+ (cdr top-bottom)))) - (setq hide-ifdef-hiding t)) - (setq buffer-read-only (or hide-ifdef-read-only hif-outside-read-only))) - -(defun show-ifdef-block () + (beginning-of-line) + (unless (or (hif-looking-at-else) (hif-looking-at-ifX)) + (up-ifdef)) + (prog1 (point) + (hif-ifdef-to-endif) + (setq max-bottom (1- (point))))) + (save-excursion + (beginning-of-line) + (unless (hif-looking-at-endif) + (hif-find-next-relevant)) + (while (hif-looking-at-ifX) + (hif-ifdef-to-endif) + (hif-find-next-relevant)) + (min max-bottom (1- (point))))))) + + +(defun hide-ifdef-block (&optional arg start end) + "Hide the ifdef block (true or false part) enclosing or before the cursor. +With optional prefix agument ARG, also hide the #ifdefs themselves." + (interactive "P\nr") + (let ((hide-ifdef-lines arg)) + (if mark-active + (let ((hif-recurse-level (1+ hif-recurse-level))) + (hif-recurse-on start end t) + (setq mark-active nil)) + (unless hide-ifdef-mode (hide-ifdef-mode 1)) + (let ((top-bottom (hif-find-ifdef-block))) + (hide-ifdef-region (car top-bottom) (cdr top-bottom)) + (when hide-ifdef-lines + (hif-hide-line (car top-bottom)) + (hif-hide-line (1+ (cdr top-bottom)))) + (setq hide-ifdef-hiding t)) + (setq buffer-read-only + (or hide-ifdef-read-only hif-outside-read-only))))) + +(defun show-ifdef-block (&optional start end) "Show the ifdef block (true or false part) enclosing or before the cursor." - (interactive) - (let ((top-bottom (hif-find-ifdef-block))) + (interactive "r") + (if mark-active + (progn + (dolist (o (overlays-in start end)) + (if (overlay-get o 'hide-ifdef) + (delete-overlay o))) + (setq mark-active nil)) + (let ((top-bottom (condition-case nil + (hif-find-ifdef-block) + (error + nil))) + (ovrs (overlays-in (max (point-min) (1- (point))) + (min (point-max) (1+ (point))))) + (del nil)) + (if top-bottom (if hide-ifdef-lines - (hif-show-ifdef-region - (save-excursion - (goto-char (car top-bottom)) (line-beginning-position)) - (save-excursion - (goto-char (1+ (cdr top-bottom))) - (hif-end-of-line) (point))) - (hif-show-ifdef-region (1- (car top-bottom)) (cdr top-bottom))))) + (hif-show-ifdef-region + (save-excursion + (goto-char (car top-bottom)) (line-beginning-position)) + (save-excursion + (goto-char (1+ (cdr top-bottom))) + (hif-end-of-line) (point))) + (setf del (hif-show-ifdef-region + (1- (car top-bottom)) (cdr top-bottom))))) + (if (not (and top-bottom + del)) + (dolist (o ovrs) + ;;(dolist (o (overlays-in (1- (point)) (1+ (point)))) + ;; (if (overlay-get o 'hide-ifdef) (message "%S" o))) + (if (overlay-get o 'hide-ifdef) + (delete-overlay o))))))) ;;; definition alist support ------------------------------------------------------------ revno: 117480 committer: Katsumi Yamaoka branch nick: trunk timestamp: Mon 2014-07-07 05:47:59 +0000 message: lisp/gnus/gnus-start.el (gnus-dribble-read-file): Don't stop auto-saving diff: === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2014-06-26 06:55:15 +0000 +++ lisp/gnus/ChangeLog 2014-07-07 05:47:59 +0000 @@ -1,3 +1,9 @@ +2014-07-07 Katsumi Yamaoka + + * gnus-start.el (gnus-dribble-read-file): Don't stop the auto-saving of + the dribble buffer even when it is shrunk a lot. + + 2014-06-26 Glenn Morris * mm-util.el (help-function-arglist): Remove outdated declaration. === modified file 'lisp/gnus/gnus-start.el' --- lisp/gnus/gnus-start.el 2014-03-23 23:13:36 +0000 +++ lisp/gnus/gnus-start.el 2014-07-07 05:47:59 +0000 @@ -889,6 +889,11 @@ (setq buffer-save-without-query t) (erase-buffer) (setq buffer-file-name dribble-file) + ;; The buffer may be shrunk a lot when deleting old entries. + ;; It caused the auto-saving to stop. + (if (featurep 'emacs) + (set (make-local-variable 'auto-save-include-big-deletions) t) + (set (make-local-variable 'disable-auto-save-when-buffer-shrinks) nil)) (auto-save-mode t) (buffer-disable-undo) (bury-buffer (current-buffer))