emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r106216: Amend to indent and fontify


From: Alan Mackenzie
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r106216: Amend to indent and fontify macros "which include their own semicolon"
Date: Fri, 28 Oct 2011 14:10:28 +0000
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 106216 [merge]
committer: Alan Mackenzie <address@hidden>
branch nick: trunk
timestamp: Fri 2011-10-28 14:10:28 +0000
message:
  Amend to indent and fontify macros "which include their own semicolon"
  correctly, using the "virtual semicolon" mechanism.
modified:
  doc/misc/cc-mode.texi
  lisp/ChangeLog
  lisp/progmodes/cc-defs.el
  lisp/progmodes/cc-engine.el
  lisp/progmodes/cc-fonts.el
  lisp/progmodes/cc-langs.el
  lisp/progmodes/cc-mode.el
  lisp/progmodes/cc-vars.el
=== modified file 'doc/misc/cc-mode.texi'
--- a/doc/misc/cc-mode.texi     2011-07-01 09:42:55 +0000
+++ b/doc/misc/cc-mode.texi     2011-10-27 20:34:23 +0000
@@ -341,6 +341,11 @@
 * Comment Line-Up::
 * Misc Line-Up::
 
+Customizing Macros
+
+* Macro Backslashes::           
+* Macros with ;::               
+
 @end detailmenu
 @end menu
 
@@ -655,6 +660,10 @@
 syntactic recognition can be wrong.  @ccmode{} manages to figure it
 out correctly most of the time, though.
 
+Some macros, when invoked, ''have their own semicolon''.  To get the
+next line indented correctly, rather than as a continuation line,
address@hidden with ;}.
+
 Reindenting large sections of code can take a long time.  When
 @ccmode{} reindents a region of code, it is essentially equivalent to
 hitting @key{TAB} on every line of the region.
@@ -6550,6 +6559,9 @@
 @section Other Special Indentations
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
+To configure macros which you invoke without a terminating @samp{;},
+see @xref{Macros with ;}.
+
 Here are the remaining odds and ends regarding indentation:
 
 @defopt c-label-minimum-indentation
@@ -6601,6 +6613,13 @@
 @cindex preprocessor directives
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
+Preprocessor macros in C, C++, and Objective C (introduced by
address@hidden) have a syntax different from the main language---for
+example, a macro declaration is not terminated by a semicolon, and if
+it is more than a line long, line breaks in it must be escaped with
+backslashes.  @ccmode{} has some commands to manipulate these, see
address@hidden Backslashes}.
+
 Normally, the lines in a multi-line macro are indented relative to
 each other as though they were code.  You can suppress this behavior
 by setting the following user option:
@@ -6612,6 +6631,28 @@
 @code{cpp-macro-cont}.
 @end defopt
 
+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
+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 ;}.
+
address@hidden !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
address@hidden
+* Macro Backslashes::           
+* Macros with ;::               
address@hidden menu
+
address@hidden !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
address@hidden     Macro Backslashes, Macros with ;, Custom Macros, Custom 
Macros
address@hidden  node-name,  next,  previous,  up
address@hidden Customizing Macro Backslashes
address@hidden #define
address@hidden !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
 @ccmode{} provides some tools to help keep the line continuation
 backslashes in macros neat and tidy.  Their precise action is
 customized with these variables:
