emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 71dc821: Handle "noise" macros and compiler directi


From: Alan Mackenzie
Subject: [Emacs-diffs] master 71dc821: Handle "noise" macros and compiler directives.
Date: Mon, 29 Feb 2016 21:55:51 +0000

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

    Handle "noise" macros and compiler directives.
    
    * lisp/progmodes/cc-langs.el (c-symbol-char-key): New language variable.
    
    * lisp/progmodes/cc-vars.el (c-noise-macro-names)
    (c-noise-macro-with-parens-names): New customizable variables.
    (c-noise-macro-name-re, c-noise-macro-with-parens-name-re): New variables.
    (c-make-noise-macro-regexps): New function.
    
    * lisp/progmodes/cc-engine.el (c-forward-sws, c-backward-sws): Adapt to 
treat
    members of c-noise-macro-names as whitespace.
    (c-forward-noise-clause): New function.
    (c-forward-keyword-prefixed-id, c-forward-type, c-forward-declarator)
    (c-forward-decl-or-cast-1, c-backward-over-enum-header)
    (c-guess-basic-syntax CASE 5A.3, CASE 5A.5, CASE 9A):
    Handle "noise clauses" in parallel with, e.g., "hangon key clauses".
    
    * lisp/progmodes/cc-fonts.el (c-complex-decl-matchers): Handle "noise 
clauses"
    in parallel with "prefix-spec keywords".
    
    * lisp/progmodes/cc-mode.el (c-mode, c++-mode, objc-mode): call
    c-make-noise-macro-regexps to initialize the internal variables.
    
    * doc/misc/cc-mode.texi ("Noise Macros"): New section documenting the new
    facilities.
---
 doc/misc/cc-mode.texi       |   68 ++++++++++++++-
 lisp/progmodes/cc-engine.el |  190 ++++++++++++++++++++++++++++++-------------
 lisp/progmodes/cc-fonts.el  |   16 +++-
 lisp/progmodes/cc-langs.el  |    5 +
 lisp/progmodes/cc-mode.el   |    3 +
 lisp/progmodes/cc-vars.el   |   43 ++++++++++
 6 files changed, 260 insertions(+), 65 deletions(-)

diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi
index bc8d24f..cdc659a 100644
--- a/doc/misc/cc-mode.texi
+++ b/doc/misc/cc-mode.texi
@@ -338,14 +338,15 @@ Line-Up Functions
 * Comment Line-Up::
 * Misc Line-Up::
 
+
 Customizing Macros
 
 * Macro Backslashes::
 * Macros with ;::
+* Noise Macros::
 
 @end detailmenu
 @end menu
-
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 @node    Introduction, Overview, Top, Top
 @comment node-name, next, previous, up
@@ -6639,15 +6640,18 @@ Because a macro can expand into anything at all, near 
where one is
 invoked @ccmode{} can only indent and fontify code heuristically.
 Sometimes it gets it wrong.  Usually you should try to design your
 macros so that they ''look like ordinary code'' when you invoke them.
-However, one situation is so common that @ccmode{} handles it
+However, two situations are so common that @ccmode{} handles them
 specially: that is when certain macros needn't (or mustn't) be
-followed by a @samp{;}.  You need to configure @ccmode{} to handle
-these macros properly, see @ref{Macros with ;}.
+followed by a @samp{;}, and when certain macros (or compiler
+directives) expand to nothing.  You need to configure @ccmode{} to
+handle these macros properly, see @ref{Macros with ;} and @ref{Noise
+Macros}.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 @menu
 * Macro Backslashes::
 * Macros with ;::
+* Noise Macros::
 @end menu
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -6699,7 +6703,7 @@ get aligned only when you explicitly invoke the command
 @end defopt
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
address@hidden Macros with ;,  , Macro Backslashes, Custom Macros
address@hidden Macros with ;, Noise Macros, Macro Backslashes, Custom Macros
 @comment  node-name,  next,  previous,  up
 @section Macros with semicolons
 @cindex macros with semicolons
