emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master aa1a4cc: Correct the indentation of CC Mode brace l


From: Alan Mackenzie
Subject: [Emacs-diffs] master aa1a4cc: Correct the indentation of CC Mode brace lists
Date: Tue, 12 Mar 2019 14:39:13 -0400 (EDT)

branch: master
commit aa1a4cceca2d93d83c721ce83950230739073727
Author: Alan Mackenzie <address@hidden>
Commit: Alan Mackenzie <address@hidden>

    Correct the indentation of CC Mode brace lists
    
    while preserving the indentation of nested C++ uniform initialization.
    
    * lisp/progmodes/cc-align.el (c-lineup-2nd-brace-entry-in-arglist)
    (c-lineup-class-decl-init-+, c-lineup-class-decl-init-after-brace): New
    indentation functions.
    
    * lisp/progmodes/cc-engine.el (c-forward-class-decl): New function.
    (c-do-declarators): New function, partially extracted from
    c-font-lock-declarators, which now calls the new function.
    (c-inside-bracelist-p): Amend the introductory comment.
    (c-add-stmt-syntax): Add code to prevent the spurious recognition of a
    'defun-block-intro when a brace pair is used as an initializer.
    (c-evaluate-offset): No longer ignore vectors of length >= 2.
    (c-calc-offset): Refactor clumsily nested `if'/`or' into a cond form.
    
    * lisp/progmodes/cc-fonts.el (c-font-lock-declarators): Replace the bulk of
    this function by a call to the new c-forward-class-decl.
    
    * lisp/progmodes/cc-langs.el (c-type-decl-prefix-key): Recognize "~" as a
    type decl operator.
    
    * lisp/progmodes/cc-mode.el (c-fl-decl-start): While searching backward for 
a
    "}" at an EOD, deal with actually finding the end of a brace list.
    
    * doc/misc/cc-mode.texi (List Line-Up): document
    c-lineup-2nd-brace-entry-in-arglist, c-lineup-class-decl-init-+, and
    c-lineup-class-decl-init-after-brace.
    
    * lisp/progmodes/cc-styles.el (c-style-alist): In styles "gnu", "bsd",
    "stroustrup", "python", and "java", change the offset for brace-list-intro
    from the default value or c-lineup-arglist-intro-after-paren to a list
    beginning with the symbol first, followed by two of the new alignment
    functions, followed by +.
    
    * lisp/progmodes/cc-vars.el (c-offset-alist): Change the default value of
    brace-list-entry from c-lineup-under-anchor back to 0.
---
 doc/misc/cc-mode.texi       | 125 +++++++++++++++++++-
 lisp/progmodes/cc-align.el  | 124 ++++++++++++++++++++
 lisp/progmodes/cc-engine.el | 271 +++++++++++++++++++++++++++++++++++---------
 lisp/progmodes/cc-fonts.el  | 143 ++++++-----------------
 lisp/progmodes/cc-langs.el  |   2 +-
 lisp/progmodes/cc-mode.el   |  11 +-
 lisp/progmodes/cc-styles.el |  16 ++-
 lisp/progmodes/cc-vars.el   |   2 +-
 8 files changed, 524 insertions(+), 170 deletions(-)

diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi
index 0c77cc0..170149e 100644
--- a/doc/misc/cc-mode.texi
+++ b/doc/misc/cc-mode.texi
@@ -5638,9 +5638,9 @@ any problems writing custom line-up functions for AWK 
mode.
 
 The calling convention for line-up functions is described fully in
 @ref{Custom Line-Up}.  Roughly speaking, the return value is either an
-offset itself (such as @code{+} or @code{[0]}) or it's @code{nil},
-meaning ``this function is inappropriate in this case; try a
-different one''.  @xref{c-offsets-alist}.
+offset itself (such as @code{+} or @code{[0]}), another line-up
+function, or it's @code{nil}, meaning ``this function is inappropriate
+in this case - try a different one''.  @xref{c-offsets-alist}.
 
 The subsections below describe all the standard line-up functions,
 categorized by the sort of token the lining-up centers around.  For
@@ -5995,6 +5995,125 @@ brace block.
 
 @comment ------------------------------------------------------------
 