@@ -6654,6 +6695,62 @@
 @end defopt
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
address@hidden Macros with ;,  , Macro Backslashes, Custom Macros
address@hidden  node-name,  next,  previous,  up
address@hidden Macros with semicolons
address@hidden macros with semicolons
address@hidden !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+Macros which needn't (or mustn't) be followed by a semicolon when you
+invoke them, @dfn{macros with semicolons}, are very common.  These can
+cause @ccmode{} to parse the next line wrongly as a
address@hidden (@pxref{Function Symbols}) and thus mis-indent
+it.
+
+You can prevent this by specifying which macros have semicolons.  It
+doesn't matter whether or not such a macro has a parameter list:
+
address@hidden c-macro-names-with-semicolon
address@hidden macro-names-with-semicolon (c-)
+This buffer-local variable specifies which macros have semicolons.
+After setting its value, you need to call
address@hidden for it to take effect.  It should be
+set to one of these values:
+
address@hidden @asis
address@hidden nil
+There are no macros with semicolons.
address@hidden a list of strings
+Each string is the name of a macro with a semicolon.  Only valid
address@hidden names are allowed here.  For example, to set the
+default value, you could write the following into your @file{.emacs}:
+
address@hidden
+(setq c-macro-names-with-semicolon
+      '("Q_OBJECT" "Q_PROPERTY" "Q_DECLARE" "Q_ENUMS"))
address@hidden example
+
address@hidden a regular expression
+This matches each symbol which is a macro with a semicolon.  It must
+not match any string which isn't a valid @code{#define} name.  For
+example:
+
address@hidden
+(setq c-macro-names-with-semicolon
+      "\\<\\(CLEAN_UP_AND_RETURN\\|Q_[[:upper:]]+\\)\\>")
address@hidden example
address@hidden table
address@hidden defopt
+
address@hidden c-make-macro-with-semi-re
address@hidden make-macro-with-semi-re (c-)
+Call this (non-interactive) function, which sets internal variables,
+each time you change the value of
address@hidden  It takes no arguments, and its
+return value has no meaning.  This function is called by @ccmode{}'s
+initialization code.
address@hidden defun
+
address@hidden !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 @node    Odds and Ends, Sample .emacs File, Custom Macros, Top
 @comment node-name, next, previous, up
 @chapter Odds and Ends

=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2011-10-28 02:50:05 +0000
+++ b/lisp/ChangeLog    2011-10-28 14:02:04 +0000
@@ -1,3 +1,41 @@
+2011-10-28  Alan Mackenzie  <address@hidden>
+
+       Amend to indent and fontify macros "which include their own semicolon"
+       correctly, using the "virtual semicolon" mechanism.
+
+       * cc-defs.el: Update "virtual semicolon" comments.
+
+       * cc-engine.el (c-crosses-statement-barrier-p): Recoded to scan one 
line at
+       at time rather than having \n and \r explicitly in c-stmt-delim-chars
+       (for some modes, e.g. AWK).
+       (c-forward-label): Amend for virtual semicolons.
+       (c-at-macro-vsemi-p, c-macro-vsemi-status-unknown-p): New functions
+
+       * cc-fonts.el (c-font-lock-declarations): Take account of the new C 
macros.
+
+       * cc-langs.el (c-at-vsemi-p-fn, c-vsemi-status-unknown-p-fn): move to
+       earlier in the file.
+       (c-opt-cpp-symbol, c-line-comment-start-regexp): New language variables.
+       (c-opt-cpp-macro-define): Make into a full language variable.
+       (c-stmt-delim-chars, c-stmt-delim-chars-with-comma): Special value for
+       AWK Mode (including \n, \r) removed, no longer needed.
+
+       * cc-mode.el (c-mode, c++-mode, objc-mode): Invoke
+       c-make-macro-with-semi-re.  (Erroneously committed early, in previous
+       version, 5.259.)
+
+       * cc-vars.el (c-macro-with-semi-re, c-macro-names-with-semicolon): New
+       variables.
+       (c-make-macro-with-semi-re): New function
+
+       * cc-mode.texi (Indentation Commands): Mention "macros with semicolons".
+       (Other Special Indentations): Add an xref to "Macros with ;".
+       (Customizing Macros): Add stuff about syntax in macros.  Add an xref to
+       "Macros with ;".
+       (Macros with ;): New page.
+
+
+
 2011-10-28  Stefan Monnier  <address@hidden>
 
        * vc/log-edit.el: Fill empty field rather than adding new one.

=== modified file 'lisp/progmodes/cc-defs.el'
--- a/lisp/progmodes/cc-defs.el 2011-09-23 09:24:47 +0000
+++ b/lisp/progmodes/cc-defs.el 2011-10-27 20:34:23 +0000
@@ -744,19 +744,20 @@
 ;; V i r t u a l   S e m i c o l o n s
 ;;
 ;; In most CC Mode languages, statements are terminated explicitly by
-;; semicolons or closing braces.  In some of the CC modes (currently only AWK
-;; Mode (April 2004)), statements are (or can be) terminated by EOLs.  Such a
-;; statement is said to be terminated by a "virtual semicolon" (VS).  A
-;; statement terminated by an actual semicolon or brace is never considered to
-;; have a VS.
+;; semicolons or closing braces.  In some of the CC modes (currently AWK Mode
+;; and certain user-specified #define macros in C, C++, etc. (November 2008)),
+;; statements are (or can be) terminated by EOLs.  Such a statement is said to
+;; be terminated by a "virtual semicolon" (VS).  A statement terminated by an
+;; actual semicolon or brace is never considered to have a VS.
 ;;
 ;; The indentation engine (or whatever) tests for a VS at a specific position
 ;; by invoking the macro `c-at-vsemi-p', which in its turn calls the mode
 ;; specific function (if any) which is the value of the language variable
-;; `c-at-vsemi-p-fn'.  The actual details of what constitutes a VS in a
-;; language are thus encapsulated in code specific to that language
-;; (e.g. cc-awk.el).  `c-at-vsemi-p' returns non-nil if point (or the optional
-;; parameter POS) is at a VS, nil otherwise.
+;; `c-at-vsemi-p-fn'.  This function should only use "low-level" features of
+;; CC Mode, i.e. features which won't trigger infinite recursion.  ;-) The
+;; actual details of what constitutes a VS in a language are thus encapsulated
+;; in code specific to that language (e.g. cc-awk.el).  `c-at-vsemi-p' returns
+;; non-nil if point (or the optional parameter POS) is at a VS, nil otherwise.
 ;;
 ;; The language specific function might well do extensive analysis of the
 ;; source text, and may use a cacheing scheme to speed up repeated calls.

=== modified file 'lisp/progmodes/cc-engine.el'
--- a/lisp/progmodes/cc-engine.el       2011-10-22 10:17:25 +0000
+++ b/lisp/progmodes/cc-engine.el       2011-10-27 20:34:23 +0000
@@ -1149,42 +1149,65 @@
 
 Note that this function might do hidden buffer changes.  See the
 comment at the start of cc-engine.el for more info."
-  (let ((skip-chars c-stmt-delim-chars)
-       lit-range)
-    (save-excursion
-      (catch 'done
-       (goto-char from)
-       (while (progn (skip-chars-forward skip-chars to)
-                     (< (point) to))
-         (cond
-          ((setq lit-range (c-literal-limits from)) ; Have we landed in a 
string/comment?
-           (goto-char (cdr lit-range)))
-          ((eq (char-after) ?:)
-           (forward-char)
-           (if (and (eq (char-after) ?:)
-                    (< (point) to))
-               ;; Ignore scope operators.
-               (forward-char)
-             (setq c-maybe-labelp (1- (point)))))
-          ((eq (char-after) ??)
-           ;; A question mark.  Can't be a label, so stop
-           ;; looking for more : and ?.
-           (setq c-maybe-labelp nil
-                 skip-chars (substring c-stmt-delim-chars 0 -2)))
-          ((memq (char-after) '(?# ?\n ?\r)) ; A virtual semicolon?
-           (if (and (eq (char-before) ?\\) (memq (char-after) '(?\n ?\r)))
-               (backward-char))
-           (skip-chars-backward " \t" from)
-           (if (c-at-vsemi-p)
-               (throw 'done (point))
-             (forward-line)))
-          (t (throw 'done (point)))))
-       ;; In trailing space after an as yet undetected virtual semicolon?
-       (c-backward-syntactic-ws from)
-       (if (and (< (point) to)
-                (c-at-vsemi-p))
-           (point)
-         nil)))))
+  (let* ((skip-chars
+         ;; If the current language has CPP macros, insert # into skip-chars.
+         (if c-opt-cpp-symbol
+             (concat (substring c-stmt-delim-chars 0 1) ; "^"
+                     c-opt-cpp-symbol                   ; usually "#"
+                     (substring c-stmt-delim-chars 1))  ; e.g. ";{}?:"
+           c-stmt-delim-chars))
+        (non-skip-list
+         (append (substring skip-chars 1) nil)) ; e.g. (?# ?\; ?{ ?} ?? ?:)
+        lit-range vsemi-pos)
+    (save-restriction
+      (widen)
+      (save-excursion
+       (catch 'done
+         (goto-char from)
+         (while (progn (skip-chars-forward
+                        skip-chars
+                        (min to (c-point 'bonl)))
+                       (< (point) to))
+           (cond
+            ;; Virtual semicolon?
+            ((and (bolp)
+                  (save-excursion
+                    (progn
+                      (if (setq lit-range (c-literal-limits from)) ; Have we 
landed in a string/comment?
+                          (goto-char (car lit-range)))
+                      (c-backward-syntactic-ws) ; ? put a limit here, maybe?
+                      (setq vsemi-pos (point))
+                      (c-at-vsemi-p))))
+             (throw 'done vsemi-pos))
+            ;; In a string/comment?
+            ((setq lit-range (c-literal-limits))
+             (goto-char (cdr lit-range)))
+            ((eq (char-after) ?:)
+             (forward-char)
+             (if (and (eq (char-after) ?:)
+                      (< (point) to))
+                 ;; Ignore scope operators.
+                 (forward-char)
+               (setq c-maybe-labelp (1- (point)))))
+            ((eq (char-after) ??)
+             ;; A question mark.  Can't be a label, so stop
+             ;; looking for more : and ?.
+             (setq c-maybe-labelp nil
+                   skip-chars (substring c-stmt-delim-chars 0 -2)))
+            ;; At a CPP construct?
+            ((and c-opt-cpp-symbol (looking-at c-opt-cpp-symbol)
+                  (save-excursion
+                    (forward-line 0)
+                    (looking-at c-opt-cpp-prefix)))
+             (c-end-of-macro))
+            ((memq (char-after) non-skip-list)
+             (throw 'done (point)))))
+         ;; In trailing space after an as yet undetected virtual semicolon?
+         (c-backward-syntactic-ws from)
+         (if (and (< (point) to)
+                  (c-at-vsemi-p))
+             (point)
+           nil))))))
 
 (defun c-at-statement-start-p ()
   "Return non-nil if the point is at the first token in a statement
@@ -7158,12 +7181,14 @@
           ;; Check that we're not after a token that can't precede a label.
           (or
            ;; Trivially succeeds when there's no preceding token.
+           ;; Succeeds when we're at a virtual semicolon.
            (if preceding-token-end
                (<= preceding-token-end (point-min))
              (save-excursion
                (c-backward-syntactic-ws)
                (setq preceding-token-end (point))
-               (bobp)))
+               (or (bobp)
+                   (c-at-vsemi-p))))
 
            ;; Check if we're after a label, if we're after a closing
            ;; paren that belong to statement, and with
@@ -8372,6 +8397,57 @@
                                                    paren-state)
                                   containing-sexp)))))
 
+(defun c-at-macro-vsemi-p (&optional pos)
+  ;; Is there a "virtual semicolon" at POS or point?
+  ;; (See cc-defs.el for full details of "virtual semicolons".)
+  ;;
+  ;; This is true when point is at the last non syntactic WS position on the
+  ;; line, there is a macro call last on the line, and this particular macro's
+  ;; name is defined by the regexp `c-vs-macro-regexp' as not needing a
+  ;; semicolon.
+  (save-excursion
+    (save-restriction
+      (widen)
+      (if pos
+         (goto-char pos)
+       (setq pos (point)))
+      (and
+       c-macro-with-semi-re
+       (not (c-in-literal))
+       (eq (skip-chars-backward " \t") 0)
+
+       ;; Check we've got nothing after this except comments and empty lines
+       ;; joined by escaped EOLs.
+       (skip-chars-forward " \t")      ; always returns non-nil.
+       (progn
+        (while                       ; go over 1 block comment per iteration.
+            (and
+             (looking-at "\\(\\\\[\n\r][ \t]*\\)*")
+             (goto-char (match-end 0))
+             (cond
+              ((looking-at c-block-comment-start-regexp)
+               (and (forward-comment 1)
+                    (skip-chars-forward " \t"))) ; always returns non-nil
+              ((looking-at c-line-comment-start-regexp)
+               (end-of-line)
+               nil)
+              (t nil))))
+        (eolp))
+            
+       (goto-char pos)
+       (progn (c-backward-syntactic-ws)
+             (eq (point) pos))
+
+       ;; Check for one of the listed macros being before point.
+       (or (not (eq (char-before) ?\)))
+          (when (c-go-list-backward)
+            (c-backward-syntactic-ws)
+            t))
+       (c-simple-skip-symbol-backward)
+       (looking-at c-macro-with-semi-re)))))
+
+(defun c-macro-vsemi-status-unknown-p () t) ; See cc-defs.el.
+
 
 ;; `c-guess-basic-syntax' and the functions that precedes it below
 ;; implements the main decision tree for determining the syntactic

=== modified file 'lisp/progmodes/cc-fonts.el'
--- a/lisp/progmodes/cc-fonts.el        2011-09-17 12:19:04 +0000
+++ b/lisp/progmodes/cc-fonts.el        2011-10-27 20:34:23 +0000
@@ -1277,9 +1277,11 @@
         (when
          ;; The result of the form below is true when we don't recognize a
          ;; declaration or cast.
-         (if (and (eq (get-text-property (point) 'face)
-                      'font-lock-keyword-face)
-                  (looking-at c-not-decl-init-keywords))
+         (if (or (and (eq (get-text-property (point) 'face)
+                          'font-lock-keyword-face)
+                      (looking-at c-not-decl-init-keywords))
+                 (and c-macro-with-semi-re
+                      (looking-at c-macro-with-semi-re))) ; 2008-11-04
              ;; Don't do anything more if we're looking at a keyword that
              ;; can't start a declaration.
              t

=== modified file 'lisp/progmodes/cc-langs.el'
--- a/lisp/progmodes/cc-langs.el        2011-08-20 22:02:25 +0000
+++ b/lisp/progmodes/cc-langs.el        2011-10-27 20:34:23 +0000
@@ -509,6 +509,31 @@
               (c-lang-const c-before-font-lock-function))
 
 
+;;; Syntactic analysis ("virtual semicolons") for line-oriented languages 
(AWK).
+(c-lang-defconst c-at-vsemi-p-fn
+  "Contains a function \"Is there a virtual semicolon at POS or point?\".
+Such a function takes one optional parameter, a buffer position (defaults to
+point), and returns nil or t.  This variable contains nil for languages which
+don't have EOL terminated statements. "
+  t nil
+  (c c++ objc) 'c-at-macro-vsemi-p
+  awk 'c-awk-at-vsemi-p)
+(c-lang-defvar c-at-vsemi-p-fn (c-lang-const c-at-vsemi-p-fn))
+
+(c-lang-defconst c-vsemi-status-unknown-p-fn
+  "Contains a function \"are we unsure whether there is a virtual semicolon on 
this line?\".
+The (admittedly kludgey) purpose of such a function is to prevent an infinite
+recursion in c-beginning-of-statement-1 when point starts at a `while' token.
+The function MUST NOT UNDER ANY CIRCUMSTANCES call c-beginning-of-statement-1,
+even indirectly.  This variable contains nil for languages which don't have
+EOL terminated statements."
+  t nil
+  (c c++ objc) 'c-macro-vsemi-status-unknown-p
+  awk 'c-awk-vsemi-status-unknown-p)
+(c-lang-defvar c-vsemi-status-unknown-p-fn
+  (c-lang-const c-vsemi-status-unknown-p-fn))
+
+
 ;;; Lexer-level syntax (identifiers, tokens etc).
 
 (c-lang-defconst c-has-bitfields
@@ -737,6 +762,12 @@
 (c-lang-defvar c-multiline-string-start-char
   (c-lang-const c-multiline-string-start-char))
 
+(c-lang-defconst c-opt-cpp-symbol
+  "The symbol which starts preprocessor constructs when in the margin."
+  t "#"
+  (java awk) nil)
+(c-lang-defvar c-opt-cpp-symbol (c-lang-const c-opt-cpp-symbol))
+
 (c-lang-defconst c-opt-cpp-prefix
   "Regexp matching the prefix of a cpp directive in the languages that
 normally use that macro preprocessor.  Tested at bol or at boi.
@@ -785,6 +816,8 @@
 definition, or nil if the language doesn't have any."
   t (if (c-lang-const c-opt-cpp-prefix)
        "define"))
+(c-lang-defvar c-opt-cpp-macro-define
+  (c-lang-const c-opt-cpp-macro-define))
 
 (c-lang-defconst c-opt-cpp-macro-define-start
   ;; Regexp matching everything up to the macro body of a cpp define, or the
@@ -1171,14 +1204,12 @@
   ;; optimize `c-crosses-statement-barrier-p' somewhat, it's assumed to
   ;; begin with "^" to negate the set.  If ? : operators should be
   ;; detected then the string must end with "?:".
-  t    "^;{}?:"
-  awk  "^;{}#\n\r?:") ; The newline chars gets special treatment.
+  t "^;{}?:")
 (c-lang-defvar c-stmt-delim-chars (c-lang-const c-stmt-delim-chars))
 
 (c-lang-defconst c-stmt-delim-chars-with-comma
   ;; Variant of `c-stmt-delim-chars' that additionally contains ','.
-  t    "^;,{}?:"
-  awk  "^;,{}\n\r?:") ; The newline chars gets special treatment.
+  t    "^;,{}?:")
 (c-lang-defvar c-stmt-delim-chars-with-comma
   (c-lang-const c-stmt-delim-chars-with-comma))
 
