CC Mode: fix indentation in switch statement after "case a(1):".

* lisp/progmodes/cc-engine.el (c-beginning-of-statement-1): Enhance the
analysis of case labels to handle parenthesised expressions (e.g. macros).

* lisp/progmodes/cc-langs.el (c-nonlabel-nonparen-token-key): New lang const
and lang var.
This commit is contained in:
Alan Mackenzie 2019-05-15 08:58:31 +00:00
parent 8f544c6104
commit 356fb18a1f
2 changed files with 35 additions and 2 deletions

View file

@ -1253,12 +1253,20 @@ comment at the start of cc-engine.el for more info."
;; (including a case label) or something like C++'s "public:"?
;; A case label might use an expression rather than a token.
(setq after-case:-pos (or tok start))
(if (or (looking-at c-nonlabel-token-key) ; e.g. "while" or "'a'"
(if (or (looking-at c-nonlabel-nonparen-token-key)
; e.g. "while" or "'a'"
;; Catch C++'s inheritance construct "class foo : bar".
(save-excursion
(and
(c-safe (c-backward-sexp) t)
(looking-at c-nonlabel-token-2-key))))
(looking-at c-nonlabel-token-2-key)))
;; Catch C++'s "case a(1):"
(and (c-major-mode-is 'c++-mode)
(eq (char-after) ?\()
(save-excursion
(not (and
(zerop (c-backward-token-2 2))
(looking-at c-case-kwds-regexp))))))
(setq c-maybe-labelp nil)
(if after-labels-pos ; Have we already encountered a label?
(if (not last-label-pos)

View file

@ -3674,6 +3674,31 @@ i.e. before \":\". Only used if `c-recognize-colon-labels' is set."
c++ (concat "\\s(\\|\"\\|" (c-lang-const c-nonlabel-token-key)))
(c-lang-defvar c-nonlabel-token-key (c-lang-const c-nonlabel-token-key))
(c-lang-defconst c-nonlabel-nonparen-token-key
"Regexp matching things that can't occur in generic colon labels,
neither in a statement nor in a declaration context, with the
exception of an open parenthesis. The regexp is tested at the
beginning of every sexp in a suspected label, i.e. before \":\".
Only used if `c-recognize-colon-labels' is set."
;; This lang const is the same as `c-nonlabel-token-key', except for a
;; slight difference in the c++-mode value.
t (concat
;; All keywords except `c-label-kwds' and `c-protection-kwds'.
(c-make-keywords-re t
(c--set-difference (c-lang-const c-keywords)
(append (c-lang-const c-label-kwds)
(c-lang-const c-protection-kwds))
:test 'string-equal)))
;; Don't allow string literals, except in AWK and Java. Character constants are OK.
(c objc pike idl) (concat "\"\\|"
(c-lang-const c-nonlabel-nonparen-token-key))
;; Also check for open parens in C++, to catch member init lists in
;; constructors. We normally allow it so that macros with arguments
;; work in labels.
c++ (concat "[{[]\\|\"\\|" (c-lang-const c-nonlabel-nonparen-token-key)))
(c-lang-defvar c-nonlabel-nonparen-token-key
(c-lang-const c-nonlabel-nonparen-token-key))
(c-lang-defconst c-nonlabel-token-2-key
"Regexp matching things that can't occur two symbols before a colon in
a label construct. This catches C++'s inheritance construct \"class foo