address@hidden c-lineup-2nd-brace-entry-in-arglist
address@hidden lineup-2nd-brace-entry-in-arglist (c-)
+Line up the second entry of a brace block under the first, when the
+first line is also contained in an arglist or an enclosing brace
address@hidden that line}.
+
+I.e. handle something like the following:
+
address@hidden
address@hidden
+set_line (line_t @address@hidden, address@hidden,
+                  address@hidden, address@hidden,       
@hereFn{brace-list-intro}
+                  address@hidden);
+         ^ enclosing parenthesis.
address@hidden group
address@hidden example
+                      
+
+The middle line of that example will have a syntactic context with
+three syntactic symbols, @code{arglist-cont-nonempty},
address@hidden, and @code{brace-list-entry} (@pxref{Brace
+List Symbols}).
+
+This function is intended for use in a list.  If the construct being
+analyzed isn't like the preceding, the function returns nil.
+Otherwise it returns the function
address@hidden, which the caller then uses
+to perform indentation.
+
address@hidden @code{brace-list-intro}.
address@hidden defun
+
address@hidden ------------------------------------------------------------
+
address@hidden c-lineup-class-decl-init-+
address@hidden lineup-class-decl-init-+ (c-)
+Line up the second entry of a class (etc.) initializer
address@hidden characters in from the identifier when:
address@hidden
address@hidden
+The type is a class, struct, union, etc. (but not an enum);
address@hidden
+There is a brace block in the type declaration, specifying it; and
address@hidden
+The first element of the initializer is on the same line as its
+opening brace.
address@hidden enumerate
+
+I.e. we have a construct like this:
+
address@hidden
address@hidden
+struct STR @{
+    int i; float f;
address@hidden str_1 = @{1, address@hidden,
+    str_2 = @{2,
+         3.1          @hereFn{brace-list-intro}
+    @};
+    @sssTBasicOffset{}
address@hidden group
address@hidden example
+        
+
+Note that the syntactic context of the @code{brace-list-intro} line
+also has a syntactic element with the symbol @code{brace-list-entry}
+(@pxref{Brace List Symbols}).
+
+This function is intended for use in a list.  If the above structure
+isn't present, the function returns nil, allowing a different offset
+specification to indent the line.
+
address@hidden @code{brace-list-intro}.
address@hidden defun
+
address@hidden ------------------------------------------------------------
+
address@hidden c-lineup-class-decl-init-after-brace
address@hidden lineup-class-decl-init-after-brace (c-)
+Line up the second entry of a class (etc.) initializer after its
+opening brace when:
address@hidden
address@hidden
+The type is a class, struct, union, etc. (but not an enum);
address@hidden
+There is a brace block in the type declaration, specifying it; and
address@hidden
+The first element of the initializer is on the same line as its
+opening brace.
address@hidden enumerate
+
+I.e. we have a construct like this:
+
address@hidden
address@hidden
+struct STR @{
+    int i; float f;
address@hidden str_1 = @{1, address@hidden,
+    str_2 = @{2,
+             3.1      @hereFn{brace-list-intro}
+    @};
address@hidden group
address@hidden example
+        
+
+Note that the syntactic context of the @code{brace-list-intro} line
+also has a syntactic element with the symbol @code{brace-list-entry}
+(@pxref{Brace List Symbols}).  Also note that this function works by
+returning the symbol @code{c-lineup-arglist-intro-after-paren}, which
+the caller then uses to perform the indentation.
+
+This function is intended for use in a list.  If the above structure
+isn't present, the function returns nil, allowing a different offset
+specification to indent the line.
+
address@hidden @code{brace-list-intro}.
address@hidden defun
+
address@hidden ------------------------------------------------------------
+
 @defun c-lineup-multi-inher
 @findex lineup-multi-inher @r{(c-)}
 Line up the classes in C++ multiple inheritance clauses and member
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index 1f94bfd..009f58e 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -1083,6 +1083,130 @@ arglist-cont."
              (vector (+ (current-column) c-basic-offset))))
        (vector 0)))))
 