@@ -1238,7 +1269,6 @@
        re)))
 (c-lang-defvar c-comment-start-regexp (c-lang-const c-comment-start-regexp))
 
-;;;; Added by ACM, 2003/9/18.
 (c-lang-defconst c-block-comment-start-regexp
   ;; Regexp which matches the start of a block comment (if such exists in the
   ;; language)
@@ -1248,6 +1278,15 @@
 (c-lang-defvar c-block-comment-start-regexp
   (c-lang-const c-block-comment-start-regexp))
 
+(c-lang-defconst c-line-comment-start-regexp
+  ;; Regexp which matches the start of a line comment (if such exists in the
+  ;; language; it does in all 7 CC Mode languages).
+  t (if (c-lang-const c-line-comment-starter)
+       (regexp-quote (c-lang-const c-line-comment-starter))
+      "\\<\\>"))
+(c-lang-defvar c-line-comment-start-regexp
+              (c-lang-const c-line-comment-start-regexp))
+
 (c-lang-defconst c-literal-start-regexp
   ;; Regexp to match the start of comments and string literals.
   t (concat (c-lang-const c-comment-start-regexp)
@@ -1475,29 +1514,6 @@
 (c-lang-defvar c-syntactic-eol (c-lang-const c-syntactic-eol))
 
 
-;;; Syntactic analysis ("virtual semicolons") for line-oriented languages 
(AWK).
-(c-lang-defconst c-at-vsemi-p-fn
-  "Contains a function \"Is there a virtual semicolon at POS or point?\".
-Such a function takes one optional parameter, a buffer position (defaults to
-point), and returns nil or t.  This variable contains nil for languages which
-don't have EOL terminated statements. "
-  t nil
-  awk 'c-awk-at-vsemi-p)
-(c-lang-defvar c-at-vsemi-p-fn (c-lang-const c-at-vsemi-p-fn))
-
-(c-lang-defconst c-vsemi-status-unknown-p-fn
-  "Contains a function \"are we unsure whether there is a virtual semicolon on 
this line?\".
-The (admittedly kludgey) purpose of such a function is to prevent an infinite
-recursion in c-beginning-of-statement-1 when point starts at a `while' token.
-The function MUST NOT UNDER ANY CIRCUMSTANCES call c-beginning-of-statement-1,
-even indirectly.  This variable contains nil for languages which don't have
-EOL terminated statements."
-  t nil
-  awk 'c-awk-vsemi-status-unknown-p)
-(c-lang-defvar c-vsemi-status-unknown-p-fn
-  (c-lang-const c-vsemi-status-unknown-p-fn))
-
-
 ;;; Defun functions
 
 ;; The Emacs variables beginning-of-defun-function and

=== modified file 'lisp/progmodes/cc-mode.el'
--- a/lisp/progmodes/cc-mode.el 2011-09-09 09:52:26 +0000
+++ b/lisp/progmodes/cc-mode.el 2011-10-27 20:34:23 +0000
@@ -1187,6 +1187,7 @@
        abbrev-mode t)
   (use-local-map c-mode-map)
   (c-init-language-vars-for 'c-mode)
+  (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
   (c-common-init 'c-mode)
   (easy-menu-add c-c-menu)
   (cc-imenu-init cc-imenu-c-generic-expression)
@@ -1246,6 +1247,7 @@
        abbrev-mode t)
   (use-local-map c++-mode-map)
   (c-init-language-vars-for 'c++-mode)
+  (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
   (c-common-init 'c++-mode)
   (easy-menu-add c-c++-menu)
   (cc-imenu-init cc-imenu-c++-generic-expression)
@@ -1303,6 +1305,7 @@
        abbrev-mode t)
   (use-local-map objc-mode-map)
   (c-init-language-vars-for 'objc-mode)
+  (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
   (c-common-init 'objc-mode)
   (easy-menu-add c-objc-menu)
   (cc-imenu-init nil 'cc-imenu-objc-function)

=== modified file 'lisp/progmodes/cc-vars.el'
--- a/lisp/progmodes/cc-vars.el 2011-07-12 23:19:33 +0000
+++ b/lisp/progmodes/cc-vars.el 2011-10-27 20:34:23 +0000
@@ -1608,6 +1608,54 @@
 
 
 ;; Non-customizable variables, still part of the interface to CC Mode
+(defvar c-macro-with-semi-re nil
+  ;; Regular expression which matches a (#define'd) symbol whose expansion
+  ;; ends with a semicolon.
+  ;; 
+  ;; This variable should be set by `c-make-macros-with-semi-re' rather than
+  ;; directly.
+)
+(make-variable-buffer-local 'c-macro-with-semi-re)
+
+(defun c-make-macro-with-semi-re ()
+  ;; Convert `c-macro-names-with-semicolon' into the regexp
+  ;; `c-macro-with-semi-re' (or just copy it if it's already a re).
+  (setq c-macro-with-semi-re
+       (and
+        c-opt-cpp-macro-define
+        (cond
+         ((stringp c-macro-names-with-semicolon)
+          (copy-sequence c-macro-names-with-semicolon))
+         ((consp c-macro-names-with-semicolon)
+          (concat
+           "\\<"
+           (regexp-opt c-macro-names-with-semicolon)
+           "\\>"))   ; N.B. the PAREN param of regexp-opt isn't supported by
+                     ; all XEmacsen.
+         ((null c-macro-names-with-semicolon)
+          nil)
+         (t (error "c-make-macro-with-semi-re: invalid \
+c-macro-names-with-semicolon: %s"
+                   c-macro-names-with-semicolon))))))
+    
+(defvar c-macro-names-with-semicolon
+  '("Q_OBJECT" "Q_PROPERTY" "Q_DECLARE" "Q_ENUMS")
+  "List of #defined symbols whose expansion ends with a semicolon.
+Alternatively it can be a string, a regular expression which
+matches all such symbols.
+
+The \"symbols\" must be syntactically valid identifiers in the
+target language \(C, C++, Objective C), or \(as the case may be)
+the regular expression must match only valid identifiers.
+
+If you change this variable's value, call the function
+`c-make-macros-with-semi-re' to set the necessary internal
+variables.
+
+Note that currently \(2008-11-04) this variable is a prototype,
+and is likely to disappear or change its form soon.")
+(make-variable-buffer-local 'c-macro-names-with-semicolon)
+
 (defvar c-file-style nil
   "Variable interface for setting style via File Local Variables.
 In a file's Local Variable section, you can set this variable to a


reply via email to

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