From: Alan Mackenzie Date: Wed, 15 May 2019 08:58:31 +0000 (+0000) Subject: CC Mode: fix indentation in switch statement after "case a(1):". X-Git-Tag: emacs-27.0.90~2885 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=356fb18a1f64e58559fef92016be258b8cc70753;p=emacs.git 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. --- diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index a25d0595535..ed8310d0e67 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -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) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 8b7e4ef7c09..30da10a6c03 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -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