@@ -6755,6 +6759,60 @@ initialization code.
 @end defun
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
address@hidden    Noise Macros,  , Macros with ;, Custom Macros
address@hidden node-name, next, previous, up
address@hidden Noise Macros
address@hidden noise macros
address@hidden !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+In @ccmode{}, @dfn{noise macros} are macros which expand to nothing,
+or compiler directives (such as GCC's @code{__attribute__}) which play
+no part in the syntax of the C (etc.) language.  Some noise macros are
+followed by arguments in parentheses (possibly optionally), others
+are not.
+
+Noise macros can easily confuse @ccmode{}'s analysis of function
+headers, causing them to be mis-fontified, or even mis-indented.  You
+can prevent this confusion by specifying the identifiers which
+constitute noise macros.
+
address@hidden c-noise-macro-names
address@hidden noise-macro-names (c-)
+This variable is a list of names of noise macros which never have
+parenthesized arguments.  Each element is a string, and must be a
+valid identifier.  An element in @code{c-noise-macro-names} must not
+also be in @code{c-noise-macro-with-parens-names}.  Such an element is
+treated as whitespace by @ccmode{}.
address@hidden defopt
+
address@hidden c-noise-macro-with-parens-names
address@hidden noise-macro-with-parens-names (c-)
+This variable is a list of names of noise macros which optionally have
+arguments in parentheses.  Each element of the list is a string, and
+must be a valid identifier.  An element in
address@hidden must not also be in
address@hidden  For performance reasons, such an element,
+together with the optional parenthesized arguments, is specially
+handled, but it is only handled when used in declaration
address@hidden this restriction causes your project
+difficulties, please get in touch with @email{bug-cc-mode@@gnu.org}.}.
+
+The two compiler directives @code{__attribute__} and @code{__declspec}
+have traditionally been handled specially in @ccmode{}; for example
+they are fontified with font-lock-keyword-face.  You don't need to
+include these directives in @code{c-noise-macro-with-parens-names},
+but doing so is OK.
address@hidden defopt
+
address@hidden c-make-noise-macro-regexps
address@hidden make-noise-macro-regexps (c-)
+Call this (non-interactive) function, which sets internal variables,
+after changing the value of @code{c-noise-macro-names} or
address@hidden (e.g. in a hook (@pxref{CC
+Hooks})).  This function is called by @ccmode{}'s initialization code.
address@hidden defun
+
address@hidden !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 @node    Odds and Ends, Sample Init File, Custom Macros, Top
 @comment node-name, next, previous, up
 @chapter Odds and Ends
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index f5aa4df..66b5369 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -1543,7 +1543,7 @@ comment at the start of cc-engine.el for more info."
 ;;    two newlines with horizontal whitespace between them.
 ;;
 ;;    The reason to include the first following char is to cope with
