(Fbase64_encode_string): New optional argument `NO_LINE_BREAK'.
[bpt/emacs.git] / lisp / progmodes / cc-engine.el
Content-type: text/html HCoop Git - bpt/emacs.git/blame - lisp/progmodes/cc-engine.el


500 - Internal Server Error

Malformed UTF-8 character (fatal) at (eval 8) line 1, <$fd> line 2394.
CommitLineData
785eecbb
RS
1;;; cc-engine.el --- core syntax guessing engine for CC mode
2
e1c458ae 3;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
785eecbb 4
0ec8351b
BW
5;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
6;; 1992-1997 Barry A. Warsaw
785eecbb
RS
7;; 1987 Dave Detlefs and Stewart Clamen
8;; 1985 Richard M. Stallman
0ec8351b 9;; Maintainer: bug-cc-mode@gnu.org
785eecbb 10;; Created: 22-Apr-1997 (split from cc-mode.el)
6430c434 11;; Version: See cc-mode.el
785eecbb
RS
12;; Keywords: c languages oop
13
14;; This file is part of GNU Emacs.
15
16;; GNU Emacs is free software; you can redistribute it and/or modify
17;; it under the terms of the GNU General Public License as published by
18;; the Free Software Foundation; either version 2, or (at your option)
19;; any later version.
20
21;; GNU Emacs is distributed in the hope that it will be useful,
22;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24;; GNU General Public License for more details.
25
26;; 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 the
28;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
29;; Boston, MA 02111-1307, USA.
30
31\f
0ec8351b
BW
32(eval-when-compile
33 (require 'cc-defs))
34
64001211
RS
35;; KLUDGE ALERT: c-maybe-labelp is used to pass information between
36;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A
37;; better way should be implemented, but this will at least shut up
38;; the byte compiler.
39(defvar c-maybe-labelp nil)
40
41;; WARNING WARNING WARNING
42;;
43;; Be *exceptionally* careful about modifications to this function!
44;; Much of CC Mode depends on this Doing The Right Thing. If you
45;; break it you will be sorry. If you think you know how this works,
46;; you probably don't. No human on Earth does! :-)
47;;
48;; WARNING WARNING WARNING
785eecbb
RS
49
50(defun c-beginning-of-statement-1 (&optional lim)
51 ;; move to the start of the current statement, or the previous
52 ;; statement if already at the beginning of one.
53 (let ((firstp t)
54 (substmt-p t)
64001211 55 donep c-in-literal-cache saved
785eecbb
RS
56 (last-begin (point)))
57 ;; first check for bare semicolon
58 (if (and (progn (c-backward-syntactic-ws lim)
59 (eq (char-before) ?\;))
60 (c-safe (progn (forward-char -1)
61 (setq saved (point))
62 t))
63 (progn (c-backward-syntactic-ws lim)
d0c50a29 64 (memq (char-before) '(?\; ?{ ?:)))
785eecbb
RS
65 )
66 (setq last-begin saved)
67 (goto-char last-begin)
68 (while (not donep)
69 ;; stop at beginning of buffer
70 (if (bobp) (setq donep t)
71 ;; go backwards one balanced expression, but be careful of
72 ;; unbalanced paren being reached
0ec8351b 73 (if (not (c-safe (progn (c-backward-sexp 1) t)))
785eecbb
RS
74 (progn
75 (if firstp
76 (backward-up-list 1)
77 (goto-char last-begin))
78 ;; skip over any unary operators, or other special
79 ;; characters appearing at front of identifier
80 (save-excursion
81 (c-backward-syntactic-ws lim)
0ec8351b 82 (skip-chars-backward "-+!*&:.~@ \t\n")
785eecbb
RS
83 (if (eq (char-before) ?\()
84 (setq last-begin (point))))
85 (goto-char last-begin)
86 (setq last-begin (point)
87 donep t)))
88
64001211 89 (setq c-maybe-labelp nil)
785eecbb
RS
90 ;; see if we're in a literal. if not, then this bufpos may be
91 ;; a candidate for stopping
92 (cond
93 ;; CASE 0: did we hit the error condition above?
94 (donep)
95 ;; CASE 1: are we in a literal?
96 ((eq (c-in-literal lim) 'pound)
97 (beginning-of-line))
98 ;; CASE 2: some other kind of literal?
99 ((c-in-literal lim))
100 ;; CASE 3: are we looking at a conditional keyword?
101 ((or (looking-at c-conditional-key)
102 (and (eq (char-after) ?\()
103 (save-excursion
0ec8351b 104 (c-forward-sexp 1)
785eecbb
RS
105 (c-forward-syntactic-ws)
106 (not (eq (char-after) ?\;)))
107 (let ((here (point))
108 (foundp (progn
109 (c-backward-syntactic-ws lim)
110 (forward-word -1)
111 (and lim
112 (<= lim (point))
113 (not (c-in-literal lim))
6430c434 114 (not (eq (char-before) ?_))
785eecbb
RS
115 (looking-at c-conditional-key)
116 ))))
117 ;; did we find a conditional?
118 (if (not foundp)
119 (goto-char here))
120 foundp)))
121 ;; are we in the middle of an else-if clause?
122 (if (save-excursion
123 (and (not substmt-p)
0ec8351b 124 (c-safe (progn (c-forward-sexp -1) t))
785eecbb
RS
125 (looking-at "\\<else\\>[ \t\n]+\\<if\\>")
126 (not (c-in-literal lim))))
127 (progn
0ec8351b 128 (c-forward-sexp -1)
785eecbb
RS
129 (c-backward-to-start-of-if lim)))
130 ;; are we sitting at an else clause, that we are not a
131 ;; substatement of?
132 (if (and (not substmt-p)
133 (looking-at "\\<else\\>[^_]"))
134 (c-backward-to-start-of-if lim))
0ec8351b
BW
135 ;; a finally or a series of catches?
136 (if (not substmt-p)
137 (while (looking-at "\\<\\(catch\\|finally\\)\\>[^_]")
138 (c-safe (c-backward-sexp 2))
139 (if (eq (char-after) ?\()
140 (c-safe (c-backward-sexp)))))
785eecbb
RS
141 ;; are we sitting at the while of a do-while?
142 (if (and (looking-at "\\<while\\>[^_]")
143 (c-backward-to-start-of-do lim))
144 (setq substmt-p nil))
145 (setq last-begin (point)
146 donep substmt-p))
147 ;; CASE 4: are we looking at a label?
148 ((looking-at c-label-key))
149 ;; CASE 5: is this the first time we're checking?
150 (firstp (setq firstp nil
151 substmt-p (not (c-crosses-statement-barrier-p
152 (point) last-begin))
153 last-begin (point)))
154 ;; CASE 6: have we crossed a statement barrier?
0ec8351b
BW
155 ((save-excursion
156 ;; Move over in-expression blocks before checking the
157 ;; barrier
158 (if (or (memq (char-after) '(?\( ?\[))
159 (and (eq (char-after) ?{)
160 (c-looking-at-inexpr-block lim)))
161 (c-forward-sexp 1))
162 (c-crosses-statement-barrier-p (point) last-begin))
785eecbb
RS
163 (setq donep t))
164 ;; CASE 7: ignore labels
64001211 165 ((and c-maybe-labelp
785eecbb
RS
166 (or (and c-access-key (looking-at c-access-key))
167 ;; with switch labels, we have to go back further
168 ;; to try to pick up the case or default
169 ;; keyword. Potential bogosity alert: we assume
170 ;; `case' or `default' is first thing on line
171 (let ((here (point)))
172 (beginning-of-line)
173 (c-forward-syntactic-ws)
174 (if (looking-at c-switch-label-key)
175 t
176 (goto-char here)
177 nil))
178 (looking-at c-label-key))))
179 ;; CASE 8: ObjC or Java method def
180 ((and c-method-key
181 (setq last-begin (c-in-method-def-p)))
182 (setq donep t))
183 ;; CASE 9: nothing special
184 (t (setq last-begin (point)))
185 ))))
186 (goto-char last-begin)
0ec8351b
BW
187 ;; We always want to skip over the non-whitespace modifier
188 ;; characters that can start a statement.
189 (let ((lim (point)))
190 (skip-chars-backward "-+!*&~@ \t\n" (c-point 'boi))
191 (skip-chars-forward " \t\n" lim))))
785eecbb
RS
192
193(defun c-end-of-statement-1 ()
041ec7f6
RS
194 (condition-case nil
195 (let (beg end found)
785eecbb 196 (while (and (not (eobp))
041ec7f6
RS
197 (progn
198 (setq beg (point))
0ec8351b 199 (c-forward-sexp 1)
041ec7f6
RS
200 (setq end (point))
201 (goto-char beg)
202 (setq found nil)
203 (while (and (not found)
204 (re-search-forward "[;{}]" end t))
205 (if (not (c-in-literal beg))
206 (setq found t)))
207 (not found)))
208 (goto-char end))
209 (re-search-backward "[;{}]")
785eecbb 210 (forward-char 1))
9796cb5b 211 (error
785eecbb 212 (let ((beg (point)))
9796cb5b 213 (c-safe (backward-up-list -1))
785eecbb
RS
214 (let ((end (point)))
215 (goto-char beg)
9796cb5b
RS
216 (search-forward ";" end 'move)))
217 )))
785eecbb
RS
218
219\f
220(defun c-crosses-statement-barrier-p (from to)
221 ;; Does buffer positions FROM to TO cross a C statement boundary?
222 (let ((here (point))
223 (lim from)
224 crossedp)
225 (condition-case ()
226 (progn
227 (goto-char from)
228 (while (and (not crossedp)
229 (< (point) to))
0ec8351b 230 (skip-chars-forward "^;{}:" (1- to))
785eecbb
RS
231 (if (not (c-in-literal lim))
232 (progn
233 (if (memq (char-after) '(?\; ?{ ?}))
234 (setq crossedp t)
235 (if (eq (char-after) ?:)
64001211 236 (setq c-maybe-labelp t))
785eecbb
RS
237 (forward-char 1))
238 (setq lim (point)))
239 (forward-char 1))))
240 (error (setq crossedp nil)))
241 (goto-char here)
242 crossedp))
243
244\f
245;; Skipping of "syntactic whitespace", defined as lexical whitespace,
246;; C and C++ style comments, and preprocessor directives. Search no
247;; farther back or forward than optional LIM. If LIM is omitted,
248;; `beginning-of-defun' is used for backward skipping, point-max is
249;; used for forward skipping.
250
251(defun c-forward-syntactic-ws (&optional lim)
252 ;; Forward skip of syntactic whitespace for Emacs 19.
e1c458ae
RS
253 (let* ((here (point-max))
254 (hugenum (point-max)))
255 (while (/= here (point))
256 (setq here (point))
257 (forward-comment hugenum)
258 ;; skip preprocessor directives
259 (when (and (eq (char-after) ?#)
785eecbb 260 (= (c-point 'boi) (point)))
e1c458ae
RS
261 (while (eq (char-before (c-point 'eol)) ?\\)
262 (forward-line 1))
263 (end-of-line))
264 )
265 (if lim (goto-char (min (point) lim)))))
266
267(defsubst c-beginning-of-macro (&optional lim)
268 ;; Go to the beginning of a cpp macro definition. Leaves point at
269 ;; the beginning of the macro and returns t if in a cpp macro
270 ;; definition, otherwise returns nil and leaves point unchanged.
271 ;; `lim' is currently ignored, but the interface requires it.
272 (let ((here (point)))
273 (beginning-of-line)
274 (while (eq (char-before (1- (point))) ?\\)
275 (forward-line -1))
276 (back-to-indentation)
277 (if (eq (char-after) ?#)
278 t
279 (goto-char here)
280 nil)))
785eecbb
RS
281
282(defun c-backward-syntactic-ws (&optional lim)
283 ;; Backward skip over syntactic whitespace for Emacs 19.
e1c458ae
RS
284 (let* ((here (point-min))
285 (hugenum (- (point-max))))
286 (while (/= here (point))
287 (setq here (point))
288 (forward-comment hugenum)
289 (c-beginning-of-macro))
290 (if lim (goto-char (max (point) lim)))))
785eecbb
RS
291
292\f
b2acd789 293;; Moving by tokens, where a token is defined as all symbols and
0ec8351b
BW
294;; identifiers which aren't syntactic whitespace (note that "->" is
295;; considered to be two tokens). Point is always either left at the
296;; beginning of a token or not moved at all. COUNT specifies the
297;; number of tokens to move; a negative COUNT moves in the opposite
298;; direction. A COUNT of 0 moves to the next token beginning only if
299;; not already at one. If BALANCED is true, move over balanced
300;; parens, otherwise move into them. Also, if BALANCED is true, never
301;; move out of an enclosing paren. LIM sets the limit for the
302;; movement and defaults to the point limit. Returns the number of
b2acd789 303;; tokens left to move (positive or negative). If BALANCED is true, a
0ec8351b
BW
304;; move over a balanced paren counts as one. Note that if COUNT is 0
305;; and no appropriate token beginning is found, 1 will be returned.
306;; Thus, a return value of 0 guarantees that point is at the requested
307;; position and a return value less (without signs) than COUNT
308;; guarantees that point is at the beginning of some token.
b2acd789
RS
309
310(defun c-forward-token-1 (&optional count balanced lim)
0ec8351b
BW
311 (or count (setq count 1))
312 (if (< count 0)
313 (- (c-backward-token-1 (- count) balanced lim))
314 (let ((jump-syntax (if balanced
315 '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?')
316 '(?w ?_ ?\" ?\\ ?/ ?')))
317 (last (point))
318 (prev (point)))
319 (if (/= (point)
320 (progn (c-forward-syntactic-ws) (point)))
321 ;; Skip whitespace. Count this as a move if we did in fact
322 ;; move and aren't out of bounds.
323 (or (eobp)
324 (and lim (> (point) lim))
325 (setq count (max (1- count) 0))))
326 (if (and (= count 0)
327 (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
328 (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
329 (eobp)))
330 ;; If count is zero we should jump if in the middle of a
331 ;; token or if there is whitespace between point and the
332 ;; following token beginning.
333 (setq count 1))
334 ;; Avoid having the limit tests inside the loop.
335 (save-restriction
336 (if lim (narrow-to-region (point-min) lim))
337 (if (eobp)
338 (goto-char last)
339 (condition-case nil
340 (while (> count 0)
341 (setq prev last
342 last (point))
343 (if (memq (char-syntax (char-after)) jump-syntax)
344 (goto-char (scan-sexps (point) 1))
345 (forward-char))
346 (c-forward-syntactic-ws lim)
347 (setq count (1- count)))
348 (error (goto-char last)))
349 (when (eobp)
350 (goto-char prev)
351 (setq count (1+ count)))))
352 count)))
b2acd789
RS
353
354(defun c-backward-token-1 (&optional count balanced lim)
0ec8351b
BW
355 (or count (setq count 1))
356 (if (< count 0)
357 (- (c-forward-token-1 (- count) balanced lim))
358 (let ((jump-syntax (if balanced
359 '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?')
360 '(?w ?_ ?\" ?\\ ?/ ?')))
361 last)
362 (if (and (= count 0)
363 (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
364 (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
365 (/= (point)
366 (save-excursion (c-forward-syntactic-ws) (point)))
367 (eobp)))
368 ;; If count is zero we should jump if in the middle of a
369 ;; token or if there is whitespace between point and the
370 ;; following token beginning.
371 (setq count 1))
372 ;; Avoid having the limit tests inside the loop.
373 (save-restriction
374 (if lim (narrow-to-region lim (point-max)))
375 (or (bobp)
376 (progn
377 (condition-case nil
378 (while (progn
379 (setq last (point))
380 (> count 0))
381 (c-backward-syntactic-ws lim)
382 (if (memq (char-syntax (char-before)) jump-syntax)
383 (goto-char (scan-sexps (point) -1))
384 (backward-char))
385 (setq count (1- count)))
386 (error (goto-char last)))
387 (if (bobp) (goto-char last)))))
388 count)))
b2acd789
RS
389
390\f
785eecbb
RS
391;; Return `c' if in a C-style comment, `c++' if in a C++ style
392;; comment, `string' if in a string literal, `pound' if on a
393;; preprocessor line, or nil if not in a comment at all. Optional LIM
394;; is used as the backward limit of the search. If omitted, or nil,
395;; `beginning-of-defun' is used."
396
397(defun c-in-literal (&optional lim)
398 ;; Determine if point is in a C++ literal. we cache the last point
399 ;; calculated if the cache is enabled
400 (if (and (boundp 'c-in-literal-cache)
401 c-in-literal-cache
402 (= (point) (aref c-in-literal-cache 0)))
403 (aref c-in-literal-cache 1)
404 (let ((rtn (save-excursion
405 (let* ((lim (or lim (c-point 'bod)))
785eecbb
RS
406 (state (parse-partial-sexp lim (point))))
407 (cond
408 ((nth 3 state) 'string)
409 ((nth 4 state) (if (nth 7 state) 'c++ 'c))
e1c458ae 410 ((c-beginning-of-macro lim) 'pound)
785eecbb
RS
411 (t nil))))))
412 ;; cache this result if the cache is enabled
413 (and (boundp 'c-in-literal-cache)
414 (setq c-in-literal-cache (vector (point) rtn)))
415 rtn)))
416
e1c458ae
RS
417;; XEmacs has a built-in function that should make this much quicker.
418;; I don't think we even need the cache, which makes our lives more
419;; complicated anyway. In this case, lim is ignored.
420(defun c-fast-in-literal (&optional lim)
421 (let ((context (buffer-syntactic-context)))
422 (cond
423 ((eq context 'string) 'string)
424 ((eq context 'comment) 'c++)
425 ((eq context 'block-comment) 'c)
426 ((save-excursion (c-beginning-of-macro lim)) 'pound))))
427
428(if (fboundp 'buffer-syntactic-context)
429 (defalias 'c-in-literal 'c-fast-in-literal))
430
0ec8351b 431(defun c-literal-limits (&optional lim near)
e1c458ae
RS
432 ;; Returns a cons of the beginning and end positions of the comment
433 ;; or string surrounding point (including both delimiters), or nil
0ec8351b
BW
434 ;; if point isn't in one. If LIM is non-nil, it's used as the
435 ;; "safe" position to start parsing from. If NEAR is non-nil, then
436 ;; the limits of any literal next to point is returned. "Next to"
437 ;; means there's only [ \t] between point and the literal. The
438 ;; search for such a literal is done first in forward direction.
439 ;;
440 ;; This is the Emacs 19 version.
e1c458ae 441 (save-excursion
0ec8351b
BW
442 (let* ((pos (point))
443 (lim (or lim (c-point 'bod)))
e1c458ae
RS
444 (state (parse-partial-sexp lim (point))))
445 (cond ((nth 3 state)
446 ;; String. Search backward for the start.
447 (while (nth 3 state)
448 (search-backward (make-string 1 (nth 3 state)))
449 (setq state (parse-partial-sexp lim (point))))
0ec8351b 450 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
e1c458ae
RS
451 (point-max))))
452 ((nth 7 state)
0ec8351b 453 ;; Line comment. Search from bol for the comment starter.
e1c458ae
RS
454 (beginning-of-line)
455 (setq state (parse-partial-sexp lim (point))
456 lim (point))
457 (while (not (nth 7 state))
458 (search-forward "//") ; Should never fail.
459 (setq state (parse-partial-sexp
460 lim (point) nil nil state)
461 lim (point)))
462 (backward-char 2)
463 (cons (point) (progn (forward-comment 1) (point))))
464 ((nth 4 state)
0ec8351b 465 ;; Block comment. Search backward for the comment starter.
e1c458ae
RS
466 (while (nth 4 state)
467 (search-backward "/*") ; Should never fail.
468 (setq state (parse-partial-sexp lim (point))))
469 (cons (point) (progn (forward-comment 1) (point))))
470 ((c-safe (nth 4 (parse-partial-sexp ; Can't use prev state due
471 lim (1+ (point))))) ; to bug in Emacs 19.34.
472 ;; We're standing in a comment starter.
473 (backward-char 2)
474 (cons (point) (progn (forward-comment 1) (point))))
0ec8351b
BW
475 (near
476 (goto-char pos)
477 ;; Search forward for a literal.
478 (skip-chars-forward " \t")
479 (cond
480 ((eq (char-syntax (or (char-after) ?\ )) ?\") ; String.
481 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
482 (point-max))))
483 ((looking-at "/[/*]") ; Line or block comment.
484 (cons (point) (progn (forward-comment 1) (point))))
485 (t
486 ;; Search backward.
487 (skip-chars-backward " \t")
488 (let ((end (point)) beg)
489 (cond
490 ((eq (char-syntax (or (char-before) ?\ )) ?\") ; String.
491 (setq beg (c-safe (c-backward-sexp 1) (point))))
492 ((and (c-safe (forward-char -2) t)
493 (looking-at "*/"))
494 ;; Block comment. Due to the nature of line
495 ;; comments, they will always be covered by the
496 ;; normal case above.
497 (goto-char end)
498 (forward-comment -1)
499 ;; If LIM is bogus, beg will be bogus.
500 (setq beg (point))))
501 (if beg (cons beg end))))))
e1c458ae
RS
502 ))))
503
504(defun c-literal-limits-fast (&optional lim)
0ec8351b
BW
505 ;; Like c-literal-limits, but for emacsen whose `parse-partial-sexp'
506 ;; returns the pos of the comment start. FIXME: Add NEAR.
e1c458ae
RS
507 (save-excursion
508 (let ((state (parse-partial-sexp lim (point))))
509 (cond ((nth 3 state) ; String.
510 (goto-char (nth 8 state))
0ec8351b 511 (cons (point) (or (c-safe (c-forward-sexp 1) (point))
e1c458ae
RS
512 (point-max))))
513 ((nth 4 state) ; Comment.
514 (goto-char (nth 8 state))
515 (cons (point) (progn (forward-comment 1) (point))))
516 ((c-safe
517 (nth 4 (parse-partial-sexp ; Works?
518 (point) (1+ (point)) nil nil state)))
519 ;; We're in a comment starter.
520 (backward-char 2)
521 (cons (point) (progn (forward-comment 1) (point))))
522 ))))
523
524(defun c-collect-line-comments (range)
525 ;; If the argument is a cons of two buffer positions (such as
526 ;; returned by c-literal-limits), and that range contains a C++
527 ;; style line comment, then an extended range is returned that
b2acd789
RS
528 ;; contains all adjacent line comments (i.e. all comments that
529 ;; starts in the same column with no empty lines or non-whitespace
530 ;; characters between them). Otherwise the argument is returned.
e1c458ae
RS
531 (save-excursion
532 (condition-case nil
533 (if (and (consp range) (progn
534 (goto-char (car range))
535 (looking-at "//")))
b2acd789
RS
536 (let ((col (current-column))
537 (beg (point))
538 (end (cdr range)))
e1c458ae
RS
539 (while (and (not (bobp))
540 (forward-comment -1)
b2acd789
RS
541 (looking-at "//")
542 (= col (current-column)))
e1c458ae 543 (setq beg (point)))
b2acd789
RS
544 (goto-char end)
545 (while (progn
546 (skip-chars-forward " \t")
547 (and (looking-at "//")
548 (= col (current-column))))
549 (forward-comment 1)
550 (setq end (point)))
551 (cons beg end))
e1c458ae
RS
552 range)
553 (error range))))
554
0ec8351b
BW
555(defun c-literal-type (range)
556 ;; Convenience function that given the result of c-literal-limits,
557 ;; returns nil or the type of literal that the range surrounds.
558 ;; It's much faster than using c-in-literal and is intended to be
559 ;; used when you need both the type of a literal and its limits.
560 (if (consp range)
561 (save-excursion
562 (goto-char (car range))
563 (cond ((eq (char-syntax (or (char-after) ?\ )) ?\") 'string)
564 ((looking-at "//") 'c++)
565 (t 'c))) ; Assuming the range is valid.
566 range))
567
e1c458ae 568
785eecbb
RS
569\f
570;; utilities for moving and querying around syntactic elements
571(defvar c-parsing-error nil)
572
573(defun c-parse-state ()
574 ;; Finds and records all open parens between some important point
575 ;; earlier in the file and point.
576 ;;
577 ;; if there's a state cache, return it
578 (setq c-parsing-error nil)
579 (if (boundp 'c-state-cache) c-state-cache
580 (let* (at-bob
581 (pos (save-excursion
582 ;; go back 2 bods, but ignore any bogus positions
583 ;; returned by beginning-of-defun (i.e. open paren
584 ;; in column zero)
585 (let ((cnt 2))
586 (while (not (or at-bob (zerop cnt)))
e1c458ae 587 (goto-char (c-point 'bod))
0ec8351b
BW
588 (if (and
589 (eq (char-after) ?\{)
590 ;; The following catches an obscure special
591 ;; case where the brace is preceded by an
592 ;; open paren. That can only legally occur
593 ;; with blocks inside expressions and in
594 ;; Pike special brace lists. Even so, this
595 ;; test is still bogus then, but hopefully
596 ;; good enough. (We don't want to use
597 ;; up-list here since it might be slow.)
598 (save-excursion
599 (c-backward-syntactic-ws)
600 (not (eq (char-before) ?\())))
785eecbb
RS
601 (setq cnt (1- cnt)))
602 (if (bobp)
603 (setq at-bob t))))
604 (point)))
605 (here (save-excursion
606 ;;(skip-chars-forward " \t}")
607 (point)))
608 (last-bod pos) (last-pos pos)
609 placeholder state sexp-end)
610 ;; cache last bod position
611 (while (catch 'backup-bod
612 (setq state nil)
613 (while (and pos (< pos here))
614 (setq last-pos pos)
615 (if (and (setq pos (c-safe (scan-lists pos 1 -1)))
616 (<= pos here))
617 (progn
618 (setq sexp-end (c-safe (scan-sexps (1- pos) 1)))
619 (if (and sexp-end
620 (<= sexp-end here))
621 ;; we want to record both the start and end
622 ;; of this sexp, but we only want to record
623 ;; the last-most of any of them before here
624 (progn
625 (if (eq (char-after (1- pos)) ?\{)
626 (setq state (cons (cons (1- pos) sexp-end)
627 (if (consp (car state))
628 (cdr state)
629 state))))
630 (setq pos sexp-end))
631 ;; we're contained in this sexp so put pos on
632 ;; front of list
633 (setq state (cons (1- pos) state))))
634 ;; something bad happened. check to see if we
635 ;; crossed an unbalanced close brace. if so, we
636 ;; didn't really find the right `important bufpos'
637 ;; so lets back up and try again
638 (if (and (not pos) (not at-bob)
639 (setq placeholder
640 (c-safe (scan-lists last-pos 1 1)))
641 ;;(char-after (1- placeholder))
642 (<= placeholder here)
643 (eq (char-after (1- placeholder)) ?\}))
644 (while t
645 (setq last-bod (c-safe (scan-lists last-bod -1 1)))
646 (if (not last-bod)
647 (progn
648 ;; bogus, but what can we do here?
649 (setq c-parsing-error (1- placeholder))
650 (throw 'backup-bod nil))
651 (setq at-bob (= last-bod (point-min))
652 pos last-bod)
653 (if (= (char-after last-bod) ?\{)
654 (throw 'backup-bod t)))
655 )) ;end-if
656 )) ;end-while
657 nil))
658 state)))
659
660(defun c-whack-state (bufpos state)
661 ;; whack off any state information that appears on STATE which lies
662 ;; after the bounds of BUFPOS.
663 (let (newstate car)
664 (while state
665 (setq car (car state)
666 state (cdr state))
667 (if (consp car)
668 ;; just check the car, because in a balanced brace
669 ;; expression, it must be impossible for the corresponding
670 ;; close brace to be before point, but the open brace to be
671 ;; after.
672 (if (<= bufpos (car car))
673 nil ; whack it off
674 ;; its possible that the open brace is before bufpos, but
675 ;; the close brace is after. In that case, convert this
676 ;; to a non-cons element.
677 (if (<= bufpos (cdr car))
678 (setq newstate (append newstate (list (car car))))
679 ;; we know that both the open and close braces are
680 ;; before bufpos, so we also know that everything else
681 ;; on state is before bufpos, so we can glom up the
682 ;; whole thing and exit.
683 (setq newstate (append newstate (list car) state)
684 state nil)))
685 (if (<= bufpos car)
686 nil ; whack it off
687 ;; it's before bufpos, so everything else should too
688 (setq newstate (append newstate (list car) state)
689 state nil))))
690 newstate))
691
692(defun c-hack-state (bufpos which state)
693 ;; Using BUFPOS buffer position, and WHICH (must be 'open or
694 ;; 'close), hack the c-parse-state STATE and return the results.
695 (if (eq which 'open)
696 (let ((car (car state)))
697 (if (or (null car)
698 (consp car)
699 (/= bufpos car))
700 (cons bufpos state)
701 state))
702 (if (not (eq which 'close))
703 (error "c-hack-state, bad argument: %s" which))
704 ;; 'close brace
705 (let ((car (car state))
706 (cdr (cdr state)))
707 (if (consp car)
708 (setq car (car cdr)
709 cdr (cdr cdr)))
710 ;; TBD: is this test relevant???
711 (if (consp car)
712 state ;on error, don't change
713 ;; watch out for balanced expr already on cdr of list
714 (cons (cons car bufpos)
715 (if (consp (car cdr))
716 (cdr cdr) cdr))
717 ))))
718
719(defun c-adjust-state (from to shift state)
720 ;; Adjust all points in state that lie in the region FROM..TO by
0ec8351b 721 ;; SHIFT amount.
785eecbb
RS
722 (mapcar
723 (function
724 (lambda (e)
725 (if (consp e)
726 (let ((car (car e))
727 (cdr (cdr e)))
728 (if (and (<= from car) (< car to))
729 (setcar e (+ shift car)))
730 (if (and (<= from cdr) (< cdr to))
731 (setcdr e (+ shift cdr))))
732 (if (and (<= from e) (< e to))
733 (setq e (+ shift e))))
734 e))
735 state))
736
737\f
738(defun c-beginning-of-inheritance-list (&optional lim)
739 ;; Go to the first non-whitespace after the colon that starts a
740 ;; multiple inheritance introduction. Optional LIM is the farthest
741 ;; back we should search.
742 (let ((lim (or lim (c-point 'bod)))
743 (placeholder (progn
744 (back-to-indentation)
745 (point))))
746 (c-backward-syntactic-ws lim)
747 (while (and (> (point) lim)
748 (memq (char-before) '(?, ?:))
749 (progn
750 (beginning-of-line)
751 (setq placeholder (point))
752 (skip-chars-forward " \t")
753 (not (looking-at c-class-key))
754 ))
755 (c-backward-syntactic-ws lim))
756 (goto-char placeholder)
757 (skip-chars-forward "^:" (c-point 'eol))))
758
785eecbb
RS
759(defun c-in-method-def-p ()
760 ;; Return nil if we aren't in a method definition, otherwise the
761 ;; position of the initial [+-].
762 (save-excursion
763 (beginning-of-line)
764 (and c-method-key
765 (looking-at c-method-key)
766 (point))
767 ))
768
769(defun c-just-after-func-arglist-p (&optional containing)
770 ;; Return t if we are between a function's argument list closing
771 ;; paren and its opening brace. Note that the list close brace
772 ;; could be followed by a "const" specifier or a member init hanging
773 ;; colon. Optional CONTAINING is position of containing s-exp open
774 ;; brace. If not supplied, point is used as search start.
775 (save-excursion
776 (c-backward-syntactic-ws)
777 (let ((checkpoint (or containing (point))))
778 (goto-char checkpoint)
779 ;; could be looking at const specifier
780 (if (and (eq (char-before) ?t)
781 (forward-word -1)
782 (looking-at "\\<const\\>"))
783 (c-backward-syntactic-ws)
784 ;; otherwise, we could be looking at a hanging member init
785 ;; colon
786 (goto-char checkpoint)
787 (if (and (eq (char-before) ?:)
788 (progn
789 (forward-char -1)
790 (c-backward-syntactic-ws)
791 (looking-at "[ \t\n]*:\\([^:]+\\|$\\)")))
792 nil
793 (goto-char checkpoint))
794 )
795 (and (eq (char-before) ?\))
796 ;; check if we are looking at a method def
797 (or (not c-method-key)
798 (progn
0ec8351b 799 (c-forward-sexp -1)
785eecbb
RS
800 (forward-char -1)
801 (c-backward-syntactic-ws)
802 (not (or (memq (char-before) '(?- ?+))
803 ;; or a class category
804 (progn
0ec8351b 805 (c-forward-sexp -2)
785eecbb
RS
806 (looking-at c-class-key))
807 )))))
808 )))
809
810;; defuns to look backwards for things
811(defun c-backward-to-start-of-do (&optional lim)
812 ;; Move to the start of the last "unbalanced" do expression.
813 ;; Optional LIM is the farthest back to search. If none is found,
814 ;; nil is returned and point is left unchanged, otherwise t is returned.
815 (let ((do-level 1)
816 (case-fold-search nil)
817 (lim (or lim (c-point 'bod)))
818 (here (point))
819 foundp)
820 (while (not (zerop do-level))
821 ;; we protect this call because trying to execute this when the
822 ;; while is not associated with a do will throw an error
823 (condition-case nil
824 (progn
0ec8351b 825 (c-backward-sexp 1)
785eecbb 826 (cond
e1c458ae
RS
827 ;; break infloop for illegal C code
828 ((bobp) (setq do-level 0))
785eecbb
RS
829 ((memq (c-in-literal lim) '(c c++)))
830 ((looking-at "while\\b[^_]")
831 (setq do-level (1+ do-level)))
832 ((looking-at "do\\b[^_]")
833 (if (zerop (setq do-level (1- do-level)))
834 (setq foundp t)))
835 ((<= (point) lim)
836 (setq do-level 0)
837 (goto-char lim))))
838 (error
839 (goto-char lim)
840 (setq do-level 0))))
841 (if (not foundp)
842 (goto-char here))
843 foundp))
844
845(defun c-backward-to-start-of-if (&optional lim)
846 ;; Move to the start of the last "unbalanced" if and return t. If
847 ;; none is found, and we are looking at an if clause, nil is
848 ;; returned. If none is found and we are looking at an else clause,
849 ;; an error is thrown.
850 (let ((if-level 1)
851 (here (c-point 'bol))
852 (case-fold-search nil)
e1c458ae
RS
853 (lim (or (and (>= (point) lim)
854 lim)
855 (c-point 'bod)))
785eecbb
RS
856 (at-if (looking-at "if\\b[^_]")))
857 (catch 'orphan-if
858 (while (and (not (bobp))
859 (not (zerop if-level)))
860 (c-backward-syntactic-ws)
861 (condition-case nil
0ec8351b 862 (c-backward-sexp 1)
785eecbb
RS
863 (error
864 (if at-if
865 (throw 'orphan-if nil)
866 (error "No matching `if' found for `else' on line %d."
867 (1+ (count-lines 1 here))))))
868 (cond
869 ((looking-at "else\\b[^_]")
870 (setq if-level (1+ if-level)))
871 ((looking-at "if\\b[^_]")
872 ;; check for else if... skip over
873 (let ((here (point)))
0ec8351b 874 (c-safe (c-forward-sexp -1))
785eecbb
RS
875 (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
876 nil
877 (setq if-level (1- if-level))
878 (goto-char here))))
879 ((< (point) lim)
880 (setq if-level 0)
881 (goto-char lim))
882 ))
883 t)))
884
885(defun c-skip-conditional ()
886 ;; skip forward over conditional at point, including any predicate
887 ;; statements in parentheses. No error checking is performed.
0ec8351b
BW
888 (c-forward-sexp (cond
889 ;; else if()
890 ((looking-at "\\<else\\>[ \t]+\\<if\\>") 3)
891 ;; do, else, try, finally
892 ((looking-at "\\<\\(do\\|else\\|try\\|finally\\)\\>") 1)
893 ;; for, if, while, switch, catch, synchronized
894 (t 2))))
785eecbb
RS
895
896(defun c-skip-case-statement-forward (state &optional lim)
897 ;; skip forward over case/default bodies, with optional maximal
898 ;; limit. if no next case body is found, nil is returned and point
899 ;; is not moved
900 (let ((lim (or lim (point-max)))
901 (here (point))
902 donep foundp bufpos
903 (safepos (point))
904 (balanced (car state)))
905 ;; search until we've passed the limit, or we've found our match
906 (while (and (< (point) lim)
907 (not donep))
908 (setq safepos (point))
909 ;; see if we can find a case statement, not in a literal
910 (if (and (re-search-forward c-switch-label-key lim 'move)
911 (setq bufpos (match-beginning 0))
912 (not (c-in-literal safepos))
913 (/= bufpos here))
914 ;; if we crossed into a balanced sexp, we know the case is
915 ;; not part of our switch statement, so just bound over the
916 ;; sexp and keep looking.
917 (if (and (consp balanced)
918 (> bufpos (car balanced))
919 (< bufpos (cdr balanced)))
920 (goto-char (cdr balanced))
921 (goto-char bufpos)
922 (setq donep t
923 foundp t))))
924 (if (not foundp)
925 (goto-char here))
926 foundp))
927
928(defun c-search-uplist-for-classkey (brace-state)
929 ;; search for the containing class, returning a 2 element vector if
0ec8351b
BW
930 ;; found. aref 0 contains the bufpos of the boi of the class key
931 ;; line, and aref 1 contains the bufpos of the open brace.
785eecbb
RS
932 (if (null brace-state)
933 ;; no brace-state means we cannot be inside a class
934 nil
935 (let ((carcache (car brace-state))
936 search-start search-end)
937 (if (consp carcache)
938 ;; a cons cell in the first element means that there is some
939 ;; balanced sexp before the current bufpos. this we can
940 ;; ignore. the nth 1 and nth 2 elements define for us the
941 ;; search boundaries
942 (setq search-start (nth 2 brace-state)
943 search-end (nth 1 brace-state))
944 ;; if the car was not a cons cell then nth 0 and nth 1 define
945 ;; for us the search boundaries
946 (setq search-start (nth 1 brace-state)
947 search-end (nth 0 brace-state)))
948 ;; search-end cannot be a cons cell
949 (and (consp search-end)
950 (error "consp search-end: %s" search-end))
951 ;; if search-end is nil, or if the search-end character isn't an
952 ;; open brace, we are definitely not in a class
953 (if (or (not search-end)
954 (< search-end (point-min))
955 (not (eq (char-after search-end) ?{)))
956 nil
957 ;; now, we need to look more closely at search-start. if
958 ;; search-start is nil, then our start boundary is really
959 ;; point-min.
960 (if (not search-start)
961 (setq search-start (point-min))
962 ;; if search-start is a cons cell, then we can start
963 ;; searching from the end of the balanced sexp just ahead of
964 ;; us
965 (if (consp search-start)
966 (setq search-start (cdr search-start))))
967 ;; now we can do a quick regexp search from search-start to
968 ;; search-end and see if we can find a class key. watch for
969 ;; class like strings in literals
970 (save-excursion
971 (save-restriction
972 (goto-char search-start)
e1c458ae 973 (let ((search-key (concat c-class-key "\\|" c-extra-toplevel-key))
785eecbb 974 foundp class match-end)
0ec8351b
BW
975 (if c-inexpr-class-key
976 (setq search-key (concat search-key "\\|"
977 c-inexpr-class-key)))
785eecbb
RS
978 (while (and (not foundp)
979 (progn
980 (c-forward-syntactic-ws)
981 (> search-end (point)))
982 (re-search-forward search-key search-end t))
983 (setq class (match-beginning 0)
984 match-end (match-end 0))
985 (if (c-in-literal search-start)
986 nil ; its in a comment or string, ignore
987 (goto-char class)
988 (skip-chars-forward " \t\n")
989 (setq foundp (vector (c-point 'boi) search-end))
990 (cond
991 ;; check for embedded keywords
992 ((let ((char (char-after (1- class))))
993 (and char
994 (memq (char-syntax char) '(?w ?_))))
995 (goto-char match-end)
996 (setq foundp nil))
997 ;; make sure we're really looking at the start of a
998 ;; class definition, and not a forward decl, return
999 ;; arg, template arg list, or an ObjC or Java method.
1000 ((and c-method-key
0ec8351b
BW
1001 (re-search-forward c-method-key search-end t)
1002 (not (c-in-literal class)))
785eecbb 1003 (setq foundp nil))
0ec8351b
BW
1004 ;; Check if this is an anonymous inner class.
1005 ((and c-inexpr-class-key
1006 (looking-at c-inexpr-class-key))
1007 (while (and (= (c-forward-token-1 1 t) 0)
1008 (looking-at "(\\|\\w\\|\\s_\\|\\.")))
1009 (if (eq (point) search-end)
1010 ;; We're done. Just trap this case in the cond.
1011 nil
1012 ;; False alarm; all conditions aren't satisfied.
1013 (setq foundp nil)))
785eecbb
RS
1014 ;; Its impossible to define a regexp for this, and
1015 ;; nearly so to do it programmatically.
1016 ;;
1017 ;; ; picks up forward decls
1018 ;; = picks up init lists
1019 ;; ) picks up return types
1020 ;; > picks up templates, but remember that we can
1021 ;; inherit from templates!
1022 ((let ((skipchars "^;=)"))
1023 ;; try to see if we found the `class' keyword
1024 ;; inside a template arg list
1025 (save-excursion
1026 (skip-chars-backward "^<>" search-start)
1027 (if (eq (char-before) ?<)
1028 (setq skipchars (concat skipchars ">"))))
0ec8351b
BW
1029 (while (progn
1030 (skip-chars-forward skipchars search-end)
1031 (c-in-literal class))
1032 (forward-char))
785eecbb
RS
1033 (/= (point) search-end))
1034 (setq foundp nil))
1035 )))
1036 foundp))
1037 )))))
1038
1039(defun c-inside-bracelist-p (containing-sexp brace-state)
1040 ;; return the buffer position of the beginning of the brace list
1041 ;; statement if we're inside a brace list, otherwise return nil.
1042 ;; CONTAINING-SEXP is the buffer pos of the innermost containing
1043 ;; paren. BRACE-STATE is the remainder of the state of enclosing braces
1044 ;;
1045 ;; N.B.: This algorithm can potentially get confused by cpp macros
1046 ;; places in inconvenient locations. Its a trade-off we make for
1047 ;; speed.
1048 (or
1049 ;; this will pick up enum lists
b2acd789
RS
1050 (c-safe
1051 (save-excursion
1052 (goto-char containing-sexp)
0ec8351b 1053 (c-forward-sexp -1)
b2acd789
RS
1054 (let (bracepos)
1055 (if (and (or (looking-at "enum[\t\n ]+")
0ec8351b 1056 (progn (c-forward-sexp -1)
b2acd789
RS
1057 (looking-at "enum[\t\n ]+")))
1058 (setq bracepos (c-safe (scan-lists (point) 1 -1)))
1059 (not (c-crosses-statement-barrier-p (point)
1060 (- bracepos 2))))
1061 (point)))))
785eecbb
RS
1062 ;; this will pick up array/aggregate init lists, even if they are nested.
1063 (save-excursion
0ec8351b
BW
1064 (let ((class-key
1065 ;; Pike can have class definitions anywhere, so we must
1066 ;; check for the class key here.
1067 (and (c-major-mode-is 'pike-mode)
1068 (concat c-class-key "\\|" c-extra-toplevel-key)))
1069 bufpos lim braceassignp)
785eecbb
RS
1070 (while (and (not bufpos)
1071 containing-sexp)
1072 (if (consp containing-sexp)
1073 (setq containing-sexp (car brace-state)
1074 brace-state (cdr brace-state))
785eecbb 1075 (goto-char containing-sexp)
0ec8351b
BW
1076 (if (c-looking-at-inexpr-block)
1077 ;; We're in an in-expression block of some kind. Do
1078 ;; not check nesting.
1079 (setq containing-sexp nil)
1080 ;; see if the open brace is preceded by = or [...] in
1081 ;; this statement, but watch out for operator=
1082 (setq lim (if (consp (car brace-state))
1083 (cdr (car brace-state))
1084 (car brace-state))
1085 braceassignp 'dontknow)
1086 (while (and (eq braceassignp 'dontknow)
1087 (zerop (c-backward-token-1 1 t lim)))
1088 (cond ((eq (char-after) ?\;)
1089 (setq braceassignp nil))
1090 ((and class-key
1091 (looking-at class-key))
1092 (setq braceassignp nil))
1093 ((eq (char-after) ?=)
1094 ;; We've seen a =, but must check earlier tokens so
1095 ;; that it isn't something that should be ignored.
1096 (setq braceassignp 'maybe)
1097 (while (and (eq braceassignp 'maybe)
1098 (zerop (c-backward-token-1 1 t lim)))
1099 (setq braceassignp
1100 (cond
1101 ;; Check for operator =
1102 ((looking-at "operator\\>") nil)
1103 ;; Check for `<opchar>= (Pike)
1104 ((eq (char-after) ?`) nil)
1105 ((looking-at "\\s.") 'maybe)
1106 ;; make sure we're not in a C++ template
1107 ;; argument assignment
1108 ((save-excursion
1109 (let ((here (point))
1110 (pos< (progn
1111 (skip-chars-backward "^<")
1112 (point))))
1113 (and (c-major-mode-is 'c++-mode)
1114 (eq (char-before) ?<)
1115 (not (c-crosses-statement-barrier-p
1116 here pos<))
1117 (not (c-in-literal))
1118 )))
1119 nil)
1120 (t t)))))
1121 ((eq (char-after) ?\[)
1122 ;; In Java, an initialization brace list may
1123 ;; follow "new Foo[]", so check for []. Got to
1124 ;; watch out for the C++ "operator[]" defun,
1125 ;; though.
1126 (setq braceassignp
1127 (save-excursion
1128 (c-backward-token-1)
1129 (not (looking-at "operator\\>")))))
1130 ))
1131 (if (memq braceassignp '(nil dontknow))
1132 (if (eq (char-after) ?\;)
1133 ;; Brace lists can't contain a semicolon, so we're done.
1134 (setq containing-sexp nil)
1135 ;; lets see if we're nested. find the most nested
1136 ;; containing brace
1137 (setq containing-sexp (car brace-state)
1138 brace-state (cdr brace-state)))
1139 ;; we've hit the beginning of the aggregate list
1140 (c-beginning-of-statement-1
1141 (c-most-enclosing-brace brace-state))
1142 (setq bufpos (point))))
785eecbb
RS
1143 ))
1144 bufpos))
1145 ))
1146
0ec8351b
BW
1147(defun c-looking-at-special-brace-list (&optional lim)
1148