aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes
diff options
context:
space:
mode:
authorAlan Mackenzie2005-12-02 12:30:36 +0000
committerAlan Mackenzie2005-12-02 12:30:36 +0000
commit0386b551af726187e2eb674fa2ffdb1cfedaabe8 (patch)
treec9fbaebac1a286f8da48c085a8476e94f18122d2 /lisp/progmodes
parentd60d4cd6ef15e4162e4e0abdddb522b541d30010 (diff)
downloademacs-0386b551af726187e2eb674fa2ffdb1cfedaabe8.tar.gz
emacs-0386b551af726187e2eb674fa2ffdb1cfedaabe8.zip
Update CC Mode to release 5.31.
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/cc-align.el430
-rw-r--r--lisp/progmodes/cc-awk.el557
-rw-r--r--lisp/progmodes/cc-bytecomp.el6
-rw-r--r--lisp/progmodes/cc-cmds.el2921
-rw-r--r--lisp/progmodes/cc-compat.el5
-rw-r--r--lisp/progmodes/cc-defs.el881
-rw-r--r--lisp/progmodes/cc-engine.el5845
-rw-r--r--lisp/progmodes/cc-fonts.el1729
-rw-r--r--lisp/progmodes/cc-langs.el1659
-rw-r--r--lisp/progmodes/cc-menus.el9
-rw-r--r--lisp/progmodes/cc-mode.el387
-rw-r--r--lisp/progmodes/cc-styles.el296
-rw-r--r--lisp/progmodes/cc-subword.el312
-rw-r--r--lisp/progmodes/cc-vars.el555
14 files changed, 9577 insertions, 6015 deletions
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index 36b4fd2545c..83b4d8387d4 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -45,19 +45,10 @@
45(cc-require 'cc-engine) 45(cc-require 'cc-engine)
46 46
47 47
48;; Standard indentation line-ups 48;; Standard line-up functions
49
50;; Calling convention:
51;;
52;; The single argument is a cons cell containing the syntactic symbol
53;; in the car, and the relpos (a.k.a. anchor position) in the cdr.
54;; The cdr may be nil for syntactic symbols which doesn't have an
55;; associated relpos.
56;; 49;;
57;; Some syntactic symbols provide more information, usually more 50;; See the section "Custom Indentation Functions" in the manual for
58;; interesting positions. The complete list for the syntactic element 51;; details on the calling convention.
59;; (beginning with the symbol itself) is available in
60;; `c-syntactic-element'.
61 52
62(defun c-lineup-topmost-intro-cont (langelem) 53(defun c-lineup-topmost-intro-cont (langelem)
63 "Line up declaration continuation lines zero or one indentation step. 54 "Line up declaration continuation lines zero or one indentation step.
@@ -91,17 +82,67 @@ statement-cont.)
91Works with: topmost-intro-cont." 82Works with: topmost-intro-cont."
92 (save-excursion 83 (save-excursion
93 (beginning-of-line) 84 (beginning-of-line)
94 (c-backward-syntactic-ws (cdr langelem)) 85 (c-backward-syntactic-ws (c-langelem-pos langelem))
95 (if (memq (char-before) '(?} ?,)) 86 (if (and (memq (char-before) '(?} ?,))
87 (not (and c-overloadable-operators-regexp
88 (c-after-special-operator-id))))
96 c-basic-offset))) 89 c-basic-offset)))
97 90
91(defun c-block-in-arglist-dwim (arglist-start)
92 ;; This function implements the DWIM to avoid far indentation of
93 ;; brace block constructs in arguments in `c-lineup-arglist' etc.
94 ;; Return non-nil if a brace block construct is detected within the
95 ;; arglist starting at ARGLIST-START.
96
97 (or
98 ;; Check if the syntactic context contains any of the symbols for
99 ;; in-expression constructs. This can both save the work that we
100 ;; have to do below, and it also detect the brace list constructs
101 ;; that `c-looking-at-inexpr-block' currently misses (they are
102 ;; recognized by `c-inside-bracelist-p' instead).
103 (assq 'inexpr-class c-syntactic-context)
104 (assq 'inexpr-statement c-syntactic-context)
105 (assq 'inlambda c-syntactic-context)
106
107 (save-restriction
108 ;; Search for open braces from the arglist start to the end of the
109 ;; line.
110 (narrow-to-region arglist-start (c-point 'eol arglist-start))
111
112 (goto-char arglist-start)
113 (while (and (c-syntactic-re-search-forward "{" nil t)
114 (progn
115 (backward-char)
116 (or
117 ;; Ignore starts of special brace lists.
118 (and c-special-brace-lists
119 (save-restriction
120 (widen)
121 (c-looking-at-special-brace-list)))
122 ;; Ignore complete blocks.
123 (c-safe (c-forward-sexp) t))))
124 (forward-char))
125
126 (looking-at "{"))
127
128 (let (containing-sexp)
129 (goto-char arglist-start)
130 ;; `c-syntactic-eol' always matches somewhere on the line.
131 (re-search-forward c-syntactic-eol)
132 (goto-char (match-beginning 0))
133 (c-forward-syntactic-ws)
134 (setq containing-sexp (c-most-enclosing-brace (c-parse-state)))
135 (c-looking-at-inexpr-block
136 (c-safe-position (or containing-sexp (point)) c-state-cache)
137 containing-sexp))))
138
98(defun c-lineup-arglist (langelem) 139(defun c-lineup-arglist (langelem)
99 "Line up the current argument line under the first argument. 140 "Line up the current argument line under the first argument.
100 141
101As a special case, if an argument on the same line as the open 142As a special case, if the indented line is inside a brace block
102parenthesis starts with a brace block opener, the indentation is 143construct, the indentation is `c-basic-offset' only. This is intended
103`c-basic-offset' only. This is intended as a \"DWIM\" measure in 144as a \"DWIM\" measure in cases like macros that contains statement
104cases like macros that contains statement blocks, e.g: 145blocks, e.g:
105 146
106A_VERY_LONG_MACRO_NAME ({ 147A_VERY_LONG_MACRO_NAME ({
107 some (code, with + long, lines * in[it]); 148 some (code, with + long, lines * in[it]);
@@ -115,38 +156,25 @@ indent such cases this way.
115 156
116Works with: arglist-cont-nonempty, arglist-close." 157Works with: arglist-cont-nonempty, arglist-close."
117 (save-excursion 158 (save-excursion
118 (goto-char (1+ (elt c-syntactic-element 2))) 159 (let ((indent-pos (point)))
119 160
120 ;; Don't stop in the middle of a special brace list opener 161 (if (c-block-in-arglist-dwim (c-langelem-2nd-pos c-syntactic-element))
121 ;; like "({". 162 c-basic-offset ; DWIM case.
122 (when c-special-brace-lists
123 (let ((special-list (c-looking-at-special-brace-list)))
124 (when (and special-list (< (car (car special-list)) (point)))
125 (goto-char (+ (car (car special-list)) 2)))))
126
127 (let ((savepos (point))
128 (eol (c-point 'eol)))
129
130 ;; Find out if an argument on the same line starts with an
131 ;; unclosed open brace paren. Note similar code in
132 ;; `c-lineup-close-paren' and
133 ;; `c-lineup-arglist-close-under-paren'.
134 (if (and (c-syntactic-re-search-forward "{" eol t t)
135 (looking-at c-syntactic-eol)
136 (progn (backward-char)
137 (not (c-looking-at-special-brace-list)))
138 (progn (c-backward-syntactic-ws)
139 (or (= (point) savepos)
140 (eq (char-before) ?,))))
141 c-basic-offset
142 163
143 ;; Normal case. Indent to the token after the arglist open paren. 164 ;; Normal case. Indent to the token after the arglist open paren.
144 (goto-char savepos) 165 (goto-char (c-langelem-2nd-pos c-syntactic-element))
145 (c-forward-syntactic-ws) 166 (if (and c-special-brace-lists
146 (when (< (point) eol) 167 (c-looking-at-special-brace-list))
147 (goto-char savepos) 168 ;; Skip a special brace list opener like "({".
148 (skip-chars-forward " \t")) 169 (progn (c-forward-token-2)
149 (vector (current-column)))))) 170 (forward-char))
171 (forward-char))
172 (let ((arglist-content-start (point)))
173 (c-forward-syntactic-ws)
174 (when (< (point) indent-pos)
175 (goto-char arglist-content-start)
176 (skip-chars-forward " \t"))
177 (vector (current-column)))))))
150 178
151;; Contributed by Kevin Ryde <user42@zip.com.au>. 179;; Contributed by Kevin Ryde <user42@zip.com.au>.
152(defun c-lineup-argcont (elem) 180(defun c-lineup-argcont (elem)
@@ -172,7 +200,7 @@ Works with: arglist-cont, arglist-cont-nonempty."
172 ;; isn't, go back to the last position in it. We do this by 200 ;; isn't, go back to the last position in it. We do this by
173 ;; stepping back over open parens until we get to the open paren 201 ;; stepping back over open parens until we get to the open paren
174 ;; of our argument list. 202 ;; of our argument list.
175 (let ((open-paren (elt c-syntactic-element 2)) 203 (let ((open-paren (c-langelem-2nd-pos c-syntactic-element))
176 (paren-state (c-parse-state))) 204 (paren-state (c-parse-state)))
177 (while (not (eq (car paren-state) open-paren)) 205 (while (not (eq (car paren-state) open-paren))
178 (unless (consp (car paren-state)) ;; ignore matched braces 206 (unless (consp (car paren-state)) ;; ignore matched braces
@@ -233,51 +261,36 @@ corresponding open paren, but can also be used with arglist-cont and
233arglist-cont-nonempty to line up all lines inside a parenthesis under 261arglist-cont-nonempty to line up all lines inside a parenthesis under
234the open paren. 262the open paren.
235 263
236As a special case, if a brace block is opened at the same line as the 264As a special case, if a brace block construct starts at the same line
237open parenthesis of the argument list, the indentation is 265as the open parenthesis of the argument list, the indentation is
238`c-basic-offset' only. See `c-lineup-arglist' for further discussion 266`c-basic-offset' only. See `c-lineup-arglist' for further discussion
239of this \"DWIM\" measure. 267of this \"DWIM\" measure.
240 268
241Works with: Almost all symbols, but are typically most useful on 269Works with: Almost all symbols, but are typically most useful on
242arglist-close, brace-list-close, arglist-cont and arglist-cont-nonempty." 270arglist-close, brace-list-close, arglist-cont and arglist-cont-nonempty."
243 (save-excursion 271 (save-excursion
244 (let (special-list paren-start savepos) 272 (if (memq (c-langelem-sym langelem)
245 (if (memq (car langelem) '(arglist-cont-nonempty arglist-close)) 273 '(arglist-cont-nonempty arglist-close))
246 (goto-char (elt c-syntactic-element 2)) 274 (goto-char (c-langelem-2nd-pos c-syntactic-element))
247 (beginning-of-line) 275 (beginning-of-line)
248 (c-go-up-list-backward)) 276 (c-go-up-list-backward))
249 277
250 (if (and c-special-brace-lists 278 (if (save-excursion (c-block-in-arglist-dwim (point)))
251 (setq special-list (c-looking-at-special-brace-list))) 279 c-basic-offset ; DWIM case.
252 ;; Don't stop in the middle of a special brace list opener 280
253 ;; like "({". 281 ;; Normal case. Indent to the arglist open paren.
254 (progn 282 (let (special-list)
255 (setq paren-start (car (car special-list))) 283 (if (and c-special-brace-lists
256 (goto-char (+ paren-start 2))) 284 (setq special-list (c-looking-at-special-brace-list)))
257 (setq paren-start (point)) 285 ;; Cope if we're in the middle of a special brace list
258 (forward-char 1)) 286 ;; opener like "({".
259 287 (goto-char (car (car special-list))))
260 (setq savepos (point))
261 ;; Find out if an argument on the same line starts with an
262 ;; unclosed open brace paren. Note similar code in
263 ;; `c-lineup-arglist' and `c-lineup-close-paren'.
264 (if (and (c-syntactic-re-search-forward "{" (c-point 'eol) t t)
265 (looking-at c-syntactic-eol)
266 (progn (backward-char)
267 (not (c-looking-at-special-brace-list)))
268 (progn (c-backward-syntactic-ws)
269 (or (= (point) savepos)
270 (eq (char-before) ?,))))
271 c-basic-offset
272
273 ;; Normal case. Indent to the arglist open paren.
274 (goto-char paren-start)
275 (vector (current-column)))))) 288 (vector (current-column))))))
276 289
277(defun c-lineup-arglist-operators (langelem) 290(defun c-lineup-arglist-operators (langelem)
278 "Line up lines starting with an infix operator under the open paren. 291 "Line up lines starting with an infix operator under the open paren.
279Return nil on lines that don't start with an operator, to leave those 292Return nil on lines that don't start with an operator, to leave those
280cases to other lineup functions. Example: 293cases to other line-up functions. Example:
281 294
282if ( x < 10 295if ( x < 10
283 || at_limit (x, <- c-lineup-arglist-operators 296 || at_limit (x, <- c-lineup-arglist-operators
@@ -285,7 +298,7 @@ if ( x < 10
285 ) 298 )
286 299
287Since this function doesn't do anything for lines without an infix 300Since this function doesn't do anything for lines without an infix
288operator you typically want to use it together with some other lineup 301operator you typically want to use it together with some other line-up
289settings, e.g. as follows \(the arglist-close setting is just a 302settings, e.g. as follows \(the arglist-close setting is just a
290suggestion to get a consistent style): 303suggestion to get a consistent style):
291 304
@@ -310,52 +323,48 @@ main (int, main (
310 char ** int, char ** 323 char ** int, char **
311 ) <-> ) <- c-lineup-close-paren 324 ) <-> ) <- c-lineup-close-paren
312 325
313As a special case, if a brace block is opened at the same line as the 326As a special case, if a brace block construct starts at the same line
314open parenthesis of the argument list, the indentation is 327as the open parenthesis of the argument list, the indentation is
315`c-basic-offset' instead of the open paren column. See 328`c-basic-offset' instead of the open paren column. See
316`c-lineup-arglist' for further discussion of this \"DWIM\" measure. 329`c-lineup-arglist' for further discussion of this \"DWIM\" measure.
317 330
318Works with: All *-close symbols." 331Works with: All *-close symbols."
319 (save-excursion 332 (save-excursion
320 (beginning-of-line) 333 (if (memq (c-langelem-sym langelem)
321 (c-go-up-list-backward) 334 '(arglist-cont-nonempty arglist-close))
335 (goto-char (c-langelem-2nd-pos c-syntactic-element))
336 (beginning-of-line)
337 (c-go-up-list-backward))
322 338
323 (let ((spec (c-looking-at-special-brace-list)) savepos argstart) 339 (let (special-list arglist-start)
324 (if spec (goto-char (car (car spec)))) 340 (if (and c-special-brace-lists
325 (setq savepos (point)) 341 (setq special-list (c-looking-at-special-brace-list)))
326 (forward-char 1) 342 ;; Cope if we're in the middle of a special brace list
327 (when spec 343 ;; opener like "({".
328 (c-forward-syntactic-ws) 344 (progn
329 (forward-char 1)) 345 (goto-char (setq arglist-start (car (car special-list))))
346 (c-forward-token-2)
347 (forward-char))
348 (setq arglist-start (point))
349 (forward-char))
330 350
331 (if (looking-at c-syntactic-eol) 351 (cond ((looking-at c-syntactic-eol)
332 ;; The arglist is "empty". 352 0) ; The arglist is "empty".
333 0 353
334 354 ((c-block-in-arglist-dwim (point))
335 ;; Find out if an argument on the same line starts with an 355 c-basic-offset) ; DWIM case.
336 ;; unclosed open brace paren. Note similar code in 356
337 ;; `c-lineup-arglist' and 357 (t
338 ;; `c-lineup-arglist-close-under-paren'. 358 ;; Normal case. Indent to the arglist open paren.
339 (setq argstart (point)) 359 (goto-char arglist-start)
340 (if (and (c-syntactic-re-search-forward "{" (c-point 'eol) t t) 360 (vector (current-column)))))))
341 (looking-at c-syntactic-eol)
342 (progn (backward-char)
343 (not (c-looking-at-special-brace-list)))
344 (progn (c-backward-syntactic-ws)
345 (or (= (point) argstart)
346 (eq (char-before) ?,))))
347 c-basic-offset
348
349 ;; Normal case. Indent to the arglist open paren.
350 (goto-char savepos)
351 (vector (current-column)))))))
352 361
353(defun c-lineup-streamop (langelem) 362(defun c-lineup-streamop (langelem)
354 "Line up C++ stream operators under each other. 363 "Line up C++ stream operators under each other.
355 364
356Works with: stream-op." 365Works with: stream-op."
357 (save-excursion 366 (save-excursion
358 (goto-char (cdr langelem)) 367 (goto-char (c-langelem-pos langelem))
359 (re-search-forward "<<\\|>>" (c-point 'eol) 'move) 368 (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
360 (goto-char (match-beginning 0)) 369 (goto-char (match-beginning 0))
361 (vector (current-column)))) 370 (vector (current-column))))
@@ -382,7 +391,8 @@ Works with: inher-cont, member-init-cont."
382 (let* ((eol (c-point 'eol)) 391 (let* ((eol (c-point 'eol))
383 (here (point)) 392 (here (point))
384 (char-after-ip (char-after))) 393 (char-after-ip (char-after)))
385 (if (cdr langelem) (goto-char (cdr langelem))) 394 (if (c-langelem-pos langelem)
395 (goto-char (c-langelem-pos langelem)))
386 396
387 ;; This kludge is necessary to support both inher-cont and 397 ;; This kludge is necessary to support both inher-cont and
388 ;; member-init-cont, since they have different anchor positions. 398 ;; member-init-cont, since they have different anchor positions.
@@ -415,7 +425,7 @@ class Foo class Foo
415 425
416Works with: inher-cont." 426Works with: inher-cont."
417 (save-excursion 427 (save-excursion
418 (goto-char (cdr langelem)) 428 (goto-char (c-langelem-pos langelem))
419 (forward-word 1) 429 (forward-word 1)
420 (if (looking-at "[ \t]*$") 430 (if (looking-at "[ \t]*$")
421 c-basic-offset 431 c-basic-offset
@@ -439,7 +449,7 @@ Works with: func-decl-cont."
439 (save-excursion 449 (save-excursion
440 (let* ((lim (1- (c-point 'bol))) 450 (let* ((lim (1- (c-point 'bol)))
441 (throws (catch 'done 451 (throws (catch 'done
442 (goto-char (cdr langelem)) 452 (goto-char (c-langelem-pos langelem))
443 (while (zerop (c-forward-token-2 1 t lim)) 453 (while (zerop (c-forward-token-2 1 t lim))
444 (if (looking-at "throws\\>[^_]") 454 (if (looking-at "throws\\>[^_]")
445 (throw 'done t)))))) 455 (throw 'done t))))))
@@ -537,13 +547,13 @@ Works with: The `c' syntactic symbol."
537 ;; matches comment-start-skip, and choose whichever is 547 ;; matches comment-start-skip, and choose whichever is
538 ;; longest. 548 ;; longest.
539 (max (save-excursion 549 (max (save-excursion
540 (goto-char (1+ (cdr langelem))) 550 (goto-char (1+ (c-langelem-pos langelem)))
541 (if (and (match-string 0) 551 (if (and (match-string 0)
542 (looking-at (regexp-quote (match-string 0)))) 552 (looking-at (regexp-quote (match-string 0))))
543 (- (match-end 0) (match-beginning 0)) 553 (- (match-end 0) (match-beginning 0))
544 0)) 554 0))
545 (save-excursion 555 (save-excursion
546 (goto-char (cdr langelem)) 556 (goto-char (c-langelem-pos langelem))
547 (looking-at comment-start-skip) 557 (looking-at comment-start-skip)
548 (- (or (match-end 1) 558 (- (or (match-end 1)
549 (save-excursion 559 (save-excursion
@@ -557,14 +567,20 @@ Works with: The `c' syntactic symbol."
557 ;; a nonempty comment prefix. Treat it as free form text 567 ;; a nonempty comment prefix. Treat it as free form text
558 ;; and don't change the indentation. 568 ;; and don't change the indentation.
559 (vector (current-column)) 569 (vector (current-column))
560 (forward-line -1) 570 ;; Go back to the previous non-blank line, if any.
561 (back-to-indentation) 571 (while
562 (if (>= (cdr langelem) (point)) 572 (progn
563 ;; On the second line in the comment. 573 (forward-line -1)
574 (back-to-indentation)
575 (and (> (point) (c-langelem-pos langelem))
576 (looking-at "[ \t]*$"))))
577 ;; Is the starting line the first continuation line with content?
578 (if (>= (c-langelem-pos langelem) (point))
564 (if (zerop prefixlen) 579 (if (zerop prefixlen)
565 ;; No nonempty comment prefix. Align after comment 580 ;; No nonempty comment prefix. Align after comment
566 ;; starter. 581 ;; starter.
567 (progn 582 (progn
583 (looking-at comment-start-skip)
568 (goto-char (match-end 0)) 584 (goto-char (match-end 0))
569 ;; The following should not be necessary, since 585 ;; The following should not be necessary, since
570 ;; comment-start-skip should match everything (i.e. 586 ;; comment-start-skip should match everything (i.e.
@@ -580,27 +596,27 @@ Works with: The `c' syntactic symbol."
580 ;; Javadoc style comments. 596 ;; Javadoc style comments.
581 (if (> starterlen prefixlen) 597 (if (> starterlen prefixlen)
582 (progn 598 (progn
583 (goto-char (cdr langelem)) 599 (goto-char (c-langelem-pos langelem))
584 (vector (1+ (current-column)))) 600 (vector (1+ (current-column))))
585 (goto-char (+ (cdr langelem) starterlen 1)) 601 (goto-char (+ (c-langelem-pos langelem) starterlen 1))
586 (vector (- (current-column) prefixlen)))) 602 (vector (- (current-column) prefixlen))))
587 ;; Not on the second line in the comment. If the previous 603 ;; We didn't start on the first non-blank continuation line. If the
588 ;; line has a nonempty comment prefix, align with it. 604 ;; previous line has a nonempty comment prefix, align with it.
589 ;; Otherwise, align with the previous nonempty line, but 605 ;; Otherwise, align with the previous nonempty line, but align the
590 ;; align the comment ender with the starter. 606 ;; comment ender with the starter.
591 (when (or (not (looking-at c-current-comment-prefix)) 607 (when (or (not (looking-at c-current-comment-prefix))
592 (eq (match-beginning 0) (match-end 0))) 608 (eq (match-beginning 0) (match-end 0)))
593 (goto-char here) 609 (goto-char here)
594 (back-to-indentation) 610 (back-to-indentation)
595 (if (looking-at (concat "\\(" c-current-comment-prefix "\\)\\*/")) 611 (if (looking-at (concat "\\(" c-current-comment-prefix "\\)\\*/"))
596 (goto-char (cdr langelem)) 612 (goto-char (c-langelem-pos langelem))
597 (while (and (zerop (forward-line -1)) 613 (while (and (zerop (forward-line -1))
598 (looking-at "^[ \t]*$"))) 614 (looking-at "^[ \t]*$")))
599 (back-to-indentation) 615 (back-to-indentation)
600 (if (< (point) (cdr langelem)) 616 (if (< (point) (c-langelem-pos langelem))
601 ;; Align with the comment starter rather than 617 ;; Align with the comment starter rather than
602 ;; with the code before it. 618 ;; with the code before it.
603 (goto-char (cdr langelem))))) 619 (goto-char (c-langelem-pos langelem)))))
604 (vector (current-column))))))) 620 (vector (current-column)))))))
605 621
606(defun c-lineup-comment (langelem) 622(defun c-lineup-comment (langelem)
@@ -665,38 +681,39 @@ If there is no statement after the opening brace to align with, nil is
665returned. This makes the function usable in list expressions. 681returned. This makes the function usable in list expressions.
666 682
667Works with: The `statement' syntactic symbol." 683Works with: The `statement' syntactic symbol."
668 (if (eq (char-after (cdr langelem)) ?{) 684 (if (eq (char-after (c-langelem-pos langelem)) ?{)
669 (save-excursion 685 (save-excursion
670 (if (cdr langelem) (goto-char (cdr langelem))) 686 (if (c-langelem-pos langelem)
687 (goto-char (c-langelem-pos langelem)))
671 (forward-char 1) 688 (forward-char 1)
672 (skip-chars-forward " \t") 689 (skip-chars-forward " \t")
673 (unless (eolp) 690 (unless (eolp)
674 (vector (current-column)))))) 691 (vector (current-column))))))
675 692
676(defun c-lineup-math (langelem) 693(defun c-lineup-assignments (langelem)
677 "Line up the current line after the equal sign on the first line in 694 "Line up the current line after the assignment operator on the first
678the statement. If there isn't any, indent with `c-basic-offset'. If 695line in the statement. If there isn't any, return nil to allow
679the current line contains an equal sign too, try to align it with the 696stacking with other line-up functions. If the current line contains
680first one. 697an assignment operator too, try to align it with the first one.
681 698
682Works with: topmost-intro-cont, statement-cont, arglist-cont, 699Works with: topmost-intro-cont, statement-cont, arglist-cont,
683arglist-cont-nonempty." 700arglist-cont-nonempty."
684 (let (startpos endpos equalp) 701 (let (startpos endpos equalp)
685 702
686 (if (eq (car langelem) 'arglist-cont-nonempty) 703 (if (eq (c-langelem-sym langelem) 'arglist-cont-nonempty)
687 ;; If it's an arglist-cont-nonempty then we're only interested 704 ;; If it's an arglist-cont-nonempty then we're only interested
688 ;; in equal signs outside it. We don't search for a "=" on 705 ;; in equal signs outside it. We don't search for a "=" on
689 ;; the current line since that'd have a different nesting 706 ;; the current line since that'd have a different nesting
690 ;; compared to the one we should align with. 707 ;; compared to the one we should align with.
691 (save-excursion 708 (save-excursion
692 (save-restriction 709 (save-restriction
693 (setq endpos (nth 2 c-syntactic-element)) 710 (setq endpos (c-langelem-2nd-pos c-syntactic-element))
694 (narrow-to-region (cdr langelem) endpos) 711 (narrow-to-region (c-langelem-pos langelem) endpos)
695 (if (setq startpos (c-up-list-backward endpos)) 712 (if (setq startpos (c-up-list-backward endpos))
696 (setq startpos (1+ startpos)) 713 (setq startpos (1+ startpos))
697 (setq startpos (cdr langelem))))) 714 (setq startpos (c-langelem-pos langelem)))))
698 715
699 (setq startpos (cdr langelem) 716 (setq startpos (c-langelem-pos langelem)
700 endpos (point)) 717 endpos (point))
701 718
702 ;; Find a syntactically relevant and unnested "=" token on the 719 ;; Find a syntactically relevant and unnested "=" token on the
@@ -727,7 +744,7 @@ arglist-cont-nonempty."
727 (eolp))) 744 (eolp)))
728 ;; There's no equal sign on the line, or there is one but 745 ;; There's no equal sign on the line, or there is one but
729 ;; nothing follows it. 746 ;; nothing follows it.
730 c-basic-offset 747 nil
731 748
732 ;; calculate indentation column after equals and ws, unless 749 ;; calculate indentation column after equals and ws, unless
733 ;; our line contains an equals sign 750 ;; our line contains an equals sign
@@ -739,6 +756,17 @@ arglist-cont-nonempty."
739 (vector (- (current-column) equalp))) 756 (vector (- (current-column) equalp)))
740 ))) 757 )))
741 758
759(defun c-lineup-math (langelem)
760 "Like `c-lineup-assignments' but indent with `c-basic-offset' if no
761assignment operator was found on the first line. I.e. this function
762is the same as specifying a list (c-lineup-assignments +). It's
763provided for compatibility with old configurations.
764
765Works with: topmost-intro-cont, statement-cont, arglist-cont,
766arglist-cont-nonempty."
767 (or (c-lineup-assignments langelem)
768 c-basic-offset))
769
742(defun c-lineup-cascaded-calls (langelem) 770(defun c-lineup-cascaded-calls (langelem)
743 "Line up \"cascaded calls\" under each other. 771 "Line up \"cascaded calls\" under each other.
744If the line begins with \"->\" or \".\" and the preceding line ends 772If the line begins with \"->\" or \".\" and the preceding line ends
@@ -755,8 +783,8 @@ expressions.
755Works with: topmost-intro-cont, statement-cont, arglist-cont, 783Works with: topmost-intro-cont, statement-cont, arglist-cont,
756arglist-cont-nonempty." 784arglist-cont-nonempty."
757 785
758 (if (and (eq (car langelem) 'arglist-cont-nonempty) 786 (if (and (eq (c-langelem-sym langelem) 'arglist-cont-nonempty)
759 (not (eq (nth 2 c-syntactic-element) 787 (not (eq (c-langelem-2nd-pos c-syntactic-element)
760 (c-most-enclosing-brace (c-parse-state))))) 788 (c-most-enclosing-brace (c-parse-state)))))
761 ;; The innermost open paren is not our one, so don't do 789 ;; The innermost open paren is not our one, so don't do
762 ;; anything. This can occur for arglist-cont-nonempty with 790 ;; anything. This can occur for arglist-cont-nonempty with
@@ -767,7 +795,7 @@ arglist-cont-nonempty."
767 (back-to-indentation) 795 (back-to-indentation)
768 (let ((operator (and (looking-at "->\\|\\.") 796 (let ((operator (and (looking-at "->\\|\\.")
769 (regexp-quote (match-string 0)))) 797 (regexp-quote (match-string 0))))
770 (stmt-start (cdr langelem)) col) 798 (stmt-start (c-langelem-pos langelem)) col)
771 799
772 (when (and operator 800 (when (and operator
773 (looking-at operator) 801 (looking-at operator)
@@ -794,7 +822,7 @@ result = prefix + \"A message \"
794 \"string.\"; <- c-lineup-string-cont 822 \"string.\"; <- c-lineup-string-cont
795 823
796Nil is returned in other situations, to allow stacking with other 824Nil is returned in other situations, to allow stacking with other
797lineup functions. 825line-up functions.
798 826
799Works with: topmost-intro-cont, statement-cont, arglist-cont, 827Works with: topmost-intro-cont, statement-cont, arglist-cont,
800arglist-cont-nonempty." 828arglist-cont-nonempty."
@@ -829,18 +857,18 @@ Works with: template-args-cont."
829Go to the position right after the message receiver, and if you are at 857Go to the position right after the message receiver, and if you are at
830the end of the line, indent the current line c-basic-offset columns 858the end of the line, indent the current line c-basic-offset columns
831from the opening bracket; otherwise you are looking at the first 859from the opening bracket; otherwise you are looking at the first
832character of the first method call argument, so lineup the current 860character of the first method call argument, so line up the current
833line with it. 861line with it.
834 862
835Works with: objc-method-call-cont." 863Works with: objc-method-call-cont."
836 (save-excursion 864 (save-excursion
837 (let* ((extra (save-excursion 865 (let* ((extra (save-excursion
838 (back-to-indentation) 866 (back-to-indentation)
839 (c-backward-syntactic-ws (cdr langelem)) 867 (c-backward-syntactic-ws (c-langelem-pos langelem))
840 (if (eq (char-before) ?:) 868 (if (eq (char-before) ?:)
841 (- c-basic-offset) 869 (- c-basic-offset)
842 0))) 870 0)))
843 (open-bracket-pos (cdr langelem)) 871 (open-bracket-pos (c-langelem-pos langelem))
844 (open-bracket-col (progn 872 (open-bracket-col (progn
845 (goto-char open-bracket-pos) 873 (goto-char open-bracket-pos)
846 (current-column))) 874 (current-column)))
@@ -864,7 +892,7 @@ Works with: objc-method-args-cont."
864 (let* ((here (c-point 'boi)) 892 (let* ((here (c-point 'boi))
865 (curcol (progn (goto-char here) (current-column))) 893 (curcol (progn (goto-char here) (current-column)))
866 (eol (c-point 'eol)) 894 (eol (c-point 'eol))
867 (relpos (cdr langelem)) 895 (relpos (c-langelem-pos langelem))
868 (first-col-column (progn 896 (first-col-column (progn
869 (goto-char relpos) 897 (goto-char relpos)
870 (skip-chars-forward "^:" eol) 898 (skip-chars-forward "^:" eol)
@@ -888,7 +916,7 @@ Works with: objc-method-args-cont."
888 (let* ((here (c-point 'boi)) 916 (let* ((here (c-point 'boi))
889 (curcol (progn (goto-char here) (current-column))) 917 (curcol (progn (goto-char here) (current-column)))
890 (eol (c-point 'eol)) 918 (eol (c-point 'eol))
891 (relpos (cdr langelem)) 919 (relpos (c-langelem-pos langelem))
892 (prev-col-column (progn 920 (prev-col-column (progn
893 (skip-chars-backward "^:" relpos) 921 (skip-chars-backward "^:" relpos)
894 (and (eq (char-before) ?:) 922 (and (eq (char-before) ?:)
@@ -927,13 +955,10 @@ Works with: inlambda, inexpr-statement, inexpr-class."
927 containing-sexp)))))) 955 containing-sexp))))))
928 (when res 956 (when res
929 (goto-char (cdr res)) 957 (goto-char (cdr res))
930 (- (current-column) 958 (vector (current-column))))))
931 (progn
932 (back-to-indentation)
933 (current-column)))))))
934 959
935(defun c-lineup-whitesmith-in-block (langelem) 960(defun c-lineup-whitesmith-in-block (langelem)
936 "Line up lines inside a block in whitesmith style. 961 "Line up lines inside a block in Whitesmith style.
937It's done in a way that works both when the opening brace hangs and 962It's done in a way that works both when the opening brace hangs and
938when it doesn't. E.g: 963when it doesn't. E.g:
939 964
@@ -946,21 +971,54 @@ something
946In the first case the indentation is kept unchanged, in the 971In the first case the indentation is kept unchanged, in the
947second `c-basic-offset' is added. 972second `c-basic-offset' is added.
948 973
949Works with: defun-close, defun-block-intro, block-close, 974Works with: defun-close, defun-block-intro, inline-close, block-close,
950brace-list-close, brace-list-intro, statement-block-intro and all in* 975brace-list-close, brace-list-intro, statement-block-intro,
976arglist-intro, arglist-cont-nonempty, arglist-close, and all in*
951symbols, e.g. inclass and inextern-lang." 977symbols, e.g. inclass and inextern-lang."
952 (save-excursion 978 (save-excursion
953 (+ (progn 979 (if (and (c-go-up-list-backward)
954 (back-to-indentation) 980 (= (point) (c-point 'boi)))
955 (if (eq (char-syntax (char-after)) ?\() 981 nil
956 c-basic-offset 982 c-basic-offset)))
957 0)) 983
958 (progn 984(defun c-lineup-after-whitesmith-blocks (langelem)
959 (goto-char (cdr langelem)) 985 "Compensate for Whitesmith style indentation of blocks.
960 (back-to-indentation) 986Due to the way CC Mode calculates anchor positions for normal lines
961 (if (eq (char-syntax (char-after)) ?\() 987inside blocks, this function is necessary for those lines to get
962 0 988correct Whitesmith style indentation. Consider the following
963 c-basic-offset))))) 989examples:
990
991 int foo()
992 {
993int foo() {
994 { a;
995 a; }
996 x; <-> x; <- c-lineup-after-whitesmith-blocks
997
998The fact that the line with \"x\" is preceded by a Whitesmith style
999indented block in one case and not the other should not affect its
1000indentation. But since CC Mode in cases like this uses the
1001indentation of the preceding statement as anchor position, the \"x\"
1002would in the rightmost case be indented too much if the offset for
1003`statement' was set simply to zero.
1004
1005This lineup function corrects for this situation by detecting if the
1006anchor position is at an open paren character. In that case, it
1007instead indents relative to the surrounding block just like
1008`c-lineup-whitesmith-in-block'.
1009
1010Works with: brace-list-entry, brace-entry-open, statement,
1011arglist-cont."
1012 (save-excursion
1013 (goto-char (c-langelem-pos langelem))
1014 (when (looking-at "\\s\(")
1015 (if (c-go-up-list-backward)
1016 (let ((pos (point)))
1017 (back-to-indentation)
1018 (if (= pos (point))
1019 (vector (current-column))
1020 (vector (+ (current-column) c-basic-offset))))
1021 (vector 0)))))
964 1022
965(defun c-lineup-cpp-define (langelem) 1023(defun c-lineup-cpp-define (langelem)
966 "Line up macro continuation lines according to the indentation of 1024 "Line up macro continuation lines according to the indentation of
@@ -1058,9 +1116,10 @@ Works with: cpp-define-intro."
1058The \"x\" line is aligned to the text after the \":\" on the \"w\" line, and 1116The \"x\" line is aligned to the text after the \":\" on the \"w\" line, and
1059similarly \"z\" under \"y\". 1117similarly \"z\" under \"y\".
1060 1118
1061This is done only in an \"asm\" or \"__asm__\" block, and only to those 1119This is done only in an \"asm\" or \"__asm__\" block, and only to
1062lines mentioned. Anywhere else nil is returned. The usual arrangement is 1120those lines mentioned. Anywhere else nil is returned. The usual
1063to have this routine as an extra feature at the start of arglist lineups, e.g. 1121arrangement is to have this routine as an extra feature at the start
1122of arglist line-ups, e.g.
1064 1123
1065 (c-lineup-gcc-asm-reg c-lineup-arglist) 1124 (c-lineup-gcc-asm-reg c-lineup-arglist)
1066 1125
@@ -1076,7 +1135,7 @@ Works with: arglist-cont, arglist-cont-nonempty."
1076 ;; This can occur for arglist-cont-nonempty with nested arglist 1135 ;; This can occur for arglist-cont-nonempty with nested arglist
1077 ;; starts on the same line. 1136 ;; starts on the same line.
1078 (or (not (eq (car elem) 'arglist-cont-nonempty)) 1137 (or (not (eq (car elem) 'arglist-cont-nonempty))
1079 (eq (elt c-syntactic-element 2) 1138 (eq (c-langelem-2nd-pos c-syntactic-element)
1080 (c-most-enclosing-brace (c-parse-state)))) 1139 (c-most-enclosing-brace (c-parse-state))))
1081 1140
1082 ;; Find the ":" to align to. Look for this first so as to quickly 1141 ;; Find the ":" to align to. Look for this first so as to quickly
@@ -1117,13 +1176,24 @@ ACTION associated with `block-close' syntax."
1117 (let (langelem) 1176 (let (langelem)
1118 (if (and (eq syntax 'block-close) 1177 (if (and (eq syntax 'block-close)
1119 (setq langelem (assq 'block-close c-syntactic-context)) 1178 (setq langelem (assq 'block-close c-syntactic-context))
1120 (progn (goto-char (elt langelem 1)) 1179 (progn (goto-char (c-langelem-pos langelem))
1121 (if (eq (char-after) ?{) 1180 (if (eq (char-after) ?{)
1122 (c-safe (c-forward-sexp -1))) 1181 (c-safe (c-forward-sexp -1)))
1123 (looking-at "\\<do\\>[^_]"))) 1182 (looking-at "\\<do\\>[^_]")))
1124 '(before) 1183 '(before)
1125 '(before after))))) 1184 '(before after)))))
1126 1185
1186(defun c-snug-1line-defun-close (syntax pos)
1187 "Determine the brace hanginess for an AWK defun-close.
1188If the action/function being closed is a one-liner, keep it so. Otherwise put
1189the closing brace on its own line."
1190 (save-excursion
1191 (goto-char pos)
1192 (if (> (c-point 'bol)
1193 (progn (up-list -1) (point)))
1194 '(before after)
1195 '(after))))
1196
1127(defun c-gnu-impose-minimum () 1197(defun c-gnu-impose-minimum ()
1128 "Imposes a minimum indentation for lines inside code blocks. 1198 "Imposes a minimum indentation for lines inside code blocks.
1129The variable `c-label-minimum-indentation' specifies the minimum 1199The variable `c-label-minimum-indentation' specifies the minimum
diff --git a/lisp/progmodes/cc-awk.el b/lisp/progmodes/cc-awk.el
index 995dc48c1ae..b16d571d277 100644
--- a/lisp/progmodes/cc-awk.el
+++ b/lisp/progmodes/cc-awk.el
@@ -1,7 +1,7 @@
1;;; cc-awk.el --- AWK specific code within cc-mode. 1;;; cc-awk.el --- AWK specific code within cc-mode.
2 2
3;; Copyright (C) 1988, 94, 96, 2000, 2001, 2002, 2003, 2004, 2005 3;; Copyright (C) 1988,94,96,2000, 2001, 2002, 2003, 2004, 2005 Free
4;; Free Software Foundation, Inc. 4;; Software Foundation, Inc.
5 5
6;; Author: Alan Mackenzie <acm@muc.de> (originally based on awk-mode.el) 6;; Author: Alan Mackenzie <acm@muc.de> (originally based on awk-mode.el)
7;; Maintainer: FSF 7;; Maintainer: FSF
@@ -20,7 +20,7 @@
20;; GNU General Public License for more details. 20;; GNU General Public License for more details.
21 21
22;; You should have received a copy of the GNU General Public License 22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to the 23;; along with this program; see the file COPYING. If not, write to the
24;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 24;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25;; Boston, MA 02110-1301, USA. 25;; Boston, MA 02110-1301, USA.
26 26
@@ -28,13 +28,14 @@
28 28
29;; This file contains (most of) the adaptations to cc-mode required for the 29;; This file contains (most of) the adaptations to cc-mode required for the
30;; integration of AWK Mode. 30;; integration of AWK Mode.
31;; It is organised thusly: 31;; It is organised thusly, the sections being separated by page breaks:
32;; 1. The AWK Mode syntax table. 32;; 1. The AWK Mode syntax table.
33;; 2. Indentation calculation stuff ("c-awk-NL-prop text-property"). 33;; 2. Regular expressions for analysing AWK code.
34;; 3. Syntax-table property/font-locking stuff, but not including the 34;; 3. Indentation calculation stuff ("c-awk-NL-prop text-property").
35;; 4. Syntax-table property/font-locking stuff, but not including the
35;; font-lock-keywords setting. 36;; font-lock-keywords setting.
36;; 4. The AWK Mode before/after-change-functions. 37;; 5. The AWK Mode before/after-change-functions.
37;; 5. AWK Mode specific versions of commands like beginning-of-defun. 38;; 6. AWK Mode specific versions of commands like beginning-of-defun.
38;; The AWK Mode keymap, abbreviation table, and the mode function itself are 39;; The AWK Mode keymap, abbreviation table, and the mode function itself are
39;; in cc-mode.el. 40;; in cc-mode.el.
40 41
@@ -70,7 +71,7 @@
70 ;; / can delimit regexes or be a division operator. By default we assume 71 ;; / can delimit regexes or be a division operator. By default we assume
71 ;; that it is a division sign, and fix the regexp operator cases with 72 ;; that it is a division sign, and fix the regexp operator cases with
72 ;; `font-lock-syntactic-keywords'. 73 ;; `font-lock-syntactic-keywords'.
73 (modify-syntax-entry ?/ "." st) ; ACM 2002/4/27. 74 (modify-syntax-entry ?/ "." st) ; ACM 2002/4/27.
74 (modify-syntax-entry ?* "." st) 75 (modify-syntax-entry ?* "." st)
75 (modify-syntax-entry ?+ "." st) 76 (modify-syntax-entry ?+ "." st)
76 (modify-syntax-entry ?- "." st) 77 (modify-syntax-entry ?- "." st)
@@ -85,8 +86,176 @@
85 st) 86 st)
86 "Syntax table in use in AWK Mode buffers.") 87 "Syntax table in use in AWK Mode buffers.")
87 88
89
90;; This section defines regular expressions used in the analysis of AWK code.
91
92;; N.B. In the following regexps, an EOL is either \n OR \r. This is because
93;; Emacs has in the past used \r to mark hidden lines in some fashion (and
94;; maybe still does).
95
96(defconst c-awk-esc-pair-re "\\\\\\(.\\|\n\\|\r\\|\\'\\)")
97;; Matches any escaped (with \) character-pair, including an escaped newline.
98(defconst c-awk-non-eol-esc-pair-re "\\\\\\(.\\|\\'\\)")
99;; Matches any escaped (with \) character-pair, apart from an escaped newline.
100(defconst c-awk-comment-without-nl "#.*")
101;; Matches an AWK comment, not including the terminating NL (if any). Note
102;; that the "enclosing" (elisp) regexp must ensure the # is real.
103(defconst c-awk-nl-or-eob "\\(\n\\|\r\\|\\'\\)")
104;; Matches a newline, or the end of buffer.
105
106;; "Space" regular expressions.
107(eval-and-compile
108 (defconst c-awk-escaped-nl "\\\\[\n\r]"))
109;; Matches an escaped newline.
110(defconst c-awk-escaped-nls* (concat "\\(" c-awk-escaped-nl "\\)*"))
111;; Matches a possibly empty sequence of escaped newlines. Used in
112;; awk-font-lock-keywords.
113;; (defconst c-awk-escaped-nls*-with-space*
114;; (concat "\\(" c-awk-escaped-nls* "\\|" "[ \t]+" "\\)*"))
115;; The above RE was very slow. It's runtime was doubling with each additional
116;; space :-( Reformulate it as below:
117(eval-and-compile
118 (defconst c-awk-escaped-nls*-with-space*
119 (concat "\\(" c-awk-escaped-nl "\\|" "[ \t]" "\\)*")))
120;; Matches a possibly empty sequence of escaped newlines with optional
121;; interspersed spaces and tabs. Used in awk-font-lock-keywords.
122(defconst c-awk-blank-or-comment-line-re
123 (concat "[ \t]*\\(#\\|\\\\?$\\)"))
124;; Matche (the tail of) a line containing at most either a comment or an
125;; escaped EOL.
126
127;; REGEXPS FOR "HARMLESS" STRINGS/LINES.
128(defconst c-awk-harmless-char-re "[^_#/\"\\\\\n\r]")
129;; Matches any character but a _, #, /, ", \, or newline. N.B. _" starts a
130;; localisation string in gawk 3.1
131(defconst c-awk-harmless-_ "_\\([^\"]\\|\\'\\)")
132;; Matches an underline NOT followed by ".
133(defconst c-awk-harmless-string*-re
134 (concat "\\(" c-awk-harmless-char-re "\\|" c-awk-esc-pair-re "\\|" c-awk-harmless-_ "\\)*"))
135;; Matches a (possibly empty) sequence of chars without unescaped /, ", \,
136;; #, or newlines.
137(defconst c-awk-harmless-string*-here-re
138 (concat "\\=" c-awk-harmless-string*-re))
139;; Matches the (possibly empty) sequence of chars without unescaped /, ", \,
140;; at point.
141(defconst c-awk-harmless-line-re
142 (concat c-awk-harmless-string*-re
143 "\\(" c-awk-comment-without-nl "\\)?" c-awk-nl-or-eob))
144;; Matches (the tail of) an AWK \"logical\" line not containing an unescaped
145;; " or /. "logical" means "possibly containing escaped newlines". A comment
146;; is matched as part of the line even if it contains a " or a /. The End of
147;; buffer is also an end of line.
148(defconst c-awk-harmless-lines+-here-re
149 (concat "\\=\\(" c-awk-harmless-line-re "\\)+"))
150;; Matches a sequence of (at least one) \"harmless-line\" at point.
151
152
153;; REGEXPS FOR AWK STRINGS.
154(defconst c-awk-string-ch-re "[^\"\\\n\r]")
155;; Matches any character which can appear unescaped in a string.
156(defconst c-awk-string-innards-re
157 (concat "\\(" c-awk-string-ch-re "\\|" c-awk-esc-pair-re "\\)*"))
158;; Matches the inside of an AWK string (i.e. without the enclosing quotes).
159(defconst c-awk-string-without-end-here-re
160 (concat "\\=_?\"" c-awk-string-innards-re))
161;; Matches an AWK string at point up to, but not including, any terminator.
162;; A gawk 3.1+ string may look like _"localisable string".
163(defconst c-awk-one-line-possibly-open-string-re
164 (concat "\"\\(" c-awk-string-ch-re "\\|" c-awk-non-eol-esc-pair-re "\\)*"
165 "\\(\"\\|\\\\?$\\|\\'\\)"))
166
167;; REGEXPS FOR AWK REGEXPS.
168(defconst c-awk-regexp-normal-re "[^[/\\\n\r]")
169;; Matches any AWK regexp character which doesn't require special analysis.
170(defconst c-awk-escaped-newlines*-re "\\(\\\\[\n\r]\\)*")
171;; Matches a (possibly empty) sequence of escaped newlines.
172
173;; NOTE: In what follows, "[asdf]" in a regexp will be called a "character
174;; list", and "[:alpha:]" inside a character list will be known as a
175;; "character class". These terms for these things vary between regexp
176;; descriptions .
177(defconst c-awk-regexp-char-class-re
178 "\\[:[a-z]+:\\]")
179 ;; Matches a character class spec (e.g. [:alpha:]).
180(defconst c-awk-regexp-char-list-re
181 (concat "\\[" c-awk-escaped-newlines*-re "^?" c-awk-escaped-newlines*-re "]?"
182 "\\(" c-awk-esc-pair-re "\\|" c-awk-regexp-char-class-re
183 "\\|" "[^]\n\r]" "\\)*" "\\(]\\|$\\)"))
184;; Matches a regexp char list, up to (but not including) EOL if the ] is
185;; missing.
186(defconst c-awk-regexp-one-line-possibly-open-char-list-re
187 (concat "\\[\\]?\\(" c-awk-non-eol-esc-pair-re "\\|" "[^]\n\r]" "\\)*"
188 "\\(]\\|\\\\?$\\|\\'\\)"))
189;; Matches the head (or all) of a regexp char class, up to (but not
190;; including) the first EOL.
191(defconst c-awk-regexp-innards-re
192 (concat "\\(" c-awk-esc-pair-re "\\|" c-awk-regexp-char-list-re
193 "\\|" c-awk-regexp-normal-re "\\)*"))
194;; Matches the inside of an AWK regexp (i.e. without the enclosing /s)
195(defconst c-awk-regexp-without-end-re
196 (concat "/" c-awk-regexp-innards-re))
197;; Matches an AWK regexp up to, but not including, any terminating /.
198(defconst c-awk-one-line-possibly-open-regexp-re
199 (concat "/\\(" c-awk-non-eol-esc-pair-re
200 "\\|" c-awk-regexp-one-line-possibly-open-char-list-re
201 "\\|" c-awk-regexp-normal-re "\\)*"
202 "\\(/\\|\\\\?$\\|\\'\\)"))
203;; Matches as much of the head of an AWK regexp which fits on one line,
204;; possibly all of it.
205
206;; REGEXPS used for scanning an AWK buffer in order to decide IF A '/' IS A
207;; REGEXP OPENER OR A DIVISION SIGN. By "state" in the following is meant
208;; whether a '/' at the current position would by a regexp opener or a
209;; division sign.
210(defconst c-awk-neutral-re
211; "\\([{}@` \t]\\|\\+\\+\\|--\\|\\\\.\\)+") ; changed, 2003/6/7
212 "\\([{}@` \t]\\|\\+\\+\\|--\\|\\\\.\\)")
213;; A "neutral" char(pair). Doesn't change the "state" of a subsequent /.
214;; This is space/tab, braces, an auto-increment/decrement operator or an
215;; escaped character. Or one of the (illegal) characters @ or `. But NOT an
216;; end of line (even if escaped).
217(defconst c-awk-neutrals*-re
218 (concat "\\(" c-awk-neutral-re "\\)*"))
219;; A (possibly empty) string of neutral characters (or character pairs).
220(defconst c-awk-var-num-ket-re "[]\)0-9a-zA-Z_$.\x80-\xff]+")
221;; Matches a char which is a constituent of a variable or number, or a ket
222;; (i.e. closing bracKET), round or square. Assume that all characters \x80 to
223;; \xff are "letters".
224(defconst c-awk-div-sign-re
225 (concat c-awk-var-num-ket-re c-awk-neutrals*-re "/"))
226;; Will match a piece of AWK buffer ending in / which is a division sign, in
227;; a context where an immediate / would be a regexp bracket. It follows a
228;; variable or number (with optional intervening "neutral" characters). This
229;; will only work when there won't be a preceding " or / before the sought /
230;; to foul things up.
231(defconst c-awk-non-arith-op-bra-re
232 "[[\(&=:!><,?;'~|]")
233;; Matches an openeing BRAcket ,round or square, or any operator character
234;; apart from +,-,/,*,%. For the purpose at hand (detecting a / which is a
235;; regexp bracket) these arith ops are unnecessary and a pain, because of "++"
236;; and "--".
237(defconst c-awk-regexp-sign-re
238 (concat c-awk-non-arith-op-bra-re c-awk-neutrals*-re "/"))
239;; Will match a piece of AWK buffer ending in / which is an opening regexp
240;; bracket, in a context where an immediate / would be a division sign. This
241;; will only work when there won't be a preceding " or / before the sought /
242;; to foul things up.
243
244;; REGEXPS USED FOR FINDING THE POSITION OF A "virtual semicolon"
245(defconst c-awk-_-harmless-nonws-char-re "[^#/\"\\\\\n\r \t]")
246;;;; NEW VERSION! (which will be restricted to the current line)
247(defconst c-awk-one-line-non-syn-ws*-re
248 (concat "\\([ \t]*"
249 "\\(" c-awk-_-harmless-nonws-char-re "\\|"
250 c-awk-non-eol-esc-pair-re "\\|"
251 c-awk-one-line-possibly-open-string-re "\\|"
252 c-awk-one-line-possibly-open-regexp-re
253 "\\)"
254 "\\)*"))
255
256
88;; ACM, 2002/5/29: 257;; ACM, 2002/5/29:
89;; 258;;
90;; The next section of code is about determining whether or not an AWK 259;; The next section of code is about determining whether or not an AWK
91;; statement is complete or not. We use this to indent the following line. 260;; statement is complete or not. We use this to indent the following line.
92;; The determination is pretty straightforward in C, where a statement ends 261;; The determination is pretty straightforward in C, where a statement ends
@@ -107,6 +276,9 @@
107;; after-change function) must be constantly updated for the mode to work 276;; after-change function) must be constantly updated for the mode to work
108;; properly). 277;; properly).
109;; 278;;
279;; This text property is also used for "syntactic whitespace" movement, this
280;; being where the distinction between the values '$' and '}' is significant.
281;;
110;; The valid values for c-awk-NL-prop are: 282;; The valid values for c-awk-NL-prop are:
111;; 283;;
112;; nil The property is not currently set for this line. 284;; nil The property is not currently set for this line.
@@ -121,11 +293,12 @@
121;; essential to the syntax of the program. (i.e. if it had been a 293;; essential to the syntax of the program. (i.e. if it had been a
122;; frivolous \, it would have been ignored and the line been given one of 294;; frivolous \, it would have been ignored and the line been given one of
123;; the other property values.) 295;; the other property values.)
124;; ';' A statement is completed as the last thing (aside from ws) on the line - 296;; '$' A non-empty statement is terminated on the line by an EOL (a "virtual
125;; i.e. there is (at least part of) a statement on this line, and the last 297;; semicolon"). This might be a content-free line terminating a statement
126;; statement on the line is complete, OR (2002/10/25) the line is 298;; from the preceding (continued) line (which has property \).
127;; content-free but terminates a statement from the preceding (continued) 299;; '}' A statement, being the last thing (aside from ws/comments) is
128;; line (which has property \). 300;; explicitly terminated on this line by a closing brace (or sometimes a
301;; semicolon).
129;; 302;;
130;; This set of values has been chosen so that the property's value on a line 303;; This set of values has been chosen so that the property's value on a line
131;; is completely determined by the contents of the line and the property on 304;; is completely determined by the contents of the line and the property on
@@ -141,6 +314,8 @@
141 ;; 314 ;;
142 ;; DO-LIM sets a limit on how far back we search for the "do" of a possible 315 ;; DO-LIM sets a limit on how far back we search for the "do" of a possible
143 ;; do-while. 316 ;; do-while.
317 ;;
318 ;; This function might do hidden buffer changes.
144 (and 319 (and
145 (eq (char-before) ?\)) 320 (eq (char-before) ?\))
146 (save-excursion 321 (save-excursion
@@ -155,6 +330,8 @@
155 330
156(defun c-awk-after-function-decl-param-list () 331(defun c-awk-after-function-decl-param-list ()
157 ;; Are we just after the ) in "function foo (bar)" ? 332 ;; Are we just after the ) in "function foo (bar)" ?
333 ;;
334 ;; This function might do hidden buffer changes.
158 (and (eq (char-before) ?\)) 335 (and (eq (char-before) ?\))
159 (save-excursion 336 (save-excursion
160 (let ((par-pos (c-safe (scan-lists (point) -1 0)))) 337 (let ((par-pos (c-safe (scan-lists (point) -1 0))))
@@ -169,6 +346,8 @@
169(defun c-awk-after-continue-token () 346(defun c-awk-after-continue-token ()
170;; Are we just after a token which can be continued onto the next line without 347;; Are we just after a token which can be continued onto the next line without
171;; a backslash? 348;; a backslash?
349;;
350;; This function might do hidden buffer changes.
172 (save-excursion 351 (save-excursion
173 (c-backward-token-1) ; FIXME 2002/10/27. What if this fails? 352 (c-backward-token-1) ; FIXME 2002/10/27. What if this fails?
174 (if (and (looking-at "[&|]") (not (bobp))) 353 (if (and (looking-at "[&|]") (not (bobp)))
@@ -178,6 +357,8 @@
178(defun c-awk-after-rbrace-or-statement-semicolon () 357(defun c-awk-after-rbrace-or-statement-semicolon ()
179 ;; Are we just after a } or a ; which closes a statement? 358 ;; Are we just after a } or a ; which closes a statement?
180 ;; Be careful about ;s in for loop control bits. They don't count! 359 ;; Be careful about ;s in for loop control bits. They don't count!
360 ;;
361 ;; This function might do hidden buffer changes.
181 (or (eq (char-before) ?\}) 362 (or (eq (char-before) ?\})
182 (and 363 (and
183 (eq (char-before) ?\;) 364 (eq (char-before) ?\;)
@@ -193,17 +374,19 @@
193 ;; Move back to just after the first found of either (i) an EOL which has 374 ;; Move back to just after the first found of either (i) an EOL which has
194 ;; the c-awk-NL-prop text-property set; or (ii) non-ws text; or (iii) BOB. 375 ;; the c-awk-NL-prop text-property set; or (ii) non-ws text; or (iii) BOB.
195 ;; We return either the value of c-awk-NL-prop (in case (i)) or nil. 376 ;; We return either the value of c-awk-NL-prop (in case (i)) or nil.
196 ;; Calling function can best distinguish cases (ii) and (iii) with (bolp). 377 ;; Calling functions can best distinguish cases (ii) and (iii) with (bolp).
197 ;; 378 ;;
198 ;; Note that an escaped eol counts as whitespace here. 379 ;; Note that an escaped eol counts as whitespace here.
199 ;; 380 ;;
200 ;; Kludge: If c-backward-syntactic-ws gets stuck at a BOL, it is likely 381 ;; Kludge: If c-backward-syntactic-ws gets stuck at a BOL, it is likely
201 ;; that the previous line contains an unterminated string (without \). In 382 ;; that the previous line contains an unterminated string (without \). In
202 ;; this case, assume that the previous line's c-awk-NL-prop is a ;. 383 ;; this case, assume that the previous line's c-awk-NL-prop is a $.
203 ;; 384 ;;
204 ;; POINT MUST BE AT THE START OF A LINE when calling this function. This 385 ;; POINT MUST BE AT THE START OF A LINE when calling this function. This
205 ;; is to ensure that the various backward-comment functions will work 386 ;; is to ensure that the various backward-comment functions will work
206 ;; properly. 387 ;; properly.
388 ;;
389 ;; This function might do hidden buffer changes.
207 (let ((nl-prop nil) 390 (let ((nl-prop nil)
208 bol-pos bsws-pos) ; starting pos for a backward-syntactic-ws call. 391 bol-pos bsws-pos) ; starting pos for a backward-syntactic-ws call.
209 (while ;; We are at a BOL here. Go back one line each iteration. 392 (while ;; We are at a BOL here. Go back one line each iteration.
@@ -214,9 +397,12 @@
214 (setq bsws-pos (point)) 397 (setq bsws-pos (point))
215 ;; N.B. the following function will not go back past an EOL if 398 ;; N.B. the following function will not go back past an EOL if
216 ;; there is an open string (without \) on the previous line. 399 ;; there is an open string (without \) on the previous line.
400 ;; If we find such, set the c-awk-NL-prop on it, too
401 ;; (2004/3/29).
217 (c-backward-syntactic-ws bol-pos) 402 (c-backward-syntactic-ws bol-pos)
218 (or (/= (point) bsws-pos) 403 (or (/= (point) bsws-pos)
219 (progn (setq nl-prop ?\;) 404 (progn (setq nl-prop ?\$)
405 (c-put-char-property (1- (point)) 'c-awk-NL-prop nl-prop)
220 nil))) 406 nil)))
221 ;; If we had a backslash at EOL, c-backward-syntactic-ws will 407 ;; If we had a backslash at EOL, c-backward-syntactic-ws will
222 ;; have gone backwards over it. Check the backslash was "real". 408 ;; have gone backwards over it. Check the backslash was "real".
@@ -238,14 +424,16 @@
238 ;; Calculate and set the value of the c-awk-NL-prop on the immediately 424 ;; Calculate and set the value of the c-awk-NL-prop on the immediately
239 ;; preceding EOL. This may also involve doing the same for several 425 ;; preceding EOL. This may also involve doing the same for several
240 ;; preceding EOLs. 426 ;; preceding EOLs.
241 ;; 427 ;;
242 ;; NOTE that if the property was already set, we return it without 428 ;; NOTE that if the property was already set, we return it without
243 ;; recalculation. (This is by accident rather than design.) 429 ;; recalculation. (This is by accident rather than design.)
244 ;; 430 ;;
245 ;; Return the property which got set (or was already set) on the previous 431 ;; Return the property which got set (or was already set) on the previous
246 ;; line. Return nil if we hit BOB. 432 ;; line. Return nil if we hit BOB.
247 ;; 433 ;;
248 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. 434 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM.
435 ;;
436 ;; This function might do hidden buffer changes.
249 (save-excursion 437 (save-excursion
250 (save-match-data 438 (save-match-data
251 (beginning-of-line) 439 (beginning-of-line)
@@ -267,7 +455,9 @@
267 ((and (looking-at "[ \t]*\\\\$") 455 ((and (looking-at "[ \t]*\\\\$")
268 (not (c-awk-after-rbrace-or-statement-semicolon))) 456 (not (c-awk-after-rbrace-or-statement-semicolon)))
269 ?\\) 457 ?\\)
270 (t ?\;))) ; A statement was completed on this line 458 ;; A statement was completed on this line. How?
459 ((memq (char-before) '(?\; ?\})) ?\}) ; Real ; or }
460 (t ?\$))) ; A virtual semicolon.
271 (end-of-line) 461 (end-of-line)
272 (c-put-char-property (point) 'c-awk-NL-prop nl-prop) 462 (c-put-char-property (point) 'c-awk-NL-prop nl-prop)
273 (forward-line)) 463 (forward-line))
@@ -276,9 +466,9 @@
276 ;; Set c-awk-NL-prop on each of these lines's EOL. 466 ;; Set c-awk-NL-prop on each of these lines's EOL.
277 (while (< (point) pos) ; one content-free line each iteration. 467 (while (< (point) pos) ; one content-free line each iteration.
278 (cond ; recalculate nl-prop from previous line's value. 468 (cond ; recalculate nl-prop from previous line's value.
279 ((memq nl-prop '(?\; nil)) (setq nl-prop ?\#)) 469 ((memq nl-prop '(?\} ?\$ nil)) (setq nl-prop ?\#))
280 ((eq nl-prop ?\\) 470 ((eq nl-prop ?\\)
281 (if (not (looking-at "[ \t]*\\\\$")) (setq nl-prop ?\;))) ; was ?\# 2002/10/25 471 (if (not (looking-at "[ \t]*\\\\$")) (setq nl-prop ?\$)))
282 ;; ?\# (empty line) and ?\{ (open stmt) don't change. 472 ;; ?\# (empty line) and ?\{ (open stmt) don't change.
283 ) 473 )
284 (forward-line) 474 (forward-line)
@@ -289,6 +479,8 @@
289 ;; Get the c-awk-NL-prop text-property from the previous line, calculating 479 ;; Get the c-awk-NL-prop text-property from the previous line, calculating
290 ;; it if necessary. Return nil iff we're already at BOB. 480 ;; it if necessary. Return nil iff we're already at BOB.
291 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. 481 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM.
482 ;;
483 ;; This function might do hidden buffer changes.
292 (if (bobp) 484 (if (bobp)
293 nil 485 nil
294 (or (c-get-char-property (c-point 'eopl) 'c-awk-NL-prop) 486 (or (c-get-char-property (c-point 'eopl) 'c-awk-NL-prop)
@@ -299,8 +491,10 @@
299 ;; if necessary. (As a special case, the property doesn't get set on an 491 ;; if necessary. (As a special case, the property doesn't get set on an
300 ;; empty line at EOB (there's no position to set the property on), but the 492 ;; empty line at EOB (there's no position to set the property on), but the
301 ;; function returns the property value an EOL would have got.) 493 ;; function returns the property value an EOL would have got.)
302 ;; 494 ;;
303 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. 495 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM.
496 ;;
497 ;; This function might do hidden buffer changes.
304 (save-excursion 498 (save-excursion
305 (let ((extra-nl nil)) 499 (let ((extra-nl nil))
306 (end-of-line) ; Necessary for the following test to work. 500 (end-of-line) ; Necessary for the following test to work.
@@ -310,67 +504,49 @@
310 (prog1 (c-awk-get-NL-prop-prev-line do-lim) 504 (prog1 (c-awk-get-NL-prop-prev-line do-lim)
311 (if extra-nl (delete-backward-char 1)))))) 505 (if extra-nl (delete-backward-char 1))))))
312 506
313(defun c-awk-prev-line-incomplete-p (&optional do-lim) 507(defsubst c-awk-prev-line-incomplete-p (&optional do-lim)
314 ;; Is there an incomplete statement at the end of the previous line? 508 ;; Is there an incomplete statement at the end of the previous line?
315 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. 509 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM.
510 ;;
511 ;; This function might do hidden buffer changes.
316 (memq (c-awk-get-NL-prop-prev-line do-lim) '(?\\ ?\{))) 512 (memq (c-awk-get-NL-prop-prev-line do-lim) '(?\\ ?\{)))
317 513
318(defun c-awk-cur-line-incomplete-p (&optional do-lim) 514(defsubst c-awk-cur-line-incomplete-p (&optional do-lim)
319 ;; Is there an incomplete statement at the end of the current line? 515 ;; Is there an incomplete statement at the end of the current line?
320 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. 516 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM.
517 ;;
518 ;; This function might do hidden buffer changes.
321 (memq (c-awk-get-NL-prop-cur-line do-lim) '(?\\ ?\{))) 519 (memq (c-awk-get-NL-prop-cur-line do-lim) '(?\\ ?\{)))
322 520
323(defun c-awk-completed-stmt-ws-ends-prev-line-p (&optional do-lim) 521;;;; NOTES ON "VIRTUAL SEMICOLONS"
324 ;; Is there a termination of a statement as the last thing (apart from an 522;;;;
325 ;; optional comment) on the previous line? 523;;;; A "virtual semicolon" is what terminates a statement when there is no ;
326 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. 524;;;; or } to do the job. Like point, it is considered to lie _between_ two
327 (eq (c-awk-get-NL-prop-prev-line do-lim) ?\;)) 525;;;; characters. As from mid-March 2004, it is considered to lie just after
328 526;;;; the last non-syntactic-whitespace character on the line; (previously, it
329(defun c-awk-completed-stmt-ws-ends-line-p (&optional pos do-lim) 527;;;; was considered an attribute of the EOL on the line). A real semicolon
330 ;; Same as previous function, but for the line containing position POS (or 528;;;; never counts as a virtual one.
331 ;; the current line if POS is omitted). 529
332 ;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. 530(defun c-awk-at-vsemi-p (&optional pos)
531 ;; Is there a virtual semicolon at POS (or POINT)?
333 (save-excursion 532 (save-excursion
334 (if pos (goto-char pos)) 533 (let (nl-prop
335 (eq (c-awk-get-NL-prop-cur-line do-lim) ?\;))) 534 (pos-or-point (progn (if pos (goto-char pos)) (point))))
336 535 (forward-line 0)
337(defun c-awk-after-logical-semicolon (&optional do-lim) 536 (search-forward-regexp c-awk-one-line-non-syn-ws*-re)
338;; Are we at BOL, the preceding EOL being a "logical semicolon"? 537 (and (eq (point) pos-or-point)
339;; See c-awk-after-if-for-while-condition-p for a description of DO-LIM. 538 (progn
340 (and (bolp) 539 (while (and (eq (setq nl-prop (c-awk-get-NL-prop-cur-line)) ?\\)
341 (eq (c-awk-get-NL-prop-prev-line do-lim) ?\;))) 540 (eq (forward-line) 0)
342 541 (looking-at c-awk-blank-or-comment-line-re)))
343(defun c-awk-backward-syntactic-ws (&optional lim) 542 (eq nl-prop ?\$))))))
344;; Skip backwards over awk-syntactic whitespace. This is whitespace 543
345;; characters, comments, and NEWLINES WHICH AREN'T "VIRTUAL SEMICOLONS". For 544(defun c-awk-vsemi-status-unknown-p ()
346;; this function, a newline isn't a "virtual semicolon" if that line ends with 545 ;; Are we unsure whether there is a virtual semicolon on the current line?
347;; a real semicolon (or closing brace). 546 ;; DO NOT under any circumstances attempt to calculate this; that would
348;; However if point starts inside a comment or preprocessor directive, the 547 ;; defeat the (admittedly kludgey) purpose of this function, which is to
349;; content of it is not treated as whitespace. LIM (optional) sets a limit on 548 ;; prevent an infinite recursion in c-beginning-of-statement-1 when point
350;; the backward movement. 549 ;; starts at a `while' token.
351 (let ((lim (or lim (point-min)))
352 after-real-br)
353 (c-backward-syntactic-ws (max lim (c-point 'bol)))
354 (while ; go back one WS line each time round this loop.
355 (and (bolp)
356 (> (point) lim)
357 (/= (c-awk-get-NL-prop-prev-line) ?\;)
358 (/= (point)
359 ;; The following function requires point at BONL [not EOL] to
360 ;; recognise a preceding comment,.
361 (progn (c-backward-syntactic-ws (max lim (c-point 'bopl)))
362 (point)))))
363 ;; Does the previous line end with a real ; or }? If so, go back to it.
364 (if (and (bolp)
365 (eq (c-awk-get-NL-prop-prev-line) ?\;)
366 (save-excursion
367 (c-backward-syntactic-ws (max lim (c-point 'bopl)))
368 (setq after-real-br (point))
369 (c-awk-after-rbrace-or-statement-semicolon)))
370 (goto-char after-real-br))))
371
372(defun c-awk-NL-prop-not-set ()
373 ;; Is the NL-prop on the current line either nil or unset?
374 (not (c-get-char-property (c-point 'eol) 'c-awk-NL-prop))) 550 (not (c-get-char-property (c-point 'eol) 'c-awk-NL-prop)))
375 551
376(defun c-awk-clear-NL-props (beg end) 552(defun c-awk-clear-NL-props (beg end)
@@ -378,6 +554,8 @@
378 ;; c-awk-NL-prop text property from beg to the end of the buffer (The END 554 ;; c-awk-NL-prop text property from beg to the end of the buffer (The END
379 ;; parameter is ignored). This ensures that the indentation engine will 555 ;; parameter is ignored). This ensures that the indentation engine will
380 ;; never use stale values for this property. 556 ;; never use stale values for this property.
557 ;;
558 ;; This function might do hidden buffer changes.
381 (save-restriction 559 (save-restriction
382 (widen) 560 (widen)
383 (c-clear-char-properties beg (point-max) 'c-awk-NL-prop))) 561 (c-clear-char-properties beg (point-max) 'c-awk-NL-prop)))
@@ -409,7 +587,7 @@
409;awk-mode-map isn't yet defined. :-( 587;awk-mode-map isn't yet defined. :-(
410 588
411;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 589;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
412 590
413;; The following section of the code is to do with font-locking. The biggest 591;; The following section of the code is to do with font-locking. The biggest
414;; problem for font-locking is deciding whether a / is a regular expression 592;; problem for font-locking is deciding whether a / is a regular expression
415;; delimiter or a division sign - determining precisely where strings and 593;; delimiter or a division sign - determining precisely where strings and
@@ -432,10 +610,12 @@
432;; Go back to the start of the (apparent) current line (or the start of the 610;; Go back to the start of the (apparent) current line (or the start of the
433;; line containing POS), returning the buffer position of that point. I.e., 611;; line containing POS), returning the buffer position of that point. I.e.,
434;; go back to the last line which doesn't have an escaped EOL before it. 612;; go back to the last line which doesn't have an escaped EOL before it.
435;; 613;;
436;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any 614;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any
437;; comment, string or regexp. IT MAY WELL BE that this function should not be 615;; comment, string or regexp. IT MAY WELL BE that this function should not be
438;; executed on a narrowed buffer. 616;; executed on a narrowed buffer.
617;;
618;; This function might do hidden buffer changes.
439 (if pos (goto-char pos)) 619 (if pos (goto-char pos))
440 (forward-line 0) 620 (forward-line 0)
441 (while (and (> (point) (point-min)) 621 (while (and (> (point) (point-min))
@@ -451,6 +631,8 @@
451;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any 631;; This is guaranteed to be "safe" for syntactic analysis, i.e. outwith any
452;; comment, string or regexp. IT MAY WELL BE that this function should not be 632;; comment, string or regexp. IT MAY WELL BE that this function should not be
453;; executed on a narrowed buffer. 633;; executed on a narrowed buffer.
634;;
635;; This function might do hidden buffer changes.
454 (if pos (goto-char pos)) 636 (if pos (goto-char pos))
455 (end-of-line) 637 (end-of-line)
456 (while (and (< (point) (point-max)) 638 (while (and (< (point) (point-max))
@@ -458,135 +640,6 @@
458 (end-of-line 2)) 640 (end-of-line 2))
459 (point)) 641 (point))
460 642
461;; N.B. In the following regexps, an EOL is either \n OR \r. This is because
462;; Emacs has in the past used \r to mark hidden lines in some fashion (and
463;; maybe still does).
464
465(defconst c-awk-esc-pair-re "\\\\\\(.\\|\n\\|\r\\|\\'\\)")
466;; Matches any escaped (with \) character-pair, including an escaped newline.
467(defconst c-awk-comment-without-nl "#.*")
468;; Matches an AWK comment, not including the terminating NL (if any). Note
469;; that the "enclosing" (elisp) regexp must ensure the # is real.
470(defconst c-awk-nl-or-eob "\\(\n\\|\r\\|\\'\\)")
471;; Matches a newline, or the end of buffer.
472
473;; "Space" regular expressions.
474(defconst c-awk-escaped-nl "\\\\[\n\r]")
475;; Matches an escaped newline.
476(defconst c-awk-escaped-nls* (concat "\\(" c-awk-escaped-nl "\\)*"))
477;; Matches a possibly empty sequence of escaped newlines. Used in
478;; awk-font-lock-keywords.
479;; (defconst c-awk-escaped-nls*-with-space*
480;; (concat "\\(" c-awk-escaped-nls* "\\|" "[ \t]+" "\\)*"))
481;; The above RE was very slow. It's runtime was doubling with each additional
482;; space :-( Reformulate it as below:
483(defconst c-awk-escaped-nls*-with-space*
484 (concat "\\(" c-awk-escaped-nl "\\|" "[ \t]" "\\)*"))
485;; Matches a possibly empty sequence of escaped newlines with optional
486;; interspersed spaces and tabs. Used in awk-font-lock-keywords.
487
488;; REGEXPS FOR "HARMLESS" STRINGS/LINES.
489(defconst c-awk-harmless-char-re "[^_#/\"\\\\\n\r]")
490;; Matches any character but a _, #, /, ", \, or newline. N.B. _" starts a
491;; localisation string in gawk 3.1
492(defconst c-awk-harmless-_ "_\\([^\"]\\|\\'\\)")
493;; Matches an underline NOT followed by ".
494(defconst c-awk-harmless-string*-re
495 (concat "\\(" c-awk-harmless-char-re "\\|" c-awk-esc-pair-re "\\|" c-awk-harmless-_ "\\)*"))
496;; Matches a (possibly empty) sequence of chars without unescaped /, ", \,
497;; #, or newlines.
498(defconst c-awk-harmless-string*-here-re
499 (concat "\\=" c-awk-harmless-string*-re))
500;; Matches the (possibly empty) sequence of chars without unescaped /, ", \,
501;; at point.
502(defconst c-awk-harmless-line-re
503 (concat c-awk-harmless-string*-re
504 "\\(" c-awk-comment-without-nl "\\)?" c-awk-nl-or-eob))
505;; Matches (the tail of) an AWK \"logical\" line not containing an unescaped
506;; " or /. "logical" means "possibly containing escaped newlines". A comment
507;; is matched as part of the line even if it contains a " or a /. The End of
508;; buffer is also an end of line.
509(defconst c-awk-harmless-lines+-here-re
510 (concat "\\=\\(" c-awk-harmless-line-re "\\)+"))
511;; Matches a sequence of (at least one) \"harmless-line\" at point.
512
513
514;; REGEXPS FOR AWK STRINGS.
515(defconst c-awk-string-ch-re "[^\"\\\n\r]")
516;; Matches any character which can appear unescaped in a string.
517(defconst c-awk-string-innards-re
518 (concat "\\(" c-awk-string-ch-re "\\|" c-awk-esc-pair-re "\\)*"))
519;; Matches the inside of an AWK string (i.e. without the enclosing quotes).
520(defconst c-awk-string-without-end-here-re
521 (concat "\\=_?\"" c-awk-string-innards-re))
522;; Matches an AWK string at point up to, but not including, any terminator.
523;; A gawk 3.1+ string may look like _"localisable string".
524
525;; REGEXPS FOR AWK REGEXPS.
526(defconst c-awk-regexp-normal-re "[^[/\\\n\r]")
527;; Matches any AWK regexp character which doesn't require special analysis.
528(defconst c-awk-escaped-newlines*-re "\\(\\\\[\n\r]\\)*")
529;; Matches a (possibly empty) sequence of escaped newlines.
530
531;; NOTE: In what follows, "[asdf]" in a regexp will be called a "character
532;; list", and "[:alpha:]" inside a character list will be known as a
533;; "character class". These terms for these things vary between regexp
534;; descriptions .
535(defconst c-awk-regexp-char-class-re
536 "\\[:[a-z]+:\\]")
537 ;; Matches a character class spec (e.g. [:alpha:]).
538(defconst c-awk-regexp-char-list-re
539 (concat "\\[" c-awk-escaped-newlines*-re "^?" c-awk-escaped-newlines*-re "]?"
540 "\\(" c-awk-esc-pair-re "\\|" c-awk-regexp-char-class-re
541 "\\|" "[^]\n\r]" "\\)*" "\\(]\\|$\\)"))
542;; Matches a regexp char list, up to (but not including) EOL if the ] is
543;; missing.
544(defconst c-awk-regexp-innards-re
545 (concat "\\(" c-awk-esc-pair-re "\\|" c-awk-regexp-char-list-re
546 "\\|" c-awk-regexp-normal-re "\\)*"))
547;; Matches the inside of an AWK regexp (i.e. without the enclosing /s)
548(defconst c-awk-regexp-without-end-re
549 (concat "/" c-awk-regexp-innards-re))
550;; Matches an AWK regexp up to, but not including, any terminating /.
551
552;; REGEXPS used for scanning an AWK buffer in order to decide IF A '/' IS A
553;; REGEXP OPENER OR A DIVISION SIGN. By "state" in the following is meant
554;; whether a '/' at the current position would by a regexp opener or a
555;; division sign.
556(defconst c-awk-neutral-re
557; "\\([{}@` \t]\\|\\+\\+\\|--\\|\\\\.\\)+") ; changed, 2003/6/7
558 "\\([{}@` \t]\\|\\+\\+\\|--\\|\\\\.\\)")
559;; A "neutral" char(pair). Doesn't change the "state" of a subsequent /.
560;; This is space/tab, braces, an auto-increment/decrement operator or an
561;; escaped character. Or one of the (illegal) characters @ or `. But NOT an
562;; end of line (even if escaped).
563(defconst c-awk-neutrals*-re
564 (concat "\\(" c-awk-neutral-re "\\)*"))
565;; A (possibly empty) string of neutral characters (or character pairs).
566(defconst c-awk-var-num-ket-re "[]\)0-9a-zA-Z_$.\x80-\xff]+")
567;; Matches a char which is a constituent of a variable or number, or a ket
568;; (i.e. closing bracKET), round or square. Assume that all characters \x80 to
569;; \xff are "letters".
570(defconst c-awk-div-sign-re
571 (concat c-awk-var-num-ket-re c-awk-neutrals*-re "/"))
572;; Will match a piece of AWK buffer ending in / which is a division sign, in
573;; a context where an immediate / would be a regexp bracket. It follows a
574;; variable or number (with optional intervening "neutral" characters). This
575;; will only work when there won't be a preceding " or / before the sought /
576;; to foul things up.
577(defconst c-awk-non-arith-op-bra-re
578 "[[\(&=:!><,?;'~|]")
579;; Matches an openeing BRAcket ,round or square, or any operator character
580;; apart from +,-,/,*,%. For the purpose at hand (detecting a / which is a
581;; regexp bracket) these arith ops are unnecessary and a pain, because of "++"
582;; and "--".
583(defconst c-awk-regexp-sign-re
584 (concat c-awk-non-arith-op-bra-re c-awk-neutrals*-re "/"))
585;; Will match a piece of AWK buffer ending in / which is an opening regexp
586;; bracket, in a context where an immediate / would be a division sign. This
587;; will only work when there won't be a preceding " or / before the sought /
588;; to foul things up.
589
590;; ACM, 2002/02/15: The idea of the next function is to put the "Error font" 643;; ACM, 2002/02/15: The idea of the next function is to put the "Error font"
591;; on strings/regexps which are missing their closing delimiter. 644;; on strings/regexps which are missing their closing delimiter.
592;; 2002/4/28. The default syntax for / has been changed from "string" to 645;; 2002/4/28. The default syntax for / has been changed from "string" to
@@ -605,24 +658,26 @@
605;; 658;;
606;; If the closing delimiter is missing (i.e., there is an EOL there) set the 659;; If the closing delimiter is missing (i.e., there is an EOL there) set the
607;; STRING-FENCE property on the opening " or / and closing EOL. 660;; STRING-FENCE property on the opening " or / and closing EOL.
661;;
662;; This function does hidden buffer changes.
608 (if (eq (char-after beg) ?_) (setq beg (1+ beg))) 663 (if (eq (char-after beg) ?_) (setq beg (1+ beg)))
609 664
610 ;; First put the properties on the delimiters. 665 ;; First put the properties on the delimiters.
611 (cond ((eq end (point-max)) ; string/regexp terminated by EOB 666 (cond ((eq end (point-max)) ; string/regexp terminated by EOB
612 (put-text-property beg (1+ beg) 'syntax-table '(15))) ; (15) = "string fence" 667 (c-put-char-property beg 'syntax-table '(15))) ; (15) = "string fence"
613 ((/= (char-after beg) (char-after end)) ; missing end delimiter 668 ((/= (char-after beg) (char-after end)) ; missing end delimiter
614 (put-text-property beg (1+ beg) 'syntax-table '(15)) 669 (c-put-char-property beg 'syntax-table '(15))
615 (put-text-property end (1+ end) 'syntax-table '(15))) 670 (c-put-char-property end 'syntax-table '(15)))
616 ((eq (char-after beg) ?/) ; Properly bracketed regexp 671 ((eq (char-after beg) ?/) ; Properly bracketed regexp
617 (put-text-property beg (1+ beg) 'syntax-table '(7)) ; (7) = "string" 672 (c-put-char-property beg 'syntax-table '(7)) ; (7) = "string"
618 (put-text-property end (1+ end) 'syntax-table '(7))) 673 (c-put-char-property end 'syntax-table '(7)))
619 (t)) ; Properly bracketed string: Nothing to do. 674 (t)) ; Properly bracketed string: Nothing to do.
620 ;; Now change the properties of any escaped "s in the string to punctuation. 675 ;; Now change the properties of any escaped "s in the string to punctuation.
621 (save-excursion 676 (save-excursion
622 (goto-char (1+ beg)) 677 (goto-char (1+ beg))
623 (or (eobp) 678 (or (eobp)
624 (while (search-forward "\"" end t) 679 (while (search-forward "\"" end t)
625 (put-text-property (1- (point)) (point) 'syntax-table '(1)))))) 680 (c-put-char-property (1- (point)) 'syntax-table '(1))))))
626 681
627(defun c-awk-syntax-tablify-string () 682(defun c-awk-syntax-tablify-string ()
628 ;; Point is at the opening " or _" of a string. Set the syntax-table 683 ;; Point is at the opening " or _" of a string. Set the syntax-table
@@ -630,6 +685,8 @@
630 ;; 685 ;;
631 ;; The result is nil if a / immediately after the string would be a regexp 686 ;; The result is nil if a / immediately after the string would be a regexp
632 ;; opener, t if it would be a division sign. 687 ;; opener, t if it would be a division sign.
688 ;;
689 ;; This function does hidden buffer changes.
633 (search-forward-regexp c-awk-string-without-end-here-re nil t) ; a (possibly unterminated) string 690 (search-forward-regexp c-awk-string-without-end-here-re nil t) ; a (possibly unterminated) string
634 (c-awk-set-string-regexp-syntax-table-properties 691 (c-awk-set-string-regexp-syntax-table-properties
635 (match-beginning 0) (match-end 0)) 692 (match-beginning 0) (match-end 0))
@@ -653,6 +710,8 @@
653 ;; point is. 710 ;; point is.
654 ;; 711 ;;
655 ;; The result is what ANCHOR-STATE-/DIV (see above) is where point is left. 712 ;; The result is what ANCHOR-STATE-/DIV (see above) is where point is left.
713 ;;
714 ;; This function might do hidden buffer changes.
656 (let ((/point (point))) 715 (let ((/point (point)))
657 (goto-char anchor) 716 (goto-char anchor)
658 ;; Analyse the line to find out what the / is. 717 ;; Analyse the line to find out what the / is.
@@ -698,14 +757,18 @@
698;; given the property "punctuation". This will later allow other routines 757;; given the property "punctuation". This will later allow other routines
699;; to use the regexp "\\S\"*" to skip over the string innards. 758;; to use the regexp "\\S\"*" to skip over the string innards.
700;; (iv) Inside a comment, all syntax-table properties are cleared. 759;; (iv) Inside a comment, all syntax-table properties are cleared.
760;;
761;; This function does hidden buffer changes.
701 (let (anchor 762 (let (anchor
702 (anchor-state-/div nil)) ; t means a following / would be a div sign. 763 (anchor-state-/div nil)) ; t means a following / would be a div sign.
703 (c-awk-beginning-of-logical-line) ; ACM 2002/7/21. This is probably redundant. 764 (c-awk-beginning-of-logical-line) ; ACM 2002/7/21. This is probably redundant.
704 (put-text-property (point) lim 'syntax-table nil) 765 (c-clear-char-properties (point) lim 'syntax-table)
705 (search-forward-regexp c-awk-harmless-lines+-here-re nil t) ; skip harmless lines.
706
707 ;; Once round the next loop for each string, regexp, or div sign 766 ;; Once round the next loop for each string, regexp, or div sign
708 (while (< (point) lim) 767 (while (progn
768 ;; Skip any "harmless" lines before the next tricky one.
769 (if (search-forward-regexp c-awk-harmless-lines+-here-re nil t)
770 (setq anchor-state-/div nil))
771 (< (point) lim))
709 (setq anchor (point)) 772 (setq anchor (point))
710 (search-forward-regexp c-awk-harmless-string*-here-re nil t) 773 (search-forward-regexp c-awk-harmless-string*-here-re nil t)
711 ;; We are now looking at either a " or a /. 774 ;; We are now looking at either a " or a /.
@@ -713,11 +776,7 @@
713 (setq anchor-state-/div 776 (setq anchor-state-/div
714 (if (looking-at "_?\"") 777 (if (looking-at "_?\"")
715 (c-awk-syntax-tablify-string) 778 (c-awk-syntax-tablify-string)
716 (c-awk-syntax-tablify-/ anchor anchor-state-/div))) 779 (c-awk-syntax-tablify-/ anchor anchor-state-/div))))
717
718 ;; Skip any further "harmless" lines before the next tricky one.
719 (if (search-forward-regexp c-awk-harmless-lines+-here-re nil t)
720 (setq anchor-state-/div nil)))
721 nil)) 780 nil))
722 781
723 782
@@ -734,6 +793,8 @@
734;; This function is called exclusively from the before-change-functions hook. 793;; This function is called exclusively from the before-change-functions hook.
735;; It does two things: Finds the end of the (logical) line on which END lies, 794;; It does two things: Finds the end of the (logical) line on which END lies,
736;; and clears c-awk-NL-prop text properties from this point onwards. 795;; and clears c-awk-NL-prop text properties from this point onwards.
796;;
797;; This function might do hidden buffer changes.
737 (save-restriction 798 (save-restriction
738 (save-excursion 799 (save-excursion
739 (setq c-awk-old-EOLL (c-awk-end-of-logical-line end)) 800 (setq c-awk-old-EOLL (c-awk-end-of-logical-line end))
@@ -745,6 +806,8 @@
745 ;; This is the end of the logical line on which the change happened, either 806 ;; This is the end of the logical line on which the change happened, either
746 ;; as it was before the change, or as it is now, which ever is later. 807 ;; as it was before the change, or as it is now, which ever is later.
747 ;; N.B. point is left undefined. 808 ;; N.B. point is left undefined.
809 ;;
810 ;; This function might do hidden buffer changes.
748 (max (+ (- c-awk-old-EOLL old-len) (- end beg)) 811 (max (+ (- c-awk-old-EOLL old-len) (- end beg))
749 (c-awk-end-of-logical-line end))) 812 (c-awk-end-of-logical-line end)))
750 813
@@ -754,6 +817,8 @@
754;; changed region. However, if font-lock is enabled, this function does 817;; changed region. However, if font-lock is enabled, this function does
755;; nothing, since an enabled font-lock after-change function will always do 818;; nothing, since an enabled font-lock after-change function will always do
756;; this. 819;; this.
820;;
821;; This function might do hidden buffer changes.
757 (unless (and (boundp 'font-lock-mode) font-lock-mode) 822 (unless (and (boundp 'font-lock-mode) font-lock-mode)
758 (save-restriction 823 (save-restriction
759 (save-excursion 824 (save-excursion
@@ -786,10 +851,14 @@
786(c-awk-advise-fl-for-awk-region lazy-lock-defer-rest-after-change) 851(c-awk-advise-fl-for-awk-region lazy-lock-defer-rest-after-change)
787(c-awk-advise-fl-for-awk-region lazy-lock-defer-line-after-change) 852(c-awk-advise-fl-for-awk-region lazy-lock-defer-line-after-change)
788 853
789;; ACM 2002/9/29. Functions for C-M-a and C-M-e 854
855;; ACM 2002/9/29. Movement functions, e.g. for C-M-a and C-M-e
790 856
857;; The following three regexps differ from those earlier on in cc-awk.el in
858;; that they assume the syntax-table properties have been set. They are thus
859;; not useful for code which sets these properties.
791(defconst c-awk-terminated-regexp-or-string-here-re "\\=\\s\"\\S\"*\\s\"") 860(defconst c-awk-terminated-regexp-or-string-here-re "\\=\\s\"\\S\"*\\s\"")
792;; Matches a terminated string/regexp (utilising syntax-table properties). 861;; Matches a terminated string/regexp.
793 862
794(defconst c-awk-unterminated-regexp-or-string-here-re "\\=\\s|\\S|*$") 863(defconst c-awk-unterminated-regexp-or-string-here-re "\\=\\s|\\S|*$")
795;; Matches an unterminated string/regexp, NOT including the eol at the end. 864;; Matches an unterminated string/regexp, NOT including the eol at the end.
@@ -798,6 +867,21 @@
798 (concat "\\([^{;#/\"\\\\\n\r]\\|" c-awk-esc-pair-re "\\)*")) 867 (concat "\\([^{;#/\"\\\\\n\r]\\|" c-awk-esc-pair-re "\\)*"))
799;; Matches any "harmless" character in a pattern or an escaped character pair. 868;; Matches any "harmless" character in a pattern or an escaped character pair.
800 869
870(defun c-awk-at-statement-end-p ()
871 ;; Point is not inside a comment or string. Is it AT the end of a
872 ;; statement? This means immediately after the last non-ws character of the
873 ;; statement. The caller is responsible for widening the buffer, if
874 ;; appropriate.
875 (and (not (bobp))
876 (save-excursion
877 (backward-char)
878 (or (looking-at "[};]")
879 (and (memq (c-awk-get-NL-prop-cur-line) '(?\$ ?\\))
880 (looking-at
881 (eval-when-compile
882 (concat "[^ \t\n\r\\]" c-awk-escaped-nls*-with-space*
883 "[#\n\r]"))))))))
884
801(defun c-awk-beginning-of-defun (&optional arg) 885(defun c-awk-beginning-of-defun (&optional arg)
802 "Move backward to the beginning of an AWK \"defun\". With ARG, do it that 886 "Move backward to the beginning of an AWK \"defun\". With ARG, do it that
803many times. Negative arg -N means move forward to Nth following beginning of 887many times. Negative arg -N means move forward to Nth following beginning of
@@ -807,7 +891,10 @@ By a \"defun\" is meant either a pattern-action pair or a function. The start
807of a defun is recognized as code starting at column zero which is neither a 891of a defun is recognized as code starting at column zero which is neither a
808closing brace nor a comment nor a continuation of the previous line. Unlike 892closing brace nor a comment nor a continuation of the previous line. Unlike
809in some other modes, having an opening brace at column 0 is neither necessary 893in some other modes, having an opening brace at column 0 is neither necessary
810nor helpful." 894nor helpful.
895
896Note that this function might do hidden buffer changes. See the
897comment at the start of cc-engine.el for more info."
811 (interactive "p") 898 (interactive "p")
812 (save-match-data 899 (save-match-data
813 (c-save-buffer-state ; ensures the buffer is writable. 900 (c-save-buffer-state ; ensures the buffer is writable.
@@ -820,14 +907,14 @@ nor helpful."
820 ;; is genuinely a beginning-of-defun. 907 ;; is genuinely a beginning-of-defun.
821 (while (and (setq found (search-backward-regexp 908 (while (and (setq found (search-backward-regexp
822 "^[^#} \t\n\r]" (point-min) 'stop-at-limit)) 909 "^[^#} \t\n\r]" (point-min) 'stop-at-limit))
823 (not (memq (c-awk-get-NL-prop-prev-line) '(?\; ?\#))))) 910 (not (memq (c-awk-get-NL-prop-prev-line) '(?\$ ?\} ?\#)))))
824 (setq arg (1- arg))) 911 (setq arg (1- arg)))
825 ;; The same for a -ve arg. 912 ;; The same for a -ve arg.
826 (if (not (eq (point) (point-max))) (forward-char 1)) 913 (if (not (eq (point) (point-max))) (forward-char 1))
827 (while (and found (< arg 0) (not (eq (point) (point-max)))) ; The same for -ve arg. 914 (while (and found (< arg 0) (not (eq (point) (point-max)))) ; The same for -ve arg.
828 (while (and (setq found (search-forward-regexp 915 (while (and (setq found (search-forward-regexp
829 "^[^#} \t\n\r]" (point-max) 'stop-at-limit)) 916 "^[^#} \t\n\r]" (point-max) 'stop-at-limit))
830 (not (memq (c-awk-get-NL-prop-prev-line) '(?\; ?\#))))) 917 (not (memq (c-awk-get-NL-prop-prev-line) '(?\$ ?\} ?\#)))))
831 (setq arg (1+ arg))) 918 (setq arg (1+ arg)))
832 (if found (goto-char (match-beginning 0)))) 919 (if found (goto-char (match-beginning 0))))
833 (eq arg 0))))) 920 (eq arg 0)))))
@@ -838,6 +925,8 @@ nor helpful."
838 ;; comment. Typically, we stop at the { which denotes the corresponding AWK 925 ;; comment. Typically, we stop at the { which denotes the corresponding AWK
839 ;; action/function body. Otherwise we stop at the EOL (or ;) marking the 926 ;; action/function body. Otherwise we stop at the EOL (or ;) marking the
840 ;; absence of an explicit action. 927 ;; absence of an explicit action.
928 ;;
929 ;; This function might do hidden buffer changes.
841 (while 930 (while
842 (progn 931 (progn
843 (search-forward-regexp c-awk-harmless-pattern-characters*) 932 (search-forward-regexp c-awk-harmless-pattern-characters*)
@@ -855,6 +944,8 @@ nor helpful."
855 944
856(defun c-awk-end-of-defun1 () 945(defun c-awk-end-of-defun1 ()
857 ;; point is at the start of a "defun". Move to its end. Return end position. 946 ;; point is at the start of a "defun". Move to its end. Return end position.
947 ;;
948 ;; This function might do hidden buffer changes.
858 (c-awk-forward-awk-pattern) 949 (c-awk-forward-awk-pattern)
859 (cond 950 (cond
860 ((looking-at "{") (goto-char (scan-sexps (point) 1))) 951 ((looking-at "{") (goto-char (scan-sexps (point) 1)))
@@ -866,6 +957,8 @@ nor helpful."
866(defun c-awk-beginning-of-defun-p () 957(defun c-awk-beginning-of-defun-p ()
867 ;; Are we already at the beginning of a defun? (i.e. at code in column 0 958 ;; Are we already at the beginning of a defun? (i.e. at code in column 0
868 ;; which isn't a }, and isn't a continuation line of any sort. 959 ;; which isn't a }, and isn't a continuation line of any sort.
960 ;;
961 ;; This function might do hidden buffer changes.
869 (and (looking-at "^[^#} \t\n\r]") 962 (and (looking-at "^[^#} \t\n\r]")
870 (not (c-awk-prev-line-incomplete-p)))) 963 (not (c-awk-prev-line-incomplete-p))))
871 964
@@ -875,7 +968,10 @@ Negative argument -N means move back to Nth preceding end of defun.
875 968
876An end of a defun occurs right after the closing brace that matches the 969An end of a defun occurs right after the closing brace that matches the
877opening brace at its start, or immediately after the AWK pattern when there is 970opening brace at its start, or immediately after the AWK pattern when there is
878no explicit action; see function `c-awk-beginning-of-defun'." 971no explicit action; see function `c-awk-beginning-of-defun'.
972
973Note that this function might do hidden buffer changes. See the
974comment at the start of cc-engine.el for more info."
879 (interactive "p") 975 (interactive "p")
880 (or arg (setq arg 1)) 976 (or arg (setq arg 1))
881 (save-match-data 977 (save-match-data
@@ -911,6 +1007,7 @@ no explicit action; see function `c-awk-beginning-of-defun'."
911 (< arg 0))) 1007 (< arg 0)))
912 (goto-char (min start-point end-point))))))) 1008 (goto-char (min start-point end-point)))))))
913 1009
1010
914(cc-provide 'cc-awk) ; Changed from 'awk-mode, ACM 2002/5/21 1011(cc-provide 'cc-awk) ; Changed from 'awk-mode, ACM 2002/5/21
915 1012
916;;; arch-tag: c4836289-3aa4-4a59-9934-9ccc2bacccf3 1013;;; arch-tag: c4836289-3aa4-4a59-9934-9ccc2bacccf3
diff --git a/lisp/progmodes/cc-bytecomp.el b/lisp/progmodes/cc-bytecomp.el
index ae7adb92edb..6358f230e7c 100644
--- a/lisp/progmodes/cc-bytecomp.el
+++ b/lisp/progmodes/cc-bytecomp.el
@@ -1,7 +1,7 @@
1;;; cc-bytecomp.el --- compile time setup for proper compilation 1;;; cc-bytecomp.el --- compile time setup for proper compilation
2 2
3;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 3;; Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation,
4;; Free Software Foundation, Inc. 4;; Inc.
5 5
6;; Author: Martin Stjernholm 6;; Author: Martin Stjernholm
7;; Maintainer: bug-cc-mode@gnu.org 7;; Maintainer: bug-cc-mode@gnu.org
@@ -22,7 +22,7 @@
22;; GNU General Public License for more details. 22;; GNU General Public License for more details.
23 23
24;; You should have received a copy of the GNU General Public License 24;; You should have received a copy of the GNU General Public License
25;; along with GNU Emacs; see the file COPYING. If not, write to 25;; along with this program; see the file COPYING. If not, write to
26;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 26;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27;; Boston, MA 02110-1301, USA. 27;; Boston, MA 02110-1301, USA.
28 28
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 42808c3e307..e17656e54dd 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1,6 +1,7 @@
1;;; cc-cmds.el --- user level commands for CC Mode 1;;; cc-cmds.el --- user level commands for CC Mode
2 2
3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation,
4;; Inc.
4 5
5;; Authors: 1998- Martin Stjernholm 6;; Authors: 1998- Martin Stjernholm
6;; 1992-1999 Barry A. Warsaw 7;; 1992-1999 Barry A. Warsaw
@@ -24,7 +25,7 @@
24;; GNU General Public License for more details. 25;; GNU General Public License for more details.
25 26
26;; You should have received a copy of the GNU General Public License 27;; You should have received a copy of the GNU General Public License
27;; along with GNU Emacs; see the file COPYING. If not, write to 28;; along with this program; see the file COPYING. If not, write to
28;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 29;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29;; Boston, MA 02110-1301, USA. 30;; Boston, MA 02110-1301, USA.
30 31
@@ -45,12 +46,11 @@
45(cc-require 'cc-engine) 46(cc-require 'cc-engine)
46 47
47;; Silence the compiler. 48;; Silence the compiler.
48(cc-bytecomp-defvar delete-key-deletes-forward) ; XEmacs 20+ 49(cc-bytecomp-defun delete-forward-p) ; XEmacs
49(cc-bytecomp-defun delete-forward-p) ; XEmacs 21+
50(cc-bytecomp-obsolete-fun insert-and-inherit) ; Marked obsolete in XEmacs 19
51(cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge 50(cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge
52 ; which looks at this. 51 ; which looks at this.
53 52(cc-bytecomp-defun c-forward-subword)
53(cc-bytecomp-defun c-backward-subword)
54 54
55(defvar c-fix-backslashes t) 55(defvar c-fix-backslashes t)
56 56
@@ -64,8 +64,6 @@ point is used to decide where the old indentation is on a lines that
64is otherwise empty \(ignoring any line continuation backslash), but 64is otherwise empty \(ignoring any line continuation backslash), but
65that's not done if IGNORE-POINT-POS is non-nil. Returns the amount of 65that's not done if IGNORE-POINT-POS is non-nil. Returns the amount of
66indentation change \(in columns)." 66indentation change \(in columns)."
67 ;;
68 ;; This function does not do any hidden buffer changes.
69 67
70 (let ((line-cont-backslash (save-excursion 68 (let ((line-cont-backslash (save-excursion
71 (end-of-line) 69 (end-of-line)
@@ -134,13 +132,11 @@ indentation change \(in columns)."
134 shift-amt)) 132 shift-amt))
135 133
136(defun c-newline-and-indent (&optional newline-arg) 134(defun c-newline-and-indent (&optional newline-arg)
137 "Inserts a newline and indents the new line. 135 "Insert a newline and indent the new line.
138This function fixes line continuation backslashes if inside a macro, 136This function fixes line continuation backslashes if inside a macro,
139and takes care to set the indentation before calling 137and takes care to set the indentation before calling
140`indent-according-to-mode', so that lineup functions like 138`indent-according-to-mode', so that lineup functions like
141`c-lineup-dont-change' works better." 139`c-lineup-dont-change' works better."
142 ;;
143 ;; This function does not do any hidden buffer changes.
144 140
145 ;; TODO: Backslashes before eol in comments and literals aren't 141 ;; TODO: Backslashes before eol in comments and literals aren't
146 ;; kept intact. 142 ;; kept intact.
@@ -221,14 +217,30 @@ With universal argument, inserts the analysis as a comment on that line."
221 (c-save-buffer-state nil 217 (c-save-buffer-state nil
222 (c-guess-basic-syntax))))) 218 (c-guess-basic-syntax)))))
223 (if (not (consp arg)) 219 (if (not (consp arg))
224 (message "syntactic analysis: %s" syntax) 220 (let (elem pos ols)
221 (message "Syntactic analysis: %s" syntax)
222 (unwind-protect
223 (progn
224 (while syntax
225 (setq elem (pop syntax))
226 (when (setq pos (c-langelem-pos elem))
227 (push (c-put-overlay pos (1+ pos)
228 'face 'highlight)
229 ols))
230 (when (setq pos (c-langelem-2nd-pos elem))
231 (push (c-put-overlay pos (1+ pos)
232 'face 'secondary-selection)
233 ols)))
234 (sit-for 10))
235 (while ols
236 (c-delete-overlay (pop ols)))))
225 (indent-for-comment) 237 (indent-for-comment)
226 (insert-and-inherit (format "%s" syntax)) 238 (insert-and-inherit (format "%s" syntax))
227 )) 239 ))
228 (c-keep-region-active)) 240 (c-keep-region-active))
229 241
230(defun c-syntactic-information-on-region (from to) 242(defun c-syntactic-information-on-region (from to)
231 "Inserts a comment with the syntactic analysis on every line in the region." 243 "Insert a comment with the syntactic analysis on every line in the region."
232 (interactive "*r") 244 (interactive "*r")
233 (save-excursion 245 (save-excursion
234 (save-restriction 246 (save-restriction
@@ -239,6 +251,23 @@ With universal argument, inserts the analysis as a comment on that line."
239 (forward-line))))) 251 (forward-line)))))
240 252
241 253
254(defun c-update-modeline ()
255 (let ((fmt (format "/%s%s%s%s"
256 (if c-electric-flag "l" "")
257 (if (and c-electric-flag c-auto-newline)
258 "a" "")
259 (if c-hungry-delete-key "h" "")
260 (if (and
261 ;; cc-subword might not be loaded.
262 (boundp 'c-subword-mode)
263 (symbol-value 'c-subword-mode))
264 "w"
265 ""))))
266 (setq c-submode-indicators
267 (if (> (length fmt) 1)
268 fmt))
269 (force-mode-line-update)))
270
242(defun c-toggle-syntactic-indentation (&optional arg) 271(defun c-toggle-syntactic-indentation (&optional arg)
243 "Toggle syntactic indentation. 272 "Toggle syntactic indentation.
244Optional numeric ARG, if supplied, turns on syntactic indentation when 273Optional numeric ARG, if supplied, turns on syntactic indentation when
@@ -249,12 +278,12 @@ When syntactic indentation is turned on (the default), the indentation
249functions and the electric keys indent according to the syntactic 278functions and the electric keys indent according to the syntactic
250context keys, when applicable. 279context keys, when applicable.
251 280
252When it's turned off, the electric keys does no reindentation, the 281When it's turned off, the electric keys don't reindent, the indentation
253indentation functions indents every new line to the same level as the 282functions indents every new line to the same level as the previous
254previous nonempty line, and \\[c-indent-command] adjusts the 283nonempty line, and \\[c-indent-command] adjusts the indentation in steps
255indentation in seps specified `c-basic-offset'. The indentation style 284specified by `c-basic-offset'. The indentation style has no effect in
256has no effect in this mode, nor any of the indentation associated 285this mode, nor any of the indentation associated variables,
257variables, e.g. `c-special-indent-hook'. 286e.g. `c-special-indent-hook'.
258 287
259This command sets the variable `c-syntactic-indentation'." 288This command sets the variable `c-syntactic-indentation'."
260 (interactive "P") 289 (interactive "P")
@@ -262,30 +291,36 @@ This command sets the variable `c-syntactic-indentation'."
262 (c-calculate-state arg c-syntactic-indentation)) 291 (c-calculate-state arg c-syntactic-indentation))
263 (c-keep-region-active)) 292 (c-keep-region-active))
264 293
265(defun c-toggle-auto-state (&optional arg) 294(defun c-toggle-auto-newline (&optional arg)
266 "Toggle auto-newline feature. 295 "Toggle auto-newline feature.
267Optional numeric ARG, if supplied, turns on auto-newline when 296Optional numeric ARG, if supplied, turns on auto-newline when
268positive, turns it off when negative, and just toggles it when zero or 297positive, turns it off when negative, and just toggles it when zero or
269left out. 298left out.
270 299
271When the auto-newline feature is enabled (as evidenced by the `/a' or 300Turning on auto-newline automatically enables electric indentation.
272`/ah' on the modeline after the mode name) newlines are automatically 301
273inserted after special characters such as brace, comma, semi-colon, 302When the auto-newline feature is enabled (indicated by \"/la\" on the
274and colon." 303modeline after the mode name) newlines are automatically inserted
304after special characters such as brace, comma, semi-colon, and colon."
275 (interactive "P") 305 (interactive "P")
276 (setq c-auto-newline (c-calculate-state arg c-auto-newline)) 306 (setq c-auto-newline
307 (c-calculate-state arg (and c-auto-newline c-electric-flag)))
308 (if c-auto-newline (setq c-electric-flag t))
277 (c-update-modeline) 309 (c-update-modeline)
278 (c-keep-region-active)) 310 (c-keep-region-active))
279 311
312(defalias 'c-toggle-auto-state 'c-toggle-auto-newline)
313(make-obsolete 'c-toggle-auto-state 'c-toggle-auto-newline)
314
280(defun c-toggle-hungry-state (&optional arg) 315(defun c-toggle-hungry-state (&optional arg)
281 "Toggle hungry-delete-key feature. 316 "Toggle hungry-delete-key feature.
282Optional numeric ARG, if supplied, turns on hungry-delete when 317Optional numeric ARG, if supplied, turns on hungry-delete when
283positive, turns it off when negative, and just toggles it when zero or 318positive, turns it off when negative, and just toggles it when zero or
284left out. 319left out.
285 320
286When the hungry-delete-key feature is enabled (as evidenced by the 321When the hungry-delete-key feature is enabled (indicated by \"/h\" on
287`/h' or `/ah' on the modeline after the mode name) the delete key 322the modeline after the mode name) the delete key gobbles all preceding
288gobbles all preceding whitespace in one fell swoop." 323whitespace in one fell swoop."
289 (interactive "P") 324 (interactive "P")
290 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key)) 325 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
291 (c-update-modeline) 326 (c-update-modeline)
@@ -297,27 +332,38 @@ Optional numeric ARG, if supplied, turns on auto-newline and
297hungry-delete when positive, turns them off when negative, and just 332hungry-delete when positive, turns them off when negative, and just
298toggles them when zero or left out. 333toggles them when zero or left out.
299 334
300See `c-toggle-auto-state' and `c-toggle-hungry-state' for details." 335See `c-toggle-auto-newline' and `c-toggle-hungry-state' for details."
301 (interactive "P") 336 (interactive "P")
302 (setq c-auto-newline (c-calculate-state arg c-auto-newline)) 337 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
303 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key)) 338 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
304 (c-update-modeline) 339 (c-update-modeline)
305 (c-keep-region-active)) 340 (c-keep-region-active))
306 341
342(defun c-toggle-electric-state (&optional arg)
343 "Toggle the electric indentation feature.
344Optional numeric ARG, if supplied, turns on electric indentation when
345positive, turns it off when negative, and just toggles it when zero or
346left out."
347 (interactive "P")
348 (setq c-electric-flag (c-calculate-state arg c-electric-flag))
349 (c-update-modeline)
350 (c-keep-region-active))
351
307 352
308;; Electric keys 353;; Electric keys
309 354
310(defun c-electric-backspace (arg) 355(defun c-electric-backspace (arg)
311 "Delete the preceding character or whitespace. 356 "Delete the preceding character or whitespace.
312If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or 357If `c-hungry-delete-key' is non-nil (indicated by \"/h\" on the mode
313\"/ah\" string on the mode line, then all preceding whitespace is 358line) then all preceding whitespace is consumed. If however a prefix
314consumed. If however a prefix argument is supplied, or 359argument is supplied, or `c-hungry-delete-key' is nil, or point is
315`c-hungry-delete-key' is nil, or point is inside a literal then the 360inside a literal then the function in the variable
316function in the variable `c-backspace-function' is called." 361`c-backspace-function' is called."
317 (interactive "*P") 362 (interactive "*P")
318 (if (or (not c-hungry-delete-key) 363 (if (c-save-buffer-state ()
319 arg 364 (or (not c-hungry-delete-key)
320 (c-in-literal)) 365 arg
366 (c-in-literal)))
321 (funcall c-backspace-function (prefix-numeric-value arg)) 367 (funcall c-backspace-function (prefix-numeric-value arg))
322 (c-hungry-backspace))) 368 (c-hungry-backspace)))
323 369
@@ -334,15 +380,16 @@ See also \\[c-hungry-delete-forward]."
334 380
335(defun c-electric-delete-forward (arg) 381(defun c-electric-delete-forward (arg)
336 "Delete the following character or whitespace. 382 "Delete the following character or whitespace.
337If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or 383If `c-hungry-delete-key' is non-nil (indicated by \"/h\" on the mode
338\"/ah\" string on the mode line, then all following whitespace is 384line) then all following whitespace is consumed. If however a prefix
339consumed. If however a prefix argument is supplied, or 385argument is supplied, or `c-hungry-delete-key' is nil, or point is
340`c-hungry-delete-key' is nil, or point is inside a literal then the 386inside a literal then the function in the variable `c-delete-function'
341function in the variable `c-delete-function' is called." 387is called."
342 (interactive "*P") 388 (interactive "*P")
343 (if (or (not c-hungry-delete-key) 389 (if (c-save-buffer-state ()
344 arg 390 (or (not c-hungry-delete-key)
345 (c-in-literal)) 391 arg
392 (c-in-literal)))
346 (funcall c-delete-function (prefix-numeric-value arg)) 393 (funcall c-delete-function (prefix-numeric-value arg))
347 (c-hungry-delete-forward))) 394 (c-hungry-delete-forward)))
348 395
@@ -361,43 +408,54 @@ See also \\[c-hungry-backspace]."
361(defun c-electric-delete (arg) 408(defun c-electric-delete (arg)
362 "Deletes preceding or following character or whitespace. 409 "Deletes preceding or following character or whitespace.
363This function either deletes forward as `c-electric-delete-forward' or 410This function either deletes forward as `c-electric-delete-forward' or
364backward as `c-electric-backspace', depending on the configuration: 411backward as `c-electric-backspace', depending on the configuration: If
365 412the function `delete-forward-p' is defined and returns non-nil, it
366If the function `delete-forward-p' is defined (XEmacs 21) and returns 413deletes forward. Otherwise it deletes backward.
367non-nil, it deletes forward. Else, if the variable 414
368`delete-key-deletes-forward' is defined (XEmacs 20) and is set to 415Note: This is the way in XEmacs to choose the correct action for the
369non-nil, it deletes forward. Otherwise it deletes backward. 416\[delete] key, whichever key that means. Other flavors don't use this
370 417function to control that."
371Note: This is the way in XEmacs 20 and later to choose the correct
372action for the [delete] key, whichever key that means. In other
373flavors this function isn't used, instead it's left to the user to
374bind [delete] to either \\[c-electric-delete-forward] or \\[c-electric-backspace] as appropriate
375\(the keymap `function-key-map' is useful for that). Emacs 21 handles
376that automatically, though."
377 (interactive "*P") 418 (interactive "*P")
378 (if (or (and (fboundp 'delete-forward-p) ;XEmacs 21 419 (if (and (fboundp 'delete-forward-p)
379 (delete-forward-p)) 420 (delete-forward-p))
380 (and (boundp 'delete-key-deletes-forward) ;XEmacs 20
381 delete-key-deletes-forward))
382 (c-electric-delete-forward arg) 421 (c-electric-delete-forward arg)
383 (c-electric-backspace arg))) 422 (c-electric-backspace arg)))
384 423
424;; This function is only used in XEmacs.
425(defun c-hungry-delete ()
426 "Delete a non-whitespace char, or all whitespace up to the next non-whitespace char.
427The direction of deletion depends on the configuration: If the
428function `delete-forward-p' is defined and returns non-nil, it deletes
429forward using `c-hungry-delete-forward'. Otherwise it deletes
430backward using `c-hungry-backspace'.
431
432Note: This is the way in XEmacs to choose the correct action for the
433\[delete] key, whichever key that means. Other flavors don't use this
434function to control that."
435 (interactive)
436 (if (and (fboundp 'delete-forward-p)
437 (delete-forward-p))
438 (c-hungry-delete-forward)
439 (c-hungry-backspace)))
440
385(defun c-electric-pound (arg) 441(defun c-electric-pound (arg)
386 "Electric pound (`#') insertion. 442 "Insert a \"#\".
387Inserts a `#' character specially depending on the variable 443If `c-electric-flag' is set, handle it specially according to the variable
388`c-electric-pound-behavior'. If a numeric ARG is supplied, or if 444`c-electric-pound-behavior'. If a numeric ARG is supplied, or if point is
389point is inside a literal or a macro, nothing special happens." 445inside a literal or a macro, nothing special happens."
390 (interactive "*P") 446 (interactive "*P")
391 (if (or arg 447 (if (c-save-buffer-state ()
392 (not (memq 'alignleft c-electric-pound-behavior)) 448 (or arg
393 (save-excursion 449 (not c-electric-flag)
394 (skip-chars-backward " \t") 450 (not (memq 'alignleft c-electric-pound-behavior))
395 (not (bolp))) 451 (save-excursion
396 (save-excursion 452 (skip-chars-backward " \t")
397 (and (= (forward-line -1) 0) 453 (not (bolp)))
398 (progn (end-of-line) 454 (save-excursion
399 (eq (char-before) ?\\)))) 455 (and (= (forward-line -1) 0)
400 (c-in-literal)) 456 (progn (end-of-line)
457 (eq (char-before) ?\\))))
458 (c-in-literal)))
401 ;; do nothing special 459 ;; do nothing special
402 (self-insert-command (prefix-numeric-value arg)) 460 (self-insert-command (prefix-numeric-value arg))
403 ;; place the pound character at the left edge 461 ;; place the pound character at the left edge
@@ -410,243 +468,332 @@ point is inside a literal or a macro, nothing special happens."
410 (goto-char (- (point-max) pos))) 468 (goto-char (- (point-max) pos)))
411 ))) 469 )))
412 470
471(defun c-point-syntax ()
472 ;; Return the syntactic context of the construct at point. (This is NOT
473 ;; nec. the same as the s.c. of the line point is on). N.B. This won't work
474 ;; between the `#' of a cpp thing and what follows (see c-opt-cpp-prefix).
475 (c-save-buffer-state (;; shut this up too
476 (c-echo-syntactic-information-p nil)
477 syntax)
478 (c-tentative-buffer-changes
479 ;; insert a newline to isolate the construct at point for syntactic
480 ;; analysis.
481 (insert-char ?\n 1)
482 ;; In AWK (etc.) or in a macro, make sure this CR hasn't changed
483 ;; the syntax. (There might already be an escaped NL there.)
484 (when (or (c-at-vsemi-p (1- (point)))
485 (let ((pt (point)))
486 (save-excursion
487 (backward-char)
488 (and (c-beginning-of-macro)
489 (progn (c-end-of-macro)
490 (< (point) pt))))))
491 (backward-char)
492 (insert-char ?\\ 1)
493 (forward-char))
494 (let ((c-syntactic-indentation-in-macros t)
495 (c-auto-newline-analysis t))
496 ;; Turn on syntactic macro analysis to help with auto
497 ;; newlines only.
498 (setq syntax (c-guess-basic-syntax))
499 nil))
500 syntax))
501
502(defun c-brace-newlines (syntax)
503 ;; A brace stands at point. SYNTAX is the syntactic context of this brace
504 ;; (not necessarily the same as the S.C. of the line it is on). Return
505 ;; NEWLINES, the list containing some combination of the symbols `before'
506 ;; and `after' saying where newlines should be inserted.
507 (c-save-buffer-state
508 ((syms
509 ;; This is the list of brace syntactic symbols that can hang.
510 ;; If any new ones are added to c-offsets-alist, they should be
511 ;; added here as well.
512 '(class-open class-close defun-open defun-close
513 inline-open inline-close
514 brace-list-open brace-list-close
515 brace-list-intro brace-entry-open
516 block-open block-close
517 substatement-open statement-case-open
518 extern-lang-open extern-lang-close
519 namespace-open namespace-close
520 module-open module-close
521 composition-open composition-close
522 inexpr-class-open inexpr-class-close
523 ;; `statement-cont' is here for the case with a brace
524 ;; list opener inside a statement. C.f. CASE B.2 in
525 ;; `c-guess-continued-construct'.
526 statement-cont))
527 ;; shut this up too
528 (c-echo-syntactic-information-p nil)
529 symb-newlines) ; e.g. (substatement-open . (after))
530
531 (setq symb-newlines
532 ;; Do not try to insert newlines around a special
533 ;; (Pike-style) brace list.
534 (if (and c-special-brace-lists
535 (save-excursion
536 (c-safe (if (= (char-before) ?{)
537 (forward-char -1)
538 (c-forward-sexp -1))
539 (c-looking-at-special-brace-list))))
540 nil
541 ;; Seek the matching entry in c-hanging-braces-alist.
542 (or (c-lookup-lists
543 syms
544 ;; Substitute inexpr-class and class-open or
545 ;; class-close with inexpr-class-open or
546 ;; inexpr-class-close.
547 (if (assq 'inexpr-class syntax)
548 (cond ((assq 'class-open syntax)
549 '((inexpr-class-open)))
550 ((assq 'class-close syntax)
551 '((inexpr-class-close)))
552 (t syntax))
553 syntax)
554 c-hanging-braces-alist)
555 '(ignore before after)))) ; Default, when not in c-h-b-l.
556
557 ;; If syntax is a function symbol, then call it using the
558 ;; defined semantics.
559 (if (and (not (consp (cdr symb-newlines)))
560 (functionp (cdr symb-newlines)))
561 (let ((c-syntactic-context syntax))
562 (funcall (cdr symb-newlines)
563 (car symb-newlines)
564 (point)))
565 (cdr symb-newlines))))
566
567(defun c-try-one-liner ()
568 ;; Point is just after a newly inserted }. If the non-whitespace
569 ;; content of the braces is a single line of code, compact the whole
570 ;; construct to a single line, if this line isn't too long. The Right
571 ;; Thing is done with comments.
572 ;;
573 ;; Point will be left after the }, regardless of whether the clean-up is
574 ;; done. Return NON-NIL if the clean-up happened, NIL if it didn't.
575
576 (let ((here (point))
577 (pos (- (point-max) (point)))
578 mbeg1 mend1 mbeg4 mend4
579 eol-col cmnt-pos cmnt-col cmnt-gap)
580
581 (when
582 (save-excursion
583 (save-restriction
584 ;; Avoid backtracking over a very large block. The one we
585 ;; deal with here can never be more than three lines.
586 (narrow-to-region (save-excursion
587 (forward-line -2)
588 (point))
589 (point))
590 (and (c-safe (c-backward-sexp))
591 (progn
592 (forward-char)
593 (narrow-to-region (point) (1- here)) ; innards of {.}
594 (looking-at
595 (cc-eval-when-compile
596 (concat
597 "\\(" ; (match-beginning 1)
598 "[ \t]*\\([\r\n][ \t]*\\)?" ; WS with opt. NL
599 "\\)" ; (match-end 1)
600 "[^ \t\r\n]+\\([ \t]+[^ \t\r\n]+\\)*" ; non-WS
601 "\\(" ; (match-beginning 4)
602 "[ \t]*\\([\r\n][ \t]*\\)?" ; WS with opt. NL
603 "\\)\\'"))))))) ; (match-end 4) at EOB.
604
605 (if (c-tentative-buffer-changes
606 (setq mbeg1 (match-beginning 1) mend1 (match-end 1)
607 mbeg4 (match-beginning 4) mend4 (match-end 4))
608 (backward-char) ; back over the `}'
609 (save-excursion
610 (setq cmnt-pos (and (c-backward-single-comment)
611 (- (point) (- mend1 mbeg1)))))
612 (delete-region mbeg4 mend4)
613 (delete-region mbeg1 mend1)
614 (setq eol-col (save-excursion (end-of-line) (current-column)))
615
616 ;; Necessary to put the closing brace before any line
617 ;; oriented comment to keep it syntactically significant.
618 ;; This isn't necessary for block comments, but the result
619 ;; looks nicer anyway.
620 (when cmnt-pos
621 (delete-char 1) ; the `}' has blundered into a comment
622 (goto-char cmnt-pos)
623 (setq cmnt-col (1+ (current-column)))
624 (setq cmnt-pos (1+ cmnt-pos)) ; we're inserting a `}'
625 (c-skip-ws-backward)
626 (insert-char ?\} 1) ; reinsert the `}' before the comment.
627 (setq cmnt-gap (- cmnt-col (current-column)))
628 (when (zerop cmnt-gap)
629 (insert-char ?\ 1) ; Put a space before a bare comment.
630 (setq cmnt-gap 1)))
631
632 (or (null c-max-one-liner-length)
633 (zerop c-max-one-liner-length)
634 (<= eol-col c-max-one-liner-length)
635 ;; Can we trim space before comment to make the line fit?
636 (and cmnt-gap
637 (< (- eol-col cmnt-gap) c-max-one-liner-length)
638 (progn (goto-char cmnt-pos)
639 (backward-delete-char-untabify
640 (- eol-col c-max-one-liner-length))
641 t))))
642 (goto-char (- (point-max) pos))))))
643
413(defun c-electric-brace (arg) 644(defun c-electric-brace (arg)
414 "Insert a brace. 645 "Insert a brace.
415 646
416If the auto-newline feature is turned on, as evidenced by the \"/a\" 647If `c-electric-flag' is non-nil, the brace is not inside a literal and a
417or \"/ah\" string on the mode line, newlines are inserted before and 648numeric ARG hasn't been supplied, the command performs several electric
418after braces based on the value of `c-hanging-braces-alist'. 649actions:
419 650
420Also, the line is re-indented unless a numeric ARG is supplied, the 651\(a) If the auto-newline feature is turned on (indicated by \"/ln\" on
421brace is inserted inside a literal, or `c-syntactic-indentation' is 652the mode line) newlines are inserted before and after the brace as
422nil. 653directed by the settings in `c-hanging-braces-alist'.
654
655\(b) Any auto-newlines are indented. The original line is also
656reindented unless `c-syntactic-indentation' is nil.
657
658\(c) If auto-newline is turned on, various newline cleanups based on the
659settings of `c-cleanup-list' are done."
423 660
424This function does various newline cleanups based on the value of
425`c-cleanup-list'."
426 (interactive "*P") 661 (interactive "*P")
427 (let* ((safepos (c-safe-position (point) (c-parse-state))) 662 (let (safepos literal
428 (literal (c-in-literal safepos)) 663 ;; We want to inhibit blinking the paren since this would be
429 ;; We want to inhibit blinking the paren since this will be 664 ;; most disruptive. We'll blink it ourselves later on.
430 ;; most disruptive. We'll blink it ourselves later on. 665 (old-blink-paren blink-paren-function)
431 (old-blink-paren blink-paren-function) 666 blink-paren-function)
432 blink-paren-function) 667
433 (cond 668 (c-save-buffer-state ()
434 ((or literal arg) 669 (setq safepos (c-safe-position (point) (c-parse-state))
435 (self-insert-command (prefix-numeric-value arg))) 670 literal (c-in-literal safepos)))
436 ((not (looking-at "[ \t]*\\\\?$")) 671
437 (self-insert-command (prefix-numeric-value arg)) 672 ;; Insert the brace. Note that expand-abbrev might reindent
438 (if c-syntactic-indentation 673 ;; the line here if there's a preceding "else" or something.
439 (indent-according-to-mode))) 674 (self-insert-command (prefix-numeric-value arg))
440 (t 675
441 (let* ((syms 676 (when (and c-electric-flag (not literal) (not arg))
442 ;; This is the list of brace syntactic symbols that can 677 (if (not (looking-at "[ \t]*\\\\?$"))
443 ;; hang. If any new ones are added to c-offsets-alist, 678 (if c-syntactic-indentation
444 ;; they should be added here as well. 679 (indent-according-to-mode))
445 '(class-open class-close defun-open defun-close 680
446 inline-open inline-close 681 (let ( ;; shut this up too
447 brace-list-open brace-list-close 682 (c-echo-syntactic-information-p nil)
448 brace-list-intro brace-entry-open 683 newlines
449 block-open block-close 684 ln-syntax br-syntax syntax) ; Syntactic context of the original line,
450 substatement-open statement-case-open 685 ; of the brace itself, of the line the brace ends up on.
451 extern-lang-open extern-lang-close 686 (c-save-buffer-state ((c-syntactic-indentation-in-macros t)
452 namespace-open namespace-close 687 (c-auto-newline-analysis t))
453 module-open module-close 688 (setq ln-syntax (c-guess-basic-syntax)))
454 composition-open composition-close 689 (if c-syntactic-indentation
455 inexpr-class-open inexpr-class-close 690 (c-indent-line ln-syntax))
456 ;; `statement-cont' is here for the case with a brace 691
457 ;; list opener inside a statement. C.f. CASE B.2 in 692 (when c-auto-newline
458 ;; `c-guess-continued-construct'. 693 (backward-char)
459 statement-cont)) 694 (setq br-syntax (c-point-syntax)
460 (insertion-point (point)) 695 newlines (c-brace-newlines br-syntax))
461 (preserve-p (and (not (bobp)) 696
462 (eq ?\ (char-syntax (char-before))))) 697 ;; Insert the BEFORE newline, if wanted, and reindent the newline.
463 ;; shut this up too 698 (if (and (memq 'before newlines)
464 (c-echo-syntactic-information-p nil) 699 (> (current-column) (current-indentation)))
465 delete-temp-newline syntax newlines) 700 (if c-syntactic-indentation
466 ;; only insert a newline if there is non-whitespace behind us 701 ;; Only a plain newline for now - it's indented
467 (when (save-excursion 702 ;; after the cleanups when the line has its final
468 (skip-chars-backward " \t") 703 ;; appearance.
469 (not (bolp))) 704 (newline)
470 (c-newline-and-indent) 705 (c-newline-and-indent)))
471 ;; Set markers around the newline and indention inserted 706 (forward-char)
472 ;; above. We insert the start marker here and not before 707
473 ;; the call to kludge around a misfeature in expand-abbrev: 708 ;; `syntax' is the syntactic context of the line which ends up
474 ;; If the line contains e.g. "else" then expand-abbrev will 709 ;; with the brace on it.
475 ;; be called when c-newline-and-indent inserts the newline. 710 (setq syntax (if (memq 'before newlines) br-syntax ln-syntax))
476 ;; That function first removes the abbrev "else" and then 711
477 ;; inserts the expansion, which is an identical "else" in 712 ;; Do all appropriate clean ups
478 ;; this case. So the marker that we put after "else" would 713 (let ((here (point))
479 ;; end up before it. 714 (pos (- (point-max) (point)))
480 (setq delete-temp-newline 715 mbeg mend
481 (cons (save-excursion 716 )
482 (end-of-line 0) 717
483 (if (eq (char-before) ?\\) 718 ;; `}': clean up empty defun braces
484 ;; Ignore a line continuation. 719 (when (c-save-buffer-state ()
485 (backward-char)) 720 (and (memq 'empty-defun-braces c-cleanup-list)
486 (skip-chars-backward " \t") 721 (eq last-command-char ?\})
487 (copy-marker (point) t)) 722 (c-intersect-lists '(defun-close class-close inline-close)
488 (point-marker)))) 723 syntax)
489 (unwind-protect 724 (progn
490 (progn 725 (forward-char -1)
491 (if (eq last-command-char ?{) 726 (c-skip-ws-backward)
492 (setq c-state-cache (cons (point) c-state-cache))) 727 (eq (char-before) ?\{))
493 (self-insert-command (prefix-numeric-value arg)) 728 ;; make sure matching open brace isn't in a comment
494 (c-save-buffer-state ((c-syntactic-indentation-in-macros t) 729 (not (c-in-literal))))
495 (c-auto-newline-analysis t)) 730 (delete-region (point) (1- here))
496 ;; Turn on syntactic macro analysis to help with auto 731 (setq here (- (point-max) pos)))
497 ;; newlines only. 732 (goto-char here)
498 (setq syntax (c-guess-basic-syntax))) 733
499 (setq newlines 734 ;; `}': compact to a one-liner defun?
500 (and 735 (save-match-data
501 c-auto-newline 736 (when
502 (or (c-lookup-lists 737 (and (eq last-command-char ?\})
503 syms 738 (memq 'one-liner-defun c-cleanup-list)
504 ;; Substitute inexpr-class and class-open or 739 (c-intersect-lists '(defun-close) syntax)
505 ;; class-close with inexpr-class-open or 740 (c-try-one-liner))
506 ;; inexpr-class-close. 741 (setq here (- (point-max) pos))))
507 (if (assq 'inexpr-class syntax) 742
508 (cond ((assq 'class-open syntax) 743 ;; `{': clean up brace-else-brace and brace-elseif-brace
509 '((inexpr-class-open))) 744 (when (eq last-command-char ?\{)
510 ((assq 'class-close syntax) 745 (cond
511 '((inexpr-class-close))) 746 ((and (memq 'brace-else-brace c-cleanup-list)
512 (t syntax)) 747 (re-search-backward
513 syntax) 748 (concat "}"
514 c-hanging-braces-alist) 749 "\\([ \t\n]\\|\\\\\n\\)*"
515 '(ignore before after)))) 750 "else"
516 ;; Do not try to insert newlines around a special 751 "\\([ \t\n]\\|\\\\\n\\)*"
517 ;; (Pike-style) brace list. 752 "{"
518 (if (and c-special-brace-lists 753 "\\=")
519 (save-excursion 754 nil t))
520 (c-save-buffer-state nil 755 (delete-region mbeg mend)
521 (c-safe (if (= (char-before) ?{) 756 (insert-and-inherit "} else {"))
522 (forward-char -1) 757 ((and (memq 'brace-elseif-brace c-cleanup-list)
523 (c-forward-sexp -1)) 758 (progn
524 (c-looking-at-special-brace-list))))) 759 (goto-char (1- here))
525 (setq newlines nil)) 760 (setq mend (point))
526 ;; If syntax is a function symbol, then call it using the 761 (c-skip-ws-backward)
527 ;; defined semantics. 762 (setq mbeg (point))
528 (if (and (not (consp (cdr newlines))) 763 (eq (char-before) ?\)))
529 (functionp (cdr newlines))) 764 (zerop (c-save-buffer-state nil (c-backward-token-2 1 t)))
530 (let ((c-syntactic-context syntax)) 765 (eq (char-after) ?\()
531 (setq newlines 766 ; (progn
532 (funcall (cdr newlines) 767 ; (setq tmp (point))
533 (car newlines) 768 (re-search-backward
534 insertion-point)))) 769 (concat "}"
535 ;; does a newline go before the open brace? 770 "\\([ \t\n]\\|\\\\\n\\)*"
536 (when (memq 'before newlines) 771 "else"
537 ;; we leave the newline we've put in there before, 772 "\\([ \t\n]\\|\\\\\n\\)+"
538 ;; but we need to re-indent the line above 773 "if"
539 (when delete-temp-newline 774 "\\([ \t\n]\\|\\\\\n\\)*"
540 (set-marker (car delete-temp-newline) nil) 775 "\\=")
541 (set-marker (cdr delete-temp-newline) nil) 776 nil t);)
542 (setq delete-temp-newline nil)) 777 ;(eq (match-end 0) tmp);
543 (when c-syntactic-indentation 778 )
544 (let ((pos (- (point-max) (point))) 779 (delete-region mbeg mend)
545 (here (point))) 780 (goto-char mbeg)
546 (forward-line -1) 781 (insert ?\ ))))
547 (indent-according-to-mode) 782
548 (goto-char (- (point-max) pos)) 783 (goto-char (- (point-max) pos))
549 ;; if the buffer has changed due to the 784
550 ;; indentation, we need to recalculate syntax for 785 ;; Indent the line after the cleanups since it might
551 ;; the current line. 786 ;; very well indent differently due to them, e.g. if
552 (if (/= (point) here) 787 ;; c-indent-one-line-block is used together with the
553 (c-save-buffer-state 788 ;; one-liner-defun cleanup.
554 ((c-syntactic-indentation-in-macros t) 789 (when c-syntactic-indentation
555 (c-auto-newline-analysis t)) 790 (c-indent-line)))
556 ;; Turn on syntactic macro analysis to help 791
557 ;; with auto newlines only. 792 ;; does a newline go after the brace?
558 (setq syntax (c-guess-basic-syntax)))))))) 793 (if (memq 'after newlines)
559 ;; must remove the newline we just stuck in (if we really did it) 794 (c-newline-and-indent))
560 (when delete-temp-newline 795 ))))
561 (save-excursion 796
562 (delete-region (car delete-temp-newline)
563 (cdr delete-temp-newline))
564 (goto-char (car delete-temp-newline))
565 (set-marker (car delete-temp-newline) nil)
566 (set-marker (cdr delete-temp-newline) nil)
567 ;; if there is whitespace before point, then preserve
568 ;; at least one space.
569 (just-one-space)
570 (if (not preserve-p)
571 (delete-char -1)))))
572 (if (not (memq 'before newlines))
573 ;; since we're hanging the brace, we need to recalculate
574 ;; syntax.
575 (c-save-buffer-state ((c-syntactic-indentation-in-macros t)
576 (c-auto-newline-analysis t))
577 ;; Turn on syntactic macro analysis to help with auto
578 ;; newlines only.
579 (setq syntax (c-guess-basic-syntax))))
580 (when c-syntactic-indentation
581 ;; Now adjust the line's indentation. Don't update the state
582 ;; cache since c-guess-basic-syntax isn't called when
583 ;; c-syntactic-context is set.
584 (let* ((c-syntactic-context syntax))
585 (indent-according-to-mode)))
586 ;; Do all appropriate clean ups
587 (let ((here (point))
588 (pos (- (point-max) (point)))
589 mbeg mend tmp)
590 ;; clean up empty defun braces
591 (if (and c-auto-newline
592 (memq 'empty-defun-braces c-cleanup-list)
593 (eq last-command-char ?\})
594 (c-intersect-lists '(defun-close class-close inline-close)
595 syntax)
596 (progn
597 (forward-char -1)
598 (c-skip-ws-backward)
599 (eq (char-before) ?\{))
600 ;; make sure matching open brace isn't in a comment
601 (not (c-in-literal)))
602 (delete-region (point) (1- here)))
603 ;; clean up brace-else-brace and brace-elseif-brace
604 (when (and c-auto-newline
605 (eq last-command-char ?\{))
606 (cond
607 ((and (memq 'brace-else-brace c-cleanup-list)
608 (re-search-backward
609 (concat "}"
610 "\\([ \t\n]\\|\\\\\n\\)*"
611 "else"
612 "\\([ \t\n]\\|\\\\\n\\)*"
613 "{")
614 nil t)
615 (progn
616 (setq mbeg (match-beginning 0)
617 mend (match-end 0))
618 (eq (match-end 0) here)))
619 (delete-region mbeg mend)
620 (insert-and-inherit "} else {"))
621 ((and (memq 'brace-elseif-brace c-cleanup-list)
622 (progn
623 (goto-char (1- here))
624 (setq mend (point))
625 (c-skip-ws-backward)
626 (setq mbeg (point))
627 (eq (char-before) ?\)))
628 (zerop (c-save-buffer-state nil (c-backward-token-2 1 t)))
629 (eq (char-after) ?\()
630 (progn
631 (setq tmp (point))
632 (re-search-backward
633 (concat "}"
634 "\\([ \t\n]\\|\\\\\n\\)*"
635 "else"
636 "\\([ \t\n]\\|\\\\\n\\)+"
637 "if"
638 "\\([ \t\n]\\|\\\\\n\\)*")
639 nil t))
640 (eq (match-end 0) tmp))
641 (delete-region mbeg mend)
642 (goto-char mbeg)
643 (insert ?\ ))))
644 (goto-char (- (point-max) pos))
645 )
646 ;; does a newline go after the brace?
647 (if (memq 'after newlines)
648 (c-newline-and-indent))
649 )))
650 ;; blink the paren 797 ;; blink the paren
651 (and (eq last-command-char ?\}) 798 (and (eq last-command-char ?\})
652 (not executing-kbd-macro) 799 (not executing-kbd-macro)
@@ -659,332 +806,465 @@ This function does various newline cleanups based on the value of
659(defun c-electric-slash (arg) 806(defun c-electric-slash (arg)
660 "Insert a slash character. 807 "Insert a slash character.
661 808
809If the slash is inserted immediately after the comment prefix in a c-style
810comment, the comment might get closed by removing whitespace and possibly
811inserting a \"*\". See the variable `c-cleanup-list'.
812
662Indent the line as a comment, if: 813Indent the line as a comment, if:
663 814
664 1. The slash is second of a `//' line oriented comment introducing 815 1. The slash is second of a \"//\" line oriented comment introducing
665 token and we are on a comment-only-line, or 816 token and we are on a comment-only-line, or
666 817
667 2. The slash is part of a `*/' token that closes a block oriented 818 2. The slash is part of a \"*/\" token that closes a block oriented
668 comment. 819 comment.
669 820
670If a numeric ARG is supplied, point is inside a literal, or 821If a numeric ARG is supplied, point is inside a literal, or
671`c-syntactic-indentation' is nil, indentation is inhibited." 822`c-syntactic-indentation' is nil or `c-electric-flag' is nil, indentation
823is inhibited."
672 (interactive "*P") 824 (interactive "*P")
673 (let* ((ch (char-before)) 825 (let ((literal (c-save-buffer-state () (c-in-literal)))
674 (literal (c-in-literal)) 826 indentp
675 (indentp (and c-syntactic-indentation 827 ;; shut this up
676 (not arg) 828 (c-echo-syntactic-information-p nil))
829
830 ;; comment-close-slash cleanup? This DOESN'T need `c-electric-flag' or
831 ;; `c-syntactic-indentation' set.
832 (when (and (not arg)
833 (eq literal 'c)
834 (memq 'comment-close-slash c-cleanup-list)
835 (eq last-command-char ?/)
836 ; (eq c-block-comment-ender "*/") ; C-style comments ALWAYS end in */
837 (save-excursion
838 (back-to-indentation)
839 (looking-at (concat c-current-comment-prefix "[ \t]*$"))))
840 (end-of-line)
841 (delete-horizontal-space)
842 (or (eq (char-before) ?*) (insert-char ?* 1))) ; Do I need a t (retain sticky properties) here?
843
844 (setq indentp (and (not arg)
845 c-syntactic-indentation
846 c-electric-flag
677 (eq last-command-char ?/) 847 (eq last-command-char ?/)
678 (or (and (eq ch ?/) 848 (eq (char-before) (if literal ?* ?/))))
679 (not literal))
680 (and (eq ch ?*)
681 literal))
682 ))
683 ;; shut this up
684 (c-echo-syntactic-information-p nil))
685 (self-insert-command (prefix-numeric-value arg)) 849 (self-insert-command (prefix-numeric-value arg))
686 (if indentp 850 (if indentp
687 (indent-according-to-mode)))) 851 (indent-according-to-mode))))
688 852
689(defun c-electric-star (arg) 853(defun c-electric-star (arg)
690 "Insert a star character. 854 "Insert a star character.
691If the star is the second character of a C style comment introducing 855If `c-electric-flag' and `c-syntactic-indentation' are both non-nil, and
692construct, and we are on a comment-only-line, indent line as comment. 856the star is the second character of a C style comment starter on a
693If a numeric ARG is supplied, point is inside a literal, or 857comment-only-line, indent the line as a comment. If a numeric ARG is
694`c-syntactic-indentation' is nil, indentation is inhibited." 858supplied, point is inside a literal, or `c-syntactic-indentation' is nil,
859this indentation is inhibited."
860
695 (interactive "*P") 861 (interactive "*P")
696 (self-insert-command (prefix-numeric-value arg)) 862 (self-insert-command (prefix-numeric-value arg))
697 ;; if we are in a literal, or if arg is given do not re-indent the 863 ;; if we are in a literal, or if arg is given do not reindent the
698 ;; current line, unless this star introduces a comment-only line. 864 ;; current line, unless this star introduces a comment-only line.
699 (if (and c-syntactic-indentation 865 (if (c-save-buffer-state ()
700 (not arg) 866 (and c-syntactic-indentation
701 (eq (c-in-literal) 'c) 867 c-electric-flag
702 (eq (char-before) ?*) 868 (not arg)
703 (save-excursion 869 (eq (c-in-literal) 'c)
704 (forward-char -1) 870 (eq (char-before) ?*)
705 (skip-chars-backward "*") 871 (save-excursion
706 (if (eq (char-before) ?/) 872 (forward-char -1)
707 (forward-char -1)) 873 (skip-chars-backward "*")
708 (skip-chars-backward " \t") 874 (if (eq (char-before) ?/)
709 (bolp))) 875 (forward-char -1))
876 (skip-chars-backward " \t")
877 (bolp))))
710 (let (c-echo-syntactic-information-p) ; shut this up 878 (let (c-echo-syntactic-information-p) ; shut this up
711 (indent-according-to-mode)) 879 (indent-according-to-mode))
712 )) 880 ))
713 881
714(defun c-electric-semi&comma (arg) 882(defun c-electric-semi&comma (arg)
715 "Insert a comma or semicolon. 883 "Insert a comma or semicolon.
716When the auto-newline feature is turned on, as evidenced by the \"/a\"
717or \"/ah\" string on the mode line, a newline might be inserted. See
718the variable `c-hanging-semi&comma-criteria' for how newline insertion
719is determined.
720 884
721When a semicolon is inserted, the line is re-indented unless a numeric 885If `c-electric-flag' is non-nil, point isn't inside a literal and a
722arg is supplied, point is inside a literal, or 886numeric ARG hasn't been supplied, the command performs several electric
723`c-syntactic-indentation' is nil. 887actions:
888
889\(a) When the auto-newline feature is turned on (indicated by \"/ln\" on
890the mode line) a newline might be inserted. See the variable
891`c-hanging-semi&comma-criteria' for how newline insertion is determined.
724 892
725Based on the value of `c-cleanup-list', this function cleans up commas 893\(b) Any auto-newlines are indented. The original line is also
726following brace lists and semicolons following defuns." 894reindented unless `c-syntactic-indentation' is nil.
895
896\(c) If auto-newline is turned on, a comma following a brace list or a
897semicolon following a defun might be cleaned up, depending on the
898settings of `c-cleanup-list'."
727 (interactive "*P") 899 (interactive "*P")
728 (let* ((lim (c-most-enclosing-brace (c-parse-state))) 900 (let* (lim literal c-syntactic-context
729 (literal (c-in-literal lim))
730 (here (point)) 901 (here (point))
731 ;; shut this up 902 ;; shut this up
732 (c-echo-syntactic-information-p nil)) 903 (c-echo-syntactic-information-p nil))
733 (if (or literal arg) 904
734 (self-insert-command (prefix-numeric-value arg)) 905 (c-save-buffer-state ()
735 ;; do some special stuff with the character 906 (setq lim (c-most-enclosing-brace (c-parse-state))
736 (self-insert-command (prefix-numeric-value arg)) 907 literal (c-in-literal lim)))
737 ;; do all cleanups and newline insertions if c-auto-newline is 908
738 ;; turned on 909 (self-insert-command (prefix-numeric-value arg))
739 (if (or (not c-auto-newline) 910
740 (not (looking-at "[ \t]*\\\\?$"))) 911 (if (and c-electric-flag (not literal) (not arg))
741 (if c-syntactic-indentation 912 ;; do all cleanups and newline insertions if c-auto-newline is on.
742 (indent-according-to-mode)) 913 (if (or (not c-auto-newline)
743 ;; clean ups 914 (not (looking-at "[ \t]*\\\\?$")))
744 (let ((pos (- (point-max) (point)))) 915 (if c-syntactic-indentation
745 (if (and (or (and 916 (c-indent-line))
746 (eq last-command-char ?,) 917 ;; clean ups: list-close-comma or defun-close-semi
747 (memq 'list-close-comma c-cleanup-list)) 918 (let ((pos (- (point-max) (point))))
748 (and 919 (if (c-save-buffer-state ()
749 (eq last-command-char ?\;) 920 (and (or (and
750 (memq 'defun-close-semi c-cleanup-list))) 921 (eq last-command-char ?,)
751 (progn 922 (memq 'list-close-comma c-cleanup-list))
752 (forward-char -1) 923 (and
753 (c-skip-ws-backward) 924 (eq last-command-char ?\;)
754 (eq (char-before) ?})) 925 (memq 'defun-close-semi c-cleanup-list)))
755 ;; make sure matching open brace isn't in a comment 926 (progn
756 (not (c-in-literal lim))) 927 (forward-char -1)
757 (delete-region (point) here)) 928 (c-skip-ws-backward)
758 (goto-char (- (point-max) pos))) 929 (eq (char-before) ?}))
759 ;; re-indent line 930 ;; make sure matching open brace isn't in a comment
760 (if c-syntactic-indentation 931 (not (c-in-literal lim))))
761 (indent-according-to-mode)) 932 (delete-region (point) here))
762 ;; check to see if a newline should be added 933 (goto-char (- (point-max) pos)))
763 (let ((criteria c-hanging-semi&comma-criteria) 934 ;; reindent line
764 answer add-newline-p) 935 (when c-syntactic-indentation
765 (while criteria 936 (setq c-syntactic-context (c-guess-basic-syntax))
766 (setq answer (funcall (car criteria))) 937 (c-indent-line c-syntactic-context))
767 ;; only nil value means continue checking 938 ;; check to see if a newline should be added
768 (if (not answer) 939 (let ((criteria c-hanging-semi&comma-criteria)
769 (setq criteria (cdr criteria)) 940 answer add-newline-p)
770 (setq criteria nil) 941 (while criteria
771 ;; only 'stop specifically says do not add a newline 942 (setq answer (funcall (car criteria)))
772 (setq add-newline-p (not (eq answer 'stop))) 943 ;; only nil value means continue checking
773 )) 944 (if (not answer)
774 (if add-newline-p 945 (setq criteria (cdr criteria))
775 (c-newline-and-indent)) 946 (setq criteria nil)
776 ))))) 947 ;; only 'stop specifically says do not add a newline
948 (setq add-newline-p (not (eq answer 'stop)))
949 ))
950 (if add-newline-p
951 (c-newline-and-indent))
952 )))))
777 953
778(defun c-electric-colon (arg) 954(defun c-electric-colon (arg)
779 "Insert a colon. 955 "Insert a colon.
780 956
781If the auto-newline feature is turned on, as evidenced by the \"/a\" 957If `c-electric-flag' is non-nil, the colon is not inside a literal and a
782or \"/ah\" string on the mode line, newlines are inserted before and 958numeric ARG hasn't been supplied, the command performs several electric
783after colons based on the value of `c-hanging-colons-alist'. 959actions:
960
961\(a) If the auto-newline feature is turned on (indicated by \"/ln\" on
962the mode line) newlines are inserted before and after the colon based on
963the settings in `c-hanging-colons-alist'.
784 964
785Also, the line is re-indented unless a numeric ARG is supplied, the 965\(b) Any auto-newlines are indented. The original line is also
786colon is inserted inside a literal, or `c-syntactic-indentation' is 966reindented unless `c-syntactic-indentation' is nil.
787nil. 967
968\(c) If auto-newline is turned on, whitespace between two colons will be
969\"cleaned up\" leaving a scope operator, if this action is set in
970`c-cleanup-list'."
788 971
789This function cleans up double colon scope operators based on the
790value of `c-cleanup-list'."
791 (interactive "*P") 972 (interactive "*P")
792 (let* ((bod (c-point 'bod)) 973 (let* ((bod (c-point 'bod))
793 (literal (c-in-literal bod)) 974 (literal (c-save-buffer-state () (c-in-literal bod)))
794 newlines is-scope-op 975 newlines is-scope-op
795 ;; shut this up 976 ;; shut this up
796 (c-echo-syntactic-information-p nil)) 977 (c-echo-syntactic-information-p nil))
797 (cond 978 (self-insert-command (prefix-numeric-value arg))
798 ((or literal arg) 979 ;; Any electric action?
799 (self-insert-command (prefix-numeric-value arg))) 980 (if (and c-electric-flag (not literal) (not arg))
800 ((not (looking-at "[ \t]*\\\\?$")) 981 ;; Unless we're at EOL, only re-indentation happens.
801 (self-insert-command (prefix-numeric-value arg)) 982 (if (not (looking-at "[ \t]*\\\\?$"))
802 (if c-syntactic-indentation 983 (if c-syntactic-indentation
803 (indent-according-to-mode))) 984 (indent-according-to-mode))
804 (t 985
805 ;; insert the colon, then do any specified cleanups 986 ;; scope-operator clean-up?
806 (self-insert-command (prefix-numeric-value arg)) 987 (let ((pos (- (point-max) (point)))
807 (let ((pos (- (point-max) (point))) 988 (here (point)))
808 (here (point))) 989 (if (c-save-buffer-state () ; Why do we need this? [ACM, 2003-03-12]
809 (if (and c-auto-newline 990 (and c-auto-newline
810 (memq 'scope-operator c-cleanup-list) 991 (memq 'scope-operator c-cleanup-list)
811 (eq (char-before) ?:) 992 (eq (char-before) ?:)
812 (progn 993 (progn
813 (forward-char -1) 994 (forward-char -1)
814 (c-skip-ws-backward) 995 (c-skip-ws-backward)
815 (eq (char-before) ?:)) 996 (eq (char-before) ?:))
816 (not (c-in-literal)) 997 (not (c-in-literal))
817 (not (eq (char-after (- (point) 2)) ?:))) 998 (not (eq (char-after (- (point) 2)) ?:))))
818 (progn 999 (progn
819 (delete-region (point) (1- here)) 1000 (delete-region (point) (1- here))
820 (setq is-scope-op t))) 1001 (setq is-scope-op t)))
821 (goto-char (- (point-max) pos))) 1002 (goto-char (- (point-max) pos)))
822 ;; indent the current line if it's done syntactically. 1003
823 (if c-syntactic-indentation 1004 ;; indent the current line if it's done syntactically.
824 ;; Cannot use the same syntax analysis as we find below, 1005 (if c-syntactic-indentation
825 ;; since that's made with c-syntactic-indentation-in-macros 1006 ;; Cannot use the same syntax analysis as we find below,
826 ;; always set to t. 1007 ;; since that's made with c-syntactic-indentation-in-macros
827 (indent-according-to-mode)) 1008 ;; always set to t.
828 (c-save-buffer-state 1009 (indent-according-to-mode))
829 ((c-syntactic-indentation-in-macros t) 1010
830 (c-auto-newline-analysis t) 1011 ;; Calculate where, if anywhere, we want newlines.
831 ;; Turn on syntactic macro analysis to help with auto newlines 1012 (c-save-buffer-state
832 ;; only. 1013 ((c-syntactic-indentation-in-macros t)
833 (syntax (c-guess-basic-syntax)) 1014 (c-auto-newline-analysis t)
834 (elem syntax)) 1015 ;; Turn on syntactic macro analysis to help with auto newlines
835 ;; Translate substatement-label to label for this operation. 1016 ;; only.
836 (while elem 1017 (syntax (c-guess-basic-syntax))
837 (if (eq (car (car elem)) 'substatement-label) 1018 (elem syntax))
838 (setcar (car elem) 'label)) 1019 ;; Translate substatement-label to label for this operation.
839 (setq elem (cdr elem))) 1020 (while elem
840 ;; some language elements can only be determined by checking 1021 (if (eq (car (car elem)) 'substatement-label)
841 ;; the following line. Lets first look for ones that can be 1022 (setcar (car elem) 'label))
842 ;; found when looking on the line with the colon 1023 (setq elem (cdr elem)))
843 (setq newlines 1024 ;; some language elements can only be determined by checking
844 (and c-auto-newline 1025 ;; the following line. Lets first look for ones that can be
845 (or (c-lookup-lists '(case-label label access-label) 1026 ;; found when looking on the line with the colon
846 syntax c-hanging-colons-alist) 1027 (setq newlines
847 (c-lookup-lists '(member-init-intro inher-intro) 1028 (and c-auto-newline
848 (progn 1029 (or (c-lookup-lists '(case-label label access-label)
849 (insert ?\n) 1030 syntax c-hanging-colons-alist)
850 (unwind-protect 1031 (c-lookup-lists '(member-init-intro inher-intro)
851 (c-guess-basic-syntax) 1032 (progn
852 (delete-char -1))) 1033 (insert ?\n)
853 c-hanging-colons-alist))))) 1034 (unwind-protect
854 ;; does a newline go before the colon? Watch out for already 1035 (c-guess-basic-syntax)
855 ;; non-hung colons. However, we don't unhang them because that 1036 (delete-char -1)))
856 ;; would be a cleanup (and anti-social). 1037 c-hanging-colons-alist)))))
857 (if (and (memq 'before newlines) 1038 ;; does a newline go before the colon? Watch out for already
858 (not is-scope-op) 1039 ;; non-hung colons. However, we don't unhang them because that
859 (save-excursion 1040 ;; would be a cleanup (and anti-social).
860 (skip-chars-backward ": \t") 1041 (if (and (memq 'before newlines)
861 (not (bolp)))) 1042 (not is-scope-op)
862 (let ((pos (- (point-max) (point)))) 1043 (save-excursion
863 (forward-char -1) 1044 (skip-chars-backward ": \t")
864 (c-newline-and-indent) 1045 (not (bolp))))
865 (goto-char (- (point-max) pos)))) 1046 (let ((pos (- (point-max) (point))))
866 ;; does a newline go after the colon? 1047 (forward-char -1)
867 (if (and (memq 'after (cdr-safe newlines)) 1048 (c-newline-and-indent)
868 (not is-scope-op)) 1049 (goto-char (- (point-max) pos))))
869 (c-newline-and-indent)) 1050 ;; does a newline go after the colon?
870 )))) 1051 (if (and (memq 'after (cdr-safe newlines))
1052 (not is-scope-op))
1053 (c-newline-and-indent))
1054 ))))
871 1055
872(defun c-electric-lt-gt (arg) 1056(defun c-electric-lt-gt (arg)
873 "Insert a less-than, or greater-than character. 1057 "Insert a \"<\" or \">\" character.
874The line will be re-indented if the character inserted is the second 1058If the current language uses angle bracket parens (e.g. template
875of a C++ style stream operator and the buffer is in C++ mode. 1059arguments in C++), try to find out if the inserted character is a
876Exceptions are when a numeric argument is supplied, point is inside a 1060paren and give it paren syntax if appropriate.
877literal, or `c-syntactic-indentation' is nil, in which case the line 1061
878will not be re-indented." 1062If `c-electric-flag' and `c-syntactic-indentation' are both non-nil, the
1063line will be reindented if the inserted character is a paren or if it
1064finishes a C++ style stream operator in C++ mode. Exceptions are when a
1065numeric argument is supplied, or the point is inside a literal."
1066
879 (interactive "*P") 1067 (interactive "*P")
880 (let ((indentp (and c-syntactic-indentation 1068 (let ((c-echo-syntactic-information-p nil)
881 (not arg) 1069 final-pos close-paren-inserted)
882 (eq (char-before) last-command-char) 1070
883 (not (c-in-literal))))
884 ;; shut this up
885 (c-echo-syntactic-information-p nil))
886 (self-insert-command (prefix-numeric-value arg)) 1071 (self-insert-command (prefix-numeric-value arg))
887 (if indentp 1072 (setq final-pos (point))
888 (indent-according-to-mode)))) 1073
1074 (c-save-buffer-state (c-parse-and-markup-<>-arglists
1075 c-restricted-<>-arglists
1076 <-pos)
1077
1078 (when c-recognize-<>-arglists
1079 (if (eq last-command-char ?<)
1080 (when (and (progn
1081 (backward-char)
1082 (= (point)
1083 (progn
1084 (c-beginning-of-current-token)
1085 (point))))
1086 (progn
1087 (c-backward-token-2)
1088 (looking-at c-opt-<>-sexp-key)))
1089 (c-mark-<-as-paren (1- final-pos)))
1090
1091 ;; It's a ">". Check if there's an earlier "<" which either has
1092 ;; open paren syntax already or that can be recognized as an arglist
1093 ;; together with this ">". Note that this won't work in cases like
1094 ;; "template <x, a < b, y>" but they ought to be rare.
1095
1096 (save-restriction
1097 ;; Narrow to avoid that `c-forward-<>-arglist' below searches past
1098 ;; our position.
1099 (narrow-to-region (point-min) final-pos)
1100
1101 (while (and
1102 (progn
1103 (goto-char final-pos)
1104 (c-syntactic-skip-backward "^<;}" nil t)
1105 (eq (char-before) ?<))
1106 (progn
1107 (backward-char)
1108 ;; If the "<" already got open paren syntax we know we
1109 ;; have the matching closer. Handle it and exit the
1110 ;; loop.
1111 (if (looking-at "\\s\(")
1112 (progn
1113 (c-mark->-as-paren (1- final-pos))
1114 (setq close-paren-inserted t)
1115 nil)
1116 t))
1117
1118 (progn
1119 (setq <-pos (point))
1120 (c-backward-syntactic-ws)
1121 (c-simple-skip-symbol-backward))
1122 (or (looking-at c-opt-<>-sexp-key)
1123 (not (looking-at c-keywords-regexp)))
1124
1125 (let ((c-parse-and-markup-<>-arglists t)
1126 c-restricted-<>-arglists
1127 (containing-sexp
1128 (c-most-enclosing-brace (c-parse-state))))
1129 (when (and containing-sexp
1130 (progn (goto-char containing-sexp)
1131 (eq (char-after) ?\())
1132 (not (eq (get-text-property (point) 'c-type)
1133 'c-decl-arg-start)))
1134 (setq c-restricted-<>-arglists t))
1135 (goto-char <-pos)
1136 (c-forward-<>-arglist nil))
1137
1138 ;; Loop here if the "<" we found above belongs to a nested
1139 ;; angle bracket sexp. When we start over we'll find the
1140 ;; previous or surrounding sexp.
1141 (if (< (point) final-pos)
1142 t
1143 (setq close-paren-inserted t)
1144 nil)))))))
1145 (goto-char final-pos)
1146
1147 ;; Indent the line if appropriate.
1148 (when (and c-electric-flag c-syntactic-indentation)
1149 (backward-char)
1150 (when (prog1 (or (looking-at "\\s\(\\|\\s\)")
1151 (and (c-major-mode-is 'c++-mode)
1152 (progn
1153 (c-beginning-of-current-token)
1154 (looking-at "<<\\|>>"))
1155 (= (match-end 0) final-pos)))
1156 (goto-char final-pos))
1157 (indent-according-to-mode)))
1158
1159 (when (and close-paren-inserted
1160 (not executing-kbd-macro)
1161 blink-paren-function)
1162 ;; Note: Most paren blink functions, such as the standard
1163 ;; `blink-matching-open', currently doesn't handle paren chars
1164 ;; marked with text properties very well. Maybe we should avoid
1165 ;; this call for the time being?
1166 (funcall blink-paren-function))))
889 1167
890(defun c-electric-paren (arg) 1168(defun c-electric-paren (arg)
891 "Insert a parenthesis. 1169 "Insert a parenthesis.
892 1170
893Some newline cleanups are done if appropriate; see the variable 1171If `c-syntactic-indentation' and `c-electric-flag' are both non-nil, the
894`c-cleanup-list'. 1172line is reindented unless a numeric ARG is supplied, or the parenthesis
1173is inserted inside a literal.
895 1174
896Also, the line is re-indented unless a numeric ARG is supplied, the 1175Whitespace between a function name and the parenthesis may get added or
897parenthesis is inserted inside a literal, or `c-syntactic-indentation' 1176removed; see the variable `c-cleanup-list'.
898is nil." 1177
1178Also, if `c-electric-flag' and `c-auto-newline' are both non-nil, some
1179newline cleanups are done if appropriate; see the variable `c-cleanup-list'."
899 (interactive "*P") 1180 (interactive "*P")
900 (let ((literal (c-in-literal (c-point 'bod))) 1181 (let ((literal (c-save-buffer-state () (c-in-literal)))
901 ;; shut this up 1182 ;; shut this up
902 (c-echo-syntactic-information-p nil)) 1183 (c-echo-syntactic-information-p nil))
903 (if (or arg literal) 1184 (self-insert-command (prefix-numeric-value arg))
904 (self-insert-command (prefix-numeric-value arg)) 1185
905 ;; do some special stuff with the character 1186 (if (and (not arg) (not literal))
906 (let* (;; We want to inhibit blinking the paren since this will 1187 (let* ( ;; We want to inhibit blinking the paren since this will
907 ;; be most disruptive. We'll blink it ourselves 1188 ;; be most disruptive. We'll blink it ourselves
908 ;; afterwards. 1189 ;; afterwards.
909 (old-blink-paren blink-paren-function) 1190 (old-blink-paren blink-paren-function)
910 blink-paren-function 1191 blink-paren-function)
911 (noblink (eq last-input-event ?\())) 1192 (if (and c-syntactic-indentation c-electric-flag)
912 (self-insert-command (prefix-numeric-value arg)) 1193 (indent-according-to-mode))
913 (if c-syntactic-indentation 1194
914 (indent-according-to-mode)) 1195 ;; If we're at EOL, check for new-line clean-ups.
915 (when (looking-at "[ \t]*\\\\?$") 1196 (when (and c-electric-flag c-auto-newline
916 (when c-auto-newline 1197 (looking-at "[ \t]*\\\\?$"))
917 ;; Do all appropriate clean ups 1198
918 (let ((here (point)) 1199 ;; clean up brace-elseif-brace
919 (pos (- (point-max) (point))) 1200 (when
920 mbeg mend) 1201 (and (memq 'brace-elseif-brace c-cleanup-list)
921 ;; clean up brace-elseif-brace 1202 (eq last-command-char ?\()
922 (if (and (memq 'brace-elseif-brace c-cleanup-list) 1203 (re-search-backward
923 (eq last-command-char ?\() 1204 (concat "}"
924 (re-search-backward 1205 "\\([ \t\n]\\|\\\\\n\\)*"
925 (concat "}" 1206 "else"
926 "\\([ \t\n]\\|\\\\\n\\)*" 1207 "\\([ \t\n]\\|\\\\\n\\)+"
927 "else" 1208 "if"
928 "\\([ \t\n]\\|\\\\\n\\)+" 1209 "\\([ \t\n]\\|\\\\\n\\)*"
929 "if" 1210 "("
930 "\\([ \t\n]\\|\\\\\n\\)*" 1211 "\\=")
931 "(") 1212 nil t)
932 nil t) 1213 (not (c-save-buffer-state () (c-in-literal))))
933 (save-excursion 1214 (delete-region (match-beginning 0) (match-end 0))
934 (setq mbeg (match-beginning 0) 1215 (insert-and-inherit "} else if ("))
935 mend (match-end 0)) 1216
936 (= mend here)) 1217 ;; clean up brace-catch-brace
937 (not (c-in-literal))) 1218 (when
938 (progn 1219 (and (memq 'brace-catch-brace c-cleanup-list)
939 (delete-region mbeg mend) 1220 (eq last-command-char ?\()
940 (insert-and-inherit "} else if (")) 1221 (re-search-backward
941 ;; clean up brace-catch-brace 1222 (concat "}"
942 (goto-char here) 1223 "\\([ \t\n]\\|\\\\\n\\)*"
943 (if (and (memq 'brace-catch-brace c-cleanup-list) 1224 "catch"
944 (eq last-command-char ?\() 1225 "\\([ \t\n]\\|\\\\\n\\)*"
945 (re-search-backward 1226 "("
946 (concat "}" 1227 "\\=")
947 "\\([ \t\n]\\|\\\\\n\\)*" 1228 nil t)
948 "catch" 1229 (not (c-save-buffer-state () (c-in-literal))))
949 "\\([ \t\n]\\|\\\\\n\\)*" 1230 (delete-region (match-beginning 0) (match-end 0))
950 "(") 1231 (insert-and-inherit "} catch (")))
951 nil t) 1232
952 (save-excursion 1233 ;; Check for clean-ups at function calls. These two DON'T need
953 (setq mbeg (match-beginning 0) 1234 ;; `c-electric-flag' or `c-syntactic-indentation' set.
954 mend (match-end 0)) 1235 ;; Point is currently just after the inserted paren.
955 (= mend here)) 1236 (let (beg (end (1- (point))))
956 (not (c-in-literal))) 1237 (cond
957 (progn 1238
958 (delete-region mbeg mend) 1239 ;; space-before-funcall clean-up?
959 (insert-and-inherit "} catch (")))) 1240 ((and (memq 'space-before-funcall c-cleanup-list)
960 (goto-char (- (point-max) pos)) 1241 (eq last-command-char ?\()
961 ))) 1242 (save-excursion
962 (let (beg (end (1- (point)))) 1243 (backward-char)
963 (cond ((and (memq 'space-before-funcall c-cleanup-list) 1244 (skip-chars-backward " \t")
964 (eq last-command-char ?\() 1245 (setq beg (point))
965 (save-excursion 1246 (c-save-buffer-state () (c-on-identifier))))
966 (backward-char) 1247 (save-excursion
967 (skip-chars-backward " \t") 1248 (delete-region beg end)
968 (setq beg (point)) 1249 (goto-char beg)
969 (c-on-identifier))) 1250 (insert ?\ )))
970 (save-excursion 1251
971 (delete-region beg end) 1252 ;; compact-empty-funcall clean-up?
972 (goto-char beg) 1253 ((c-save-buffer-state ()
973 (insert ?\ ))) 1254 (and (memq 'compact-empty-funcall c-cleanup-list)
974 ((and (memq 'compact-empty-funcall c-cleanup-list) 1255 (eq last-command-char ?\))
975 (eq last-command-char ?\)) 1256 (save-excursion
976 (save-excursion 1257 (c-safe (backward-char 2))
977 (c-safe (backward-char 2)) 1258 (when (looking-at "()")
978 (when (looking-at "()") 1259 (setq end (point))
979 (setq end (point)) 1260 (skip-chars-backward " \t")
980 (skip-chars-backward " \t") 1261 (setq beg (point))
981 (setq beg (point)) 1262 (c-on-identifier)))))
982 (c-on-identifier)))) 1263 (delete-region beg end))))
983 (delete-region beg end)))) 1264 (and (eq last-input-event ?\))
984 (and (not executing-kbd-macro) 1265 (not executing-kbd-macro)
985 old-blink-paren 1266 old-blink-paren
986 (not noblink) 1267 (funcall old-blink-paren))))))
987 (funcall old-blink-paren))))))
988 1268
989(defun c-electric-continued-statement () 1269(defun c-electric-continued-statement ()
990 "Reindent the current line if appropriate. 1270 "Reindent the current line if appropriate.
@@ -995,16 +1275,18 @@ continues an earlier statement is typed, e.g. an \"else\" or the
995 1275
996The line is reindented if there is nothing but whitespace before the 1276The line is reindented if there is nothing but whitespace before the
997keyword on the line, the keyword is not inserted inside a literal, and 1277keyword on the line, the keyword is not inserted inside a literal, and
998`c-syntactic-indentation' is non-nil." 1278`c-electric-flag' and `c-syntactic-indentation' are both non-nil."
999 (let (;; shut this up 1279 (let (;; shut this up
1000 (c-echo-syntactic-information-p nil)) 1280 (c-echo-syntactic-information-p nil))
1001 (when (and c-syntactic-indentation 1281 (when (c-save-buffer-state ()
1002 (not (eq last-command-char ?_)) 1282 (and c-electric-flag
1003 (= (save-excursion 1283 c-syntactic-indentation
1004 (skip-syntax-backward "w") 1284 (not (eq last-command-char ?_))
1005 (point)) 1285 (= (save-excursion
1006 (c-point 'boi)) 1286 (skip-syntax-backward "w")
1007 (not (c-in-literal (c-point 'bod)))) 1287 (point))
1288 (c-point 'boi))
1289 (not (c-in-literal (c-point 'bod)))))
1008 ;; Have to temporarily insert a space so that 1290 ;; Have to temporarily insert a space so that
1009 ;; c-guess-basic-syntax recognizes the keyword. Follow the 1291 ;; c-guess-basic-syntax recognizes the keyword. Follow the
1010 ;; space with a nonspace to avoid messing up any whitespace 1292 ;; space with a nonspace to avoid messing up any whitespace
@@ -1016,36 +1298,19 @@ keyword on the line, the keyword is not inserted inside a literal, and
1016 (delete-char -2))))) 1298 (delete-char -2)))))
1017 1299
1018 1300
1019;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
1020;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com
1021(defun c-forward-into-nomenclature (&optional arg) 1301(defun c-forward-into-nomenclature (&optional arg)
1022 "Move forward to end of a nomenclature section or word. 1302 "Compatibility alias for `c-forward-subword'."
1023With arg, do it arg times."
1024 (interactive "p") 1303 (interactive "p")
1025 (let ((case-fold-search nil)) 1304 (require 'cc-subword)
1026 (if (> arg 0) 1305 (c-forward-subword arg))
1027 (re-search-forward 1306(make-obsolete 'c-forward-into-nomenclature 'c-forward-subword)
1028 (cc-eval-when-compile
1029 (concat "\\W*\\([" c-upper "]*[" c-lower c-digit "]*\\)"))
1030 (point-max) t arg)
1031 (while (and (< arg 0)
1032 (re-search-backward
1033 (cc-eval-when-compile
1034 (concat
1035 "\\(\\(\\W\\|[" c-lower c-digit "]\\)[" c-upper "]+"
1036 "\\|\\W\\w+\\)"))
1037 (point-min) 0))
1038 (forward-char 1)
1039 (setq arg (1+ arg)))))
1040 (c-keep-region-active))
1041 1307
1042(defun c-backward-into-nomenclature (&optional arg) 1308(defun c-backward-into-nomenclature (&optional arg)
1043 "Move backward to beginning of a nomenclature section or word. 1309 "Compatibility alias for `c-backward-subword'."
1044With optional ARG, move that many times. If ARG is negative, move
1045forward."
1046 (interactive "p") 1310 (interactive "p")
1047 (c-forward-into-nomenclature (- arg)) 1311 (require 'cc-subword)
1048 (c-keep-region-active)) 1312 (c-backward-subword arg))
1313(make-obsolete 'c-backward-into-nomenclature 'c-backward-subword)
1049 1314
1050(defun c-scope-operator () 1315(defun c-scope-operator ()
1051 "Insert a double colon scope operator at point. 1316 "Insert a double colon scope operator at point.
@@ -1246,6 +1511,8 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
1246 ;; following one is chosen instead (if there is any). The end 1511 ;; following one is chosen instead (if there is any). The end
1247 ;; position is at the next line, providing there is one before the 1512 ;; position is at the next line, providing there is one before the
1248 ;; declaration. 1513 ;; declaration.
1514 ;;
1515 ;; This function might do hidden buffer changes.
1249 (save-excursion 1516 (save-excursion
1250 1517
1251 ;; Note: Some code duplication in `c-beginning-of-defun' and 1518 ;; Note: Some code duplication in `c-beginning-of-defun' and
@@ -1369,6 +1636,604 @@ function does not require the declaration to contain a brace block."
1369 (push-mark (cdr decl-limits) nil t)))) 1636 (push-mark (cdr decl-limits) nil t))))
1370 1637
1371 1638
1639(defun c-in-comment-line-prefix-p ()
1640 ;; Point is within a comment. Is it also within a comment-prefix?
1641 ;; Space at BOL which precedes a comment-prefix counts as part of it.
1642 ;;
1643 ;; This function might do hidden buffer changes.
1644 (let ((here (point)))
1645 (save-excursion
1646 (beginning-of-line)
1647 (skip-chars-forward " \t")
1648 (and (looking-at c-current-comment-prefix)
1649 (/= (match-beginning 0) (match-end 0))
1650 (< here (match-end 0))))))
1651
1652(defun c-narrow-to-comment-innards (range)
1653 ;; Narrow to the "inside" of the comment (block) defined by range, as
1654 ;; follows:
1655 ;;
1656 ;; A c-style block comment has its opening "/*" and its closing "*/" (if
1657 ;; present) removed. A c++-style line comment retains its opening "//" but
1658 ;; has any final NL removed. If POINT is currently outwith these innards,
1659 ;; move it to the appropriate boundary.
1660 ;;
1661 ;; This narrowing simplifies the sentence movement functions, since it
1662 ;; eliminates awkward things at the boundaries of the comment (block).
1663 ;;
1664 ;; This function might do hidden buffer changes.
1665 (let* ((lit-type (c-literal-type range))
1666 (beg (if (eq lit-type 'c) (+ (car range) 2) (car range)))
1667 (end (if (eq lit-type 'c)
1668 (if (and (eq (char-before (cdr range)) ?/)
1669 (eq (char-before (1- (cdr range))) ?*))
1670 (- (cdr range) 2)
1671 (point-max))
1672 (if (eq (cdr range) (point-max))
1673 (point-max)
1674 (- (cdr range) 1)))))
1675 (if (> (point) end)
1676 (goto-char end)) ; This would be done automatically by ...
1677 (if (< (point) beg)
1678 (goto-char beg)) ; ... narrow-to-region but is not documented.
1679 (narrow-to-region beg end)))
1680
1681(defun c-beginning-of-sentence-in-comment (range)
1682 ;; Move backwards to the "beginning of a sentence" within the comment
1683 ;; defined by RANGE, a cons of its starting and ending positions. If we
1684 ;; find a BOS, return NIL. Otherwise, move point to just before the start
1685 ;; of the comment and return T.
1686 ;;
1687 ;; The BOS is either text which follows a regexp match of sentence-end,
1688 ;; or text which is a beginning of "paragraph".
1689 ;; Comment-prefixes are treated like WS when calculating BOSes or BOPs.
1690 ;;
1691 ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
1692 ;; It is not a general function, but is intended only for calling from
1693 ;; c-move-over-sentence. Not all preconditions have been explicitly stated.
1694 ;;
1695 ;; This function might do hidden buffer changes.
1696 (save-match-data
1697 (let ((start-point (point)))
1698 (save-restriction
1699 (c-narrow-to-comment-innards range) ; This may move point back.
1700 (let* ((here (point))
1701 last
1702 (here-filler ; matches WS and comment-prefices at point.
1703 (concat "\\=\\(^[ \t]*\\(" c-current-comment-prefix "\\)"
1704 "\\|[ \t\n\r\f]\\)*"))
1705 (prefix-at-bol-here ; matches WS and prefix at BOL, just before point
1706 (concat "^[ \t]*\\(" c-current-comment-prefix "\\)[ \t\n\r\f]*\\="))
1707 ;; First, find the previous paragraph start, if any.
1708 (par-beg ; point where non-WS/non-prefix text of paragraph starts.
1709 (save-excursion
1710 (forward-paragraph -1) ; uses cc-mode values of
1711 ; paragraph-\(start\|separate\)
1712 (if (> (re-search-forward here-filler nil t) here)
1713 (goto-char here))
1714 (when (>= (point) here)
1715 (forward-paragraph -2)
1716 (if (> (re-search-forward here-filler nil t) here)
1717 (goto-char here)))
1718 (point))))
1719
1720 ;; Now seek successively earlier sentence ends between PAR-BEG and
1721 ;; HERE, until the "start of sentence" following it is earlier than
1722 ;; HERE, or we hit PAR-BEG. Beware of comment prefices!
1723 (while (and (re-search-backward (c-sentence-end) par-beg 'limit)
1724 (setq last (point))
1725 (goto-char (match-end 0)) ; tentative beginning of sentence
1726 (or (>= (point) here)
1727 (and (not (bolp)) ; Found a non-blank comment-prefix?
1728 (save-excursion
1729 (if (re-search-backward prefix-at-bol-here nil t)
1730 (/= (match-beginning 1) (match-end 1)))))
1731 (progn ; Skip the crud to find a real b-o-s.
1732 (if (c-in-comment-line-prefix-p)
1733 (beginning-of-line))
1734 (re-search-forward here-filler) ; always succeeds.
1735 (>= (point) here))))
1736 (goto-char last))
1737 (re-search-forward here-filler)))
1738
1739 (if (< (point) start-point)
1740 nil
1741 (goto-char (car range))
1742 t))))
1743
1744(defun c-end-of-sentence-in-comment (range)
1745 ;; Move forward to the "end of a sentence" within the comment defined by
1746 ;; RANGE, a cons of its starting and ending positions (enclosing the opening
1747 ;; comment delimiter and the terminating */ or newline). If we find an EOS,
1748 ;; return NIL. Otherwise, move point to just after the end of the comment
1749 ;; and return T.
1750 ;;
1751 ;; The EOS is just after the non-WS part of the next match of the regexp
1752 ;; sentence-end. Typically, this is just after one of [.!?]. If there is
1753 ;; no sentence-end match following point, any WS before the end of the
1754 ;; comment will count as EOS, providing we're not already in it.
1755 ;;
1756 ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
1757 ;; It is not a general function, but is intended only for calling from
1758 ;; c-move-over-sentence.
1759 ;;
1760 ;; This function might do hidden buffer changes.
1761 (save-match-data
1762 (let ((start-point (point))
1763 ;; (lit-type (c-literal-type range)) ; Commented out, 2005/11/23, ACM
1764 )
1765 (save-restriction
1766 (c-narrow-to-comment-innards range) ; This might move point forwards.
1767 (let* ((here (point))
1768 (par-end ; EOL position of last text in current/next paragraph.
1769 (save-excursion
1770 ;; The cc-mode values of paragraph-\(start\|separate\), set
1771 ;; in c-setup-paragraph-variables, are used in the
1772 ;; following.
1773 (forward-paragraph 1)
1774 (if (eq (preceding-char) ?\n) (forward-char -1))
1775 (when (<= (point) here) ; can happen, e.g., when HERE is at EOL.
1776 (goto-char here)
1777 (forward-paragraph 2)
1778 (if (eq (preceding-char) ?\n) (forward-char -1)))
1779 (point)))
1780
1781 last
1782 (prefix-at-bol-here
1783 (concat "^[ \t]*\\(" c-current-comment-prefix "\\)\\=")))
1784 ;; Go forward one "comment-prefix which looks like sentence-end"
1785 ;; each time round the following:
1786 (while (and (re-search-forward (c-sentence-end) par-end 'limit)
1787 (progn
1788 (setq last (point))
1789 (skip-chars-backward " \t\n")
1790 (or (and (not (bolp))
1791 (re-search-backward prefix-at-bol-here nil t)
1792 (/= (match-beginning 1) (match-end 1)))
1793 (<= (point) here))))
1794 (goto-char last))
1795
1796 ;; Take special action if we're up against the end of a comment (of
1797 ;; either sort): Leave point just after the last non-ws text.
1798 (if (eq (point) (point-max))
1799 (while (or (/= (skip-chars-backward " \t\n") 0)
1800 (and (re-search-backward prefix-at-bol-here nil t)
1801 (/= (match-beginning 1) (match-end 1))))))))
1802
1803 (if (> (point) start-point)
1804 nil
1805 (goto-char (cdr range))
1806 t))))
1807
1808(defun c-beginning-of-sentence-in-string (range)
1809 ;; Move backwards to the "beginning of a sentence" within the string defined
1810 ;; by RANGE, a cons of its starting and ending positions (enclosing the
1811 ;; string quotes). If we find a BOS, return NIL. Otherwise, move point to
1812 ;; just before the start of the string and return T.
1813 ;;
1814 ;; The BOS is either the text which follows a regexp match of sentence-end
1815 ;; or text which is a beginning of "paragraph". For the purposes of
1816 ;; determining paragraph boundaries, escaped newlines are treated as
1817 ;; ordinary newlines.
1818 ;;
1819 ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
1820 ;; It is not a general function, but is intended only for calling from
1821 ;; c-move-over-sentence.
1822 ;;
1823 ;; This function might do hidden buffer changes.
1824 (save-match-data
1825 (let* ((here (point)) last
1826 (end (1- (cdr range)))
1827 (here-filler ; matches WS and escaped newlines at point.
1828 "\\=\\([ \t\n\r\f]\\|\\\\[\n\r]\\)*")
1829 ;; Enhance paragraph-start and paragraph-separate also to recognise
1830 ;; blank lines terminated by escaped EOLs. IT MAY WELL BE that
1831 ;; these values should be customizable user options, or something.
1832 (paragraph-start c-string-par-start)
1833 (paragraph-separate c-string-par-separate)
1834
1835 (par-beg ; beginning of current (or previous) paragraph.
1836 (save-excursion
1837 (save-restriction
1838 (narrow-to-region (1+ (car range)) end)
1839 (forward-paragraph -1) ; uses above values of
1840 ; paragraph-\(start\|separate\)
1841 (if (> (re-search-forward here-filler nil t) here)
1842 (goto-char here))
1843 (when (>= (point) here)
1844 (forward-paragraph -2)
1845 (if (> (re-search-forward here-filler nil t) here)
1846 (goto-char here)))
1847 (point)))))
1848 ;; Now see if we can find a sentence end after PAR-BEG.
1849 (while (and (re-search-backward c-sentence-end-with-esc-eol par-beg 'limit)
1850 (setq last (point))
1851 (goto-char (match-end 0))
1852 (or (> (point) end)
1853 (progn
1854 (re-search-forward
1855 here-filler end t) ; always succeeds. Use end rather
1856 ; than here, in case point starts
1857 ; beyond the closing quote.
1858 (>= (point) here))))
1859 (goto-char last))
1860 (re-search-forward here-filler here t)
1861 (if (< (point) here)
1862 nil
1863 (goto-char (car range))
1864 t))))
1865
1866(defun c-end-of-sentence-in-string (range)
1867 ;; Move forward to the "end of a sentence" within the string defined by
1868 ;; RANGE, a cons of its starting and ending positions. If we find an EOS,
1869 ;; return NIL. Otherwise, move point to just after the end of the string
1870 ;; and return T.
1871 ;;
1872 ;; The EOS is just after the non-WS part of the next match of the regexp
1873 ;; sentence-end. Typically, this is just after one of [.!?]. If there is
1874 ;; no sentence-end match following point, any WS before the end of the
1875 ;; string will count as EOS, providing we're not already in it.
1876 ;;
1877 ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
1878 ;; It is not a general function, but is intended only for calling from
1879 ;; c-move-over-sentence.
1880 ;;
1881 ;; This function might do hidden buffer changes.
1882 (save-match-data
1883 (let* ((here (point))
1884 last
1885 ;; Enhance paragraph-start and paragraph-separate to recognise
1886 ;; blank lines terminated by escaped EOLs.
1887 (paragraph-start c-string-par-start)
1888 (paragraph-separate c-string-par-separate)
1889
1890 (par-end ; EOL position of last text in current/next paragraph.
1891 (save-excursion
1892 (save-restriction
1893 (narrow-to-region (car range) (1- (cdr range)))
1894 ;; The above values of paragraph-\(start\|separate\) are used
1895 ;; in the following.
1896 (forward-paragraph 1)
1897 (setq last (point))
1898 ;; (re-search-backward filler-here nil t) would find an empty
1899 ;; string. Therefore we simulate it by the following:
1900 (while (or (/= (skip-chars-backward " \t\n\r\f") 0)
1901 (re-search-backward "\\\\\\($\\)\\=" nil t)))
1902 (unless (> (point) here)
1903 (goto-char last)
1904 (forward-paragraph 1)
1905 (while (or (/= (skip-chars-backward " \t\n\r\f") 0)
1906 (re-search-backward "\\\\\\($\\)\\=" nil t))))
1907 (point)))))
1908 ;; Try to go forward a sentence.
1909 (when (re-search-forward c-sentence-end-with-esc-eol par-end 'limit)
1910 (setq last (point))
1911 (while (or (/= (skip-chars-backward " \t\n") 0)
1912 (re-search-backward "\\\\\\($\\)\\=" nil t))))
1913 ;; Did we move a sentence, or did we hit the end of the string?
1914 (if (> (point) here)
1915 nil
1916 (goto-char (cdr range))
1917 t))))
1918
1919(defun c-ascertain-preceding-literal ()
1920 ;; Point is not in a literal (i.e. comment or string (include AWK regexp)).
1921 ;; If a literal is the next thing (aside from whitespace) to be found before
1922 ;; point, return a cons of its start.end positions (enclosing the
1923 ;; delimiters). Otherwise return NIL.
1924 ;;
1925 ;; This function might do hidden buffer changes.
1926 (save-excursion
1927 (c-collect-line-comments
1928 (let ((here (point))
1929 pos)
1930 (if (c-backward-single-comment)
1931 (cons (point) (progn (c-forward-single-comment) (point)))
1932 (save-restriction
1933 ;; to prevent `looking-at' seeing a " at point.
1934 (narrow-to-region (point-min) here)
1935 (when
1936 (or
1937 ;; An EOL can act as an "open string" terminator in AWK.
1938 (looking-at c-ws*-string-limit-regexp)
1939 (and (not (bobp))
1940 (progn (backward-char)
1941 (looking-at c-string-limit-regexp))))
1942 (goto-char (match-end 0)) ; just after the string terminator.
1943 (setq pos (point))
1944 (c-safe (c-backward-sexp 1) ; move back over the string.
1945 (cons (point) pos)))))))))
1946
1947(defun c-ascertain-following-literal ()
1948 ;; Point is not in a literal (i.e. comment or string (include AWK regexp)).
1949 ;; If a literal is the next thing (aside from whitespace) following point,
1950 ;; return a cons of its start.end positions (enclosing the delimiters).
1951 ;; Otherwise return NIL.
1952 ;;
1953 ;; This function might do hidden buffer changes.
1954 (save-excursion
1955 (c-collect-line-comments
1956 (let (pos)
1957 (c-skip-ws-forward)
1958 (if (looking-at c-string-limit-regexp) ; string-delimiter.
1959 (cons (point) (or (c-safe (progn (c-forward-sexp 1) (point)))
1960 (point-max)))
1961 (setq pos (point))
1962 (if (c-forward-single-comment)
1963 (cons pos (point))))))))
1964
1965(defun c-after-statement-terminator-p () ; Should we pass in LIM here?
1966 ;; Does point immediately follow a statement "terminator"? A virtual
1967 ;; semicolon is regarded here as such. So is a an opening brace ;-)
1968 ;;
1969 ;; This function might do hidden buffer changes.
1970 (or (save-excursion
1971 (backward-char)
1972 (and (looking-at "[;{}]")
1973 (not (and c-special-brace-lists ; Pike special brace lists.
1974 (eq (char-after) ?{)
1975 (c-looking-at-special-brace-list)))))
1976 (c-at-vsemi-p)
1977 ;; The following (for macros) is not strict about exactly where we are
1978 ;; wrt white space at the end of the macro. Doesn't seem to matter too
1979 ;; much. ACM 2004/3/29.
1980 (let (eom)
1981 (save-excursion
1982 (if (c-beginning-of-macro)
1983 (setq eom (progn (c-end-of-macro)
1984 (point)))))
1985 (when eom
1986 (save-excursion
1987 (c-forward-comments)
1988 (>= (point) eom))))))
1989
1990(defun c-back-over-illiterals (macro-start)
1991 ;; Move backwards over code which isn't a literal (i.e. comment or string),
1992 ;; stopping before reaching BOB or a literal or the boundary of a
1993 ;; preprocessor statement or the "beginning of a statement". MACRO-START is
1994 ;; the position of the '#' beginning the current preprocessor directive, or
1995 ;; NIL if we're not in such.
1996 ;;
1997 ;; Return a cons (A.B), where
1998 ;; A is NIL if we moved back to a BOS (and know it), T otherwise (we
1999 ;; didn't move, or we hit a literal, or we're not sure about BOS).
2000 ;; B is MACRO-BOUNDARY if we are about to cross the boundary out of or
2001 ;; into a macro, otherwise LITERAL if we've hit a literal, otherwise NIL
2002 ;;
2003 ;; The total collection of returned values is as follows:
2004 ;; (nil . nil): Found a BOS whilst remaining inside the illiterals.
2005 ;; (t . literal): No BOS found: only a comment/string. We _might_ be at
2006 ;; a BOS - the caller must check this.
2007 ;; (nil . macro-boundary): only happens with non-nil macro-start. We've
2008 ;; moved and reached the opening # of the macro.
2009 ;; (t . macro-boundary): Every other circumstance in which we're at a
2010 ;; macro-boundary. We might be at a BOS.
2011 ;;
2012 ;; Point is left either at the beginning-of-statement, or at the last non-ws
2013 ;; code before encountering the literal/BOB or macro-boundary.
2014 ;;
2015 ;; Note that this function moves within either preprocessor commands
2016 ;; (macros) or normal code, but will not cross a boundary between the two,
2017 ;; or between two distinct preprocessor commands.
2018 ;;
2019 ;; Stop before `{' and after `;', `{', `}' and `};' when not followed by `}'
2020 ;; or `)', but on the other side of the syntactic ws. Move by sexps and
2021 ;; move into parens. Also stop before `#' when it's at boi on a line.
2022 ;;
2023 ;; This function might do hidden buffer changes.
2024 (save-match-data
2025 (let ((here (point))
2026 last) ; marks the position of non-ws code, what'll be BOS if, say, a
2027 ; semicolon precedes it.
2028 (catch 'done
2029 (while t ;; We go back one "token" each iteration of the loop.
2030 (setq last (point))
2031 (cond
2032 ;; Stop at the token after a comment.
2033 ((c-backward-single-comment) ; Also functions as backwards-ws.
2034 (goto-char last)
2035 (throw 'done '(t . literal)))
2036
2037 ;; If we've gone back over a LF, we might have moved into or out of
2038 ;; a preprocessor line.
2039 ((and (save-excursion
2040 (beginning-of-line)
2041 (re-search-forward "\\(^\\|[^\\]\\)[\n\r]" last t))
2042 (if macro-start
2043 (< (point) macro-start)
2044 (c-beginning-of-macro)))
2045 (goto-char last)
2046 ;; Return a car of NIL ONLY if we've hit the opening # of a macro.
2047 (throw 'done (cons (or (eq (point) here)
2048 (not macro-start))
2049 'macro-boundary)))
2050
2051 ;; Have we found a virtual semicolon? If so, stop, unless the next
2052 ;; statement is where we started from.
2053 ((and (c-at-vsemi-p)
2054 (< last here)
2055 (not (memq (char-after last) '(?\) ?})))) ; we've moved back from ) or }
2056 (goto-char last)
2057 (throw 'done '(nil . nil)))
2058
2059 ;; Hit the beginning of the buffer/region?
2060 ((bobp)
2061 (if (/= here last)
2062 (goto-char last))
2063 (throw 'done '(nil . nil)))
2064
2065 ;; Move back a character.
2066 ((progn (backward-char) nil))
2067
2068 ;; Stop at "{" (unless it's a PIKE special brace list.)
2069 ((eq (char-after) ?\{)
2070 (if (and c-special-brace-lists
2071 (c-looking-at-special-brace-list))
2072 (skip-syntax-backward "w_") ; Speedup only.
2073 (if (/= here last)
2074 (goto-char last))
2075 (throw 'done '(nil . nil))))
2076
2077 ;; Have we reached the start of a macro? This always counts as
2078 ;; BOS. (N.B. I don't think (eq (point) here) can ever be true
2079 ;; here. FIXME!!! ACM 2004/3/29)
2080 ((and macro-start (eq (point) macro-start))
2081 (throw 'done (cons (eq (point) here) 'macro-boundary)))
2082
2083 ;; Stop at token just after "}" or ";".
2084 ((looking-at "[;}]")
2085 ;; If we've gone back over ;, {, or }, we're done.
2086 (if (or (= here last)
2087 (memq (char-after last) '(?\) ?}))) ; we've moved back from ) or }
2088 (if (and (eq (char-before) ?}) ; If };, treat them as a unit.
2089 (eq (char-after) ?\;))
2090 (backward-char))
2091 (goto-char last) ; To the statement starting after the ; or }.
2092 (throw 'done '(nil . nil))))
2093
2094 ;; Stop at the token after a string.
2095 ((looking-at c-string-limit-regexp) ; Just gone back over a string terminator?
2096 (goto-char last)
2097 (throw 'done '(t . literal)))
2098
2099 ;; Nothing special: go back word characters.
2100 (t (skip-syntax-backward "w_")) ; Speedup only.
2101 ))))))
2102
2103(defun c-forward-over-illiterals (macro-end allow-early-stop)
2104 ;; Move forwards over code, stopping before reaching EOB or a literal
2105 ;; (i.e. a comment/string) or the boundary of a preprocessor statement or
2106 ;; the "end of a statement". MACRO-END is the position of the EOL/EOB which
2107 ;; terminates the current preprocessor directive, or NIL if we're not in
2108 ;; such.
2109 ;;
2110 ;; ALLOW-EARLY-STOP is non-nil if it is permissible to return without moving
2111 ;; forward at all, should we encounter a `{'. This is an ugly kludge, but
2112 ;; seems unavoidable. Depending on the context this function is called
2113 ;; from, we _sometimes_ need to stop there. Currently (2004/4/3),
2114 ;; ALLOW-EARLY-STOP is applied only to open braces, not to virtual
2115 ;; semicolons, or anything else.
2116 ;;
2117 ;; Return a cons (A.B), where
2118 ;; A is NIL if we moved forward to an EOS, or stay at one (when
2119 ;; ALLOW-EARLY-STOP is set), T otherwise (we hit a literal).
2120 ;; B is 'MACRO-BOUNDARY if we are about to cross the boundary out of or
2121 ;; into a macro, otherwise 'LITERAL if we've hit a literal, otherwise NIL
2122 ;;
2123 ;; Point is left either after the end-of-statement, or at the last non-ws
2124 ;; code before encountering the literal, or the # of the preprocessor
2125 ;; statement, or at EOB [or just after last non-WS stuff??].
2126 ;;
2127 ;; As a clarification of "after the end-of-statement", if a comment or
2128 ;; whitespace follows a completed AWK statement, that statement is treated
2129 ;; as ending just after the last non-ws character before the comment.
2130 ;;
2131 ;; Note that this function moves within either preprocessor commands
2132 ;; (macros) or normal code, but not both within the same invocation.
2133 ;;
2134 ;; Stop before `{', `}', and `#' when it's at boi on a line, but on the
2135 ;; other side of the syntactic ws, and after `;', `}' and `};'. Only
2136 ;; stop before `{' if at top level or inside braces, though. Move by
2137 ;; sexps and move into parens. Also stop at eol of lines with `#' at
2138 ;; the boi.
2139 ;;
2140 ;; This function might do hidden buffer changes.
2141 (let ((here (point))
2142 last)
2143 (catch 'done
2144 (while t ;; We go one "token" forward each time round this loop.
2145 (setq last (point))
2146
2147 ;; If we've moved forward to a virtual semicolon, we're done.
2148 (if (and (> last here) ; Should we check ALLOW-EARLY-STOP, here? 2004/4/3
2149 (c-at-vsemi-p))
2150 (throw 'done '(nil . nil)))
2151
2152 (c-skip-ws-forward)
2153 (cond
2154 ;; Gone past the end of a macro?
2155 ((and macro-end (> (point) macro-end))
2156 (goto-char last)
2157 (throw 'done (cons (eq (point) here) 'macro-boundary)))
2158
2159 ;; About to hit a comment?
2160 ((save-excursion (c-forward-single-comment))
2161 (goto-char last)
2162 (throw 'done '(t . literal)))
2163
2164 ;; End of buffer?
2165 ((eobp)
2166 (if (/= here last)
2167 (goto-char last))
2168 (throw 'done '(nil . nil)))
2169
2170 ;; If we encounter a '{', stop just after the previous token.
2171 ((and (eq (char-after) ?{)
2172 (not (and c-special-brace-lists
2173 (c-looking-at-special-brace-list)))
2174 (or allow-early-stop (/= here last))
2175 (save-excursion ; Is this a check that we're NOT at top level?
2176;;;; NO! This seems to check that (i) EITHER we're at the top level; OR (ii) The next enclosing
2177;;;; level of bracketing is a '{'. HMM. Doesn't seem to make sense.
2178;;;; 2003/8/8 This might have something to do with the GCC extension "Statement Expressions", e.g.
2179;;;; while ({stmt1 ; stmt2 ; exp ;}). This form excludes such Statement Expressions.
2180 (or (not (c-safe (up-list -1) t))
2181 (= (char-after) ?{))))
2182 (goto-char last)
2183 (throw 'done '(nil . nil)))
2184
2185 ;; End of a PIKE special brace list? If so, step over it and continue.
2186 ((and c-special-brace-lists
2187 (eq (char-after) ?})
2188 (save-excursion
2189 (and (c-safe (up-list -1) t)
2190 (c-looking-at-special-brace-list))))
2191 (forward-char)
2192 (skip-syntax-forward "w_")) ; Speedup only.
2193
2194 ;; Have we got a '}' after having moved? If so, stop after the
2195 ;; previous token.
2196 ((and (eq (char-after) ?})
2197 (/= here last))
2198 (goto-char last)
2199 (throw 'done '(nil . nil)))
2200
2201 ;; Stop if we encounter a preprocessor line.
2202 ((and (not macro-end)
2203 (eq (char-after) ?#)
2204 (= (point) (c-point 'boi)))
2205 (goto-char last)
2206 ;(throw 'done (cons (eq (point) here) 'macro-boundary))) ; Changed 2003/3/26
2207 (throw 'done '(t . macro-boundary)))
2208
2209 ;; Stop after a ';', '}', or "};"
2210 ((looking-at ";\\|};?")
2211 (goto-char (match-end 0))
2212 (throw 'done '(nil . nil)))
2213
2214 ;; Found a string (this subsumes AWK regexps)?
2215 ((looking-at c-string-limit-regexp)
2216 (goto-char last)
2217 (throw 'done '(t . literal)))
2218
2219 (t
2220 (forward-char) ; Can't fail - we checked (eobp) earlier on.
2221 (skip-syntax-forward "w_") ; Speedup only.
2222 (when (and macro-end (> (point) macro-end))
2223 (goto-char last)
2224 (throw 'done (cons (eq (point) here) 'macro-boundary))))
2225 )))))
2226
2227(defun c-one-line-string-p (range)
2228 ;; Is the literal defined by RANGE a string contained in a single line?
2229 ;;
2230 ;; This function might do hidden buffer changes.
2231 (save-excursion
2232 (goto-char (car range))
2233 (and (looking-at c-string-limit-regexp)
2234 (progn (skip-chars-forward "^\n" (cdr range))
2235 (eq (point) (cdr range))))))
2236
1372(defun c-beginning-of-statement (&optional count lim sentence-flag) 2237(defun c-beginning-of-statement (&optional count lim sentence-flag)
1373 "Go to the beginning of the innermost C statement. 2238 "Go to the beginning of the innermost C statement.
1374With prefix arg, go back N - 1 statements. If already at the 2239With prefix arg, go back N - 1 statements. If already at the
@@ -1382,318 +2247,93 @@ repetition count, a buffer position limit which is the farthest back
1382to search for the syntactic context, and a flag saying whether to do 2247to search for the syntactic context, and a flag saying whether to do
1383sentence motion in or near comments and multiline strings. 2248sentence motion in or near comments and multiline strings.
1384 2249
1385Note that `c-beginning-of-statement-1' is usually better to use from 2250Note that for use in programs, `c-beginning-of-statement-1' is
1386programs. It has much more well defined semantics than this one, 2251usually better. It has much better defined semantics than this one,
1387which is intended for interactive use and might therefore change to be 2252which is intended for interactive use, and might therefore change to
1388more \"DWIM:ey\"." 2253be more \"DWIM:ey\"."
1389 (interactive (list (prefix-numeric-value current-prefix-arg) 2254 (interactive (list (prefix-numeric-value current-prefix-arg)
1390 nil t)) 2255 nil t))
1391 (c-save-buffer-state 2256 (if (< count 0)
1392 ((count (or count 1)) 2257 (c-end-of-statement (- count) lim sentence-flag)
1393 here 2258 (c-save-buffer-state
1394 (range (c-collect-line-comments (c-literal-limits lim)))) 2259 ((count (or count 1))
1395 (while (and (/= count 0) 2260 last ; start point for going back ONE chunk. Updated each chunk movement.
1396 (or (not lim) (> (point) lim))) 2261 (macro-fence
1397 (setq here (point)) 2262 (save-excursion (and (not (bobp)) (c-beginning-of-macro) (point))))
1398 (if (and (not range) sentence-flag) 2263 res ; result from sub-function call
1399 (save-excursion 2264 not-bos ; "not beginning-of-statement"
1400 ;; Find the comment next to point if we're not in one. 2265 (range (c-collect-line-comments (c-literal-limits lim)))) ; (start.end) of current literal or NIL
1401 (if (> count 0) 2266
1402 (if (c-backward-single-comment) 2267 ;; Go back one statement at each iteration of the following loop.
1403 (setq range (cons (point) 2268 (while (and (/= count 0)
1404 (progn (c-forward-single-comment) 2269 (or (not lim) (> (point) lim)))
1405 (point)))) 2270 ;; Go back one "chunk" each time round the following loop, stopping
1406 (c-skip-ws-backward) 2271 ;; when we reach a statement boundary, etc.
1407 (setq range (point)) 2272 (setq last (point))
1408 (setq range 2273 (while
1409 (if (eq (char-before) ?\") 2274 (cond ; Each arm of this cond returns NIL on reaching a desired
1410 (c-safe (c-backward-sexp 1) 2275 ; statement boundary, non-NIL otherwise.
1411 (cons (point) range))))) 2276 ((bobp)
1412 (c-skip-ws-forward) 2277 (setq count 0)
1413 (if (eq (char-after) ?\") 2278 nil)
1414 (setq range (cons (point) 2279
1415 (progn 2280 (range ; point is within or approaching a literal.
1416 (c-forward-sexp 1) 2281 (cond
1417 (point)))) 2282 ;; Single line string or sentence-flag is null => skip the
1418 (setq range (point)) 2283 ;; entire literal.
1419 (setq range (if (c-forward-single-comment) 2284 ((or (null sentence-flag)
1420 (cons range (point)) 2285 (c-one-line-string-p range))
1421 nil)))) 2286 (goto-char (car range))
1422 (setq range (c-collect-line-comments range)))) 2287 (setq range (c-ascertain-preceding-literal))
1423 (if (and (< count 0) (= here (point-max))) 2288 ;; N.B. The following is essentially testing for an AWK regexp
1424 ;; Special case because eob might be in a literal. 2289 ;; at BOS:
1425 (setq range nil)) 2290 ;; Was the previous non-ws thing an end of statement?
1426 (if range 2291 (save-excursion
1427 (if (and sentence-flag 2292 (if macro-fence
1428 (or (/= (char-syntax (char-after (car range))) ?\") 2293 (c-backward-comments)
1429 ;; Only visit a string if it spans more than one line. 2294 (c-backward-syntactic-ws))
1430 (save-excursion 2295 (not (or (bobp) (c-after-statement-terminator-p)))))
1431 (goto-char (car range)) 2296
1432 (skip-chars-forward "^\n" (cdr range)) 2297 ;; Comment inside a statement or a multi-line string.
1433 (< (point) (cdr range))))) 2298 (t (when (setq res ; returns non-nil when we go out of the literal
1434 (let* ((lit-type (c-literal-type range)) 2299 (if (eq (c-literal-type range) 'string)
1435 (line-prefix (concat "[ \t]*\\(" 2300 (c-beginning-of-sentence-in-string range)
1436 c-current-comment-prefix 2301 (c-beginning-of-sentence-in-comment range)))
1437 "\\)[ \t]*")) 2302 (setq range (c-ascertain-preceding-literal)))
1438 (beg (if (eq lit-type 'string) 2303 res)))
1439 (1+ (car range)) 2304
1440 (save-excursion 2305 ;; Non-literal code.
1441 (goto-char (car range)) 2306 (t (setq res (c-back-over-illiterals macro-fence))
1442 (max (progn 2307 (setq not-bos ; "not reached beginning-of-statement".
1443 (looking-at comment-start-skip) 2308 (or (= (point) last)
1444 (match-end 0)) 2309 (memq (char-after) '(?\) ?\}))
1445 (progn 2310 (and
1446 (looking-at line-prefix) 2311 (car res)
1447 (match-end 0)))))) 2312 ;; We're at a tentative BOS. The next form goes
1448 (end (- (cdr range) (if (eq lit-type 'c) 2 1))) 2313 ;; back over WS looking for an end of previous
1449 (beg-of-para (if (eq lit-type 'string) 2314 ;; statement.
1450 (lambda ()) 2315 (not (save-excursion
1451 (lambda () 2316 (if macro-fence
1452 (beginning-of-line) 2317 (c-backward-comments)
1453 (if (looking-at line-prefix) 2318 (c-backward-syntactic-ws))
1454 (goto-char (match-end 0))))))) 2319 (or (bobp) (c-after-statement-terminator-p)))))))
1455 (save-restriction 2320 ;; Are we about to move backwards into or out of a
1456 ;; Move by sentence, but not past the limit of the 2321 ;; preprocessor command? If so, locate it's beginning.
1457 ;; literal, narrowed to the appropriate 2322 (when (eq (cdr res) 'macro-boundary)
1458 ;; paragraph(s). 2323 (save-excursion
1459 (narrow-to-region (save-excursion 2324 (beginning-of-line)
1460 (let ((pos (min here end))) 2325 (setq macro-fence
1461 (goto-char pos) 2326 (and (not (bobp))
1462 (forward-paragraph -1) 2327 (progn (c-skip-ws-backward) (c-beginning-of-macro))
1463 (if (looking-at paragraph-separate) 2328 (point)))))
1464 (forward-line)) 2329 ;; Are we about to move backwards into a literal?
1465 (when (> (point) beg) 2330 (when (memq (cdr res) '(macro-boundary literal))
1466 (funcall beg-of-para) 2331 (setq range (c-ascertain-preceding-literal)))
1467 (when (>= (point) pos) 2332 not-bos))
1468 (forward-paragraph -2) 2333 (setq last (point)))
1469 (funcall beg-of-para))) 2334
1470 (max (point) beg))) 2335 (if (/= count 0) (setq count (1- count))))
1471 end) 2336 (c-keep-region-active))))
1472 (c-safe (forward-sentence (if (< count 0) 1 -1)))
1473 (if (and (memq lit-type '(c c++))
1474 ;; Check if we stopped due to a comment
1475 ;; prefix and not a sentence end.
1476 (/= (point) (point-min))
1477 (/= (point) (point-max))
1478 (save-excursion
1479 (beginning-of-line)
1480 (looking-at line-prefix))
1481 (>= (point) (match-beginning 0))
1482 (/= (match-beginning 1) (match-end 1))
1483 (or (< (point) (match-end 0))
1484 (and
1485 (= (point) (match-end 0))
1486 ;; The comment prefix may contain
1487 ;; characters that is regarded as end
1488 ;; of sentence.
1489 (or (eolp)
1490 (and
1491 (save-excursion
1492 (forward-paragraph -1)
1493 (< (point) (match-beginning 0)))
1494 (save-excursion
1495 (beginning-of-line)
1496 (or (not (re-search-backward
1497 (sentence-end)
1498 (c-point 'bopl)
1499 t))
1500 (< (match-end 0)
1501 (c-point 'eol)))))))))
1502 (setq count (+ count (if (< count 0) -1 1)))
1503 (if (< count 0)
1504 (progn
1505 ;; In block comments, if there's only
1506 ;; horizontal ws between the text and the
1507 ;; comment ender, stop before it. Stop after
1508 ;; the ender if there's either nothing or
1509 ;; newlines between.
1510 (when (and (eq lit-type 'c)
1511 (eq (point) (point-max)))
1512 (widen)
1513 (when (or (= (skip-chars-backward " \t") 0)
1514 (eq (point) (point-max))
1515 (bolp))
1516 (goto-char (cdr range)))))
1517 (when (and (eq (point) (point-min))
1518 (looking-at "[ \t]*\\\\?$"))
1519 ;; Stop before instead of after the comment
1520 ;; starter if nothing follows it.
1521 (widen)
1522 (goto-char (car range))
1523 (if (and (eq lit-type 'string) (/= (point) here))
1524 (setq count (1+ count)
1525 range nil))))))
1526 ;; See if we should escape the literal.
1527 (if (> count 0)
1528 (if (< (point) here)
1529 (setq count (1- count))
1530 (goto-char (car range))
1531 (setq range nil))
1532 (if (> (point) here)
1533 (setq count (1+ count))
1534 (goto-char (cdr range))
1535 (setq range nil))))
1536 (goto-char (if (> count 0) (car range) (cdr range)))
1537 (setq range nil))
1538 (goto-char here)
1539 (if (> count 0)
1540 (condition-case nil
1541 ;; Stop before `{' and after `;', `{', `}' and `};'
1542 ;; when not followed by `}' or `)', but on the other
1543 ;; side of the syntactic ws. Move by sexps and move
1544 ;; into parens. Also stop before `#' when it's at boi
1545 ;; on a line.
1546 (let ((literal-pos (not sentence-flag))
1547 last last-below-line)
1548 (catch 'done
1549 (while t
1550 (setq last (point))
1551 (when (and (or (eq (char-after) ?\{)
1552 (and (eq (char-after) ?#)
1553 (eq (point) (c-point 'boi)))
1554 )
1555 (/= here last))
1556 (unless (and c-special-brace-lists
1557 (eq (char-after) ?{)
1558 (c-looking-at-special-brace-list))
1559 (if (and (eq (char-after) ?#)
1560 (numberp last-below-line)
1561 (not (eq last-below-line here)))
1562 (goto-char last-below-line))
1563 (throw 'done t)))
1564 ;; Don't know why I added the following, but it
1565 ;; doesn't work when point is preceded by a line
1566 ;; style comment. /mast
1567 ;;(c-skip-ws-backward)
1568 (if literal-pos
1569 (c-backward-comments)
1570 (when (c-backward-single-comment)
1571 ;; Record position of first comment.
1572 (save-excursion
1573 (c-forward-single-comment)
1574 (setq literal-pos (point)))
1575 (c-backward-comments)))
1576 (unless last-below-line
1577 (if (save-excursion
1578 (re-search-forward "\\(^\\|[^\\]\\)$" last t))
1579 (setq last-below-line last)))
1580 (cond ((bobp) ; Must handle bob specially.
1581 (if (= here last)
1582 (throw 'done t)
1583 (goto-char last)
1584 (throw 'done t)))
1585 ((progn (backward-char)
1586 (looking-at "[;{}]"))
1587 (if (and c-special-brace-lists
1588 (eq (char-after) ?{)
1589 (c-looking-at-special-brace-list))
1590 (skip-syntax-backward "w_") ; Speedup only.
1591 (if (or (= here last)
1592 (memq (char-after last) '(?\) ?})))
1593 (if (and (eq (char-before) ?})
1594 (eq (char-after) ?\;))
1595 (backward-char))
1596 (goto-char last)
1597 (throw 'done t))))
1598 ((= (char-syntax (char-after)) ?\")
1599 (let ((end (point)))
1600 (forward-char)
1601 (c-backward-sexp)
1602 (save-excursion
1603 (skip-chars-forward "^\n" end)
1604 (when (< (point) end)
1605 ;; Break at multiline string.
1606 (setq literal-pos (1+ end))
1607 (throw 'done t)))))
1608 (t (skip-syntax-backward "w_")) ; Speedup only.
1609 )))
1610 (if (and (numberp literal-pos)
1611 (< (point) literal-pos))
1612 ;; We jumped over a comment or string that
1613 ;; should be investigated.
1614 (goto-char literal-pos)
1615 (setq count (1- count))))
1616 (error
1617 (goto-char (point-min))
1618 (setq count 0)))
1619 (condition-case nil
1620 ;; Stop before `{', `}', and `#' when it's at boi on a
1621 ;; line, but on the other side of the syntactic ws, and
1622 ;; after `;', `}' and `};'. Only stop before `{' if at
1623 ;; top level or inside braces, though. Move by sexps
1624 ;; and move into parens. Also stop at eol of lines
1625 ;; with `#' at the boi.
1626 (let ((literal-pos (not sentence-flag))
1627 last)
1628 (catch 'done
1629 (while t
1630 (setq last (point))
1631 (if literal-pos
1632 (c-forward-comments)
1633 (if (progn
1634 (c-skip-ws-forward)
1635 ;; Record position of first comment.
1636 (setq literal-pos (point))
1637 (c-forward-single-comment))
1638 (c-forward-comments)
1639 (setq literal-pos nil)))
1640 (cond ((and (eq (char-after) ?{)
1641 (not (and c-special-brace-lists
1642 (c-looking-at-special-brace-list)))
1643 (/= here last)
1644 (save-excursion
1645 (or (not (c-safe (up-list -1) t))
1646 (= (char-after) ?{))))
1647 (goto-char last)
1648 (throw 'done t))
1649 ((and c-special-brace-lists
1650 (eq (char-after) ?})
1651 (save-excursion
1652 (and (c-safe (up-list -1) t)
1653 (c-looking-at-special-brace-list))))
1654 (forward-char 1)
1655 (skip-syntax-forward "w_")) ; Speedup only.
1656 ((and (eq (char-after) ?})
1657 (/= here last))
1658 (goto-char last)
1659 (throw 'done t))
1660; ((and (eq (char-after) ?#)
1661; (= (point) (c-point 'boi)))
1662; (if (= here last)
1663; (or (re-search-forward "\\(^\\|[^\\]\\)$" nil t)
1664; (goto-char (point-max)))
1665; (goto-char last))
1666; (throw 'done t))
1667 ((looking-at ";\\|};?")
1668 (goto-char (match-end 0))
1669 (throw 'done t))
1670 ((= (char-syntax (char-after)) ?\")
1671 (let ((beg (point)))
1672 (c-forward-sexp)
1673 (save-excursion
1674 (skip-chars-backward "^\n" beg)
1675 (when (> (point) beg)
1676 ;; Break at multiline string.
1677 (setq literal-pos beg)
1678 (throw 'done t)))))
1679 (t
1680 (forward-char 1)
1681 (skip-syntax-forward "w_")) ; Speedup only.
1682 )))
1683 (if (and (numberp literal-pos)
1684 (> (point) literal-pos))
1685 ;; We jumped over a comment that should be investigated.
1686 (goto-char literal-pos)
1687 (setq count (1+ count))))
1688 (error
1689 (goto-char (point-max))
1690 (setq count 0)))
1691 ))
1692 ;; If we haven't moved we're near a buffer limit.
1693 (when (and (not (zerop count)) (= (point) here))
1694 (goto-char (if (> count 0) (point-min) (point-max)))
1695 (setq count 0))))
1696 (c-keep-region-active))
1697 2337
1698(defun c-end-of-statement (&optional count lim sentence-flag) 2338(defun c-end-of-statement (&optional count lim sentence-flag)
1699 "Go to the end of the innermost C statement. 2339 "Go to the end of the innermost C statement.
@@ -1708,8 +2348,77 @@ to search for the syntactic context, and a flag saying whether to do
1708sentence motion in or near comments and multiline strings." 2348sentence motion in or near comments and multiline strings."
1709 (interactive (list (prefix-numeric-value current-prefix-arg) 2349 (interactive (list (prefix-numeric-value current-prefix-arg)
1710 nil t)) 2350 nil t))
1711 (c-beginning-of-statement (- (or count 1)) lim sentence-flag) 2351 (setq count (or count 1))
1712 (c-keep-region-active)) 2352 (if (< count 0) (c-beginning-of-statement (- count) lim sentence-flag)
2353
2354 (c-save-buffer-state
2355 (here ; start point for going forward ONE statement. Updated each statement.
2356 (macro-fence
2357 (save-excursion
2358 (and (not (eobp)) (c-beginning-of-macro)
2359 (progn (c-end-of-macro) (point)))))
2360 res
2361 (range (c-collect-line-comments (c-literal-limits lim)))) ; (start.end) of current literal or NIL
2362
2363 ;; Go back/forward one statement at each iteration of the following loop.
2364 (while (and (/= count 0)
2365 (or (not lim) (< (point) lim)))
2366 (setq here (point)) ; ONLY HERE is HERE updated
2367
2368 ;; Go forward one "chunk" each time round the following loop, stopping
2369 ;; when we reach a statement boundary, etc.
2370 (while
2371 (cond ; Each arm of this cond returns NIL on reaching a desired
2372 ; statement boundary, non-NIL otherwise.
2373 ((eobp)
2374 (setq count 0)
2375 nil)
2376
2377 (range ; point is within a literal.
2378 (cond
2379 ;; sentence-flag is null => skip the entire literal.
2380 ;; or a Single line string.
2381 ((or (null sentence-flag)
2382 (c-one-line-string-p range))
2383 (goto-char (cdr range))
2384 (setq range (c-ascertain-following-literal))
2385 ;; Is there a virtual semicolon here (e.g. for AWK)?
2386 (not (c-at-vsemi-p)))
2387
2388 ;; Comment or multi-line string.
2389 (t (when (setq res ; gets non-nil when we go out of the literal
2390 (if (eq (c-literal-type range) 'string)
2391 (c-end-of-sentence-in-string range)
2392 (c-end-of-sentence-in-comment range)))
2393 (setq range (c-ascertain-following-literal)))
2394 ;; If we've just come forward out of a literal, check for
2395 ;; vsemi. (N.B. AWK can't have a vsemi after a comment, but
2396 ;; some other language may do in the future)
2397 (and res
2398 (not (c-at-vsemi-p))))))
2399
2400 ;; Non-literal code.
2401 (t (setq res (c-forward-over-illiterals macro-fence
2402 (> (point) here)))
2403 ;; Are we about to move forward into or out of a
2404 ;; preprocessor command?
2405 (when (eq (cdr res) 'macro-boundary)
2406 (save-excursion
2407 (end-of-line)
2408 (setq macro-fence
2409 (and (not (eobp))
2410 (progn (c-skip-ws-forward)
2411 (c-beginning-of-macro))
2412 (progn (c-end-of-macro)
2413 (point))))))
2414 ;; Are we about to move forward into a literal?
2415 (when (memq (cdr res) '(macro-boundary literal))
2416 (setq range (c-ascertain-following-literal)))
2417 (car res))))
2418
2419 (if (/= count 0) (setq count (1- count))))
2420 (c-keep-region-active))))
2421
1713 2422
1714 2423
1715;; set up electric character functions to work with pending-del, 2424;; set up electric character functions to work with pending-del,
@@ -1737,6 +2446,7 @@ sentence motion in or near comments and multiline strings."
1737 2446
1738 2447
1739(defun c-calc-comment-indent (entry) 2448(defun c-calc-comment-indent (entry)
2449 ;; This function might do hidden buffer changes.
1740 (if (symbolp entry) 2450 (if (symbolp entry)
1741 (setq entry (or (assq entry c-indent-comment-alist) 2451 (setq entry (or (assq entry c-indent-comment-alist)
1742 (assq 'other c-indent-comment-alist) 2452 (assq 'other c-indent-comment-alist)
@@ -1760,7 +2470,7 @@ sentence motion in or near comments and multiline strings."
1760 (let ((lim (c-literal-limits (c-point 'bol) t))) 2470 (let ((lim (c-literal-limits (c-point 'bol) t)))
1761 (when (consp lim) 2471 (when (consp lim)
1762 (goto-char (car lim)) 2472 (goto-char (car lim))
1763 (when (looking-at "/[/*]") 2473 (when (looking-at "/[/*]") ; FIXME!!! Adapt for AWK! (ACM, 2005/11/18)
1764 ;; Found comment to align with. 2474 ;; Found comment to align with.
1765 (if (bolp) 2475 (if (bolp)
1766 ;; Do not pad with one space if we're at bol. 2476 ;; Do not pad with one space if we're at bol.
@@ -1835,15 +2545,16 @@ See `c-indent-comment-alist' for a description."
1835A prefix argument acts as a repeat count. With a negative argument, 2545A prefix argument acts as a repeat count. With a negative argument,
1836move forward to the end of the containing preprocessor conditional. 2546move forward to the end of the containing preprocessor conditional.
1837 2547
1838`#elif' is treated like `#else' followed by `#if', so the function 2548\"#elif\" is treated like \"#else\" followed by \"#if\", so the
1839stops at them when going backward, but not when going forward." 2549function stops at them when going backward, but not when going
2550forward."
1840 (interactive "p") 2551 (interactive "p")
1841 (c-forward-conditional (- count) -1) 2552 (c-forward-conditional (- count) -1)
1842 (c-keep-region-active)) 2553 (c-keep-region-active))
1843 2554
1844(defun c-up-conditional-with-else (count) 2555(defun c-up-conditional-with-else (count)
1845 "Move back to the containing preprocessor conditional, including `#else'. 2556 "Move back to the containing preprocessor conditional, including \"#else\".
1846Just like `c-up-conditional', except it also stops at `#else' 2557Just like `c-up-conditional', except it also stops at \"#else\"
1847directives." 2558directives."
1848 (interactive "p") 2559 (interactive "p")
1849 (c-forward-conditional (- count) -1 t) 2560 (c-forward-conditional (- count) -1 t)
@@ -1854,15 +2565,16 @@ directives."
1854A prefix argument acts as a repeat count. With a negative argument, 2565A prefix argument acts as a repeat count. With a negative argument,
1855move backward into the previous preprocessor conditional. 2566move backward into the previous preprocessor conditional.
1856 2567
1857`#elif' is treated like `#else' followed by `#if', so the function 2568\"#elif\" is treated like \"#else\" followed by \"#if\", so the
1858stops at them when going forward, but not when going backward." 2569function stops at them when going forward, but not when going
2570backward."
1859 (interactive "p") 2571 (interactive "p")
1860 (c-forward-conditional count 1) 2572 (c-forward-conditional count 1)
1861 (c-keep-region-active)) 2573 (c-keep-region-active))
1862 2574
1863(defun c-down-conditional-with-else (count) 2575(defun c-down-conditional-with-else (count)
1864 "Move forward into the next preprocessor conditional, including `#else'. 2576 "Move forward into the next preprocessor conditional, including \"#else\".
1865Just like `c-down-conditional', except it also stops at `#else' 2577Just like `c-down-conditional', except it also stops at \"#else\"
1866directives." 2578directives."
1867 (interactive "p") 2579 (interactive "p")
1868 (c-forward-conditional count 1 t) 2580 (c-forward-conditional count 1 t)
@@ -1881,16 +2593,16 @@ move forward across a preprocessor conditional."
1881A prefix argument acts as a repeat count. With a negative argument, 2593A prefix argument acts as a repeat count. With a negative argument,
1882move backward across a preprocessor conditional. 2594move backward across a preprocessor conditional.
1883 2595
1884`#elif' is treated like `#else' followed by `#if', except that the 2596\"#elif\" is treated like \"#else\" followed by \"#if\", except that
1885nesting level isn't changed when tracking subconditionals. 2597the nesting level isn't changed when tracking subconditionals.
1886 2598
1887The optional argument TARGET-DEPTH specifies the wanted nesting depth 2599The optional argument TARGET-DEPTH specifies the wanted nesting depth
1888after each scan. I.e. if TARGET-DEPTH is -1, the function will move 2600after each scan. I.e. if TARGET-DEPTH is -1, the function will move
1889out of the enclosing conditional. A non-integer non-nil TARGET-DEPTH 2601out of the enclosing conditional. A non-integer non-nil TARGET-DEPTH
1890counts as -1. 2602counts as -1.
1891 2603
1892If the optional argument WITH-ELSE is non-nil, `#else' directives are 2604If the optional argument WITH-ELSE is non-nil, \"#else\" directives
1893treated as conditional clause limits. Normally they are ignored." 2605are treated as conditional clause limits. Normally they are ignored."
1894 (interactive "p") 2606 (interactive "p")
1895 (let* ((forward (> count 0)) 2607 (let* ((forward (> count 0))
1896 (increment (if forward -1 1)) 2608 (increment (if forward -1 1))
@@ -1996,15 +2708,15 @@ prefix argument is equivalent to -1.
1996 just inserts a tab character, or the equivalent number of spaces, 2708 just inserts a tab character, or the equivalent number of spaces,
1997 depending on the variable `indent-tabs-mode'." 2709 depending on the variable `indent-tabs-mode'."
1998 2710
1999 (interactive "p") 2711 (interactive "P")
2000 (let ((indent-function 2712 (let ((indent-function
2001 (if c-syntactic-indentation 2713 (if c-syntactic-indentation
2002 (symbol-function 'indent-according-to-mode) 2714 (symbol-function 'indent-according-to-mode)
2003 (lambda () 2715 (lambda ()
2004 (let ((c-macro-start c-macro-start) 2716 (let ((c-macro-start c-macro-start)
2005 (steps (cond ((not current-prefix-arg) 1) 2717 (steps (if (equal arg '(4))
2006 ((equal current-prefix-arg '(4)) -1) 2718 -1
2007 (t arg)))) 2719 (prefix-numeric-value arg))))
2008 (c-shift-line-indentation (* steps c-basic-offset)) 2720 (c-shift-line-indentation (* steps c-basic-offset))
2009 (when (and c-auto-align-backslashes 2721 (when (and c-auto-align-backslashes
2010 (save-excursion 2722 (save-excursion
@@ -2014,7 +2726,7 @@ prefix argument is equivalent to -1.
2014 ;; Realign the line continuation backslash if inside a macro. 2726 ;; Realign the line continuation backslash if inside a macro.
2015 (c-backslash-region (point) (point) nil t))) 2727 (c-backslash-region (point) (point) nil t)))
2016 )))) 2728 ))))
2017 (if (and c-syntactic-indentation current-prefix-arg) 2729 (if (and c-syntactic-indentation arg)
2018 ;; If c-syntactic-indentation and got arg, always indent this 2730 ;; If c-syntactic-indentation and got arg, always indent this
2019 ;; line as C and shift remaining lines of expression the same 2731 ;; line as C and shift remaining lines of expression the same
2020 ;; amount. 2732 ;; amount.
@@ -2029,7 +2741,7 @@ prefix argument is equivalent to -1.
2029 shift-amt)) 2741 shift-amt))
2030 (save-excursion 2742 (save-excursion
2031 (if (eq c-tab-always-indent t) 2743 (if (eq c-tab-always-indent t)
2032 (beginning-of-line)) 2744 (beginning-of-line)) ; FIXME!!! What is this here for? ACM 2005/10/31
2033 (setq beg (point)) 2745 (setq beg (point))
2034 (c-forward-sexp 1) 2746 (c-forward-sexp 1)
2035 (setq end (point)) 2747 (setq end (point))
@@ -2040,7 +2752,7 @@ prefix argument is equivalent to -1.
2040 (indent-code-rigidly beg end shift-amt "#"))) 2752 (indent-code-rigidly beg end shift-amt "#")))
2041 ;; Else use c-tab-always-indent to determine behavior. 2753 ;; Else use c-tab-always-indent to determine behavior.
2042 (cond 2754 (cond
2043 ;; CASE 1: indent when at column zero or in lines indentation, 2755 ;; CASE 1: indent when at column zero or in line's indentation,
2044 ;; otherwise insert a tab 2756 ;; otherwise insert a tab
2045 ((not c-tab-always-indent) 2757 ((not c-tab-always-indent)
2046 (if (save-excursion 2758 (if (save-excursion
@@ -2054,7 +2766,7 @@ prefix argument is equivalent to -1.
2054 ;; CASE 3: if in a literal, insert a tab, but always indent the 2766 ;; CASE 3: if in a literal, insert a tab, but always indent the
2055 ;; line 2767 ;; line
2056 (t 2768 (t
2057 (if (c-in-literal) 2769 (if (c-save-buffer-state () (c-in-literal))
2058 (funcall c-insert-tab-function)) 2770 (funcall c-insert-tab-function))
2059 (funcall indent-function) 2771 (funcall indent-function)
2060 ))))) 2772 )))))
@@ -2135,7 +2847,8 @@ non-nil."
2135 ;; shut up any echo msgs on indiv lines 2847 ;; shut up any echo msgs on indiv lines
2136 (c-echo-syntactic-information-p nil) 2848 (c-echo-syntactic-information-p nil)
2137 (in-macro (and c-auto-align-backslashes 2849 (in-macro (and c-auto-align-backslashes
2138 (save-excursion (c-beginning-of-macro)) 2850 (c-save-buffer-state ()
2851 (save-excursion (c-beginning-of-macro)))
2139 start)) 2852 start))
2140 (c-fix-backslashes nil) 2853 (c-fix-backslashes nil)
2141 syntax) 2854 syntax)
@@ -2181,8 +2894,6 @@ non-nil."
2181(defun c-fn-region-is-active-p () 2894(defun c-fn-region-is-active-p ()
2182 ;; Function version of the macro for use in places that aren't 2895 ;; Function version of the macro for use in places that aren't
2183 ;; compiled, e.g. in the menus. 2896 ;; compiled, e.g. in the menus.
2184 ;;
2185 ;; This function does not do any hidden buffer changes.
2186 (c-region-is-active-p)) 2897 (c-region-is-active-p))
2187 2898
2188(defun c-indent-line-or-region () 2899(defun c-indent-line-or-region ()
@@ -2199,7 +2910,6 @@ indent the current line syntactically."
2199(defvar c-progress-info nil) 2910(defvar c-progress-info nil)
2200 2911
2201(defun c-progress-init (start end context) 2912(defun c-progress-init (start end context)
2202 ;; This function does not do any hidden buffer changes.
2203 (cond 2913 (cond
2204 ;; Be silent 2914 ;; Be silent
2205 ((not c-progress-interval)) 2915 ((not c-progress-interval))
@@ -2221,7 +2931,6 @@ indent the current line syntactically."
2221 )) 2931 ))
2222 2932
2223(defun c-progress-update () 2933(defun c-progress-update ()
2224 ;; This function does not do any hidden buffer changes.
2225 (if (not (and c-progress-info c-progress-interval)) 2934 (if (not (and c-progress-info c-progress-interval))
2226 nil 2935 nil
2227 (let ((now (nth 1 (current-time))) 2936 (let ((now (nth 1 (current-time)))
@@ -2238,7 +2947,6 @@ indent the current line syntactically."
2238 ))) 2947 )))
2239 2948
2240(defun c-progress-fini (context) 2949(defun c-progress-fini (context)
2241 ;; This function does not do any hidden buffer changes.
2242 (if (not c-progress-interval) 2950 (if (not c-progress-interval)
2243 nil 2951 nil
2244 (if (or (eq context (aref c-progress-info 3)) 2952 (if (or (eq context (aref c-progress-info 3))
@@ -2399,7 +3107,6 @@ command to conveniently insert and align the necessary backslashes."
2399 (set-marker point-pos nil)))) 3107 (set-marker point-pos nil))))
2400 3108
2401(defun c-append-backslashes-forward (to-mark column point-pos) 3109(defun c-append-backslashes-forward (to-mark column point-pos)
2402 ;; This function does not do any hidden buffer changes.
2403 (let ((state (parse-partial-sexp (c-point 'bol) (point)))) 3110 (let ((state (parse-partial-sexp (c-point 'bol) (point))))
2404 (if column 3111 (if column
2405 (while 3112 (while
@@ -2473,7 +3180,6 @@ command to conveniently insert and align the necessary backslashes."
2473 (bolp)))))) ; forward-line has funny behavior at eob. 3180 (bolp)))))) ; forward-line has funny behavior at eob.
2474 3181
2475(defun c-delete-backslashes-forward (to-mark point-pos) 3182(defun c-delete-backslashes-forward (to-mark point-pos)
2476 ;; This function does not do any hidden buffer changes.
2477 (while 3183 (while
2478 (and (<= (point) to-mark) 3184 (and (<= (point) to-mark)
2479 (progn 3185 (progn
@@ -2518,6 +3224,8 @@ command to conveniently insert and align the necessary backslashes."
2518 ;; comment. Return a cons of the prefix string and the column where 3224 ;; comment. Return a cons of the prefix string and the column where
2519 ;; it ends. If fill-prefix is set, it'll override. Note that this 3225 ;; it ends. If fill-prefix is set, it'll override. Note that this
2520 ;; function also uses the value of point in some heuristics. 3226 ;; function also uses the value of point in some heuristics.
3227 ;;
3228 ;; This function might do hidden buffer changes.
2521 3229
2522 (let* ((here (point)) 3230 (let* ((here (point))
2523 (prefix-regexp (concat "[ \t]*\\(" 3231 (prefix-regexp (concat "[ \t]*\\("
@@ -2877,7 +3585,7 @@ command to conveniently insert and align the necessary backslashes."
2877 ;; If APPLY-OUTSIDE-LITERAL is nil then the function will be called 3585 ;; If APPLY-OUTSIDE-LITERAL is nil then the function will be called
2878 ;; only if the point turns out to be inside a comment or a string. 3586 ;; only if the point turns out to be inside a comment or a string.
2879 ;; 3587 ;;
2880 ;; This function does not do any hidden buffer changes. 3588 ;; Note that this function does not do any hidden buffer changes.
2881 3589
2882 (let (fill 3590 (let (fill
2883 ;; beg and end limits the region to narrow. end is a marker. 3591 ;; beg and end limits the region to narrow. end is a marker.
@@ -2892,6 +3600,10 @@ command to conveniently insert and align the necessary backslashes."
2892 ;; hanging. In that case it's set to the number of spaces 3600 ;; hanging. In that case it's set to the number of spaces
2893 ;; that should be between the text and the ender. 3601 ;; that should be between the text and the ender.
2894 hang-ender-stuck 3602 hang-ender-stuck
3603 ;; auto-fill-spaces is the exact sequence of whitespace between a
3604 ;; comment's last word and the comment ender, temporarily replaced
3605 ;; with 'x's before calling FUN when FILL-PARAGRAPH is nil.
3606 auto-fill-spaces
2895 (here (point)) 3607 (here (point))
2896 (c-lit-limits c-lit-limits) 3608 (c-lit-limits c-lit-limits)
2897 (c-lit-type c-lit-type)) 3609 (c-lit-type c-lit-type))
@@ -2902,29 +3614,30 @@ command to conveniently insert and align the necessary backslashes."
2902 (if (and buffer-undo-list (not (eq buffer-undo-list t))) 3614 (if (and buffer-undo-list (not (eq buffer-undo-list t)))
2903 (setq buffer-undo-list (cons (point) buffer-undo-list))) 3615 (setq buffer-undo-list (cons (point) buffer-undo-list)))
2904 3616
2905 (save-restriction 3617 (c-save-buffer-state ()
2906 ;; Widen to catch comment limits correctly. 3618 (save-restriction
2907 (widen) 3619 ;; Widen to catch comment limits correctly.
2908 (unless c-lit-limits 3620 (widen)
2909 (setq c-lit-limits (c-literal-limits nil fill-paragraph))) 3621 (unless c-lit-limits
2910 (setq c-lit-limits (c-collect-line-comments c-lit-limits)) 3622 (setq c-lit-limits (c-literal-limits nil fill-paragraph)))
2911 (unless c-lit-type 3623 (setq c-lit-limits (c-collect-line-comments c-lit-limits))
2912 (setq c-lit-type (c-literal-type c-lit-limits)))) 3624 (unless c-lit-type
3625 (setq c-lit-type (c-literal-type c-lit-limits))))
2913 3626
2914 (save-excursion 3627 (save-excursion
2915 (unless (c-safe (backward-char) 3628 (unless (c-safe (backward-char)
2916 (forward-paragraph) 3629 (forward-paragraph)
2917 (>= (point) here)) 3630 (>= (point) here))
2918 (goto-char here) 3631 (goto-char here)
2919 (forward-paragraph)) 3632 (forward-paragraph))
2920 (setq end (point-marker))) 3633 (setq end (point-marker)))
2921 (save-excursion 3634 (save-excursion
2922 (unless (c-safe (forward-char) 3635 (unless (c-safe (forward-char)
2923 (backward-paragraph) 3636 (backward-paragraph)
2924 (<= (point) here)) 3637 (<= (point) here))
2925 (goto-char here) 3638 (goto-char here)
2926 (backward-paragraph)) 3639 (backward-paragraph))
2927 (setq beg (point))) 3640 (setq beg (point))))
2928 3641
2929 (unwind-protect 3642 (unwind-protect
2930 (progn 3643 (progn
@@ -2965,73 +3678,76 @@ command to conveniently insert and align the necessary backslashes."
2965 ;; own. Keep it that way. 3678 ;; own. Keep it that way.
2966 (set-marker end (point)))) 3679 (set-marker end (point))))
2967 3680
2968 (if fill-paragraph 3681 ;; The comment ender should hang. Replace all space between
2969 ;; The comment ender should hang. Replace all 3682 ;; it and the last word either by one or two 'x's (when
2970 ;; cruft between it and the last word with one or 3683 ;; FILL-PARAGRAPH is non-nil), or a row of x's the same width
2971 ;; two 'x' and include it in the region. We'll 3684 ;; as the whitespace (when auto filling), and include it in
2972 ;; change them back to spaces afterwards. This 3685 ;; the region. We'll change them back to whitespace
2973 ;; isn't done when auto filling, since that'd 3686 ;; afterwards. The effect of this is to glue the comment
2974 ;; effectively make it impossible to insert extra 3687 ;; ender to the last word in the comment during filling.
2975 ;; spaces before the comment ender. 3688 (let* ((ender-start (save-excursion
2976 (let* ((ender-start (save-excursion 3689 (goto-char (cdr c-lit-limits))
2977 (goto-char (cdr c-lit-limits)) 3690 (skip-syntax-backward "^w ")
2978 (skip-syntax-backward "^w ") 3691 (point)))
2979 (point))) 3692 (ender-column (save-excursion
2980 (point-rel (- ender-start here)) 3693 (goto-char ender-start)
2981 spaces) 3694 (current-column)))
2982 3695 (point-rel (- ender-start here))
2983 (save-excursion 3696 spaces)
2984 (goto-char (cdr c-lit-limits)) 3697
2985 (setq tmp-post (point-marker)) 3698 (save-excursion
2986 (insert ?\n) 3699 (goto-char (cdr c-lit-limits))
2987 (set-marker end (point)) 3700 (setq tmp-post (point-marker))
2988 (forward-line -1) 3701 (insert ?\n)
2989 (if (and (looking-at (concat "[ \t]*\\(\\(" 3702 (set-marker end (point))
2990 c-current-comment-prefix 3703 (forward-line -1) ; last line of the comment
2991 "\\)[ \t]*\\)")) 3704 (if (and (looking-at (concat "[ \t]*\\(\\("
2992 (eq ender-start (match-end 0))) 3705 c-current-comment-prefix
2993 ;; The comment ender is prefixed by nothing 3706 "\\)[ \t]*\\)"))
2994 ;; but a comment line prefix. Remove it 3707 (eq ender-start (match-end 0)))
2995 ;; along with surrounding ws. 3708 ;; The comment ender is prefixed by nothing
2996 (setq spaces (- (match-end 1) (match-end 2))) 3709 ;; but a comment line prefix. Remove it
2997 (goto-char ender-start)) 3710 ;; along with surrounding ws.
2998 (skip-chars-backward " \t\r\n") 3711 (setq spaces (- (match-end 1) (match-end 2)))
2999 3712 (goto-char ender-start))
3000 (if (/= (point) ender-start) 3713 (skip-chars-backward " \t\r\n") ; Surely this can be
3001 (progn 3714 ; " \t"? "*/" is NOT alone on the line (ACM, 2005/8/18)
3002 (if (<= here (point)) 3715
3003 ;; Don't adjust point below if it's 3716 (if (/= (point) ender-start)
3004 ;; before the string we replace. 3717 (progn
3005 (setq point-rel -1)) 3718 (if (<= here (point))
3006 ;; Keep one or two spaces between the 3719 ;; Don't adjust point below if it's
3007 ;; text and the ender, depending on how 3720 ;; before the string we replace.
3008 ;; many there are now. 3721 (setq point-rel -1))
3009 (unless spaces 3722 ;; Keep one or two spaces between the
3010 (setq spaces (- ender-start (point)))) 3723 ;; text and the ender, depending on how
3724 ;; many there are now.
3725 (unless spaces
3726 (setq spaces (- ender-column (current-column))))
3727 (setq auto-fill-spaces (c-delete-and-extract-region
3728 (point) ender-start))
3729 ;; paragraph filling condenses multiple spaces to
3730 ;; single or double spaces. auto-fill doesn't.
3731 (if fill-paragraph
3011 (setq spaces 3732 (setq spaces
3012 (max 3733 (max
3013 (min spaces 3734 (min spaces
3014 (if sentence-end-double-space 2 1)) 3735 (if sentence-end-double-space 2 1))
3015 1)) 3736 1)))
3016 ;; Insert the filler first to keep marks right. 3737 ;; Insert the filler first to keep marks right.
3017 (insert-char ?x spaces t) 3738 (insert-char ?x spaces t)
3018 (delete-region (point) (+ ender-start spaces)) 3739 (setq hang-ender-stuck spaces)
3019 (setq hang-ender-stuck spaces) 3740 (setq point-rel
3020 (setq point-rel 3741 (and (>= point-rel 0)
3021 (and (>= point-rel 0) 3742 (- (point) (min point-rel spaces)))))
3022 (- (point) (min point-rel spaces))))) 3743 (setq point-rel nil)))
3023 (setq point-rel nil))) 3744
3024 3745 (if point-rel
3025 (if point-rel 3746 ;; Point was in the middle of the string we
3026 ;; Point was in the middle of the string we 3747 ;; replaced above, so put it back in the same
3027 ;; replaced above, so put it back in the same 3748 ;; relative position, counting from the end.
3028 ;; relative position, counting from the end. 3749 (goto-char point-rel)))
3029 (goto-char point-rel))) 3750 ))
3030
3031 ;; We're doing auto filling. Just move the marker
3032 ;; to the comment end to ignore any code after the
3033 ;; comment.
3034 (move-marker end (cdr c-lit-limits)))))
3035 3751
3036 (when (<= beg (car c-lit-limits)) 3752 (when (<= beg (car c-lit-limits))
3037 ;; The region includes the comment starter. 3753 ;; The region includes the comment starter.
@@ -3068,14 +3784,15 @@ command to conveniently insert and align the necessary backslashes."
3068 ;; inside macros is bogus to begin with since the line 3784 ;; inside macros is bogus to begin with since the line
3069 ;; continuation backslashes aren't handled). 3785 ;; continuation backslashes aren't handled).
3070 (save-excursion 3786 (save-excursion
3071 (c-beginning-of-macro) 3787 (c-save-buffer-state ()
3072 (beginning-of-line) 3788 (c-beginning-of-macro)
3073 (if (> (point) beg) 3789 (beginning-of-line)
3074 (setq beg (point))) 3790 (if (> (point) beg)
3075 (c-end-of-macro) 3791 (setq beg (point)))
3076 (forward-line) 3792 (c-end-of-macro)
3077 (if (< (point) end) 3793 (forward-line)
3078 (set-marker end (point))))) 3794 (if (< (point) end)
3795 (set-marker end (point))))))
3079 3796
3080 (t ; Other code. 3797 (t ; Other code.
3081 ;; Try to avoid comments and macros in the paragraph to 3798 ;; Try to avoid comments and macros in the paragraph to
@@ -3192,7 +3909,10 @@ Warning: Regexp from `c-comment-prefix-regexp' doesn't match the comment prefix
3192 (goto-char tmp-post) 3909 (goto-char tmp-post)
3193 (skip-syntax-backward "^w ") 3910 (skip-syntax-backward "^w ")
3194 (forward-char (- hang-ender-stuck)) 3911 (forward-char (- hang-ender-stuck))
3195 (insert-char ?\ hang-ender-stuck t) 3912 (if (or fill-paragraph (not auto-fill-spaces))
3913 (insert-char ?\ hang-ender-stuck t)
3914 (insert auto-fill-spaces)
3915 (setq here (- here (- hang-ender-stuck (length auto-fill-spaces)))))
3196 (delete-char hang-ender-stuck) 3916 (delete-char hang-ender-stuck)
3197 (goto-char here)) 3917 (goto-char here))
3198 (set-marker tmp-post nil)) 3918 (set-marker tmp-post nil))
@@ -3233,8 +3953,6 @@ Optional prefix ARG means justify paragraph as well."
3233(defun c-do-auto-fill () 3953(defun c-do-auto-fill ()
3234 ;; Do automatic filling if not inside a context where it should be 3954 ;; Do automatic filling if not inside a context where it should be
3235 ;; ignored. 3955 ;; ignored.
3236 ;;
3237 ;; This function does not do any hidden buffer changes.
3238 (let ((c-auto-fill-prefix 3956 (let ((c-auto-fill-prefix
3239 ;; The decision whether the line should be broken is actually 3957 ;; The decision whether the line should be broken is actually
3240 ;; done in c-indent-new-comment-line, which do-auto-fill 3958 ;; done in c-indent-new-comment-line, which do-auto-fill
@@ -3274,31 +3992,36 @@ If a fill prefix is specified, it overrides all the above."
3274 (c-lit-limits c-lit-limits) 3992 (c-lit-limits c-lit-limits)
3275 (c-lit-type c-lit-type) 3993 (c-lit-type c-lit-type)
3276 (c-macro-start c-macro-start)) 3994 (c-macro-start c-macro-start))
3277 (when (not (eq c-auto-fill-prefix t)) 3995
3278 ;; Called from do-auto-fill. 3996 (c-save-buffer-state ()
3279 (unless c-lit-limits 3997 (when (not (eq c-auto-fill-prefix t))
3280 (setq c-lit-limits (c-literal-limits nil nil t))) 3998 ;; Called from do-auto-fill.
3281 (unless c-lit-type 3999 (unless c-lit-limits
3282 (setq c-lit-type (c-literal-type c-lit-limits))) 4000 (setq c-lit-limits (c-literal-limits nil nil t)))
3283 (if (memq (cond ((c-query-and-set-macro-start) 'cpp) 4001 (unless c-lit-type
3284 ((null c-lit-type) 'code) 4002 (setq c-lit-type (c-literal-type c-lit-limits)))
3285 (t c-lit-type)) 4003 (if (memq (cond ((c-query-and-set-macro-start) 'cpp)
3286 c-ignore-auto-fill) 4004 ((null c-lit-type) 'code)
3287 (setq fill-prefix t) ; Used as flag in the cond. 4005 (t c-lit-type))
3288 (if (and (null c-auto-fill-prefix) 4006 c-ignore-auto-fill)
3289 (eq c-lit-type 'c) 4007 (setq fill-prefix t) ; Used as flag in the cond.
3290 (<= (c-point 'bol) (car c-lit-limits))) 4008 (if (and (null c-auto-fill-prefix)
3291 ;; The adaptive fill function has generated a prefix, but 4009 (eq c-lit-type 'c)
3292 ;; we're on the first line in a block comment so it'll be 4010 (<= (c-point 'bol) (car c-lit-limits)))
3293 ;; wrong. Ignore it to guess a better one below. 4011 ;; The adaptive fill function has generated a prefix, but
3294 (setq fill-prefix nil) 4012 ;; we're on the first line in a block comment so it'll be
3295 (when (and (eq c-lit-type 'c++) 4013 ;; wrong. Ignore it to guess a better one below.
3296 (not (string-match "\\`[ \t]*//" (or fill-prefix "")))) 4014 (setq fill-prefix nil)
3297 ;; Kludge: If the function that adapted the fill prefix 4015 (when (and (eq c-lit-type 'c++)
3298 ;; doesn't produce the required comment starter for line 4016 (not (string-match (concat "\\`[ \t]*"
3299 ;; comments, then we ignore it. 4017 c-line-comment-starter)
3300 (setq fill-prefix nil))) 4018 (or fill-prefix ""))))
3301 )) 4019 ;; Kludge: If the function that adapted the fill prefix
4020 ;; doesn't produce the required comment starter for line
4021 ;; comments, then we ignore it.
4022 (setq fill-prefix nil)))
4023 )))
4024
3302 (cond ((eq fill-prefix t) 4025 (cond ((eq fill-prefix t)
3303 ;; A call from do-auto-fill which should be ignored. 4026 ;; A call from do-auto-fill which should be ignored.
3304 ) 4027 )
@@ -3306,7 +4029,7 @@ If a fill prefix is specified, it overrides all the above."
3306 ;; A fill-prefix overrides anything. 4029 ;; A fill-prefix overrides anything.
3307 (funcall do-line-break) 4030 (funcall do-line-break)
3308 (insert-and-inherit fill-prefix)) 4031 (insert-and-inherit fill-prefix))
3309 ((progn 4032 ((c-save-buffer-state ()
3310 (unless c-lit-limits 4033 (unless c-lit-limits
3311 (setq c-lit-limits (c-literal-limits))) 4034 (setq c-lit-limits (c-literal-limits)))
3312 (unless c-lit-type 4035 (unless c-lit-type
@@ -3440,31 +4163,38 @@ When point is inside a comment, continue it with the appropriate
3440comment prefix (see the `c-comment-prefix-regexp' and 4163comment prefix (see the `c-comment-prefix-regexp' and
3441`c-block-comment-prefix' variables for details). The end of a 4164`c-block-comment-prefix' variables for details). The end of a
3442C++-style line comment doesn't count as inside it." 4165C++-style line comment doesn't count as inside it."
4166
3443 (interactive "*") 4167 (interactive "*")
3444 (let* ((c-lit-limits (c-literal-limits nil nil t)) 4168 (let* (c-lit-limits c-lit-type
3445 (c-lit-type (c-literal-type c-lit-limits))
3446 (c-macro-start c-macro-start)) 4169 (c-macro-start c-macro-start))
3447 (if (or (eq c-lit-type 'c) 4170
3448 (and (eq c-lit-type 'c++) 4171 (if (c-save-buffer-state ()
3449 (< (save-excursion 4172 (setq c-lit-limits (c-literal-limits nil nil t)
3450 (skip-chars-forward " \t") 4173 c-lit-type (c-literal-type c-lit-limits))
3451 (point)) 4174 (or (eq c-lit-type 'c)
3452 (1- (cdr (setq c-lit-limits 4175 (and (eq c-lit-type 'c++)
3453 (c-collect-line-comments c-lit-limits)))))) 4176 (< (save-excursion
3454 (and (or (not (looking-at "\\s *$")) 4177 (skip-chars-forward " \t")
3455 (eq (char-before) ?\\)) 4178 (point))
3456 (c-query-and-set-macro-start) 4179 (1- (cdr (setq c-lit-limits (c-collect-line-comments
3457 (<= (save-excursion 4180 c-lit-limits))))))
3458 (goto-char c-macro-start) 4181 (and (or (not (looking-at "\\s *$"))
3459 (if (looking-at c-opt-cpp-start) 4182 (eq (char-before) ?\\))
3460 (goto-char (match-end 0))) 4183 (c-query-and-set-macro-start)
3461 (point)) 4184 (<= (save-excursion
3462 (point)))) 4185 (goto-char c-macro-start)
4186 (if (looking-at c-opt-cpp-start)
4187 (goto-char (match-end 0)))
4188 (point))
4189 (point)))))
4190
3463 (let ((comment-multi-line t) 4191 (let ((comment-multi-line t)
3464 (fill-prefix nil)) 4192 (fill-prefix nil))
3465 (c-indent-new-comment-line nil t)) 4193 (c-indent-new-comment-line nil t))
4194
3466 (delete-horizontal-space) 4195 (delete-horizontal-space)
3467 (newline) 4196 (newline)
4197
3468 ;; c-indent-line may look at the current indentation, so let's 4198 ;; c-indent-line may look at the current indentation, so let's
3469 ;; start out with the same indentation as the previous line. 4199 ;; start out with the same indentation as the previous line.
3470 (let ((col (save-excursion 4200 (let ((col (save-excursion
@@ -3473,6 +4203,7 @@ C++-style line comment doesn't count as inside it."
3473 (= (forward-line -1) 0))) 4203 (= (forward-line -1) 0)))
3474 (current-indentation)))) 4204 (current-indentation))))
3475 (indent-to col)) 4205 (indent-to col))
4206
3476 (indent-according-to-mode)))) 4207 (indent-according-to-mode))))
3477 4208
3478(defun c-context-open-line () 4209(defun c-context-open-line ()
diff --git a/lisp/progmodes/cc-compat.el b/lisp/progmodes/cc-compat.el
index 60dcbd135d8..66bf9a55d79 100644
--- a/lisp/progmodes/cc-compat.el
+++ b/lisp/progmodes/cc-compat.el
@@ -1,6 +1,7 @@
1;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion 1;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion
2 2
3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation,
4;; Inc.
4 5
5;; Authors: 1998- Martin Stjernholm 6;; Authors: 1998- Martin Stjernholm
6;; 1994-1999 Barry A. Warsaw 7;; 1994-1999 Barry A. Warsaw
@@ -22,7 +23,7 @@
22;; GNU General Public License for more details. 23;; GNU General Public License for more details.
23 24
24;; You should have received a copy of the GNU General Public License 25;; You should have received a copy of the GNU General Public License
25;; along with GNU Emacs; see the file COPYING. If not, write to 26;; along with this program; see the file COPYING. If not, write to
26;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 27;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27;; Boston, MA 02110-1301, USA. 28;; Boston, MA 02110-1301, USA.
28 29
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index a78fd8f7f74..b68e167ffa0 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -1,6 +1,7 @@
1;;; cc-defs.el --- compile time definitions for CC Mode 1;;; cc-defs.el --- compile time definitions for CC Mode
2 2
3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation,
4;; Inc.
4 5
5;; Authors: 1998- Martin Stjernholm 6;; Authors: 1998- Martin Stjernholm
6;; 1992-1999 Barry A. Warsaw 7;; 1992-1999 Barry A. Warsaw
@@ -24,7 +25,7 @@
24;; GNU General Public License for more details. 25;; GNU General Public License for more details.
25 26
26;; You should have received a copy of the GNU General Public License 27;; You should have received a copy of the GNU General Public License
27;; along with GNU Emacs; see the file COPYING. If not, write to 28;; along with this program; see the file COPYING. If not, write to
28;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 29;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29;; Boston, MA 02110-1301, USA. 30;; Boston, MA 02110-1301, USA.
30 31
@@ -43,8 +44,8 @@
43 load-path))) 44 load-path)))
44 (load "cc-bytecomp" nil t))) 45 (load "cc-bytecomp" nil t)))
45 46
46;; `require' in XEmacs doesn't have the third NOERROR argument. 47(eval-when-compile (require 'cl)) ; was (cc-external-require 'cl). ACM 2005/11/29.
47(condition-case nil (require 'regexp-opt) (file-error nil)) 48(cc-external-require 'regexp-opt)
48 49
49;; Silence the compiler. 50;; Silence the compiler.
50(cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el 51(cc-bytecomp-defvar c-enable-xemacs-performance-kludge-p) ; In cc-vars.el
@@ -55,31 +56,18 @@
55(cc-bytecomp-defvar mark-active) ; Emacs 56(cc-bytecomp-defvar mark-active) ; Emacs
56(cc-bytecomp-defvar deactivate-mark) ; Emacs 57(cc-bytecomp-defvar deactivate-mark) ; Emacs
57(cc-bytecomp-defvar inhibit-point-motion-hooks) ; Emacs 58(cc-bytecomp-defvar inhibit-point-motion-hooks) ; Emacs
58(cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs 20+ 59(cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs
59(cc-bytecomp-defvar text-property-default-nonsticky) ; Emacs 21 60(cc-bytecomp-defvar text-property-default-nonsticky) ; Emacs 21
60(cc-bytecomp-defvar lookup-syntax-properties) ; XEmacs 21 61(cc-bytecomp-defvar lookup-syntax-properties) ; XEmacs
61(cc-bytecomp-defun string-to-syntax) ; Emacs 21 62(cc-bytecomp-defun string-to-syntax) ; Emacs 21
62(cc-bytecomp-defun regexp-opt-depth) ; (X)Emacs 20+
63 63
64 64
65;; cc-fix.el contains compatibility macros that should be used if 65;; cc-fix.el contains compatibility macros that should be used if
66;; needed. 66;; needed.
67(eval-and-compile 67(eval-and-compile
68 (if (or (not (fboundp 'functionp)) 68 (if (or (/= (regexp-opt-depth "\\(\\(\\)\\)") 2)
69 (not (condition-case nil 69 (not (fboundp 'push)))
70 (progn (eval '(char-before)) t) 70 (cc-load "cc-fix")))
71 (error nil)))
72 (not (condition-case nil
73 (progn (eval '(char-after)) t)
74 (error nil)))
75 (not (fboundp 'when))
76 (not (fboundp 'unless))
77 (not (fboundp 'regexp-opt))
78 (not (cc-bytecomp-fboundp 'regexp-opt-depth))
79 (/= (regexp-opt-depth "\\(\\(\\)\\)") 2))
80 (cc-load "cc-fix")
81 (defalias 'c-regexp-opt 'regexp-opt)
82 (defalias 'c-regexp-opt-depth 'regexp-opt-depth)))
83 71
84(eval-after-load "font-lock" 72(eval-after-load "font-lock"
85 '(if (and (not (featurep 'cc-fix)) ; only load the file once. 73 '(if (and (not (featurep 'cc-fix)) ; only load the file once.
@@ -99,12 +87,10 @@
99 font-lock-keywords))) 87 font-lock-keywords)))
100 (cc-load "cc-fix"))) 88 (cc-load "cc-fix")))
101 89
102(eval-when-compile (require 'cl))
103
104 90
105;;; Variables also used at compile time. 91;;; Variables also used at compile time.
106 92
107(defconst c-version "5.30.10" 93(defconst c-version "5.31"
108 "CC Mode version number.") 94 "CC Mode version number.")
109 95
110(defconst c-version-sym (intern c-version)) 96(defconst c-version-sym (intern c-version))
@@ -192,29 +178,29 @@ This variant works around bugs in `eval-when-compile' in various
192The current point is used if POINT isn't specified. POSITION can be 178The current point is used if POINT isn't specified. POSITION can be
193one of the following symbols: 179one of the following symbols:
194 180
195`bol' -- beginning of line 181`bol' -- beginning of line
196`eol' -- end of line 182`eol' -- end of line
197`bod' -- beginning of defun 183`bod' -- beginning of defun
198`eod' -- end of defun 184`eod' -- end of defun
199`boi' -- beginning of indentation 185`boi' -- beginning of indentation
200`ionl' -- indentation of next line 186`ionl' -- indentation of next line
201`iopl' -- indentation of previous line 187`iopl' -- indentation of previous line
202`bonl' -- beginning of next line 188`bonl' -- beginning of next line
203`eonl' -- end of next line 189`eonl' -- end of next line
204`bopl' -- beginning of previous line 190`bopl' -- beginning of previous line
205`eopl' -- end of previous line 191`eopl' -- end of previous line
192`bosws' -- beginning of syntactic whitespace
193`eosws' -- end of syntactic whitespace
206 194
207If the referenced position doesn't exist, the closest accessible point 195If the referenced position doesn't exist, the closest accessible point
208to it is returned. This function does not modify point or mark. 196to it is returned. This function does not modify the point or the mark."
209
210This function does not do any hidden buffer changes."
211 197
212 (if (eq (car-safe position) 'quote) 198 (if (eq (car-safe position) 'quote)
213 (let ((position (eval position))) 199 (let ((position (eval position)))
214 (cond 200 (cond
215 201
216 ((eq position 'bol) 202 ((eq position 'bol)
217 (if (and (fboundp 'line-beginning-position) (not point)) 203 (if (and (cc-bytecomp-fboundp 'line-beginning-position) (not point))
218 `(line-beginning-position) 204 `(line-beginning-position)
219 `(save-excursion 205 `(save-excursion
220 ,@(if point `((goto-char ,point))) 206 ,@(if point `((goto-char ,point)))
@@ -222,7 +208,7 @@ This function does not do any hidden buffer changes."
222 (point)))) 208 (point))))
223 209
224 ((eq position 'eol) 210 ((eq position 'eol)
225 (if (and (fboundp 'line-end-position) (not point)) 211 (if (and (cc-bytecomp-fboundp 'line-end-position) (not point))
226 `(line-end-position) 212 `(line-end-position)
227 `(save-excursion 213 `(save-excursion
228 ,@(if point `((goto-char ,point))) 214 ,@(if point `((goto-char ,point)))
@@ -248,7 +234,7 @@ This function does not do any hidden buffer changes."
248 (point))) 234 (point)))
249 235
250 ((eq position 'bopl) 236 ((eq position 'bopl)
251 (if (and (fboundp 'line-beginning-position) (not point)) 237 (if (and (cc-bytecomp-fboundp 'line-beginning-position) (not point))
252 `(line-beginning-position 0) 238 `(line-beginning-position 0)
253 `(save-excursion 239 `(save-excursion
254 ,@(if point `((goto-char ,point))) 240 ,@(if point `((goto-char ,point)))
@@ -256,7 +242,7 @@ This function does not do any hidden buffer changes."
256 (point)))) 242 (point))))
257 243
258 ((eq position 'bonl) 244 ((eq position 'bonl)
259 (if (and (fboundp 'line-beginning-position) (not point)) 245 (if (and (cc-bytecomp-fboundp 'line-beginning-position) (not point))
260 `(line-beginning-position 2) 246 `(line-beginning-position 2)
261 `(save-excursion 247 `(save-excursion
262 ,@(if point `((goto-char ,point))) 248 ,@(if point `((goto-char ,point)))
@@ -264,7 +250,7 @@ This function does not do any hidden buffer changes."
264 (point)))) 250 (point))))
265 251
266 ((eq position 'eopl) 252 ((eq position 'eopl)
267 (if (and (fboundp 'line-end-position) (not point)) 253 (if (and (cc-bytecomp-fboundp 'line-end-position) (not point))
268 `(line-end-position 0) 254 `(line-end-position 0)
269 `(save-excursion 255 `(save-excursion
270 ,@(if point `((goto-char ,point))) 256 ,@(if point `((goto-char ,point)))
@@ -273,7 +259,7 @@ This function does not do any hidden buffer changes."
273 (point)))) 259 (point))))
274 260
275 ((eq position 'eonl) 261 ((eq position 'eonl)
276 (if (and (fboundp 'line-end-position) (not point)) 262 (if (and (cc-bytecomp-fboundp 'line-end-position) (not point))
277 `(line-end-position 2) 263 `(line-end-position 2)
278 `(save-excursion 264 `(save-excursion
279 ,@(if point `((goto-char ,point))) 265 ,@(if point `((goto-char ,point)))
@@ -295,54 +281,138 @@ This function does not do any hidden buffer changes."
295 (back-to-indentation) 281 (back-to-indentation)
296 (point))) 282 (point)))
297 283
284 ((eq position 'bosws)
285 `(save-excursion
286 ,@(if point `((goto-char ,point)))
287 (c-backward-syntactic-ws)
288 (point)))
289
290 ((eq position 'eosws)
291 `(save-excursion
292 ,@(if point `((goto-char ,point)))
293 (c-forward-syntactic-ws)
294 (point)))
295
298 (t (error "Unknown buffer position requested: %s" position)))) 296 (t (error "Unknown buffer position requested: %s" position))))
299 297
300 ;;(message "c-point long expansion") 298 ;; The bulk of this should perhaps be in a function to avoid large
299 ;; expansions, but this case is not used anywhere in CC Mode (and
300 ;; probably not anywhere else either) so we only have it to be on
301 ;; the safe side.
302 (message "Warning: c-point long expansion")
301 `(save-excursion 303 `(save-excursion
302 ,@(if point `((goto-char ,point))) 304 ,@(if point `((goto-char ,point)))
303 (let ((position ,position)) 305 (let ((position ,position))
304 (cond 306 (cond
305 ((eq position 'bol) (beginning-of-line)) 307 ((eq position 'bol) (beginning-of-line))
306 ((eq position 'eol) (end-of-line)) 308 ((eq position 'eol) (end-of-line))
307 ((eq position 'boi) (back-to-indentation)) 309 ((eq position 'boi) (back-to-indentation))
308 ((eq position 'bod) (c-beginning-of-defun-1)) 310 ((eq position 'bod) (c-beginning-of-defun-1))
309 ((eq position 'eod) (c-end-of-defun-1)) 311 ((eq position 'eod) (c-end-of-defun-1))
310 ((eq position 'bopl) (forward-line -1)) 312 ((eq position 'bopl) (forward-line -1))
311 ((eq position 'bonl) (forward-line 1)) 313 ((eq position 'bonl) (forward-line 1))
312 ((eq position 'eopl) (progn 314 ((eq position 'eopl) (progn
313 (beginning-of-line) 315 (beginning-of-line)
314 (or (bobp) (backward-char)))) 316 (or (bobp) (backward-char))))
315 ((eq position 'eonl) (progn 317 ((eq position 'eonl) (progn
316 (forward-line 1) 318 (forward-line 1)
317 (end-of-line))) 319 (end-of-line)))
318 ((eq position 'iopl) (progn 320 ((eq position 'iopl) (progn
319 (forward-line -1) 321 (forward-line -1)
320 (back-to-indentation))) 322 (back-to-indentation)))
321 ((eq position 'ionl) (progn 323 ((eq position 'ionl) (progn
322 (forward-line 1) 324 (forward-line 1)
323 (back-to-indentation))) 325 (back-to-indentation)))
326 ((eq position 'bosws) (c-backward-syntactic-ws))
327 ((eq position 'eosws) (c-forward-syntactic-ws))
324 (t (error "Unknown buffer position requested: %s" position)))) 328 (t (error "Unknown buffer position requested: %s" position))))
325 (point)))) 329 (point))))
326 330
331(defmacro c-region-is-active-p ()
332 ;; Return t when the region is active. The determination of region
333 ;; activeness is different in both Emacs and XEmacs.
334 (if (cc-bytecomp-fboundp 'region-active-p)
335 ;; XEmacs.
336 '(region-active-p)
337 ;; Emacs.
338 'mark-active))
339
340(defmacro c-set-region-active (activate)
341 ;; Activate the region if ACTIVE is non-nil, deactivate it
342 ;; otherwise. Covers the differences between Emacs and XEmacs.
343 (if (cc-bytecomp-fboundp 'zmacs-activate-region)
344 ;; XEmacs.
345 `(if ,activate
346 (zmacs-activate-region)
347 (zmacs-deactivate-region))
348 ;; Emacs.
349 `(setq mark-active ,activate)))
350
351(defmacro c-delete-and-extract-region (start end)
352 "Delete the text between START and END and return it."
353 (if (cc-bytecomp-fboundp 'delete-and-extract-region)
354 ;; Emacs 21.1 and later
355 `(delete-and-extract-region ,start ,end)
356 ;; XEmacs and Emacs 20.x
357 `(prog1
358 (buffer-substring ,start ,end)
359 (delete-region ,start ,end))))
360
327(defmacro c-safe (&rest body) 361(defmacro c-safe (&rest body)
328 ;; safely execute BODY, return nil if an error occurred 362 ;; safely execute BODY, return nil if an error occurred
329 ;;
330 ;; This function does not do any hidden buffer changes.
331 `(condition-case nil 363 `(condition-case nil
332 (progn ,@body) 364 (progn ,@body)
333 (error nil))) 365 (error nil)))
334(put 'c-safe 'lisp-indent-function 0) 366(put 'c-safe 'lisp-indent-function 0)
335 367
368(defmacro c-int-to-char (integer)
369 ;; In GNU Emacs, a character is an integer. In XEmacs, a character is a
370 ;; type distinct from an integer. Sometimes we need to convert integers to
371 ;; characters. `c-int-to-char' makes this conversion, if necessary.
372 (if (fboundp 'int-to-char)
373 `(int-to-char ,integer)
374 integer))
375
376(defmacro c-sentence-end ()
377 ;; Get the regular expression `sentence-end'.
378 (if (cc-bytecomp-fboundp 'sentence-end)
379 ;; Emacs 22:
380 `(sentence-end)
381 ;; Emacs <22 + XEmacs
382 `sentence-end))
383
384(defmacro c-default-value-sentence-end ()
385 ;; Get the default value of the variable sentence end.
386 (if (cc-bytecomp-fboundp 'sentence-end)
387 ;; Emacs 22:
388 `(let (sentence-end) (sentence-end))
389 ;; Emacs <22 + XEmacs
390 `(default-value 'sentence-end)))
391
336;; The following is essentially `save-buffer-state' from lazy-lock.el. 392;; The following is essentially `save-buffer-state' from lazy-lock.el.
337;; It ought to be a standard macro. 393;; It ought to be a standard macro.
338(defmacro c-save-buffer-state (varlist &rest body) 394(defmacro c-save-buffer-state (varlist &rest body)
339 "Bind variables according to VARLIST (in `let*' style) and eval BODY, 395 "Bind variables according to VARLIST (in `let*' style) and eval BODY,
340then restore the buffer state under the assumption that no significant 396then restore the buffer state under the assumption that no significant
341modification has been made. A change is considered significant if it 397modification has been made in BODY. A change is considered
342affects the buffer text in any way that isn't completely restored 398significant if it affects the buffer text in any way that isn't
343again. Changes in text properties like `face' or `syntax-table' are 399completely restored again. Changes in text properties like `face' or
344considered insignificant. This macro allows text properties to be 400`syntax-table' are considered insignificant. This macro allows text
345changed, even in a read-only buffer. 401properties to be changed, even in a read-only buffer.
402
403This macro should be placed around all calculations which set
404\"insignificant\" text properties in a buffer, even when the buffer is
405known to be writeable. That way, these text properties remain set
406even if the user undoes the command which set them.
407
408This macro should ALWAYS be placed around \"temporary\" internal buffer
409changes \(like adding a newline to calculate a text-property then
410deleting it again\), so that the user never sees them on his
411`buffer-undo-list'. See also `c-tentative-buffer-changes'.
412
413However, any user-visible changes to the buffer \(like auto-newlines\)
414must not be within a `c-save-buffer-state', since the user then
415wouldn't be able to undo them.
346 416
347The return value is the value of the last form in BODY." 417The return value is the value of the last form in BODY."
348 `(let* ((modified (buffer-modified-p)) (buffer-undo-list t) 418 `(let* ((modified (buffer-modified-p)) (buffer-undo-list t)
@@ -350,12 +420,80 @@ The return value is the value of the last form in BODY."
350 before-change-functions after-change-functions 420 before-change-functions after-change-functions
351 deactivate-mark 421 deactivate-mark
352 ,@varlist) 422 ,@varlist)
353 (prog1 (progn ,@body) 423 (unwind-protect
424 (progn ,@body)
354 (and (not modified) 425 (and (not modified)
355 (buffer-modified-p) 426 (buffer-modified-p)
356 (set-buffer-modified-p nil))))) 427 (set-buffer-modified-p nil)))))
357(put 'c-save-buffer-state 'lisp-indent-function 1) 428(put 'c-save-buffer-state 'lisp-indent-function 1)
358 429
430(defmacro c-tentative-buffer-changes (&rest body)
431 "Eval BODY and optionally restore the buffer contents to the state it
432was in before BODY. Any changes are kept if the last form in BODY
433returns non-nil. Otherwise it's undone using the undo facility, and
434various other buffer state that might be affected by the changes is
435restored. That includes the current buffer, point, mark, mark
436activation \(similar to `save-excursion'), and the modified state.
437The state is also restored if BODY exits nonlocally.
438
439If BODY makes a change that unconditionally is undone then wrap this
440macro inside `c-save-buffer-state'. That way the change can be done
441even when the buffer is read-only, and without interference from
442various buffer change hooks."
443 `(let (-tnt-chng-keep
444 -tnt-chng-state)
445 (unwind-protect
446 ;; Insert an undo boundary for use with `undo-more'. We
447 ;; don't use `undo-boundary' since it doesn't insert one
448 ;; unconditionally.
449 (setq buffer-undo-list (cons nil buffer-undo-list)
450 -tnt-chng-state (c-tnt-chng-record-state)
451 -tnt-chng-keep (progn ,@body))
452 (c-tnt-chng-cleanup -tnt-chng-keep -tnt-chng-state))))
453(put 'c-tentative-buffer-changes 'lisp-indent-function 0)
454
455(defun c-tnt-chng-record-state ()
456 ;; Used internally in `c-tentative-buffer-changes'.
457 (vector buffer-undo-list ; 0
458 (current-buffer) ; 1
459 ;; No need to use markers for the point and mark; if the
460 ;; undo got out of synch we're hosed anyway.
461 (point) ; 2
462 (mark t) ; 3
463 (c-region-is-active-p) ; 4
464 (buffer-modified-p))) ; 5
465
466(defun c-tnt-chng-cleanup (keep saved-state)
467 ;; Used internally in `c-tentative-buffer-changes'.
468
469 (let ((saved-undo-list (elt saved-state 0)))
470 (if (eq buffer-undo-list saved-undo-list)
471 ;; No change was done afterall.
472 (setq buffer-undo-list (cdr saved-undo-list))
473
474 (if keep
475 ;; Find and remove the undo boundary.
476 (let ((p buffer-undo-list))
477 (while (not (eq (cdr p) saved-undo-list))
478 (setq p (cdr p)))
479 (setcdr p (cdr saved-undo-list)))
480
481 ;; `primitive-undo' will remove the boundary.
482 (setq saved-undo-list (cdr saved-undo-list))
483 (let ((undo-in-progress t))
484 (while (not (eq (setq buffer-undo-list
485 (primitive-undo 1 buffer-undo-list))
486 saved-undo-list))))
487
488 (when (buffer-live-p (elt saved-state 1))
489 (set-buffer (elt saved-state 1))
490 (goto-char (elt saved-state 2))
491 (set-mark (elt saved-state 3))
492 (c-set-region-active (elt saved-state 4))
493 (and (not (elt saved-state 5))
494 (buffer-modified-p)
495 (set-buffer-modified-p nil)))))))
496
359(defmacro c-forward-syntactic-ws (&optional limit) 497(defmacro c-forward-syntactic-ws (&optional limit)
360 "Forward skip over syntactic whitespace. 498 "Forward skip over syntactic whitespace.
361Syntactic whitespace is defined as whitespace characters, comments, 499Syntactic whitespace is defined as whitespace characters, comments,
@@ -402,91 +540,127 @@ fails for any reason.
402This is like `forward-sexp' except that it isn't interactive and does 540This is like `forward-sexp' except that it isn't interactive and does
403not do any user friendly adjustments of the point and that it isn't 541not do any user friendly adjustments of the point and that it isn't
404susceptible to user configurations such as disabling of signals in 542susceptible to user configurations such as disabling of signals in
405certain situations. 543certain situations."
406
407This function does not do any hidden buffer changes."
408 (or count (setq count 1)) 544 (or count (setq count 1))
409 `(goto-char (or (scan-sexps (point) ,count) 545 `(goto-char (scan-sexps (point) ,count)))
410 ,(if (numberp count)
411 (if (> count 0) `(point-max) `(point-min))
412 `(if (> ,count 0) (point-max) (point-min))))))
413 546
414(defmacro c-backward-sexp (&optional count) 547(defmacro c-backward-sexp (&optional count)
415 "See `c-forward-sexp' and reverse directions." 548 "See `c-forward-sexp' and reverse directions."
416 (or count (setq count 1)) 549 (or count (setq count 1))
417 `(c-forward-sexp ,(if (numberp count) (- count) `(- ,count)))) 550 `(c-forward-sexp ,(if (numberp count) (- count) `(- ,count))))
418 551
419(defmacro c-safe-scan-lists (from count depth) 552(defmacro c-safe-scan-lists (from count depth &optional limit)
420 "Like `scan-lists' but returns nil instead of signaling errors. 553 "Like `scan-lists' but returns nil instead of signalling errors
421 554for unbalanced parens.
422This function does not do any hidden buffer changes." 555
423 (if (featurep 'xemacs) 556A limit for the search may be given. FROM is assumed to be on the
424 `(scan-lists ,from ,count ,depth nil t) 557right side of it."
425 `(c-safe (scan-lists ,from ,count ,depth)))) 558 (let ((res (if (featurep 'xemacs)
559 `(scan-lists ,from ,count ,depth nil t)
560 `(c-safe (scan-lists ,from ,count ,depth)))))
561 (if limit
562 `(save-restriction
563 ,(if (numberp count)
564 (if (< count 0)
565 `(narrow-to-region ,limit (point-max))
566 `(narrow-to-region (point-min) ,limit))
567 `(if (< ,count 0)
568 (narrow-to-region ,limit (point-max))
569 (narrow-to-region (point-min) ,limit)))
570 ,res)
571 res)))
426 572
427 573
428;; Wrappers for common scan-lists cases, mainly because it's almost 574;; Wrappers for common scan-lists cases, mainly because it's almost
429;; impossible to get a feel for how that function works. 575;; impossible to get a feel for how that function works.
430 576
431(defmacro c-up-list-forward (&optional pos) 577(defmacro c-up-list-forward (&optional pos limit)
432 "Return the first position after the list sexp containing POS, 578 "Return the first position after the list sexp containing POS,
433or nil if no such position exists. The point is used if POS is left out. 579or nil if no such position exists. The point is used if POS is left out.
434 580
435This function does not do any hidden buffer changes." 581A limit for the search may be given. The start position is assumed to
436 `(c-safe-scan-lists ,(or pos `(point)) 1 1)) 582be before it."
583 `(c-safe-scan-lists ,(or pos `(point)) 1 1 ,limit))
437 584
438(defmacro c-up-list-backward (&optional pos) 585(defmacro c-up-list-backward (&optional pos limit)
439 "Return the position of the start of the list sexp containing POS, 586 "Return the position of the start of the list sexp containing POS,
440or nil if no such position exists. The point is used if POS is left out. 587or nil if no such position exists. The point is used if POS is left out.
441 588
442This function does not do any hidden buffer changes." 589A limit for the search may be given. The start position is assumed to
443 `(c-safe-scan-lists ,(or pos `(point)) -1 1)) 590be after it."
591 `(c-safe-scan-lists ,(or pos `(point)) -1 1 ,limit))
444 592
445(defmacro c-down-list-forward (&optional pos) 593(defmacro c-down-list-forward (&optional pos limit)
446 "Return the first position inside the first list sexp after POS, 594 "Return the first position inside the first list sexp after POS,
447or nil if no such position exists. The point is used if POS is left out. 595or nil if no such position exists. The point is used if POS is left out.
448 596
449This function does not do any hidden buffer changes." 597A limit for the search may be given. The start position is assumed to
450 `(c-safe-scan-lists ,(or pos `(point)) 1 -1)) 598be before it."
599 `(c-safe-scan-lists ,(or pos `(point)) 1 -1 ,limit))
451 600
452(defmacro c-down-list-backward (&optional pos) 601(defmacro c-down-list-backward (&optional pos limit)
453 "Return the last position inside the last list sexp before POS, 602 "Return the last position inside the last list sexp before POS,
454or nil if no such position exists. The point is used if POS is left out. 603or nil if no such position exists. The point is used if POS is left out.
455 604
456This function does not do any hidden buffer changes." 605A limit for the search may be given. The start position is assumed to
457 `(c-safe-scan-lists ,(or pos `(point)) -1 -1)) 606be after it."
607 `(c-safe-scan-lists ,(or pos `(point)) -1 -1 ,limit))
458 608
459(defmacro c-go-up-list-forward (&optional pos) 609(defmacro c-go-up-list-forward (&optional pos limit)
460 "Move the point to the first position after the list sexp containing POS, 610 "Move the point to the first position after the list sexp containing POS,
461or the point if POS is left out. Return t if such a position exists, 611or containing the point if POS is left out. Return t if such a
462otherwise nil is returned and the point isn't moved. 612position exists, otherwise nil is returned and the point isn't moved.
463 613
464This function does not do any hidden buffer changes." 614A limit for the search may be given. The start position is assumed to
465 `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 1)) t)) 615be before it."
466 616 (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 1)) t)))
467(defmacro c-go-up-list-backward (&optional pos) 617 (if limit
618 `(save-restriction
619 (narrow-to-region (point-min) ,limit)
620 ,res)
621 res)))
622
623(defmacro c-go-up-list-backward (&optional pos limit)
468 "Move the point to the position of the start of the list sexp containing POS, 624 "Move the point to the position of the start of the list sexp containing POS,
469or the point if POS is left out. Return t if such a position exists, 625or containing the point if POS is left out. Return t if such a
470otherwise nil is returned and the point isn't moved. 626position exists, otherwise nil is returned and the point isn't moved.
471 627
472This function does not do any hidden buffer changes." 628A limit for the search may be given. The start position is assumed to
473 `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 1)) t)) 629be after it."
474 630 (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 1)) t)))
475(defmacro c-go-down-list-forward (&optional pos) 631 (if limit
632 `(save-restriction
633 (narrow-to-region ,limit (point-max))
634 ,res)
635 res)))
636
637(defmacro c-go-down-list-forward (&optional pos limit)
476 "Move the point to the first position inside the first list sexp after POS, 638 "Move the point to the first position inside the first list sexp after POS,
477or the point if POS is left out. Return t if such a position exists, 639or before the point if POS is left out. Return t if such a position
478otherwise nil is returned and the point isn't moved. 640exists, otherwise nil is returned and the point isn't moved.
479 641
480This function does not do any hidden buffer changes." 642A limit for the search may be given. The start position is assumed to
481 `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 -1)) t)) 643be before it."
482 644 (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) 1 -1)) t)))
483(defmacro c-go-down-list-backward (&optional pos) 645 (if limit
646 `(save-restriction
647 (narrow-to-region (point-min) ,limit)
648 ,res)
649 res)))
650
651(defmacro c-go-down-list-backward (&optional pos limit)
484 "Move the point to the last position inside the last list sexp before POS, 652 "Move the point to the last position inside the last list sexp before POS,
485or the point if POS is left out. Return t if such a position exists, 653or before the point if POS is left out. Return t if such a position
486otherwise nil is returned and the point isn't moved. 654exists, otherwise nil is returned and the point isn't moved.
487 655
488This function does not do any hidden buffer changes." 656A limit for the search may be given. The start position is assumed to
489 `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 -1)) t)) 657be after it."
658 (let ((res `(c-safe (goto-char (scan-lists ,(or pos `(point)) -1 -1)) t)))
659 (if limit
660 `(save-restriction
661 (narrow-to-region ,limit (point-max))
662 ,res)
663 res)))
490 664
491 665
492(defmacro c-beginning-of-defun-1 () 666(defmacro c-beginning-of-defun-1 ()
@@ -501,8 +675,6 @@ This function does not do any hidden buffer changes."
501 ;; This is really a bit too large to be a macro but that isn't a 675 ;; This is really a bit too large to be a macro but that isn't a
502 ;; problem as long as it only is used in one place in 676 ;; problem as long as it only is used in one place in
503 ;; `c-parse-state'. 677 ;; `c-parse-state'.
504 ;;
505 ;; This function does not do any hidden buffer changes.
506 678
507 `(progn 679 `(progn
508 (if (and ,(cc-bytecomp-fboundp 'buffer-syntactic-context-depth) 680 (if (and ,(cc-bytecomp-fboundp 'buffer-syntactic-context-depth)
@@ -542,31 +714,84 @@ This function does not do any hidden buffer changes."
542 (looking-at defun-prompt-regexp) 714 (looking-at defun-prompt-regexp)
543 (goto-char (match-end 0))))) 715 (goto-char (match-end 0)))))
544 716
717
718;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
719;; V i r t u a l S e m i c o l o n s
720;;
721;; In most CC Mode languages, statements are terminated explicitly by
722;; semicolons or closing braces. In some of the CC modes (currently only AWK
723;; Mode (April 2004)), statements are (or can be) terminated by EOLs. Such a
724;; statement is said to be terminated by a "virtual semicolon" (VS). A
725;; statement terminated by an actual semicolon or brace is never considered to
726;; have a VS.
727;;
728;; The indentation engine (or whatever) tests for a VS at a specific position
729;; by invoking the macro `c-at-vsemi-p', which in its turn calls the mode
730;; specific function (if any) which is the value of the language variable
731;; `c-at-vsemi-p-fn'. The actual details of what constitutes a VS in a
732;; language are thus encapsulated in code specific to that language
733;; (e.g. cc-awk.el). `c-at-vsemi-p' returns non-nil if point (or the optional
734;; parameter POS) is at a VS, nil otherwise.
735;;
736;; The language specific function might well do extensive analysis of the
737;; source text, and may use a cacheing scheme to speed up repeated calls.
738;;
739;; The "virtual semicolon" lies just after the last non-ws token on the line.
740;; Like POINT, it is considered to lie between two characters. For example,
741;; at the place shown in the following AWK source line:
742;;
743;; kbyte = 1024 # 1000 if you're not picky
744;; ^
745;; |
746;; Virtual Semicolon
747;;
748;; In addition to `c-at-vsemi-p-fn', a mode may need to supply a function for
749;; `c-vsemi-status-unknown-p-fn'. The macro `c-vsemi-status-unknown-p' is a
750;; rather recondite kludge. It exists because the function
751;; `c-beginning-of-statement-1' sometimes tests for VSs as an optimisation,
752;; but `c-at-vsemi-p' might well need to call `c-beginning-of-statement-1' in
753;; its calculations, thus potentially leading to infinite recursion.
754;;
755;; The macro `c-vsemi-status-unknown-p' resolves this problem; it may return
756;; non-nil at any time; returning nil is a guarantee that an immediate
757;; invocation of `c-at-vsemi-p' at point will NOT call
758;; `c-beginning-of-statement-1'. `c-vsemi-status-unknown-p' may not itself
759;; call `c-beginning-of-statement-1'.
760;;
761;; The macro `c-vsemi-status-unknown-p' will typically check the cacheing
762;; scheme used by the `c-at-vsemp-p-fn', hence the name - the status is
763;; "unknown" if there is no cache entry current for the line.
764;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
765
766(defmacro c-at-vsemi-p (&optional pos)
767 ;; Is there a virtual semicolon (not a real one or a }) at POS (defaults to
768 ;; point)? Always returns nil for languages which don't have Virtual
769 ;; semicolons.
770 ;; This macro might do hidden buffer changes.
771 `(if c-at-vsemi-p-fn
772 (funcall c-at-vsemi-p-fn ,@(if pos `(,pos)))))
773
774(defmacro c-vsemi-status-unknown-p ()
775 ;; Return NIL only if it can be guaranteed that an immediate
776 ;; (c-at-vsemi-p) will NOT call c-beginning-of-statement-1. Otherwise,
777 ;; return non-nil. (See comments above). The function invoked by this
778 ;; macro MUST NOT UNDER ANY CIRCUMSTANCES itself call
779 ;; c-beginning-of-statement-1.
780 ;; Languages which don't have EOL terminated statements always return NIL
781 ;; (they _know_ there's no vsemi ;-).
782 `(if c-vsemi-status-unknown-p-fn (funcall c-vsemi-status-unknown-p-fn)))
783
784
545(defmacro c-benign-error (format &rest args) 785(defmacro c-benign-error (format &rest args)
546 ;; Formats an error message for the echo area and dings, i.e. like 786 ;; Formats an error message for the echo area and dings, i.e. like
547 ;; `error' but doesn't abort. 787 ;; `error' but doesn't abort.
548 ;;
549 ;; This function does not do any hidden buffer changes.
550 `(progn 788 `(progn
551 (message ,format ,@args) 789 (message ,format ,@args)
552 (ding))) 790 (ding)))
553 791
554(defmacro c-update-modeline ()
555 ;; set the c-auto-hungry-string for the correct designation on the modeline
556 ;;
557 ;; This function does not do any hidden buffer changes.
558 `(progn
559 (setq c-auto-hungry-string
560 (if c-auto-newline
561 (if c-hungry-delete-key "/ah" "/a")
562 (if c-hungry-delete-key "/h" nil)))
563 (force-mode-line-update)))
564
565(defmacro c-with-syntax-table (table &rest code) 792(defmacro c-with-syntax-table (table &rest code)
566 ;; Temporarily switches to the specified syntax table in a failsafe 793 ;; Temporarily switches to the specified syntax table in a failsafe
567 ;; way to execute code. 794 ;; way to execute code.
568 ;;
569 ;; This function does not do any hidden buffer changes.
570 `(let ((c-with-syntax-table-orig-table (syntax-table))) 795 `(let ((c-with-syntax-table-orig-table (syntax-table)))
571 (unwind-protect 796 (unwind-protect
572 (progn 797 (progn
@@ -578,9 +803,7 @@ This function does not do any hidden buffer changes."
578(defmacro c-skip-ws-forward (&optional limit) 803(defmacro c-skip-ws-forward (&optional limit)
579 "Skip over any whitespace following point. 804 "Skip over any whitespace following point.
580This function skips over horizontal and vertical whitespace and line 805This function skips over horizontal and vertical whitespace and line
581continuations. 806continuations."
582
583This function does not do any hidden buffer changes."
584 (if limit 807 (if limit
585 `(let ((limit (or ,limit (point-max)))) 808 `(let ((limit (or ,limit (point-max))))
586 (while (progn 809 (while (progn
@@ -601,9 +824,7 @@ This function does not do any hidden buffer changes."
601(defmacro c-skip-ws-backward (&optional limit) 824(defmacro c-skip-ws-backward (&optional limit)
602 "Skip over any whitespace preceding point. 825 "Skip over any whitespace preceding point.
603This function skips over horizontal and vertical whitespace and line 826This function skips over horizontal and vertical whitespace and line
604continuations. 827continuations."
605
606This function does not do any hidden buffer changes."
607 (if limit 828 (if limit
608 `(let ((limit (or ,limit (point-min)))) 829 `(let ((limit (or ,limit (point-min))))
609 (while (progn 830 (while (progn
@@ -624,9 +845,7 @@ This function does not do any hidden buffer changes."
624 845
625(defmacro c-major-mode-is (mode) 846(defmacro c-major-mode-is (mode)
626 "Return non-nil if the current CC Mode major mode is MODE. 847 "Return non-nil if the current CC Mode major mode is MODE.
627MODE is either a mode symbol or a list of mode symbols. 848MODE is either a mode symbol or a list of mode symbols."
628
629This function does not do any hidden buffer changes."
630 849
631 (if c-langs-are-parametric 850 (if c-langs-are-parametric
632 ;; Inside a `c-lang-defconst'. 851 ;; Inside a `c-lang-defconst'.
@@ -643,28 +862,9 @@ This function does not do any hidden buffer changes."
643 (memq c-buffer-is-cc-mode mode) 862 (memq c-buffer-is-cc-mode mode)
644 (eq c-buffer-is-cc-mode mode)))))) 863 (eq c-buffer-is-cc-mode mode))))))
645 864
646(defmacro c-mode-is-new-awk-p ()
647 ;; Is the current mode the "new" awk mode? It is important for
648 ;; (e.g.) the cc-engine functions do distinguish between the old and
649 ;; new awk-modes.
650 '(and (c-major-mode-is 'awk-mode)
651 (memq 'syntax-properties c-emacs-features)))
652
653(defmacro c-parse-sexp-lookup-properties ()
654 ;; Return the value of the variable that says whether the
655 ;; syntax-table property affects the sexp routines. Always return
656 ;; nil in (X)Emacsen without support for that.
657 ;;
658 ;; This function does not do any hidden buffer changes.
659 (cond ((cc-bytecomp-boundp 'parse-sexp-lookup-properties)
660 `parse-sexp-lookup-properties)
661 ((cc-bytecomp-boundp 'lookup-syntax-properties)
662 `lookup-syntax-properties)
663 (t nil)))
664
665 865
666;; Macros/functions to handle so-called "char properties", which are 866;; Macros/functions to handle so-called "char properties", which are
667;; properties set on a single character and that never spreads to any 867;; properties set on a single character and that never spread to any
668;; other characters. 868;; other characters.
669 869
670(eval-and-compile 870(eval-and-compile
@@ -719,6 +919,8 @@ This function does not do any hidden buffer changes."
719 ;; 919 ;;
720 ;; If there's a `text-property-default-nonsticky' variable (Emacs 920 ;; If there's a `text-property-default-nonsticky' variable (Emacs
721 ;; 21) then it's assumed that the property is present on it. 921 ;; 21) then it's assumed that the property is present on it.
922 ;;
923 ;; This macro does a hidden buffer change.
722 (setq property (eval property)) 924 (setq property (eval property))
723 (if (or c-use-extents 925 (if (or c-use-extents
724 (not (cc-bytecomp-boundp 'text-property-default-nonsticky))) 926 (not (cc-bytecomp-boundp 'text-property-default-nonsticky)))
@@ -761,6 +963,8 @@ This function does not do any hidden buffer changes."
761 ;; Remove the given property on the character at POS if it's been put 963 ;; Remove the given property on the character at POS if it's been put
762 ;; there by `c-put-char-property'. PROPERTY is assumed to be 964 ;; there by `c-put-char-property'. PROPERTY is assumed to be
763 ;; constant. 965 ;; constant.
966 ;;
967 ;; This macro does a hidden buffer change.
764 (setq property (eval property)) 968 (setq property (eval property))
765 (cond (c-use-extents 969 (cond (c-use-extents
766 ;; XEmacs. 970 ;; XEmacs.
@@ -785,6 +989,8 @@ This function does not do any hidden buffer changes."
785 ;; lists of the `rear-nonsticky' properties in the region, if such 989 ;; lists of the `rear-nonsticky' properties in the region, if such
786 ;; are used. Thus it should not be used for common properties like 990 ;; are used. Thus it should not be used for common properties like
787 ;; `syntax-table'. 991 ;; `syntax-table'.
992 ;;
993 ;; This macro does hidden buffer changes.
788 (setq property (eval property)) 994 (setq property (eval property))
789 (if c-use-extents 995 (if c-use-extents
790 ;; XEmacs. 996 ;; XEmacs.
@@ -795,12 +1001,44 @@ This function does not do any hidden buffer changes."
795 `(remove-text-properties ,from ,to '(,property nil)))) 1001 `(remove-text-properties ,from ,to '(,property nil))))
796 1002
797 1003
1004;; Macros to put overlays (Emacs) or extents (XEmacs) on buffer text.
1005;; For our purposes, these are characterized by being possible to
1006;; remove again without affecting the other text properties in the
1007;; buffer that got overridden when they were put.
1008
1009(defmacro c-put-overlay (from to property value)
1010 ;; Put an overlay/extent covering the given range in the current
1011 ;; buffer. It's currently undefined whether it's front/end sticky
1012 ;; or not. The overlay/extent object is returned.
1013 (if (cc-bytecomp-fboundp 'make-overlay)
1014 ;; Emacs.
1015 `(let ((ol (make-overlay ,from ,to)))
1016 (overlay-put ol ,property ,value)
1017 ol)
1018 ;; XEmacs.
1019 `(let ((ext (make-extent ,from ,to)))
1020 (set-extent-property ext ,property ,value)
1021 ext)))
1022
1023(defmacro c-delete-overlay (overlay)
1024 ;; Deletes an overlay/extent object previously retrieved using
1025 ;; `c-put-overlay'.
1026 (if (cc-bytecomp-fboundp 'make-overlay)
1027 ;; Emacs.
1028 `(delete-overlay ,overlay)
1029 ;; XEmacs.
1030 `(delete-extent ,overlay)))
1031
1032
798;; Make edebug understand the macros. 1033;; Make edebug understand the macros.
799(eval-after-load "edebug" 1034(eval-after-load "edebug"
800 '(progn 1035 '(progn
1036 (def-edebug-spec cc-eval-when-compile t)
801 (def-edebug-spec c-point t) 1037 (def-edebug-spec c-point t)
1038 (def-edebug-spec c-set-region-active t)
802 (def-edebug-spec c-safe t) 1039 (def-edebug-spec c-safe t)
803 (def-edebug-spec c-save-buffer-state let*) 1040 (def-edebug-spec c-save-buffer-state let*)
1041 (def-edebug-spec c-tentative-buffer-changes t)
804 (def-edebug-spec c-forward-syntactic-ws t) 1042 (def-edebug-spec c-forward-syntactic-ws t)
805 (def-edebug-spec c-backward-syntactic-ws t) 1043 (def-edebug-spec c-backward-syntactic-ws t)
806 (def-edebug-spec c-forward-sexp t) 1044 (def-edebug-spec c-forward-sexp t)
@@ -820,7 +1058,8 @@ This function does not do any hidden buffer changes."
820 (def-edebug-spec c-get-char-property t) 1058 (def-edebug-spec c-get-char-property t)
821 (def-edebug-spec c-clear-char-property t) 1059 (def-edebug-spec c-clear-char-property t)
822 (def-edebug-spec c-clear-char-properties t) 1060 (def-edebug-spec c-clear-char-properties t)
823 (def-edebug-spec cc-eval-when-compile t))) 1061 (def-edebug-spec c-put-overlay t)
1062 (def-edebug-spec c-delete-overlay t)))
824 1063
825 1064
826;;; Functions. 1065;;; Functions.
@@ -847,25 +1086,23 @@ This function does not do any hidden buffer changes."
847 1086
848(defsubst c-mark-<-as-paren (pos) 1087(defsubst c-mark-<-as-paren (pos)
849 ;; Mark the "<" character at POS as an sexp list opener using the 1088 ;; Mark the "<" character at POS as an sexp list opener using the
850 ;; syntax-table property. Note that Emacs 19 and XEmacs <= 20 1089 ;; syntax-table property.
851 ;; doesn't support syntax properties, so this function might not 1090 ;;
852 ;; have any effect. 1091 ;; This function does a hidden buffer change.
853 (c-put-char-property pos 'syntax-table c-<-as-paren-syntax)) 1092 (c-put-char-property pos 'syntax-table c-<-as-paren-syntax))
854 1093
855(defconst c->-as-paren-syntax '(5 . ?<)) 1094(defconst c->-as-paren-syntax '(5 . ?<))
856 1095
857(defsubst c-mark->-as-paren (pos) 1096(defsubst c-mark->-as-paren (pos)
858 ;; Mark the ">" character at POS as an sexp list closer using the 1097 ;; Mark the ">" character at POS as an sexp list closer using the
859 ;; syntax-table property. Note that Emacs 19 and XEmacs <= 20 1098 ;; syntax-table property.
860 ;; doesn't support syntax properties, so this function might not 1099 ;;
861 ;; have any effect. 1100 ;; This function does a hidden buffer change.
862 (c-put-char-property pos 'syntax-table c->-as-paren-syntax)) 1101 (c-put-char-property pos 'syntax-table c->-as-paren-syntax))
863 1102
864(defsubst c-intersect-lists (list alist) 1103(defsubst c-intersect-lists (list alist)
865 ;; return the element of ALIST that matches the first element found 1104 ;; return the element of ALIST that matches the first element found
866 ;; in LIST. Uses assq. 1105 ;; in LIST. Uses assq.
867 ;;
868 ;; This function does not do any hidden buffer changes.
869 (let (match) 1106 (let (match)
870 (while (and list 1107 (while (and list
871 (not (setq match (assq (car list) alist)))) 1108 (not (setq match (assq (car list) alist))))
@@ -875,41 +1112,33 @@ This function does not do any hidden buffer changes."
875(defsubst c-lookup-lists (list alist1 alist2) 1112(defsubst c-lookup-lists (list alist1 alist2)
876 ;; first, find the first entry from LIST that is present in ALIST1, 1113 ;; first, find the first entry from LIST that is present in ALIST1,
877 ;; then find the entry in ALIST2 for that entry. 1114 ;; then find the entry in ALIST2 for that entry.
878 ;;
879 ;; This function does not do any hidden buffer changes.
880 (assq (car (c-intersect-lists list alist1)) alist2)) 1115 (assq (car (c-intersect-lists list alist1)) alist2))
881 1116
882(defsubst c-langelem-sym (langelem) 1117(defsubst c-langelem-sym (langelem)
883 "Return the syntactic symbol in LANGELEM. 1118 "Return the syntactic symbol in LANGELEM.
884 1119
885LANGELEM is a syntactic element, i.e. either a cons cell on the 1120LANGELEM is either a cons cell on the \"old\" form given as the first
886\"old\" form given as the first argument to lineup functions or a list 1121argument to lineup functions or a syntactic element on the \"new\"
887on the \"new\" form as used in `c-syntactic-element'. 1122form as used in `c-syntactic-element'."
888
889This function does not do any hidden buffer changes."
890 (car langelem)) 1123 (car langelem))
891 1124
892(defsubst c-langelem-pos (langelem) 1125(defsubst c-langelem-pos (langelem)
893 "Return the (primary) anchor position in LANGELEM, or nil if there is none. 1126 "Return the anchor position in LANGELEM, or nil if there is none.
894
895LANGELEM is a syntactic element, i.e. either a cons cell on the
896\"old\" form given as the first argument to lineup functions or a list
897on the \"new\" form as used in `c-syntactic-element'.
898 1127
899This function does not do any hidden buffer changes." 1128LANGELEM is either a cons cell on the \"old\" form given as the first
1129argument to lineup functions or a syntactic element on the \"new\"
1130form as used in `c-syntactic-element'."
900 (if (consp (cdr langelem)) 1131 (if (consp (cdr langelem))
901 (car-safe (cdr langelem)) 1132 (car-safe (cdr langelem))
902 (cdr langelem))) 1133 (cdr langelem)))
903 1134
904(defun c-langelem-col (langelem &optional preserve-point) 1135(defun c-langelem-col (langelem &optional preserve-point)
905 "Return the column of the (primary) anchor position in LANGELEM. 1136 "Return the column of the anchor position in LANGELEM.
906Leave point at that position unless PRESERVE-POINT is non-nil. 1137Also move the point to that position unless PRESERVE-POINT is non-nil.
907 1138
908LANGELEM is a syntactic element, i.e. either a cons cell on the 1139LANGELEM is either a cons cell on the \"old\" form given as the first
909\"old\" form given as the first argument to lineup functions or a list 1140argument to lineup functions or a syntactic element on the \"new\"
910on the \"new\" form as used in `c-syntactic-element'. 1141form as used in `c-syntactic-element'."
911
912This function does not do any hidden buffer changes."
913 (let ((pos (c-langelem-pos langelem)) 1142 (let ((pos (c-langelem-pos langelem))
914 (here (point))) 1143 (here (point)))
915 (if pos 1144 (if pos
@@ -923,38 +1152,18 @@ This function does not do any hidden buffer changes."
923(defsubst c-langelem-2nd-pos (langelem) 1152(defsubst c-langelem-2nd-pos (langelem)
924 "Return the secondary position in LANGELEM, or nil if there is none. 1153 "Return the secondary position in LANGELEM, or nil if there is none.
925 1154
926LANGELEM is a syntactic element, typically on the \"new\" form as used 1155LANGELEM is typically a syntactic element on the \"new\" form as used
927in `c-syntactic-element'. It may be on the \"old\" form that is used 1156in `c-syntactic-element'. It may also be a cons cell as passed in the
928as the first argument to lineup functions, but then the returned value 1157first argument to lineup functions, but then the returned value always
929always will be nil. 1158will be nil."
930
931This function does not do any hidden buffer changes."
932 (car-safe (cdr-safe (cdr-safe langelem)))) 1159 (car-safe (cdr-safe (cdr-safe langelem))))
933 1160
934(defsubst c-keep-region-active () 1161(defsubst c-keep-region-active ()
935 ;; Do whatever is necessary to keep the region active in XEmacs. 1162 ;; Do whatever is necessary to keep the region active in XEmacs.
936 ;; This is not needed for Emacs. 1163 ;; This is not needed for Emacs.
937 ;;
938 ;; This function does not do any hidden buffer changes.
939 (and (boundp 'zmacs-region-stays) 1164 (and (boundp 'zmacs-region-stays)
940 (setq zmacs-region-stays t))) 1165 (setq zmacs-region-stays t)))
941 1166
942(defsubst c-region-is-active-p ()
943 ;; Return t when the region is active. The determination of region
944 ;; activeness is different in both Emacs and XEmacs.
945 ;;
946 ;; This function does not do any hidden buffer changes.
947 (cond
948 ;; XEmacs
949 ((and (fboundp 'region-active-p)
950 (boundp 'zmacs-regions)
951 zmacs-regions)
952 (region-active-p))
953 ;; Emacs
954 ((boundp 'mark-active) mark-active)
955 ;; fallback; shouldn't get here
956 (t (mark t))))
957
958(put 'c-mode 'c-mode-prefix "c-") 1167(put 'c-mode 'c-mode-prefix "c-")
959(put 'c++-mode 'c-mode-prefix "c++-") 1168(put 'c++-mode 'c-mode-prefix "c++-")
960(put 'objc-mode 'c-mode-prefix "objc-") 1169(put 'objc-mode 'c-mode-prefix "objc-")
@@ -965,9 +1174,7 @@ This function does not do any hidden buffer changes."
965 1174
966(defsubst c-mode-symbol (suffix) 1175(defsubst c-mode-symbol (suffix)
967 "Prefix the current mode prefix (e.g. \"c-\") to SUFFIX and return 1176 "Prefix the current mode prefix (e.g. \"c-\") to SUFFIX and return
968the corresponding symbol. 1177the corresponding symbol."
969
970This function does not do any hidden buffer changes."
971 (or c-buffer-is-cc-mode 1178 (or c-buffer-is-cc-mode
972 (error "Not inside a CC Mode based mode")) 1179 (error "Not inside a CC Mode based mode"))
973 (let ((mode-prefix (get c-buffer-is-cc-mode 'c-mode-prefix))) 1180 (let ((mode-prefix (get c-buffer-is-cc-mode 'c-mode-prefix)))
@@ -978,16 +1185,12 @@ This function does not do any hidden buffer changes."
978 1185
979(defsubst c-mode-var (suffix) 1186(defsubst c-mode-var (suffix)
980 "Prefix the current mode prefix (e.g. \"c-\") to SUFFIX and return 1187 "Prefix the current mode prefix (e.g. \"c-\") to SUFFIX and return
981the value of the variable with that name. 1188the value of the variable with that name."
982
983This function does not do any hidden buffer changes."
984 (symbol-value (c-mode-symbol suffix))) 1189 (symbol-value (c-mode-symbol suffix)))
985 1190
986(defsubst c-got-face-at (pos faces) 1191(defsubst c-got-face-at (pos faces)
987 "Return non-nil if position POS in the current buffer has any of the 1192 "Return non-nil if position POS in the current buffer has any of the
988faces in the list FACES. 1193faces in the list FACES."
989
990This function does not do any hidden buffer changes."
991 (let ((pos-faces (get-text-property pos 'face))) 1194 (let ((pos-faces (get-text-property pos 'face)))
992 (if (consp pos-faces) 1195 (if (consp pos-faces)
993 (progn 1196 (progn
@@ -1003,31 +1206,72 @@ This function does not do any hidden buffer changes."
1003 ;; face objects (while it's only their names that are used just 1206 ;; face objects (while it's only their names that are used just
1004 ;; about anywhere else) without providing a predicate that tests 1207 ;; about anywhere else) without providing a predicate that tests
1005 ;; face names. 1208 ;; face names.
1006 ;;
1007 ;; This function does not do any hidden buffer changes.
1008 (memq facename (face-list))) 1209 (memq facename (face-list)))
1009 1210
1211(defun c-concat-separated (list separator)
1212 "Like `concat' on LIST, but separate each element with SEPARATOR.
1213Notably, null elements in LIST are ignored."
1214 (mapconcat 'identity (delete nil (append list nil)) separator))
1215
1010(defun c-make-keywords-re (adorn list &optional mode) 1216(defun c-make-keywords-re (adorn list &optional mode)
1011 "Make a regexp that matches all the strings the list. 1217 "Make a regexp that matches all the strings the list.
1012Duplicates in the list are removed. The resulting regexp may contain 1218Duplicates and nil elements in the list are removed. The resulting
1013zero or more submatch expressions. 1219regexp may contain zero or more submatch expressions.
1220
1221If ADORN is t there will be at least one submatch and the first
1222surrounds the matched alternative, and the regexp will also not match
1223a prefix of any identifier. Adorned regexps cannot be appended. The
1224language variable `c-nonsymbol-key' is used to make the adornment.
1225
1226A value 'appendable for ADORN is like above, but all alternatives in
1227the list that end with a word constituent char will have \\> appended
1228instead, so that the regexp remains appendable. Note that this
1229variant doesn't always guarantee that an identifier prefix isn't
1230matched since the symbol constituent '_' is normally considered a
1231nonword token by \\>.
1014 1232
1015If ADORN is non-nil there will be at least one submatch and the first 1233The optional MODE specifies the language to get `c-nonsymbol-key' from
1016matches the whole keyword, and the regexp will also not match a prefix 1234when it's needed. The default is the current language taken from
1017of any identifier. Adorned regexps cannot be appended. The language 1235`c-buffer-is-cc-mode'."
1018variable `c-nonsymbol-key' is used to make the adornment. The
1019optional MODE specifies the language to get it in. The default is the
1020current language (taken from `c-buffer-is-cc-mode')."
1021 1236
1022 (let (unique) 1237 (let (unique)
1023 (dolist (elt list) 1238 (dolist (elt list)
1024 (unless (member elt unique) 1239 (unless (member elt unique)
1025 (push elt unique))) 1240 (push elt unique)))
1026 (setq list unique)) 1241 (setq list (delete nil unique)))
1027 (if list 1242 (if list
1028 (let ((re (c-regexp-opt list))) 1243 (let (re)
1029 1244
1030 ;; Emacs < 21 and XEmacs (all versions so far) has a buggy 1245 (if (eq adorn 'appendable)
1246 ;; This is kludgy but it works: Search for a string that
1247 ;; doesn't occur in any word in LIST. Append it to all
1248 ;; the alternatives where we want to add \>. Run through
1249 ;; `regexp-opt' and then replace it with \>.
1250 (let ((unique "") pos)
1251 (while (let (found)
1252 (setq unique (concat unique "@")
1253 pos list)
1254 (while (and pos
1255 (if (string-match unique (car pos))
1256 (progn (setq found t)
1257 nil)
1258 t))
1259 (setq pos (cdr pos)))
1260 found))
1261 (setq pos list)
1262 (while pos
1263 (if (string-match "\\w\\'" (car pos))
1264 (setcar pos (concat (car pos) unique)))
1265 (setq pos (cdr pos)))
1266 (setq re (regexp-opt list))
1267 (setq pos 0)
1268 (while (string-match unique re pos)
1269 (setq pos (+ (match-beginning 0) 2)
1270 re (replace-match "\\>" t t re))))
1271
1272 (setq re (regexp-opt list)))
1273
1274 ;; Emacs 20 and XEmacs (all versions so far) has a buggy
1031 ;; regexp-opt that doesn't always cope with strings containing 1275 ;; regexp-opt that doesn't always cope with strings containing
1032 ;; newlines. This kludge doesn't handle shy parens correctly 1276 ;; newlines. This kludge doesn't handle shy parens correctly
1033 ;; so we can't advice regexp-opt directly with it. 1277 ;; so we can't advice regexp-opt directly with it.
@@ -1041,21 +1285,31 @@ current language (taken from `c-buffer-is-cc-mode')."
1041 (when fail-list 1285 (when fail-list
1042 (setq re (concat re 1286 (setq re (concat re
1043 "\\|" 1287 "\\|"
1044 (mapconcat 'regexp-quote 1288 (mapconcat
1045 (sort fail-list 1289 (if (eq adorn 'appendable)
1046 (lambda (a b) 1290 (lambda (str)
1047 (> (length a) (length b)))) 1291 (if (string-match "\\w\\'" str)
1048 "\\|"))))) 1292 (concat (regexp-quote str)
1293 "\\>")
1294 (regexp-quote str)))
1295 'regexp-quote)
1296 (sort fail-list
1297 (lambda (a b)
1298 (> (length a) (length b))))
1299 "\\|")))))
1049 1300
1050 ;; Add our own grouping parenthesis around re instead of 1301 ;; Add our own grouping parenthesis around re instead of
1051 ;; passing adorn to `regexp-opt', since in XEmacs it makes the 1302 ;; passing adorn to `regexp-opt', since in XEmacs it makes the
1052 ;; top level grouping "shy". 1303 ;; top level grouping "shy".
1053 (if adorn 1304 (cond ((eq adorn 'appendable)
1054 (concat "\\(" re "\\)" 1305 (concat "\\(" re "\\)"))
1055 "\\(" 1306 (adorn
1056 (c-get-lang-constant 'c-nonsymbol-key nil mode) 1307 (concat "\\(" re "\\)"
1057 "\\|$\\)") 1308 "\\("
1058 re)) 1309 (c-get-lang-constant 'c-nonsymbol-key nil mode)
1310 "\\|$\\)"))
1311 (t
1312 re)))
1059 1313
1060 ;; Produce a regexp that matches nothing. 1314 ;; Produce a regexp that matches nothing.
1061 (if adorn 1315 (if adorn
@@ -1064,6 +1318,35 @@ current language (taken from `c-buffer-is-cc-mode')."
1064 1318
1065(put 'c-make-keywords-re 'lisp-indent-function 1) 1319(put 'c-make-keywords-re 'lisp-indent-function 1)
1066 1320
1321(defun c-make-bare-char-alt (chars &optional inverted)
1322 "Make a character alternative string from the list of characters CHARS.
1323The returned string is of the type that can be used with
1324`skip-chars-forward' and `skip-chars-backward'. If INVERTED is
1325non-nil, a caret is prepended to invert the set."
1326 ;; This function ought to be in the elisp core somewhere.
1327 (let ((str (if inverted "^" "")) char char2)
1328 (setq chars (sort (append chars nil) `<))
1329 (while chars
1330 (setq char (pop chars))
1331 (if (memq char '(?\\ ?^ ?-))
1332 ;; Quoting necessary (this method only works in the skip
1333 ;; functions).
1334 (setq str (format "%s\\%c" str char))
1335 (setq str (format "%s%c" str char)))
1336 ;; Check for range.
1337 (setq char2 char)
1338 (while (and chars (>= (1+ char2) (car chars)))
1339 (setq char2 (pop chars)))
1340 (unless (= char char2)
1341 (if (< (1+ char) char2)
1342 (setq str (format "%s-%c" str char2))
1343 (push char2 chars))))
1344 str))
1345
1346;; Leftovers from (X)Emacs 19 compatibility.
1347(defalias 'c-regexp-opt 'regexp-opt)
1348(defalias 'c-regexp-opt-depth 'regexp-opt-depth)
1349
1067 1350
1068;; Figure out what features this Emacs has 1351;; Figure out what features this Emacs has
1069 1352
@@ -1076,24 +1359,21 @@ current language (taken from `c-buffer-is-cc-mode')."
1076 ;; I've no idea what this actually is, but it's legacy. /mast 1359 ;; I've no idea what this actually is, but it's legacy. /mast
1077 (setq list (cons 'infodock list))) 1360 (setq list (cons 'infodock list)))
1078 1361
1079 ;; XEmacs 19 and beyond use 8-bit modify-syntax-entry flags. 1362 ;; XEmacs uses 8-bit modify-syntax-entry flags.
1080 ;; Emacs 19 uses a 1-bit flag. We will have to set up our 1363 ;; Emacs uses a 1-bit flag. We will have to set up our
1081 ;; syntax tables differently to handle this. 1364 ;; syntax tables differently to handle this.
1082 (let ((table (copy-syntax-table)) 1365 (let ((table (copy-syntax-table))
1083 entry) 1366 entry)
1084 (modify-syntax-entry ?a ". 12345678" table) 1367 (modify-syntax-entry ?a ". 12345678" table)
1085 (cond 1368 (cond
1086 ;; XEmacs 19, and beyond Emacs 19.34 1369 ;; Emacs
1087 ((arrayp table) 1370 ((arrayp table)
1088 (setq entry (aref table ?a)) 1371 (setq entry (aref table ?a))
1089 ;; In Emacs, table entries are cons cells 1372 ;; In Emacs, table entries are cons cells
1090 (if (consp entry) (setq entry (car entry)))) 1373 (if (consp entry) (setq entry (car entry))))
1091 ;; XEmacs 20 1374 ;; XEmacs
1092 ((fboundp 'get-char-table) (setq entry (get-char-table ?a table))) 1375 ((fboundp 'get-char-table)
1093 ;; before and including Emacs 19.34 1376 (setq entry (get-char-table ?a table)))
1094 ((and (fboundp 'char-table-p)
1095 (char-table-p table))
1096 (setq entry (car (char-table-range table [?a]))))
1097 ;; incompatible 1377 ;; incompatible
1098 (t (error "CC Mode is incompatible with this version of Emacs"))) 1378 (t (error "CC Mode is incompatible with this version of Emacs")))
1099 (setq list (cons (if (= (logand (lsh entry -16) 255) 255) 1379 (setq list (cons (if (= (logand (lsh entry -16) 255) 255)
@@ -1125,7 +1405,11 @@ current language (taken from `c-buffer-is-cc-mode')."
1125 (goto-char 1) 1405 (goto-char 1)
1126 (c-forward-sexp) 1406 (c-forward-sexp)
1127 (if (= (point) 5) 1407 (if (= (point) 5)
1128 (setq list (cons 'syntax-properties list))) 1408 (setq list (cons 'syntax-properties list))
1409 (error (concat
1410 "CC Mode is incompatible with this version of Emacs - "
1411 "support for the `syntax-table' text property "
1412 "is required.")))
1129 1413
1130 ;; Find out if generic comment delimiters work. 1414 ;; Find out if generic comment delimiters work.
1131 (c-safe 1415 (c-safe
@@ -1153,7 +1437,7 @@ current language (taken from `c-buffer-is-cc-mode')."
1153 (setq list (cons 'posix-char-classes list))) 1437 (setq list (cons 'posix-char-classes list)))
1154 1438
1155 ;; See if `open-paren-in-column-0-is-defun-start' exists and 1439 ;; See if `open-paren-in-column-0-is-defun-start' exists and
1156 ;; isn't buggy. 1440 ;; isn't buggy (Emacs >= 21.4).
1157 (when (boundp 'open-paren-in-column-0-is-defun-start) 1441 (when (boundp 'open-paren-in-column-0-is-defun-start)
1158 (let ((open-paren-in-column-0-is-defun-start nil) 1442 (let ((open-paren-in-column-0-is-defun-start nil)
1159 (parse-sexp-ignore-comments t)) 1443 (parse-sexp-ignore-comments t))
@@ -1180,8 +1464,11 @@ current language (taken from `c-buffer-is-cc-mode')."
1180 (kill-buffer buf)) 1464 (kill-buffer buf))
1181 1465
1182 ;; See if `parse-partial-sexp' returns the eighth element. 1466 ;; See if `parse-partial-sexp' returns the eighth element.
1183 (when (c-safe (>= (length (save-excursion (parse-partial-sexp 1 1))) 10)) 1467 (if (c-safe (>= (length (save-excursion (parse-partial-sexp 1 1))) 10))
1184 (setq list (cons 'pps-extended-state list))) 1468 (setq list (cons 'pps-extended-state list))
1469 (error (concat
1470 "CC Mode is incompatible with this version of Emacs - "
1471 "`parse-partial-sexp' has to return at least 10 elements.")))
1185 1472
1186 ;;(message "c-emacs-features: %S" list) 1473 ;;(message "c-emacs-features: %S" list)
1187 list) 1474 list)
@@ -1193,14 +1480,17 @@ might be present:
1193'8-bit 8 bit syntax entry flags (XEmacs style). 1480'8-bit 8 bit syntax entry flags (XEmacs style).
1194'1-bit 1 bit syntax entry flags (Emacs style). 1481'1-bit 1 bit syntax entry flags (Emacs style).
1195'syntax-properties It works to override the syntax for specific characters 1482'syntax-properties It works to override the syntax for specific characters
1196 in the buffer with the 'syntax-table property. 1483 in the buffer with the 'syntax-table property. It's
1484 always set - CC Mode no longer works in emacsen without
1485 this feature.
1197'gen-comment-delim Generic comment delimiters work 1486'gen-comment-delim Generic comment delimiters work
1198 (i.e. the syntax class `!'). 1487 (i.e. the syntax class `!').
1199'gen-string-delim Generic string delimiters work 1488'gen-string-delim Generic string delimiters work
1200 (i.e. the syntax class `|'). 1489 (i.e. the syntax class `|').
1201'pps-extended-state `parse-partial-sexp' returns a list with at least 10 1490'pps-extended-state `parse-partial-sexp' returns a list with at least 10
1202 elements, i.e. it contains the position of the 1491 elements, i.e. it contains the position of the start of
1203 start of the last comment or string. 1492 the last comment or string. It's always set - CC Mode no
1493 longer works in emacsen without this feature.
1204'posix-char-classes The regexp engine understands POSIX character classes. 1494'posix-char-classes The regexp engine understands POSIX character classes.
1205'col-0-paren It's possible to turn off the ad-hoc rule that a paren 1495'col-0-paren It's possible to turn off the ad-hoc rule that a paren
1206 in column zero is the start of a defun. 1496 in column zero is the start of a defun.
@@ -1359,9 +1649,7 @@ To work well with repeated loads and interactive reevaluation, only
1359one `c-lang-defconst' for each NAME is permitted per file. If there 1649one `c-lang-defconst' for each NAME is permitted per file. If there
1360already is one it will be completely replaced; the value in the 1650already is one it will be completely replaced; the value in the
1361earlier definition will not affect `c-lang-const' on the same 1651earlier definition will not affect `c-lang-const' on the same
1362constant. A file is identified by its base name. 1652constant. A file is identified by its base name."
1363
1364This macro does not do any hidden buffer changes."
1365 1653
1366 (let* ((sym (intern (symbol-name name) c-lang-constants)) 1654 (let* ((sym (intern (symbol-name name) c-lang-constants))
1367 ;; Make `c-lang-const' expand to a straightforward call to 1655 ;; Make `c-lang-const' expand to a straightforward call to
@@ -1451,8 +1739,7 @@ This macro does not do any hidden buffer changes."
1451 (&define name [&optional stringp] [&rest sexp def-form]))) 1739 (&define name [&optional stringp] [&rest sexp def-form])))
1452 1740
1453(defun c-define-lang-constant (name bindings &optional pre-files) 1741(defun c-define-lang-constant (name bindings &optional pre-files)
1454 ;; Used by `c-lang-defconst'. This function does not do any hidden 1742 ;; Used by `c-lang-defconst'.
1455 ;; buffer changes.
1456 1743
1457 (let* ((sym (intern (symbol-name name) c-lang-constants)) 1744 (let* ((sym (intern (symbol-name name) c-lang-constants))
1458 (source (get sym 'source)) 1745 (source (get sym 'source))
@@ -1504,9 +1791,7 @@ LANG is the name of the language, i.e. the mode name without the
1504\"-mode\" suffix. If used inside `c-lang-defconst' or 1791\"-mode\" suffix. If used inside `c-lang-defconst' or
1505`c-lang-defvar', LANG may be left out to refer to the current 1792`c-lang-defvar', LANG may be left out to refer to the current
1506language. NAME and LANG are not evaluated so they should not be 1793language. NAME and LANG are not evaluated so they should not be
1507quoted. 1794quoted."
1508
1509This macro does not do any hidden buffer changes."
1510 1795
1511 (or (symbolp name) 1796 (or (symbolp name)
1512 (error "Not a symbol: %s" name)) 1797 (error "Not a symbol: %s" name))
@@ -1516,18 +1801,12 @@ This macro does not do any hidden buffer changes."
1516 (let ((sym (intern (symbol-name name) c-lang-constants)) 1801 (let ((sym (intern (symbol-name name) c-lang-constants))
1517 mode source-files args) 1802 mode source-files args)
1518 1803
1519 (if lang 1804 (when lang
1520 (progn 1805 (setq mode (intern (concat (symbol-name lang) "-mode")))
1521 (setq mode (intern (concat (symbol-name lang) "-mode"))) 1806 (unless (get mode 'c-mode-prefix)
1522 (unless (get mode 'c-mode-prefix) 1807 (error
1523 (error 1808 "Unknown language %S since it got no `c-mode-prefix' property"
1524 "Unknown language %S since it got no `c-mode-prefix' property" 1809 (symbol-name lang))))
1525 (symbol-name lang))))
1526 (if c-buffer-is-cc-mode
1527 (setq lang c-buffer-is-cc-mode)
1528 (or c-langs-are-parametric
1529 (error
1530 "`c-lang-const' requires a literal language in this context"))))
1531 1810
1532 (if (eq c-lang-const-expansion 'immediate) 1811 (if (eq c-lang-const-expansion 'immediate)
1533 ;; No need to find out the source file(s) when we evaluate 1812 ;; No need to find out the source file(s) when we evaluate
@@ -1550,7 +1829,7 @@ This macro does not do any hidden buffer changes."
1550 (list (car elem)))) 1829 (list (car elem))))
1551 (get sym 'source)))))) 1830 (get sym 'source))))))
1552 1831
1553 ;; Spend some effort to make a compact call to 1832 ;; Make some effort to do a compact call to
1554 ;; `c-get-lang-constant' since it will be compiled in. 1833 ;; `c-get-lang-constant' since it will be compiled in.
1555 (setq args (and mode `(',mode))) 1834 (setq args (and mode `(',mode)))
1556 (if (or source-files args) 1835 (if (or source-files args)
@@ -1558,12 +1837,15 @@ This macro does not do any hidden buffer changes."
1558 args))) 1837 args)))
1559 1838
1560 (if (or (eq c-lang-const-expansion 'call) 1839 (if (or (eq c-lang-const-expansion 'call)
1840 (and (not c-lang-const-expansion)
1841 (not mode))
1561 load-in-progress 1842 load-in-progress
1562 (not (boundp 'byte-compile-dest-file)) 1843 (not (boundp 'byte-compile-dest-file))
1563 (not (stringp byte-compile-dest-file))) 1844 (not (stringp byte-compile-dest-file)))
1564 ;; Either a straight call is requested in the context, or 1845 ;; Either a straight call is requested in the context, or
1565 ;; we're not being byte compiled so the compile time stuff 1846 ;; we're in an "uncontrolled" context and got no language,
1566 ;; below is unnecessary. 1847 ;; or we're not being byte compiled so the compile time
1848 ;; stuff below is unnecessary.
1567 `(c-get-lang-constant ',name ,@args) 1849 `(c-get-lang-constant ',name ,@args)
1568 1850
1569 ;; Being compiled. If the loading and compiling version is 1851 ;; Being compiled. If the loading and compiling version is
@@ -1577,8 +1859,7 @@ This macro does not do any hidden buffer changes."
1577(defvar c-lang-constants-under-evaluation nil) 1859(defvar c-lang-constants-under-evaluation nil)
1578 1860
1579(defun c-get-lang-constant (name &optional source-files mode) 1861(defun c-get-lang-constant (name &optional source-files mode)
1580 ;; Used by `c-lang-const'. This function does not do any hidden 1862 ;; Used by `c-lang-const'.
1581 ;; buffer changes.
1582 1863
1583 (or mode 1864 (or mode
1584 (setq mode c-buffer-is-cc-mode) 1865 (setq mode c-buffer-is-cc-mode)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 71dc39a56e9..c9f2b87b7f1 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -1,6 +1,7 @@
1;;; cc-engine.el --- core syntax guessing engine for CC mode 1;;; cc-engine.el --- core syntax guessing engine for CC mode
2 2
3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation,
4;; Inc.
4 5
5;; Authors: 1998- Martin Stjernholm 6;; Authors: 1998- Martin Stjernholm
6;; 1992-1999 Barry A. Warsaw 7;; 1992-1999 Barry A. Warsaw
@@ -44,21 +45,29 @@
44;; 45;;
45;; Various functions in CC Mode use text properties for caching and 46;; Various functions in CC Mode use text properties for caching and
46;; syntactic markup purposes, and those of them that might modify such 47;; syntactic markup purposes, and those of them that might modify such
47;; properties are said to do "hidden buffer changes". They should be 48;; properties but still don't modify the buffer in a visible way are
48;; used within `c-save-buffer-state' or a similar function that saves 49;; said to do "hidden buffer changes". They should be used within
49;; and restores buffer modifiedness etc. 50;; `c-save-buffer-state' or a similar function that saves and restores
51;; buffer modifiedness, disables buffer change hooks, etc.
50;; 52;;
51;; Interactive functions are assumed to not do hidden buffer changes 53;; Interactive functions are assumed to not do hidden buffer changes,
52;; (this isn't applicable in the specific parts of them that do real 54;; except in the specific parts of them that do real changes.
53;; changes, though).
54;; 55;;
55;; All other functions are assumed to do hidden buffer changes and 56;; Lineup functions are assumed to do hidden buffer changes. They
56;; must thus be wrapped inside `c-save-buffer-state' if they're used 57;; must not do real changes, though.
57;; from any function that does not do hidden buffer changes.
58;; 58;;
59;; Every function, except the interactive ones, that doesn't do hidden 59;; All other functions that do hidden buffer changes have that noted
60;; buffer changes have that explicitly stated in their docstring or 60;; in their doc string or comment.
61;; comment. 61;;
62;; The intention with this system is to avoid wrapping every leaf
63;; function that do hidden buffer changes inside
64;; `c-save-buffer-state'. It should be used as near the top of the
65;; interactive functions as possible.
66;;
67;; Functions called during font locking are allowed to do hidden
68;; buffer changes since the font-lock package run them in a context
69;; similar to `c-save-buffer-state' (in fact, that function is heavily
70;; inspired by `save-buffer-state' in the font-lock package).
62 71
63;; Use of text properties 72;; Use of text properties
64;; 73;;
@@ -86,8 +95,8 @@
86;; 95;;
87;; 'c-type 96;; 'c-type
88;; This property is used on single characters to mark positions with 97;; This property is used on single characters to mark positions with
89;; special syntactic relevance of various sorts. It's primary use 98;; special syntactic relevance of various sorts. Its primary use is
90;; is to avoid glitches when multiline constructs are refontified 99;; to avoid glitches when multiline constructs are refontified
91;; interactively (on font lock decoration level 3). It's cleared in 100;; interactively (on font lock decoration level 3). It's cleared in
92;; a region before it's fontified and is then put on relevant chars 101;; a region before it's fontified and is then put on relevant chars
93;; in that region as they are encountered during the fontification. 102;; in that region as they are encountered during the fontification.
@@ -134,19 +143,6 @@
134(cc-require-when-compile 'cc-langs) 143(cc-require-when-compile 'cc-langs)
135(cc-require 'cc-vars) 144(cc-require 'cc-vars)
136 145
137;; Some functions/constants in cc-awk.el that are called/referenced here.
138;; (Can't use cc-require due to cyclicity.)
139(cc-bytecomp-defun c-awk-unstick-NL-prop)
140(cc-bytecomp-defun c-awk-clear-NL-props)
141(cc-bytecomp-defvar awk-mode-syntax-table)
142(cc-bytecomp-defun c-awk-backward-syntactic-ws)
143(cc-bytecomp-defun c-awk-after-logical-semicolon)
144(cc-bytecomp-defun c-awk-NL-prop-not-set)
145(cc-bytecomp-defun c-awk-completed-stmt-ws-ends-line-p)
146(cc-bytecomp-defun c-awk-completed-stmt-ws-ends-prev-line-p)
147(cc-bytecomp-defun c-awk-prev-line-incomplete-p)
148(cc-bytecomp-defun c-awk-after-change)
149
150;; Silence the compiler. 146;; Silence the compiler.
151(cc-bytecomp-defun buffer-syntactic-context) ; XEmacs 147(cc-bytecomp-defun buffer-syntactic-context) ; XEmacs
152 148
@@ -171,13 +167,20 @@
171(defvar c-hungry-delete-key nil) 167(defvar c-hungry-delete-key nil)
172(make-variable-buffer-local 'c-hungry-delete-key) 168(make-variable-buffer-local 'c-hungry-delete-key)
173 169
170;; The electric flag (toggled by `c-toggle-electric-state').
171;; If t, electric actions (like automatic reindentation, and (if
172;; c-auto-newline is also set) auto newlining) will happen when an electric
173;; key like `{' is pressed (or an electric keyword like `else').
174(defvar c-electric-flag t)
175(make-variable-buffer-local 'c-electric-flag)
176
174;; Internal state of auto newline feature. 177;; Internal state of auto newline feature.
175(defvar c-auto-newline nil) 178(defvar c-auto-newline nil)
176(make-variable-buffer-local 'c-auto-newline) 179(make-variable-buffer-local 'c-auto-newline)
177 180
178;; Internal auto-newline/hungry-delete designation string for mode line. 181;; Included in the mode line to indicate the active submodes.
179(defvar c-auto-hungry-string nil) 182(defvar c-submode-indicators nil)
180(make-variable-buffer-local 'c-auto-hungry-string) 183(make-variable-buffer-local 'c-submode-indicators)
181 184
182(defun c-calculate-state (arg prevstate) 185(defun c-calculate-state (arg prevstate)
183 ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If 186 ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
@@ -191,11 +194,6 @@
191;; Dynamically bound cache for `c-in-literal'. 194;; Dynamically bound cache for `c-in-literal'.
192(defvar c-in-literal-cache t) 195(defvar c-in-literal-cache t)
193 196
194;; Must be set in buffers where the `c-type' text property might be used
195;; with the value `c-decl-end'.
196(defvar c-type-decl-end-used nil)
197(make-variable-buffer-local 'c-type-decl-end-used)
198
199 197
200;; Basic handling of preprocessor directives. 198;; Basic handling of preprocessor directives.
201 199
@@ -205,19 +203,19 @@
205(defvar c-macro-start 'unknown) 203(defvar c-macro-start 'unknown)
206 204
207(defsubst c-query-and-set-macro-start () 205(defsubst c-query-and-set-macro-start ()
208 ;; This function does not do any hidden buffer changes.
209 (if (symbolp c-macro-start) 206 (if (symbolp c-macro-start)
210 (setq c-macro-start (save-excursion 207 (setq c-macro-start (save-excursion
211 (and (c-beginning-of-macro) 208 (c-save-buffer-state ()
212 (point)))) 209 (and (c-beginning-of-macro)
210 (point)))))
213 c-macro-start)) 211 c-macro-start))
214 212
215(defsubst c-query-macro-start () 213(defsubst c-query-macro-start ()
216 ;; This function does not do any hidden buffer changes.
217 (if (symbolp c-macro-start) 214 (if (symbolp c-macro-start)
218 (save-excursion 215 (save-excursion
219 (and (c-beginning-of-macro) 216 (c-save-buffer-state ()
220 (point))) 217 (and (c-beginning-of-macro)
218 (point))))
221 c-macro-start)) 219 c-macro-start))
222 220
223(defun c-beginning-of-macro (&optional lim) 221(defun c-beginning-of-macro (&optional lim)
@@ -225,7 +223,8 @@
225Leave point at the beginning of the directive and return t if in one, 223Leave point at the beginning of the directive and return t if in one,
226otherwise return nil and leave point unchanged. 224otherwise return nil and leave point unchanged.
227 225
228This function does not do any hidden buffer changes." 226Note that this function might do hidden buffer changes. See the
227comment at the start of cc-engine.el for more info."
229 (when c-opt-cpp-prefix 228 (when c-opt-cpp-prefix
230 (let ((here (point))) 229 (let ((here (point)))
231 (save-restriction 230 (save-restriction
@@ -242,10 +241,12 @@ This function does not do any hidden buffer changes."
242 241
243(defun c-end-of-macro () 242(defun c-end-of-macro ()
244 "Go to the end of a preprocessor directive. 243 "Go to the end of a preprocessor directive.
245More accurately, move point to the end of the closest following line 244More accurately, move the point to the end of the closest following
246that doesn't end with a line continuation backslash. 245line that doesn't end with a line continuation backslash - no check is
246done that the point is inside a cpp directive to begin with.
247 247
248This function does not do any hidden buffer changes." 248Note that this function might do hidden buffer changes. See the
249comment at the start of cc-engine.el for more info."
249 (while (progn 250 (while (progn
250 (end-of-line) 251 (end-of-line)
251 (when (and (eq (char-before) ?\\) 252 (when (and (eq (char-before) ?\\)
@@ -256,45 +257,104 @@ This function does not do any hidden buffer changes."
256(defun c-forward-to-cpp-define-body () 257(defun c-forward-to-cpp-define-body ()
257 ;; Assuming point is at the "#" that introduces a preprocessor 258 ;; Assuming point is at the "#" that introduces a preprocessor
258 ;; directive, it's moved forward to the start of the definition body 259 ;; directive, it's moved forward to the start of the definition body
259 ;; if it's a "#define". Non-nil is returned in this case, in all 260 ;; if it's a "#define" (or whatever c-opt-cpp-macro-define
260 ;; other cases nil is returned and point isn't moved. 261 ;; specifies). Non-nil is returned in this case, in all other cases
261 (when (and (looking-at 262 ;; nil is returned and point isn't moved.
262 (concat "#[ \t]*" 263 ;;
263 "define[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?" 264 ;; This function might do hidden buffer changes.
264 "\\([ \t]\\|\\\\\n\\)*")) 265 (when (and c-opt-cpp-macro-define-start
266 (looking-at c-opt-cpp-macro-define-start)
265 (not (= (match-end 0) (c-point 'eol)))) 267 (not (= (match-end 0) (c-point 'eol))))
266 (goto-char (match-end 0)))) 268 (goto-char (match-end 0))))
267 269
268 270
269;;; Basic utility functions. 271;;; Basic utility functions.
270 272
271(defun c-syntactic-content (from to) 273(defun c-syntactic-content (from to paren-level)
272 ;; Return the given region as a string where all syntactic 274 ;; Return the given region as a string where all syntactic
273 ;; whitespace is removed or, where necessary, replaced with a single 275 ;; whitespace is removed or, where necessary, replaced with a single
274 ;; space. 276 ;; space. If PAREN-LEVEL is given then all parens in the region are
277 ;; collapsed to "()", "[]" etc.
278 ;;
279 ;; This function might do hidden buffer changes.
280
275 (save-excursion 281 (save-excursion
276 (goto-char from) 282 (save-restriction
277 (let* ((parts (list nil)) (tail parts) pos) 283 (narrow-to-region from to)
278 (while (re-search-forward c-syntactic-ws-start to t) 284 (goto-char from)
279 (goto-char (setq pos (match-beginning 0))) 285 (let* ((parts (list nil)) (tail parts) pos in-paren)
280 (c-forward-syntactic-ws to) 286
281 (if (= (point) pos) 287 (while (re-search-forward c-syntactic-ws-start to t)
282 (forward-char) 288 (goto-char (setq pos (match-beginning 0)))
283 (if (and (> pos from) 289 (c-forward-syntactic-ws)
284 (< (point) to) 290 (if (= (point) pos)
285 (looking-at "\\w\\|\\s_") 291 (forward-char)
286 (save-excursion 292
287 (goto-char (1- pos)) 293 (when paren-level
288 (looking-at "\\w\\|\\s_"))) 294 (save-excursion
289 (progn 295 (setq in-paren (= (car (parse-partial-sexp from pos 1)) 1)
290 (setcdr tail (list (buffer-substring-no-properties from pos) 296 pos (point))))
291 " ")) 297
292 (setq tail (cddr tail))) 298 (if (and (> pos from)
293 (setcdr tail (list (buffer-substring-no-properties from pos))) 299 (< (point) to)
294 (setq tail (cdr tail))) 300 (looking-at "\\w\\|\\s_")
295 (setq from (point)))) 301 (save-excursion
296 (setcdr tail (list (buffer-substring-no-properties from to))) 302 (goto-char (1- pos))
297 (apply 'concat (cdr parts))))) 303 (looking-at "\\w\\|\\s_")))
304 (progn
305 (setcdr tail (list (buffer-substring-no-properties from pos)
306 " "))
307 (setq tail (cddr tail)))
308 (setcdr tail (list (buffer-substring-no-properties from pos)))
309 (setq tail (cdr tail)))
310
311 (when in-paren
312 (when (= (car (parse-partial-sexp pos to -1)) -1)
313 (setcdr tail (list (buffer-substring-no-properties
314 (1- (point)) (point))))
315 (setq tail (cdr tail))))
316
317 (setq from (point))))
318
319 (setcdr tail (list (buffer-substring-no-properties from to)))
320 (apply 'concat (cdr parts))))))
321
322(defun c-shift-line-indentation (shift-amt)
323 ;; Shift the indentation of the current line with the specified
324 ;; amount (positive inwards). The buffer is modified only if
325 ;; SHIFT-AMT isn't equal to zero.
326 (let ((pos (- (point-max) (point)))
327 (c-macro-start c-macro-start)
328 tmp-char-inserted)
329 (if (zerop shift-amt)
330 nil
331 ;; If we're on an empty line inside a macro, we take the point
332 ;; to be at the current indentation and shift it to the
333 ;; appropriate column. This way we don't treat the extra
334 ;; whitespace out to the line continuation as indentation.
335 (when (and (c-query-and-set-macro-start)
336 (looking-at "[ \t]*\\\\$")
337 (save-excursion
338 (skip-chars-backward " \t")
339 (bolp)))
340 (insert ?x)
341 (backward-char)
342 (setq tmp-char-inserted t))
343 (unwind-protect
344 (let ((col (current-indentation)))
345 (delete-region (c-point 'bol) (c-point 'boi))
346 (beginning-of-line)
347 (indent-to (+ col shift-amt)))
348 (when tmp-char-inserted
349 (delete-char 1))))
350 ;; If initial point was within line's indentation and we're not on
351 ;; a line with a line continuation in a macro, position after the
352 ;; indentation. Else stay at same point in text.
353 (if (and (< (point) (c-point 'boi))
354 (not tmp-char-inserted))
355 (back-to-indentation)
356 (if (> (- (point-max) pos) (point))
357 (goto-char (- (point-max) pos))))))
298 358
299(defsubst c-keyword-sym (keyword) 359(defsubst c-keyword-sym (keyword)
300 ;; Return non-nil if the string KEYWORD is a known keyword. More 360 ;; Return non-nil if the string KEYWORD is a known keyword. More
@@ -314,18 +374,21 @@ This function does not do any hidden buffer changes."
314 "\"|" 374 "\"|"
315 "\"")) 375 "\""))
316 376
317;; Regexp matching string start syntax. 377;; Regexp matching string limit syntax.
318(defconst c-string-limit-regexp (if (memq 'gen-string-delim c-emacs-features) 378(defconst c-string-limit-regexp (if (memq 'gen-string-delim c-emacs-features)
319 "\\s\"\\|\\s|" 379 "\\s\"\\|\\s|"
320 "\\s\"")) 380 "\\s\""))
321 381
382;; Regexp matching WS followed by string limit syntax.
383(defconst c-ws*-string-limit-regexp
384 (concat "[ \t]*\\(" c-string-limit-regexp "\\)"))
385
322;; Holds formatted error strings for the few cases where parse errors 386;; Holds formatted error strings for the few cases where parse errors
323;; are reported. 387;; are reported.
324(defvar c-parsing-error nil) 388(defvar c-parsing-error nil)
325(make-variable-buffer-local 'c-parsing-error) 389(make-variable-buffer-local 'c-parsing-error)
326 390
327(defun c-echo-parsing-error (&optional quiet) 391(defun c-echo-parsing-error (&optional quiet)
328 ;; This function does not do any hidden buffer changes.
329 (when (and c-report-syntactic-errors c-parsing-error (not quiet)) 392 (when (and c-report-syntactic-errors c-parsing-error (not quiet))
330 (c-benign-error "%s" c-parsing-error)) 393 (c-benign-error "%s" c-parsing-error))
331 c-parsing-error) 394 c-parsing-error)
@@ -335,39 +398,29 @@ This function does not do any hidden buffer changes."
335;; locking is in use. This variable is extended with the face in 398;; locking is in use. This variable is extended with the face in
336;; `c-doc-face-name' when fontification is activated in cc-fonts.el. 399;; `c-doc-face-name' when fontification is activated in cc-fonts.el.
337(defvar c-literal-faces 400(defvar c-literal-faces
338 '(font-lock-comment-face font-lock-string-face 401 (append '(font-lock-comment-face font-lock-string-face)
339 font-lock-comment-delimiter-face)) 402 (when (facep 'font-lock-comment-delimiter-face)
340 403 ;; New in Emacs 22.
341(defun c-shift-line-indentation (shift-amt) 404 '(font-lock-comment-delimiter-face))))
342 ;; This function does not do any hidden buffer changes. 405
343 (let ((pos (- (point-max) (point))) 406(defsubst c-put-c-type-property (pos value)
344 (c-macro-start c-macro-start) 407 ;; Put a c-type property with the given value at POS.
345 tmp-char-inserted) 408 (c-put-char-property pos 'c-type value))
346 (if (zerop shift-amt) 409
347 nil 410(defun c-clear-c-type-property (from to value)
348 (when (and (c-query-and-set-macro-start) 411 ;; Remove all occurences of the c-type property that has the given
349 (looking-at "[ \t]*\\\\$") 412 ;; value in the region between FROM and TO. VALUE is assumed to not
350 (save-excursion 413 ;; be nil.
351 (skip-chars-backward " \t") 414 ;;
352 (bolp))) 415 ;; Note: This assumes that c-type is put on single chars only; it's
353 (insert ?x) 416 ;; very inefficient if matching properties cover large regions.
354 (backward-char) 417 (save-excursion
355 (setq tmp-char-inserted t)) 418 (goto-char from)
356 (unwind-protect 419 (while (progn
357 (let ((col (current-indentation))) 420 (when (eq (get-text-property (point) 'c-type) value)
358 (delete-region (c-point 'bol) (c-point 'boi)) 421 (c-clear-char-property (point) 'c-type))
359 (beginning-of-line) 422 (goto-char (next-single-property-change (point) 'c-type nil to))
360 (indent-to (+ col shift-amt))) 423 (< (point) to)))))
361 (when tmp-char-inserted
362 (delete-char 1))))
363 ;; If initial point was within line's indentation and we're not on
364 ;; a line with a line continuation in a macro, position after the
365 ;; indentation. Else stay at same point in text.
366 (if (and (< (point) (c-point 'boi))
367 (not tmp-char-inserted))
368 (back-to-indentation)
369 (if (> (- (point-max) pos) (point))
370 (goto-char (- (point-max) pos))))))
371 424
372 425
373;; Some debug tools to visualize various special positions. This 426;; Some debug tools to visualize various special positions. This
@@ -414,7 +467,7 @@ This function does not do any hidden buffer changes."
414;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A 467;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A
415;; better way should be implemented, but this will at least shut up 468;; better way should be implemented, but this will at least shut up
416;; the byte compiler. 469;; the byte compiler.
417(defvar c-maybe-labelp nil) 470(defvar c-maybe-labelp)
418 471
419;; New awk-compatible version of c-beginning-of-statement-1, ACM 2002/6/22 472;; New awk-compatible version of c-beginning-of-statement-1, ACM 2002/6/22
420 473
@@ -470,11 +523,9 @@ corresponding statement start. If at the beginning of a statement,
470move to the closest containing statement if there is any. This might 523move to the closest containing statement if there is any. This might
471also stop at a continuation clause. 524also stop at a continuation clause.
472 525
473Labels are treated as separate statements if IGNORE-LABELS is non-nil. 526Labels are treated as part of the following statements if
474The function is not overly intelligent in telling labels from other 527IGNORE-LABELS is non-nil. (FIXME: Doesn't work if we stop at a known
475uses of colons; if used outside a statement context it might trip up 528statement start keyword.)
476on e.g. inherit colons, so IGNORE-LABELS should be used then. There
477should be no such mistakes in a statement context, however.
478 529
479Macros are ignored unless point is within one, in which case the 530Macros are ignored unless point is within one, in which case the
480content of the macro is treated as normal code. Aside from any normal 531content of the macro is treated as normal code. Aside from any normal
@@ -497,7 +548,10 @@ position if that is less ('same is returned in this case).
497NOERROR turns off error logging to `c-parsing-error'. 548NOERROR turns off error logging to `c-parsing-error'.
498 549
499Normally only ';' is considered to delimit statements, but if 550Normally only ';' is considered to delimit statements, but if
500COMMA-DELIM is non-nil then ',' is treated likewise." 551COMMA-DELIM is non-nil then ',' is treated likewise.
552
553Note that this function might do hidden buffer changes. See the
554comment at the start of cc-engine.el for more info."
501 555
502 ;; The bulk of this function is a pushdown automaton that looks at statement 556 ;; The bulk of this function is a pushdown automaton that looks at statement
503 ;; boundaries and the tokens (such as "while") in c-opt-block-stmt-key. Its 557 ;; boundaries and the tokens (such as "while") in c-opt-block-stmt-key. Its
@@ -587,20 +641,43 @@ COMMA-DELIM is non-nil then ',' is treated likewise."
587 (c-stmt-delim-chars (if comma-delim 641 (c-stmt-delim-chars (if comma-delim
588 c-stmt-delim-chars-with-comma 642 c-stmt-delim-chars-with-comma
589 c-stmt-delim-chars)) 643 c-stmt-delim-chars))
590 pos ; Current position. 644 c-in-literal-cache c-maybe-labelp saved
591 boundary-pos ; Position of last stmt boundary character (e.g. ;). 645 ;; Current position.
592 after-labels-pos ; Value of tok after first found colon. 646 pos
593 last-label-pos ; Value of tok after last found colon. 647 ;; Position of last stmt boundary character (e.g. ;).
594 sym ; Symbol just scanned back over (e.g. 'while or 648 boundary-pos
595 ; 'boundary). See above 649 ;; The position of the last sexp or bound that follows the
596 state ; Current state in the automaton. See above. 650 ;; first found colon, i.e. the start of the nonlabel part of
597 saved-pos ; Current saved positions. See above 651 ;; the statement. It's `start' if a colon is found just after
598 stack ; Stack of conses (state . saved-pos). 652 ;; the start.
599 (cond-key (or c-opt-block-stmt-key ; regexp which matches "for", "if", etc. 653 after-labels-pos
654 ;; Like `after-labels-pos', but the first such position inside
655 ;; a label, i.e. the start of the last label before the start
656 ;; of the nonlabel part of the statement.
657 last-label-pos
658 ;; The last position where a label is possible provided the
659 ;; statement started there. It's nil as long as no invalid
660 ;; label content has been found (according to
661 ;; `c-nonlabel-token-key'. It's `start' if no valid label
662 ;; content was found in the label. Note that we might still
663 ;; regard it a label if it starts with `c-label-kwds'.
664 label-good-pos
665 ;; Symbol just scanned back over (e.g. 'while or 'boundary).
666 ;; See above.
667 sym
668 ;; Current state in the automaton. See above.
669 state
670 ;; Current saved positions. See above.
671 saved-pos
672 ;; Stack of conses (state . saved-pos).
673 stack
674 ;; Regexp which matches "for", "if", etc.
675 (cond-key (or c-opt-block-stmt-key
600 "\\<\\>")) ; Matches nothing. 676 "\\<\\>")) ; Matches nothing.
601 (ret 'same) ; Return value. 677 ;; Return value.
602 tok ptok pptok ; Pos of last three sexps or bounds. 678 (ret 'same)
603 c-in-literal-cache c-maybe-labelp saved) 679 ;; Positions of the last three sexps or bounds we've stopped at.
680 tok ptok pptok)
604 681
605 (save-restriction 682 (save-restriction
606 (if lim (narrow-to-region lim (point-max))) 683 (if lim (narrow-to-region lim (point-max)))
@@ -614,32 +691,23 @@ COMMA-DELIM is non-nil then ',' is treated likewise."
614 ;; that we've moved. 691 ;; that we've moved.
615 (while (progn 692 (while (progn
616 (setq pos (point)) 693 (setq pos (point))
617 (if (c-mode-is-new-awk-p) 694 (c-backward-syntactic-ws)
618 (c-awk-backward-syntactic-ws) 695 ;; Protect post-++/-- operators just before a virtual semicolon.
619 (c-backward-syntactic-ws)) 696 (and (not (c-at-vsemi-p))
620 (/= (skip-chars-backward "-+!*&~@`#") 0))) ; ACM, 2002/5/31; 697 (/= (skip-chars-backward "-+!*&~@`#") 0))))
621 ; Make a variable in
622 ; cc-langs.el, maybe
623 698
624 ;; Skip back over any semicolon here. If it was a bare semicolon, we're 699 ;; Skip back over any semicolon here. If it was a bare semicolon, we're
625 ;; done. Later on we ignore the boundaries for statements that doesn't 700 ;; done. Later on we ignore the boundaries for statements that don't
626 ;; contain any sexp. The only thing that is affected is that the error 701 ;; contain any sexp. The only thing that is affected is that the error
627 ;; checking is a little less strict, and we really don't bother. 702 ;; checking is a little less strict, and we really don't bother.
628 (if (and (memq (char-before) delims) 703 (if (and (memq (char-before) delims)
629 (progn (forward-char -1) 704 (progn (forward-char -1)
630 (setq saved (point)) 705 (setq saved (point))
631 (if (c-mode-is-new-awk-p) 706 (c-backward-syntactic-ws)
632 (c-awk-backward-syntactic-ws)
633 (c-backward-syntactic-ws))
634 (or (memq (char-before) delims) 707 (or (memq (char-before) delims)
635 (memq (char-before) '(?: nil)) 708 (memq (char-before) '(?: nil))
636 (eq (char-syntax (char-before)) ?\() 709 (eq (char-syntax (char-before)) ?\()
637 (and (c-mode-is-new-awk-p) 710 (c-at-vsemi-p))))
638 (c-awk-after-logical-semicolon))))) ; ACM 2002/6/22
639 ;; ACM, 2002/7/20: What about giving a limit to the above function?
640 ;; ACM, 2003/6/16: The above two lines (checking for
641 ;; awk-logical-semicolon) are probably redundant after rewriting
642 ;; c-awk-backward-syntactic-ws.
643 (setq ret 'previous 711 (setq ret 'previous
644 pos saved) 712 pos saved)
645 713
@@ -657,11 +725,8 @@ COMMA-DELIM is non-nil then ',' is treated likewise."
657 (while 725 (while
658 (catch 'loop ;; Throw nil to break, non-nil to continue. 726 (catch 'loop ;; Throw nil to break, non-nil to continue.
659 (cond 727 (cond
660 ;; Check for macro start. Take this out for AWK Mode (ACM, 2002/5/31)
661 ;; NO!! just make sure macro-start is nil in AWK Mode (ACM, 2002/6/22)
662 ;; It always is (ACM, 2002/6/23)
663 ((save-excursion 728 ((save-excursion
664 (and macro-start 729 (and macro-start ; Always NIL for AWK.
665 (progn (skip-chars-backward " \t") 730 (progn (skip-chars-backward " \t")
666 (eq (char-before) ?#)) 731 (eq (char-before) ?#))
667 (progn (setq saved (1- (point))) 732 (progn (setq saved (1- (point)))
@@ -767,23 +832,22 @@ COMMA-DELIM is non-nil then ',' is treated likewise."
767 (c-bos-save-error-info 'if 'else) 832 (c-bos-save-error-info 'if 'else)
768 (setq state 'else)) 833 (setq state 'else))
769 ((eq sym 'while) 834 ((eq sym 'while)
835 ;; Is this a real while, or a do-while?
836 ;; The next `when' triggers unless we are SURE that
837 ;; the `while' is not the tailend of a `do-while'.
770 (when (or (not pptok) 838 (when (or (not pptok)
771 (memq (char-after pptok) delims) 839 (memq (char-after pptok) delims)
772 (and (c-mode-is-new-awk-p) 840 ;; The following kludge is to prevent
773 (or 841 ;; infinite recursion when called from
774 ;; might we be calling this from 842 ;; c-awk-after-if-for-while-condition-p,
775 ;; c-awk-after-if-do-for-while-condition-p? 843 ;; or the like.
776 ;; If so, avoid infinite recursion. 844 (and (eq (point) start)
777 (and (eq (point) start) 845 (c-vsemi-status-unknown-p))
778 (c-awk-NL-prop-not-set)) 846 (c-at-vsemi-p pptok))
779 ;; The following may recursively
780 ;; call this function.
781 (c-awk-completed-stmt-ws-ends-line-p pptok))))
782 ;; Since this can cause backtracking we do a 847 ;; Since this can cause backtracking we do a
783 ;; little more careful analysis to avoid it: If 848 ;; little more careful analysis to avoid it: If
784 ;; the while isn't followed by a semicolon it 849 ;; the while isn't followed by a (possibly
785 ;; can't be a do-while. 850 ;; virtual) semicolon it can't be a do-while.
786 ;; ACM, 2002/5/31; IT CAN IN AWK Mode. ;-(
787 (c-bos-push-state) 851 (c-bos-push-state)
788 (setq state 'while))) 852 (setq state 'while)))
789 ((memq sym '(catch finally)) 853 ((memq sym '(catch finally))
@@ -805,80 +869,95 @@ COMMA-DELIM is non-nil then ',' is treated likewise."
805 (setq ret 'previous) 869 (setq ret 'previous)
806 870
807 ;; HERE IS THE SINGLE PLACE INSIDE THE PDA LOOP WHERE WE MOVE 871 ;; HERE IS THE SINGLE PLACE INSIDE THE PDA LOOP WHERE WE MOVE
808 ;; BACKWARDS THROUGH THE SOURCE. The following loop goes back 872 ;; BACKWARDS THROUGH THE SOURCE.
809 ;; one sexp and then only loops in special circumstances (line 873
810 ;; continuations and skipping past entire macros). 874 ;; This is typically fast with the caching done by
811 (while 875 ;; c-(backward|forward)-sws.
812 (progn 876 (c-backward-syntactic-ws)
813 (or (c-safe (goto-char (scan-sexps (point) -1)) t) 877
814 ;; Give up if we hit an unbalanced block. 878 (let ((before-sws-pos (point))
815 ;; Since the stack won't be empty the code 879 ;; Set as long as we have to continue jumping by sexps.
816 ;; below will report a suitable error. 880 ;; It's the position to use as end in the next round.
881 sexp-loop-continue-pos
882 ;; The end position of the area to search for statement
883 ;; barriers in this round.
884 (sexp-loop-end-pos pos))
885
886 (while
887 (progn
888 (unless (c-safe (c-backward-sexp) t)
889 ;; Give up if we hit an unbalanced block. Since the
890 ;; stack won't be empty the code below will report a
891 ;; suitable error.
817 (throw 'loop nil)) 892 (throw 'loop nil))
818 (cond ((looking-at "\\\\$") 893
819 ;; Step again if we hit a line continuation. 894 ;; Check if the sexp movement crossed a statement or
820 t) 895 ;; declaration boundary. But first modify the point
821 (macro-start 896 ;; so that `c-crosses-statement-barrier-p' only looks
822 ;; If we started inside a macro then this 897 ;; at the non-sexp chars following the sexp.
823 ;; sexp is always interesting. 898 (save-excursion
824 nil) 899 (when (setq
825 ((not (c-mode-is-new-awk-p)) ; Changed from t, ACM 2002/6/25 900 boundary-pos
826 ;; Otherwise check that we didn't step 901 (cond
827 ;; into a macro from the end. 902 ((if macro-start
828 (let ((macro-start 903 nil
829 (save-excursion 904 (save-excursion
830 (and (c-beginning-of-macro) 905 (when (c-beginning-of-macro)
831 (point))))) 906 ;; Set continuation position in case
832 (when macro-start 907 ;; `c-crosses-statement-barrier-p'
833 (goto-char macro-start) 908 ;; doesn't detect anything below.
834 t)))))) 909 (setq sexp-loop-continue-pos (point)))))
835 910 ;; If the sexp movement took us into a
836 ;; Did the last movement by a sexp cross a statement boundary? 911 ;; macro then there were only some non-sexp
837 (when (save-excursion 912 ;; chars after it. Skip out of the macro
838 (if (if (eq (char-after) ?{) 913 ;; to analyze them but not the non-sexp
839 (c-looking-at-inexpr-block lim nil) 914 ;; chars that might be inside the macro.
840 (looking-at "\\s\(")) 915 (c-end-of-macro)
841 916 (c-crosses-statement-barrier-p
842 ;; Should not include the paren sexp we've 917 (point) sexp-loop-end-pos))
843 ;; passed over in the boundary check. 918
844 (if (> (point) (- pos 100)) 919 ((and
845 (c-forward-sexp 1) 920 (eq (char-after) ?{)
846 921 (not (c-looking-at-inexpr-block lim nil t)))
847 ;; Find its end position this way instead of 922 ;; Passed a block sexp. That's a boundary
848 ;; moving forward if the sexp is large. 923 ;; alright.
849 (goto-char pos) 924 (point))
850 (while 925
851 (progn 926 ((looking-at "\\s\(")
852 (goto-char (1+ (c-down-list-backward))) 927 ;; Passed some other paren. Only analyze
853 (unless macro-start 928 ;; the non-sexp chars after it.
854 ;; Check that we didn't step into 929 (goto-char (1+ (c-down-list-backward
855 ;; a macro from the end. 930 before-sws-pos)))
856 (let ((macro-start 931 ;; We're at a valid token start position
857 (save-excursion 932 ;; (outside the `save-excursion') if
858 (and (c-beginning-of-macro) 933 ;; `c-crosses-statement-barrier-p' failed.
859 (point))))) 934 (c-crosses-statement-barrier-p
860 (when macro-start 935 (point) sexp-loop-end-pos))
861 (goto-char macro-start) 936
862 t))))))) 937 (t
863 938 ;; Passed a symbol sexp or line
864 (setq boundary-pos (c-crosses-statement-barrier-p 939 ;; continuation. It doesn't matter that
865 (point) pos))) 940 ;; it's included in the analyzed region.
866 941 (if (c-crosses-statement-barrier-p
867 (setq pptok ptok 942 (point) sexp-loop-end-pos)
868 ptok tok 943 t
869 tok boundary-pos 944 ;; If it was a line continuation then we
870 sym 'boundary) 945 ;; have to continue looping.
871 (throw 'loop t))) ; like a C "continue". Analyze the next sexp. 946 (if (looking-at "\\\\$")
872 947 (setq sexp-loop-continue-pos (point)))
873 (when (and (numberp c-maybe-labelp) 948 nil))))
874 (not ignore-labels) 949
875 (not (looking-at "\\s\("))) 950 (setq pptok ptok
876 ;; c-crosses-statement-barrier-p has found a colon, so 951 ptok tok
877 ;; we might be in a label now. 952 tok boundary-pos
878 (if (not after-labels-pos) 953 sym 'boundary)
879 (setq after-labels-pos tok)) 954 ;; Like a C "continue". Analyze the next sexp.
880 (setq last-label-pos tok 955 (throw 'loop t)))
881 c-maybe-labelp t)) 956
957 sexp-loop-continue-pos)
958 (goto-char sexp-loop-continue-pos)
959 (setq sexp-loop-end-pos sexp-loop-continue-pos
960 sexp-loop-continue-pos nil))))
882 961
883 ;; ObjC method def? 962 ;; ObjC method def?
884 (when (and c-opt-method-key 963 (when (and c-opt-method-key
@@ -887,7 +966,26 @@ COMMA-DELIM is non-nil then ',' is treated likewise."
887 ignore-labels t) ; Avoid the label check on exit. 966 ignore-labels t) ; Avoid the label check on exit.
888 (throw 'loop nil)) 967 (throw 'loop nil))
889 968
890 ;; We've moved back by a sexp, so update the token positions. 969 ;; Handle labels.
970 (unless (eq ignore-labels t)
971 (when (numberp c-maybe-labelp)
972 ;; `c-crosses-statement-barrier-p' has found a
973 ;; colon, so we might be in a label now.
974 (if after-labels-pos
975 (if (not last-label-pos)
976 (setq last-label-pos (or tok start)))
977 (setq after-labels-pos (or tok start)))
978 (setq c-maybe-labelp t
979 label-good-pos nil))
980
981 (when (and (not label-good-pos)
982 (looking-at c-nonlabel-token-key))
983 ;; We're in a potential label and it's the first
984 ;; time we've found something that isn't allowed in
985 ;; one.
986 (setq label-good-pos (or tok start))))
987
988 ;; We've moved back by a sexp, so update the token positions.
891 (setq sym nil 989 (setq sym nil
892 pptok ptok 990 pptok ptok
893 ptok tok 991 ptok tok
@@ -911,25 +1009,34 @@ COMMA-DELIM is non-nil then ',' is treated likewise."
911 (cond ((> start saved) (setq pos saved)) 1009 (cond ((> start saved) (setq pos saved))
912 ((= start saved) (setq ret 'up))))) 1010 ((= start saved) (setq ret 'up)))))
913 1011
914 (when (and c-maybe-labelp 1012 (when (and (not ignore-labels)
915 (not ignore-labels) 1013 (eq c-maybe-labelp t)
916 (not (eq ret 'beginning)) 1014 (not (eq ret 'beginning))
917 after-labels-pos) 1015 after-labels-pos
1016 (or (not label-good-pos)
1017 (<= label-good-pos pos)
1018 (progn
1019 (goto-char (if (and last-label-pos
1020 (< last-label-pos start))
1021 last-label-pos
1022 pos))
1023 (looking-at c-label-kwds-regexp))))
918 ;; We're in a label. Maybe we should step to the statement 1024 ;; We're in a label. Maybe we should step to the statement
919 ;; after it. 1025 ;; after it.
920 (if (< after-labels-pos start) 1026 (if (< after-labels-pos start)
921 (setq pos after-labels-pos) 1027 (setq pos after-labels-pos)
922 (setq ret 'label) 1028 (setq ret 'label)
923 (if (< last-label-pos start) 1029 (if (and last-label-pos (< last-label-pos start))
1030 ;; Might have jumped over several labels. Go to the last one.
924 (setq pos last-label-pos))))) 1031 (setq pos last-label-pos)))))
925 1032
926 ;; Skip over the unary operators that can start the statement. 1033 ;; Skip over the unary operators that can start the statement.
927 (goto-char pos) 1034 (goto-char pos)
928 (while (progn 1035 (while (progn
929 (if (c-mode-is-new-awk-p) 1036 (c-backward-syntactic-ws)
930 (c-awk-backward-syntactic-ws) 1037 ;; protect AWK post-inc/decrement operators, etc.
931 (c-backward-syntactic-ws)) 1038 (and (not (c-at-vsemi-p (point)))
932 (/= (skip-chars-backward "-+!*&~@`#") 0)) ; Hopefully the # won't hurt awk. 1039 (/= (skip-chars-backward "-+!*&~@`#") 0)))
933 (setq pos (point))) 1040 (setq pos (point)))
934 (goto-char pos) 1041 (goto-char pos)
935 ret))) 1042 ret)))
@@ -942,7 +1049,14 @@ a string or comment.
942 1049
943The variable `c-maybe-labelp' is set to the position of the first `:' that 1050The variable `c-maybe-labelp' is set to the position of the first `:' that
944might start a label (i.e. not part of `::' and not preceded by `?'). If a 1051might start a label (i.e. not part of `::' and not preceded by `?'). If a
945single `?' is found, then `c-maybe-labelp' is cleared." 1052single `?' is found, then `c-maybe-labelp' is cleared.
1053
1054For AWK, a statement which is terminated by an EOL (not a \; or a }) is
1055regarded as having a \"virtual semicolon\" immediately after the last token on
1056the line. If this virtual semicolon is _at_ from, the function recognises it.
1057
1058Note that this function might do hidden buffer changes. See the
1059comment at the start of cc-engine.el for more info."
946 (let ((skip-chars c-stmt-delim-chars) 1060 (let ((skip-chars c-stmt-delim-chars)
947 lit-range) 1061 lit-range)
948 (save-excursion 1062 (save-excursion
@@ -950,30 +1064,85 @@ single `?' is found, then `c-maybe-labelp' is cleared."
950 (goto-char from) 1064 (goto-char from)
951 (while (progn (skip-chars-forward skip-chars to) 1065 (while (progn (skip-chars-forward skip-chars to)
952 (< (point) to)) 1066 (< (point) to))
953 (if (setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment? 1067 (cond
954 (progn (goto-char (setq from (cdr lit-range))) 1068 ((setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment?
955 (if (and (c-mode-is-new-awk-p) (bolp)) ; ACM 2002/7/17. Make sure we 1069 (goto-char (cdr lit-range)))
956 (backward-char))) ; don't skip over a virtual semi-colon after an awk comment. :-( 1070 ((eq (char-after) ?:)
957 (cond ((eq (char-after) ?:) 1071 (forward-char)
958 (forward-char) 1072 (if (and (eq (char-after) ?:)
959 (if (and (eq (char-after) ?:) 1073 (< (point) to))
960 (< (point) to)) 1074 ;; Ignore scope operators.
961 ;; Ignore scope operators. 1075 (forward-char)
962 (forward-char) 1076 (setq c-maybe-labelp (1- (point)))))
963 (setq c-maybe-labelp (1- (point))))) 1077 ((eq (char-after) ??)
964 ((eq (char-after) ??) 1078 ;; A question mark. Can't be a label, so stop
965 ;; A question mark. Can't be a label, so stop 1079 ;; looking for more : and ?.
966 ;; looking for more : and ?. 1080 (setq c-maybe-labelp nil
967 (setq c-maybe-labelp nil 1081 skip-chars (substring c-stmt-delim-chars 0 -2)))
968 skip-chars (substring c-stmt-delim-chars 0 -2))) 1082 ((memq (char-after) '(?# ?\n ?\r)) ; A virtual semicolon?
969 ((and (eolp) ; Can only happen in AWK Mode 1083 (if (and (eq (char-before) ?\\) (memq (char-after) '(?\n ?\r)))
970 (not (c-awk-completed-stmt-ws-ends-line-p))) 1084 (backward-char))
971 (forward-char)) 1085 (skip-chars-backward " \t" from)
972 ((and (c-mode-is-new-awk-p) 1086 (if (c-at-vsemi-p)
973 (bolp) lit-range ; awk: comment/string ended prev line. 1087 (throw 'done (point))
974 (not (c-awk-completed-stmt-ws-ends-prev-line-p)))) 1088 (forward-line)))
975 (t (throw 'done (point)))))) 1089 (t (throw 'done (point)))))
976 nil)))) 1090 ;; In trailing space after an as yet undetected virtual semicolon?
1091 (c-backward-syntactic-ws from)
1092 (if (and (< (point) to)
1093 (c-at-vsemi-p))
1094 (point)
1095 nil)))))
1096
1097(defun c-at-statement-start-p ()
1098 "Return non-nil if the point is at the first token in a statement
1099or somewhere in the syntactic whitespace before it.
1100
1101A \"statement\" here is not restricted to those inside code blocks.
1102Any kind of declaration-like construct that occur outside function
1103bodies is also considered a \"statement\".
1104
1105Note that this function might do hidden buffer changes. See the
1106comment at the start of cc-engine.el for more info."
1107
1108 (save-excursion
1109 (let ((end (point))
1110 c-maybe-labelp)
1111 (c-syntactic-skip-backward (substring c-stmt-delim-chars 1) nil t)
1112 (or (bobp)
1113 (eq (char-before) ?})
1114 (and (eq (char-before) ?{)
1115 (not (and c-special-brace-lists
1116 (progn (backward-char)
1117 (c-looking-at-special-brace-list)))))
1118 (c-crosses-statement-barrier-p (point) end)))))
1119
1120(defun c-at-expression-start-p ()
1121 "Return non-nil if the point is at the first token in an expression or
1122statement, or somewhere in the syntactic whitespace before it.
1123
1124An \"expression\" here is a bit different from the normal language
1125grammar sense: It's any sequence of expression tokens except commas,
1126unless they are enclosed inside parentheses of some kind. Also, an
1127expression never continues past an enclosing parenthesis, but it might
1128contain parenthesis pairs of any sort except braces.
1129
1130Since expressions never cross statement boundaries, this function also
1131recognizes statement beginnings, just like `c-at-statement-start-p'.
1132
1133Note that this function might do hidden buffer changes. See the
1134comment at the start of cc-engine.el for more info."
1135
1136 (save-excursion
1137 (let ((end (point))
1138 (c-stmt-delim-chars c-stmt-delim-chars-with-comma)
1139 c-maybe-labelp)
1140 (c-syntactic-skip-backward (substring c-stmt-delim-chars 1) nil t)
1141 (or (bobp)
1142 (memq (char-before) '(?{ ?}))
1143 (save-excursion (backward-char)
1144 (looking-at "\\s("))
1145 (c-crosses-statement-barrier-p (point) end)))))
977 1146
978 1147
979;; A set of functions that covers various idiosyncrasies in 1148;; A set of functions that covers various idiosyncrasies in
@@ -1020,7 +1189,8 @@ This function does not do any hidden buffer changes."
1020Line continuations, i.e. a backslashes followed by line breaks, are 1189Line continuations, i.e. a backslashes followed by line breaks, are
1021treated as whitespace. 1190treated as whitespace.
1022 1191
1023This function does not do any hidden buffer changes." 1192Note that this function might do hidden buffer changes. See the
1193comment at the start of cc-engine.el for more info."
1024 1194
1025 (while (or 1195 (while (or
1026 ;; If forward-comment in at least XEmacs 21 is given a large 1196 ;; If forward-comment in at least XEmacs 21 is given a large
@@ -1054,8 +1224,7 @@ This function does not do any hidden buffer changes."
1054 (while (progn 1224 (while (progn
1055 (skip-chars-backward " \t\n\r\f\v") 1225 (skip-chars-backward " \t\n\r\f\v")
1056 (and (looking-at "[\n\r]") 1226 (and (looking-at "[\n\r]")
1057 (eq (char-before) ?\\) 1227 (eq (char-before) ?\\)))
1058 (< (point) start)))
1059 (backward-char)) 1228 (backward-char))
1060 1229
1061 (if (bobp) 1230 (if (bobp)
@@ -1088,13 +1257,16 @@ This function does not do any hidden buffer changes."
1088Line continuations, i.e. a backslashes followed by line breaks, are 1257Line continuations, i.e. a backslashes followed by line breaks, are
1089treated as whitespace. The line breaks that end line comments are 1258treated as whitespace. The line breaks that end line comments are
1090considered to be the comment enders, so the point cannot be at the end 1259considered to be the comment enders, so the point cannot be at the end
1091of the same line to move over a line comment. 1260of the same line to move over a line comment. Unlike
1261c-backward-syntactic-ws, this function doesn't move back over
1262preprocessor directives.
1092 1263
1093This function does not do any hidden buffer changes." 1264Note that this function might do hidden buffer changes. See the
1265comment at the start of cc-engine.el for more info."
1094 1266
1095 (let ((start (point))) 1267 (let ((start (point)))
1096 (while (and 1268 (while (and
1097 ;; `forward-comment' in some emacsen (e.g. Emacs 19.34) 1269 ;; `forward-comment' in some emacsen (e.g. XEmacs 21.4)
1098 ;; return t when moving backwards at bob. 1270 ;; return t when moving backwards at bob.
1099 (not (bobp)) 1271 (not (bobp))
1100 1272
@@ -1189,7 +1361,7 @@ This function does not do any hidden buffer changes."
1189; ;; properties in the buffer. 1361; ;; properties in the buffer.
1190; (interactive) 1362; (interactive)
1191; (save-excursion 1363; (save-excursion
1192; (let (in-face) 1364; (c-save-buffer-state (in-face)
1193; (goto-char (point-min)) 1365; (goto-char (point-min))
1194; (setq in-face (if (get-text-property (point) 'c-is-sws) 1366; (setq in-face (if (get-text-property (point) 'c-is-sws)
1195; (point))) 1367; (point)))
@@ -1220,30 +1392,35 @@ This function does not do any hidden buffer changes."
1220 ) 1392 )
1221 1393
1222(defmacro c-put-is-sws (beg end) 1394(defmacro c-put-is-sws (beg end)
1395 ;; This macro does a hidden buffer change.
1223 `(let ((beg ,beg) (end ,end)) 1396 `(let ((beg ,beg) (end ,end))
1224 (put-text-property beg end 'c-is-sws t) 1397 (put-text-property beg end 'c-is-sws t)
1225 ,@(when (facep 'c-debug-is-sws-face) 1398 ,@(when (facep 'c-debug-is-sws-face)
1226 `((c-debug-add-face beg end 'c-debug-is-sws-face))))) 1399 `((c-debug-add-face beg end 'c-debug-is-sws-face)))))
1227 1400
1228(defmacro c-put-in-sws (beg end) 1401(defmacro c-put-in-sws (beg end)
1402 ;; This macro does a hidden buffer change.
1229 `(let ((beg ,beg) (end ,end)) 1403 `(let ((beg ,beg) (end ,end))
1230 (put-text-property beg end 'c-in-sws t) 1404 (put-text-property beg end 'c-in-sws t)
1231 ,@(when (facep 'c-debug-is-sws-face) 1405 ,@(when (facep 'c-debug-is-sws-face)
1232 `((c-debug-add-face beg end 'c-debug-in-sws-face))))) 1406 `((c-debug-add-face beg end 'c-debug-in-sws-face)))))
1233 1407
1234(defmacro c-remove-is-sws (beg end) 1408(defmacro c-remove-is-sws (beg end)
1409 ;; This macro does a hidden buffer change.
1235 `(let ((beg ,beg) (end ,end)) 1410 `(let ((beg ,beg) (end ,end))
1236 (remove-text-properties beg end '(c-is-sws nil)) 1411 (remove-text-properties beg end '(c-is-sws nil))
1237 ,@(when (facep 'c-debug-is-sws-face) 1412 ,@(when (facep 'c-debug-is-sws-face)
1238 `((c-debug-remove-face beg end 'c-debug-is-sws-face))))) 1413 `((c-debug-remove-face beg end 'c-debug-is-sws-face)))))
1239 1414
1240(defmacro c-remove-in-sws (beg end) 1415(defmacro c-remove-in-sws (beg end)
1416 ;; This macro does a hidden buffer change.
1241 `(let ((beg ,beg) (end ,end)) 1417 `(let ((beg ,beg) (end ,end))
1242 (remove-text-properties beg end '(c-in-sws nil)) 1418 (remove-text-properties beg end '(c-in-sws nil))
1243 ,@(when (facep 'c-debug-is-sws-face) 1419 ,@(when (facep 'c-debug-is-sws-face)
1244 `((c-debug-remove-face beg end 'c-debug-in-sws-face))))) 1420 `((c-debug-remove-face beg end 'c-debug-in-sws-face)))))
1245 1421
1246(defmacro c-remove-is-and-in-sws (beg end) 1422(defmacro c-remove-is-and-in-sws (beg end)
1423 ;; This macro does a hidden buffer change.
1247 `(let ((beg ,beg) (end ,end)) 1424 `(let ((beg ,beg) (end ,end))
1248 (remove-text-properties beg end '(c-is-sws nil c-in-sws nil)) 1425 (remove-text-properties beg end '(c-is-sws nil c-in-sws nil))
1249 ,@(when (facep 'c-debug-is-sws-face) 1426 ,@(when (facep 'c-debug-is-sws-face)
@@ -1255,6 +1432,8 @@ This function does not do any hidden buffer changes."
1255 ;; `c-forward-sws' or `c-backward-sws' are used outside 1432 ;; `c-forward-sws' or `c-backward-sws' are used outside
1256 ;; `c-save-buffer-state' or similar then this will remove the cache 1433 ;; `c-save-buffer-state' or similar then this will remove the cache
1257 ;; properties right after they're added. 1434 ;; properties right after they're added.
1435 ;;
1436 ;; This function does hidden buffer changes.
1258 1437
1259 (save-excursion 1438 (save-excursion
1260 ;; Adjust the end to remove the properties in any following simple 1439 ;; Adjust the end to remove the properties in any following simple
@@ -1291,6 +1470,8 @@ This function does not do any hidden buffer changes."
1291 1470
1292(defun c-forward-sws () 1471(defun c-forward-sws ()
1293 ;; Used by `c-forward-syntactic-ws' to implement the unbounded search. 1472 ;; Used by `c-forward-syntactic-ws' to implement the unbounded search.
1473 ;;
1474 ;; This function might do hidden buffer changes.
1294 1475
1295 (let (;; `rung-pos' is set to a position as early as possible in the 1476 (let (;; `rung-pos' is set to a position as early as possible in the
1296 ;; unmarked part of the simple ws region. 1477 ;; unmarked part of the simple ws region.
@@ -1483,6 +1664,8 @@ This function does not do any hidden buffer changes."
1483 1664
1484(defun c-backward-sws () 1665(defun c-backward-sws ()
1485 ;; Used by `c-backward-syntactic-ws' to implement the unbounded search. 1666 ;; Used by `c-backward-syntactic-ws' to implement the unbounded search.
1667 ;;
1668 ;; This function might do hidden buffer changes.
1486 1669
1487 (let (;; `rung-pos' is set to a position as late as possible in the unmarked 1670 (let (;; `rung-pos' is set to a position as late as possible in the unmarked
1488 ;; part of the simple ws region. 1671 ;; part of the simple ws region.
@@ -1703,12 +1886,13 @@ This function does not do any hidden buffer changes."
1703 ))) 1886 )))
1704 1887
1705 1888
1706;; A system for handling noteworthy parens before the point. 1889;; A system for finding noteworthy parens before the point.
1707 1890
1708(defvar c-state-cache nil) 1891(defvar c-state-cache nil)
1709(make-variable-buffer-local 'c-state-cache) 1892(make-variable-buffer-local 'c-state-cache)
1710;; The state cache used by `c-parse-state' to cut down the amount of 1893;; The state cache used by `c-parse-state' to cut down the amount of
1711;; searching. It's the result from some earlier `c-parse-state' call. 1894;; searching. It's the result from some earlier `c-parse-state' call.
1895;;
1712;; The use of the cached info is more effective if the next 1896;; The use of the cached info is more effective if the next
1713;; `c-parse-state' call is on a line close by the one the cached state 1897;; `c-parse-state' call is on a line close by the one the cached state
1714;; was made at; the cache can actually slow down a little if the 1898;; was made at; the cache can actually slow down a little if the
@@ -1722,24 +1906,58 @@ This function does not do any hidden buffer changes."
1722;; change of narrowing is likely to affect the parens that are visible 1906;; change of narrowing is likely to affect the parens that are visible
1723;; before the point. 1907;; before the point.
1724 1908
1909(defvar c-state-cache-good-pos 1)
1910(make-variable-buffer-local 'c-state-cache-good-pos)
1911;; This is a position where `c-state-cache' is known to be correct.
1912;; It's a position inside one of the recorded unclosed parens or the
1913;; top level, but not further nested inside any literal or subparen
1914;; that is closed before the last recorded position.
1915;;
1916;; The exact position is chosen to try to be close to yet earlier than
1917;; the position where `c-state-cache' will be called next. Right now
1918;; the heuristic is to set it to the position after the last found
1919;; closing paren (of any type) before the line on which
1920;; `c-parse-state' was called. That is chosen primarily to work well
1921;; with refontification of the current line.
1922
1725(defsubst c-invalidate-state-cache (pos) 1923(defsubst c-invalidate-state-cache (pos)
1726 ;; Invalidate all info on `c-state-cache' that applies to the buffer 1924 ;; Invalidate all info on `c-state-cache' that applies to the buffer
1727 ;; at POS or higher. This is much like `c-whack-state-after', but 1925 ;; at POS or higher. This is much like `c-whack-state-after', but
1728 ;; it never changes a paren pair element into an open paren element. 1926 ;; it never changes a paren pair element into an open paren element.
1729 ;; Doing that would mean that the new open paren wouldn't have the 1927 ;; Doing that would mean that the new open paren wouldn't have the
1730 ;; required preceding paren pair element. 1928 ;; required preceding paren pair element.
1731 ;; 1929 (while (and (or c-state-cache
1732 ;; This function does not do any hidden buffer changes. 1930 (when (< pos c-state-cache-good-pos)
1733 (while (and c-state-cache 1931 (setq c-state-cache-good-pos 1)
1932 nil))
1734 (let ((elem (car c-state-cache))) 1933 (let ((elem (car c-state-cache)))
1735 (if (consp elem) 1934 (if (consp elem)
1736 (or (<= pos (car elem)) 1935 (or (< pos (cdr elem))
1737 (< pos (cdr elem))) 1936 (when (< pos c-state-cache-good-pos)
1738 (<= pos elem)))) 1937 (setq c-state-cache-good-pos (cdr elem))
1938 nil))
1939 (or (<= pos elem)
1940 (when (< pos c-state-cache-good-pos)
1941 (setq c-state-cache-good-pos (1+ elem))
1942 nil)))))
1739 (setq c-state-cache (cdr c-state-cache)))) 1943 (setq c-state-cache (cdr c-state-cache))))
1740 1944
1945(defun c-get-fallback-start-pos (here)
1946 ;; Return the start position for building `c-state-cache' from
1947 ;; scratch.
1948 (save-excursion
1949 ;; Go back 2 bods, but ignore any bogus positions returned by
1950 ;; beginning-of-defun (i.e. open paren in column zero).
1951 (goto-char here)
1952 (let ((cnt 2))
1953 (while (not (or (bobp) (zerop cnt)))
1954 (c-beginning-of-defun-1)
1955 (if (eq (char-after) ?\{)
1956 (setq cnt (1- cnt)))))
1957 (point)))
1958
1741(defun c-parse-state () 1959(defun c-parse-state ()
1742 ;; Finds and records all noteworthy parens between some good point 1960 ;; Find and record all noteworthy parens between some good point
1743 ;; earlier in the file and point. That good point is at least the 1961 ;; earlier in the file and point. That good point is at least the
1744 ;; beginning of the top-level construct we are in, or the beginning 1962 ;; beginning of the top-level construct we are in, or the beginning
1745 ;; of the preceding top-level construct if we aren't in one. 1963 ;; of the preceding top-level construct if we aren't in one.
@@ -1750,22 +1968,32 @@ This function does not do any hidden buffer changes."
1750 ;; the point. If an element is a cons, it gives the position of a 1968 ;; the point. If an element is a cons, it gives the position of a
1751 ;; closed brace paren pair; the car is the start paren position and 1969 ;; closed brace paren pair; the car is the start paren position and
1752 ;; the cdr is the position following the closing paren. Only the 1970 ;; the cdr is the position following the closing paren. Only the
1753 ;; last closed brace paren pair before each open paren is recorded, 1971 ;; last closed brace paren pair before each open paren and before
1754 ;; and thus the state never contains two cons elements in 1972 ;; the point is recorded, and thus the state never contains two cons
1755 ;; succession. 1973 ;; elements in succession.
1756 ;; 1974 ;;
1757 ;; Currently no characters which are given paren syntax with the 1975 ;; Currently no characters which are given paren syntax with the
1758 ;; syntax-table property are recorded, i.e. angle bracket arglist 1976 ;; syntax-table property are recorded, i.e. angle bracket arglist
1759 ;; parens are never present here. Note that this might change. 1977 ;; parens are never present here. Note that this might change.
1760 ;; 1978 ;;
1761 ;; This function does not do any hidden buffer changes. 1979 ;; BUG: This function doesn't cope entirely well with unbalanced
1980 ;; parens in macros. E.g. in the following case the brace before
1981 ;; the macro isn't balanced with the one after it:
1982 ;;
1983 ;; {
1984 ;; #define X {
1985 ;; }
1986 ;;
1987 ;; This function might do hidden buffer changes.
1762 1988
1763 (save-restriction 1989 (save-restriction
1764 (let* ((here (point)) 1990 (let* ((here (point))
1991 (here-bol (c-point 'bol))
1765 (c-macro-start (c-query-macro-start)) 1992 (c-macro-start (c-query-macro-start))
1766 (in-macro-start (or c-macro-start (point))) 1993 (in-macro-start (or c-macro-start (point)))
1767 old-state last-pos pairs pos save-pos) 1994 old-state last-pos brace-pair-open brace-pair-close
1768 (c-invalidate-state-cache (point)) 1995 pos save-pos)
1996 (c-invalidate-state-cache here)
1769 1997
1770 ;; If the minimum position has changed due to narrowing then we 1998 ;; If the minimum position has changed due to narrowing then we
1771 ;; have to fix the tail of `c-state-cache' accordingly. 1999 ;; have to fix the tail of `c-state-cache' accordingly.
@@ -1780,12 +2008,14 @@ This function does not do any hidden buffer changes."
1780 (setq ptr (cdr ptr))) 2008 (setq ptr (cdr ptr)))
1781 (when (consp ptr) 2009 (when (consp ptr)
1782 (if (eq (cdr ptr) c-state-cache) 2010 (if (eq (cdr ptr) c-state-cache)
1783 (setq c-state-cache nil) 2011 (setq c-state-cache nil
2012 c-state-cache-good-pos 1)
1784 (setcdr ptr nil)))) 2013 (setcdr ptr nil))))
1785 ;; If point-min has moved backward then we drop the state 2014 ;; If point-min has moved backward then we drop the state
1786 ;; completely. It's possible to do a better job here and 2015 ;; completely. It's possible to do a better job here and
1787 ;; recalculate the top only. 2016 ;; recalculate the top only.
1788 (setq c-state-cache nil)) 2017 (setq c-state-cache nil
2018 c-state-cache-good-pos 1))
1789 (setq c-state-cache-start (point-min))) 2019 (setq c-state-cache-start (point-min)))
1790 2020
1791 ;; Get the latest position we know are directly inside the 2021 ;; Get the latest position we know are directly inside the
@@ -1794,115 +2024,152 @@ This function does not do any hidden buffer changes."
1794 (if (consp (car c-state-cache)) 2024 (if (consp (car c-state-cache))
1795 (cdr (car c-state-cache)) 2025 (cdr (car c-state-cache))
1796 (1+ (car c-state-cache))))) 2026 (1+ (car c-state-cache)))))
1797 2027 (if (or (not last-pos)
1798 ;; Check if the found last-pos is in a macro. If it is, and 2028 (< last-pos c-state-cache-good-pos))
1799 ;; we're not in the same macro, we must discard everything on 2029 (setq last-pos c-state-cache-good-pos)
1800 ;; c-state-cache that is inside the macro before using it. 2030 ;; Take the opportunity to move the cached good position
1801 (when last-pos 2031 ;; further down.
1802 (save-excursion 2032 (if (< last-pos here-bol)
1803 (goto-char last-pos) 2033 (setq c-state-cache-good-pos last-pos)))
1804 (when (and (c-beginning-of-macro) 2034
1805 (/= (point) in-macro-start)) 2035 ;; Check if `last-pos' is in a macro. If it is, and we're not
1806 (c-invalidate-state-cache (point)) 2036 ;; in the same macro, we must discard everything on
1807 ;; Set last-pos again, just like above. 2037 ;; `c-state-cache' that is inside the macro before using it.
1808 (setq last-pos (and c-state-cache 2038 (save-excursion
1809 (if (consp (car c-state-cache)) 2039 (goto-char last-pos)
1810 (cdr (car c-state-cache)) 2040 (when (and (c-beginning-of-macro)
1811 (1+ (car c-state-cache)))))))) 2041 (/= (point) in-macro-start))
1812 2042 (c-invalidate-state-cache (point))
1813 (setq pos 2043 ;; Set `last-pos' again just like above except that there's
1814 ;; Find the start position for the forward search. (Can't 2044 ;; no use looking at `c-state-cache-good-pos' here.
1815 ;; search in the backward direction since point might be 2045 (setq last-pos (if c-state-cache
1816 ;; in some kind of literal.) 2046 (if (consp (car c-state-cache))
1817 (or (when last-pos 2047 (cdr (car c-state-cache))
1818 2048 (1+ (car c-state-cache)))
1819 ;; There's a cached state with a containing paren. Pop 2049 1))))
1820 ;; off the stale containing sexps from it by going 2050
1821 ;; forward out of parens as far as possible. 2051 ;; If we've moved very far from the last cached position then
1822 (narrow-to-region (point-min) here) 2052 ;; it's probably better to redo it from scratch, otherwise we
1823 (let (placeholder pair-beg) 2053 ;; might spend a lot of time searching from `last-pos' down to
1824 (while (and c-state-cache 2054 ;; here.
1825 (setq placeholder 2055 (when (< last-pos (- here 20000))
1826 (c-up-list-forward last-pos))) 2056 ;; First get the fallback start position. If it turns out
1827 (setq last-pos placeholder) 2057 ;; that it's so far back that the cached state is closer then
1828 (if (consp (car c-state-cache)) 2058 ;; we'll keep it afterall.
1829 (setq pair-beg (car-safe (cdr c-state-cache)) 2059 (setq pos (c-get-fallback-start-pos here))
1830 c-state-cache (cdr-safe (cdr c-state-cache))) 2060 (if (<= pos last-pos)
1831 (setq pair-beg (car c-state-cache) 2061 (setq pos nil)
1832 c-state-cache (cdr c-state-cache)))) 2062 (setq last-pos nil
1833 2063 c-state-cache nil
1834 (when (and pair-beg (eq (char-after pair-beg) ?{)) 2064 c-state-cache-good-pos 1)))
1835 ;; The last paren pair we moved out from was a brace 2065
1836 ;; pair. Modify the state to record this as a closed 2066 ;; Find the start position for the forward search. (Can't
1837 ;; pair now. 2067 ;; search in the backward direction since the point might be in
1838 (if (consp (car-safe c-state-cache)) 2068 ;; some kind of literal.)
1839 (setq c-state-cache (cdr c-state-cache))) 2069
1840 (setq c-state-cache (cons (cons pair-beg last-pos) 2070 (unless pos
1841 c-state-cache)))) 2071 (setq old-state c-state-cache)
1842 2072
1843 ;; Check if the preceding balanced paren is within a 2073 ;; There's a cached state with a containing paren. Pop off
1844 ;; macro; it should be ignored if we're outside the 2074 ;; the stale containing sexps from it by going forward out of
1845 ;; macro. There's no need to check any further upwards; 2075 ;; parens as far as possible.
1846 ;; if the macro contains an unbalanced opening paren then 2076 (narrow-to-region (point-min) here)
1847 ;; we're smoked anyway. 2077 (let (placeholder pair-beg)
1848 (when (and (<= (point) in-macro-start) 2078 (while (and c-state-cache
1849 (consp (car c-state-cache))) 2079 (setq placeholder
1850 (save-excursion 2080 (c-up-list-forward last-pos)))
1851 (goto-char (car (car c-state-cache))) 2081 (setq last-pos placeholder)
1852 (when (c-beginning-of-macro) 2082 (if (consp (car c-state-cache))
1853 (setq here (point) 2083 (setq pair-beg (car-safe (cdr c-state-cache))
1854 c-state-cache (cdr c-state-cache))))) 2084 c-state-cache (cdr-safe (cdr c-state-cache)))
1855 2085 (setq pair-beg (car c-state-cache)
1856 (when c-state-cache 2086 c-state-cache (cdr c-state-cache))))
1857 (setq old-state c-state-cache) 2087
1858 last-pos)) 2088 (when (and pair-beg (eq (char-after pair-beg) ?{))
1859 2089 ;; The last paren pair we moved out from was a brace
1860 (save-excursion 2090 ;; pair. Modify the state to record this as a closed
1861 ;; go back 2 bods, but ignore any bogus positions 2091 ;; pair now.
1862 ;; returned by beginning-of-defun (i.e. open paren in 2092 (if (consp (car-safe c-state-cache))
1863 ;; column zero) 2093 (setq c-state-cache (cdr c-state-cache)))
1864 (goto-char here) 2094 (setq c-state-cache (cons (cons pair-beg last-pos)
1865 (let ((cnt 2)) 2095 c-state-cache))))
1866 (while (not (or (bobp) (zerop cnt))) 2096
1867 (c-beginning-of-defun-1) 2097 ;; Check if the preceding balanced paren is within a
1868 (if (eq (char-after) ?\{) 2098 ;; macro; it should be ignored if we're outside the
1869 (setq cnt (1- cnt))))) 2099 ;; macro. There's no need to check any further upwards;
1870 (point)))) 2100 ;; if the macro contains an unbalanced opening paren then
2101 ;; we're smoked anyway.
2102 (when (and (<= (point) in-macro-start)
2103 (consp (car c-state-cache)))
2104 (save-excursion
2105 (goto-char (car (car c-state-cache)))
2106 (when (c-beginning-of-macro)
2107 (setq here (point)
2108 c-state-cache (cdr c-state-cache)))))
2109
2110 (unless (eq c-state-cache old-state)
2111 ;; Have to adjust the cached good position if state has been
2112 ;; popped off.
2113 (setq c-state-cache-good-pos
2114 (if c-state-cache
2115 (if (consp (car c-state-cache))
2116 (cdr (car c-state-cache))
2117 (1+ (car c-state-cache)))
2118 1)
2119 old-state c-state-cache))
2120
2121 (when c-state-cache
2122 (setq pos last-pos)))
2123
2124 ;; Get the fallback start position.
2125 (unless pos
2126 (setq pos (c-get-fallback-start-pos here)
2127 c-state-cache nil
2128 c-state-cache-good-pos 1))
1871 2129
1872 (narrow-to-region (point-min) here) 2130 (narrow-to-region (point-min) here)
1873 2131
1874 (while pos 2132 (while pos
1875 ;; Find the balanced brace pairs.
1876 (setq save-pos pos 2133 (setq save-pos pos
1877 pairs nil) 2134 brace-pair-open nil)
1878 (while (and (setq last-pos (c-down-list-forward pos)) 2135
1879 (setq pos (c-up-list-forward last-pos))) 2136 ;; Find the balanced brace pairs. This loop is hot, so it
1880 (if (eq (char-before last-pos) ?{) 2137 ;; does ugly tricks to go faster.
1881 (setq pairs (cons (cons last-pos pos) pairs)))) 2138 (c-safe
1882 2139 (let (set-good-pos set-brace-pair)
1883 ;; Should ignore any pairs that are in a macro, providing 2140 (while t
1884 ;; we're not in the same one. 2141 (setq last-pos nil
1885 (when (and pairs (< (car (car pairs)) in-macro-start)) 2142 last-pos (scan-lists pos 1 -1)) ; Might signal.
1886 (while (and (save-excursion 2143 (setq pos (scan-lists last-pos 1 1) ; Might signal.
1887 (goto-char (car (car pairs))) 2144 set-good-pos (< pos here-bol)
1888 (c-beginning-of-macro)) 2145 set-brace-pair (eq (char-before last-pos) ?{))
1889 (setq pairs (cdr pairs))))) 2146
2147 ;; Update the cached good position and record the brace
2148 ;; pair, whichever is applicable for the paren we've
2149 ;; just jumped over. But first check that it isn't
2150 ;; inside a macro and the point isn't inside the same
2151 ;; one.
2152 (when (and (or set-good-pos set-brace-pair)
2153 (or (>= pos in-macro-start)
2154 (save-excursion
2155 (goto-char pos)
2156 (not (c-beginning-of-macro)))))
2157 (if set-good-pos
2158 (setq c-state-cache-good-pos pos))
2159 (if set-brace-pair
2160 (setq brace-pair-open last-pos
2161 brace-pair-close pos))))))
1890 2162
1891 ;; Record the last brace pair. 2163 ;; Record the last brace pair.
1892 (when pairs 2164 (when brace-pair-open
1893 (if (and (eq c-state-cache old-state) 2165 (let ((head (car-safe c-state-cache)))
1894 (consp (car-safe c-state-cache))) 2166 (if (consp head)
1895 ;; There's a closed pair on the cached state but we've 2167 (progn
1896 ;; found a later one, so remove it. 2168 (setcar head (1- brace-pair-open))
1897 (setq c-state-cache (cdr c-state-cache))) 2169 (setcdr head brace-pair-close))
1898 (setq pairs (car pairs)) 2170 (setq c-state-cache (cons (cons (1- brace-pair-open)
1899 (setcar pairs (1- (car pairs))) 2171 brace-pair-close)
1900 (when (consp (car-safe c-state-cache)) 2172 c-state-cache)))))
1901 ;; There could already be a cons first in `c-state-cache'
1902 ;; if we've e.g. jumped over an unbalanced open paren in a
1903 ;; macro below.
1904 (setq c-state-cache (cdr c-state-cache)))
1905 (setq c-state-cache (cons pairs c-state-cache)))
1906 2173
1907 (if last-pos 2174 (if last-pos
1908 ;; Prepare to loop, but record the open paren only if it's 2175 ;; Prepare to loop, but record the open paren only if it's
@@ -1911,16 +2178,18 @@ This function does not do any hidden buffer changes."
1911 ;; that got an open paren syntax-table property. 2178 ;; that got an open paren syntax-table property.
1912 (progn 2179 (progn
1913 (setq pos last-pos) 2180 (setq pos last-pos)
1914 (if (and (or (>= last-pos in-macro-start) 2181 (when (and (or (>= last-pos in-macro-start)
1915 (save-excursion 2182 (save-excursion
1916 (goto-char last-pos) 2183 (goto-char last-pos)
1917 (not (c-beginning-of-macro)))) 2184 (not (c-beginning-of-macro))))
1918 ;; Check for known types of parens that we want 2185 ;; Check for known types of parens that we
1919 ;; to record. The syntax table is not to be 2186 ;; want to record. The syntax table is not to
1920 ;; trusted here since the caller might be using 2187 ;; be trusted here since the caller might be
1921 ;; e.g. `c++-template-syntax-table'. 2188 ;; using e.g. `c++-template-syntax-table'.
1922 (memq (char-before last-pos) '(?{ ?\( ?\[))) 2189 (memq (char-before last-pos) '(?{ ?\( ?\[)))
1923 (setq c-state-cache (cons (1- last-pos) c-state-cache)))) 2190 (if (< last-pos here-bol)
2191 (setq c-state-cache-good-pos last-pos))
2192 (setq c-state-cache (cons (1- last-pos) c-state-cache))))
1924 2193
1925 (if (setq last-pos (c-up-list-forward pos)) 2194 (if (setq last-pos (c-up-list-forward pos))
1926 ;; Found a close paren without a corresponding opening 2195 ;; Found a close paren without a corresponding opening
@@ -1928,7 +2197,8 @@ This function does not do any hidden buffer changes."
1928 ;; scan backward for the start paren and then start over. 2197 ;; scan backward for the start paren and then start over.
1929 (progn 2198 (progn
1930 (setq pos (c-up-list-backward pos) 2199 (setq pos (c-up-list-backward pos)
1931 c-state-cache nil) 2200 c-state-cache nil
2201 c-state-cache-good-pos c-state-cache-start)
1932 (when (or (not pos) 2202 (when (or (not pos)
1933 ;; Emacs (up to at least 21.2) can get confused by 2203 ;; Emacs (up to at least 21.2) can get confused by
1934 ;; open parens in column zero inside comments: The 2204 ;; open parens in column zero inside comments: The
@@ -1943,6 +2213,7 @@ This function does not do any hidden buffer changes."
1943 (c-point 'bol last-pos))))))) 2213 (c-point 'bol last-pos)))))))
1944 (setq pos nil)))) 2214 (setq pos nil))))
1945 2215
2216 ;;(message "c-parse-state: %S end: %S" c-state-cache c-state-cache-good-pos)
1946 c-state-cache))) 2217 c-state-cache)))
1947 2218
1948;; Debug tool to catch cache inconsistencies. 2219;; Debug tool to catch cache inconsistencies.
@@ -1952,11 +2223,23 @@ This function does not do any hidden buffer changes."
1952(cc-bytecomp-defun c-real-parse-state) 2223(cc-bytecomp-defun c-real-parse-state)
1953(defun c-debug-parse-state () 2224(defun c-debug-parse-state ()
1954 (let ((res1 (c-real-parse-state)) res2) 2225 (let ((res1 (c-real-parse-state)) res2)
1955 (let ((c-state-cache nil)) 2226 (let ((c-state-cache nil)
2227 (c-state-cache-start 1)
2228 (c-state-cache-good-pos 1))
1956 (setq res2 (c-real-parse-state))) 2229 (setq res2 (c-real-parse-state)))
1957 (unless (equal res1 res2) 2230 (unless (equal res1 res2)
1958 (error "c-parse-state inconsistency: using cache: %s, from scratch: %s" 2231 ;; The cache can actually go further back due to the ad-hoc way
1959 res1 res2)) 2232 ;; the first paren is found, so try to whack off a bit of its
2233 ;; start before complaining.
2234 (save-excursion
2235 (goto-char (or (c-least-enclosing-brace res2) (point)))
2236 (c-beginning-of-defun-1)
2237 (while (not (or (bobp) (eq (char-after) ?{)))
2238 (c-beginning-of-defun-1))
2239 (unless (equal (c-whack-state-before (point) res1) res2)
2240 (message (concat "c-parse-state inconsistency: "
2241 "using cache: %s, from scratch: %s")
2242 res1 res2))))
1960 res1)) 2243 res1))
1961(defun c-toggle-parse-state-debug (&optional arg) 2244(defun c-toggle-parse-state-debug (&optional arg)
1962 (interactive "P") 2245 (interactive "P")
@@ -1965,12 +2248,12 @@ This function does not do any hidden buffer changes."
1965 'c-debug-parse-state 2248 'c-debug-parse-state
1966 'c-real-parse-state))) 2249 'c-real-parse-state)))
1967 (c-keep-region-active)) 2250 (c-keep-region-active))
2251(when c-debug-parse-state
2252 (c-toggle-parse-state-debug 1))
1968 2253
1969(defun c-whack-state-before (bufpos paren-state) 2254(defun c-whack-state-before (bufpos paren-state)
1970 ;; Whack off any state information from PAREN-STATE which lies 2255 ;; Whack off any state information from PAREN-STATE which lies
1971 ;; before BUFPOS. Not destructive on PAREN-STATE. 2256 ;; before BUFPOS. Not destructive on PAREN-STATE.
1972 ;;
1973 ;; This function does not do any hidden buffer changes.
1974 (let* ((newstate (list nil)) 2257 (let* ((newstate (list nil))
1975 (ptr newstate) 2258 (ptr newstate)
1976 car) 2259 car)
@@ -1986,8 +2269,6 @@ This function does not do any hidden buffer changes."
1986(defun c-whack-state-after (bufpos paren-state) 2269(defun c-whack-state-after (bufpos paren-state)
1987 ;; Whack off any state information from PAREN-STATE which lies at or 2270 ;; Whack off any state information from PAREN-STATE which lies at or
1988 ;; after BUFPOS. Not destructive on PAREN-STATE. 2271 ;; after BUFPOS. Not destructive on PAREN-STATE.
1989 ;;
1990 ;; This function does not do any hidden buffer changes.
1991 (catch 'done 2272 (catch 'done
1992 (while paren-state 2273 (while paren-state
1993 (let ((car (car paren-state))) 2274 (let ((car (car paren-state)))
@@ -2018,9 +2299,7 @@ This function does not do any hidden buffer changes."
2018 2299
2019(defun c-most-enclosing-brace (paren-state &optional bufpos) 2300(defun c-most-enclosing-brace (paren-state &optional bufpos)
2020 ;; Return the bufpos of the innermost enclosing open paren before 2301 ;; Return the bufpos of the innermost enclosing open paren before
2021 ;; bufpos that hasn't been narrowed out, or nil if none was found. 2302 ;; bufpos, or nil if none was found.
2022 ;;
2023 ;; This function does not do any hidden buffer changes.
2024 (let (enclosingp) 2303 (let (enclosingp)
2025 (or bufpos (setq bufpos 134217727)) 2304 (or bufpos (setq bufpos 134217727))
2026 (while paren-state 2305 (while paren-state
@@ -2029,34 +2308,31 @@ This function does not do any hidden buffer changes."
2029 (if (or (consp enclosingp) 2308 (if (or (consp enclosingp)
2030 (>= enclosingp bufpos)) 2309 (>= enclosingp bufpos))
2031 (setq enclosingp nil) 2310 (setq enclosingp nil)
2032 (if (< enclosingp (point-min))
2033 (setq enclosingp nil))
2034 (setq paren-state nil))) 2311 (setq paren-state nil)))
2035 enclosingp)) 2312 enclosingp))
2036 2313
2037(defun c-least-enclosing-brace (paren-state &optional bufpos) 2314(defun c-least-enclosing-brace (paren-state)
2038 ;; Return the bufpos of the outermost enclosing open paren before 2315 ;; Return the bufpos of the outermost enclosing open paren, or nil
2039 ;; bufpos that hasn't been narrowed out, or nil if none was found. 2316 ;; if none was found.
2040 ;;
2041 ;; This function does not do any hidden buffer changes.
2042 (let (pos elem) 2317 (let (pos elem)
2043 (or bufpos (setq bufpos 134217727))
2044 (while paren-state 2318 (while paren-state
2045 (setq elem (car paren-state) 2319 (setq elem (car paren-state)
2046 paren-state (cdr paren-state)) 2320 paren-state (cdr paren-state))
2047 (unless (or (consp elem) 2321 (if (integerp elem)
2048 (>= elem bufpos)) 2322 (setq pos elem)))
2049 (if (>= elem (point-min))
2050 (setq pos elem))))
2051 pos)) 2323 pos))
2052 2324
2053(defun c-safe-position (bufpos paren-state) 2325(defun c-safe-position (bufpos paren-state)
2054 ;; Return the closest known safe position higher up than BUFPOS, or 2326 ;; Return the closest "safe" position recorded on PAREN-STATE that
2055 ;; nil if PAREN-STATE doesn't contain one. Return nil if BUFPOS is 2327 ;; is higher up than BUFPOS. Return nil if PAREN-STATE doesn't
2056 ;; nil, which is useful to find the closest limit before a given 2328 ;; contain any. Return nil if BUFPOS is nil, which is useful to
2057 ;; limit that might be nil. 2329 ;; find the closest limit before a given limit that might be nil.
2058 ;; 2330 ;;
2059 ;; This function does not do any hidden buffer changes. 2331 ;; A "safe" position is a position at or after a recorded open
2332 ;; paren, or after a recorded close paren. The returned position is
2333 ;; thus either the first position after a close brace, or the first
2334 ;; position after an enclosing paren, or at the enclosing paren in
2335 ;; case BUFPOS is immediately after it.
2060 (when bufpos 2336 (when bufpos
2061 (let (elem) 2337 (let (elem)
2062 (catch 'done 2338 (catch 'done
@@ -2118,33 +2394,61 @@ This function does not do any hidden buffer changes."
2118 "Return non-nil if the point is on or directly after an identifier. 2394 "Return non-nil if the point is on or directly after an identifier.
2119Keywords are recognized and not considered identifiers. If an 2395Keywords are recognized and not considered identifiers. If an
2120identifier is detected, the returned value is its starting position. 2396identifier is detected, the returned value is its starting position.
2121If an identifier both starts and stops at the point \(can only happen 2397If an identifier ends at the point and another begins at it \(can only
2122in Pike) then the point for the preceding one is returned. 2398happen in Pike) then the point for the preceding one is returned.
2123 2399
2124This function does not do any hidden buffer changes." 2400Note that this function might do hidden buffer changes. See the
2401comment at the start of cc-engine.el for more info."
2402
2403 ;; FIXME: Shouldn't this function handle "operator" in C++?
2125 2404
2126 (save-excursion 2405 (save-excursion
2127 (if (zerop (skip-syntax-backward "w_")) 2406 (skip-syntax-backward "w_")
2128 2407
2129 (when (c-major-mode-is 'pike-mode) 2408 (or
2130 ;; Handle the `<operator> syntax in Pike. 2409
2131 (let ((pos (point))) 2410 ;; Check for a normal (non-keyword) identifier.
2132 (skip-chars-backward "-!%&*+/<=>^|~[]()") 2411 (and (looking-at c-symbol-start)
2133 (and (if (< (skip-chars-backward "`") 0) 2412 (not (looking-at c-keywords-regexp))
2134 t 2413 (point))
2135 (goto-char pos) 2414
2136 (eq (char-after) ?\`)) 2415 (when (c-major-mode-is 'pike-mode)
2137 (looking-at c-symbol-key) 2416 ;; Handle the `<operator> syntax in Pike.
2138 (>= (match-end 0) pos) 2417 (let ((pos (point)))
2139 (point)))) 2418 (skip-chars-backward "-!%&*+/<=>^|~[]()")
2140 2419 (and (if (< (skip-chars-backward "`") 0)
2141 (and (not (looking-at c-keywords-regexp)) 2420 t
2142 (point))))) 2421 (goto-char pos)
2422 (eq (char-after) ?\`))
2423 (looking-at c-symbol-key)
2424 (>= (match-end 0) pos)
2425 (point))))
2426
2427 ;; Handle the "operator +" syntax in C++.
2428 (when (and c-overloadable-operators-regexp
2429 (= (c-backward-token-2 0) 0))
2430
2431 (cond ((and (looking-at c-overloadable-operators-regexp)
2432 (or (not c-opt-op-identitier-prefix)
2433 (and (= (c-backward-token-2 1) 0)
2434 (looking-at c-opt-op-identitier-prefix))))
2435 (point))
2436
2437 ((save-excursion
2438 (and c-opt-op-identitier-prefix
2439 (looking-at c-opt-op-identitier-prefix)
2440 (= (c-forward-token-2 1) 0)
2441 (looking-at c-overloadable-operators-regexp)))
2442 (point))))
2443
2444 )))
2143 2445
2144(defsubst c-simple-skip-symbol-backward () 2446(defsubst c-simple-skip-symbol-backward ()
2145 ;; If the point is at the end of a symbol then skip backward to the 2447 ;; If the point is at the end of a symbol then skip backward to the
2146 ;; beginning of it. Don't move otherwise. Return non-nil if point 2448 ;; beginning of it. Don't move otherwise. Return non-nil if point
2147 ;; moved. 2449 ;; moved.
2450 ;;
2451 ;; This function might do hidden buffer changes.
2148 (or (< (skip-syntax-backward "w_") 0) 2452 (or (< (skip-syntax-backward "w_") 0)
2149 (and (c-major-mode-is 'pike-mode) 2453 (and (c-major-mode-is 'pike-mode)
2150 ;; Handle the `<operator> syntax in Pike. 2454 ;; Handle the `<operator> syntax in Pike.
@@ -2157,11 +2461,13 @@ This function does not do any hidden buffer changes."
2157 (goto-char pos) 2461 (goto-char pos)
2158 nil))))) 2462 nil)))))
2159 2463
2160(defsubst c-beginning-of-current-token (&optional back-limit) 2464(defun c-beginning-of-current-token (&optional back-limit)
2161 ;; Move to the beginning of the current token. Do not move if not 2465 ;; Move to the beginning of the current token. Do not move if not
2162 ;; in the middle of one. BACK-LIMIT may be used to bound the 2466 ;; in the middle of one. BACK-LIMIT may be used to bound the
2163 ;; backward search; if given it's assumed to be at the boundary 2467 ;; backward search; if given it's assumed to be at the boundary
2164 ;; between two tokens. 2468 ;; between two tokens.
2469 ;;
2470 ;; This function might do hidden buffer changes.
2165 (if (looking-at "\\w\\|\\s_") 2471 (if (looking-at "\\w\\|\\s_")
2166 (skip-syntax-backward "w_" back-limit) 2472 (skip-syntax-backward "w_" back-limit)
2167 (let ((start (point))) 2473 (let ((start (point)))
@@ -2183,6 +2489,8 @@ This function does not do any hidden buffer changes."
2183 ;; middle of one. BACK-LIMIT may be used to bound the backward 2489 ;; middle of one. BACK-LIMIT may be used to bound the backward
2184 ;; search; if given it's assumed to be at the boundary between two 2490 ;; search; if given it's assumed to be at the boundary between two
2185 ;; tokens. Return non-nil if the point is moved, nil otherwise. 2491 ;; tokens. Return non-nil if the point is moved, nil otherwise.
2492 ;;
2493 ;; This function might do hidden buffer changes.
2186 (let ((start (point))) 2494 (let ((start (point)))
2187 (cond ((< (skip-syntax-backward "w_" (1- start)) 0) 2495 (cond ((< (skip-syntax-backward "w_" (1- start)) 0)
2188 (skip-syntax-forward "w_")) 2496 (skip-syntax-forward "w_"))
@@ -2228,7 +2536,10 @@ BALANCED is true, a move over a balanced paren counts as one. Note
2228that if COUNT is 0 and no appropriate token beginning is found, 1 will 2536that if COUNT is 0 and no appropriate token beginning is found, 1 will
2229be returned. Thus, a return value of 0 guarantees that point is at 2537be returned. Thus, a return value of 0 guarantees that point is at
2230the requested position and a return value less \(without signs) than 2538the requested position and a return value less \(without signs) than
2231COUNT guarantees that point is at the beginning of some token." 2539COUNT guarantees that point is at the beginning of some token.
2540
2541Note that this function might do hidden buffer changes. See the
2542comment at the start of cc-engine.el for more info."
2232 2543
2233 (or count (setq count 1)) 2544 (or count (setq count 1))
2234 (if (< count 0) 2545 (if (< count 0)
@@ -2417,7 +2728,10 @@ matches syntactic whitespace.
2417 2728
2418Bug: Unbalanced parens inside cpp directives are currently not handled 2729Bug: Unbalanced parens inside cpp directives are currently not handled
2419correctly \(i.e. they don't get ignored as they should) when 2730correctly \(i.e. they don't get ignored as they should) when
2420PAREN-LEVEL is set." 2731PAREN-LEVEL is set.
2732
2733Note that this function might do hidden buffer changes. See the
2734comment at the start of cc-engine.el for more info."
2421 2735
2422 (or bound (setq bound (point-max))) 2736 (or bound (setq bound (point-max)))
2423 (if paren-level (setq paren-level -1)) 2737 (if paren-level (setq paren-level -1))
@@ -2601,23 +2915,39 @@ PAREN-LEVEL is set."
2601 (goto-char bound)) 2915 (goto-char bound))
2602 nil))) 2916 nil)))
2603 2917
2604(defun c-syntactic-skip-backward (skip-chars &optional limit) 2918(defun c-syntactic-skip-backward (skip-chars &optional limit paren-level)
2605 "Like `skip-chars-backward' but only look at syntactically relevant chars, 2919 "Like `skip-chars-backward' but only look at syntactically relevant chars,
2606i.e. don't stop at positions inside syntactic whitespace or string 2920i.e. don't stop at positions inside syntactic whitespace or string
2607literals. Preprocessor directives are also ignored, with the exception 2921literals. Preprocessor directives are also ignored, with the exception
2608of the one that the point starts within, if any. If LIMIT is given, 2922of the one that the point starts within, if any. If LIMIT is given,
2609it's assumed to be at a syntactically relevant position." 2923it's assumed to be at a syntactically relevant position.
2924
2925If PAREN-LEVEL is non-nil, the function won't stop in nested paren
2926sexps, and the search will also not go outside the current paren sexp.
2927However, if LIMIT or the buffer limit is reached inside a nested paren
2928then the point will be left at the limit.
2929
2930Non-nil is returned if the point moved, nil otherwise.
2931
2932Note that this function might do hidden buffer changes. See the
2933comment at the start of cc-engine.el for more info."
2610 2934
2611 (let ((start (point)) 2935 (let ((start (point))
2936 state
2612 ;; A list of syntactically relevant positions in descending 2937 ;; A list of syntactically relevant positions in descending
2613 ;; order. It's used to avoid scanning repeatedly over 2938 ;; order. It's used to avoid scanning repeatedly over
2614 ;; potentially large regions with `parse-partial-sexp' to verify 2939 ;; potentially large regions with `parse-partial-sexp' to verify
2615 ;; each position. 2940 ;; each position.
2616 safe-pos-list 2941 safe-pos-list
2942 ;; The position at the beginning of `safe-pos-list'.
2943 safe-pos
2617 ;; The result from `c-beginning-of-macro' at the start position or the 2944 ;; The result from `c-beginning-of-macro' at the start position or the
2618 ;; start position itself if it isn't within a macro. Evaluated on 2945 ;; start position itself if it isn't within a macro. Evaluated on
2619 ;; demand. 2946 ;; demand.
2620 start-macro-beg) 2947 start-macro-beg
2948 ;; The earliest position after the current one with the same paren
2949 ;; level. Used only when `paren-level' is set.
2950 (paren-level-pos (point)))
2621 2951
2622 (while (progn 2952 (while (progn
2623 (while (and 2953 (while (and
@@ -2626,7 +2956,7 @@ it's assumed to be at a syntactically relevant position."
2626 ;; Use `parse-partial-sexp' from a safe position down to 2956 ;; Use `parse-partial-sexp' from a safe position down to
2627 ;; the point to check if it's outside comments and 2957 ;; the point to check if it's outside comments and
2628 ;; strings. 2958 ;; strings.
2629 (let ((pos (point)) safe-pos state) 2959 (let ((pos (point)) state-2 pps-end-pos)
2630 ;; Pick a safe position as close to the point as 2960 ;; Pick a safe position as close to the point as
2631 ;; possible. 2961 ;; possible.
2632 ;; 2962 ;;
@@ -2643,13 +2973,18 @@ it's assumed to be at a syntactically relevant position."
2643 (point-min)) 2973 (point-min))
2644 safe-pos-list (list safe-pos))) 2974 safe-pos-list (list safe-pos)))
2645 2975
2976 ;; Cache positions along the way to use if we have to
2977 ;; back up more. We cache every closing paren on the
2978 ;; same level. If the paren cache is relevant in this
2979 ;; region then we're typically already on the same
2980 ;; level as the target position. Note that we might
2981 ;; cache positions after opening parens in case
2982 ;; safe-pos is in a nested list. That's both uncommon
2983 ;; and harmless.
2646 (while (progn 2984 (while (progn
2647 (setq state (parse-partial-sexp 2985 (setq state (parse-partial-sexp
2648 safe-pos pos 0)) 2986 safe-pos pos 0))
2649 (< (point) pos)) 2987 (< (point) pos))
2650 ;; Cache positions along the way to use if we have to
2651 ;; back up more. Every closing paren on the same
2652 ;; level seems like fairly well spaced positions.
2653 (setq safe-pos (point) 2988 (setq safe-pos (point)
2654 safe-pos-list (cons safe-pos safe-pos-list))) 2989 safe-pos-list (cons safe-pos safe-pos-list)))
2655 2990
@@ -2657,13 +2992,50 @@ it's assumed to be at a syntactically relevant position."
2657 ((or (elt state 3) (elt state 4)) 2992 ((or (elt state 3) (elt state 4))
2658 ;; Inside string or comment. Continue search at the 2993 ;; Inside string or comment. Continue search at the
2659 ;; beginning of it. 2994 ;; beginning of it.
2660 (if (setq pos (nth 8 state)) 2995 (goto-char (elt state 8))
2661 ;; It's an emacs where `parse-partial-sexp'
2662 ;; supplies the starting position.
2663 (goto-char pos)
2664 (goto-char (car (c-literal-limits safe-pos))))
2665 t) 2996 t)
2666 2997
2998 ((and paren-level
2999 (save-excursion
3000 (setq state-2 (parse-partial-sexp
3001 pos paren-level-pos -1)
3002 pps-end-pos (point))
3003 (/= (car state-2) 0)))
3004 ;; Not at the right level.
3005
3006 (if (and (< (car state-2) 0)
3007 ;; We stop above if we go out of a paren.
3008 ;; Now check whether it precedes or is
3009 ;; nested in the starting sexp.
3010 (save-excursion
3011 (setq state-2
3012 (parse-partial-sexp
3013 pps-end-pos paren-level-pos
3014 nil nil state-2))
3015 (< (car state-2) 0)))
3016
3017 ;; We've stopped short of the starting position
3018 ;; so the hit was inside a nested list. Go up
3019 ;; until we are at the right level.
3020 (condition-case nil
3021 (progn
3022 (goto-char (scan-lists pos -1
3023 (- (car state-2))))
3024 (setq paren-level-pos (point))
3025 (if (and limit (>= limit paren-level-pos))
3026 (progn
3027 (goto-char limit)
3028 nil)
3029 t))
3030 (error
3031 (goto-char (or limit (point-min)))
3032 nil))
3033
3034 ;; The hit was outside the list at the start
3035 ;; position. Go to the start of the list and exit.
3036 (goto-char (1+ (elt state-2 1)))
3037 nil))
3038
2667 ((c-beginning-of-macro limit) 3039 ((c-beginning-of-macro limit)
2668 ;; Inside a macro. 3040 ;; Inside a macro.
2669 (if (< (point) 3041 (if (< (point)
@@ -2674,10 +3046,20 @@ it's assumed to be at a syntactically relevant position."
2674 (c-beginning-of-macro limit) 3046 (c-beginning-of-macro limit)
2675 (point))))) 3047 (point)))))
2676 t 3048 t
3049
2677 ;; It's inside the same macro we started in so it's 3050 ;; It's inside the same macro we started in so it's
2678 ;; a relevant match. 3051 ;; a relevant match.
2679 (goto-char pos) 3052 (goto-char pos)
2680 nil)))))) 3053 nil)))))
3054
3055 ;; If the state contains the start of the containing sexp we
3056 ;; cache that position too, so that parse-partial-sexp in the
3057 ;; next run has a bigger chance of starting at the same level
3058 ;; as the target position and thus will get more good safe
3059 ;; positions into the list.
3060 (if (elt state 1)
3061 (setq safe-pos (1+ (elt state 1))
3062 safe-pos-list (cons safe-pos safe-pos-list))))
2681 3063
2682 (> (point) 3064 (> (point)
2683 (progn 3065 (progn
@@ -2686,7 +3068,124 @@ it's assumed to be at a syntactically relevant position."
2686 (c-backward-syntactic-ws) 3068 (c-backward-syntactic-ws)
2687 (point))))) 3069 (point)))))
2688 3070
2689 (- (point) start))) 3071 ;; We might want to extend this with more useful return values in
3072 ;; the future.
3073 (/= (point) start)))
3074
3075;; The following is an alternative implementation of
3076;; `c-syntactic-skip-backward' that uses backward movement to keep
3077;; track of the syntactic context. It turned out to be generally
3078;; slower than the one above which uses forward checks from earlier
3079;; safe positions.
3080;;
3081;;(defconst c-ssb-stop-re
3082;; ;; The regexp matching chars `c-syntactic-skip-backward' needs to
3083;; ;; stop at to avoid going into comments and literals.
3084;; (concat
3085;; ;; Match comment end syntax and string literal syntax. Also match
3086;; ;; '/' for block comment endings (not covered by comment end
3087;; ;; syntax).
3088;; "\\s>\\|/\\|\\s\""
3089;; (if (memq 'gen-string-delim c-emacs-features)
3090;; "\\|\\s|"
3091;; "")
3092;; (if (memq 'gen-comment-delim c-emacs-features)
3093;; "\\|\\s!"
3094;; "")))
3095;;
3096;;(defconst c-ssb-stop-paren-re
3097;; ;; Like `c-ssb-stop-re' but also stops at paren chars.
3098;; (concat c-ssb-stop-re "\\|\\s(\\|\\s)"))
3099;;
3100;;(defconst c-ssb-sexp-end-re
3101;; ;; Regexp matching the ending syntax of a complex sexp.
3102;; (concat c-string-limit-regexp "\\|\\s)"))
3103;;
3104;;(defun c-syntactic-skip-backward (skip-chars &optional limit paren-level)
3105;; "Like `skip-chars-backward' but only look at syntactically relevant chars,
3106;;i.e. don't stop at positions inside syntactic whitespace or string
3107;;literals. Preprocessor directives are also ignored. However, if the
3108;;point is within a comment, string literal or preprocessor directory to
3109;;begin with, its contents is treated as syntactically relevant chars.
3110;;If LIMIT is given, it limits the backward search and the point will be
3111;;left there if no earlier position is found.
3112;;
3113;;If PAREN-LEVEL is non-nil, the function won't stop in nested paren
3114;;sexps, and the search will also not go outside the current paren sexp.
3115;;However, if LIMIT or the buffer limit is reached inside a nested paren
3116;;then the point will be left at the limit.
3117;;
3118;;Non-nil is returned if the point moved, nil otherwise.
3119;;
3120;;Note that this function might do hidden buffer changes. See the
3121;;comment at the start of cc-engine.el for more info."
3122;;
3123;; (save-restriction
3124;; (when limit
3125;; (narrow-to-region limit (point-max)))
3126;;
3127;; (let ((start (point)))
3128;; (catch 'done
3129;; (while (let ((last-pos (point))
3130;; (stop-pos (progn
3131;; (skip-chars-backward skip-chars)
3132;; (point))))
3133;;
3134;; ;; Skip back over the same region as
3135;; ;; `skip-chars-backward' above, but keep to
3136;; ;; syntactically relevant positions.
3137;; (goto-char last-pos)
3138;; (while (and
3139;; ;; `re-search-backward' with a single char regexp
3140;; ;; should be fast.
3141;; (re-search-backward
3142;; (if paren-level c-ssb-stop-paren-re c-ssb-stop-re)
3143;; stop-pos 'move)
3144;;
3145;; (progn
3146;; (cond
3147;; ((looking-at "\\s(")
3148;; ;; `paren-level' is set and we've found the
3149;; ;; start of the containing paren.
3150;; (forward-char)
3151;; (throw 'done t))
3152;;
3153;; ((looking-at c-ssb-sexp-end-re)
3154;; ;; We're at the end of a string literal or paren
3155;; ;; sexp (if `paren-level' is set).
3156;; (forward-char)
3157;; (condition-case nil
3158;; (c-backward-sexp)
3159;; (error
3160;; (goto-char limit)
3161;; (throw 'done t))))
3162;;
3163;; (t
3164;; (forward-char)
3165;; ;; At the end of some syntactic ws or possibly
3166;; ;; after a plain '/' operator.
3167;; (let ((pos (point)))
3168;; (c-backward-syntactic-ws)
3169;; (if (= pos (point))
3170;; ;; Was a plain '/' operator. Go past it.
3171;; (backward-char)))))
3172;;
3173;; (> (point) stop-pos))))
3174;;
3175;; ;; Now the point is either at `stop-pos' or at some
3176;; ;; position further back if `stop-pos' was at a
3177;; ;; syntactically irrelevant place.
3178;;
3179;; ;; Skip additional syntactic ws so that we don't stop
3180;; ;; at the end of a comment if `skip-chars' is
3181;; ;; something like "^/".
3182;; (c-backward-syntactic-ws)
3183;;
3184;; (< (point) stop-pos))))
3185;;
3186;; ;; We might want to extend this with more useful return values
3187;; ;; in the future.
3188;; (/= (point) start))))
2690 3189
2691 3190
2692;; Tools for handling comments and string literals. 3191;; Tools for handling comments and string literals.
@@ -2702,7 +3201,9 @@ or nil, `c-beginning-of-defun' is used.
2702The last point calculated is cached if the cache is enabled, i.e. if 3201The last point calculated is cached if the cache is enabled, i.e. if
2703`c-in-literal-cache' is bound to a two element vector. 3202`c-in-literal-cache' is bound to a two element vector.
2704 3203
2705This function does not do any hidden buffer changes." 3204Note that this function might do hidden buffer changes. See the
3205comment at the start of cc-engine.el for more info."
3206
2706 (if (and (vectorp c-in-literal-cache) 3207 (if (and (vectorp c-in-literal-cache)
2707 (= (point) (aref c-in-literal-cache 0))) 3208 (= (point) (aref c-in-literal-cache 0)))
2708 (aref c-in-literal-cache 1) 3209 (aref c-in-literal-cache 1)
@@ -2748,6 +3249,7 @@ This function does not do any hidden buffer changes."
2748;; (Alan Mackenzie, 2003/4/30). 3249;; (Alan Mackenzie, 2003/4/30).
2749 3250
2750(defun c-fast-in-literal (&optional lim detect-cpp) 3251(defun c-fast-in-literal (&optional lim detect-cpp)
3252 ;; This function might do hidden buffer changes.
2751 (let ((context (buffer-syntactic-context))) 3253 (let ((context (buffer-syntactic-context)))
2752 (cond 3254 (cond
2753 ((eq context 'string) 'string) 3255 ((eq context 'string) 'string)
@@ -2775,104 +3277,8 @@ non-nil, the case when point is inside a starting delimiter won't be
2775recognized. This only has effect for comments, which have starting 3277recognized. This only has effect for comments, which have starting
2776delimiters with more than one character. 3278delimiters with more than one character.
2777 3279
2778This function does not do any hidden buffer changes." 3280Note that this function might do hidden buffer changes. See the
2779 3281comment at the start of cc-engine.el for more info."
2780 (save-excursion
2781 (let* ((pos (point))
2782 (lim (or lim (progn
2783 (c-beginning-of-syntax)
2784 (point))))
2785 (state (parse-partial-sexp lim pos)))
2786
2787 (cond ((elt state 3)
2788 ;; String. Search backward for the start.
2789 (while (elt state 3)
2790 (search-backward (make-string 1 (elt state 3)))
2791 (setq state (parse-partial-sexp lim (point))))
2792 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
2793 (point-max))))
2794
2795 ((elt state 7)
2796 ;; Line comment. Search from bol for the comment starter.
2797 (beginning-of-line)
2798 (setq state (parse-partial-sexp lim (point))
2799 lim (point))
2800 (while (not (elt state 7))
2801 (search-forward "//") ; Should never fail.
2802 (setq state (parse-partial-sexp
2803 lim (point) nil nil state)
2804 lim (point)))
2805 (backward-char 2)
2806 (cons (point) (progn (c-forward-single-comment) (point))))
2807
2808 ((elt state 4)
2809 ;; Block comment. Search backward for the comment starter.
2810 (while (elt state 4)
2811 (search-backward "/*") ; Should never fail.
2812 (setq state (parse-partial-sexp lim (point))))
2813 (cons (point) (progn (c-forward-single-comment) (point))))
2814
2815 ((and (not not-in-delimiter)
2816 (not (elt state 5))
2817 (eq (char-before) ?/)
2818 (looking-at "[/*]"))
2819 ;; We're standing in a comment starter.
2820 (backward-char 1)
2821 (cons (point) (progn (c-forward-single-comment) (point))))
2822
2823 (near
2824 (goto-char pos)
2825
2826 ;; Search forward for a literal.
2827 (skip-chars-forward " \t")
2828
2829 (cond
2830 ((looking-at c-string-limit-regexp) ; String.
2831 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
2832 (point-max))))
2833
2834 ((looking-at c-comment-start-regexp) ; Line or block comment.
2835 (cons (point) (progn (c-forward-single-comment) (point))))
2836
2837 (t
2838 ;; Search backward.
2839 (skip-chars-backward " \t")
2840
2841 (let ((end (point)) beg)
2842 (cond
2843 ((save-excursion
2844 (< (skip-syntax-backward c-string-syntax) 0)) ; String.
2845 (setq beg (c-safe (c-backward-sexp 1) (point))))
2846
2847 ((and (c-safe (forward-char -2) t)
2848 (looking-at "*/"))
2849 ;; Block comment. Due to the nature of line
2850 ;; comments, they will always be covered by the
2851 ;; normal case above.
2852 (goto-char end)
2853 (c-backward-single-comment)
2854 ;; If LIM is bogus, beg will be bogus.
2855 (setq beg (point))))
2856
2857 (if beg (cons beg end))))))
2858 ))))
2859
2860(defun c-literal-limits-fast (&optional lim near not-in-delimiter)
2861 ;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp'
2862 ;; returns the pos of the comment start.
2863
2864 "Return a cons of the beginning and end positions of the comment or
2865string surrounding point (including both delimiters), or nil if point
2866isn't in one. If LIM is non-nil, it's used as the \"safe\" position
2867to start parsing from. If NEAR is non-nil, then the limits of any
2868literal next to point is returned. \"Next to\" means there's only
2869spaces and tabs between point and the literal. The search for such a
2870literal is done first in forward direction. If NOT-IN-DELIMITER is
2871non-nil, the case when point is inside a starting delimiter won't be
2872recognized. This only has effect for comments, which have starting
2873delimiters with more than one character.
2874
2875This function does not do any hidden buffer changes."
2876 3282
2877 (save-excursion 3283 (save-excursion
2878 (let* ((pos (point)) 3284 (let* ((pos (point))
@@ -2935,8 +3341,8 @@ This function does not do any hidden buffer changes."
2935 (if beg (cons beg end)))))) 3341 (if beg (cons beg end))))))
2936 )))) 3342 ))))
2937 3343
2938(if (memq 'pps-extended-state c-emacs-features) 3344;; In case external callers use this; it did have a docstring.
2939 (defalias 'c-literal-limits 'c-literal-limits-fast)) 3345(defalias 'c-literal-limits-fast 'c-literal-limits)
2940 3346
2941(defun c-collect-line-comments (range) 3347(defun c-collect-line-comments (range)
2942 "If the argument is a cons of two buffer positions (such as returned by 3348 "If the argument is a cons of two buffer positions (such as returned by
@@ -2946,13 +3352,15 @@ comments (i.e. all comments that starts in the same column with no
2946empty lines or non-whitespace characters between them). Otherwise the 3352empty lines or non-whitespace characters between them). Otherwise the
2947argument is returned. 3353argument is returned.
2948 3354
2949This function does not do any hidden buffer changes." 3355Note that this function might do hidden buffer changes. See the
3356comment at the start of cc-engine.el for more info."
3357
2950 (save-excursion 3358 (save-excursion
2951 (condition-case nil 3359 (condition-case nil
2952 (if (and (consp range) (progn 3360 (if (and (consp range) (progn
2953 (goto-char (car range)) 3361 (goto-char (car range))
2954 (looking-at "//"))) 3362 (looking-at c-line-comment-starter)))
2955 (let ((col (current-column)) 3363 (let ((col (current-column))
2956 (beg (point)) 3364 (beg (point))
2957 (bopl (c-point 'bopl)) 3365 (bopl (c-point 'bopl))
2958 (end (cdr range))) 3366 (end (cdr range)))
@@ -2960,13 +3368,13 @@ This function does not do any hidden buffer changes."
2960 ;; comments which are preceded by code. 3368 ;; comments which are preceded by code.
2961 (while (and (c-backward-single-comment) 3369 (while (and (c-backward-single-comment)
2962 (>= (point) bopl) 3370 (>= (point) bopl)
2963 (looking-at "//") 3371 (looking-at c-line-comment-starter)
2964 (= col (current-column))) 3372 (= col (current-column)))
2965 (setq beg (point) 3373 (setq beg (point)
2966 bopl (c-point 'bopl))) 3374 bopl (c-point 'bopl)))
2967 (goto-char end) 3375 (goto-char end)
2968 (while (and (progn (skip-chars-forward " \t") 3376 (while (and (progn (skip-chars-forward " \t")
2969 (looking-at "//")) 3377 (looking-at c-line-comment-starter))
2970 (= col (current-column)) 3378 (= col (current-column))
2971 (prog1 (zerop (forward-line 1)) 3379 (prog1 (zerop (forward-line 1))
2972 (setq end (point))))) 3380 (setq end (point)))))
@@ -2980,7 +3388,9 @@ returns nil or the type of literal that the range surrounds. It's
2980much faster than using `c-in-literal' and is intended to be used when 3388much faster than using `c-in-literal' and is intended to be used when
2981you need both the type of a literal and its limits. 3389you need both the type of a literal and its limits.
2982 3390
2983This function does not do any hidden buffer changes." 3391Note that this function might do hidden buffer changes. See the
3392comment at the start of cc-engine.el for more info."
3393
2984 (if (consp range) 3394 (if (consp range)
2985 (save-excursion 3395 (save-excursion
2986 (goto-char (car range)) 3396 (goto-char (car range))
@@ -3032,14 +3442,14 @@ This function does not do any hidden buffer changes."
3032 3442
3033(defmacro c-debug-put-decl-spot-faces (match-pos decl-pos) 3443(defmacro c-debug-put-decl-spot-faces (match-pos decl-pos)
3034 (when (facep 'c-debug-decl-spot-face) 3444 (when (facep 'c-debug-decl-spot-face)
3035 `(let ((match-pos ,match-pos) (decl-pos ,decl-pos)) 3445 `(c-save-buffer-state ((match-pos ,match-pos) (decl-pos ,decl-pos))
3036 (c-debug-add-face (max match-pos (point-min)) decl-pos 3446 (c-debug-add-face (max match-pos (point-min)) decl-pos
3037 'c-debug-decl-sws-face) 3447 'c-debug-decl-sws-face)
3038 (c-debug-add-face decl-pos (min (1+ decl-pos) (point-max)) 3448 (c-debug-add-face decl-pos (min (1+ decl-pos) (point-max))
3039 'c-debug-decl-spot-face)))) 3449 'c-debug-decl-spot-face))))
3040(defmacro c-debug-remove-decl-spot-faces (beg end) 3450(defmacro c-debug-remove-decl-spot-faces (beg end)
3041 (when (facep 'c-debug-decl-spot-face) 3451 (when (facep 'c-debug-decl-spot-face)
3042 `(progn 3452 `(c-save-buffer-state ()
3043 (c-debug-remove-face ,beg ,end 'c-debug-decl-spot-face) 3453 (c-debug-remove-face ,beg ,end 'c-debug-decl-spot-face)
3044 (c-debug-remove-face ,beg ,end 'c-debug-decl-sws-face)))) 3454 (c-debug-remove-face ,beg ,end 'c-debug-decl-sws-face))))
3045 3455
@@ -3048,6 +3458,8 @@ This function does not do any hidden buffer changes."
3048 ;; but it contains lots of free variables that refer to things 3458 ;; but it contains lots of free variables that refer to things
3049 ;; inside `c-find-decl-spots'. The point is left at `cfd-match-pos' 3459 ;; inside `c-find-decl-spots'. The point is left at `cfd-match-pos'
3050 ;; if there is a match, otherwise at `cfd-limit'. 3460 ;; if there is a match, otherwise at `cfd-limit'.
3461 ;;
3462 ;; This macro might do hidden buffer changes.
3051 3463
3052 '(progn 3464 '(progn
3053 ;; Find the next property match position if we haven't got one already. 3465 ;; Find the next property match position if we haven't got one already.
@@ -3061,21 +3473,46 @@ This function does not do any hidden buffer changes."
3061 'c-decl-end))))) 3473 'c-decl-end)))))
3062 (setq cfd-prop-match (point)))) 3474 (setq cfd-prop-match (point))))
3063 3475
3064 ;; Find the next `c-decl-prefix-re' match if we haven't got one already. 3476 ;; Find the next `c-decl-prefix-or-start-re' match if we haven't
3477 ;; got one already.
3065 (unless cfd-re-match 3478 (unless cfd-re-match
3066 (while (and (setq cfd-re-match 3479
3067 (re-search-forward c-decl-prefix-re cfd-limit 'move)) 3480 (if (> cfd-re-match-end (point))
3068 (c-got-face-at (1- (setq cfd-re-match (match-end 1))) 3481 (goto-char cfd-re-match-end))
3069 c-literal-faces)) 3482
3070 ;; Search again if the match is within a comment or a string literal. 3483 (while (if (setq cfd-re-match-end
3484 (re-search-forward c-decl-prefix-or-start-re
3485 cfd-limit 'move))
3486
3487 ;; Match. Check if it's inside a comment or string literal.
3488 (c-got-face-at
3489 (if (setq cfd-re-match (match-end 1))
3490 ;; Matched the end of a token preceding a decl spot.
3491 (progn
3492 (goto-char cfd-re-match)
3493 (1- cfd-re-match))
3494 ;; Matched a token that start a decl spot.
3495 (goto-char (match-beginning 0))
3496 (point))
3497 c-literal-faces)
3498
3499 ;; No match. Finish up and exit the loop.
3500 (setq cfd-re-match cfd-limit)
3501 nil)
3502
3503 ;; Skip out of comments and string literals.
3071 (while (progn 3504 (while (progn
3072 (goto-char (next-single-property-change 3505 (goto-char (next-single-property-change
3073 cfd-re-match 'face nil cfd-limit)) 3506 (point) 'face nil cfd-limit))
3074 (and (< (point) cfd-limit) 3507 (and (< (point) cfd-limit)
3075 (c-got-face-at (point) c-literal-faces))) 3508 (c-got-face-at (point) c-literal-faces)))))
3076 (setq cfd-re-match (point)))) 3509
3510 ;; If we matched at the decl start, we have to back up over the
3511 ;; preceding syntactic ws to set `cfd-match-pos' and to catch
3512 ;; any decl spots in the syntactic ws.
3077 (unless cfd-re-match 3513 (unless cfd-re-match
3078 (setq cfd-re-match cfd-limit))) 3514 (c-backward-syntactic-ws)
3515 (setq cfd-re-match (point))))
3079 3516
3080 ;; Choose whichever match is closer to the start. 3517 ;; Choose whichever match is closer to the start.
3081 (if (< cfd-re-match cfd-prop-match) 3518 (if (< cfd-re-match cfd-prop-match)
@@ -3098,14 +3535,21 @@ This function does not do any hidden buffer changes."
3098 (point)))))) 3535 (point))))))
3099 3536
3100(defun c-find-decl-spots (cfd-limit cfd-decl-re cfd-face-checklist cfd-fun) 3537(defun c-find-decl-spots (cfd-limit cfd-decl-re cfd-face-checklist cfd-fun)
3101 ;; Call CFD-FUN for each possible spot for a declaration from the 3538 ;; Call CFD-FUN for each possible spot for a declaration, cast or
3102 ;; point to CFD-LIMIT. A spot for a declaration is the first token 3539 ;; label from the point to CFD-LIMIT. Such a spot is:
3103 ;; in the buffer and each token after the ones matched by 3540 ;;
3104 ;; `c-decl-prefix-re' and after the occurrences of the `c-type' 3541 ;; o The first token after bob.
3105 ;; property with the value `c-decl-end' (if `c-type-decl-end-used' 3542 ;; o The first token after the end of submatch 1 in
3106 ;; is set). Only a spot that match CFD-DECL-RE and whose face is in 3543 ;; `c-decl-prefix-or-start-re' when that submatch matches.
3107 ;; the CFD-FACE-CHECKLIST list causes CFD-FUN to be called. The 3544 ;; o The start of each `c-decl-prefix-or-start-re' match when
3108 ;; face check is disabled if CFD-FACE-CHECKLIST is nil. 3545 ;; submatch 1 doesn't match.
3546 ;; o The first token after the end of each occurence of the
3547 ;; `c-type' text property with the value `c-decl-end', provided
3548 ;; `c-type-decl-end-used' is set.
3549 ;;
3550 ;; Only a spot that match CFD-DECL-RE and whose face is in the
3551 ;; CFD-FACE-CHECKLIST list causes CFD-FUN to be called. The face
3552 ;; check is disabled if CFD-FACE-CHECKLIST is nil.
3109 ;; 3553 ;;
3110 ;; If the match is inside a macro then the buffer is narrowed to the 3554 ;; If the match is inside a macro then the buffer is narrowed to the
3111 ;; end of it, so that CFD-FUN can investigate the following tokens 3555 ;; end of it, so that CFD-FUN can investigate the following tokens
@@ -3115,11 +3559,21 @@ This function does not do any hidden buffer changes."
3115 ;; 3559 ;;
3116 ;; CFD-FUN is called with point at the start of the spot. It's 3560 ;; CFD-FUN is called with point at the start of the spot. It's
3117 ;; passed two arguments: The first is the end position of the token 3561 ;; passed two arguments: The first is the end position of the token
3118 ;; that `c-decl-prefix-re' matched, or 0 for the implicit match at 3562 ;; preceding the spot, or 0 for the implicit match at bob. The
3119 ;; bob. The second is a flag that is t when the match is inside a 3563 ;; second is a flag that is t when the match is inside a macro. If
3120 ;; macro. 3564 ;; CFD-FUN adds `c-decl-end' properties somewhere below the current
3565 ;; spot, it should return non-nil to ensure that the next search
3566 ;; will find them.
3567 ;;
3568 ;; The spots are visited approximately in order from top to bottom.
3569 ;; It's however the positions where `c-decl-prefix-or-start-re'
3570 ;; matches and where `c-decl-end' properties are found that are in
3571 ;; order. Since the spots often are at the following token, they
3572 ;; might be visited out of order insofar as more spots are reported
3573 ;; later on within the syntactic whitespace between the match
3574 ;; positions and their spots.
3121 ;; 3575 ;;
3122 ;; It's assumed that comment and strings are fontified in the 3576 ;; It's assumed that comments and strings are fontified in the
3123 ;; searched range. 3577 ;; searched range.
3124 ;; 3578 ;;
3125 ;; This is mainly used in fontification, and so has an elaborate 3579 ;; This is mainly used in fontification, and so has an elaborate
@@ -3128,19 +3582,28 @@ This function does not do any hidden buffer changes."
3128 ;; 3582 ;;
3129 ;; All variables in this function begin with `cfd-' to avoid name 3583 ;; All variables in this function begin with `cfd-' to avoid name
3130 ;; collision with the (dynamically bound) variables used in CFD-FUN. 3584 ;; collision with the (dynamically bound) variables used in CFD-FUN.
3585 ;;
3586 ;; This function might do hidden buffer changes.
3131 3587
3132 (let ((cfd-buffer-end (point-max)) 3588 (let ((cfd-start-pos (point))
3133 ;; The last regexp match found by `c-find-decl-prefix-search'. 3589 (cfd-buffer-end (point-max))
3590 ;; The end of the token preceding the decl spot last found
3591 ;; with `c-decl-prefix-or-start-re'. `cfd-limit' if there's
3592 ;; no match.
3134 cfd-re-match 3593 cfd-re-match
3135 ;; The last `c-decl-end' found by `c-find-decl-prefix-search'. 3594 ;; The end position of the last `c-decl-prefix-or-start-re'
3136 ;; If searching for the property isn't needed then we disable 3595 ;; match. If this is greater than `cfd-continue-pos', the
3137 ;; it by faking a first match at the limit. 3596 ;; next regexp search is started here instead.
3597 (cfd-re-match-end (point-min))
3598 ;; The end of the last `c-decl-end' found by
3599 ;; `c-find-decl-prefix-search'. `cfd-limit' if there's no
3600 ;; match. If searching for the property isn't needed then we
3601 ;; disable it by setting it to `cfd-limit' directly.
3138 (cfd-prop-match (unless c-type-decl-end-used cfd-limit)) 3602 (cfd-prop-match (unless c-type-decl-end-used cfd-limit))
3139 ;; The position of the last match found by 3603 ;; The end of the token preceding the decl spot last found by
3140 ;; `c-find-decl-prefix-search'. For regexp matches it's the 3604 ;; `c-find-decl-prefix-search'. 0 for the implicit match at
3141 ;; end of the matched token, for property matches it's the end 3605 ;; bob. `cfd-limit' if there's no match. In other words,
3142 ;; of the property. 0 for the implicit match at bob. 3606 ;; this is the minimum of `cfd-re-match' and `cfd-prop-match'.
3143 ;; `cfd-limit' if there's no match.
3144 (cfd-match-pos cfd-limit) 3607 (cfd-match-pos cfd-limit)
3145 ;; The position to continue searching at. 3608 ;; The position to continue searching at.
3146 cfd-continue-pos 3609 cfd-continue-pos
@@ -3153,127 +3616,219 @@ This function does not do any hidden buffer changes."
3153 (cfd-macro-end 0)) 3616 (cfd-macro-end 0))
3154 3617
3155 ;; Initialize by finding a syntactically relevant start position 3618 ;; Initialize by finding a syntactically relevant start position
3156 ;; before the point, and do the first `c-decl-prefix-re' search 3619 ;; before the point, and do the first `c-decl-prefix-or-start-re'
3157 ;; unless we're at bob. 3620 ;; search unless we're at bob.
3158 3621
3159 (let ((start-pos (point)) syntactic-pos) 3622 (let (start-in-literal start-in-macro syntactic-pos)
3160 ;; Must back up a bit since we look for the end of the previous 3623 ;; Must back up a bit since we look for the end of the previous
3161 ;; statement or declaration, which is earlier than the first 3624 ;; statement or declaration, which is earlier than the first
3162 ;; returned match. 3625 ;; returned match.
3163 3626
3164 (when (c-got-face-at (point) c-literal-faces) 3627 (cond
3165 ;; But first we need to move to a syntactically relevant 3628 ;; First we need to move to a syntactically relevant position.
3166 ;; position. Use the faces to back up to the start of the 3629 ;; Begin by backing out of comment or string literals.
3167 ;; comment or string literal. 3630 ((and
3168 (when (and (not (bobp)) 3631 (when (c-got-face-at (point) c-literal-faces)
3169 (c-got-face-at (1- (point)) c-literal-faces)) 3632 ;; Try to use the faces to back up to the start of the
3170 (while (progn 3633 ;; literal. FIXME: What if the point is on a declaration
3171 (goto-char (previous-single-property-change 3634 ;; inside a comment?
3172 (point) 'face nil (point-min))) 3635 (while (and (not (bobp))
3173 (and (> (point) (point-min)) 3636 (c-got-face-at (1- (point)) c-literal-faces))
3174 (c-got-face-at (point) c-literal-faces))))) 3637 (goto-char (previous-single-property-change
3175 3638 (point) 'face nil (point-min))))
3176 ;; XEmacs doesn't fontify the quotes surrounding string 3639
3177 ;; literals. 3640 ;; XEmacs doesn't fontify the quotes surrounding string
3178 (and (featurep 'xemacs) 3641 ;; literals.
3179 (eq (get-text-property (point) 'face) 3642 (and (featurep 'xemacs)
3180 'font-lock-string-face) 3643 (eq (get-text-property (point) 'face)
3181 (not (bobp)) 3644 'font-lock-string-face)
3182 (progn (backward-char) 3645 (not (bobp))
3183 (not (looking-at c-string-limit-regexp))) 3646 (progn (backward-char)
3184 (forward-char)) 3647 (not (looking-at c-string-limit-regexp)))
3185 3648 (forward-char))
3186 ;; The font lock package might not have fontified the start of 3649
3187 ;; the literal at all so check that we have arrived at 3650 ;; Don't trust the literal to contain only literal faces
3188 ;; something that looks like a start or else resort to 3651 ;; (the font lock package might not have fontified the
3189 ;; `c-literal-limits'. 3652 ;; start of it at all, for instance) so check that we have
3190 (unless (looking-at c-literal-start-regexp) 3653 ;; arrived at something that looks like a start or else
3191 (let ((range (c-literal-limits))) 3654 ;; resort to `c-literal-limits'.
3192 (if range (goto-char (car range)))))) 3655 (unless (looking-at c-literal-start-regexp)
3193 3656 (let ((range (c-literal-limits)))
3194 ;; Must back out of any macro so that we don't miss any 3657 (if range (goto-char (car range)))))
3195 ;; declaration that could follow after it, unless the limit is 3658
3196 ;; inside the macro. We only check that for the current line to 3659 (setq start-in-literal (point)))
3197 ;; save some time; it's enough for the by far most common case 3660
3198 ;; when font-lock refontifies the current line only. 3661 ;; The start is in a literal. If the limit is in the same
3199 (when (save-excursion 3662 ;; one we don't have to find a syntactic position etc. We
3200 (and (= (forward-line 1) 0) 3663 ;; only check that if the limit is at or before bonl to save
3201 (bolp) ; forward-line has funny behavior at eob. 3664 ;; time; it covers the by far most common case when font-lock
3202 (or (< (c-point 'eol) cfd-limit) 3665 ;; refontifies the current line only.
3203 (progn (backward-char) 3666 (<= cfd-limit (c-point 'bonl cfd-start-pos))
3204 (not (eq (char-before) ?\\)))))) 3667 (save-excursion
3205 (c-beginning-of-macro)) 3668 (goto-char cfd-start-pos)
3206 3669 (while (progn
3207 ;; Clear the cache if it applied further down. 3670 (goto-char (next-single-property-change
3208 (c-invalidate-find-decl-cache start-pos) 3671 (point) 'face nil cfd-limit))
3209 3672 (and (< (point) cfd-limit)
3210 (setq syntactic-pos (point)) 3673 (c-got-face-at (point) c-literal-faces))))
3211 (c-backward-syntactic-ws c-find-decl-syntactic-pos) 3674 (= (point) cfd-limit)))
3212 3675
3213 ;; If we hit `c-find-decl-syntactic-pos' and 3676 ;; Completely inside a literal. Set up variables to trig the
3214 ;; `c-find-decl-match-pos' is set then we install the cached 3677 ;; (< cfd-continue-pos cfd-start-pos) case below and it'll
3215 ;; values. If we hit `c-find-decl-syntactic-pos' and 3678 ;; find a suitable start position.
3216 ;; `c-find-decl-match-pos' is nil then we know there's no decl 3679 (setq cfd-continue-pos start-in-literal))
3217 ;; prefix in the whitespace before `c-find-decl-syntactic-pos' 3680
3218 ;; and so we can continue the search from this point. If we 3681 ;; Check if the region might be completely inside a macro, to
3219 ;; didn't hit `c-find-decl-syntactic-pos' then we're now in the 3682 ;; optimize that like the completely-inside-literal above.
3220 ;; right spot to begin searching anyway. 3683 ((save-excursion
3221 (if (and (eq (point) c-find-decl-syntactic-pos) 3684 (and (= (forward-line 1) 0)
3222 c-find-decl-match-pos) 3685 (bolp) ; forward-line has funny behavior at eob.
3686 (>= (point) cfd-limit)
3687 (progn (backward-char)
3688 (eq (char-before) ?\\))))
3689 ;; (Maybe) completely inside a macro. Only need to trig the
3690 ;; (< cfd-continue-pos cfd-start-pos) case below to make it
3691 ;; set things up.
3692 (setq cfd-continue-pos (1- cfd-start-pos)
3693 start-in-macro t))
3223 3694
3224 (progn 3695 (t
3225 ;; The match is always outside macros and comments so we 3696 ;; Back out of any macro so we don't miss any declaration
3226 ;; start at the next token. The loop below will later go 3697 ;; that could follow after it.
3227 ;; back using `cfd-continue-pos' to fix declarations inside 3698 (when (c-beginning-of-macro)
3228 ;; the syntactic ws. 3699 (setq start-in-macro t))
3229 (goto-char syntactic-pos) 3700
3230 (c-forward-syntactic-ws) 3701 ;; Now we're at a proper syntactically relevant position so we
3702 ;; can use the cache. But first clear it if it applied
3703 ;; further down.
3704 (c-invalidate-find-decl-cache cfd-start-pos)
3705
3706 (setq syntactic-pos (point))
3707 (unless (eq syntactic-pos c-find-decl-syntactic-pos)
3708 ;; Don't have to do this if the cache is relevant here,
3709 ;; typically if the same line is refontified again. If
3710 ;; we're just some syntactic whitespace further down we can
3711 ;; still use the cache to limit the skipping.
3712 (c-backward-syntactic-ws c-find-decl-syntactic-pos))
3713
3714 ;; If we hit `c-find-decl-syntactic-pos' and
3715 ;; `c-find-decl-match-pos' is set then we install the cached
3716 ;; values. If we hit `c-find-decl-syntactic-pos' and
3717 ;; `c-find-decl-match-pos' is nil then we know there's no decl
3718 ;; prefix in the whitespace before `c-find-decl-syntactic-pos'
3719 ;; and so we can continue the search from this point. If we
3720 ;; didn't hit `c-find-decl-syntactic-pos' then we're now in
3721 ;; the right spot to begin searching anyway.
3722 (if (and (eq (point) c-find-decl-syntactic-pos)
3723 c-find-decl-match-pos)
3231 (setq cfd-match-pos c-find-decl-match-pos 3724 (setq cfd-match-pos c-find-decl-match-pos
3232 cfd-continue-pos syntactic-pos) 3725 cfd-continue-pos syntactic-pos)
3233 (if (< cfd-continue-pos (point)) 3726
3234 (setq cfd-token-pos (point)))) 3727 (setq c-find-decl-syntactic-pos syntactic-pos)
3235 3728
3236 (setq c-find-decl-syntactic-pos syntactic-pos) 3729 (when (if (bobp)
3237 3730 ;; Always consider bob a match to get the first
3238 (when (if (bobp) 3731 ;; declaration in the file. Do this separately instead of
3239 ;; Always consider bob a match to get the first declaration 3732 ;; letting `c-decl-prefix-or-start-re' match bob, so that
3240 ;; in the file. Do this separately instead of letting 3733 ;; regexp always can consume at least one character to
3241 ;; `c-decl-prefix-re' match bob, so that it always can 3734 ;; ensure that we won't get stuck in an infinite loop.
3242 ;; consume at least one character to ensure that we won't 3735 (setq cfd-re-match 0)
3243 ;; get stuck in an infinite loop. 3736 (backward-char)
3244 (setq cfd-re-match 0) 3737 (c-beginning-of-current-token)
3245 (backward-char) 3738 (< (point) cfd-limit))
3246 (c-beginning-of-current-token) 3739 ;; Do an initial search now. In the bob case above it's
3247 (< (point) cfd-limit)) 3740 ;; only done to search for a `c-decl-end' spot.
3248 ;; Do an initial search now. In the bob case above it's only done 3741 (c-find-decl-prefix-search))
3249 ;; to search for the `c-type' property. 3742
3250 (c-find-decl-prefix-search)) 3743 (setq c-find-decl-match-pos (and (< cfd-match-pos cfd-start-pos)
3251 3744 cfd-match-pos)))))
3252 ;; Advance `cfd-continue-pos' if we got a hit before the start 3745
3253 ;; position. The earliest position that could affect after 3746 ;; Advance `cfd-continue-pos' if it's before the start position.
3254 ;; the start position is the char before the preceding 3747 ;; The closest continue position that might have effect at or
3255 ;; comments. 3748 ;; after the start depends on what we started in. This also
3256 (when (and cfd-continue-pos (< cfd-continue-pos start-pos)) 3749 ;; finds a suitable start position in the special cases when the
3257 (goto-char syntactic-pos) 3750 ;; region is completely within a literal or macro.
3751 (when (and cfd-continue-pos (< cfd-continue-pos cfd-start-pos))
3752
3753 (cond
3754 (start-in-macro
3755 ;; If we're in a macro then it's the closest preceding token
3756 ;; in the macro. Check this before `start-in-literal',
3757 ;; since if we're inside a literal in a macro, the preceding
3758 ;; token is earlier than any `c-decl-end' spot inside the
3759 ;; literal (comment).
3760 (goto-char (or start-in-literal cfd-start-pos))
3761 ;; The only syntactic ws in macros are comments.
3258 (c-backward-comments) 3762 (c-backward-comments)
3259 (unless (bobp) 3763 (backward-char)
3260 (backward-char) 3764 (c-beginning-of-current-token))
3261 (c-beginning-of-current-token)) 3765
3262 (setq cfd-continue-pos (max cfd-continue-pos (point)))) 3766 (start-in-literal
3263 3767 ;; If we're in a comment it can only be the closest
3264 ;; If we got a match it's always outside macros and comments so 3768 ;; preceding `c-decl-end' position within that comment, if
3265 ;; advance to the next token and set `cfd-token-pos'. The loop 3769 ;; any. Go back to the beginning of such a property so that
3266 ;; below will later go back using `cfd-continue-pos' to fix 3770 ;; `c-find-decl-prefix-search' will find the end of it.
3267 ;; declarations inside the syntactic ws. 3771 ;; (Can't stop at the end and install it directly on
3268 (when (and (< cfd-match-pos cfd-limit) (< (point) syntactic-pos)) 3772 ;; `cfd-prop-match' since that variable might be cleared
3269 (goto-char syntactic-pos) 3773 ;; after `cfd-fun' below.)
3270 (c-forward-syntactic-ws) 3774 ;;
3271 (and cfd-continue-pos 3775 ;; Note that if the literal is a string then the property
3272 (< cfd-continue-pos (point)) 3776 ;; search will simply skip to the beginning of it right
3273 (setq cfd-token-pos (point)))) 3777 ;; away.
3778 (if (not c-type-decl-end-used)
3779 (goto-char start-in-literal)
3780 (goto-char cfd-start-pos)
3781 (while (progn
3782 (goto-char (previous-single-property-change
3783 (point) 'c-type nil start-in-literal))
3784 (and (> (point) start-in-literal)
3785 (not (eq (c-get-char-property (point) 'c-type)
3786 'c-decl-end))))))
3787
3788 (when (= (point) start-in-literal)
3789 ;; Didn't find any property inside the comment, so we can
3790 ;; skip it entirely. (This won't skip past a string, but
3791 ;; that'll be handled quickly by the next
3792 ;; `c-find-decl-prefix-search' anyway.)
3793 (c-forward-single-comment)
3794 (if (> (point) cfd-limit)
3795 (goto-char cfd-limit))))
3274 3796
3275 (setq c-find-decl-match-pos (and (< cfd-match-pos start-pos) 3797 (t
3276 cfd-match-pos)))) 3798 ;; If we started in normal code, the only match that might
3799 ;; apply before the start is what we already got in
3800 ;; `cfd-match-pos' so we can continue at the start position.
3801 ;; (Note that we don't get here if the first match is below
3802 ;; it.)
3803 (goto-char cfd-start-pos)))
3804
3805 ;; Delete found matches if they are before our new continue
3806 ;; position, so that `c-find-decl-prefix-search' won't back up
3807 ;; to them later on.
3808 (setq cfd-continue-pos (point))
3809 (when (and cfd-re-match (< cfd-re-match cfd-continue-pos))
3810 (setq cfd-re-match nil))
3811 (when (and cfd-prop-match (< cfd-prop-match cfd-continue-pos))
3812 (setq cfd-prop-match nil)))
3813
3814 (if syntactic-pos
3815 ;; This is the normal case and we got a proper syntactic
3816 ;; position. If there's a match then it's always outside
3817 ;; macros and comments, so advance to the next token and set
3818 ;; `cfd-token-pos'. The loop below will later go back using
3819 ;; `cfd-continue-pos' to fix declarations inside the
3820 ;; syntactic ws.
3821 (when (and cfd-match-pos (< cfd-match-pos syntactic-pos))
3822 (goto-char syntactic-pos)
3823 (c-forward-syntactic-ws)
3824 (and cfd-continue-pos
3825 (< cfd-continue-pos (point))
3826 (setq cfd-token-pos (point))))
3827
3828 ;; Have one of the special cases when the region is completely
3829 ;; within a literal or macro. `cfd-continue-pos' is set to a
3830 ;; good start position for the search, so do it.
3831 (c-find-decl-prefix-search)))
3277 3832
3278 ;; Now loop. We already got the first match. 3833 ;; Now loop. We already got the first match.
3279 3834
@@ -3323,33 +3878,37 @@ This function does not do any hidden buffer changes."
3323 3878
3324 (< (point) cfd-limit)) 3879 (< (point) cfd-limit))
3325 3880
3326 (when (progn 3881 (when (and
3327 ;; Narrow to the end of the macro if we got a hit inside 3882 (>= (point) cfd-start-pos)
3328 ;; one, to avoid recognizing things that start inside
3329 ;; the macro and end outside it.
3330 (when (> cfd-match-pos cfd-macro-end)
3331 ;; Not in the same macro as in the previous round.
3332 (save-excursion
3333 (goto-char cfd-match-pos)
3334 (setq cfd-macro-end
3335 (if (save-excursion (and (c-beginning-of-macro)
3336 (< (point) cfd-match-pos)))
3337 (progn (c-end-of-macro)
3338 (point))
3339 0))))
3340 3883
3341 (if (zerop cfd-macro-end) 3884 (progn
3342 t 3885 ;; Narrow to the end of the macro if we got a hit inside
3343 (if (> cfd-macro-end (point)) 3886 ;; one, to avoid recognizing things that start inside the
3344 (progn (narrow-to-region (point-min) cfd-macro-end) 3887 ;; macro and end outside it.
3345 t) 3888 (when (> cfd-match-pos cfd-macro-end)
3346 ;; The matched token was the last thing in the 3889 ;; Not in the same macro as in the previous round.
3347 ;; macro, so the whole match is bogus. 3890 (save-excursion
3348 (setq cfd-macro-end 0) 3891 (goto-char cfd-match-pos)
3349 nil))) 3892 (setq cfd-macro-end
3893 (if (save-excursion (and (c-beginning-of-macro)
3894 (< (point) cfd-match-pos)))
3895 (progn (c-end-of-macro)
3896 (point))
3897 0))))
3898
3899 (if (zerop cfd-macro-end)
3900 t
3901 (if (> cfd-macro-end (point))
3902 (progn (narrow-to-region (point-min) cfd-macro-end)
3903 t)
3904 ;; The matched token was the last thing in the macro,
3905 ;; so the whole match is bogus.
3906 (setq cfd-macro-end 0)
3907 nil))))
3350 3908
3351 (c-debug-put-decl-spot-faces cfd-match-pos (point)) 3909 (c-debug-put-decl-spot-faces cfd-match-pos (point))
3352 (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0)) 3910 (if (funcall cfd-fun cfd-match-pos (/= cfd-macro-end 0))
3911 (setq cfd-prop-match nil))
3353 3912
3354 (when (/= cfd-macro-end 0) 3913 (when (/= cfd-macro-end 0)
3355 ;; Restore limits if we did macro narrowment above. 3914 ;; Restore limits if we did macro narrowment above.
@@ -3370,14 +3929,23 @@ This function does not do any hidden buffer changes."
3370;; bother with the scoping rules of the languages, but in practice the 3929;; bother with the scoping rules of the languages, but in practice the
3371;; same name is seldom used as both a type and something else in a 3930;; same name is seldom used as both a type and something else in a
3372;; file, and we only use this as a last resort in ambiguous cases (see 3931;; file, and we only use this as a last resort in ambiguous cases (see
3373;; `c-font-lock-declarations'). 3932;; `c-forward-decl-or-cast-1').
3933;;
3934;; Template types in C++ are added here too but with the template
3935;; arglist replaced with "<>" in references or "<" for the one in the
3936;; primary type. E.g. the type "Foo<A,B>::Bar<C>" is stored as
3937;; "Foo<>::Bar<". This avoids storing very long strings (since C++
3938;; template specs can be fairly sized programs in themselves) and
3939;; improves the hit ratio (it's a type regardless of the template
3940;; args; it's just not the same type, but we're only interested in
3941;; recognizing types, not telling distinct types apart). Note that
3942;; template types in references are added here too; from the example
3943;; above there will also be an entry "Foo<".
3374(defvar c-found-types nil) 3944(defvar c-found-types nil)
3375(make-variable-buffer-local 'c-found-types) 3945(make-variable-buffer-local 'c-found-types)
3376 3946
3377(defsubst c-clear-found-types () 3947(defsubst c-clear-found-types ()
3378 ;; Clears `c-found-types'. 3948 ;; Clears `c-found-types'.
3379 ;;
3380 ;; This function does not do any hidden buffer changes.
3381 (setq c-found-types (make-vector 53 0))) 3949 (setq c-found-types (make-vector 53 0)))
3382 3950
3383(defun c-add-type (from to) 3951(defun c-add-type (from to)
@@ -3389,23 +3957,20 @@ This function does not do any hidden buffer changes."
3389 ;; doesn't cover cases like when characters are removed from a type 3957 ;; doesn't cover cases like when characters are removed from a type
3390 ;; or added in the middle. We'd need the position of point when the 3958 ;; or added in the middle. We'd need the position of point when the
3391 ;; font locking is invoked to solve this well. 3959 ;; font locking is invoked to solve this well.
3392 (unless (and c-recognize-<>-arglists 3960 ;;
3393 (save-excursion 3961 ;; This function might do hidden buffer changes.
3394 (goto-char from) 3962 (let ((type (c-syntactic-content from to c-recognize-<>-arglists)))
3395 (c-syntactic-re-search-forward "<" to t))) 3963 (unless (intern-soft type c-found-types)
3396 ;; To avoid storing very long strings, do not add a type that 3964 (unintern (substring type 0 -1) c-found-types)
3397 ;; contains '<' in languages with angle bracket arglists, since 3965 (intern type c-found-types))))
3398 ;; the type then probably contains a C++ template spec and those
3399 ;; can be fairly sized programs in themselves.
3400 (let ((type (c-syntactic-content from to)))
3401 (unless (intern-soft type c-found-types)
3402 (unintern (substring type 0 -1) c-found-types)
3403 (intern type c-found-types)))))
3404 3966
3405(defsubst c-check-type (from to) 3967(defsubst c-check-type (from to)
3406 ;; Return non-nil if the given region contains a type in 3968 ;; Return non-nil if the given region contains a type in
3407 ;; `c-found-types'. 3969 ;; `c-found-types'.
3408 (intern-soft (c-syntactic-content from to) c-found-types)) 3970 ;;
3971 ;; This function might do hidden buffer changes.
3972 (intern-soft (c-syntactic-content from to c-recognize-<>-arglists)
3973 c-found-types))
3409 3974
3410(defun c-list-found-types () 3975(defun c-list-found-types ()
3411 ;; Return all the types in `c-found-types' as a sorted list of 3976 ;; Return all the types in `c-found-types' as a sorted list of
@@ -3420,17 +3985,43 @@ This function does not do any hidden buffer changes."
3420 3985
3421;; Handling of small scale constructs like types and names. 3986;; Handling of small scale constructs like types and names.
3422 3987
3423(defun c-remove-<>-arglist-properties (from to) 3988(defun c-after-change-check-<>-operators (beg end)
3424 ;; Remove all the properties put by `c-forward-<>-arglist' in the 3989 ;; This is called from `after-change-functions' when
3425 ;; specified region. Point is clobbered. 3990 ;; c-recognize-<>-arglists' is set. It ensures that no "<" or ">"
3426 (goto-char from) 3991 ;; chars with paren syntax become part of another operator like "<<"
3427 (while (progn (skip-chars-forward "^<>," to) 3992 ;; or ">=".
3428 (< (point) to)) 3993 ;;
3429 (if (eq (char-after) ?,) 3994 ;; This function might do hidden buffer changes.
3430 (when (eq (c-get-char-property (point) 'c-type) 'c-<>-arg-sep) 3995
3431 (c-clear-char-property (point) 'c-type)) 3996 (save-excursion
3432 (c-clear-char-property (point) 'syntax-table)) 3997 (goto-char beg)
3433 (forward-char))) 3998 (when (or (looking-at "[<>]")
3999 (< (skip-chars-backward "<>") 0))
4000
4001 (goto-char beg)
4002 (c-beginning-of-current-token)
4003 (when (and (< (point) beg)
4004 (looking-at c-<>-multichar-token-regexp)
4005 (< beg (setq beg (match-end 0))))
4006 (while (progn (skip-chars-forward "^<>" beg)
4007 (< (point) beg))
4008 (c-clear-char-property (point) 'syntax-table)
4009 (forward-char))))
4010
4011 (when (< beg end)
4012 (goto-char end)
4013 (when (or (looking-at "[<>]")
4014 (< (skip-chars-backward "<>") 0))
4015
4016 (goto-char end)
4017 (c-beginning-of-current-token)
4018 (when (and (< (point) end)
4019 (looking-at c-<>-multichar-token-regexp)
4020 (< end (setq end (match-end 0))))
4021 (while (progn (skip-chars-forward "^<>" end)
4022 (< (point) end))
4023 (c-clear-char-property (point) 'syntax-table)
4024 (forward-char)))))))
3434 4025
3435;; Dynamically bound variable that instructs `c-forward-type' to also 4026;; Dynamically bound variable that instructs `c-forward-type' to also
3436;; treat possible types (i.e. those that it normally returns 'maybe or 4027;; treat possible types (i.e. those that it normally returns 'maybe or
@@ -3440,6 +4031,20 @@ This function does not do any hidden buffer changes."
3440(defvar c-promote-possible-types nil) 4031(defvar c-promote-possible-types nil)
3441 4032
3442;; Dynamically bound variable that instructs `c-forward-<>-arglist' to 4033;; Dynamically bound variable that instructs `c-forward-<>-arglist' to
4034;; mark up successfully parsed arglists with paren syntax properties on
4035;; the surrounding angle brackets and with `c-<>-arg-sep' in the
4036;; `c-type' property of each argument separating comma.
4037;;
4038;; Setting this variable also makes `c-forward-<>-arglist' recurse into
4039;; all arglists for side effects (i.e. recording types), otherwise it
4040;; exploits any existing paren syntax properties to quickly jump to the
4041;; end of already parsed arglists.
4042;;
4043;; Marking up the arglists is not the default since doing that correctly
4044;; depends on a proper value for `c-restricted-<>-arglists'.
4045(defvar c-parse-and-markup-<>-arglists nil)
4046
4047;; Dynamically bound variable that instructs `c-forward-<>-arglist' to
3443;; not accept arglists that contain binary operators. 4048;; not accept arglists that contain binary operators.
3444;; 4049;;
3445;; This is primarily used to handle C++ template arglists. C++ 4050;; This is primarily used to handle C++ template arglists. C++
@@ -3455,31 +4060,36 @@ This function does not do any hidden buffer changes."
3455;; "if (a < b || c > d)", it's probably not a template. 4060;; "if (a < b || c > d)", it's probably not a template.
3456(defvar c-restricted-<>-arglists nil) 4061(defvar c-restricted-<>-arglists nil)
3457 4062
3458;; Dynamically bound variables that instructs `c-forward-name', 4063;; Dynamically bound variables that instructs
3459;; `c-forward-type' and `c-forward-<>-arglist' to record the ranges of 4064;; `c-forward-keyword-clause', `c-forward-<>-arglist',
3460;; all the type and reference identifiers they encounter. They will 4065;; `c-forward-name', `c-forward-type', `c-forward-decl-or-cast-1', and
3461;; build lists on these variables where each element is a cons of the 4066;; `c-forward-label' to record the ranges of all the type and
3462;; buffer positions surrounding each identifier. This recording is 4067;; reference identifiers they encounter. They will build lists on
3463;; only activated when `c-record-type-identifiers' is non-nil. 4068;; these variables where each element is a cons of the buffer
4069;; positions surrounding each identifier. This recording is only
4070;; activated when `c-record-type-identifiers' is non-nil.
3464;; 4071;;
3465;; All known types that can't be identifiers are recorded, and also 4072;; All known types that can't be identifiers are recorded, and also
3466;; other possible types if `c-promote-possible-types' is set. 4073;; other possible types if `c-promote-possible-types' is set.
3467;; Recording is however disabled inside angle bracket arglists that 4074;; Recording is however disabled inside angle bracket arglists that
3468;; are encountered inside names and other angle bracket arglists. 4075;; are encountered inside names and other angle bracket arglists.
3469;; Such occurences are taken care of by `c-font-lock-<>-arglists' 4076;; Such occurrences are taken care of by `c-font-lock-<>-arglists'
3470;; instead. 4077;; instead.
3471;; 4078;;
3472;; Only the names in C++ template style references (e.g. "tmpl" in 4079;; Only the names in C++ template style references (e.g. "tmpl" in
3473;; "tmpl<a,b>::foo") are recorded as references, other references 4080;; "tmpl<a,b>::foo") are recorded as references, other references
3474;; aren't handled here. 4081;; aren't handled here.
4082;;
4083;; `c-forward-label' records the label identifier(s) on
4084;; `c-record-ref-identifiers'.
3475(defvar c-record-type-identifiers nil) 4085(defvar c-record-type-identifiers nil)
3476(defvar c-record-ref-identifiers nil) 4086(defvar c-record-ref-identifiers nil)
3477 4087
3478;; If `c-record-type-identifiers' is set, this will receive a cons 4088;; This variable will receive a cons cell of the range of the last
3479;; cell of the range of the last single identifier symbol stepped over 4089;; single identifier symbol stepped over by `c-forward-name' if it's
3480;; by `c-forward-name' if it's successful. This is the range that 4090;; successful. This is the range that should be put on one of the
3481;; should be put on one of the record lists by the caller. It's 4091;; record lists above by the caller. It's assigned nil if there's no
3482;; assigned nil if there's no such symbol in the name. 4092;; such symbol in the name.
3483(defvar c-last-identifier-range nil) 4093(defvar c-last-identifier-range nil)
3484 4094
3485(defmacro c-record-type-id (range) 4095(defmacro c-record-type-id (range)
@@ -3516,45 +4126,70 @@ This function does not do any hidden buffer changes."
3516 ;; over. The point is clobbered if nil is returned. If range 4126 ;; over. The point is clobbered if nil is returned. If range
3517 ;; recording is enabled, the identifier is recorded on as a type 4127 ;; recording is enabled, the identifier is recorded on as a type
3518 ;; if TYPE is 'type or as a reference if TYPE is 'ref. 4128 ;; if TYPE is 'type or as a reference if TYPE is 'ref.
4129 ;;
4130 ;; This macro might do hidden buffer changes.
3519 `(let (res) 4131 `(let (res)
3520 (while (if (setq res ,(if (eq type 'type) 4132 (while (if (setq res ,(if (eq type 'type)
3521 `(c-forward-type) 4133 `(c-forward-type)
3522 `(c-forward-name))) 4134 `(c-forward-name)))
3523 nil 4135 nil
3524 (and (looking-at c-keywords-regexp) 4136 (and (looking-at c-keywords-regexp)
3525 (c-forward-keyword-clause)))) 4137 (c-forward-keyword-clause 1))))
3526 (when (memq res '(t known found prefix)) 4138 (when (memq res '(t known found prefix))
3527 ,(when (eq type 'ref) 4139 ,(when (eq type 'ref)
3528 `(when c-record-type-identifiers 4140 `(when c-record-type-identifiers
3529 (c-record-ref-id c-last-identifier-range))) 4141 (c-record-ref-id c-last-identifier-range)))
3530 t))) 4142 t)))
3531 4143
3532(defmacro c-forward-id-comma-list (type) 4144(defmacro c-forward-id-comma-list (type update-safe-pos)
3533 ;; Used internally in `c-forward-keyword-clause' to move forward 4145 ;; Used internally in `c-forward-keyword-clause' to move forward
3534 ;; over a comma separated list of types or names using 4146 ;; over a comma separated list of types or names using
3535 ;; `c-forward-keyword-prefixed-id'. 4147 ;; `c-forward-keyword-prefixed-id'.
4148 ;;
4149 ;; This macro might do hidden buffer changes.
3536 `(while (and (progn 4150 `(while (and (progn
3537 (setq safe-pos (point)) 4151 ,(when update-safe-pos
4152 `(setq safe-pos (point)))
3538 (eq (char-after) ?,)) 4153 (eq (char-after) ?,))
3539 (progn 4154 (progn
3540 (forward-char) 4155 (forward-char)
3541 (c-forward-syntactic-ws) 4156 (c-forward-syntactic-ws)
3542 (c-forward-keyword-prefixed-id ,type))))) 4157 (c-forward-keyword-prefixed-id ,type)))))
3543 4158
3544(defun c-forward-keyword-clause () 4159(defun c-forward-keyword-clause (match)
3545 ;; The first submatch in the current match data is assumed to 4160 ;; Submatch MATCH in the current match data is assumed to surround a
3546 ;; surround a token. If it's a keyword, move over it and any 4161 ;; token. If it's a keyword, move over it and any immediately
3547 ;; following clauses associated with it, stopping at the next 4162 ;; following clauses associated with it, stopping at the start of
3548 ;; following token. t is returned in that case, otherwise the point 4163 ;; the next token. t is returned in that case, otherwise the point
3549 ;; stays and nil is returned. The kind of clauses that are 4164 ;; stays and nil is returned. The kind of clauses that are
3550 ;; recognized are those specified by `c-type-list-kwds', 4165 ;; recognized are those specified by `c-type-list-kwds',
3551 ;; `c-ref-list-kwds', `c-colon-type-list-kwds', 4166 ;; `c-ref-list-kwds', `c-colon-type-list-kwds',
3552 ;; `c-paren-nontype-kwds', `c-paren-type-kwds', `c-<>-type-kwds', 4167 ;; `c-paren-nontype-kwds', `c-paren-type-kwds', `c-<>-type-kwds',
3553 ;; and `c-<>-arglist-kwds'. 4168 ;; and `c-<>-arglist-kwds'.
4169 ;;
4170 ;; This function records identifier ranges on
4171 ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
4172 ;; `c-record-type-identifiers' is non-nil.
4173 ;;
4174 ;; Note that for `c-colon-type-list-kwds', which doesn't necessary
4175 ;; apply directly after the keyword, the type list is moved over
4176 ;; only when there is no unaccounted token before it (i.e. a token
4177 ;; that isn't moved over due to some other keyword list). The
4178 ;; identifier ranges in the list are still recorded if that should
4179 ;; be done, though.
4180 ;;
4181 ;; This function might do hidden buffer changes.
4182
4183 (let ((kwd-sym (c-keyword-sym (match-string match))) safe-pos pos
4184 ;; The call to `c-forward-<>-arglist' below is made after
4185 ;; `c-<>-sexp-kwds' keywords, so we're certain they actually
4186 ;; are angle bracket arglists and `c-restricted-<>-arglists'
4187 ;; should therefore be nil.
4188 (c-parse-and-markup-<>-arglists t)
4189 c-restricted-<>-arglists)
3554 4190
3555 (let ((kwd-sym (c-keyword-sym (match-string 1))) safe-pos pos)
3556 (when kwd-sym 4191 (when kwd-sym
3557 (goto-char (match-end 1)) 4192 (goto-char (match-end match))
3558 (c-forward-syntactic-ws) 4193 (c-forward-syntactic-ws)
3559 (setq safe-pos (point)) 4194 (setq safe-pos (point))
3560 4195
@@ -3562,12 +4197,12 @@ This function does not do any hidden buffer changes."
3562 ((and (c-keyword-member kwd-sym 'c-type-list-kwds) 4197 ((and (c-keyword-member kwd-sym 'c-type-list-kwds)
3563 (c-forward-keyword-prefixed-id type)) 4198 (c-forward-keyword-prefixed-id type))
3564 ;; There's a type directly after a keyword in `c-type-list-kwds'. 4199 ;; There's a type directly after a keyword in `c-type-list-kwds'.
3565 (c-forward-id-comma-list type)) 4200 (c-forward-id-comma-list type t))
3566 4201
3567 ((and (c-keyword-member kwd-sym 'c-ref-list-kwds) 4202 ((and (c-keyword-member kwd-sym 'c-ref-list-kwds)
3568 (c-forward-keyword-prefixed-id ref)) 4203 (c-forward-keyword-prefixed-id ref))
3569 ;; There's a name directly after a keyword in `c-ref-list-kwds'. 4204 ;; There's a name directly after a keyword in `c-ref-list-kwds'.
3570 (c-forward-id-comma-list ref)) 4205 (c-forward-id-comma-list ref t))
3571 4206
3572 ((and (c-keyword-member kwd-sym 'c-paren-any-kwds) 4207 ((and (c-keyword-member kwd-sym 'c-paren-any-kwds)
3573 (eq (char-after) ?\()) 4208 (eq (char-after) ?\())
@@ -3592,9 +4227,7 @@ This function does not do any hidden buffer changes."
3592 4227
3593 ((and (c-keyword-member kwd-sym 'c-<>-sexp-kwds) 4228 ((and (c-keyword-member kwd-sym 'c-<>-sexp-kwds)
3594 (eq (char-after) ?<) 4229 (eq (char-after) ?<)
3595 (c-forward-<>-arglist (c-keyword-member kwd-sym 'c-<>-type-kwds) 4230 (c-forward-<>-arglist (c-keyword-member kwd-sym 'c-<>-type-kwds)))
3596 (or c-record-type-identifiers
3597 c-restricted-<>-arglists)))
3598 (c-forward-syntactic-ws) 4231 (c-forward-syntactic-ws)
3599 (setq safe-pos (point))) 4232 (setq safe-pos (point)))
3600 4233
@@ -3604,46 +4237,56 @@ This function does not do any hidden buffer changes."
3604 (c-forward-syntactic-ws) 4237 (c-forward-syntactic-ws)
3605 (setq safe-pos (point)))) 4238 (setq safe-pos (point))))
3606 4239
3607 (when (and (c-keyword-member kwd-sym 'c-colon-type-list-kwds) 4240 (when (c-keyword-member kwd-sym 'c-colon-type-list-kwds)
3608 (progn 4241 (if (eq (char-after) ?:)
3609 ;; If a keyword matched both one of the types above and 4242 ;; If we are at the colon already, we move over the type
3610 ;; this one, we match `c-colon-type-list-re' after the 4243 ;; list after it.
3611 ;; clause matched above. 4244 (progn
3612 (goto-char safe-pos) 4245 (forward-char)
3613 (looking-at c-colon-type-list-re)) 4246 (c-forward-syntactic-ws)
3614 (progn 4247 (when (c-forward-keyword-prefixed-id type)
3615 (goto-char (match-end 0)) 4248 (c-forward-id-comma-list type t)))
3616 (c-forward-syntactic-ws) 4249 ;; Not at the colon, so stop here. But the identifier
3617 (c-forward-keyword-prefixed-id type))) 4250 ;; ranges in the type list later on should still be
3618 ;; There's a type after the `c-colon-type-list-re' 4251 ;; recorded.
3619 ;; match after a keyword in `c-colon-type-list-kwds'. 4252 (and c-record-type-identifiers
3620 (c-forward-id-comma-list type)) 4253 (progn
4254 ;; If a keyword matched both one of the types above and
4255 ;; this one, we match `c-colon-type-list-re' after the
4256 ;; clause matched above.
4257 (goto-char safe-pos)
4258 (looking-at c-colon-type-list-re))
4259 (progn
4260 (goto-char (match-end 0))
4261 (c-forward-syntactic-ws)
4262 (c-forward-keyword-prefixed-id type))
4263 ;; There's a type after the `c-colon-type-list-re' match
4264 ;; after a keyword in `c-colon-type-list-kwds'.
4265 (c-forward-id-comma-list type nil))))
3621 4266
3622 (goto-char safe-pos) 4267 (goto-char safe-pos)
3623 t))) 4268 t)))
3624 4269
3625(defun c-forward-<>-arglist (all-types reparse) 4270(defun c-forward-<>-arglist (all-types)
3626 ;; The point is assumed to be at a '<'. Try to treat it as the open 4271 ;; The point is assumed to be at a "<". Try to treat it as the open
3627 ;; paren of an angle bracket arglist and move forward to the the 4272 ;; paren of an angle bracket arglist and move forward to the the
3628 ;; corresponding '>'. If successful, the point is left after the 4273 ;; corresponding ">". If successful, the point is left after the
3629 ;; '>' and t is returned, otherwise the point isn't moved and nil is 4274 ;; ">" and t is returned, otherwise the point isn't moved and nil is
3630 ;; returned. If ALL-TYPES is t then all encountered arguments in 4275 ;; returned. If ALL-TYPES is t then all encountered arguments in
3631 ;; the arglist that might be types are treated as found types. 4276 ;; the arglist that might be types are treated as found types.
3632 ;; 4277 ;;
3633 ;; The surrounding '<' and '>' are given syntax-table properties to 4278 ;; The variable `c-parse-and-markup-<>-arglists' controls how this
3634 ;; make them behave like parentheses. Each argument separating ',' 4279 ;; function handles text properties on the angle brackets and argument
3635 ;; is also set to `c-<>-arg-sep' in the `c-type' property. These 4280 ;; separating commas.
3636 ;; properties are also cleared in a relevant region forward from the
3637 ;; point if they seems to be set and it turns out to not be an
3638 ;; arglist.
3639 ;; 4281 ;;
3640 ;; If the arglist has been successfully parsed before then paren 4282 ;; `c-restricted-<>-arglists' controls how lenient the template
3641 ;; syntax properties will be exploited to quickly jump to the end, 4283 ;; arglist recognition should be.
3642 ;; but that can be disabled by setting REPARSE to t. That is 4284 ;;
3643 ;; necessary if the various side effects, e.g. recording of type 4285 ;; This function records identifier ranges on
3644 ;; ranges, are important. Setting REPARSE to t only applies 4286 ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
3645 ;; recursively to nested angle bracket arglists if 4287 ;; `c-record-type-identifiers' is non-nil.
3646 ;; `c-restricted-<>-arglists' is set. 4288 ;;
4289 ;; This function might do hidden buffer changes.
3647 4290
3648 (let ((start (point)) 4291 (let ((start (point))
3649 ;; If `c-record-type-identifiers' is set then activate 4292 ;; If `c-record-type-identifiers' is set then activate
@@ -3652,7 +4295,7 @@ This function does not do any hidden buffer changes."
3652 (c-record-found-types (if c-record-type-identifiers t))) 4295 (c-record-found-types (if c-record-type-identifiers t)))
3653 (if (catch 'angle-bracket-arglist-escape 4296 (if (catch 'angle-bracket-arglist-escape
3654 (setq c-record-found-types 4297 (setq c-record-found-types
3655 (c-forward-<>-arglist-recur all-types reparse))) 4298 (c-forward-<>-arglist-recur all-types)))
3656 (progn 4299 (progn
3657 (when (consp c-record-found-types) 4300 (when (consp c-record-found-types)
3658 (setq c-record-type-identifiers 4301 (setq c-record-type-identifiers
@@ -3664,8 +4307,10 @@ This function does not do any hidden buffer changes."
3664 (goto-char start) 4307 (goto-char start)
3665 nil))) 4308 nil)))
3666 4309
3667(defun c-forward-<>-arglist-recur (all-types reparse) 4310(defun c-forward-<>-arglist-recur (all-types)
3668 ;; Recursive part of `c-forward-<>-arglist'. 4311 ;; Recursive part of `c-forward-<>-arglist'.
4312 ;;
4313 ;; This function might do hidden buffer changes.
3669 4314
3670 (let ((start (point)) res pos tmp 4315 (let ((start (point)) res pos tmp
3671 ;; Cover this so that any recorded found type ranges are 4316 ;; Cover this so that any recorded found type ranges are
@@ -3677,61 +4322,24 @@ This function does not do any hidden buffer changes."
3677 ;; separating ',' in the arglist. 4322 ;; separating ',' in the arglist.
3678 arg-start-pos) 4323 arg-start-pos)
3679 4324
3680 ;; If the '<' has paren open syntax then we've marked it as an 4325 ;; If the '<' has paren open syntax then we've marked it as an angle
3681 ;; angle bracket arglist before, so try to skip to the end and see 4326 ;; bracket arglist before, so skip to the end.
3682 ;; that the close paren matches. 4327 (if (and (not c-parse-and-markup-<>-arglists)
3683 (if (and (c-get-char-property (point) 'syntax-table) 4328 (c-get-char-property (point) 'syntax-table))
3684 (progn 4329
3685 (forward-char) 4330 (progn
3686 (if (and (not (looking-at c-<-op-cont-regexp)) 4331 (forward-char)
3687 (if (c-parse-sexp-lookup-properties) 4332 (if (and (c-go-up-list-forward)
3688 (c-go-up-list-forward) 4333 (eq (char-before) ?>))
3689 (catch 'at-end 4334 t
3690 (let ((depth 1)) 4335
3691 (while (c-syntactic-re-search-forward 4336 ;; Got unmatched paren angle brackets. We don't clear the paren
3692 "[<>]" nil t t) 4337 ;; syntax properties and retry, on the basis that it's very
3693 (when (c-get-char-property (1- (point)) 4338 ;; unlikely that paren angle brackets become operators by code
3694 'syntax-table) 4339 ;; manipulation. It's far more likely that it doesn't match due
3695 (if (eq (char-before) ?<) 4340 ;; to narrowing or some temporary change.
3696 (setq depth (1+ depth)) 4341 (goto-char start)
3697 (setq depth (1- depth)) 4342 nil))
3698 (when (= depth 0) (throw 'at-end t)))))
3699 nil)))
3700 (not (looking-at c->-op-cont-regexp))
3701 (save-excursion
3702 (backward-char)
3703 (= (point)
3704 (progn (c-beginning-of-current-token)
3705 (point)))))
3706
3707 ;; Got an arglist that appears to be valid.
3708 (if reparse
3709 ;; Reparsing is requested, so zap the properties in the
3710 ;; region and go on to redo it. It's done here to
3711 ;; avoid leaving it behind if we exit through
3712 ;; `angle-bracket-arglist-escape' below.
3713 (progn
3714 (c-remove-<>-arglist-properties start (point))
3715 (goto-char start)
3716 nil)
3717 t)
3718
3719 ;; Got unmatched paren brackets or either paren was
3720 ;; actually some other token. Recover by clearing the
3721 ;; syntax properties on all the '<' and '>' in the
3722 ;; range where we'll search for the arglist below.
3723 (goto-char start)
3724 (while (progn (skip-chars-forward "^<>,;{}")
3725 (looking-at "[<>,]"))
3726 (if (eq (char-after) ?,)
3727 (when (eq (c-get-char-property (point) 'c-type)
3728 'c-<>-arg-sep)
3729 (c-clear-char-property (point) 'c-type))
3730 (c-clear-char-property (point) 'syntax-table))
3731 (forward-char))
3732 (goto-char start)
3733 nil)))
3734 t
3735 4343
3736 (forward-char) 4344 (forward-char)
3737 (unless (looking-at c-<-op-cont-regexp) 4345 (unless (looking-at c-<-op-cont-regexp)
@@ -3793,11 +4401,6 @@ This function does not do any hidden buffer changes."
3793 ;; balanced sexp. In that case we stop just short 4401 ;; balanced sexp. In that case we stop just short
3794 ;; of it so check if the following char is the closer. 4402 ;; of it so check if the following char is the closer.
3795 (when (eq (char-after) ?>) 4403 (when (eq (char-after) ?>)
3796 ;; Remove its syntax so that we don't enter the
3797 ;; recovery code below. That's not necessary
3798 ;; since there's no real reason to suspect that
3799 ;; things inside the arglist are unbalanced.
3800 (c-clear-char-property (point) 'syntax-table)
3801 (forward-char) 4404 (forward-char)
3802 t))) 4405 t)))
3803 4406
@@ -3806,40 +4409,21 @@ This function does not do any hidden buffer changes."
3806 ;; Either an operator starting with '>' or the end of 4409 ;; Either an operator starting with '>' or the end of
3807 ;; the angle bracket arglist. 4410 ;; the angle bracket arglist.
3808 4411
3809 (if (and (/= (1- (point)) pos) 4412 (if (looking-at c->-op-cont-regexp)
3810 (c-get-char-property (1- (point)) 'syntax-table)
3811 (progn
3812 (c-clear-char-property (1- (point)) 'syntax-table)
3813 (c-parse-sexp-lookup-properties)))
3814
3815 ;; We've skipped past a list that ended with '>'. It
3816 ;; must be unbalanced since nested arglists are handled
3817 ;; in the case below. Recover by removing all paren
3818 ;; properties on '<' and '>' in the searched region and
3819 ;; redo the search.
3820 (progn 4413 (progn
3821 (c-remove-<>-arglist-properties pos (point)) 4414 (goto-char (match-end 0))
3822 (goto-char pos) 4415 t) ; Continue the loop.
3823 t)
3824 4416
3825 (if (looking-at c->-op-cont-regexp) 4417 ;; The angle bracket arglist is finished.
3826 (progn 4418 (when c-parse-and-markup-<>-arglists
3827 (when (text-property-not-all
3828 (1- (point)) (match-end 0) 'syntax-table nil)
3829 (c-remove-<>-arglist-properties (1- (point))
3830 (match-end 0)))
3831 (goto-char (match-end 0))
3832 t)
3833
3834 ;; The angle bracket arglist is finished.
3835 (while arg-start-pos 4419 (while arg-start-pos
3836 (c-put-char-property (1- (car arg-start-pos)) 4420 (c-put-c-type-property (1- (car arg-start-pos))
3837 'c-type 'c-<>-arg-sep) 4421 'c-<>-arg-sep)
3838 (setq arg-start-pos (cdr arg-start-pos))) 4422 (setq arg-start-pos (cdr arg-start-pos)))
3839 (c-mark-<-as-paren start) 4423 (c-mark-<-as-paren start)
3840 (c-mark->-as-paren (1- (point))) 4424 (c-mark->-as-paren (1- (point))))
3841 (setq res t) 4425 (setq res t)
3842 nil))) 4426 nil)) ; Exit the loop.
3843 4427
3844 ((eq (char-before) ?<) 4428 ((eq (char-before) ?<)
3845 ;; Either an operator starting with '<' or a nested arglist. 4429 ;; Either an operator starting with '<' or a nested arglist.
@@ -3854,7 +4438,7 @@ This function does not do any hidden buffer changes."
3854 (and 4438 (and
3855 4439
3856 (save-excursion 4440 (save-excursion
3857 ;; There's always an identifier before a angle 4441 ;; There's always an identifier before an angle
3858 ;; bracket arglist, or a keyword in 4442 ;; bracket arglist, or a keyword in
3859 ;; `c-<>-type-kwds' or `c-<>-arglist-kwds'. 4443 ;; `c-<>-type-kwds' or `c-<>-arglist-kwds'.
3860 (c-backward-syntactic-ws) 4444 (c-backward-syntactic-ws)
@@ -3872,26 +4456,11 @@ This function does not do any hidden buffer changes."
3872 (and keyword-match 4456 (and keyword-match
3873 (c-keyword-member 4457 (c-keyword-member
3874 (c-keyword-sym (match-string 1)) 4458 (c-keyword-sym (match-string 1))
3875 'c-<>-type-kwds)) 4459 'c-<>-type-kwds)))))
3876 (and reparse
3877 c-restricted-<>-arglists))))
3878 ))) 4460 )))
3879 4461
3880 ;; It was not an angle bracket arglist. 4462 ;; It was not an angle bracket arglist.
3881 (progn 4463 (goto-char tmp)
3882 (when (text-property-not-all
3883 (1- pos) tmp 'syntax-table nil)
3884 (if (c-parse-sexp-lookup-properties)
3885 ;; Got an invalid open paren syntax on this
3886 ;; '<'. We'll probably get an unbalanced '>'
3887 ;; further ahead if we just remove the syntax
3888 ;; here, so recover by removing all paren
3889 ;; properties up to and including the
3890 ;; balancing close paren.
3891 (parse-partial-sexp pos (point-max) -1)
3892 (goto-char tmp))
3893 (c-remove-<>-arglist-properties pos (point)))
3894 (goto-char tmp))
3895 4464
3896 ;; It was an angle bracket arglist. 4465 ;; It was an angle bracket arglist.
3897 (setq c-record-found-types subres) 4466 (setq c-record-found-types subres)
@@ -3926,6 +4495,70 @@ This function does not do any hidden buffer changes."
3926 (if res 4495 (if res
3927 (or c-record-found-types t))))) 4496 (or c-record-found-types t)))))
3928 4497
4498(defun c-backward-<>-arglist (all-types &optional limit)
4499 ;; The point is assumed to be directly after a ">". Try to treat it
4500 ;; as the close paren of an angle bracket arglist and move back to
4501 ;; the corresponding "<". If successful, the point is left at
4502 ;; the "<" and t is returned, otherwise the point isn't moved and
4503 ;; nil is returned. ALL-TYPES is passed on to
4504 ;; `c-forward-<>-arglist'.
4505 ;;
4506 ;; If the optional LIMIT is given, it bounds the backward search.
4507 ;; It's then assumed to be at a syntactically relevant position.
4508 ;;
4509 ;; This is a wrapper around `c-forward-<>-arglist'. See that
4510 ;; function for more details.
4511
4512 (let ((start (point)))
4513 (backward-char)
4514 (if (and (not c-parse-and-markup-<>-arglists)
4515 (c-get-char-property (point) 'syntax-table))
4516
4517 (if (and (c-go-up-list-backward)
4518 (eq (char-after) ?<))
4519 t
4520 ;; See corresponding note in `c-forward-<>-arglist'.
4521 (goto-char start)
4522 nil)
4523
4524 (while (and
4525 (c-syntactic-skip-backward "^<;{}" limit t)
4526
4527 (if (eq (char-before) ?<)
4528 t
4529 ;; Stopped at bob or a char that isn't allowed in an
4530 ;; arglist, so we've failed.
4531 (goto-char start)
4532 nil)
4533
4534 (if (> (point)
4535 (progn (c-beginning-of-current-token)
4536 (point)))
4537 ;; If we moved then the "<" was part of some
4538 ;; multicharacter token.
4539 t
4540
4541 (backward-char)
4542 (let ((beg-pos (point)))
4543 (if (c-forward-<>-arglist all-types)
4544 (cond ((= (point) start)
4545 ;; Matched the arglist. Break the while.
4546 (goto-char beg-pos)
4547 nil)
4548 ((> (point) start)
4549 ;; We started from a non-paren ">" inside an
4550 ;; arglist.
4551 (goto-char start)
4552 nil)
4553 (t
4554 ;; Matched a shorter arglist. Can be a nested
4555 ;; one so continue looking.
4556 (goto-char beg-pos)
4557 t))
4558 t)))))
4559
4560 (/= (point) start))))
4561
3929(defun c-forward-name () 4562(defun c-forward-name ()
3930 ;; Move forward over a complete name if at the beginning of one, 4563 ;; Move forward over a complete name if at the beginning of one,
3931 ;; stopping at the next following token. If the point is not at 4564 ;; stopping at the next following token. If the point is not at
@@ -3939,8 +4572,14 @@ This function does not do any hidden buffer changes."
3939 ;; name is found, 'template if it's an identifier ending with an 4572 ;; name is found, 'template if it's an identifier ending with an
3940 ;; angle bracket arglist, 'operator of it's an operator identifier, 4573 ;; angle bracket arglist, 'operator of it's an operator identifier,
3941 ;; or t if it's some other kind of name. 4574 ;; or t if it's some other kind of name.
4575 ;;
4576 ;; This function records identifier ranges on
4577 ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
4578 ;; `c-record-type-identifiers' is non-nil.
4579 ;;
4580 ;; This function might do hidden buffer changes.
3942 4581
3943 (let ((pos (point)) res id-start id-end 4582 (let ((pos (point)) (start (point)) res id-start id-end
3944 ;; Turn off `c-promote-possible-types' here since we might 4583 ;; Turn off `c-promote-possible-types' here since we might
3945 ;; call `c-forward-<>-arglist' and we don't want it to promote 4584 ;; call `c-forward-<>-arglist' and we don't want it to promote
3946 ;; every suspect thing in the arglist to a type. We're 4585 ;; every suspect thing in the arglist to a type. We're
@@ -3955,12 +4594,9 @@ This function does not do any hidden buffer changes."
3955 (progn 4594 (progn
3956 ;; Check for keyword. We go to the last symbol in 4595 ;; Check for keyword. We go to the last symbol in
3957 ;; `c-identifier-key' first. 4596 ;; `c-identifier-key' first.
3958 (if (eq c-identifier-key c-symbol-key) 4597 (goto-char (setq id-end (match-end 0)))
3959 (setq id-start (point) 4598 (c-simple-skip-symbol-backward)
3960 id-end (match-end 0)) 4599 (setq id-start (point))
3961 (goto-char (setq id-end (match-end 0)))
3962 (c-simple-skip-symbol-backward)
3963 (setq id-start (point)))
3964 4600
3965 (if (looking-at c-keywords-regexp) 4601 (if (looking-at c-keywords-regexp)
3966 (when (and (c-major-mode-is 'c++-mode) 4602 (when (and (c-major-mode-is 'c++-mode)
@@ -4018,9 +4654,8 @@ This function does not do any hidden buffer changes."
4018 4654
4019 ((looking-at c-overloadable-operators-regexp) 4655 ((looking-at c-overloadable-operators-regexp)
4020 ;; Got some other operator. 4656 ;; Got some other operator.
4021 (when c-record-type-identifiers 4657 (setq c-last-identifier-range
4022 (setq c-last-identifier-range 4658 (cons (point) (match-end 0)))
4023 (cons (point) (match-end 0))))
4024 (goto-char (match-end 0)) 4659 (goto-char (match-end 0))
4025 (c-forward-syntactic-ws) 4660 (c-forward-syntactic-ws)
4026 (setq pos (point) 4661 (setq pos (point)
@@ -4028,7 +4663,11 @@ This function does not do any hidden buffer changes."
4028 4663
4029 nil) 4664 nil)
4030 4665
4031 (when c-record-type-identifiers 4666 ;; `id-start' is equal to `id-end' if we've jumped over
4667 ;; an identifier that doesn't end with a symbol token.
4668 ;; That can occur e.g. for Java import directives on the
4669 ;; form "foo.bar.*".
4670 (when (and id-start (/= id-start id-end))
4032 (setq c-last-identifier-range 4671 (setq c-last-identifier-range
4033 (cons id-start id-end))) 4672 (cons id-start id-end)))
4034 (goto-char id-end) 4673 (goto-char id-end)
@@ -4054,29 +4693,30 @@ This function does not do any hidden buffer changes."
4054 ((and c-recognize-<>-arglists 4693 ((and c-recognize-<>-arglists
4055 (eq (char-after) ?<)) 4694 (eq (char-after) ?<))
4056 ;; Maybe an angle bracket arglist. 4695 ;; Maybe an angle bracket arglist.
4057 (when (let ((c-record-type-identifiers nil) 4696
4058 (c-record-found-types nil)) 4697 (when (let (c-record-type-identifiers
4059 (c-forward-<>-arglist 4698 c-record-found-types)
4060 nil c-restricted-<>-arglists)) 4699 (c-forward-<>-arglist nil))
4700
4701 (c-add-type start (1+ pos))
4061 (c-forward-syntactic-ws) 4702 (c-forward-syntactic-ws)
4062 (setq pos (point)) 4703 (setq pos (point)
4704 c-last-identifier-range nil)
4705
4063 (if (and c-opt-identifier-concat-key 4706 (if (and c-opt-identifier-concat-key
4064 (looking-at c-opt-identifier-concat-key)) 4707 (looking-at c-opt-identifier-concat-key))
4708
4065 ;; Continue if there's an identifier concatenation 4709 ;; Continue if there's an identifier concatenation
4066 ;; operator after the template argument. 4710 ;; operator after the template argument.
4067 (progn 4711 (progn
4068 (when c-record-type-identifiers 4712 (when (and c-record-type-identifiers id-start)
4069 (c-record-ref-id (cons id-start id-end)) 4713 (c-record-ref-id (cons id-start id-end)))
4070 (setq c-last-identifier-range nil))
4071 (forward-char 2) 4714 (forward-char 2)
4072 (c-forward-syntactic-ws) 4715 (c-forward-syntactic-ws)
4073 t) 4716 t)
4074 ;; `c-add-type' isn't called here since we don't 4717
4075 ;; want to add types containing angle bracket 4718 (when (and c-record-type-identifiers id-start)
4076 ;; arglists. 4719 (c-record-type-id (cons id-start id-end)))
4077 (when c-record-type-identifiers
4078 (c-record-type-id (cons id-start id-end))
4079 (setq c-last-identifier-range nil))
4080 (setq res 'template) 4720 (setq res 'template)
4081 nil))) 4721 nil)))
4082 ))))) 4722 )))))
@@ -4098,7 +4738,14 @@ This function does not do any hidden buffer changes."
4098 ;; Note that this function doesn't skip past the brace definition 4738 ;; Note that this function doesn't skip past the brace definition
4099 ;; that might be considered part of the type, e.g. 4739 ;; that might be considered part of the type, e.g.
4100 ;; "enum {a, b, c} foo". 4740 ;; "enum {a, b, c} foo".
4101 (let ((start (point)) pos res res2 id-start id-end id-range) 4741 ;;
4742 ;; This function records identifier ranges on
4743 ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
4744 ;; `c-record-type-identifiers' is non-nil.
4745 ;;
4746 ;; This function might do hidden buffer changes.
4747
4748 (let ((start (point)) pos res name-res id-start id-end id-range)
4102 4749
4103 ;; Skip leading type modifiers. If any are found we know it's a 4750 ;; Skip leading type modifiers. If any are found we know it's a
4104 ;; prefix of a type. 4751 ;; prefix of a type.
@@ -4115,13 +4762,14 @@ This function does not do any hidden buffer changes."
4115 (goto-char (match-end 1)) 4762 (goto-char (match-end 1))
4116 (c-forward-syntactic-ws) 4763 (c-forward-syntactic-ws)
4117 (setq pos (point)) 4764 (setq pos (point))
4118 (if (memq (setq res2 (c-forward-name)) '(t template)) 4765 (if (memq (setq name-res (c-forward-name)) '(t template))
4119 (progn 4766 (progn
4120 (when (eq res2 t) 4767 (when (eq name-res t)
4121 ;; In many languages the name can be used without the 4768 ;; In many languages the name can be used without the
4122 ;; prefix, so we add it to `c-found-types'. 4769 ;; prefix, so we add it to `c-found-types'.
4123 (c-add-type pos (point)) 4770 (c-add-type pos (point))
4124 (when c-record-type-identifiers 4771 (when (and c-record-type-identifiers
4772 c-last-identifier-range)
4125 (c-record-type-id c-last-identifier-range))) 4773 (c-record-type-id c-last-identifier-range)))
4126 (setq res t)) 4774 (setq res t))
4127 ;; Invalid syntax. 4775 ;; Invalid syntax.
@@ -4133,8 +4781,8 @@ This function does not do any hidden buffer changes."
4133 (if (looking-at c-identifier-start) 4781 (if (looking-at c-identifier-start)
4134 (save-excursion 4782 (save-excursion
4135 (setq id-start (point) 4783 (setq id-start (point)
4136 res2 (c-forward-name)) 4784 name-res (c-forward-name))
4137 (when res2 4785 (when name-res
4138 (setq id-end (point) 4786 (setq id-end (point)
4139 id-range c-last-identifier-range)))) 4787 id-range c-last-identifier-range))))
4140 (and (cond ((looking-at c-primitive-type-key) 4788 (and (cond ((looking-at c-primitive-type-key)
@@ -4165,7 +4813,7 @@ This function does not do any hidden buffer changes."
4165 (looking-at c-opt-type-component-key))) 4813 (looking-at c-opt-type-component-key)))
4166 ;; There might be more keywords for the type. 4814 ;; There might be more keywords for the type.
4167 (let (safe-pos) 4815 (let (safe-pos)
4168 (c-forward-keyword-clause) 4816 (c-forward-keyword-clause 1)
4169 (while (progn 4817 (while (progn
4170 (setq safe-pos (point)) 4818 (setq safe-pos (point))
4171 (looking-at c-opt-type-component-key)) 4819 (looking-at c-opt-type-component-key))
@@ -4173,30 +4821,30 @@ This function does not do any hidden buffer changes."
4173 (looking-at c-primitive-type-key)) 4821 (looking-at c-primitive-type-key))
4174 (c-record-type-id (cons (match-beginning 1) 4822 (c-record-type-id (cons (match-beginning 1)
4175 (match-end 1)))) 4823 (match-end 1))))
4176 (c-forward-keyword-clause)) 4824 (c-forward-keyword-clause 1))
4177 (if (looking-at c-primitive-type-key) 4825 (if (looking-at c-primitive-type-key)
4178 (progn 4826 (progn
4179 (when c-record-type-identifiers 4827 (when c-record-type-identifiers
4180 (c-record-type-id (cons (match-beginning 1) 4828 (c-record-type-id (cons (match-beginning 1)
4181 (match-end 1)))) 4829 (match-end 1))))
4182 (c-forward-keyword-clause) 4830 (c-forward-keyword-clause 1)
4183 (setq res t)) 4831 (setq res t))
4184 (goto-char safe-pos) 4832 (goto-char safe-pos)
4185 (setq res 'prefix))) 4833 (setq res 'prefix)))
4186 (unless (save-match-data (c-forward-keyword-clause)) 4834 (unless (save-match-data (c-forward-keyword-clause 1))
4187 (if pos 4835 (if pos
4188 (goto-char pos) 4836 (goto-char pos)
4189 (goto-char (match-end 1)) 4837 (goto-char (match-end 1))
4190 (c-forward-syntactic-ws))))) 4838 (c-forward-syntactic-ws)))))
4191 4839
4192 (res2 4840 (name-res
4193 (cond ((eq res2 t) 4841 (cond ((eq name-res t)
4194 ;; A normal identifier. 4842 ;; A normal identifier.
4195 (goto-char id-end) 4843 (goto-char id-end)
4196 (if (or res c-promote-possible-types) 4844 (if (or res c-promote-possible-types)
4197 (progn 4845 (progn
4198 (c-add-type id-start id-end) 4846 (c-add-type id-start id-end)
4199 (when c-record-type-identifiers 4847 (when (and c-record-type-identifiers id-range)
4200 (c-record-type-id id-range)) 4848 (c-record-type-id id-range))
4201 (unless res 4849 (unless res
4202 (setq res 'found))) 4850 (setq res 'found)))
@@ -4206,7 +4854,7 @@ This function does not do any hidden buffer changes."
4206 'found 4854 'found
4207 ;; It's an identifier that might be a type. 4855 ;; It's an identifier that might be a type.
4208 'maybe)))) 4856 'maybe))))
4209 ((eq res2 'template) 4857 ((eq name-res 'template)
4210 ;; A template is a type. 4858 ;; A template is a type.
4211 (goto-char id-end) 4859 (goto-char id-end)
4212 (setq res t)) 4860 (setq res t))
@@ -4234,9 +4882,11 @@ This function does not do any hidden buffer changes."
4234 (c-forward-syntactic-ws))) 4882 (c-forward-syntactic-ws)))
4235 4883
4236 (when c-opt-type-concat-key 4884 (when c-opt-type-concat-key
4237 ;; Look for a trailing operator that concatenate the type with 4885 ;; Look for a trailing operator that concatenates the type
4238 ;; a following one, and if so step past that one through a 4886 ;; with a following one, and if so step past that one through
4239 ;; recursive call. 4887 ;; a recursive call. Note that we don't record concatenated
4888 ;; types in `c-found-types' - it's the component types that
4889 ;; are recorded when appropriate.
4240 (setq pos (point)) 4890 (setq pos (point))
4241 (let* ((c-promote-possible-types (or (memq res '(t known)) 4891 (let* ((c-promote-possible-types (or (memq res '(t known))
4242 c-promote-possible-types)) 4892 c-promote-possible-types))
@@ -4244,29 +4894,31 @@ This function does not do any hidden buffer changes."
4244 ;; we can merge in the types from the second part afterwards if 4894 ;; we can merge in the types from the second part afterwards if
4245 ;; it turns out to be a known type there. 4895 ;; it turns out to be a known type there.
4246 (c-record-found-types (and c-record-type-identifiers 4896 (c-record-found-types (and c-record-type-identifiers
4247 (not c-promote-possible-types)))) 4897 (not c-promote-possible-types)))
4898 subres)
4248 (if (and (looking-at c-opt-type-concat-key) 4899 (if (and (looking-at c-opt-type-concat-key)
4249 4900
4250 (progn 4901 (progn
4251 (goto-char (match-end 1)) 4902 (goto-char (match-end 1))
4252 (c-forward-syntactic-ws) 4903 (c-forward-syntactic-ws)
4253 (setq res2 (c-forward-type)))) 4904 (setq subres (c-forward-type))))
4254 4905
4255 (progn 4906 (progn
4256 ;; If either operand certainly is a type then both are, but we 4907 ;; If either operand certainly is a type then both are, but we
4257 ;; don't let the existence of the operator itself promote two 4908 ;; don't let the existence of the operator itself promote two
4258 ;; uncertain types to a certain one. 4909 ;; uncertain types to a certain one.
4259 (cond ((eq res t)) 4910 (cond ((eq res t))
4260 ((eq res2 t) 4911 ((eq subres t)
4261 (c-add-type id-start id-end) 4912 (unless (eq name-res 'template)
4262 (when c-record-type-identifiers 4913 (c-add-type id-start id-end))
4914 (when (and c-record-type-identifiers id-range)
4263 (c-record-type-id id-range)) 4915 (c-record-type-id id-range))
4264 (setq res t)) 4916 (setq res t))
4265 ((eq res 'known)) 4917 ((eq res 'known))
4266 ((eq res2 'known) 4918 ((eq subres 'known)
4267 (setq res 'known)) 4919 (setq res 'known))
4268 ((eq res 'found)) 4920 ((eq res 'found))
4269 ((eq res2 'found) 4921 ((eq subres 'found)
4270 (setq res 'found)) 4922 (setq res 'found))
4271 (t 4923 (t
4272 (setq res 'maybe))) 4924 (setq res 'maybe)))
@@ -4294,23 +4946,1099 @@ This function does not do any hidden buffer changes."
4294 4946
4295;; Handling of large scale constructs like statements and declarations. 4947;; Handling of large scale constructs like statements and declarations.
4296 4948
4949;; Macro used inside `c-forward-decl-or-cast-1'. It ought to be a
4950;; defsubst or perhaps even a defun, but it contains lots of free
4951;; variables that refer to things inside `c-forward-decl-or-cast-1'.
4952(defmacro c-fdoc-shift-type-backward (&optional short)
4953 ;; `c-forward-decl-or-cast-1' can consume an arbitrary length list
4954 ;; of types when parsing a declaration, which means that it
4955 ;; sometimes consumes the identifier in the declaration as a type.
4956 ;; This is used to "backtrack" and make the last type be treated as
4957 ;; an identifier instead.
4958 `(progn
4959 ,(unless short
4960 ;; These identifiers are bound only in the inner let.
4961 '(setq identifier-type at-type
4962 identifier-start type-start
4963 got-parens nil
4964 got-identifier t
4965 got-suffix t
4966 got-suffix-after-parens id-start
4967 paren-depth 0))
4968
4969 (if (setq at-type (if (eq backup-at-type 'prefix)
4970 t
4971 backup-at-type))
4972 (setq type-start backup-type-start
4973 id-start backup-id-start)
4974 (setq type-start start-pos
4975 id-start start-pos))
4976
4977 ;; When these flags already are set we've found specifiers that
4978 ;; unconditionally signal these attributes - backtracking doesn't
4979 ;; change that. So keep them set in that case.
4980 (or at-type-decl
4981 (setq at-type-decl backup-at-type-decl))
4982 (or maybe-typeless
4983 (setq maybe-typeless backup-maybe-typeless))
4984
4985 ,(unless short
4986 ;; This identifier is bound only in the inner let.
4987 '(setq start id-start))))
4988
4989(defun c-forward-decl-or-cast-1 (preceding-token-end context last-cast-end)
4990 ;; Move forward over a declaration or a cast if at the start of one.
4991 ;; The point is assumed to be at the start of some token. Nil is
4992 ;; returned if no declaration or cast is recognized, and the point
4993 ;; is clobbered in that case.
4994 ;;
4995 ;; If a declaration is parsed:
4996 ;;
4997 ;; The point is left at the first token after the first complete
4998 ;; declarator, if there is one. The return value is a cons where
4999 ;; the car is the position of the first token in the declarator.
5000 ;; Some examples:
5001 ;;
5002 ;; void foo (int a, char *b) stuff ...
5003 ;; car ^ ^ point
5004 ;; float (*a)[], b;
5005 ;; car ^ ^ point
5006 ;; unsigned int a = c_style_initializer, b;
5007 ;; car ^ ^ point
5008 ;; unsigned int a (cplusplus_style_initializer), b;
5009 ;; car ^ ^ point (might change)
5010 ;; class Foo : public Bar {}
5011 ;; car ^ ^ point
5012 ;; class PikeClass (int a, string b) stuff ...
5013 ;; car ^ ^ point
5014 ;; enum bool;
5015 ;; car ^ ^ point
5016 ;; enum bool flag;
5017 ;; car ^ ^ point
5018 ;; void cplusplus_function (int x) throw (Bad);
5019 ;; car ^ ^ point
5020 ;; Foo::Foo (int b) : Base (b) {}
5021 ;; car ^ ^ point
5022 ;;
5023 ;; The cdr of the return value is non-nil iff a
5024 ;; `c-typedef-decl-kwds' specifier is found in the declaration,
5025 ;; i.e. the declared identifier(s) are types.
5026 ;;
5027 ;; If a cast is parsed:
5028 ;;
5029 ;; The point is left at the first token after the closing paren of
5030 ;; the cast. The return value is `cast'. Note that the start
5031 ;; position must be at the first token inside the cast parenthesis
5032 ;; to recognize it.
5033 ;;
5034 ;; PRECEDING-TOKEN-END is the first position after the preceding
5035 ;; token, i.e. on the other side of the syntactic ws from the point.
5036 ;; Use a value less than or equal to (point-min) if the point is at
5037 ;; the first token in (the visible part of) the buffer.
5038 ;;
5039 ;; CONTEXT is a symbol that describes the context at the point:
5040 ;; 'decl In a comma-separatded declaration context (typically
5041 ;; inside a function declaration arglist).
5042 ;; '<> In an angle bracket arglist.
5043 ;; 'arglist Some other type of arglist.
5044 ;; nil Some other context or unknown context.
5045 ;;
5046 ;; LAST-CAST-END is the first token after the closing paren of a
5047 ;; preceding cast, or nil if none is known. If
5048 ;; `c-forward-decl-or-cast-1' is used in succession, it should be
5049 ;; the position after the closest preceding call where a cast was
5050 ;; matched. In that case it's used to discover chains of casts like
5051 ;; "(a) (b) c".
5052 ;;
5053 ;; This function records identifier ranges on
5054 ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
5055 ;; `c-record-type-identifiers' is non-nil.
5056 ;;
5057 ;; This function might do hidden buffer changes.
5058
5059 (let (;; `start-pos' is used below to point to the start of the
5060 ;; first type, i.e. after any leading specifiers. It might
5061 ;; also point at the beginning of the preceding syntactic
5062 ;; whitespace.
5063 (start-pos (point))
5064 ;; Set to the result of `c-forward-type'.
5065 at-type
5066 ;; The position of the first token in what we currently
5067 ;; believe is the type in the declaration or cast, after any
5068 ;; specifiers and their associated clauses.
5069 type-start
5070 ;; The position of the first token in what we currently
5071 ;; believe is the declarator for the first identifier. Set
5072 ;; when the type is found, and moved forward over any
5073 ;; `c-decl-hangon-kwds' and their associated clauses that
5074 ;; occurs after the type.
5075 id-start
5076 ;; These store `at-type', `type-start' and `id-start' of the
5077 ;; identifier before the one in those variables. The previous
5078 ;; identifier might turn out to be the real type in a
5079 ;; declaration if the last one has to be the declarator in it.
5080 ;; If `backup-at-type' is nil then the other variables have
5081 ;; undefined values.
5082 backup-at-type backup-type-start backup-id-start
5083 ;; Set if we've found a specifier that makes the defined
5084 ;; identifier(s) types.
5085 at-type-decl
5086 ;; Set if we've found a specifier that can start a declaration
5087 ;; where there's no type.
5088 maybe-typeless
5089 ;; If a specifier is found that also can be a type prefix,
5090 ;; these flags are set instead of those above. If we need to
5091 ;; back up an identifier, they are copied to the real flag
5092 ;; variables. Thus they only take effect if we fail to
5093 ;; interpret it as a type.
5094 backup-at-type-decl backup-maybe-typeless
5095 ;; Whether we've found a declaration or a cast. We might know
5096 ;; this before we've found the type in it. It's 'ids if we've
5097 ;; found two consecutive identifiers (usually a sure sign, but
5098 ;; we should allow that in labels too), and t if we've found a
5099 ;; specifier keyword (a 100% sure sign).
5100 at-decl-or-cast
5101 ;; Set when we need to back up to parse this as a declaration
5102 ;; but not as a cast.
5103 backup-if-not-cast
5104 ;; For casts, the return position.
5105 cast-end
5106 ;; Save `c-record-type-identifiers' and
5107 ;; `c-record-ref-identifiers' since ranges are recorded
5108 ;; speculatively and should be thrown away if it turns out
5109 ;; that it isn't a declaration or cast.
5110 (save-rec-type-ids c-record-type-identifiers)
5111 (save-rec-ref-ids c-record-ref-identifiers))
5112
5113 ;; Check for a type. Unknown symbols are treated as possible
5114 ;; types, but they could also be specifiers disguised through
5115 ;; macros like __INLINE__, so we recognize both types and known
5116 ;; specifiers after them too.
5117 (while
5118 (let* ((start (point)) kwd-sym kwd-clause-end found-type)
5119
5120 ;; Look for a specifier keyword clause.
5121 (when (looking-at c-prefix-spec-kwds-re)
5122 (setq kwd-sym (c-keyword-sym (match-string 1)))
5123 (save-excursion
5124 (c-forward-keyword-clause 1)
5125 (setq kwd-clause-end (point))))
5126
5127 (when (setq found-type (c-forward-type))
5128 ;; Found a known or possible type or a prefix of a known type.
5129
5130 (when at-type
5131 ;; Got two identifiers with nothing but whitespace
5132 ;; between them. That can only happen in declarations.
5133 (setq at-decl-or-cast 'ids)
5134
5135 (when (eq at-type 'found)
5136 ;; If the previous identifier is a found type we
5137 ;; record it as a real one; it might be some sort of
5138 ;; alias for a prefix like "unsigned".
5139 (save-excursion
5140 (goto-char type-start)
5141 (let ((c-promote-possible-types t))
5142 (c-forward-type)))))
5143
5144 (setq backup-at-type at-type
5145 backup-type-start type-start
5146 backup-id-start id-start
5147 at-type found-type
5148 type-start start
5149 id-start (point)
5150 ;; The previous ambiguous specifier/type turned out
5151 ;; to be a type since we've parsed another one after
5152 ;; it, so clear these backup flags.
5153 backup-at-type-decl nil
5154 backup-maybe-typeless nil))
5155
5156 (if kwd-sym
5157 (progn
5158 ;; Handle known specifier keywords and
5159 ;; `c-decl-hangon-kwds' which can occur after known
5160 ;; types.
5161
5162 (if (c-keyword-member kwd-sym 'c-decl-hangon-kwds)
5163 ;; It's a hang-on keyword that can occur anywhere.
5164 (progn
5165 (setq at-decl-or-cast t)
5166 (if at-type
5167 ;; Move the identifier start position if
5168 ;; we've passed a type.
5169 (setq id-start kwd-clause-end)
5170 ;; Otherwise treat this as a specifier and
5171 ;; move the fallback position.
5172 (setq start-pos kwd-clause-end))
5173 (goto-char kwd-clause-end))
5174
5175 ;; It's an ordinary specifier so we know that
5176 ;; anything before this can't be the type.
5177 (setq backup-at-type nil
5178 start-pos kwd-clause-end)
5179
5180 (if found-type
5181 ;; It's ambiguous whether this keyword is a
5182 ;; specifier or a type prefix, so set the backup
5183 ;; flags. (It's assumed that `c-forward-type'
5184 ;; moved further than `c-forward-keyword-clause'.)
5185 (progn
5186 (when (c-keyword-member kwd-sym 'c-typedef-decl-kwds)
5187 (setq backup-at-type-decl t))
5188 (when (c-keyword-member kwd-sym 'c-typeless-decl-kwds)
5189 (setq backup-maybe-typeless t)))
5190
5191 (when (c-keyword-member kwd-sym 'c-typedef-decl-kwds)
5192 (setq at-type-decl t))
5193 (when (c-keyword-member kwd-sym 'c-typeless-decl-kwds)
5194 (setq maybe-typeless t))
5195
5196 ;; Haven't matched a type so it's an umambiguous
5197 ;; specifier keyword and we know we're in a
5198 ;; declaration.
5199 (setq at-decl-or-cast t)
5200
5201 (goto-char kwd-clause-end))))
5202
5203 ;; If the type isn't known we continue so that we'll jump
5204 ;; over all specifiers and type identifiers. The reason
5205 ;; to do this for a known type prefix is to make things
5206 ;; like "unsigned INT16" work.
5207 (and found-type (not (eq found-type t))))))
5208
5209 (cond
5210 ((eq at-type t)
5211 ;; If a known type was found, we still need to skip over any
5212 ;; hangon keyword clauses after it. Otherwise it has already
5213 ;; been done in the loop above.
5214 (while (looking-at c-decl-hangon-key)
5215 (c-forward-keyword-clause 1))
5216 (setq id-start (point)))
5217
5218 ((eq at-type 'prefix)
5219 ;; A prefix type is itself a primitive type when it's not
5220 ;; followed by another type.
5221 (setq at-type t))
5222
5223 ((not at-type)
5224 ;; Got no type but set things up to continue anyway to handle
5225 ;; the various cases when a declaration doesn't start with a
5226 ;; type.
5227 (setq id-start start-pos))
5228
5229 ((and (eq at-type 'maybe)
5230 (c-major-mode-is 'c++-mode))
5231 ;; If it's C++ then check if the last "type" ends on the form
5232 ;; "foo::foo" or "foo::~foo", i.e. if it's the name of a
5233 ;; (con|de)structor.
5234 (save-excursion
5235 (let (name end-2 end-1)
5236 (goto-char id-start)
5237 (c-backward-syntactic-ws)
5238 (setq end-2 (point))
5239 (when (and
5240 (c-simple-skip-symbol-backward)
5241 (progn
5242 (setq name
5243 (buffer-substring-no-properties (point) end-2))
5244 ;; Cheating in the handling of syntactic ws below.
5245 (< (skip-chars-backward ":~ \t\n\r\v\f") 0))
5246 (progn
5247 (setq end-1 (point))
5248 (c-simple-skip-symbol-backward))
5249 (>= (point) type-start)
5250 (equal (buffer-substring-no-properties (point) end-1)
5251 name))
5252 ;; It is a (con|de)structor name. In that case the
5253 ;; declaration is typeless so zap out any preceding
5254 ;; identifier(s) that we might have taken as types.
5255 (goto-char type-start)
5256 (setq at-type nil
5257 backup-at-type nil
5258 id-start type-start))))))
5259
5260 ;; Check for and step over a type decl expression after the thing
5261 ;; that is or might be a type. This can't be skipped since we
5262 ;; need the correct end position of the declarator for
5263 ;; `max-type-decl-end-*'.
5264 (let ((start (point)) (paren-depth 0) pos
5265 ;; True if there's a non-open-paren match of
5266 ;; `c-type-decl-prefix-key'.
5267 got-prefix
5268 ;; True if the declarator is surrounded by a parenthesis pair.
5269 got-parens
5270 ;; True if there is an identifier in the declarator.
5271 got-identifier
5272 ;; True if there's a non-close-paren match of
5273 ;; `c-type-decl-suffix-key'.
5274 got-suffix
5275 ;; True if there's a prefix match outside the outermost
5276 ;; paren pair that surrounds the declarator.
5277 got-prefix-before-parens
5278y ;; True if there's a suffix match outside the outermost
5279 ;; paren pair that surrounds the declarator. The value is
5280 ;; the position of the first suffix match.
5281 got-suffix-after-parens
5282 ;; True if we've parsed the type decl to a token that is
5283 ;; known to end declarations in this context.
5284 at-decl-end
5285 ;; The earlier values of `at-type' and `type-start' if we've
5286 ;; shifted the type backwards.
5287 identifier-type identifier-start
5288 ;; If `c-parse-and-markup-<>-arglists' is set we need to
5289 ;; turn it off during the name skipping below to avoid
5290 ;; getting `c-type' properties that might be bogus. That
5291 ;; can happen since we don't know if
5292 ;; `c-restricted-<>-arglists' will be correct inside the
5293 ;; arglist paren that gets entered.
5294 c-parse-and-markup-<>-arglists)
5295
5296 (goto-char id-start)
5297
5298 ;; Skip over type decl prefix operators. (Note similar code in
5299 ;; `c-font-lock-declarators'.)
5300 (while (and (looking-at c-type-decl-prefix-key)
5301 (if (and (c-major-mode-is 'c++-mode)
5302 (match-beginning 2))
5303 ;; If the second submatch matches in C++ then
5304 ;; we're looking at an identifier that's a
5305 ;; prefix only if it specifies a member pointer.
5306 (when (setq got-identifier (c-forward-name))
5307 (if (looking-at "\\(::\\)")
5308 ;; We only check for a trailing "::" and
5309 ;; let the "*" that should follow be
5310 ;; matched in the next round.
5311 (progn (setq got-identifier nil) t)
5312 ;; It turned out to be the real identifier,
5313 ;; so stop.
5314 nil))
5315 t))
5316
5317 (if (eq (char-after) ?\()
5318 (progn
5319 (setq paren-depth (1+ paren-depth))
5320 (forward-char))
5321 (unless got-prefix-before-parens
5322 (setq got-prefix-before-parens (= paren-depth 0)))
5323 (setq got-prefix t)
5324 (goto-char (match-end 1)))
5325 (c-forward-syntactic-ws))
5326
5327 (setq got-parens (> paren-depth 0))
5328
5329 ;; Skip over an identifier.
5330 (or got-identifier
5331 (and (looking-at c-identifier-start)
5332 (setq got-identifier (c-forward-name))))
5333
5334 ;; Skip over type decl suffix operators.
5335 (while (if (looking-at c-type-decl-suffix-key)
5336
5337 (if (eq (char-after) ?\))
5338 (when (> paren-depth 0)
5339 (setq paren-depth (1- paren-depth))
5340 (forward-char)
5341 t)
5342 (when (if (save-match-data (looking-at "\\s\("))
5343 (c-safe (c-forward-sexp 1) t)
5344 (goto-char (match-end 1))
5345 t)
5346 (when (and (not got-suffix-after-parens)
5347 (= paren-depth 0))
5348 (setq got-suffix-after-parens (match-beginning 0)))
5349 (setq got-suffix t)))
5350
5351 ;; No suffix matched. We might have matched the
5352 ;; identifier as a type and the open paren of a
5353 ;; function arglist as a type decl prefix. In that
5354 ;; case we should "backtrack": Reinterpret the last
5355 ;; type as the identifier, move out of the arglist and
5356 ;; continue searching for suffix operators.
5357 ;;
5358 ;; Do this even if there's no preceding type, to cope
5359 ;; with old style function declarations in K&R C,
5360 ;; (con|de)structors in C++ and `c-typeless-decl-kwds'
5361 ;; style declarations. That isn't applicable in an
5362 ;; arglist context, though.
5363 (when (and (= paren-depth 1)
5364 (not got-prefix-before-parens)
5365 (not (eq at-type t))
5366 (or backup-at-type
5367 maybe-typeless
5368 backup-maybe-typeless
5369 (when c-recognize-typeless-decls
5370 (not context)))
5371 (setq pos (c-up-list-forward (point)))
5372 (eq (char-before pos) ?\)))
5373 (c-fdoc-shift-type-backward)
5374 (goto-char pos)
5375 t))
5376
5377 (c-forward-syntactic-ws))
5378
5379 (when (and (or maybe-typeless backup-maybe-typeless)
5380 (not got-identifier)
5381 (not got-prefix)
5382 at-type)
5383 ;; Have found no identifier but `c-typeless-decl-kwds' has
5384 ;; matched so we know we're inside a declaration. The
5385 ;; preceding type must be the identifier instead.
5386 (c-fdoc-shift-type-backward))
5387
5388 (setq
5389 at-decl-or-cast
5390 (catch 'at-decl-or-cast
5391
5392 (when (> paren-depth 0)
5393 ;; Encountered something inside parens that isn't matched by
5394 ;; the `c-type-decl-*' regexps, so it's not a type decl
5395 ;; expression. Try to skip out to the same paren depth to
5396 ;; not confuse the cast check below.
5397 (c-safe (goto-char (scan-lists (point) 1 paren-depth)))
5398 ;; If we've found a specifier keyword then it's a
5399 ;; declaration regardless.
5400 (throw 'at-decl-or-cast (eq at-decl-or-cast t)))
5401
5402 (setq at-decl-end
5403 (looking-at (cond ((eq context '<>) "[,>]")
5404 (context "[,\)]")
5405 (t "[,;]"))))
5406
5407 ;; Now we've collected info about various characteristics of
5408 ;; the construct we're looking at. Below follows a decision
5409 ;; tree based on that. It's ordered to check more certain
5410 ;; signs before less certain ones.
5411
5412 (if got-identifier
5413 (progn
5414
5415 (when (and (or at-type maybe-typeless)
5416 (not (or got-prefix got-parens)))
5417 ;; Got another identifier directly after the type, so it's a
5418 ;; declaration.
5419 (throw 'at-decl-or-cast t))
5420
5421 (when (and got-parens
5422 (not got-prefix)
5423 (not got-suffix-after-parens)
5424 (or backup-at-type
5425 maybe-typeless
5426 backup-maybe-typeless))
5427 ;; Got a declaration of the form "foo bar (gnu);" where we've
5428 ;; recognized "bar" as the type and "gnu" as the declarator.
5429 ;; In this case it's however more likely that "bar" is the
5430 ;; declarator and "gnu" a function argument or initializer (if
5431 ;; `c-recognize-paren-inits' is set), since the parens around
5432 ;; "gnu" would be superfluous if it's a declarator. Shift the
5433 ;; type one step backward.
5434 (c-fdoc-shift-type-backward)))
5435
5436 ;; Found no identifier.
5437
5438 (if backup-at-type
5439 (progn
5440
5441 (when (= (point) start)
5442 ;; Got a plain list of identifiers. If a colon follows it's
5443 ;; a valid label. Otherwise the last one probably is the
5444 ;; declared identifier and we should back up to the previous
5445 ;; type, providing it isn't a cast.
5446 (if (eq (char-after) ?:)
5447 ;; If we've found a specifier keyword then it's a
5448 ;; declaration regardless.
5449 (throw 'at-decl-or-cast (eq at-decl-or-cast t))
5450 (setq backup-if-not-cast t)
5451 (throw 'at-decl-or-cast t)))
5452
5453 (when (and got-suffix
5454 (not got-prefix)
5455 (not got-parens))
5456 ;; Got a plain list of identifiers followed by some suffix.
5457 ;; If this isn't a cast then the last identifier probably is
5458 ;; the declared one and we should back up to the previous
5459 ;; type.
5460 (setq backup-if-not-cast t)
5461 (throw 'at-decl-or-cast t)))
5462
5463 (when (eq at-type t)
5464 ;; If the type is known we know that there can't be any
5465 ;; identifier somewhere else, and it's only in declarations in
5466 ;; e.g. function prototypes and in casts that the identifier may
5467 ;; be left out.
5468 (throw 'at-decl-or-cast t))
5469
5470 (when (= (point) start)
5471 ;; Only got a single identifier (parsed as a type so far).
5472 (if (and
5473 ;; Check that the identifier isn't at the start of an
5474 ;; expression.
5475 at-decl-end
5476 (cond
5477 ((eq context 'decl)
5478 ;; Inside an arglist that contains declarations. If K&R
5479 ;; style declarations and parenthesis style initializers
5480 ;; aren't allowed then the single identifier must be a
5481 ;; type, else we require that it's known or found
5482 ;; (primitive types are handled above).
5483 (or (and (not c-recognize-knr-p)
5484 (not c-recognize-paren-inits))
5485 (memq at-type '(known found))))
5486 ((eq context '<>)
5487 ;; Inside a template arglist. Accept known and found
5488 ;; types; other identifiers could just as well be
5489 ;; constants in C++.
5490 (memq at-type '(known found)))))
5491 (throw 'at-decl-or-cast t)
5492 ;; Can't be a valid declaration or cast, but if we've found a
5493 ;; specifier it can't be anything else either, so treat it as
5494 ;; an invalid/unfinished declaration or cast.
5495 (throw 'at-decl-or-cast at-decl-or-cast))))
5496
5497 (if (and got-parens
5498 (not got-prefix)
5499 (not context)
5500 (not (eq at-type t))
5501 (or backup-at-type
5502 maybe-typeless
5503 backup-maybe-typeless
5504 (when c-recognize-typeless-decls
5505 (or (not got-suffix)
5506 (not (looking-at
5507 c-after-suffixed-type-maybe-decl-key))))))
5508 ;; Got an empty paren pair and a preceding type that probably
5509 ;; really is the identifier. Shift the type backwards to make
5510 ;; the last one the identifier. This is analogous to the
5511 ;; "backtracking" done inside the `c-type-decl-suffix-key' loop
5512 ;; above.
5513 ;;
5514 ;; Exception: In addition to the conditions in that
5515 ;; "backtracking" code, do not shift backward if we're not
5516 ;; looking at either `c-after-suffixed-type-decl-key' or "[;,]".
5517 ;; Since there's no preceding type, the shift would mean that
5518 ;; the declaration is typeless. But if the regexp doesn't match
5519 ;; then we will simply fall through in the tests below and not
5520 ;; recognize it at all, so it's better to try it as an abstract
5521 ;; declarator instead.
5522 (c-fdoc-shift-type-backward)
5523
5524 ;; Still no identifier.
5525
5526 (when (and got-prefix (or got-parens got-suffix))
5527 ;; Require `got-prefix' together with either `got-parens' or
5528 ;; `got-suffix' to recognize it as an abstract declarator:
5529 ;; `got-parens' only is probably an empty function call.
5530 ;; `got-suffix' only can build an ordinary expression together
5531 ;; with the preceding identifier which we've taken as a type.
5532 ;; We could actually accept on `got-prefix' only, but that can
5533 ;; easily occur temporarily while writing an expression so we
5534 ;; avoid that case anyway. We could do a better job if we knew
5535 ;; the point when the fontification was invoked.
5536 (throw 'at-decl-or-cast t))
5537
5538 (when (and at-type
5539 (not got-prefix)
5540 (not got-parens)
5541 got-suffix-after-parens
5542 (eq (char-after got-suffix-after-parens) ?\())
5543 ;; Got a type, no declarator but a paren suffix. I.e. it's a
5544 ;; normal function call afterall (or perhaps a C++ style object
5545 ;; instantiation expression).
5546 (throw 'at-decl-or-cast nil))))
5547
5548 (when at-decl-or-cast
5549 ;; By now we've located the type in the declaration that we know
5550 ;; we're in.
5551 (throw 'at-decl-or-cast t))
5552
5553 (when (and got-identifier
5554 (not context)
5555 (looking-at c-after-suffixed-type-decl-key)
5556 (if (and got-parens
5557 (not got-prefix)
5558 (not got-suffix)
5559 (not (eq at-type t)))
5560 ;; Shift the type backward in the case that there's a
5561 ;; single identifier inside parens. That can only
5562 ;; occur in K&R style function declarations so it's
5563 ;; more likely that it really is a function call.
5564 ;; Therefore we only do this after
5565 ;; `c-after-suffixed-type-decl-key' has matched.
5566 (progn (c-fdoc-shift-type-backward) t)
5567 got-suffix-after-parens))
5568 ;; A declaration according to `c-after-suffixed-type-decl-key'.
5569 (throw 'at-decl-or-cast t))
5570
5571 (when (and (or got-prefix (not got-parens))
5572 (memq at-type '(t known)))
5573 ;; It's a declaration if a known type precedes it and it can't be a
5574 ;; function call.
5575 (throw 'at-decl-or-cast t))
5576
5577 ;; If we get here we can't tell if this is a type decl or a normal
5578 ;; expression by looking at it alone. (That's under the assumption
5579 ;; that normal expressions always can look like type decl expressions,
5580 ;; which isn't really true but the cases where it doesn't hold are so
5581 ;; uncommon (e.g. some placements of "const" in C++) it's not worth
5582 ;; the effort to look for them.)
5583
5584 (unless (or at-decl-end (looking-at "=[^=]"))
5585 ;; If this is a declaration it should end here or its initializer(*)
5586 ;; should start here, so check for allowed separation tokens. Note
5587 ;; that this rule doesn't work e.g. with a K&R arglist after a
5588 ;; function header.
5589 ;;
5590 ;; *) Don't check for C++ style initializers using parens
5591 ;; since those already have been matched as suffixes.
5592 ;;
5593 ;; If `at-decl-or-cast' is then we've found some other sign that
5594 ;; it's a declaration or cast, so then it's probably an
5595 ;; invalid/unfinished one.
5596 (throw 'at-decl-or-cast at-decl-or-cast))
5597
5598 ;; Below are tests that only should be applied when we're certain to
5599 ;; not have parsed halfway through an expression.
5600
5601 (when (memq at-type '(t known))
5602 ;; The expression starts with a known type so treat it as a
5603 ;; declaration.
5604 (throw 'at-decl-or-cast t))
5605
5606 (when (and (c-major-mode-is 'c++-mode)
5607 ;; In C++ we check if the identifier is a known type, since
5608 ;; (con|de)structors use the class name as identifier.
5609 ;; We've always shifted over the identifier as a type and
5610 ;; then backed up again in this case.
5611 identifier-type
5612 (or (memq identifier-type '(found known))
5613 (and (eq (char-after identifier-start) ?~)
5614 ;; `at-type' probably won't be 'found for
5615 ;; destructors since the "~" is then part of the
5616 ;; type name being checked against the list of
5617 ;; known types, so do a check without that
5618 ;; operator.
5619 (or (save-excursion
5620 (goto-char (1+ identifier-start))
5621 (c-forward-syntactic-ws)
5622 (c-with-syntax-table
5623 c-identifier-syntax-table
5624 (looking-at c-known-type-key)))
5625 (save-excursion
5626 (goto-char (1+ identifier-start))
5627 ;; We have already parsed the type earlier,
5628 ;; so it'd be possible to cache the end
5629 ;; position instead of redoing it here, but
5630 ;; then we'd need to keep track of another
5631 ;; position everywhere.
5632 (c-check-type (point)
5633 (progn (c-forward-type)
5634 (point))))))))
5635 (throw 'at-decl-or-cast t))
5636
5637 (if got-identifier
5638 (progn
5639 (when (and got-prefix-before-parens
5640 at-type
5641 (or at-decl-end (looking-at "=[^=]"))
5642 (not context)
5643 (not got-suffix))
5644 ;; Got something like "foo * bar;". Since we're not inside an
5645 ;; arglist it would be a meaningless expression because the
5646 ;; result isn't used. We therefore choose to recognize it as
5647 ;; a declaration. Do not allow a suffix since it could then
5648 ;; be a function call.
5649 (throw 'at-decl-or-cast t))
5650
5651 (when (and (or got-suffix-after-parens
5652 (looking-at "=[^=]"))
5653 (eq at-type 'found)
5654 (not (eq context 'arglist)))
5655 ;; Got something like "a (*b) (c);" or "a (b) = c;". It could
5656 ;; be an odd expression or it could be a declaration. Treat
5657 ;; it as a declaration if "a" has been used as a type
5658 ;; somewhere else (if it's a known type we won't get here).
5659 (throw 'at-decl-or-cast t)))
5660
5661 (when (and context
5662 (or got-prefix
5663 (and (eq context 'decl)
5664 (not c-recognize-paren-inits)
5665 (or got-parens got-suffix))))
5666 ;; Got a type followed by an abstract declarator. If `got-prefix'
5667 ;; is set it's something like "a *" without anything after it. If
5668 ;; `got-parens' or `got-suffix' is set it's "a()", "a[]", "a()[]",
5669 ;; or similar, which we accept only if the context rules out
5670 ;; expressions.
5671 (throw 'at-decl-or-cast t)))
5672
5673 ;; If we had a complete symbol table here (which rules out
5674 ;; `c-found-types') we should return t due to the disambiguation rule
5675 ;; (in at least C++) that anything that can be parsed as a declaration
5676 ;; is a declaration. Now we're being more defensive and prefer to
5677 ;; highlight things like "foo (bar);" as a declaration only if we're
5678 ;; inside an arglist that contains declarations.
5679 (eq context 'decl))))
5680
5681 ;; The point is now after the type decl expression.
5682
5683 (cond
5684 ;; Check for a cast.
5685 ((save-excursion
5686 (and
5687 c-cast-parens
5688
5689 ;; Should be the first type/identifier in a cast paren.
5690 (> preceding-token-end (point-min))
5691 (memq (char-before preceding-token-end) c-cast-parens)
5692
5693 ;; The closing paren should follow.
5694 (progn
5695 (c-forward-syntactic-ws)
5696 (looking-at "\\s\)"))
5697
5698 ;; There should be a primary expression after it.
5699 (let (pos)
5700 (forward-char)
5701 (c-forward-syntactic-ws)
5702 (setq cast-end (point))
5703 (and (looking-at c-primary-expr-regexp)
5704 (progn
5705 (setq pos (match-end 0))
5706 (or
5707 ;; Check if the expression begins with a prefix keyword.
5708 (match-beginning 2)
5709 (if (match-beginning 1)
5710 ;; Expression begins with an ambiguous operator. Treat
5711 ;; it as a cast if it's a type decl or if we've
5712 ;; recognized the type somewhere else.
5713 (or at-decl-or-cast
5714 (memq at-type '(t known found)))
5715 ;; Unless it's a keyword, it's the beginning of a primary
5716 ;; expression.
5717 (not (looking-at c-keywords-regexp)))))
5718 ;; If `c-primary-expr-regexp' matched a nonsymbol token, check
5719 ;; that it matched a whole one so that we don't e.g. confuse
5720 ;; the operator '-' with '->'. It's ok if it matches further,
5721 ;; though, since it e.g. can match the float '.5' while the
5722 ;; operator regexp only matches '.'.
5723 (or (not (looking-at c-nonsymbol-token-regexp))
5724 (<= (match-end 0) pos))))
5725
5726 ;; There should either be a cast before it or something that isn't an
5727 ;; identifier or close paren.
5728 (> preceding-token-end (point-min))
5729 (progn
5730 (goto-char (1- preceding-token-end))
5731 (or (eq (point) last-cast-end)
5732 (progn
5733 (c-backward-syntactic-ws)
5734 (if (< (skip-syntax-backward "w_") 0)
5735 ;; It's a symbol. Accept it only if it's one of the
5736 ;; keywords that can precede an expression (without
5737 ;; surrounding parens).
5738 (looking-at c-simple-stmt-key)
5739 (and
5740 ;; Check that it isn't a close paren (block close is ok,
5741 ;; though).
5742 (not (memq (char-before) '(?\) ?\])))
5743 ;; Check that it isn't a nonsymbol identifier.
5744 (not (c-on-identifier)))))))))
5745
5746 ;; Handle the cast.
5747 (when (and c-record-type-identifiers at-type (not (eq at-type t)))
5748 (let ((c-promote-possible-types t))
5749 (goto-char type-start)
5750 (c-forward-type)))
5751
5752 (goto-char cast-end)
5753 'cast)
5754
5755 (at-decl-or-cast
5756 ;; We're at a declaration. Highlight the type and the following
5757 ;; declarators.
5758
5759 (when backup-if-not-cast
5760 (c-fdoc-shift-type-backward t))
5761
5762 (when (and (eq context 'decl) (looking-at ","))
5763 ;; Make sure to propagate the `c-decl-arg-start' property to
5764 ;; the next argument if it's set in this one, to cope with
5765 ;; interactive refontification.
5766 (c-put-c-type-property (point) 'c-decl-arg-start))
5767
5768 (when (and c-record-type-identifiers at-type (not (eq at-type t)))
5769 (let ((c-promote-possible-types t))
5770 (save-excursion
5771 (goto-char type-start)
5772 (c-forward-type))))
5773
5774 (cons id-start at-type-decl))
5775
5776 (t
5777 ;; False alarm. Restore the recorded ranges.
5778 (setq c-record-type-identifiers save-rec-type-ids
5779 c-record-ref-identifiers save-rec-ref-ids)
5780 nil))))
5781
5782(defun c-forward-label (&optional assume-markup preceding-token-end limit)
5783 ;; Assuming the point is at the beginning of a token, check if it
5784 ;; starts a label and if so move over it and return t, otherwise
5785 ;; don't move and return nil. The end of the label is taken to be
5786 ;; the end of the first submatch in `c-opt-extra-label-key' if it
5787 ;; matched, otherwise it's the colon. The point is directly after
5788 ;; the end on return. The terminating char is marked with
5789 ;; `c-decl-end' to improve recognition of the following declaration
5790 ;; or statement.
5791 ;;
5792 ;; If ASSUME-MARKUP is non-nil, it's assumed that the preceding
5793 ;; label, if any, has been marked up like that.
5794 ;;
5795 ;; If PRECEDING-TOKEN-END is given, it should be the first position
5796 ;; after the preceding token, i.e. on the other side of the
5797 ;; syntactic ws from the point. Use a value less than or equal to
5798 ;; (point-min) if the point is at the first token in (the visible
5799 ;; part of) the buffer.
5800 ;;
5801 ;; The optional LIMIT limits the forward scan for the colon.
5802 ;;
5803 ;; This function records the ranges of the label symbols on
5804 ;; `c-record-ref-identifiers' if `c-record-type-identifiers' (!) is
5805 ;; non-nil.
5806 ;;
5807 ;; This function might do hidden buffer changes.
5808
5809 (let ((start (point)))
5810 (cond
5811 ((looking-at c-label-kwds-regexp)
5812 (let ((kwd-end (match-end 1)))
5813 ;; Record only the keyword itself for fontification, since in
5814 ;; case labels the following is a constant expression and not
5815 ;; a label.
5816 (when c-record-type-identifiers
5817 (c-record-ref-id (cons (match-beginning 1) kwd-end)))
5818
5819 ;; Find the label end.
5820 (goto-char kwd-end)
5821 (if (and (c-syntactic-re-search-forward
5822 ;; Stop on chars that aren't allowed in expressions,
5823 ;; and on operator chars that would be meaningless
5824 ;; there. FIXME: This doesn't cope with ?: operators.
5825 "[;{=,@]\\|\\(\\=\\|[^:]\\):\\([^:]\\|\\'\\)"
5826 limit t t nil 1)
5827 (match-beginning 2))
5828
5829 (progn
5830 (goto-char (match-beginning 2))
5831 (c-put-c-type-property (1- (point)) 'c-decl-end)
5832 t)
5833
5834 ;; It's an unfinished label. We consider the keyword enough
5835 ;; to recognize it as a label, so that it gets fontified.
5836 ;; Leave the point at the end of it, but don't put any
5837 ;; `c-decl-end' marker.
5838 (goto-char kwd-end)
5839 t)))
5840
5841 ((and c-opt-extra-label-key
5842 (looking-at c-opt-extra-label-key))
5843 ;; For a `c-opt-extra-label-key' match, we record the whole
5844 ;; thing for fontification. That's to get the leading '@' in
5845 ;; Objective-C protection labels fontified.
5846 (goto-char (match-end 1))
5847 (when c-record-type-identifiers
5848 (c-record-ref-id (cons (match-beginning 1) (point))))
5849 (c-put-c-type-property (1- (point)) 'c-decl-end)
5850 t)
5851
5852 ((and c-recognize-colon-labels
5853
5854 ;; A colon label must have something before the colon.
5855 (not (eq (char-after) ?:))
5856
5857 ;; Check that we're not after a token that can't precede a label.
5858 (or
5859 ;; Trivially succeeds when there's no preceding token.
5860 (if preceding-token-end
5861 (<= preceding-token-end (point-min))
5862 (save-excursion
5863 (c-backward-syntactic-ws)
5864 (setq preceding-token-end (point))
5865 (bobp)))
5866
5867 ;; Check if we're after a label, if we're after a closing
5868 ;; paren that belong to statement, and with
5869 ;; `c-label-prefix-re'. It's done in different order
5870 ;; depending on `assume-markup' since the checks have
5871 ;; different expensiveness.
5872 (if assume-markup
5873 (or
5874 (eq (c-get-char-property (1- preceding-token-end) 'c-type)
5875 'c-decl-end)
5876
5877 (save-excursion
5878 (goto-char (1- preceding-token-end))
5879 (c-beginning-of-current-token)
5880 (looking-at c-label-prefix-re))
5881
5882 (and (eq (char-before preceding-token-end) ?\))
5883 (c-after-conditional)))
5884
5885 (or
5886 (save-excursion
5887 (goto-char (1- preceding-token-end))
5888 (c-beginning-of-current-token)
5889 (looking-at c-label-prefix-re))
5890
5891 (cond
5892 ((eq (char-before preceding-token-end) ?\))
5893 (c-after-conditional))
5894
5895 ((eq (char-before preceding-token-end) ?:)
5896 ;; Might be after another label, so check it recursively.
5897 (save-excursion
5898 (goto-char (1- preceding-token-end))
5899 ;; Essentially the same as the
5900 ;; `c-syntactic-re-search-forward' regexp below.
5901 (c-syntactic-skip-backward "^-]:?;}=*/%&|,<>!@+" nil t)
5902 (let ((pte (point))
5903 ;; If the caller turned on recording for us,
5904 ;; it shouldn't apply when we check the
5905 ;; preceding label.
5906 c-record-type-identifiers)
5907 (c-forward-syntactic-ws)
5908 (c-forward-label nil pte start))))))))
5909
5910 ;; Check that the next nonsymbol token is ":". Allow '('
5911 ;; for the sake of macro arguments. FIXME: Should build
5912 ;; this regexp from the language constants.
5913 (c-syntactic-re-search-forward
5914 "[[:?;{=*/%&|,<>!@+-]" limit t t)
5915 (eq (char-before) ?:)
5916 (not (eq (char-after) ?:)))
5917
5918 (save-restriction
5919 (narrow-to-region start (point))
5920
5921 ;; Check that `c-nonlabel-token-key' doesn't match anywhere.
5922 (catch 'check-label
5923 (goto-char start)
5924 (while (progn
5925 (when (looking-at c-nonlabel-token-key)
5926 (goto-char start)
5927 (throw 'check-label nil))
5928 (and (c-safe (c-forward-sexp)
5929 (c-forward-syntactic-ws)
5930 t)
5931 (not (eobp)))))
5932
5933 ;; Record the identifiers in the label for fontification, unless
5934 ;; it begins with `c-label-kwds' in which case the following
5935 ;; identifiers are part of a (constant) expression that
5936 ;; shouldn't be fontified.
5937 (when (and c-record-type-identifiers
5938 (progn (goto-char start)
5939 (not (looking-at c-label-kwds-regexp))))
5940 (while (c-syntactic-re-search-forward c-symbol-key nil t)
5941 (c-record-ref-id (cons (match-beginning 0)
5942 (match-end 0)))))
5943
5944 (c-put-c-type-property (1- (point-max)) 'c-decl-end)
5945 (goto-char (point-max))
5946 t)))
5947
5948 (t
5949 ;; Not a label.
5950 (goto-char start)
5951 nil))))
5952
5953(defun c-forward-objc-directive ()
5954 ;; Assuming the point is at the beginning of a token, try to move
5955 ;; forward to the end of the Objective-C directive that starts
5956 ;; there. Return t if a directive was fully recognized, otherwise
5957 ;; the point is moved as far as one could be successfully parsed and
5958 ;; nil is returned.
5959 ;;
5960 ;; This function records identifier ranges on
5961 ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
5962 ;; `c-record-type-identifiers' is non-nil.
5963 ;;
5964 ;; This function might do hidden buffer changes.
5965
5966 (let ((start (point))
5967 start-char
5968 (c-promote-possible-types t)
5969 ;; Turn off recognition of angle bracket arglists while parsing
5970 ;; types here since the protocol reference list might then be
5971 ;; considered part of the preceding name or superclass-name.
5972 c-recognize-<>-arglists)
5973
5974 (if (or
5975 (when (looking-at
5976 (eval-when-compile
5977 (c-make-keywords-re t
5978 (append (c-lang-const c-protection-kwds objc)
5979 '("@end"))
5980 'objc-mode)))
5981 (goto-char (match-end 1))
5982 t)
5983
5984 (and
5985 (looking-at
5986 (eval-when-compile
5987 (c-make-keywords-re t
5988 '("@interface" "@implementation" "@protocol")
5989 'objc-mode)))
5990
5991 ;; Handle the name of the class itself.
5992 (progn
5993 (c-forward-token-2)
5994 (c-forward-type))
5995
5996 (catch 'break
5997 ;; Look for ": superclass-name" or "( category-name )".
5998 (when (looking-at "[:\(]")
5999 (setq start-char (char-after))
6000 (forward-char)
6001 (c-forward-syntactic-ws)
6002 (unless (c-forward-type) (throw 'break nil))
6003 (when (eq start-char ?\()
6004 (unless (eq (char-after) ?\)) (throw 'break nil))
6005 (forward-char)
6006 (c-forward-syntactic-ws)))
6007
6008 ;; Look for a protocol reference list.
6009 (if (eq (char-after) ?<)
6010 (let ((c-recognize-<>-arglists t)
6011 (c-parse-and-markup-<>-arglists t)
6012 c-restricted-<>-arglists)
6013 (c-forward-<>-arglist t))
6014 t))))
6015
6016 (progn
6017 (c-backward-syntactic-ws)
6018 (c-clear-c-type-property start (1- (point)) 'c-decl-end)
6019 (c-put-c-type-property (1- (point)) 'c-decl-end)
6020 t)
6021
6022 (c-clear-c-type-property start (point) 'c-decl-end)
6023 nil)))
6024
4297(defun c-beginning-of-inheritance-list (&optional lim) 6025(defun c-beginning-of-inheritance-list (&optional lim)
4298 ;; Go to the first non-whitespace after the colon that starts a 6026 ;; Go to the first non-whitespace after the colon that starts a
4299 ;; multiple inheritance introduction. Optional LIM is the farthest 6027 ;; multiple inheritance introduction. Optional LIM is the farthest
4300 ;; back we should search. 6028 ;; back we should search.
4301 (let* ((lim (or lim (save-excursion 6029 ;;
4302 (c-beginning-of-syntax) 6030 ;; This function might do hidden buffer changes.
4303 (point))))) 6031 (c-with-syntax-table c++-template-syntax-table
4304 (c-with-syntax-table c++-template-syntax-table 6032 (c-backward-token-2 0 t lim)
4305 (c-backward-token-2 0 t lim) 6033 (while (and (or (looking-at c-symbol-start)
4306 (while (and (or (looking-at c-symbol-start) 6034 (looking-at "[<,]\\|::"))
4307 (looking-at "[<,]\\|::")) 6035 (zerop (c-backward-token-2 1 t lim))))))
4308 (zerop (c-backward-token-2 1 t lim))))
4309 (skip-chars-forward "^:"))))
4310 6036
4311(defun c-in-method-def-p () 6037(defun c-in-method-def-p ()
4312 ;; Return nil if we aren't in a method definition, otherwise the 6038 ;; Return nil if we aren't in a method definition, otherwise the
4313 ;; position of the initial [+-]. 6039 ;; position of the initial [+-].
6040 ;;
6041 ;; This function might do hidden buffer changes.
4314 (save-excursion 6042 (save-excursion
4315 (beginning-of-line) 6043 (beginning-of-line)
4316 (and c-opt-method-key 6044 (and c-opt-method-key
@@ -4327,6 +6055,8 @@ This function does not do any hidden buffer changes."
4327 ;; Only one level of enclosing parentheses is considered, so for 6055 ;; Only one level of enclosing parentheses is considered, so for
4328 ;; instance `nil' is returned when in a function call within an asm 6056 ;; instance `nil' is returned when in a function call within an asm
4329 ;; operand. 6057 ;; operand.
6058 ;;
6059 ;; This function might do hidden buffer changes.
4330 6060
4331 (and c-opt-asm-stmt-key 6061 (and c-opt-asm-stmt-key
4332 (save-excursion 6062 (save-excursion
@@ -4347,79 +6077,65 @@ top-level not enclosed within a class definition, t is returned.
4347Otherwise, a 2-vector is returned where the zeroth element is the 6077Otherwise, a 2-vector is returned where the zeroth element is the
4348buffer position of the start of the class declaration, and the first 6078buffer position of the start of the class declaration, and the first
4349element is the buffer position of the enclosing class's opening 6079element is the buffer position of the enclosing class's opening
4350brace." 6080brace.
6081
6082Note that this function might do hidden buffer changes. See the
6083comment at the start of cc-engine.el for more info."
4351 (let ((paren-state (c-parse-state))) 6084 (let ((paren-state (c-parse-state)))
4352 (or (not (c-most-enclosing-brace paren-state)) 6085 (or (not (c-most-enclosing-brace paren-state))
4353 (c-search-uplist-for-classkey paren-state)))) 6086 (c-search-uplist-for-classkey paren-state))))
4354 6087
4355(defun c-just-after-func-arglist-p (&optional lim) 6088(defun c-just-after-func-arglist-p (&optional lim)
4356 ;; Return non-nil if we are between a function's argument list closing 6089 ;; Return non-nil if the point is in the region after the argument
4357 ;; paren and its opening brace. Note that the list close brace 6090 ;; list of a function and its opening brace (or semicolon in case it
4358 ;; could be followed by a "const" specifier or a member init hanging 6091 ;; got no body). If there are K&R style argument declarations in
4359 ;; colon. LIM is used as bound for some backward buffer searches; 6092 ;; that region, the point has to be inside the first one for this
4360 ;; the search might continue past it. 6093 ;; function to recognize it.
4361 ;; 6094 ;;
4362 ;; Note: This test is easily fooled. It only works reasonably well 6095 ;; If successful, the point is moved to the first token after the
4363 ;; in the situations where `c-guess-basic-syntax' uses it. 6096 ;; function header (see `c-forward-decl-or-cast-1' for details) and
4364 (save-excursion 6097 ;; the position of the opening paren of the function arglist is
4365 (if (c-mode-is-new-awk-p) 6098 ;; returned.
4366 (c-awk-backward-syntactic-ws lim) 6099 ;;
4367 (c-backward-syntactic-ws lim)) 6100 ;; The point is clobbered if not successful.
4368 (let ((checkpoint (point))) 6101 ;;
4369 ;; could be looking at const specifier 6102 ;; LIM is used as bound for backward buffer searches.
4370 (if (and (eq (char-before) ?t) 6103 ;;
4371 (forward-word -1) 6104 ;; This function might do hidden buffer changes.
4372 (looking-at "\\<const\\>[^_]")) 6105
4373 (c-backward-syntactic-ws lim) 6106 (let ((beg (point)) end id-start)
4374 ;; otherwise, we could be looking at a hanging member init 6107 (and
4375 ;; colon 6108 (eq (c-beginning-of-statement-1 lim) 'same)
4376 (goto-char checkpoint) 6109
4377 (while (and 6110 (not (or (c-major-mode-is 'objc-mode)
4378 (eq (char-before) ?,) 6111 (c-forward-objc-directive)))
4379 ;; this will catch member inits with multiple 6112
4380 ;; line arglists 6113 (setq id-start
4381 (progn 6114 (car-safe (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil)))
4382 (forward-char -1) 6115 (< id-start beg)
4383 (c-backward-syntactic-ws (c-point 'bol)) 6116
4384 (c-safe (c-backward-sexp 1) t)) 6117 ;; There should not be a '=' or ',' between beg and the
4385 (or (not (looking-at "\\s\(")) 6118 ;; start of the declaration since that means we were in the
4386 (c-safe (c-backward-sexp 1) t))) 6119 ;; "expression part" of the declaration.
4387 (c-backward-syntactic-ws lim)) 6120 (or (> (point) beg)
4388 (if (and (eq (char-before) ?:) 6121 (not (looking-at "[=,]")))
4389 (progn 6122
4390 (forward-char -1) 6123 (save-excursion
4391 (c-backward-syntactic-ws lim) 6124 ;; Check that there's an arglist paren in the
4392 (looking-at "\\([ \t\n]\\|\\\\\n\\)*:\\([^:]+\\|$\\)"))) 6125 ;; declaration.
4393 nil 6126 (goto-char id-start)
4394 (goto-char checkpoint)) 6127 (cond ((eq (char-after) ?\()
4395 ) 6128 ;; The declarator is a paren expression, so skip past it
4396 (setq checkpoint (point)) 6129 ;; so that we don't get stuck on that instead of the
4397 (and (eq (char-before) ?\)) 6130 ;; function arglist.
4398 ;; Check that it isn't a cpp expression, e.g. the 6131 (c-forward-sexp))
4399 ;; expression of an #if directive or the "function header" 6132 ((and c-opt-op-identitier-prefix
4400 ;; of a #define. 6133 (looking-at c-opt-op-identitier-prefix))
4401 (or (not (c-beginning-of-macro)) 6134 ;; Don't trip up on "operator ()".
4402 (and (c-forward-to-cpp-define-body) 6135 (c-forward-token-2 2 t)))
4403 (< (point) checkpoint))) 6136 (and (< (point) beg)
4404 ;; Check if we are looking at an ObjC method def or a class 6137 (c-syntactic-re-search-forward "(" beg t t)
4405 ;; category. 6138 (1- (point)))))))
4406 (not (and c-opt-method-key
4407 (progn
4408 (goto-char checkpoint)
4409 (c-safe (c-backward-sexp) t))
4410 (progn
4411 (c-backward-syntactic-ws lim)
4412 (or (memq (char-before) '(?- ?+))
4413 (and (c-safe (c-forward-sexp -2) t)
4414 (looking-at c-class-key))))))
4415 ;; Pike has compound types that include parens,
4416 ;; e.g. "array(string)". Check that we aren't after one.
4417 (not (and (c-major-mode-is 'pike-mode)
4418 (progn
4419 (goto-char checkpoint)
4420 (c-safe (c-backward-sexp 2) t))
4421 (looking-at c-primitive-type-key)))
4422 ))))
4423 6139
4424(defun c-in-knr-argdecl (&optional lim) 6140(defun c-in-knr-argdecl (&optional lim)
4425 ;; Return the position of the first argument declaration if point is 6141 ;; Return the position of the first argument declaration if point is
@@ -4429,6 +6145,8 @@ brace."
4429 ;; 6145 ;;
4430 ;; Note: A declaration level context is assumed; the test can return 6146 ;; Note: A declaration level context is assumed; the test can return
4431 ;; false positives for statements. 6147 ;; false positives for statements.
6148 ;;
6149 ;; This function might do hidden buffer changes.
4432 6150
4433 (save-excursion 6151 (save-excursion
4434 (save-restriction 6152 (save-restriction
@@ -4488,6 +6206,8 @@ brace."
4488(defun c-skip-conditional () 6206(defun c-skip-conditional ()
4489 ;; skip forward over conditional at point, including any predicate 6207 ;; skip forward over conditional at point, including any predicate
4490 ;; statements in parentheses. No error checking is performed. 6208 ;; statements in parentheses. No error checking is performed.
6209 ;;
6210 ;; This function might do hidden buffer changes.
4491 (c-forward-sexp (cond 6211 (c-forward-sexp (cond
4492 ;; else if() 6212 ;; else if()
4493 ((looking-at (concat "\\<else" 6213 ((looking-at (concat "\\<else"
@@ -4505,6 +6225,8 @@ brace."
4505(defun c-after-conditional (&optional lim) 6225(defun c-after-conditional (&optional lim)
4506 ;; If looking at the token after a conditional then return the 6226 ;; If looking at the token after a conditional then return the
4507 ;; position of its start, otherwise return nil. 6227 ;; position of its start, otherwise return nil.
6228 ;;
6229 ;; This function might do hidden buffer changes.
4508 (save-excursion 6230 (save-excursion
4509 (and (zerop (c-backward-token-2 1 t lim)) 6231 (and (zerop (c-backward-token-2 1 t lim))
4510 (or (looking-at c-block-stmt-1-key) 6232 (or (looking-at c-block-stmt-1-key)
@@ -4513,12 +6235,32 @@ brace."
4513 (looking-at c-block-stmt-2-key))) 6235 (looking-at c-block-stmt-2-key)))
4514 (point)))) 6236 (point))))
4515 6237
6238(defun c-after-special-operator-id (&optional lim)
6239 ;; If the point is after an operator identifier that isn't handled
6240 ;; like an ordinary symbol (i.e. like "operator =" in C++) then the
6241 ;; position of the start of that identifier is returned. nil is
6242 ;; returned otherwise. The point may be anywhere in the syntactic
6243 ;; whitespace after the last token of the operator identifier.
6244 ;;
6245 ;; This function might do hidden buffer changes.
6246 (save-excursion
6247 (and c-overloadable-operators-regexp
6248 (zerop (c-backward-token-2 1 nil lim))
6249 (looking-at c-overloadable-operators-regexp)
6250 (or (not c-opt-op-identitier-prefix)
6251 (and
6252 (zerop (c-backward-token-2 1 nil lim))
6253 (looking-at c-opt-op-identitier-prefix)))
6254 (point))))
6255
4516(defsubst c-backward-to-block-anchor (&optional lim) 6256(defsubst c-backward-to-block-anchor (&optional lim)
4517 ;; Assuming point is at a brace that opens a statement block of some 6257 ;; Assuming point is at a brace that opens a statement block of some
4518 ;; kind, move to the proper anchor point for that block. It might 6258 ;; kind, move to the proper anchor point for that block. It might
4519 ;; need to be adjusted further by c-add-stmt-syntax, but the 6259 ;; need to be adjusted further by c-add-stmt-syntax, but the
4520 ;; position at return is suitable as start position for that 6260 ;; position at return is suitable as start position for that
4521 ;; function. 6261 ;; function.
6262 ;;
6263 ;; This function might do hidden buffer changes.
4522 (unless (= (point) (c-point 'boi)) 6264 (unless (= (point) (c-point 'boi))
4523 (let ((start (c-after-conditional lim))) 6265 (let ((start (c-after-conditional lim)))
4524 (if start 6266 (if start
@@ -4528,6 +6270,8 @@ brace."
4528 ;; Assuming point is at a brace that opens the block of a top level 6270 ;; Assuming point is at a brace that opens the block of a top level
4529 ;; declaration of some kind, move to the proper anchor point for 6271 ;; declaration of some kind, move to the proper anchor point for
4530 ;; that block. 6272 ;; that block.
6273 ;;
6274 ;; This function might do hidden buffer changes.
4531 (unless (= (point) (c-point 'boi)) 6275 (unless (= (point) (c-point 'boi))
4532 (c-beginning-of-statement-1 lim))) 6276 (c-beginning-of-statement-1 lim)))
4533 6277
@@ -4538,6 +6282,8 @@ brace."
4538 ;; semicolon. I.e. search forward for the closest following 6282 ;; semicolon. I.e. search forward for the closest following
4539 ;; (syntactically relevant) '{', '=' or ';' token. Point is left 6283 ;; (syntactically relevant) '{', '=' or ';' token. Point is left
4540 ;; _after_ the first found token, or at point-max if none is found. 6284 ;; _after_ the first found token, or at point-max if none is found.
6285 ;;
6286 ;; This function might do hidden buffer changes.
4541 6287
4542 (let ((base (point))) 6288 (let ((base (point)))
4543 (if (c-major-mode-is 'c++-mode) 6289 (if (c-major-mode-is 'c++-mode)
@@ -4552,7 +6298,7 @@ brace."
4552 ;; operator token preceded by "operator". 6298 ;; operator token preceded by "operator".
4553 (save-excursion 6299 (save-excursion
4554 (and (c-safe (c-backward-sexp) t) 6300 (and (c-safe (c-backward-sexp) t)
4555 (looking-at "operator\\>\\([^_]\\|$\\)"))) 6301 (looking-at c-opt-op-identitier-prefix)))
4556 (and (eq (char-before) ?<) 6302 (and (eq (char-before) ?<)
4557 (c-with-syntax-table c++-template-syntax-table 6303 (c-with-syntax-table c++-template-syntax-table
4558 (if (c-safe (goto-char (c-up-list-forward (point)))) 6304 (if (c-safe (goto-char (c-up-list-forward (point))))
@@ -4569,7 +6315,7 @@ brace."
4569(defun c-beginning-of-decl-1 (&optional lim) 6315(defun c-beginning-of-decl-1 (&optional lim)
4570 ;; Go to the beginning of the current declaration, or the beginning 6316 ;; Go to the beginning of the current declaration, or the beginning
4571 ;; of the previous one if already at the start of it. Point won't 6317 ;; of the previous one if already at the start of it. Point won't
4572 ;; be moved out of any surrounding paren. Return a cons cell on the 6318 ;; be moved out of any surrounding paren. Return a cons cell of the
4573 ;; form (MOVE . KNR-POS). MOVE is like the return value from 6319 ;; form (MOVE . KNR-POS). MOVE is like the return value from
4574 ;; `c-beginning-of-statement-1'. If point skipped over some K&R 6320 ;; `c-beginning-of-statement-1'. If point skipped over some K&R
4575 ;; style argument declarations (and they are to be recognized) then 6321 ;; style argument declarations (and they are to be recognized) then
@@ -4580,10 +6326,12 @@ brace."
4580 ;; NB: Cases where the declaration continues after the block, as in 6326 ;; NB: Cases where the declaration continues after the block, as in
4581 ;; "struct foo { ... } bar;", are currently recognized as two 6327 ;; "struct foo { ... } bar;", are currently recognized as two
4582 ;; declarations, e.g. "struct foo { ... }" and "bar;" in this case. 6328 ;; declarations, e.g. "struct foo { ... }" and "bar;" in this case.
6329 ;;
6330 ;; This function might do hidden buffer changes.
4583 (catch 'return 6331 (catch 'return
4584 (let* ((start (point)) 6332 (let* ((start (point))
4585 (last-stmt-start (point)) 6333 (last-stmt-start (point))
4586 (move (c-beginning-of-statement-1 lim t t))) 6334 (move (c-beginning-of-statement-1 lim nil t)))
4587 6335
4588 ;; `c-beginning-of-statement-1' stops at a block start, but we 6336 ;; `c-beginning-of-statement-1' stops at a block start, but we
4589 ;; want to continue if the block doesn't begin a top level 6337 ;; want to continue if the block doesn't begin a top level
@@ -4604,7 +6352,7 @@ brace."
4604 ;; Check that we don't move from the first thing in a 6352 ;; Check that we don't move from the first thing in a
4605 ;; macro to its header. 6353 ;; macro to its header.
4606 (not (eq (setq tentative-move 6354 (not (eq (setq tentative-move
4607 (c-beginning-of-statement-1 lim t t)) 6355 (c-beginning-of-statement-1 lim nil t))
4608 'macro))) 6356 'macro)))
4609 (setq last-stmt-start beg 6357 (setq last-stmt-start beg
4610 beg (point) 6358 beg (point)
@@ -4625,7 +6373,7 @@ brace."
4625 (< knr-argdecl-start start) 6373 (< knr-argdecl-start start)
4626 (progn 6374 (progn
4627 (goto-char knr-argdecl-start) 6375 (goto-char knr-argdecl-start)
4628 (not (eq (c-beginning-of-statement-1 lim t t) 'macro)))) 6376 (not (eq (c-beginning-of-statement-1 lim nil t) 'macro))))
4629 (throw 'return 6377 (throw 'return
4630 (cons (if (eq (char-after fallback-pos) ?{) 6378 (cons (if (eq (char-after fallback-pos) ?{)
4631 'previous 6379 'previous
@@ -4633,17 +6381,6 @@ brace."
4633 knr-argdecl-start)) 6381 knr-argdecl-start))
4634 (goto-char fallback-pos)))) 6382 (goto-char fallback-pos))))
4635 6383
4636 (when c-opt-access-key
4637 ;; Might have ended up before a protection label. This should
4638 ;; perhaps be checked before `c-recognize-knr-p' to be really
4639 ;; accurate, but we know that no language has both.
4640 (while (looking-at c-opt-access-key)
4641 (goto-char (match-end 0))
4642 (c-forward-syntactic-ws)
4643 (when (>= (point) start)
4644 (goto-char start)
4645 (throw 'return (cons 'same nil)))))
4646
4647 ;; `c-beginning-of-statement-1' counts each brace block as a 6384 ;; `c-beginning-of-statement-1' counts each brace block as a
4648 ;; separate statement, so the result will be 'previous if we've 6385 ;; separate statement, so the result will be 'previous if we've
4649 ;; moved over any. If they were brace list initializers we might 6386 ;; moved over any. If they were brace list initializers we might
@@ -4675,6 +6412,8 @@ brace."
4675 ;; point is moved as far as possible within the current sexp and nil 6412 ;; point is moved as far as possible within the current sexp and nil
4676 ;; is returned. This function doesn't handle macros; use 6413 ;; is returned. This function doesn't handle macros; use
4677 ;; `c-end-of-macro' instead in those cases. 6414 ;; `c-end-of-macro' instead in those cases.
6415 ;;
6416 ;; This function might do hidden buffer changes.
4678 (let ((start (point)) 6417 (let ((start (point))
4679 (decl-syntax-table (if (c-major-mode-is 'c++-mode) 6418 (decl-syntax-table (if (c-major-mode-is 'c++-mode)
4680 c++-template-syntax-table 6419 c++-template-syntax-table
@@ -4729,178 +6468,171 @@ brace."
4729 (c-syntactic-re-search-forward ";" nil 'move t)))) 6468 (c-syntactic-re-search-forward ";" nil 'move t))))
4730 nil))) 6469 nil)))
4731 6470
4732(defun c-beginning-of-member-init-list (&optional limit) 6471(defun c-looking-at-decl-block (containing-sexp goto-start &optional limit)
4733 ;; Go to the beginning of a member init list (i.e. just after the 6472 ;; Assuming the point is at an open brace, check if it starts a
4734 ;; ':') if inside one. Returns t in that case, nil otherwise. 6473 ;; block that contains another declaration level, i.e. that isn't a
4735 (or limit 6474 ;; statement block or a brace list, and if so return non-nil.
4736 (setq limit (point-min))) 6475 ;;
4737 (skip-chars-forward " \t") 6476 ;; If the check is successful, the return value is the start of the
4738 6477 ;; keyword that tells what kind of construct it is, i.e. typically
4739 (if (eq (char-after) ?,) 6478 ;; what `c-decl-block-key' matched. Also, if GOTO-START is set then
4740 (forward-char 1) 6479 ;; the point will be at the start of the construct, before any
4741 (c-backward-syntactic-ws limit)) 6480 ;; leading specifiers, otherwise it's at the returned position.
4742 6481 ;;
4743 (catch 'exit 6482 ;; The point is clobbered if the check is unsuccessful.
4744 (while (and (< limit (point)) 6483 ;;
4745 (eq (char-before) ?,)) 6484 ;; CONTAINING-SEXP is the position of the open of the surrounding
4746 6485 ;; paren, or nil if none.
4747 ;; this will catch member inits with multiple 6486 ;;
4748 ;; line arglists 6487 ;; The optional LIMIT limits the backward search for the start of
4749 (forward-char -1) 6488 ;; the construct. It's assumed to be at a syntactically relevant
4750 (c-backward-syntactic-ws limit) 6489 ;; position.
4751 (if (eq (char-before) ?\)) 6490 ;;
4752 (unless (c-safe (c-backward-sexp 1)) 6491 ;; If any template arglists are found in the searched region before
4753 (throw 'exit nil))) 6492 ;; the open brace, they get marked with paren syntax.
4754 (c-backward-syntactic-ws limit) 6493 ;;
4755 6494 ;; This function might do hidden buffer changes.
4756 ;; Skip over any template arg to the class. This way with a 6495
4757 ;; syntax table is bogus but it'll have to do for now. 6496 (let ((open-brace (point)) kwd-start first-specifier-pos)
4758 (if (and (eq (char-before) ?>) 6497 (c-syntactic-skip-backward c-block-prefix-charset limit t)
4759 (c-major-mode-is 'c++-mode)) 6498
4760 (c-with-syntax-table c++-template-syntax-table 6499 (when (and c-recognize-<>-arglists
4761 (unless (c-safe (c-backward-sexp 1)) 6500 (eq (char-before) ?>))
4762 (throw 'exit nil)))) 6501 ;; Could be at the end of a template arglist.
4763 (c-safe (c-backward-sexp 1)) 6502 (let ((c-parse-and-markup-<>-arglists t)
4764 (c-backward-syntactic-ws limit) 6503 (c-disallow-comma-in-<>-arglists
4765 6504 (and containing-sexp
4766 ;; Skip backwards over a fully::qualified::name. 6505 (not (eq (char-after containing-sexp) ?{)))))
4767 (while (and (eq (char-before) ?:) 6506 (while (and
4768 (save-excursion 6507 (c-backward-<>-arglist nil limit)
4769 (forward-char -1) 6508 (progn
4770 (eq (char-before) ?:))) 6509 (c-syntactic-skip-backward c-block-prefix-charset limit t)
4771 (backward-char 2) 6510 (eq (char-before) ?>))))))
4772 (c-safe (c-backward-sexp 1))) 6511
4773 6512 ;; Note: Can't get bogus hits inside template arglists below since they
4774 ;; If we've stepped over a number then this is a bitfield. 6513 ;; have gotten paren syntax above.
4775 (when (and c-opt-bitfield-key 6514 (when (and
4776 (looking-at "[0-9]")) 6515 ;; If `goto-start' is set we begin by searching for the
4777 (throw 'exit nil)) 6516 ;; first possible position of a leading specifier list.
4778 6517 ;; The `c-decl-block-key' search continues from there since
4779 ;; now continue checking 6518 ;; we know it can't match earlier.
4780 (c-backward-syntactic-ws limit)) 6519 (if goto-start
4781 6520 (when (c-syntactic-re-search-forward c-symbol-start
4782 (and (< limit (point)) 6521 open-brace t t)
4783 (eq (char-before) ?:)))) 6522 (goto-char (setq first-specifier-pos (match-beginning 0)))
6523 t)
6524 t)
6525
6526 (cond
6527 ((c-syntactic-re-search-forward c-decl-block-key open-brace t t t)
6528 (goto-char (setq kwd-start (match-beginning 0)))
6529 (or
6530
6531 ;; Found a keyword that can't be a type?
6532 (match-beginning 1)
6533
6534 ;; Can be a type too, in which case it's the return type of a
6535 ;; function (under the assumption that no declaration level
6536 ;; block construct starts with a type).
6537 (not (c-forward-type))
6538
6539 ;; Jumped over a type, but it could be a declaration keyword
6540 ;; followed by the declared identifier that we've jumped over
6541 ;; instead (e.g. in "class Foo {"). If it indeed is a type
6542 ;; then we should be at the declarator now, so check for a
6543 ;; valid declarator start.
6544 ;;
6545 ;; Note: This doesn't cope with the case when a declared
6546 ;; identifier is followed by e.g. '(' in a language where '('
6547 ;; also might be part of a declarator expression. Currently
6548 ;; there's no such language.
6549 (not (or (looking-at c-symbol-start)
6550 (looking-at c-type-decl-prefix-key)))))
6551
6552 ;; In Pike a list of modifiers may be followed by a brace
6553 ;; to make them apply to many identifiers. Note that the
6554 ;; match data will be empty on return in this case.
6555 ((and (c-major-mode-is 'pike-mode)
6556 (progn
6557 (goto-char open-brace)
6558 (= (c-backward-token-2) 0))
6559 (looking-at c-specifier-key)
6560 ;; Use this variant to avoid yet another special regexp.
6561 (c-keyword-member (c-keyword-sym (match-string 1))
6562 'c-modifier-kwds))
6563 (setq kwd-start (point))
6564 t)))
6565
6566 ;; Got a match.
6567
6568 (if goto-start
6569 ;; Back up over any preceding specifiers and their clauses
6570 ;; by going forward from `first-specifier-pos', which is the
6571 ;; earliest possible position where the specifier list can
6572 ;; start.
6573 (progn
6574 (goto-char first-specifier-pos)
6575
6576 (while (< (point) kwd-start)
6577 (if (looking-at c-symbol-key)
6578 ;; Accept any plain symbol token on the ground that
6579 ;; it's a specifier masked through a macro (just
6580 ;; like `c-forward-decl-or-cast-1' skip forward over
6581 ;; such tokens).
6582 ;;
6583 ;; Could be more restrictive wrt invalid keywords,
6584 ;; but that'd only occur in invalid code so there's
6585 ;; no use spending effort on it.
6586 (let ((end (match-end 0)))
6587 (unless (c-forward-keyword-clause 0)
6588 (goto-char end)
6589 (c-forward-syntactic-ws)))
6590
6591 ;; Can't parse a declaration preamble and is still
6592 ;; before `kwd-start'. That means `first-specifier-pos'
6593 ;; was in some earlier construct. Search again.
6594 (if (c-syntactic-re-search-forward c-symbol-start
6595 kwd-start 'move t)
6596 (goto-char (setq first-specifier-pos (match-beginning 0)))
6597 ;; Got no preamble before the block declaration keyword.
6598 (setq first-specifier-pos kwd-start))))
6599
6600 (goto-char first-specifier-pos))
6601 (goto-char kwd-start))
6602
6603 kwd-start)))
4784 6604
4785(defun c-search-uplist-for-classkey (paren-state) 6605(defun c-search-uplist-for-classkey (paren-state)
4786 ;; search for the containing class, returning a 2 element vector if 6606 ;; Check if the closest containing paren sexp is a declaration
4787 ;; found. aref 0 contains the bufpos of the boi of the class key 6607 ;; block, returning a 2 element vector in that case. Aref 0
4788 ;; line, and aref 1 contains the bufpos of the open brace. 6608 ;; contains the bufpos at boi of the class key line, and aref 1
4789 (if (null paren-state) 6609 ;; contains the bufpos of the open brace. This function is an
4790 ;; no paren-state means we cannot be inside a class 6610 ;; obsolete wrapper for `c-looking-at-decl-block'.
4791 nil 6611 ;;
4792 (let ((carcache (car paren-state)) 6612 ;; This function might do hidden buffer changes.
4793 search-start search-end) 6613 (let ((open-paren-pos (c-most-enclosing-brace paren-state)))
4794 (if (consp carcache) 6614 (when open-paren-pos
4795 ;; a cons cell in the first element means that there is some 6615 (save-excursion
4796 ;; balanced sexp before the current bufpos. this we can 6616 (goto-char open-paren-pos)
4797 ;; ignore. the nth 1 and nth 2 elements define for us the 6617 (when (and (eq (char-after) ?{)
4798 ;; search boundaries 6618 (c-looking-at-decl-block
4799 (setq search-start (nth 2 paren-state) 6619 (c-safe-position open-paren-pos paren-state)
4800 search-end (nth 1 paren-state)) 6620 nil))
4801 ;; if the car was not a cons cell then nth 0 and nth 1 define 6621 (back-to-indentation)
4802 ;; for us the search boundaries 6622 (vector (point) open-paren-pos))))))
4803 (setq search-start (nth 1 paren-state)
4804 search-end (nth 0 paren-state)))
4805 ;; if search-end is nil, or if the search-end character isn't an
4806 ;; open brace, we are definitely not in a class
4807 (if (or (not search-end)
4808 (< search-end (point-min))
4809 (not (eq (char-after search-end) ?{)))
4810 nil
4811 ;; now, we need to look more closely at search-start. if
4812 ;; search-start is nil, then our start boundary is really
4813 ;; point-min.
4814 (if (not search-start)
4815 (setq search-start (point-min))
4816 ;; if search-start is a cons cell, then we can start
4817 ;; searching from the end of the balanced sexp just ahead of
4818 ;; us
4819 (if (consp search-start)
4820 (setq search-start (cdr search-start))
4821 ;; Otherwise we start searching within the surrounding paren sexp.
4822 (setq search-start (1+ search-start))))
4823 ;; now we can do a quick regexp search from search-start to
4824 ;; search-end and see if we can find a class key. watch for
4825 ;; class like strings in literals
4826 (save-excursion
4827 (save-restriction
4828 (goto-char search-start)
4829 (let (foundp class match-end)
4830 (while (and (not foundp)
4831 (progn
4832 (c-forward-syntactic-ws search-end)
4833 (> search-end (point)))
4834 ;; Add one to the search limit, to allow
4835 ;; matching of the "{" in the regexp.
4836 (re-search-forward c-decl-block-key
4837 (1+ search-end)
4838 t))
4839 (setq class (match-beginning 0)
4840 match-end (match-end 0))
4841 (goto-char class)
4842 (if (c-in-literal search-start)
4843 (goto-char match-end) ; its in a comment or string, ignore
4844 (c-skip-ws-forward)
4845 (setq foundp (vector (c-point 'boi) search-end))
4846 (cond
4847 ;; check for embedded keywords
4848 ((let ((char (char-after (1- class))))
4849 (and char
4850 (memq (char-syntax char) '(?w ?_))))
4851 (goto-char match-end)
4852 (setq foundp nil))
4853 ;; make sure we're really looking at the start of a
4854 ;; class definition, and not an ObjC method.
4855 ((and c-opt-method-key
4856 (re-search-forward c-opt-method-key search-end t)
4857 (not (c-in-literal class)))
4858 (setq foundp nil))
4859 ;; Check if this is an anonymous inner class.
4860 ((and c-opt-inexpr-class-key
4861 (looking-at c-opt-inexpr-class-key))
4862 (while (and (zerop (c-forward-token-2 1 t))
4863 (looking-at "(\\|\\w\\|\\s_\\|\\.")))
4864 (if (eq (point) search-end)
4865 ;; We're done. Just trap this case in the cond.
4866 nil
4867 ;; False alarm; all conditions aren't satisfied.
4868 (setq foundp nil)))
4869 ;; Its impossible to define a regexp for this, and
4870 ;; nearly so to do it programmatically.
4871 ;;
4872 ;; ; picks up forward decls
4873 ;; = picks up init lists
4874 ;; ) picks up return types
4875 ;; > picks up templates, but remember that we can
4876 ;; inherit from templates!
4877 ((let ((skipchars "^;=)"))
4878 ;; try to see if we found the `class' keyword
4879 ;; inside a template arg list
4880 (save-excursion
4881 (skip-chars-backward "^<>" search-start)
4882 (if (eq (char-before) ?<)
4883 (setq skipchars (concat skipchars ">"))))
4884 (while (progn
4885 (skip-chars-forward skipchars search-end)
4886 (c-in-literal class))
4887 (forward-char))
4888 (/= (point) search-end))
4889 (setq foundp nil))
4890 )))
4891 foundp))
4892 )))))
4893 6623
4894(defun c-inside-bracelist-p (containing-sexp paren-state) 6624(defun c-inside-bracelist-p (containing-sexp paren-state)
4895 ;; return the buffer position of the beginning of the brace list 6625 ;; return the buffer position of the beginning of the brace list
4896 ;; statement if we're inside a brace list, otherwise return nil. 6626 ;; statement if we're inside a brace list, otherwise return nil.
4897 ;; CONTAINING-SEXP is the buffer pos of the innermost containing 6627 ;; CONTAINING-SEXP is the buffer pos of the innermost containing
4898 ;; paren. BRACE-STATE is the remainder of the state of enclosing 6628 ;; paren. PAREN-STATE is the remainder of the state of enclosing
4899 ;; braces 6629 ;; braces
4900 ;; 6630 ;;
4901 ;; N.B.: This algorithm can potentially get confused by cpp macros 6631 ;; N.B.: This algorithm can potentially get confused by cpp macros
4902 ;; places in inconvenient locations. Its a trade-off we make for 6632 ;; placed in inconvenient locations. It's a trade-off we make for
4903 ;; speed. 6633 ;; speed.
6634 ;;
6635 ;; This function might do hidden buffer changes.
4904 (or 6636 (or
4905 ;; This will pick up brace list declarations. 6637 ;; This will pick up brace list declarations.
4906 (c-safe 6638 (c-safe
@@ -4977,7 +6709,9 @@ brace."
4977 (setq braceassignp 6709 (setq braceassignp
4978 (cond 6710 (cond
4979 ;; Check for operator = 6711 ;; Check for operator =
4980 ((looking-at "operator\\>[^_]") nil) 6712 ((and c-opt-op-identitier-prefix
6713 (looking-at c-opt-op-identitier-prefix))
6714 nil)
4981 ;; Check for `<opchar>= in Pike. 6715 ;; Check for `<opchar>= in Pike.
4982 ((and (c-major-mode-is 'pike-mode) 6716 ((and (c-major-mode-is 'pike-mode)
4983 (or (eq (char-after) ?`) 6717 (or (eq (char-after) ?`)
@@ -5033,6 +6767,8 @@ brace."
5033 ;; matching closer, but assumes it's correct if no balanced paren is 6767 ;; matching closer, but assumes it's correct if no balanced paren is
5034 ;; found (i.e. the case `({ ... } ... )' is detected as _not_ being 6768 ;; found (i.e. the case `({ ... } ... )' is detected as _not_ being
5035 ;; a special brace list). 6769 ;; a special brace list).
6770 ;;
6771 ;; This function might do hidden buffer changes.
5036 (if c-special-brace-lists 6772 (if c-special-brace-lists
5037 (condition-case () 6773 (condition-case ()
5038 (save-excursion 6774 (save-excursion
@@ -5087,82 +6823,103 @@ brace."
5087(defun c-looking-at-bos (&optional lim) 6823(defun c-looking-at-bos (&optional lim)
5088 ;; Return non-nil if between two statements or declarations, assuming 6824 ;; Return non-nil if between two statements or declarations, assuming
5089 ;; point is not inside a literal or comment. 6825 ;; point is not inside a literal or comment.
5090 (save-excursion 6826 ;;
5091 (c-backward-syntactic-ws lim) 6827 ;; Obsolete - `c-at-statement-start-p' or `c-at-expression-start-p'
5092 (or (bobp) 6828 ;; are recommended instead.
5093 ;; Return t if at the start inside some parenthesis expression 6829 ;;
5094 ;; too, to catch macros that have statements as arguments. 6830 ;; This function might do hidden buffer changes.
5095 (memq (char-before) '(?\; ?} ?\()) 6831 (c-at-statement-start-p))
5096 (and (eq (char-before) ?{) 6832(make-obsolete 'c-looking-at-bos 'c-at-statement-start-p)
5097 (not (and c-special-brace-lists 6833
5098 (progn (backward-char) 6834(defun c-looking-at-inexpr-block (lim containing-sexp &optional check-at-end)
5099 (c-looking-at-special-brace-list)))))))) 6835 ;; Return non-nil if we're looking at the beginning of a block
5100
5101(defun c-looking-at-inexpr-block (lim containing-sexp)
5102 ;; Returns non-nil if we're looking at the beginning of a block
5103 ;; inside an expression. The value returned is actually a cons of 6836 ;; inside an expression. The value returned is actually a cons of
5104 ;; either 'inlambda, 'inexpr-statement or 'inexpr-class and the 6837 ;; either 'inlambda, 'inexpr-statement or 'inexpr-class and the
5105 ;; position of the beginning of the construct. LIM limits the 6838 ;; position of the beginning of the construct.
5106 ;; backward search. CONTAINING-SEXP is the start position of the 6839 ;;
5107 ;; closest containing list. If it's nil, the containing paren isn't 6840 ;; LIM limits the backward search. CONTAINING-SEXP is the start
5108 ;; used to decide whether we're inside an expression or not. If 6841 ;; position of the closest containing list. If it's nil, the
5109 ;; both LIM and CONTAINING-SEXP is used, LIM needs to be farther 6842 ;; containing paren isn't used to decide whether we're inside an
5110 ;; back. 6843 ;; expression or not. If both LIM and CONTAINING-SEXP are used, LIM
6844 ;; needs to be farther back.
6845 ;;
6846 ;; If CHECK-AT-END is non-nil then extra checks at the end of the
6847 ;; brace block might be done. It should only be used when the
6848 ;; construct can be assumed to be complete, i.e. when the original
6849 ;; starting position was further down than that.
6850 ;;
6851 ;; This function might do hidden buffer changes.
6852
5111 (save-excursion 6853 (save-excursion
5112 (let ((res 'maybe) passed-bracket 6854 (let ((res 'maybe) passed-paren
5113 (closest-lim (or containing-sexp lim (point-min))) 6855 (closest-lim (or containing-sexp lim (point-min)))
5114 ;; Look at the character after point only as a last resort 6856 ;; Look at the character after point only as a last resort
5115 ;; when we can't disambiguate. 6857 ;; when we can't disambiguate.
5116 (block-follows (and (eq (char-after) ?{) (point)))) 6858 (block-follows (and (eq (char-after) ?{) (point))))
6859
5117 (while (and (eq res 'maybe) 6860 (while (and (eq res 'maybe)
5118 (progn (c-backward-syntactic-ws) 6861 (progn (c-backward-syntactic-ws)
5119 (> (point) closest-lim)) 6862 (> (point) closest-lim))
5120 (not (bobp)) 6863 (not (bobp))
5121 (progn (backward-char) 6864 (progn (backward-char)
5122 (looking-at "[\]\).]\\|\\w\\|\\s_")) 6865 (looking-at "[\]\).]\\|\\w\\|\\s_"))
5123 (progn (forward-char) 6866 (c-safe (forward-char)
5124 (goto-char (scan-sexps (point) -1)))) 6867 (goto-char (scan-sexps (point) -1))))
6868
5125 (setq res 6869 (setq res
5126 (cond 6870 (if (looking-at c-keywords-regexp)
5127 ((and block-follows 6871 (let ((kw-sym (c-keyword-sym (match-string 1))))
5128 c-opt-inexpr-class-key 6872 (cond
5129 (looking-at c-opt-inexpr-class-key)) 6873 ((and block-follows
5130 (and (not passed-bracket) 6874 (c-keyword-member kw-sym 'c-inexpr-class-kwds))
5131 (or (not (looking-at c-class-key)) 6875 (and (not (eq passed-paren ?\[))
5132 ;; If the class definition is at the start of 6876 (or (not (looking-at c-class-key))
5133 ;; a statement, we don't consider it an 6877 ;; If the class definition is at the start of
5134 ;; in-expression class. 6878 ;; a statement, we don't consider it an
5135 (let ((prev (point))) 6879 ;; in-expression class.
5136 (while (and 6880 (let ((prev (point)))
5137 (= (c-backward-token-2 1 nil closest-lim) 0) 6881 (while (and
5138 (eq (char-syntax (char-after)) ?w)) 6882 (= (c-backward-token-2 1 nil closest-lim) 0)
5139 (setq prev (point))) 6883 (eq (char-syntax (char-after)) ?w))
5140 (goto-char prev) 6884 (setq prev (point)))
5141 (not (c-looking-at-bos))) 6885 (goto-char prev)
5142 ;; Also, in Pike we treat it as an 6886 (not (c-at-statement-start-p)))
5143 ;; in-expression class if it's used in an 6887 ;; Also, in Pike we treat it as an
5144 ;; object clone expression. 6888 ;; in-expression class if it's used in an
5145 (save-excursion 6889 ;; object clone expression.
5146 (and (c-major-mode-is 'pike-mode) 6890 (save-excursion
5147 (progn (goto-char block-follows) 6891 (and check-at-end
5148 (zerop (c-forward-token-2 1 t))) 6892 (c-major-mode-is 'pike-mode)
5149 (eq (char-after) ?\()))) 6893 (progn (goto-char block-follows)
5150 (cons 'inexpr-class (point)))) 6894 (zerop (c-forward-token-2 1 t)))
5151 ((and c-opt-inexpr-block-key 6895 (eq (char-after) ?\())))
5152 (looking-at c-opt-inexpr-block-key)) 6896 (cons 'inexpr-class (point))))
5153 (cons 'inexpr-statement (point))) 6897 ((c-keyword-member kw-sym 'c-inexpr-block-kwds)
5154 ((and c-opt-lambda-key 6898 (when (not passed-paren)
5155 (looking-at c-opt-lambda-key)) 6899 (cons 'inexpr-statement (point))))
5156 (cons 'inlambda (point))) 6900 ((c-keyword-member kw-sym 'c-lambda-kwds)
5157 ((and c-opt-block-stmt-key 6901 (when (or (not passed-paren)
5158 (looking-at c-opt-block-stmt-key)) 6902 (eq passed-paren ?\())
5159 nil) 6903 (cons 'inlambda (point))))
5160 (t 6904 ((c-keyword-member kw-sym 'c-block-stmt-kwds)
5161 (if (eq (char-after) ?\[) 6905 nil)
5162 (setq passed-bracket t)) 6906 (t
5163 'maybe)))) 6907 'maybe)))
6908
6909 (if (looking-at "\\s(")
6910 (if passed-paren
6911 (if (and (eq passed-paren ?\[)
6912 (eq (char-after) ?\[))
6913 ;; Accept several square bracket sexps for
6914 ;; Java array initializations.
6915 'maybe)
6916 (setq passed-paren (char-after))
6917 'maybe)
6918 'maybe))))
6919
5164 (if (eq res 'maybe) 6920 (if (eq res 'maybe)
5165 (when (and block-follows 6921 (when (and c-recognize-paren-inexpr-blocks
6922 block-follows
5166 containing-sexp 6923 containing-sexp
5167 (eq (char-after containing-sexp) ?\()) 6924 (eq (char-after containing-sexp) ?\())
5168 (goto-char containing-sexp) 6925 (goto-char containing-sexp)
@@ -5174,12 +6931,15 @@ brace."
5174 (c-looking-at-special-brace-list))) 6931 (c-looking-at-special-brace-list)))
5175 nil 6932 nil
5176 (cons 'inexpr-statement (point)))) 6933 (cons 'inexpr-statement (point))))
6934
5177 res)))) 6935 res))))
5178 6936
5179(defun c-looking-at-inexpr-block-backward (paren-state) 6937(defun c-looking-at-inexpr-block-backward (paren-state)
5180 ;; Returns non-nil if we're looking at the end of an in-expression 6938 ;; Returns non-nil if we're looking at the end of an in-expression
5181 ;; block, otherwise the same as `c-looking-at-inexpr-block'. 6939 ;; block, otherwise the same as `c-looking-at-inexpr-block'.
5182 ;; PAREN-STATE is the paren state relevant at the current position. 6940 ;; PAREN-STATE is the paren state relevant at the current position.
6941 ;;
6942 ;; This function might do hidden buffer changes.
5183 (save-excursion 6943 (save-excursion
5184 ;; We currently only recognize a block. 6944 ;; We currently only recognize a block.
5185 (let ((here (point)) 6945 (let ((here (point))
@@ -5196,31 +6956,6 @@ brace."
5196 paren-state) 6956 paren-state)
5197 containing-sexp))))) 6957 containing-sexp)))))
5198 6958
5199(defun c-narrow-out-enclosing-class (paren-state lim)
5200 ;; Narrow the buffer so that the enclosing class is hidden. Uses
5201 ;; and returns the value from c-search-uplist-for-classkey.
5202 (setq paren-state (c-whack-state-after (point) paren-state))
5203 (let (inclass-p)
5204 (and paren-state
5205 (setq inclass-p (c-search-uplist-for-classkey paren-state))
5206 (narrow-to-region
5207 (progn
5208 (goto-char (1+ (aref inclass-p 1)))
5209 (c-skip-ws-forward lim)
5210 ;; if point is now left of the class opening brace, we're
5211 ;; hosed, so try a different tact
5212 (if (<= (point) (aref inclass-p 1))
5213 (progn
5214 (goto-char (1+ (aref inclass-p 1)))
5215 (c-forward-syntactic-ws lim)))
5216 (point))
5217 ;; end point is the end of the current line
5218 (progn
5219 (goto-char lim)
5220 (c-point 'eol))))
5221 ;; return the class vector
5222 inclass-p))
5223
5224 6959
5225;; `c-guess-basic-syntax' and the functions that precedes it below 6960;; `c-guess-basic-syntax' and the functions that precedes it below
5226;; implements the main decision tree for determining the syntactic 6961;; implements the main decision tree for determining the syntactic
@@ -5247,7 +6982,6 @@ brace."
5247(defun c-add-stmt-syntax (syntax-symbol 6982(defun c-add-stmt-syntax (syntax-symbol
5248 syntax-extra-args 6983 syntax-extra-args
5249 stop-at-boi-only 6984 stop-at-boi-only
5250 at-block-start
5251 containing-sexp 6985 containing-sexp
5252 paren-state) 6986 paren-state)
5253 ;; Do the generic processing to anchor the given syntax symbol on 6987 ;; Do the generic processing to anchor the given syntax symbol on
@@ -5264,177 +6998,170 @@ brace."
5264 ;; SYNTAX-EXTRA-ARGS are a list of the extra arguments for the 6998 ;; SYNTAX-EXTRA-ARGS are a list of the extra arguments for the
5265 ;; syntax symbol. They are appended after the anchor point. 6999 ;; syntax symbol. They are appended after the anchor point.
5266 ;; 7000 ;;
5267 ;; If STOP-AT-BOI-ONLY is nil, we might stop in the middle of the 7001 ;; If STOP-AT-BOI-ONLY is nil, we can stop in the middle of the line
5268 ;; line if another statement precedes the current one on this line. 7002 ;; if the current statement starts there.
7003 ;;
7004 ;; Note: It's not a problem if PAREN-STATE "overshoots"
7005 ;; CONTAINING-SEXP, i.e. contains info about parens further down.
5269 ;; 7006 ;;
5270 ;; If AT-BLOCK-START is non-nil, point is taken to be at the 7007 ;; This function might do hidden buffer changes.
5271 ;; beginning of a block or brace list, which then might be nested 7008
5272 ;; inside an expression. If AT-BLOCK-START is nil, this is found
5273 ;; out by checking whether the character at point is "{" or not.
5274 (if (= (point) (c-point 'boi)) 7009 (if (= (point) (c-point 'boi))
5275 ;; This is by far the most common case, so let's give it special 7010 ;; This is by far the most common case, so let's give it special
5276 ;; treatment. 7011 ;; treatment.
5277 (apply 'c-add-syntax syntax-symbol (point) syntax-extra-args) 7012 (apply 'c-add-syntax syntax-symbol (point) syntax-extra-args)
5278 7013
5279 (let ((savepos (point)) 7014 (let ((syntax-last c-syntactic-context)
5280 (syntax-last c-syntactic-context)
5281 (boi (c-point 'boi)) 7015 (boi (c-point 'boi))
5282 (prev-paren (if at-block-start ?{ (char-after))) 7016 ;; Set when we're on a label, so that we don't stop there.
5283 step-type step-tmp at-comment special-list) 7017 ;; FIXME: To be complete we should check if we're on a label
5284 (apply 'c-add-syntax syntax-symbol nil syntax-extra-args) 7018 ;; now at the start.
5285 7019 on-label)
5286 ;; Begin by skipping any labels and containing statements that
5287 ;; are on the same line.
5288 (while (and (/= (point) boi)
5289 (if (memq (setq step-tmp
5290 (c-beginning-of-statement-1 boi nil t))
5291 '(up label))
5292 t
5293 (goto-char savepos)
5294 nil)
5295 (/= (point) savepos))
5296 (setq savepos (point)
5297 step-type step-tmp))
5298
5299 (catch 'done
5300 ;; Loop if we have to back out of the containing block.
5301 (while
5302 (progn
5303 7020
5304 ;; Loop if we have to back up another statement. 7021 (apply 'c-add-syntax syntax-symbol nil syntax-extra-args)
5305 (while
5306 (progn
5307 7022
5308 ;; Always start by skipping over any comments that 7023 ;; Loop while we have to back out of containing blocks.
5309 ;; stands between the statement and boi. 7024 (while
5310 (while (and (/= (setq savepos (point)) boi) 7025 (and
5311 (c-backward-single-comment)) 7026 (catch 'back-up-block
5312 (setq at-comment t 7027
5313 boi (c-point 'boi))) 7028 ;; Loop while we have to back up statements.
5314 (goto-char savepos) 7029 (while (or (/= (point) boi)
5315 7030 on-label
5316 (and 7031 (looking-at c-comment-start-regexp))
5317 (or at-comment 7032
5318 (eq step-type 'label) 7033 ;; Skip past any comments that stands between the
5319 (/= savepos boi)) 7034 ;; statement start and boi.
5320 7035 (let ((savepos (point)))
5321 (let ((save-step-type step-type)) 7036 (while (and (/= savepos boi)
5322 ;; Current position might not be good enough; 7037 (c-backward-single-comment))
5323 ;; skip backward another statement. 7038 (setq savepos (point)
5324 (setq step-type (c-beginning-of-statement-1 7039 boi (c-point 'boi)))
5325 containing-sexp)) 7040 (goto-char savepos))
5326 7041
5327 (if (and (not stop-at-boi-only) 7042 ;; Skip to the beginning of this statement or backward
5328 (/= savepos boi) 7043 ;; another one.
5329 (memq step-type '(up previous))) 7044 (let ((old-pos (point))
5330 ;; If stop-at-boi-only is nil, we shouldn't 7045 (old-boi boi)
5331 ;; back up over previous or containing 7046 (step-type (c-beginning-of-statement-1 containing-sexp)))
5332 ;; statements to try to reach boi, so go 7047 (setq boi (c-point 'boi)
5333 ;; back to the last position and exit. 7048 on-label (eq step-type 'label))
7049
7050 (cond ((= (point) old-pos)
7051 ;; If we didn't move we're at the start of a block and
7052 ;; have to continue outside it.
7053 (throw 'back-up-block t))
7054
7055 ((and (eq step-type 'up)
7056 (>= (point) old-boi)
7057 (looking-at "else\\>[^_]")
7058 (save-excursion
7059 (goto-char old-pos)
7060 (looking-at "if\\>[^_]")))
7061 ;; Special case to avoid deeper and deeper indentation
7062 ;; of "else if" clauses.
7063 )
7064
7065 ((and (not stop-at-boi-only)
7066 (/= old-pos old-boi)
7067 (memq step-type '(up previous)))
7068 ;; If stop-at-boi-only is nil, we shouldn't back up
7069 ;; over previous or containing statements to try to
7070 ;; reach boi, so go back to the last position and
7071 ;; exit.
7072 (goto-char old-pos)
7073 (throw 'back-up-block nil))
7074
7075 (t
7076 (if (and (not stop-at-boi-only)
7077 (memq step-type '(up previous beginning)))
7078 ;; If we've moved into another statement then we
7079 ;; should no longer try to stop in the middle of a
7080 ;; line.
7081 (setq stop-at-boi-only t))
7082
7083 ;; Record this as a substatement if we skipped up one
7084 ;; level.
7085 (when (eq step-type 'up)
7086 (c-add-syntax 'substatement nil))))
7087 )))
7088
7089 containing-sexp)
7090
7091 ;; Now we have to go out of this block.
7092 (goto-char containing-sexp)
7093
7094 ;; Don't stop in the middle of a special brace list opener
7095 ;; like "({".
7096 (when c-special-brace-lists
7097 (let ((special-list (c-looking-at-special-brace-list)))
7098 (when (and special-list
7099 (< (car (car special-list)) (point)))
7100 (setq containing-sexp (car (car special-list)))
7101 (goto-char containing-sexp))))
7102
7103 (setq paren-state (c-whack-state-after containing-sexp paren-state)
7104 containing-sexp (c-most-enclosing-brace paren-state)
7105 boi (c-point 'boi))
7106
7107 ;; Analyze the construct in front of the block we've stepped out
7108 ;; from and add the right syntactic element for it.
7109 (let ((paren-pos (point))
7110 (paren-char (char-after))
7111 step-type)
7112
7113 (if (eq paren-char ?\()
7114 ;; Stepped out of a parenthesis block, so we're in an
7115 ;; expression now.
7116 (progn
7117 (when (/= paren-pos boi)
7118 (if (and c-recognize-paren-inexpr-blocks
5334 (progn 7119 (progn
5335 (goto-char savepos) 7120 (c-backward-syntactic-ws containing-sexp)
5336 nil) 7121 (or (not (looking-at "\\>"))
5337 (if (and (not stop-at-boi-only) 7122 (not (c-on-identifier))))
5338 (memq step-type '(up previous beginning))) 7123 (save-excursion
5339 ;; If we've moved into another statement 7124 (goto-char (1+ paren-pos))
5340 ;; then we should no longer try to stop 7125 (c-forward-syntactic-ws)
5341 ;; after boi. 7126 (eq (char-after) ?{)))
5342 (setq stop-at-boi-only t)) 7127 ;; Stepped out of an in-expression statement. This
5343 7128 ;; syntactic element won't get an anchor pos.
5344 ;; Record this a substatement if we skipped up 7129 (c-add-syntax 'inexpr-statement)
5345 ;; one level, but not if we're still on the 7130
5346 ;; same line. This so e.g. a sequence of "else 7131 ;; A parenthesis normally belongs to an arglist.
5347 ;; if" clauses won't indent deeper and deeper. 7132 (c-add-syntax 'arglist-cont-nonempty nil paren-pos)))
5348 (when (and (eq step-type 'up) 7133
5349 (< (point) boi)) 7134 (goto-char (max boi
5350 (c-add-syntax 'substatement nil)) 7135 (if containing-sexp
5351 7136 (1+ containing-sexp)
5352 (setq boi (c-point 'boi)) 7137 (point-min))))
5353 (if (= (point) savepos) 7138 (setq step-type 'same
5354 (progn 7139 on-label nil))
5355 (setq step-type save-step-type) 7140
5356 nil) 7141 (setq step-type (c-beginning-of-statement-1 containing-sexp)
5357 t))))) 7142 on-label (eq step-type 'label))
5358 7143
5359 (setq savepos (point) 7144 (if (and (eq step-type 'same)
5360 at-comment nil)) 7145 (/= paren-pos (point)))
5361 (setq at-comment nil) 7146 (save-excursion
5362 7147 (goto-char paren-pos)
5363 (when (and containing-sexp 7148 (let ((inexpr (c-looking-at-inexpr-block
5364 (if (memq step-type '(nil same)) 7149 (c-safe-position containing-sexp
5365 (/= (point) boi) 7150 paren-state)
5366 (eq step-type 'label))) 7151 containing-sexp)))
5367 (goto-char containing-sexp) 7152 (if (and inexpr
5368 7153 (not (eq (car inexpr) 'inlambda)))
5369 ;; Don't stop in the middle of a special brace list opener 7154 (c-add-syntax 'statement-block-intro nil)
5370 ;; like "({". 7155 (c-add-syntax 'defun-block-intro nil))))
5371 (when (and c-special-brace-lists 7156 (c-add-syntax 'statement-block-intro nil)))
5372 (setq special-list 7157
5373 (c-looking-at-special-brace-list))) 7158 (if (= paren-pos boi)
5374 (setq containing-sexp (car (car special-list))) 7159 ;; Always done if the open brace was at boi. The
5375 (goto-char containing-sexp)) 7160 ;; c-beginning-of-statement-1 call above is necessary
5376 7161 ;; anyway, to decide the type of block-intro to add.
5377 (setq paren-state (c-whack-state-after containing-sexp 7162 (goto-char paren-pos)
5378 paren-state) 7163 (setq boi (c-point 'boi)))
5379 containing-sexp (c-most-enclosing-brace paren-state) 7164 ))
5380 savepos (point)
5381 boi (c-point 'boi))
5382
5383 (if (eq (setq prev-paren (char-after)) ?\()
5384 (progn
5385 (c-backward-syntactic-ws containing-sexp)
5386 (when (/= savepos boi)
5387 (if (and (or (not (looking-at "\\>"))
5388 (not (c-on-identifier)))
5389 (not special-list)
5390 (save-excursion
5391 (c-forward-syntactic-ws)
5392 (forward-char)
5393 (c-forward-syntactic-ws)
5394 (eq (char-after) ?{)))
5395 ;; We're in an in-expression statement.
5396 ;; This syntactic element won't get an anchor pos.
5397 (c-add-syntax 'inexpr-statement)
5398 (c-add-syntax 'arglist-cont-nonempty nil savepos)))
5399 (goto-char (max boi
5400 (if containing-sexp
5401 (1+ containing-sexp)
5402 (point-min))))
5403 (setq step-type 'same))
5404 (setq step-type
5405 (c-beginning-of-statement-1 containing-sexp)))
5406
5407 (let ((at-bod (and (eq step-type 'same)
5408 (/= savepos (point))
5409 (eq prev-paren ?{))))
5410
5411 (when (= savepos boi)
5412 ;; If the open brace was at boi, we're always
5413 ;; done. The c-beginning-of-statement-1 call
5414 ;; above is necessary anyway, to decide the type
5415 ;; of block-intro to add.
5416 (goto-char savepos)
5417 (setq savepos nil))
5418
5419 (when (eq prev-paren ?{)
5420 (c-add-syntax (if at-bod
5421 'defun-block-intro
5422 'statement-block-intro)
5423 nil))
5424
5425 (when (and (not at-bod) savepos)
5426 ;; Loop if the brace wasn't at boi, and we didn't
5427 ;; arrive at a defun block.
5428 (if (eq step-type 'same)
5429 ;; Avoid backing up another sexp if the point
5430 ;; we're at now is found to be good enough in
5431 ;; the loop above.
5432 (setq step-type nil))
5433 (if (and (not stop-at-boi-only)
5434 (memq step-type '(up previous beginning)))
5435 (setq stop-at-boi-only t))
5436 (setq boi (c-point 'boi)))))
5437 )))
5438 7165
5439 ;; Fill in the current point as the anchor for all the symbols 7166 ;; Fill in the current point as the anchor for all the symbols
5440 ;; added above. 7167 ;; added above.
@@ -5443,30 +7170,33 @@ brace."
5443 (if (cdr (car p)) 7170 (if (cdr (car p))
5444 (setcar (cdr (car p)) (point))) 7171 (setcar (cdr (car p)) (point)))
5445 (setq p (cdr p)))) 7172 (setq p (cdr p))))
5446
5447 ))) 7173 )))
5448 7174
5449(defun c-add-class-syntax (symbol classkey paren-state) 7175(defun c-add-class-syntax (symbol
7176 containing-decl-open
7177 containing-decl-start
7178 containing-decl-kwd
7179 paren-state)
5450 ;; The inclass and class-close syntactic symbols are added in 7180 ;; The inclass and class-close syntactic symbols are added in
5451 ;; several places and some work is needed to fix everything. 7181 ;; several places and some work is needed to fix everything.
5452 ;; Therefore it's collected here. 7182 ;; Therefore it's collected here.
5453 (save-restriction 7183 ;;
5454 (widen) 7184 ;; This function might do hidden buffer changes.
5455 (let (inexpr anchor containing-sexp) 7185 (goto-char containing-decl-open)
5456 (goto-char (aref classkey 1)) 7186 (if (and (eq symbol 'inclass) (= (point) (c-point 'boi)))
5457 (if (and (eq symbol 'inclass) (= (point) (c-point 'boi))) 7187 (progn
5458 (c-add-syntax symbol (setq anchor (point))) 7188 (c-add-syntax symbol containing-decl-open)
5459 (c-add-syntax symbol (setq anchor (aref classkey 0))) 7189 containing-decl-open)
5460 (if (and c-opt-inexpr-class-key 7190 (goto-char containing-decl-start)
5461 (setq containing-sexp (c-most-enclosing-brace paren-state 7191 ;; Ought to use `c-add-stmt-syntax' instead of backing up to boi
5462 (point)) 7192 ;; here, but we have to do like this for compatibility.
5463 inexpr (cdr (c-looking-at-inexpr-block 7193 (back-to-indentation)
5464 (c-safe-position containing-sexp 7194 (c-add-syntax symbol (point))
5465 paren-state) 7195 (if (and (c-keyword-member containing-decl-kwd
5466 containing-sexp))) 7196 'c-inexpr-class-kwds)
5467 (/= inexpr (c-point 'boi inexpr))) 7197 (/= containing-decl-start (c-point 'boi containing-decl-start)))
5468 (c-add-syntax 'inexpr-class))) 7198 (c-add-syntax 'inexpr-class))
5469 anchor))) 7199 (point)))
5470 7200
5471(defun c-guess-continued-construct (indent-point 7201(defun c-guess-continued-construct (indent-point
5472 char-after-ip 7202 char-after-ip
@@ -5476,6 +7206,8 @@ brace."
5476 ;; This function contains the decision tree reached through both 7206 ;; This function contains the decision tree reached through both
5477 ;; cases 18 and 10. It's a continued statement or top level 7207 ;; cases 18 and 10. It's a continued statement or top level
5478 ;; construct of some kind. 7208 ;; construct of some kind.
7209 ;;
7210 ;; This function might do hidden buffer changes.
5479 7211
5480 (let (special-brace-list) 7212 (let (special-brace-list)
5481 (goto-char indent-point) 7213 (goto-char indent-point)
@@ -5492,11 +7224,9 @@ brace."
5492 (cond 7224 (cond
5493 ;; CASE B.1: class-open 7225 ;; CASE B.1: class-open
5494 ((save-excursion 7226 ((save-excursion
5495 (skip-chars-forward "{") 7227 (and (eq (char-after) ?{)
5496 (let ((decl (c-search-uplist-for-classkey (c-parse-state)))) 7228 (c-looking-at-decl-block containing-sexp t)
5497 (and decl 7229 (setq beg-of-same-or-containing-stmt (point))))
5498 (setq beg-of-same-or-containing-stmt (aref decl 0)))
5499 ))
5500 (c-add-syntax 'class-open beg-of-same-or-containing-stmt)) 7230 (c-add-syntax 'class-open beg-of-same-or-containing-stmt))
5501 7231
5502 ;; CASE B.2: brace-list-open 7232 ;; CASE B.2: brace-list-open
@@ -5518,26 +7248,23 @@ brace."
5518 ;; for the auto newline feature. 7248 ;; for the auto newline feature.
5519 'brace-list-open 7249 'brace-list-open
5520 'statement-cont) 7250 'statement-cont)
5521 nil nil nil 7251 nil nil
5522 containing-sexp paren-state)) 7252 containing-sexp paren-state))
5523 7253
5524 ;; CASE B.3: The body of a function declared inside a normal 7254 ;; CASE B.3: The body of a function declared inside a normal
5525 ;; block. Can occur e.g. in Pike and when using gcc 7255 ;; block. Can occur e.g. in Pike and when using gcc
5526 ;; extensions, but watch out for macros followed by blocks. 7256 ;; extensions, but watch out for macros followed by blocks.
5527 ;; C.f. cases E, 16F and 17G. 7257 ;; C.f. cases E, 16F and 17G.
5528 ((and (not (c-looking-at-bos)) 7258 ((and (not (c-at-statement-start-p))
5529 (eq (c-beginning-of-statement-1 containing-sexp nil nil t) 7259 (eq (c-beginning-of-statement-1 containing-sexp nil nil t)
5530 'same) 7260 'same)
5531 (save-excursion 7261 (save-excursion
5532 ;; Look for a type followed by a symbol, i.e. the start of a 7262 (let ((c-recognize-typeless-decls nil))
5533 ;; function declaration. Doesn't work for declarations like 7263 ;; Turn off recognition of constructs that lacks a
5534 ;; "int *foo() ..."; we'd need to refactor the more competent 7264 ;; type in this case, since that's more likely to be
5535 ;; analysis in `c-font-lock-declarations' for that. 7265 ;; a macro followed by a block.
5536 (and (c-forward-type) 7266 (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil))))
5537 (progn 7267 (c-add-stmt-syntax 'defun-open nil t
5538 (c-forward-syntactic-ws)
5539 (looking-at c-symbol-start)))))
5540 (c-add-stmt-syntax 'defun-open nil t nil
5541 containing-sexp paren-state)) 7268 containing-sexp paren-state))
5542 7269
5543 ;; CASE B.4: Continued statement with block open. The most 7270 ;; CASE B.4: Continued statement with block open. The most
@@ -5547,7 +7274,7 @@ brace."
5547 ;; followed by a block which makes it very similar to a 7274 ;; followed by a block which makes it very similar to a
5548 ;; statement with a substatement block. 7275 ;; statement with a substatement block.
5549 (t 7276 (t
5550 (c-add-stmt-syntax 'substatement-open nil nil nil 7277 (c-add-stmt-syntax 'substatement-open nil nil
5551 containing-sexp paren-state)) 7278 containing-sexp paren-state))
5552 )) 7279 ))
5553 7280
@@ -5577,94 +7304,89 @@ brace."
5577 ;; prototype in a code block without resorting to this. 7304 ;; prototype in a code block without resorting to this.
5578 (c-forward-syntactic-ws) 7305 (c-forward-syntactic-ws)
5579 (eq (char-after) ?{)) 7306 (eq (char-after) ?{))
5580 (not (c-looking-at-bos)) 7307 (not (c-at-statement-start-p))
5581 (eq (c-beginning-of-statement-1 containing-sexp nil nil t) 7308 (eq (c-beginning-of-statement-1 containing-sexp nil nil t)
5582 'same) 7309 'same)
5583 (save-excursion 7310 (save-excursion
5584 ;; Look for a type followed by a symbol, i.e. the start of a 7311 (let ((c-recognize-typeless-decls nil))
5585 ;; function declaration. Doesn't work for declarations like "int 7312 ;; Turn off recognition of constructs that lacks a
5586 ;; *foo() ..."; we'd need to refactor the more competent analysis 7313 ;; type in this case, since that's more likely to be
5587 ;; in `c-font-lock-declarations' for that. 7314 ;; a macro followed by a block.
5588 (and (c-forward-type) 7315 (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil))))
5589 (progn 7316 (c-add-stmt-syntax 'func-decl-cont nil t
5590 (c-forward-syntactic-ws)
5591 (looking-at c-symbol-start)))))
5592 (c-add-stmt-syntax 'func-decl-cont nil t nil
5593 containing-sexp paren-state)) 7317 containing-sexp paren-state))
5594 7318
5595 ;; CASE D: continued statement. 7319 ;; CASE D: continued statement.
5596 (t 7320 (t
5597 (c-beginning-of-statement-1 containing-sexp) 7321 (c-beginning-of-statement-1 containing-sexp)
5598 (c-add-stmt-syntax 'statement-cont nil nil nil 7322 (c-add-stmt-syntax 'statement-cont nil nil
5599 containing-sexp paren-state)) 7323 containing-sexp paren-state))
5600 ))) 7324 )))
5601 7325
7326;; The next autoload was added by RMS on 2005/8/9 - don't know why (ACM,
7327;; 2005/11/29).
5602;;;###autoload 7328;;;###autoload
5603(defun c-guess-basic-syntax () 7329(defun c-guess-basic-syntax ()
5604 "Return the syntactic context of the current line. 7330 "Return the syntactic context of the current line."
5605This function does not do any hidden buffer changes."
5606 (save-excursion 7331 (save-excursion
5607 (save-restriction
5608 (beginning-of-line) 7332 (beginning-of-line)
5609 (c-save-buffer-state 7333 (c-save-buffer-state
5610 ((indent-point (point)) 7334 ((indent-point (point))
5611 (case-fold-search nil) 7335 (case-fold-search nil)
7336 ;; A whole ugly bunch of various temporary variables. Have
7337 ;; to declare them here since it's not possible to declare
7338 ;; a variable with only the scope of a cond test and the
7339 ;; following result clauses, and most of this function is a
7340 ;; single gigantic cond. :P
7341 literal char-before-ip before-ws-ip char-after-ip macro-start
7342 in-macro-expr c-syntactic-context placeholder c-in-literal-cache
7343 step-type tmpsymbol keyword injava-inher special-brace-list tmp-pos
7344 ;; The following record some positions for the containing
7345 ;; declaration block if we're directly within one:
7346 ;; `containing-decl-open' is the position of the open
7347 ;; brace. `containing-decl-start' is the start of the
7348 ;; declaration. `containing-decl-kwd' is the keyword
7349 ;; symbol of the keyword that tells what kind of block it
7350 ;; is.
7351 containing-decl-open
7352 containing-decl-start
7353 containing-decl-kwd
7354 ;; The open paren of the closest surrounding sexp or nil if
7355 ;; there is none.
7356 containing-sexp
7357 ;; The position after the closest preceding brace sexp
7358 ;; (nested sexps are ignored), or the position after
7359 ;; `containing-sexp' if there is none, or (point-min) if
7360 ;; `containing-sexp' is nil.
7361 lim
7362 ;; The paren state outside `containing-sexp', or at
7363 ;; `indent-point' if `containing-sexp' is nil.
5612 (paren-state (c-parse-state)) 7364 (paren-state (c-parse-state))
5613 literal containing-sexp char-before-ip char-after-ip lim
5614 c-syntactic-context placeholder c-in-literal-cache step-type
5615 tmpsymbol keyword injava-inher special-brace-list
5616 ;; narrow out any enclosing class or extern "C" block
5617 (inclass-p (c-narrow-out-enclosing-class paren-state
5618 indent-point))
5619 ;; `c-state-cache' is shadowed here so that we don't
5620 ;; throw it away due to the narrowing that might be done
5621 ;; by the function above. That means we must not do any
5622 ;; changes during the execution of this function, since
5623 ;; `c-invalidate-state-cache' then would change this local
5624 ;; variable and leave a bogus value in the global one.
5625 (c-state-cache (if inclass-p
5626 (c-whack-state-before (point-min) paren-state)
5627 paren-state))
5628 (c-state-cache-start (point-min))
5629 inenclosing-p macro-start in-macro-expr
5630 ;; There's always at most one syntactic element which got 7365 ;; There's always at most one syntactic element which got
5631 ;; a relpos. It's stored in syntactic-relpos. 7366 ;; an anchor pos. It's stored in syntactic-relpos.
5632 syntactic-relpos 7367 syntactic-relpos
5633 (c-stmt-delim-chars c-stmt-delim-chars)) 7368 (c-stmt-delim-chars c-stmt-delim-chars))
5634 ;; Check for meta top-level enclosing constructs such as 7369
5635 ;; extern language definitions. 7370 ;; Check if we're directly inside an enclosing declaration
5636 (save-excursion 7371 ;; level block.
5637 (save-restriction 7372 (when (and (setq containing-sexp
5638 (widen) 7373 (c-most-enclosing-brace paren-state))
5639 (when (and inclass-p 7374 (progn
5640 (progn 7375 (goto-char containing-sexp)
5641 (goto-char (aref inclass-p 0)) 7376 (eq (char-after) ?{))
5642 (looking-at c-other-decl-block-key))) 7377 (setq placeholder
5643 (setq inenclosing-p (match-string 1)) 7378 (c-looking-at-decl-block
5644 (if (string-equal inenclosing-p "extern") 7379 (c-most-enclosing-brace paren-state
5645 ;; Compatibility with legacy choice of name for the 7380 containing-sexp)
5646 ;; extern-lang syntactic symbols. 7381 t)))
5647 (setq inenclosing-p "extern-lang"))))) 7382 (setq containing-decl-open containing-sexp
5648 7383 containing-decl-start (point)
5649 ;; Init some position variables: 7384 containing-sexp nil)
5650 ;; 7385 (goto-char placeholder)
5651 ;; containing-sexp is the open paren of the closest 7386 (setq containing-decl-kwd (and (looking-at c-keywords-regexp)
5652 ;; surrounding sexp or nil if there is none that hasn't been 7387 (c-keyword-sym (match-string 1)))))
5653 ;; narrowed out. 7388
5654 ;; 7389 ;; Init some position variables.
5655 ;; lim is the position after the closest preceding brace sexp
5656 ;; (nested sexps are ignored), or the position after
5657 ;; containing-sexp if there is none, or (point-min) if
5658 ;; containing-sexp is nil.
5659 ;;
5660 ;; c-state-cache is the state from c-parse-state at
5661 ;; indent-point, without any parens outside the region
5662 ;; narrowed by c-narrow-out-enclosing-class.
5663 ;;
5664 ;; paren-state is the state from c-parse-state outside
5665 ;; containing-sexp, or at indent-point if containing-sexp is
5666 ;; nil. paren-state is not limited to the narrowed region, as
5667 ;; opposed to c-state-cache.
5668 (if c-state-cache 7390 (if c-state-cache
5669 (progn 7391 (progn
5670 (setq containing-sexp (car paren-state) 7392 (setq containing-sexp (car paren-state)
@@ -5697,7 +7419,8 @@ This function does not do any hidden buffer changes."
5697 ;; the most likely position to perform the majority of tests 7419 ;; the most likely position to perform the majority of tests
5698 (goto-char indent-point) 7420 (goto-char indent-point)
5699 (c-backward-syntactic-ws lim) 7421 (c-backward-syntactic-ws lim)
5700 (setq char-before-ip (char-before)) 7422 (setq before-ws-ip (point)
7423 char-before-ip (char-before))
5701 (goto-char indent-point) 7424 (goto-char indent-point)
5702 (skip-chars-forward " \t") 7425 (skip-chars-forward " \t")
5703 (setq char-after-ip (char-after)) 7426 (setq char-after-ip (char-after))
@@ -5707,9 +7430,11 @@ This function does not do any hidden buffer changes."
5707 7430
5708 ;; now figure out syntactic qualities of the current line 7431 ;; now figure out syntactic qualities of the current line
5709 (cond 7432 (cond
7433
5710 ;; CASE 1: in a string. 7434 ;; CASE 1: in a string.
5711 ((eq literal 'string) 7435 ((eq literal 'string)
5712 (c-add-syntax 'string (c-point 'bopl))) 7436 (c-add-syntax 'string (c-point 'bopl)))
7437
5713 ;; CASE 2: in a C or C++ style comment. 7438 ;; CASE 2: in a C or C++ style comment.
5714 ((and (memq literal '(c c++)) 7439 ((and (memq literal '(c c++))
5715 ;; This is a kludge for XEmacs where we use 7440 ;; This is a kludge for XEmacs where we use
@@ -5722,6 +7447,7 @@ This function does not do any hidden buffer changes."
5722 ;; we're inside a comment. 7447 ;; we're inside a comment.
5723 (setq placeholder (c-literal-limits lim))) 7448 (setq placeholder (c-literal-limits lim)))
5724 (c-add-syntax literal (car placeholder))) 7449 (c-add-syntax literal (car placeholder)))
7450
5725 ;; CASE 3: in a cpp preprocessor macro continuation. 7451 ;; CASE 3: in a cpp preprocessor macro continuation.
5726 ((and (save-excursion 7452 ((and (save-excursion
5727 (when (c-beginning-of-macro) 7453 (when (c-beginning-of-macro)
@@ -5747,11 +7473,13 @@ This function does not do any hidden buffer changes."
5747 nil))))) 7473 nil)))))
5748 (c-add-syntax tmpsymbol macro-start) 7474 (c-add-syntax tmpsymbol macro-start)
5749 (setq macro-start nil)) 7475 (setq macro-start nil))
7476
5750 ;; CASE 11: an else clause? 7477 ;; CASE 11: an else clause?
5751 ((looking-at "else\\>[^_]") 7478 ((looking-at "else\\>[^_]")
5752 (c-beginning-of-statement-1 containing-sexp) 7479 (c-beginning-of-statement-1 containing-sexp)
5753 (c-add-stmt-syntax 'else-clause nil t nil 7480 (c-add-stmt-syntax 'else-clause nil t
5754 containing-sexp paren-state)) 7481 containing-sexp paren-state))
7482
5755 ;; CASE 12: while closure of a do/while construct? 7483 ;; CASE 12: while closure of a do/while construct?
5756 ((and (looking-at "while\\>[^_]") 7484 ((and (looking-at "while\\>[^_]")
5757 (save-excursion 7485 (save-excursion
@@ -5759,8 +7487,9 @@ This function does not do any hidden buffer changes."
5759 'beginning) 7487 'beginning)
5760 (setq placeholder (point))))) 7488 (setq placeholder (point)))))
5761 (goto-char placeholder) 7489 (goto-char placeholder)
5762 (c-add-stmt-syntax 'do-while-closure nil t nil 7490 (c-add-stmt-syntax 'do-while-closure nil t
5763 containing-sexp paren-state)) 7491 containing-sexp paren-state))
7492
5764 ;; CASE 13: A catch or finally clause? This case is simpler 7493 ;; CASE 13: A catch or finally clause? This case is simpler
5765 ;; than if-else and do-while, because a block is required 7494 ;; than if-else and do-while, because a block is required
5766 ;; after every try, catch and finally. 7495 ;; after every try, catch and finally.
@@ -5782,14 +7511,14 @@ This function does not do any hidden buffer changes."
5782 (looking-at "\\(try\\|catch\\)\\>[^_]") 7511 (looking-at "\\(try\\|catch\\)\\>[^_]")
5783 (setq placeholder (point)))) 7512 (setq placeholder (point))))
5784 (goto-char placeholder) 7513 (goto-char placeholder)
5785 (c-add-stmt-syntax 'catch-clause nil t nil 7514 (c-add-stmt-syntax 'catch-clause nil t
5786 containing-sexp paren-state)) 7515 containing-sexp paren-state))
7516
5787 ;; CASE 18: A substatement we can recognize by keyword. 7517 ;; CASE 18: A substatement we can recognize by keyword.
5788 ((save-excursion 7518 ((save-excursion
5789 (and c-opt-block-stmt-key 7519 (and c-opt-block-stmt-key
5790 (if (c-mode-is-new-awk-p) 7520 (not (eq char-before-ip ?\;))
5791 (c-awk-prev-line-incomplete-p containing-sexp) ; ACM 2002/3/29 7521 (not (c-at-vsemi-p before-ws-ip))
5792 (not (eq char-before-ip ?\;)))
5793 (not (memq char-after-ip '(?\) ?\] ?,))) 7522 (not (memq char-after-ip '(?\) ?\] ?,)))
5794 (or (not (eq char-before-ip ?})) 7523 (or (not (eq char-before-ip ?}))
5795 (c-looking-at-inexpr-block-backward c-state-cache)) 7524 (c-looking-at-inexpr-block-backward c-state-cache))
@@ -5826,23 +7555,25 @@ This function does not do any hidden buffer changes."
5826 (and (zerop (c-forward-token-2 1 nil)) 7555 (and (zerop (c-forward-token-2 1 nil))
5827 (eq (char-after) ?\()) 7556 (eq (char-after) ?\())
5828 (looking-at c-opt-block-stmt-key)))) 7557 (looking-at c-opt-block-stmt-key))))
7558
5829 (if (eq step-type 'up) 7559 (if (eq step-type 'up)
5830 ;; CASE 18A: Simple substatement. 7560 ;; CASE 18A: Simple substatement.
5831 (progn 7561 (progn
5832 (goto-char placeholder) 7562 (goto-char placeholder)
5833 (cond 7563 (cond
5834 ((eq char-after-ip ?{) 7564 ((eq char-after-ip ?{)
5835 (c-add-stmt-syntax 'substatement-open nil nil nil 7565 (c-add-stmt-syntax 'substatement-open nil nil
5836 containing-sexp paren-state)) 7566 containing-sexp paren-state))
5837 ((save-excursion 7567 ((save-excursion
5838 (goto-char indent-point) 7568 (goto-char indent-point)
5839 (back-to-indentation) 7569 (back-to-indentation)
5840 (looking-at c-label-key)) 7570 (c-forward-label))
5841 (c-add-stmt-syntax 'substatement-label nil nil nil 7571 (c-add-stmt-syntax 'substatement-label nil nil
5842 containing-sexp paren-state)) 7572 containing-sexp paren-state))
5843 (t 7573 (t
5844 (c-add-stmt-syntax 'substatement nil nil nil 7574 (c-add-stmt-syntax 'substatement nil nil
5845 containing-sexp paren-state)))) 7575 containing-sexp paren-state))))
7576
5846 ;; CASE 18B: Some other substatement. This is shared 7577 ;; CASE 18B: Some other substatement. This is shared
5847 ;; with case 10. 7578 ;; with case 10.
5848 (c-guess-continued-construct indent-point 7579 (c-guess-continued-construct indent-point
@@ -5850,14 +7581,66 @@ This function does not do any hidden buffer changes."
5850 placeholder 7581 placeholder
5851 lim 7582 lim
5852 paren-state))) 7583 paren-state)))
7584
7585 ;; CASE 14: A case or default label
7586 ((looking-at c-label-kwds-regexp)
7587 (if containing-sexp
7588 (progn
7589 (goto-char containing-sexp)
7590 (setq lim (c-most-enclosing-brace c-state-cache
7591 containing-sexp))
7592 (c-backward-to-block-anchor lim)
7593 (c-add-stmt-syntax 'case-label nil t lim paren-state))
7594 ;; Got a bogus label at the top level. In lack of better
7595 ;; alternatives, anchor it on (point-min).
7596 (c-add-syntax 'case-label (point-min))))
7597
7598 ;; CASE 15: any other label
7599 ((save-excursion
7600 (back-to-indentation)
7601 (and (not (looking-at c-syntactic-ws-start))
7602 (c-forward-label)))
7603 (cond (containing-decl-open
7604 (setq placeholder (c-add-class-syntax 'inclass
7605 containing-decl-open
7606 containing-decl-start
7607 containing-decl-kwd
7608 paren-state))
7609 ;; Append access-label with the same anchor point as
7610 ;; inclass gets.
7611 (c-append-syntax 'access-label placeholder))
7612
7613 (containing-sexp
7614 (goto-char containing-sexp)
7615 (setq lim (c-most-enclosing-brace c-state-cache
7616 containing-sexp))
7617 (save-excursion
7618 (setq tmpsymbol
7619 (if (and (eq (c-beginning-of-statement-1 lim) 'up)
7620 (looking-at "switch\\>[^_]"))
7621 ;; If the surrounding statement is a switch then
7622 ;; let's analyze all labels as switch labels, so
7623 ;; that they get lined up consistently.
7624 'case-label
7625 'label)))
7626 (c-backward-to-block-anchor lim)
7627 (c-add-stmt-syntax tmpsymbol nil t lim paren-state))
7628
7629 (t
7630 ;; A label on the top level. Treat it as a class
7631 ;; context. (point-min) is the closest we get to the
7632 ;; class open brace.
7633 (c-add-syntax 'access-label (point-min)))))
7634
5853 ;; CASE 4: In-expression statement. C.f. cases 7B, 16A and 7635 ;; CASE 4: In-expression statement. C.f. cases 7B, 16A and
5854 ;; 17E. 7636 ;; 17E.
5855 ((and (or c-opt-inexpr-class-key 7637 ((setq placeholder (c-looking-at-inexpr-block
5856 c-opt-inexpr-block-key 7638 (c-safe-position containing-sexp paren-state)
5857 c-opt-lambda-key) 7639 containing-sexp
5858 (setq placeholder (c-looking-at-inexpr-block 7640 ;; Have to turn on the heuristics after
5859 (c-safe-position containing-sexp paren-state) 7641 ;; the point even though it doesn't work
5860 containing-sexp))) 7642 ;; very well. C.f. test case class-16.pike.
7643 t))
5861 (setq tmpsymbol (assq (car placeholder) 7644 (setq tmpsymbol (assq (car placeholder)
5862 '((inexpr-class . class-open) 7645 '((inexpr-class . class-open)
5863 (inexpr-statement . block-open)))) 7646 (inexpr-statement . block-open))))
@@ -5872,14 +7655,16 @@ This function does not do any hidden buffer changes."
5872 'lambda-intro-cont))) 7655 'lambda-intro-cont)))
5873 (goto-char (cdr placeholder)) 7656 (goto-char (cdr placeholder))
5874 (back-to-indentation) 7657 (back-to-indentation)
5875 (c-add-stmt-syntax tmpsymbol nil t nil 7658 (c-add-stmt-syntax tmpsymbol nil t
5876 (c-most-enclosing-brace c-state-cache (point)) 7659 (c-most-enclosing-brace c-state-cache (point))
5877 (c-whack-state-after (point) paren-state)) 7660 paren-state)
5878 (unless (eq (point) (cdr placeholder)) 7661 (unless (eq (point) (cdr placeholder))
5879 (c-add-syntax (car placeholder)))) 7662 (c-add-syntax (car placeholder))))
5880 ;; CASE 5: Line is at top level. 7663
5881 ((null containing-sexp) 7664 ;; CASE 5: Line is inside a declaration level block or at top level.
7665 ((or containing-decl-open (null containing-sexp))
5882 (cond 7666 (cond
7667
5883 ;; CASE 5A: we are looking at a defun, brace list, class, 7668 ;; CASE 5A: we are looking at a defun, brace list, class,
5884 ;; or inline-inclass method opening brace 7669 ;; or inline-inclass method opening brace
5885 ((setq special-brace-list 7670 ((setq special-brace-list
@@ -5887,36 +7672,36 @@ This function does not do any hidden buffer changes."
5887 (c-looking-at-special-brace-list)) 7672 (c-looking-at-special-brace-list))
5888 (eq char-after-ip ?{))) 7673 (eq char-after-ip ?{)))
5889 (cond 7674 (cond
7675
5890 ;; CASE 5A.1: Non-class declaration block open. 7676 ;; CASE 5A.1: Non-class declaration block open.
5891 ((save-excursion 7677 ((save-excursion
5892 (goto-char indent-point) 7678 (let (tmp)
5893 (skip-chars-forward " \t") 7679 (and (eq char-after-ip ?{)
5894 (and (c-safe (c-backward-sexp 2) t) 7680 (setq tmp (c-looking-at-decl-block containing-sexp t))
5895 (looking-at c-other-decl-block-key) 7681 (progn
5896 (setq keyword (match-string 1) 7682 (setq placeholder (point))
5897 placeholder (point)) 7683 (goto-char tmp)
5898 (if (string-equal keyword "extern") 7684 (looking-at c-symbol-key))
5899 ;; Special case for extern-lang-open. The 7685 (c-keyword-member
5900 ;; check for a following string is disabled 7686 (c-keyword-sym (setq keyword (match-string 0)))
5901 ;; since it doesn't disambiguate anything. 7687 'c-other-block-decl-kwds))))
5902 (and ;;(progn
5903 ;; (c-forward-sexp 1)
5904 ;; (c-forward-syntactic-ws)
5905 ;; (eq (char-after) ?\"))
5906 (setq tmpsymbol 'extern-lang-open))
5907 (setq tmpsymbol (intern (concat keyword "-open"))))
5908 ))
5909 (goto-char placeholder) 7688 (goto-char placeholder)
5910 (c-add-syntax tmpsymbol (c-point 'boi))) 7689 (c-add-stmt-syntax
7690 (if (string-equal keyword "extern")
7691 ;; Special case for extern-lang-open.
7692 'extern-lang-open
7693 (intern (concat keyword "-open")))
7694 nil t containing-sexp paren-state))
7695
5911 ;; CASE 5A.2: we are looking at a class opening brace 7696 ;; CASE 5A.2: we are looking at a class opening brace
5912 ((save-excursion 7697 ((save-excursion
5913 (goto-char indent-point) 7698 (goto-char indent-point)
5914 (skip-chars-forward " \t{") 7699 (skip-chars-forward " \t")
5915 (let ((decl (c-search-uplist-for-classkey (c-parse-state)))) 7700 (and (eq (char-after) ?{)
5916 (and decl 7701 (c-looking-at-decl-block containing-sexp t)
5917 (setq placeholder (aref decl 0))) 7702 (setq placeholder (point))))
5918 ))
5919 (c-add-syntax 'class-open placeholder)) 7703 (c-add-syntax 'class-open placeholder))
7704
5920 ;; CASE 5A.3: brace list open 7705 ;; CASE 5A.3: brace list open
5921 ((save-excursion 7706 ((save-excursion
5922 (c-beginning-of-decl-1 lim) 7707 (c-beginning-of-decl-1 lim)
@@ -5958,65 +7743,69 @@ This function does not do any hidden buffer changes."
5958 (c-beginning-of-statement-1 lim) 7743 (c-beginning-of-statement-1 lim)
5959 (c-add-syntax 'topmost-intro-cont (c-point 'boi))) 7744 (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
5960 (c-add-syntax 'brace-list-open placeholder))) 7745 (c-add-syntax 'brace-list-open placeholder)))
7746
5961 ;; CASE 5A.4: inline defun open 7747 ;; CASE 5A.4: inline defun open
5962 ((and inclass-p (not inenclosing-p)) 7748 ((and containing-decl-open
7749 (not (c-keyword-member containing-decl-kwd
7750 'c-other-block-decl-kwds)))
5963 (c-add-syntax 'inline-open) 7751 (c-add-syntax 'inline-open)
5964 (c-add-class-syntax 'inclass inclass-p paren-state)) 7752 (c-add-class-syntax 'inclass
7753 containing-decl-open
7754 containing-decl-start
7755 containing-decl-kwd
7756 paren-state))
7757
5965 ;; CASE 5A.5: ordinary defun open 7758 ;; CASE 5A.5: ordinary defun open
5966 (t 7759 (t
5967 (goto-char placeholder) 7760 (goto-char placeholder)
5968 (if (or inclass-p macro-start) 7761 (if (or containing-decl-open macro-start)
5969 (c-add-syntax 'defun-open (c-point 'boi)) 7762 (c-add-syntax 'defun-open (c-point 'boi))
5970 ;; Bogus to use bol here, but it's the legacy. 7763 ;; Bogus to use bol here, but it's the legacy.
5971 (c-add-syntax 'defun-open (c-point 'bol))) 7764 (c-add-syntax 'defun-open (c-point 'bol)))
5972 ))) 7765 )))
5973 ;; CASE 5B: first K&R arg decl or member init 7766
5974 ((c-just-after-func-arglist-p lim) 7767 ;; CASE 5B: After a function header but before the body (or
7768 ;; the ending semicolon if there's no body).
7769 ((save-excursion
7770 (when (setq placeholder (c-just-after-func-arglist-p lim))
7771 (setq tmp-pos (point))))
5975 (cond 7772 (cond
5976 ;; CASE 5B.1: a member init 7773
5977 ((or (eq char-before-ip ?:) 7774 ;; CASE 5B.1: Member init list.
5978 (eq char-after-ip ?:)) 7775 ((eq (char-after tmp-pos) ?:)
5979 ;; this line should be indented relative to the beginning 7776 (if (or (> tmp-pos indent-point)
5980 ;; of indentation for the topmost-intro line that contains 7777 (= (c-point 'bosws) (1+ tmp-pos)))
5981 ;; the prototype's open paren 7778 (progn
5982 ;; TBD: is the following redundant? 7779 ;; There is no preceding member init clause.
5983 (if (eq char-before-ip ?:) 7780 ;; Indent relative to the beginning of indentation
5984 (forward-char -1)) 7781 ;; for the topmost-intro line that contains the
5985 (c-backward-syntactic-ws lim) 7782 ;; prototype's open paren.
5986 ;; TBD: is the preceding redundant? 7783 (goto-char placeholder)
5987 (if (eq (char-before) ?:) 7784 (c-add-syntax 'member-init-intro (c-point 'boi)))
5988 (progn (forward-char -1) 7785 ;; Indent relative to the first member init clause.
5989 (c-backward-syntactic-ws lim))) 7786 (goto-char (1+ tmp-pos))
5990 (if (eq (char-before) ?\)) 7787 (c-forward-syntactic-ws)
5991 (c-backward-sexp 1)) 7788 (c-add-syntax 'member-init-cont (point))))
5992 (setq placeholder (point)) 7789
5993 (save-excursion
5994 (and (c-safe (c-backward-sexp 1) t)
5995 (looking-at "throw[^_]")
5996 (c-safe (c-backward-sexp 1) t)
5997 (setq placeholder (point))))
5998 (goto-char placeholder)
5999 (c-add-syntax 'member-init-intro (c-point 'boi))
6000 ;; we don't need to add any class offset since this
6001 ;; should be relative to the ctor's indentation
6002 )
6003 ;; CASE 5B.2: K&R arg decl intro 7790 ;; CASE 5B.2: K&R arg decl intro
6004 ((and c-recognize-knr-p 7791 ((and c-recognize-knr-p
6005 (c-in-knr-argdecl lim)) 7792 (c-in-knr-argdecl lim))
6006 (c-beginning-of-statement-1 lim) 7793 (c-beginning-of-statement-1 lim)
6007 (c-add-syntax 'knr-argdecl-intro (c-point 'boi)) 7794 (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
6008 (if inclass-p 7795 (if containing-decl-open
6009 (c-add-class-syntax 'inclass inclass-p paren-state))) 7796 (c-add-class-syntax 'inclass
6010 ;; CASE 5B.3: Inside a member init list. 7797 containing-decl-open
6011 ((c-beginning-of-member-init-list lim) 7798 containing-decl-start
6012 (c-forward-syntactic-ws) 7799 containing-decl-kwd
6013 (c-add-syntax 'member-init-cont (point))) 7800 paren-state)))
7801
6014 ;; CASE 5B.4: Nether region after a C++ or Java func 7802 ;; CASE 5B.4: Nether region after a C++ or Java func
6015 ;; decl, which could include a `throws' declaration. 7803 ;; decl, which could include a `throws' declaration.
6016 (t 7804 (t
6017 (c-beginning-of-statement-1 lim) 7805 (c-beginning-of-statement-1 lim)
6018 (c-add-syntax 'func-decl-cont (c-point 'boi)) 7806 (c-add-syntax 'func-decl-cont (c-point 'boi))
6019 ))) 7807 )))
7808
6020 ;; CASE 5C: inheritance line. could be first inheritance 7809 ;; CASE 5C: inheritance line. could be first inheritance
6021 ;; line, or continuation of a multiple inheritance 7810 ;; line, or continuation of a multiple inheritance
6022 ((or (and (c-major-mode-is 'c++-mode) 7811 ((or (and (c-major-mode-is 'c++-mode)
@@ -6061,6 +7850,7 @@ This function does not do any hidden buffer changes."
6061 (point))) 7850 (point)))
6062 )) 7851 ))
6063 (cond 7852 (cond
7853
6064 ;; CASE 5C.1: non-hanging colon on an inher intro 7854 ;; CASE 5C.1: non-hanging colon on an inher intro
6065 ((eq char-after-ip ?:) 7855 ((eq char-after-ip ?:)
6066 (c-beginning-of-statement-1 lim) 7856 (c-beginning-of-statement-1 lim)
@@ -6068,12 +7858,18 @@ This function does not do any hidden buffer changes."
6068 ;; don't add inclass symbol since relative point already 7858 ;; don't add inclass symbol since relative point already
6069 ;; contains any class offset 7859 ;; contains any class offset
6070 ) 7860 )
7861
6071 ;; CASE 5C.2: hanging colon on an inher intro 7862 ;; CASE 5C.2: hanging colon on an inher intro
6072 ((eq char-before-ip ?:) 7863 ((eq char-before-ip ?:)
6073 (c-beginning-of-statement-1 lim) 7864 (c-beginning-of-statement-1 lim)
6074 (c-add-syntax 'inher-intro (c-point 'boi)) 7865 (c-add-syntax 'inher-intro (c-point 'boi))
6075 (if inclass-p 7866 (if containing-decl-open
6076 (c-add-class-syntax 'inclass inclass-p paren-state))) 7867 (c-add-class-syntax 'inclass
7868 containing-decl-open
7869 containing-decl-start
7870 containing-decl-kwd
7871 paren-state)))
7872
6077 ;; CASE 5C.3: in a Java implements/extends 7873 ;; CASE 5C.3: in a Java implements/extends
6078 (injava-inher 7874 (injava-inher
6079 (let ((where (cdr injava-inher)) 7875 (let ((where (cdr injava-inher))
@@ -6089,6 +7885,7 @@ This function does not do any hidden buffer changes."
6089 (c-beginning-of-statement-1 lim) 7885 (c-beginning-of-statement-1 lim)
6090 (point)))) 7886 (point))))
6091 ))) 7887 )))
7888
6092 ;; CASE 5C.4: a continued inheritance line 7889 ;; CASE 5C.4: a continued inheritance line
6093 (t 7890 (t
6094 (c-beginning-of-inheritance-list lim) 7891 (c-beginning-of-inheritance-list lim)
@@ -6096,77 +7893,67 @@ This function does not do any hidden buffer changes."
6096 ;; don't add inclass symbol since relative point already 7893 ;; don't add inclass symbol since relative point already
6097 ;; contains any class offset 7894 ;; contains any class offset
6098 ))) 7895 )))
7896
6099 ;; CASE 5D: this could be a top-level initialization, a 7897 ;; CASE 5D: this could be a top-level initialization, a
6100 ;; member init list continuation, or a template argument 7898 ;; member init list continuation, or a template argument
6101 ;; list continuation. 7899 ;; list continuation.
6102 ((c-with-syntax-table (if (c-major-mode-is 'c++-mode) 7900 ((save-excursion
6103 c++-template-syntax-table 7901 ;; Note: We use the fact that lim always is after any
6104 (syntax-table)) 7902 ;; preceding brace sexp.
6105 (save-excursion 7903 (if c-recognize-<>-arglists
6106 ;; Note: We use the fact that lim is always after any 7904 (while (and
6107 ;; preceding brace sexp. 7905 (progn
6108 (while (and (zerop (c-backward-token-2 1 t lim)) 7906 (c-syntactic-skip-backward "^;,=<>" lim t)
6109 (or (not (looking-at "[;<,=]")) 7907 (> (point) lim))
6110 (and c-overloadable-operators-regexp 7908 (or
6111 (looking-at c-overloadable-operators-regexp) 7909 (when c-overloadable-operators-regexp
6112 (save-excursion 7910 (when (setq placeholder (c-after-special-operator-id lim))
6113 (c-backward-token-2 1 nil lim) 7911 (goto-char placeholder)
6114 (looking-at "operator\\>[^_]")))))) 7912 t))
6115 (or (memq (char-after) '(?, ?=)) 7913 (cond
6116 (and (c-major-mode-is 'c++-mode) 7914 ((eq (char-before) ?>)
6117 (zerop (c-backward-token-2 1 nil lim)) 7915 (or (c-backward-<>-arglist nil lim)
6118 (eq (char-after) ?<))))) 7916 (backward-char))
6119 (goto-char indent-point) 7917 t)
6120 (setq placeholder 7918 ((eq (char-before) ?<)
6121 (c-beginning-of-member-init-list lim)) 7919 (backward-char)
7920 (if (save-excursion
7921 (c-forward-<>-arglist nil))
7922 (progn (forward-char)
7923 nil)
7924 t))
7925 (t nil)))))
7926 ;; NB: No c-after-special-operator-id stuff in this
7927 ;; clause - we assume only C++ needs it.
7928 (c-syntactic-skip-backward "^;,=" lim t))
7929 (memq (char-before) '(?, ?= ?<)))
6122 (cond 7930 (cond
6123 ;; CASE 5D.1: hanging member init colon, but watch out 7931
6124 ;; for bogus matches on access specifiers inside classes.
6125 ((and placeholder
6126 (save-excursion
6127 (setq placeholder (point))
6128 (c-backward-token-2 1 t lim)
6129 (and (eq (char-after) ?:)
6130 (not (eq (char-before) ?:))))
6131 (save-excursion
6132 (goto-char placeholder)
6133 (back-to-indentation)
6134 (or
6135 (/= (car (save-excursion
6136 (parse-partial-sexp (point) placeholder)))
6137 0)
6138 (and
6139 (if c-opt-access-key
6140 (not (looking-at c-opt-access-key)) t)
6141 (not (looking-at c-class-key))
6142 (if c-opt-bitfield-key
6143 (not (looking-at c-opt-bitfield-key)) t))
6144 )))
6145 (goto-char placeholder)
6146 (c-forward-syntactic-ws)
6147 (c-add-syntax 'member-init-cont (point))
6148 ;; we do not need to add class offset since relative
6149 ;; point is the member init above us
6150 )
6151 ;; CASE 5D.2: non-hanging member init colon
6152 ((progn
6153 (c-forward-syntactic-ws indent-point)
6154 (eq (char-after) ?:))
6155 (skip-chars-forward " \t:")
6156 (c-add-syntax 'member-init-cont (point)))
6157 ;; CASE 5D.3: perhaps a template list continuation? 7932 ;; CASE 5D.3: perhaps a template list continuation?
6158 ((and (c-major-mode-is 'c++-mode) 7933 ((and (c-major-mode-is 'c++-mode)
6159 (save-excursion 7934 (save-excursion
6160 (save-restriction 7935 (save-restriction
6161 (c-with-syntax-table c++-template-syntax-table 7936 (c-with-syntax-table c++-template-syntax-table
6162 (goto-char indent-point) 7937 (goto-char indent-point)
6163 (setq placeholder (c-up-list-backward (point))) 7938 (setq placeholder (c-up-list-backward))
6164 (and placeholder 7939 (and placeholder
6165 (eq (char-after placeholder) ?<)))))) 7940 (eq (char-after placeholder) ?<))))))
6166 ;; we can probably indent it just like an arglist-cont 7941 (c-with-syntax-table c++-template-syntax-table
6167 (goto-char placeholder) 7942 (goto-char placeholder)
6168 (c-beginning-of-statement-1 lim t) 7943 (c-beginning-of-statement-1 lim t)
6169 (c-add-syntax 'template-args-cont (c-point 'boi))) 7944 (if (save-excursion
7945 (c-backward-syntactic-ws lim)
7946 (eq (char-before) ?<))
7947 ;; In a nested template arglist.
7948 (progn
7949 (goto-char placeholder)
7950 (c-syntactic-skip-backward "^,;" lim t)
7951 (c-forward-syntactic-ws))
7952 (back-to-indentation)))
7953 ;; FIXME: Should use c-add-stmt-syntax, but it's not yet
7954 ;; template aware.
7955 (c-add-syntax 'template-args-cont (point)))
7956
6170 ;; CASE 5D.4: perhaps a multiple inheritance line? 7957 ;; CASE 5D.4: perhaps a multiple inheritance line?
6171 ((and (c-major-mode-is 'c++-mode) 7958 ((and (c-major-mode-is 'c++-mode)
6172 (save-excursion 7959 (save-excursion
@@ -6183,6 +7970,7 @@ This function does not do any hidden buffer changes."
6183 (eq (char-after) ?:)))) 7970 (eq (char-after) ?:))))
6184 (goto-char placeholder) 7971 (goto-char placeholder)
6185 (c-add-syntax 'inher-cont (c-point 'boi))) 7972 (c-add-syntax 'inher-cont (c-point 'boi)))
7973
6186 ;; CASE 5D.5: Continuation of the "expression part" of a 7974 ;; CASE 5D.5: Continuation of the "expression part" of a
6187 ;; top level construct. 7975 ;; top level construct.
6188 (t 7976 (t
@@ -6199,33 +7987,38 @@ This function does not do any hidden buffer changes."
6199 ;; the first variable declaration. C.f. case 5N. 7987 ;; the first variable declaration. C.f. case 5N.
6200 'topmost-intro-cont 7988 'topmost-intro-cont
6201 'statement-cont) 7989 'statement-cont)
6202 nil nil nil containing-sexp paren-state)) 7990 nil nil containing-sexp paren-state))
6203 )) 7991 ))
6204 ;; CASE 5E: we are looking at a access specifier 7992
6205 ((and inclass-p
6206 c-opt-access-key
6207 (looking-at c-opt-access-key))
6208 (setq placeholder (c-add-class-syntax 'inclass inclass-p
6209 paren-state))
6210 ;; Append access-label with the same anchor point as inclass gets.
6211 (c-append-syntax 'access-label placeholder))
6212 ;; CASE 5F: Close of a non-class declaration level block. 7993 ;; CASE 5F: Close of a non-class declaration level block.
6213 ((and inenclosing-p 7994 ((and (eq char-after-ip ?})
6214 (eq char-after-ip ?})) 7995 (c-keyword-member containing-decl-kwd
6215 (c-add-syntax (intern (concat inenclosing-p "-close")) 7996 'c-other-block-decl-kwds))
6216 (aref inclass-p 0))) 7997 ;; This is inconsistent: Should use `containing-decl-open'
7998 ;; here if it's at boi, like in case 5J.
7999 (goto-char containing-decl-start)
8000 (c-add-stmt-syntax
8001 (if (string-equal (symbol-name containing-decl-kwd) "extern")
8002 ;; Special case for compatibility with the
8003 ;; extern-lang syntactic symbols.
8004 'extern-lang-close
8005 (intern (concat (symbol-name containing-decl-kwd)
8006 "-close")))
8007 nil t
8008 (c-most-enclosing-brace paren-state (point))
8009 paren-state))
8010
6217 ;; CASE 5G: we are looking at the brace which closes the 8011 ;; CASE 5G: we are looking at the brace which closes the
6218 ;; enclosing nested class decl 8012 ;; enclosing nested class decl
6219 ((and inclass-p 8013 ((and containing-sexp
6220 (eq char-after-ip ?}) 8014 (eq char-after-ip ?})
6221 (save-excursion 8015 (eq containing-decl-open containing-sexp))
6222 (save-restriction 8016 (c-add-class-syntax 'class-close
6223 (widen) 8017 containing-decl-open
6224 (forward-char 1) 8018 containing-decl-start
6225 (and (c-safe (c-backward-sexp 1) t) 8019 containing-decl-kwd
6226 (= (point) (aref inclass-p 1)) 8020 paren-state))
6227 )))) 8021
6228 (c-add-class-syntax 'class-close inclass-p paren-state))
6229 ;; CASE 5H: we could be looking at subsequent knr-argdecls 8022 ;; CASE 5H: we could be looking at subsequent knr-argdecls
6230 ((and c-recognize-knr-p 8023 ((and c-recognize-knr-p
6231 (not (eq char-before-ip ?})) 8024 (not (eq char-before-ip ?}))
@@ -6241,6 +8034,7 @@ This function does not do any hidden buffer changes."
6241 (< placeholder indent-point)) 8034 (< placeholder indent-point))
6242 (goto-char placeholder) 8035 (goto-char placeholder)
6243 (c-add-syntax 'knr-argdecl (point))) 8036 (c-add-syntax 'knr-argdecl (point)))
8037
6244 ;; CASE 5I: ObjC method definition. 8038 ;; CASE 5I: ObjC method definition.
6245 ((and c-opt-method-key 8039 ((and c-opt-method-key
6246 (looking-at c-opt-method-key)) 8040 (looking-at c-opt-method-key))
@@ -6254,17 +8048,19 @@ This function does not do any hidden buffer changes."
6254 ;; directive. 8048 ;; directive.
6255 (goto-char (point-min))) 8049 (goto-char (point-min)))
6256 (c-add-syntax 'objc-method-intro (c-point 'boi))) 8050 (c-add-syntax 'objc-method-intro (c-point 'boi)))
8051
6257 ;; CASE 5P: AWK pattern or function or continuation 8052 ;; CASE 5P: AWK pattern or function or continuation
6258 ;; thereof. 8053 ;; thereof.
6259 ((c-mode-is-new-awk-p) 8054 ((c-major-mode-is 'awk-mode)
6260 (setq placeholder (point)) 8055 (setq placeholder (point))
6261 (c-add-stmt-syntax 8056 (c-add-stmt-syntax
6262 (if (and (eq (c-beginning-of-statement-1) 'same) 8057 (if (and (eq (c-beginning-of-statement-1) 'same)
6263 (/= (point) placeholder)) 8058 (/= (point) placeholder))
6264 'topmost-intro-cont 8059 'topmost-intro-cont
6265 'topmost-intro) 8060 'topmost-intro)
6266 nil nil nil 8061 nil nil
6267 containing-sexp paren-state)) 8062 containing-sexp paren-state))
8063
6268 ;; CASE 5N: At a variable declaration that follows a class 8064 ;; CASE 5N: At a variable declaration that follows a class
6269 ;; definition or some other block declaration that doesn't 8065 ;; definition or some other block declaration that doesn't
6270 ;; end at the closing '}'. C.f. case 5D.5. 8066 ;; end at the closing '}'. C.f. case 5D.5.
@@ -6273,9 +8069,9 @@ This function does not do any hidden buffer changes."
6273 (and (eq (char-before) ?}) 8069 (and (eq (char-before) ?})
6274 (save-excursion 8070 (save-excursion
6275 (let ((start (point))) 8071 (let ((start (point)))
6276 (if paren-state 8072 (if c-state-cache
6277 ;; Speed up the backward search a bit. 8073 ;; Speed up the backward search a bit.
6278 (goto-char (car (car paren-state)))) 8074 (goto-char (caar c-state-cache)))
6279 (c-beginning-of-decl-1 containing-sexp) 8075 (c-beginning-of-decl-1 containing-sexp)
6280 (setq placeholder (point)) 8076 (setq placeholder (point))
6281 (if (= start (point)) 8077 (if (= start (point))
@@ -6284,71 +8080,102 @@ This function does not do any hidden buffer changes."
6284 (c-end-of-decl-1) 8080 (c-end-of-decl-1)
6285 (>= (point) indent-point)))))) 8081 (>= (point) indent-point))))))
6286 (goto-char placeholder) 8082 (goto-char placeholder)
6287 (c-add-stmt-syntax 'topmost-intro-cont nil nil nil 8083 (c-add-stmt-syntax 'topmost-intro-cont nil nil
6288 containing-sexp paren-state)) 8084 containing-sexp paren-state))
8085
8086 ;; NOTE: The point is at the end of the previous token here.
8087
6289 ;; CASE 5J: we are at the topmost level, make 8088 ;; CASE 5J: we are at the topmost level, make
6290 ;; sure we skip back past any access specifiers 8089 ;; sure we skip back past any access specifiers
6291 ((progn 8090 ((save-excursion
6292 (while (and inclass-p 8091 (setq placeholder (point))
6293 c-opt-access-key 8092 (or (memq char-before-ip '(?\; ?{ ?} nil))
6294 (not (bobp)) 8093 (c-at-vsemi-p before-ws-ip)
6295 (save-excursion 8094 (when (and (eq char-before-ip ?:)
6296 (c-safe (c-backward-sexp 1) t) 8095 (eq (c-beginning-of-statement-1 lim)
6297 (looking-at c-opt-access-key))) 8096 'label))
6298 (c-backward-sexp 1) 8097 (c-backward-syntactic-ws lim)
6299 (c-backward-syntactic-ws lim)) 8098 (setq placeholder (point)))
6300 (or (bobp)
6301 (if (c-mode-is-new-awk-p)
6302 (not (c-awk-prev-line-incomplete-p))
6303 (memq (char-before) '(?\; ?})))
6304 (and (c-major-mode-is 'objc-mode) 8099 (and (c-major-mode-is 'objc-mode)
6305 (progn 8100 (catch 'not-in-directive
6306 (c-beginning-of-statement-1 lim) 8101 (c-beginning-of-statement-1 lim)
6307 (eq (char-after) ?@))))) 8102 (setq placeholder (point))
6308 ;; real beginning-of-line could be narrowed out due to 8103 (while (and (c-forward-objc-directive)
6309 ;; enclosure in a class block 8104 (< (point) indent-point))
6310 (save-restriction 8105 (c-forward-syntactic-ws)
6311 (widen) 8106 (if (>= (point) indent-point)
6312 (c-add-syntax 'topmost-intro (c-point 'bol)) 8107 (throw 'not-in-directive t))
6313 ;; Using bol instead of boi above is highly bogus, and 8108 (setq placeholder (point)))
6314 ;; it makes our lives hard to remain compatible. :P 8109 nil))))
6315 (if inclass-p 8110 ;; For historic reasons we anchor at bol of the last
6316 (progn 8111 ;; line of the previous declaration. That's clearly
6317 (goto-char (aref inclass-p 1)) 8112 ;; highly bogus and useless, and it makes our lives hard
6318 (or (= (point) (c-point 'boi)) 8113 ;; to remain compatible. :P
6319 (goto-char (aref inclass-p 0))) 8114 (goto-char placeholder)
6320 (if inenclosing-p 8115 (c-add-syntax 'topmost-intro (c-point 'bol))
6321 (c-add-syntax (intern (concat "in" inenclosing-p)) 8116 (if containing-decl-open
6322 (c-point 'boi)) 8117 (if (c-keyword-member containing-decl-kwd
6323 (c-add-class-syntax 'inclass inclass-p paren-state)) 8118 'c-other-block-decl-kwds)
6324 )) 8119 (progn
6325 (when (and c-syntactic-indentation-in-macros 8120 (goto-char containing-decl-open)
6326 macro-start 8121 (unless (= (point) (c-point 'boi))
6327 (/= macro-start (c-point 'boi indent-point))) 8122 (goto-char containing-decl-start))
6328 (c-add-syntax 'cpp-define-intro) 8123 (c-add-stmt-syntax
6329 (setq macro-start nil)) 8124 (if (string-equal (symbol-name containing-decl-kwd)
6330 )) 8125 "extern")
8126 ;; Special case for compatibility with the
8127 ;; extern-lang syntactic symbols.
8128 'inextern-lang
8129 (intern (concat "in"
8130 (symbol-name containing-decl-kwd))))
8131 nil t
8132 (c-most-enclosing-brace paren-state (point))
8133 paren-state))
8134 (c-add-class-syntax 'inclass
8135 containing-decl-open
8136 containing-decl-start
8137 containing-decl-kwd
8138 paren-state)))
8139 (when (and c-syntactic-indentation-in-macros
8140 macro-start
8141 (/= macro-start (c-point 'boi indent-point)))
8142 (c-add-syntax 'cpp-define-intro)
8143 (setq macro-start nil)))
8144
6331 ;; CASE 5K: we are at an ObjC method definition 8145 ;; CASE 5K: we are at an ObjC method definition
6332 ;; continuation line. 8146 ;; continuation line.
6333 ((and c-opt-method-key 8147 ((and c-opt-method-key
6334 (save-excursion 8148 (save-excursion
6335 (goto-char indent-point)
6336 (c-beginning-of-statement-1 lim) 8149 (c-beginning-of-statement-1 lim)
6337 (beginning-of-line) 8150 (beginning-of-line)
6338 (when (looking-at c-opt-method-key) 8151 (when (looking-at c-opt-method-key)
6339 (setq placeholder (point))))) 8152 (setq placeholder (point)))))
6340 (c-add-syntax 'objc-method-args-cont placeholder)) 8153 (c-add-syntax 'objc-method-args-cont placeholder))
8154
6341 ;; CASE 5L: we are at the first argument of a template 8155 ;; CASE 5L: we are at the first argument of a template
6342 ;; arglist that begins on the previous line. 8156 ;; arglist that begins on the previous line.
6343 ((eq (char-before) ?<) 8157 ((and c-recognize-<>-arglists
8158 (eq (char-before) ?<)
8159 (not (and c-overloadable-operators-regexp
8160 (c-after-special-operator-id lim))))
6344 (c-beginning-of-statement-1 (c-safe-position (point) paren-state)) 8161 (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
6345 (c-add-syntax 'template-args-cont (c-point 'boi))) 8162 (c-add-syntax 'template-args-cont (c-point 'boi)))
8163
6346 ;; CASE 5M: we are at a topmost continuation line 8164 ;; CASE 5M: we are at a topmost continuation line
6347 (t 8165 (t
6348 (c-beginning-of-statement-1 (c-safe-position (point) paren-state)) 8166 (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
8167 (when (c-major-mode-is 'objc-mode)
8168 (setq placeholder (point))
8169 (while (and (c-forward-objc-directive)
8170 (< (point) indent-point))
8171 (c-forward-syntactic-ws)
8172 (setq placeholder (point)))
8173 (goto-char placeholder))
6349 (c-add-syntax 'topmost-intro-cont (c-point 'boi))) 8174 (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
6350 )) 8175 ))
8176
6351 ;; (CASE 6 has been removed.) 8177 ;; (CASE 6 has been removed.)
8178
6352 ;; CASE 7: line is an expression, not a statement. Most 8179 ;; CASE 7: line is an expression, not a statement. Most
6353 ;; likely we are either in a function prototype or a function 8180 ;; likely we are either in a function prototype or a function
6354 ;; call argument list 8181 ;; call argument list
@@ -6358,6 +8185,7 @@ This function does not do any hidden buffer changes."
6358 (c-looking-at-special-brace-list))) 8185 (c-looking-at-special-brace-list)))
6359 (eq (char-after containing-sexp) ?{))) 8186 (eq (char-after containing-sexp) ?{)))
6360 (cond 8187 (cond
8188
6361 ;; CASE 7A: we are looking at the arglist closing paren. 8189 ;; CASE 7A: we are looking at the arglist closing paren.
6362 ;; C.f. case 7F. 8190 ;; C.f. case 7F.
6363 ((memq char-after-ip '(?\) ?\])) 8191 ((memq char-after-ip '(?\) ?\]))
@@ -6369,16 +8197,17 @@ This function does not do any hidden buffer changes."
6369 (forward-char) 8197 (forward-char)
6370 (skip-chars-forward " \t")) 8198 (skip-chars-forward " \t"))
6371 (goto-char placeholder)) 8199 (goto-char placeholder))
6372 (c-add-stmt-syntax 'arglist-close (list containing-sexp) t nil 8200 (c-add-stmt-syntax 'arglist-close (list containing-sexp) t
6373 (c-most-enclosing-brace paren-state (point)) 8201 (c-most-enclosing-brace paren-state (point))
6374 (c-whack-state-after (point) paren-state))) 8202 paren-state))
8203
6375 ;; CASE 7B: Looking at the opening brace of an 8204 ;; CASE 7B: Looking at the opening brace of an
6376 ;; in-expression block or brace list. C.f. cases 4, 16A 8205 ;; in-expression block or brace list. C.f. cases 4, 16A
6377 ;; and 17E. 8206 ;; and 17E.
6378 ((and (eq char-after-ip ?{) 8207 ((and (eq char-after-ip ?{)
6379 (progn 8208 (progn
6380 (setq placeholder (c-inside-bracelist-p (point) 8209 (setq placeholder (c-inside-bracelist-p (point)
6381 c-state-cache)) 8210 paren-state))
6382 (if placeholder 8211 (if placeholder
6383 (setq tmpsymbol '(brace-list-open . inexpr-class)) 8212 (setq tmpsymbol '(brace-list-open . inexpr-class))
6384 (setq tmpsymbol '(block-open . inexpr-statement) 8213 (setq tmpsymbol '(block-open . inexpr-statement)
@@ -6393,23 +8222,28 @@ This function does not do any hidden buffer changes."
6393 ))) 8222 )))
6394 (goto-char placeholder) 8223 (goto-char placeholder)
6395 (back-to-indentation) 8224 (back-to-indentation)
6396 (c-add-stmt-syntax (car tmpsymbol) nil t nil 8225 (c-add-stmt-syntax (car tmpsymbol) nil t
6397 (c-most-enclosing-brace paren-state (point)) 8226 (c-most-enclosing-brace paren-state (point))
6398 (c-whack-state-after (point) paren-state)) 8227 paren-state)
6399 (if (/= (point) placeholder) 8228 (if (/= (point) placeholder)
6400 (c-add-syntax (cdr tmpsymbol)))) 8229 (c-add-syntax (cdr tmpsymbol))))
8230
6401 ;; CASE 7C: we are looking at the first argument in an empty 8231 ;; CASE 7C: we are looking at the first argument in an empty
6402 ;; argument list. Use arglist-close if we're actually 8232 ;; argument list. Use arglist-close if we're actually
6403 ;; looking at a close paren or bracket. 8233 ;; looking at a close paren or bracket.
6404 ((memq char-before-ip '(?\( ?\[)) 8234 ((memq char-before-ip '(?\( ?\[))
6405 (goto-char containing-sexp) 8235 (goto-char containing-sexp)
6406 (setq placeholder (c-point 'boi)) 8236 (setq placeholder (c-point 'boi))
6407 (when (and (c-safe (backward-up-list 1) t) 8237 (if (and (c-safe (backward-up-list 1) t)
6408 (>= (point) placeholder)) 8238 (>= (point) placeholder))
6409 (forward-char) 8239 (progn
6410 (skip-chars-forward " \t") 8240 (forward-char)
6411 (setq placeholder (point))) 8241 (skip-chars-forward " \t"))
6412 (c-add-syntax 'arglist-intro placeholder)) 8242 (goto-char placeholder))
8243 (c-add-stmt-syntax 'arglist-intro (list containing-sexp) t
8244 (c-most-enclosing-brace paren-state (point))
8245 paren-state))
8246
6413 ;; CASE 7D: we are inside a conditional test clause. treat 8247 ;; CASE 7D: we are inside a conditional test clause. treat
6414 ;; these things as statements 8248 ;; these things as statements
6415 ((progn 8249 ((progn
@@ -6422,6 +8256,7 @@ This function does not do any hidden buffer changes."
6422 (c-add-syntax 'statement (point)) 8256 (c-add-syntax 'statement (point))
6423 (c-add-syntax 'statement-cont (point)) 8257 (c-add-syntax 'statement-cont (point))
6424 )) 8258 ))
8259
6425 ;; CASE 7E: maybe a continued ObjC method call. This is the 8260 ;; CASE 7E: maybe a continued ObjC method call. This is the
6426 ;; case when we are inside a [] bracketed exp, and what 8261 ;; case when we are inside a [] bracketed exp, and what
6427 ;; precede the opening bracket is not an identifier. 8262 ;; precede the opening bracket is not an identifier.
@@ -6433,6 +8268,7 @@ This function does not do any hidden buffer changes."
6433 (if (not (looking-at c-symbol-key)) 8268 (if (not (looking-at c-symbol-key))
6434 (c-add-syntax 'objc-method-call-cont containing-sexp)) 8269 (c-add-syntax 'objc-method-call-cont containing-sexp))
6435 ))) 8270 )))
8271
6436 ;; CASE 7F: we are looking at an arglist continuation line, 8272 ;; CASE 7F: we are looking at an arglist continuation line,
6437 ;; but the preceding argument is on the same line as the 8273 ;; but the preceding argument is on the same line as the
6438 ;; opening paren. This case includes multi-line 8274 ;; opening paren. This case includes multi-line
@@ -6440,9 +8276,10 @@ This function does not do any hidden buffer changes."
6440 ;; for-list continuation line. C.f. case 7A. 8276 ;; for-list continuation line. C.f. case 7A.
6441 ((progn 8277 ((progn
6442 (goto-char (1+ containing-sexp)) 8278 (goto-char (1+ containing-sexp))
6443 (skip-chars-forward " \t") 8279 (< (save-excursion
6444 (and (not (eolp)) 8280 (c-forward-syntactic-ws)
6445 (not (looking-at "\\\\$")))) 8281 (point))
8282 (c-point 'bonl)))
6446 (goto-char containing-sexp) 8283 (goto-char containing-sexp)
6447 (setq placeholder (c-point 'boi)) 8284 (setq placeholder (c-point 'boi))
6448 (if (and (c-safe (backward-up-list 1) t) 8285 (if (and (c-safe (backward-up-list 1) t)
@@ -6451,15 +8288,16 @@ This function does not do any hidden buffer changes."
6451 (forward-char) 8288 (forward-char)
6452 (skip-chars-forward " \t")) 8289 (skip-chars-forward " \t"))
6453 (goto-char placeholder)) 8290 (goto-char placeholder))
6454 (c-add-stmt-syntax 'arglist-cont-nonempty (list containing-sexp) 8291 (c-add-stmt-syntax 'arglist-cont-nonempty (list containing-sexp) t
6455 t nil
6456 (c-most-enclosing-brace c-state-cache (point)) 8292 (c-most-enclosing-brace c-state-cache (point))
6457 (c-whack-state-after (point) paren-state))) 8293 paren-state))
8294
6458 ;; CASE 7G: we are looking at just a normal arglist 8295 ;; CASE 7G: we are looking at just a normal arglist
6459 ;; continuation line 8296 ;; continuation line
6460 (t (c-forward-syntactic-ws indent-point) 8297 (t (c-forward-syntactic-ws indent-point)
6461 (c-add-syntax 'arglist-cont (c-point 'boi))) 8298 (c-add-syntax 'arglist-cont (c-point 'boi)))
6462 )) 8299 ))
8300
6463 ;; CASE 8: func-local multi-inheritance line 8301 ;; CASE 8: func-local multi-inheritance line
6464 ((and (c-major-mode-is 'c++-mode) 8302 ((and (c-major-mode-is 'c++-mode)
6465 (save-excursion 8303 (save-excursion
@@ -6469,27 +8307,32 @@ This function does not do any hidden buffer changes."
6469 (goto-char indent-point) 8307 (goto-char indent-point)
6470 (skip-chars-forward " \t") 8308 (skip-chars-forward " \t")
6471 (cond 8309 (cond
8310
6472 ;; CASE 8A: non-hanging colon on an inher intro 8311 ;; CASE 8A: non-hanging colon on an inher intro
6473 ((eq char-after-ip ?:) 8312 ((eq char-after-ip ?:)
6474 (c-backward-syntactic-ws lim) 8313 (c-backward-syntactic-ws lim)
6475 (c-add-syntax 'inher-intro (c-point 'boi))) 8314 (c-add-syntax 'inher-intro (c-point 'boi)))
8315
6476 ;; CASE 8B: hanging colon on an inher intro 8316 ;; CASE 8B: hanging colon on an inher intro
6477 ((eq char-before-ip ?:) 8317 ((eq char-before-ip ?:)
6478 (c-add-syntax 'inher-intro (c-point 'boi))) 8318 (c-add-syntax 'inher-intro (c-point 'boi)))
8319
6479 ;; CASE 8C: a continued inheritance line 8320 ;; CASE 8C: a continued inheritance line
6480 (t 8321 (t
6481 (c-beginning-of-inheritance-list lim) 8322 (c-beginning-of-inheritance-list lim)
6482 (c-add-syntax 'inher-cont (point)) 8323 (c-add-syntax 'inher-cont (point))
6483 ))) 8324 )))
8325
6484 ;; CASE 9: we are inside a brace-list 8326 ;; CASE 9: we are inside a brace-list
6485 ((and (not (c-mode-is-new-awk-p)) ; Maybe this isn't needed (ACM, 2002/3/29) 8327 ((and (not (c-major-mode-is 'awk-mode)) ; Maybe this isn't needed (ACM, 2002/3/29)
6486 (setq special-brace-list 8328 (setq special-brace-list
6487 (or (and c-special-brace-lists 8329 (or (and c-special-brace-lists ;;;; ALWAYS NIL FOR AWK!!
6488 (save-excursion 8330 (save-excursion
6489 (goto-char containing-sexp) 8331 (goto-char containing-sexp)
6490 (c-looking-at-special-brace-list))) 8332 (c-looking-at-special-brace-list)))
6491 (c-inside-bracelist-p containing-sexp paren-state)))) 8333 (c-inside-bracelist-p containing-sexp paren-state))))
6492 (cond 8334 (cond
8335
6493 ;; CASE 9A: In the middle of a special brace list opener. 8336 ;; CASE 9A: In the middle of a special brace list opener.
6494 ((and (consp special-brace-list) 8337 ((and (consp special-brace-list)
6495 (save-excursion 8338 (save-excursion
@@ -6509,6 +8352,7 @@ This function does not do any hidden buffer changes."
6509 (goto-char (match-end 1)) 8352 (goto-char (match-end 1))
6510 (c-forward-syntactic-ws)) 8353 (c-forward-syntactic-ws))
6511 (c-add-syntax 'brace-list-open (c-point 'boi)))) 8354 (c-add-syntax 'brace-list-open (c-point 'boi))))
8355
6512 ;; CASE 9B: brace-list-close brace 8356 ;; CASE 9B: brace-list-close brace
6513 ((if (consp special-brace-list) 8357 ((if (consp special-brace-list)
6514 ;; Check special brace list closer. 8358 ;; Check special brace list closer.
@@ -6533,8 +8377,8 @@ This function does not do any hidden buffer changes."
6533 (c-add-syntax 'brace-list-close (point)) 8377 (c-add-syntax 'brace-list-close (point))
6534 (setq lim (c-most-enclosing-brace c-state-cache (point))) 8378 (setq lim (c-most-enclosing-brace c-state-cache (point)))
6535 (c-beginning-of-statement-1 lim) 8379 (c-beginning-of-statement-1 lim)
6536 (c-add-stmt-syntax 'brace-list-close nil t t lim 8380 (c-add-stmt-syntax 'brace-list-close nil t lim paren-state)))
6537 (c-whack-state-after (point) paren-state)))) 8381
6538 (t 8382 (t
6539 ;; Prepare for the rest of the cases below by going to the 8383 ;; Prepare for the rest of the cases below by going to the
6540 ;; token following the opening brace 8384 ;; token following the opening brace
@@ -6549,6 +8393,7 @@ This function does not do any hidden buffer changes."
6549 (goto-char (max start (c-point 'bol)))) 8393 (goto-char (max start (c-point 'bol))))
6550 (c-skip-ws-forward indent-point) 8394 (c-skip-ws-forward indent-point)
6551 (cond 8395 (cond
8396
6552 ;; CASE 9C: we're looking at the first line in a brace-list 8397 ;; CASE 9C: we're looking at the first line in a brace-list
6553 ((= (point) indent-point) 8398 ((= (point) indent-point)
6554 (if (consp special-brace-list) 8399 (if (consp special-brace-list)
@@ -6558,8 +8403,8 @@ This function does not do any hidden buffer changes."
6558 (c-add-syntax 'brace-list-intro (point)) 8403 (c-add-syntax 'brace-list-intro (point))
6559 (setq lim (c-most-enclosing-brace c-state-cache (point))) 8404 (setq lim (c-most-enclosing-brace c-state-cache (point)))
6560 (c-beginning-of-statement-1 lim) 8405 (c-beginning-of-statement-1 lim)
6561 (c-add-stmt-syntax 'brace-list-intro nil t t lim 8406 (c-add-stmt-syntax 'brace-list-intro nil t lim paren-state)))
6562 (c-whack-state-after (point) paren-state)))) 8407
6563 ;; CASE 9D: this is just a later brace-list-entry or 8408 ;; CASE 9D: this is just a later brace-list-entry or
6564 ;; brace-entry-open 8409 ;; brace-entry-open
6565 (t (if (or (eq char-after-ip ?{) 8410 (t (if (or (eq char-after-ip ?{)
@@ -6572,12 +8417,12 @@ This function does not do any hidden buffer changes."
6572 (c-add-syntax 'brace-list-entry (point)) 8417 (c-add-syntax 'brace-list-entry (point))
6573 )) 8418 ))
6574 )))) 8419 ))))
8420
6575 ;; CASE 10: A continued statement or top level construct. 8421 ;; CASE 10: A continued statement or top level construct.
6576 ((and (if (c-mode-is-new-awk-p) 8422 ((and (not (memq char-before-ip '(?\; ?:)))
6577 (c-awk-prev-line-incomplete-p containing-sexp) ; ACM 2002/3/29 8423 (not (c-at-vsemi-p before-ws-ip))
6578 (and (not (memq char-before-ip '(?\; ?:))) 8424 (or (not (eq char-before-ip ?}))
6579 (or (not (eq char-before-ip ?})) 8425 (c-looking-at-inexpr-block-backward c-state-cache))
6580 (c-looking-at-inexpr-block-backward c-state-cache))))
6581 (> (point) 8426 (> (point)
6582 (save-excursion 8427 (save-excursion
6583 (c-beginning-of-statement-1 containing-sexp) 8428 (c-beginning-of-statement-1 containing-sexp)
@@ -6589,29 +8434,7 @@ This function does not do any hidden buffer changes."
6589 placeholder 8434 placeholder
6590 containing-sexp 8435 containing-sexp
6591 paren-state)) 8436 paren-state))
6592 ;; CASE 14: A case or default label 8437
6593 ((looking-at c-label-kwds-regexp)
6594 (goto-char containing-sexp)
6595 (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
6596 (c-backward-to-block-anchor lim)
6597 (c-add-stmt-syntax 'case-label nil t nil
6598 lim paren-state))
6599 ;; CASE 15: any other label
6600 ((looking-at c-label-key)
6601 (goto-char containing-sexp)
6602 (setq lim (c-most-enclosing-brace c-state-cache containing-sexp))
6603 (save-excursion
6604 (setq tmpsymbol
6605 (if (and (eq (c-beginning-of-statement-1 lim) 'up)
6606 (looking-at "switch\\>[^_]"))
6607 ;; If the surrounding statement is a switch then
6608 ;; let's analyze all labels as switch labels, so
6609 ;; that they get lined up consistently.
6610 'case-label
6611 'label)))
6612 (c-backward-to-block-anchor lim)
6613 (c-add-stmt-syntax tmpsymbol nil t nil
6614 lim paren-state))
6615 ;; CASE 16: block close brace, possibly closing the defun or 8438 ;; CASE 16: block close brace, possibly closing the defun or
6616 ;; the class 8439 ;; the class
6617 ((eq char-after-ip ?}) 8440 ((eq char-after-ip ?})
@@ -6619,14 +8442,15 @@ This function does not do any hidden buffer changes."
6619 (setq lim (c-most-enclosing-brace paren-state)) 8442 (setq lim (c-most-enclosing-brace paren-state))
6620 (goto-char containing-sexp) 8443 (goto-char containing-sexp)
6621 (cond 8444 (cond
8445
6622 ;; CASE 16E: Closing a statement block? This catches 8446 ;; CASE 16E: Closing a statement block? This catches
6623 ;; cases where it's preceded by a statement keyword, 8447 ;; cases where it's preceded by a statement keyword,
6624 ;; which works even when used in an "invalid" context, 8448 ;; which works even when used in an "invalid" context,
6625 ;; e.g. a macro argument. 8449 ;; e.g. a macro argument.
6626 ((c-after-conditional) 8450 ((c-after-conditional)
6627 (c-backward-to-block-anchor lim) 8451 (c-backward-to-block-anchor lim)
6628 (c-add-stmt-syntax 'block-close nil t nil 8452 (c-add-stmt-syntax 'block-close nil t lim paren-state))
6629 lim paren-state)) 8453
6630 ;; CASE 16A: closing a lambda defun or an in-expression 8454 ;; CASE 16A: closing a lambda defun or an in-expression
6631 ;; block? C.f. cases 4, 7B and 17E. 8455 ;; block? C.f. cases 4, 7B and 17E.
6632 ((setq placeholder (c-looking-at-inexpr-block 8456 ((setq placeholder (c-looking-at-inexpr-block
@@ -6641,56 +8465,59 @@ This function does not do any hidden buffer changes."
6641 (c-add-syntax tmpsymbol (point)) 8465 (c-add-syntax tmpsymbol (point))
6642 (goto-char (cdr placeholder)) 8466 (goto-char (cdr placeholder))
6643 (back-to-indentation) 8467 (back-to-indentation)
6644 (c-add-stmt-syntax tmpsymbol nil t nil 8468 (c-add-stmt-syntax tmpsymbol nil t
6645 (c-most-enclosing-brace paren-state (point)) 8469 (c-most-enclosing-brace paren-state (point))
6646 (c-whack-state-after (point) paren-state)) 8470 paren-state)
6647 (if (/= (point) (cdr placeholder)) 8471 (if (/= (point) (cdr placeholder))
6648 (c-add-syntax (car placeholder))))) 8472 (c-add-syntax (car placeholder)))))
8473
6649 ;; CASE 16B: does this close an inline or a function in 8474 ;; CASE 16B: does this close an inline or a function in
6650 ;; a non-class declaration level block? 8475 ;; a non-class declaration level block?
6651 ((setq placeholder (c-search-uplist-for-classkey paren-state)) 8476 ((save-excursion
8477 (and lim
8478 (progn
8479 (goto-char lim)
8480 (c-looking-at-decl-block
8481 (c-most-enclosing-brace paren-state lim)
8482 nil))
8483 (setq placeholder (point))))
6652 (c-backward-to-decl-anchor lim) 8484 (c-backward-to-decl-anchor lim)
6653 (back-to-indentation) 8485 (back-to-indentation)
6654 (if (save-excursion 8486 (if (save-excursion
6655 (goto-char (aref placeholder 0)) 8487 (goto-char placeholder)
6656 (looking-at c-other-decl-block-key)) 8488 (looking-at c-other-decl-block-key))
6657 (c-add-syntax 'defun-close (point)) 8489 (c-add-syntax 'defun-close (point))
6658 (c-add-syntax 'inline-close (point)))) 8490 (c-add-syntax 'inline-close (point))))
8491
6659 ;; CASE 16F: Can be a defun-close of a function declared 8492 ;; CASE 16F: Can be a defun-close of a function declared
6660 ;; in a statement block, e.g. in Pike or when using gcc 8493 ;; in a statement block, e.g. in Pike or when using gcc
6661 ;; extensions, but watch out for macros followed by 8494 ;; extensions, but watch out for macros followed by
6662 ;; blocks. Let it through to be handled below. 8495 ;; blocks. Let it through to be handled below.
6663 ;; C.f. cases B.3 and 17G. 8496 ;; C.f. cases B.3 and 17G.
6664 ((and (not inenclosing-p) 8497 ((save-excursion
6665 lim 8498 (and (not (c-at-statement-start-p))
6666 (save-excursion 8499 (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
6667 (and (not (c-looking-at-bos)) 8500 (setq placeholder (point))
6668 (eq (c-beginning-of-statement-1 lim nil nil t) 'same) 8501 (let ((c-recognize-typeless-decls nil))
6669 (setq placeholder (point)) 8502 ;; Turn off recognition of constructs that
6670 ;; Look for a type or identifier followed by a 8503 ;; lacks a type in this case, since that's more
6671 ;; symbol, i.e. the start of a function declaration. 8504 ;; likely to be a macro followed by a block.
6672 ;; Doesn't work for declarations like "int *foo() 8505 (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil))))
6673 ;; ..."; we'd need to refactor the more competent
6674 ;; analysis in `c-font-lock-declarations' for that.
6675 (c-forward-type)
6676 (progn
6677 (c-forward-syntactic-ws)
6678 (looking-at c-symbol-start)))))
6679 (back-to-indentation) 8506 (back-to-indentation)
6680 (if (/= (point) containing-sexp) 8507 (if (/= (point) containing-sexp)
6681 (goto-char placeholder)) 8508 (goto-char placeholder))
6682 (c-add-stmt-syntax 'defun-close nil t nil 8509 (c-add-stmt-syntax 'defun-close nil t lim paren-state))
6683 lim paren-state)) 8510
6684 ;; CASE 16C: if there an enclosing brace that hasn't 8511 ;; CASE 16C: If there is an enclosing brace then this is
6685 ;; been narrowed out by a class, then this is a 8512 ;; a block close since defun closes inside declaration
6686 ;; block-close. C.f. case 17H. 8513 ;; level blocks have been handled above.
6687 ((and (not inenclosing-p) lim) 8514 (lim
6688 ;; If the block is preceded by a case/switch label on 8515 ;; If the block is preceded by a case/switch label on
6689 ;; the same line, we anchor at the first preceding label 8516 ;; the same line, we anchor at the first preceding label
6690 ;; at boi. The default handling in c-add-stmt-syntax is 8517 ;; at boi. The default handling in c-add-stmt-syntax
6691 ;; really fixes it better, but we do like this to keep 8518 ;; really fixes it better, but we do like this to keep
6692 ;; the indentation compatible with version 5.28 and 8519 ;; the indentation compatible with version 5.28 and
6693 ;; earlier. 8520 ;; earlier. C.f. case 17H.
6694 (while (and (/= (setq placeholder (point)) (c-point 'boi)) 8521 (while (and (/= (setq placeholder (point)) (c-point 'boi))
6695 (eq (c-beginning-of-statement-1 lim) 'label))) 8522 (eq (c-beginning-of-statement-1 lim) 'label)))
6696 (goto-char placeholder) 8523 (goto-char placeholder)
@@ -6699,21 +8526,17 @@ This function does not do any hidden buffer changes."
6699 (goto-char containing-sexp) 8526 (goto-char containing-sexp)
6700 ;; c-backward-to-block-anchor not necessary here; those 8527 ;; c-backward-to-block-anchor not necessary here; those
6701 ;; situations are handled in case 16E above. 8528 ;; situations are handled in case 16E above.
6702 (c-add-stmt-syntax 'block-close nil t nil 8529 (c-add-stmt-syntax 'block-close nil t lim paren-state)))
6703 lim paren-state))) 8530
6704 ;; CASE 16D: find out whether we're closing a top-level 8531 ;; CASE 16D: Only top level defun close left.
6705 ;; class or a defun
6706 (t 8532 (t
6707 (save-restriction 8533 (goto-char containing-sexp)
6708 (narrow-to-region (point-min) indent-point) 8534 (c-backward-to-decl-anchor lim)
6709 (let ((decl (c-search-uplist-for-classkey (c-parse-state)))) 8535 (c-add-stmt-syntax 'defun-close nil nil
6710 (if decl 8536 (c-most-enclosing-brace paren-state)
6711 (c-add-class-syntax 'class-close decl paren-state) 8537 paren-state))
6712 (goto-char containing-sexp) 8538 ))
6713 (c-backward-to-decl-anchor lim) 8539
6714 (back-to-indentation)
6715 (c-add-syntax 'defun-close (point)))))
6716 )))
6717 ;; CASE 17: Statement or defun catchall. 8540 ;; CASE 17: Statement or defun catchall.
6718 (t 8541 (t
6719 (goto-char indent-point) 8542 (goto-char indent-point)
@@ -6728,11 +8551,13 @@ This function does not do any hidden buffer changes."
6728 (setq step-type last-step-type) 8551 (setq step-type last-step-type)
6729 (/= (point) (c-point 'boi))))) 8552 (/= (point) (c-point 'boi)))))
6730 (cond 8553 (cond
8554
6731 ;; CASE 17B: continued statement 8555 ;; CASE 17B: continued statement
6732 ((and (eq step-type 'same) 8556 ((and (eq step-type 'same)
6733 (/= (point) indent-point)) 8557 (/= (point) indent-point))
6734 (c-add-stmt-syntax 'statement-cont nil nil nil 8558 (c-add-stmt-syntax 'statement-cont nil nil
6735 containing-sexp paren-state)) 8559 containing-sexp paren-state))
8560
6736 ;; CASE 17A: After a case/default label? 8561 ;; CASE 17A: After a case/default label?
6737 ((progn 8562 ((progn
6738 (while (and (eq step-type 'label) 8563 (while (and (eq step-type 'label)
@@ -6743,17 +8568,19 @@ This function does not do any hidden buffer changes."
6743 (c-add-stmt-syntax (if (eq char-after-ip ?{) 8568 (c-add-stmt-syntax (if (eq char-after-ip ?{)
6744 'statement-case-open 8569 'statement-case-open
6745 'statement-case-intro) 8570 'statement-case-intro)
6746 nil t nil containing-sexp paren-state)) 8571 nil t containing-sexp paren-state))
8572
6747 ;; CASE 17D: any old statement 8573 ;; CASE 17D: any old statement
6748 ((progn 8574 ((progn
6749 (while (eq step-type 'label) 8575 (while (eq step-type 'label)
6750 (setq step-type 8576 (setq step-type
6751 (c-beginning-of-statement-1 containing-sexp))) 8577 (c-beginning-of-statement-1 containing-sexp)))
6752 (eq step-type 'previous)) 8578 (eq step-type 'previous))
6753 (c-add-stmt-syntax 'statement nil t nil 8579 (c-add-stmt-syntax 'statement nil t
6754 containing-sexp paren-state) 8580 containing-sexp paren-state)
6755 (if (eq char-after-ip ?{) 8581 (if (eq char-after-ip ?{)
6756 (c-add-syntax 'block-open))) 8582 (c-add-syntax 'block-open)))
8583
6757 ;; CASE 17I: Inside a substatement block. 8584 ;; CASE 17I: Inside a substatement block.
6758 ((progn 8585 ((progn
6759 ;; The following tests are all based on containing-sexp. 8586 ;; The following tests are all based on containing-sexp.
@@ -6762,10 +8589,11 @@ This function does not do any hidden buffer changes."
6762 (setq lim (c-most-enclosing-brace paren-state containing-sexp)) 8589 (setq lim (c-most-enclosing-brace paren-state containing-sexp))
6763 (c-after-conditional)) 8590 (c-after-conditional))
6764 (c-backward-to-block-anchor lim) 8591 (c-backward-to-block-anchor lim)
6765 (c-add-stmt-syntax 'statement-block-intro nil t nil 8592 (c-add-stmt-syntax 'statement-block-intro nil t
6766 lim paren-state) 8593 lim paren-state)
6767 (if (eq char-after-ip ?{) 8594 (if (eq char-after-ip ?{)
6768 (c-add-syntax 'block-open))) 8595 (c-add-syntax 'block-open)))
8596
6769 ;; CASE 17E: first statement in an in-expression block. 8597 ;; CASE 17E: first statement in an in-expression block.
6770 ;; C.f. cases 4, 7B and 16A. 8598 ;; C.f. cases 4, 7B and 16A.
6771 ((setq placeholder (c-looking-at-inexpr-block 8599 ((setq placeholder (c-looking-at-inexpr-block
@@ -6779,54 +8607,58 @@ This function does not do any hidden buffer changes."
6779 (c-add-syntax tmpsymbol (point)) 8607 (c-add-syntax tmpsymbol (point))
6780 (goto-char (cdr placeholder)) 8608 (goto-char (cdr placeholder))
6781 (back-to-indentation) 8609 (back-to-indentation)
6782 (c-add-stmt-syntax tmpsymbol nil t nil 8610 (c-add-stmt-syntax tmpsymbol nil t
6783 (c-most-enclosing-brace c-state-cache (point)) 8611 (c-most-enclosing-brace c-state-cache (point))
6784 (c-whack-state-after (point) paren-state)) 8612 paren-state)
6785 (if (/= (point) (cdr placeholder)) 8613 (if (/= (point) (cdr placeholder))
6786 (c-add-syntax (car placeholder)))) 8614 (c-add-syntax (car placeholder))))
6787 (if (eq char-after-ip ?{) 8615 (if (eq char-after-ip ?{)
6788 (c-add-syntax 'block-open))) 8616 (c-add-syntax 'block-open)))
8617
6789 ;; CASE 17F: first statement in an inline, or first 8618 ;; CASE 17F: first statement in an inline, or first
6790 ;; statement in a top-level defun. we can tell this is it 8619 ;; statement in a top-level defun. we can tell this is it
6791 ;; if there are no enclosing braces that haven't been 8620 ;; if there are no enclosing braces that haven't been
6792 ;; narrowed out by a class (i.e. don't use bod here). 8621 ;; narrowed out by a class (i.e. don't use bod here).
6793 ((save-excursion 8622 ((save-excursion
6794 (save-restriction 8623 (or (not (setq placeholder (c-most-enclosing-brace
6795 (widen) 8624 paren-state)))
6796 (c-narrow-out-enclosing-class paren-state containing-sexp) 8625 (and (progn
6797 (not (c-most-enclosing-brace paren-state)))) 8626 (goto-char placeholder)
8627 (eq (char-after) ?{))
8628 (c-looking-at-decl-block (c-most-enclosing-brace
8629 paren-state (point))
8630 nil))))
6798 (c-backward-to-decl-anchor lim) 8631 (c-backward-to-decl-anchor lim)
6799 (back-to-indentation) 8632 (back-to-indentation)
6800 (c-add-syntax 'defun-block-intro (point))) 8633 (c-add-syntax 'defun-block-intro (point)))
8634
6801 ;; CASE 17G: First statement in a function declared inside 8635 ;; CASE 17G: First statement in a function declared inside
6802 ;; a normal block. This can occur in Pike and with 8636 ;; a normal block. This can occur in Pike and with
6803 ;; e.g. the gcc extensions, but watch out for macros 8637 ;; e.g. the gcc extensions, but watch out for macros
6804 ;; followed by blocks. C.f. cases B.3 and 16F. 8638 ;; followed by blocks. C.f. cases B.3 and 16F.
6805 ((save-excursion 8639 ((save-excursion
6806 (and (not (c-looking-at-bos)) 8640 (and (not (c-at-statement-start-p))
6807 (eq (c-beginning-of-statement-1 lim nil nil t) 'same) 8641 (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
6808 (setq placeholder (point)) 8642 (setq placeholder (point))
6809 ;; Look for a type or identifier followed by a 8643 (let ((c-recognize-typeless-decls nil))
6810 ;; symbol, i.e. the start of a function declaration. 8644 ;; Turn off recognition of constructs that lacks
6811 ;; Doesn't work for declarations like "int *foo() 8645 ;; a type in this case, since that's more likely
6812 ;; ..."; we'd need to refactor the more competent 8646 ;; to be a macro followed by a block.
6813 ;; analysis in `c-font-lock-declarations' for that. 8647 (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil))))
6814 (c-forward-type)
6815 (progn
6816 (c-forward-syntactic-ws)
6817 (looking-at c-symbol-start))))
6818 (back-to-indentation) 8648 (back-to-indentation)
6819 (if (/= (point) containing-sexp) 8649 (if (/= (point) containing-sexp)
6820 (goto-char placeholder)) 8650 (goto-char placeholder))
6821 (c-add-stmt-syntax 'defun-block-intro nil t nil 8651 (c-add-stmt-syntax 'defun-block-intro nil t
6822 lim paren-state)) 8652 lim paren-state))
6823 ;; CASE 17H: First statement in a block. C.f. case 16C. 8653
8654 ;; CASE 17H: First statement in a block.
6824 (t 8655 (t
6825 ;; If the block is preceded by a case/switch label on the 8656 ;; If the block is preceded by a case/switch label on the
6826 ;; same line, we anchor at the first preceding label at 8657 ;; same line, we anchor at the first preceding label at
6827 ;; boi. The default handling in c-add-stmt-syntax is 8658 ;; boi. The default handling in c-add-stmt-syntax is
6828 ;; really fixes it better, but we do like this to keep the 8659 ;; really fixes it better, but we do like this to keep the
6829 ;; indentation compatible with version 5.28 and earlier. 8660 ;; indentation compatible with version 5.28 and earlier.
8661 ;; C.f. case 16C.
6830 (while (and (/= (setq placeholder (point)) (c-point 'boi)) 8662 (while (and (/= (setq placeholder (point)) (c-point 'boi))
6831 (eq (c-beginning-of-statement-1 lim) 'label))) 8663 (eq (c-beginning-of-statement-1 lim) 'label)))
6832 (goto-char placeholder) 8664 (goto-char placeholder)
@@ -6835,19 +8667,22 @@ This function does not do any hidden buffer changes."
6835 (goto-char containing-sexp) 8667 (goto-char containing-sexp)
6836 ;; c-backward-to-block-anchor not necessary here; those 8668 ;; c-backward-to-block-anchor not necessary here; those
6837 ;; situations are handled in case 17I above. 8669 ;; situations are handled in case 17I above.
6838 (c-add-stmt-syntax 'statement-block-intro nil t nil 8670 (c-add-stmt-syntax 'statement-block-intro nil t
6839 lim paren-state)) 8671 lim paren-state))
6840 (if (eq char-after-ip ?{) 8672 (if (eq char-after-ip ?{)
6841 (c-add-syntax 'block-open))) 8673 (c-add-syntax 'block-open)))
6842 )) 8674 ))
6843 ) 8675 )
8676
6844 ;; now we need to look at any modifiers 8677 ;; now we need to look at any modifiers
6845 (goto-char indent-point) 8678 (goto-char indent-point)
6846 (skip-chars-forward " \t") 8679 (skip-chars-forward " \t")
8680
6847 ;; are we looking at a comment only line? 8681 ;; are we looking at a comment only line?
6848 (when (and (looking-at c-comment-start-regexp) 8682 (when (and (looking-at c-comment-start-regexp)
6849 (/= (c-forward-token-2 0 nil (c-point 'eol)) 0)) 8683 (/= (c-forward-token-2 0 nil (c-point 'eol)) 0))
6850 (c-append-syntax 'comment-intro)) 8684 (c-append-syntax 'comment-intro))
8685
6851 ;; we might want to give additional offset to friends (in C++). 8686 ;; we might want to give additional offset to friends (in C++).
6852 (when (and c-opt-friend-key 8687 (when (and c-opt-friend-key
6853 (looking-at c-opt-friend-key)) 8688 (looking-at c-opt-friend-key))
@@ -6856,9 +8691,9 @@ This function does not do any hidden buffer changes."
6856 ;; Set syntactic-relpos. 8691 ;; Set syntactic-relpos.
6857 (let ((p c-syntactic-context)) 8692 (let ((p c-syntactic-context))
6858 (while (and p 8693 (while (and p
6859 (if (integerp (car-safe (cdr-safe (car p)))) 8694 (if (integerp (c-langelem-pos (car p)))
6860 (progn 8695 (progn
6861 (setq syntactic-relpos (car (cdr (car p)))) 8696 (setq syntactic-relpos (c-langelem-pos (car p)))
6862 nil) 8697 nil)
6863 t)) 8698 t))
6864 (setq p (cdr p)))) 8699 (setq p (cdr p))))
@@ -6897,8 +8732,9 @@ This function does not do any hidden buffer changes."
6897 ;; we add cpp-define-intro to get the extra 8732 ;; we add cpp-define-intro to get the extra
6898 ;; indentation of the #define body. 8733 ;; indentation of the #define body.
6899 (c-add-syntax 'cpp-define-intro))))) 8734 (c-add-syntax 'cpp-define-intro)))))
8735
6900 ;; return the syntax 8736 ;; return the syntax
6901 c-syntactic-context)))) 8737 c-syntactic-context)))
6902 8738
6903 8739
6904;; Indentation calculation. 8740;; Indentation calculation.
@@ -6906,44 +8742,118 @@ This function does not do any hidden buffer changes."
6906(defun c-evaluate-offset (offset langelem symbol) 8742(defun c-evaluate-offset (offset langelem symbol)
6907 ;; offset can be a number, a function, a variable, a list, or one of 8743 ;; offset can be a number, a function, a variable, a list, or one of
6908 ;; the symbols + or - 8744 ;; the symbols + or -
6909 (cond 8745 ;;
6910 ((eq offset '+) c-basic-offset) 8746 ;; This function might do hidden buffer changes.
6911 ((eq offset '-) (- c-basic-offset)) 8747 (let ((res
6912 ((eq offset '++) (* 2 c-basic-offset)) 8748 (cond
6913 ((eq offset '--) (* 2 (- c-basic-offset))) 8749 ((numberp offset) offset)
6914 ((eq offset '*) (/ c-basic-offset 2)) 8750 ((vectorp offset) offset)
6915 ((eq offset '/) (/ (- c-basic-offset) 2)) 8751 ((null offset) nil)
6916 ((numberp offset) offset) 8752
6917 ((functionp offset) (c-evaluate-offset 8753 ((eq offset '+) c-basic-offset)
6918 (funcall offset 8754 ((eq offset '-) (- c-basic-offset))
6919 (cons (car langelem) 8755 ((eq offset '++) (* 2 c-basic-offset))
6920 (car-safe (cdr langelem)))) 8756 ((eq offset '--) (* 2 (- c-basic-offset)))
6921 langelem symbol)) 8757 ((eq offset '*) (/ c-basic-offset 2))
6922 ((vectorp offset) offset) 8758 ((eq offset '/) (/ (- c-basic-offset) 2))
6923 ((null offset) nil) 8759
6924 ((listp offset) 8760 ((functionp offset)
6925 (if (eq (car offset) 'quote) 8761 (c-evaluate-offset
6926 (error 8762 (funcall offset
6927"Setting in c-offsets-alist element \"(%s . '%s)\" was mistakenly quoted" 8763 (cons (c-langelem-sym langelem)
6928 symbol (cadr offset))) 8764 (c-langelem-pos langelem)))
6929 (let (done) 8765 langelem symbol))
6930 (while (and (not done) offset) 8766
6931 (setq done (c-evaluate-offset (car offset) langelem symbol) 8767 ((listp offset)
6932 offset (cdr offset))) 8768 (cond
6933 (if (and c-strict-syntax-p (not done)) 8769 ((eq (car offset) 'quote)
6934 (c-benign-error "No offset found for syntactic symbol %s" symbol)) 8770 (c-benign-error "The offset %S for %s was mistakenly quoted"
6935 done)) 8771 offset symbol)
6936 (t (symbol-value offset)) 8772 nil)
6937 )) 8773
8774 ((memq (car offset) '(min max))
8775 (let (res val (method (car offset)))
8776 (setq offset (cdr offset))
8777 (while offset
8778 (setq val (c-evaluate-offset (car offset) langelem symbol))
8779 (cond
8780 ((not val))
8781 ((not res)
8782 (setq res val))
8783 ((integerp val)
8784 (if (vectorp res)
8785 (c-benign-error "\
8786Error evaluating offset %S for %s: \
8787Cannot combine absolute offset %S with relative %S in `%s' method"
8788 (car offset) symbol res val method)
8789 (setq res (funcall method res val))))
8790 (t
8791 (if (integerp res)
8792 (c-benign-error "\
8793Error evaluating offset %S for %s: \
8794Cannot combine relative offset %S with absolute %S in `%s' method"
8795 (car offset) symbol res val method)
8796 (setq res (vector (funcall method (aref res 0)
8797 (aref val 0)))))))
8798 (setq offset (cdr offset)))
8799 res))
8800
8801 ((eq (car offset) 'add)
8802 (let (res val)
8803 (setq offset (cdr offset))
8804 (while offset
8805 (setq val (c-evaluate-offset (car offset) langelem symbol))
8806 (cond
8807 ((not val))
8808 ((not res)
8809 (setq res val))
8810 ((integerp val)
8811 (if (vectorp res)
8812 (setq res (vector (+ (aref res 0) val)))
8813 (setq res (+ res val))))
8814 (t
8815 (if (vectorp res)
8816 (c-benign-error "\
8817Error evaluating offset %S for %s: \
8818Cannot combine absolute offsets %S and %S in `add' method"
8819 (car offset) symbol res val)
8820 (setq res val)))) ; Override.
8821 (setq offset (cdr offset)))
8822 res))
8823
8824 (t
8825 (let (res)
8826 (when (eq (car offset) 'first)
8827 (setq offset (cdr offset)))
8828 (while (and (not res) offset)
8829 (setq res (c-evaluate-offset (car offset) langelem symbol)
8830 offset (cdr offset)))
8831 res))))
8832
8833 ((and (symbolp offset) (boundp offset))
8834 (symbol-value offset))
8835
8836 (t
8837 (c-benign-error "Unknown offset format %S for %s" offset symbol)
8838 nil))))
8839
8840 (if (or (null res) (integerp res)
8841 (and (vectorp res) (= (length res) 1) (integerp (aref res 0))))
8842 res
8843 (c-benign-error "Error evaluating offset %S for %s: Got invalid value %S"
8844 offset symbol res)
8845 nil)))
6938 8846
6939(defun c-calc-offset (langelem) 8847(defun c-calc-offset (langelem)
6940 ;; Get offset from LANGELEM which is a list beginning with the 8848 ;; Get offset from LANGELEM which is a list beginning with the
6941 ;; syntactic symbol and followed by any analysis data it provides. 8849 ;; syntactic symbol and followed by any analysis data it provides.
6942 ;; That data may be zero or more elements, but if at least one is 8850 ;; That data may be zero or more elements, but if at least one is
6943 ;; given then the first is the relpos (or nil). The symbol is 8851 ;; given then the first is the anchor position (or nil). The symbol
6944 ;; matched against `c-offsets-alist' and the offset calculated from 8852 ;; is matched against `c-offsets-alist' and the offset calculated
6945 ;; that is returned. 8853 ;; from that is returned.
6946 (let* ((symbol (car langelem)) 8854 ;;
8855 ;; This function might do hidden buffer changes.
8856 (let* ((symbol (c-langelem-sym langelem))
6947 (match (assq symbol c-offsets-alist)) 8857 (match (assq symbol c-offsets-alist))
6948 (offset (cdr-safe match))) 8858 (offset (cdr-safe match)))
6949 (if match 8859 (if match
@@ -6961,21 +8871,26 @@ This function does not do any hidden buffer changes."
6961(defun c-get-offset (langelem) 8871(defun c-get-offset (langelem)
6962 ;; This is a compatibility wrapper for `c-calc-offset' in case 8872 ;; This is a compatibility wrapper for `c-calc-offset' in case
6963 ;; someone is calling it directly. It takes an old style syntactic 8873 ;; someone is calling it directly. It takes an old style syntactic
6964 ;; element on the form (SYMBOL . RELPOS) and converts it to the new 8874 ;; element on the form (SYMBOL . ANCHOR-POS) and converts it to the
6965 ;; list form. 8875 ;; new list form.
6966 (if (cdr langelem) 8876 ;;
6967 (c-calc-offset (list (car langelem) (cdr langelem))) 8877 ;; This function might do hidden buffer changes.
8878 (if (c-langelem-pos langelem)
8879 (c-calc-offset (list (c-langelem-sym langelem)
8880 (c-langelem-pos langelem)))
6968 (c-calc-offset langelem))) 8881 (c-calc-offset langelem)))
6969 8882
6970(defun c-get-syntactic-indentation (langelems) 8883(defun c-get-syntactic-indentation (langelems)
6971 ;; Calculate the syntactic indentation from a syntactic description 8884 ;; Calculate the syntactic indentation from a syntactic description
6972 ;; as returned by `c-guess-syntax'. 8885 ;; as returned by `c-guess-syntax'.
6973 ;; 8886 ;;
6974 ;; Note that topmost-intro always has a relpos at bol, for 8887 ;; Note that topmost-intro always has an anchor position at bol, for
6975 ;; historical reasons. It's often used together with other symbols 8888 ;; historical reasons. It's often used together with other symbols
6976 ;; that has more sane positions. Since we always use the first 8889 ;; that has more sane positions. Since we always use the first
6977 ;; found relpos, we rely on that these other symbols always precede 8890 ;; found anchor position, we rely on that these other symbols always
6978 ;; topmost-intro in the LANGELEMS list. 8891 ;; precede topmost-intro in the LANGELEMS list.
8892 ;;
8893 ;; This function might do hidden buffer changes.
6979 (let ((indent 0) anchor) 8894 (let ((indent 0) anchor)
6980 8895
6981 (while langelems 8896 (while langelems
@@ -6997,9 +8912,7 @@ This function does not do any hidden buffer changes."
6997 ;; Use the anchor position from the first syntactic 8912 ;; Use the anchor position from the first syntactic
6998 ;; element with one. 8913 ;; element with one.
6999 (unless anchor 8914 (unless anchor
7000 (let ((relpos (car-safe (cdr (car langelems))))) 8915 (setq anchor (c-langelem-pos (car langelems)))))
7001 (if relpos
7002 (setq anchor relpos)))))
7003 8916
7004 (setq langelems (cdr langelems)))) 8917 (setq langelems (cdr langelems))))
7005 8918
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 95e4e5226f0..e5dcecf459f 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -1,6 +1,6 @@
1;;; cc-fonts.el --- font lock support for CC Mode 1;;; cc-fonts.el --- font lock support for CC Mode
2 2
3;; Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 4
5;; Authors: 2003- Alan Mackenzie 5;; Authors: 2003- Alan Mackenzie
6;; 2002- Martin Stjernholm 6;; 2002- Martin Stjernholm
@@ -30,8 +30,8 @@
30 30
31;; Some comments on the use of faces: 31;; Some comments on the use of faces:
32;; 32;;
33;; o `c-label-face-name' is either `font-lock-constant-face' (in Emacs 33;; o `c-label-face-name' is either `font-lock-constant-face' (in
34;; 20 and later), or `font-lock-reference-face'. 34;; Emacs), or `font-lock-reference-face'.
35;; 35;;
36;; o `c-constant-face-name', `c-reference-face-name' and 36;; o `c-constant-face-name', `c-reference-face-name' and
37;; `c-doc-markup-face-name' are essentially set up like 37;; `c-doc-markup-face-name' are essentially set up like
@@ -47,10 +47,6 @@
47;; documentation are actually comments in these languages, as opposed 47;; documentation are actually comments in these languages, as opposed
48;; to elisp). 48;; to elisp).
49;; 49;;
50;; o `c-invalid-face-name' is `font-lock-warning-face' in Emacs. In
51;; older XEmacs there's no corresponding standard face, so there
52;; it's mapped to a special `c-invalid-face'.
53;;
54;; TBD: We should probably provide real faces for the above uses and 50;; TBD: We should probably provide real faces for the above uses and
55;; instead initialize them from the standard faces. 51;; instead initialize them from the standard faces.
56 52
@@ -103,17 +99,9 @@
103(cc-bytecomp-defvar c-reference-face-name) 99(cc-bytecomp-defvar c-reference-face-name)
104(cc-bytecomp-defun c-fontify-recorded-types-and-refs) 100(cc-bytecomp-defun c-fontify-recorded-types-and-refs)
105(cc-bytecomp-defun c-font-lock-declarators) 101(cc-bytecomp-defun c-font-lock-declarators)
106(cc-bytecomp-defun c-font-lock-objc-iip-decl)
107(cc-bytecomp-defun c-font-lock-objc-method) 102(cc-bytecomp-defun c-font-lock-objc-method)
108(cc-bytecomp-defun c-font-lock-invalid-string) 103(cc-bytecomp-defun c-font-lock-invalid-string)
109 104
110;; Emacs 19 doesn't have `defface'. This "replacement" leaves a lot
111;; to be wished for but at least it avoids any errors.
112(cc-eval-when-compile
113 (or (fboundp 'defface)
114 (cc-bytecomp-defmacro defface (face spec doc &rest args)
115 `(make-face ',face))))
116
117 105
118;; Note that font-lock in XEmacs doesn't expand face names as 106;; Note that font-lock in XEmacs doesn't expand face names as
119;; variables, so we have to use the (eval . FORM) in the font lock 107;; variables, so we have to use the (eval . FORM) in the font lock
@@ -124,8 +112,8 @@
124 ;; XEmacs has a font-lock-preprocessor-face. 112 ;; XEmacs has a font-lock-preprocessor-face.
125 'font-lock-preprocessor-face) 113 'font-lock-preprocessor-face)
126 ((c-face-name-p 'font-lock-builtin-face) 114 ((c-face-name-p 'font-lock-builtin-face)
127 ;; In Emacs 20 and later font-lock-builtin-face has 115 ;; In Emacs font-lock-builtin-face has traditionally been
128 ;; traditionally been used for preprocessor directives. 116 ;; used for preprocessor directives.
129 'font-lock-builtin-face) 117 'font-lock-builtin-face)
130 (t 118 (t
131 'font-lock-reference-face))) 119 'font-lock-reference-face)))
@@ -150,19 +138,19 @@
150(defconst c-constant-face-name 138(defconst c-constant-face-name
151 (if (and (c-face-name-p 'font-lock-constant-face) 139 (if (and (c-face-name-p 'font-lock-constant-face)
152 (eq font-lock-constant-face 'font-lock-constant-face)) 140 (eq font-lock-constant-face 'font-lock-constant-face))
153 ;; This doesn't exist in XEmacs <= 20 and some earlier versions 141 ;; This doesn't exist in some earlier versions of XEmacs 21.
154 ;; of XEmacs 21.
155 'font-lock-constant-face 142 'font-lock-constant-face
156 c-label-face-name)) 143 c-label-face-name))
157 144
158(defconst c-reference-face-name 145(defconst c-reference-face-name
159 (if (and (c-face-name-p 'font-lock-reference-face) 146 (with-no-warnings
160 (eq font-lock-reference-face 'font-lock-reference-face)) 147 (if (and (c-face-name-p 'font-lock-reference-face)
161 ;; This is considered obsolete in Emacs 20 and later, but it 148 (eq font-lock-reference-face 'font-lock-reference-face))
162 ;; still maps well to this use. (Another reason to do this is 149 ;; This is considered obsolete in Emacs, but it still maps well
163 ;; to get unique faces for the test suite.) 150 ;; to this use. (Another reason to do this is to get unique
164 'font-lock-reference-face 151 ;; faces for the test suite.)
165 c-label-face-name)) 152 'font-lock-reference-face
153 c-label-face-name)))
166 154
167;; This should not mapped to a face that also is used to fontify things 155;; This should not mapped to a face that also is used to fontify things
168;; that aren't comments or string literals. 156;; that aren't comments or string literals.
@@ -184,31 +172,10 @@
184 'font-lock-doc-markup-face 172 'font-lock-doc-markup-face
185 c-label-face-name)) 173 c-label-face-name))
186 174
187(defconst c-invalid-face-name 175(defconst c-negation-char-face-name
188 (if (c-face-name-p 'font-lock-warning-face) 176 (if (c-face-name-p 'font-lock-negation-char-face)
189 ;; Emacs >= 20 and XEmacs >= 21 has a font-lock-warning-face. 177 ;; Emacs 22 has a special face for negation chars.
190 'font-lock-warning-face 178 'font-lock-negation-char-face))
191 ;; Otherwise we provide a face.
192 'c-invalid-face))
193
194(unless (c-face-name-p c-invalid-face-name)
195 (defconst c-invalid-face 'c-invalid-face) ; Necessary in Emacs 19.
196 ;; This face should be called `c-invalid' for consistency with the
197 ;; rest of emacs, but as it's only used in very old versions of Emacs,
198 ;; we leave it unchanged (the face-alias mechanism doesn't exist in
199 ;; those old versions).
200 (defface c-invalid-face
201 '((((class color) (background light)) (:foreground "red1"))
202 (((class color)) (:foreground "hotpink"))
203 (t (:inverse-video t)))
204 "Face used to highlight invalid syntax."
205 :group 'c-fonts))
206
207;; To make hard spaces visible an inverted version of
208;; `c-invalid-face-name' is used. Since font-lock in Emacs expands
209;; all face names in `font-lock-keywords' as variables we need to have
210;; a variable for it.
211(defconst c-nonbreakable-space-face 'c-nonbreakable-space)
212 179
213(cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs. 180(cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs.
214(cc-bytecomp-defun face-property-instance) ; Only in XEmacs. 181(cc-bytecomp-defun face-property-instance) ; Only in XEmacs.
@@ -216,25 +183,18 @@
216(defun c-make-inverse-face (oldface newface) 183(defun c-make-inverse-face (oldface newface)
217 ;; Emacs and XEmacs have completely different face manipulation 184 ;; Emacs and XEmacs have completely different face manipulation
218 ;; routines. :P 185 ;; routines. :P
219 ;;
220 ;; This function does not do any hidden buffer changes
221 (copy-face oldface newface) 186 (copy-face oldface newface)
222 (cond ((fboundp 'face-inverse-video-p) 187 (cond ((fboundp 'face-inverse-video-p)
223 ;; Emacs 20 and later. This only looks at the inverse flag 188 ;; Emacs. This only looks at the inverse flag in the current
224 ;; in the current frame. Other display configurations might 189 ;; frame. Other display configurations might be different,
225 ;; be different, but it can only show if the same Emacs has 190 ;; but it can only show if the same Emacs has frames on
226 ;; frames on e.g. a color and a monochrome display 191 ;; e.g. a color and a monochrome display simultaneously.
227 ;; simultaneously.
228 (unless (face-inverse-video-p oldface) 192 (unless (face-inverse-video-p oldface)
229 (invert-face newface))) 193 (invert-face newface)))
230 ((fboundp 'face-property-instance) 194 ((fboundp 'face-property-instance)
231 ;; XEmacs. Same pitfall here. 195 ;; XEmacs. Same pitfall here.
232 (unless (face-property-instance oldface 'reverse) 196 (unless (face-property-instance oldface 'reverse)
233 (invert-face newface))) 197 (invert-face newface)))))
234 (t
235 ;; Emacs 19 has no inverse flag at all. Just inverse the
236 ;; face and hope it wasn't inversed already.
237 (invert-face newface))))
238 198
239(eval-and-compile 199(eval-and-compile
240 ;; We need the following functions during compilation since they're 200 ;; We need the following functions during compilation since they're
@@ -247,6 +207,8 @@
247 ;; additional font-lock property, or else the font-lock package 207 ;; additional font-lock property, or else the font-lock package
248 ;; won't recognize it as fontified and might override it 208 ;; won't recognize it as fontified and might override it
249 ;; incorrectly. 209 ;; incorrectly.
210 ;;
211 ;; This function does a hidden buffer change.
250 (if (fboundp 'font-lock-set-face) 212 (if (fboundp 'font-lock-set-face)
251 ;; Note: This function has no docstring in XEmacs so it might be 213 ;; Note: This function has no docstring in XEmacs so it might be
252 ;; considered internal. 214 ;; considered internal.
@@ -255,6 +217,8 @@
255 217
256 (defmacro c-remove-font-lock-face (from to) 218 (defmacro c-remove-font-lock-face (from to)
257 ;; This is the inverse of `c-put-font-lock-face'. 219 ;; This is the inverse of `c-put-font-lock-face'.
220 ;;
221 ;; This function does a hidden buffer change.
258 (if (fboundp 'font-lock-remove-face) 222 (if (fboundp 'font-lock-remove-face)
259 `(font-lock-remove-face ,from ,to) 223 `(font-lock-remove-face ,from ,to)
260 `(remove-text-properties ,from ,to '(face nil)))) 224 `(remove-text-properties ,from ,to '(face nil))))
@@ -263,6 +227,8 @@
263 ;; Put `font-lock-string-face' on a string. The surrounding 227 ;; Put `font-lock-string-face' on a string. The surrounding
264 ;; quotes are included in Emacs but not in XEmacs. The passed 228 ;; quotes are included in Emacs but not in XEmacs. The passed
265 ;; region should include them. 229 ;; region should include them.
230 ;;
231 ;; This function does a hidden buffer change.
266 (if (featurep 'xemacs) 232 (if (featurep 'xemacs)
267 `(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face) 233 `(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face)
268 `(c-put-font-lock-face ,from ,to 'font-lock-string-face))) 234 `(c-put-font-lock-face ,from ,to 'font-lock-string-face)))
@@ -271,19 +237,22 @@
271 ;; Like `let', but additionally activates `c-record-type-identifiers' 237 ;; Like `let', but additionally activates `c-record-type-identifiers'
272 ;; and `c-record-ref-identifiers', and fontifies the recorded ranges 238 ;; and `c-record-ref-identifiers', and fontifies the recorded ranges
273 ;; accordingly on exit. 239 ;; accordingly on exit.
240 ;;
241 ;; This function does hidden buffer changes.
274 `(let ((c-record-type-identifiers t) 242 `(let ((c-record-type-identifiers t)
275 c-record-ref-identifiers 243 c-record-ref-identifiers
276 ,@varlist) 244 ,@varlist)
277 (prog1 (progn ,@body) 245 (prog1 (progn ,@body)
278 (c-fontify-recorded-types-and-refs)))) 246 (c-fontify-recorded-types-and-refs))))
279 (put 'c-fontify-types-and-refs 'lisp-indent-function 1) 247 (put 'c-fontify-types-and-refs 'lisp-indent-function 1)
280 (eval-after-load "edebug" '(def-edebug-spec c-fontify-types-and-refs let*))
281 248
282 (defun c-skip-comments-and-strings (limit) 249 (defun c-skip-comments-and-strings (limit)
283 ;; If the point is within a region fontified as a comment or 250 ;; If the point is within a region fontified as a comment or
284 ;; string literal skip to the end of it or to LIMIT, whichever 251 ;; string literal skip to the end of it or to LIMIT, whichever
285 ;; comes first, and return t. Otherwise return nil. The match 252 ;; comes first, and return t. Otherwise return nil. The match
286 ;; data is not clobbered. 253 ;; data is not clobbered.
254 ;;
255 ;; This function might do hidden buffer changes.
287 (when (c-got-face-at (point) c-literal-faces) 256 (when (c-got-face-at (point) c-literal-faces)
288 (while (progn 257 (while (progn
289 (goto-char (next-single-property-change 258 (goto-char (next-single-property-change
@@ -292,6 +261,26 @@
292 (c-got-face-at (point) c-literal-faces)))) 261 (c-got-face-at (point) c-literal-faces))))
293 t)) 262 t))
294 263
264 (defun c-make-syntactic-matcher (regexp)
265 ;; Returns a byte compiled function suitable for use in place of a
266 ;; regexp string in a `font-lock-keywords' matcher, except that
267 ;; only matches outside comments and string literals count.
268 ;;
269 ;; This function does not do any hidden buffer changes, but the
270 ;; generated functions will. (They are however used in places
271 ;; covered by the font-lock context.)
272 (byte-compile
273 `(lambda (limit)
274 (let (res)
275 (while (and (setq res (re-search-forward ,regexp limit t))
276 (progn
277 (goto-char (match-beginning 0))
278 (or (c-skip-comments-and-strings limit)
279 (progn
280 (goto-char (match-end 0))
281 nil)))))
282 res))))
283
295 (defun c-make-font-lock-search-function (regexp &rest highlights) 284 (defun c-make-font-lock-search-function (regexp &rest highlights)
296 ;; This function makes a byte compiled function that works much like 285 ;; This function makes a byte compiled function that works much like
297 ;; a matcher element in `font-lock-keywords'. It cuts out a little 286 ;; a matcher element in `font-lock-keywords'. It cuts out a little
@@ -315,32 +304,30 @@
315 ;; the anchored matcher forms. 304 ;; the anchored matcher forms.
316 ;; 305 ;;
317 ;; This function does not do any hidden buffer changes, but the 306 ;; This function does not do any hidden buffer changes, but the
318 ;; generated functions will. They are however used in places 307 ;; generated functions will. (They are however used in places
319 ;; covered by the font-lock context. 308 ;; covered by the font-lock context.)
320 309
321 ;; Note: Replace `byte-compile' with `eval' to debug the generated 310 ;; Note: Replace `byte-compile' with `eval' to debug the generated
322 ;; lambda easier. 311 ;; lambda easier.
323 (byte-compile 312 (byte-compile
324 `(lambda (limit) 313 `(lambda (limit)
325 (let (-match-end-pos- 314 (let (;; The font-lock package in Emacs is known to clobber
326 ;; The font-lock package in Emacs is known to clobber
327 ;; `parse-sexp-lookup-properties' (when it exists). 315 ;; `parse-sexp-lookup-properties' (when it exists).
328 (parse-sexp-lookup-properties 316 (parse-sexp-lookup-properties
329 (cc-eval-when-compile 317 (cc-eval-when-compile
330 (boundp 'parse-sexp-lookup-properties)))) 318 (boundp 'parse-sexp-lookup-properties))))
331 (while (re-search-forward ,regexp limit t) 319 (while (re-search-forward ,regexp limit t)
332 (setq -match-end-pos- (point))
333 (unless (progn 320 (unless (progn
334 (goto-char (match-beginning 0)) 321 (goto-char (match-beginning 0))
335 (c-skip-comments-and-strings limit)) 322 (c-skip-comments-and-strings limit))
336 (goto-char -match-end-pos-) 323 (goto-char (match-end 0))
337 ,@(mapcar 324 ,@(mapcar
338 (lambda (highlight) 325 (lambda (highlight)
339 (if (integerp (car highlight)) 326 (if (integerp (car highlight))
340 (progn 327 (progn
341 (unless (nth 2 highlight) 328 (unless (eq (nth 2 highlight) t)
342 (error 329 (error
343 "The override flag must currently be set in %s" 330 "The override flag must currently be t in %s"
344 highlight)) 331 highlight))
345 (when (nth 3 highlight) 332 (when (nth 3 highlight)
346 (error 333 (error
@@ -359,11 +346,23 @@
359 (save-match-data ,(car highlight)) 346 (save-match-data ,(car highlight))
360 ,(nth 2 highlight)))) 347 ,(nth 2 highlight))))
361 highlights)))) 348 highlights))))
362 nil)))) 349 nil)))
350
351 (eval-after-load "edebug"
352 '(progn
353 (def-edebug-spec c-fontify-types-and-refs let*)
354 (def-edebug-spec c-make-syntactic-matcher t)
355 ;; If there are literal quoted or backquoted highlight specs in
356 ;; the call to `c-make-font-lock-search-function' then let's
357 ;; instrument the forms in them.
358 (def-edebug-spec c-make-font-lock-search-function
359 (form &rest &or ("quote" (&rest form)) ("`" (&rest form)) form)))))
363 360
364(defun c-fontify-recorded-types-and-refs () 361(defun c-fontify-recorded-types-and-refs ()
365 ;; Converts the ranges recorded on `c-record-type-identifiers' and 362 ;; Convert the ranges recorded on `c-record-type-identifiers' and
366 ;; `c-record-ref-identifiers' to fontification. 363 ;; `c-record-ref-identifiers' to fontification.
364 ;;
365 ;; This function does hidden buffer changes.
367 (let (elem) 366 (let (elem)
368 (while (consp c-record-type-identifiers) 367 (while (consp c-record-type-identifiers)
369 (setq elem (car c-record-type-identifiers) 368 (setq elem (car c-record-type-identifiers)
@@ -388,108 +387,123 @@ stuff. Used on level 1 and higher."
388 387
389 t `(,@(when (c-lang-const c-opt-cpp-prefix) 388 t `(,@(when (c-lang-const c-opt-cpp-prefix)
390 (let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)") 389 (let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)")
391 (ncle-depth (c-regexp-opt-depth noncontinued-line-end)) 390 (ncle-depth (regexp-opt-depth noncontinued-line-end))
392 (sws-depth (c-lang-const c-syntactic-ws-depth))) 391 (sws-depth (c-lang-const c-syntactic-ws-depth))
392 (nsws-depth (c-lang-const c-nonempty-syntactic-ws-depth)))
393
393 `(;; The stuff after #error and #warning is a message, so 394 `(;; The stuff after #error and #warning is a message, so
394 ;; fontify it as a string. 395 ;; fontify it as a string.
395 (,(concat noncontinued-line-end 396 ,@(when (c-lang-const c-cpp-message-directives)
396 (c-lang-const c-opt-cpp-prefix) 397 (let* ((re (c-make-keywords-re nil
397 "\\(error\\|warning\\)\\>\\s *\\(.*\\)$") 398 (c-lang-const c-cpp-message-directives)))
398 ,(+ ncle-depth 2) font-lock-string-face) 399 (re-depth (regexp-opt-depth re)))
400 `((,(concat noncontinued-line-end
401 (c-lang-const c-opt-cpp-prefix)
402 re
403 "\\s +\\(.*\\)$")
404 ,(+ ncle-depth re-depth 1) font-lock-string-face))))
399 405
400 ;; Fontify filenames in #include <...> as strings. 406 ;; Fontify filenames in #include <...> as strings.
401 (,(concat noncontinued-line-end 407 ,@(when (c-lang-const c-cpp-include-directives)
402 (c-lang-const c-opt-cpp-prefix) 408 (let* ((re (c-make-keywords-re nil
403 "\\(import\\|include\\)\\>" 409 (c-lang-const c-cpp-include-directives)))
404 (c-lang-const c-syntactic-ws) 410 (re-depth (regexp-opt-depth re)))
405 "\\(<[^>\n\r]*>?\\)") 411 `((,(concat noncontinued-line-end
406 (,(+ ncle-depth sws-depth 2) 412 (c-lang-const c-opt-cpp-prefix)
407 font-lock-string-face) 413 re
408 414 (c-lang-const c-syntactic-ws)
409 ;; Use an anchored matcher to put paren syntax on the brackets. 415 "\\(<[^>\n\r]*>?\\)")
410 (,(byte-compile 416 (,(+ ncle-depth re-depth sws-depth 1)
411 `(lambda (limit) 417 font-lock-string-face)
412 (let ((beg-pos 418
413 (match-beginning ,(+ ncle-depth sws-depth 2))) 419 ;; Use an anchored matcher to put paren syntax
414 (end-pos 420 ;; on the brackets.
415 (1- (match-end ,(+ ncle-depth sws-depth 2))))) 421 (,(byte-compile
416 (if (eq (char-after end-pos) ?>) 422 `(lambda (limit)
417 (progn 423 (let ((beg (match-beginning
418 (c-mark-<-as-paren beg-pos) 424 ,(+ ncle-depth re-depth sws-depth 1)))
419 (c-mark->-as-paren end-pos)) 425 (end (1- (match-end ,(+ ncle-depth re-depth
420 (c-clear-char-property beg-pos 'syntax-table))) 426 sws-depth 1)))))
421 nil)))) 427 (if (eq (char-after end) ?>)
428 (progn
429 (c-mark-<-as-paren beg)
430 (c-mark->-as-paren end))
431 (c-clear-char-property beg 'syntax-table)))
432 nil)))))))
422 433
423 ;; #define. 434 ;; #define.
424 (,(c-make-font-lock-search-function 435 ,@(when (c-lang-const c-opt-cpp-macro-define)
425 (concat 436 `((,(c-make-font-lock-search-function
426 noncontinued-line-end 437 (concat
427 (c-lang-const c-opt-cpp-prefix) 438 noncontinued-line-end
428 "define\\>" 439 (c-lang-const c-opt-cpp-prefix)
429 (c-lang-const c-syntactic-ws) 440 (c-lang-const c-opt-cpp-macro-define)
430 "\\(" (c-lang-const c-symbol-key) "\\)" ; 1 + ncle + sws 441 (c-lang-const c-nonempty-syntactic-ws)
431 (concat "\\(" ; 2 + ncle + sws + c-sym-key 442 "\\(" (c-lang-const ; 1 + ncle + nsws
432 ;; Macro with arguments - a "function". 443 c-symbol-key) "\\)"
433 "\\(\(\\)" ; 3 + ncle + sws + c-sym-key 444 (concat "\\(" ; 2 + ncle + nsws + c-sym-key
434 "\\|" 445 ;; Macro with arguments - a "function".
435 ;; Macro without arguments - a "variable". 446 "\\(\(\\)" ; 3 + ncle + nsws + c-sym-key
436 "\\([^\(]\\|$\\)" 447 "\\|"
437 "\\)")) 448 ;; Macro without arguments - a "variable".
438 `((if (match-beginning ,(+ 3 ncle-depth sws-depth 449 "\\([^\(]\\|$\\)"
439 (c-lang-const c-symbol-key-depth))) 450 "\\)"))
440 ;; "Function". Fontify the name and the arguments. 451 `((if (match-beginning
441 (save-restriction 452 ,(+ 3 ncle-depth nsws-depth
442 (c-put-font-lock-face 453 (c-lang-const c-symbol-key-depth)))
443 (match-beginning ,(+ 1 ncle-depth sws-depth)) 454
444 (match-end ,(+ 1 ncle-depth sws-depth)) 455 ;; "Function". Fontify the name and the arguments.
445 'font-lock-function-name-face) 456 (save-restriction
446 (goto-char (match-end 457 (c-put-font-lock-face
447 ,(+ 3 ncle-depth sws-depth 458 (match-beginning ,(+ 1 ncle-depth nsws-depth))
448 (c-lang-const c-symbol-key-depth)))) 459 (match-end ,(+ 1 ncle-depth nsws-depth))
449 460 'font-lock-function-name-face)
450 (narrow-to-region (point-min) limit) 461 (goto-char
451 (while (and 462 (match-end
452 (progn 463 ,(+ 3 ncle-depth nsws-depth
453 (c-forward-syntactic-ws) 464 (c-lang-const c-symbol-key-depth))))
454 (looking-at c-symbol-key)) 465
455 (progn 466 (narrow-to-region (point-min) limit)
456 (c-put-font-lock-face 467 (while (and
457 (match-beginning 0) (match-end 0) 468 (progn
458 'font-lock-variable-name-face) 469 (c-forward-syntactic-ws)
459 (goto-char (match-end 0)) 470 (looking-at c-symbol-key))
460 (c-forward-syntactic-ws) 471 (progn
461 (eq (char-after) ?,))) 472 (c-put-font-lock-face
462 (forward-char))) 473 (match-beginning 0) (match-end 0)
463 474 'font-lock-variable-name-face)
464 ;; "Variable". 475 (goto-char (match-end 0))
465 (c-put-font-lock-face 476 (c-forward-syntactic-ws)
466 (match-beginning ,(+ 1 ncle-depth sws-depth)) 477 (eq (char-after) ?,)))
467 (match-end ,(+ 1 ncle-depth sws-depth)) 478 (forward-char)))
468 'font-lock-variable-name-face))))) 479
480 ;; "Variable".
481 (c-put-font-lock-face
482 (match-beginning ,(+ 1 ncle-depth nsws-depth))
483 (match-end ,(+ 1 ncle-depth nsws-depth))
484 'font-lock-variable-name-face)))))))
469 485
470 ;; Fontify cpp function names in preprocessor 486 ;; Fontify cpp function names in preprocessor
471 ;; expressions in #if and #elif. 487 ;; expressions in #if and #elif.
472 ,(when (c-lang-const c-cpp-defined-fns) 488 ,@(when (and (c-lang-const c-cpp-expr-directives)
473 `(,(c-make-font-lock-search-function 489 (c-lang-const c-cpp-expr-functions))
474 (concat noncontinued-line-end 490 (let ((ced-re (c-make-keywords-re t
475 (c-lang-const c-opt-cpp-prefix) 491 (c-lang-const c-cpp-expr-directives)))
476 "\\(if\\|elif\\)\\>" ; 1 + ncle-depth 492 (cef-re (c-make-keywords-re t
477 ;; Match the whole logical line to look 493 (c-lang-const c-cpp-expr-functions))))
478 ;; for the functions in. 494 `((,(c-make-font-lock-search-function
479 "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*") 495 (concat noncontinued-line-end
480 `((let ((limit (match-end 0))) 496 (c-lang-const c-opt-cpp-prefix)
481 (while (re-search-forward 497 ced-re ; 1 + ncle-depth
482 ,(concat "\\<\\(" 498 ;; Match the whole logical line to look
483 (c-regexp-opt 499 ;; for the functions in.
484 (c-lang-const c-cpp-defined-fns) 500 "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*")
485 nil) 501 `((let ((limit (match-end 0)))
486 "\\)\\>" 502 (while (re-search-forward ,cef-re limit 'move)
487 "\\s *\(?") 503 (c-put-font-lock-face (match-beginning 1)
488 limit 'move) 504 (match-end 1)
489 (c-put-font-lock-face (match-beginning 1) 505 c-preprocessor-face-name)))
490 (match-end 1) 506 (goto-char (match-end ,(1+ ncle-depth)))))))))
491 c-preprocessor-face-name)))
492 (goto-char (match-end ,(1+ ncle-depth)))))))
493 507
494 ;; Fontify the directive names. 508 ;; Fontify the directive names.
495 (,(c-make-font-lock-search-function 509 (,(c-make-font-lock-search-function
@@ -500,45 +514,52 @@ stuff. Used on level 1 and higher."
500 "\\)") 514 "\\)")
501 `(,(1+ ncle-depth) c-preprocessor-face-name t))) 515 `(,(1+ ncle-depth) c-preprocessor-face-name t)))
502 516
503 ;; fontify the n in ifndef 517 (eval . (list ,(c-make-syntactic-matcher
504 (,(concat noncontinued-line-end 518 (concat noncontinued-line-end
505 (c-lang-const c-opt-cpp-prefix) 519 (c-lang-const c-opt-cpp-prefix)
506 "if\\(n\\)def\\>") 520 "if\\(n\\)def\\>"))
507 ,(+ ncle-depth 1) font-lock-negation-char-face prepend) 521 ,(+ ncle-depth 1)
522 c-negation-char-face-name
523 'append))
508 ))) 524 )))
509 525
510 ,@(when (c-major-mode-is 'pike-mode) 526 ,@(when (c-major-mode-is 'pike-mode)
527 ;; Recognize hashbangs in Pike.
511 `((eval . (list "\\`#![^\n\r]*" 528 `((eval . (list "\\`#![^\n\r]*"
512 0 c-preprocessor-face-name)))) 529 0 c-preprocessor-face-name))))
513 530
514 ;; Make hard spaces visible through an inverted `c-invalid-face-name'. 531 ;; Make hard spaces visible through an inverted `font-lock-warning-face'.
515 (eval . (list 532 (eval . (list
516 "\240" 533 "\240"
517 0 (progn 534 0 (progn
518 (unless (c-face-name-p c-nonbreakable-space-face) 535 (unless (c-face-name-p 'c-nonbreakable-space-face)
519 (c-make-inverse-face c-invalid-face-name 536 (c-make-inverse-face 'font-lock-warning-face
520 c-nonbreakable-space-face)) 537 'c-nonbreakable-space-face))
521 'c-nonbreakable-space-face))) 538 ''c-nonbreakable-space-face)))
522 )) 539 ))
523 540
524(defun c-font-lock-invalid-string () 541(defun c-font-lock-invalid-string ()
525 ;; Assuming the point is after the opening character of a string, 542 ;; Assuming the point is after the opening character of a string,
526 ;; fontify that char with `c-invalid-face-name' if the string 543 ;; fontify that char with `font-lock-warning-face' if the string
527 ;; decidedly isn't terminated properly. 544 ;; decidedly isn't terminated properly.
545 ;;
546 ;; This function does hidden buffer changes.
528 (let ((start (1- (point)))) 547 (let ((start (1- (point))))
529 (save-excursion 548 (save-excursion
530 (and (nth 3 (parse-partial-sexp start (c-point 'eol))) 549 (and (eq (elt (parse-partial-sexp start (c-point 'eol)) 8) start)
531 (if (c-major-mode-is '(c-mode c++-mode objc-mode pike-mode)) 550 (if (integerp c-multiline-string-start-char)
551 ;; There's no multiline string start char before the
552 ;; string, so newlines aren't allowed.
553 (not (eq (char-before start) c-multiline-string-start-char))
554 ;; Multiline strings are allowed anywhere if
555 ;; c-multiline-string-start-char is t.
556 (not c-multiline-string-start-char))
557 (if c-string-escaped-newlines
532 ;; There's no \ before the newline. 558 ;; There's no \ before the newline.
533 (not (eq (char-before (point)) ?\\)) 559 (not (eq (char-before (point)) ?\\))
534 ;; Quoted newlines aren't supported. 560 ;; Escaped newlines aren't supported.
535 t) 561 t)
536 (if (c-major-mode-is 'pike-mode) 562 (c-put-font-lock-face start (1+ start) 'font-lock-warning-face)))))
537 ;; There's no # before the string, so newlines
538 ;; aren't allowed.
539 (not (eq (char-before start) ?#))
540 t)
541 (c-put-font-lock-face start (1+ start) c-invalid-face-name)))))
542 563
543(c-lang-defconst c-basic-matchers-before 564(c-lang-defconst c-basic-matchers-before
544 "Font lock matchers for basic keywords, labels, references and various 565 "Font lock matchers for basic keywords, labels, references and various
@@ -566,18 +587,18 @@ casts and declarations are fontified. Used on level 2 and higher."
566 (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds)))) 587 (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds))))
567 (if (c-major-mode-is 'pike-mode) 588 (if (c-major-mode-is 'pike-mode)
568 ;; No symbol is a keyword after "->" in Pike. 589 ;; No symbol is a keyword after "->" in Pike.
569 `((eval . (list ,(concat "\\(\\=\\|\\(\\=\\|[^-]\\)[^>]\\)" 590 `((eval . (list ,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
570 "\\<\\(" re "\\)\\>") 591 "\\<\\(" re "\\)\\>")
571 3 c-constant-face-name))) 592 2 c-constant-face-name)))
572 `((eval . (list ,(concat "\\<\\(" re "\\)\\>") 593 `((eval . (list ,(concat "\\<\\(" re "\\)\\>")
573 1 c-constant-face-name)))))) 594 1 c-constant-face-name))))))
574 595
575 ;; Fontify all keywords except the primitive types. 596 ;; Fontify all keywords except the primitive types.
576 ,(if (c-major-mode-is 'pike-mode) 597 ,(if (c-major-mode-is 'pike-mode)
577 ;; No symbol is a keyword after "->" in Pike. 598 ;; No symbol is a keyword after "->" in Pike.
578 `(,(concat "\\(\\=\\|\\(\\=\\|[^-]\\)[^>]\\)" 599 `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
579 "\\<" (c-lang-const c-regular-keywords-regexp)) 600 "\\<" (c-lang-const c-regular-keywords-regexp))
580 3 font-lock-keyword-face) 601 2 font-lock-keyword-face)
581 `(,(concat "\\<" (c-lang-const c-regular-keywords-regexp)) 602 `(,(concat "\\<" (c-lang-const c-regular-keywords-regexp))
582 1 font-lock-keyword-face)) 603 1 font-lock-keyword-face))
583 604
@@ -596,9 +617,10 @@ casts and declarations are fontified. Used on level 2 and higher."
596 ;; Search for class identifiers preceded by ".". The 617 ;; Search for class identifiers preceded by ".". The
597 ;; anchored matcher takes it from there. 618 ;; anchored matcher takes it from there.
598 (concat (c-lang-const c-opt-identifier-concat-key) 619 (concat (c-lang-const c-opt-identifier-concat-key)
599 "[ \t\n\r\f\v]*" 620 (c-lang-const c-simple-ws) "*"
600 (concat "\\(" 621 (concat "\\("
601 "[" c-upper "][" (c-lang-const c-symbol-chars) "]*" 622 "[" c-upper "]"
623 "[" (c-lang-const c-symbol-chars) "]*"
602 "\\|" 624 "\\|"
603 "\\*" 625 "\\*"
604 "\\)")) 626 "\\)"))
@@ -612,24 +634,26 @@ casts and declarations are fontified. Used on level 2 and higher."
612 (< (skip-chars-backward 634 (< (skip-chars-backward
613 ,(c-lang-const c-symbol-chars)) 0)) 635 ,(c-lang-const c-symbol-chars)) 0))
614 (not (get-text-property (point) 'face))) 636 (not (get-text-property (point) 'face)))
615 (c-put-font-lock-face (point) id-end c-reference-face-name) 637 (c-put-font-lock-face (point) id-end
638 c-reference-face-name)
616 (c-backward-syntactic-ws))) 639 (c-backward-syntactic-ws)))
617 nil 640 nil
618 (goto-char (match-end 0))))) 641 (goto-char (match-end 0)))))
619 642
620 `((,(byte-compile 643 `((,(byte-compile
621 ;; Must use a function here since we match longer than we 644 ;; Must use a function here since we match longer than
622 ;; want to move before doing a new search. This is not 645 ;; we want to move before doing a new search. This is
623 ;; necessary for XEmacs >= 20 since it restarts the search 646 ;; not necessary for XEmacs since it restarts the
624 ;; from the end of the first highlighted submatch (something 647 ;; search from the end of the first highlighted
625 ;; that causes problems in other places). 648 ;; submatch (something that causes problems in other
649 ;; places).
626 `(lambda (limit) 650 `(lambda (limit)
627 (while (re-search-forward 651 (while (re-search-forward
628 ,(concat "\\(\\<" ; 1 652 ,(concat "\\(\\<" ; 1
629 "\\(" (c-lang-const c-symbol-key) "\\)" ; 2 653 "\\(" (c-lang-const c-symbol-key) "\\)" ; 2
630 "[ \t\n\r\f\v]*" 654 (c-lang-const c-simple-ws) "*"
631 (c-lang-const c-opt-identifier-concat-key) 655 (c-lang-const c-opt-identifier-concat-key)
632 "[ \t\n\r\f\v]*" 656 (c-lang-const c-simple-ws) "*"
633 "\\)" 657 "\\)"
634 "\\(" 658 "\\("
635 (c-lang-const c-opt-after-id-concat-key) 659 (c-lang-const c-opt-after-id-concat-key)
@@ -660,29 +684,30 @@ casts and declarations are fontified. Used on level 2 and higher."
660 (if (> (point) limit) (goto-char limit))))) 684 (if (> (point) limit) (goto-char limit)))))
661 685
662 ;; The @interface/@implementation/@protocol directives. 686 ;; The @interface/@implementation/@protocol directives.
663 (,(concat "\\<" 687 ,(c-make-font-lock-search-function
664 (c-regexp-opt 688 (concat "\\<"
689 (regexp-opt
665 '("@interface" "@implementation" "@protocol") 690 '("@interface" "@implementation" "@protocol")
666 t) 691 t)
667 "\\>") 692 "\\>")
668 (,(byte-compile 693 '((c-fontify-types-and-refs
669 (lambda (limit) 694 (;; The font-lock package in Emacs is known to clobber
670 (let (;; The font-lock package in Emacs is known to clobber 695 ;; `parse-sexp-lookup-properties' (when it exists).
671 ;; `parse-sexp-lookup-properties' (when it exists). 696 (parse-sexp-lookup-properties
672 (parse-sexp-lookup-properties 697 (cc-eval-when-compile
673 (cc-eval-when-compile 698 (boundp 'parse-sexp-lookup-properties))))
674 (boundp 'parse-sexp-lookup-properties)))) 699 (c-forward-objc-directive)
675 (save-restriction 700 nil)
676 (narrow-to-region (point-min) limit) 701 (goto-char (match-beginning 0))))))
677 (c-font-lock-objc-iip-decl))) 702
678 nil)))))) 703 (eval . (list "\\(!\\)[^=]" 1 c-negation-char-face-name))
679
680 ("\\(!\\)[^=]" 1 font-lock-negation-char-face)
681 )) 704 ))
682 705
683(defun c-font-lock-complex-decl-prepare (limit) 706(defun c-font-lock-complex-decl-prepare (limit)
684 ;; Called before any of the matchers in `c-complex-decl-matchers'. 707 ;; Called before any of the matchers in `c-complex-decl-matchers'.
685 ;; Nil is always returned. 708 ;; Nil is always returned.
709 ;;
710 ;; This function does hidden buffer changes.
686 711
687 ;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit) 712 ;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit)
688 713
@@ -718,17 +743,20 @@ casts and declarations are fontified. Used on level 2 and higher."
718 743
719(defun c-font-lock-<>-arglists (limit) 744(defun c-font-lock-<>-arglists (limit)
720 ;; Fontify types and references in names containing angle bracket 745 ;; Fontify types and references in names containing angle bracket
721 ;; arglists from the point to LIMIT. This will also fontify cases 746 ;; arglists from the point to LIMIT. Note that
722 ;; like normal function calls on the form "foo (a < b, c > d)", but 747 ;; `c-font-lock-declarations' already has handled many of them. Nil
723 ;; `c-font-lock-declarations' will undo that later. Nil is always 748 ;; is always returned.
724 ;; returned. 749 ;;
750 ;; This function might do hidden buffer changes.
725 751
726 (let (;; The font-lock package in Emacs is known to clobber 752 (let (;; The font-lock package in Emacs is known to clobber
727 ;; `parse-sexp-lookup-properties' (when it exists). 753 ;; `parse-sexp-lookup-properties' (when it exists).
728 (parse-sexp-lookup-properties 754 (parse-sexp-lookup-properties
729 (cc-eval-when-compile 755 (cc-eval-when-compile
730 (boundp 'parse-sexp-lookup-properties))) 756 (boundp 'parse-sexp-lookup-properties)))
731 id-start id-end pos kwd-sym) 757 (c-parse-and-markup-<>-arglists t)
758 c-restricted-<>-arglists
759 id-start id-end id-face pos kwd-sym)
732 760
733 (while (and (< (point) limit) 761 (while (and (< (point) limit)
734 (re-search-forward c-opt-<>-arglist-start limit t)) 762 (re-search-forward c-opt-<>-arglist-start limit t))
@@ -739,28 +767,51 @@ casts and declarations are fontified. Used on level 2 and higher."
739 767
740 (goto-char id-start) 768 (goto-char id-start)
741 (unless (c-skip-comments-and-strings limit) 769 (unless (c-skip-comments-and-strings limit)
742 (setq kwd-sym nil) 770 (setq kwd-sym nil
743 (if (or (not (eq (get-text-property id-start 'face) 771 c-restricted-<>-arglists nil
744 'font-lock-keyword-face)) 772 id-face (get-text-property id-start 'face))
745 (when (looking-at c-opt-<>-sexp-key) 773
746 (setq kwd-sym (c-keyword-sym (match-string 1))))) 774 (if (cond
775 ((eq id-face 'font-lock-type-face)
776 ;; The identifier got the type face so it has already been
777 ;; handled in `c-font-lock-declarations'.
778 nil)
779
780 ((eq id-face 'font-lock-keyword-face)
781 (when (looking-at c-opt-<>-sexp-key)
782 ;; There's a special keyword before the "<" that tells
783 ;; that it's an angle bracket arglist.
784 (setq kwd-sym (c-keyword-sym (match-string 1)))))
785
786 (t
787 ;; There's a normal identifier before the "<". If we're not in
788 ;; a declaration context then we set `c-restricted-<>-arglists'
789 ;; to avoid recognizing templates in function calls like "foo (a
790 ;; < b, c > d)".
791 (c-backward-syntactic-ws)
792 (when (and (memq (char-before) '(?\( ?,))
793 (not (eq (get-text-property (1- (point)) 'c-type)
794 'c-decl-arg-start)))
795 (setq c-restricted-<>-arglists t))
796 t))
797
747 (progn 798 (progn
748 (goto-char (1- pos)) 799 (goto-char (1- pos))
749 ;; Check for comment/string both at the identifier and 800 ;; Check for comment/string both at the identifier and
750 ;; at the "<". 801 ;; at the "<".
751 (unless (c-skip-comments-and-strings limit) 802 (unless (c-skip-comments-and-strings limit)
752 803
753 (when (c-forward-<>-arglist (c-keyword-member kwd-sym 804 (c-fontify-types-and-refs ()
754 'c-<>-type-kwds) 805 (when (c-forward-<>-arglist (c-keyword-member
755 t) 806 kwd-sym 'c-<>-type-kwds))
756 (when (and c-opt-identifier-concat-key 807 (when (and c-opt-identifier-concat-key
757 (not (get-text-property id-start 'face))) 808 (not (get-text-property id-start 'face)))
758 (c-forward-syntactic-ws) 809 (c-forward-syntactic-ws)
759 (if (looking-at c-opt-identifier-concat-key) 810 (if (looking-at c-opt-identifier-concat-key)
811 (c-put-font-lock-face id-start id-end
812 c-reference-face-name)
760 (c-put-font-lock-face id-start id-end 813 (c-put-font-lock-face id-start id-end
761 c-reference-face-name) 814 'font-lock-type-face)))))
762 (c-put-font-lock-face id-start id-end
763 'font-lock-type-face))))
764 815
765 (goto-char pos))) 816 (goto-char pos)))
766 (goto-char pos))))) 817 (goto-char pos)))))
@@ -773,6 +824,8 @@ casts and declarations are fontified. Used on level 2 and higher."
773 ;; "bar" in "int foo = 17, bar;"). Stop at LIMIT. If TYPES is 824 ;; "bar" in "int foo = 17, bar;"). Stop at LIMIT. If TYPES is
774 ;; non-nil, fontify all identifiers as types. Nil is always 825 ;; non-nil, fontify all identifiers as types. Nil is always
775 ;; returned. 826 ;; returned.
827 ;;
828 ;; This function might do hidden buffer changes.
776 829
777 ;;(message "c-font-lock-declarators from %s to %s" (point) limit) 830 ;;(message "c-font-lock-declarators from %s to %s" (point) limit)
778 (c-fontify-types-and-refs 831 (c-fontify-types-and-refs
@@ -789,7 +842,7 @@ casts and declarations are fontified. Used on level 2 and higher."
789 (let (got-identifier) 842 (let (got-identifier)
790 (setq paren-depth 0) 843 (setq paren-depth 0)
791 ;; Skip over type decl prefix operators. (Note similar 844 ;; Skip over type decl prefix operators. (Note similar
792 ;; code in `c-font-lock-declarations'.) 845 ;; code in `c-forward-decl-or-cast-1'.)
793 (while (and (looking-at c-type-decl-prefix-key) 846 (while (and (looking-at c-type-decl-prefix-key)
794 (if (and (c-major-mode-is 'c++-mode) 847 (if (and (c-major-mode-is 'c++-mode)
795 (match-beginning 2)) 848 (match-beginning 2))
@@ -830,6 +883,11 @@ casts and declarations are fontified. Used on level 2 and higher."
830 883
831 (<= (point) limit) 884 (<= (point) limit)
832 885
886 (progn
887 (when (looking-at c-decl-hangon-key)
888 (c-forward-keyword-clause 1))
889 (<= (point) limit))
890
833 ;; Search syntactically to the end of the declarator (";", 891 ;; Search syntactically to the end of the declarator (";",
834 ;; ",", a closen paren, eob etc) or to the beginning of an 892 ;; ",", a closen paren, eob etc) or to the beginning of an
835 ;; initializer or function prototype ("=" or "\\s\("). 893 ;; initializer or function prototype ("=" or "\\s\(").
@@ -883,6 +941,9 @@ casts and declarations are fontified. Used on level 2 and higher."
883 (looking-at "{")) 941 (looking-at "{"))
884 (c-safe (c-forward-sexp) t) 942 (c-safe (c-forward-sexp) t)
885 t) 943 t)
944 ;; FIXME: Should look for c-decl-end markers here;
945 ;; we might go far into the following declarations
946 ;; in e.g. ObjC mode (see e.g. methods-4.m).
886 (c-syntactic-re-search-forward "[;,{]" limit 'move t) 947 (c-syntactic-re-search-forward "[;,{]" limit 'move t)
887 (backward-char))) 948 (backward-char)))
888 949
@@ -905,106 +966,50 @@ casts and declarations are fontified. Used on level 2 and higher."
905 c-reference-face-name 966 c-reference-face-name
906 font-lock-keyword-face)) 967 font-lock-keyword-face))
907 968
908;; Macro used inside `c-font-lock-declarations'. It ought to be a
909;; defsubst or perhaps even a defun, but it contains lots of free
910;; variables that refer to things inside `c-font-lock-declarations'.
911(defmacro c-fl-shift-type-backward (&optional short)
912 ;; `c-font-lock-declarations' can consume an arbitrary length list
913 ;; of types when parsing a declaration, which means that it
914 ;; sometimes consumes the identifier in the declaration as a type.
915 ;; This is used to "backtrack" and make the last type be treated
916 ;; as an identifier instead.
917 `(progn
918 ,(unless short
919 ;; These identifiers are bound only in the inner let.
920 '(setq identifier-type at-type
921 identifier-start type-start
922 identifier-end type-end))
923 (if (setq at-type (if (eq prev-at-type 'prefix)
924 t
925 prev-at-type))
926 (setq type-start prev-type-start
927 type-end prev-type-end)
928 (setq type-start start-pos
929 type-end start-pos))
930 ,(unless short
931 ;; These identifiers are bound only in the inner let.
932 '(setq start type-end
933 got-parens nil
934 got-identifier t
935 got-suffix t
936 got-suffix-after-parens t
937 paren-depth 0))))
938
939(defun c-font-lock-declarations (limit) 969(defun c-font-lock-declarations (limit)
940 ;; Fontify all the declarations and casts from the point to LIMIT. 970 ;; Fontify all the declarations, casts and labels from the point to LIMIT.
941 ;; Assumes that strings and comments have been fontified already. 971 ;; Assumes that strings and comments have been fontified already. Nil is
942 ;; Nil is always returned. 972 ;; always returned.
943 ;; 973 ;;
944 ;; This function can make hidden buffer changes, but the font-lock 974 ;; This function might do hidden buffer changes.
945 ;; context covers that.
946 975
947 ;;(message "c-font-lock-declarations search from %s to %s" (point) limit) 976 ;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
948 977
949 (save-restriction 978 (save-restriction
950 (let (start-pos 979 (let (;; The position where `c-find-decl-spots' stopped.
951 c-restricted-<>-arglists 980 start-pos
952 ;; Nonzero if the `c-decl-prefix-re' match is in an arglist context, 981 ;; 'decl if we're in an arglist containing declarations (but
953 ;; as opposed to a statement-level context. The major difference is 982 ;; if `c-recognize-paren-inits' is set it might also be an
954 ;; that "," works as declaration delimiter in an arglist context, 983 ;; initializer arglist), '<> if the arglist is of angle
955 ;; whereas it only separates declarators in the same declaration in 984 ;; bracket type, 'arglist if it's some other arglist, or nil
956 ;; a statement context. If it's nonzero then the value is the 985 ;; if not in an arglist at all.
957 ;; matched char, e.g. ?\( or ?,. 986 context
958 arglist-match 987 ;; The position of the next token after the closing paren of
959 ;; 'decl if we're in an arglist containing declarations (but if 988 ;; the last detected cast.
960 ;; `c-recognize-paren-inits' is set it might also be an initializer
961 ;; arglist), '<> if the arglist is of angle bracket type, 'other if
962 ;; it's some other arglist, or nil if not in an arglist at all.
963 arglist-type
964 ;; Set to the result of `c-forward-type'.
965 at-type
966 ;; These record the start and end of the type or possible type found
967 ;; by `c-forward-type'. `type-start' is at the start of the first
968 ;; type token, and `type-end' is at the start of the first token
969 ;; after the type (and after any specifiers).
970 type-start type-end
971 ;; These store `at-type', `type-start' and `type-end' of the
972 ;; identifier before the one in those variables. The previous
973 ;; identifier might turn out to be the real type in a declaration if
974 ;; the last one has to be the declarator in it. If `prev-at-type'
975 ;; is nil then the other variables have undefined values.
976 prev-at-type prev-type-start prev-type-end
977 ;; Whether we've found a declaration or a cast. We might know this
978 ;; before we've found the type in it.
979 at-decl-or-cast
980 ;; Set when we need to back up to parse this as a declaration but
981 ;; not as a cast.
982 backup-if-not-cast
983 ;; Set if we've found a "typedef" specifier. The identifiers in the
984 ;; declaration are then fontified as types.
985 at-typedef
986 ;; Set if we've found a specifier that can start a declaration where
987 ;; there's no type.
988 maybe-typeless
989 ;; The position of the next token after the closing paren of the
990 ;; last fontified cast.
991 last-cast-end 989 last-cast-end
992 ;; The same for the currently investigated cast. 990 ;; The result from `c-forward-decl-or-cast-1'.
993 cast-end 991 decl-or-cast
994 ;; The maximum of the end positions of all the checked type decl 992 ;; The maximum of the end positions of all the checked type
995 ;; expressions in the successfully identified declarations. The 993 ;; decl expressions in the successfully identified
996 ;; position might be either before or after the syntactic whitespace 994 ;; declarations. The position might be either before or
997 ;; following the last token in the type decl expression. 995 ;; after the syntactic whitespace following the last token
996 ;; in the type decl expression.
998 (max-type-decl-end 0) 997 (max-type-decl-end 0)
999 ;; Same as `max-type-decl-*', but used when we're before 998 ;; Same as `max-type-decl-*', but used when we're before
1000 ;; `token-pos'. 999 ;; `token-pos'.
1001 (max-type-decl-end-before-token 0) 1000 (max-type-decl-end-before-token 0)
1002 ;; Allow recording of identifier ranges in `c-forward-type' etc for 1001 ;; Set according to the context to direct the heuristics for
1003 ;; later fontification. Not using `c-fontify-types-and-refs' here 1002 ;; recognizing C++ templates.
1004 ;; since the ranges should be fontified selectively only when a 1003 c-restricted-<>-arglists
1005 ;; declaration or cast has been successfully recognized. 1004 ;; Turn on recording of identifier ranges in
1006 c-record-type-identifiers 1005 ;; `c-forward-decl-or-cast-1' and `c-forward-label' for
1006 ;; later fontification.
1007 (c-record-type-identifiers t)
1007 c-record-ref-identifiers 1008 c-record-ref-identifiers
1009 ;; Make `c-forward-type' calls mark up template arglists if
1010 ;; it finds any. That's necessary so that we later will
1011 ;; stop inside them to fontify types there.
1012 (c-parse-and-markup-<>-arglists t)
1008 ;; The font-lock package in Emacs is known to clobber 1013 ;; The font-lock package in Emacs is known to clobber
1009 ;; `parse-sexp-lookup-properties' (when it exists). 1014 ;; `parse-sexp-lookup-properties' (when it exists).
1010 (parse-sexp-lookup-properties 1015 (parse-sexp-lookup-properties
@@ -1024,737 +1029,162 @@ casts and declarations are fontified. Used on level 2 and higher."
1024 ;; "some_other_variable" as an identifier, and the latter will not 1029 ;; "some_other_variable" as an identifier, and the latter will not
1025 ;; correct itself until the second line is changed. To avoid that we 1030 ;; correct itself until the second line is changed. To avoid that we
1026 ;; narrow to the limit if the region to fontify is a single line. 1031 ;; narrow to the limit if the region to fontify is a single line.
1027 (when (<= limit (c-point 'bonl)) 1032 (narrow-to-region
1028 (narrow-to-region 1033 (point-min)
1029 (point-min) 1034 (if (<= limit (c-point 'bonl))
1030 (save-excursion 1035 (save-excursion
1031 ;; Narrow after any operator chars following the limit though, since 1036 ;; Narrow after any operator chars following the limit though,
1032 ;; those characters can be useful in recognizing a declaration (in 1037 ;; since those characters can be useful in recognizing a
1033 ;; particular the '{' that opens a function body after the header). 1038 ;; declaration (in particular the '{' that opens a function body
1034 (goto-char limit) 1039 ;; after the header).
1035 (skip-chars-forward c-nonsymbol-chars) 1040 (goto-char limit)
1036 (point)))) 1041 (skip-chars-forward c-nonsymbol-chars)
1042 (point))
1043 limit))
1037 1044
1038 (c-find-decl-spots 1045 (c-find-decl-spots
1039 limit 1046 limit
1040 c-identifier-start 1047 c-decl-start-re
1041 c-font-lock-maybe-decl-faces 1048 c-font-lock-maybe-decl-faces
1042 1049
1043 (lambda (match-pos inside-macro) 1050 (lambda (match-pos inside-macro)
1044 (catch 'false-alarm 1051 (setq start-pos (point))
1045 ;; Don't do anything more if we're looking at a keyword 1052 (when
1046 ;; that can't start a declaration. 1053 ;; The result of the form below is true when we don't recognize a
1047 (when (and (eq (get-text-property (point) 'face) 1054 ;; declaration or cast.
1048 'font-lock-keyword-face) 1055 (if (and (eq (get-text-property (point) 'face)
1049 (looking-at c-not-decl-init-keywords)) 1056 'font-lock-keyword-face)
1050 (throw 'false-alarm t)) 1057 (looking-at c-not-decl-init-keywords))
1051 1058 ;; Don't do anything more if we're looking at a keyword that
1052 ;; Set `arglist-match' and `arglist-type'. Look for "<" for the 1059 ;; can't start a declaration.
1053 ;; sake of C++-style template arglists. 1060 t
1054 (setq arglist-match (char-before match-pos)) 1061
1055 (if (memq arglist-match '(?\( ?, ?\[ ?<)) 1062 ;; Set `context'. Look for "<" for the sake of C++-style template
1056 1063 ;; arglists.
1057 ;; Find out the type of the arglist. 1064 (if (memq (char-before match-pos) '(?\( ?, ?\[ ?<))
1058 (if (<= match-pos (point-min)) 1065
1059 (setq arglist-type 'other) 1066 ;; Find out the type of the arglist.
1060 (let ((type (c-get-char-property (1- match-pos) 'c-type))) 1067 (if (<= match-pos (point-min))
1061 (cond ((eq type 'c-decl-arg-start) 1068 (setq context 'arglist)
1062 ;; Got a cached hit in a declaration arglist. 1069 (let ((type (c-get-char-property (1- match-pos) 'c-type)))
1063 (setq arglist-type 'decl)) 1070 (cond ((eq type 'c-decl-arg-start)
1064 ((or (eq type 'c-<>-arg-sep) 1071 ;; Got a cached hit in a declaration arglist.
1065 (eq arglist-match ?<)) 1072 (setq context 'decl))
1066 ;; Inside an angle bracket arglist. 1073 ((or (eq type 'c-<>-arg-sep)
1067 (setq arglist-type '<>)) 1074 (eq (char-before match-pos) ?<))
1068 (type 1075 ;; Inside an angle bracket arglist.
1069 ;; Got a cached hit in some other type of arglist. 1076 (setq context '<>))
1070 (setq arglist-type 'other)) 1077 (type
1071 ((if inside-macro 1078 ;; Got a cached hit in some other type of arglist.
1072 (< match-pos max-type-decl-end-before-token) 1079 (setq context 'arglist))
1073 (< match-pos max-type-decl-end)) 1080 ((if inside-macro
1074 ;; The point is within the range of a previously 1081 (< match-pos max-type-decl-end-before-token)
1075 ;; encountered type decl expression, so the arglist 1082 (< match-pos max-type-decl-end))
1076 ;; is probably one that contains declarations. 1083 ;; The point is within the range of a previously
1077 ;; However, if `c-recognize-paren-inits' is set it 1084 ;; encountered type decl expression, so the arglist
1078 ;; might also be an initializer arglist. 1085 ;; is probably one that contains declarations.
1079 (setq arglist-type 'decl) 1086 ;; However, if `c-recognize-paren-inits' is set it
1080 ;; The result of this check is cached with a char 1087 ;; might also be an initializer arglist.
1081 ;; property on the match token, so that we can look 1088 (setq context 'decl)
1082 ;; it up again when refontifying single lines in a 1089 ;; The result of this check is cached with a char
1083 ;; multiline declaration. 1090 ;; property on the match token, so that we can look
1084 (c-put-char-property (1- match-pos) 1091 ;; it up again when refontifying single lines in a
1085 'c-type 'c-decl-arg-start)) 1092 ;; multiline declaration.
1086 (t 1093 (c-put-char-property (1- match-pos)
1087 (setq arglist-type 'other))))) 1094 'c-type 'c-decl-arg-start))
1088 1095 (t
1089 (setq arglist-match nil 1096 (setq context 'arglist)))))
1090 arglist-type nil)) 1097
1091 1098 (setq context nil))
1092 (setq at-type nil 1099
1093 at-decl-or-cast nil 1100 ;; If we're in a normal arglist context we don't want to
1094 backup-if-not-cast nil 1101 ;; recognize commas in nested angle bracket arglists since
1095 at-typedef nil 1102 ;; those commas could be part of our own arglist.
1096 maybe-typeless nil 1103 (setq c-restricted-<>-arglists (and c-recognize-<>-arglists
1097 c-record-type-identifiers t 1104 (eq context 'arglist))
1098 c-record-ref-identifiers nil 1105
1099 ;; `start-pos' is used below to point to the start of the 1106 ;; Now analyze the construct.
1100 ;; first type, i.e. after any leading specifiers. It might 1107 decl-or-cast (c-forward-decl-or-cast-1
1101 ;; also point at the beginning of the preceding syntactic 1108 match-pos context last-cast-end))
1102 ;; whitespace. 1109
1103 start-pos (point) 1110 (if (not decl-or-cast)
1104 ;; If we're in a normal arglist context we don't want to 1111 ;; False alarm. Return t to go on to the next check.
1105 ;; recognize commas in nested angle bracket arglists since 1112 t
1106 ;; those commas could be part of our own arglist. 1113
1107 c-restricted-<>-arglists 1114 (if (eq decl-or-cast 'cast)
1108 (and c-recognize-<>-arglists 1115 ;; Save the position after the previous cast so we can feed
1109 (eq arglist-type 'other))) 1116 ;; it to `c-forward-decl-or-cast-1' in the next round. That
1110 1117 ;; helps it discover cast chains like "(a) (b) c".
1111 (when (and c-restricted-<>-arglists 1118 (setq last-cast-end (point))
1112 (/= arglist-match ?,)) 1119
1113 ;; We're standing at the start of a normal arglist so remove any 1120 ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
1114 ;; angle bracket arglists containing commas that's been 1121 ;; under the assumption that we're after the first type decl
1115 ;; recognized inside it by the preceding slightly opportunistic 1122 ;; expression in the declaration now. That's not really true;
1116 ;; scan in `c-font-lock-<>-arglists'. 1123 ;; we could also be after a parenthesized initializer
1117 (while (and (c-syntactic-re-search-forward 1124 ;; expression in C++, but this is only used as a last resort
1118 c-opt-<>-arglist-start-in-paren nil t t) 1125 ;; to slant ambiguous expression/declarations, and overall
1119 (match-beginning 1)) 1126 ;; it's worth the risk to occasionally fontify an expression
1120 (backward-char) 1127 ;; as a declaration in an initializer expression compared to
1121 (when (save-match-data 1128 ;; getting ambiguous things in normal function prototypes
1122 (and (c-get-char-property (point) 'syntax-table) 1129 ;; fontified as expressions.
1123 (not (c-forward-<>-arglist nil t)))) 1130 (if inside-macro
1124 (c-remove-font-lock-face (match-beginning 2) (match-end 2)))) 1131 (when (> (point) max-type-decl-end-before-token)
1125 (goto-char start-pos)) 1132 (setq max-type-decl-end-before-token (point)))
1126 1133 (when (> (point) max-type-decl-end)
1127 ;; Check for a type, but be prepared to skip over leading 1134 (setq max-type-decl-end (point))))
1128 ;; specifiers like "static". Unknown symbols are treated as 1135
1129 ;; possible types, but they could also be specifiers disguised 1136 ;; Back up to the type to fontify the declarator(s).
1130 ;; through macros like __INLINE__, so we recognize both types and 1137 (goto-char (car decl-or-cast))
1131 ;; known specifiers after them too. 1138
1132 (while (let ((start (point)) 1139 (let ((decl-list
1133 (res (unless (eq at-type t) 1140 (if context
1134 ;; Don't look for a type if we already found a 1141 ;; Should normally not fontify a list of
1135 ;; positive one; we only loop for the 1142 ;; declarators inside an arglist, but the first
1136 ;; `c-specifier-key' check then. 1143 ;; argument in the ';' separated list of a "for"
1137 (c-forward-type)))) 1144 ;; statement is an exception.
1138 1145 (when (eq (char-before match-pos) ?\()
1139 (when res 1146 (save-excursion
1140 ;; Found a known or possible type or a prefix of a known 1147 (goto-char (1- match-pos))
1141 ;; type. 1148 (c-backward-syntactic-ws)
1142 1149 (and (c-simple-skip-symbol-backward)
1143 (when at-type 1150 (looking-at c-paren-stmt-key))))
1144 ;; Got two identifiers with nothing but whitespace 1151 t)))
1145 ;; between them. That can only happen in 1152
1146 ;; declarations. 1153 ;; Fix the `c-decl-id-start' or `c-decl-type-start' property
1147 (setq at-decl-or-cast t) 1154 ;; before the first declarator if it's a list.
1148 1155 ;; `c-font-lock-declarators' handles the rest.
1149 (when (eq at-type 'found) 1156 (when decl-list
1150 ;; If the previous identifier is a found type we 1157 (save-excursion
1151 ;; record it as a real one; it might be some sort of 1158 (c-backward-syntactic-ws)
1152 ;; alias for a prefix like "unsigned". 1159 (unless (bobp)
1153 (save-excursion 1160 (c-put-char-property (1- (point)) 'c-type
1154 (goto-char type-start) 1161 (if (cdr decl-or-cast)
1155 (let ((c-promote-possible-types t)) 1162 'c-decl-type-start
1156 (c-forward-type))))) 1163 'c-decl-id-start)))))
1157 1164
1158 (setq prev-at-type at-type 1165 (c-font-lock-declarators
1159 prev-type-start type-start 1166 (point-max) decl-list (cdr decl-or-cast))))
1160 prev-type-end type-end 1167
1161 at-type res 1168 ;; A cast or declaration has been successfully identified, so do
1162 type-start start 1169 ;; all the fontification of types and refs that's been recorded.
1163 type-end (point)) 1170 (c-fontify-recorded-types-and-refs)
1164 1171 nil))
1165 ;; If the type isn't known we continue so that we'll 1172
1166 ;; jump over all specifiers and type identifiers. The 1173 ;; It was a false alarm. Check if we're in a label instead.
1167 ;; reason to do this for a known type prefix is to make 1174 (goto-char start-pos)
1168 ;; things like "unsigned INT16" work. 1175 (when (c-forward-label t match-pos nil)
1169 (setq res (not (eq res t)))) 1176 ;; Can't use `c-fontify-types-and-refs' here since we
1170 1177 ;; should use the label face.
1171 (if (looking-at c-specifier-key) 1178 (let (elem)
1172 ;; Found a known specifier keyword. The specifier 1179 (while c-record-ref-identifiers
1173 ;; keywords are restrictive, so we check for them 1180 (setq elem (car c-record-ref-identifiers)
1174 ;; anywhere inside or around the type(s). We thereby 1181 c-record-ref-identifiers (cdr c-record-ref-identifiers))
1175 ;; avoid having special cases for specifiers like MSVC 1182 (c-put-font-lock-face (car elem) (cdr elem)
1176 ;; '__declspec' which can come after the type. 1183 c-label-face-name)))
1177 (progn 1184 ;; `c-forward-label' probably has added a `c-decl-end'
1178 (setq at-decl-or-cast t) 1185 ;; marker, so return t to `c-find-decl-spots' to signal
1179 (let ((kwd-sym (c-keyword-sym (match-string 1)))) 1186 ;; that.
1180 (when (c-keyword-member 1187 t))))
1181 kwd-sym 'c-typedef-decl-kwds)
1182 (setq at-typedef t))
1183 (when (c-keyword-member
1184 kwd-sym 'c-typeless-decl-kwds)
1185 (setq maybe-typeless t)))
1186 (c-forward-keyword-clause)
1187 ;; Move type-end forward if we've passed a type,
1188 ;; otherwise move start-pos forward.
1189 (if at-type
1190 (setq type-end (point))
1191 (setq start-pos (point))))
1192
1193 res)))
1194
1195 (cond
1196 ((eq at-type 'prefix)
1197 ;; A prefix type is itself a primitive type when it's not
1198 ;; followed by another type.
1199 (setq at-type t))
1200
1201 ((not at-type)
1202 ;; Got no type but set things up to continue anyway to handle the
1203 ;; various cases when a declaration doesn't start with a type.
1204 (setq type-end start-pos))
1205
1206 ((and (eq at-type 'maybe)
1207 (c-major-mode-is 'c++-mode))
1208 ;; If it's C++ then check if the last "type" ends on the form
1209 ;; "foo::foo" or "foo::~foo", i.e. if it's the name of a
1210 ;; (con|de)structor.
1211 (save-excursion
1212 (let (name end-2 end-1)
1213 (goto-char type-end)
1214 (c-backward-syntactic-ws)
1215 (setq end-2 (point))
1216 (when (and
1217 (c-simple-skip-symbol-backward)
1218 (progn
1219 (setq name
1220 (buffer-substring-no-properties (point) end-2))
1221 ;; Cheating in the handling of syntactic ws below.
1222 (< (skip-chars-backward ":~ \t\n\r\v\f") 0))
1223 (progn
1224 (setq end-1 (point))
1225 (c-simple-skip-symbol-backward))
1226 (>= (point) type-start)
1227 (equal (buffer-substring-no-properties (point) end-1)
1228 name))
1229 ;; It is a (con|de)structor name. In that case the
1230 ;; declaration is typeless so zap out any preceding
1231 ;; identifier(s) that we might have taken as types.
1232 (goto-char type-start)
1233 (setq at-type nil
1234 prev-at-type nil
1235 type-end type-start))))))
1236
1237 ;; Check for and step over a type decl expression after the thing
1238 ;; that is or might be a type. This can't be skipped since we need
1239 ;; the correct end position of the declarator for
1240 ;; `max-type-decl-end-*'.
1241 (let ((start (point)) (paren-depth 0) pos
1242 ;; True if there's a non-open-paren match of
1243 ;; `c-type-decl-prefix-key'.
1244 got-prefix
1245 ;; True if the declarator is surrounded by a parenthesis pair.
1246 got-parens
1247 ;; True if there is an identifier in the declarator.
1248 got-identifier
1249 ;; True if there's a non-close-paren match of
1250 ;; `c-type-decl-suffix-key'.
1251 got-suffix
1252 ;; True if there's a prefix or suffix match outside the
1253 ;; outermost paren pair that surrounds the declarator.
1254 got-prefix-before-parens
1255 got-suffix-after-parens
1256 ;; True if we've parsed the type decl to a token that
1257 ;; is known to end declarations in this context.
1258 at-decl-end
1259 ;; The earlier values of `at-type', `type-start' and
1260 ;; `type-end' if we've shifted the type backwards.
1261 identifier-type identifier-start identifier-end)
1262 (goto-char type-end)
1263
1264 ;; Skip over type decl prefix operators. (Note similar code in
1265 ;; `c-font-lock-declarators'.)
1266 (while (and (looking-at c-type-decl-prefix-key)
1267 (if (and (c-major-mode-is 'c++-mode)
1268 (match-beginning 2))
1269 ;; If the second submatch matches in C++ then
1270 ;; we're looking at an identifier that's a prefix
1271 ;; only if it specifies a member pointer.
1272 (when (setq got-identifier (c-forward-name))
1273 (if (looking-at "\\(::\\)")
1274 ;; We only check for a trailing "::" and
1275 ;; let the "*" that should follow be
1276 ;; matched in the next round.
1277 (progn (setq got-identifier nil) t)
1278 ;; It turned out to be the real identifier,
1279 ;; so stop.
1280 nil))
1281 t))
1282 (if (eq (char-after) ?\()
1283 (progn
1284 (setq paren-depth (1+ paren-depth))
1285 (forward-char))
1286 (unless got-prefix-before-parens
1287 (setq got-prefix-before-parens (= paren-depth 0)))
1288 (setq got-prefix t)
1289 (goto-char (match-end 1)))
1290 (c-forward-syntactic-ws))
1291 (setq got-parens (> paren-depth 0))
1292
1293 ;; Skip over an identifier.
1294 (or got-identifier
1295 (and (looking-at c-identifier-start)
1296 (setq got-identifier (c-forward-name))))
1297
1298 ;; Skip over type decl suffix operators.
1299 (while (if (looking-at c-type-decl-suffix-key)
1300 (if (eq (char-after) ?\))
1301 (when (> paren-depth 0)
1302 (setq paren-depth (1- paren-depth))
1303 (forward-char)
1304 t)
1305 (when (if (save-match-data (looking-at "\\s\("))
1306 (c-safe (c-forward-sexp 1) t)
1307 (goto-char (match-end 1))
1308 t)
1309 (unless got-suffix-after-parens
1310 (setq got-suffix-after-parens (= paren-depth 0)))
1311 (setq got-suffix t)))
1312 ;; No suffix matched. We might have matched the
1313 ;; identifier as a type and the open paren of a function
1314 ;; arglist as a type decl prefix. In that case we
1315 ;; should "backtrack": Reinterpret the last type as the
1316 ;; identifier, move out of the arglist and continue
1317 ;; searching for suffix operators.
1318 ;;
1319 ;; Do this even if there's no preceding type, to cope
1320 ;; with old style function declarations in K&R C,
1321 ;; (con|de)structors in C++ and `c-typeless-decl-kwds'
1322 ;; style declarations. That isn't applicable in an
1323 ;; arglist context, though.
1324 (when (and (= paren-depth 1)
1325 (not got-prefix-before-parens)
1326 (not (eq at-type t))
1327 (or prev-at-type
1328 maybe-typeless
1329 (when c-recognize-typeless-decls
1330 (not arglist-type)))
1331 (setq pos (c-up-list-forward (point)))
1332 (eq (char-before pos) ?\)))
1333 (c-fl-shift-type-backward)
1334 (goto-char pos)
1335 t))
1336 (c-forward-syntactic-ws))
1337
1338 (when (and maybe-typeless
1339 (not got-identifier)
1340 (not got-prefix)
1341 at-type
1342 (not (eq at-type t)))
1343 ;; Have found no identifier but `c-typeless-decl-kwds' has
1344 ;; matched so we know we're inside a declaration. The
1345 ;; preceding type must be the identifier instead.
1346 (c-fl-shift-type-backward))
1347
1348 (setq
1349 at-decl-or-cast
1350 (catch 'at-decl-or-cast
1351
1352 (when (> paren-depth 0)
1353 ;; Encountered something inside parens that isn't matched by
1354 ;; the `c-type-decl-*' regexps, so it's not a type decl
1355 ;; expression. Try to skip out to the same paren depth to
1356 ;; not confuse the cast check below.
1357 (c-safe (goto-char (scan-lists (point) 1 paren-depth)))
1358 (throw 'at-decl-or-cast nil))
1359
1360 (setq at-decl-end
1361 (looking-at (cond ((eq arglist-type '<>) "[,>]")
1362 (arglist-type "[,\)]")
1363 (t "[,;]"))))
1364
1365 ;; Now we've collected info about various characteristics of
1366 ;; the construct we're looking at. Below follows a decision
1367 ;; tree based on that. It's ordered to check more certain
1368 ;; signs before less certain ones.
1369
1370 (if got-identifier
1371 (progn
1372
1373 (when (and (or at-type maybe-typeless)
1374 (not (or got-prefix got-parens)))
1375 ;; Got another identifier directly after the type, so
1376 ;; it's a declaration.
1377 (throw 'at-decl-or-cast t))
1378
1379 (when (and got-parens
1380 (not got-prefix)
1381 (not got-suffix-after-parens)
1382 (or prev-at-type maybe-typeless))
1383 ;; Got a declaration of the form "foo bar (gnu);"
1384 ;; where we've recognized "bar" as the type and "gnu"
1385 ;; as the declarator. In this case it's however more
1386 ;; likely that "bar" is the declarator and "gnu" a
1387 ;; function argument or initializer (if
1388 ;; `c-recognize-paren-inits' is set), since the parens
1389 ;; around "gnu" would be superfluous if it's a
1390 ;; declarator. Shift the type one step backward.
1391 (c-fl-shift-type-backward)))
1392
1393 ;; Found no identifier.
1394
1395 (if prev-at-type
1396 (when (or (= (point) start)
1397 (and got-suffix
1398 (not got-prefix)
1399 (not got-parens)))
1400 ;; Got two types after each other, so if this isn't a
1401 ;; cast then the latter probably is the identifier and
1402 ;; we should back up to the previous type.
1403 (setq backup-if-not-cast t)
1404 (throw 'at-decl-or-cast t))
1405
1406 (when (eq at-type t)
1407 ;; If the type is known we know that there can't be any
1408 ;; identifier somewhere else, and it's only in
1409 ;; declarations in e.g. function prototypes and in casts
1410 ;; that the identifier may be left out.
1411 (throw 'at-decl-or-cast t))
1412
1413 (when (= (point) start)
1414 ;; Only got a single identifier (parsed as a type so
1415 ;; far).
1416 (if (and
1417 ;; Check that the identifier isn't at the start of
1418 ;; an expression.
1419 at-decl-end
1420 (cond
1421 ((eq arglist-type 'decl)
1422 ;; Inside an arglist that contains declarations.
1423 ;; If K&R style declarations and parenthesis
1424 ;; style initializers aren't allowed then the
1425 ;; single identifier must be a type, else we
1426 ;; require that it's known or found (primitive
1427 ;; types are handled above).
1428 (or (and (not c-recognize-knr-p)
1429 (not c-recognize-paren-inits))
1430 (memq at-type '(known found))))
1431 ((eq arglist-type '<>)
1432 ;; Inside a template arglist. Accept known and
1433 ;; found types; other identifiers could just as
1434 ;; well be constants in C++.
1435 (memq at-type '(known found)))))
1436 (throw 'at-decl-or-cast t)
1437 (throw 'at-decl-or-cast nil))))
1438
1439 (if (and
1440 got-parens
1441 (not got-prefix)
1442 (not arglist-type)
1443 (not (eq at-type t))
1444 (or
1445 prev-at-type
1446 maybe-typeless
1447 (when c-recognize-typeless-decls
1448 (or (not got-suffix)
1449 (not (looking-at
1450 c-after-suffixed-type-maybe-decl-key))))))
1451 ;; Got an empty paren pair and a preceding type that
1452 ;; probably really is the identifier. Shift the type
1453 ;; backwards to make the last one the identifier. This
1454 ;; is analogous to the "backtracking" done inside the
1455 ;; `c-type-decl-suffix-key' loop above.
1456 ;;
1457 ;; Exception: In addition to the conditions in that
1458 ;; "backtracking" code, do not shift backward if we're
1459 ;; not looking at either `c-after-suffixed-type-decl-key'
1460 ;; or "[;,]". Since there's no preceding type, the
1461 ;; shift would mean that the declaration is typeless.
1462 ;; But if the regexp doesn't match then we will simply
1463 ;; fall through in the tests below and not recognize it
1464 ;; at all, so it's better to try it as an abstract
1465 ;; declarator instead.
1466 (c-fl-shift-type-backward)
1467
1468 ;; Still no identifier.
1469
1470 (when (and got-prefix (or got-parens got-suffix))
1471 ;; Require `got-prefix' together with either
1472 ;; `got-parens' or `got-suffix' to recognize it as an
1473 ;; abstract declarator: `got-parens' only is probably an
1474 ;; empty function call. `got-suffix' only can build an
1475 ;; ordinary expression together with the preceding
1476 ;; identifier which we've taken as a type. We could
1477 ;; actually accept on `got-prefix' only, but that can
1478 ;; easily occur temporarily while writing an expression
1479 ;; so we avoid that case anyway. We could do a better
1480 ;; job if we knew the point when the fontification was
1481 ;; invoked.
1482 (throw 'at-decl-or-cast t))))
1483
1484 (when at-decl-or-cast
1485 ;; By now we've located the type in the declaration that we
1486 ;; know we're in.
1487 (throw 'at-decl-or-cast t))
1488
1489 (when (and got-identifier
1490 (not arglist-type)
1491 (looking-at c-after-suffixed-type-decl-key)
1492 (if (and got-parens
1493 (not got-prefix)
1494 (not got-suffix)
1495 (not (eq at-type t)))
1496 ;; Shift the type backward in the case that
1497 ;; there's a single identifier inside parens.
1498 ;; That can only occur in K&R style function
1499 ;; declarations so it's more likely that it
1500 ;; really is a function call. Therefore we
1501 ;; only do this after
1502 ;; `c-after-suffixed-type-decl-key' has
1503 ;; matched.
1504 (progn (c-fl-shift-type-backward) t)
1505 got-suffix-after-parens))
1506 ;; A declaration according to
1507 ;; `c-after-suffixed-type-decl-key'.
1508 (throw 'at-decl-or-cast t))
1509
1510 (when (and (or got-prefix (not got-parens))
1511 (memq at-type '(t known)))
1512 ;; It's a declaration if a known type precedes it and it
1513 ;; can't be a function call.
1514 (throw 'at-decl-or-cast t))
1515
1516 ;; If we get here we can't tell if this is a type decl or a
1517 ;; normal expression by looking at it alone. (That's under
1518 ;; the assumption that normal expressions always can look like
1519 ;; type decl expressions, which isn't really true but the
1520 ;; cases where it doesn't hold are so uncommon (e.g. some
1521 ;; placements of "const" in C++) it's not worth the effort to
1522 ;; look for them.)
1523
1524 (unless (or at-decl-end (looking-at "=[^=]"))
1525 ;; If this is a declaration it should end here or its
1526 ;; initializer(*) should start here, so check for allowed
1527 ;; separation tokens. Note that this rule doesn't work
1528 ;; e.g. with a K&R arglist after a function header.
1529 ;;
1530 ;; *) Don't check for C++ style initializers using parens
1531 ;; since those already have been matched as suffixes.
1532 (throw 'at-decl-or-cast nil))
1533
1534 ;; Below are tests that only should be applied when we're
1535 ;; certain to not have parsed halfway through an expression.
1536
1537 (when (memq at-type '(t known))
1538 ;; The expression starts with a known type so treat it as a
1539 ;; declaration.
1540 (throw 'at-decl-or-cast t))
1541
1542 (when (and (c-major-mode-is 'c++-mode)
1543 ;; In C++ we check if the identifier is a known
1544 ;; type, since (con|de)structors use the class name
1545 ;; as identifier. We've always shifted over the
1546 ;; identifier as a type and then backed up again in
1547 ;; this case.
1548 identifier-type
1549 (or (memq identifier-type '(found known))
1550 (and (eq (char-after identifier-start) ?~)
1551 ;; `at-type' probably won't be 'found for
1552 ;; destructors since the "~" is then part
1553 ;; of the type name being checked against
1554 ;; the list of known types, so do a check
1555 ;; without that operator.
1556 (or (save-excursion
1557 (goto-char (1+ identifier-start))
1558 (c-forward-syntactic-ws)
1559 (c-with-syntax-table
1560 c-identifier-syntax-table
1561 (looking-at c-known-type-key)))
1562 (c-check-type (1+ identifier-start)
1563 identifier-end)))))
1564 (throw 'at-decl-or-cast t))
1565
1566 (if got-identifier
1567 (progn
1568 (when (and got-prefix-before-parens
1569 at-type
1570 (or at-decl-end (looking-at "=[^=]"))
1571 (not arglist-type)
1572 (not got-suffix))
1573 ;; Got something like "foo * bar;". Since we're not
1574 ;; inside an arglist it would be a meaningless
1575 ;; expression because the result isn't used. We
1576 ;; therefore choose to recognize it as a declaration.
1577 ;; Do not allow a suffix since it could then be a
1578 ;; function call.
1579 (throw 'at-decl-or-cast t))
1580
1581 (when (and (or got-suffix-after-parens
1582 (looking-at "=[^=]"))
1583 (eq at-type 'found)
1584 (not (eq arglist-type 'other)))
1585 ;; Got something like "a (*b) (c);" or "a (b) = c;".
1586 ;; It could be an odd expression or it could be a
1587 ;; declaration. Treat it as a declaration if "a" has
1588 ;; been used as a type somewhere else (if it's a known
1589 ;; type we won't get here).
1590 (throw 'at-decl-or-cast t)))
1591
1592 (when (and arglist-type
1593 (or got-prefix
1594 (and (eq arglist-type 'decl)
1595 (not c-recognize-paren-inits)
1596 (or got-parens got-suffix))))
1597 ;; Got a type followed by an abstract declarator. If
1598 ;; `got-prefix' is set it's something like "a *" without
1599 ;; anything after it. If `got-parens' or `got-suffix' is
1600 ;; set it's "a()", "a[]", "a()[]", or similar, which we
1601 ;; accept only if the context rules out expressions.
1602 (throw 'at-decl-or-cast t)))
1603
1604 ;; If we had a complete symbol table here (which rules out
1605 ;; `c-found-types') we should return t due to the
1606 ;; disambiguation rule (in at least C++) that anything that
1607 ;; can be parsed as a declaration is a declaration. Now we're
1608 ;; being more defensive and prefer to highlight things like
1609 ;; "foo (bar);" as a declaration only if we're inside an
1610 ;; arglist that contains declarations.
1611 (eq arglist-type 'decl))))
1612
1613 ;; Point is now after the type decl expression.
1614
1615 (cond
1616 ;; Check for a cast.
1617 ((save-excursion
1618 (and
1619 c-cast-parens
1620
1621 ;; Should be the first type/identifier in a cast paren.
1622 (memq arglist-match c-cast-parens)
1623
1624 ;; The closing paren should follow.
1625 (progn
1626 (c-forward-syntactic-ws)
1627 (looking-at "\\s\)"))
1628
1629 ;; There should be a primary expression after it.
1630 (let (pos)
1631 (forward-char)
1632 (c-forward-syntactic-ws)
1633 (setq cast-end (point))
1634 (and (looking-at c-primary-expr-regexp)
1635 (progn
1636 (setq pos (match-end 0))
1637 (or
1638 ;; Check if the expression begins with a prefix
1639 ;; keyword.
1640 (match-beginning 2)
1641 (if (match-beginning 1)
1642 ;; Expression begins with an ambiguous operator.
1643 ;; Treat it as a cast if it's a type decl or if
1644 ;; we've recognized the type somewhere else.
1645 (or at-decl-or-cast
1646 (memq at-type '(t known found)))
1647 ;; Unless it's a keyword, it's the beginning of a
1648 ;; primary expression.
1649 (not (looking-at c-keywords-regexp)))))
1650 ;; If `c-primary-expr-regexp' matched a nonsymbol
1651 ;; token, check that it matched a whole one so that we
1652 ;; don't e.g. confuse the operator '-' with '->'. It's
1653 ;; ok if it matches further, though, since it e.g. can
1654 ;; match the float '.5' while the operator regexp only
1655 ;; matches '.'.
1656 (or (not (looking-at c-nonsymbol-token-regexp))
1657 (<= (match-end 0) pos))))
1658
1659 ;; There should either be a cast before it or something that
1660 ;; isn't an identifier or close paren.
1661 (/= match-pos 0)
1662 (progn
1663 (goto-char (1- match-pos))
1664 (or (eq (point) last-cast-end)
1665 (progn
1666 (c-backward-syntactic-ws)
1667 (if (< (skip-syntax-backward "w_") 0)
1668 ;; It's a symbol. Accept it only if it's one of
1669 ;; the keywords that can precede an expression
1670 ;; (without surrounding parens).
1671 (looking-at c-simple-stmt-key)
1672 (and
1673 ;; Check that it isn't a close paren (block close
1674 ;; is ok, though).
1675 (not (memq (char-before) '(?\) ?\])))
1676 ;; Check that it isn't a nonsymbol identifier.
1677 (not (c-on-identifier)))))))))
1678
1679 ;; Handle the cast.
1680 (setq last-cast-end cast-end)
1681 (when (and at-type (not (eq at-type t)))
1682 (let ((c-promote-possible-types t))
1683 (goto-char type-start)
1684 (c-forward-type))))
1685
1686 (at-decl-or-cast
1687 ;; We're at a declaration. Highlight the type and the following
1688 ;; declarators.
1689
1690 (when backup-if-not-cast
1691 (c-fl-shift-type-backward t))
1692
1693 (when (and (eq arglist-type 'decl) (looking-at ","))
1694 ;; Make sure to propagate the `c-decl-arg-start' property to
1695 ;; the next argument if it's set in this one, to cope with
1696 ;; interactive refontification.
1697 (c-put-char-property (point) 'c-type 'c-decl-arg-start))
1698
1699 ;; Set `max-type-decl-end' or `max-type-decl-end-before-token'
1700 ;; under the assumption that we're after the first type decl
1701 ;; expression in the declaration now. That's not really true; we
1702 ;; could also be after a parenthesized initializer expression in
1703 ;; C++, but this is only used as a last resort to slant ambiguous
1704 ;; expression/declarations, and overall it's worth the risk to
1705 ;; occasionally fontify an expression as a declaration in an
1706 ;; initializer expression compared to getting ambiguous things in
1707 ;; normal function prototypes fontified as expressions.
1708 (if inside-macro
1709 (when (> (point) max-type-decl-end-before-token)
1710 (setq max-type-decl-end-before-token (point)))
1711 (when (> (point) max-type-decl-end)
1712 (setq max-type-decl-end (point))))
1713
1714 (when (and at-type (not (eq at-type t)))
1715 (let ((c-promote-possible-types t))
1716 (goto-char type-start)
1717 (c-forward-type)))
1718
1719 (goto-char type-end)
1720
1721 (let ((decl-list
1722 (if arglist-type
1723 ;; Should normally not fontify a list of declarators
1724 ;; inside an arglist, but the first argument in the
1725 ;; ';' separated list of a "for" statement is an
1726 ;; exception.
1727 (when (and (eq arglist-match ?\() (/= match-pos 0))
1728 (save-excursion
1729 (goto-char (1- match-pos))
1730 (c-backward-syntactic-ws)
1731 (and (c-simple-skip-symbol-backward)
1732 (looking-at c-paren-stmt-key))))
1733 t)))
1734
1735 ;; Fix the `c-decl-id-start' or `c-decl-type-start' property
1736 ;; before the first declarator if it's a list.
1737 ;; `c-font-lock-declarators' handles the rest.
1738 (when decl-list
1739 (save-excursion
1740 (c-backward-syntactic-ws)
1741 (unless (bobp)
1742 (c-put-char-property (1- (point)) 'c-type
1743 (if at-typedef
1744 'c-decl-type-start
1745 'c-decl-id-start)))))
1746
1747 (c-font-lock-declarators (point-max) decl-list at-typedef)))
1748
1749 (t
1750 ;; False alarm. Skip the fontification done below.
1751 (throw 'false-alarm t)))
1752
1753 ;; A cast or declaration has been successfully identified, so do
1754 ;; all the fontification of types and refs that's been recorded by
1755 ;; the calls to `c-forward-type' and `c-forward-name' above.
1756 (c-fontify-recorded-types-and-refs)
1757 nil)))
1758 1188
1759 nil))) 1189 nil)))
1760 1190
@@ -1794,32 +1224,40 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1794 ;; Fontify types preceded by `c-type-prefix-kwds' and the 1224 ;; Fontify types preceded by `c-type-prefix-kwds' and the
1795 ;; identifiers in the declarations they might start. 1225 ;; identifiers in the declarations they might start.
1796 ,@(when (c-lang-const c-type-prefix-kwds) 1226 ,@(when (c-lang-const c-type-prefix-kwds)
1797 (let ((prefix-re (c-make-keywords-re nil 1227 (let* ((prefix-re (c-make-keywords-re nil
1798 (c-lang-const c-type-prefix-kwds)))) 1228 (c-lang-const c-type-prefix-kwds)))
1229 (type-match (+ 2
1230 (regexp-opt-depth prefix-re)
1231 (c-lang-const c-simple-ws-depth))))
1799 `((,(c-make-font-lock-search-function 1232 `((,(c-make-font-lock-search-function
1800 (concat "\\<\\(" prefix-re "\\)" 1233 (concat "\\<\\(" prefix-re "\\)" ; 1
1801 "[ \t\n\r\f\v]+" 1234 (c-lang-const c-simple-ws) "+"
1802 "\\(" (c-lang-const c-symbol-key) "\\)") 1235 (concat "\\(" ; 2 + prefix-re + c-simple-ws
1803 `(,(+ (c-regexp-opt-depth prefix-re) 2) 1236 (c-lang-const c-symbol-key)
1237 "\\)"))
1238 `(,type-match
1804 'font-lock-type-face t) 1239 'font-lock-type-face t)
1805 '((c-font-lock-declarators limit t nil) 1240 `((c-font-lock-declarators limit t nil)
1806 (save-match-data 1241 (save-match-data
1807 (goto-char (match-end 2)) 1242 (goto-char (match-end ,type-match))
1808 (c-forward-syntactic-ws)) 1243 (c-forward-syntactic-ws))
1809 (goto-char (match-end 2)))))))) 1244 (goto-char (match-end ,type-match))))))))
1810 1245
1811 ;; Fontify special declarations that lacks a type. 1246 ;; Fontify special declarations that lacks a type.
1812 ,@(when (c-lang-const c-typeless-decl-kwds) 1247 ,@(when (c-lang-const c-typeless-decl-kwds)
1813 `((,(c-make-font-lock-search-function 1248 `((,(c-make-font-lock-search-function
1814 (concat "\\<\\(" 1249 (concat "\\<\\("
1815 (c-regexp-opt (c-lang-const c-typeless-decl-kwds)) 1250 (regexp-opt (c-lang-const c-typeless-decl-kwds))
1816 "\\)\\>") 1251 "\\)\\>")
1817 '((c-font-lock-declarators limit t nil) 1252 '((c-font-lock-declarators limit t nil)
1818 (save-match-data 1253 (save-match-data
1819 (goto-char (match-end 1)) 1254 (goto-char (match-end 1))
1820 (c-forward-syntactic-ws)) 1255 (c-forward-syntactic-ws))
1821 (goto-char (match-end 1))))))) 1256 (goto-char (match-end 1)))))))
1822 )) 1257
1258 ;; Fontify generic colon labels in languages that support them.
1259 ,@(when (c-lang-const c-recognize-colon-labels)
1260 `(c-font-lock-labels))))
1823 1261
1824(c-lang-defconst c-complex-decl-matchers 1262(c-lang-defconst c-complex-decl-matchers
1825 "Complex font lock matchers for types and declarations. Used on level 1263 "Complex font lock matchers for types and declarations. Used on level
@@ -1828,10 +1266,6 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1828 t `(;; Initialize some things before the search functions below. 1266 t `(;; Initialize some things before the search functions below.
1829 c-font-lock-complex-decl-prepare 1267 c-font-lock-complex-decl-prepare
1830 1268
1831 ;; Fontify angle bracket arglists like templates in C++.
1832 ,@(when (c-lang-const c-recognize-<>-arglists)
1833 `(c-font-lock-<>-arglists))
1834
1835 ,@(if (c-major-mode-is 'objc-mode) 1269 ,@(if (c-major-mode-is 'objc-mode)
1836 ;; Fontify method declarations in Objective-C, but first 1270 ;; Fontify method declarations in Objective-C, but first
1837 ;; we have to put the `c-decl-end' `c-type' property on 1271 ;; we have to put the `c-decl-end' `c-type' property on
@@ -1847,18 +1281,15 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1847 nil))) 1281 nil)))
1848 '((c-put-char-property (1- (match-end 1)) 1282 '((c-put-char-property (1- (match-end 1))
1849 'c-type 'c-decl-end))) 1283 'c-type 'c-decl-end)))
1284 c-font-lock-objc-methods))
1850 1285
1851 c-font-lock-objc-methods) 1286 ;; Fontify all declarations, casts and normal labels.
1852
1853 (when (c-lang-const c-opt-access-key)
1854 `(,(c-make-font-lock-search-function
1855 (c-lang-const c-opt-access-key)
1856 '((c-put-char-property (1- (match-end 0))
1857 'c-type 'c-decl-end))))))
1858
1859 ;; Fontify all declarations and casts.
1860 c-font-lock-declarations 1287 c-font-lock-declarations
1861 1288
1289 ;; Fontify angle bracket arglists like templates in C++.
1290 ,@(when (c-lang-const c-recognize-<>-arglists)
1291 `(c-font-lock-<>-arglists))
1292
1862 ;; The first two rules here mostly find occurences that 1293 ;; The first two rules here mostly find occurences that
1863 ;; `c-font-lock-declarations' has found already, but not 1294 ;; `c-font-lock-declarations' has found already, but not
1864 ;; declarations containing blocks in the type (see note below). 1295 ;; declarations containing blocks in the type (see note below).
@@ -1870,9 +1301,9 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1870 (c-lang-const c-primitive-type-kwds)))) 1301 (c-lang-const c-primitive-type-kwds))))
1871 (if (c-major-mode-is 'pike-mode) 1302 (if (c-major-mode-is 'pike-mode)
1872 ;; No symbol is a keyword after "->" in Pike. 1303 ;; No symbol is a keyword after "->" in Pike.
1873 `(,(concat "\\(\\=\\|\\(\\=\\|[^-]\\)[^>]\\)" 1304 `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)"
1874 "\\<\\(" re "\\)\\>") 1305 "\\<\\(" re "\\)\\>")
1875 3 font-lock-type-face) 1306 2 font-lock-type-face)
1876 `(,(concat "\\<\\(" re "\\)\\>") 1307 `(,(concat "\\<\\(" re "\\)\\>")
1877 1 'font-lock-type-face))) 1308 1 'font-lock-type-face)))
1878 1309
@@ -1900,8 +1331,8 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1900 (unless (c-skip-comments-and-strings limit) 1331 (unless (c-skip-comments-and-strings limit)
1901 (c-forward-syntactic-ws) 1332 (c-forward-syntactic-ws)
1902 ;; Handle prefix declaration specifiers. 1333 ;; Handle prefix declaration specifiers.
1903 (when (looking-at c-specifier-key) 1334 (when (looking-at c-prefix-spec-kwds-re)
1904 (c-forward-keyword-clause)) 1335 (c-forward-keyword-clause 1))
1905 ,(if (c-major-mode-is 'c++-mode) 1336 ,(if (c-major-mode-is 'c++-mode)
1906 `(when (and (c-forward-type) 1337 `(when (and (c-forward-type)
1907 (eq (char-after) ?=)) 1338 (eq (char-after) ?=))
@@ -1949,12 +1380,15 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1949 )) 1380 ))
1950 1381
1951(defun c-font-lock-labels (limit) 1382(defun c-font-lock-labels (limit)
1952 ;; Fontify all the declarations from the point to LIMIT. Assumes 1383 ;; Fontify all statement labels from the point to LIMIT. Assumes
1953 ;; that strings and comments have been fontified already. Nil is 1384 ;; that strings and comments have been fontified already. Nil is
1954 ;; always returned. 1385 ;; always returned.
1955 ;; 1386 ;;
1956 ;; This function can make hidden buffer changes, but the font-lock 1387 ;; Note: This function is only used on decoration level 2; this is
1957 ;; context covers that. 1388 ;; taken care of directly by the gargantuan
1389 ;; `c-font-lock-declarations' on higher levels.
1390 ;;
1391 ;; This function might do hidden buffer changes.
1958 1392
1959 (let (continue-pos id-start 1393 (let (continue-pos id-start
1960 ;; The font-lock package in Emacs is known to clobber 1394 ;; The font-lock package in Emacs is known to clobber
@@ -2027,11 +1461,9 @@ higher."
2027 (c-forward-syntactic-ws)) 1461 (c-forward-syntactic-ws))
2028 (goto-char (match-end 0))))))) 1462 (goto-char (match-end 0)))))))
2029 1463
2030 ;; Fontify labels in languages that supports them. 1464 ;; Fontify labels after goto etc.
2031 ,@(when (c-lang-const c-label-key) 1465 ,@(when (c-lang-const c-before-label-kwds)
2032 1466 `(;; (Got three different interpretation levels here,
2033 `(;; Fontify labels after goto etc.
2034 ;; (Got three different interpretation levels here,
2035 ;; which makes it a bit complicated: 1) The backquote 1467 ;; which makes it a bit complicated: 1) The backquote
2036 ;; stuff is expanded when compiled or loaded, 2) the 1468 ;; stuff is expanded when compiled or loaded, 2) the
2037 ;; eval form is evaluated at font-lock setup (to 1469 ;; eval form is evaluated at font-lock setup (to
@@ -2048,11 +1480,8 @@ higher."
2048 "\\(" ; identifier-offset 1480 "\\(" ; identifier-offset
2049 (c-lang-const c-symbol-key) 1481 (c-lang-const c-symbol-key)
2050 "\\)") 1482 "\\)")
2051 (list ,(+ (c-regexp-opt-depth c-before-label-re) 2) 1483 (list ,(+ (regexp-opt-depth c-before-label-re) 2)
2052 c-label-face-name nil t)))) 1484 c-label-face-name nil t))))))
2053
2054 ;; Fontify normal labels.
2055 c-font-lock-labels))
2056 1485
2057 ;; Fontify the clauses after various keywords. 1486 ;; Fontify the clauses after various keywords.
2058 ,@(when (or (c-lang-const c-type-list-kwds) 1487 ,@(when (or (c-lang-const c-type-list-kwds)
@@ -2068,7 +1497,7 @@ higher."
2068 (c-lang-const c-paren-type-kwds))) 1497 (c-lang-const c-paren-type-kwds)))
2069 "\\)\\>") 1498 "\\)\\>")
2070 '((c-fontify-types-and-refs ((c-promote-possible-types t)) 1499 '((c-fontify-types-and-refs ((c-promote-possible-types t))
2071 (c-forward-keyword-clause) 1500 (c-forward-keyword-clause 1)
2072 (if (> (point) limit) (goto-char limit)))))))) 1501 (if (> (point) limit) (goto-char limit))))))))
2073 )) 1502 ))
2074 1503
@@ -2135,8 +1564,6 @@ higher."
2135 ;; to override, but we should otoh avoid clobbering a user setting. 1564 ;; to override, but we should otoh avoid clobbering a user setting.
2136 ;; This heuristic for that isn't perfect, but I can't think of any 1565 ;; This heuristic for that isn't perfect, but I can't think of any
2137 ;; better. /mast 1566 ;; better. /mast
2138 ;;
2139 ;; This function does not do any hidden buffer changes.
2140 (when (and (boundp def-var) 1567 (when (and (boundp def-var)
2141 (memq (symbol-value def-var) 1568 (memq (symbol-value def-var)
2142 (cons nil 1569 (cons nil
@@ -2193,6 +1620,8 @@ need for `c-font-lock-extra-types'.")
2193 ;; 1620 ;;
2194 ;; As usual, C++ takes the prize in coming up with a hard to parse 1621 ;; As usual, C++ takes the prize in coming up with a hard to parse
2195 ;; syntax. :P 1622 ;; syntax. :P
1623 ;;
1624 ;; This function might do hidden buffer changes.
2196 1625
2197 (unless (c-skip-comments-and-strings limit) 1626 (unless (c-skip-comments-and-strings limit)
2198 (save-excursion 1627 (save-excursion
@@ -2338,50 +1767,13 @@ need for `c++-font-lock-extra-types'.")
2338 1767
2339;;; Objective-C. 1768;;; Objective-C.
2340 1769
2341(defun c-font-lock-objc-iip-decl ()
2342 ;; Assuming the point is after an "@interface", "@implementation",
2343 ;; "@protocol" declaration, fontify all the types in the directive.
2344 ;; Return t if the directive was fully recognized. Point will then
2345 ;; be at the end of it.
2346
2347 (c-fontify-types-and-refs
2348 (start-char
2349 (c-promote-possible-types t)
2350 ;; Turn off recognition of angle bracket arglists while parsing
2351 ;; types here since the protocol reference list might then be
2352 ;; considered part of the preceding name or superclass-name.
2353 c-recognize-<>-arglists)
2354 (catch 'break
2355
2356 ;; Handle the name of the class itself.
2357 (c-forward-syntactic-ws)
2358 (unless (c-forward-type) (throw 'break nil))
2359
2360 ;; Look for ": superclass-name" or "( category-name )".
2361 (when (looking-at "[:\(]")
2362 (setq start-char (char-after))
2363 (forward-char)
2364 (c-forward-syntactic-ws)
2365 (unless (c-forward-type) (throw 'break nil))
2366 (when (eq start-char ?\()
2367 (unless (eq (char-after) ?\)) (throw 'break nil))
2368 (forward-char)
2369 (c-forward-syntactic-ws)))
2370
2371 ;; Look for a protocol reference list.
2372 (when (if (eq (char-after) ?<)
2373 (progn
2374 (setq c-recognize-<>-arglists t)
2375 (c-forward-<>-arglist t t))
2376 t)
2377 (c-put-char-property (1- (point)) 'c-type 'c-decl-end)
2378 t))))
2379
2380(defun c-font-lock-objc-method () 1770(defun c-font-lock-objc-method ()
2381 ;; Assuming the point is after the + or - that starts an Objective-C 1771 ;; Assuming the point is after the + or - that starts an Objective-C
2382 ;; method declaration, fontify it. This must be done before normal 1772 ;; method declaration, fontify it. This must be done before normal
2383 ;; casts, declarations and labels are fontified since they will get 1773 ;; casts, declarations and labels are fontified since they will get
2384 ;; false matches in these things. 1774 ;; false matches in these things.
1775 ;;
1776 ;; This function might do hidden buffer changes.
2385 1777
2386 (c-fontify-types-and-refs 1778 (c-fontify-types-and-refs
2387 ((first t) 1779 ((first t)
@@ -2430,6 +1822,8 @@ need for `c++-font-lock-extra-types'.")
2430(defun c-font-lock-objc-methods (limit) 1822(defun c-font-lock-objc-methods (limit)
2431 ;; Fontify method declarations in Objective-C. Nil is always 1823 ;; Fontify method declarations in Objective-C. Nil is always
2432 ;; returned. 1824 ;; returned.
1825 ;;
1826 ;; This function might do hidden buffer changes.
2433 1827
2434 (let (;; The font-lock package in Emacs is known to clobber 1828 (let (;; The font-lock package in Emacs is known to clobber
2435 ;; `parse-sexp-lookup-properties' (when it exists). 1829 ;; `parse-sexp-lookup-properties' (when it exists).
@@ -2605,6 +1999,8 @@ need for `pike-font-lock-extra-types'.")
2605 ;; Note that faces added through KEYWORDS should never replace the 1999 ;; Note that faces added through KEYWORDS should never replace the
2606 ;; existing `c-doc-face-name' face since the existence of that face 2000 ;; existing `c-doc-face-name' face since the existence of that face
2607 ;; is used as a flag in other code to skip comments. 2001 ;; is used as a flag in other code to skip comments.
2002 ;;
2003 ;; This function might do hidden buffer changes.
2608 2004
2609 (let (comment-beg region-beg) 2005 (let (comment-beg region-beg)
2610 (if (eq (get-text-property (point) 'face) 2006 (if (eq (get-text-property (point) 'face)
@@ -2686,6 +2082,8 @@ need for `pike-font-lock-extra-types'.")
2686 ;; between the point and LIMIT that only is fontified with 2082 ;; between the point and LIMIT that only is fontified with
2687 ;; `c-doc-face-name'. If a match is found then submatch 0 surrounds 2083 ;; `c-doc-face-name'. If a match is found then submatch 0 surrounds
2688 ;; the first char and t is returned, otherwise nil is returned. 2084 ;; the first char and t is returned, otherwise nil is returned.
2085 ;;
2086 ;; This function might do hidden buffer changes.
2689 (let (start) 2087 (let (start)
2690 (while (if (re-search-forward regexp limit t) 2088 (while (if (re-search-forward regexp limit t)
2691 (not (eq (get-text-property 2089 (not (eq (get-text-property
@@ -2697,11 +2095,40 @@ need for `pike-font-lock-extra-types'.")
2697 (copy-marker (1+ start)))) 2095 (copy-marker (1+ start))))
2698 t))) 2096 t)))
2699 2097
2098;; GtkDoc patterns contributed by Masatake YAMATO <jet@gyve.org>.
2099
2100(defconst gtkdoc-font-lock-doc-comments
2101 (let ((symbol "[a-zA-Z0-9_]+")
2102 (header "^ \\* "))
2103 `((,(concat header "\\(" symbol "\\):[ \t]*$")
2104 1 ,c-doc-markup-face-name prepend nil)
2105 (,(concat symbol "()")
2106 0 ,c-doc-markup-face-name prepend nil)
2107 (,(concat header "\\(" "@" symbol "\\):")
2108 1 ,c-doc-markup-face-name prepend nil)
2109 (,(concat "[#%]" symbol)
2110 0 ,c-doc-markup-face-name prepend nil))
2111 ))
2112
2113(defconst gtkdoc-font-lock-doc-protection
2114 `(("< \\(public\\|private\\|protected\\) >"
2115 1 ,c-doc-markup-face-name prepend nil)))
2116
2117(defconst gtkdoc-font-lock-keywords
2118 `((,(lambda (limit)
2119 (c-font-lock-doc-comments "/\\*\\*$" limit
2120 gtkdoc-font-lock-doc-comments)
2121 (c-font-lock-doc-comments "/\\*< " limit
2122 gtkdoc-font-lock-doc-protection)
2123 ))))
2124
2125;; Javadoc.
2126
2700(defconst javadoc-font-lock-doc-comments 2127(defconst javadoc-font-lock-doc-comments
2701 `(("{@[a-z]+[^}\n\r]*}" ; "{@foo ...}" markup. 2128 `(("{@[a-z]+[^}\n\r]*}" ; "{@foo ...}" markup.
2702 0 ,c-doc-markup-face-name prepend nil) 2129 0 ,c-doc-markup-face-name prepend nil)
2703 ("^\\(/\\*\\)?[ \t*]*\\(@[a-z]+\\)" ; "@foo ..." markup. 2130 ("^\\(/\\*\\)?\\(\\s \\|\\*\\)*\\(@[a-z]+\\)" ; "@foo ..." markup.
2704 2 ,c-doc-markup-face-name prepend nil) 2131 3 ,c-doc-markup-face-name prepend nil)
2705 (,(concat "</?\\sw" ; HTML tags. 2132 (,(concat "</?\\sw" ; HTML tags.
2706 "\\(" 2133 "\\("
2707 (concat "\\sw\\|\\s \\|[=\n\r*.:]\\|" 2134 (concat "\\sw\\|\\s \\|[=\n\r*.:]\\|"
@@ -2715,13 +2142,15 @@ need for `pike-font-lock-extra-types'.")
2715 ;; allowed in non-markup use. 2142 ;; allowed in non-markup use.
2716 (,(lambda (limit) 2143 (,(lambda (limit)
2717 (c-find-invalid-doc-markup "[<>&]\\|{@" limit)) 2144 (c-find-invalid-doc-markup "[<>&]\\|{@" limit))
2718 0 ,c-invalid-face-name prepend nil))) 2145 0 'font-lock-warning-face prepend nil)))
2719 2146
2720(defconst javadoc-font-lock-keywords 2147(defconst javadoc-font-lock-keywords
2721 `((,(lambda (limit) 2148 `((,(lambda (limit)
2722 (c-font-lock-doc-comments "/\\*\\*" limit 2149 (c-font-lock-doc-comments "/\\*\\*" limit
2723 javadoc-font-lock-doc-comments))))) 2150 javadoc-font-lock-doc-comments)))))
2724 2151
2152;; Pike autodoc.
2153
2725(defconst autodoc-decl-keywords 2154(defconst autodoc-decl-keywords
2726 ;; Adorned regexp matching the keywords that introduce declarations 2155 ;; Adorned regexp matching the keywords that introduce declarations
2727 ;; in Pike Autodoc. 2156 ;; in Pike Autodoc.
@@ -2736,6 +2165,8 @@ need for `pike-font-lock-extra-types'.")
2736(defun autodoc-font-lock-line-markup (limit) 2165(defun autodoc-font-lock-line-markup (limit)
2737 ;; Fontify all line oriented keywords between the point and LIMIT. 2166 ;; Fontify all line oriented keywords between the point and LIMIT.
2738 ;; Nil is always returned. 2167 ;; Nil is always returned.
2168 ;;
2169 ;; This function might do hidden buffer changes.
2739 2170
2740 (let ((line-re (concat "^\\(\\(/\\*!\\|\\s *\\(" 2171 (let ((line-re (concat "^\\(\\(/\\*!\\|\\s *\\("
2741 c-current-comment-prefix 2172 c-current-comment-prefix
@@ -2765,7 +2196,7 @@ need for `pike-font-lock-extra-types'.")
2765 (and (eq (char-before) ?@) 2196 (and (eq (char-before) ?@)
2766 (not (eobp)) 2197 (not (eobp))
2767 (progn (forward-char) 2198 (progn (forward-char)
2768 (skip-chars-forward " \t") 2199 (skip-syntax-forward " ")
2769 (looking-at c-current-comment-prefix)))) 2200 (looking-at c-current-comment-prefix))))
2770 (goto-char (match-end 0)) 2201 (goto-char (match-end 0))
2771 (c-remove-font-lock-face pos (1- end)) 2202 (c-remove-font-lock-face pos (1- end))
@@ -2804,7 +2235,7 @@ need for `pike-font-lock-extra-types'.")
2804 (and (eq (char-before) ?@) 2235 (and (eq (char-before) ?@)
2805 (not (eobp)) 2236 (not (eobp))
2806 (progn (forward-char) 2237 (progn (forward-char)
2807 (skip-chars-forward " \t") 2238 (skip-syntax-forward " ")
2808 (looking-at c-current-comment-prefix)))) 2239 (looking-at c-current-comment-prefix))))
2809 (goto-char (match-end 0)))))) 2240 (goto-char (match-end 0))))))
2810 2241
@@ -2818,12 +2249,14 @@ need for `pike-font-lock-extra-types'.")
2818 ;; Fontify remaining markup characters as invalid. 2249 ;; Fontify remaining markup characters as invalid.
2819 (,(lambda (limit) 2250 (,(lambda (limit)
2820 (c-find-invalid-doc-markup "@" limit)) 2251 (c-find-invalid-doc-markup "@" limit))
2821 0 ,c-invalid-face-name prepend nil) 2252 0 'font-lock-warning-face prepend nil)
2822 )) 2253 ))
2823 2254
2824(defun autodoc-font-lock-keywords () 2255(defun autodoc-font-lock-keywords ()
2825 ;; Note that we depend on that `c-current-comment-prefix' has got 2256 ;; Note that we depend on that `c-current-comment-prefix' has got
2826 ;; its proper value here. 2257 ;; its proper value here.
2258 ;;
2259 ;; This function might do hidden buffer changes.
2827 2260
2828 ;; The `c-type' text property with `c-decl-end' is used to mark the 2261 ;; The `c-type' text property with `c-decl-end' is used to mark the
2829 ;; end of the `autodoc-decl-keywords' occurrences to fontify the 2262 ;; end of the `autodoc-decl-keywords' occurrences to fontify the
@@ -2846,13 +2279,13 @@ need for `pike-font-lock-extra-types'.")
2846 ',(eval-when-compile ; Evaluate while compiling cc-fonts 2279 ',(eval-when-compile ; Evaluate while compiling cc-fonts
2847 (list 2280 (list
2848 ;; Function names. 2281 ;; Function names.
2849 '("^[ \t]*\\(func\\(tion\\)?\\)\\>[ \t]*\\(\\sw+\\)?" 2282 '("^\\s *\\(func\\(tion\\)?\\)\\>\\s *\\(\\sw+\\)?"
2850 (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t)) 2283 (1 font-lock-keyword-face) (3 font-lock-function-name-face nil t))
2851 ;; 2284 ;;
2852 ;; Variable names. 2285 ;; Variable names.
2853 (cons 2286 (cons
2854 (concat "\\<" 2287 (concat "\\<"
2855 (c-regexp-opt 2288 (regexp-opt
2856 '("ARGC" "ARGIND" "ARGV" "BINMODE" "CONVFMT" "ENVIRON" 2289 '("ARGC" "ARGIND" "ARGV" "BINMODE" "CONVFMT" "ENVIRON"
2857 "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR" "FS" "IGNORECASE" 2290 "ERRNO" "FIELDWIDTHS" "FILENAME" "FNR" "FS" "IGNORECASE"
2858 "LINT" "NF" "NR" "OFMT" "OFS" "ORS" "PROCINFO" "RLENGTH" 2291 "LINT" "NF" "NR" "OFMT" "OFS" "ORS" "PROCINFO" "RLENGTH"
@@ -2861,7 +2294,7 @@ need for `pike-font-lock-extra-types'.")
2861 2294
2862 ;; Special file names. (acm, 2002/7/22) 2295 ;; Special file names. (acm, 2002/7/22)
2863 ;; The following regexp was created by first evaluating this in GNU Emacs 21.1: 2296 ;; The following regexp was created by first evaluating this in GNU Emacs 21.1:
2864 ;; (c-regexp-opt '("/dev/stdin" "/dev/stdout" "/dev/stderr" "/dev/fd/n" "/dev/pid" 2297 ;; (regexp-opt '("/dev/stdin" "/dev/stdout" "/dev/stderr" "/dev/fd/n" "/dev/pid"
2865 ;; "/dev/ppid" "/dev/pgrpid" "/dev/user") 'words) 2298 ;; "/dev/ppid" "/dev/pgrpid" "/dev/user") 'words)
2866 ;; , removing the "?:" from each "\\(?:" (for backward compatibility with older Emacsen) 2299 ;; , removing the "?:" from each "\\(?:" (for backward compatibility with older Emacsen)
2867 ;; , replacing the "n" in "dev/fd/n" with "[0-9]+" 2300 ;; , replacing the "n" in "dev/fd/n" with "[0-9]+"
@@ -2875,7 +2308,7 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
2875 (1 font-lock-variable-name-face t) 2308 (1 font-lock-variable-name-face t)
2876 (8 font-lock-variable-name-face t t)) 2309 (8 font-lock-variable-name-face t t))
2877 ;; Do the same (almost) with 2310 ;; Do the same (almost) with
2878 ;; (c-regexp-opt '("/inet/tcp/lport/rhost/rport" "/inet/udp/lport/rhost/rport" 2311 ;; (regexp-opt '("/inet/tcp/lport/rhost/rport" "/inet/udp/lport/rhost/rport"
2879 ;; "/inet/raw/lport/rhost/rport") 'words) 2312 ;; "/inet/raw/lport/rhost/rport") 'words)
2880 ;; This cannot be combined with the above pattern, because the match number 2313 ;; This cannot be combined with the above pattern, because the match number
2881 ;; for the (optional) closing \" would then exceed 9. 2314 ;; for the (optional) closing \" would then exceed 9.
@@ -2886,7 +2319,7 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
2886 2319
2887 ;; Keywords. 2320 ;; Keywords.
2888 (concat "\\<" 2321 (concat "\\<"
2889 (c-regexp-opt 2322 (regexp-opt
2890 '("BEGIN" "END" "break" "continue" "delete" "do" "else" 2323 '("BEGIN" "END" "break" "continue" "delete" "do" "else"
2891 "exit" "for" "getline" "if" "in" "next" "nextfile" 2324 "exit" "for" "getline" "if" "in" "next" "nextfile"
2892 "return" "while") 2325 "return" "while")
@@ -2896,7 +2329,7 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
2896 `(eval . (list 2329 `(eval . (list
2897 ,(concat 2330 ,(concat
2898 "\\<" 2331 "\\<"
2899 (c-regexp-opt 2332 (regexp-opt
2900 '("adump" "and" "asort" "atan2" "bindtextdomain" "close" 2333 '("adump" "and" "asort" "atan2" "bindtextdomain" "close"
2901 "compl" "cos" "dcgettext" "exp" "extension" "fflush" 2334 "compl" "cos" "dcgettext" "exp" "extension" "fflush"
2902 "gensub" "gsub" "index" "int" "length" "log" "lshift" 2335 "gensub" "gsub" "index" "int" "length" "log" "lshift"
@@ -2909,17 +2342,17 @@ std\\(err\\|in\\|out\\)\\|user\\)\\)\\>\
2909 2342
2910 ;; gawk debugging keywords. (acm, 2002/7/21) 2343 ;; gawk debugging keywords. (acm, 2002/7/21)
2911 ;; (Removed, 2003/6/6. These functions are now fontified as built-ins) 2344 ;; (Removed, 2003/6/6. These functions are now fontified as built-ins)
2912;; (list (concat "\\<" (c-regexp-opt '("adump" "stopme") t) "\\>") 2345;; (list (concat "\\<" (regexp-opt '("adump" "stopme") t) "\\>")
2913;; 0 'font-lock-warning-face) 2346;; 0 'font-lock-warning-face)
2914 2347
2915 ;; User defined functions with an apparent spurious space before the 2348 ;; User defined functions with an apparent spurious space before the
2916 ;; opening parenthesis. acm, 2002/5/30. 2349 ;; opening parenthesis. acm, 2002/5/30.
2917 `(,(concat "\\(\\w\\|_\\)" c-awk-escaped-nls* "[ \t]" 2350 `(,(concat "\\(\\w\\|_\\)" c-awk-escaped-nls* "\\s "
2918 c-awk-escaped-nls*-with-space* "(") 2351 c-awk-escaped-nls*-with-space* "(")
2919 (0 'font-lock-warning-face)) 2352 (0 'font-lock-warning-face))
2920 2353
2921 ;; Space after \ in what looks like an escaped newline. 2002/5/31 2354 ;; Space after \ in what looks like an escaped newline. 2002/5/31
2922 '("\\\\[ \t]+$" 0 font-lock-warning-face t) 2355 '("\\\\\\s +$" 0 font-lock-warning-face t)
2923 2356
2924 ;; Unbalanced string (") or regexp (/) delimiters. 2002/02/16. 2357 ;; Unbalanced string (") or regexp (/) delimiters. 2002/02/16.
2925 '("\\s|" 0 font-lock-warning-face t nil) 2358 '("\\s|" 0 font-lock-warning-face t nil)
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 27753aa69c9..de2dab7ebc0 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -1,6 +1,7 @@
1;;; cc-langs.el --- language specific settings for CC Mode 1;;; cc-langs.el --- language specific settings for CC Mode
2 2
3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation,
4;; Inc.
4 5
5;; Authors: 1998- Martin Stjernholm 6;; Authors: 1998- Martin Stjernholm
6;; 1992-1999 Barry A. Warsaw 7;; 1992-1999 Barry A. Warsaw
@@ -24,7 +25,7 @@
24;; GNU General Public License for more details. 25;; GNU General Public License for more details.
25 26
26;; You should have received a copy of the GNU General Public License 27;; You should have received a copy of the GNU General Public License
27;; along with GNU Emacs; see the file COPYING. If not, write to 28;; along with this program; see the file COPYING. If not, write to
28;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 29;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29;; Boston, MA 02110-1301, USA. 30;; Boston, MA 02110-1301, USA.
30 31
@@ -124,6 +125,7 @@
124(cc-require 'cc-defs) 125(cc-require 'cc-defs)
125(cc-require 'cc-vars) 126(cc-require 'cc-vars)
126 127
128
127;; This file is not always loaded. See note above. 129;; This file is not always loaded. See note above.
128(cc-external-require 'cl) 130(cc-external-require 'cl)
129 131
@@ -140,16 +142,14 @@
140 c-lang-variable-inits-tail c-lang-variable-inits)) 142 c-lang-variable-inits-tail c-lang-variable-inits))
141 143
142(defmacro c-lang-defvar (var val &optional doc) 144(defmacro c-lang-defvar (var val &optional doc)
143 "Declares the buffer local variable VAR to get the value VAL at mode 145 "Declares the buffer local variable VAR to get the value VAL. VAL is
144initialization, at which point VAL is evaluated. More accurately, VAL 146evaluated and assigned at mode initialization. More precisely, VAL is
145is evaluated and bound to VAR when the result from the macro 147evaluated and bound to VAR when the result from the macro
146`c-init-language-vars' is evaluated. 148`c-init-language-vars' is evaluated.
147 149
148`c-lang-const' is typically used in VAL to get the right value for the 150`c-lang-const' is typically used in VAL to get the right value for the
149language being initialized, and such calls will be macro expanded to 151language being initialized, and such calls will be macro expanded to
150the evaluated constant value at compile time. 152the evaluated constant value at compile time."
151
152This macro does not do any hidden buffer changes."
153 153
154 (when (and (not doc) 154 (when (and (not doc)
155 (eq (car-safe val) 'c-lang-const) 155 (eq (car-safe val) 'c-lang-const)
@@ -177,6 +177,57 @@ This macro does not do any hidden buffer changes."
177 '(def-edebug-spec c-lang-defvar 177 '(def-edebug-spec c-lang-defvar
178 (&define name def-form &optional stringp))) 178 (&define name def-form &optional stringp)))
179 179
180(eval-when-compile
181 ;; Some helper functions used when building the language constants.
182
183 (defun c-filter-ops (ops opgroup-filter op-filter &optional xlate)
184 ;; Used to filter operators from the list OPS in a DWIM:ey way:
185 ;; OPS either has the structure of `c-operators', as a single
186 ;; group in `c-operators', or is a plain list of operators.
187 ;; OPGROUP-FILTER is used filter out the operator groups. It can
188 ;; be t to choose all groups, a list of the group type symbols to
189 ;; accept, or a function which will be called with the group
190 ;; symbol for each group and should return non-nil for those to
191 ;; include. OP-FILTER filters the individual operators in each
192 ;; group. It can be t to choose all operators, a regexp to test
193 ;; against each operator, or a function which will be called for
194 ;; each operator and should return non-nil for those to include.
195 ;; If XLATE is given, it's a function which is called for each
196 ;; matching operator and its return value is collected instead.
197 ;; If it returns a list, the elements are spliced directly into
198 ;; the final result, which is returned as a list with duplicates
199 ;; removed using `equal'. `c-mode-syntax-table' for the current
200 ;; mode is in effect during the whole procedure.
201 (unless (listp (car-safe ops))
202 (setq ops (list ops)))
203 (cond ((eq opgroup-filter t)
204 (setq opgroup-filter (lambda (opgroup) t)))
205 ((not (functionp opgroup-filter))
206 (setq opgroup-filter `(lambda (opgroup)
207 (memq opgroup ',opgroup-filter)))))
208 (cond ((eq op-filter t)
209 (setq op-filter (lambda (op) t)))
210 ((stringp op-filter)
211 (setq op-filter `(lambda (op)
212 (string-match ,op-filter op)))))
213 (unless xlate
214 (setq xlate 'identity))
215 (c-with-syntax-table (c-lang-const c-mode-syntax-table)
216 (delete-duplicates
217 (mapcan (lambda (opgroup)
218 (when (if (symbolp (car opgroup))
219 (when (funcall opgroup-filter (car opgroup))
220 (setq opgroup (cdr opgroup))
221 t)
222 t)
223 (mapcan (lambda (op)
224 (when (funcall op-filter op)
225 (let ((res (funcall xlate op)))
226 (if (listp res) res (list res)))))
227 opgroup)))
228 ops)
229 :test 'equal))))
230
180 231
181;;; Various mode specific values that aren't language related. 232;;; Various mode specific values that aren't language related.
182 233
@@ -208,7 +259,7 @@ This macro does not do any hidden buffer changes."
208 "----" 259 "----"
209 ("Toggle..." 260 ("Toggle..."
210 ["Syntactic indentation" c-toggle-syntactic-indentation t] 261 ["Syntactic indentation" c-toggle-syntactic-indentation t]
211 ["Auto newline" c-toggle-auto-state t] 262 ["Auto newline" c-toggle-auto-newline t]
212 ["Hungry delete" c-toggle-hungry-state t]))) 263 ["Hungry delete" c-toggle-hungry-state t])))
213 264
214 265
@@ -261,6 +312,10 @@ The syntax tables aren't stored directly since they're quite large."
261 (c-populate-syntax-table table) 312 (c-populate-syntax-table table)
262 ;; Mode specific syntaxes. 313 ;; Mode specific syntaxes.
263 ,(cond ((c-major-mode-is 'objc-mode) 314 ,(cond ((c-major-mode-is 'objc-mode)
315 ;; Let '@' be part of symbols in ObjC to cope with
316 ;; its compiler directives as single keyword tokens.
317 ;; This is then necessary since it's assumed that
318 ;; every keyword is a single symbol.
264 `(modify-syntax-entry ?@ "_" table)) 319 `(modify-syntax-entry ?@ "_" table))
265 ((c-major-mode-is 'pike-mode) 320 ((c-major-mode-is 'pike-mode)
266 `(modify-syntax-entry ?@ "." table))) 321 `(modify-syntax-entry ?@ "." table)))
@@ -328,6 +383,7 @@ so that all identifiers are recognized as words.")
328keyword. It's unspecified how far it matches. Does not contain a \\| 383keyword. It's unspecified how far it matches. Does not contain a \\|
329operator at the top level." 384operator at the top level."
330 t (concat "[" c-alpha "_]") 385 t (concat "[" c-alpha "_]")
386 objc (concat "[" c-alpha "@]")
331 pike (concat "[" c-alpha "_`]")) 387 pike (concat "[" c-alpha "_`]"))
332(c-lang-defvar c-symbol-start (c-lang-const c-symbol-start)) 388(c-lang-defvar c-symbol-start (c-lang-const c-symbol-start))
333 389
@@ -340,8 +396,8 @@ This is on the form that fits inside [ ] in a regexp."
340 objc (concat c-alnum "_$@")) 396 objc (concat c-alnum "_$@"))
341 397
342(c-lang-defconst c-symbol-key 398(c-lang-defconst c-symbol-key
343 "Regexp matching identifiers and keywords. Assumed to match if 399 "Regexp matching identifiers and keywords (with submatch 0). Assumed
344`c-symbol-start' matches on the same position." 400to match if `c-symbol-start' matches on the same position."
345 t (concat (c-lang-const c-symbol-start) 401 t (concat (c-lang-const c-symbol-start)
346 "[" (c-lang-const c-symbol-chars) "]*") 402 "[" (c-lang-const c-symbol-chars) "]*")
347 pike (concat 403 pike (concat
@@ -355,7 +411,7 @@ This is on the form that fits inside [ ] in a regexp."
355 411
356(c-lang-defconst c-symbol-key-depth 412(c-lang-defconst c-symbol-key-depth
357 ;; Number of regexp grouping parens in `c-symbol-key'. 413 ;; Number of regexp grouping parens in `c-symbol-key'.
358 t (c-regexp-opt-depth (c-lang-const c-symbol-key))) 414 t (regexp-opt-depth (c-lang-const c-symbol-key)))
359 415
360(c-lang-defconst c-nonsymbol-chars 416(c-lang-defconst c-nonsymbol-chars
361 "This is the set of chars that can't be part of a symbol, i.e. the 417 "This is the set of chars that can't be part of a symbol, i.e. the
@@ -371,165 +427,181 @@ It's assumed to not contain any submatchers."
371 ;; `c-symbol-key'. 427 ;; `c-symbol-key'.
372 t (concat "[" (c-lang-const c-nonsymbol-chars) "]")) 428 t (concat "[" (c-lang-const c-nonsymbol-chars) "]"))
373 429
374(c-lang-defconst c-opt-identifier-concat-key 430(c-lang-defconst c-identifier-ops
375 "Regexp matching the operators that join symbols to fully qualified 431 "The operators that make up fully qualified identifiers. nil in
376identifiers, or nil in languages that don't have such things. Does 432languages that don't have such things. See `c-operators' for a
377not contain a \\| operator at the top level." 433description of the format. Binary operators can concatenate symbols,
434e.g. \"::\" in \"A::B::C\". Prefix operators can precede identifiers,
435e.g. \"~\" in \"~A::B\". Other types of operators aren't supported.
436
437This value is by default merged into `c-operators'."
378 t nil 438 t nil
379 c++ "::" 439 c++ '((prefix "~" "??-" "compl")
440 (right-assoc "::")
441 (prefix "::"))
380 ;; Java has "." to concatenate identifiers but it's also used for 442 ;; Java has "." to concatenate identifiers but it's also used for
381 ;; normal indexing. There's special code in the Java font lock 443 ;; normal indexing. There's special code in the Java font lock
382 ;; rules to fontify qualified identifiers based on the standard 444 ;; rules to fontify qualified identifiers based on the standard
383 ;; naming conventions. We still define "." here to make 445 ;; naming conventions. We still define "." here to make
384 ;; `c-forward-name' move over as long names as possible which is 446 ;; `c-forward-name' move over as long names as possible which is
385 ;; necessary to e.g. handle throws clauses correctly. 447 ;; necessary to e.g. handle throws clauses correctly.
386 java "\\." 448 java '((left-assoc "."))
387 idl "::" 449 idl '((left-assoc "::")
388 pike "\\(::\\|\\.\\)") 450 (prefix "::"))
451 pike '((left-assoc "::")
452 (prefix "::")
453 (left-assoc ".")))
454
455(c-lang-defconst c-opt-identifier-concat-key
456 ;; Appendable adorned regexp matching the operators that join
457 ;; symbols to fully qualified identifiers, or nil in languages that
458 ;; don't have such things.
459 ;;
460 ;; This was a docstring constant in 5.30. It still works but is now
461 ;; considered internal - change `c-identifier-ops' instead.
462 t (let ((ops (c-filter-ops (c-lang-const c-identifier-ops)
463 '(left-assoc right-assoc)
464 t)))
465 (when ops
466 (c-make-keywords-re 'appendable ops))))
389(c-lang-defvar c-opt-identifier-concat-key 467(c-lang-defvar c-opt-identifier-concat-key
390 (c-lang-const c-opt-identifier-concat-key) 468 (c-lang-const c-opt-identifier-concat-key)
391 'dont-doc) 469 'dont-doc)
392 470
471(c-lang-defconst c-opt-identifier-concat-key-depth
472 ;; Number of regexp grouping parens in `c-opt-identifier-concat-key'.
473 t (regexp-opt-depth (c-lang-const c-opt-identifier-concat-key)))
474
475(c-lang-defconst c-opt-identifier-prefix-key
476 ;; Appendable adorned regexp matching operators that might precede
477 ;; an identifier and that are part of the identifier in that case.
478 ;; nil in languages without such things.
479 t (let ((ops (c-filter-ops (c-lang-const c-identifier-ops)
480 '(prefix)
481 t)))
482 (when ops
483 (c-make-keywords-re 'appendable ops))))
484
485(c-lang-defconst c-after-id-concat-ops
486 "Operators that can occur after a binary operator on `c-identifier-ops'
487in identifiers. nil in languages that don't have such things.
488
489Operators here should also have appropriate entries in `c-operators' -
490it's not taken care of by default."
491 t nil
492 ;; '~' for destructors in C++, '*' for member pointers.
493 c++ '("~" "*")
494 ;; In Java we recognize '*' to deal with "foo.bar.*" that can occur
495 ;; in import declarations. (This will also match bogus things like
496 ;; "foo.*bar" but we don't bother.)
497 java '("*"))
498
393(c-lang-defconst c-opt-after-id-concat-key 499(c-lang-defconst c-opt-after-id-concat-key
394 "Regexp that must match the token after `c-opt-identifier-concat-key' 500 ;; Regexp that must match the token after
395for it to be considered an identifier concatenation operator (which 501 ;; `c-opt-identifier-concat-key' for it to be considered an
396e.g. causes the preceding identifier to be fontified as a reference). 502 ;; identifier concatenation operator (which e.g. causes the
397Assumed to be a string if `c-opt-identifier-concat-key' is." 503 ;; preceding identifier to be fontified as a reference). Assumed to
398 t (if (c-lang-const c-opt-identifier-concat-key) 504 ;; be a string if `c-opt-identifier-concat-key' is.
399 (c-lang-const c-symbol-start)) 505 ;;
400 c++ (concat (c-lang-const c-symbol-start) 506 ;; This was a docstring constant in 5.30. It still works but is now
401 "\\|[~*]") 507 ;; considered internal - change `c-after-id-concat-ops' instead.
402 java (concat (c-lang-const c-symbol-start) 508 t (concat (c-lang-const c-symbol-start)
403 "\\|\\*")) 509 (if (c-lang-const c-after-id-concat-ops)
510 (concat "\\|" (c-make-keywords-re 'appendable
511 (c-lang-const c-after-id-concat-ops)))
512 "")))
404 513
405(c-lang-defconst c-identifier-start 514(c-lang-defconst c-identifier-start
406 "Regexp that matches the start of an \(optionally qualified) 515 "Regexp that matches the start of an (optionally qualified) identifier.
407identifier. It should also match all keywords. It's unspecified how 516It should also match all keywords. It's unspecified how far it
408far it matches." 517matches."
409 t (concat (c-lang-const c-symbol-start) 518 t (concat (c-lang-const c-symbol-start)
410 (if (c-lang-const c-opt-identifier-concat-key) 519 (if (c-lang-const c-opt-identifier-prefix-key)
411 (concat "\\|" (c-lang-const c-opt-identifier-concat-key)) 520 (concat "\\|"
412 "")) 521 (c-lang-const c-opt-identifier-prefix-key))
413 c++ (concat (c-lang-const c-identifier-start) 522 "")))
414 "\\|"
415 "[~*][ \t\n\r\f\v]*" (c-lang-const c-symbol-start))
416 ;; Java does not allow a leading qualifier operator.
417 java (c-lang-const c-symbol-start))
418(c-lang-defvar c-identifier-start (c-lang-const c-identifier-start)) 523(c-lang-defvar c-identifier-start (c-lang-const c-identifier-start))
419 524
420(c-lang-defconst c-identifier-key 525(c-lang-defconst c-identifier-key
421 "Regexp matching a fully qualified identifier, like \"A::B::c\" in 526 "Regexp matching a fully qualified identifier, like \"A::B::c\" in
422C++. It does not recognize the full range of syntactic whitespace 527C++. It does not recognize the full range of syntactic whitespace
423between the tokens; `c-forward-name' has to be used for that." 528between the tokens; `c-forward-name' has to be used for that. It
424 t (c-lang-const c-symbol-key) ; Default to `c-symbol-key'. 529should also not match identifiers containing parenthesis groupings,
425 ;; C++ allows a leading qualifier operator and a `~' before the last 530e.g. identifiers with template arguments such as \"A<X,Y>\" in C++."
426 ;; symbol. This regexp is more complex than strictly necessary to 531 ;; This regexp is more complex than strictly necessary to ensure
427 ;; ensure that it can be matched with a minimum of backtracking. 532 ;; that it can be matched with a minimum of backtracking.
428 c++ (concat 533 t (concat (if (c-lang-const c-opt-identifier-prefix-key)
429 "\\(" (c-lang-const c-opt-identifier-concat-key) "[ \t\n\r\f\v]*\\)?" 534 (concat
430 (concat 535 "\\("
431 "\\(" 536 (c-lang-const c-opt-identifier-prefix-key)
432 ;; The submatch below is depth of `c-opt-identifier-concat-key' + 3. 537 (c-lang-const c-simple-ws) "*"
433 "\\(" (c-lang-const c-symbol-key) "\\)"
434 (concat "\\("
435 "[ \t\n\r\f\v]*"
436 (c-lang-const c-opt-identifier-concat-key)
437 "[ \t\n\r\f\v]*"
438 ;; The submatch below is: `c-symbol-key-depth' +
439 ;; 2 * depth of `c-opt-identifier-concat-key' + 5.
440 "\\(" (c-lang-const c-symbol-key) "\\)"
441 "\\)*")
442 (concat "\\("
443 "[ \t\n\r\f\v]*"
444 (c-lang-const c-opt-identifier-concat-key)
445 "[ \t\n\r\f\v]*"
446 "[~*]"
447 "[ \t\n\r\f\v]*"
448 ;; The submatch below is: 2 * `c-symbol-key-depth' +
449 ;; 3 * depth of `c-opt-identifier-concat-key' + 7.
450 "\\(" (c-lang-const c-symbol-key) "\\)"
451 "\\)?") 538 "\\)?")
452 "\\|" 539 "")
453 "~[ \t\n\r\f\v]*" 540 "\\(" (c-lang-const c-symbol-key) "\\)"
454 ;; The submatch below is: 3 * `c-symbol-key-depth' + 541 (if (c-lang-const c-opt-identifier-concat-key)
455 ;; 3 * depth of `c-opt-identifier-concat-key' + 8. 542 (concat
456 "\\(" (c-lang-const c-symbol-key) "\\)" 543 "\\("
457 "\\)")) 544 (c-lang-const c-simple-ws) "*"
458 ;; IDL and Pike allows a leading qualifier operator. 545 (c-lang-const c-opt-identifier-concat-key)
459 (idl pike) (concat 546 (c-lang-const c-simple-ws) "*"
460 "\\(" 547 (if (c-lang-const c-after-id-concat-ops)
461 (c-lang-const c-opt-identifier-concat-key) 548 (concat
462 "[ \t\n\r\f\v]*" 549 "\\("
463 "\\)?" 550 (c-make-keywords-re 'appendable
464 ;; The submatch below is depth of 551 (c-lang-const c-after-id-concat-ops))
465 ;; `c-opt-identifier-concat-key' + 2. 552 (concat
466 "\\(" (c-lang-const c-symbol-key) "\\)" 553 ;; For flexibility, consider the symbol match
467 (concat "\\(" 554 ;; optional if we've hit a
468 "[ \t\n\r\f\v]*" 555 ;; `c-after-id-concat-ops' operator. This is
469 (c-lang-const c-opt-identifier-concat-key) 556 ;; also necessary to handle the "*" that can
470 "[ \t\n\r\f\v]*" 557 ;; end import declaration identifiers in Java.
471 ;; The submatch below is: `c-symbol-key-depth' + 558 "\\("
472 ;; 2 * depth of `c-opt-identifier-concat-key' + 4. 559 (c-lang-const c-simple-ws) "*"
560 "\\(" (c-lang-const c-symbol-key) "\\)"
561 "\\)?")
562 "\\|"
473 "\\(" (c-lang-const c-symbol-key) "\\)" 563 "\\(" (c-lang-const c-symbol-key) "\\)"
474 "\\)*")) 564 "\\)")
475 ;; Java does not allow a leading qualifier operator. If it ends 565 (concat "\\(" (c-lang-const c-symbol-key) "\\)"))
476 ;; with ".*" (used in import declarations) we also consider that as 566 "\\)*")
477 ;; part of the name. ("*" is actually recognized in any position 567 "")))
478 ;; except the first by this regexp, but we don't bother.)
479 java (concat "\\(" (c-lang-const c-symbol-key) "\\)" ; 1
480 (concat "\\("
481 "[ \t\n\r\f\v]*"
482 (c-lang-const c-opt-identifier-concat-key)
483 "[ \t\n\r\f\v]*"
484 (concat "\\("
485 ;; The submatch below is `c-symbol-key-depth' +
486 ;; depth of `c-opt-identifier-concat-key' + 4.
487 "\\(" (c-lang-const c-symbol-key) "\\)"
488 "\\|\\*\\)")
489 "\\)*")))
490(c-lang-defvar c-identifier-key (c-lang-const c-identifier-key)) 568(c-lang-defvar c-identifier-key (c-lang-const c-identifier-key))
491 569
492(c-lang-defconst c-identifier-last-sym-match 570(c-lang-defconst c-identifier-last-sym-match
493 "Used to identify the submatch in `c-identifier-key' that surrounds 571 ;; This was a docstring constant in 5.30 but it's no longer used.
494the last symbol in the qualified identifier. It's a list of submatch 572 ;; It's only kept to avoid breaking third party code.
495numbers, of which the first that has a match is taken. It's assumed 573 ;;
496that at least one does when the regexp has matched." 574 ;; Used to identify the submatch in `c-identifier-key' that
497 t '(0) 575 ;; surrounds the last symbol in the qualified identifier. It's a
498 c++ (list (+ (* 3 (c-lang-const c-symbol-key-depth)) 576 ;; list of submatch numbers, of which the first that has a match is
499 (* 3 (c-regexp-opt-depth 577 ;; taken. It's assumed that at least one does when the regexp has
500 (c-lang-const c-opt-identifier-concat-key))) 578 ;; matched.
501 8) 579 t nil)
502 (+ (* 2 (c-lang-const c-symbol-key-depth)) 580
503 (* 3 (c-regexp-opt-depth 581(c-lang-defconst c-string-escaped-newlines
504 (c-lang-const c-opt-identifier-concat-key))) 582 "Set if the language support backslash escaped newlines inside string
505 7) 583literals."
506 (+ (c-lang-const c-symbol-key-depth) 584 t nil
507 (* 2 (c-regexp-opt-depth 585 (c c++ objc pike) t)
508 (c-lang-const c-opt-identifier-concat-key))) 586(c-lang-defvar c-string-escaped-newlines
509 5) 587 (c-lang-const c-string-escaped-newlines))
510 (+ (c-regexp-opt-depth 588
511 (c-lang-const c-opt-identifier-concat-key)) 589(c-lang-defconst c-multiline-string-start-char
512 3)) 590 "Set if the language supports multiline string literals without escaped
513 (idl pike) (list (+ (c-lang-const c-symbol-key-depth) 591newlines. If t, all string literals are multiline. If a character,
514 (* 2 (c-regexp-opt-depth 592only literals where the open quote is immediately preceded by that
515 (c-lang-const c-opt-identifier-concat-key))) 593literal are multiline."
516 4) 594 t nil
517 (+ (c-regexp-opt-depth 595 pike ?#)
518 (c-lang-const c-opt-identifier-concat-key)) 596(c-lang-defvar c-multiline-string-start-char
519 2)) 597 (c-lang-const c-multiline-string-start-char))
520 java (list (+ (c-lang-const c-symbol-key-depth)
521 (c-regexp-opt-depth
522 (c-lang-const c-opt-identifier-concat-key))
523 4)
524 1))
525(c-lang-defvar c-identifier-last-sym-match
526 (c-lang-const c-identifier-last-sym-match)
527 'dont-doc)
528 598
529(c-lang-defconst c-opt-cpp-prefix 599(c-lang-defconst c-opt-cpp-prefix
530 "Regexp matching the prefix of a cpp directive in the languages that 600 "Regexp matching the prefix of a cpp directive in the languages that
531normally use that macro preprocessor. Tested at bol or at boi. 601normally use that macro preprocessor. Tested at bol or at boi.
532Assumed to not contain any submatches or \\| operators." 602Assumed to not contain any submatches or \\| operators."
603 ;; TODO (ACM, 2005-04-01). Amend the following to recognise escaped NLs;
604 ;; amend all uses of c-opt-cpp-prefix which count regexp-depth.
533 t "\\s *#\\s *" 605 t "\\s *#\\s *"
534 (java awk) nil) 606 (java awk) nil)
535(c-lang-defvar c-opt-cpp-prefix (c-lang-const c-opt-cpp-prefix)) 607(c-lang-defvar c-opt-cpp-prefix (c-lang-const c-opt-cpp-prefix))
@@ -546,9 +618,46 @@ submatch surrounds the directive name."
546 "\\([" c-alnum "]+\\|!\\)")) 618 "\\([" c-alnum "]+\\|!\\)"))
547(c-lang-defvar c-opt-cpp-start (c-lang-const c-opt-cpp-start)) 619(c-lang-defvar c-opt-cpp-start (c-lang-const c-opt-cpp-start))
548 620
549(c-lang-defconst c-cpp-defined-fns 621(c-lang-defconst c-cpp-message-directives
550 ;; Name of functions in cpp expressions that take an identifier as 622 "List of cpp directives (without the prefix) that are followed by a
551 ;; the argument. 623string message."
624 t (if (c-lang-const c-opt-cpp-prefix)
625 '("error"))
626 pike '("error" "warning"))
627
628(c-lang-defconst c-cpp-include-directives
629 "List of cpp directives (without the prefix) that are followed by a
630file name in angle brackets or quotes."
631 t (if (c-lang-const c-opt-cpp-prefix)
632 '("include"))
633 objc '("include" "import"))
634
635(c-lang-defconst c-opt-cpp-macro-define
636 "Cpp directive (without the prefix) that is followed by a macro
637definition, or nil if the language doesn't have any."
638 t (if (c-lang-const c-opt-cpp-prefix)
639 "define"))
640
641(c-lang-defconst c-opt-cpp-macro-define-start
642 ;; Regexp matching everything up to the macro body of a cpp define,
643 ;; or the end of the logical line if there is none. Set if
644 ;; c-opt-cpp-macro-define is.
645 t (if (c-lang-const c-opt-cpp-macro-define)
646 (concat (c-lang-const c-opt-cpp-prefix)
647 (c-lang-const c-opt-cpp-macro-define)
648 "[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?"
649 "\\([ \t]\\|\\\\\n\\)*")))
650(c-lang-defvar c-opt-cpp-macro-define-start
651 (c-lang-const c-opt-cpp-macro-define-start))
652
653(c-lang-defconst c-cpp-expr-directives
654 "List if cpp directives (without the prefix) that are followed by an
655expression."
656 t (if (c-lang-const c-opt-cpp-prefix)
657 '("if" "elif")))
658
659(c-lang-defconst c-cpp-expr-functions
660 "List of functions in cpp expressions."
552 t (if (c-lang-const c-opt-cpp-prefix) 661 t (if (c-lang-const c-opt-cpp-prefix)
553 '("defined")) 662 '("defined"))
554 pike '("defined" "efun" "constant")) 663 pike '("defined" "efun" "constant"))
@@ -559,7 +668,7 @@ submatch surrounds the directive name."
559 java (append (c-lang-const c-assignment-operators) 668 java (append (c-lang-const c-assignment-operators)
560 '(">>>=")) 669 '(">>>="))
561 c++ (append (c-lang-const c-assignment-operators) 670 c++ (append (c-lang-const c-assignment-operators)
562 '("and_eq" "or_eq" "xor_eq")) 671 '("and_eq" "or_eq" "xor_eq" "??!=" "??'="))
563 idl nil) 672 idl nil)
564 673
565(c-lang-defconst c-operators 674(c-lang-defconst c-operators
@@ -573,6 +682,9 @@ it. The operator group types are:
573 682
574'prefix Unary prefix operators. 683'prefix Unary prefix operators.
575'postfix Unary postfix operators. 684'postfix Unary postfix operators.
685'postfix-if-paren
686 Unary postfix operators if and only if the chars have
687 parenthesis syntax.
576'left-assoc Binary left associative operators (i.e. a+b+c means (a+b)+c). 688'left-assoc Binary left associative operators (i.e. a+b+c means (a+b)+c).
577'right-assoc Binary right associative operators (i.e. a=b=c means a=(b=c)). 689'right-assoc Binary right associative operators (i.e. a=b=c means a=(b=c)).
578'right-assoc-sequence 690'right-assoc-sequence
@@ -605,20 +717,14 @@ since CC Mode treats every identifier as an expression."
605 ,@(when (c-major-mode-is '(c-mode c++-mode)) 717 ,@(when (c-major-mode-is '(c-mode c++-mode))
606 '("%:%:" "??=??="))))) 718 '("%:%:" "??=??=")))))
607 719
608 ;; Primary. Info duplicated in `c-opt-identifier-concat-key' 720 ;; Primary.
609 ;; and `c-identifier-key'. 721 ,@(c-lang-const c-identifier-ops)
610 ,@(cond ((c-major-mode-is 'c++-mode) 722 ,@(cond ((c-major-mode-is 'c++-mode)
611 `((postfix-if-paren "<" ">") ; Templates. 723 `((postfix-if-paren "<" ">"))) ; Templates.
612 (prefix "~" "??-" "compl")
613 (right-assoc "::")
614 (prefix "::")))
615 ((c-major-mode-is 'pike-mode) 724 ((c-major-mode-is 'pike-mode)
616 `((left-assoc "::") 725 `((prefix "global" "predef")))
617 (prefix "::" "global" "predef")))
618 ((c-major-mode-is 'java-mode) 726 ((c-major-mode-is 'java-mode)
619 `(;; Not necessary since it's also in the postfix group below. 727 `((prefix "super"))))
620 ;;(left-assoc ".")
621 (prefix "super"))))
622 728
623 ;; Postfix. 729 ;; Postfix.
624 ,@(when (c-major-mode-is 'c++-mode) 730 ,@(when (c-major-mode-is 'c++-mode)
@@ -718,10 +824,8 @@ since CC Mode treats every identifier as an expression."
718 idl `(;; Preprocessor. 824 idl `(;; Preprocessor.
719 (prefix "#") 825 (prefix "#")
720 (left-assoc "##") 826 (left-assoc "##")
721 ;; Primary. Info duplicated in `c-opt-identifier-concat-key' 827 ;; Primary.
722 ;; and `c-identifier-key'. 828 ,@(c-lang-const c-identifier-ops)
723 (left-assoc "::")
724 (prefix "::")
725 ;; Unary. 829 ;; Unary.
726 (prefix "+" "-" "~") 830 (prefix "+" "-" "~")
727 ;; Multiplicative. 831 ;; Multiplicative.
@@ -739,14 +843,12 @@ since CC Mode treats every identifier as an expression."
739 843
740(c-lang-defconst c-operator-list 844(c-lang-defconst c-operator-list
741 ;; The operators as a flat list (without duplicates). 845 ;; The operators as a flat list (without duplicates).
742 t (delete-duplicates (mapcan (lambda (elem) (append (cdr elem) nil)) 846 t (c-filter-ops (c-lang-const c-operators) t t))
743 (c-lang-const c-operators))
744 :test 'string-equal))
745 847
746(c-lang-defconst c-overloadable-operators 848(c-lang-defconst c-overloadable-operators
747 "List of the operators that are overloadable, in their \"identifier form\"." 849 "List of the operators that are overloadable, in their \"identifier
850form\". See also `c-op-identitier-prefix'."
748 t nil 851 t nil
749 ;; The preceding "operator" keyword is treated separately in C++.
750 c++ '("new" "delete" ;; Can be followed by "[]" but we ignore that. 852 c++ '("new" "delete" ;; Can be followed by "[]" but we ignore that.
751 "+" "-" "*" "/" "%" 853 "+" "-" "*" "/" "%"
752 "^" "??'" "xor" "&" "bitand" "|" "??!" "bitor" "~" "??-" "compl" 854 "^" "??'" "xor" "&" "bitand" "|" "??!" "bitor" "~" "??-" "compl"
@@ -768,6 +870,20 @@ since CC Mode treats every identifier as an expression."
768(c-lang-defvar c-overloadable-operators-regexp 870(c-lang-defvar c-overloadable-operators-regexp
769 (c-lang-const c-overloadable-operators-regexp)) 871 (c-lang-const c-overloadable-operators-regexp))
770 872
873(c-lang-defconst c-opt-op-identitier-prefix
874 "Regexp matching the token before the ones in
875`c-overloadable-operators' when operators are specified in their
876\"identifier form\". This typically matches \"operator\" in C++ where
877operator functions are specified as e.g. \"operator +\". It's nil in
878languages without operator functions or where the complete operator
879identifier is listed in `c-overloadable-operators'.
880
881This regexp is assumed to not match any non-operator identifier."
882 t nil
883 c++ (c-make-keywords-re t '("operator")))
884(c-lang-defvar c-opt-op-identitier-prefix
885 (c-lang-const c-opt-op-identitier-prefix))
886
771(c-lang-defconst c-other-op-syntax-tokens 887(c-lang-defconst c-other-op-syntax-tokens
772 "List of the tokens made up of characters in the punctuation or 888 "List of the tokens made up of characters in the punctuation or
773parenthesis syntax classes that have uses other than as expression 889parenthesis syntax classes that have uses other than as expression
@@ -776,9 +892,9 @@ operators."
776 (c c++ pike) (append '("#" "##" ; Used by cpp. 892 (c c++ pike) (append '("#" "##" ; Used by cpp.
777 "::" "...") 893 "::" "...")
778 (c-lang-const c-other-op-syntax-tokens)) 894 (c-lang-const c-other-op-syntax-tokens))
779 (c c++) (append '("<%" "%>" "<:" ":>" "%:" "%:%:" "*") 895 (c c++) (append '("*") (c-lang-const c-other-op-syntax-tokens))
780 (c-lang-const c-other-op-syntax-tokens)) 896 c++ (append '("&" "<%" "%>" "<:" ":>" "%:" "%:%:")
781 c++ (append '("&") (c-lang-const c-other-op-syntax-tokens)) 897 (c-lang-const c-other-op-syntax-tokens))
782 objc (append '("#" "##" ; Used by cpp. 898 objc (append '("#" "##" ; Used by cpp.
783 "+" "-") (c-lang-const c-other-op-syntax-tokens)) 899 "+" "-") (c-lang-const c-other-op-syntax-tokens))
784 idl (append '("#" "##") ; Used by cpp. 900 idl (append '("#" "##") ; Used by cpp.
@@ -788,17 +904,35 @@ operators."
788 (c-lang-const c-overloadable-operators)) 904 (c-lang-const c-overloadable-operators))
789 awk '("{" "}" "(" ")" "[" "]" ";" "," "=" "/")) 905 awk '("{" "}" "(" ")" "[" "]" ";" "," "=" "/"))
790 906
907(c-lang-defconst c-all-op-syntax-tokens
908 ;; List of all tokens in the punctuation and parenthesis syntax
909 ;; classes.
910 t (delete-duplicates (append (c-lang-const c-other-op-syntax-tokens)
911 (c-lang-const c-operator-list))
912 :test 'string-equal))
913
914(c-lang-defconst c-nonsymbol-token-char-list
915 ;; List containing all chars not in the word, symbol or
916 ;; syntactically irrelevant syntax classes, i.e. all punctuation,
917 ;; parenthesis and string delimiter chars.
918 t (c-with-syntax-table (c-lang-const c-mode-syntax-table)
919 ;; Only go through the chars in the printable ASCII range. No
920 ;; language so far has 8-bit or widestring operators.
921 (let (list (char 32))
922 (while (< char 127)
923 (or (memq (char-syntax char) '(?w ?_ ?< ?> ?\ ))
924 (setq list (cons (c-int-to-char char) list)))
925 (setq char (1+ char)))
926 list)))
927
791(c-lang-defconst c-nonsymbol-token-regexp 928(c-lang-defconst c-nonsymbol-token-regexp
792 ;; Regexp matching all tokens in the punctuation and parenthesis 929 ;; Regexp matching all tokens in the punctuation and parenthesis
793 ;; syntax classes. Note that this also matches ".", which can start 930 ;; syntax classes. Note that this also matches ".", which can start
794 ;; a float. 931 ;; a float.
795 t (c-make-keywords-re nil 932 t (c-make-keywords-re nil
796 (c-with-syntax-table (c-lang-const c-mode-syntax-table) 933 (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
797 (mapcan (lambda (op) 934 t
798 (if (string-match "\\`\\(\\s.\\|\\s\(\\|\\s\)\\)+\\'" op) 935 "\\`\\(\\s.\\|\\s\(\\|\\s\)\\)+\\'")))
799 (list op)))
800 (append (c-lang-const c-other-op-syntax-tokens)
801 (c-lang-const c-operator-list))))))
802(c-lang-defvar c-nonsymbol-token-regexp 936(c-lang-defvar c-nonsymbol-token-regexp
803 (c-lang-const c-nonsymbol-token-regexp)) 937 (c-lang-const c-nonsymbol-token-regexp))
804 938
@@ -819,26 +953,34 @@ operators."
819(c-lang-defvar c-assignment-op-regexp 953(c-lang-defvar c-assignment-op-regexp
820 (c-lang-const c-assignment-op-regexp)) 954 (c-lang-const c-assignment-op-regexp))
821 955
956(c-lang-defconst c-<>-multichar-token-regexp
957 ;; Regexp matching all tokens containing "<" or ">" which are longer
958 ;; than one char.
959 t (c-make-keywords-re nil
960 (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
961 t
962 ".[<>]\\|[<>].")))
963(c-lang-defvar c-<>-multichar-token-regexp
964 (c-lang-const c-<>-multichar-token-regexp))
965
822(c-lang-defconst c-<-op-cont-regexp 966(c-lang-defconst c-<-op-cont-regexp
823 ;; Regexp matching the second and subsequent characters of all 967 ;; Regexp matching the second and subsequent characters of all
824 ;; multicharacter tokens that begin with "<". 968 ;; multicharacter tokens that begin with "<".
825 t (c-make-keywords-re nil 969 t (c-make-keywords-re nil
826 (mapcan (lambda (op) 970 (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
827 (if (string-match "\\`<." op) 971 t
828 (list (substring op 1)))) 972 "\\`<."
829 (append (c-lang-const c-other-op-syntax-tokens) 973 (lambda (op) (substring op 1)))))
830 (c-lang-const c-operator-list)))))
831(c-lang-defvar c-<-op-cont-regexp (c-lang-const c-<-op-cont-regexp)) 974(c-lang-defvar c-<-op-cont-regexp (c-lang-const c-<-op-cont-regexp))
832 975
833(c-lang-defconst c->-op-cont-regexp 976(c-lang-defconst c->-op-cont-regexp
834 ;; Regexp matching the second and subsequent characters of all 977 ;; Regexp matching the second and subsequent characters of all
835 ;; multicharacter tokens that begin with ">". 978 ;; multicharacter tokens that begin with ">".
836 t (c-make-keywords-re nil 979 t (c-make-keywords-re nil
837 (mapcan (lambda (op) 980 (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
838 (if (string-match "\\`>." op) 981 t
839 (list (substring op 1)))) 982 "\\`>."
840 (append (c-lang-const c-other-op-syntax-tokens) 983 (lambda (op) (substring op 1)))))
841 (c-lang-const c-operator-list)))))
842(c-lang-defvar c->-op-cont-regexp (c-lang-const c->-op-cont-regexp)) 984(c-lang-defvar c->-op-cont-regexp (c-lang-const c->-op-cont-regexp))
843 985
844(c-lang-defconst c-stmt-delim-chars 986(c-lang-defconst c-stmt-delim-chars
@@ -847,7 +989,7 @@ operators."
847 ;; begin with "^" to negate the set. If ? : operators should be 989 ;; begin with "^" to negate the set. If ? : operators should be
848 ;; detected then the string must end with "?:". 990 ;; detected then the string must end with "?:".
849 t "^;{}?:" 991 t "^;{}?:"
850 awk "^;{}\n\r?:") ; The newline chars gets special treatment. 992 awk "^;{}#\n\r?:") ; The newline chars gets special treatment.
851(c-lang-defvar c-stmt-delim-chars (c-lang-const c-stmt-delim-chars)) 993(c-lang-defvar c-stmt-delim-chars (c-lang-const c-stmt-delim-chars))
852 994
853(c-lang-defconst c-stmt-delim-chars-with-comma 995(c-lang-defconst c-stmt-delim-chars-with-comma
@@ -860,15 +1002,69 @@ operators."
860 1002
861;;; Syntactic whitespace. 1003;;; Syntactic whitespace.
862 1004
1005(c-lang-defconst c-simple-ws
1006 "Regexp matching an ordinary whitespace character.
1007Does not contain a \\| operator at the top level."
1008 ;; "\\s " is not enough since it doesn't match line breaks.
1009 t "\\(\\s \\|[\n\r]\\)")
1010
1011(c-lang-defconst c-simple-ws-depth
1012 ;; Number of regexp grouping parens in `c-simple-ws'.
1013 t (regexp-opt-depth (c-lang-const c-simple-ws)))
1014
1015(c-lang-defconst c-line-comment-starter
1016 "String that starts line comments, or nil if such don't exist.
1017Line comments are always terminated by newlines. At least one of
1018`c-block-comment-starter' and this one is assumed to be set.
1019
1020Note that it's currently not enough to set this to support a new
1021comment style. Other stuff like the syntax table must also be set up
1022properly."
1023 t "//"
1024 awk "#")
1025(c-lang-defvar c-line-comment-starter (c-lang-const c-line-comment-starter))
1026
1027(c-lang-defconst c-block-comment-starter
1028 "String that starts block comments, or nil if such don't exist.
1029Block comments are ended by `c-block-comment-ender', which is assumed
1030to be set if this is. At least one of `c-line-comment-starter' and
1031this one is assumed to be set.
1032
1033Note that it's currently not enough to set this to support a new
1034comment style. Other stuff like the syntax table must also be set up
1035properly."
1036 t "/*"
1037 awk nil)
1038
1039(c-lang-defconst c-block-comment-ender
1040 "String that ends block comments, or nil if such don't exist.
1041
1042Note that it's currently not enough to set this to support a new
1043comment style. Other stuff like the syntax table must also be set up
1044properly."
1045 t "*/"
1046 awk nil)
1047
863(c-lang-defconst c-comment-start-regexp 1048(c-lang-defconst c-comment-start-regexp
864 ;; Regexp to match the start of any type of comment. 1049 ;; Regexp to match the start of any type of comment.
865 ;; 1050 t (let ((re (c-make-keywords-re nil
866 ;; TODO: Ought to use `c-comment-prefix-regexp' with some 1051 (list (c-lang-const c-line-comment-starter)
867 ;; modifications instead of this. 1052 (c-lang-const c-block-comment-starter)))))
868 t "/[/*]" 1053 (if (memq 'gen-comment-delim c-emacs-features)
869 awk "#") 1054 (concat re "\\|\\s!")
1055 re)))
870(c-lang-defvar c-comment-start-regexp (c-lang-const c-comment-start-regexp)) 1056(c-lang-defvar c-comment-start-regexp (c-lang-const c-comment-start-regexp))
871 1057
1058;;;; Added by ACM, 2003/9/18.
1059(c-lang-defconst c-block-comment-start-regexp
1060 ;; Regexp which matches the start of a block comment (if such exists in the
1061 ;; language)
1062 t (if (c-lang-const c-block-comment-starter)
1063 (regexp-quote (c-lang-const c-block-comment-starter))
1064 "\\<\\>"))
1065(c-lang-defvar c-block-comment-start-regexp
1066 (c-lang-const c-block-comment-start-regexp))
1067
872(c-lang-defconst c-literal-start-regexp 1068(c-lang-defconst c-literal-start-regexp
873 ;; Regexp to match the start of comments and string literals. 1069 ;; Regexp to match the start of comments and string literals.
874 t (concat (c-lang-const c-comment-start-regexp) 1070 t (concat (c-lang-const c-comment-start-regexp)
@@ -891,129 +1087,235 @@ operators."
891(c-lang-defconst comment-start 1087(c-lang-defconst comment-start
892 "String that starts comments inserted with M-; etc. 1088 "String that starts comments inserted with M-; etc.
893`comment-start' is initialized from this." 1089`comment-start' is initialized from this."
894 t "// " 1090 ;; Default: Prefer line comments to block comments, and pad with a space.
895 c "/* " 1091 t (concat (or (c-lang-const c-line-comment-starter)
896 awk "# ") 1092 (c-lang-const c-block-comment-starter))
1093 " ")
1094 ;; In C we still default to the block comment style since line
1095 ;; comments aren't entirely portable.
1096 c "/* ")
897(c-lang-defvar comment-start (c-lang-const comment-start) 1097(c-lang-defvar comment-start (c-lang-const comment-start)
898 'dont-doc) 1098 'dont-doc)
899 1099
900(c-lang-defconst comment-end 1100(c-lang-defconst comment-end
901 "String that ends comments inserted with M-; etc. 1101 "String that ends comments inserted with M-; etc.
902`comment-end' is initialized from this." 1102`comment-end' is initialized from this."
903 t "" 1103 ;; Default: Use block comment style if comment-start uses block
904 c " */") 1104 ;; comments, and pad with a space in that case.
1105 t (if (string-match (concat "\\`\\("
1106 (c-lang-const c-block-comment-start-regexp)
1107 "\\)")
1108 (c-lang-const comment-start))
1109 (concat " " (c-lang-const c-block-comment-ender))
1110 ""))
905(c-lang-defvar comment-end (c-lang-const comment-end) 1111(c-lang-defvar comment-end (c-lang-const comment-end)
906 'dont-doc) 1112 'dont-doc)
907 1113
908(c-lang-defconst comment-start-skip 1114(c-lang-defconst comment-start-skip
909 "Regexp to match the start of a comment plus everything up to its body. 1115 "Regexp to match the start of a comment plus everything up to its body.
910`comment-start-skip' is initialized from this." 1116`comment-start-skip' is initialized from this."
911 t "/\\*+ *\\|//+ *" 1117 ;; Default: Allow the last char of the comment starter(s) to be
912 awk "#+ *") 1118 ;; repeated, then allow any amount of horizontal whitespace.
1119 t (concat "\\("
1120 (c-concat-separated
1121 (mapcar (lambda (cs)
1122 (when cs
1123 (concat (regexp-quote cs) "+")))
1124 (list (c-lang-const c-line-comment-starter)
1125 (c-lang-const c-block-comment-starter)))
1126 "\\|")
1127 "\\)\\s *"))
913(c-lang-defvar comment-start-skip (c-lang-const comment-start-skip) 1128(c-lang-defvar comment-start-skip (c-lang-const comment-start-skip)
914 'dont-doc) 1129 'dont-doc)
915 1130
916(c-lang-defconst c-syntactic-ws-start 1131(c-lang-defconst c-syntactic-ws-start
917 "Regexp matching any sequence that can start syntactic whitespace. 1132 ;; Regexp matching any sequence that can start syntactic whitespace.
918The only uncertain case is '#' when there are cpp directives." 1133 ;; The only uncertain case is '#' when there are cpp directives.
919 t "[ \n\t\r\v\f#]\\|/[/*]\\|\\\\[\n\r]" 1134 t (concat "\\s \\|"
920 awk "[ \n\t\r\v\f#]\\|\\\\[\n\r]") 1135 (c-make-keywords-re nil
921(c-lang-defvar c-syntactic-ws-start (c-lang-const c-syntactic-ws-start) 1136 (append (list (c-lang-const c-line-comment-starter)
922 'dont-doc) 1137 (c-lang-const c-block-comment-starter)
1138 (when (c-lang-const c-opt-cpp-prefix)
1139 "#"))
1140 '("\n" "\r")))
1141 "\\|\\\\[\n\r]"
1142 (when (memq 'gen-comment-delim c-emacs-features)
1143 "\\|\\s!")))
1144(c-lang-defvar c-syntactic-ws-start (c-lang-const c-syntactic-ws-start))
923 1145
924(c-lang-defconst c-syntactic-ws-end 1146(c-lang-defconst c-syntactic-ws-end
925 "Regexp matching any single character that might end syntactic whitespace." 1147 ;; Regexp matching any single character that might end syntactic whitespace.
926 t "[ \n\t\r\v\f/]" 1148 t (concat "\\s \\|"
927 awk "[ \n\t\r\v\f]") 1149 (c-make-keywords-re nil
928(c-lang-defvar c-syntactic-ws-end (c-lang-const c-syntactic-ws-end) 1150 (append (when (c-lang-const c-block-comment-ender)
929 'dont-doc) 1151 (list
1152 (string
1153 (elt (c-lang-const c-block-comment-ender)
1154 (1- (length
1155 (c-lang-const c-block-comment-ender)))))))
1156 '("\n" "\r")))
1157 (when (memq 'gen-comment-delim c-emacs-features)
1158 "\\|\\s!")))
1159(c-lang-defvar c-syntactic-ws-end (c-lang-const c-syntactic-ws-end))
1160
1161(c-lang-defconst c-unterminated-block-comment-regexp
1162 ;; Regexp matching an unterminated block comment that doesn't
1163 ;; contain line breaks, or nil in languages without block comments.
1164 ;; Does not contain a \| operator at the top level.
1165 t (when (c-lang-const c-block-comment-starter)
1166 (concat
1167 (regexp-quote (c-lang-const c-block-comment-starter))
1168 ;; It's messy to cook together a regexp that matches anything
1169 ;; but c-block-comment-ender.
1170 (let ((end (c-lang-const c-block-comment-ender)))
1171 (cond ((= (length end) 1)
1172 (concat "[^" end "\n\r]*"))
1173 ((= (length end) 2)
1174 (concat "[^" (substring end 0 1) "\n\r]*"
1175 "\\("
1176 (regexp-quote (substring end 0 1)) "+"
1177 "[^"
1178 ;; The quoting rules inside char classes are silly. :P
1179 (cond ((= (elt end 0) (elt end 1))
1180 (concat (substring end 0 1) "\n\r"))
1181 ((= (elt end 1) ?\])
1182 (concat (substring end 1 2) "\n\r"
1183 (substring end 0 1)))
1184 (t
1185 (concat (substring end 0 1) "\n\r"
1186 (substring end 1 2))))
1187 "]"
1188 "[^" (substring end 0 1) "\n\r]*"
1189 "\\)*"))
1190 (t
1191 (error "Can't handle a block comment ender of length %s"
1192 (length end))))))))
1193
1194(c-lang-defconst c-block-comment-regexp
1195 ;; Regexp matching a block comment that doesn't contain line breaks,
1196 ;; or nil in languages without block comments. The reason we don't
1197 ;; allow line breaks is to avoid going very far and risk running out
1198 ;; of regexp stack; this regexp is intended to handle only short
1199 ;; comments that might be put in the middle of limited constructs
1200 ;; like declarations. Does not contain a \| operator at the top
1201 ;; level.
1202 t (when (c-lang-const c-unterminated-block-comment-regexp)
1203 (concat
1204 (c-lang-const c-unterminated-block-comment-regexp)
1205 (let ((end (c-lang-const c-block-comment-ender)))
1206 (cond ((= (length end) 1)
1207 (regexp-quote end))
1208 ((= (length end) 2)
1209 (concat (regexp-quote (substring end 0 1)) "+"
1210 (regexp-quote (substring end 1 2))))
1211 (t
1212 (error "Can't handle a block comment ender of length %s"
1213 (length end))))))))
930 1214
931(c-lang-defconst c-nonwhite-syntactic-ws 1215(c-lang-defconst c-nonwhite-syntactic-ws
932 ;; Regexp matching a piece of syntactic whitespace that isn't a 1216 ;; Regexp matching a piece of syntactic whitespace that isn't a
933 ;; sequence of simple whitespace characters. As opposed to 1217 ;; sequence of simple whitespace characters. As opposed to
934 ;; `c-(forward|backward)-syntactic-ws', this doesn't regard cpp 1218 ;; `c-(forward|backward)-syntactic-ws', this doesn't regard cpp
935 ;; directives as syntactic whitespace. 1219 ;; directives as syntactic whitespace.
936 t (concat "/" (concat 1220 t (c-concat-separated
937 "\\(" 1221 (list (when (c-lang-const c-line-comment-starter)
938 "/[^\n\r]*[\n\r]" ; Line comment. 1222 (concat (regexp-quote (c-lang-const c-line-comment-starter))
939 "\\|" 1223 "[^\n\r]*[\n\r]"))
940 ;; Block comment. We intentionally don't allow line 1224 (c-lang-const c-block-comment-regexp)
941 ;; breaks in them to avoid going very far and risk 1225 "\\\\[\n\r]"
942 ;; running out of regexp stack; this regexp is 1226 (when (memq 'gen-comment-delim c-emacs-features)
943 ;; intended to handle only short comments that 1227 "\\s!\\S!*\\s!"))
944 ;; might be put in the middle of limited constructs 1228 "\\|"))
945 ;; like declarations.
946 "\\*\\([^*\n\r]\\|\\*[^/\n\r]\\)*\\*/"
947 "\\)")
948 "\\|"
949 "\\\\[\n\r]") ; Line continuations.
950 awk ("#.*[\n\r]\\|\\\\[\n\r]"))
951 1229
952(c-lang-defconst c-syntactic-ws 1230(c-lang-defconst c-syntactic-ws
953 ;; Regexp matching syntactic whitespace, including possibly the 1231 ;; Regexp matching syntactic whitespace, including possibly the
954 ;; empty string. As opposed to `c-(forward|backward)-syntactic-ws', 1232 ;; empty string. As opposed to `c-(forward|backward)-syntactic-ws',
955 ;; this doesn't regard cpp directives as syntactic whitespace. Does 1233 ;; this doesn't regard cpp directives as syntactic whitespace. Does
956 ;; not contain a \| operator at the top level. 1234 ;; not contain a \| operator at the top level.
957 t (concat "[ \t\n\r\f\v]*\\(" 1235 t (concat (c-lang-const c-simple-ws) "*"
958 "\\(" (c-lang-const c-nonwhite-syntactic-ws) "\\)" 1236 "\\("
959 "[ \t\n\r\f\v]*\\)*")) 1237 (concat "\\(" (c-lang-const c-nonwhite-syntactic-ws) "\\)"
1238 (c-lang-const c-simple-ws) "*")
1239 "\\)*"))
960 1240
961(c-lang-defconst c-syntactic-ws-depth 1241(c-lang-defconst c-syntactic-ws-depth
962 ;; Number of regexp grouping parens in `c-syntactic-ws'. 1242 ;; Number of regexp grouping parens in `c-syntactic-ws'.
963 t (c-regexp-opt-depth (c-lang-const c-syntactic-ws))) 1243 t (regexp-opt-depth (c-lang-const c-syntactic-ws)))
964 1244
965(c-lang-defconst c-nonempty-syntactic-ws 1245(c-lang-defconst c-nonempty-syntactic-ws
966 ;; Regexp matching syntactic whitespace, which is at least one 1246 ;; Regexp matching syntactic whitespace, which is at least one
967 ;; character long. As opposed to `c-(forward|backward)-syntactic-ws', 1247 ;; character long. As opposed to `c-(forward|backward)-syntactic-ws',
968 ;; this doesn't regard cpp directives as syntactic whitespace. Does 1248 ;; this doesn't regard cpp directives as syntactic whitespace. Does
969 ;; not contain a \| operator at the top level. 1249 ;; not contain a \| operator at the top level.
970 t (concat "\\([ \t\n\r\f\v]\\|" 1250 t (concat "\\("
1251 (c-lang-const c-simple-ws)
1252 "\\|"
971 (c-lang-const c-nonwhite-syntactic-ws) 1253 (c-lang-const c-nonwhite-syntactic-ws)
972 "\\)+")) 1254 "\\)+"))
973 1255
974(c-lang-defconst c-nonempty-syntactic-ws-depth 1256(c-lang-defconst c-nonempty-syntactic-ws-depth
975 ;; Number of regexp grouping parens in `c-nonempty-syntactic-ws'. 1257 ;; Number of regexp grouping parens in `c-nonempty-syntactic-ws'.
976 t (c-regexp-opt-depth (c-lang-const c-nonempty-syntactic-ws))) 1258 t (regexp-opt-depth (c-lang-const c-nonempty-syntactic-ws)))
977 1259
978(c-lang-defconst c-single-line-syntactic-ws 1260(c-lang-defconst c-single-line-syntactic-ws
979 ;; Regexp matching syntactic whitespace without any line breaks. As 1261 ;; Regexp matching syntactic whitespace without any line breaks. As
980 ;; opposed to `c-(forward|backward)-syntactic-ws', this doesn't 1262 ;; opposed to `c-(forward|backward)-syntactic-ws', this doesn't
981 ;; regard cpp directives as syntactic whitespace. Does not contain 1263 ;; regard cpp directives as syntactic whitespace. Does not contain
982 ;; a \| operator at the top level. 1264 ;; a \| operator at the top level.
983 t (concat "[ \t]*\\(" 1265 t (if (c-lang-const c-block-comment-regexp)
984 "/\\*\\([^*\n\r]\\|\\*[^/\n\r]\\)*\\*/" ; Block comment 1266 (concat "\\s *\\("
985 "[ \t]*\\)*") 1267 (c-lang-const c-block-comment-regexp)
986 awk ("[ \t]*\\(#.*$\\)?")) 1268 "\\s *\\)*")
1269 "\\s *"))
987 1270
988(c-lang-defconst c-single-line-syntactic-ws-depth 1271(c-lang-defconst c-single-line-syntactic-ws-depth
989 ;; Number of regexp grouping parens in `c-single-line-syntactic-ws'. 1272 ;; Number of regexp grouping parens in `c-single-line-syntactic-ws'.
990 t (c-regexp-opt-depth (c-lang-const c-single-line-syntactic-ws))) 1273 t (regexp-opt-depth (c-lang-const c-single-line-syntactic-ws)))
991 1274
992(c-lang-defvar c-syntactic-eol 1275(c-lang-defconst c-syntactic-eol
993 ;; Regexp that matches when there is no syntactically significant 1276 ;; Regexp that matches when there is no syntactically significant
994 ;; text before eol. Macros are regarded as syntactically 1277 ;; text before eol. Macros are regarded as syntactically
995 ;; significant text here. 1278 ;; significant text here.
996 (concat (concat 1279 t (concat (c-lang-const c-single-line-syntactic-ws)
997 ;; Match horizontal whitespace and block comments that 1280 ;; Match eol (possibly inside a block comment or preceded
998 ;; don't contain newlines. 1281 ;; by a line continuation backslash), or the beginning of a
999 "\\(\\s \\|" 1282 ;; line comment. Note: This has to be modified for awk
1000 (concat "/\\*" 1283 ;; where line comments start with '#'.
1001 "\\([^*\n\r]\\|\\*[^/\n\r]\\)*" 1284 "\\("
1002 "\\*/") 1285 (c-concat-separated
1003 "\\)*") 1286 (list (when (c-lang-const c-line-comment-starter)
1004 (concat 1287 (regexp-quote (c-lang-const c-line-comment-starter)))
1005 ;; Match eol (possibly inside a block comment or preceded 1288 (when (c-lang-const c-unterminated-block-comment-regexp)
1006 ;; by a line continuation backslash), or the beginning of a 1289 (concat (c-lang-const c-unterminated-block-comment-regexp)
1007 ;; line comment. Note: This has to be modified for awk 1290 "$"))
1008 ;; where line comments start with '#'. 1291 "\\\\$"
1009 "\\("
1010 (concat "\\("
1011 "/\\*\\([^*\n\r]\\|\\*[^/\n\r]\\)*"
1012 "\\|"
1013 "\\\\"
1014 "\\)?"
1015 "$") 1292 "$")
1016 "\\|//\\)"))) 1293 "\\|")
1294 "\\)"))
1295(c-lang-defvar c-syntactic-eol (c-lang-const c-syntactic-eol))
1296
1297
1298;;; Syntactic analysis ("virtual semicolons") for line-oriented languages (AWK).
1299(c-lang-defconst c-at-vsemi-p-fn
1300 "Contains a function \"Is there a virtual semicolon at POS or point?\".
1301Such a function takes one optional parameter, a buffer position (defaults to
1302point), and returns NIL or t. This variable contains NIL for languages which
1303don't have EOL terminated statements. "
1304 t nil
1305 awk 'c-awk-at-vsemi-p)
1306(c-lang-defvar c-at-vsemi-p-fn (c-lang-const c-at-vsemi-p-fn))
1307
1308(c-lang-defconst c-vsemi-status-unknown-p-fn
1309 "Contains a function \"are we unsure whether there is a virtual semicolon on this line?\".
1310The (admittedly kludgey) purpose of such a function is to prevent an infinite
1311recursion in c-beginning-of-statement-1 when point starts at a `while' token.
1312The function MUST NOT UNDER ANY CIRCUMSTANCES call c-beginning-of-statement-1,
1313even indirectly. This variable contains NIL for languages which don't have
1314EOL terminated statements."
1315 t nil
1316 awk 'c-awk-vsemi-status-unknown-p)
1317(c-lang-defvar c-vsemi-status-unknown-p-fn
1318 (c-lang-const c-vsemi-status-unknown-p-fn))
1017 1319
1018 1320
1019;;; In-comment text handling. 1321;;; In-comment text handling.
@@ -1137,6 +1439,14 @@ not the type face."
1137(c-lang-defvar c-opt-type-component-key 1439(c-lang-defvar c-opt-type-component-key
1138 (c-lang-const c-opt-type-component-key)) 1440 (c-lang-const c-opt-type-component-key))
1139 1441
1442(c-lang-defconst c-type-start-kwds
1443 ;; All keywords that can start a type (i.e. are either a type prefix
1444 ;; or a complete type).
1445 t (delete-duplicates (append (c-lang-const c-primitive-type-kwds)
1446 (c-lang-const c-type-prefix-kwds)
1447 (c-lang-const c-type-modifier-kwds))
1448 :test 'string-equal))
1449
1140(c-lang-defconst c-class-decl-kwds 1450(c-lang-defconst c-class-decl-kwds
1141 "Keywords introducing declarations where the following block (if any) 1451 "Keywords introducing declarations where the following block (if any)
1142contains another declaration level that should be considered a class. 1452contains another declaration level that should be considered a class.
@@ -1187,14 +1497,26 @@ will be handled."
1187 1497
1188(c-lang-defconst c-other-block-decl-kwds 1498(c-lang-defconst c-other-block-decl-kwds
1189 "Keywords where the following block (if any) contains another 1499 "Keywords where the following block (if any) contains another
1190declaration level that should not be considered a class. 1500declaration level that should not be considered a class. For every
1501keyword here, CC Mode will add a set of special syntactic symbols for
1502those blocks. E.g. if the keyword is \"foo\" then there will be
1503`foo-open', `foo-close', and `infoo' symbols.
1504
1505The intention is that this category should be used for block
1506constructs that aren't related to object orientation concepts like
1507classes (which thus also include e.g. interfaces, templates,
1508contracts, structs, etc). The more pragmatic distinction is that
1509while most want some indentation inside classes, it's fairly common
1510that they don't want it in some of these constructs, so it should be
1511simple to configure that differently from classes. See also
1512`c-class-decl-kwds'.
1191 1513
1192If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', 1514If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
1193`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', 1515`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
1194`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses 1516`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
1195will be handled." 1517will be handled."
1196 t nil 1518 t nil
1197 c '("extern") 1519 (c objc) '("extern")
1198 c++ '("namespace" "extern") 1520 c++ '("namespace" "extern")
1199 idl '("module" 1521 idl '("module"
1200 ;; In CORBA CIDL: 1522 ;; In CORBA CIDL:
@@ -1207,39 +1529,52 @@ will be handled."
1207(c-lang-defvar c-other-decl-block-key (c-lang-const c-other-decl-block-key)) 1529(c-lang-defvar c-other-decl-block-key (c-lang-const c-other-decl-block-key))
1208 1530
1209(c-lang-defconst c-typedef-decl-kwds 1531(c-lang-defconst c-typedef-decl-kwds
1210 "Keywords introducing declarations where the identifiers are defined 1532 "Keywords introducing declarations where the identifier(s) being
1211to be types. 1533declared are types.
1212 1534
1213If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', 1535If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
1214`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', 1536`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
1215`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses 1537`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
1216will be handled." 1538will be handled."
1217 t '("typedef") 1539 ;; Default to `c-class-decl-kwds' and `c-brace-list-decl-kwds'
1218 (java awk) nil) 1540 ;; (since e.g. "Foo" is a type that's being defined in "class Foo
1541 ;; {...}").
1542 t (append (c-lang-const c-class-decl-kwds)
1543 (c-lang-const c-brace-list-decl-kwds))
1544 ;; Languages that have a "typedef" construct.
1545 (c c++ objc idl pike) (append (c-lang-const c-typedef-decl-kwds)
1546 '("typedef"))
1547 ;; Unlike most other languages, exception names are not handled as
1548 ;; types in IDL since they only can occur in "raises" specs.
1549 idl (delete "exception" (append (c-lang-const c-typedef-decl-kwds) nil)))
1219 1550
1220(c-lang-defconst c-typeless-decl-kwds 1551(c-lang-defconst c-typeless-decl-kwds
1221 "Keywords introducing declarations where the identifier (declarator) 1552 "Keywords introducing declarations where the \(first) identifier
1222list follows directly after the keyword, without any type. 1553\(declarator) follows directly after the keyword, without any type.
1223 1554
1224If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', 1555If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
1225`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', 1556`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
1226`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses 1557`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
1227will be handled." 1558will be handled."
1228 t nil 1559 ;; Default to `c-class-decl-kwds' and `c-brace-list-decl-kwds'
1229 ;; Unlike most other languages, exception names are not handled as 1560 ;; (since e.g. "Foo" is the identifier being defined in "class Foo
1230 ;; types in IDL since they only can occur in "raises" specs. 1561 ;; {...}").
1231 idl '("exception" "factory" "finder" "native" 1562 t (append (c-lang-const c-class-decl-kwds)
1232 ;; In CORBA PSDL: 1563 (c-lang-const c-brace-list-decl-kwds))
1233 "key" "stores" 1564 ;; Note: "manages" for CORBA CIDL clashes with its presence on
1234 ;; In CORBA CIDL: 1565 ;; `c-type-list-kwds' for IDL.
1235 ;; Note that "manages" here clashes with its presence on 1566 idl (append (c-lang-const c-typeless-decl-kwds)
1236 ;; `c-type-list-kwds' for IDL. 1567 '("factory" "finder" "native"
1237 "executor" "facet" "manages" "segment") 1568 ;; In CORBA PSDL:
1238 pike '("constant")) 1569 "key" "stores"
1570 ;; In CORBA CIDL:
1571 "facet"))
1572 pike (append (c-lang-const c-class-decl-kwds)
1573 '("constant")))
1239 1574
1240(c-lang-defconst c-modifier-kwds 1575(c-lang-defconst c-modifier-kwds
1241 "Keywords that can prefix normal declarations of identifiers 1576 "Keywords that can prefix normal declarations of identifiers
1242\(and typically acts as flags). Things like argument declarations 1577\(and typically act as flags). Things like argument declarations
1243inside function headers are also considered declarations in this 1578inside function headers are also considered declarations in this
1244sense. 1579sense.
1245 1580
@@ -1270,53 +1605,119 @@ will be handled."
1270 "Keywords that can start or prefix any declaration level construct, 1605 "Keywords that can start or prefix any declaration level construct,
1271besides those on `c-class-decl-kwds', `c-brace-list-decl-kwds', 1606besides those on `c-class-decl-kwds', `c-brace-list-decl-kwds',
1272`c-other-block-decl-kwds', `c-typedef-decl-kwds', 1607`c-other-block-decl-kwds', `c-typedef-decl-kwds',
1273`c-typeless-decl-kwds' and `c-modifier-kwds'. In a declaration, these 1608`c-typeless-decl-kwds' and `c-modifier-kwds'.
1274keywords are also recognized inside or after the identifiers that
1275makes up the type.
1276 1609
1277If any of these also are on `c-type-list-kwds', `c-ref-list-kwds', 1610If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
1278`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds', 1611`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
1279`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses 1612`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
1280will be handled." 1613will be handled."
1281 t nil 1614 t nil
1282 (c c++) '("__declspec") ; MSVC extension.
1283 objc '("@class" "@end" "@defs") 1615 objc '("@class" "@end" "@defs")
1284 java '("import" "package") 1616 java '("import" "package")
1285 pike '("import" "inherit")) 1617 pike '("import" "inherit"))
1286 1618
1619(c-lang-defconst c-decl-start-kwds
1620 "Keywords that always start declarations, wherever they occur.
1621This can be used for declarations that aren't recognized by the normal
1622combination of `c-decl-prefix-re' and `c-decl-start-re'."
1623 t nil
1624 ;; Classes can be declared anywhere in a Pike expression.
1625 pike '("class"))
1626
1627(c-lang-defconst c-decl-hangon-kwds
1628 "Keywords that can occur anywhere in a declaration level construct.
1629This is used for self-contained things that can be tacked on anywhere
1630on a declaration and that should be ignored to be able to recognize it
1631correctly. Typical cases are compiler extensions like
1632\"__attribute__\" or \"__declspec\":
1633
1634 __declspec(noreturn) void foo();
1635 class __declspec(dllexport) classname {...};
1636 void foo() __attribute__((noreturn));
1637
1638Note that unrecognized plain symbols are skipped anyway if they occur
1639before the type, so such things are not necessary to mention here.
1640Mentioning them here is necessary only if they can occur in other
1641places, or if they are followed by a construct that must be skipped
1642over \(like the parens in the \"__attribute__\" and \"__declspec\"
1643examples above). In the last case, they alse need to be present on
1644one of `c-type-list-kwds', `c-ref-list-kwds',
1645`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
1646`c-<>-type-kwds', or `c-<>-arglist-kwds'."
1647 ;; NB: These are currently not recognized in all parts of a
1648 ;; declaration. Specifically, they aren't recognized in the middle
1649 ;; of multi-token types, inside declarators, and between the
1650 ;; identifier and the arglist paren of a function declaration.
1651 ;;
1652 ;; FIXME: This ought to be user customizable since compiler stuff
1653 ;; like this usually is wrapped in project specific macros. (It'd
1654 ;; of course be even better if we could cope without knowing this.)
1655 t nil
1656 (c c++) '(;; GCC extension.
1657 "__attribute__"
1658 ;; MSVC extension.
1659 "__declspec"))
1660
1661(c-lang-defconst c-decl-hangon-key
1662 ;; Adorned regexp matching `c-decl-hangon-kwds'.
1663 t (c-make-keywords-re t (c-lang-const c-decl-hangon-kwds)))
1664(c-lang-defvar c-decl-hangon-key (c-lang-const c-decl-hangon-key))
1665
1666(c-lang-defconst c-prefix-spec-kwds
1667 ;; All keywords that can occur in the preamble of a declaration.
1668 ;; They typically occur before the type, but they are also matched
1669 ;; after presumptive types since we often can't be sure that
1670 ;; something is a type or just some sort of macro in front of the
1671 ;; declaration. They might be ambiguous with types or type
1672 ;; prefixes.
1673 t (delete-duplicates (append (c-lang-const c-class-decl-kwds)
1674 (c-lang-const c-brace-list-decl-kwds)
1675 (c-lang-const c-other-block-decl-kwds)
1676 (c-lang-const c-typedef-decl-kwds)
1677 (c-lang-const c-typeless-decl-kwds)
1678 (c-lang-const c-modifier-kwds)
1679 (c-lang-const c-other-decl-kwds)
1680 (c-lang-const c-decl-start-kwds)
1681 (c-lang-const c-decl-hangon-kwds))
1682 :test 'string-equal))
1683
1684(c-lang-defconst c-prefix-spec-kwds-re
1685 ;; Adorned regexp of `c-prefix-spec-kwds'.
1686 t (c-make-keywords-re t (c-lang-const c-prefix-spec-kwds)))
1687(c-lang-defvar c-prefix-spec-kwds-re (c-lang-const c-prefix-spec-kwds-re))
1688
1287(c-lang-defconst c-specifier-key 1689(c-lang-defconst c-specifier-key
1288 ;; Adorned regexp matching keywords that can start a declaration but 1690 ;; Adorned regexp of the keywords in `c-prefix-spec-kwds' that
1289 ;; not a type. 1691 ;; aren't ambiguous with types or type prefixes.
1290 t (c-make-keywords-re t 1692 t (c-make-keywords-re t
1291 (set-difference (append (c-lang-const c-class-decl-kwds) 1693 (set-difference (c-lang-const c-prefix-spec-kwds)
1292 (c-lang-const c-brace-list-decl-kwds) 1694 (c-lang-const c-type-start-kwds)
1293 (c-lang-const c-other-block-decl-kwds)
1294 (c-lang-const c-typedef-decl-kwds)
1295 (c-lang-const c-typeless-decl-kwds)
1296 (c-lang-const c-modifier-kwds)
1297 (c-lang-const c-other-decl-kwds))
1298 (append (c-lang-const c-primitive-type-kwds)
1299 (c-lang-const c-type-prefix-kwds)
1300 (c-lang-const c-type-modifier-kwds))
1301 :test 'string-equal))) 1695 :test 'string-equal)))
1302(c-lang-defvar c-specifier-key (c-lang-const c-specifier-key)) 1696(c-lang-defvar c-specifier-key (c-lang-const c-specifier-key))
1303 1697
1698(c-lang-defconst c-postfix-spec-kwds
1699 ;; Keywords that can occur after argument list of a function header
1700 ;; declaration, i.e. in the "K&R region".
1701 t (append (c-lang-const c-postfix-decl-spec-kwds)
1702 (c-lang-const c-decl-hangon-kwds)))
1703
1704(c-lang-defconst c-not-decl-init-keywords
1705 ;; Adorned regexp matching all keywords that can't appear at the
1706 ;; start of a declaration.
1707 t (c-make-keywords-re t
1708 (set-difference (c-lang-const c-keywords)
1709 (append (c-lang-const c-type-start-kwds)
1710 (c-lang-const c-prefix-spec-kwds))
1711 :test 'string-equal)))
1712(c-lang-defvar c-not-decl-init-keywords
1713 (c-lang-const c-not-decl-init-keywords))
1714
1304(c-lang-defconst c-protection-kwds 1715(c-lang-defconst c-protection-kwds
1305 "Protection label keywords in classes." 1716 "Access protection label keywords in classes."
1306 t nil 1717 t nil
1307 c++ '("private" "protected" "public") 1718 c++ '("private" "protected" "public")
1308 objc '("@private" "@protected" "@public")) 1719 objc '("@private" "@protected" "@public"))
1309 1720
1310(c-lang-defconst c-opt-access-key
1311 ;; Regexp matching an access protection label in a class, or nil in
1312 ;; languages that don't have such things.
1313 t (if (c-lang-const c-protection-kwds)
1314 (c-make-keywords-re t (c-lang-const c-protection-kwds)))
1315 c++ (concat "\\("
1316 (c-make-keywords-re nil (c-lang-const c-protection-kwds))
1317 "\\)[ \t\n\r\f\v]*:"))
1318(c-lang-defvar c-opt-access-key (c-lang-const c-opt-access-key))
1319
1320(c-lang-defconst c-block-decls-with-vars 1721(c-lang-defconst c-block-decls-with-vars
1321 "Keywords introducing declarations that can contain a block which 1722 "Keywords introducing declarations that can contain a block which
1322might be followed by variable declarations, e.g. like \"foo\" in 1723might be followed by variable declarations, e.g. like \"foo\" in
@@ -1342,7 +1743,6 @@ The keywords on list are assumed to also be present on one of the
1342between the header and the body \(i.e. the \"K&R-region\") in 1743between the header and the body \(i.e. the \"K&R-region\") in
1343declarations." 1744declarations."
1344 t nil 1745 t nil
1345 (c c++) '("__attribute__") ; GCC extension.
1346 java '("extends" "implements" "throws") 1746 java '("extends" "implements" "throws")
1347 idl '("context" "getraises" "manages" "primarykey" "raises" "setraises" 1747 idl '("context" "getraises" "manages" "primarykey" "raises" "setraises"
1348 "supports" 1748 "supports"
@@ -1366,22 +1766,18 @@ reason to put keywords on this list if they are on `c-type-prefix-kwds'.
1366There's also no reason to add keywords that prefixes a normal 1766There's also no reason to add keywords that prefixes a normal
1367declaration consisting of a type followed by a declarator (list), so 1767declaration consisting of a type followed by a declarator (list), so
1368the keywords on `c-modifier-kwds' should normally not be listed here 1768the keywords on `c-modifier-kwds' should normally not be listed here
1369too. 1769either.
1370 1770
1371Note: Use `c-typeless-decl-kwds' for keywords followed by a function 1771Note: Use `c-typeless-decl-kwds' for keywords followed by a function
1372or variable identifier (that's being defined)." 1772or variable identifier (that's being defined)."
1373 t '("struct" "union" "enum") 1773 t nil
1374 (c awk) nil
1375 c++ '("operator") 1774 c++ '("operator")
1376 objc (append '("@class" "@interface" "@implementation" "@protocol") 1775 objc '("@class")
1377 (c-lang-const c-type-list-kwds)) 1776 java '("import" "new" "extends" "implements" "throws")
1378 java '("class" "import" "interface" "new" "extends" "implements" "throws") 1777 idl '("manages" "native" "primarykey" "supports"
1379 idl (append '("component" "eventtype" "home" "interface" "manages" "native" 1778 ;; In CORBA PSDL:
1380 "primarykey" "supports" "valuetype" 1779 "as" "implements" "of" "scope")
1381 ;; In CORBA PSDL: 1780 pike '("inherit"))
1382 "as" "implements" "of" "scope" "storagehome" "storagetype")
1383 (c-lang-const c-type-list-kwds))
1384 pike '("class" "enum" "inherit"))
1385 1781
1386(c-lang-defconst c-ref-list-kwds 1782(c-lang-defconst c-ref-list-kwds
1387 "Keywords that may be followed by a comma separated list of 1783 "Keywords that may be followed by a comma separated list of
@@ -1414,9 +1810,8 @@ special case when the list can contain only one element.)"
1414(c-lang-defconst c-colon-type-list-re 1810(c-lang-defconst c-colon-type-list-re
1415 "Regexp matched after the keywords in `c-colon-type-list-kwds' to skip 1811 "Regexp matched after the keywords in `c-colon-type-list-kwds' to skip
1416forward to the colon. The end of the match is assumed to be directly 1812forward to the colon. The end of the match is assumed to be directly
1417after the colon, so the regexp should end with \":\" although that 1813after the colon, so the regexp should end with \":\". Must be a
1418isn't necessary. Must be a regexp if `c-colon-type-list-kwds' isn't 1814regexp if `c-colon-type-list-kwds' isn't nil."
1419nil."
1420 t (if (c-lang-const c-colon-type-list-kwds) 1815 t (if (c-lang-const c-colon-type-list-kwds)
1421 ;; Disallow various common punctuation chars that can't come 1816 ;; Disallow various common punctuation chars that can't come
1422 ;; before the ":" that starts the inherit list after "class" 1817 ;; before the ":" that starts the inherit list after "class"
@@ -1429,7 +1824,10 @@ nil."
1429 "Keywords that may be followed by a parenthesis expression that doesn't 1824 "Keywords that may be followed by a parenthesis expression that doesn't
1430contain type identifiers." 1825contain type identifiers."
1431 t nil 1826 t nil
1432 (c c++) '("__declspec")) ; MSVC extension. 1827 (c c++) '(;; GCC extension.
1828 "__attribute__"
1829 ;; MSVC extension.
1830 "__declspec"))
1433 1831
1434(c-lang-defconst c-paren-type-kwds 1832(c-lang-defconst c-paren-type-kwds
1435 "Keywords that may be followed by a parenthesis expression containing 1833 "Keywords that may be followed by a parenthesis expression containing
@@ -1512,6 +1910,12 @@ identifiers that follows the type in a normal declaration."
1512 t (c-make-keywords-re t (c-lang-const c-block-stmt-2-kwds))) 1910 t (c-make-keywords-re t (c-lang-const c-block-stmt-2-kwds)))
1513(c-lang-defvar c-block-stmt-2-key (c-lang-const c-block-stmt-2-key)) 1911(c-lang-defvar c-block-stmt-2-key (c-lang-const c-block-stmt-2-key))
1514 1912
1913(c-lang-defconst c-block-stmt-kwds
1914 ;; Union of `c-block-stmt-1-kwds' and `c-block-stmt-2-kwds'.
1915 t (delete-duplicates (append (c-lang-const c-block-stmt-1-kwds)
1916 (c-lang-const c-block-stmt-2-kwds))
1917 :test 'string-equal))
1918
1515(c-lang-defconst c-opt-block-stmt-key 1919(c-lang-defconst c-opt-block-stmt-key
1516 ;; Regexp matching the start of any statement that has a 1920 ;; Regexp matching the start of any statement that has a
1517 ;; substatement (except a bare block). Nil in languages that 1921 ;; substatement (except a bare block). Nil in languages that
@@ -1563,10 +1967,15 @@ nevertheless contains a list separated with ';' and not ','."
1563(c-lang-defvar c-opt-asm-stmt-key (c-lang-const c-opt-asm-stmt-key)) 1967(c-lang-defvar c-opt-asm-stmt-key (c-lang-const c-opt-asm-stmt-key))
1564 1968
1565(c-lang-defconst c-label-kwds 1969(c-lang-defconst c-label-kwds
1566 "Keywords introducing labels in blocks." 1970 "Keywords introducing colon terminated labels in blocks."
1567 t '("case" "default") 1971 t '("case" "default")
1568 awk nil) 1972 awk nil)
1569 1973
1974(c-lang-defconst c-label-kwds-regexp
1975 ;; Adorned regexp matching any keyword that introduces a label.
1976 t (c-make-keywords-re t (c-lang-const c-label-kwds)))
1977(c-lang-defvar c-label-kwds-regexp (c-lang-const c-label-kwds-regexp))
1978
1570(c-lang-defconst c-before-label-kwds 1979(c-lang-defconst c-before-label-kwds
1571 "Keywords that might be followed by a label identifier." 1980 "Keywords that might be followed by a label identifier."
1572 t '("goto") 1981 t '("goto")
@@ -1575,11 +1984,6 @@ nevertheless contains a list separated with ';' and not ','."
1575 idl nil 1984 idl nil
1576 awk nil) 1985 awk nil)
1577 1986
1578(c-lang-defconst c-label-kwds-regexp
1579 ;; Regexp matching any keyword that introduces a label.
1580 t (c-make-keywords-re t (c-lang-const c-label-kwds)))
1581(c-lang-defvar c-label-kwds-regexp (c-lang-const c-label-kwds-regexp))
1582
1583(c-lang-defconst c-constant-kwds 1987(c-lang-defconst c-constant-kwds
1584 "Keywords for constants." 1988 "Keywords for constants."
1585 t nil 1989 t nil
@@ -1602,11 +2006,9 @@ nevertheless contains a list separated with ';' and not ','."
1602 ;; `c-primary-expr-kwds' and all keyword operators in `c-operators'. 2006 ;; `c-primary-expr-kwds' and all keyword operators in `c-operators'.
1603 t (delete-duplicates 2007 t (delete-duplicates
1604 (append (c-lang-const c-primary-expr-kwds) 2008 (append (c-lang-const c-primary-expr-kwds)
1605 (c-with-syntax-table (c-lang-const c-mode-syntax-table) 2009 (c-filter-ops (c-lang-const c-operator-list)
1606 (mapcan (lambda (op) 2010 t
1607 (and (string-match "\\`\\(\\w\\|\\s_\\)+\\'" op) 2011 "\\`\\(\\w\\|\\s_\\)+\\'"))
1608 (list op)))
1609 (c-lang-const c-operator-list))))
1610 :test 'string-equal)) 2012 :test 'string-equal))
1611 2013
1612(c-lang-defconst c-lambda-kwds 2014(c-lang-defconst c-lambda-kwds
@@ -1615,40 +2017,19 @@ expressions."
1615 t nil 2017 t nil
1616 pike '("lambda")) 2018 pike '("lambda"))
1617 2019
1618(c-lang-defconst c-opt-lambda-key
1619 ;; Adorned regexp matching the start of lambda constructs, or nil in
1620 ;; languages that don't have such things.
1621 t (and (c-lang-const c-lambda-kwds)
1622 (c-make-keywords-re t (c-lang-const c-lambda-kwds))))
1623(c-lang-defvar c-opt-lambda-key (c-lang-const c-opt-lambda-key))
1624
1625(c-lang-defconst c-inexpr-block-kwds 2020(c-lang-defconst c-inexpr-block-kwds
1626 "Keywords that start constructs followed by statement blocks which can 2021 "Keywords that start constructs followed by statement blocks which can
1627be used in expressions \(the gcc extension for this in C and C++ is 2022be used in expressions \(the gcc extension for this in C and C++ is
1628handled separately)." 2023handled separately by `c-recognize-paren-inexpr-blocks')."
1629 t nil 2024 t nil
1630 pike '("catch" "gauge")) 2025 pike '("catch" "gauge"))
1631 2026
1632(c-lang-defconst c-opt-inexpr-block-key
1633 ;; Regexp matching the start of in-expression statements, or nil in
1634 ;; languages that don't have such things.
1635 t nil
1636 pike (c-make-keywords-re t (c-lang-const c-inexpr-block-kwds)))
1637(c-lang-defvar c-opt-inexpr-block-key (c-lang-const c-opt-inexpr-block-key))
1638
1639(c-lang-defconst c-inexpr-class-kwds 2027(c-lang-defconst c-inexpr-class-kwds
1640 "Keywords that can start classes inside expressions." 2028 "Keywords that can start classes inside expressions."
1641 t nil 2029 t nil
1642 java '("new") 2030 java '("new")
1643 pike '("class")) 2031 pike '("class"))
1644 2032
1645(c-lang-defconst c-opt-inexpr-class-key
1646 ;; Regexp matching the start of a class in an expression, or nil in
1647 ;; languages that don't have such things.
1648 t (and (c-lang-const c-inexpr-class-kwds)
1649 (c-make-keywords-re t (c-lang-const c-inexpr-class-kwds))))
1650(c-lang-defvar c-opt-inexpr-class-key (c-lang-const c-opt-inexpr-class-key))
1651
1652(c-lang-defconst c-inexpr-brace-list-kwds 2033(c-lang-defconst c-inexpr-brace-list-kwds
1653 "Keywords that can start brace list blocks inside expressions. 2034 "Keywords that can start brace list blocks inside expressions.
1654Note that Java specific rules are currently applied to tell this from 2035Note that Java specific rules are currently applied to tell this from
@@ -1665,30 +2046,26 @@ Note that Java specific rules are currently applied to tell this from
1665(c-lang-defvar c-opt-inexpr-brace-list-key 2046(c-lang-defvar c-opt-inexpr-brace-list-key
1666 (c-lang-const c-opt-inexpr-brace-list-key)) 2047 (c-lang-const c-opt-inexpr-brace-list-key))
1667 2048
1668(c-lang-defconst c-any-class-key
1669 ;; Regexp matching the start of any class, both at top level and in
1670 ;; expressions.
1671 t (c-make-keywords-re t
1672 (append (c-lang-const c-class-decl-kwds)
1673 (c-lang-const c-inexpr-class-kwds))))
1674(c-lang-defvar c-any-class-key (c-lang-const c-any-class-key))
1675
1676(c-lang-defconst c-decl-block-key 2049(c-lang-defconst c-decl-block-key
1677 ;; Regexp matching the start of any declaration-level block that 2050 ;; Regexp matching keywords in any construct that contain another
1678 ;; contain another declaration level, i.e. that isn't a function 2051 ;; declaration level, i.e. that isn't followed by a function block
1679 ;; block or brace list. 2052 ;; or brace list. When the first submatch matches, it's an
1680 t (c-make-keywords-re t 2053 ;; unambiguous construct, otherwise it's an ambiguous match that
1681 (append (c-lang-const c-class-decl-kwds) 2054 ;; might also be the return type of a function declaration.
1682 (c-lang-const c-other-block-decl-kwds) 2055 t (let* ((decl-kwds (append (c-lang-const c-class-decl-kwds)
1683 (c-lang-const c-inexpr-class-kwds))) 2056 (c-lang-const c-other-block-decl-kwds)
1684 ;; In Pike modifiers might be followed by a block 2057 (c-lang-const c-inexpr-class-kwds)))
1685 ;; to apply to several declarations. 2058 (unambiguous (set-difference decl-kwds
1686 pike (concat (c-lang-const c-decl-block-key) 2059 (c-lang-const c-type-start-kwds)
1687 "\\|" 2060 :test 'string-equal))
1688 "\\(" (c-make-keywords-re nil 2061 (ambiguous (intersection decl-kwds
1689 (c-lang-const c-modifier-kwds)) "\\)" 2062 (c-lang-const c-type-start-kwds)
1690 (c-lang-const c-syntactic-ws) 2063 :test 'string-equal)))
1691 "{")) 2064 (if ambiguous
2065 (concat (c-make-keywords-re t unambiguous)
2066 "\\|"
2067 (c-make-keywords-re t ambiguous))
2068 (c-make-keywords-re t unambiguous))))
1692(c-lang-defvar c-decl-block-key (c-lang-const c-decl-block-key)) 2069(c-lang-defvar c-decl-block-key (c-lang-const c-decl-block-key))
1693 2070
1694(c-lang-defconst c-bitfield-kwds 2071(c-lang-defconst c-bitfield-kwds
@@ -1794,7 +2171,7 @@ Note that Java specific rules are currently applied to tell this from
1794 alist (cdr alist)) 2171 alist (cdr alist))
1795 (setplist (intern kwd obarray) 2172 (setplist (intern kwd obarray)
1796 ;; Emacs has an odd bug that causes `mapcan' to fail 2173 ;; Emacs has an odd bug that causes `mapcan' to fail
1797 ;; with unintelligible errors. (XEmacs >= 20 works.) 2174 ;; with unintelligible errors. (XEmacs works.)
1798 ;;(mapcan (lambda (lang-const) 2175 ;;(mapcan (lambda (lang-const)
1799 ;; (list lang-const t)) 2176 ;; (list lang-const t))
1800 ;; lang-const-list) 2177 ;; lang-const-list)
@@ -1804,8 +2181,8 @@ Note that Java specific rules are currently applied to tell this from
1804 obarray)) 2181 obarray))
1805 2182
1806(c-lang-defconst c-regular-keywords-regexp 2183(c-lang-defconst c-regular-keywords-regexp
1807 ;; Adorned regexp matching all keywords that aren't types or 2184 ;; Adorned regexp matching all keywords that should be fontified
1808 ;; constants. 2185 ;; with the keywords face. I.e. that aren't types or constants.
1809 t (c-make-keywords-re t 2186 t (c-make-keywords-re t
1810 (set-difference (c-lang-const c-keywords) 2187 (set-difference (c-lang-const c-keywords)
1811 (append (c-lang-const c-primitive-type-kwds) 2188 (append (c-lang-const c-primitive-type-kwds)
@@ -1814,25 +2191,6 @@ Note that Java specific rules are currently applied to tell this from
1814(c-lang-defvar c-regular-keywords-regexp 2191(c-lang-defvar c-regular-keywords-regexp
1815 (c-lang-const c-regular-keywords-regexp)) 2192 (c-lang-const c-regular-keywords-regexp))
1816 2193
1817(c-lang-defconst c-not-decl-init-keywords
1818 ;; Adorned regexp matching all keywords that can't appear at the
1819 ;; start of a declaration.
1820 t (c-make-keywords-re t
1821 (set-difference (c-lang-const c-keywords)
1822 (append (c-lang-const c-primitive-type-kwds)
1823 (c-lang-const c-type-prefix-kwds)
1824 (c-lang-const c-type-modifier-kwds)
1825 (c-lang-const c-class-decl-kwds)
1826 (c-lang-const c-brace-list-decl-kwds)
1827 (c-lang-const c-other-block-decl-kwds)
1828 (c-lang-const c-typedef-decl-kwds)
1829 (c-lang-const c-typeless-decl-kwds)
1830 (c-lang-const c-modifier-kwds)
1831 (c-lang-const c-other-decl-kwds))
1832 :test 'string-equal)))
1833(c-lang-defvar c-not-decl-init-keywords
1834 (c-lang-const c-not-decl-init-keywords))
1835
1836(c-lang-defconst c-primary-expr-regexp 2194(c-lang-defconst c-primary-expr-regexp
1837 ;; Regexp matching the start of any primary expression, i.e. any 2195 ;; Regexp matching the start of any primary expression, i.e. any
1838 ;; literal, symbol, prefix operator, and '('. It doesn't need to 2196 ;; literal, symbol, prefix operator, and '('. It doesn't need to
@@ -1842,92 +2200,108 @@ Note that Java specific rules are currently applied to tell this from
1842 ;; be a match of e.g. an infix operator. (The case with ambiguous 2200 ;; be a match of e.g. an infix operator. (The case with ambiguous
1843 ;; keyword operators isn't handled.) 2201 ;; keyword operators isn't handled.)
1844 2202
1845 t (c-with-syntax-table (c-lang-const c-mode-syntax-table) 2203 t (let* ((prefix-ops
1846 (let* ((prefix-ops 2204 (c-filter-ops (c-lang-const c-operators)
1847 (mapcan (lambda (op) 2205 '(prefix)
1848 ;; Filter out the special case prefix 2206 (lambda (op)
1849 ;; operators that are close parens. 2207 ;; Filter out the special case prefix
1850 (unless (string-match "\\s\)" op) 2208 ;; operators that are close parens.
1851 (list op))) 2209 (not (string-match "\\s)" op)))))
1852 (mapcan 2210
1853 (lambda (opclass) 2211 (nonkeyword-prefix-ops
1854 (when (eq (car opclass) 'prefix) 2212 (c-filter-ops prefix-ops
1855 (append (cdr opclass) nil))) 2213 t
1856 (c-lang-const c-operators)))) 2214 "\\`\\(\\s.\\|\\s(\\|\\s)\\)+\\'"))
1857 2215
1858 (nonkeyword-prefix-ops 2216 (in-or-postfix-ops
1859 (mapcan (lambda (op) 2217 (c-filter-ops (c-lang-const c-operators)
1860 (unless (string-match "\\`\\(\\w\\|\\s_\\)+\\'" op) 2218 '(postfix
1861 (list op))) 2219 postfix-if-paren
1862 prefix-ops)) 2220 left-assoc
1863 2221 right-assoc
1864 (in-or-postfix-ops 2222 right-assoc-sequence)
1865 (mapcan (lambda (opclass) 2223 t))
1866 (when (memq (car opclass) 2224
1867 '(postfix 2225 (unambiguous-prefix-ops (set-difference nonkeyword-prefix-ops
1868 left-assoc 2226 in-or-postfix-ops
1869 right-assoc 2227 :test 'string-equal))
1870 right-assoc-sequence)) 2228 (ambiguous-prefix-ops (intersection nonkeyword-prefix-ops
1871 (append (cdr opclass) nil))) 2229 in-or-postfix-ops
1872 (c-lang-const c-operators))) 2230 :test 'string-equal)))
1873 2231
1874 (unambiguous-prefix-ops (set-difference nonkeyword-prefix-ops 2232 (concat
1875 in-or-postfix-ops 2233 "\\("
1876 :test 'string-equal)) 2234 ;; Take out all symbol class operators from `prefix-ops' and make the
1877 (ambiguous-prefix-ops (intersection nonkeyword-prefix-ops 2235 ;; first submatch from them together with `c-primary-expr-kwds'.
1878 in-or-postfix-ops 2236 (c-make-keywords-re t
1879 :test 'string-equal))) 2237 (append (c-lang-const c-primary-expr-kwds)
1880 2238 (set-difference prefix-ops nonkeyword-prefix-ops
1881 (concat 2239 :test 'string-equal)))
1882 "\\(" 2240
1883 ;; Take out all symbol class operators from `prefix-ops' and make the 2241 "\\|"
1884 ;; first submatch from them together with `c-primary-expr-kwds'. 2242 ;; Match all ambiguous operators.
1885 (c-make-keywords-re t 2243 (c-make-keywords-re nil
1886 (append (c-lang-const c-primary-expr-kwds) 2244 (intersection nonkeyword-prefix-ops in-or-postfix-ops
1887 (set-difference prefix-ops nonkeyword-prefix-ops 2245 :test 'string-equal))
1888 :test 'string-equal))) 2246 "\\)"
1889
1890 "\\|"
1891 ;; Match all ambiguous operators.
1892 (c-make-keywords-re nil
1893 (intersection nonkeyword-prefix-ops in-or-postfix-ops
1894 :test 'string-equal))
1895 "\\)"
1896 2247
1897 "\\|" 2248 "\\|"
1898 ;; Now match all other symbols. 2249 ;; Now match all other symbols.
1899 (c-lang-const c-symbol-start) 2250 (c-lang-const c-symbol-start)
1900 2251
1901 "\\|" 2252 "\\|"
1902 ;; The chars that can start integer and floating point 2253 ;; The chars that can start integer and floating point
1903 ;; constants. 2254 ;; constants.
1904 "\\.?[0-9]" 2255 "\\.?[0-9]"
1905 2256
1906 "\\|" 2257 "\\|"
1907 ;; The nonambiguous operators from `prefix-ops'. 2258 ;; The nonambiguous operators from `prefix-ops'.
1908 (c-make-keywords-re nil 2259 (c-make-keywords-re nil
1909 (set-difference nonkeyword-prefix-ops in-or-postfix-ops 2260 (set-difference nonkeyword-prefix-ops in-or-postfix-ops
1910 :test 'string-equal)) 2261 :test 'string-equal))
1911 2262
1912 "\\|" 2263 "\\|"
1913 ;; Match string and character literals. 2264 ;; Match string and character literals.
1914 "\\s\"" 2265 "\\s\""
1915 (if (memq 'gen-string-delim c-emacs-features) 2266 (if (memq 'gen-string-delim c-emacs-features)
1916 "\\|\\s|" 2267 "\\|\\s|"
1917 ""))))) 2268 ""))))
1918(c-lang-defvar c-primary-expr-regexp (c-lang-const c-primary-expr-regexp)) 2269(c-lang-defvar c-primary-expr-regexp (c-lang-const c-primary-expr-regexp))
1919 2270
1920 2271
1921;;; Additional constants for parser-level constructs. 2272;;; Additional constants for parser-level constructs.
1922 2273
1923(c-lang-defconst c-decl-prefix-re 2274(c-lang-defconst c-decl-prefix-re
1924 "Regexp matching something that might precede a declaration or a cast, 2275 "Regexp matching something that might precede a declaration, cast or
1925such as the last token of a preceding statement or declaration. It 2276label, such as the last token of a preceding statement or declaration.
1926should not match bob, though. It can't require a match longer than 2277This is used in the common situation where a declaration or cast
1927one token. The end of the token is taken to be at the end of the 2278doesn't start with any specific token that can be searched for.
1928first submatch. It must not include any following whitespace. It's 2279
1929undefined whether identifier syntax (see `c-identifier-syntax-table') 2280The regexp should not match bob; that is done implicitly. It can't
1930is in effect or not." 2281require a match longer than one token. The end of the token is taken
2282to be at the end of the first submatch, which is assumed to always
2283match. It's undefined whether identifier syntax (see
2284`c-identifier-syntax-table') is in effect or not. This regexp is
2285assumed to be a superset of `c-label-prefix-re' if
2286`c-recognize-colon-labels' is set.
2287
2288Besides this, `c-decl-start-kwds' is used to find declarations.
2289
2290Note: This variable together with `c-decl-start-re' and
2291`c-decl-start-kwds' is only used to detect \"likely\"
2292declaration/cast/label starts. I.e. they might produce more matches
2293but should not miss anything (or else it's necessary to use text
2294properties - see the next note). Wherever they match, the following
2295construct is analyzed to see if it indeed is a declaration, cast or
2296label. That analysis is not cheap, so it's important that not too
2297many false matches are triggered.
2298
2299Note: If a declaration/cast/label start can't be detected with this
2300variable, it's necessary to use the `c-type' text property with the
2301value `c-decl-end' on the last char of the last token preceding the
2302declaration. See the comment blurb at the start of cc-engine.el for
2303more info."
2304
1931 ;; We match a sequence of characters to skip over things like \"};\" 2305 ;; We match a sequence of characters to skip over things like \"};\"
1932 ;; more quickly. We match ")" in C for K&R region declarations, and 2306 ;; more quickly. We match ")" in C for K&R region declarations, and
1933 ;; in all languages except Java for when a cpp macro definition 2307 ;; in all languages except Java for when a cpp macro definition
@@ -1937,12 +2311,7 @@ is in effect or not."
1937 ;; Match "<" in C++ to get the first argument in a template arglist. 2311 ;; Match "<" in C++ to get the first argument in a template arglist.
1938 ;; In that case there's an additional check in `c-find-decl-spots' 2312 ;; In that case there's an additional check in `c-find-decl-spots'
1939 ;; that it got open paren syntax. 2313 ;; that it got open paren syntax.
1940 ;; 2314 c++ "\\([\{\}\(\);,<]+\\)"
1941 ;; Also match a single ":" for protection labels. We cheat a little
1942 ;; and require a symbol immediately before to avoid false matches
1943 ;; when starting directly on a single ":", which can be the start of
1944 ;; the base class initializer list in a constructor.
1945 c++ "\\([\{\}\(\);,<]+\\|\\(\\w\\|\\s_\\):\\)\\([^:]\\|\\'\\)"
1946 ;; Additionally match the protection directives in Objective-C. 2315 ;; Additionally match the protection directives in Objective-C.
1947 ;; Note that this doesn't cope with the longer directives, which we 2316 ;; Note that this doesn't cope with the longer directives, which we
1948 ;; would have to match from start to end since they don't end with 2317 ;; would have to match from start to end since they don't end with
@@ -1950,37 +2319,135 @@ is in effect or not."
1950 objc (concat "\\([\{\}\(\);,]+\\|" 2319 objc (concat "\\([\{\}\(\);,]+\\|"
1951 (c-make-keywords-re nil (c-lang-const c-protection-kwds)) 2320 (c-make-keywords-re nil (c-lang-const c-protection-kwds))
1952 "\\)") 2321 "\\)")
1953 ;; Match ":" for switch labels inside union declarations in IDL.
1954 idl "\\([\{\}\(\);:,]+\\)\\([^:]\\|\\'\\)"
1955 ;; Pike is like C but we also match "[" for multiple value 2322 ;; Pike is like C but we also match "[" for multiple value
1956 ;; assignments and type casts. 2323 ;; assignments and type casts.
1957 pike "\\([\{\}\(\)\[;,]+\\)") 2324 pike "\\([\{\}\(\)\[;,]+\\)")
1958(c-lang-defvar c-decl-prefix-re (c-lang-const c-decl-prefix-re) 2325(c-lang-defvar c-decl-prefix-re (c-lang-const c-decl-prefix-re)
1959 'dont-doc) 2326 'dont-doc)
1960 2327
2328(c-lang-defconst c-decl-start-re
2329 "Regexp matching the start of any declaration, cast or label.
2330It's used on the token after the one `c-decl-prefix-re' matched. This
2331regexp should not try to match those constructs accurately as it's
2332only used as a sieve to avoid spending more time checking other
2333constructs."
2334 t (c-lang-const c-identifier-start))
2335(c-lang-defvar c-decl-start-re (c-lang-const c-decl-start-re))
2336
2337(c-lang-defconst c-decl-prefix-or-start-re
2338 ;; Regexp matching something that might precede or start a
2339 ;; declaration, cast or label.
2340 ;;
2341 ;; If the first submatch matches, it's taken to match the end of a
2342 ;; token that might precede such a construct, e.g. ';', '}' or '{'.
2343 ;; It's built from `c-decl-prefix-re'.
2344 ;;
2345 ;; If the first submatch did not match, the match of the whole
2346 ;; regexp is taken to be at the first token in the declaration.
2347 ;; `c-decl-start-re' is not checked in this case.
2348 ;;
2349 ;; Design note: The reason the same regexp is used to match both
2350 ;; tokens that precede declarations and start them is to avoid an
2351 ;; extra regexp search from the previous declaration spot in
2352 ;; `c-find-decl-spots'. Users of `c-find-decl-spots' also count on
2353 ;; that it finds all declaration/cast/label starts in approximately
2354 ;; linear order, so we can't do the searches in two separate passes.
2355 t (if (c-lang-const c-decl-start-kwds)
2356 (concat (c-lang-const c-decl-prefix-re)
2357 "\\|"
2358 (c-make-keywords-re t (c-lang-const c-decl-start-kwds)))
2359 (c-lang-const c-decl-prefix-re)))
2360(c-lang-defvar c-decl-prefix-or-start-re
2361 (c-lang-const c-decl-prefix-or-start-re)
2362 'dont-doc)
2363
1961(c-lang-defconst c-cast-parens 2364(c-lang-defconst c-cast-parens
1962 ;; List containing the paren characters that can open a cast, or nil in 2365 ;; List containing the paren characters that can open a cast, or nil in
1963 ;; languages without casts. 2366 ;; languages without casts.
1964 t (c-with-syntax-table (c-lang-const c-mode-syntax-table) 2367 t (c-filter-ops (c-lang-const c-operators)
1965 (mapcan (lambda (opclass) 2368 '(prefix)
1966 (when (eq (car opclass) 'prefix) 2369 "\\`\\s\(\\'"
1967 (mapcan (lambda (op) 2370 (lambda (op) (elt op 0))))
1968 (when (string-match "\\`\\s\(\\'" op)
1969 (list (elt op 0))))
1970 (cdr opclass))))
1971 (c-lang-const c-operators))))
1972(c-lang-defvar c-cast-parens (c-lang-const c-cast-parens)) 2371(c-lang-defvar c-cast-parens (c-lang-const c-cast-parens))
1973 2372
2373(c-lang-defconst c-block-prefix-disallowed-chars
2374 "List of syntactically relevant characters that never can occur before
2375the open brace in any construct that contains a brace block, e.g. in
2376the \"class Foo: public Bar\" part of:
2377
2378 class Foo: public Bar {int x();} a, *b;
2379
2380If parens can occur, the chars inside those aren't filtered with this
2381list.
2382
2383'<' and '>' should be disallowed even if angle bracket arglists can
2384occur. That since the search function needs to stop at them anyway to
2385ensure they are given paren syntax.
2386
2387This is used to skip backward from the open brace to find the region
2388in which to look for a construct like \"class\", \"enum\",
2389\"namespace\" or whatever. That skipping should be as tight as
2390possible for good performance."
2391
2392 ;; Default to all chars that only occurs in nonsymbol tokens outside
2393 ;; identifiers.
2394 t (set-difference
2395 (c-lang-const c-nonsymbol-token-char-list)
2396 (c-filter-ops (append (c-lang-const c-identifier-ops)
2397 (list (cons nil
2398 (c-lang-const c-after-id-concat-ops))))
2399 t
2400 t
2401 (lambda (op)
2402 (let ((pos 0) res)
2403 (while (string-match "\\(\\s.\\|\\s(\\|\\s)\\)"
2404 op pos)
2405 (setq res (cons (aref op (match-beginning 1)) res)
2406 pos (match-end 0)))
2407 res))))
2408
2409 ;; Allow cpp operatios (where applicable).
2410 t (if (c-lang-const c-opt-cpp-prefix)
2411 (set-difference (c-lang-const c-block-prefix-disallowed-chars)
2412 '(?#))
2413 (c-lang-const c-block-prefix-disallowed-chars))
2414
2415 ;; Allow ':' for inherit list starters.
2416 (c++ objc idl) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
2417 '(?:))
2418
2419 ;; Allow ',' for multiple inherits.
2420 (c++ java) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
2421 '(?,))
2422
2423 ;; Allow parentheses for anonymous inner classes in Java and class
2424 ;; initializer lists in Pike.
2425 (java pike) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
2426 '(?\( ?\)))
2427
2428 ;; Allow '"' for extern clauses (e.g. extern "C" {...}).
2429 (c c++ objc) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
2430 '(?\" ?')))
2431
2432(c-lang-defconst c-block-prefix-charset
2433 ;; `c-block-prefix-disallowed-chars' as an inverted charset suitable
2434 ;; for `c-syntactic-skip-backward'.
2435 t (c-make-bare-char-alt (c-lang-const c-block-prefix-disallowed-chars) t))
2436(c-lang-defvar c-block-prefix-charset (c-lang-const c-block-prefix-charset))
2437
1974(c-lang-defconst c-type-decl-prefix-key 2438(c-lang-defconst c-type-decl-prefix-key
1975 "Regexp matching the operators that might precede the identifier in a 2439 "Regexp matching the declarator operators that might precede the
1976declaration, e.g. the \"*\" in \"char *argv\". This regexp should 2440identifier in a declaration, e.g. the \"*\" in \"char *argv\". This
1977match \"(\" if parentheses are valid in type declarations. The end of 2441regexp should match \"(\" if parentheses are valid in declarators.
1978the first submatch is taken as the end of the operator. Identifier 2442The end of the first submatch is taken as the end of the operator.
1979syntax is in effect when this is matched (see `c-identifier-syntax-table')." 2443Identifier syntax is in effect when this is matched \(see
2444`c-identifier-syntax-table')."
1980 t (if (c-lang-const c-type-modifier-kwds) 2445 t (if (c-lang-const c-type-modifier-kwds)
1981 (concat (c-regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>") 2446 (concat (regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>")
1982 ;; Default to a regexp that never matches. 2447 ;; Default to a regexp that never matches.
1983 "\\<\\>") 2448 "\\<\\>")
2449 ;; Check that there's no "=" afterwards to avoid matching tokens
2450 ;; like "*=".
1984 (c objc) (concat "\\(" 2451 (c objc) (concat "\\("
1985 "[*\(]" 2452 "[*\(]"
1986 "\\|" 2453 "\\|"
@@ -2001,14 +2468,14 @@ syntax is in effect when this is matched (see `c-identifier-syntax-table')."
2001 (c-lang-const c-type-decl-prefix-key) 2468 (c-lang-const c-type-decl-prefix-key)
2002 "\\)" 2469 "\\)"
2003 "\\([^=]\\|$\\)") 2470 "\\([^=]\\|$\\)")
2004 pike "\\([*\(!~]\\)\\([^=]\\|$\\)") 2471 pike "\\(\\*\\)\\([^=]\\|$\\)")
2005(c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key) 2472(c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key)
2006 'dont-doc) 2473 'dont-doc)
2007 2474
2008(c-lang-defconst c-type-decl-suffix-key 2475(c-lang-defconst c-type-decl-suffix-key
2009 "Regexp matching the operators that might follow after the identifier 2476 "Regexp matching the declarator operators that might follow after the
2010in a declaration, e.g. the \"[\" in \"char argv[]\". This regexp 2477identifier in a declaration, e.g. the \"[\" in \"char argv[]\". This
2011should match \")\" if parentheses are valid in type declarations. If 2478regexp should match \")\" if parentheses are valid in declarators. If
2012it matches an open paren of some kind, the type declaration check 2479it matches an open paren of some kind, the type declaration check
2013continues at the corresponding close paren, otherwise the end of the 2480continues at the corresponding close paren, otherwise the end of the
2014first submatch is taken as the end of the operator. Identifier syntax 2481first submatch is taken as the end of the operator. Identifier syntax
@@ -2017,24 +2484,28 @@ is in effect when this is matched (see `c-identifier-syntax-table')."
2017 ;; function argument list parenthesis. 2484 ;; function argument list parenthesis.
2018 t (if (c-lang-const c-type-modifier-kwds) 2485 t (if (c-lang-const c-type-modifier-kwds)
2019 (concat "\\(\(\\|" 2486 (concat "\\(\(\\|"
2020 (c-regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>" 2487 (regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>"
2021 "\\)") 2488 "\\)")
2022 "\\(\(\\)") 2489 "\\(\(\\)")
2023 (c c++ objc) (concat 2490 (c c++ objc) (concat
2024 "\\(" 2491 "\\("
2025 "[\)\[\(]" 2492 "[\)\[\(]"
2026 "\\|" 2493 (if (c-lang-const c-type-modifier-kwds)
2027 ;; "throw" in `c-type-modifier-kwds' is followed by a 2494 (concat
2028 ;; parenthesis list, but no extra measures are 2495 "\\|"
2029 ;; necessary to handle that. 2496 ;; "throw" in `c-type-modifier-kwds' is followed
2030 (c-regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>" 2497 ;; by a parenthesis list, but no extra measures
2498 ;; are necessary to handle that.
2499 (regexp-opt (c-lang-const c-type-modifier-kwds) t)
2500 "\\>")
2501 "")
2031 "\\)") 2502 "\\)")
2032 (java idl) "\\([\[\(]\\)") 2503 (java idl) "\\([\[\(]\\)")
2033(c-lang-defvar c-type-decl-suffix-key (c-lang-const c-type-decl-suffix-key) 2504(c-lang-defvar c-type-decl-suffix-key (c-lang-const c-type-decl-suffix-key)
2034 'dont-doc) 2505 'dont-doc)
2035 2506
2036(c-lang-defconst c-after-suffixed-type-decl-key 2507(c-lang-defconst c-after-suffixed-type-decl-key
2037 "This regexp is matched after a type declaration expression where 2508 "This regexp is matched after a declarator expression where
2038`c-type-decl-suffix-key' has matched. If it matches then the 2509`c-type-decl-suffix-key' has matched. If it matches then the
2039construct is taken as a declaration. It's typically used to match the 2510construct is taken as a declaration. It's typically used to match the
2040beginning of a function body or whatever might occur after the 2511beginning of a function body or whatever might occur after the
@@ -2052,11 +2523,11 @@ not \",\" or \";\"."
2052 ;; could however produce false matches on code like "FOO(bar) x" 2523 ;; could however produce false matches on code like "FOO(bar) x"
2053 ;; where FOO is a cpp macro, so it's better to leave it out and rely 2524 ;; where FOO is a cpp macro, so it's better to leave it out and rely
2054 ;; on the other heuristics in that case. 2525 ;; on the other heuristics in that case.
2055 t (if (c-lang-const c-postfix-decl-spec-kwds) 2526 t (if (c-lang-const c-postfix-spec-kwds)
2056 ;; Add on the keywords in `c-postfix-decl-spec-kwds'. 2527 ;; Add on the keywords in `c-postfix-spec-kwds'.
2057 (concat (c-lang-const c-after-suffixed-type-decl-key) 2528 (concat (c-lang-const c-after-suffixed-type-decl-key)
2058 "\\|" 2529 "\\|"
2059 (c-make-keywords-re t (c-lang-const c-postfix-decl-spec-kwds))) 2530 (c-make-keywords-re t (c-lang-const c-postfix-spec-kwds)))
2060 (c-lang-const c-after-suffixed-type-decl-key)) 2531 (c-lang-const c-after-suffixed-type-decl-key))
2061 ;; Also match the colon that starts a base class initializer list in 2532 ;; Also match the colon that starts a base class initializer list in
2062 ;; C++. That can be confused with a function call before the colon 2533 ;; C++. That can be confused with a function call before the colon
@@ -2096,7 +2567,7 @@ It's undefined whether identifier syntax (see `c-identifier-syntax-table')
2096is in effect or not." 2567is in effect or not."
2097 t nil 2568 t nil
2098 (c c++ objc pike) "\\(\\.\\.\\.\\)" 2569 (c c++ objc pike) "\\(\\.\\.\\.\\)"
2099 java "\\(\\[[ \t\n\r\f\v]*\\]\\)") 2570 java (concat "\\(\\[" (c-lang-const c-simple-ws) "*\\]\\)"))
2100(c-lang-defvar c-opt-type-suffix-key (c-lang-const c-opt-type-suffix-key)) 2571(c-lang-defvar c-opt-type-suffix-key (c-lang-const c-opt-type-suffix-key))
2101 2572
2102(c-lang-defvar c-known-type-key 2573(c-lang-defvar c-known-type-key
@@ -2105,13 +2576,26 @@ is in effect or not."
2105 ;; submatch is the one that matches the type. Note that this regexp 2576 ;; submatch is the one that matches the type. Note that this regexp
2106 ;; assumes that symbol constituents like '_' and '$' have word 2577 ;; assumes that symbol constituents like '_' and '$' have word
2107 ;; syntax. 2578 ;; syntax.
2108 (let ((extra-types (when (boundp (c-mode-symbol "font-lock-extra-types")) 2579 (let* ((extra-types
2109 (c-mode-var "font-lock-extra-types")))) 2580 (when (boundp (c-mode-symbol "font-lock-extra-types"))
2581 (c-mode-var "font-lock-extra-types")))
2582 (regexp-strings
2583 (mapcan (lambda (re)
2584 (when (string-match "[][.*+?^$\\]" re)
2585 (list re)))
2586 extra-types))
2587 (plain-strings
2588 (mapcan (lambda (re)
2589 (unless (string-match "[][.*+?^$\\]" re)
2590 (list re)))
2591 extra-types)))
2110 (concat "\\<\\(" 2592 (concat "\\<\\("
2111 (c-make-keywords-re nil (c-lang-const c-primitive-type-kwds)) 2593 (c-concat-separated
2112 (if (consp extra-types) 2594 (append (list (c-make-keywords-re nil
2113 (concat "\\|" (mapconcat 'identity extra-types "\\|")) 2595 (append (c-lang-const c-primitive-type-kwds)
2114 "") 2596 plain-strings)))
2597 regexp-strings)
2598 "\\|")
2115 "\\)\\>"))) 2599 "\\)\\>")))
2116 2600
2117(c-lang-defconst c-special-brace-lists 2601(c-lang-defconst c-special-brace-lists
@@ -2163,6 +2647,14 @@ Foo bar = gnu;"
2163 c++ t) 2647 c++ t)
2164(c-lang-defvar c-recognize-paren-inits (c-lang-const c-recognize-paren-inits)) 2648(c-lang-defvar c-recognize-paren-inits (c-lang-const c-recognize-paren-inits))
2165 2649
2650(c-lang-defconst c-recognize-paren-inexpr-blocks
2651 "Non-nil to recognize gcc style in-expression blocks,
2652i.e. compound statements surrounded by parentheses inside expressions."
2653 t nil
2654 (c c++) t)
2655(c-lang-defvar c-recognize-paren-inexpr-blocks
2656 (c-lang-const c-recognize-paren-inexpr-blocks))
2657
2166(c-lang-defconst c-opt-<>-arglist-start 2658(c-lang-defconst c-opt-<>-arglist-start
2167 ;; Regexp matching the start of angle bracket arglists in languages 2659 ;; Regexp matching the start of angle bracket arglists in languages
2168 ;; where `c-recognize-<>-arglists' is set. Does not exclude 2660 ;; where `c-recognize-<>-arglists' is set. Does not exclude
@@ -2188,52 +2680,117 @@ Foo bar = gnu;"
2188(c-lang-defvar c-opt-<>-arglist-start-in-paren 2680(c-lang-defvar c-opt-<>-arglist-start-in-paren
2189 (c-lang-const c-opt-<>-arglist-start-in-paren)) 2681 (c-lang-const c-opt-<>-arglist-start-in-paren))
2190 2682
2191(c-lang-defconst c-label-key
2192 "Regexp matching a normal label, i.e. a label that doesn't begin with
2193a keyword like switch labels. It's only used at the beginning of a
2194statement."
2195 t "\\<\\>"
2196 (c c++ objc java pike) (concat "\\(" (c-lang-const c-symbol-key) "\\)"
2197 "[ \t\n\r\f\v]*:\\([^:]\\|$\\)"))
2198(c-lang-defvar c-label-key (c-lang-const c-label-key)
2199 'dont-doc)
2200
2201(c-lang-defconst c-opt-postfix-decl-spec-key 2683(c-lang-defconst c-opt-postfix-decl-spec-key
2202 ;; Regexp matching the beginning of a declaration specifier in the 2684 ;; Regexp matching the beginning of a declaration specifier in the
2203 ;; region between the header and the body of a declaration. 2685 ;; region between the header and the body of a declaration.
2204 ;; 2686 ;;
2205 ;; TODO: This is currently not used uniformly; c++-mode and 2687 ;; TODO: This is currently not used uniformly; c++-mode and
2206 ;; java-mode each have their own ways of using it. 2688 ;; java-mode each have their own ways of using it.
2207 t nil 2689 t nil
2208 c++ (concat ":?[ \t\n\r\f\v]*\\(virtual[ \t\n\r\f\v]+\\)?\\(" 2690 c++ (concat ":?"
2209 (c-make-keywords-re nil (c-lang-const c-protection-kwds)) 2691 (c-lang-const c-simple-ws) "*"
2210 "\\)[ \t\n\r\f\v]+" 2692 "\\(virtual" (c-lang-const c-simple-ws) "+\\)?\\("
2211 "\\(" (c-lang-const c-symbol-key) "\\)") 2693 (c-make-keywords-re nil (c-lang-const c-protection-kwds))
2212 java (c-make-keywords-re t (c-lang-const c-postfix-decl-spec-kwds))) 2694 "\\)" (c-lang-const c-simple-ws) "+"
2695 "\\(" (c-lang-const c-symbol-key) "\\)")
2696 java (c-make-keywords-re t (c-lang-const c-postfix-spec-kwds)))
2213(c-lang-defvar c-opt-postfix-decl-spec-key 2697(c-lang-defvar c-opt-postfix-decl-spec-key
2214 (c-lang-const c-opt-postfix-decl-spec-key)) 2698 (c-lang-const c-opt-postfix-decl-spec-key))
2215 2699
2700(c-lang-defconst c-recognize-colon-labels
2701 "Non-nil if generic labels ending with \":\" should be recognized.
2702That includes labels in code and access keys in classes. This does
2703not apply to labels recognized by `c-label-kwds' and
2704`c-opt-extra-label-key'."
2705 t nil
2706 (c c++ objc java pike) t)
2707(c-lang-defvar c-recognize-colon-labels
2708 (c-lang-const c-recognize-colon-labels))
2709
2710(c-lang-defconst c-label-prefix-re
2711 "Regexp like `c-decl-prefix-re' that matches any token that can precede
2712a generic colon label. Not used if `c-recognize-colon-labels' is
2713nil."
2714 t "\\([{};]+\\)")
2715(c-lang-defvar c-label-prefix-re
2716 (c-lang-const c-label-prefix-re))
2717
2718(c-lang-defconst c-nonlabel-token-key
2719 "Regexp matching things that can't occur in generic colon labels,
2720neither in a statement nor in a declaration context. The regexp is
2721tested at the beginning of every sexp in a suspected label,
2722i.e. before \":\". Only used if `c-recognize-colon-labels' is set."
2723 t (concat
2724 ;; Don't allow string literals.
2725 "[\"']\\|"
2726 ;; All keywords except `c-label-kwds' and `c-protection-kwds'.
2727 (c-make-keywords-re t
2728 (set-difference (c-lang-const c-keywords)
2729 (append (c-lang-const c-label-kwds)
2730 (c-lang-const c-protection-kwds))
2731 :test 'string-equal)))
2732 ;; Also check for open parens in C++, to catch member init lists in
2733 ;; constructors. We normally allow it so that macros with arguments
2734 ;; work in labels.
2735 c++ (concat "\\s\(\\|" (c-lang-const c-nonlabel-token-key)))
2736(c-lang-defvar c-nonlabel-token-key (c-lang-const c-nonlabel-token-key))
2737
2738(c-lang-defconst c-opt-extra-label-key
2739 "Optional regexp matching labels.
2740Normally, labels are detected according to `c-nonlabel-token-key',
2741`c-decl-prefix-re' and `c-nonlabel-decl-prefix-re'. This regexp can
2742be used if there are additional labels that aren't recognized that
2743way."
2744 t nil
2745 objc (c-make-keywords-re t (c-lang-const c-protection-kwds)))
2746(c-lang-defvar c-opt-extra-label-key (c-lang-const c-opt-extra-label-key))
2747
2216(c-lang-defconst c-opt-friend-key 2748(c-lang-defconst c-opt-friend-key
2217 ;; Regexp describing friend declarations classes, or nil in 2749 ;; Regexp describing friend declarations classes, or nil in
2218 ;; languages that don't have such things. 2750 ;; languages that don't have such things.
2219 ;; 2751 ;;
2220 ;; TODO: Ought to use `c-specifier-key' or similar, and the template 2752 ;; TODO: Ought to use `c-prefix-spec-kwds-re' or similar, and the
2221 ;; skipping isn't done properly. This will disappear soon. 2753 ;; template skipping isn't done properly. This will disappear soon.
2222 t nil 2754 t nil
2223 c++ "friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+") 2755 c++ (concat "friend" (c-lang-const c-simple-ws) "+"
2756 "\\|"
2757 (concat "template"
2758 (c-lang-const c-simple-ws) "*"
2759 "<.+>"
2760 (c-lang-const c-simple-ws) "*"
2761 "friend"
2762 (c-lang-const c-simple-ws) "+")))
2224(c-lang-defvar c-opt-friend-key (c-lang-const c-opt-friend-key)) 2763(c-lang-defvar c-opt-friend-key (c-lang-const c-opt-friend-key))
2225 2764
2226(c-lang-defconst c-opt-method-key 2765(c-lang-defconst c-opt-method-key
2227 ;; Special regexp to match the start of Objective-C methods. The 2766 ;; Special regexp to match the start of Objective-C methods. The
2228 ;; first submatch is assumed to end after the + or - key. 2767 ;; first submatch is assumed to end after the + or - key.
2229 t nil 2768 t nil
2230 objc (concat 2769 objc (concat
2231 ;; TODO: Ought to use a better method than anchoring on bol. 2770 ;; TODO: Ought to use a better method than anchoring on bol.
2232 "^[ \t]*\\([+-]\\)[ \t\n\r\f\v]*" 2771 "^\\s *"
2233 "\\(([^)]*)[ \t\n\r\f\v]*\\)?" ; return type 2772 "\\([+-]\\)"
2773 (c-lang-const c-simple-ws) "*"
2774 (concat "\\(" ; Return type.
2775 "([^\)]*)"
2776 (c-lang-const c-simple-ws) "*"
2777 "\\)?")
2234 "\\(" (c-lang-const c-symbol-key) "\\)")) 2778 "\\(" (c-lang-const c-symbol-key) "\\)"))
2235(c-lang-defvar c-opt-method-key (c-lang-const c-opt-method-key)) 2779(c-lang-defvar c-opt-method-key (c-lang-const c-opt-method-key))
2236 2780
2781(c-lang-defconst c-type-decl-end-used
2782 ;; Must be set in buffers where the `c-type' text property might be
2783 ;; used with the value `c-decl-end'.
2784 ;;
2785 ;; `c-decl-end' is used to mark the ends of labels and access keys
2786 ;; to make interactive refontification work better.
2787 t (or (c-lang-const c-recognize-colon-labels)
2788 (and (c-lang-const c-label-kwds) t))
2789 ;; `c-decl-end' is used to mark the end of the @-style directives in
2790 ;; Objective-C.
2791 objc t)
2792(c-lang-defvar c-type-decl-end-used (c-lang-const c-type-decl-end-used))
2793
2237 2794
2238;;; Wrap up the `c-lang-defvar' system. 2795;;; Wrap up the `c-lang-defvar' system.
2239 2796
@@ -2249,9 +2806,7 @@ for the given mode.
2249This function should be evaluated at compile time, so that the 2806This function should be evaluated at compile time, so that the
2250function it returns is byte compiled with all the evaluated results 2807function it returns is byte compiled with all the evaluated results
2251from the language constants. Use the `c-init-language-vars' macro to 2808from the language constants. Use the `c-init-language-vars' macro to
2252accomplish that conveniently. 2809accomplish that conveniently."
2253
2254This function does not do any hidden buffer changes."
2255 2810
2256 (if (and (not load-in-progress) 2811 (if (and (not load-in-progress)
2257 (boundp 'byte-compile-dest-file) 2812 (boundp 'byte-compile-dest-file)
@@ -2282,12 +2837,14 @@ This function does not do any hidden buffer changes."
2282 (elt init 1)))) 2837 (elt init 1))))
2283 (cdr c-lang-variable-inits)))) 2838 (cdr c-lang-variable-inits))))
2284 2839
2285 (unless (get ',mode 'c-has-warned-lang-consts) 2840 ;; This diagnostic message isn't useful for end
2286 (message ,(concat "%s compiled with CC Mode %s " 2841 ;; users, so it's disabled.
2287 "but loaded with %s - evaluating " 2842 ;;(unless (get ',mode 'c-has-warned-lang-consts)
2288 "language constants from source") 2843 ;; (message ,(concat "%s compiled with CC Mode %s "
2289 ',mode ,c-version c-version) 2844 ;; "but loaded with %s - evaluating "
2290 (put ',mode 'c-has-warned-lang-consts t)) 2845 ;; "language constants from source")
2846 ;; ',mode ,c-version c-version)
2847 ;; (put ',mode 'c-has-warned-lang-consts t))
2291 2848
2292 (require 'cc-langs) 2849 (require 'cc-langs)
2293 (let ((init (cdr c-lang-variable-inits))) 2850 (let ((init (cdr c-lang-variable-inits)))
@@ -2328,9 +2885,7 @@ This function does not do any hidden buffer changes."
2328 "Initialize all the language dependent variables for the given mode. 2885 "Initialize all the language dependent variables for the given mode.
2329This macro is expanded at compile time to a form tailored for the mode 2886This macro is expanded at compile time to a form tailored for the mode
2330in question, so MODE must be a constant. Therefore MODE is not 2887in question, so MODE must be a constant. Therefore MODE is not
2331evaluated and should not be quoted. 2888evaluated and should not be quoted."
2332
2333This macro does not do any hidden buffer changes."
2334 `(funcall ,(c-make-init-lang-vars-fun mode))) 2889 `(funcall ,(c-make-init-lang-vars-fun mode)))
2335 2890
2336 2891
diff --git a/lisp/progmodes/cc-menus.el b/lisp/progmodes/cc-menus.el
index 6de4aa8c79c..e11f50c581b 100644
--- a/lisp/progmodes/cc-menus.el
+++ b/lisp/progmodes/cc-menus.el
@@ -1,6 +1,7 @@
1;;; cc-menus.el --- imenu support for CC Mode 1;;; cc-menus.el --- imenu support for CC Mode
2 2
3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation,
4;; Inc.
4 5
5;; Authors: 1998- Martin Stjernholm 6;; Authors: 1998- Martin Stjernholm
6;; 1992-1999 Barry A. Warsaw 7;; 1992-1999 Barry A. Warsaw
@@ -24,7 +25,7 @@
24;; GNU General Public License for more details. 25;; GNU General Public License for more details.
25 26
26;; You should have received a copy of the GNU General Public License 27;; You should have received a copy of the GNU General Public License
27;; along with GNU Emacs; see the file COPYING. If not, write to 28;; along with this program; see the file COPYING. If not, write to
28;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 29;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29;; Boston, MA 02110-1301, USA. 30;; Boston, MA 02110-1301, USA.
30 31
@@ -240,7 +241,6 @@ Example:
240- perform: (SEL)aSelector withObject: object1 withObject: object2; /* METHOD */ 241- perform: (SEL)aSelector withObject: object1 withObject: object2; /* METHOD */
241=> 242=>
242-perform:withObject:withObject:withObject: /* selector */" 243-perform:withObject:withObject:withObject: /* selector */"
243 ;; This function does not do any hidden buffer changes.
244 (let ((return "") ; String to be returned 244 (let ((return "") ; String to be returned
245 (p 0) ; Current scanning position in METHOD 245 (p 0) ; Current scanning position in METHOD
246 (pmax (length method)) ; 246 (pmax (length method)) ;
@@ -281,7 +281,6 @@ Example:
281 281
282(defun cc-imenu-objc-remove-white-space (str) 282(defun cc-imenu-objc-remove-white-space (str)
283 "Remove all spaces and tabs from STR." 283 "Remove all spaces and tabs from STR."
284 ;; This function does not do any hidden buffer changes.
285 (let ((return "") 284 (let ((return "")
286 (p 0) 285 (p 0)
287 (max (length str)) 286 (max (length str))
@@ -296,7 +295,6 @@ Example:
296 295
297(defun cc-imenu-objc-function () 296(defun cc-imenu-objc-function ()
298 "imenu supports for objc-mode." 297 "imenu supports for objc-mode."
299 ;; This function does not do any hidden buffer changes.
300 (let (methodlist 298 (let (methodlist
301 clist 299 clist
302 ;; 300 ;;
@@ -415,7 +413,6 @@ Example:
415 413
416(defun cc-imenu-init (mode-generic-expression 414(defun cc-imenu-init (mode-generic-expression
417 &optional mode-create-index-function) 415 &optional mode-create-index-function)
418 ;; This function does not do any hidden buffer changes.
419 (setq imenu-generic-expression mode-generic-expression 416 (setq imenu-generic-expression mode-generic-expression
420 imenu-case-fold-search nil) 417 imenu-case-fold-search nil)
421 (when mode-create-index-function 418 (when mode-create-index-function
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 63c6aad3aa1..247a4021abf 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1,6 +1,7 @@
1;;; cc-mode.el --- major mode for editing C and similar languages 1;;; cc-mode.el --- major mode for editing C and similar languages
2 2
3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation,
4;; Inc.
4 5
5;; Authors: 2003- Alan Mackenzie 6;; Authors: 2003- Alan Mackenzie
6;; 1998- Martin Stjernholm 7;; 1998- Martin Stjernholm
@@ -92,10 +93,9 @@
92(cc-require 'cc-menus) 93(cc-require 'cc-menus)
93 94
94;; Silence the compiler. 95;; Silence the compiler.
95(cc-bytecomp-defvar comment-line-break-function) ; (X)Emacs 20+ 96(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
96(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs 20+
97(cc-bytecomp-defun set-keymap-parents) ; XEmacs 97(cc-bytecomp-defun set-keymap-parents) ; XEmacs
98(cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1+ 98(cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1
99(cc-bytecomp-obsolete-fun make-local-hook) ; Marked obsolete in Emacs 21.1. 99(cc-bytecomp-obsolete-fun make-local-hook) ; Marked obsolete in Emacs 21.1.
100 100
101;; We set these variables during mode init, yet we don't require 101;; We set these variables during mode init, yet we don't require
@@ -107,6 +107,11 @@
107;; with your version of Emacs, you are incompatible! 107;; with your version of Emacs, you are incompatible!
108(cc-external-require 'easymenu) 108(cc-external-require 'easymenu)
109 109
110;; Autoload directive for emacsen that doesn't have an older CC Mode
111;; version in the dist.
112(autoload 'c-subword-mode "cc-subword"
113 "Mode enabling subword movement and editing keys." t)
114
110;; Load cc-fonts first after font-lock is loaded, since it isn't 115;; Load cc-fonts first after font-lock is loaded, since it isn't
111;; necessary until font locking is requested. 116;; necessary until font locking is requested.
112(eval-after-load "font-lock" 117(eval-after-load "font-lock"
@@ -153,7 +158,6 @@ directly supported by CC Mode. This can be used instead of the
153`c-init-language-vars' macro if the language you want to use is one of 158`c-init-language-vars' macro if the language you want to use is one of
154those, rather than a derived language defined through the language 159those, rather than a derived language defined through the language
155variable system (see \"cc-langs.el\")." 160variable system (see \"cc-langs.el\")."
156 ;; This function does not do any hidden buffer changes.
157 (cond ((eq mode 'c-mode) (c-init-language-vars c-mode)) 161 (cond ((eq mode 'c-mode) (c-init-language-vars c-mode))
158 ((eq mode 'c++-mode) (c-init-language-vars c++-mode)) 162 ((eq mode 'c++-mode) (c-init-language-vars c++-mode))
159 ((eq mode 'objc-mode) (c-init-language-vars objc-mode)) 163 ((eq mode 'objc-mode) (c-init-language-vars objc-mode))
@@ -171,8 +175,6 @@ initialization to run CC Mode for the C language is done. Otherwise
171only some basic setup is done, and a call to `c-init-language-vars' or 175only some basic setup is done, and a call to `c-init-language-vars' or
172`c-init-language-vars-for' is necessary too (which gives more 176`c-init-language-vars-for' is necessary too (which gives more
173control). See \"cc-mode.el\" for more info." 177control). See \"cc-mode.el\" for more info."
174 ;;
175 ;; This function does not do any hidden buffer changes.
176 178
177 (setq c-buffer-is-cc-mode t) 179 (setq c-buffer-is-cc-mode t)
178 180
@@ -220,7 +222,7 @@ control). See \"cc-mode.el\" for more info."
220(defun c-define-abbrev-table (name defs) 222(defun c-define-abbrev-table (name defs)
221 ;; Compatibility wrapper for `define-abbrev' which passes a non-nil 223 ;; Compatibility wrapper for `define-abbrev' which passes a non-nil
222 ;; sixth argument for SYSTEM-FLAG in emacsen that support it 224 ;; sixth argument for SYSTEM-FLAG in emacsen that support it
223 ;; (currently only Emacs 21.2). 225 ;; (currently only Emacs >= 21.2).
224 (let ((table (or (symbol-value name) 226 (let ((table (or (symbol-value name)
225 (progn (define-abbrev-table name nil) 227 (progn (define-abbrev-table name nil)
226 (symbol-value name))))) 228 (symbol-value name)))))
@@ -232,20 +234,25 @@ control). See \"cc-mode.el\" for more info."
232 (setq defs (cdr defs))))) 234 (setq defs (cdr defs)))))
233(put 'c-define-abbrev-table 'lisp-indent-function 1) 235(put 'c-define-abbrev-table 'lisp-indent-function 1)
234 236
237(defun c-bind-special-erase-keys ()
238 ;; Only used in Emacs to bind C-c C-<delete> and C-c C-<backspace>
239 ;; to the proper keys depending on `normal-erase-is-backspace'.
240 (if normal-erase-is-backspace
241 (progn
242 (define-key c-mode-base-map (kbd "C-c C-<delete>")
243 'c-hungry-delete-forward)
244 (define-key c-mode-base-map (kbd "C-c C-<backspace>")
245 'c-hungry-backspace))
246 (define-key c-mode-base-map (kbd "C-c C-<delete>")
247 'c-hungry-backspace)
248 (define-key c-mode-base-map (kbd "C-c C-<backspace>")
249 'c-hungry-delete-forward)))
250
235(if c-mode-base-map 251(if c-mode-base-map
236 nil 252 nil
237 ;; TBD: should we even worry about naming this keymap. My vote: no, 253
238 ;; because Emacs and XEmacs do it differently.
239 (setq c-mode-base-map (make-sparse-keymap)) 254 (setq c-mode-base-map (make-sparse-keymap))
240 ;; put standard keybindings into MAP 255
241 ;; the following mappings correspond more or less directly to BOCM
242 (define-key c-mode-base-map "{" 'c-electric-brace)
243 (define-key c-mode-base-map "}" 'c-electric-brace)
244 (define-key c-mode-base-map ";" 'c-electric-semi&comma)
245 (define-key c-mode-base-map "#" 'c-electric-pound)
246 (define-key c-mode-base-map ":" 'c-electric-colon)
247 (define-key c-mode-base-map "(" 'c-electric-paren)
248 (define-key c-mode-base-map ")" 'c-electric-paren)
249 ;; Separate M-BS from C-M-h. The former should remain 256 ;; Separate M-BS from C-M-h. The former should remain
250 ;; backward-kill-word. 257 ;; backward-kill-word.
251 (define-key c-mode-base-map [(control meta h)] 'c-mark-function) 258 (define-key c-mode-base-map [(control meta h)] 'c-mark-function)
@@ -259,21 +266,23 @@ control). See \"cc-mode.el\" for more info."
259 (substitute-key-definition 'indent-new-comment-line 266 (substitute-key-definition 'indent-new-comment-line
260 'c-indent-new-comment-line 267 'c-indent-new-comment-line
261 c-mode-base-map global-map) 268 c-mode-base-map global-map)
269 (substitute-key-definition 'indent-for-tab-command
270 'c-indent-command
271 c-mode-base-map global-map)
262 (when (fboundp 'comment-indent-new-line) 272 (when (fboundp 'comment-indent-new-line)
263 ;; indent-new-comment-line has changed name to 273 ;; indent-new-comment-line has changed name to
264 ;; comment-indent-new-line in Emacs 21. 274 ;; comment-indent-new-line in Emacs 21.
265 (substitute-key-definition 'comment-indent-new-line 275 (substitute-key-definition 'comment-indent-new-line
266 'c-indent-new-comment-line 276 'c-indent-new-comment-line
267 c-mode-base-map global-map)) 277 c-mode-base-map global-map))
278
268 ;; RMS says don't make these the default. 279 ;; RMS says don't make these the default.
269;; (define-key c-mode-base-map "\e\C-a" 'c-beginning-of-defun) 280;; (define-key c-mode-base-map "\e\C-a" 'c-beginning-of-defun)
270;; (define-key c-mode-base-map "\e\C-e" 'c-end-of-defun) 281;; (define-key c-mode-base-map "\e\C-e" 'c-end-of-defun)
282
271 (define-key c-mode-base-map "\C-c\C-n" 'c-forward-conditional) 283 (define-key c-mode-base-map "\C-c\C-n" 'c-forward-conditional)
272 (define-key c-mode-base-map "\C-c\C-p" 'c-backward-conditional) 284 (define-key c-mode-base-map "\C-c\C-p" 'c-backward-conditional)
273 (define-key c-mode-base-map "\C-c\C-u" 'c-up-conditional) 285 (define-key c-mode-base-map "\C-c\C-u" 'c-up-conditional)
274 (substitute-key-definition 'indent-for-tab-command
275 'c-indent-command
276 c-mode-base-map global-map)
277 286
278 ;; It doesn't suffice to put `c-fill-paragraph' on 287 ;; It doesn't suffice to put `c-fill-paragraph' on
279 ;; `fill-paragraph-function' since `c-fill-paragraph' must be called 288 ;; `fill-paragraph-function' since `c-fill-paragraph' must be called
@@ -290,34 +299,74 @@ control). See \"cc-mode.el\" for more info."
290 (substitute-key-definition 'fill-paragraph-or-region 'c-fill-paragraph 299 (substitute-key-definition 'fill-paragraph-or-region 'c-fill-paragraph
291 c-mode-base-map global-map) 300 c-mode-base-map global-map)
292 301
302 ;; We bind the forward deletion key and (implicitly) C-d to
303 ;; `c-electric-delete-forward', and the backward deletion key to
304 ;; `c-electric-backspace'. The hungry variants are bound to the
305 ;; same keys but prefixed with C-c. This implies that C-c C-d is
306 ;; `c-hungry-delete-forward'. For consistency, we bind not only C-c
307 ;; <backspace> to `c-hungry-backspace' but also C-c C-<backspace>,
308 ;; so that the Ctrl key can be held down during the whole sequence
309 ;; regardless of the direction. This in turn implies that we bind
310 ;; C-c C-<delete> to `c-hungry-delete-forward', for the same reason.
311
293 ;; Bind the electric deletion functions to C-d and DEL. Emacs 21 312 ;; Bind the electric deletion functions to C-d and DEL. Emacs 21
294 ;; automatically maps the [delete] and [backspace] keys to these two 313 ;; automatically maps the [delete] and [backspace] keys to these two
295 ;; depending on window system and user preferences. (In earlier 314 ;; depending on window system and user preferences. (In earlier
296 ;; versions it's possible to do the same by using `function-key-map'.) 315 ;; versions it's possible to do the same by using `function-key-map'.)
297 (define-key c-mode-base-map "\C-d" 'c-electric-delete-forward) 316 (define-key c-mode-base-map "\C-d" 'c-electric-delete-forward)
298 (define-key c-mode-base-map "\177" 'c-electric-backspace) 317 (define-key c-mode-base-map "\177" 'c-electric-backspace)
299 (when (boundp 'delete-key-deletes-forward) 318 (define-key c-mode-base-map "\C-c\C-d" 'c-hungry-delete-forward)
300 ;; In XEmacs 20 and later we fix the forward and backward deletion 319 (define-key c-mode-base-map [?\C-c ?\d] 'c-hungry-backspace)
301 ;; behavior by binding the keysyms for the [delete] and 320 (define-key c-mode-base-map [?\C-c ?\C-\d] 'c-hungry-backspace)
302 ;; [backspace] keys directly, and use `delete-forward-p' or 321 (define-key c-mode-base-map [?\C-c deletechar] 'c-hungry-delete-forward) ; C-c <delete> on a tty.
303 ;; `delete-key-deletes-forward' to decide what [delete] should do. 322 (define-key c-mode-base-map [?\C-c (control deletechar)] ; C-c C-<delete> on a tty.
323 'c-hungry-delete-forward)
324 (when (boundp 'normal-erase-is-backspace)
325 ;; The automatic C-d and DEL mapping functionality doesn't extend
326 ;; to special combinations like C-c C-<delete>, so we have to hook
327 ;; into the `normal-erase-is-backspace' system to bind it directly
328 ;; as appropriate.
329 (add-hook 'normal-erase-is-backspace-hook 'c-bind-special-erase-keys)
330 (c-bind-special-erase-keys))
331
332 (when (fboundp 'delete-forward-p)
333 ;; In XEmacs we fix the forward and backward deletion behavior by
334 ;; binding the keysyms for the [delete] and [backspace] keys
335 ;; directly, and use `delete-forward-p' to decide what [delete]
336 ;; should do. That's done in the XEmacs specific
337 ;; `c-electric-delete' and `c-hungry-delete' functions.
304 (define-key c-mode-base-map [delete] 'c-electric-delete) 338 (define-key c-mode-base-map [delete] 'c-electric-delete)
305 (define-key c-mode-base-map [backspace] 'c-electric-backspace)) 339 (define-key c-mode-base-map [backspace] 'c-electric-backspace)
306 (define-key c-mode-base-map "," 'c-electric-semi&comma) 340 (define-key c-mode-base-map (kbd "C-c <delete>") 'c-hungry-delete)
307 (define-key c-mode-base-map "*" 'c-electric-star) 341 (define-key c-mode-base-map (kbd "C-c C-<delete>") 'c-hungry-delete)
342 (define-key c-mode-base-map (kbd "C-c <backspace>") 'c-hungry-backspace)
343 (define-key c-mode-base-map (kbd "C-c C-<backspace>") 'c-hungry-backspace))
344
345 (define-key c-mode-base-map "#" 'c-electric-pound)
346 (define-key c-mode-base-map "{" 'c-electric-brace)
347 (define-key c-mode-base-map "}" 'c-electric-brace)
308 (define-key c-mode-base-map "/" 'c-electric-slash) 348 (define-key c-mode-base-map "/" 'c-electric-slash)
309 (define-key c-mode-base-map "\C-c\C-q" 'c-indent-defun) 349 (define-key c-mode-base-map "*" 'c-electric-star)
350 (define-key c-mode-base-map ";" 'c-electric-semi&comma)
351 (define-key c-mode-base-map "," 'c-electric-semi&comma)
352 (define-key c-mode-base-map ":" 'c-electric-colon)
353 (define-key c-mode-base-map "(" 'c-electric-paren)
354 (define-key c-mode-base-map ")" 'c-electric-paren)
355
310 (define-key c-mode-base-map "\C-c\C-\\" 'c-backslash-region) 356 (define-key c-mode-base-map "\C-c\C-\\" 'c-backslash-region)
311 (define-key c-mode-base-map "\C-c\C-a" 'c-toggle-auto-state) 357 (define-key c-mode-base-map "\C-c\C-a" 'c-toggle-auto-newline)
312 (define-key c-mode-base-map "\C-c\C-b" 'c-submit-bug-report) 358 (define-key c-mode-base-map "\C-c\C-b" 'c-submit-bug-report)
313 (define-key c-mode-base-map "\C-c\C-c" 'comment-region) 359 (define-key c-mode-base-map "\C-c\C-c" 'comment-region)
314 (define-key c-mode-base-map "\C-c\C-d" 'c-toggle-hungry-state) 360 (define-key c-mode-base-map "\C-c\C-l" 'c-toggle-electric-state)
315 (define-key c-mode-base-map "\C-c\C-o" 'c-set-offset) 361 (define-key c-mode-base-map "\C-c\C-o" 'c-set-offset)
362 (define-key c-mode-base-map "\C-c\C-q" 'c-indent-defun)
316 (define-key c-mode-base-map "\C-c\C-s" 'c-show-syntactic-information) 363 (define-key c-mode-base-map "\C-c\C-s" 'c-show-syntactic-information)
317 (define-key c-mode-base-map "\C-c\C-t" 'c-toggle-auto-hungry-state) 364 ;; (define-key c-mode-base-map "\C-c\C-t" 'c-toggle-auto-hungry-state) Commented out by ACM, 2005-03-05.
318 (define-key c-mode-base-map "\C-c." 'c-set-style) 365 (define-key c-mode-base-map "\C-c." 'c-set-style)
319 ;; conflicts with OOBR 366 ;; conflicts with OOBR
320 ;;(define-key c-mode-base-map "\C-c\C-v" 'c-version) 367 ;;(define-key c-mode-base-map "\C-c\C-v" 'c-version)
368 ;; (define-key c-mode-base-map "\C-c\C-y" 'c-toggle-hungry-state) Commented out by ACM, 2005-11-22.
369 (define-key c-mode-base-map "\C-c\C-w" 'c-subword-mode)
321 ) 370 )
322 371
323;; We don't require the outline package, but we configure it a bit anyway. 372;; We don't require the outline package, but we configure it a bit anyway.
@@ -341,32 +390,47 @@ preferably use the `c-mode-menu' language constant directly."
341 (let ((f (symbol-function 'c-populate-syntax-table))) 390 (let ((f (symbol-function 'c-populate-syntax-table)))
342 (if (byte-code-function-p f) f (byte-compile f))))) 391 (if (byte-code-function-p f) f (byte-compile f)))))
343 392
393;; CAUTION: Try to avoid installing things on
394;; `before-change-functions'. The macro `combine-after-change-calls'
395;; is used and it doesn't work if there are things on that hook. That
396;; can cause font lock functions to run in inconvenient places during
397;; temporary changes in some font lock support modes, causing extra
398;; unnecessary work and font lock glitches due to interactions between
399;; various text properties.
400
344(defun c-after-change (beg end len) 401(defun c-after-change (beg end len)
345 ;; Function put on `after-change-functions' to adjust various 402 ;; Function put on `after-change-functions' to adjust various caches
346 ;; caches. Prefer speed to finesse here, since there will be an 403 ;; etc. Prefer speed to finesse here, since there will be an order
347 ;; order of magnitude more calls to this function than any of the 404 ;; of magnitude more calls to this function than any of the
348 ;; functions that use the caches. 405 ;; functions that use the caches.
349 ;; 406 ;;
350 ;; Note that care must be taken so that this is called before any 407 ;; Note that care must be taken so that this is called before any
351 ;; font-lock callbacks since we might get calls to functions using 408 ;; font-lock callbacks since we might get calls to functions using
352 ;; these caches from inside them, and we must thus be sure that this 409 ;; these caches from inside them, and we must thus be sure that this
353 ;; has already been executed. 410 ;; has already been executed.
354 ;;
355 ;; This function does not do any hidden buffer changes.
356 411
357 (c-save-buffer-state () 412 (c-save-buffer-state ()
358 (when (> end (point-max)) 413 ;; When `combine-after-change-calls' is used we might get calls
359 ;; Some emacsen might return positions past the end. This has been 414 ;; with regions outside the current narrowing. This has been
360 ;; observed in Emacs 20.7 when rereading a buffer changed on disk 415 ;; observed in Emacs 20.7.
361 ;; (haven't been able to minimize it, but Emacs 21.3 appears to 416 (save-restriction
362 ;; work). 417 (widen)
363 (setq end (point-max)) 418
364 (when (> beg end) 419 (when (> end (point-max))
365 (setq beg end))) 420 ;; Some emacsen might return positions past the end. This has been
366 421 ;; observed in Emacs 20.7 when rereading a buffer changed on disk
367 (c-invalidate-sws-region-after beg end) 422 ;; (haven't been able to minimize it, but Emacs 21.3 appears to
368 (c-invalidate-state-cache beg) 423 ;; work).
369 (c-invalidate-find-decl-cache beg))) 424 (setq end (point-max))
425 (when (> beg end)
426 (setq beg end)))
427
428 (c-invalidate-sws-region-after beg end)
429 (c-invalidate-state-cache beg)
430 (c-invalidate-find-decl-cache beg)
431
432 (when c-recognize-<>-arglists
433 (c-after-change-check-<>-operators beg end)))))
370 434
371(defun c-basic-common-init (mode default-style) 435(defun c-basic-common-init (mode default-style)
372 "Do the necessary initialization for the syntax handling routines 436 "Do the necessary initialization for the syntax handling routines
@@ -380,8 +444,6 @@ same format as `c-default-style'.
380Note that `c-init-language-vars' must be called before this function. 444Note that `c-init-language-vars' must be called before this function.
381This function cannot do that since `c-init-language-vars' is a macro 445This function cannot do that since `c-init-language-vars' is a macro
382that requires a literal mode spec at compile time." 446that requires a literal mode spec at compile time."
383 ;;
384 ;; This function does not do any hidden buffer changes.
385 447
386 (setq c-buffer-is-cc-mode mode) 448 (setq c-buffer-is-cc-mode mode)
387 449
@@ -395,13 +457,20 @@ that requires a literal mode spec at compile time."
395 (make-local-variable 'comment-end) 457 (make-local-variable 'comment-end)
396 (make-local-variable 'comment-start-skip) 458 (make-local-variable 'comment-start-skip)
397 (make-local-variable 'comment-multi-line) 459 (make-local-variable 'comment-multi-line)
460 (make-local-variable 'comment-line-break-function)
461 (make-local-variable 'paragraph-start)
462 (make-local-variable 'paragraph-separate)
463 (make-local-variable 'paragraph-ignore-fill-prefix)
464 (make-local-variable 'adaptive-fill-mode)
465 (make-local-variable 'adaptive-fill-regexp)
398 466
399 ;; now set their values 467 ;; now set their values
400 (setq parse-sexp-ignore-comments t 468 (setq parse-sexp-ignore-comments t
401 indent-line-function 'c-indent-line 469 indent-line-function 'c-indent-line
402 indent-region-function 'c-indent-region 470 indent-region-function 'c-indent-region
403 normal-auto-fill-function 'c-do-auto-fill 471 normal-auto-fill-function 'c-do-auto-fill
404 comment-multi-line t) 472 comment-multi-line t
473 comment-line-break-function 'c-indent-new-comment-line)
405 474
406 ;; Install `c-fill-paragraph' on `fill-paragraph-function' so that a 475 ;; Install `c-fill-paragraph' on `fill-paragraph-function' so that a
407 ;; direct call to `fill-paragraph' behaves better. This still 476 ;; direct call to `fill-paragraph' behaves better. This still
@@ -409,21 +478,25 @@ that requires a literal mode spec at compile time."
409 (make-local-variable 'fill-paragraph-function) 478 (make-local-variable 'fill-paragraph-function)
410 (setq fill-paragraph-function 'c-fill-paragraph) 479 (setq fill-paragraph-function 'c-fill-paragraph)
411 480
412 ;; (X)Emacs 20 and later. 481 (when (or c-recognize-<>-arglists
413 (when (boundp 'comment-line-break-function) 482 (c-major-mode-is 'awk-mode))
414 (make-local-variable 'comment-line-break-function) 483 ;; We'll use the syntax-table text property to change the syntax
415 (setq comment-line-break-function 484 ;; of some chars for this language, so do the necessary setup for
416 'c-indent-new-comment-line)) 485 ;; that.
417 486 ;;
418 ;; Emacs 20 and later. 487 ;; Note to other package developers: It's ok to turn this on in CC
419 (when (boundp 'parse-sexp-lookup-properties) 488 ;; Mode buffers when CC Mode doesn't, but it's not ok to turn it
420 (make-local-variable 'parse-sexp-lookup-properties) 489 ;; off if CC Mode has turned it on.
421 (setq parse-sexp-lookup-properties t)) 490
422 491 ;; Emacs.
423 ;; Same as above for XEmacs 21 (although currently undocumented). 492 (when (boundp 'parse-sexp-lookup-properties)
424 (when (boundp 'lookup-syntax-properties) 493 (make-local-variable 'parse-sexp-lookup-properties)
425 (make-local-variable 'lookup-syntax-properties) 494 (setq parse-sexp-lookup-properties t))
426 (setq lookup-syntax-properties t)) 495
496 ;; Same as above for XEmacs.
497 (when (boundp 'lookup-syntax-properties)
498 (make-local-variable 'lookup-syntax-properties)
499 (setq lookup-syntax-properties t)))
427 500
428 ;; Use this in Emacs 21 to avoid meddling with the rear-nonsticky 501 ;; Use this in Emacs 21 to avoid meddling with the rear-nonsticky
429 ;; property on each character. 502 ;; property on each character.
@@ -441,18 +514,12 @@ that requires a literal mode spec at compile time."
441 514
442 ;; In Emacs 21 and later it's possible to turn off the ad-hoc 515 ;; In Emacs 21 and later it's possible to turn off the ad-hoc
443 ;; heuristic that open parens in column 0 are defun starters. Since 516 ;; heuristic that open parens in column 0 are defun starters. Since
444 ;; we have c-state-cache that isn't useful and only causes trouble 517 ;; we have c-state-cache, that heuristic isn't useful and only causes
445 ;; so turn it off. 518 ;; trouble, so turn it off.
446 (when (memq 'col-0-paren c-emacs-features) 519 (when (memq 'col-0-paren c-emacs-features)
447 (make-local-variable 'open-paren-in-column-0-is-defun-start) 520 (make-local-variable 'open-paren-in-column-0-is-defun-start)
448 (setq open-paren-in-column-0-is-defun-start nil)) 521 (setq open-paren-in-column-0-is-defun-start nil))
449 522
450 ;; The `c-type' text property with `c-decl-end' is used to mark the
451 ;; ends of access keys to make interactive refontification work
452 ;; better.
453 (when c-opt-access-key
454 (setq c-type-decl-end-used t))
455
456 (c-clear-found-types) 523 (c-clear-found-types)
457 524
458 ;; now set the mode style based on default-style 525 ;; now set the mode style based on default-style
@@ -483,14 +550,15 @@ that requires a literal mode spec at compile time."
483 (make-local-variable 'comment-indent-function) 550 (make-local-variable 'comment-indent-function)
484 (setq comment-indent-function 'c-comment-indent) 551 (setq comment-indent-function 'c-comment-indent)
485 552
486 ;; put auto-hungry designators onto minor-mode-alist, but only once 553 ;; Put submode indicators onto minor-mode-alist, but only once.
487 (or (assq 'c-auto-hungry-string minor-mode-alist) 554 (or (assq 'c-submode-indicators minor-mode-alist)
488 (setq minor-mode-alist 555 (setq minor-mode-alist
489 (cons '(c-auto-hungry-string c-auto-hungry-string) 556 (cons '(c-submode-indicators c-submode-indicators)
490 minor-mode-alist))) 557 minor-mode-alist)))
491 558
492 ;; Install the functions that ensure that various internal caches 559 ;; Install the functions that ensure that various internal caches
493 ;; don't become invalid due to buffer changes. 560 ;; don't become invalid due to buffer changes.
561 (make-local-hook 'after-change-functions)
494 (add-hook 'after-change-functions 'c-after-change nil t)) 562 (add-hook 'after-change-functions 'c-after-change nil t))
495 563
496(defun c-after-font-lock-init () 564(defun c-after-font-lock-init ()
@@ -505,7 +573,7 @@ This does not load the font-lock package. Use after
505 573
506 (make-local-variable 'font-lock-defaults) 574 (make-local-variable 'font-lock-defaults)
507 (setq font-lock-defaults 575 (setq font-lock-defaults
508 `(,(if (c-mode-is-new-awk-p) 576 `(,(if (c-major-mode-is 'awk-mode)
509 ;; awk-mode currently has only one font lock level. 577 ;; awk-mode currently has only one font lock level.
510 'awk-font-lock-keywords 578 'awk-font-lock-keywords
511 (mapcar 'c-mode-symbol 579 (mapcar 'c-mode-symbol
@@ -517,6 +585,8 @@ This does not load the font-lock package. Use after
517 (font-lock-lines-before . 1) 585 (font-lock-lines-before . 1)
518 (font-lock-mark-block-function 586 (font-lock-mark-block-function
519 . c-mark-function))) 587 . c-mark-function)))
588
589 (make-local-hook 'font-lock-mode-hook)
520 (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t)) 590 (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t))
521 591
522(defun c-setup-doc-comment-style () 592(defun c-setup-doc-comment-style ()
@@ -536,9 +606,7 @@ Mode to operate correctly.
536 606
537MODE is the symbol for the mode to initialize, like 'c-mode. See 607MODE is the symbol for the mode to initialize, like 'c-mode. See
538`c-basic-common-init' for details. It's only optional to be 608`c-basic-common-init' for details. It's only optional to be
539compatible with old code; callers should always specify it. 609compatible with old code; callers should always specify it."
540
541This function does not do any hidden buffer changes."
542 610
543 (unless mode 611 (unless mode
544 ;; Called from an old third party package. The fallback is to 612 ;; Called from an old third party package. The fallback is to
@@ -569,8 +637,6 @@ setting found in `c-file-style', then it applies any offset settings
569it finds in `c-file-offsets'. 637it finds in `c-file-offsets'.
570 638
571Note that the style variables are always made local to the buffer." 639Note that the style variables are always made local to the buffer."
572 ;;
573 ;; This function does not do any hidden buffer changes.
574 640
575 ;; apply file styles and offsets 641 ;; apply file styles and offsets
576 (when c-buffer-is-cc-mode 642 (when c-buffer-is-cc-mode
@@ -584,7 +650,18 @@ Note that the style variables are always made local to the buffer."
584 (let ((langelem (car langentry)) 650 (let ((langelem (car langentry))
585 (offset (cdr langentry))) 651 (offset (cdr langentry)))
586 (c-set-offset langelem offset))) 652 (c-set-offset langelem offset)))
587 c-file-offsets)))) 653 c-file-offsets))
654 ;; Problem: The file local variable block might have explicitly set a
655 ;; style variable. The `c-set-style' or `mapcar' call might have
656 ;; overwritten this. So we run `hack-local-variables' again to remedy
657 ;; this. There are no guarantees this will work properly, particularly as
658 ;; we have no control over what the other hook functions on
659 ;; `hack-local-variables-hook' would have done, or what any "eval"
660 ;; expression will do when evaluated again. C'est la vie! ACM,
661 ;; 2005/11/2.
662 (if (or c-file-style c-file-offsets)
663 (let ((hack-local-variables-hook nil))
664 (hack-local-variables)))))
588 665
589(add-hook 'hack-local-variables-hook 'c-postprocess-file-styles) 666(add-hook 'hack-local-variables-hook 'c-postprocess-file-styles)
590 667
@@ -794,9 +871,6 @@ Key bindings:
794 mode-name "ObjC" 871 mode-name "ObjC"
795 local-abbrev-table objc-mode-abbrev-table 872 local-abbrev-table objc-mode-abbrev-table
796 abbrev-mode t) 873 abbrev-mode t)
797 ;; The `c-type' text property with `c-decl-end' is used to mark the
798 ;; end of the @-style directives.
799 (setq c-type-decl-end-used t)
800 (use-local-map objc-mode-map) 874 (use-local-map objc-mode-map)
801 (c-init-language-vars-for 'objc-mode) 875 (c-init-language-vars-for 'objc-mode)
802 (c-common-init 'objc-mode) 876 (c-common-init 'objc-mode)
@@ -996,8 +1070,7 @@ Key bindings:
996 (c-update-modeline)) 1070 (c-update-modeline))
997 1071
998 1072
999;; Support for awk. This is purposely disabled for older (X)Emacsen which 1073;; Support for AWK
1000;; don't support syntax-table properties.
1001 1074
1002;;;###autoload (add-to-list 'auto-mode-alist '("\\.awk\\'" . awk-mode)) 1075;;;###autoload (add-to-list 'auto-mode-alist '("\\.awk\\'" . awk-mode))
1003;;;###autoload (add-to-list 'interpreter-mode-alist '("awk" . awk-mode)) 1076;;;###autoload (add-to-list 'interpreter-mode-alist '("awk" . awk-mode))
@@ -1009,37 +1082,34 @@ Key bindings:
1009;;; autoload form instead. 1082;;; autoload form instead.
1010;;;###autoload (autoload 'awk-mode "cc-mode" "Major mode for editing AWK code." t) 1083;;;###autoload (autoload 'awk-mode "cc-mode" "Major mode for editing AWK code." t)
1011 1084
1012(if (not (memq 'syntax-properties c-emacs-features)) 1085(defvar awk-mode-abbrev-table nil
1013 (autoload 'awk-mode "awk-mode" "Major mode for editing AWK code." t) 1086 "Abbreviation table used in awk-mode buffers.")
1014 1087(c-define-abbrev-table 'awk-mode-abbrev-table
1015 (defvar awk-mode-abbrev-table nil 1088 '(("else" "else" c-electric-continued-statement 0)
1016 "Abbreviation table used in awk-mode buffers.") 1089 ("while" "while" c-electric-continued-statement 0)))
1017 (c-define-abbrev-table 'awk-mode-abbrev-table 1090
1018 '(("else" "else" c-electric-continued-statement 0) 1091(defvar awk-mode-map ()
1019 ("while" "while" c-electric-continued-statement 0))) 1092 "Keymap used in awk-mode buffers.")
1020 1093(if awk-mode-map
1021 (defvar awk-mode-map () 1094 nil
1022 "Keymap used in awk-mode buffers.") 1095 (setq awk-mode-map (c-make-inherited-keymap))
1023 (if awk-mode-map 1096 ;; add bindings which are only useful for awk.
1024 nil 1097 (define-key awk-mode-map "#" 'self-insert-command)
1025 (setq awk-mode-map (c-make-inherited-keymap)) 1098 (define-key awk-mode-map "/" 'self-insert-command)
1026 ;; add bindings which are only useful for awk. 1099 (define-key awk-mode-map "*" 'self-insert-command)
1027 (define-key awk-mode-map "#" 'self-insert-command) 1100 (define-key awk-mode-map "\C-c\C-n" 'undefined) ; #if doesn't exist in awk.
1028 (define-key awk-mode-map "/" 'self-insert-command) 1101 (define-key awk-mode-map "\C-c\C-p" 'undefined)
1029 (define-key awk-mode-map "*" 'self-insert-command) 1102 (define-key awk-mode-map "\C-c\C-u" 'undefined)
1030 (define-key awk-mode-map "\C-c\C-n" 'undefined) ; #if doesn't exist in awk. 1103 (define-key awk-mode-map "\M-a" 'c-beginning-of-statement) ; 2003/10/7
1031 (define-key awk-mode-map "\C-c\C-p" 'undefined) 1104 (define-key awk-mode-map "\M-e" 'c-end-of-statement) ; 2003/10/7
1032 (define-key awk-mode-map "\C-c\C-u" 'undefined) 1105 (define-key awk-mode-map "\C-\M-a" 'c-awk-beginning-of-defun)
1033 (define-key awk-mode-map "\M-a" 'undefined) ; c-awk-beginning-of-statement isn't yet implemented. 1106 (define-key awk-mode-map "\C-\M-e" 'c-awk-end-of-defun))
1034 (define-key awk-mode-map "\M-e" 'undefined) ; c-awk-end-of-statement isn't yet implemented. 1107
1035 (define-key awk-mode-map "\C-\M-a" 'c-awk-beginning-of-defun) 1108(easy-menu-define c-awk-menu awk-mode-map "AWK Mode Commands"
1036 (define-key awk-mode-map "\C-\M-e" 'c-awk-end-of-defun)) 1109 (cons "AWK" (c-lang-const c-mode-menu awk)))
1037 1110
1038 (easy-menu-define c-awk-menu awk-mode-map "AWK Mode Commands" 1111(defun awk-mode ()
1039 (cons "AWK" (c-lang-const c-mode-menu awk))) 1112 "Major mode for editing AWK code.
1040
1041 (defun awk-mode ()
1042 "Major mode for editing AWK code.
1043To submit a problem report, enter `\\[c-submit-bug-report]' from an 1113To submit a problem report, enter `\\[c-submit-bug-report]' from an
1044awk-mode buffer. This automatically sets up a mail buffer with version 1114awk-mode buffer. This automatically sets up a mail buffer with version
1045information already added. You just need to add a description of the 1115information already added. You just need to add a description of the
@@ -1052,41 +1122,40 @@ initialization, then `awk-mode-hook'.
1052 1122
1053Key bindings: 1123Key bindings:
1054\\{awk-mode-map}" 1124\\{awk-mode-map}"
1055 (interactive) 1125 (interactive)
1056 (require 'cc-awk) ; Added 2003/6/10. 1126 (require 'cc-awk) ; Added 2003/6/10.
1057 (kill-all-local-variables) 1127 (kill-all-local-variables)
1058 (c-initialize-cc-mode t) 1128 (c-initialize-cc-mode t)
1059 (set-syntax-table awk-mode-syntax-table) 1129 (set-syntax-table awk-mode-syntax-table)
1060 (setq major-mode 'awk-mode 1130 (setq major-mode 'awk-mode
1061 mode-name "AWK" 1131 mode-name "AWK"
1062 local-abbrev-table awk-mode-abbrev-table 1132 local-abbrev-table awk-mode-abbrev-table
1063 abbrev-mode t) 1133 abbrev-mode t)
1064 (use-local-map awk-mode-map) 1134 (use-local-map awk-mode-map)
1065 (c-init-language-vars-for 'awk-mode) 1135 (c-init-language-vars-for 'awk-mode)
1066 (c-common-init 'awk-mode) 1136 (c-common-init 'awk-mode)
1067 ;; The rest of CC Mode does not (yet) use `font-lock-syntactic-keywords', 1137 ;; The rest of CC Mode does not (yet) use `font-lock-syntactic-keywords',
1068 ;; so it's not set by `c-font-lock-init'. 1138 ;; so it's not set by `c-font-lock-init'.
1069 (make-local-variable 'font-lock-syntactic-keywords) 1139 (make-local-variable 'font-lock-syntactic-keywords)
1070 (setq font-lock-syntactic-keywords 1140 (setq font-lock-syntactic-keywords
1071 '((c-awk-set-syntax-table-properties 1141 '((c-awk-set-syntax-table-properties
1072 0 (0) ; Everything on this line is a dummy. 1142 0 (0) ; Everything on this line is a dummy.
1073 nil t))) 1143 nil t)))
1074 (c-awk-unstick-NL-prop) 1144 (c-awk-unstick-NL-prop)
1075 (add-hook 'before-change-functions 'c-awk-before-change nil t) 1145 (add-hook 'before-change-functions 'c-awk-before-change nil t)
1076 (add-hook 'after-change-functions 'c-awk-after-change nil t) 1146 (add-hook 'after-change-functions 'c-awk-after-change nil t)
1077 (c-save-buffer-state nil 1147 (c-save-buffer-state nil
1078 (save-restriction 1148 (save-restriction
1079 (widen) 1149 (widen)
1080 (c-awk-clear-NL-props (point-min) (point-max)) 1150 (c-awk-clear-NL-props (point-min) (point-max))
1081 (c-awk-after-change (point-min) (point-max) 0))) ; Set syntax-table props. 1151 (c-awk-after-change (point-min) (point-max) 0))) ; Set syntax-table props.
1082 1152
1083 ;; Prevent Xemacs's buffer-syntactic-context being used. See the comment 1153 ;; Prevent Xemacs's buffer-syntactic-context being used. See the comment
1084 ;; in cc-engine.el, just before (defun c-fast-in-literal ... 1154 ;; in cc-engine.el, just before (defun c-fast-in-literal ...
1085 (defalias 'c-in-literal 'c-slow-in-literal) 1155 (defalias 'c-in-literal 'c-slow-in-literal)
1086 1156
1087 (c-run-mode-hooks 'c-mode-common-hook 'awk-mode-hook) 1157 (c-run-mode-hooks 'c-mode-common-hook 'awk-mode-hook)
1088 (c-update-modeline)) 1158 (c-update-modeline))
1089) ;; closes the (if (not (memq 'syntax-properties c-emacs-features))
1090 1159
1091 1160
1092;; bug reporting 1161;; bug reporting
@@ -1175,5 +1244,5 @@ Key bindings:
1175 1244
1176(cc-provide 'cc-mode) 1245(cc-provide 'cc-mode)
1177 1246
1178;; arch-tag: 7825e5c4-fd09-439f-a04d-4c13208ba3d7 1247;;; arch-tag: 7825e5c4-fd09-439f-a04d-4c13208ba3d7
1179;;; cc-mode.el ends here 1248;;; cc-mode.el ends here
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
index f20eb8e57de..2377b4ce8bd 100644
--- a/lisp/progmodes/cc-styles.el
+++ b/lisp/progmodes/cc-styles.el
@@ -1,6 +1,7 @@
1;;; cc-styles.el --- support for styles in CC Mode 1;;; cc-styles.el --- support for styles in CC Mode
2 2
3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation,
4;; Inc.
4 5
5;; Authors: 1998- Martin Stjernholm 6;; Authors: 1998- Martin Stjernholm
6;; 1992-1999 Barry A. Warsaw 7;; 1992-1999 Barry A. Warsaw
@@ -24,7 +25,7 @@
24;; GNU General Public License for more details. 25;; GNU General Public License for more details.
25 26
26;; You should have received a copy of the GNU General Public License 27;; You should have received a copy of the GNU General Public License
27;; along with GNU Emacs; see the file COPYING. If not, write to 28;; along with this program; see the file COPYING. If not, write to
28;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 29;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29;; Boston, MA 02110-1301, USA. 30;; Boston, MA 02110-1301, USA.
30 31
@@ -55,6 +56,7 @@
55 '(("gnu" 56 '(("gnu"
56 (c-basic-offset . 2) 57 (c-basic-offset . 2)
57 (c-comment-only-line-offset . (0 . 0)) 58 (c-comment-only-line-offset . (0 . 0))
59 (c-hanging-braces-alist . ((substatement-open before after)))
58 (c-offsets-alist . ((statement-block-intro . +) 60 (c-offsets-alist . ((statement-block-intro . +)
59 (knr-argdecl-intro . 5) 61 (knr-argdecl-intro . 5)
60 (substatement-open . +) 62 (substatement-open . +)
@@ -65,11 +67,10 @@
65 (arglist-intro . c-lineup-arglist-intro-after-paren) 67 (arglist-intro . c-lineup-arglist-intro-after-paren)
66 (arglist-close . c-lineup-arglist) 68 (arglist-close . c-lineup-arglist)
67 (inline-open . 0) 69 (inline-open . 0)
68 (brace-list-open . +) 70 (brace-list-open . +)))
69 ))
70 (c-special-indent-hook . c-gnu-impose-minimum) 71 (c-special-indent-hook . c-gnu-impose-minimum)
71 (c-block-comment-prefix . "") 72 (c-block-comment-prefix . ""))
72 ) 73
73 ("k&r" 74 ("k&r"
74 (c-basic-offset . 5) 75 (c-basic-offset . 5)
75 (c-comment-only-line-offset . 0) 76 (c-comment-only-line-offset . 0)
@@ -78,9 +79,8 @@
78 (substatement-open . 0) 79 (substatement-open . 0)
79 (substatement-label . 0) 80 (substatement-label . 0)
80 (label . 0) 81 (label . 0)
81 (statement-cont . +) 82 (statement-cont . +))))
82 )) 83
83 )
84 ("bsd" 84 ("bsd"
85 (c-basic-offset . 8) 85 (c-basic-offset . 8)
86 (c-comment-only-line-offset . 0) 86 (c-comment-only-line-offset . 0)
@@ -91,9 +91,8 @@
91 (label . 0) 91 (label . 0)
92 (statement-cont . +) 92 (statement-cont . +)
93 (inline-open . 0) 93 (inline-open . 0)
94 (inexpr-class . 0) 94 (inexpr-class . 0))))
95 )) 95
96 )
97 ("stroustrup" 96 ("stroustrup"
98 (c-basic-offset . 4) 97 (c-basic-offset . 4)
99 (c-comment-only-line-offset . 0) 98 (c-comment-only-line-offset . 0)
@@ -101,46 +100,61 @@
101 (substatement-open . 0) 100 (substatement-open . 0)
102 (substatement-label . 0) 101 (substatement-label . 0)
103 (label . 0) 102 (label . 0)
104 (statement-cont . +) 103 (statement-cont . +))))
105 )) 104
106 )
107 ("whitesmith" 105 ("whitesmith"
108 (c-basic-offset . 4) 106 (c-basic-offset . 4)
109 (c-comment-only-line-offset . 0) 107 (c-comment-only-line-offset . 0)
110 (c-offsets-alist . ((knr-argdecl-intro . +) 108 ;; It's obvious that the CC Mode way of choosing anchor positions
111 (label . 0) 109 ;; doesn't fit this style at all. :P
112 (statement-cont . +) 110 (c-offsets-alist . ((defun-open . +)
113 (substatement-open . +)
114 (substatement-label . +)
115 (block-open . +)
116 (statement-block-intro . c-lineup-whitesmith-in-block)
117 (block-close . c-lineup-whitesmith-in-block)
118 (inline-open . +)
119 (defun-open . +)
120 (defun-block-intro . c-lineup-whitesmith-in-block)
121 (defun-close . c-lineup-whitesmith-in-block) 111 (defun-close . c-lineup-whitesmith-in-block)
112 (defun-block-intro . (add c-lineup-whitesmith-in-block
113 c-indent-multi-line-block))
114 (class-open . +)
115 (class-close . +)
116 (inline-open . +)
117 (inline-close . c-lineup-whitesmith-in-block)
118 (knr-argdecl-intro . +)
119 (block-open . 0) ; Get indentation from `statement' instead.
120 (block-close . c-lineup-whitesmith-in-block)
122 (brace-list-open . +) 121 (brace-list-open . +)
123 (brace-list-intro . c-lineup-whitesmith-in-block)
124 (brace-entry-open . c-indent-multi-line-block)
125 (brace-list-close . c-lineup-whitesmith-in-block) 122 (brace-list-close . c-lineup-whitesmith-in-block)
126 (class-open . +) 123 (brace-list-intro . (add c-lineup-whitesmith-in-block
124 c-indent-multi-line-block))
125 (brace-list-entry . (add c-lineup-after-whitesmith-blocks
126 c-indent-multi-line-block))
127 (brace-entry-open . (add c-lineup-after-whitesmith-blocks
128 c-indent-multi-line-block))
129 (statement . (add c-lineup-after-whitesmith-blocks
130 c-indent-multi-line-block))
131 (statement-block-intro . (add c-lineup-whitesmith-in-block
132 c-indent-multi-line-block))
133 (substatement-open . +)
134 (substatement-label . +)
135 (label . 0)
136 (arglist-intro . (add c-lineup-whitesmith-in-block
137 c-indent-multi-line-block))
138 (arglist-cont . (add c-lineup-after-whitesmith-blocks
139 c-indent-multi-line-block))
140 (arglist-cont-nonempty . (add c-lineup-whitesmith-in-block
141 c-indent-multi-line-block))
142 (arglist-close . c-lineup-whitesmith-in-block)
127 (inclass . c-lineup-whitesmith-in-block) 143 (inclass . c-lineup-whitesmith-in-block)
128 (class-close . +)
129 (inexpr-class . 0)
130 (extern-lang-open . +) 144 (extern-lang-open . +)
131 (inextern-lang . c-lineup-whitesmith-in-block)
132 (extern-lang-close . +)
133 (namespace-open . +) 145 (namespace-open . +)
134 (innamespace . c-lineup-whitesmith-in-block)
135 (namespace-close . +)
136 (module-open . +) 146 (module-open . +)
137 (inmodule . c-lineup-whitesmith-in-block)
138 (module-close . +)
139 (composition-open . +) 147 (composition-open . +)
140 (incomposition . c-lineup-whitesmith-in-block) 148 (extern-lang-close . +)
149 (namespace-close . +)
150 (module-close . +)
141 (composition-close . +) 151 (composition-close . +)
142 )) 152 (inextern-lang . c-lineup-whitesmith-in-block)
143 ) 153 (innamespace . c-lineup-whitesmith-in-block)
154 (inmodule . c-lineup-whitesmith-in-block)
155 (incomposition . c-lineup-whitesmith-in-block)
156 (inexpr-class . 0))))
157
144 ("ellemtel" 158 ("ellemtel"
145 (c-basic-offset . 3) 159 (c-basic-offset . 3)
146 (c-comment-only-line-offset . 0) 160 (c-comment-only-line-offset . 0)
@@ -151,9 +165,8 @@
151 (case-label . +) 165 (case-label . +)
152 (access-label . -) 166 (access-label . -)
153 (inclass . ++) 167 (inclass . ++)
154 (inline-open . 0) 168 (inline-open . 0))))
155 )) 169
156 )
157 ("linux" 170 ("linux"
158 (c-basic-offset . 8) 171 (c-basic-offset . 8)
159 (c-comment-only-line-offset . 0) 172 (c-comment-only-line-offset . 0)
@@ -167,9 +180,8 @@
167 (substatement-open . 0) 180 (substatement-open . 0)
168 (substatement-label . 0) 181 (substatement-label . 0)
169 (label . 0) 182 (label . 0)
170 (statement-cont . +) 183 (statement-cont . +))))
171 )) 184
172 )
173 ("python" 185 ("python"
174 (indent-tabs-mode . t) 186 (indent-tabs-mode . t)
175 (fill-column . 78) 187 (fill-column . 78)
@@ -177,17 +189,15 @@
177 (c-offsets-alist . ((substatement-open . 0) 189 (c-offsets-alist . ((substatement-open . 0)
178 (inextern-lang . 0) 190 (inextern-lang . 0)
179 (arglist-intro . +) 191 (arglist-intro . +)
180 (knr-argdecl-intro . +) 192 (knr-argdecl-intro . +)))
181 ))
182 (c-hanging-braces-alist . ((brace-list-open) 193 (c-hanging-braces-alist . ((brace-list-open)
183 (brace-list-intro) 194 (brace-list-intro)
184 (brace-list-close) 195 (brace-list-close)
185 (brace-entry-open) 196 (brace-entry-open)
186 (substatement-open after) 197 (substatement-open after)
187 (block-close . c-snug-do-while) 198 (block-close . c-snug-do-while)))
188 )) 199 (c-block-comment-prefix . ""))
189 (c-block-comment-prefix . "") 200
190 )
191 ("java" 201 ("java"
192 (c-basic-offset . 4) 202 (c-basic-offset . 4)
193 (c-comment-only-line-offset . (0 . 0)) 203 (c-comment-only-line-offset . (0 . 0))
@@ -205,9 +215,23 @@
205 (arglist-close . c-lineup-arglist) 215 (arglist-close . c-lineup-arglist)
206 (access-label . 0) 216 (access-label . 0)
207 (inher-cont . c-lineup-java-inher) 217 (inher-cont . c-lineup-java-inher)
208 (func-decl-cont . c-lineup-java-throws) 218 (func-decl-cont . c-lineup-java-throws))))
209 )) 219
210 ) 220 ;; awk style exists primarily for auto-newline settings. Otherwise it's
221 ;; pretty much like k&r.
222 ("awk"
223 (c-basic-offset . 4)
224 (c-comment-only-line-offset . 0)
225 (c-hanging-braces-alist . ((defun-open after)
226 (defun-close . c-snug-1line-defun-close)
227 (substatement-open after)
228 (block-close . c-snug-do-while)))
229 (c-hanging-semi&comma-criteria . nil)
230 (c-cleanup-list . nil) ; You might want one-liner-defun here.
231 (c-offsets-alist . ((statement-block-intro . +)
232 (substatement-open . 0)
233 (statement-cont . +))))
234
211 ) 235 )
212 "Styles of indentation. 236 "Styles of indentation.
213Elements of this alist are of the form: 237Elements of this alist are of the form:
@@ -246,8 +270,6 @@ the existing style.")
246;; Functions that manipulate styles 270;; Functions that manipulate styles
247(defun c-set-style-1 (conscell dont-override) 271(defun c-set-style-1 (conscell dont-override)
248 ;; Set the style for one variable 272 ;; Set the style for one variable
249 ;;
250 ;; This function does not do any hidden buffer changes.
251 (let ((attr (car conscell)) 273 (let ((attr (car conscell))
252 (val (cdr conscell))) 274 (val (cdr conscell)))
253 (cond 275 (cond
@@ -291,8 +313,6 @@ the existing style.")
291 313
292(defun c-get-style-variables (style basestyles) 314(defun c-get-style-variables (style basestyles)
293 ;; Return all variables in a style by resolving inheritances. 315 ;; Return all variables in a style by resolving inheritances.
294 ;;
295 ;; This function does not do any hidden buffer changes.
296 (if (not style) 316 (if (not style)
297 (copy-alist c-fallback-style) 317 (copy-alist c-fallback-style)
298 (let ((vars (cdr (or (assoc (downcase style) c-style-alist) 318 (let ((vars (cdr (or (assoc (downcase style) c-style-alist)
@@ -314,48 +334,36 @@ the existing style.")
314 334
315;;;###autoload 335;;;###autoload
316(defun c-set-style (stylename &optional dont-override) 336(defun c-set-style (stylename &optional dont-override)
317 "Set CC Mode variables to use one of several different indentation styles. 337 "Set the current buffer to use the style STYLENAME.
318STYLENAME is a string representing the desired style from the list of 338STYLENAME, a string, must be an existing CC Mode style - These are contained
319styles described in the variable `c-style-alist'. See that variable 339in the variable `c-style-alist'.
320for details of setting up styles. 340
321 341The variable `c-indentation-style' will get set to STYLENAME.
322The variable `c-indentation-style' always contains the buffer's current 342
323style name. 343\"Setting the style\" is done by setting CC Mode's \"style variables\" to the
324 344values indicated by the pertinent entry in `c-style-alist'. Other variables
325If the optional argument DONT-OVERRIDE is t, no style variables that 345might get set too.
326already have values will be overridden. I.e. in the case of 346
327`c-offsets-alist', syntactic symbols will only be added, and in the 347If DONT-OVERRIDE is neither nil nor t, style variables whose default values
328case of all other style variables, only those set to `set-from-style' 348have been set (more precisely, whose default values are not the symbol
329will be reassigned. 349`set-from-style') will not be changed. This avoids overriding global settings
330 350done in ~/.emacs. It is useful to call c-set-style from a mode hook in this
331If DONT-OVERRIDE is neither nil nor t, only those style variables that 351way.
332have default (i.e. non-buffer local) values will keep their settings 352
333while the rest will be overridden. This is useful to avoid overriding 353If DONT-OVERRIDE is t, style variables that already have values (i.e., whose
334global settings done in ~/.emacs when setting a style from a mode hook 354values are not the symbol `set-from-style') will not be overridden. CC Mode
335\(providing the style variables are buffer local, which is the 355calls c-set-style internally in this way whilst initializing a buffer; if
336default). 356cc-set-style is called like this from anywhere else, it will usually behave as
337 357a null operation."
338Obviously, setting DONT-OVERRIDE to t is useful mainly when the
339initial style is chosen for a CC Mode buffer by a major mode. Since
340that is done internally by CC Mode, it typically won't have any effect
341when used elsewhere."
342 (interactive 358 (interactive
343 (list (let ((completion-ignore-case t) 359 (list (let ((completion-ignore-case t)
344 (prompt (format "Which %s indentation style? " 360 (prompt (format "Which %s indentation style? "
345 mode-name))) 361 mode-name)))
346 (condition-case nil 362 (completing-read prompt c-style-alist nil t nil
347 ;; The default argument is preferred over 363 'c-set-style-history
348 ;; initial-contents, but it only exists in Emacs >= 20 364 c-indentation-style))))
349 ;; and XEmacs >= 21. 365 (or c-buffer-is-cc-mode
350 (completing-read prompt c-style-alist nil t nil 366 (error "Buffer %s is not a CC Mode buffer (c-set-style)" (buffer-name)))
351 'c-set-style-history
352 c-indentation-style)
353 (wrong-number-of-arguments
354 ;; If the call above failed, we fall back to the old way
355 ;; of specifying the default value.
356 (completing-read prompt c-style-alist nil t
357 (cons c-indentation-style 0)
358 'c-set-style-history))))))
359 (or (stringp stylename) 367 (or (stringp stylename)
360 (error "Argument to c-set-style was not a string")) 368 (error "Argument to c-set-style was not a string"))
361 (c-initialize-builtin-style) 369 (c-initialize-builtin-style)
@@ -406,8 +414,6 @@ STYLE using `c-set-style' if the optional SET-P flag is non-nil."
406(defun c-read-offset (langelem) 414(defun c-read-offset (langelem)
407 ;; read new offset value for LANGELEM from minibuffer. return a 415 ;; read new offset value for LANGELEM from minibuffer. return a
408 ;; legal value only 416 ;; legal value only
409 ;;
410 ;; This function does not do any hidden buffer changes.
411 (let* ((oldoff (cdr-safe (or (assq langelem c-offsets-alist) 417 (let* ((oldoff (cdr-safe (or (assq langelem c-offsets-alist)
412 (assq langelem (get 'c-offsets-alist 418 (assq langelem (get 'c-offsets-alist
413 'c-stylevar-fallback))))) 419 'c-stylevar-fallback)))))
@@ -475,20 +481,22 @@ and exists only for compatibility reasons."
475 (setq c-offsets-alist (cons (cons symbol offset) 481 (setq c-offsets-alist (cons (cons symbol offset)
476 c-offsets-alist)) 482 c-offsets-alist))
477 (c-benign-error "%s is not a valid syntactic symbol" symbol)))) 483 (c-benign-error "%s is not a valid syntactic symbol" symbol))))
478 (c-benign-error "Invalid indentation setting for symbol %s: %s" 484 (c-benign-error "Invalid indentation setting for symbol %s: %S"
479 symbol offset)) 485 symbol offset))
480 (c-keep-region-active)) 486 (c-keep-region-active))
481 487
482 488
483(defun c-setup-paragraph-variables () 489(defun c-setup-paragraph-variables ()
484 "Fix things up for paragraph recognition and filling inside comments by 490 "Fix things up for paragraph recognition and filling inside comments and
485incorporating the value of `c-comment-prefix-regexp' in the relevant 491strings by incorporating the values of `c-comment-prefix-regexp',
492`sentence-end', `paragraph-start' and `paragraph-separate' in the relevant
486variables." 493variables."
487 ;;
488 ;; This function does not do any hidden buffer changes.
489 494
490 (interactive) 495 (interactive)
491 496 (or c-buffer-is-cc-mode
497 (error "Buffer %s is not a CC Mode buffer (c-setup-paragraph-variables)"
498 (buffer-name)))
499 ;; Set up the values for use in comments.
492 (setq c-current-comment-prefix 500 (setq c-current-comment-prefix
493 (if (listp c-comment-prefix-regexp) 501 (if (listp c-comment-prefix-regexp)
494 (cdr-safe (or (assoc major-mode c-comment-prefix-regexp) 502 (cdr-safe (or (assoc major-mode c-comment-prefix-regexp)
@@ -498,34 +506,48 @@ variables."
498 (let ((comment-line-prefix 506 (let ((comment-line-prefix
499 (concat "[ \t]*\\(" c-current-comment-prefix "\\)[ \t]*"))) 507 (concat "[ \t]*\\(" c-current-comment-prefix "\\)[ \t]*")))
500 508
501 (set (make-local-variable 'paragraph-start) 509 (setq paragraph-start (concat comment-line-prefix
502 (concat comment-line-prefix 510 c-paragraph-start
503 c-paragraph-start 511 "\\|"
504 "\\|" 512 page-delimiter)
505 page-delimiter)) 513 paragraph-separate (concat comment-line-prefix
506 (set (make-local-variable 'paragraph-separate) 514 c-paragraph-separate
507 (concat comment-line-prefix 515 "\\|"
508 c-paragraph-separate 516 page-delimiter)
509 "\\|" 517 paragraph-ignore-fill-prefix t
510 page-delimiter)) 518 adaptive-fill-mode t
511 (set (make-local-variable 'paragraph-ignore-fill-prefix) t) 519 adaptive-fill-regexp
512 (set (make-local-variable 'adaptive-fill-mode) t) 520 (concat comment-line-prefix
513 (set (make-local-variable 'adaptive-fill-regexp) 521 (if (default-value 'adaptive-fill-regexp)
514 (concat comment-line-prefix 522 (concat "\\("
515 (if (default-value 'adaptive-fill-regexp) 523 (default-value 'adaptive-fill-regexp)
516 (concat "\\(" 524 "\\)")
517 (default-value 'adaptive-fill-regexp) 525 "")))
518 "\\)")
519 "")))
520 526
521 (when (boundp 'adaptive-fill-first-line-regexp) 527 (when (boundp 'adaptive-fill-first-line-regexp)
522 ;; XEmacs (20.x) adaptive fill mode doesn't have this. 528 ;; XEmacs adaptive fill mode doesn't have this.
523 (set (make-local-variable 'adaptive-fill-first-line-regexp) 529 (make-local-variable 'adaptive-fill-first-line-regexp)
524 (concat "\\`" comment-line-prefix 530 (setq adaptive-fill-first-line-regexp
525 ;; Maybe we should incorporate the old value here, 531 (concat "\\`" comment-line-prefix
526 ;; but then we have to do all sorts of kludges to 532 ;; Maybe we should incorporate the old value here,
527 ;; deal with the \` and \' it probably contains. 533 ;; but then we have to do all sorts of kludges to
528 "\\'"))))) 534 ;; deal with the \` and \' it probably contains.
535 "\\'"))))
536
537 ;; Set up the values for use in strings. These are the default
538 ;; paragraph-start/separate values, enhanced to accept escaped EOLs as
539 ;; whitespace. Used in c-beginning/end-of-sentence-in-string in cc-cmds.
540 (setq c-string-par-start
541 ;;(concat "\\(" (default-value 'paragraph-start) "\\)\\|[ \t]*\\\\$"))
542 "\f\\|[ \t]*\\\\?$")
543 (setq c-string-par-separate
544 ;;(concat "\\(" (default-value 'paragraph-separate) "\\)\\|[ \t]*\\\\$"))
545 "[ \t\f]*\\\\?$")
546 (setq c-sentence-end-with-esc-eol
547 (concat "\\(\\(" (c-default-value-sentence-end) "\\)"
548 ;; N.B.: "$" would be illegal when not enclosed like "\\($\\)".
549 "\\|" "[.?!][]\"')}]* ?\\\\\\($\\)[ \t\n]*"
550 "\\)")))
529 551
530 552
531;; Helper for setting up Filladapt mode. It's not used by CC Mode itself. 553;; Helper for setting up Filladapt mode. It's not used by CC Mode itself.
@@ -542,8 +564,6 @@ CC Mode by making sure the proper entries are present on
542`c-mode-common-hook' or similar." 564`c-mode-common-hook' or similar."
543 ;; This function is intended to be used explicitly by the end user 565 ;; This function is intended to be used explicitly by the end user
544 ;; only. 566 ;; only.
545 ;;
546 ;; This function does not do any hidden buffer changes.
547 567
548 ;; The default configuration already handles C++ comments, but we 568 ;; The default configuration already handles C++ comments, but we
549 ;; need to add handling of C block comments. A new filladapt token 569 ;; need to add handling of C block comments. A new filladapt token
@@ -573,8 +593,6 @@ CC Mode by making sure the proper entries are present on
573 ;; crucial because future c-set-style calls will always reset the 593 ;; crucial because future c-set-style calls will always reset the
574 ;; variables first to the `cc-mode' style before instituting the new 594 ;; variables first to the `cc-mode' style before instituting the new
575 ;; style. Only do this once! 595 ;; style. Only do this once!
576 ;;
577 ;; This function does not do any hidden buffer changes.
578 (unless (get 'c-initialize-builtin-style 'is-run) 596 (unless (get 'c-initialize-builtin-style 'is-run)
579 (put 'c-initialize-builtin-style 'is-run t) 597 (put 'c-initialize-builtin-style 'is-run t)
580 ;;(c-initialize-cc-mode) 598 ;;(c-initialize-cc-mode)
@@ -601,13 +619,11 @@ CC Mode by making sure the proper entries are present on
601 "Make all CC Mode style variables buffer local. 619 "Make all CC Mode style variables buffer local.
602If `this-buf-only-p' is non-nil, the style variables will be made 620If `this-buf-only-p' is non-nil, the style variables will be made
603buffer local only in the current buffer. Otherwise they'll be made 621buffer local only in the current buffer. Otherwise they'll be made
604permanently buffer local in any buffer that change their values. 622permanently buffer local in any buffer that changes their values.
605 623
606The buffer localness of the style variables are normally controlled 624The buffer localness of the style variables are normally controlled
607with the variable `c-style-variables-are-local-p', so there's seldom 625with the variable `c-style-variables-are-local-p', so there's seldom
608any reason to call this function directly." 626any reason to call this function directly."
609 ;;
610 ;; This function does not do any hidden buffer changes.
611 627
612 ;; style variables 628 ;; style variables
613 (let ((func (if this-buf-only-p 629 (let ((func (if this-buf-only-p
@@ -619,7 +635,7 @@ any reason to call this function directly."
619 ;; Hooks must be handled specially 635 ;; Hooks must be handled specially
620 (if this-buf-only-p 636 (if this-buf-only-p
621 (make-local-hook 'c-special-indent-hook) 637 (make-local-hook 'c-special-indent-hook)
622 (make-variable-buffer-local 'c-special-indent-hook) 638 (with-no-warnings (make-variable-buffer-local 'c-special-indent-hook))
623 (setq c-style-variables-are-local-p t)) 639 (setq c-style-variables-are-local-p t))
624 )) 640 ))
625 641
@@ -627,5 +643,5 @@ any reason to call this function directly."
627 643
628(cc-provide 'cc-styles) 644(cc-provide 'cc-styles)
629 645
630;; arch-tag: c764f61a-96ba-484a-a68f-101c0e9d5d2c 646;;; arch-tag: c764f61a-96ba-484a-a68f-101c0e9d5d2c
631;;; cc-styles.el ends here 647;;; cc-styles.el ends here
diff --git a/lisp/progmodes/cc-subword.el b/lisp/progmodes/cc-subword.el
new file mode 100644
index 00000000000..fd4ca891298
--- /dev/null
+++ b/lisp/progmodes/cc-subword.el
@@ -0,0 +1,312 @@
1;;; cc-subword.el --- Handling capitalized subwords in a nomenclature
2
3;; Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4
5;; Author: Masatake YAMATO
6
7;; This program is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11
12;; This program is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with this program; see the file COPYING. If not, write to
19;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20;; Boston, MA 02110-1301, USA.
21
22;;; Commentary:
23
24;; This package provides `subword' oriented commands and a minor mode
25;; (`c-subword-mode') that substitutes the common word handling
26;; functions with them.
27
28;; In spite of GNU Coding Standards, it is popular to name a symbol by
29;; mixing uppercase and lowercase letters, e.g. "GtkWidget",
30;; "EmacsFrameClass", "NSGraphicsContext", etc. Here we call these
31;; mixed case symbols `nomenclatures'. Also, each capitalized (or
32;; completely uppercase) part of a nomenclature is called a `subword'.
33;; Here are some examples:
34
35;; Nomenclature Subwords
36;; ===========================================================
37;; GtkWindow => "Gtk" and "Window"
38;; EmacsFrameClass => "Emacs", "Frame" and "Class"
39;; NSGraphicsContext => "NS", "Graphics" and "Context"
40
41;; The subword oriented commands defined in this package recognize
42;; subwords in a nomenclature to move between them and to edit them as
43;; words.
44
45;; In the minor mode, all common key bindings for word oriented
46;; commands are overridden by the subword oriented commands:
47
48;; Key Word oriented command Subword oriented command
49;; ============================================================
50;; M-f `forward-word' `c-forward-subword'
51;; M-b `backward-word' `c-backward-subword'
52;; M-@ `mark-word' `c-mark-subword'
53;; M-d `kill-word' `c-kill-subword'
54;; M-DEL `backward-kill-word' `c-backward-kill-subword'
55;; M-t `transpose-words' `c-transpose-subwords'
56;; M-c `capitalize-word' `c-capitalize-subword'
57;; M-u `upcase-word' `c-upcase-subword'
58;; M-l `downcase-word' `c-downcase-subword'
59;;
60;; Note: If you have changed the key bindings for the word oriented
61;; commands in your .emacs or a similar place, the keys you've changed
62;; to are also used for the corresponding subword oriented commands.
63
64;; To make the mode turn on automatically, put the following code in
65;; your .emacs:
66;;
67;; (add-hook 'c-mode-common-hook
68;; (lambda () (c-subword-mode 1)))
69;;
70
71;; Acknowledgment:
72;; The regular expressions to detect subwords are mostly based on
73;; the old `c-forward-into-nomenclature' originally contributed by
74;; Terry_Glanfield dot Southern at rxuk dot xerox dot com.
75
76;; TODO: ispell-word and subword oriented C-w in isearch.
77
78;;; Code:
79
80(eval-when-compile
81 (let ((load-path
82 (if (and (boundp 'byte-compile-dest-file)
83 (stringp byte-compile-dest-file))
84 (cons (file-name-directory byte-compile-dest-file) load-path)
85 load-path)))
86 (load "cc-bytecomp" nil t)))
87
88(cc-require 'cc-defs)
89(cc-require 'cc-cmds)
90
91;; Don't complain about the `define-minor-mode' form if it isn't defined.
92(cc-bytecomp-defvar c-subword-mode)
93
94;;; Autoload directives must be on the top level, so we construct an
95;;; autoload form instead.
96;;;###autoload (autoload 'c-subword-mode "cc-subword" "Mode enabling subword movement and editing keys." t)
97
98(if (not (fboundp 'define-minor-mode))
99 (defun c-subword-mode ()
100 "(Missing) mode enabling subword movement and editing keys.
101This mode is not (yet) available in this version of (X)Emacs. Sorry! If
102you really want it, please send a request to <bug-gnu-emacs@gnu.org>,
103telling us which (X)Emacs version you're using."
104 (interactive)
105 (error
106 "c-subword-mode is not (yet) available in this version of (X)Emacs. Sorry!"))
107
108 (defvar c-subword-mode-map
109 (let ((map (make-sparse-keymap)))
110 (substitute-key-definition 'forward-word
111 'c-forward-subword
112 map global-map)
113 (substitute-key-definition 'backward-word
114 'c-backward-subword
115 map global-map)
116 (substitute-key-definition 'mark-word
117 'c-mark-subword
118 map global-map)
119
120 (substitute-key-definition 'kill-word
121 'c-kill-subword
122 map global-map)
123 (substitute-key-definition 'backward-kill-word
124 'c-backward-kill-subword
125 map global-map)
126
127 (substitute-key-definition 'transpose-words
128 'c-transpose-subwords
129 map global-map)
130
131 (substitute-key-definition 'capitalize-word
132 'c-capitalize-subword
133 map global-map)
134 (substitute-key-definition 'upcase-word
135 'c-upcase-subword
136 map global-map)
137 (substitute-key-definition 'downcase-word
138 'c-downcase-subword
139 map global-map)
140 map)
141 "Keymap used in command `c-subword-mode' minor mode.")
142
143 (define-minor-mode c-subword-mode
144 "Mode enabling subword movement and editing keys.
145In spite of GNU Coding Standards, it is popular to name a symbol by
146mixing uppercase and lowercase letters, e.g. \"GtkWidget\",
147\"EmacsFrameClass\", \"NSGraphicsContext\", etc. Here we call these
148mixed case symbols `nomenclatures'. Also, each capitalized (or
149completely uppercase) part of a nomenclature is called a `subword'.
150Here are some examples:
151
152 Nomenclature Subwords
153 ===========================================================
154 GtkWindow => \"Gtk\" and \"Window\"
155 EmacsFrameClass => \"Emacs\", \"Frame\" and \"Class\"
156 NSGraphicsContext => \"NS\", \"Graphics\" and \"Context\"
157
158The subword oriented commands activated in this minor mode recognize
159subwords in a nomenclature to move between subwords and to edit them
160as words.
161
162\\{c-subword-mode-map}"
163 nil
164 nil
165 c-subword-mode-map
166 (c-update-modeline))
167
168 )
169
170(defun c-forward-subword (&optional arg)
171 "Do the same as `forward-word' but on subwords.
172See the command `c-subword-mode' for a description of subwords.
173Optional argument ARG is the same as for `forward-word'."
174 (interactive "p")
175 (unless arg (setq arg 1))
176 (c-keep-region-active)
177 (cond
178 ((< 0 arg)
179 (dotimes (i arg (point))
180 (c-forward-subword-internal)))
181 ((> 0 arg)
182 (dotimes (i (- arg) (point))
183 (c-backward-subword-internal)))
184 (t
185 (point))))
186
187(defun c-backward-subword (&optional arg)
188 "Do the same as `backward-word' but on subwords.
189See the command `c-subword-mode' for a description of subwords.
190Optional argument ARG is the same as for `backward-word'."
191 (interactive "p")
192 (c-forward-subword (- (or arg 1))))
193
194(defun c-mark-subword (arg)
195 "Do the same as `mark-word' but on subwords.
196See the command `c-subword-mode' for a description of subwords.
197Optional argument ARG is the same as for `mark-word'."
198 ;; This code is almost copied from `mark-word' in GNU Emacs.
199 (interactive "p")
200 (cond ((and (eq last-command this-command) (mark t))
201 (set-mark
202 (save-excursion
203 (goto-char (mark))
204 (c-forward-subword arg)
205 (point))))
206 (t
207 (push-mark
208 (save-excursion
209 (c-forward-subword arg)
210 (point))
211 nil t))))
212
213(defun c-kill-subword (arg)
214 "Do the same as `kill-word' but on subwords.
215See the command `c-subword-mode' for a description of subwords.
216Optional argument ARG is the same as for `kill-word'."
217 (interactive "p")
218 (kill-region (point) (c-forward-subword arg)))
219
220(defun c-backward-kill-subword (arg)
221 "Do the same as `backward-kill-word' but on subwords.
222See the command `c-subword-mode' for a description of subwords.
223Optional argument ARG is the same as for `backward-kill-word'."
224 (interactive "p")
225 (c-kill-subword (- arg)))
226
227(defun c-transpose-subwords (arg)
228 "Do the same as `transpose-words' but on subwords.
229See the command `c-subword-mode' for a description of subwords.
230Optional argument ARG is the same as for `transpose-words'."
231 (interactive "*p")
232 (transpose-subr 'c-forward-subword arg))
233
234(defun c-capitalize-subword (arg)
235 "Do the same as `capitalize-word' but on subwords.
236See the command `c-subword-mode' for a description of subwords.
237Optional argument ARG is the same as for `capitalize-word'."
238 (interactive "p")
239 (let ((count (abs arg))
240 (direction (if (< 0 arg) 1 -1)))
241 (dotimes (i count)
242 (when (re-search-forward
243 (concat "[" c-alpha "]")
244 nil t)
245 (goto-char (match-beginning 0)))
246 (let* ((p (point))
247 (pp (1+ p))
248 (np (c-forward-subword direction)))
249 (upcase-region p pp)
250 (downcase-region pp np)
251 (goto-char np)))))
252
253(defun c-downcase-subword (arg)
254 "Do the same as `downcase-word' but on subwords.
255See the command `c-subword-mode' for a description of subwords.
256Optional argument ARG is the same as for `downcase-word'."
257 (interactive "p")
258 (downcase-region (point) (c-forward-subword arg)))
259
260(defun c-upcase-subword (arg)
261 "Do the same as `upcase-word' but on subwords.
262See the command `c-subword-mode' for a description of subwords.
263Optional argument ARG is the same as for `upcase-word'."
264 (interactive "p")
265 (upcase-region (point) (c-forward-subword arg)))
266
267
268;;
269;; Internal functions
270;;
271(defun c-forward-subword-internal ()
272 (if (and
273 (save-excursion
274 (let ((case-fold-search nil))
275 (re-search-forward
276 (concat "\\W*\\(\\([" c-upper "]*\\W?\\)[" c-lower c-digit "]*\\)")
277 nil t)))
278 (> (match-end 0) (point))) ; So we don't get stuck at a
279 ; "word-constituent" which isn't c-upper,
280 ; c-lower or c-digit
281 (goto-char
282 (cond
283 ((< 1 (- (match-end 2) (match-beginning 2)))
284 (1- (match-end 2)))
285 (t
286 (match-end 0))))
287 (forward-word 1)))
288
289
290(defun c-backward-subword-internal ()
291 (if (save-excursion
292 (let ((case-fold-search nil))
293 (re-search-backward
294 (concat
295 "\\(\\(\\W\\|[" c-lower c-digit "]\\)\\([" c-upper "]+\\W*\\)"
296 "\\|\\W\\w+\\)")
297 nil t)))
298 (goto-char
299 (cond
300 ((and (match-end 3)
301 (< 1 (- (match-end 3) (match-beginning 3)))
302 (not (eq (point) (match-end 3))))
303 (1- (match-end 3)))
304 (t
305 (1+ (match-beginning 0)))))
306 (backward-word 1)))
307
308
309(cc-provide 'cc-subword)
310
311;;; arch-tag: 2be9d294-7f30-4626-95e6-9964bb93c7a3
312;;; cc-subword.el ends here
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index b6a3c404957..4c5d03c6f4c 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -1,6 +1,7 @@
1;;; cc-vars.el --- user customization variables for CC Mode 1;;; cc-vars.el --- user customization variables for CC Mode
2 2
3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software Foundation, Inc. 3;; Copyright (C) 1985,1987,1992-2003, 2004, 2005 Free Software
4;; Foundation, Inc.
4 5
5;; Authors: 1998- Martin Stjernholm 6;; Authors: 1998- Martin Stjernholm
6;; 1992-1999 Barry A. Warsaw 7;; 1992-1999 Barry A. Warsaw
@@ -24,7 +25,7 @@
24;; GNU General Public License for more details. 25;; GNU General Public License for more details.
25 26
26;; You should have received a copy of the GNU General Public License 27;; You should have received a copy of the GNU General Public License
27;; along with GNU Emacs; see the file COPYING. If not, write to 28;; along with this program; see the file COPYING. If not, write to
28;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 29;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29;; Boston, MA 02110-1301, USA. 30;; Boston, MA 02110-1301, USA.
30 31
@@ -43,33 +44,11 @@
43(cc-require 'cc-defs) 44(cc-require 'cc-defs)
44 45
45;; Silence the compiler. 46;; Silence the compiler.
46(cc-bytecomp-defun get-char-table) ; XEmacs 20+ 47(cc-bytecomp-defun get-char-table) ; XEmacs
47(cc-bytecomp-defun char-table-range) ; Emacs 19+ 48
48(cc-bytecomp-defun char-table-p) ; Emacs 19+, XEmacs 20+ 49(cc-eval-when-compile
49 50 (require 'custom)
50;; Pull in custom if it exists and is recent enough (the one in Emacs 51 (require 'widget))
51;; 19.34 isn't).
52(eval
53 (cc-eval-when-compile
54 (condition-case nil
55 (progn
56 (require 'custom)
57 (or (fboundp 'defcustom) (error ""))
58 (require 'widget)
59 '(progn ; Compile in the require's.
60 (require 'custom)
61 (require 'widget)))
62 (error
63 (message "Warning: Compiling without Customize support \
64since a (good enough) custom library wasn't found")
65 (cc-bytecomp-defmacro define-widget (name class doc &rest args))
66 (cc-bytecomp-defmacro defgroup (symbol members doc &rest args))
67 (cc-bytecomp-defmacro defcustom (symbol value doc &rest args)
68 `(defvar ,symbol ,value ,doc))
69 (cc-bytecomp-defmacro custom-declare-variable (symbol value doc
70 &rest args)
71 `(defvar ,(eval symbol) ,(eval value) ,doc))
72 nil))))
73 52
74(cc-eval-when-compile 53(cc-eval-when-compile
75 ;; Need the function form of `backquote', which isn't standardized 54 ;; Need the function form of `backquote', which isn't standardized
@@ -207,7 +186,6 @@ the value set here overrides the style system (there is a variable
207(defun c-valid-offset (offset) 186(defun c-valid-offset (offset)
208 "Return non-nil iff OFFSET is a valid offset for a syntactic symbol. 187 "Return non-nil iff OFFSET is a valid offset for a syntactic symbol.
209See `c-offsets-alist'." 188See `c-offsets-alist'."
210 ;; This function does not do any hidden buffer changes.
211 (or (eq offset '+) 189 (or (eq offset '+)
212 (eq offset '-) 190 (eq offset '-)
213 (eq offset '++) 191 (eq offset '++)
@@ -216,17 +194,19 @@ See `c-offsets-alist'."
216 (eq offset '/) 194 (eq offset '/)
217 (integerp offset) 195 (integerp offset)
218 (functionp offset) 196 (functionp offset)
219 (and (symbolp offset) 197 (and (symbolp offset) (boundp offset))
220 (or (boundp offset)
221 (fboundp offset)))
222 (and (vectorp offset) 198 (and (vectorp offset)
223 (= (length offset) 1) 199 (= (length offset) 1)
224 (integerp (elt offset 0))) 200 (integerp (elt offset 0)))
225 (progn 201 (and (consp offset)
226 (while (and (consp offset) 202 (not (eq (car offset) 'quote)) ; Detect misquoted lists.
227 (c-valid-offset (car offset))) 203 (progn
228 (setq offset (cdr offset))) 204 (when (memq (car offset) '(first min max add))
229 (null offset)))) 205 (setq offset (cdr offset)))
206 (while (and (consp offset)
207 (c-valid-offset (car offset)))
208 (setq offset (cdr offset)))
209 (null offset)))))
230 210
231 211
232 212
@@ -311,6 +291,7 @@ effect in this mode, nor any of the indentation associated variables,
311e.g. `c-special-indent-hook'." 291e.g. `c-special-indent-hook'."
312 :type 'boolean 292 :type 'boolean
313 :group 'c) 293 :group 'c)
294(make-variable-buffer-local 'c-syntactic-indentation)
314 295
315(defcustom c-syntactic-indentation-in-macros t 296(defcustom c-syntactic-indentation-in-macros t
316 "*Enable syntactic analysis inside macros. 297 "*Enable syntactic analysis inside macros.
@@ -470,6 +451,7 @@ style comments."
470 451
471(defcustom-c-stylevar c-comment-prefix-regexp 452(defcustom-c-stylevar c-comment-prefix-regexp
472 '((pike-mode . "//+!?\\|\\**") 453 '((pike-mode . "//+!?\\|\\**")
454 (awk-mode . "#+")
473 (other . "//+\\|\\**")) 455 (other . "//+\\|\\**"))
474 "*Regexp to match the line prefix inside comments. 456 "*Regexp to match the line prefix inside comments.
475This regexp is used to recognize the fill prefix inside comments for 457This regexp is used to recognize the fill prefix inside comments for
@@ -517,14 +499,17 @@ variable in a mode hook."
517 (cons :format "%v" 499 (cons :format "%v"
518 (const :format "IDL " idl-mode) (regexp :format "%v")) 500 (const :format "IDL " idl-mode) (regexp :format "%v"))
519 (cons :format "%v" 501 (cons :format "%v"
520 (const :format "Pike " pike-mode) (regexp :format "%v"))) 502 (const :format "Pike " pike-mode) (regexp :format "%v"))
503 (cons :format "%v"
504 (const :format "AWK " awk-mode) (regexp :format "%v")))
521 (cons :format " %v" 505 (cons :format " %v"
522 (const :format "Other " other) (regexp :format "%v")))) 506 (const :format "Other " other) (regexp :format "%v"))))
523 :group 'c) 507 :group 'c)
524 508
525(defcustom-c-stylevar c-doc-comment-style 509(defcustom-c-stylevar c-doc-comment-style
526 '((java-mode . javadoc) 510 '((java-mode . javadoc)
527 (pike-mode . autodoc)) 511 (pike-mode . autodoc)
512 (c-mode . gtkdoc))
528 "*Specifies documentation comment style(s) to recognize. 513 "*Specifies documentation comment style(s) to recognize.
529This is primarily used to fontify doc comments and the markup within 514This is primarily used to fontify doc comments and the markup within
530them, e.g. Javadoc comments. 515them, e.g. Javadoc comments.
@@ -534,6 +519,7 @@ comment styles:
534 519
535 javadoc -- Javadoc style for \"/** ... */\" comments (default in Java mode). 520 javadoc -- Javadoc style for \"/** ... */\" comments (default in Java mode).
536 autodoc -- Pike autodoc style for \"//! ...\" comments (default in Pike mode). 521 autodoc -- Pike autodoc style for \"//! ...\" comments (default in Pike mode).
522 gtkdoc -- GtkDoc style for \"/** ... **/\" comments (default in C mode).
537 523
538The value may also be a list of doc comment styles, in which case all 524The value may also be a list of doc comment styles, in which case all
539of them are recognized simultaneously (presumably with markup cues 525of them are recognized simultaneously (presumably with markup cues
@@ -586,6 +572,9 @@ afterwards to redo that work."
586 (const :format "Pike " pike-mode) 572 (const :format "Pike " pike-mode)
587 (c-symbol-list :format "%v")) 573 (c-symbol-list :format "%v"))
588 (cons :format "%v" 574 (cons :format "%v"
575 (const :format "AWK " awk-mode)
576 (c-symbol-list :format "%v"))
577 (cons :format "%v"
589 (const :format "Other " other) 578 (const :format "Other " other)
590 (c-symbol-list :format "%v"))))) 579 (c-symbol-list :format "%v")))))
591 :group 'c) 580 :group 'c)
@@ -613,8 +602,8 @@ contexts are:
613(defcustom-c-stylevar c-cleanup-list '(scope-operator) 602(defcustom-c-stylevar c-cleanup-list '(scope-operator)
614 "*List of various C/C++/ObjC constructs to \"clean up\". 603 "*List of various C/C++/ObjC constructs to \"clean up\".
615The following clean ups only take place when the auto-newline feature 604The following clean ups only take place when the auto-newline feature
616is turned on, as evidenced by the `/a' or `/ah' appearing next to the 605is turned on, as evidenced by the `/la' appearing next to the mode
617mode name: 606name:
618 607
619 brace-else-brace -- Clean up \"} else {\" constructs by placing 608 brace-else-brace -- Clean up \"} else {\" constructs by placing
620 entire construct on a single line. This clean 609 entire construct on a single line. This clean
@@ -630,21 +619,28 @@ mode name:
630 \"} catch (...) {\" constructs. 619 \"} catch (...) {\" constructs.
631 empty-defun-braces -- Clean up empty defun braces by placing the 620 empty-defun-braces -- Clean up empty defun braces by placing the
632 braces on the same line. Clean up occurs when 621 braces on the same line. Clean up occurs when
633 the defun closing brace is typed. 622 the defun closing brace is typed.
623 one-liner-defun -- If the code inside a function body is a single
624 line then remove any newlines between that
625 line and the defun braces so that the whole
626 body becomes a single line.
627 `c-max-one-liner-length' gives the maximum
628 length allowed for the resulting line. Clean
629 up occurs when the closing brace is typed.
634 defun-close-semi -- Clean up the terminating semi-colon on defuns 630 defun-close-semi -- Clean up the terminating semi-colon on defuns
635 by placing the semi-colon on the same line as 631 by placing the semi-colon on the same line as
636 the closing brace. Clean up occurs when the 632 the closing brace. Clean up occurs when the
637 semi-colon is typed. 633 semi-colon is typed.
638 list-close-comma -- Clean up commas following braces in array 634 list-close-comma -- Clean up commas following braces in array
639 and aggregate initializers. Clean up occurs 635 and aggregate initializers. Clean up occurs
640 when the comma is typed. 636 when the comma is typed.
641 scope-operator -- Clean up double colons which may designate 637 scope-operator -- Clean up double colons which may designate
642 a C++ scope operator split across multiple 638 a C++ scope operator split across multiple
643 lines. Note that certain C++ constructs can 639 lines. Note that certain C++ constructs can
644 generate ambiguous situations. This clean up 640 generate ambiguous situations. This clean up
645 only takes place when there is nothing but 641 only takes place when there is nothing but
646 whitespace between colons. Clean up occurs 642 whitespace between colons. Clean up occurs
647 when the second colon is typed. 643 when the second colon is typed.
648 644
649The following clean ups always take place when they are on this list, 645The following clean ups always take place when they are on this list,
650regardless of the auto-newline feature, since they typically don't 646regardless of the auto-newline feature, since they typically don't
@@ -654,31 +650,39 @@ involve auto-newline inserted newlines:
654 parenthesis of a function call. Clean up 650 parenthesis of a function call. Clean up
655 occurs when the opening parenthesis is typed. 651 occurs when the opening parenthesis is typed.
656 compact-empty-funcall -- Clean up any space before the function call 652 compact-empty-funcall -- Clean up any space before the function call
657 opening parenthesis if and only if the 653 opening parenthesis if and only if the
658 argument list is empty. This is typically 654 argument list is empty. This is typically
659 useful together with `space-before-funcall' to 655 useful together with `space-before-funcall' to
660 get the style \"foo (bar)\" and \"foo()\". 656 get the style \"foo (bar)\" and \"foo()\".
661 Clean up occurs when the closing parenthesis 657 Clean up occurs when the closing parenthesis
662 is typed." 658 is typed.
659 comment-close-slash -- When a slash is typed after the comment prefix
660 on a bare line in a c-style comment, the comment
661 is closed by cleaning up preceding space and
662 inserting a star if needed."
663 :type '(set 663 :type '(set
664 (const :tag "Put \"} else {\" on one line" 664 (const :tag "Put \"} else {\" on one line (brace-else-brace)"
665 brace-else-brace) 665 brace-else-brace)
666 (const :tag "Put \"} else if (...) {\" on one line" 666 (const :tag "Put \"} else if (...) {\" on one line (brace-elseif-brace)"
667 brace-elseif-brace) 667 brace-elseif-brace)
668 (const :tag "Put \"} catch (...) {\" on one line" 668 (const :tag "Put \"} catch (...) {\" on one line (brace-catch-brace)"
669 brace-catch-brace) 669 brace-catch-brace)
670 (const :tag "Put empty defun braces on one line" 670 (const :tag "Put empty defun braces on one line (empty-defun-braces)"
671 empty-defun-braces) 671 empty-defun-braces)
672 (const :tag "Put \"};\" ending defuns on one line" 672 (const :tag "Put short function bodies on one line (one-liner-defun)"
673 one-liner-defun)
674 (const :tag "Put \"};\" ending defuns on one line (defun-close-semi)"
673 defun-close-semi) 675 defun-close-semi)
674 (const :tag "Put \"},\" in aggregates on one line" 676 (const :tag "Put \"},\" in aggregates on one line (list-close-comma)"
675 list-close-comma) 677 list-close-comma)
676 (const :tag "Put C++ style \"::\" on one line" 678 (const :tag "Put C++ style \"::\" on one line (scope-operator)"
677 scope-operator) 679 scope-operator)
678 (const :tag "Put a space before funcall parens, e.g. \"foo (bar)\"" 680 (const :tag "Put a space before funcall parens, e.g. \"foo (bar)\" (space-before-funcall)"
679 space-before-funcall) 681 space-before-funcall)
680 (const :tag "Remove space before empty funcalls, e.g. \"foo()\"" 682 (const :tag "Remove space before empty funcalls, e.g. \"foo()\" (compact-empty-funcall)"
681 compact-empty-funcall)) 683 compact-empty-funcall)
684 (const :tag "Make / on a bare line of a C-style comment close it (comment-close-slash)"
685 comment-close-slash))
682 :group 'c) 686 :group 'c)
683 687
684(defcustom-c-stylevar c-hanging-braces-alist '((brace-list-open) 688(defcustom-c-stylevar c-hanging-braces-alist '((brace-list-open)
@@ -751,6 +755,12 @@ syntactic context for the brace line."
751 inexpr-class-open inexpr-class-close))) 755 inexpr-class-open inexpr-class-close)))
752 :group 'c) 756 :group 'c)
753 757
758(defcustom c-max-one-liner-length 80
759 "Maximum length of line that clean-up \"one-liner-defun\" will compact to.
760Zero or nil means no limit."
761 :type 'integer
762 :group 'c)
763
754(defcustom-c-stylevar c-hanging-colons-alist nil 764(defcustom-c-stylevar c-hanging-colons-alist nil
755 "*Controls the insertion of newlines before and after certain colons. 765 "*Controls the insertion of newlines before and after certain colons.
756This variable contains an association list with elements of the 766This variable contains an association list with elements of the
@@ -832,35 +842,40 @@ space."
832 :group 'c) 842 :group 'c)
833 843
834(defcustom c-require-final-newline 844(defcustom c-require-final-newline
835 ;; C and C++ mandates that all nonempty files should end with a 845 ;; C and C++ mandate that all nonempty files should end with a
836 ;; newline. Objective-C refers to C for all things it doesn't 846 ;; newline. Objective-C refers to C for all things it doesn't
837 ;; specify, so the same holds there. The other languages does not 847 ;; specify, so the same holds there. The other languages do not
838 ;; require it (at least not explicitly in a normative text). 848 ;; require it (at least not explicitly in a normative text).
839 '((c-mode . t) 849 '((c-mode . t)
840 (c++-mode . t) 850 (c++-mode . t)
841 (objc-mode . t)) 851 (objc-mode . t))
842 "*Controls `require-final-newline' in C-related major modes. 852 "*Controls whether a final newline is ensured when the file is saved.
843The value is an association list specifying, for each specific mode, 853The value is an association list that for each language mode specifies
844whether to override `require-final-newline'. If the cdr of the element 854the value to give to `require-final-newline' at mode initialization;
845is non-nil, that means to use `mode-require-final-newline' instead." 855see that variable for details about the value. If a language isn't
856present on the association list, CC Mode won't touch
857`require-final-newline' in buffers for that language."
846 :type `(set (cons :format "%v" 858 :type `(set (cons :format "%v"
847 (const :format "C " c-mode) 859 (const :format "C " c-mode)
848 (const t)) 860 (symbol :format "%v" :value ,require-final-newline))
849 (cons :format "%v" 861 (cons :format "%v"
850 (const :format "C++ " c++-mode) 862 (const :format "C++ " c++-mode)
851 (const t)) 863 (symbol :format "%v" :value ,require-final-newline))
852 (cons :format "%v" 864 (cons :format "%v"
853 (const :format "ObjC " objc-mode) 865 (const :format "ObjC " objc-mode)
854 (const t)) 866 (symbol :format "%v" :value ,require-final-newline))
855 (cons :format "%v" 867 (cons :format "%v"
856 (const :format "Java " java-mode) 868 (const :format "Java " java-mode)
857 (const t)) 869 (symbol :format "%v" :value ,require-final-newline))
858 (cons :format "%v" 870 (cons :format "%v"
859 (const :format "IDL " idl-mode) 871 (const :format "IDL " idl-mode)
860 (const t)) 872 (symbol :format "%v" :value ,require-final-newline))
861 (cons :format "%v" 873 (cons :format "%v"
862 (const :format "Pike " pike-mode) 874 (const :format "Pike " pike-mode)
863 (const t))) 875 (symbol :format "%v" :value ,require-final-newline))
876 (cons :format "%v"
877 (const :format "AWK " awk-mode)
878 (symbol :format "%v" :value ,require-final-newline)))
864 :group 'c) 879 :group 'c)
865 880
866(defcustom c-electric-pound-behavior nil 881(defcustom c-electric-pound-behavior nil
@@ -892,7 +907,8 @@ this variable to nil."
892 :type 'integer 907 :type 'integer
893 :group 'c) 908 :group 'c)
894 909
895(defcustom c-default-style '((java-mode . "java") (other . "gnu")) 910(defcustom c-default-style '((java-mode . "java") (awk-mode . "awk")
911 (other . "gnu"))
896 "*Style which gets installed by default when a file is visited. 912 "*Style which gets installed by default when a file is visited.
897 913
898The value of this variable can be any style defined in 914The value of this variable can be any style defined in
@@ -927,6 +943,8 @@ can always override the use of `c-default-style' by making calls to
927 (cons :format "%v" 943 (cons :format "%v"
928 (const :format "Pike " pike-mode) (string :format "%v")) 944 (const :format "Pike " pike-mode) (string :format "%v"))
929 (cons :format "%v" 945 (cons :format "%v"
946 (const :format "AWK " awk-mode) (string :format "%v"))
947 (cons :format "%v"
930 (const :format "Other " other) (string :format "%v")))) 948 (const :format "Other " other) (string :format "%v"))))
931 :group 'c) 949 :group 'c)
932 950
@@ -939,170 +957,170 @@ can always override the use of `c-default-style' by making calls to
939;; symbol and continue searching. 957;; symbol and continue searching.
940(c-set-stylevar-fallback 'c-offsets-alist 958(c-set-stylevar-fallback 'c-offsets-alist
941 '((string . c-lineup-dont-change) 959 '((string . c-lineup-dont-change)
942 ;; Relpos: Beg of previous line. 960 ;; Anchor pos: Beg of previous line.
943 (c . c-lineup-C-comments) 961 (c . c-lineup-C-comments)
944 ;; Relpos: Beg of the comment. 962 ;; Anchor pos: Beg of the comment.
945 (defun-open . 0) 963 (defun-open . 0)
946 ;; Relpos: When inside a class: Boi at the func decl start. 964 ;; Anchor pos: When inside a class: Boi at the func decl start.
947 ;; When at top level: Bol at the func decl start. When inside 965 ;; When at top level: Bol at the func decl start. When inside
948 ;; a code block (only possible in Pike): At the func decl 966 ;; a code block (only possible in Pike): At the func decl
949 ;; start(*). 967 ;; start(*).
950 (defun-close . 0) 968 (defun-close . 0)
951 ;; Relpos: At the defun block open if it's at boi, otherwise 969 ;; Anchor pos: At the defun block open if it's at boi,
952 ;; boi at the func decl start. 970 ;; otherwise boi at the func decl start.
953 (defun-block-intro . +) 971 (defun-block-intro . +)
954 ;; Relpos: At the block open(*). 972 ;; Anchor pos: At the block open(*).
955 (class-open . 0) 973 (class-open . 0)
956 ;; Relpos: Boi at the class decl start. 974 ;; Anchor pos: Boi at the class decl start.
957 (class-close . 0) 975 (class-close . 0)
958 ;; Relpos: Boi at the class decl start. 976 ;; Anchor pos: Boi at the class decl start.
959 (inline-open . +) 977 (inline-open . +)
960 ;; Relpos: None for functions (inclass got the relpos then), 978 ;; Anchor pos: None for functions (inclass got the relpos
961 ;; boi at the lambda start for lambdas. 979 ;; then), boi at the lambda start for lambdas.
962 (inline-close . 0) 980 (inline-close . 0)
963 ;; Relpos: Inexpr functions: At the lambda block open if it's 981 ;; Anchor pos: Inexpr functions: At the lambda block open if
964 ;; at boi, else at the statement(*) at boi of the start of the 982 ;; it's at boi, else at the statement(*) at boi of the start of
965 ;; lambda construct. Otherwise: At the inline block open if 983 ;; the lambda construct. Otherwise: At the inline block open
966 ;; it's at boi, otherwise boi at the func decl start. 984 ;; if it's at boi, otherwise boi at the func decl start.
967 (func-decl-cont . +) 985 (func-decl-cont . +)
968 ;; Relpos: Boi at the func decl start. 986 ;; Anchor pos: Boi at the func decl start.
969 (knr-argdecl-intro . +) 987 (knr-argdecl-intro . +)
970 ;; Relpos: Boi at the topmost intro line. 988 ;; Anchor pos: Boi at the topmost intro line.
971 (knr-argdecl . 0) 989 (knr-argdecl . 0)
972 ;; Relpos: At the beginning of the first K&R argdecl. 990 ;; Anchor pos: At the beginning of the first K&R argdecl.
973 (topmost-intro . 0) 991 (topmost-intro . 0)
974 ;; Relpos: Bol at the last line of previous construct. 992 ;; Anchor pos: Bol at the last line of previous construct.
975 (topmost-intro-cont . c-lineup-topmost-intro-cont) 993 (topmost-intro-cont . c-lineup-topmost-intro-cont)
976 ;; Relpos: Boi at the topmost intro line. 994 ;; Anchor pos: Boi at the topmost intro line.
977 (member-init-intro . +) 995 (member-init-intro . +)
978 ;; Relpos: Boi at the func decl arglist open. 996 ;; Anchor pos: Boi at the func decl arglist open.
979 (member-init-cont . c-lineup-multi-inher) 997 (member-init-cont . c-lineup-multi-inher)
980 ;; Relpos: Beg of the first member init. 998 ;; Anchor pos: Beg of the first member init.
981 (inher-intro . +) 999 (inher-intro . +)
982 ;; Relpos: Boi at the class decl start. 1000 ;; Anchor pos: Boi at the class decl start.
983 (inher-cont . c-lineup-multi-inher) 1001 (inher-cont . c-lineup-multi-inher)
984 ;; Relpos: Java: At the implements/extends keyword start. 1002 ;; Anchor pos: Java: At the implements/extends keyword start.
985 ;; Otherwise: At the inher start colon, or boi at the class 1003 ;; Otherwise: At the inher start colon, or boi at the class
986 ;; decl start if the first inherit clause hangs and it's not a 1004 ;; decl start if the first inherit clause hangs and it's not a
987 ;; func-local inherit clause (when does that occur?). 1005 ;; func-local inherit clause (when does that occur?).
988 (block-open . 0) 1006 (block-open . 0)
989 ;; Relpos: Inexpr statement: At the statement(*) at boi of the 1007 ;; Anchor pos: Inexpr statement: At the statement(*) at boi of
990 ;; start of the inexpr construct. Otherwise: None. 1008 ;; the start of the inexpr construct. Otherwise: None.
991 (block-close . 0) 1009 (block-close . 0)
992 ;; Relpos: Inexpr statement: At the inexpr block open if it's 1010 ;; Anchor pos: Inexpr statement: At the inexpr block open if
993 ;; at boi, else at the statement(*) at boi of the start of the 1011 ;; it's at boi, else at the statement(*) at boi of the start of
994 ;; inexpr construct. Block hanging on a case/default label: At 1012 ;; the inexpr construct. Block hanging on a case/default
995 ;; the closest preceding label that starts at boi. Otherwise: 1013 ;; label: At the closest preceding label that starts at boi.
996 ;; At the block open(*). 1014 ;; Otherwise: At the block open(*).
997 (brace-list-open . 0) 1015 (brace-list-open . 0)
998 ;; Relpos: Boi at the brace list decl start, but a starting 1016 ;; Anchor pos: Boi at the brace list decl start, but a starting
999 ;; "typedef" token is ignored. 1017 ;; "typedef" token is ignored.
1000 (brace-list-close . 0) 1018 (brace-list-close . 0)
1001 ;; Relpos: At the brace list decl start(*). 1019 ;; Anchor pos: At the brace list decl start(*).
1002 (brace-list-intro . +) 1020 (brace-list-intro . +)
1003 ;; Relpos: At the brace list decl start(*). 1021 ;; Anchor pos: At the brace list decl start(*).
1004 (brace-list-entry . 0) 1022 (brace-list-entry . 0)
1005 ;; Relpos: At the first non-ws char after the open paren if the 1023 ;; Anchor pos: At the first non-ws char after the open paren if
1006 ;; first token is on the same line, otherwise boi at that 1024 ;; the first token is on the same line, otherwise boi at that
1007 ;; token. 1025 ;; token.
1008 (brace-entry-open . 0) 1026 (brace-entry-open . 0)
1009 ;; Relpos: Same as brace-list-entry. 1027 ;; Anchor pos: Same as brace-list-entry.
1010 (statement . 0) 1028 (statement . 0)
1011 ;; Relpos: After a `;' in the condition clause of a for 1029 ;; Anchor pos: After a `;' in the condition clause of a for
1012 ;; statement: At the first token after the starting paren. 1030 ;; statement: At the first token after the starting paren.
1013 ;; Otherwise: At the preceding statement(*). 1031 ;; Otherwise: At the preceding statement(*).
1014 (statement-cont . +) 1032 (statement-cont . +)
1015 ;; Relpos: After the first token in the condition clause of a 1033 ;; Anchor pos: After the first token in the condition clause of
1016 ;; for statement: At the first token after the starting paren. 1034 ;; a for statement: At the first token after the starting
1017 ;; Otherwise: At the containing statement(*). 1035 ;; paren. Otherwise: At the containing statement(*).
1018 (statement-block-intro . +) 1036 (statement-block-intro . +)
1019 ;; Relpos: In inexpr statement block: At the inexpr block open 1037 ;; Anchor pos: In inexpr statement block: At the inexpr block
1020 ;; if it's at boi, else at the statement(*) at boi of the start 1038 ;; open if it's at boi, else at the statement(*) at boi of the
1021 ;; of the inexpr construct. In a block hanging on a 1039 ;; start of the inexpr construct. In a block hanging on a
1022 ;; case/default label: At the closest preceding label that 1040 ;; case/default label: At the closest preceding label that
1023 ;; starts at boi. Otherwise: At the start of the containing 1041 ;; starts at boi. Otherwise: At the start of the containing
1024 ;; block(*). 1042 ;; block(*).
1025 (statement-case-intro . +) 1043 (statement-case-intro . +)
1026 ;; Relpos: At the case/default label(*). 1044 ;; Anchor pos: At the case/default label(*).
1027 (statement-case-open . 0) 1045 (statement-case-open . 0)
1028 ;; Relpos: At the case/default label(*). 1046 ;; Anchor pos: At the case/default label(*).
1029 (substatement . +) 1047 (substatement . +)
1030 ;; Relpos: At the containing statement(*). 1048 ;; Anchor pos: At the containing statement(*).
1031 (substatement-open . +) 1049 (substatement-open . +)
1032 ;; Relpos: At the containing statement(*). 1050 ;; Anchor pos: At the containing statement(*).
1033 (substatement-label . 2) 1051 (substatement-label . 2)
1034 ;; Relpos: At the containing statement(*). 1052 ;; Anchor pos: At the containing statement(*).
1035 (case-label . 0) 1053 (case-label . 0)
1036 ;; Relpos: At the start of the switch block(*). 1054 ;; Anchor pos: At the start of the switch block(*).
1037 (access-label . -) 1055 (access-label . -)
1038 ;; Relpos: Same as inclass. 1056 ;; Anchor pos: Same as inclass.
1039 (label . 2) 1057 (label . 2)
1040 ;; Relpos: At the start of the containing block(*). 1058 ;; Anchor pos: At the start of the containing block(*).
1041 (do-while-closure . 0) 1059 (do-while-closure . 0)
1042 ;; Relpos: At the corresponding while statement(*). 1060 ;; Anchor pos: At the corresponding while statement(*).
1043 (else-clause . 0) 1061 (else-clause . 0)
1044 ;; Relpos: At the corresponding if statement(*). 1062 ;; Anchor pos: At the corresponding if statement(*).
1045 (catch-clause . 0) 1063 (catch-clause . 0)
1046 ;; Relpos: At the previous try or catch statement clause(*). 1064 ;; Anchor pos: At the previous try or catch statement clause(*).
1047 (comment-intro . (c-lineup-knr-region-comment c-lineup-comment)) 1065 (comment-intro . (c-lineup-knr-region-comment c-lineup-comment))
1048 ;; Relpos: None. 1066 ;; Anchor pos: None.
1049 (arglist-intro . +) 1067 (arglist-intro . +)
1050 ;; Relpos: Boi at the open paren, or at the first non-ws after 1068 ;; Anchor pos: At the containing statement(*).
1051 ;; the open paren of the surrounding sexp, whichever is later. 1069 ;; 2nd pos: At the open paren.
1052 (arglist-cont . (c-lineup-gcc-asm-reg 0)) 1070 (arglist-cont . (c-lineup-gcc-asm-reg 0))
1053 ;; Relpos: At the first token after the open paren. 1071 ;; Anchor pos: At the first token after the open paren.
1054 (arglist-cont-nonempty . (c-lineup-gcc-asm-reg c-lineup-arglist)) 1072 (arglist-cont-nonempty . (c-lineup-gcc-asm-reg c-lineup-arglist))
1055 ;; Relpos: At the containing statement(*). 1073 ;; Anchor pos: At the containing statement(*).
1056 ;; 2nd pos: At the open paren. 1074 ;; 2nd pos: At the open paren.
1057 (arglist-close . +) 1075 (arglist-close . +)
1058 ;; Relpos: At the containing statement(*). 1076 ;; Anchor pos: At the containing statement(*).
1059 ;; 2nd pos: At the open paren. 1077 ;; 2nd pos: At the open paren.
1060 (stream-op . c-lineup-streamop) 1078 (stream-op . c-lineup-streamop)
1061 ;; Relpos: Boi at the first stream op in the statement. 1079 ;; Anchor pos: Boi at the first stream op in the statement.
1062 (inclass . +) 1080 (inclass . +)
1063 ;; Relpos: At the class open brace if it's at boi, otherwise 1081 ;; Anchor pos: At the class open brace if it's at boi,
1064 ;; boi at the class decl start. 1082 ;; otherwise boi at the class decl start.
1065 (cpp-macro . [0]) 1083 (cpp-macro . [0])
1066 ;; Relpos: None. 1084 ;; Anchor pos: None.
1067 (cpp-macro-cont . +) 1085 (cpp-macro-cont . +)
1068 ;; Relpos: At the macro start (always at boi). 1086 ;; Anchor pos: At the macro start (always at boi).
1069 (cpp-define-intro . (c-lineup-cpp-define +)) 1087 (cpp-define-intro . (c-lineup-cpp-define +))
1070 ;; Relpos: None. 1088 ;; Anchor pos: None.
1071 (friend . 0) 1089 (friend . 0)
1072 ;; Relpos: None. 1090 ;; Anchor pos: None.
1073 (objc-method-intro . [0]) 1091 (objc-method-intro . [0])
1074 ;; Relpos: Boi. 1092 ;; Anchor pos: Boi.
1075 (objc-method-args-cont . c-lineup-ObjC-method-args) 1093 (objc-method-args-cont . c-lineup-ObjC-method-args)
1076 ;; Relpos: At the method start (always at boi). 1094 ;; Anchor pos: At the method start (always at boi).
1077 (objc-method-call-cont . c-lineup-ObjC-method-call) 1095 (objc-method-call-cont . c-lineup-ObjC-method-call)
1078 ;; Relpos: At the open bracket. 1096 ;; Anchor pos: At the open bracket.
1079 (extern-lang-open . 0) 1097 (extern-lang-open . 0)
1080 (namespace-open . 0) 1098 (namespace-open . 0)
1081 (module-open . 0) 1099 (module-open . 0)
1082 (composition-open . 0) 1100 (composition-open . 0)
1083 ;; Relpos: Boi at the extern/namespace/etc keyword. 1101 ;; Anchor pos: Boi at the extern/namespace/etc keyword.
1084 (extern-lang-close . 0) 1102 (extern-lang-close . 0)
1085 (namespace-close . 0) 1103 (namespace-close . 0)
1086 (module-close . 0) 1104 (module-close . 0)
1087 (composition-close . 0) 1105 (composition-close . 0)
1088 ;; Relpos: Boi at the corresponding extern/namespace/etc keyword. 1106 ;; Anchor pos: Boi at the corresponding extern/namespace/etc keyword.
1089 (inextern-lang . +) 1107 (inextern-lang . +)
1090 (innamespace . +) 1108 (innamespace . +)
1091 (inmodule . +) 1109 (inmodule . +)
1092 (incomposition . +) 1110 (incomposition . +)
1093 ;; Relpos: At the extern/namespace/etc block open brace if it's 1111 ;; Anchor pos: At the extern/namespace/etc block open brace if
1094 ;; at boi, otherwise boi at the keyword. 1112 ;; it's at boi, otherwise boi at the keyword.
1095 (template-args-cont . (c-lineup-template-args +)) 1113 (template-args-cont . (c-lineup-template-args +))
1096 ;; Relpos: Boi at the decl start. This might be changed; the 1114 ;; Anchor pos: Boi at the decl start. This might be changed;
1097 ;; logical position is clearly the opening '<'. 1115 ;; the logical position is clearly the opening '<'.
1098 (inlambda . c-lineup-inexpr-block) 1116 (inlambda . c-lineup-inexpr-block)
1099 ;; Relpos: None. 1117 ;; Anchor pos: None.
1100 (lambda-intro-cont . +) 1118 (lambda-intro-cont . +)
1101 ;; Relpos: Boi at the lambda start. 1119 ;; Anchor pos: Boi at the lambda start.
1102 (inexpr-statement . +) 1120 (inexpr-statement . +)
1103 ;; Relpos: None. 1121 ;; Anchor pos: None.
1104 (inexpr-class . +) 1122 (inexpr-class . +)
1105 ;; Relpos: None. 1123 ;; Anchor pos: None.
1106 )) 1124 ))
1107(defcustom c-offsets-alist nil 1125(defcustom c-offsets-alist nil
1108 "Association list of syntactic element symbols and indentation offsets. 1126 "Association list of syntactic element symbols and indentation offsets.
@@ -1112,50 +1130,66 @@ As described below, each cons cell in this list has the form:
1112 1130
1113When a line is indented, CC Mode first determines the syntactic 1131When a line is indented, CC Mode first determines the syntactic
1114context of it by generating a list of symbols called syntactic 1132context of it by generating a list of symbols called syntactic
1115elements. This list can contain more than one syntactic element and 1133elements. The global variable `c-syntactic-context' is bound to the
1116the global variable `c-syntactic-context' contains the context list 1134that list. Each element in the list is in turn a list where the first
1117for the line being indented. Each element in this list is actually a 1135element is a syntactic symbol which tells what kind of construct the
1118cons cell of the syntactic symbol and a buffer position. This buffer 1136indentation point is located within. More elements in the syntactic
1119position is called the relative indent point for the line. Some 1137element lists are optional. If there is one more and it isn't nil,
1120syntactic symbols may not have a relative indent point associated with 1138then it's the anchor position for that construct.
1121them. 1139
1122 1140After generating the syntactic context for the line, CC Mode
1123After the syntactic context list for a line is generated, CC Mode 1141calculates the absolute indentation: First the base indentation is
1124calculates the absolute indentation for the line by looking at each 1142found by using the anchor position for the first syntactic element
1125syntactic element in the list. It compares the syntactic element 1143that provides one. If none does, zero is used as base indentation.
1126against the SYNTACTIC-SYMBOL's in `c-offsets-alist'. When it finds a 1144Then CC Mode looks at each syntactic element in the context in turn.
1127match, it adds the OFFSET to the column of the relative indent point. 1145It compares the car of the syntactic element against the
1128The sum of this calculation for each element in the syntactic list is 1146SYNTACTIC-SYMBOL's in `c-offsets-alist'. When it finds a match, it
1147adds OFFSET to the base indentation. The sum of this calculation is
1129the absolute offset for line being indented. 1148the absolute offset for line being indented.
1130 1149
1131If the syntactic element does not match any in the `c-offsets-alist', 1150If the syntactic element does not match any in the `c-offsets-alist',
1132the element is ignored. 1151the element is ignored.
1133 1152
1134If OFFSET is nil, the syntactic element is ignored in the offset 1153OFFSET can specify an offset in several different ways:
1135calculation. 1154
1155 If OFFSET is nil then it's ignored.
1156
1157 If OFFSET is an integer then it's used as relative offset, i.e. it's
1158 added to the base indentation.
1136 1159
1137If OFFSET is an integer, it's added to the relative indent. 1160 If OFFSET is one of the symbols `+', `-', `++', `--', `*', or `/'
1161 then a positive or negative multiple of `c-basic-offset' is added to
1162 the base indentation; 1, -1, 2, -2, 0.5, and -0.5, respectively.
1138 1163
1139If OFFSET is one of the symbols `+', `-', `++', `--', `*', or `/', a 1164 If OFFSET is a symbol with a value binding then that value, which
1140positive or negative multiple of `c-basic-offset' is added; 1, -1, 2, 1165 must be an integer, is used as relative offset.
1141-2, 0.5, and -0.5, respectively.
1142 1166
1143If OFFSET is a vector, it's first element, which must be an integer, 1167 If OFFSET is a vector then it's first element, which must be an
1144is used as an absolute indentation column. This overrides all 1168 integer, is used as an absolute indentation column. This overrides
1145relative offsets. If there are several syntactic elements which 1169 the previous base indentation and the relative offsets applied to
1146evaluates to absolute indentation columns, the first one takes 1170 it, and it becomes the new base indentation.
1147precedence. You can see in which order CC Mode combines the syntactic
1148elements in a certain context by using \\[c-show-syntactic-information] on the line.
1149 1171
1150If OFFSET is a function, it's called with a single argument 1172 If OFFSET is a function or a lambda expression then it's called with
1151containing the cons of the syntactic element symbol and the relative 1173 a single argument containing the cons of the syntactic symbol and
1152indent point. The return value from the function is then 1174 the anchor position (or nil if there is none). The return value
1153reinterpreted as an OFFSET value. 1175 from the function is then reinterpreted as an offset specification.
1154 1176
1155If OFFSET is a list, it's recursively evaluated using the semantics 1177 If OFFSET is a list then its elements are evaluated recursively as
1156described above. The first element of the list to return a non-nil 1178 offset specifications. If the first element is any of the symbols
1157value succeeds. If none of the elements returns a non-nil value, the 1179 below then it isn't evaluated but instead specifies how the
1158syntactic element is ignored. 1180 remaining offsets in the list should be combined. If it's something
1181 else then the list is combined according the method `first'. The
1182 valid combination methods are:
1183
1184 `first' -- Use the first offset (that doesn't evaluate to nil).
1185 `min' -- Use the minimum of all the offsets. All must be either
1186 relative or absolute - they can't be mixed.
1187 `max' -- Use the maximum of all the offsets. All must be either
1188 relative or absolute - they can't be mixed.
1189 `add' -- Add all the evaluated offsets together. Exactly one of
1190 them may be absolute, in which case the result is
1191 absolute. Any relative offsets that preceded the
1192 absolute one in the list will be ignored in that case.
1159 1193
1160`c-offsets-alist' is a style variable. This means that the offsets on 1194`c-offsets-alist' is a style variable. This means that the offsets on
1161this variable are normally taken from the style system in CC Mode 1195this variable are normally taken from the style system in CC Mode
@@ -1336,6 +1370,11 @@ The list of variables to buffer localize are:
1336 :type 'hook 1370 :type 'hook
1337 :group 'c) 1371 :group 'c)
1338 1372
1373(defcustom awk-mode-hook nil
1374 "*Hook called by `awk-mode'."
1375 :type 'hook
1376 :group 'c)
1377
1339(defcustom c-mode-common-hook nil 1378(defcustom c-mode-common-hook nil
1340 "*Hook called by all CC Mode modes for common initializations." 1379 "*Hook called by all CC Mode modes for common initializations."
1341 :type 'hook 1380 :type 'hook
@@ -1380,16 +1419,17 @@ working due to this change.")
1380 :args '((const :tag "none" nil) 1419 :args '((const :tag "none" nil)
1381 (repeat :tag "types" regexp))) 1420 (repeat :tag "types" regexp)))
1382 1421
1383(eval-and-compile 1422(defun c-make-font-lock-extra-types-blurb (mode1 mode2 example)
1384 ;; XEmacs 19 evaluates this at compile time below, while most other 1423 (concat "\
1385 ;; versions delays the evaluation until the package is loaded.
1386 (defun c-make-font-lock-extra-types-blurb (mode1 mode2 example)
1387 (concat "\
1388*List of extra types (aside from the type keywords) to recognize in " 1424*List of extra types (aside from the type keywords) to recognize in "
1389mode1 " mode. 1425mode1 " mode.
1390Each list item should be a regexp matching a single identifier. 1426Each list item should be a regexp matching a single identifier.
1391" example " 1427" example "
1392 1428
1429Note that items on this list that don't include any regexp special
1430characters are automatically optimized using `regexp-opt', so you
1431should not use `regexp-opt' explicitly to build regexps here.
1432
1393On decoration level 3 (and higher, where applicable), a method is used 1433On decoration level 3 (and higher, where applicable), a method is used
1394that finds most types and declarations by syntax alone. This variable 1434that finds most types and declarations by syntax alone. This variable
1395is still used as a first step, but other types are recognized 1435is still used as a first step, but other types are recognized
@@ -1401,43 +1441,58 @@ initialized. If you change it later you have to reinitialize CC Mode
1401by doing \\[" mode2 "]. 1441by doing \\[" mode2 "].
1402 1442
1403Despite the name, this variable is not only used for font locking but 1443Despite the name, this variable is not only used for font locking but
1404also elsewhere in CC Mode to tell types from other identifiers."))) 1444also elsewhere in CC Mode to tell types from other identifiers."))
1405 1445
1406;; Note: Most of the variables below are also defined in font-lock.el 1446;; Note: Most of the variables below are also defined in font-lock.el
1407;; in older versions in Emacs, so depending on the load order we might 1447;; in older versions of Emacs, so depending on the load order we might
1408;; not install the values below. There's no kludge to cope with this 1448;; not install the values below. There's no kludge to cope with this
1409;; (as opposed to the *-font-lock-keywords-* variables) since the old 1449;; (as opposed to the *-font-lock-keywords-* variables) since the old
1410;; values work fairly well anyway. 1450;; values work fairly well anyway.
1411 1451
1412(defcustom c-font-lock-extra-types 1452(defcustom c-font-lock-extra-types
1413 '("FILE" "\\sw+_t" 1453 '("\\sw+_t"
1414 "bool" "complex" "imaginary" ; Defined in C99. 1454 ;; Defined in C99:
1455 "bool" "complex" "imaginary"
1456 ;; Standard library types (except those matched by the _t pattern):
1457 "FILE" "lconv" "tm" "va_list" "jmp_buf"
1415 ;; I do not appreciate the following very Emacs-specific luggage 1458 ;; I do not appreciate the following very Emacs-specific luggage
1416 ;; in the default value, but otoh it can hardly get in the way for 1459 ;; in the default value, but otoh it can hardly get in the way for
1417 ;; other users, and removing it would cause unnecessary grief for 1460 ;; other users, and removing it would cause unnecessary grief for
1418 ;; the old timers that are used to it. /mast 1461 ;; the old timers that are used to it. /mast
1419 "Lisp_Object") 1462 "Lisp_Object")
1420 (c-make-font-lock-extra-types-blurb "C" "c-mode" 1463 (c-make-font-lock-extra-types-blurb "C" "c-mode"
1421"For example, a value of (\"FILE\" \"\\\\sw+_t\") means the word FILE 1464"For example, a value of (\"FILE\" \"\\\\sw+_t\") means the word \"FILE\"
1422and words ending in _t are treated as type names.") 1465and words ending in \"_t\" are treated as type names.")
1423 :type 'c-extra-types-widget 1466 :type 'c-extra-types-widget
1424 :group 'c) 1467 :group 'c)
1425 1468
1426(defcustom c++-font-lock-extra-types 1469(defcustom c++-font-lock-extra-types
1427 '("\\sw+_t" 1470 '("\\sw+_t"
1428 "\\([iof]\\|str\\)+stream\\(buf\\)?" "ios" 1471 ;; C library types (except those matched by the _t pattern):
1472 "FILE" "lconv" "tm" "va_list" "jmp_buf"
1473 ;; Some standard C++ types that came from font-lock.el.
1474 ;; Experienced C++ users says there's no clear benefit in
1475 ;; extending this to all the types in the standard library, at
1476 ;; least not when they'll be recognized without "std::" too.
1477 "istream" "istreambuf"
1478 "ostream" "ostreambuf"
1479 "ifstream" "ofstream" "fstream"
1480 "strstream" "strstreambuf" "istrstream" "ostrstream"
1481 "ios"
1429 "string" "rope" 1482 "string" "rope"
1430 "list" "slist" 1483 "list" "slist"
1431 "deque" "vector" "bit_vector" 1484 "deque" "vector" "bit_vector"
1432 "set" "multiset" 1485 "set" "multiset"
1433 "map" "multimap" 1486 "map" "multimap"
1434 "hash\\(_\\(m\\(ap\\|ulti\\(map\\|set\\)\\)\\|set\\)\\)?" 1487 "hash"
1488 "hash_set" "hash_multiset"
1489 "hash_map" "hash_multimap"
1435 "stack" "queue" "priority_queue" 1490 "stack" "queue" "priority_queue"
1436 "type_info" 1491 "type_info"
1437 "iterator" "const_iterator" "reverse_iterator" "const_reverse_iterator" 1492 "iterator" "const_iterator" "reverse_iterator" "const_reverse_iterator"
1438 "reference" "const_reference") 1493 "reference" "const_reference")
1439 (c-make-font-lock-extra-types-blurb "C++" "c++-mode" 1494 (c-make-font-lock-extra-types-blurb "C++" "c++-mode"
1440"For example, a value of (\"string\") means the word string is treated 1495"For example, a value of (\"string\") means the word \"string\" is treated
1441as a type name.") 1496as a type name.")
1442 :type 'c-extra-types-widget 1497 :type 'c-extra-types-widget
1443 :group 'c) 1498 :group 'c)
@@ -1499,40 +1554,49 @@ Note that file offset settings are applied after file style settings
1499as designated in the variable `c-file-style'.") 1554as designated in the variable `c-file-style'.")
1500(make-variable-buffer-local 'c-file-offsets) 1555(make-variable-buffer-local 'c-file-offsets)
1501 1556
1502;; It isn't possible to specify a docstring without specifying an 1557;; It isn't possible to specify a doc-string without specifying an
1503;; initial value with `defvar', so the following two variables have 1558;; initial value with `defvar', so the following two variables have been
1504;; only doc comments even though they are part of the API. It's 1559;; given doc-strings by setting the property `variable-documentation'
1505;; really good not to have an initial value for variables like these 1560;; directly. C-h v will read this documentation only for versions of GNU
1506;; that always should be dynamically bound, so it's worth the 1561;; Emacs from 22.1. It's really good not to have an initial value for
1507;; inconvenience. 1562;; variables like these that always should be dynamically bound, so it's
1563;; worth the inconvenience.
1508 1564
1509(cc-bytecomp-defvar c-syntactic-context) 1565(cc-bytecomp-defvar c-syntactic-context)
1510(defvar c-syntactic-context) 1566(defvar c-syntactic-context)
1511;; Variable containing the syntactic analysis list during indentation. 1567(put 'c-syntactic-context 'variable-documentation
1512;; It is a list with one element for each found syntactic symbol. See 1568 "Variable containing the syntactic analysis list for a line of code.
1513;; `c-syntactic-element' for further info. 1569
1514;; 1570It is a list with one element for each syntactic symbol pertinent to the
1515;; This is always bound dynamically. It should never be set 1571line, for example \"((defun-block-intro 1) (comment-intro))\".
1516;; statically (e.g. with `setq'). 1572
1573It is dynamically bound when calling \(i) a brace hanging \"action
1574function\"; \(ii) a semicolon/comma hanging \"criteria function\"; \(iii) a
1575\"line-up function\"; \(iv) a c-special-indent-hook function. It is also
1576used internally by CC Mode.
1577
1578c-syntactic-context is always bound dynamically. It must NEVER be set
1579statically (e.g. with `setq').")
1580
1517 1581
1518(cc-bytecomp-defvar c-syntactic-element) 1582(cc-bytecomp-defvar c-syntactic-element)
1519(defvar c-syntactic-element) 1583(defvar c-syntactic-element)
1520;; Variable containing the info regarding the current syntactic 1584(put 'c-syntactic-element 'variable-documentation
1521;; element during calls to the lineup functions. The value is one of 1585 "Variable containing the current syntactic element during calls to
1522;; the elements in the list in `c-syntactic-context' and is a list 1586the lineup functions. The value is one of the elements in the list in
1523;; with the symbol name in the first position, followed by zero or 1587`c-syntactic-context' and is a list with the symbol name in the first
1524;; more elements containing any additional info associated with the 1588position, followed by zero or more elements containing any additional
1525;; syntactic symbol. There are accessor functions `c-langelem-sym', 1589info associated with the syntactic symbol. There are accessor functions
1526;; `c-langelem-pos', `c-langelem-col', and `c-langelem-2nd-pos' to 1590`c-langelem-sym', `c-langelem-pos', `c-langelem-col', and
1527;; access the list. 1591`c-langelem-2nd-pos' to access the list.
1528;; 1592
1529;; Specifically, the element returned by `c-langelem-pos' is the 1593Specifically, the element returned by `c-langelem-pos' is the anchor
1530;; relpos (a.k.a. anchor position), or nil if there isn't any. See 1594position, or nil if there isn't any. See the comments in the
1531;; the comments in the `c-offsets-alist' variable for more detailed 1595`c-offsets-alist' variable and the CC Mode manual for more detailed info
1532;; info about the data each syntactic symbol provides. 1596about the data each syntactic symbol provides.
1533;; 1597
1534;; This is always bound dynamically. It should never be set 1598This is always bound dynamically. It should never be set
1535;; statically (e.g. with `setq'). 1599statically (e.g. with `setq').")
1536 1600
1537(defvar c-indentation-style nil 1601(defvar c-indentation-style nil
1538 "Name of the currently installed style. 1602 "Name of the currently installed style.
@@ -1543,6 +1607,29 @@ Don't change this directly; call `c-set-style' instead.")
1543Set from `c-comment-prefix-regexp' at mode initialization.") 1607Set from `c-comment-prefix-regexp' at mode initialization.")
1544(make-variable-buffer-local 'c-current-comment-prefix) 1608(make-variable-buffer-local 'c-current-comment-prefix)
1545 1609
1610;; N.B. The next three variables are initialized in
1611;; c-setup-paragraph-variables. Their initializations here are "just in
1612;; case". ACM, 2004/2/15. They are NOT buffer local (yet?).
1613(defvar c-string-par-start
1614;; (concat "\\(" (default-value 'paragraph-start) "\\)\\|[ \t]*\\\\$")
1615 "\f\\|[ \t]*\\\\?$"
1616 "Value of paragraph-start used when scanning strings.
1617It treats escaped EOLs as whitespace.")
1618
1619(defvar c-string-par-separate
1620 ;; (concat "\\(" (default-value 'paragraph-separate) "\\)\\|[ \t]*\\\\$")
1621 "[ \t\f]*\\\\?$"
1622 "Value of paragraph-separate used when scanning strings.
1623It treats escaped EOLs as whitespace.")
1624
1625(defvar c-sentence-end-with-esc-eol
1626 (concat "\\(\\(" (c-default-value-sentence-end) "\\)"
1627 ;; N.B.: "$" would be illegal when not enclosed like "\\($\\)".
1628 "\\|" "[.?!][]\"')}]* ?\\\\\\($\\)[ \t\n]*"
1629 "\\)")
1630 "Value used like sentence-end used when scanning strings.
1631It treats escaped EOLs as whitespace.")
1632
1546 1633
1547(cc-provide 'cc-vars) 1634(cc-provide 'cc-vars)
1548 1635