-;;    "rung positions" that doesn't have any ordinary whitespace.  If
+;;    "rung positions" that don't have any ordinary whitespace.  If
 ;;    `c-is-sws' is put on a token character it does not have
 ;;    `c-in-sws' set simultaneously.  That's the only case when that
 ;;    can occur, and the reason for not extending the `c-in-sws'
@@ -1714,7 +1714,9 @@ comment at the start of cc-engine.el for more info."
     ;; if it's anything that can't start syntactic ws, so we can bail out
     ;; early in the majority of cases when there just are a few ws chars.
     (skip-chars-forward " \t\n\r\f\v")
-    (when (looking-at c-syntactic-ws-start)
+    (when (or (looking-at c-syntactic-ws-start)
+             (and c-opt-cpp-prefix
+                  (looking-at c-noise-macro-name-re)))
 
       (setq rung-end-pos (min (1+ (point)) (point-max)))
       (if (setq rung-is-marked (text-property-any rung-pos rung-end-pos
@@ -1733,6 +1735,10 @@ comment at the start of cc-engine.el for more info."
       (with-silent-modifications
       (while
          (progn
+           ;; In the following while form, we move over a "ladder" and
+           ;; following simple WS each time round the loop, appending the WS
+           ;; onto the ladder, joining adjacent ladders, and terminating when
+           ;; there is no more WS or we reach EOB.
            (while
                (when (and rung-is-marked
                           (get-text-property (point) 'c-in-sws))
@@ -1776,6 +1782,7 @@ comment at the start of cc-engine.el for more info."
                            (setq rung-pos (point)
                                  last-put-in-sws-pos rung-pos)))
 
+           ;; Now move over any comments (x)or a CPP construct.
            (setq simple-ws-end (point))
            (c-forward-comments)
 
@@ -1801,6 +1808,13 @@ comment at the start of cc-engine.el for more info."
              (forward-line 1)
              (setq safe-start t)
              ;; Don't cache at eob in case the buffer is narrowed.
+             (not (eobp)))
+
+            ((and c-opt-cpp-prefix
+                  (looking-at c-noise-macro-name-re))
+             ;; Skip over a noise macro.
+             (goto-char (match-end 1))
+             (setq safe-start t)
              (not (eobp)))))
 
        ;; We've searched over a piece of non-white syntactic ws.  See if this
@@ -1907,8 +1921,11 @@ comment at the start of cc-engine.el for more info."
     (when (and (not (bobp))
               (save-excursion
                 (backward-char)
-                (looking-at c-syntactic-ws-end)))
-
+                (or (looking-at c-syntactic-ws-end)
+                    (and c-opt-cpp-prefix
+                         (looking-at c-symbol-char-key)
+                         (progn (c-beginning-of-current-token)
+                                (looking-at c-noise-macro-name-re))))))
       ;; Try to find a rung position in the simple ws preceding point, so that
       ;; we can get a cache hit even if the last bit of the simple ws has
       ;; changed recently.
@@ -1927,6 +1944,9 @@ comment at the start of cc-engine.el for more info."
       (with-silent-modifications
       (while
          (progn
+           ;; Each time round the next while form, we move back over a ladder
+           ;; and append any simple WS preceding it, if possible joining with
+           ;; the previous ladder.
            (while
                (when (and rung-is-marked
                           (not (bobp))
@@ -2035,6 +2055,15 @@ comment at the start of cc-engine.el for more info."
              ;; narrowed out, and we can't risk marking the simple ws
              ;; at the end of it.
              (goto-char next-rung-pos)
+             t)
+
+            ((and c-opt-cpp-prefix
+                  (save-excursion
+                    (and (< (skip-syntax-backward "w_") 0)
+                         (progn (setq next-rung-pos (point))
+                                (looking-at c-noise-macro-name-re)))))
+             ;; Skipped over a noise macro
+             (goto-char next-rung-pos)
              t)))
 
        ;; We've searched over a piece of non-white syntactic ws.  See if this
@@ -5807,8 +5836,10 @@ comment at the start of cc-engine.el for more info."
                               `(c-forward-type)
                             `(c-forward-name)))
                nil
-             (and (looking-at c-keywords-regexp)
-                  (c-forward-keyword-clause 1))))
+             (cond ((looking-at c-keywords-regexp)
+                    (c-forward-keyword-clause 1))
+                   ((looking-at c-noise-macro-with-parens-name-re)
+                    (c-forward-noise-clause)))))
      (when (memq res '(t known found prefix))
        ,(when (eq type 'ref)
          `(when c-record-type-identifiers
@@ -5830,6 +5861,17 @@ comment at the start of cc-engine.el for more info."
                 (c-forward-syntactic-ws)
                 (c-forward-keyword-prefixed-id ,type)))))
 
