commit ae0ec1eede3dac8ae82c3a82d7d7f6b956d8db24 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Sun Oct 30 13:13:28 2022 +0800 Plug big leaks upon display IO error Frame GCs are still leaked, but there is nothing that can be done in that case because the display connection is dead. * src/xterm.c (x_delete_terminal): Always free xkb desc and modmap. diff --git a/src/xterm.c b/src/xterm.c index f1bccddb6c..7dd969b821 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -30277,11 +30277,6 @@ x_delete_terminal (struct terminal *terminal) closing all the displays. */ XrmDestroyDatabase (dpyinfo->rdb); #endif - -#ifdef HAVE_XKB - if (dpyinfo->xkb_desc) - XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True); -#endif #ifdef USE_GTK xg_display_close (dpyinfo->display); #else @@ -30291,9 +30286,6 @@ x_delete_terminal (struct terminal *terminal) XCloseDisplay (dpyinfo->display); #endif #endif /* ! USE_GTK */ - - if (dpyinfo->modmap) - XFreeModifiermap (dpyinfo->modmap); /* Do not close the connection here because it's already closed by X(t)CloseDisplay (Bug#18403). */ dpyinfo->display = NULL; @@ -30306,6 +30298,18 @@ x_delete_terminal (struct terminal *terminal) else if (dpyinfo->connection >= 0) emacs_close (dpyinfo->connection); + /* Free the keyboard and modifier maps here; that is safe to do + without a display, and not doing so leads to a lot of data being + leaked upon IO error. */ + +#ifdef HAVE_XKB + if (dpyinfo->xkb_desc) + XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True); +#endif + + if (dpyinfo->modmap) + XFreeModifiermap (dpyinfo->modmap); + /* No more input on this descriptor. */ delete_keyboard_wait_descriptor (dpyinfo->connection); /* Mark as dead. */ commit 1d62c964238a82ccfcbd07a554abe8e6c096fcd5 Author: Basil L. Contovounesios Date: Sun Oct 30 00:44:44 2022 +0300 ; Silence warning in last hierarchy.el change. diff --git a/lisp/emacs-lisp/hierarchy.el b/lisp/emacs-lisp/hierarchy.el index 4cb5ba64a8..fb5d518b22 100644 --- a/lisp/emacs-lisp/hierarchy.el +++ b/lisp/emacs-lisp/hierarchy.el @@ -567,7 +567,7 @@ LABELFN is the same function passed to `hierarchy-convert-to-tree-widget'. INDENT is the same function passed to `hierarchy-convert-to-tree-widget'. CHILDRENFN is the function used to discover the children of ELEM." - (lambda (widget) + (lambda (_widget) (mapcar (lambda (item) (widget-convert commit 44f1b1edcf74de3be7251780f058b29ccd038150 Author: Eli Zaretskii Date: Sat Oct 29 19:52:48 2022 +0300 ; * lisp/dired.el (dired--make-directory-clickable): Fix typo. diff --git a/lisp/dired.el b/lisp/dired.el index 7a8f1ae7a1..209e270942 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1919,7 +1919,7 @@ mouse-2: visit this file in other window" (let ((bound (line-end-position)) (segment-start (point)) (inhibit-read-only t) - (dir (substring (match-string 1) 2))) + (dir (substring (match-string 0) 2))) (while (search-forward "/" bound t 1) (setq dir (concat dir (buffer-substring segment-start (point)))) (add-text-properties commit df7ca69920e0a21ec425118090a4116fa0f7c0a6 Author: Eli Zaretskii Date: Sat Oct 29 18:59:04 2022 +0300 Set 'native-comp-debug' to zero on MS-Windows * lisp/emacs-lisp/comp.el (native-comp-debug): Don't emit debug symbols on MS-Windows. The default was originally made 1 because without that, C backtraces on Windows would not show natively-compiled functions correctly, or would even stop short of reaching the topmost call frame. But that turned out to be due to a bug in GDB, which was meanwhile fixed in GDB 12. So we can now reset the value back to zero, and gain smaller *.eln files on MS-Windows. diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index 21395c23d9..863e895efd 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -57,7 +57,7 @@ :safe #'integerp :version "28.1") -(defcustom native-comp-debug (if (eq 'windows-nt system-type) 1 0) +(defcustom native-comp-debug 0 "Debug level for native compilation, a number between 0 and 3. This is intended for debugging the compiler itself. 0 no debug output. @@ -67,7 +67,7 @@ This is intended for debugging the compiler itself. passes and libgccjit log file." :type 'natnum :safe #'natnump - :version "28.1") + :version "29.1") (defcustom native-comp-verbose 0 "Compiler verbosity for native compilation, a number between 0 and 3. commit 81d7827f34f1ac1108891421a44b36554776b04e Author: Stefan Kangas Date: Sat Oct 29 17:08:51 2022 +0200 Prefer defvar-keymap in ps-mode.el * lisp/progmodes/ps-mode.el (ps-mode-map, ps-run-mode-map): Prefer defvar-keymap. diff --git a/lisp/progmodes/ps-mode.el b/lisp/progmodes/ps-mode.el index 89482d86ce..6355b17e4a 100644 --- a/lisp/progmodes/ps-mode.el +++ b/lisp/progmodes/ps-mode.el @@ -278,24 +278,22 @@ If nil, use `temporary-file-directory'." ;; Variables. -(defvar ps-mode-map - (let ((map (make-sparse-keymap))) - (define-key map "\C-c\C-v" #'ps-run-boundingbox) - (define-key map "\C-c\C-u" #'ps-mode-uncomment-region) - (define-key map "\C-c\C-t" #'ps-mode-epsf-rich) - (define-key map "\C-c\C-s" #'ps-run-start) - (define-key map "\C-c\C-r" #'ps-run-region) - (define-key map "\C-c\C-q" #'ps-run-quit) - (define-key map "\C-c\C-p" #'ps-mode-print-buffer) - (define-key map "\C-c\C-o" #'ps-mode-comment-out-region) - (define-key map "\C-c\C-k" #'ps-run-kill) - (define-key map "\C-c\C-j" #'ps-mode-other-newline) - (define-key map "\C-c\C-l" #'ps-run-clear) - (define-key map "\C-c\C-b" #'ps-run-buffer) - ;; FIXME: Add `indent' to backward-delete-char-untabify-method instead? - (define-key map "\177" #'ps-mode-backward-delete-char) - map) - "Local keymap to use in PostScript mode.") +(defvar-keymap ps-mode-map + :doc "Local keymap to use in PostScript mode." + "C-c C-v" #'ps-run-boundingbox + "C-c C-u" #'ps-mode-uncomment-region + "C-c C-t" #'ps-mode-epsf-rich + "C-c C-s" #'ps-run-start + "C-c C-r" #'ps-run-region + "C-c C-q" #'ps-run-quit + "C-c C-p" #'ps-mode-print-buffer + "C-c C-o" #'ps-mode-comment-out-region + "C-c C-k" #'ps-run-kill + "C-c C-j" #'ps-mode-other-newline + "C-c C-l" #'ps-run-clear + "C-c C-b" #'ps-run-buffer + ;; FIXME: Add `indent' to backward-delete-char-untabify-method instead? + "DEL" #'ps-mode-backward-delete-char) (defvar ps-mode-syntax-table (let ((st (make-syntax-table))) @@ -332,15 +330,13 @@ If nil, use `temporary-file-directory'." st) "Syntax table used while in PostScript mode.") -(defvar ps-run-mode-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map comint-mode-map) - (define-key map "\C-c\C-q" #'ps-run-quit) - (define-key map "\C-c\C-k" #'ps-run-kill) - (define-key map "\C-c\C-e" #'ps-run-goto-error) - (define-key map [mouse-2] #'ps-run-mouse-goto-error) - map) - "Local keymap to use in PostScript run mode.") +(defvar-keymap ps-run-mode-map + :doc "Local keymap to use in PostScript run mode." + :parent comint-mode-map + "C-c C-q" #'ps-run-quit + "C-c C-k" #'ps-run-kill + "C-c C-e" #'ps-run-goto-error + "" #'ps-run-mouse-goto-error) (defvar ps-mode-tmp-file nil "Name of temporary file, set by `ps-run'.") commit 5686df3d217b63b2ef63cee121a7786ce1f681c2 Author: Stefan Kangas Date: Sat Oct 29 17:02:27 2022 +0200 ; Remove redundant declares of w3m-minor-mode-map * lisp/gnus/gnus-art.el (w3m-minor-mode-map): * lisp/net/newst-backend.el (w3m-minor-mode-map): Don't declare. diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 3bea1a4c1d..814d21823d 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el @@ -26,7 +26,6 @@ (eval-when-compile (require 'cl-lib)) (defvar tool-bar-map) -(defvar w3m-minor-mode-map) (require 'gnus) (require 'gnus-sum) diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el index f65ef522f2..af196ccecf 100644 --- a/lisp/net/newst-backend.el +++ b/lisp/net/newst-backend.el @@ -40,7 +40,6 @@ ;; Silence warnings (defvar newsticker-groups) -(defvar w3m-minor-mode-map) (defvar newsticker--retrieval-timer-list nil "List of timers for news retrieval. commit 647c36cbfa485e54bbe8e4f0825b4fc3be7c5706 Author: Eli Zaretskii Date: Sat Oct 29 16:34:08 2022 +0300 ; * etc/NEWS: Add entry about more performant overlays. diff --git a/etc/NEWS b/etc/NEWS index bf50c900ea..a185967483 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -105,29 +105,20 @@ configuration on X is known to have problems, such as undesirable frame positioning and various issues with keyboard input of sequences such as 'C-;' and 'C-S-u'. +--- +** The implementation of overlays has changed. +Emacs now uses an implementation of overlays that is much more +efficient than the original one, and should speed up all the +operations that involve overlays, especially when there are lots of +them in a buffer. However, no changes in behavior of overlays should +be visible on the Lisp or user level, with the exception of better +performance. + --- ** The docstrings of preloaded files are not in "etc/DOC" any more. Instead, they're fetched as needed from the corresponding ".elc" file, as was already the case for all the non-preloaded files. -** Emacs Sessions (Desktop) - -+++ -*** New user option to load a locked desktop if locking Emacs is not running. -The option 'desktop-load-locked-desktop' can now be set to the value -'check-pid', which means to allow loading a locked ".emacs.desktop" -file if the Emacs process which locked it is no longer running on the -local machine. This allows avoiding questions about locked desktop -files when the Emacs session which locked it crashes, or was otherwise -interrupted, and didn't exit gracefully. See the "(emacs) Saving -Emacs Sessions" node in the Emacs manual for more details. - -** Miscellaneous - -+++ -*** User option 'minibuffer-eldef-shorten-default' is now obsolete. -Customize the user option 'minibuffer-default-prompt-format' instead. - * Startup Changes in Emacs 29.1 @@ -1557,6 +1548,18 @@ These commands can be useful if the ".elc" files are out of date If no packages are marked, 'x' will install the package under point if it isn't already, and remove it if it is installed. +** Emacs Sessions (Desktop) + ++++ +*** New user option to load a locked desktop if locking Emacs is not running. +The option 'desktop-load-locked-desktop' can now be set to the value +'check-pid', which means to allow loading a locked ".emacs.desktop" +file if the Emacs process which locked it is no longer running on the +local machine. This allows avoiding questions about locked desktop +files when the Emacs session which locked it crashes, or was otherwise +interrupted, and didn't exit gracefully. See the "(emacs) Saving +Emacs Sessions" node in the Emacs manual for more details. + ** Miscellaneous +++ @@ -1695,6 +1698,10 @@ but completes on the history items instead of the default completion table. 'minibuffer-complete-defaults' ('C-x ') completes on the list of default items. ++++ +*** User option 'minibuffer-eldef-shorten-default' is now obsolete. +Customize the user option 'minibuffer-default-prompt-format' instead. + +++ *** New user option 'completions-sort'. This option controls the sorting of the completion candidates in commit 31e7b9c073bd0dddedb90a1ff882dc78ff33315c Author: Alan Mackenzie Date: Sat Oct 29 13:21:39 2022 +0000 Fix the subr-arity returned by native compiled functions with lots of args This fixes bug #58739. Make subr-arity return, e.g., (12 . 12) rather than (12 . many) for a function with a fixed number of arguments more than 8. * lisp/emacs-lisp/comp.el (comp-prepare-args-for-top-level): Only return a cdr of 'many when there are &rest arguments. * src/eval.c (eval_sub): Also check for a fixed number of args over 8 when using the nargs + *args calling convention. (funcall_subr): Also check numargs <= 8 before using the fixed args calling convention. Include the case numargs > 8 in the aMany calling convention. * src/lisp.h (DEFUN): Amend the comment about MANY. diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index 3987692f6f..21395c23d9 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -2057,9 +2057,10 @@ and the annotation emission." "Lexically-scoped FUNCTION." (let ((args (comp-func-l-args function))) (cons (make-comp-mvar :constant (comp-args-base-min args)) - (make-comp-mvar :constant (if (comp-args-p args) - (comp-args-max args) - 'many))))) + (make-comp-mvar :constant (cond + ((comp-args-p args) (comp-args-max args)) + ((comp-nargs-rest args) 'many) + (t (comp-nargs-nonrest args))))))) (cl-defmethod comp-prepare-args-for-top-level ((function comp-func-d)) "Dynamically scoped FUNCTION." diff --git a/src/eval.c b/src/eval.c index e1399d6a05..ea23829948 100644 --- a/src/eval.c +++ b/src/eval.c @@ -2435,7 +2435,9 @@ eval_sub (Lisp_Object form) else if (XSUBR (fun)->max_args == UNEVALLED) val = (XSUBR (fun)->function.aUNEVALLED) (args_left); - else if (XSUBR (fun)->max_args == MANY) + else if (XSUBR (fun)->max_args == MANY + || XSUBR (fun)->max_args > 8) + { /* Pass a vector of evaluated arguments. */ Lisp_Object *vals; @@ -2998,7 +3000,8 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args) if (numargs >= subr->min_args) { /* Conforming call to finite-arity subr. */ - if (numargs <= subr->max_args) + if (numargs <= subr->max_args + && subr->max_args <= 8) { Lisp_Object argbuf[8]; Lisp_Object *a; @@ -3034,15 +3037,13 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args) return subr->function.a8 (a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); default: - /* If a subr takes more than 8 arguments without using MANY - or UNEVALLED, we need to extend this function to support it. - Until this is done, there is no way to call the function. */ - emacs_abort (); + emacs_abort (); /* Can't happen. */ } } /* Call to n-adic subr. */ - if (subr->max_args == MANY) + if (subr->max_args == MANY + || subr->max_args > 8) return subr->function.aMANY (numargs, args); } diff --git a/src/lisp.h b/src/lisp.h index 4701dfa868..d87f954938 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -3183,10 +3183,11 @@ CHECK_SUBR (Lisp_Object x) `minargs' should be a number, the minimum number of arguments allowed. `maxargs' should be a number, the maximum number of arguments allowed, or else MANY or UNEVALLED. - MANY means pass a vector of evaluated arguments, - in the form of an integer number-of-arguments - followed by the address of a vector of Lisp_Objects - which contains the argument values. + MANY means there are &rest arguments. Here we pass a vector + of evaluated arguments in the form of an integer + number-of-arguments followed by the address of a vector of + Lisp_Objects which contains the argument values. (We also use + this convention when calling a subr with more than 8 parameters.) UNEVALLED means pass the list of unevaluated arguments `intspec' says how interactive arguments are to be fetched. If the string starts with a `(', `intspec' is evaluated and the resulting commit 174dd064643e9487c0fa1460727d0935a60b3646 Author: Eli Zaretskii Date: Sat Oct 29 16:16:06 2022 +0300 Make Dired header clickable on non-Posix systems as well * lisp/dired.el (dired--make-directory-clickable): Support MS-Windows and MS-DOS absolute directory names with drive letters and UNCs. (Bug#21973) diff --git a/lisp/dired.el b/lisp/dired.el index 128770105b..7a8f1ae7a1 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1911,11 +1911,15 @@ mouse-2: visit this file in other window" (defun dired--make-directory-clickable () (save-excursion (goto-char (point-min)) - (while (re-search-forward "^ /" nil t 1) + (while (re-search-forward + (if (memq system-type '(windows-nt ms-dos)) + "^ \\([a-zA-Z]:/\\|//\\)" + "^ /") + nil t 1) (let ((bound (line-end-position)) (segment-start (point)) (inhibit-read-only t) - (dir "/")) + (dir (substring (match-string 1) 2))) (while (search-forward "/" bound t 1) (setq dir (concat dir (buffer-substring segment-start (point)))) (add-text-properties commit e9bdf3d4bd5aa2be7448b0f7a968af5abb058db0 Author: Eli Zaretskii Date: Sat Oct 29 16:02:35 2022 +0300 Display the Dired buffer as unmodified initially * lisp/dired.el (dired-readin): Make sure a newly-created Dired buffer is shown as unmodified. (Bug#58863) diff --git a/lisp/dired.el b/lisp/dired.el index 85a7131570..128770105b 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1457,9 +1457,9 @@ wildcards, erases the buffer, and builds the subdir-alist anew (if (eq (car attributes) t) (set-visited-file-modtime (file-attribute-modification-time attributes)))) - (set-buffer-modified-p nil) (when dired-make-directory-clickable (dired--make-directory-clickable)) + (set-buffer-modified-p nil) ;; No need to narrow since the whole buffer contains just ;; dired-readin's output, nothing else. The hook can ;; successfully use dired functions (e.g. dired-get-filename) commit f826f56a413a07eee2782655809e1f5e102c6153 Author: Po Lu Date: Sat Oct 29 18:21:51 2022 +0800 Fix another GCC warning * src/nsterm.m (ns_draw_glyphless_glyph_string_foreground): Fix another compiler warning. diff --git a/src/nsterm.m b/src/nsterm.m index e70463b987..17f40dc7e3 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -4242,7 +4242,7 @@ Function modeled after x_draw_glyph_string_box (). #else enum { PACIFY_GCC_BUG_81401 = 0 }; #endif - char buf[7 + PACIFY_GCC_BUG_81401]; + char buf[8 + PACIFY_GCC_BUG_81401]; char *str = NULL; int len = glyph->u.glyphless.len; @@ -4268,7 +4268,7 @@ Function modeled after x_draw_glyph_string_box (). { unsigned int ch = glyph->u.glyphless.ch; eassume (ch <= MAX_CHAR); - snprintf (buf, 7, "%0*X", ch < 0x10000 ? 4 : 6, ch); + snprintf (buf, 8, "%0*X", ch < 0x10000 ? 4 : 6, ch); str = buf; } commit 6f3d8ec4f5f4107e2a14a0bd154b61e05a4586c7 Author: Po Lu Date: Sat Oct 29 18:21:09 2022 +0800 Fix crash destroying NS frame tool bar * src/nsterm.m (ns_draw_glyphless_glyph_string_foreground): Work around silly GCC bug causing splurious warnings. ([EmacsWindow dealloc]): Detach tool bar before dealloc'ing window. (bug#58857) diff --git a/src/nsterm.m b/src/nsterm.m index 1fc72d83f6..e70463b987 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -4237,7 +4237,12 @@ Function modeled after x_draw_glyph_string_box (). for (i = 0; i < s->nchars; i++, glyph++) { - char buf[7]; +#ifdef GCC_LINT + enum { PACIFY_GCC_BUG_81401 = 1 }; +#else + enum { PACIFY_GCC_BUG_81401 = 0 }; +#endif + char buf[7 + PACIFY_GCC_BUG_81401]; char *str = NULL; int len = glyph->u.glyphless.len; @@ -9158,6 +9163,7 @@ - (void)dealloc NSTRACE ("[EmacsWindow dealloc]"); /* We need to release the toolbar ourselves. */ + [self setToolbar: nil]; [[self toolbar] release]; /* Also the last button press event . */ commit dfde4fc82b1b11f19edaf795ce62e8d5ff25f9ff Author: Alan Mackenzie Date: Sat Oct 29 10:04:37 2022 +0000 c-get-fontification-context: Refine the last non-default arm of the cond This fixes bug #58772. * lisp/progmodes/cc-fonts.el (c-get-fontification-context): Make the function return (decl . nil) when MATCH-POS is in the second paren list of something like DEFUN (..) (..). Tidy up untidy code with save-excursion's for greater accuracy. Set a c-type text property value c-decl-arg-start to speed up future calls. Reindent the entire function. diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 608919d0c9..9444828a0e 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -1218,134 +1218,145 @@ casts and declarations are fontified. Used on level 2 and higher." (c-backward-syntactic-ws) (eq (char-before) ?\())))) (c-get-fontification-context (point) not-front-decl toplev)) - ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{))) - (cons (and toplev 'top) nil)) - ;; A control flow expression or a decltype - ((and (eq (char-before match-pos) ?\() - (save-excursion - (goto-char match-pos) - (backward-char) - (c-backward-token-2) - (cond - ((looking-at c-paren-stmt-key) - ;; Allow comma separated <> arglists in for statements. - (cons nil nil)) - ((or (looking-at c-block-stmt-2-key) - (looking-at c-block-stmt-1-2-key) - (looking-at c-typeof-key)) - (cons nil t)) - (t nil))))) - ;; Near BOB. - ((<= match-pos (point-min)) - (cons 'arglist t)) - ;; Got a cached hit in a declaration arglist. - ((eq type 'c-decl-arg-start) - (cons 'decl nil)) - ;; We're inside (probably) a brace list. - ((eq type 'c-not-decl) - (cons 'not-decl nil)) - ;; Inside a C++11 lambda function arglist. - ((and (c-major-mode-is 'c++-mode) - (eq (char-before match-pos) ?\() - (save-excursion - (goto-char match-pos) - (c-backward-token-2) - (and - (c-safe (goto-char (scan-sexps (point) -1))) - (c-looking-at-c++-lambda-capture-list)))) - (c-put-char-property (1- match-pos) 'c-type - 'c-decl-arg-start) - (cons 'decl nil)) - ;; We're inside a brace list. - ((and (eq (char-before match-pos) ?{) - (c-inside-bracelist-p (1- match-pos) - (cdr (c-parse-state)) - nil)) - (c-put-char-property (1- match-pos) 'c-type - 'c-not-decl) - (cons 'not-decl nil)) - ;; We're inside an "ordinary" open brace. - ((eq (char-before match-pos) ?{) - (cons (and toplev 'top) nil)) - ;; Inside an angle bracket arglist. - ((or (eq type 'c-<>-arg-sep) - (eq (char-before match-pos) ?<)) - (cons '<> nil)) - ;; Got a cached hit in some other type of arglist. - (type - (cons 'arglist t)) - ;; We're at a C++ uniform initialization. - ((and (c-major-mode-is 'c++-mode) - (eq (char-before match-pos) ?\() - (save-excursion - (goto-char match-pos) - (and - (zerop (c-backward-token-2 2)) - (looking-at c-identifier-start) - (c-got-face-at (point) - '(font-lock-variable-name-face))))) - (cons 'not-decl nil)) - ((and not-front-decl + ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{))) + (cons (and toplev 'top) nil)) + ;; A control flow expression or a decltype + ((and (eq (char-before match-pos) ?\() + (save-excursion + (goto-char match-pos) + (backward-char) + (c-backward-token-2) + (cond + ((looking-at c-paren-stmt-key) + ;; Allow comma separated <> arglists in for statements. + (cons nil nil)) + ((or (looking-at c-block-stmt-2-key) + (looking-at c-block-stmt-1-2-key) + (looking-at c-typeof-key)) + (cons nil t)) + (t nil))))) + ;; Near BOB. + ((<= match-pos (point-min)) + (cons 'arglist t)) + ;; Got a cached hit in a declaration arglist. + ((eq type 'c-decl-arg-start) + (cons 'decl nil)) + ;; We're inside (probably) a brace list. + ((eq type 'c-not-decl) + (cons 'not-decl nil)) + ;; Inside a C++11 lambda function arglist. + ((and (c-major-mode-is 'c++-mode) + (eq (char-before match-pos) ?\() + (save-excursion + (goto-char match-pos) + (c-backward-token-2) + (and + (c-safe (goto-char (scan-sexps (point) -1))) + (c-looking-at-c++-lambda-capture-list)))) + (c-put-char-property (1- match-pos) 'c-type + 'c-decl-arg-start) + (cons 'decl nil)) + ;; We're inside a brace list. + ((and (eq (char-before match-pos) ?{) + (c-inside-bracelist-p (1- match-pos) + (cdr (c-parse-state)) + nil)) + (c-put-char-property (1- match-pos) 'c-type + 'c-not-decl) + (cons 'not-decl nil)) + ;; We're inside an "ordinary" open brace. + ((eq (char-before match-pos) ?{) + (cons (and toplev 'top) nil)) + ;; Inside an angle bracket arglist. + ((or (eq type 'c-<>-arg-sep) + (eq (char-before match-pos) ?<)) + (cons '<> nil)) + ;; Got a cached hit in some other type of arglist. + (type + (cons 'arglist t)) + ;; We're at a C++ uniform initialization. + ((and (c-major-mode-is 'c++-mode) + (eq (char-before match-pos) ?\() + (save-excursion + (goto-char match-pos) + (and + (zerop (c-backward-token-2 2)) + (looking-at c-identifier-start) + (c-got-face-at (point) + '(font-lock-variable-name-face))))) + (cons 'not-decl nil)) + ((and not-front-decl ;; The point is within the range of a previously ;; encountered type decl expression, so the arglist ;; is probably one that contains declarations. ;; However, if `c-recognize-paren-inits' is set it ;; might also be an initializer arglist. - (or (not c-recognize-paren-inits) - (save-excursion - (goto-char match-pos) - (not (c-back-over-member-initializers))))) - ;; The result of this check is cached with a char - ;; property on the match token, so that we can look - ;; it up again when refontifying single lines in a - ;; multiline declaration. - (c-put-char-property (1- match-pos) - 'c-type 'c-decl-arg-start) - (cons 'decl nil)) - ;; Got (an) open paren(s) preceded by an arith operator. - ((and (eq (char-before match-pos) ?\() - (save-excursion - (goto-char match-pos) - (while - (and (zerop (c-backward-token-2)) - (eq (char-after) ?\())) - (looking-at c-arithmetic-op-regexp))) - (cons nil nil)) - ;; In a C++ member initialization list. - ((and (eq (char-before match-pos) ?,) - (c-major-mode-is 'c++-mode) - (save-excursion - (goto-char match-pos) - (c-back-over-member-initializers))) - (c-put-char-property (1- match-pos) 'c-type 'c-not-decl) - (cons 'not-decl nil)) - ;; At start of a declaration inside a declaration paren. - ((save-excursion + (or (not c-recognize-paren-inits) + (save-excursion + (goto-char match-pos) + (not (c-back-over-member-initializers))))) + ;; The result of this check is cached with a char + ;; property on the match token, so that we can look + ;; it up again when refontifying single lines in a + ;; multiline declaration. + (c-put-char-property (1- match-pos) + 'c-type 'c-decl-arg-start) + (cons 'decl nil)) + ;; Got (an) open paren(s) preceded by an arith operator. + ((and (eq (char-before match-pos) ?\() + (save-excursion (goto-char match-pos) - (and (memq (char-before match-pos) '(?\( ?\,)) - (c-go-up-list-backward match-pos - ; c-determine-limit is too slow, here. - (max (- (point) 2000) (point-min))) - (eq (char-after) ?\() - (let ((type (c-get-char-property (point) 'c-type))) - (or (memq type '(c-decl-arg-start c-decl-type-start)) - (and - (progn (c-backward-syntactic-ws) t) - (or - (and - (c-back-over-compound-identifier) - (progn - (c-backward-syntactic-ws) - (or (bobp) - (progn - (setq type (c-get-char-property (1- (point)) - 'c-type)) - (memq type '(c-decl-arg-start - c-decl-type-start)))))) - (and (zerop (c-backward-token-2)) - (looking-at c-fun-name-substitute-key)))))))) - (cons 'decl nil)) - (t (cons 'arglist t))))) + (while + (and (zerop (c-backward-token-2)) + (eq (char-after) ?\())) + (looking-at c-arithmetic-op-regexp))) + (cons nil nil)) + ;; In a C++ member initialization list. + ((and (eq (char-before match-pos) ?,) + (c-major-mode-is 'c++-mode) + (save-excursion + (goto-char match-pos) + (c-back-over-member-initializers))) + (c-put-char-property (1- match-pos) 'c-type 'c-not-decl) + (cons 'not-decl nil)) + ;; At start of a declaration inside a declaration paren. + ((save-excursion + (goto-char match-pos) + (and (memq (char-before match-pos) '(?\( ?\,)) + (c-go-up-list-backward match-pos + ; c-determine-limit is too slow, here. + (max (- (point) 2000) (point-min))) + (eq (char-after) ?\() + (let ((type (c-get-char-property (point) 'c-type))) + (or (memq type '(c-decl-arg-start c-decl-type-start)) + (progn + (c-backward-syntactic-ws) + (cond + ((and toplev + (eq (char-before) ?\))) + (save-excursion + (and (c-go-list-backward nil (max (- (point) 2000) + (point-min))) + (eq (char-after) ?\() + (progn (c-backward-syntactic-ws) + (c-back-over-compound-identifier))))) + ((save-excursion + (and + (c-back-over-compound-identifier) + (progn + (c-backward-syntactic-ws) + (or (bobp) + (progn + (setq type (c-get-char-property (1- (point)) + 'c-type)) + (memq type '(c-decl-arg-start + c-decl-type-start)))))))) + ((and (zerop (c-backward-token-2)) + (looking-at c-fun-name-substitute-key))))))))) + ;; Cache the result of this test for next time around. + (c-put-char-property (1- match-pos) 'c-type 'c-decl-arg-start) + (cons 'decl nil)) + (t (cons 'arglist t))))) (defun c-font-lock-single-decl (limit decl-or-cast match-pos context toplev) ;; Try to fontify a single declaration, together with all its declarators.