comparison lisp/progmodes/cc-engine.el @ 36920:32a4317c6aa5

Update to version 5.28.
author Gerd Moellmann <gerd@gnu.org>
date Wed, 21 Mar 2001 12:58:33 +0000
parents dd613770eb0f
children 7a94f1c588c4
comparison
equal deleted inserted replaced
36919:c7548b39717f 36920:32a4317c6aa5
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,87,92,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc. 3 ;; Copyright (C) 1985,1987,1992-2001 Free Software Foundation, Inc.
4 4
5 ;; Authors: 2000- Martin Stjernholm 5 ;; Authors: 2000- Martin Stjernholm
6 ;; 1998-1999 Barry A. Warsaw and Martin Stjernholm 6 ;; 1998-1999 Barry A. Warsaw and Martin Stjernholm
7 ;; 1992-1997 Barry A. Warsaw 7 ;; 1992-1997 Barry A. Warsaw
8 ;; 1987 Dave Detlefs and Stewart Clamen 8 ;; 1987 Dave Detlefs and Stewart Clamen
23 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 23 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
24 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 ;; GNU General Public License for more details. 25 ;; GNU General Public License for more details.
26 26
27 ;; 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
28 ;; along with GNU Emacs; see the file COPYING. If not, write to the 28 ;; along with this program; see the file COPYING. If not, write to
29 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 29 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
30 ;; Boston, MA 02111-1307, USA. 30 ;; Boston, MA 02111-1307, USA.
31 31
32 (eval-when-compile 32 (eval-when-compile
33 (let ((load-path 33 (let ((load-path
34 (if (and (boundp 'byte-compile-current-file) 34 (if (and (boundp 'byte-compile-dest-file)
35 (stringp byte-compile-current-file)) 35 (stringp byte-compile-dest-file))
36 (cons (file-name-directory byte-compile-current-file) 36 (cons (file-name-directory byte-compile-dest-file) load-path)
37 load-path)
38 load-path))) 37 load-path)))
39 (load "cc-defs" nil t))) 38 (require 'cc-bytecomp)))
40 (require 'cc-langs) 39
40 (cc-require 'cc-defs)
41 (cc-require 'cc-vars)
42 (cc-require 'cc-langs)
43
44 ;; Silence the compiler.
45 (cc-bytecomp-defun buffer-syntactic-context) ; XEmacs
41 46
42 47
48 (defvar c-state-cache nil)
49 (defvar c-in-literal-cache t)
50
43 ;; KLUDGE ALERT: c-maybe-labelp is used to pass information between 51 ;; KLUDGE ALERT: c-maybe-labelp is used to pass information between
44 ;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A 52 ;; c-crosses-statement-barrier-p and c-beginning-of-statement-1. A
45 ;; better way should be implemented, but this will at least shut up 53 ;; better way should be implemented, but this will at least shut up
46 ;; the byte compiler. 54 ;; the byte compiler.
47 (defvar c-maybe-labelp nil) 55 (defvar c-maybe-labelp nil)
201 )))) 209 ))))
202 (goto-char last-begin) 210 (goto-char last-begin)
203 ;; We always want to skip over the non-whitespace modifier 211 ;; We always want to skip over the non-whitespace modifier
204 ;; characters that can start a statement. 212 ;; characters that can start a statement.
205 (let ((lim (point))) 213 (let ((lim (point)))
206 (skip-chars-backward "-+!*&~@` \t\n" (c-point 'boi)) 214 (skip-chars-backward "-+!*&~@`# \t\n" (c-point 'boi))
207 (skip-chars-forward " \t\n" lim)))) 215 (skip-chars-forward " \t\n" lim))))
208 216
209 (defun c-end-of-statement-1 () 217 (defun c-end-of-statement-1 ()
210 (condition-case nil 218 (condition-case nil
211 (let (beg end found) 219 (let (beg end found)
256 (error (setq crossedp nil))) 264 (error (setq crossedp nil)))
257 (goto-char here) 265 (goto-char here)
258 crossedp)) 266 crossedp))
259 267
260 268
269 (defun c-beginning-of-macro (&optional lim)
270 ;; Go to the beginning of a cpp macro definition. Leaves point at
271 ;; the beginning of the macro and returns t if in a cpp macro
272 ;; definition, otherwise returns nil and leaves point unchanged.
273 ;; `lim' is currently ignored, but the interface requires it.
274 (let ((here (point)))
275 (beginning-of-line)
276 (while (eq (char-before (1- (point))) ?\\)
277 (forward-line -1))
278 (back-to-indentation)
279 (if (and (<= (point) here)
280 (eq (char-after) ?#))
281 t
282 (goto-char here)
283 nil)))
284
261 ;; Skipping of "syntactic whitespace", defined as lexical whitespace, 285 ;; Skipping of "syntactic whitespace", defined as lexical whitespace,
262 ;; C and C++ style comments, and preprocessor directives. Search no 286 ;; C and C++ style comments, and preprocessor directives. Search no
263 ;; farther back or forward than optional LIM. If LIM is omitted, 287 ;; farther back or forward than optional LIM. If LIM is omitted,
264 ;; `beginning-of-defun' is used for backward skipping, point-max is 288 ;; `beginning-of-defun' is used for backward skipping, point-max is
265 ;; used for forward skipping. 289 ;; used for forward skipping.
315 (let ((jump-syntax (if balanced 339 (let ((jump-syntax (if balanced
316 '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?') 340 '(?w ?_ ?\( ?\) ?\" ?\\ ?/ ?$ ?')
317 '(?w ?_ ?\" ?\\ ?/ ?'))) 341 '(?w ?_ ?\" ?\\ ?/ ?')))
318 (last (point)) 342 (last (point))
319 (prev (point))) 343 (prev (point)))
320 (if (/= (point)
321 (progn (c-forward-syntactic-ws) (point)))
322 ;; Skip whitespace. Count this as a move if we did in fact
323 ;; move and aren't out of bounds.
324 (or (eobp)
325 (and lim (> (point) lim))
326 (setq count (max (1- count) 0))))
327 (if (and (= count 0)
328 (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
329 (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
330 (eobp)))
331 ;; If count is zero we should jump if in the middle of a
332 ;; token or if there is whitespace between point and the
333 ;; following token beginning.
334 (setq count 1))
335 ;; Avoid having the limit tests inside the loop.
336 (save-restriction 344 (save-restriction
337 (if lim (narrow-to-region (point-min) lim)) 345 (if lim (narrow-to-region (point-min) lim))
346 (if (/= (point)
347 (progn (c-forward-syntactic-ws) (point)))
348 ;; Skip whitespace. Count this as a move if we did in fact
349 ;; move and aren't out of bounds.
350 (or (eobp)
351 (setq count (max (1- count) 0))))
352 (if (and (= count 0)
353 (or (and (memq (char-syntax (or (char-after) ? )) '(?w ?_))
354 (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
355 (eobp)))
356 ;; If count is zero we should jump if in the middle of a
357 ;; token or if there is whitespace between point and the
358 ;; following token beginning.
359 (setq count 1))
338 (if (eobp) 360 (if (eobp)
339 (goto-char last) 361 (goto-char last)
362 ;; Avoid having the limit tests inside the loop.
340 (condition-case nil 363 (condition-case nil
341 (while (> count 0) 364 (while (> count 0)
342 (setq prev last 365 (setq prev last
343 last (point)) 366 last (point))
344 (if (memq (char-syntax (char-after)) jump-syntax) 367 (if (memq (char-syntax (char-after)) jump-syntax)
368 (eobp))) 391 (eobp)))
369 ;; If count is zero we should jump if in the middle of a 392 ;; If count is zero we should jump if in the middle of a
370 ;; token or if there is whitespace between point and the 393 ;; token or if there is whitespace between point and the
371 ;; following token beginning. 394 ;; following token beginning.
372 (setq count 1)) 395 (setq count 1))
373 ;; Avoid having the limit tests inside the loop.
374 (save-restriction 396 (save-restriction
375 (if lim (narrow-to-region lim (point-max))) 397 (if lim (narrow-to-region lim (point-max)))
376 (or (bobp) 398 (or (bobp)
377 (progn 399 (progn
400 ;; Avoid having the limit tests inside the loop.
378 (condition-case nil 401 (condition-case nil
379 (while (progn 402 (while (progn
380 (setq last (point)) 403 (setq last (point))
381 (> count 0)) 404 (> count 0))
382 (c-backward-syntactic-ws lim) 405 (c-backward-syntactic-ws lim)
396 ;; `beginning-of-defun' is used." 419 ;; `beginning-of-defun' is used."
397 420
398 (defun c-in-literal (&optional lim) 421 (defun c-in-literal (&optional lim)
399 ;; Determine if point is in a C++ literal. we cache the last point 422 ;; Determine if point is in a C++ literal. we cache the last point
400 ;; calculated if the cache is enabled 423 ;; calculated if the cache is enabled
401 (if (and (boundp 'c-in-literal-cache) 424 (if (and (vectorp c-in-literal-cache)
402 c-in-literal-cache
403 (= (point) (aref c-in-literal-cache 0))) 425 (= (point) (aref c-in-literal-cache 0)))
404 (aref c-in-literal-cache 1) 426 (aref c-in-literal-cache 1)
405 (let ((rtn (save-excursion 427 (let ((rtn (save-excursion
406 (let* ((lim (or lim (c-point 'bod))) 428 (let* ((lim (or lim (c-point 'bod)))
407 (state (parse-partial-sexp lim (point)))) 429 (state (parse-partial-sexp lim (point))))
409 ((nth 3 state) 'string) 431 ((nth 3 state) 'string)
410 ((nth 4 state) (if (nth 7 state) 'c++ 'c)) 432 ((nth 4 state) (if (nth 7 state) 'c++ 'c))
411 ((c-beginning-of-macro lim) 'pound) 433 ((c-beginning-of-macro lim) 'pound)
412 (t nil)))))) 434 (t nil))))))
413 ;; cache this result if the cache is enabled 435 ;; cache this result if the cache is enabled
414 (and (boundp 'c-in-literal-cache) 436 (if (not c-in-literal-cache)
415 (setq c-in-literal-cache (vector (point) rtn))) 437 (setq c-in-literal-cache (vector (point) rtn)))
416 rtn))) 438 rtn)))
417 439
418 ;; XEmacs has a built-in function that should make this much quicker. 440 ;; XEmacs has a built-in function that should make this much quicker.
419 ;; I don't think we even need the cache, which makes our lives more 441 ;; I don't think we even need the cache, which makes our lives more
420 ;; complicated anyway. In this case, lim is ignored. 442 ;; complicated anyway. In this case, lim is ignored.
571 (if (and (consp range) (progn 593 (if (and (consp range) (progn
572 (goto-char (car range)) 594 (goto-char (car range))
573 (looking-at "//"))) 595 (looking-at "//")))
574 (let ((col (current-column)) 596 (let ((col (current-column))
575 (beg (point)) 597 (beg (point))
598 (bopl (c-point 'bopl))
576 (end (cdr range))) 599 (end (cdr range)))
600 ;; Got to take care in the backward direction to handle
601 ;; comments which are preceded by code.
577 (while (and (c-forward-comment -1) 602 (while (and (c-forward-comment -1)
603 (>= (point) bopl)
578 (looking-at "//") 604 (looking-at "//")
579 (= col (current-column))) 605 (= col (current-column)))
580 (setq beg (point))) 606 (setq beg (point)
607 bopl (c-point 'bopl)))
581 (goto-char end) 608 (goto-char end)
582 (while (and (progn (skip-chars-forward " \t") 609 (while (and (progn (skip-chars-forward " \t")
583 (looking-at "//")) 610 (looking-at "//"))
584 (= col (current-column)) 611 (= col (current-column))
585 (prog1 (zerop (forward-line 1)) 612 (prog1 (zerop (forward-line 1))
609 (defun c-parse-state () 636 (defun c-parse-state ()
610 ;; Finds and records all open parens between some important point 637 ;; Finds and records all open parens between some important point
611 ;; earlier in the file and point. 638 ;; earlier in the file and point.
612 ;; 639 ;;
613 ;; if there's a state cache, return it 640 ;; if there's a state cache, return it
614 (setq c-parsing-error nil) 641 (if c-state-cache c-state-cache
615 (if (boundp 'c-state-cache) c-state-cache
616 (let* (at-bob 642 (let* (at-bob
617 (pos (save-excursion 643 (pos (save-excursion
618 ;; go back 2 bods, but ignore any bogus positions 644 ;; go back 2 bods, but ignore any bogus positions
619 ;; returned by beginning-of-defun (i.e. open paren 645 ;; returned by beginning-of-defun (i.e. open paren
620 ;; in column zero) 646 ;; in column zero)
639 (setq at-bob t)))) 665 (setq at-bob t))))
640 (point))) 666 (point)))
641 (here (save-excursion 667 (here (save-excursion
642 ;;(skip-chars-forward " \t}") 668 ;;(skip-chars-forward " \t}")
643 (point))) 669 (point)))
644 (last-bod pos) (last-pos pos) 670 (last-bod here) (last-pos pos)
645 placeholder state sexp-end) 671 placeholder state sexp-end)
646 ;; cache last bod position 672 ;; cache last bod position
647 (while (catch 'backup-bod 673 (while (catch 'backup-bod
648 (setq state nil) 674 (setq state nil)
649 (while (and pos (< pos here)) 675 (while (and pos (< pos here))
678 (<= placeholder here) 704 (<= placeholder here)
679 (eq (char-after (1- placeholder)) ?\})) 705 (eq (char-after (1- placeholder)) ?\}))
680 (while t 706 (while t
681 (setq last-bod (c-safe (scan-lists last-bod -1 1))) 707 (setq last-bod (c-safe (scan-lists last-bod -1 1)))
682 (if (not last-bod) 708 (if (not last-bod)
683 (progn 709 (save-excursion
684 ;; bogus, but what can we do here? 710 ;; bogus, but what can we do here?
685 (setq c-parsing-error (1- placeholder)) 711 (goto-char placeholder)
712 (beginning-of-line)
713 (setq c-parsing-error
714 (format "\
715 Unbalanced close brace at line %d" (1+ (count-lines 1 (point)))))
686 (throw 'backup-bod nil)) 716 (throw 'backup-bod nil))
687 (setq at-bob (= last-bod (point-min)) 717 (setq at-bob (= last-bod (point-min))
688 pos last-bod) 718 pos last-bod)
689 (if (= (char-after last-bod) ?\{) 719 (if (= (char-after last-bod) ?\{)
690 (throw 'backup-bod t))) 720 (throw 'backup-bod t)))
908 foundp)) 938 foundp))
909 939
910 (defun c-backward-to-start-of-if (&optional lim) 940 (defun c-backward-to-start-of-if (&optional lim)
911 ;; Move to the start of the last "unbalanced" if and return t. If 941 ;; Move to the start of the last "unbalanced" if and return t. If
912 ;; none is found, and we are looking at an if clause, nil is 942 ;; none is found, and we are looking at an if clause, nil is
913 ;; returned. If none is found and we are looking at an else clause, 943 ;; returned.
914 ;; an error is thrown.
915 (let ((if-level 1) 944 (let ((if-level 1)
916 (here (c-point 'bol)) 945 (here (c-point 'bol))
917 (case-fold-search nil) 946 (case-fold-search nil)
918 (lim (or (and (>= (point) lim) 947 (lim (or (and lim (>= (point) lim) lim)
919 lim)
920 (c-point 'bod))) 948 (c-point 'bod)))
921 (at-if (looking-at "if\\b[^_]"))) 949 (at-if (looking-at "if\\b[^_]")))
922 (catch 'orphan-if 950 (catch 'orphan-if
923 (while (and (not (bobp)) 951 (while (and (not (bobp))
924 (not (zerop if-level))) 952 (not (zerop if-level)))
925 (c-backward-syntactic-ws) 953 (c-backward-syntactic-ws)
926 (condition-case nil 954 (condition-case nil
927 (c-backward-sexp 1) 955 (c-backward-sexp 1)
928 (error 956 (error
929 (if at-if 957 (unless at-if
930 (throw 'orphan-if nil) 958 (goto-char here)
931 (error "No matching `if' found for `else' on line %d." 959 (c-beginning-of-statement-1)
932 (1+ (count-lines 1 here)))))) 960 (setq c-parsing-error
961 (format "No matching `if' found for `else' on line %d"
962 (1+ (count-lines 1 here))))
963 (throw 'orphan-if nil))))
933 (cond 964 (cond
934 ((looking-at "else\\b[^_]") 965 ((looking-at "else\\b[^_]")
935 (setq if-level (1+ if-level))) 966 (setq if-level (1+ if-level)))
936 ((looking-at "if\\b[^_]") 967 ((looking-at "if\\b[^_]")
937 ;; check for else if... skip over 968 ;; check for else if... skip over
938 (let ((here (point))) 969 (let ((here (point)))
939 (c-safe (c-forward-sexp -1)) 970 (c-safe (c-forward-sexp -1))
940 (if (looking-at "\\<else\\>[ \t]+\\<if\\>") 971 (if (looking-at "\\<else\\>[ \t]+\\<if\\>[^_]")
941 nil 972 nil
942 (setq if-level (1- if-level)) 973 (setq if-level (1- if-level))
943 (goto-char here)))) 974 (goto-char here))))
944 ((< (point) lim) 975 ((< (point) lim)
945 (setq if-level 0) 976 (setq if-level 0)
950 (defun c-skip-conditional () 981 (defun c-skip-conditional ()
951 ;; skip forward over conditional at point, including any predicate 982 ;; skip forward over conditional at point, including any predicate
952 ;; statements in parentheses. No error checking is performed. 983 ;; statements in parentheses. No error checking is performed.
953 (c-forward-sexp (cond 984 (c-forward-sexp (cond
954 ;; else if() 985 ;; else if()
955 ((looking-at "\\<else\\>[ \t]+\\<if\\>") 3) 986 ((looking-at "\\<else\\>[ \t]+\\<if\\>\\([^_]\\|$\\)") 3)
956 ;; do, else, try, finally 987 ;; do, else, try, finally
957 ((looking-at "\\<\\(do\\|else\\|try\\|finally\\)\\>") 1) 988 ((looking-at
989 "\\<\\(do\\|else\\|try\\|finally\\)\\>\\([^_]\\|$\\)")
990 1)
958 ;; for, if, while, switch, catch, synchronized, foreach 991 ;; for, if, while, switch, catch, synchronized, foreach
959 (t 2)))) 992 (t 2))))
960 993
961 (defun c-beginning-of-closest-statement (&optional lim) 994 (defun c-beginning-of-closest-statement (&optional lim)
962 ;; Go back to the closest preceding statement start. 995 ;; Go back to the closest preceding statement start.
989 (setq limit (point-min))) 1022 (setq limit (point-min)))
990 (skip-chars-forward " \t") 1023 (skip-chars-forward " \t")
991 (if (eq (char-after) ?,) 1024 (if (eq (char-after) ?,)
992 (forward-char 1) 1025 (forward-char 1)
993 (c-backward-syntactic-ws limit)) 1026 (c-backward-syntactic-ws limit))
994 (while (and (< limit (point)) 1027 (c-with-syntax-table (if (c-major-mode-is 'c++-mode)
995 (eq (char-before) ?,)) 1028 c++-template-syntax-table
996 ;; this will catch member inits with multiple 1029 (syntax-table))
997 ;; line arglists 1030 (while (and (< limit (point))
998 (forward-char -1) 1031 (eq (char-before) ?,))
999 (c-backward-syntactic-ws) 1032 ;; this will catch member inits with multiple
1000 (if (eq (char-before) ?\)) 1033 ;; line arglists
1001 (c-backward-sexp 2) 1034 (forward-char -1)
1002 (c-backward-sexp 1)) 1035 (c-backward-syntactic-ws)
1003 ;; Skip backwards over a fully::qualified::name. 1036 (if (eq (char-before) ?\))
1004 (c-backward-syntactic-ws limit) 1037 (c-backward-sexp 2)
1005 (while (and (eq (char-before) ?:) 1038 (c-backward-sexp 1))
1006 (save-excursion 1039 ;; Skip over any template arg to the class.
1007 (forward-char -1) 1040 (if (eq (char-after) ?<)
1008 (eq (char-before) ?:))) 1041 (c-backward-sexp 1))
1009 (backward-char 2) 1042 ;; Skip backwards over a fully::qualified::name.
1010 (c-backward-sexp 1)) 1043 (c-backward-syntactic-ws limit)
1011 ;; now continue checking 1044 (while (and (eq (char-before) ?:)
1012 (c-backward-syntactic-ws limit)) 1045 (save-excursion
1046 (forward-char -1)
1047 (eq (char-before) ?:)))
1048 (backward-char 2)
1049 (c-backward-sexp 1))
1050 ;; now continue checking
1051 (c-backward-syntactic-ws limit)))
1013 (and (< limit (point)) 1052 (and (< limit (point))
1014 (eq (char-before) ?:))) 1053 (eq (char-before) ?:)))
1015 1054
1016 (defun c-skip-case-statement-forward (state &optional lim) 1055 (defun c-skip-case-statement-forward (state &optional lim)
1017 ;; skip forward over case/default bodies, with optional maximal 1056 ;; skip forward over case/default bodies, with optional maximal
1158 1197
1159 (defun c-inside-bracelist-p (containing-sexp brace-state) 1198 (defun c-inside-bracelist-p (containing-sexp brace-state)
1160 ;; return the buffer position of the beginning of the brace list 1199 ;; return the buffer position of the beginning of the brace list
1161 ;; statement if we're inside a brace list, otherwise return nil. 1200 ;; statement if we're inside a brace list, otherwise return nil.
1162 ;; CONTAINING-SEXP is the buffer pos of the innermost containing 1201 ;; CONTAINING-SEXP is the buffer pos of the innermost containing
1163 ;; paren. BRACE-STATE is the remainder of the state of enclosing braces 1202 ;; paren. BRACE-STATE is the remainder of the state of enclosing
1203 ;; braces
1164 ;; 1204 ;;
1165 ;; N.B.: This algorithm can potentially get confused by cpp macros 1205 ;; N.B.: This algorithm can potentially get confused by cpp macros
1166 ;; places in inconvenient locations. Its a trade-off we make for 1206 ;; places in inconvenient locations. Its a trade-off we make for
1167 ;; speed. 1207 ;; speed.
1168 (or 1208 (or
1211 ;; directly after "new Foo[]", so check for a "new" 1251 ;; directly after "new Foo[]", so check for a "new"
1212 ;; earlier. 1252 ;; earlier.
1213 (while (eq braceassignp 'dontknow) 1253 (while (eq braceassignp 'dontknow)
1214 (setq braceassignp 1254 (setq braceassignp
1215 (cond ((/= (c-backward-token-1 1 t lim) 0) nil) 1255 (cond ((/= (c-backward-token-1 1 t lim) 0) nil)
1216 ((looking-at "new\\>") t) 1256 ((looking-at "new\\>[^_]") t)
1217 ((looking-at "\\sw\\|\\s_\\|[.[]") 1257 ((looking-at "\\sw\\|\\s_\\|[.[]")
1218 ;; Carry on looking if this is an 1258 ;; Carry on looking if this is an
1219 ;; identifier (may contain "." in Java) 1259 ;; identifier (may contain "." in Java)
1220 ;; or another "[]" sexp. 1260 ;; or another "[]" sexp.
1221 'dontknow) 1261 'dontknow)
1236 (zerop (c-backward-token-1 1 t lim))) 1276 (zerop (c-backward-token-1 1 t lim)))
1237 (setq braceassignp 1277 (setq braceassignp
1238 (cond 1278 (cond
1239 ;; Check for operator = 1279 ;; Check for operator =
1240 ((looking-at "operator\\>") nil) 1280 ((looking-at "operator\\>") nil)
1241 ;; Check for `<opchar>= (Pike) 1281 ;; Check for `<opchar>= in Pike.
1242 ((eq (char-after) ?`) nil) 1282 ((and (c-major-mode-is 'pike-mode)
1283 (or (eq (char-after) ?`)
1284 ;; Special case for Pikes
1285 ;; `[]=, since '[' is not in
1286 ;; the punctuation class.
1287 (and (eq (char-after) ?\[)
1288 (eq (char-before) ?`))))
1289 nil)
1243 ((looking-at "\\s.") 'maybe) 1290 ((looking-at "\\s.") 'maybe)
1244 ;; make sure we're not in a C++ template 1291 ;; make sure we're not in a C++ template
1245 ;; argument assignment 1292 ;; argument assignment
1246 ((save-excursion 1293 ((and (c-major-mode-is 'c++-mode)
1247 (let ((here (point)) 1294 (save-excursion
1248 (pos< (progn 1295 (let ((here (point))
1249 (skip-chars-backward "^<") 1296 (pos< (progn
1250 (point)))) 1297 (skip-chars-backward "^<>")
1251 (and (c-major-mode-is 'c++-mode) 1298 (point))))
1252 (eq (char-before) ?<) 1299 (and (eq (char-before) ?<)
1253 (not (c-crosses-statement-barrier-p 1300 (not (c-crosses-statement-barrier-p
1254 pos< here)) 1301 pos< here))
1255 (not (c-in-literal)) 1302 (not (c-in-literal))
1256 ))) 1303 ))))
1257 nil) 1304 nil)
1258 (t t)))))) 1305 (t t))))))
1259 (if (and (eq braceassignp 'dontknow) 1306 (if (and (eq braceassignp 'dontknow)
1260 (/= (c-backward-token-1 1 t lim) 0)) 1307 (/= (c-backward-token-1 1 t lim) 0))
1261 (setq braceassignp nil))) 1308 (setq braceassignp nil)))
1391 (if (eq (char-before) ?}) ; Recognize only a block currently. 1438 (if (eq (char-before) ?}) ; Recognize only a block currently.
1392 (progn 1439 (progn
1393 (c-forward-sexp -1) 1440 (c-forward-sexp -1)
1394 (if (>= (point) lim) 1441 (if (>= (point) lim)
1395 (c-looking-at-inexpr-block lim)))))))) 1442 (c-looking-at-inexpr-block lim))))))))
1443
1444 (defun c-on-identifier ()
1445 ;; Returns non-nil if we're on or directly after an identifier.
1446 (if (or (memq (char-syntax (or (char-after) ? )) '(?w ?_))
1447 (memq (char-syntax (or (char-before) ? )) '(?w ?_)))
1448 (save-excursion
1449 (skip-syntax-backward "w_")
1450 (not (looking-at c-keywords)))
1451 (if (c-major-mode-is 'pike-mode)
1452 ;; Handle the `<operator> syntax in Pike.
1453 (save-excursion
1454 (if (eq (char-after) ?\`) (forward-char))
1455 (skip-chars-backward "!%&*+\\-/<=>^|~")
1456 (let ((pos (point)))
1457 (cond ((memq (char-before) '(?\) ?\]))
1458 (c-safe (backward-char 2)))
1459 ((memq (char-before) '(?\( ?\[))
1460 (c-safe (backward-char 1))))
1461 (if (not (looking-at "()\\|\\[]"))
1462 (goto-char pos)))
1463 (and (eq (char-before) ?\`)
1464 (looking-at "[-!%&*+/<=>^|~]\\|()\\|\\[]"))))))
1396 1465
1397 1466
1398 (defun c-most-enclosing-brace (state) 1467 (defun c-most-enclosing-brace (state)
1399 ;; return the bufpos of the most enclosing brace that hasn't been 1468 ;; return the bufpos of the most enclosing brace that hasn't been
1400 ;; narrowed out by any enclosing class, or nil if none was found 1469 ;; narrowed out by any enclosing class, or nil if none was found
1560 ;; opener. 1629 ;; opener.
1561 (setq tmpsymbol (if (eq char-after-ip ?{) 1630 (setq tmpsymbol (if (eq char-after-ip ?{)
1562 'inline-open 1631 'inline-open
1563 'lambda-intro-cont))) 1632 'lambda-intro-cont)))
1564 (goto-char (cdr placeholder)) 1633 (goto-char (cdr placeholder))
1565 (c-add-syntax tmpsymbol (c-point 'boi)) 1634 (back-to-indentation)
1566 (c-add-syntax (car placeholder))) 1635 (c-add-syntax tmpsymbol (point))
1636 (unless (eq (point) (cdr placeholder))
1637 (c-add-syntax (car placeholder))))
1567 ;; CASE 5: Line is at top level. 1638 ;; CASE 5: Line is at top level.
1568 ((null containing-sexp) 1639 ((null containing-sexp)
1569 (cond 1640 (cond
1570 ;; CASE 5A: we are looking at a defun, brace list, class, 1641 ;; CASE 5A: we are looking at a defun, brace list, class,
1571 ;; or inline-inclass method opening brace 1642 ;; or inline-inclass method opening brace
1600 ;; TBD: watch out! there could be a bogus 1671 ;; TBD: watch out! there could be a bogus
1601 ;; c-state-cache in place when we get here. we have 1672 ;; c-state-cache in place when we get here. we have
1602 ;; to go through much chicanery to ignore the cache. 1673 ;; to go through much chicanery to ignore the cache.
1603 ;; But of course, there may not be! BLECH! BOGUS! 1674 ;; But of course, there may not be! BLECH! BOGUS!
1604 (let ((decl 1675 (let ((decl
1605 (if (boundp 'c-state-cache) 1676 (let ((c-state-cache nil))
1606 (let ((old-cache c-state-cache))
1607 (prog2
1608 (makunbound 'c-state-cache)
1609 (c-search-uplist-for-classkey (c-parse-state))
1610 (setq c-state-cache old-cache)))
1611 (c-search-uplist-for-classkey (c-parse-state)) 1677 (c-search-uplist-for-classkey (c-parse-state))
1612 ))) 1678 )))
1613 (and decl 1679 (and decl
1614 (setq placeholder (aref decl 0))) 1680 (setq placeholder (aref decl 0)))
1615 )) 1681 ))
1623 (if (looking-at "typedef[^_]") 1689 (if (looking-at "typedef[^_]")
1624 (progn (c-forward-sexp 1) 1690 (progn (c-forward-sexp 1)
1625 (c-forward-syntactic-ws indent-point))) 1691 (c-forward-syntactic-ws indent-point)))
1626 (setq placeholder (c-point 'boi)) 1692 (setq placeholder (c-point 'boi))
1627 (or (consp special-brace-list) 1693 (or (consp special-brace-list)
1628 (and (or (looking-at "enum[ \t\n]+") 1694 (and (or (save-excursion
1629 (save-excursion
1630 (goto-char indent-point) 1695 (goto-char indent-point)
1696 (setq tmpsymbol nil)
1631 (while (and (> (point) placeholder) 1697 (while (and (> (point) placeholder)
1632 (= (c-backward-token-1 1 t) 0) 1698 (= (c-backward-token-1 1 t) 0)
1633 (/= (char-after) ?=))) 1699 (/= (char-after) ?=))
1634 (eq (char-after) ?=))) 1700 (if (and (not tmpsymbol)
1701 (looking-at "new\\>[^_]"))
1702 (setq tmpsymbol 'topmost-intro-cont)))
1703 (eq (char-after) ?=))
1704 (looking-at "enum[ \t\n]+"))
1635 (save-excursion 1705 (save-excursion
1636 (while (and (< (point) indent-point) 1706 (while (and (< (point) indent-point)
1637 (= (c-forward-token-1 1 t) 0) 1707 (= (c-forward-token-1 1 t) 0)
1638 (not (memq (char-after) '(?\; ?\())))) 1708 (not (memq (char-after) '(?\; ?\()))))
1639 (not (memq (char-after) '(?\; ?\())) 1709 (not (memq (char-after) '(?\; ?\()))
1640 )))) 1710 ))))
1641 (c-add-syntax 'brace-list-open placeholder)) 1711 (if (and (c-major-mode-is 'java-mode)
1712 (eq tmpsymbol 'topmost-intro-cont))
1713 ;; We're in Java and have found that the open brace
1714 ;; belongs to a "new Foo[]" initialization list,
1715 ;; which means the brace list is part of an
1716 ;; expression and not a top level definition. We
1717 ;; therefore treat it as any topmost continuation
1718 ;; even though the semantically correct symbol still
1719 ;; is brace-list-open, on the same grounds as in
1720 ;; case 10B.2.
1721 (progn
1722 (c-beginning-of-statement-1 lim)
1723 (c-forward-syntactic-ws)
1724 (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
1725 (c-add-syntax 'brace-list-open placeholder)))
1642 ;; CASE 5A.4: inline defun open 1726 ;; CASE 5A.4: inline defun open
1643 ((and inclass-p (not inenclosing-p)) 1727 ((and inclass-p (not inenclosing-p))
1644 (c-add-syntax 'inline-open) 1728 (c-add-syntax 'inline-open)
1645 (c-add-class-syntax 'inclass inclass-p)) 1729 (c-add-class-syntax 'inclass inclass-p))
1646 ;; CASE 5A.5: ordinary defun open 1730 ;; CASE 5A.5: ordinary defun open
2040 ;; CASE 7F: we are looking at an arglist continuation line, 2124 ;; CASE 7F: we are looking at an arglist continuation line,
2041 ;; but the preceding argument is on the same line as the 2125 ;; but the preceding argument is on the same line as the
2042 ;; opening paren. This case includes multi-line 2126 ;; opening paren. This case includes multi-line
2043 ;; mathematical paren groupings, but we could be on a 2127 ;; mathematical paren groupings, but we could be on a
2044 ;; for-list continuation line 2128 ;; for-list continuation line
2045 ((and (save-excursion 2129 ((save-excursion
2046 (goto-char (1+ containing-sexp)) 2130 (goto-char (1+ containing-sexp))
2047 (skip-chars-forward " \t") 2131 (skip-chars-forward " \t")
2048 (not (eolp))) 2132 (not (eolp)))
2049 (save-excursion
2050 (c-beginning-of-statement-1 lim)
2051 (skip-chars-backward " \t([")
2052 (<= (point) containing-sexp)))
2053 (goto-char containing-sexp) 2133 (goto-char containing-sexp)
2054 (setq placeholder (c-point 'boi)) 2134 (setq placeholder (c-point 'boi))
2055 (when (and (c-safe (backward-up-list 1) t) 2135 (when (and (c-safe (backward-up-list 1) t)
2056 (> (point) placeholder)) 2136 (> (point) placeholder))
2057 (forward-char) 2137 (forward-char)
2100 (goto-char containing-sexp) 2180 (goto-char containing-sexp)
2101 (eq (char-after) ?\()) 2181 (eq (char-after) ?\())
2102 (eq char-after-ip (car (cdr special-brace-list)))) 2182 (eq char-after-ip (car (cdr special-brace-list))))
2103 (goto-char (car (car special-brace-list))) 2183 (goto-char (car (car special-brace-list)))
2104 (skip-chars-backward " \t") 2184 (skip-chars-backward " \t")
2105 (if (bolp) 2185 (if (and (bolp)
2106 (setq syntax (c-guess-basic-syntax)) 2186 (assoc 'statement-cont
2187 (setq placeholder (c-guess-basic-syntax))))
2188 (setq syntax placeholder)
2107 (c-beginning-of-statement-1 lim) 2189 (c-beginning-of-statement-1 lim)
2108 (c-forward-token-1 0) 2190 (c-forward-token-1 0)
2109 (if (looking-at "typedef\\>") (c-forward-token-1 1)) 2191 (if (looking-at "typedef\\>") (c-forward-token-1 1))
2110 (c-add-syntax 'brace-list-open (c-point 'boi)))) 2192 (c-add-syntax 'brace-list-open (c-point 'boi))))
2111 ;; CASE 9B: brace-list-close brace 2193 ;; CASE 9B: brace-list-close brace
2149 ((= (point) indent-point) 2231 ((= (point) indent-point)
2150 (goto-char containing-sexp) 2232 (goto-char containing-sexp)
2151 (c-add-syntax 'brace-list-intro (c-point 'boi)) 2233 (c-add-syntax 'brace-list-intro (c-point 'boi))
2152 ) ; end CASE 9C 2234 ) ; end CASE 9C
2153 ;; CASE 9D: this is just a later brace-list-entry or 2235 ;; CASE 9D: this is just a later brace-list-entry or
2154 ;; brace-entry-open 2236 ;; brace-entry-open
2155 (t (if (or (eq char-after-ip ?{) 2237 (t (if (or (eq char-after-ip ?{)
2156 (and c-special-brace-lists 2238 (and c-special-brace-lists
2157 (save-excursion 2239 (save-excursion
2158 (goto-char indent-point) 2240 (goto-char indent-point)
2159 (c-forward-syntactic-ws (c-point 'eol)) 2241 (c-forward-syntactic-ws (c-point 'eol))
2344 (goto-char containing-sexp) 2426 (goto-char containing-sexp)
2345 (back-to-indentation) 2427 (back-to-indentation)
2346 (if (= containing-sexp (point)) 2428 (if (= containing-sexp (point))
2347 (c-add-syntax tmpsymbol (point)) 2429 (c-add-syntax tmpsymbol (point))
2348 (goto-char (cdr placeholder)) 2430 (goto-char (cdr placeholder))
2349 (c-add-syntax tmpsymbol (c-point 'boi)) 2431 (back-to-indentation)
2350 (c-add-syntax (car placeholder)))) 2432 (c-add-syntax tmpsymbol (point))
2433 (if (/= (point) (cdr placeholder))
2434 (c-add-syntax (car placeholder)))))
2351 ;; CASE 16B: does this close an inline or a function in 2435 ;; CASE 16B: does this close an inline or a function in
2352 ;; an extern block or namespace? 2436 ;; an extern block or namespace?
2353 ((progn 2437 ((progn
2354 (goto-char containing-sexp) 2438 (goto-char containing-sexp)
2355 (setq placeholder (c-search-uplist-for-classkey state))) 2439 (setq placeholder (c-search-uplist-for-classkey state)))
2478 'defun-block-intro 2562 'defun-block-intro
2479 'statement-block-intro))) 2563 'statement-block-intro)))
2480 (if (= containing-sexp (point)) 2564 (if (= containing-sexp (point))
2481 (c-add-syntax block-intro (point)) 2565 (c-add-syntax block-intro (point))
2482 (goto-char (cdr placeholder)) 2566 (goto-char (cdr placeholder))
2483 (c-add-syntax block-intro (c-point 'boi)) 2567 (back-to-indentation)
2484 (c-add-syntax (car placeholder)))) 2568 (c-add-syntax block-intro (point))
2569 (if (/= (point) (cdr placeholder))
2570 (c-add-syntax (car placeholder)))))
2485 (if (eq char-after-ip ?{) 2571 (if (eq char-after-ip ?{)
2486 (c-add-syntax 'block-open))) 2572 (c-add-syntax 'block-open)))
2487 ;; CASE 17F: first statement in an inline, or first 2573 ;; CASE 17F: first statement in an inline, or first
2488 ;; statement in a top-level defun. we can tell this is it 2574 ;; statement in a top-level defun. we can tell this is it
2489 ;; if there are no enclosing braces that haven't been 2575 ;; if there are no enclosing braces that haven't been
2531 ;; now we need to look at any modifiers 2617 ;; now we need to look at any modifiers
2532 (goto-char indent-point) 2618 (goto-char indent-point)
2533 (skip-chars-forward " \t") 2619 (skip-chars-forward " \t")
2534 (cond 2620 (cond
2535 ;; are we looking at a comment only line? 2621 ;; are we looking at a comment only line?
2536 ((looking-at c-comment-start-regexp) 2622 ((and (looking-at c-comment-start-regexp)
2623 (/= (c-forward-token-1 0 nil (c-point 'eol)) 0))
2537 (c-add-syntax 'comment-intro)) 2624 (c-add-syntax 'comment-intro))
2538 ;; we might want to give additional offset to friends (in C++). 2625 ;; we might want to give additional offset to friends (in C++).
2539 ((and (c-major-mode-is 'c++-mode) 2626 ((and (c-major-mode-is 'c++-mode)
2540 (looking-at c-C++-friend-key)) 2627 (looking-at c-C++-friend-key))
2541 (c-add-syntax 'friend)) 2628 (c-add-syntax 'friend))
2542 ;; Start of a preprocessor directive? 2629 ;; Start of a preprocessor directive?
2543 ((and (eq literal 'pound) 2630 ((and (eq literal 'pound)
2544 (= (save-excursion 2631 (= (save-excursion
2545 (c-beginning-of-macro lim) 2632 (c-beginning-of-macro lim)
2546 (setq placeholder (point))) 2633 (setq placeholder (point)))
2547 (c-point 'boi))) 2634 (c-point 'boi))
2635 (not (and (c-major-mode-is 'pike-mode)
2636 (eq (char-after (1+ placeholder)) ?\"))))
2548 (c-add-syntax 'cpp-macro))) 2637 (c-add-syntax 'cpp-macro)))
2549 ;; return the syntax 2638 ;; return the syntax
2550 syntax)))) 2639 syntax))))
2551 2640
2552 2641
2553 (defun c-echo-parsing-error () 2642 (defun c-echo-parsing-error (&optional quiet)
2554 (if (not c-parsing-error) 2643 (when (and c-parsing-error (not quiet))
2555 nil 2644 (message "%s" c-parsing-error)
2556 (message "unbalanced close brace at bufpos %d -- INDENTATION IS SUSPECT!"
2557 c-parsing-error)
2558 (ding)) 2645 (ding))
2559 c-parsing-error) 2646 c-parsing-error)
2560 2647
2561 (defun c-shift-line-indentation (shift-amt) 2648 (defun c-shift-line-indentation (shift-amt)
2562 (let ((pos (- (point-max) (point))) 2649 (let ((pos (- (point-max) (point)))
2571 ;; If initial point was within line's indentation, position after 2658 ;; If initial point was within line's indentation, position after
2572 ;; the indentation. Else stay at same point in text. 2659 ;; the indentation. Else stay at same point in text.
2573 (if (> (- (point-max) pos) (point)) 2660 (if (> (- (point-max) pos) (point))
2574 (goto-char (- (point-max) pos)))))) 2661 (goto-char (- (point-max) pos))))))
2575 2662
2576 (defun c-indent-line (&optional syntax) 2663 (defun c-evaluate-offset (offset langelem symbol)
2577 ;; Indent the current line as C/C++/ObjC code, if 2664 ;; offset can be a number, a function, a variable, a list, or one of
2665 ;; the symbols + or -
2666 (cond
2667 ((eq offset '+) c-basic-offset)
2668 ((eq offset '-) (- c-basic-offset))
2669 ((eq offset '++) (* 2 c-basic-offset))
2670 ((eq offset '--) (* 2 (- c-basic-offset)))
2671 ((eq offset '*) (/ c-basic-offset 2))
2672 ((eq offset '/) (/ (- c-basic-offset) 2))
2673 ((numberp offset) offset)
2674 ((functionp offset) (c-evaluate-offset
2675 (funcall offset langelem) langelem symbol))
2676 ((vectorp offset) offset)
2677 ((null offset) nil)
2678 ((listp offset)
2679 (let (done)
2680 (while (and (not done) offset)
2681 (setq done (c-evaluate-offset (car offset) langelem symbol)
2682 offset (cdr offset)))
2683 (if (not done)
2684 (if c-strict-syntax-p
2685 (error "No offset found for syntactic symbol %s" symbol))
2686 done)))
2687 (t (symbol-value offset))
2688 ))
2689
2690 (defun c-get-offset (langelem)
2691 ;; Get offset from LANGELEM which is a cons cell of the form:
2692 ;; (SYMBOL . RELPOS). The symbol is matched against
2693 ;; c-offsets-alist and the offset found there is either returned,
2694 ;; or added to the indentation at RELPOS. If RELPOS is nil, then
2695 ;; the offset is simply returned.
2696 (let* ((symbol (car langelem))
2697 (relpos (cdr langelem))
2698 (match (assq symbol c-offsets-alist))
2699 (offset (cdr-safe match)))
2700 (if (not match)
2701 (if c-strict-syntax-p
2702 (error "No offset found for syntactic symbol %s" symbol)
2703 (setq offset 0
2704 relpos 0))
2705 (setq offset (c-evaluate-offset offset langelem symbol)))
2706 (if (vectorp offset)
2707 offset
2708 (+ (if (and relpos
2709 (< relpos (c-point 'bol)))
2710 (save-excursion
2711 (goto-char relpos)
2712 (current-column))
2713 0)
2714 (or (and (numberp offset) offset)
2715 (and (symbolp offset) (symbol-value offset))
2716 0)))
2717 ))
2718
2719 (defun c-get-syntactic-indentation (langelems)
2720 ;; Apply c-get-offset to a list of langelem cells to get the total
2721 ;; syntactic indentation. Special treatment is needed for vectors
2722 ;; containing absolute columns.
2723 (let ((indent 0))
2724 (catch 'done
2725 (while langelems
2726 (let ((res (c-get-offset (car langelems))))
2727 (if (vectorp res)
2728 (throw 'done (elt res 0))
2729 (setq indent (+ indent res)
2730 langelems (cdr langelems)))))
2731 indent)))
2732
2733 (defun c-indent-line (&optional syntax quiet)
2734 ;; Indent the current line according to the syntactic context, if
2578 ;; c-syntactic-indentation is non-nil. Optional SYNTAX is the 2735 ;; c-syntactic-indentation is non-nil. Optional SYNTAX is the
2579 ;; syntactic information for the current line. Returns the amount 2736 ;; syntactic information for the current line. Be silent about
2580 ;; of indentation change (in columns). 2737 ;; syntactic errors if the optional argument QUIET is non-nil.
2738 ;; Returns the amount of indentation change (in columns).
2581 (let (shift-amt) 2739 (let (shift-amt)
2582 (if c-syntactic-indentation 2740 (if c-syntactic-indentation
2583 (let* ((c-syntactic-context (or syntax (c-guess-basic-syntax))) 2741 (setq c-parsing-error
2584 (indent (apply '+ (mapcar 'c-get-offset c-syntactic-context)))) 2742 (or (let* ((c-parsing-error nil)
2585 (and c-echo-syntactic-information-p 2743 (c-syntactic-context (or syntax
2586 (not (c-echo-parsing-error)) 2744 c-syntactic-context
2587 (message "syntax: %s, indent= %d" c-syntactic-context indent)) 2745 (c-guess-basic-syntax)))
2588 (setq shift-amt (- indent (current-indentation))) 2746 (indent (c-get-syntactic-indentation c-syntactic-context)))
2589 (c-shift-line-indentation shift-amt) 2747 (and (not (c-echo-parsing-error quiet))
2590 (run-hooks 'c-special-indent-hook)) 2748 c-echo-syntactic-information-p
2749 (message "syntax: %s, indent: %d"
2750 c-syntactic-context indent))
2751 (setq shift-amt (- indent (current-indentation)))
2752 (c-shift-line-indentation shift-amt)
2753 (run-hooks 'c-special-indent-hook)
2754 c-parsing-error)
2755 c-parsing-error))
2591 (let ((indent 0)) 2756 (let ((indent 0))
2592 (save-excursion 2757 (save-excursion
2593 (while (and (= (forward-line -1) 0) 2758 (while (and (= (forward-line -1) 0)
2594 (if (looking-at "\\s-*$") 2759 (if (looking-at "\\s-*$")
2595 t 2760 t
2604 "Show syntactic information for current line. 2769 "Show syntactic information for current line.
2605 With universal argument, inserts the analysis as a comment on that line." 2770 With universal argument, inserts the analysis as a comment on that line."
2606 (interactive "P") 2771 (interactive "P")
2607 (let ((syntax (c-guess-basic-syntax))) 2772 (let ((syntax (c-guess-basic-syntax)))
2608 (if (not (consp arg)) 2773 (if (not (consp arg))
2609 (if (not (c-echo-parsing-error)) 2774 (message "syntactic analysis: %s" syntax)
2610 (message "syntactic analysis: %s" syntax))
2611 (indent-for-comment) 2775 (indent-for-comment)
2612 (insert (format "%s" syntax)) 2776 (insert (format "%s" syntax))
2613 )) 2777 ))
2614 (c-keep-region-active)) 2778 (c-keep-region-active))
2615 2779
2623 (while (not (eobp)) 2787 (while (not (eobp))
2624 (c-show-syntactic-information '(0)) 2788 (c-show-syntactic-information '(0))
2625 (forward-line))))) 2789 (forward-line)))))
2626 2790
2627 2791
2628 (provide 'cc-engine) 2792 (cc-provide 'cc-engine)
2629 ;;; cc-engine.el ends here 2793 ;;; cc-engine.el ends here