+(defun c-forward-noise-clause ()
+  ;; Point is at a c-noise-macro-with-parens-names macro identifier.  Go
+  ;; forward over this name, any parenthesis expression which follows it, and
+  ;; any syntactic WS, ending up at the next token.  If there is an unbalanced
+  ;; paren expression, leave point at it.  Always Return t.
+  (c-forward-token-2)
+  (if (and (eq (char-after) ?\()
+          (c-go-list-forward))
+      (c-forward-syntactic-ws))
+  t)
+
 (defun c-forward-keyword-clause (match)
   ;; Submatch MATCH in the current match data is assumed to surround a
   ;; token.  If it's a keyword, move over it and any immediately
@@ -6460,6 +6502,13 @@ comment at the start of cc-engine.el for more info."
                                     ; "typedef".
       (goto-char (match-end 1))
       (c-forward-syntactic-ws)
+
+      (while (cond
+             ((looking-at c-decl-hangon-key)
+              (c-forward-keyword-clause 1))
+             ((looking-at c-noise-macro-with-parens-name-re)
+              (c-forward-noise-clause))))
+
       (setq pos (point))
 
       (setq name-res (c-forward-name))
@@ -6852,31 +6901,38 @@ comment at the start of cc-engine.el for more info."
           ;; of the while.  These are, e.g. "*" in "int *foo" or "(" and
           ;; "*" in "int (*foo) (void)" (Note similar code in
           ;; `c-forward-decl-or-cast-1'.)
-          (while (and (looking-at c-type-decl-prefix-key)
-                      (if (and (c-major-mode-is 'c++-mode)
-                               (match-beginning 3))
-                          ;; If the third submatch matches in C++ then
-                          ;; we're looking at an identifier that's a
-                          ;; prefix only if it specifies a member pointer.
-                          (progn
-                            (setq id-start (point))
-                            (c-forward-name)
-                            (if (looking-at "\\(::\\)")
-                                ;; We only check for a trailing "::" and
-                                ;; let the "*" that should follow be
-                                ;; matched in the next round.
-                                t
-                              ;; It turned out to be the real identifier,
-                              ;; so flag that and stop.
-                              (setq got-identifier t)
-                              nil))
-                        t))
-            (if (eq (char-after) ?\()
-                (progn
-                  (setq paren-depth (1+ paren-depth))
-                  (forward-char))
-              (goto-char (match-end 1)))
-            (c-forward-syntactic-ws))
+             (while
+                 (cond
+                  ((looking-at c-decl-hangon-key)
+                   (c-forward-keyword-clause 1))
+                  ((looking-at c-noise-macro-with-parens-name-re)
+                   (c-forward-noise-clause))
+                  ((and (looking-at c-type-decl-prefix-key)
+                        (if (and (c-major-mode-is 'c++-mode)
+                                 (match-beginning 3))
+                            ;; If the third submatch matches in C++ then
+                            ;; we're looking at an identifier that's a
+                            ;; prefix only if it specifies a member pointer.
+                            (progn
+                              (setq id-start (point))
+                              (c-forward-name)
+                              (if (looking-at "\\(::\\)")
+                                  ;; We only check for a trailing "::" and
+                                  ;; let the "*" that should follow be
+                                  ;; matched in the next round.
+                                  t
+                                ;; It turned out to be the real identifier,
+                                ;; so flag that and stop.
+                                (setq got-identifier t)
+                                nil))
+                          t))
+                   (if (eq (char-after) ?\()
+                       (progn
+                         (setq paren-depth (1+ paren-depth))
+                         (forward-char))
+                     (goto-char (match-end 1)))
+                   (c-forward-syntactic-ws)
+                   t)))
 
           ;; If we haven't passed the identifier already, do it now.
           (unless got-identifier
@@ -6901,9 +6957,12 @@ comment at the start of cc-engine.el for more info."
 
         ;; Skip over any trailing bit, such as "__attribute__".
         (progn
-          (when (looking-at c-decl-hangon-key)
-            (c-forward-keyword-clause 1))
-          (<= (point) limit))
+             (while (cond
+                     ((looking-at c-decl-hangon-key)
+                      (c-forward-keyword-clause 1))
+                     ((looking-at c-noise-macro-with-parens-name-re)
+                      (c-forward-noise-clause))))
+             (<= (point) limit))
 
         ;; Search syntactically to the end of the declarator (";",
         ;; ",", a closing paren, eob etc) or to the beginning of an
@@ -7082,18 +7141,24 @@ comment at the start of cc-engine.el for more info."
     ;; macros like __INLINE__, so we recognize both types and known
     ;; specifiers after them too.
     (while
-       (let* ((start (point)) kwd-sym kwd-clause-end found-type)
+       (let* ((start (point)) kwd-sym kwd-clause-end found-type noise-start)
 
+         (cond
          ;; Look for a specifier keyword clause.
-         (when (or (looking-at c-prefix-spec-kwds-re) ;FIXME!!! includes auto
-                   (and (c-major-mode-is 'java-mode)
-                        (looking-at "@[A-Za-z0-9]+")))
-           (if (save-match-data (looking-at c-typedef-key))
-               (setq at-typedef t))
+          ((or (looking-at c-prefix-spec-kwds-re)
+               (and (c-major-mode-is 'java-mode)
+                (looking-at "@[A-Za-z0-9]+")))
+           (save-match-data
+             (if (looking-at c-typedef-key)
+                 (setq at-typedef t)))
            (setq kwd-sym (c-keyword-sym (match-string 1)))
            (save-excursion
              (c-forward-keyword-clause 1)
              (setq kwd-clause-end (point))))
+          ((looking-at c-noise-macro-with-parens-name-re)
+           (setq noise-start (point))
+           (c-forward-noise-clause)
+           (setq kwd-clause-end (point))))
 
          (when (setq found-type (c-forward-type t)) ; brace-block-too
            ;; Found a known or possible type or a prefix of a known type.
@@ -7131,16 +7196,17 @@ comment at the start of cc-engine.el for more info."
                  backup-at-type-decl nil
                  backup-maybe-typeless nil))
 
-         (if kwd-sym
+         (if (or kwd-sym noise-start)
              (progn
                ;; Handle known specifier keywords and
                ;; `c-decl-hangon-kwds' which can occur after known
                ;; types.
 
-               (if (c-keyword-member kwd-sym 'c-decl-hangon-kwds)
-                   ;; It's a hang-on keyword that can occur anywhere.
+               (if (or (c-keyword-member kwd-sym 'c-decl-hangon-kwds)
+                       noise-start)
+                   ;; It's a hang-on keyword or noise clause that can occur
+                   ;; anywhere.
                    (progn
-                     (setq at-decl-or-cast t)
                      (if at-type
                          ;; Move the identifier start position if
                          ;; we've passed a type.
@@ -7192,8 +7258,11 @@ comment at the start of cc-engine.el for more info."
       ;; If a known type was found, we still need to skip over any
       ;; hangon keyword clauses after it.  Otherwise it has already
       ;; been done in the loop above.
-      (while (looking-at c-decl-hangon-key)
-       (c-forward-keyword-clause 1))
+      (while
+         (cond ((looking-at c-decl-hangon-key)
+                (c-forward-keyword-clause 1))
+               ((looking-at c-noise-macro-with-parens-name-re)
+                (c-forward-noise-clause))))
       (setq id-start (point)))
 
      ((eq at-type 'prefix)
@@ -8960,6 +9029,11 @@ comment at the start of cc-engine.el for more info."
           t)
          ((looking-at c-after-brace-list-key) t)
          ((looking-at c-brace-list-key) nil)
+         ((eq (char-after) ?\()
+          (and (eq (c-backward-token-2) 0)
+               (or (looking-at c-decl-hangon-key)
+                   (looking-at c-noise-macro-with-parens-name-re))))
+
          ((and c-recognize-<>-arglists
                (eq (char-after) ?<)
                (looking-at "\\s("))
@@ -10220,9 +10294,11 @@ comment at the start of cc-engine.el for more info."
           ;; CASE 5A.3: brace list open
           ((save-excursion
              (c-beginning-of-decl-1 lim)
-             (while (looking-at c-specifier-key)
-               (goto-char (match-end 1))
-               (c-forward-syntactic-ws indent-point))
+             (while (cond
+                     ((looking-at c-specifier-key)
+                      (c-forward-keyword-clause 1))
+                     ((looking-at c-noise-macro-with-parens-name-re)
+                      (c-forward-noise-clause))))
              (setq placeholder (c-point 'boi))
              (or (consp special-brace-list)
                  (and (or (save-excursion
@@ -10274,9 +10350,11 @@ comment at the start of cc-engine.el for more info."
           (t
            (save-excursion
              (c-beginning-of-decl-1 lim)
-             (while (looking-at c-specifier-key)
-               (goto-char (match-end 1))
-               (c-forward-syntactic-ws indent-point))
+             (while (cond
+                     ((looking-at c-specifier-key)
+                      (c-forward-keyword-clause 1))
+                     ((looking-at c-noise-macro-with-parens-name-re)
+                      (c-forward-noise-clause))))
              (c-add-syntax 'defun-open (c-point 'boi))
              ;; Bogus to use bol here, but it's the legacy.  (Resolved,
              ;; 2007-11-09)
@@ -10907,9 +10985,11 @@ comment at the start of cc-engine.el for more info."
            (c-beginning-of-statement-1
             (c-safe-position (1- containing-sexp) paren-state))
            (c-forward-token-2 0)
-           (while (looking-at c-specifier-key)
-             (goto-char (match-end 1))
-             (c-forward-syntactic-ws))
+           (while (cond
+                   ((looking-at c-specifier-key)
+                    (c-forward-keyword-clause 1))
+                   ((looking-at c-noise-macro-with-parens-name-re)
+                    (c-forward-noise-clause))))
            (c-add-syntax 'brace-list-open (c-point 'boi))))
 
         ;; CASE 9B: brace-list-close brace
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 3cc537b..a7097b9 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -1698,10 +1698,16 @@ on level 2 only and so aren't combined with 
`c-complex-decl-matchers'."
                        (unless (c-skip-comments-and-strings limit)
                          (c-forward-syntactic-ws)
                          ;; Handle prefix declaration specifiers.
-                         (when (or (looking-at c-prefix-spec-kwds-re)
-                                   (and (c-major-mode-is 'java-mode)
-                                        (looking-at "@[A-Za-z0-9]+")))
-                           (c-forward-keyword-clause 1))
+                         (while
+                             (or
+                              (when (or (looking-at c-prefix-spec-kwds-re)
+                                        (and (c-major-mode-is 'java-mode)
+                                             (looking-at "@[A-Za-z0-9]+")))
+                                (c-forward-keyword-clause 1)
+                                t)
+                              (when (looking-at 
c-noise-macro-with-parens-name-re)
+                                (c-forward-noise-clause)
+                                t)))
                          ,(if (c-major-mode-is 'c++-mode)
                               `(when (and (c-forward-type)
                                           (eq (char-after) ?=))
@@ -1827,7 +1833,7 @@ higher."
                "\\)\\>"
                ;; Disallow various common punctuation chars that can't come
                ;; before the '{' of the enum list, to avoid searching too far.
-               "[^][{}();/#=]*"
+               "[^][{};/#=]*"
                "{")
               '((c-font-lock-declarators limit t nil)
                 (save-match-data
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 86b6bec..d212482 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -619,6 +619,11 @@ This is of the form that fits inside [ ] in a regexp."
   objc (concat c-alnum "_$@"))
 (c-lang-defvar c-symbol-chars (c-lang-const c-symbol-chars))
 
+(c-lang-defconst c-symbol-char-key
+  "Regexp matching a sequence of at least one identifier character."
+  t (concat "[" (c-lang-const c-symbol-chars) "]+"))
+(c-lang-defvar c-symbol-char-key (c-lang-const c-symbol-char-key))
+
 (c-lang-defconst c-symbol-key
   "Regexp matching identifiers and keywords (with submatch 0).  Assumed
 to match if `c-symbol-start' matches on the same position."
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 58aebf8..9ebe6f7 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1493,6 +1493,7 @@ Key bindings:
        abbrev-mode t)
   (use-local-map c-mode-map)
   (c-init-language-vars-for 'c-mode)
+  (c-make-noise-macro-regexps)
   (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
   (c-common-init 'c-mode)
   (easy-menu-add c-c-menu)
@@ -1548,6 +1549,7 @@ Key bindings:
        abbrev-mode t)
   (use-local-map c++-mode-map)
   (c-init-language-vars-for 'c++-mode)
+  (c-make-noise-macro-regexps)
   (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
   (c-common-init 'c++-mode)
   (easy-menu-add c-c++-menu)
@@ -1601,6 +1603,7 @@ Key bindings:
        abbrev-mode t)
   (use-local-map objc-mode-map)
   (c-init-language-vars-for 'objc-mode)
+  (c-make-noise-macro-regexps)
   (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
   (c-common-init 'objc-mode)
   (easy-menu-add c-objc-menu)
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index 8cee733..a695718 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -1619,6 +1619,49 @@ names)."))
   :type 'c-extra-types-widget
   :group 'c)
 
+(defvar c-noise-macro-with-parens-name-re nil)
+(defvar c-noise-macro-name-re nil)
+
+(defcustom c-noise-macro-names nil
+  "A list of names of macros which expand to nothing, or compiler extensions
+like \"????\" which are syntactic noise.  Such a macro/extension is complete in
+itself, never having parentheses.  All these names must be syntactically valid
+identifiers.
+
+If you change this variable's value, call the function
+`c-make-noise-macro-regexps' to set the necessary internal variables (or do
+this implicitly by reinitialising C/C++/Objc Mode on any buffer)."
+  :type '(repeat :tag "List of names" string)
+  :group 'c)
+
+(defcustom c-noise-macro-with-parens-names nil
+  "A list of names of macros \(or compiler extensions like \"__attribute__\")
+which optionally have arguments in parentheses, and which expand to nothing.
+These are recognized by CC Mode only in declarations."
+  :type '(regexp :tag "List of names (possibly empty)" string)
+  :group 'c)
+
+(defun c-make-noise-macro-regexps ()
+  ;; Convert `c-noise-macro-names' and `c-noise-macro-with-parens-names' into
+  ;; `c-noise-macro-name-re' and `c-noise-macro-with-parens-name-re'.
+  (setq c-noise-macro-with-parens-name-re
+       (cond ((null c-noise-macro-with-parens-names) "\\<\\>")
+             ((consp c-noise-macro-with-parens-names)
+              (concat (regexp-opt c-noise-macro-with-parens-names t)
+                      "\\([^[:alnum:]_$]\\|$\\)"))
+             ((stringp c-noise-macro-with-parens-names)
+              (copy-sequence c-noise-macro-with-parens-names))
+             (t (error "c-make-noise-macro-regexps: \
+c-noise-macro-with-parens-names is invalid: %s" 
c-noise-macro-with-parens-names))))
+  (setq c-noise-macro-name-re
+       (cond ((null c-noise-macro-names) "\\<\\>")
+             ((consp c-noise-macro-names)
+              (concat (regexp-opt c-noise-macro-names t)
+                      "\\([^[:alnum:]_$]\\|$\\)"))
+             ((stringp c-noise-macro-names)
+              (copy-sequence c-noise-macro-names))
+             (t (error "c-make-noise-macro-regexps: \
+c-noise-macro-names is invalid: %s" c-noise-macro-names)))))
 
 ;; Non-customizable variables, still part of the interface to CC Mode
 (defvar c-macro-with-semi-re nil



reply via email to

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