commit 74c5b735212ccd5f335312db693fd4754fddbce1 (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Sun Sep 11 19:55:41 2016 -0700 * doc/lispref/files.texi: Remove @vindex. diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 9a56d0a..9af5ce9 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -1822,7 +1822,6 @@ operating system might not write data to secondary storage immediately, which will lose the data if power is lost. @findex write-region -@vindex write-region-inhibit-fsync Although both sorts of failures can largely be avoided by a suitably configured file system, such systems are typically more expensive or less efficient. In more-typical systems, to survive media failure you commit 073048d5de3ddc720fe11589cadaebab74e668df Author: Paul Eggert Date: Sun Sep 11 15:09:04 2016 -0700 Remove unnecessary ref to coreutils manual * doc/lispref/files.texi: Document write-region-inhibit-fsync. diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index b912d7b..9a56d0a 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -661,6 +661,15 @@ feature is useful for programs that use files for internal purposes, files that the user does not need to know about. @end deffn +@defvar write-region-inhibit-fsync +If this variable's value is @code{nil}, @code{write-region} uses the +@code{fsync} system call after writing a file. Although this slows +Emacs down, it lessens the risk of data loss after power failure. If +the value is @code{t}, Emacs does not use @code{fsync}. The default +value is @code{nil} when Emacs is interactive, and @code{t} when Emacs +runs in batch mode. @xref{Files and Storage}. +@end defvar + @defmac with-temp-file file body@dots{} @anchor{Definition of with-temp-file} The @code{with-temp-file} macro evaluates the @var{body} forms with a @@ -1812,12 +1821,15 @@ copy on secondary storage is lost due to media failure. Second, the operating system might not write data to secondary storage immediately, which will lose the data if power is lost. +@findex write-region +@vindex write-region-inhibit-fsync Although both sorts of failures can largely be avoided by a suitably configured file system, such systems are typically more expensive or less efficient. In more-typical systems, to survive media failure you can copy the file to a different device, and to survive a power -failure you can invoke the @command{sync} utility (@pxref{sync -invocation,,, coreutils, The @sc{gnu} @code{Coreutils} Manual}). +failure you can use the @code{write-region} function with the +@code{write-region-inhibit-fsync} variable set to @code{nil}. +@xref{Writing to Files}. @node File Names @section File Names commit c417f08b16cd9e16451a6d3231097eeb4a804f2d Author: Alan Mackenzie Date: Sun Sep 11 21:09:08 2016 +0000 Correctly fontify C++ direct initializations with parens inside functions Or, more clearly, when something looks like a function declaration and it's inside a function, fontify it as a direct initialization. For this purpose, introduce a "brace stack" for each buffer, where an entry on the brace stack states how deeply nested a particular position is inside braces inside a "top level", which includes classes and namespaces. Also introduce a new "context", "top", with which c-font-lock-declarations signals to c-forward-decl-or-cast-1 that point is at the top level. * lisp/progmodes/cc-langs.el (c-get-state-before-change-functions): add c-truncate-bs-cache. (c-flat-decl-block-kwds, c-brace-stack-thing-key, c-brace-stack-no-semi-key) (c-type-decl-operator-prefix-key): new language constants/variables. * lisp/progmodes/cc-engine.el (c-bs-interval, c-bs-cache, c-bs-cache-limit) (c-bs-prev-pos, c-bs-prev-stack): New mostly local variables for the brace stack cache. (c-init-bs-cache, c-truncate-bs-cache, c-truncate-bs-cache, c-brace-stack-at) (c-bs-at-toplevel-p): New functions which manipulate the brace stack (cache). (c-find-decl-prefix-search): Keep track of whether we're at top level. (c-find-decl-spots): New local variable cfd-top-level which records what it says. On calling cfd-fun, pass cfd-top-level as an additional argument. (c-forward-declarator): Add new element DECORATED to the result list. Set it to non-nil when a match for c-type-decl-operator-prefix-key is found. (c-forward-decl-or-cast-1): Handle the newly introduced context "top". Introduce "CASE 9.5", which recognizes direct initializations. * lisp/progmodes/cc-fonts.el (c-font-lock-complex-decl-prepare) (c-font-lock-enum-tail, c-font-lock-cut-off-declarators) (c-font-lock-enclosing-decls, c-simple-decl-matchers, c-basic-matchers-after): Add appropriate `not-top' argument to calls to c-font-lock-declarators. (c-font-lock-declarators): Additional parameter `not-top'. Use not-top to participate in the decision whether to fontify an identifier as a function or a variable. (c-font-lock-declarations): The internal lambda function takes an additional argument `toplev' from c-find-decl-spots, which it uses in determining the "context" of a declaration. Add appropriate `not-top' argument to calls to c-font-lock-declarators. (c-font-lock-objc-methods): Add extra parameter to internal lambda function, like for c-font-lock-declarators. * lisp/progmodes/cc-mode.el (c-basic-common-init): Initialize the brace stack cache. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 259f8a0..a1574b2 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -5128,6 +5128,211 @@ comment at the start of cc-engine.el for more info." (c-debug-remove-face ,beg ,end 'c-debug-decl-spot-face) (c-debug-remove-face ,beg ,end 'c-debug-decl-sws-face)))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Machinery for determining when we're at top level (this including being +;; directly inside a class or namespace, etc.) +;; +;; We maintain a stack of brace depths in structures like classes and +;; namespaces. The car of this structure, when non-nil, indicates that the +;; associated position is within a template (etc.) structure, and the value is +;; the position where the (outermost) template ends. The other elements in +;; the structure are stacked elements, one each for each enclosing "top level" +;; structure. +;; +;; At the very outermost level, the value of the stack would be (nil 1), the +;; "1" indicating an enclosure in a notional all-enclosing block. After +;; passing a keyword such as "namespace", the value would become (nil 0 1). +;; At this point, passing a semicolon would cause the 0 to be dropped from the +;; stack (at any other time, a semicolon is ignored). Alternatively, on +;; passing an opening brace, the stack would become (nil 1 1). Each opening +;; brace passed causes the cadr to be incremented, and passing closing braces +;; causes it to be decremented until it reaches 1. On passing a closing brace +;; when the cadr of the stack is at 1, this causes it to be removed from the +;; stack, the corresponding namespace (etc.) structure having been closed. +;; +;; There is a special stack value -1 which means the C++ colon operator +;; introducing a list of inherited classes has just been parsed. The value +;; persists on the stack until the next open brace or semicolon. +;; +;; When the car of the stack is non-nil, i.e. when we're in a template (etc.) +;; structure, braces are not counted. The counting resumes only after passing +;; the template's closing position, which is recorded in the car of the stack. +;; +;; The test for being at top level consists of the cadr being 0 or 1. +;; +;; The values of this stack throughout a buffer are cached in a simple linear +;; cache, every 5000 characters. +;; +;; Note to maintainers: This cache mechanism is MUCH faster than recalculating +;; the stack at every entry to `c-find-decl-spots' using `c-at-toplevel-p' or +;; the like. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; The approximate interval at which we cache the value of the brace stack. +(defconst c-bs-interval 5000) +;; The list of cached values of the brace stack. Each value in the list is a +;; cons of the position it is valid for and the value of the stack as +;; described above. +(defvar c-bs-cache nil) +(make-variable-buffer-local 'c-bs-cache) +;; The position of the buffer at and below which entries in `c-bs-cache' are +;; valid. +(defvar c-bs-cache-limit 1) +(make-variable-buffer-local 'c-bs-cache-limit) +;; The previous buffer position for which the brace stack value was +;; determined. +(defvar c-bs-prev-pos most-positive-fixnum) +(make-variable-buffer-local 'c-bs-prev-pos) +;; The value of the brace stack at `c-bs-prev-pos'. +(defvar c-bs-prev-stack nil) +(make-variable-buffer-local 'c-bs-prev-stack) + +(defun c-init-bs-cache () + ;; Initialize the cache in `c-bs-cache' and related variables. + (setq c-bs-cache nil + c-bs-cache-limit 1 + c-bs-prev-pos most-positive-fixnum + c-bs-prev-stack nil)) + +(defun c-truncate-bs-cache (pos &rest _ignore) + ;; Truncate the upper bound of the cache `c-bs-cache' to POS, if it is + ;; higher than that position. This is called as either a before- or + ;; after-change-function. + (setq c-bs-cache-limit + (min c-bs-cache-limit pos))) + +(defun c-update-brace-stack (stack from to) + ;; Give a brace-stack which has the value STACK at position FROM, update it + ;; to it's value at position TO, where TO is after (or equal to) FROM. + ;; Return a cons of either TO (if it is outside a literal) and this new + ;; value, or of the next position after TO outside a literal and the new + ;; value. + (let (match kwd-sym (prev-match-pos 1) + (s (cdr stack)) + (bound-<> (car stack)) + ) + (save-excursion + (cond + ((and bound-<> (<= to bound-<>)) + (goto-char to)) ; Nothing to do. + (bound-<> + (goto-char bound-<>) + (setq bound-<> nil)) + (t (goto-char from))) + (while (and (< (point) to) + (c-syntactic-re-search-forward + (if (<= (car s) 0) + c-brace-stack-thing-key + c-brace-stack-no-semi-key) + to 'after-literal) + (> (point) prev-match-pos)) ; prevent infinite loop. + (setq prev-match-pos (point)) + (setq match (match-string-no-properties 1) + kwd-sym (c-keyword-sym match)) + (cond + ((and (equal match "{") + (progn (backward-char) + (prog1 (looking-at "\\s(") + (forward-char)))) + (setq s (if s + (cons (if (<= (car s) 0) + 1 + (1+ (car s))) + (cdr s)) + (list 1)))) + ((and (equal match "}") + (progn (backward-char) + (prog1 (looking-at "\\s)") + (forward-char)))) + (setq s + (cond + ((and s (> (car s) 1)) + (cons (1- (car s)) (cdr s))) + ((and (cdr s) (eq (car s) 1)) + (cdr s)) + (t s)))) + ((and (equal match "<") + (progn (backward-char) + (prog1 (looking-at "\\s(") + (forward-char)))) + (backward-char) + (if (c-forward-<>-arglist nil) ; Should always work. + (when (> (point) to) + (setq bound-<> (point))) + (forward-char))) + ((and (equal match ":") + s + (eq (car s) 0)) + (setq s (cons -1 (cdr s)))) + ((and (equal match ",") + (eq (car s) -1))) ; at "," in "class foo : bar, ..." + ((member match '(";" "," ")")) + (when (and s (cdr s) (<= (car s) 0)) + (setq s (cdr s)))) + ((c-keyword-member kwd-sym 'c-flat-decl-block-kwds) + (push 0 s)))) + (cons (point) + (cons bound-<> s))))) + +(defun c-brace-stack-at (here) + ;; Given a buffer position HERE, Return the value of the brace stack there. + (save-excursion + (save-restriction + (widen) + (let ((c c-bs-cache) + (can-use-prev (<= c-bs-prev-pos c-bs-cache-limit)) + elt stack pos npos high-elt) + ;; Trim the cache to take account of buffer changes. + (while (and c + (> (caar c) c-bs-cache-limit)) + (setq c (cdr c))) + (setq c-bs-cache c) + + (while (and c + (> (caar c) here)) + (setq high-elt (car c)) + (setq c (cdr c))) + (setq pos (or (and c (caar c)) + (point-min))) + + (setq elt (if c + (car c) + (cons (point-min) + (cons nil (list 1))))) + (when (not high-elt) + (setq stack (cdr elt)) + (while + ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration. + (<= (setq npos (+ pos c-bs-interval)) here) + (setq elt (c-update-brace-stack stack pos npos)) + (setq npos (car elt)) + (setq stack (cdr elt)) + (unless (eq npos (point-max)) ; NPOS could be in a literal at EOB. + (setq c-bs-cache (cons elt c-bs-cache))) + (setq pos npos))) + + (if (> pos c-bs-cache-limit) + (setq c-bs-cache-limit pos)) + + ;; Can we just use the previous value? + (if (and can-use-prev + (<= c-bs-prev-pos here) + (> c-bs-prev-pos (car elt))) + (setq pos c-bs-prev-pos + stack c-bs-prev-stack) + (setq pos (car elt) + stack (cdr elt))) + (if (> here c-bs-cache-limit) + (setq c-bs-cache-limit here)) + (setq elt (c-update-brace-stack stack pos here) + c-bs-prev-pos (car elt) + c-bs-prev-stack (cdr elt)))))) + +(defun c-bs-at-toplevel-p (here) + ;; Is position HERE at the top level, as indicated by the brace stack? + (let ((stack (c-brace-stack-at here))) + (or (null stack) ; Probably unnecessary. + (<= (cadr stack) 1)))) + (defmacro c-find-decl-prefix-search () ;; Macro used inside `c-find-decl-spots'. It ought to be a defun, ;; but it contains lots of free variables that refer to things @@ -5221,6 +5426,7 @@ comment at the start of cc-engine.el for more info." cfd-re-match nil) (setq cfd-match-pos cfd-prop-match cfd-prop-match nil)) + (setq cfd-top-level (c-bs-at-toplevel-p cfd-match-pos)) (goto-char cfd-match-pos) @@ -5319,7 +5525,11 @@ comment at the start of cc-engine.el for more info." ;; comments. (cfd-token-pos 0) ;; The end position of the last entered macro. - (cfd-macro-end 0)) + (cfd-macro-end 0) + ;; Whether the last position returned from `c-find-decl-prefix-search' + ;; is at the top-level (including directly in a class or namespace, + ;; etc.). + cfd-top-level) ;; Initialize by finding a syntactically relevant start position ;; before the point, and do the first `c-decl-prefix-or-start-re' @@ -5627,7 +5837,7 @@ comment at the start of cc-engine.el for more info." nil)))) ; end of when condition (c-debug-put-decl-spot-faces cfd-match-pos (point)) - (if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0)) + (if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0) cfd-top-level) (setq cfd-prop-match nil)) (when (/= cfd-macro-end 0) @@ -7552,10 +7762,12 @@ comment at the start of cc-engine.el for more info." ;; Assuming point is at the start of a declarator, move forward over it, ;; leaving point at the next token after it (e.g. a ) or a ; or a ,). ;; - ;; Return a list (ID-START ID-END BRACKETS-AFTER-ID GOT-INIT), where ID-START and - ;; ID-END are the bounds of the declarator's identifier, and - ;; BRACKETS-AFTER-ID is non-nil if a [...] pair is present after the id. - ;; GOT-INIT is non-nil when the declarator is followed by "=" or "(". + ;; Return a list (ID-START ID-END BRACKETS-AFTER-ID GOT-INIT DECORATED), + ;; where ID-START and ID-END are the bounds of the declarator's identifier, + ;; and BRACKETS-AFTER-ID is non-nil if a [...] pair is present after the id. + ;; GOT-INIT is non-nil when the declarator is followed by "=" or "(", + ;; DECORATED is non-nil when the identifier is embellished by an operator, + ;; like "*x", or "(*x)". ;; ;; If ACCEPT-ANON is non-nil, move forward over any "anonymous declarator", ;; i.e. something like the (*) in int (*), such as might be found in a @@ -7574,7 +7786,7 @@ comment at the start of cc-engine.el for more info." ;; array/struct initialization) or "=" or terminating delimiter ;; (e.g. "," or ";" or "}"). (let ((here (point)) - id-start id-end brackets-after-id paren-depth) + id-start id-end brackets-after-id paren-depth decorated) (or limit (setq limit (point-max))) (if (and (< (point) limit) @@ -7614,6 +7826,8 @@ comment at the start of cc-engine.el for more info." (setq got-identifier t) nil)) t)) + (if (looking-at c-type-decl-operator-prefix-key) + (setq decorated t)) (if (eq (char-after) ?\() (progn (setq paren-depth (1+ paren-depth)) @@ -7668,7 +7882,7 @@ comment at the start of cc-engine.el for more info." (setq brackets-after-id t)) (backward-char) found)) - (list id-start id-end brackets-after-id (match-beginning 1)) + (list id-start id-end brackets-after-id (match-beginning 1) decorated) (goto-char here) nil))) @@ -7744,6 +7958,9 @@ comment at the start of cc-engine.el for more info." ;; inside a function declaration arglist). ;; '<> In an angle bracket arglist. ;; 'arglist Some other type of arglist. + ;; 'top Some other context and point is at the top-level (either + ;; outside any braces or directly inside a class or namespace, + ;; etc.) ;; nil Some other context or unknown context. Includes ;; within the parens of an if, for, ... construct. ;; 'not-decl This value is never supplied to this function. It @@ -8152,7 +8369,7 @@ comment at the start of cc-engine.el for more info." maybe-typeless backup-maybe-typeless (when c-recognize-typeless-decls - (and (not context) + (and (memq context '(nil top)) ;; Deal with C++11's "copy-initialization" ;; where we have (), by ;; contrasting with a typeless @@ -8215,7 +8432,7 @@ comment at the start of cc-engine.el for more info." (setq at-decl-end (looking-at (cond ((eq context '<>) "[,>]") - (context "[,)]") + ((not (memq context '(nil top))) "[,\)]") (t "[,;]")))) ;; Now we've collected info about various characteristics of @@ -8344,7 +8561,7 @@ comment at the start of cc-engine.el for more info." (if (and got-parens (not got-prefix) - (not context) + (memq context '(nil top)) (not (eq at-type t)) (or backup-at-type maybe-typeless @@ -8394,6 +8611,18 @@ comment at the start of cc-engine.el for more info." ;; instantiation expression). (throw 'at-decl-or-cast nil)))) + ;; CASE 9.5 + (when (and (not context) ; i.e. not at top level. + (c-major-mode-is 'c++-mode) + (eq at-decl-or-cast 'ids) + after-paren-pos) + ;; We've got something like "foo bar (...)" in C++ which isn't at + ;; the top level. This is probably a uniform initialization of bar + ;; to the contents of the parens. In this case the declarator ends + ;; at the open paren. + (goto-char (1- after-paren-pos)) + (throw 'at-decl-or-cast t)) + ;; CASE 10 (when at-decl-or-cast ;; By now we've located the type in the declaration that we know @@ -8402,7 +8631,7 @@ comment at the start of cc-engine.el for more info." ;; CASE 11 (when (and got-identifier - (not context) + (memq context '(nil top)) (looking-at c-after-suffixed-type-decl-key) (if (and got-parens (not got-prefix) @@ -8498,7 +8727,7 @@ comment at the start of cc-engine.el for more info." (when (and got-prefix-before-parens at-type (or at-decl-end (looking-at "=[^=]")) - (not context) + (memq context '(nil top)) (or (not got-suffix) at-decl-start)) ;; Got something like "foo * bar;". Since we're not inside @@ -8524,7 +8753,7 @@ comment at the start of cc-engine.el for more info." (throw 'at-decl-or-cast t))) ;; CASE 18 - (when (and context + (when (and (not (memq context '(nil top))) (or got-prefix (and (eq context 'decl) (not c-recognize-paren-inits) diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 735108f..26a002a 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -899,7 +899,8 @@ casts and declarations are fontified. Used on level 2 and higher." (c-get-char-property (1- (point)) 'c-type))))) (when (memq prop '(c-decl-id-start c-decl-type-start)) (c-forward-syntactic-ws limit) - (c-font-lock-declarators limit t (eq prop 'c-decl-type-start)))) + (c-font-lock-declarators limit t (eq prop 'c-decl-type-start) + (c-bs-at-toplevel-p (point))))) (setq c-font-lock-context ;; (c-guess-font-lock-context) (save-excursion @@ -991,7 +992,7 @@ casts and declarations are fontified. Used on level 2 and higher." (goto-char pos))))) nil) -(defun c-font-lock-declarators (limit list types) +(defun c-font-lock-declarators (limit list types not-top) ;; Assuming the point is at the start of a declarator in a declaration, ;; fontify the identifier it declares. (If TYPES is set, it does this via ;; the macro `c-fontify-types-and-refs'.) @@ -1001,7 +1002,9 @@ casts and declarations are fontified. Used on level 2 and higher." ;; additionally, mark the commas with c-type property 'c-decl-id-start or ;; 'c-decl-type-start (according to TYPES). Stop at LIMIT. ;; - ;; If TYPES is non-nil, fontify all identifiers as types. + ;; If TYPES is non-nil, fontify all identifiers as types. If NOT-TOP is + ;; non-nil, we are not at the top-level ("top-level" includes being directly + ;; inside a class or namespace, etc.). ;; ;; Nil is always returned. The function leaves point at the delimiter after ;; the last declarator it processes. @@ -1025,6 +1028,14 @@ casts and declarations are fontified. Used on level 2 and higher." (setq next-pos (point) id-start (car decl-res) id-face (if (and (eq (char-after) ?\() + (or (not (c-major-mode-is 'c++-mode)) + (not not-top) + (car (cddr (cddr decl-res))) ; Id is in + ; parens, etc. + (save-excursion + (forward-char) + (c-forward-syntactic-ws) + (looking-at "[*&]"))) (not (car (cddr decl-res))) ; brackets-after-id (or (not (c-major-mode-is 'c++-mode)) (save-excursion @@ -1199,7 +1210,7 @@ casts and declarations are fontified. Used on level 2 and higher." c-decl-start-re (eval c-maybe-decl-faces) - (lambda (match-pos inside-macro) + (lambda (match-pos inside-macro &optional toplev) ;; Note to maintainers: don't use `limit' inside this lambda form; ;; c-find-decl-spots sometimes narrows to less than `limit'. (setq start-pos (point)) @@ -1223,7 +1234,7 @@ casts and declarations are fontified. Used on level 2 and higher." (let ((type (and (> match-pos (point-min)) (c-get-char-property (1- match-pos) 'c-type)))) (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{))) - (setq context nil + (setq context (and toplev 'top) c-restricted-<>-arglists nil)) ;; A control flow expression or a decltype ((and (eq (char-before match-pos) ?\() @@ -1273,7 +1284,7 @@ casts and declarations are fontified. Used on level 2 and higher." 'c-not-decl)) ;; We're inside an "ordinary" open brace. ((eq (char-before match-pos) ?{) - (setq context nil + (setq context (and toplev 'top) c-restricted-<>-arglists nil)) ;; Inside an angle bracket arglist. ((or (eq type 'c-<>-arg-sep) @@ -1411,7 +1422,7 @@ casts and declarations are fontified. Used on level 2 and higher." (goto-char (car decl-or-cast)) (let ((decl-list - (if context + (if (not (memq context '(nil top))) ;; Should normally not fontify a list of ;; declarators inside an arglist, but the first ;; argument in the ';' separated list of a "for" @@ -1437,7 +1448,8 @@ casts and declarations are fontified. Used on level 2 and higher." 'c-decl-id-start))))) (c-font-lock-declarators - (min limit (point-max)) decl-list (cadr decl-or-cast))) + (min limit (point-max)) decl-list + (cadr decl-or-cast) (not toplev))) ;; A declaration has been successfully identified, so do all the ;; fontification of types and refs that've been recorded. @@ -1498,7 +1510,7 @@ casts and declarations are fontified. Used on level 2 and higher." (c-put-char-property (1- (point)) 'c-type 'c-decl-id-start) (c-forward-syntactic-ws) - (c-font-lock-declarators limit t nil))) + (c-font-lock-declarators limit t nil t))) nil) (defun c-font-lock-cut-off-declarators (limit) @@ -1512,6 +1524,7 @@ casts and declarations are fontified. Used on level 2 and higher." ;; fontification". (let ((decl-search-lim (c-determine-limit 1000)) paren-state bod-res is-typedef encl-pos + (here (point)) c-recognize-knr-p) ; Strictly speaking, bogus, but it ; speeds up lisp.h tremendously. (save-excursion @@ -1539,7 +1552,8 @@ casts and declarations are fontified. Used on level 2 and higher." (c-forward-syntactic-ws)) ;; At a real declaration? (if (memq (c-forward-type t) '(t known found decltype)) - (c-font-lock-declarators limit t is-typedef))))))) + (c-font-lock-declarators + limit t is-typedef (not (c-bs-at-toplevel-p here))))))))) nil)) (defun c-font-lock-enclosing-decls (limit) @@ -1573,7 +1587,8 @@ casts and declarations are fontified. Used on level 2 and higher." (goto-char ps-elt) (when (c-safe (c-forward-sexp)) (c-forward-syntactic-ws) - (c-font-lock-declarators limit t in-typedef)))))))) + (c-font-lock-declarators limit t in-typedef + (not (c-bs-at-toplevel-p (point))))))))))) (defun c-font-lock-raw-strings (limit) ;; Fontify C++ raw strings. @@ -1741,7 +1756,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." (eval . (list ,(c-make-font-lock-search-function 'c-known-type-key '(1 'font-lock-type-face t) - '((c-font-lock-declarators limit t nil) + '((c-font-lock-declarators limit t nil nil) (save-match-data (goto-char (match-end 1)) (c-forward-syntactic-ws)) @@ -1763,7 +1778,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." "\\)")) `(,type-match 'font-lock-type-face t) - `((c-font-lock-declarators limit t nil) + `((c-font-lock-declarators limit t nil nil) (save-match-data (goto-char (match-end ,type-match)) (c-forward-syntactic-ws)) @@ -1775,7 +1790,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." (concat "\\<\\(" (regexp-opt (c-lang-const c-typeless-decl-kwds)) "\\)\\>") - '((c-font-lock-declarators limit t nil) + '((c-font-lock-declarators limit t nil nil) (save-match-data (goto-char (match-end 1)) (c-forward-syntactic-ws)) @@ -2014,7 +2029,7 @@ higher." ;; before the '{' of the enum list, to avoid searching too far. "[^][{};/#=]*" "{") - '((c-font-lock-declarators limit t nil) + '((c-font-lock-declarators limit t nil t) (save-match-data (goto-char (match-end 0)) (c-put-char-property (1- (point)) 'c-type @@ -2413,7 +2428,7 @@ need for `c++-font-lock-extra-types'.") limit "[-+]" nil - (lambda (match-pos inside-macro) + (lambda (match-pos inside-macro &optional top-level) (forward-char) (c-font-lock-objc-method)))) nil) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index ae6e6a3..3c32848 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -479,10 +479,12 @@ so that all identifiers are recognized as words.") c-before-change-check-<>-operators c-depropertize-CPP c-before-after-change-digit-quote - c-invalidate-macro-cache) + c-invalidate-macro-cache + c-truncate-bs-cache) (c objc) '(c-extend-region-for-CPP c-depropertize-CPP - c-invalidate-macro-cache) + c-invalidate-macro-cache + c-truncate-bs-cache) ;; java 'c-before-change-check-<>-operators awk 'c-awk-record-region-clear-NL) (c-lang-defvar c-get-state-before-change-functions @@ -2588,6 +2590,41 @@ Note that Java specific rules are currently applied to tell this from (c-lang-defvar c-opt-inexpr-brace-list-key (c-lang-const c-opt-inexpr-brace-list-key)) +(c-lang-defconst c-flat-decl-block-kwds + ;; Keywords that can introduce another declaration level, i.e. where a + ;; following "{" isn't a function block or brace list. Note that, for + ;; historical reasons, `c-decl-block-key' is NOT constructed from this lang + ;; const. + t (c--delete-duplicates + (append (c-lang-const c-class-decl-kwds) + (c-lang-const c-other-block-decl-kwds) + (c-lang-const c-inexpr-class-kwds)) + :test 'string-equal)) + +(c-lang-defconst c-brace-stack-thing-key + ;; Regexp matching any keyword or operator relevant to the brace stack (see + ;; `c-update-brace-stack' in cc-engine.el). + t (c-make-keywords-re 'appendable + (append + (c-lang-const c-flat-decl-block-kwds) + (if (c-lang-const c-recognize-<>-arglists) + '("{" "}" ";" "," ")" ":" "<") + '("{" "}" ";" "," ")" ":"))))) +(c-lang-defvar c-brace-stack-thing-key (c-lang-const c-brace-stack-thing-key)) + +(c-lang-defconst c-brace-stack-no-semi-key + ;; Regexp matching any keyword or operator relevant to the brace stack when + ;; a semicolon is not relevant (see `c-update-brace-stack' in + ;; cc-engine.el). + t (c-make-keywords-re 'appendable + (append + (c-lang-const c-flat-decl-block-kwds) + (if (c-lang-const c-recognize-<>-arglists) + '("{" "}" "<") + '("{" "}"))))) +(c-lang-defvar c-brace-stack-no-semi-key + (c-lang-const c-brace-stack-no-semi-key)) + (c-lang-defconst c-decl-block-key ;; Regexp matching keywords in any construct that contain another ;; declaration level, i.e. that isn't followed by a function block @@ -3031,6 +3068,28 @@ Identifier syntax is in effect when this is matched \(see (c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key) 'dont-doc) +(c-lang-defconst c-type-decl-operator-prefix-key + "Regexp matching any declarator operator which isn't a keyword +that might precede the identifier in a declaration, e.g. the +\"*\" in \"char *argv\". The end of the first submatch is taken +as the end of the operator. Identifier syntax is in effect when +this is matched \(see `c-identifier-syntax-table')." + t ;; Default to a regexp that never matches. + "\\<\\>" + ;; Check that there's no "=" afterwards to avoid matching tokens + ;; like "*=". + (c objc) (concat "\\(\\*\\)" + "\\([^=]\\|$\\)") + c++ (concat "\\(" + "\\.\\.\\." + "\\|" + "\\*" + "\\)" + "\\([^=]\\|$\\)") + pike "\\(\\*\\)\\([^=]\\|$\\)") +(c-lang-defvar c-type-decl-operator-prefix-key + (c-lang-const c-type-decl-operator-prefix-key)) + (c-lang-defconst c-type-decl-suffix-key "Regexp matching the declarator operators that might follow after the identifier in a declaration, e.g. the \"[\" in \"char argv[]\". This diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index f2c6256..5b0679a 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -557,6 +557,8 @@ that requires a literal mode spec at compile time." ;; Initialize the cache of brace pairs, and opening braces/brackets/parens. (c-state-cache-init) + ;; Initialize the "brace stack" cache. + (c-init-bs-cache) (when (or c-recognize-<>-arglists (c-major-mode-is 'awk-mode) commit f95ca1268da211f5c60985d411df43bb5477430b Author: Eli Zaretskii Date: Sun Sep 11 22:07:47 2016 +0300 Avoid signaling errors when computing "Stop" in GDB menu * lisp/progmodes/gdb-mi.el (gdb-show-stop-p): Don't assume 'gdb-running-threads-count' must have a numeric value. (Bug#24414) diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 8047e20..a2d4f14 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -1976,6 +1976,7 @@ is running." (not gdb-non-stop)) gud-running) (and gdb-gud-control-all-threads + (not (null gdb-running-threads-count)) (> gdb-running-threads-count 0)))) ;; GUD displays the selected GDB frame. This might might not be the current commit 7edaa77c5e1c0284aac4ce2dc0254d22ae6e49af Author: Philipp Stephani Date: Sat Sep 3 20:37:47 2016 +0200 Stop calling ‘byte-compile-log-warning’ For errors, use ‘byte-compile-report-error’ instead so that the error is registered and causes compilation to fail (Bug#24359). For warnings, use ‘byte-compile-warn’ instead so that ‘byte-compile-error-on-warn’ is honored (Bug#24360). * lisp/emacs-lisp/macroexp.el (macroexp--funcall-if-compiled) (macroexp--warn-and-return): Use ‘byte-compile-warn’ instead of ‘byte-compile-log-warning’. * lisp/emacs-lisp/bytecomp.el (byte-compile-form, byte-compile-unfold-bcf) (byte-compile-setq, byte-compile-funcall): Use ‘byte-compile-report-error’ instead of ‘byte-compile-log-warning’. (byte-compile-log-warning): Convert comment to documentation string. Explain that the function shouldn’t be called directly. (byte-compile-report-error): Add optional FILL argument. * lisp/emacs-lisp/cconv.el (cconv-convert, cconv--analyze-use) (cconv--analyze-function, cconv-analyze-form): Use ‘byte-compile-warn’ instead of ‘byte-compile-log-warning’. * lisp/emacs-lisp/byte-opt.el (byte-compile-inline-expand): Use ‘byte-compile-warn’ instead of ‘byte-compile-log-warning’. * lisp/subr.el (add-to-list): Use ‘byte-compile-report-error’ instead of ‘byte-compile-log-warning’. (do-after-load-evaluation): Use ‘byte-compile-warn’ instead of ‘byte-compile-log-warning’. diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index dbaf2bc..610c3b6 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -288,8 +288,8 @@ (if (eq (car-safe newfn) 'function) (byte-compile-unfold-lambda `(,(cadr newfn) ,@(cdr form))) ;; This can happen because of macroexp-warn-and-return &co. - (byte-compile-log-warning - (format "Inlining closure %S failed" name)) + (byte-compile-warn + "Inlining closure %S failed" name) form)))) (_ ;; Give up on inlining. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 175690a..b6bb1d6 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1160,9 +1160,13 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'." (compilation-forget-errors) pt)))) -;; Log a message STRING in `byte-compile-log-buffer'. -;; Also log the current function and file if not already done. (defun byte-compile-log-warning (string &optional fill level) + "Log a message STRING in `byte-compile-log-buffer'. +Also log the current function and file if not already done. If +FILL is non-nil, set `warning-fill-prefix' to four spaces. LEVEL +is the warning level (`:warning' or `:error'). Do not call this +function directly; use `byte-compile-warn' or +`byte-compile-report-error' instead." (let ((warning-prefix-function 'byte-compile-warning-prefix) (warning-type-format "") (warning-fill-prefix (if fill " "))) @@ -1186,15 +1190,16 @@ Each function's symbol gets added to `byte-compile-noruntime-functions'." (unless (and funcp (memq symbol byte-compile-not-obsolete-funcs)) (byte-compile-warn "%s" msg))))) -(defun byte-compile-report-error (error-info) +(defun byte-compile-report-error (error-info &optional fill) "Report Lisp error in compilation. ERROR-INFO is the error data, in the form of either (ERROR-SYMBOL . DATA) -or STRING." +or STRING. If FILL is non-nil, set ‘warning-fill-prefix’ to four spaces +when printing the error message." (setq byte-compiler-error-flag t) (byte-compile-log-warning (if (stringp error-info) error-info (error-message-string error-info)) - nil :error)) + fill :error)) ;;; sanity-checking arglists @@ -3025,9 +3030,8 @@ for symbols generated by the byte compiler itself." (pcase (cdr form) (`(',var . ,_) (when (assq var byte-compile-lexical-variables) - (byte-compile-log-warning - (format-message "%s cannot use lexical var `%s'" fn var) - nil :error))))) + (byte-compile-report-error + (format-message "%s cannot use lexical var `%s'" fn var)))))) (when (macroexp--const-symbol-p fn) (byte-compile-warn "`%s' called as a function" fn)) (when (and (byte-compile-warning-enabled-p 'interactive-only) @@ -3044,9 +3048,8 @@ for symbols generated by the byte compiler itself." interactive-only)) (t ".")))) (if (eq (car-safe (symbol-function (car form))) 'macro) - (byte-compile-log-warning - (format "Forgot to expand macro %s in %S" (car form) form) - nil :error)) + (byte-compile-report-error + (format "Forgot to expand macro %s in %S" (car form) form))) (if (and handler ;; Make sure that function exists. (and (functionp handler) @@ -3143,9 +3146,8 @@ for symbols generated by the byte compiler itself." (dotimes (_ (- (/ (1+ fmax2) 2) alen)) (byte-compile-push-constant nil))) ((zerop (logand fmax2 1)) - (byte-compile-log-warning - (format "Too many arguments for inlined function %S" form) - nil :error) + (byte-compile-report-error + (format "Too many arguments for inlined function %S" form)) (byte-compile-discard (- alen (/ fmax2 2)))) (t ;; Turn &rest args into a list. @@ -3755,10 +3757,9 @@ discarding." (len (length args))) (if (= (logand len 1) 1) (progn - (byte-compile-log-warning + (byte-compile-report-error (format-message - "missing value for `%S' at end of setq" (car (last args))) - nil :error) + "missing value for `%S' at end of setq" (car (last args)))) (byte-compile-form `(signal 'wrong-number-of-arguments '(setq ,len)) byte-compile--for-effect)) @@ -4028,8 +4029,8 @@ that suppresses all warnings during execution of BODY." (progn (mapc 'byte-compile-form (cdr form)) (byte-compile-out 'byte-call (length (cdr (cdr form))))) - (byte-compile-log-warning - (format-message "`funcall' called with no arguments") nil :error) + (byte-compile-report-error + (format-message "`funcall' called with no arguments")) (byte-compile-form '(signal 'wrong-number-of-arguments '(funcall 0)) byte-compile--for-effect))) diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index 9f84367..46b5a7f 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -325,9 +325,9 @@ places where they originally did not directly appear." (var (if (not (consp binder)) (prog1 binder (setq binder (list binder))) (when (cddr binder) - (byte-compile-log-warning - (format-message "Malformed `%S' binding: %S" - letsym binder))) + (byte-compile-warn + "Malformed `%S' binding: %S" + letsym binder)) (setq value (cadr binder)) (car binder))) (new-val @@ -568,8 +568,8 @@ FORM is the parent form that binds this var." (`(,_ nil nil nil nil) nil) (`((,(and var (guard (eq ?_ (aref (symbol-name var) 0)))) . ,_) ,_ ,_ ,_ ,_) - (byte-compile-log-warning - (format-message "%s `%S' not left unused" varkind var)))) + (byte-compile-warn + "%s `%S' not left unused" varkind var))) (pcase vardata (`((,var . ,_) nil ,_ ,_ nil) ;; FIXME: This gives warnings in the wrong order, with imprecise line @@ -581,8 +581,8 @@ FORM is the parent form that binds this var." (eq ?_ (aref (symbol-name var) 0)) ;; As a special exception, ignore "ignore". (eq var 'ignored)) - (byte-compile-log-warning (format-message "Unused lexical %s `%S'" - varkind var)))) + (byte-compile-warn "Unused lexical %s `%S'" + varkind var))) ;; If it's unused, there's no point converting it into a cons-cell, even if ;; it's captured and mutated. (`(,binder ,_ t t ,_) @@ -606,9 +606,9 @@ FORM is the parent form that binds this var." (dolist (arg args) (cond ((byte-compile-not-lexical-var-p arg) - (byte-compile-log-warning - (format "Lexical argument shadows the dynamic variable %S" - arg))) + (byte-compile-warn + "Lexical argument shadows the dynamic variable %S" + arg)) ((eq ?& (aref (symbol-name arg) 0)) nil) ;Ignore &rest, &optional, ... (t (let ((varstruct (list arg nil nil nil nil))) (cl-pushnew arg byte-compile-lexical-variables) @@ -690,9 +690,8 @@ and updates the data stored in ENV." (setq forms (cddr forms)))) (`((lambda . ,_) . ,_) ; First element is lambda expression. - (byte-compile-log-warning - (format "Use of deprecated ((lambda %s ...) ...) form" (nth 1 (car form))) - t :warning) + (byte-compile-warn + "Use of deprecated ((lambda %s ...) ...) form" (nth 1 (car form))) (dolist (exp `((function ,(car form)) . ,(cdr form))) (cconv-analyze-form exp env))) @@ -701,8 +700,8 @@ and updates the data stored in ENV." (dolist (form forms) (cconv-analyze-form form env)))) ;; ((and `(quote ,v . ,_) (guard (assq v env))) - ;; (byte-compile-log-warning - ;; (format-message "Possible confusion variable/symbol for `%S'" v))) + ;; (byte-compile-warn + ;; "Possible confusion variable/symbol for `%S'" v)) (`(quote . ,_) nil) ; quote form (`(function . ,_) nil) ; same as quote @@ -719,8 +718,8 @@ and updates the data stored in ENV." (`(condition-case ,var ,protected-form . ,handlers) (cconv-analyze-form protected-form env) (when (and var (symbolp var) (byte-compile-not-lexical-var-p var)) - (byte-compile-log-warning - (format "Lexical variable shadows the dynamic variable %S" var))) + (byte-compile-warn + "Lexical variable shadows the dynamic variable %S" var)) (let* ((varstruct (list var nil nil nil nil))) (if var (push varstruct env)) (dolist (handler handlers) diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el index 310ca29..6d89145 100644 --- a/lisp/emacs-lisp/macroexp.el +++ b/lisp/emacs-lisp/macroexp.el @@ -103,7 +103,7 @@ each clause." (defun macroexp--funcall-if-compiled (_form) "Pseudo function used internally by macroexp to delay warnings. The purpose is to delay warnings to bytecomp.el, so they can use things -like `byte-compile-log-warning' to get better file-and-line-number data +like `byte-compile-warn' to get better file-and-line-number data and also to avoid outputting the warning during normal execution." nil) (put 'macroexp--funcall-if-compiled 'byte-compile @@ -122,7 +122,7 @@ and also to avoid outputting the warning during normal execution." (defvar macroexp--warned (make-hash-table :test #'equal :weakness 'key)) (defun macroexp--warn-and-return (msg form &optional compile-only) - (let ((when-compiled (lambda () (byte-compile-log-warning msg t)))) + (let ((when-compiled (lambda () (byte-compile-warn "%s" msg)))) (cond ((null msg) form) ((macroexp--compiling-p) diff --git a/lisp/subr.el b/lisp/subr.el index 96917b9..e913e37 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1635,7 +1635,7 @@ can do the job." ;; FIXME: We should also emit a warning for let-bound ;; variables with dynamic binding. (when (assq sym byte-compile--lexical-environment) - (byte-compile-log-warning msg t :error)))) + (byte-compile-report-error msg :fill)))) (code (macroexp-let2 macroexp-copyable-p x element `(if ,(if compare-fn @@ -4058,7 +4058,7 @@ This function is called directly from the C code." (expand-file-name byte-compile-current-file byte-compile-root-dir))) - (byte-compile-log-warning msg)) + (byte-compile-warn "%s" msg)) (run-with-timer 0 nil (lambda (msg) (message "%s" msg))