+(defun c-lineup-2nd-brace-entry-in-arglist (langelem)
+  "Lineup the second entry of a brace block under the first, when the first
+line is also contained in an arglist or an enclosing brace ON THAT LINE.
+
+I.e. handle something like the following:
+
+    set_line (line_t {point_t{0.4, 0.2},
+                      point_t{0.2, 0.5},       <---- brace-list-intro
+                      .....});
+             ^ enclosing parenthesis.
+
+The middle line of that example will have a syntactic context
+with three syntactic symbols, arglist-cont-nonempty, brace-list-intro, and
+brace-list-entry.
+
+This function is intended for use in a list.  If the construct
+being analyzed isn't like the preceding, the function returns nil.
+Otherwise it returns the function `c-lineup-arglist-intro-after-paren', which
+the caller then uses to perform indentation.
+
+Works with brace-list-intro."
+  ;; brace-list-intro and brace-list-entry are both present for the second
+  ;; entry of the list when the first entry is on the same line as the opening
+  ;; brace.
+  (and (assq 'brace-list-intro c-syntactic-context)
+       (assq 'brace-list-entry c-syntactic-context)
+       (or (assq 'arglist-cont-nonempty c-syntactic-context) ; "(" earlier on
+                                                            ; the line.
+          (save-excursion              ; "{" earlier on the line
+            (goto-char (c-langelem-pos
+                        (assq 'brace-list-intro c-syntactic-context)))
+            (and
+             (eq (c-backward-token-2
+                  1 nil
+                  (c-point 'bol (c-langelem-pos
+                                 (assq 'brace-list-entry
+                                       c-syntactic-context))))
+                 0)
+             (eq (char-after) ?{))))
+       'c-lineup-arglist-intro-after-paren))
+
+(defun c-lineup-class-decl-init-+ (langelem)
+  "Line up the second entry of a class (etc.) initializer c-basic-offset
+characters in from the identifier when:
+\(i) The type is a class, struct, union, etc. (but not an enum);
+\(ii) There is a brace block in the type declaration, specifying it; and
+\(iii) The first element of the initializer is on the same line as its opening
+brace.
+
+I.e. we have a construct like this:
+
+    struct STR {
+        int i; float f;
+    } str_1 = {1, 1.7},
+        str_2 = {2,
+             3.1                   <---- brace-list-intro
+        };
+        <-->                       <---- c-basic-offset
+
+Note that the syntactic context of the brace-list-intro line also has a
+syntactic element with the symbol brace-list-entry.
+
+This function is intended for use in a list.  If the above structure isn't
+present, this function returns nil, allowing a different offset specification
+to indent the line.
+
+Works with: brace-list-intro."
+  (and (assq 'brace-list-intro c-syntactic-context)
+       (assq 'brace-list-entry c-syntactic-context)
+       (let ((init-pos (c-point 'boi (c-langelem-pos
+                                     (assq 'brace-list-entry
+                                           c-syntactic-context))))
+            )
+        (save-excursion
+          (goto-char (c-langelem-pos (assq 'brace-list-intro
+                                           c-syntactic-context)))
+          (and
+           (c-forward-class-decl)
+           (not (c-do-declarators init-pos t nil nil nil))
+           (eq (point) init-pos)
+           (vector (+ (current-column) c-basic-offset)))))))
+
+(defun c-lineup-class-decl-init-after-brace (langelem)
+  "Line up the second entry of a class (etc.) initializer after its opening
+brace when:
+\(i) The type is a class, struct, union, etc. (but not an enum);
+\(ii) There is a brace block in the type declaration, specifying it; and
+\(iii) The first element of the initializer is on the same line as its opening
+brace.
+
+I.e. we have a construct like this:
+
+    struct STR {
+        int i; float f;
+    } str_1 = {1, 1.7},
+        str_2 = {2,
+                 3.1                   <---- brace-list-intro
+        };
+
+Note that the syntactic context of the brace-list-intro line also has a
+syntactic element with the symbol brace-list-entry.  Also note that this
+function works by returning the symbol `c-lineup-arglist-intro-after-paren',
+which the caller then uses to perform the indentation.
+
+This function is intended for use in a list.  If the above structure isn't
+present, this function returns nil, allowing a different offset specification
+to indent the line.
+
+Works with: brace-list-intro."
+  (and (assq 'brace-list-intro c-syntactic-context)
+       (assq 'brace-list-entry c-syntactic-context)
+       (let ((init-pos (c-point 'boi (c-langelem-pos
+                                     (assq 'brace-list-entry
+                                           c-syntactic-context))))
+            )
+        (save-excursion
+          (goto-char (c-langelem-pos (assq 'brace-list-intro
+                                           c-syntactic-context)))
+          (and
+           (c-forward-class-decl)
+           (not (c-do-declarators init-pos t nil nil nil))
+           (eq (point) init-pos)
+           'c-lineup-arglist-intro-after-paren)))))
+
 (defun c-lineup-cpp-define (_langelem)
   "Line up macro continuation lines according to the indentation of
 the construct preceding the macro.  E.g.:
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 301d07c..fd66928 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -8040,49 +8040,28 @@ comment at the start of cc-engine.el for more info."
     (or res (goto-char here))
     res))
 
+(defun c-forward-class-decl ()
+  "From the beginning of a struct/union, etc. move forward to
+after the brace block which defines it, leaving point at the
+start of the next token and returning point.  On failure leave
+point unchanged and return nil."
+  (let ((here (point)))
+    (if
+       (and
+        (looking-at c-class-key)
+        (eq (c-forward-token-2) 0)
+        (c-on-identifier)
+        (eq (c-forward-token-2) 0)
+        (eq (char-after) ?{)
+        (c-go-list-forward))
+       (progn
+         (c-forward-syntactic-ws)
+         (point))
+      (goto-char here)
+      nil)))
 
 ;; Handling of large scale constructs like statements and declarations.
 
-;; Macro used inside `c-forward-decl-or-cast-1'.  It ought to be a
-;; defsubst or perhaps even a defun, but it contains lots of free
-;; variables that refer to things inside `c-forward-decl-or-cast-1'.
-(defmacro c-fdoc-shift-type-backward (&optional short)
-  ;; `c-forward-decl-or-cast-1' can consume an arbitrary length list
-  ;; of types when parsing a declaration, which means that it
-  ;; sometimes consumes the identifier in the declaration as a type.
-  ;; This is used to "backtrack" and make the last type be treated as
-  ;; an identifier instead.
-  `(progn
-     ,(unless short
-       ;; These identifiers are bound only in the inner let.
-       '(setq identifier-type at-type
-              identifier-start type-start
-              got-parens nil
-              got-identifier t
-              got-suffix t
-              got-suffix-after-parens id-start
-              paren-depth 0))
-
-     (if (setq at-type (if (eq backup-at-type 'prefix)
-                          t
-                        backup-at-type))
-        (setq type-start backup-type-start
-              id-start backup-id-start)
-       (setq type-start start-pos
-            id-start start-pos))
-
-     ;; When these flags already are set we've found specifiers that
-     ;; unconditionally signal these attributes - backtracking doesn't
-     ;; change that.  So keep them set in that case.
-     (or at-type-decl
-        (setq at-type-decl backup-at-type-decl))
-     (or maybe-typeless
-        (setq maybe-typeless backup-maybe-typeless))
-
-     ,(unless short
-       ;; This identifier is bound only in the inner let.
-       '(setq start id-start))))
-
 (defun c-forward-declarator (&optional limit accept-anon)
   ;; 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 ,).
@@ -8235,6 +8214,176 @@ comment at the start of cc-engine.el for more info."
       (goto-char here)
       nil)))
 
+(defun c-do-declarators
+    (cdd-limit cdd-list cdd-not-top cdd-comma-prop cdd-function)
+  "Assuming point is at the start of a comma separated list of declarators,
+apply CDD-FUNCTION to each declarator (when CDD-LIST is non-nil) or just the
+first declarator (when CDD-LIST is nil).  When CDD-FUNCTION is nil, no
+function is applied.
+
+CDD-FUNCTION is supplied with 6 arguments:
+0. The start position of the declarator's identifier;
+1. The end position of this identifier;
+\[Note: if there is no identifier, as in int (*);, both of these are nil.]
+2. The position of the next token after the declarator (CLARIFY!!!).
+3. CDD-NOT-TOP;
+4. Non-nil if the identifier is of a function.
+5. When there is an initialization following the declarator (such as \"=
+....\" or \"( ....\".), the character which introduces this initialization,
+otherwise nil.
+
+Additionally, if CDD-COMMA-PROP is non-nil, mark the separating commas with
+this value of the c-type property, when CDD-LIST is non-nil.
+
+Stop at or before CDD-LIMIT (which may NOT be nil).
+
+If CDD-NOT-TOP is non-nil, we are not at the top-level (\"top-level\" includes
+being directly inside a class or namespace, etc.).
+
+Return non-nil if we've reached the token after the last declarator (often a
+semicolon, or a comma when CDD-LIST is nil); otherwise (when we hit CDD-LIMIT,
+or fail otherwise) return nil, leaving point at the beginning of the putative
+declarator that could not be processed.
+
+This function might do hidden buffer changes."
+  ;; N.B.: We use the "cdd-" prefix in this routine to try to prevent
+  ;; confusion with possible reference to common variable names from within
+  ;; CDD-FUNCTION.
+  (let
+      ((cdd-pos (point)) cdd-next-pos cdd-id-start cdd-id-end
+       cdd-decl-res cdd-got-func cdd-got-type cdd-got-init
+       c-last-identifier-range cdd-exhausted)
+
+    ;; The following `while' applies `cdd-function' to a single declarator id
+    ;; each time round.  It loops only when CDD-LIST is non-nil.
+    (while
+       (and (not cdd-exhausted)
+            (setq cdd-decl-res (c-forward-declarator cdd-limit)))
+      (setq cdd-next-pos (point)
+           cdd-id-start (car cdd-decl-res)
+           cdd-id-end (cadr cdd-decl-res)
+           cdd-got-func (and (eq (char-after) ?\()
+                         (or (not (c-major-mode-is 'c++-mode))
+                             (not cdd-not-top)
+                             (car (cddr (cddr cdd-decl-res))) ; Id is in
+                                       ; parens, etc.
+                             (save-excursion
+                               (forward-char)
+                               (c-forward-syntactic-ws)
+                               (looking-at "[*&]")))
+                         (not (car (cddr cdd-decl-res)))
+                         (or (not (c-major-mode-is 'c++-mode))
+                             (save-excursion
+                               (let (c-last-identifier-range)
+                                 (forward-char)
+                                 (c-forward-syntactic-ws)
+                                 (catch 'is-function
+                                   (while
+                                       (progn
+                                         (if (eq (char-after) ?\))
+                                             (throw 'is-function t))
+                                         (setq cdd-got-type (c-forward-type))
+                                         (cond
+                                          ((null cdd-got-type)
+                                           (throw 'is-function nil))
+                                          ((not (eq cdd-got-type 'maybe))
+                                           (throw 'is-function t)))
+                                         (c-forward-declarator nil t)
+                                         (eq (char-after) ?,))
+                                     (forward-char)
+                                     (c-forward-syntactic-ws))
+                                   t)))))
+           cdd-got-init (and (cadr (cddr cdd-decl-res))
+                         (char-after)))
+
+      ;; Jump past any initializer or function prototype to see if
+      ;; there's a ',' to continue at.
+      (cond (cdd-got-func
+            ;; Skip a parenthesized initializer (C++) or a function
+            ;; prototype.
+            (if (c-go-list-forward (point) cdd-limit) ; over the parameter 
list.
+                (c-forward-syntactic-ws cdd-limit)
+              (setq cdd-exhausted t))) ; unbalanced parens
+
+           (cdd-got-init       ; "=" sign OR opening "(", "[", or "{"
+            ;; Skip an initializer expression.  If we're at a '='
+            ;; then accept a brace list directly after it to cope
+            ;; with array initializers.  Otherwise stop at braces
+            ;; to avoid going past full function and class blocks.
+            (if (and (if (and (eq cdd-got-init ?=)
+                              (= (c-forward-token-2 1 nil cdd-limit) 0)
+                              (looking-at "{"))
+                         (c-go-list-forward (point) cdd-limit)
+                       t)
+                     ;; FIXME: Should look for c-decl-end markers here;
+                     ;; we might go far into the following declarations
+                     ;; in e.g. ObjC mode (see e.g. methods-4.m).
+                     (c-syntactic-re-search-forward "[;,{]" cdd-limit 'move t))
+                (backward-char)
+              (setq cdd-exhausted t)
+              ))
+
+           (t (c-forward-syntactic-ws cdd-limit)))
+
+      (if cdd-function
+         (funcall cdd-function cdd-id-start cdd-id-end cdd-next-pos
+                  cdd-not-top cdd-got-func cdd-got-init))
+
+      ;; If a ',' is found we set cdd-pos to the next declarator and iterate.
+      (if (and cdd-list (< (point) cdd-limit) (looking-at ","))
+         (progn
+           (when cdd-comma-prop
+             (c-put-char-property (point) 'c-type cdd-comma-prop))
+           (forward-char)
+           (c-forward-syntactic-ws cdd-limit)
+           (setq cdd-pos (point)))
+       (setq cdd-exhausted t)))
+
+    (if (> (point) cdd-pos)
+       t
+      (goto-char cdd-pos)
+      nil)))
+
+;; Macro used inside `c-forward-decl-or-cast-1'.  It ought to be a
+;; defsubst or perhaps even a defun, but it contains lots of free
+;; variables that refer to things inside `c-forward-decl-or-cast-1'.
+(defmacro c-fdoc-shift-type-backward (&optional short)
+  ;; `c-forward-decl-or-cast-1' can consume an arbitrary length list
+  ;; of types when parsing a declaration, which means that it
+  ;; sometimes consumes the identifier in the declaration as a type.
+  ;; This is used to "backtrack" and make the last type be treated as
+  ;; an identifier instead.
+  `(progn
+     ,(unless short
+       ;; These identifiers are bound only in the inner let.
+       '(setq identifier-type at-type
+              identifier-start type-start
+              got-parens nil
+              got-identifier t
+              got-suffix t
+              got-suffix-after-parens id-start
+              paren-depth 0))
+
+     (if (setq at-type (if (eq backup-at-type 'prefix)
+                          t
+                        backup-at-type))
+        (setq type-start backup-type-start
+              id-start backup-id-start)
+       (setq type-start start-pos
+            id-start start-pos))
+
+     ;; When these flags already are set we've found specifiers that
+     ;; unconditionally signal these attributes - backtracking doesn't
+     ;; change that.  So keep them set in that case.
+     (or at-type-decl
+        (setq at-type-decl backup-at-type-decl))
+     (or maybe-typeless
+        (setq maybe-typeless backup-maybe-typeless))
+
+     ,(unless short
+       ;; This identifier is bound only in the inner let.
+       '(setq start id-start))))
+
 (defun c-forward-decl-or-cast-1 (preceding-token-end context last-cast-end)
   ;; Move forward over a declaration or a cast if at the start of one.
   ;; The point is assumed to be at the start of some token.  Nil is
@@ -10727,12 +10876,17 @@ comment at the start of cc-engine.el for more info."
       )))
 
 (defun c-inside-bracelist-p (containing-sexp paren-state accept-in-paren)
-  ;; return the buffer position of the beginning of the brace list
-  ;; statement if we're inside a brace list, otherwise return nil.
-  ;; CONTAINING-SEXP is the buffer pos of the innermost containing
-  ;; paren.  PAREN-STATE is the remainder of the state of enclosing
-  ;; braces.  ACCEPT-IN-PAREN is non-nil iff we will accept as a brace
-  ;; list a brace directly enclosed in a parenthesis.
+  ;; return the buffer position of the beginning of the brace list statement
+  ;; if CONTAINING-SEXP is inside a brace list, otherwise return nil.
+  ;;
+  ;; CONTAINING-SEXP is the buffer pos of the innermost containing paren.  NO
+  ;; IT ISN'T!!!  [This function is badly designed, and probably needs
+  ;; reformulating without its first argument, and the critical position being
+  ;; at point.]
+  ;;
+  ;; PAREN-STATE is the remainder of the state of enclosing braces.
+  ;; ACCEPT-IN-PAREN is non-nil iff we will accept as a brace list a brace
+  ;; directly enclosed in a parenthesis.
   ;;
   ;; The "brace list" here is recognized solely by its context, not by
   ;; its contents.
@@ -10852,7 +11006,8 @@ comment at the start of cc-engine.el for more info."
 (defun c-looking-at-statement-block ()
   ;; Point is at an opening brace.  If this is a statement block (i.e. the
   ;; elements in the block are terminated by semicolons, or the block is
-  ;; empty, or the block contains a keyword) return t.  Otherwise, return nil.
+  ;; empty, or the block contains a keyword) return non-nil.  Otherwise,
+  ;; return nil.
   (let ((here (point)))
     (prog1
        (if (c-go-list-forward)
@@ -11356,7 +11511,7 @@ comment at the start of cc-engine.el for more info."
 
            (if (and (eq step-type 'same)
                     (/= paren-pos (point)))
-               (let (inexpr)
+               (let (inexpr bspec)
                  (cond
                   ((save-excursion
                      (goto-char paren-pos)
@@ -11378,6 +11533,13 @@ comment at the start of cc-engine.el for more info."
                          (c-looking-at-statement-block))
                        (c-add-syntax 'defun-block-intro nil)
                      (c-add-syntax 'brace-list-intro nil)))
+                  ((save-excursion
+                     (goto-char paren-pos)
+                     (setq bspec (c-looking-at-or-maybe-in-bracelist
+                                  containing-sexp containing-sexp))
+                     (and (consp bspec)
+                          (eq (cdr bspec) 'in-paren)))
+                   (c-add-syntax 'brace-list-intro (car bspec)))
                   (t (c-add-syntax 'defun-block-intro nil))))
 
              (c-add-syntax 'statement-block-intro nil)))
@@ -13242,7 +13404,7 @@ Cannot combine absolute offsets %S and %S in `add' 
method"
           nil))))
 
     (if (or (null res) (integerp res)
-           (and (vectorp res) (= (length res) 1) (integerp (aref res 0))))
+           (and (vectorp res) (>= (length res) 1) (integerp (aref res 0))))
        res
       (c-benign-error "Error evaluating offset %S for %s: Got invalid value %S"
                      offset symbol res)
@@ -13265,12 +13427,11 @@ Cannot combine absolute offsets %S and %S in `add' 
method"
       (if c-strict-syntax-p
          (c-benign-error "No offset found for syntactic symbol %s" symbol))
       (setq offset 0))
-    (if (vectorp offset)
-       offset
-      (or (and (numberp offset) offset)
-         (and (symbolp offset) (symbol-value offset))
-         0))
-    ))
+    (cond
+     ((or (vectorp offset) (numberp offset))
+      offset)
+     ((and (symbolp offset) (symbol-value offset)))
+     (t 0))))
 
 (defun c-get-offset (langelem)
   ;; This is a compatibility wrapper for `c-calc-offset' in case
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 0588032..0b41eff 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -1032,114 +1032,41 @@ casts and declarations are fontified.  Used on level 2 
and higher."
 
   ;;(message "c-font-lock-declarators from %s to %s" (point) limit)
   (c-fontify-types-and-refs
-      ((pos (point)) next-pos id-start
-       decl-res
-       id-face got-type got-init
-       c-last-identifier-range
-       (separator-prop (if types 'c-decl-type-start 'c-decl-id-start)))
-
-    ;; The following `while' fontifies a single declarator id each time round.
-    ;; It loops only when LIST is non-nil.
-    (while
-       (and pos (setq decl-res (c-forward-declarator)))
-      (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)))
-                            (or (not (c-major-mode-is 'c++-mode))
-                                (save-excursion
-                                  (let (c-last-identifier-range)
-                                    (forward-char)
-                                    (c-forward-syntactic-ws)
-                                    (catch 'is-function
-                                      (while
-                                          (progn
-                                            (if (eq (char-after) ?\))
-                                                (throw 'is-function t))
-                                            (setq got-type (c-forward-type))
-                                            (cond
-                                             ((null got-type)
-                                              (throw 'is-function nil))
-                                             ((not (eq got-type 'maybe))
-                                              (throw 'is-function t)))
-                                            (c-forward-declarator nil t)
-                                            (eq (char-after) ?,))
-                                        (forward-char)
-                                        (c-forward-syntactic-ws))
-                                      t)))))
-                       'font-lock-function-name-face
-                     'font-lock-variable-name-face)
-           got-init (and (cadr (cddr decl-res)) ; got-init
-                         (char-after)))
-
-      (if types
-         ;; Register and fontify the identifier as a type.
-         (let ((c-promote-possible-types t))
-           (goto-char id-start)
-           (c-forward-type))
-       ;; Fontify the last symbol in the identifier if it isn't fontified
-       ;; already.  The check is necessary only in certain cases where this
-       ;; function is used "sloppily", e.g. in `c-simple-decl-matchers'.
-       (when (and c-last-identifier-range
-                  (not (get-text-property (car c-last-identifier-range)
-                                          'face)))
-         (c-put-font-lock-face (car c-last-identifier-range)
-                               (cdr c-last-identifier-range)
-                               id-face)))
-
-      (goto-char next-pos)
-      (setq pos nil)         ; So as to terminate the enclosing `while' form.
-      (if (and template-class
-              (eq got-init ?=) ; C++ "<class X = Y>"?
-              (c-forward-token-2 1 nil limit) ; Over "="
-              (let ((c-promote-possible-types t))
-                (c-forward-type t)))          ; Over "Y"
-         (setq list nil)) ; Shouldn't be needed.  We can't have a list, here.
-
-      (when list
-       ;; Jump past any initializer or function prototype to see if
-       ;; there's a ',' to continue at.
-       (cond ((eq id-face 'font-lock-function-name-face)
-              ;; Skip a parenthesized initializer (C++) or a function
-              ;; prototype.
-              (if (c-safe (c-forward-sexp 1) t) ; over the parameter list.
-                  (c-forward-syntactic-ws limit)
-                (goto-char limit)))    ; unbalanced parens
-
-             (got-init ; "=" sign OR opening "(", "[", or "{"
-              ;; Skip an initializer expression.  If we're at a '='
-              ;; then accept a brace list directly after it to cope
-              ;; with array initializers.  Otherwise stop at braces
-              ;; to avoid going past full function and class blocks.
-              (and (if (and (eq got-init ?=)
-                            (= (c-forward-token-2 1 nil limit) 0)
-                            (looking-at "{"))
-                       (c-safe (c-forward-sexp) t) ; over { .... }
-                     t)
-                   (< (point) limit)
-                   ;; FIXME: Should look for c-decl-end markers here;
-                   ;; we might go far into the following declarations
-                   ;; in e.g. ObjC mode (see e.g. methods-4.m).
-                   (c-syntactic-re-search-forward "[;,{]" limit 'move t)
-                   (backward-char)))
-
-             (t (c-forward-syntactic-ws limit)))
-
-       ;; If a ',' is found we set pos to the next declarator and iterate.
-       (when (and (< (point) limit) (looking-at ","))
-         (c-put-char-property (point) 'c-type separator-prop)
-         (forward-char)
-         (c-forward-syntactic-ws limit)
-         (setq pos (point))))))     ; acts to make the `while' form continue.
-  nil)
+      ()
+    (c-do-declarators
+     limit list not-top
+     (if types 'c-decl-type-start 'c-decl-id-start)
+     (lambda (id-start id-end end-pos not-top is-function init-char)
+       (if types
+          ;; Register and fontify the identifier as a type.
+          (let ((c-promote-possible-types t))
+            (goto-char id-start)
+            (c-forward-type))
+        ;; The following doesn't work properly (yet, 2018-09-22).
+        ;; (c-put-font-lock-face id-start id-end
+        ;;                    (if is-function
+        ;;                        'font-lock-function-name-face
+        ;;                      'font-lock-variable-name-face))
+        (when (and c-last-identifier-range
+                   (not (get-text-property (car c-last-identifier-range)
+                                           'face)))
+          ;; We use `c-last-identifier-range' rather than `id-start' and
+          ;; `id-end', since the latter two can be erroneous.  E.g. in
+          ;; "~Foo", `id-start' is at the tilde.  This is a bug in
+          ;; `c-forward-declarator'.
+          (c-put-font-lock-face (car c-last-identifier-range)
+                                (cdr c-last-identifier-range)
+                                (if is-function
+                                    'font-lock-function-name-face
+                                  'font-lock-variable-name-face))))
+       (and template-class
+           (eq init-char ?=)           ; C++ "<class X = Y>"?
+           (progn
+             (goto-char end-pos)
+             (c-forward-token-2 1 nil limit) ; Over "="
+             (let ((c-promote-possible-types t))
+               (c-forward-type t))))))
+    nil))
 
 (defun c-get-fontification-context (match-pos not-front-decl &optional toplev)
   ;; Return a cons (CONTEXT . RESTRICTED-<>-ARGLISTS) for MATCH-POS.
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 5334271..7cc8029 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -3258,7 +3258,7 @@ Identifier syntax is in effect when this is matched \(see
               "\\|"
               "\\.\\.\\."
               "\\|"
-              "[*(&]"
+              "[*(&~]"
               "\\|"
               (c-lang-const c-type-decl-prefix-key)
               "\\|"
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 4e63bd9..8343978 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1803,7 +1803,16 @@ Note that this is a strict tail, so won't match, e.g. 
\"0x....\".")
        ;; Go to a less nested declaration each time round this loop.
        (and
         (setq old-pos (point))
-        (c-syntactic-skip-backward "^;{}" bod-lim t)
+        (let (pseudo)
+          (while
+              (progn
+                (c-syntactic-skip-backward "^;{}" bod-lim t)
+                (and (eq (char-before) ?})
+                     (save-excursion
+                       (backward-char)
+                       (setq pseudo (c-cheap-inside-bracelist-p 
(c-parse-state))))))
+            (goto-char pseudo))
+          t)
         (> (point) bod-lim)
         (progn (c-forward-syntactic-ws)
                ;; Have we got stuck in a comment at EOB?
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
index d2c4100..92ea671 100644
--- a/lisp/progmodes/cc-styles.el
+++ b/lisp/progmodes/cc-styles.el
@@ -68,7 +68,9 @@
                         (arglist-close . c-lineup-arglist)
                         (inline-open . 0)
                         (brace-list-open . +)
-                        (brace-list-intro . c-lineup-arglist-intro-after-paren)
+                        (brace-list-intro . (first
+                                             
c-lineup-2nd-brace-entry-in-arglist
+                                             c-lineup-class-decl-init-+ +))
                         (topmost-intro-cont
                          . (first c-lineup-topmost-intro-cont
                                   c-lineup-gnu-DEFUN-intro-cont))))
@@ -95,6 +97,9 @@
                         (label . 0)
                         (statement-cont . +)
                         (inline-open . 0)
+                        (brace-list-intro . (first
+                                             
c-lineup-2nd-brace-entry-in-arglist
+                                             c-lineup-class-decl-init-+ +))
                         (inexpr-class . 0))))
 
     ("stroustrup"
@@ -104,6 +109,9 @@
                         (substatement-open . 0)
                         (substatement-label . 0)
                         (label . 0)
+                        (brace-list-intro . (first
+                                             
c-lineup-2nd-brace-entry-in-arglist
+                                             c-lineup-class-decl-init-+ +))
                         (statement-cont . +))))
 
     ("whitesmith"
@@ -194,6 +202,9 @@
      (c-offsets-alist  . ((substatement-open . 0)
                          (inextern-lang . 0)
                          (arglist-intro . +)
+                         (brace-list-intro . (first
+                                              
c-lineup-2nd-brace-entry-in-arglist
+                                              c-lineup-class-decl-init-+ +))
                          (knr-argdecl-intro . +)))
      (c-hanging-braces-alist . ((brace-list-open)
                                (brace-list-intro)
@@ -219,6 +230,9 @@
                         (statement-cont        . +)
                         (arglist-intro  . c-lineup-arglist-intro-after-paren)
                         (arglist-close  . c-lineup-arglist)
+                        (brace-list-intro . (first
+                                             
c-lineup-2nd-brace-entry-in-arglist
+                                             c-lineup-class-decl-init-+ +))
                         (access-label   . 0)
                         (inher-cont     . c-lineup-java-inher)
                         (func-decl-cont . c-lineup-java-throws))))
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index 8953488..6e8acd4 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -1115,7 +1115,7 @@ can always override the use of `c-default-style' by 
making calls to
        ;; Anchor pos: At the brace list decl start(*).
        (brace-list-intro      . +)
        ;; Anchor pos: At the brace list decl start(*).
-       (brace-list-entry      . c-lineup-under-anchor)
+       (brace-list-entry      . 0)
        ;; Anchor pos: At the first non-ws char after the open paren if
        ;; the first token is on the same line, otherwise boi at that
        ;; token.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]