aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorAlan Mackenzie2011-10-27 20:34:23 +0000
committerAlan Mackenzie2011-10-27 20:34:23 +0000
commit536610a433e6edc0b3f831272c4e0424ebebee46 (patch)
treefcb6f43d840d6fd67d20b64ba4e510ddee34ae45 /lisp
parent86c606818495d9411fd5d6b1477f9a097eb18020 (diff)
downloademacs-536610a433e6edc0b3f831272c4e0424ebebee46.tar.gz
emacs-536610a433e6edc0b3f831272c4e0424ebebee46.zip
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. 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.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/progmodes/cc-defs.el19
-rw-r--r--lisp/progmodes/cc-engine.el150
-rw-r--r--lisp/progmodes/cc-fonts.el8
-rw-r--r--lisp/progmodes/cc-langs.el72
-rw-r--r--lisp/progmodes/cc-mode.el3
-rw-r--r--lisp/progmodes/cc-vars.el48
6 files changed, 223 insertions, 77 deletions
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index e5b4d7e35a4..93da6e3e2be 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -744,19 +744,20 @@ be after it."
744;; V i r t u a l S e m i c o l o n s 744;; V i r t u a l S e m i c o l o n s
745;; 745;;
746;; In most CC Mode languages, statements are terminated explicitly by 746;; In most CC Mode languages, statements are terminated explicitly by
747;; semicolons or closing braces. In some of the CC modes (currently only AWK 747;; semicolons or closing braces. In some of the CC modes (currently AWK Mode
748;; Mode (April 2004)), statements are (or can be) terminated by EOLs. Such a 748;; and certain user-specified #define macros in C, C++, etc. (November 2008)),
749;; statement is said to be terminated by a "virtual semicolon" (VS). A 749;; statements are (or can be) terminated by EOLs. Such a statement is said to
750;; statement terminated by an actual semicolon or brace is never considered to 750;; be terminated by a "virtual semicolon" (VS). A statement terminated by an
751;; have a VS. 751;; actual semicolon or brace is never considered to have a VS.
752;; 752;;
753;; The indentation engine (or whatever) tests for a VS at a specific position 753;; The indentation engine (or whatever) tests for a VS at a specific position
754;; by invoking the macro `c-at-vsemi-p', which in its turn calls the mode 754;; by invoking the macro `c-at-vsemi-p', which in its turn calls the mode
755;; specific function (if any) which is the value of the language variable 755;; specific function (if any) which is the value of the language variable
756;; `c-at-vsemi-p-fn'. The actual details of what constitutes a VS in a 756;; `c-at-vsemi-p-fn'. This function should only use "low-level" features of
757;; language are thus encapsulated in code specific to that language 757;; CC Mode, i.e. features which won't trigger infinite recursion. ;-) The
758;; (e.g. cc-awk.el). `c-at-vsemi-p' returns non-nil if point (or the optional 758;; actual details of what constitutes a VS in a language are thus encapsulated
759;; parameter POS) is at a VS, nil otherwise. 759;; in code specific to that language (e.g. cc-awk.el). `c-at-vsemi-p' returns
760;; non-nil if point (or the optional parameter POS) is at a VS, nil otherwise.
760;; 761;;
761;; The language specific function might well do extensive analysis of the 762;; The language specific function might well do extensive analysis of the
762;; source text, and may use a cacheing scheme to speed up repeated calls. 763;; source text, and may use a cacheing scheme to speed up repeated calls.
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index b2c548847c3..c7e02a1bbd5 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -1149,42 +1149,65 @@ the line. If this virtual semicolon is _at_ from, the function recognizes it.
1149 1149
1150Note that this function might do hidden buffer changes. See the 1150Note that this function might do hidden buffer changes. See the
1151comment at the start of cc-engine.el for more info." 1151comment at the start of cc-engine.el for more info."
1152 (let ((skip-chars c-stmt-delim-chars) 1152 (let* ((skip-chars
1153 lit-range) 1153 ;; If the current language has CPP macros, insert # into skip-chars.
1154 (save-excursion 1154 (if c-opt-cpp-symbol
1155 (catch 'done 1155 (concat (substring c-stmt-delim-chars 0 1) ; "^"
1156 (goto-char from) 1156 c-opt-cpp-symbol ; usually "#"
1157 (while (progn (skip-chars-forward skip-chars to) 1157 (substring c-stmt-delim-chars 1)) ; e.g. ";{}?:"
1158 (< (point) to)) 1158 c-stmt-delim-chars))
1159 (cond 1159 (non-skip-list
1160 ((setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment? 1160 (append (substring skip-chars 1) nil)) ; e.g. (?# ?\; ?{ ?} ?? ?:)
1161 (goto-char (cdr lit-range))) 1161 lit-range vsemi-pos)
1162 ((eq (char-after) ?:) 1162 (save-restriction
1163 (forward-char) 1163 (widen)
1164 (if (and (eq (char-after) ?:) 1164 (save-excursion
1165 (< (point) to)) 1165 (catch 'done
1166 ;; Ignore scope operators. 1166 (goto-char from)
1167 (forward-char) 1167 (while (progn (skip-chars-forward
1168 (setq c-maybe-labelp (1- (point))))) 1168 skip-chars
1169 ((eq (char-after) ??) 1169 (min to (c-point 'bonl)))
1170 ;; A question mark. Can't be a label, so stop 1170 (< (point) to))
1171 ;; looking for more : and ?. 1171 (cond
1172 (setq c-maybe-labelp nil 1172 ;; Virtual semicolon?
1173 skip-chars (substring c-stmt-delim-chars 0 -2))) 1173 ((and (bolp)
1174 ((memq (char-after) '(?# ?\n ?\r)) ; A virtual semicolon? 1174 (save-excursion
1175 (if (and (eq (char-before) ?\\) (memq (char-after) '(?\n ?\r))) 1175 (progn
1176 (backward-char)) 1176 (if (setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment?
1177 (skip-chars-backward " \t" from) 1177 (goto-char (car lit-range)))
1178 (if (c-at-vsemi-p) 1178 (c-backward-syntactic-ws) ; ? put a limit here, maybe?
1179 (throw 'done (point)) 1179 (setq vsemi-pos (point))
1180 (forward-line))) 1180 (c-at-vsemi-p))))
1181 (t (throw 'done (point))))) 1181 (throw 'done vsemi-pos))
1182 ;; In trailing space after an as yet undetected virtual semicolon? 1182 ;; In a string/comment?
1183 (c-backward-syntactic-ws from) 1183 ((setq lit-range (c-literal-limits))
1184 (if (and (< (point) to) 1184 (goto-char (cdr lit-range)))
1185 (c-at-vsemi-p)) 1185 ((eq (char-after) ?:)
1186 (point) 1186 (forward-char)
1187 nil))))) 1187 (if (and (eq (char-after) ?:)
1188 (< (point) to))
1189 ;; Ignore scope operators.
1190 (forward-char)
1191 (setq c-maybe-labelp (1- (point)))))
1192 ((eq (char-after) ??)
1193 ;; A question mark. Can't be a label, so stop
1194 ;; looking for more : and ?.
1195 (setq c-maybe-labelp nil
1196 skip-chars (substring c-stmt-delim-chars 0 -2)))
1197 ;; At a CPP construct?
1198 ((and c-opt-cpp-symbol (looking-at c-opt-cpp-symbol)
1199 (save-excursion
1200 (forward-line 0)
1201 (looking-at c-opt-cpp-prefix)))
1202 (c-end-of-macro))
1203 ((memq (char-after) non-skip-list)
1204 (throw 'done (point)))))
1205 ;; In trailing space after an as yet undetected virtual semicolon?
1206 (c-backward-syntactic-ws from)
1207 (if (and (< (point) to)
1208 (c-at-vsemi-p))
1209 (point)
1210 nil))))))
1188 1211
1189(defun c-at-statement-start-p () 1212(defun c-at-statement-start-p ()
1190 "Return non-nil if the point is at the first token in a statement 1213 "Return non-nil if the point is at the first token in a statement
@@ -7158,12 +7181,14 @@ comment at the start of cc-engine.el for more info."
7158 ;; Check that we're not after a token that can't precede a label. 7181 ;; Check that we're not after a token that can't precede a label.
7159 (or 7182 (or
7160 ;; Trivially succeeds when there's no preceding token. 7183 ;; Trivially succeeds when there's no preceding token.
7184 ;; Succeeds when we're at a virtual semicolon.
7161 (if preceding-token-end 7185 (if preceding-token-end
7162 (<= preceding-token-end (point-min)) 7186 (<= preceding-token-end (point-min))
7163 (save-excursion 7187 (save-excursion
7164 (c-backward-syntactic-ws) 7188 (c-backward-syntactic-ws)
7165 (setq preceding-token-end (point)) 7189 (setq preceding-token-end (point))
7166 (bobp))) 7190 (or (bobp)
7191 (c-at-vsemi-p))))
7167 7192
7168 ;; Check if we're after a label, if we're after a closing 7193 ;; Check if we're after a label, if we're after a closing
7169 ;; paren that belong to statement, and with 7194 ;; paren that belong to statement, and with
@@ -8372,6 +8397,57 @@ comment at the start of cc-engine.el for more info."
8372 paren-state) 8397 paren-state)
8373 containing-sexp))))) 8398 containing-sexp)))))
8374 8399
8400(defun c-at-macro-vsemi-p (&optional pos)
8401 ;; Is there a "virtual semicolon" at POS or point?
8402 ;; (See cc-defs.el for full details of "virtual semicolons".)
8403 ;;
8404 ;; This is true when point is at the last non syntactic WS position on the
8405 ;; line, there is a macro call last on the line, and this particular macro's
8406 ;; name is defined by the regexp `c-vs-macro-regexp' as not needing a
8407 ;; semicolon.
8408 (save-excursion
8409 (save-restriction
8410 (widen)
8411 (if pos
8412 (goto-char pos)
8413 (setq pos (point)))
8414 (and
8415 c-macro-with-semi-re
8416 (not (c-in-literal))
8417 (eq (skip-chars-backward " \t") 0)
8418
8419 ;; Check we've got nothing after this except comments and empty lines
8420 ;; joined by escaped EOLs.
8421 (skip-chars-forward " \t") ; always returns non-nil.
8422 (progn
8423 (while ; go over 1 block comment per iteration.
8424 (and
8425 (looking-at "\\(\\\\[\n\r][ \t]*\\)*")
8426 (goto-char (match-end 0))
8427 (cond
8428 ((looking-at c-block-comment-start-regexp)
8429 (and (forward-comment 1)
8430 (skip-chars-forward " \t"))) ; always returns non-nil
8431 ((looking-at c-line-comment-start-regexp)
8432 (end-of-line)
8433 nil)
8434 (t nil))))
8435 (eolp))
8436
8437 (goto-char pos)
8438 (progn (c-backward-syntactic-ws)
8439 (eq (point) pos))
8440
8441 ;; Check for one of the listed macros being before point.
8442 (or (not (eq (char-before) ?\)))
8443 (when (c-go-list-backward)
8444 (c-backward-syntactic-ws)
8445 t))
8446 (c-simple-skip-symbol-backward)
8447 (looking-at c-macro-with-semi-re)))))
8448
8449(defun c-macro-vsemi-status-unknown-p () t) ; See cc-defs.el.
8450
8375 8451
8376;; `c-guess-basic-syntax' and the functions that precedes it below 8452;; `c-guess-basic-syntax' and the functions that precedes it below
8377;; implements the main decision tree for determining the syntactic 8453;; implements the main decision tree for determining the syntactic
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index fd817e3b4f4..9a83d5196db 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -1277,9 +1277,11 @@ casts and declarations are fontified. Used on level 2 and higher."
1277 (when 1277 (when
1278 ;; The result of the form below is true when we don't recognize a 1278 ;; The result of the form below is true when we don't recognize a
1279 ;; declaration or cast. 1279 ;; declaration or cast.
1280 (if (and (eq (get-text-property (point) 'face) 1280 (if (or (and (eq (get-text-property (point) 'face)
1281 'font-lock-keyword-face) 1281 'font-lock-keyword-face)
1282 (looking-at c-not-decl-init-keywords)) 1282 (looking-at c-not-decl-init-keywords))
1283 (and c-macro-with-semi-re
1284 (looking-at c-macro-with-semi-re))) ; 2008-11-04
1283 ;; Don't do anything more if we're looking at a keyword that 1285 ;; Don't do anything more if we're looking at a keyword that
1284 ;; can't start a declaration. 1286 ;; can't start a declaration.
1285 t 1287 t
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 279c5e46c46..09f8b318378 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -509,6 +509,31 @@ parameters \(point-min), \(point-max) and <buffer size>."
509 (c-lang-const c-before-font-lock-function)) 509 (c-lang-const c-before-font-lock-function))
510 510
511 511
512;;; Syntactic analysis ("virtual semicolons") for line-oriented languages (AWK).
513(c-lang-defconst c-at-vsemi-p-fn
514 "Contains a function \"Is there a virtual semicolon at POS or point?\".
515Such a function takes one optional parameter, a buffer position (defaults to
516point), and returns nil or t. This variable contains nil for languages which
517don't have EOL terminated statements. "
518 t nil
519 (c c++ objc) 'c-at-macro-vsemi-p
520 awk 'c-awk-at-vsemi-p)
521(c-lang-defvar c-at-vsemi-p-fn (c-lang-const c-at-vsemi-p-fn))
522
523(c-lang-defconst c-vsemi-status-unknown-p-fn
524 "Contains a function \"are we unsure whether there is a virtual semicolon on this line?\".
525The (admittedly kludgey) purpose of such a function is to prevent an infinite
526recursion in c-beginning-of-statement-1 when point starts at a `while' token.
527The function MUST NOT UNDER ANY CIRCUMSTANCES call c-beginning-of-statement-1,
528even indirectly. This variable contains nil for languages which don't have
529EOL terminated statements."
530 t nil
531 (c c++ objc) 'c-macro-vsemi-status-unknown-p
532 awk 'c-awk-vsemi-status-unknown-p)
533(c-lang-defvar c-vsemi-status-unknown-p-fn
534 (c-lang-const c-vsemi-status-unknown-p-fn))
535
536
512;;; Lexer-level syntax (identifiers, tokens etc). 537;;; Lexer-level syntax (identifiers, tokens etc).
513 538
514(c-lang-defconst c-has-bitfields 539(c-lang-defconst c-has-bitfields
@@ -737,6 +762,12 @@ literal are multiline."
737(c-lang-defvar c-multiline-string-start-char 762(c-lang-defvar c-multiline-string-start-char
738 (c-lang-const c-multiline-string-start-char)) 763 (c-lang-const c-multiline-string-start-char))
739 764
765(c-lang-defconst c-opt-cpp-symbol
766 "The symbol which starts preprocessor constructs when in the margin."
767 t "#"
768 (java awk) nil)
769(c-lang-defvar c-opt-cpp-symbol (c-lang-const c-opt-cpp-symbol))
770
740(c-lang-defconst c-opt-cpp-prefix 771(c-lang-defconst c-opt-cpp-prefix
741 "Regexp matching the prefix of a cpp directive in the languages that 772 "Regexp matching the prefix of a cpp directive in the languages that
742normally use that macro preprocessor. Tested at bol or at boi. 773normally use that macro preprocessor. Tested at bol or at boi.
@@ -785,6 +816,8 @@ file name in angle brackets or quotes."
785definition, or nil if the language doesn't have any." 816definition, or nil if the language doesn't have any."
786 t (if (c-lang-const c-opt-cpp-prefix) 817 t (if (c-lang-const c-opt-cpp-prefix)
787 "define")) 818 "define"))
819(c-lang-defvar c-opt-cpp-macro-define
820 (c-lang-const c-opt-cpp-macro-define))
788 821
789(c-lang-defconst c-opt-cpp-macro-define-start 822(c-lang-defconst c-opt-cpp-macro-define-start
790 ;; Regexp matching everything up to the macro body of a cpp define, or the 823 ;; Regexp matching everything up to the macro body of a cpp define, or the
@@ -1171,14 +1204,12 @@ operators."
1171 ;; optimize `c-crosses-statement-barrier-p' somewhat, it's assumed to 1204 ;; optimize `c-crosses-statement-barrier-p' somewhat, it's assumed to
1172 ;; begin with "^" to negate the set. If ? : operators should be 1205 ;; begin with "^" to negate the set. If ? : operators should be
1173 ;; detected then the string must end with "?:". 1206 ;; detected then the string must end with "?:".
1174 t "^;{}?:" 1207 t "^;{}?:")
1175 awk "^;{}#\n\r?:") ; The newline chars gets special treatment.
1176(c-lang-defvar c-stmt-delim-chars (c-lang-const c-stmt-delim-chars)) 1208(c-lang-defvar c-stmt-delim-chars (c-lang-const c-stmt-delim-chars))
1177 1209
1178(c-lang-defconst c-stmt-delim-chars-with-comma 1210(c-lang-defconst c-stmt-delim-chars-with-comma
1179 ;; Variant of `c-stmt-delim-chars' that additionally contains ','. 1211 ;; Variant of `c-stmt-delim-chars' that additionally contains ','.
1180 t "^;,{}?:" 1212 t "^;,{}?:")
1181 awk "^;,{}\n\r?:") ; The newline chars gets special treatment.
1182(c-lang-defvar c-stmt-delim-chars-with-comma 1213(c-lang-defvar c-stmt-delim-chars-with-comma
1183 (c-lang-const c-stmt-delim-chars-with-comma)) 1214 (c-lang-const c-stmt-delim-chars-with-comma))
1184 1215
@@ -1238,7 +1269,6 @@ properly."
1238 re))) 1269 re)))
1239(c-lang-defvar c-comment-start-regexp (c-lang-const c-comment-start-regexp)) 1270(c-lang-defvar c-comment-start-regexp (c-lang-const c-comment-start-regexp))
1240 1271
1241;;;; Added by ACM, 2003/9/18.
1242(c-lang-defconst c-block-comment-start-regexp 1272(c-lang-defconst c-block-comment-start-regexp
1243 ;; Regexp which matches the start of a block comment (if such exists in the 1273 ;; Regexp which matches the start of a block comment (if such exists in the
1244 ;; language) 1274 ;; language)
@@ -1248,6 +1278,15 @@ properly."
1248(c-lang-defvar c-block-comment-start-regexp 1278(c-lang-defvar c-block-comment-start-regexp
1249 (c-lang-const c-block-comment-start-regexp)) 1279 (c-lang-const c-block-comment-start-regexp))
1250 1280
1281(c-lang-defconst c-line-comment-start-regexp
1282 ;; Regexp which matches the start of a line comment (if such exists in the
1283 ;; language; it does in all 7 CC Mode languages).
1284 t (if (c-lang-const c-line-comment-starter)
1285 (regexp-quote (c-lang-const c-line-comment-starter))
1286 "\\<\\>"))
1287(c-lang-defvar c-line-comment-start-regexp
1288 (c-lang-const c-line-comment-start-regexp))
1289
1251(c-lang-defconst c-literal-start-regexp 1290(c-lang-defconst c-literal-start-regexp
1252 ;; Regexp to match the start of comments and string literals. 1291 ;; Regexp to match the start of comments and string literals.
1253 t (concat (c-lang-const c-comment-start-regexp) 1292 t (concat (c-lang-const c-comment-start-regexp)
@@ -1475,29 +1514,6 @@ properly."
1475(c-lang-defvar c-syntactic-eol (c-lang-const c-syntactic-eol)) 1514(c-lang-defvar c-syntactic-eol (c-lang-const c-syntactic-eol))
1476 1515
1477 1516
1478;;; Syntactic analysis ("virtual semicolons") for line-oriented languages (AWK).
1479(c-lang-defconst c-at-vsemi-p-fn
1480 "Contains a function \"Is there a virtual semicolon at POS or point?\".
1481Such a function takes one optional parameter, a buffer position (defaults to
1482point), and returns nil or t. This variable contains nil for languages which
1483don't have EOL terminated statements. "
1484 t nil
1485 awk 'c-awk-at-vsemi-p)
1486(c-lang-defvar c-at-vsemi-p-fn (c-lang-const c-at-vsemi-p-fn))
1487
1488(c-lang-defconst c-vsemi-status-unknown-p-fn
1489 "Contains a function \"are we unsure whether there is a virtual semicolon on this line?\".
1490The (admittedly kludgey) purpose of such a function is to prevent an infinite
1491recursion in c-beginning-of-statement-1 when point starts at a `while' token.
1492The function MUST NOT UNDER ANY CIRCUMSTANCES call c-beginning-of-statement-1,
1493even indirectly. This variable contains nil for languages which don't have
1494EOL terminated statements."
1495 t nil
1496 awk 'c-awk-vsemi-status-unknown-p)
1497(c-lang-defvar c-vsemi-status-unknown-p-fn
1498 (c-lang-const c-vsemi-status-unknown-p-fn))
1499
1500
1501;;; Defun functions 1517;;; Defun functions
1502 1518
1503;; The Emacs variables beginning-of-defun-function and 1519;; The Emacs variables beginning-of-defun-function and
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index eec63b4fa3b..a6bf241f0db 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1187,6 +1187,7 @@ Key bindings:
1187 abbrev-mode t) 1187 abbrev-mode t)
1188 (use-local-map c-mode-map) 1188 (use-local-map c-mode-map)
1189 (c-init-language-vars-for 'c-mode) 1189 (c-init-language-vars-for 'c-mode)
1190 (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
1190 (c-common-init 'c-mode) 1191 (c-common-init 'c-mode)
1191 (easy-menu-add c-c-menu) 1192 (easy-menu-add c-c-menu)
1192 (cc-imenu-init cc-imenu-c-generic-expression) 1193 (cc-imenu-init cc-imenu-c-generic-expression)
@@ -1246,6 +1247,7 @@ Key bindings:
1246 abbrev-mode t) 1247 abbrev-mode t)
1247 (use-local-map c++-mode-map) 1248 (use-local-map c++-mode-map)
1248 (c-init-language-vars-for 'c++-mode) 1249 (c-init-language-vars-for 'c++-mode)
1250 (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
1249 (c-common-init 'c++-mode) 1251 (c-common-init 'c++-mode)
1250 (easy-menu-add c-c++-menu) 1252 (easy-menu-add c-c++-menu)
1251 (cc-imenu-init cc-imenu-c++-generic-expression) 1253 (cc-imenu-init cc-imenu-c++-generic-expression)
@@ -1303,6 +1305,7 @@ Key bindings:
1303 abbrev-mode t) 1305 abbrev-mode t)
1304 (use-local-map objc-mode-map) 1306 (use-local-map objc-mode-map)
1305 (c-init-language-vars-for 'objc-mode) 1307 (c-init-language-vars-for 'objc-mode)
1308 (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
1306 (c-common-init 'objc-mode) 1309 (c-common-init 'objc-mode)
1307 (easy-menu-add c-objc-menu) 1310 (easy-menu-add c-objc-menu)
1308 (cc-imenu-init nil 'cc-imenu-objc-function) 1311 (cc-imenu-init nil 'cc-imenu-objc-function)
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index 58dc1737c5a..055d5f4c57c 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -1608,6 +1608,54 @@ names)."))
1608 1608
1609 1609
1610;; Non-customizable variables, still part of the interface to CC Mode 1610;; Non-customizable variables, still part of the interface to CC Mode
1611(defvar c-macro-with-semi-re nil
1612 ;; Regular expression which matches a (#define'd) symbol whose expansion
1613 ;; ends with a semicolon.
1614 ;;
1615 ;; This variable should be set by `c-make-macros-with-semi-re' rather than
1616 ;; directly.
1617)
1618(make-variable-buffer-local 'c-macro-with-semi-re)
1619
1620(defun c-make-macro-with-semi-re ()
1621 ;; Convert `c-macro-names-with-semicolon' into the regexp
1622 ;; `c-macro-with-semi-re' (or just copy it if it's already a re).
1623 (setq c-macro-with-semi-re
1624 (and
1625 c-opt-cpp-macro-define
1626 (cond
1627 ((stringp c-macro-names-with-semicolon)
1628 (copy-sequence c-macro-names-with-semicolon))
1629 ((consp c-macro-names-with-semicolon)
1630 (concat
1631 "\\<"
1632 (regexp-opt c-macro-names-with-semicolon)
1633 "\\>")) ; N.B. the PAREN param of regexp-opt isn't supported by
1634 ; all XEmacsen.
1635 ((null c-macro-names-with-semicolon)
1636 nil)
1637 (t (error "c-make-macro-with-semi-re: invalid \
1638c-macro-names-with-semicolon: %s"
1639 c-macro-names-with-semicolon))))))
1640
1641(defvar c-macro-names-with-semicolon
1642 '("Q_OBJECT" "Q_PROPERTY" "Q_DECLARE" "Q_ENUMS")
1643 "List of #defined symbols whose expansion ends with a semicolon.
1644Alternatively it can be a string, a regular expression which
1645matches all such symbols.
1646
1647The \"symbols\" must be syntactically valid identifiers in the
1648target language \(C, C++, Objective C), or \(as the case may be)
1649the regular expression must match only valid identifiers.
1650
1651If you change this variable's value, call the function
1652`c-make-macros-with-semi-re' to set the necessary internal
1653variables.
1654
1655Note that currently \(2008-11-04) this variable is a prototype,
1656and is likely to disappear or change its form soon.")
1657(make-variable-buffer-local 'c-macro-names-with-semicolon)
1658
1611(defvar c-file-style nil 1659(defvar c-file-style nil
1612 "Variable interface for setting style via File Local Variables. 1660 "Variable interface for setting style via File Local Variables.
1613In a file's Local Variable section, you can set this variable to a 1661In a file's Local Variable section, you can set this variable to a