Annotation of OpenXM_contrib2/windows/post-msg-asirgui/asir-mode.el, Revision 1.2
1.1 takayama 1: ;; -*- mode: emacs-lisp -*-
2: ;;
3: ;; asir-mode.el -- asir mode
4: ;;
1.2 ! ohara 5: ;; $OpenXM: OpenXM_contrib2/windows/post-msg-asirgui/asir-mode.el,v 1.1 2013/08/27 05:51:50 takayama Exp $
1.1 takayama 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 3 of the License, or
10: ;; (at your option) any later version.
11:
12: ;;;; AsirGUI for Windows
13: (defconst asir-exec-path-default '("~/Desktop/asir/bin" "c:/Program Files/asir/bin" "c:/Program Files (x64)/asir/bin" "c:/asir/bin")
14: "Default Search path for asir binary in Windows")
15:
16: (defvar asir-exec-path asir-exec-path-default
17: "Search path for asir binary")
18:
19: (defun asir-effective-exec-path ()
20: "Search path for command"
21: (let* ((dir (getenv "ASIR_ROOTDIR"))
22: (path (append asir-exec-path exec-path)))
23: (if dir (cons (concat dir "/bin") path) path)))
24:
25: (defun asir-executable-find (command)
26: "Search for command"
27: (let* ((exec-path (asir-effective-exec-path)))
28: (executable-find command)))
29:
30: (defun asir-start-asirgui ()
31: "Run asirgui"
32: (interactive)
33: (let ((exec-path (asir-effective-exec-path)))
34: (start-process "asir-proc-asirgui" nil "asirgui")))
35:
36: (defun asir-terminate-asirgui ()
37: "Execute the current buffer on asir"
38: (interactive)
39: (let ((exec-path (asir-effective-exec-path)))
40: (start-process "asir-proc-cmdasir" nil "cmdasir" "--quit")))
41:
42: (defun asir-execute-current-buffer-on-asir ()
43: "Execute the current buffer on asir"
44: (interactive)
45: (let ((exec-path (asir-effective-exec-path)))
46: (start-process "asir-proc-cmdasir" nil "cmdasir" (buffer-file-name))))
47:
48: (defun asir-execute-region-on-asir ()
49: "Execute the region on asir"
50: (interactive)
51: (save-excursion
52: (if mark-active
53: (let ((exec-path (asir-effective-exec-path))
54: (temp-file (make-temp-file (format "%s/cmdasir-" (getenv "TEMP")))))
55: (write-region (region-beginning) (region-end) temp-file)
56: (start-process "asir-proc-cmdasir" nil "cmdasir" temp-file)))))
57:
58: ;;;; Extension for CC-mode.
59:
60: (require 'cc-mode)
61:
62: (eval-when-compile
63: (require 'cc-langs)
64: (require 'cc-engine)
65: (require 'cc-fonts))
66:
67: (eval-and-compile
68: ;; Make our mode known to the language constant system. Use Java
69: ;; mode as the fallback for the constants we don't change here.
70: ;; This needs to be done also at compile time since the language
71: ;; constants are evaluated then.
72: (c-add-language 'asir-mode 'c++-mode))
73:
74: (c-lang-defconst c-stmt-delim-chars asir "^;${}?:")
75: (c-lang-defconst c-stmt-delim-chars-with-comma asir "^;$,{}?:")
76: (c-lang-defconst c-other-op-syntax-tokens
77: asir (cons "$" (c-lang-const c-other-op-syntax-tokens c)))
78: (c-lang-defconst c-identifier-syntax-modifications
79: asir (remove '(?$ . "w") (c-lang-const c-identifier-syntax-modifications c)))
80: (c-lang-defconst c-symbol-chars asir (concat c-alnum "_"))
81:
82: (c-lang-defconst c-primitive-type-kwds asir '("def" "extern" "static" "localf" "function"))
83: (c-lang-defconst c-primitive-type-prefix-kwds asir nil)
84: (c-lang-defconst c-type-list-kwds asir nil)
85: (c-lang-defconst c-class-decl-kwds asir '("module"))
86: (c-lang-defconst c-othe-decl-kwds asir '("endmodule" "end"))
87: (c-lang-defconst c-type-modifier-kwds asir nil)
88: (c-lang-defconst c-modifier-kwds asir nil)
89:
90: (c-lang-defconst c-mode-menu
91: asir
92: (append (c-lang-const c-mode-menu c)
93: '("----"
94: ["Start asirgui" asir-start-asirgui (eq system-type 'windows-nt)]
95: ["Terminate asirgui" asir-terminate-asirgui (eq system-type 'windows-nt)]
96: ["Execute the current buffer on asir" asir-execute-current-buffer-on-asir
97: (and (eq system-type 'windows-nt) (buffer-file-name))]
98: ["Execute the region on asir" asir-execute-region-on-asir
99: (and (eq system-type 'windows-nt) mark-active)]
100: )))
101:
102: (defvar asir-font-lock-extra-types nil
103: "*List of extra types (aside from the type keywords) to recognize in asir mode.
104: Each list item should be a regexp matching a single identifier.")
105:
106: (defconst asir-font-lock-keywords-1 (c-lang-const c-matchers-1 asir)
107: "Minimal highlighting for asir mode.")
108:
109: (defconst asir-font-lock-keywords-2 (c-lang-const c-matchers-2 asir)
110: "Fast normal highlighting for asir mode.")
111:
112: (defconst asir-font-lock-keywords-3 (c-lang-const c-matchers-3 asir)
113: "Accurate normal highlighting for asir mode.")
114:
115: (defvar asir-font-lock-keywords asir-font-lock-keywords-3
116: "Default expressions to highlight in asir mode.")
117:
118: (defvar asir-mode-syntax-table nil
119: "Syntax table used in asir-mode buffers.")
120: (or asir-mode-syntax-table
121: (setq asir-mode-syntax-table
122: (funcall (c-lang-const c-make-mode-syntax-table asir))))
123:
124: (defvar asir-mode-abbrev-table nil
125: "Abbreviation table used in asir-mode buffers.")
126:
127: (defvar asir-mode-map (let ((map (c-make-inherited-keymap)))
128: ;; Add bindings which are only useful for asir
129: map)
130: "Keymap used in asir-mode buffers.")
131:
1.2 ! ohara 132: ;; Key binding for asir-mode
! 133: (define-key asir-mode-map (kbd "C-c s") 'asir-start-asirgui)
! 134: (define-key asir-mode-map (kbd "C-c t") 'asir-terminate-asirgui)
! 135: (define-key asir-mode-map (kbd "C-c l") 'asir-execute-current-buffer-on-asir)
! 136: (define-key asir-mode-map (kbd "C-c r") 'asir-execute-region-on-asir)
! 137:
1.1 takayama 138: (easy-menu-define asir-menu asir-mode-map "asir Mode Commands"
139: ;; Can use `asir' as the language for `c-mode-menu'
140: ;; since its definition covers any language. In
141: ;; this case the language is used to adapt to the
142: ;; nonexistence of a cpp pass and thus removing some
143: ;; irrelevant menu alternatives.
144: (cons "Asir" (c-lang-const c-mode-menu asir)))
145:
146: (defun asir-mode ()
147: "Major mode for editing asir code.
148: This is a simple example of a separate mode derived from CC Mode to
149: support a language with syntax similar to C/C++/ObjC/Java/IDL/Pike.
150:
151: The hook `c-mode-common-hook' is run with no args at mode
152: initialization, then `asir-mode-hook'.
153:
154: Key bindings:
155: \\{asir-mode-map}"
156: (interactive)
157: (kill-all-local-variables)
158: (c-initialize-cc-mode t)
159: (set-syntax-table asir-mode-syntax-table)
160: (setq major-mode 'asir-mode
161: mode-name "asir"
162: local-abbrev-table asir-mode-abbrev-table
163: abbrev-mode t)
164: (use-local-map asir-mode-map)
165: ;; `c-init-language-vars' is a macro that is expanded at compile
166: ;; time to a large `setq' with all the language variables and their
167: ;; customized values for our language.
168: (c-init-language-vars asir-mode)
169: ;; `c-common-init' initializes most of the components of a CC Mode
170: ;; buffer, including setup of the mode menu, font-lock, etc.
171: ;; There's also a lower level routine `c-basic-common-init' that
172: ;; only makes the necessary initialization to get the syntactic
173: ;; analysis and similar things working.
174: (c-common-init 'asir-mode)
175: ;;(easy-menu-add asir-menu)
176: (run-hooks 'c-mode-common-hook)
177: (run-hooks 'asir-mode-hook)
178: (c-update-modeline))
179:
180: (if (fboundp 'asir-backup:c-guess-basic-syntax)
181: nil
182: (fset 'asir-backup:c-guess-basic-syntax (symbol-function 'c-guess-basic-syntax))
183: (defun c-guess-basic-syntax ()
184: "A modified c-guess-basic-syntax for asir-mode"
185: (if (eq major-mode 'asir-mode)
186: (asir-c-guess-basic-syntax)
187: (asir-backup:c-guess-basic-syntax))))
188:
189: ;; Meadow 3 does not have `c-brace-anchor-point'
190: ;; This function was copied from cc-engine.el of Emacs 23.4
191: (if (and (featurep 'meadow) (not (fboundp 'c-brace-anchor-point)))
192: (defun c-brace-anchor-point (bracepos)
193: ;; BRACEPOS is the position of a brace in a construct like "namespace
194: ;; Bar {". Return the anchor point in this construct; this is the
195: ;; earliest symbol on the brace's line which isn't earlier than
196: ;; "namespace".
197: ;;
198: ;; Currently (2007-08-17), "like namespace" means "matches
199: ;; c-other-block-decl-kwds". It doesn't work with "class" or "struct"
200: ;; or anything like that.
201: (save-excursion
202: (let ((boi (c-point 'boi bracepos)))
203: (goto-char bracepos)
204: (while (and (> (point) boi)
205: (not (looking-at c-other-decl-block-key)))
206: (c-backward-token-2))
207: (if (> (point) boi) (point) boi))))
208: )
209:
210: ;; The function `c-guess-basic-syntax' was copied from cc-engine.el of Emacs 23.4 and
211: ;; was modified for Risa/Asir.
212: ;; CASE 5D, 5J, 18 are corrected.
213:
214: ;;;; Beginning of `asir-c-guess-basic-syntax'
215: (defun asir-c-guess-basic-syntax ()
216: "Return the syntactic context of the current line."
217: (save-excursion
218: (beginning-of-line)
219: (c-save-buffer-state
220: ((indent-point (point))
221: (case-fold-search nil)
222: ;; A whole ugly bunch of various temporary variables. Have
223: ;; to declare them here since it's not possible to declare
224: ;; a variable with only the scope of a cond test and the
225: ;; following result clauses, and most of this function is a
226: ;; single gigantic cond. :P
227: literal char-before-ip before-ws-ip char-after-ip macro-start
228: in-macro-expr c-syntactic-context placeholder c-in-literal-cache
229: step-type tmpsymbol keyword injava-inher special-brace-list tmp-pos
230: containing-<
231: ;; The following record some positions for the containing
232: ;; declaration block if we're directly within one:
233: ;; `containing-decl-open' is the position of the open
234: ;; brace. `containing-decl-start' is the start of the
235: ;; declaration. `containing-decl-kwd' is the keyword
236: ;; symbol of the keyword that tells what kind of block it
237: ;; is.
238: containing-decl-open
239: containing-decl-start
240: containing-decl-kwd
241: ;; The open paren of the closest surrounding sexp or nil if
242: ;; there is none.
243: containing-sexp
244: ;; The position after the closest preceding brace sexp
245: ;; (nested sexps are ignored), or the position after
246: ;; `containing-sexp' if there is none, or (point-min) if
247: ;; `containing-sexp' is nil.
248: lim
249: ;; The paren state outside `containing-sexp', or at
250: ;; `indent-point' if `containing-sexp' is nil.
251: (paren-state (c-parse-state))
252: ;; There's always at most one syntactic element which got
253: ;; an anchor pos. It's stored in syntactic-relpos.
254: syntactic-relpos
255: (c-stmt-delim-chars c-stmt-delim-chars))
256:
257: ;; Check if we're directly inside an enclosing declaration
258: ;; level block.
259: (when (and (setq containing-sexp
260: (c-most-enclosing-brace paren-state))
261: (progn
262: (goto-char containing-sexp)
263: (eq (char-after) ?{))
264: (setq placeholder
265: (c-looking-at-decl-block
266: (c-most-enclosing-brace paren-state
267: containing-sexp)
268: t)))
269: (setq containing-decl-open containing-sexp
270: containing-decl-start (point)
271: containing-sexp nil)
272: (goto-char placeholder)
273: (setq containing-decl-kwd (and (looking-at c-keywords-regexp)
274: (c-keyword-sym (match-string 1)))))
275:
276: ;; Init some position variables.
277: (if c-state-cache
278: (progn
279: (setq containing-sexp (car paren-state)
280: paren-state (cdr paren-state))
281: (if (consp containing-sexp)
282: (progn
283: (setq lim (cdr containing-sexp))
284: (if (cdr c-state-cache)
285: ;; Ignore balanced paren. The next entry
286: ;; can't be another one.
287: (setq containing-sexp (car (cdr c-state-cache))
288: paren-state (cdr paren-state))
289: ;; If there is no surrounding open paren then
290: ;; put the last balanced pair back on paren-state.
291: (setq paren-state (cons containing-sexp paren-state)
292: containing-sexp nil)))
293: (setq lim (1+ containing-sexp))))
294: (setq lim (point-min)))
295:
296: ;; If we're in a parenthesis list then ',' delimits the
297: ;; "statements" rather than being an operator (with the
298: ;; exception of the "for" clause). This difference is
299: ;; typically only noticeable when statements are used in macro
300: ;; arglists.
301: (when (and containing-sexp
302: (eq (char-after containing-sexp) ?\())
303: (setq c-stmt-delim-chars c-stmt-delim-chars-with-comma))
304:
305: ;; cache char before and after indent point, and move point to
306: ;; the most likely position to perform the majority of tests
307: (goto-char indent-point)
308: (c-backward-syntactic-ws lim)
309: (setq before-ws-ip (point)
310: char-before-ip (char-before))
311: (goto-char indent-point)
312: (skip-chars-forward " \t")
313: (setq char-after-ip (char-after))
314:
315: ;; are we in a literal?
316: (setq literal (c-in-literal lim))
317:
318: ;; now figure out syntactic qualities of the current line
319: (cond
320:
321: ;; CASE 1: in a string.
322: ((eq literal 'string)
323: (c-add-syntax 'string (c-point 'bopl)))
324:
325: ;; CASE 2: in a C or C++ style comment.
326: ((and (memq literal '(c c++))
327: ;; This is a kludge for XEmacs where we use
328: ;; `buffer-syntactic-context', which doesn't correctly
329: ;; recognize "\*/" to end a block comment.
330: ;; `parse-partial-sexp' which is used by
331: ;; `c-literal-limits' will however do that in most
332: ;; versions, which results in that we get nil from
333: ;; `c-literal-limits' even when `c-in-literal' claims
334: ;; we're inside a comment.
335: (setq placeholder (c-literal-limits lim)))
336: (c-add-syntax literal (car placeholder)))
337:
338: ;; CASE 3: in a cpp preprocessor macro continuation.
339: ((and (save-excursion
340: (when (c-beginning-of-macro)
341: (setq macro-start (point))))
342: (/= macro-start (c-point 'boi))
343: (progn
344: (setq tmpsymbol 'cpp-macro-cont)
345: (or (not c-syntactic-indentation-in-macros)
346: (save-excursion
347: (goto-char macro-start)
348: ;; If at the beginning of the body of a #define
349: ;; directive then analyze as cpp-define-intro
350: ;; only. Go on with the syntactic analysis
351: ;; otherwise. in-macro-expr is set if we're in a
352: ;; cpp expression, i.e. before the #define body
353: ;; or anywhere in a non-#define directive.
354: (if (c-forward-to-cpp-define-body)
355: (let ((indent-boi (c-point 'boi indent-point)))
356: (setq in-macro-expr (> (point) indent-boi)
357: tmpsymbol 'cpp-define-intro)
358: (= (point) indent-boi))
359: (setq in-macro-expr t)
360: nil)))))
361: (c-add-syntax tmpsymbol macro-start)
362: (setq macro-start nil))
363:
364: ;; CASE 11: an else clause?
365: ((looking-at "else\\>[^_]")
366: (c-beginning-of-statement-1 containing-sexp)
367: (c-add-stmt-syntax 'else-clause nil t
368: containing-sexp paren-state))
369:
370: ;; CASE 12: while closure of a do/while construct?
371: ((and (looking-at "while\\>[^_]")
372: (save-excursion
373: (prog1 (eq (c-beginning-of-statement-1 containing-sexp)
374: 'beginning)
375: (setq placeholder (point)))))
376: (goto-char placeholder)
377: (c-add-stmt-syntax 'do-while-closure nil t
378: containing-sexp paren-state))
379:
380: ;; CASE 13: A catch or finally clause? This case is simpler
381: ;; than if-else and do-while, because a block is required
382: ;; after every try, catch and finally.
383: ((save-excursion
384: (and (cond ((c-major-mode-is 'c++-mode)
385: (looking-at "catch\\>[^_]"))
386: ((c-major-mode-is 'java-mode)
387: (looking-at "\\(catch\\|finally\\)\\>[^_]")))
388: (and (c-safe (c-backward-syntactic-ws)
389: (c-backward-sexp)
390: t)
391: (eq (char-after) ?{)
392: (c-safe (c-backward-syntactic-ws)
393: (c-backward-sexp)
394: t)
395: (if (eq (char-after) ?\()
396: (c-safe (c-backward-sexp) t)
397: t))
398: (looking-at "\\(try\\|catch\\)\\>[^_]")
399: (setq placeholder (point))))
400: (goto-char placeholder)
401: (c-add-stmt-syntax 'catch-clause nil t
402: containing-sexp paren-state))
403:
404: ;; CASE 18: A substatement we can recognize by keyword.
405: ((save-excursion
406: (and c-opt-block-stmt-key
407: (not (eq char-before-ip ?\;))
408: (not (c-at-vsemi-p before-ws-ip))
409: (not (memq char-after-ip '(?\) ?\] ?,)))
410: (or (not (eq char-before-ip ?}))
411: (c-looking-at-inexpr-block-backward c-state-cache))
412: (> (point)
413: (progn
414: ;; Ought to cache the result from the
415: ;; c-beginning-of-statement-1 calls here.
416: (setq placeholder (point))
417: (while (eq (setq step-type
418: (c-beginning-of-statement-1 lim))
419: 'label))
420: (if (eq step-type 'previous)
421: (goto-char placeholder)
422: (setq placeholder (point))
423: (if (and (eq step-type 'same)
424: (not (looking-at c-opt-block-stmt-key)))
425: ;; Step up to the containing statement if we
426: ;; stayed in the same one.
427: (let (step)
428: (while (eq
429: (setq step
430: (c-beginning-of-statement-1 lim))
431: 'label))
432: (if (eq step 'up)
433: (setq placeholder (point))
434: ;; There was no containing statement after all.
435: (goto-char placeholder)))))
436: placeholder))
437: (if (looking-at c-block-stmt-2-key)
438: ;; Require a parenthesis after these keywords.
439: ;; Necessary to catch e.g. synchronized in Java,
440: ;; which can be used both as statement and
441: ;; modifier.
442: (and (zerop (c-forward-token-2 1 nil))
443: (eq (char-after) ?\())
444: (looking-at c-opt-block-stmt-key))))
445:
446: (if (eq step-type 'up)
447: ;; CASE 18A: Simple substatement.
448: (progn
449: (goto-char placeholder)
450: (cond
451: ((eq char-after-ip ?{)
452: (c-add-stmt-syntax 'substatement-open nil nil
453: containing-sexp paren-state))
454: ((save-excursion
455: (goto-char indent-point)
456: (back-to-indentation)
457: (c-forward-label))
458: (c-add-stmt-syntax 'substatement-label nil nil
459: containing-sexp paren-state))
460: (t
461: (c-add-stmt-syntax 'substatement nil nil
462: containing-sexp paren-state))))
463:
464: ;; CASE 18B: Some other substatement. This is shared
465: ;; with case 10.
466: (c-guess-continued-construct indent-point
467: char-after-ip
468: placeholder
469: lim
470: paren-state)))
471:
472: ;; CASE 14: A case or default label
473: ((looking-at c-label-kwds-regexp)
474: (if containing-sexp
475: (progn
476: (goto-char containing-sexp)
477: (setq lim (c-most-enclosing-brace c-state-cache
478: containing-sexp))
479: (c-backward-to-block-anchor lim)
480: (c-add-stmt-syntax 'case-label nil t lim paren-state))
481: ;; Got a bogus label at the top level. In lack of better
482: ;; alternatives, anchor it on (point-min).
483: (c-add-syntax 'case-label (point-min))))
484:
485: ;; CASE 15: any other label
486: ((save-excursion
487: (back-to-indentation)
488: (and (not (looking-at c-syntactic-ws-start))
489: (c-forward-label)))
490: (cond (containing-decl-open
491: (setq placeholder (c-add-class-syntax 'inclass
492: containing-decl-open
493: containing-decl-start
494: containing-decl-kwd
495: paren-state))
496: ;; Append access-label with the same anchor point as
497: ;; inclass gets.
498: (c-append-syntax 'access-label placeholder))
499:
500: (containing-sexp
501: (goto-char containing-sexp)
502: (setq lim (c-most-enclosing-brace c-state-cache
503: containing-sexp))
504: (save-excursion
505: (setq tmpsymbol
506: (if (and (eq (c-beginning-of-statement-1 lim) 'up)
507: (looking-at "switch\\>[^_]"))
508: ;; If the surrounding statement is a switch then
509: ;; let's analyze all labels as switch labels, so
510: ;; that they get lined up consistently.
511: 'case-label
512: 'label)))
513: (c-backward-to-block-anchor lim)
514: (c-add-stmt-syntax tmpsymbol nil t lim paren-state))
515:
516: (t
517: ;; A label on the top level. Treat it as a class
518: ;; context. (point-min) is the closest we get to the
519: ;; class open brace.
520: (c-add-syntax 'access-label (point-min)))))
521:
522: ;; CASE 4: In-expression statement. C.f. cases 7B, 16A and
523: ;; 17E.
524: ((setq placeholder (c-looking-at-inexpr-block
525: (c-safe-position containing-sexp paren-state)
526: containing-sexp
527: ;; Have to turn on the heuristics after
528: ;; the point even though it doesn't work
529: ;; very well. C.f. test case class-16.pike.
530: t))
531: (setq tmpsymbol (assq (car placeholder)
532: '((inexpr-class . class-open)
533: (inexpr-statement . block-open))))
534: (if tmpsymbol
535: ;; It's a statement block or an anonymous class.
536: (setq tmpsymbol (cdr tmpsymbol))
537: ;; It's a Pike lambda. Check whether we are between the
538: ;; lambda keyword and the argument list or at the defun
539: ;; opener.
540: (setq tmpsymbol (if (eq char-after-ip ?{)
541: 'inline-open
542: 'lambda-intro-cont)))
543: (goto-char (cdr placeholder))
544: (back-to-indentation)
545: (c-add-stmt-syntax tmpsymbol nil t
546: (c-most-enclosing-brace c-state-cache (point))
547: paren-state)
548: (unless (eq (point) (cdr placeholder))
549: (c-add-syntax (car placeholder))))
550:
551: ;; CASE 5: Line is inside a declaration level block or at top level.
552: ((or containing-decl-open (null containing-sexp))
553: (cond
554:
555: ;; CASE 5A: we are looking at a defun, brace list, class,
556: ;; or inline-inclass method opening brace
557: ((setq special-brace-list
558: (or (and c-special-brace-lists
559: (c-looking-at-special-brace-list))
560: (eq char-after-ip ?{)))
561: (cond
562:
563: ;; CASE 5A.1: Non-class declaration block open.
564: ((save-excursion
565: (let (tmp)
566: (and (eq char-after-ip ?{)
567: (setq tmp (c-looking-at-decl-block containing-sexp t))
568: (progn
569: (setq placeholder (point))
570: (goto-char tmp)
571: (looking-at c-symbol-key))
572: (c-keyword-member
573: (c-keyword-sym (setq keyword (match-string 0)))
574: 'c-other-block-decl-kwds))))
575: (goto-char placeholder)
576: (c-add-stmt-syntax
577: (if (string-equal keyword "extern")
578: ;; Special case for extern-lang-open.
579: 'extern-lang-open
580: (intern (concat keyword "-open")))
581: nil t containing-sexp paren-state))
582:
583: ;; CASE 5A.2: we are looking at a class opening brace
584: ((save-excursion
585: (goto-char indent-point)
586: (skip-chars-forward " \t")
587: (and (eq (char-after) ?{)
588: (c-looking-at-decl-block containing-sexp t)
589: (setq placeholder (point))))
590: (c-add-syntax 'class-open placeholder))
591:
592: ;; CASE 5A.3: brace list open
593: ((save-excursion
594: (c-beginning-of-decl-1 lim)
595: (while (looking-at c-specifier-key)
596: (goto-char (match-end 1))
597: (c-forward-syntactic-ws indent-point))
598: (setq placeholder (c-point 'boi))
599: (or (consp special-brace-list)
600: (and (or (save-excursion
601: (goto-char indent-point)
602: (setq tmpsymbol nil)
603: (while (and (> (point) placeholder)
604: (zerop (c-backward-token-2 1 t))
605: (/= (char-after) ?=))
606: (and c-opt-inexpr-brace-list-key
607: (not tmpsymbol)
608: (looking-at c-opt-inexpr-brace-list-key)
609: (setq tmpsymbol 'topmost-intro-cont)))
610: (eq (char-after) ?=))
611: (looking-at c-brace-list-key))
612: (save-excursion
613: (while (and (< (point) indent-point)
614: (zerop (c-forward-token-2 1 t))
615: (not (memq (char-after) '(?\; ?\()))))
616: (not (memq (char-after) '(?\; ?\()))
617: ))))
618: (if (and (not c-auto-newline-analysis)
619: (c-major-mode-is 'java-mode)
620: (eq tmpsymbol 'topmost-intro-cont))
621: ;; We're in Java and have found that the open brace
622: ;; belongs to a "new Foo[]" initialization list,
623: ;; which means the brace list is part of an
624: ;; expression and not a top level definition. We
625: ;; therefore treat it as any topmost continuation
626: ;; even though the semantically correct symbol still
627: ;; is brace-list-open, on the same grounds as in
628: ;; case B.2.
629: (progn
630: (c-beginning-of-statement-1 lim)
631: (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
632: (c-add-syntax 'brace-list-open placeholder)))
633:
634: ;; CASE 5A.4: inline defun open
635: ((and containing-decl-open
636: (not (c-keyword-member containing-decl-kwd
637: 'c-other-block-decl-kwds)))
638: (c-add-syntax 'inline-open)
639: (c-add-class-syntax 'inclass
640: containing-decl-open
641: containing-decl-start
642: containing-decl-kwd
643: paren-state))
644:
645: ;; CASE 5A.5: ordinary defun open
646: (t
647: (save-excursion
648: (c-beginning-of-decl-1 lim)
649: (while (looking-at c-specifier-key)
650: (goto-char (match-end 1))
651: (c-forward-syntactic-ws indent-point))
652: (c-add-syntax 'defun-open (c-point 'boi))
653: ;; Bogus to use bol here, but it's the legacy. (Resolved,
654: ;; 2007-11-09)
655: ))))
656:
657: ;; CASE 5B: After a function header but before the body (or
658: ;; the ending semicolon if there's no body).
659: ((save-excursion
660: (when (setq placeholder (c-just-after-func-arglist-p lim))
661: (setq tmp-pos (point))))
662: (cond
663:
664: ;; CASE 5B.1: Member init list.
665: ((eq (char-after tmp-pos) ?:)
666: (if (or (> tmp-pos indent-point)
667: (= (c-point 'bosws) (1+ tmp-pos)))
668: (progn
669: ;; There is no preceding member init clause.
670: ;; Indent relative to the beginning of indentation
671: ;; for the topmost-intro line that contains the
672: ;; prototype's open paren.
673: (goto-char placeholder)
674: (c-add-syntax 'member-init-intro (c-point 'boi)))
675: ;; Indent relative to the first member init clause.
676: (goto-char (1+ tmp-pos))
677: (c-forward-syntactic-ws)
678: (c-add-syntax 'member-init-cont (point))))
679:
680: ;; CASE 5B.2: K&R arg decl intro
681: ((and c-recognize-knr-p
682: (c-in-knr-argdecl lim))
683: (c-beginning-of-statement-1 lim)
684: (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
685: (if containing-decl-open
686: (c-add-class-syntax 'inclass
687: containing-decl-open
688: containing-decl-start
689: containing-decl-kwd
690: paren-state)))
691:
692: ;; CASE 5B.4: Nether region after a C++ or Java func
693: ;; decl, which could include a `throws' declaration.
694: (t
695: (c-beginning-of-statement-1 lim)
696: (c-add-syntax 'func-decl-cont (c-point 'boi))
697: )))
698:
699: ;; CASE 5C: inheritance line. could be first inheritance
700: ;; line, or continuation of a multiple inheritance
701: ((or (and (c-major-mode-is 'c++-mode)
702: (progn
703: (when (eq char-after-ip ?,)
704: (skip-chars-forward " \t")
705: (forward-char))
706: (looking-at c-opt-postfix-decl-spec-key)))
707: (and (or (eq char-before-ip ?:)
708: ;; watch out for scope operator
709: (save-excursion
710: (and (eq char-after-ip ?:)
711: (c-safe (forward-char 1) t)
712: (not (eq (char-after) ?:))
713: )))
714: (save-excursion
715: (c-backward-syntactic-ws lim)
716: (if (eq char-before-ip ?:)
717: (progn
718: (forward-char -1)
719: (c-backward-syntactic-ws lim)))
720: (back-to-indentation)
721: (looking-at c-class-key)))
722: ;; for Java
723: (and (c-major-mode-is 'java-mode)
724: (let ((fence (save-excursion
725: (c-beginning-of-statement-1 lim)
726: (point)))
727: cont done)
728: (save-excursion
729: (while (not done)
730: (cond ((looking-at c-opt-postfix-decl-spec-key)
731: (setq injava-inher (cons cont (point))
732: done t))
733: ((or (not (c-safe (c-forward-sexp -1) t))
734: (<= (point) fence))
735: (setq done t))
736: )
737: (setq cont t)))
738: injava-inher)
739: (not (c-crosses-statement-barrier-p (cdr injava-inher)
740: (point)))
741: ))
742: (cond
743:
744: ;; CASE 5C.1: non-hanging colon on an inher intro
745: ((eq char-after-ip ?:)
746: (c-beginning-of-statement-1 lim)
747: (c-add-syntax 'inher-intro (c-point 'boi))
748: ;; don't add inclass symbol since relative point already
749: ;; contains any class offset
750: )
751:
752: ;; CASE 5C.2: hanging colon on an inher intro
753: ((eq char-before-ip ?:)
754: (c-beginning-of-statement-1 lim)
755: (c-add-syntax 'inher-intro (c-point 'boi))
756: (if containing-decl-open
757: (c-add-class-syntax 'inclass
758: containing-decl-open
759: containing-decl-start
760: containing-decl-kwd
761: paren-state)))
762:
763: ;; CASE 5C.3: in a Java implements/extends
764: (injava-inher
765: (let ((where (cdr injava-inher))
766: (cont (car injava-inher)))
767: (goto-char where)
768: (cond ((looking-at "throws\\>[^_]")
769: (c-add-syntax 'func-decl-cont
770: (progn (c-beginning-of-statement-1 lim)
771: (c-point 'boi))))
772: (cont (c-add-syntax 'inher-cont where))
773: (t (c-add-syntax 'inher-intro
774: (progn (goto-char (cdr injava-inher))
775: (c-beginning-of-statement-1 lim)
776: (point))))
777: )))
778:
779: ;; CASE 5C.4: a continued inheritance line
780: (t
781: (c-beginning-of-inheritance-list lim)
782: (c-add-syntax 'inher-cont (point))
783: ;; don't add inclass symbol since relative point already
784: ;; contains any class offset
785: )))
786:
787: ;; CASE 5D: this could be a top-level initialization, a
788: ;; member init list continuation, or a template argument
789: ;; list continuation.
790: ((save-excursion
791: ;; Note: We use the fact that lim is always after any
792: ;; preceding brace sexp.
793: (if c-recognize-<>-arglists
794: (while (and
795: (progn
796: (c-syntactic-skip-backward "^;$,=<>" lim t)
797: (> (point) lim))
798: (or
799: (when c-overloadable-operators-regexp
800: (when (setq placeholder (c-after-special-operator-id lim))
801: (goto-char placeholder)
802: t))
803: (cond
804: ((eq (char-before) ?>)
805: (or (c-backward-<>-arglist nil lim)
806: (backward-char))
807: t)
808: ((eq (char-before) ?<)
809: (backward-char)
810: (if (save-excursion
811: (c-forward-<>-arglist nil))
812: (progn (forward-char)
813: nil)
814: t))
815: (t nil)))))
816: ;; NB: No c-after-special-operator-id stuff in this
817: ;; clause - we assume only C++ needs it.
818: (c-syntactic-skip-backward "^;$,=" lim t))
819: (memq (char-before) '(?, ?= ?<)))
820: (cond
821:
822: ;; CASE 5D.3: perhaps a template list continuation?
823: ((and (c-major-mode-is 'c++-mode)
824: (save-excursion
825: (save-restriction
826: (c-with-syntax-table c++-template-syntax-table
827: (goto-char indent-point)
828: (setq placeholder (c-up-list-backward))
829: (and placeholder
830: (eq (char-after placeholder) ?<))))))
831: (c-with-syntax-table c++-template-syntax-table
832: (goto-char placeholder)
833: (c-beginning-of-statement-1 lim t)
834: (if (save-excursion
835: (c-backward-syntactic-ws lim)
836: (eq (char-before) ?<))
837: ;; In a nested template arglist.
838: (progn
839: (goto-char placeholder)
840: (c-syntactic-skip-backward "^,;" lim t)
841: (c-forward-syntactic-ws))
842: (back-to-indentation)))
843: ;; FIXME: Should use c-add-stmt-syntax, but it's not yet
844: ;; template aware.
845: (c-add-syntax 'template-args-cont (point) placeholder))
846:
847: ;; CASE 5D.4: perhaps a multiple inheritance line?
848: ((and (c-major-mode-is 'c++-mode)
849: (save-excursion
850: (c-beginning-of-statement-1 lim)
851: (setq placeholder (point))
852: (if (looking-at "static\\>[^_]")
853: (c-forward-token-2 1 nil indent-point))
854: (and (looking-at c-class-key)
855: (zerop (c-forward-token-2 2 nil indent-point))
856: (if (eq (char-after) ?<)
857: (c-with-syntax-table c++-template-syntax-table
858: (zerop (c-forward-token-2 1 t indent-point)))
859: t)
860: (eq (char-after) ?:))))
861: (goto-char placeholder)
862: (c-add-syntax 'inher-cont (c-point 'boi)))
863:
864: ;; CASE 5D.5: Continuation of the "expression part" of a
865: ;; top level construct. Or, perhaps, an unrecognized construct.
866: (t
867: (while (and (setq placeholder (point))
868: (eq (car (c-beginning-of-decl-1 containing-sexp))
869: 'same)
870: (save-excursion
871: (c-backward-syntactic-ws)
872: (eq (char-before) ?}))
873: (< (point) placeholder)))
874: (c-add-stmt-syntax
875: (cond
876: ((eq (point) placeholder) 'statement) ; unrecognized construct
877: ;; A preceding comma at the top level means that a
878: ;; new variable declaration starts here. Use
879: ;; topmost-intro-cont for it, for consistency with
880: ;; the first variable declaration. C.f. case 5N.
881: ((eq char-before-ip ?,) 'topmost-intro-cont)
882: (t 'statement-cont))
883: nil nil containing-sexp paren-state))
884: ))
885:
886: ;; CASE 5F: Close of a non-class declaration level block.
887: ((and (eq char-after-ip ?})
888: (c-keyword-member containing-decl-kwd
889: 'c-other-block-decl-kwds))
890: ;; This is inconsistent: Should use `containing-decl-open'
891: ;; here if it's at boi, like in case 5J.
892: (goto-char containing-decl-start)
893: (c-add-stmt-syntax
894: (if (string-equal (symbol-name containing-decl-kwd) "extern")
895: ;; Special case for compatibility with the
896: ;; extern-lang syntactic symbols.
897: 'extern-lang-close
898: (intern (concat (symbol-name containing-decl-kwd)
899: "-close")))
900: nil t
901: (c-most-enclosing-brace paren-state (point))
902: paren-state))
903:
904: ;; CASE 5G: we are looking at the brace which closes the
905: ;; enclosing nested class decl
906: ((and containing-sexp
907: (eq char-after-ip ?})
908: (eq containing-decl-open containing-sexp))
909: (c-add-class-syntax 'class-close
910: containing-decl-open
911: containing-decl-start
912: containing-decl-kwd
913: paren-state))
914:
915: ;; CASE 5H: we could be looking at subsequent knr-argdecls
916: ((and c-recognize-knr-p
917: (not containing-sexp) ; can't be knr inside braces.
918: (not (eq char-before-ip ?}))
919: (save-excursion
920: (setq placeholder (cdr (c-beginning-of-decl-1 lim)))
921: (and placeholder
922: ;; Do an extra check to avoid tripping up on
923: ;; statements that occur in invalid contexts
924: ;; (e.g. in macro bodies where we don't really
925: ;; know the context of what we're looking at).
926: (not (and c-opt-block-stmt-key
927: (looking-at c-opt-block-stmt-key)))))
928: (< placeholder indent-point))
929: (goto-char placeholder)
930: (c-add-syntax 'knr-argdecl (point)))
931:
932: ;; CASE 5I: ObjC method definition.
933: ((and c-opt-method-key
934: (looking-at c-opt-method-key))
935: (c-beginning-of-statement-1 nil t)
936: (if (= (point) indent-point)
937: ;; Handle the case when it's the first (non-comment)
938: ;; thing in the buffer. Can't look for a 'same return
939: ;; value from cbos1 since ObjC directives currently
940: ;; aren't recognized fully, so that we get 'same
941: ;; instead of 'previous if it moved over a preceding
942: ;; directive.
943: (goto-char (point-min)))
944: (c-add-syntax 'objc-method-intro (c-point 'boi)))
945:
946: ;; CASE 5P: AWK pattern or function or continuation
947: ;; thereof.
948: ((c-major-mode-is 'awk-mode)
949: (setq placeholder (point))
950: (c-add-stmt-syntax
951: (if (and (eq (c-beginning-of-statement-1) 'same)
952: (/= (point) placeholder))
953: 'topmost-intro-cont
954: 'topmost-intro)
955: nil nil
956: containing-sexp paren-state))
957:
958: ;; CASE 5N: At a variable declaration that follows a class
959: ;; definition or some other block declaration that doesn't
960: ;; end at the closing '}'. C.f. case 5D.5.
961: ((progn
962: (c-backward-syntactic-ws lim)
963: (and (eq (char-before) ?})
964: (save-excursion
965: (let ((start (point)))
966: (if (and c-state-cache
967: (consp (car c-state-cache))
968: (eq (cdar c-state-cache) (point)))
969: ;; Speed up the backward search a bit.
970: (goto-char (caar c-state-cache)))
971: (c-beginning-of-decl-1 containing-sexp)
972: (setq placeholder (point))
973: (if (= start (point))
974: ;; The '}' is unbalanced.
975: nil
976: (c-end-of-decl-1)
977: (>= (point) indent-point))))))
978: (goto-char placeholder)
979: (c-add-stmt-syntax 'topmost-intro-cont nil nil
980: containing-sexp paren-state))
981:
982: ;; NOTE: The point is at the end of the previous token here.
983:
984: ;; CASE 5J: we are at the topmost level, make
985: ;; sure we skip back past any access specifiers
986: ((and
987: ;; A macro continuation line is never at top level.
988: (not (and macro-start
989: (> indent-point macro-start)))
990: (save-excursion
991: (setq placeholder (point))
992: (or (memq char-before-ip '(?\; ?$ ?{ ?} nil))
993: (c-at-vsemi-p before-ws-ip)
994: (when (and (eq char-before-ip ?:)
995: (eq (c-beginning-of-statement-1 lim)
996: 'label))
997: (c-backward-syntactic-ws lim)
998: (setq placeholder (point)))
999: (and (c-major-mode-is 'objc-mode)
1000: (catch 'not-in-directive
1001: (c-beginning-of-statement-1 lim)
1002: (setq placeholder (point))
1003: (while (and (c-forward-objc-directive)
1004: (< (point) indent-point))
1005: (c-forward-syntactic-ws)
1006: (if (>= (point) indent-point)
1007: (throw 'not-in-directive t))
1008: (setq placeholder (point)))
1009: nil)))))
1010: ;; For historic reasons we anchor at bol of the last
1011: ;; line of the previous declaration. That's clearly
1012: ;; highly bogus and useless, and it makes our lives hard
1013: ;; to remain compatible. :P
1014: (goto-char placeholder)
1015: (c-add-syntax 'topmost-intro (c-point 'bol))
1016: (if containing-decl-open
1017: (if (c-keyword-member containing-decl-kwd
1018: 'c-other-block-decl-kwds)
1019: (progn
1020: (goto-char (c-brace-anchor-point containing-decl-open))
1021: (c-add-stmt-syntax
1022: (if (string-equal (symbol-name containing-decl-kwd)
1023: "extern")
1024: ;; Special case for compatibility with the
1025: ;; extern-lang syntactic symbols.
1026: 'inextern-lang
1027: (intern (concat "in"
1028: (symbol-name containing-decl-kwd))))
1029: nil t
1030: (c-most-enclosing-brace paren-state (point))
1031: paren-state))
1032: (c-add-class-syntax 'inclass
1033: containing-decl-open
1034: containing-decl-start
1035: containing-decl-kwd
1036: paren-state)))
1037: (when (and c-syntactic-indentation-in-macros
1038: macro-start
1039: (/= macro-start (c-point 'boi indent-point)))
1040: (c-add-syntax 'cpp-define-intro)
1041: (setq macro-start nil)))
1042:
1043: ;; CASE 5K: we are at an ObjC method definition
1044: ;; continuation line.
1045: ((and c-opt-method-key
1046: (save-excursion
1047: (c-beginning-of-statement-1 lim)
1048: (beginning-of-line)
1049: (when (looking-at c-opt-method-key)
1050: (setq placeholder (point)))))
1051: (c-add-syntax 'objc-method-args-cont placeholder))
1052:
1053: ;; CASE 5L: we are at the first argument of a template
1054: ;; arglist that begins on the previous line.
1055: ((and c-recognize-<>-arglists
1056: (eq (char-before) ?<)
1057: (setq placeholder (1- (point)))
1058: (not (and c-overloadable-operators-regexp
1059: (c-after-special-operator-id lim))))
1060: (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
1061: (c-add-syntax 'template-args-cont (c-point 'boi) placeholder))
1062:
1063: ;; CASE 5Q: we are at a statement within a macro.
1064: (macro-start
1065: (c-beginning-of-statement-1 containing-sexp)
1066: (c-add-stmt-syntax 'statement nil t containing-sexp paren-state))
1067:
1068: ;; CASE 5M: we are at a topmost continuation line
1069: (t
1070: (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
1071: (when (c-major-mode-is 'objc-mode)
1072: (setq placeholder (point))
1073: (while (and (c-forward-objc-directive)
1074: (< (point) indent-point))
1075: (c-forward-syntactic-ws)
1076: (setq placeholder (point)))
1077: (goto-char placeholder))
1078: (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
1079: ))
1080:
1081: ;; (CASE 6 has been removed.)
1082:
1083: ;; CASE 19: line is an expression, not a statement, and is directly
1084: ;; contained by a template delimiter. Most likely, we are in a
1085: ;; template arglist within a statement. This case is based on CASE
1086: ;; 7. At some point in the future, we may wish to create more
1087: ;; syntactic symbols such as `template-intro',
1088: ;; `template-cont-nonempty', etc., and distinguish between them as we
1089: ;; do for `arglist-intro' etc. (2009-12-07).
1090: ((and c-recognize-<>-arglists
1091: (setq containing-< (c-up-list-backward indent-point containing-sexp))
1092: (eq (char-after containing-<) ?\<))
1093: (setq placeholder (c-point 'boi containing-<))
1094: (goto-char containing-sexp) ; Most nested Lbrace/Lparen (but not
1095: ; '<') before indent-point.
1096: (if (>= (point) placeholder)
1097: (progn
1098: (forward-char)
1099: (skip-chars-forward " \t"))
1100: (goto-char placeholder))
1101: (c-add-stmt-syntax 'template-args-cont (list containing-<) t
1102: (c-most-enclosing-brace c-state-cache (point))
1103: paren-state))
1104:
1105:
1106: ;; CASE 7: line is an expression, not a statement. Most
1107: ;; likely we are either in a function prototype or a function
1108: ;; call argument list, or a template argument list.
1109: ((not (or (and c-special-brace-lists
1110: (save-excursion
1111: (goto-char containing-sexp)
1112: (c-looking-at-special-brace-list)))
1113: (eq (char-after containing-sexp) ?{)
1114: (eq (char-after containing-sexp) ?<)))
1115: (cond
1116:
1117: ;; CASE 7A: we are looking at the arglist closing paren.
1118: ;; C.f. case 7F.
1119: ((memq char-after-ip '(?\) ?\]))
1120: (goto-char containing-sexp)
1121: (setq placeholder (c-point 'boi))
1122: (if (and (c-safe (backward-up-list 1) t)
1123: (>= (point) placeholder))
1124: (progn
1125: (forward-char)
1126: (skip-chars-forward " \t"))
1127: (goto-char placeholder))
1128: (c-add-stmt-syntax 'arglist-close (list containing-sexp) t
1129: (c-most-enclosing-brace paren-state (point))
1130: paren-state))
1131:
1132: ;; CASE 7B: Looking at the opening brace of an
1133: ;; in-expression block or brace list. C.f. cases 4, 16A
1134: ;; and 17E.
1135: ((and (eq char-after-ip ?{)
1136: (progn
1137: (setq placeholder (c-inside-bracelist-p (point)
1138: paren-state))
1139: (if placeholder
1140: (setq tmpsymbol '(brace-list-open . inexpr-class))
1141: (setq tmpsymbol '(block-open . inexpr-statement)
1142: placeholder
1143: (cdr-safe (c-looking-at-inexpr-block
1144: (c-safe-position containing-sexp
1145: paren-state)
1146: containing-sexp)))
1147: ;; placeholder is nil if it's a block directly in
1148: ;; a function arglist. That makes us skip out of
1149: ;; this case.
1150: )))
1151: (goto-char placeholder)
1152: (back-to-indentation)
1153: (c-add-stmt-syntax (car tmpsymbol) nil t
1154: (c-most-enclosing-brace paren-state (point))
1155: paren-state)
1156: (if (/= (point) placeholder)
1157: (c-add-syntax (cdr tmpsymbol))))
1158:
1159: ;; CASE 7C: we are looking at the first argument in an empty
1160: ;; argument list. Use arglist-close if we're actually
1161: ;; looking at a close paren or bracket.
1162: ((memq char-before-ip '(?\( ?\[))
1163: (goto-char containing-sexp)
1164: (setq placeholder (c-point 'boi))
1165: (if (and (c-safe (backward-up-list 1) t)
1166: (>= (point) placeholder))
1167: (progn
1168: (forward-char)
1169: (skip-chars-forward " \t"))
1170: (goto-char placeholder))
1171: (c-add-stmt-syntax 'arglist-intro (list containing-sexp) t
1172: (c-most-enclosing-brace paren-state (point))
1173: paren-state))
1174:
1175: ;; CASE 7D: we are inside a conditional test clause. treat
1176: ;; these things as statements
1177: ((progn
1178: (goto-char containing-sexp)
1179: (and (c-safe (c-forward-sexp -1) t)
1180: (looking-at "\\<for\\>[^_]")))
1181: (goto-char (1+ containing-sexp))
1182: (c-forward-syntactic-ws indent-point)
1183: (if (eq char-before-ip ?\;)
1184: (c-add-syntax 'statement (point))
1185: (c-add-syntax 'statement-cont (point))
1186: ))
1187:
1188: ;; CASE 7E: maybe a continued ObjC method call. This is the
1189: ;; case when we are inside a [] bracketed exp, and what
1190: ;; precede the opening bracket is not an identifier.
1191: ((and c-opt-method-key
1192: (eq (char-after containing-sexp) ?\[)
1193: (progn
1194: (goto-char (1- containing-sexp))
1195: (c-backward-syntactic-ws (c-point 'bod))
1196: (if (not (looking-at c-symbol-key))
1197: (c-add-syntax 'objc-method-call-cont containing-sexp))
1198: )))
1199:
1200: ;; CASE 7F: we are looking at an arglist continuation line,
1201: ;; but the preceding argument is on the same line as the
1202: ;; opening paren. This case includes multi-line
1203: ;; mathematical paren groupings, but we could be on a
1204: ;; for-list continuation line. C.f. case 7A.
1205: ((progn
1206: (goto-char (1+ containing-sexp))
1207: (< (save-excursion
1208: (c-forward-syntactic-ws)
1209: (point))
1210: (c-point 'bonl)))
1211: (goto-char containing-sexp) ; paren opening the arglist
1212: (setq placeholder (c-point 'boi))
1213: (if (and (c-safe (backward-up-list 1) t)
1214: (>= (point) placeholder))
1215: (progn
1216: (forward-char)
1217: (skip-chars-forward " \t"))
1218: (goto-char placeholder))
1219: (c-add-stmt-syntax 'arglist-cont-nonempty (list containing-sexp) t
1220: (c-most-enclosing-brace c-state-cache (point))
1221: paren-state))
1222:
1223: ;; CASE 7G: we are looking at just a normal arglist
1224: ;; continuation line
1225: (t (c-forward-syntactic-ws indent-point)
1226: (c-add-syntax 'arglist-cont (c-point 'boi)))
1227: ))
1228:
1229: ;; CASE 8: func-local multi-inheritance line
1230: ((and (c-major-mode-is 'c++-mode)
1231: (save-excursion
1232: (goto-char indent-point)
1233: (skip-chars-forward " \t")
1234: (looking-at c-opt-postfix-decl-spec-key)))
1235: (goto-char indent-point)
1236: (skip-chars-forward " \t")
1237: (cond
1238:
1239: ;; CASE 8A: non-hanging colon on an inher intro
1240: ((eq char-after-ip ?:)
1241: (c-backward-syntactic-ws lim)
1242: (c-add-syntax 'inher-intro (c-point 'boi)))
1243:
1244: ;; CASE 8B: hanging colon on an inher intro
1245: ((eq char-before-ip ?:)
1246: (c-add-syntax 'inher-intro (c-point 'boi)))
1247:
1248: ;; CASE 8C: a continued inheritance line
1249: (t
1250: (c-beginning-of-inheritance-list lim)
1251: (c-add-syntax 'inher-cont (point))
1252: )))
1253:
1254: ;; CASE 9: we are inside a brace-list
1255: ((and (not (c-major-mode-is 'awk-mode)) ; Maybe this isn't needed (ACM, 2002/3/29)
1256: (setq special-brace-list
1257: (or (and c-special-brace-lists ;;;; ALWAYS NIL FOR AWK!!
1258: (save-excursion
1259: (goto-char containing-sexp)
1260: (c-looking-at-special-brace-list)))
1261: (c-inside-bracelist-p containing-sexp paren-state))))
1262: (cond
1263:
1264: ;; CASE 9A: In the middle of a special brace list opener.
1265: ((and (consp special-brace-list)
1266: (save-excursion
1267: (goto-char containing-sexp)
1268: (eq (char-after) ?\())
1269: (eq char-after-ip (car (cdr special-brace-list))))
1270: (goto-char (car (car special-brace-list)))
1271: (skip-chars-backward " \t")
1272: (if (and (bolp)
1273: (assoc 'statement-cont
1274: (setq placeholder (c-guess-basic-syntax))))
1275: (setq c-syntactic-context placeholder)
1276: (c-beginning-of-statement-1
1277: (c-safe-position (1- containing-sexp) paren-state))
1278: (c-forward-token-2 0)
1279: (while (looking-at c-specifier-key)
1280: (goto-char (match-end 1))
1281: (c-forward-syntactic-ws))
1282: (c-add-syntax 'brace-list-open (c-point 'boi))))
1283:
1284: ;; CASE 9B: brace-list-close brace
1285: ((if (consp special-brace-list)
1286: ;; Check special brace list closer.
1287: (progn
1288: (goto-char (car (car special-brace-list)))
1289: (save-excursion
1290: (goto-char indent-point)
1291: (back-to-indentation)
1292: (or
1293: ;; We were between the special close char and the `)'.
1294: (and (eq (char-after) ?\))
1295: (eq (1+ (point)) (cdr (car special-brace-list))))
1296: ;; We were before the special close char.
1297: (and (eq (char-after) (cdr (cdr special-brace-list)))
1298: (zerop (c-forward-token-2))
1299: (eq (1+ (point)) (cdr (car special-brace-list)))))))
1300: ;; Normal brace list check.
1301: (and (eq char-after-ip ?})
1302: (c-safe (goto-char (c-up-list-backward (point))) t)
1303: (= (point) containing-sexp)))
1304: (if (eq (point) (c-point 'boi))
1305: (c-add-syntax 'brace-list-close (point))
1306: (setq lim (c-most-enclosing-brace c-state-cache (point)))
1307: (c-beginning-of-statement-1 lim)
1308: (c-add-stmt-syntax 'brace-list-close nil t lim paren-state)))
1309:
1310: (t
1311: ;; Prepare for the rest of the cases below by going to the
1312: ;; token following the opening brace
1313: (if (consp special-brace-list)
1314: (progn
1315: (goto-char (car (car special-brace-list)))
1316: (c-forward-token-2 1 nil indent-point))
1317: (goto-char containing-sexp))
1318: (forward-char)
1319: (let ((start (point)))
1320: (c-forward-syntactic-ws indent-point)
1321: (goto-char (max start (c-point 'bol))))
1322: (c-skip-ws-forward indent-point)
1323: (cond
1324:
1325: ;; CASE 9C: we're looking at the first line in a brace-list
1326: ((= (point) indent-point)
1327: (if (consp special-brace-list)
1328: (goto-char (car (car special-brace-list)))
1329: (goto-char containing-sexp))
1330: (if (eq (point) (c-point 'boi))
1331: (c-add-syntax 'brace-list-intro (point))
1332: (setq lim (c-most-enclosing-brace c-state-cache (point)))
1333: (c-beginning-of-statement-1 lim)
1334: (c-add-stmt-syntax 'brace-list-intro nil t lim paren-state)))
1335:
1336: ;; CASE 9D: this is just a later brace-list-entry or
1337: ;; brace-entry-open
1338: (t (if (or (eq char-after-ip ?{)
1339: (and c-special-brace-lists
1340: (save-excursion
1341: (goto-char indent-point)
1342: (c-forward-syntactic-ws (c-point 'eol))
1343: (c-looking-at-special-brace-list (point)))))
1344: (c-add-syntax 'brace-entry-open (point))
1345: (c-add-syntax 'brace-list-entry (point))
1346: ))
1347: ))))
1348:
1349: ;; CASE 10: A continued statement or top level construct.
1350: ((and (not (memq char-before-ip '(?\; ?:)))
1351: (not (c-at-vsemi-p before-ws-ip))
1352: (or (not (eq char-before-ip ?}))
1353: (c-looking-at-inexpr-block-backward c-state-cache))
1354: (> (point)
1355: (save-excursion
1356: (c-beginning-of-statement-1 containing-sexp)
1357: (setq placeholder (point))))
1358: (/= placeholder containing-sexp))
1359: ;; This is shared with case 18.
1360: (c-guess-continued-construct indent-point
1361: char-after-ip
1362: placeholder
1363: containing-sexp
1364: paren-state))
1365:
1366: ;; CASE 16: block close brace, possibly closing the defun or
1367: ;; the class
1368: ((eq char-after-ip ?})
1369: ;; From here on we have the next containing sexp in lim.
1370: (setq lim (c-most-enclosing-brace paren-state))
1371: (goto-char containing-sexp)
1372: (cond
1373:
1374: ;; CASE 16E: Closing a statement block? This catches
1375: ;; cases where it's preceded by a statement keyword,
1376: ;; which works even when used in an "invalid" context,
1377: ;; e.g. a macro argument.
1378: ((c-after-conditional)
1379: (c-backward-to-block-anchor lim)
1380: (c-add-stmt-syntax 'block-close nil t lim paren-state))
1381:
1382: ;; CASE 16A: closing a lambda defun or an in-expression
1383: ;; block? C.f. cases 4, 7B and 17E.
1384: ((setq placeholder (c-looking-at-inexpr-block
1385: (c-safe-position containing-sexp paren-state)
1386: nil))
1387: (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
1388: 'inline-close
1389: 'block-close))
1390: (goto-char containing-sexp)
1391: (back-to-indentation)
1392: (if (= containing-sexp (point))
1393: (c-add-syntax tmpsymbol (point))
1394: (goto-char (cdr placeholder))
1395: (back-to-indentation)
1396: (c-add-stmt-syntax tmpsymbol nil t
1397: (c-most-enclosing-brace paren-state (point))
1398: paren-state)
1399: (if (/= (point) (cdr placeholder))
1400: (c-add-syntax (car placeholder)))))
1401:
1402: ;; CASE 16B: does this close an inline or a function in
1403: ;; a non-class declaration level block?
1404: ((save-excursion
1405: (and lim
1406: (progn
1407: (goto-char lim)
1408: (c-looking-at-decl-block
1409: (c-most-enclosing-brace paren-state lim)
1410: nil))
1411: (setq placeholder (point))))
1412: (c-backward-to-decl-anchor lim)
1413: (back-to-indentation)
1414: (if (save-excursion
1415: (goto-char placeholder)
1416: (looking-at c-other-decl-block-key))
1417: (c-add-syntax 'defun-close (point))
1418: (c-add-syntax 'inline-close (point))))
1419:
1420: ;; CASE 16F: Can be a defun-close of a function declared
1421: ;; in a statement block, e.g. in Pike or when using gcc
1422: ;; extensions, but watch out for macros followed by
1423: ;; blocks. Let it through to be handled below.
1424: ;; C.f. cases B.3 and 17G.
1425: ((save-excursion
1426: (and (not (c-at-statement-start-p))
1427: (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
1428: (setq placeholder (point))
1429: (let ((c-recognize-typeless-decls nil))
1430: ;; Turn off recognition of constructs that
1431: ;; lacks a type in this case, since that's more
1432: ;; likely to be a macro followed by a block.
1433: (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil))))
1434: (back-to-indentation)
1435: (if (/= (point) containing-sexp)
1436: (goto-char placeholder))
1437: (c-add-stmt-syntax 'defun-close nil t lim paren-state))
1438:
1439: ;; CASE 16C: If there is an enclosing brace then this is
1440: ;; a block close since defun closes inside declaration
1441: ;; level blocks have been handled above.
1442: (lim
1443: ;; If the block is preceded by a case/switch label on
1444: ;; the same line, we anchor at the first preceding label
1445: ;; at boi. The default handling in c-add-stmt-syntax
1446: ;; really fixes it better, but we do like this to keep
1447: ;; the indentation compatible with version 5.28 and
1448: ;; earlier. C.f. case 17H.
1449: (while (and (/= (setq placeholder (point)) (c-point 'boi))
1450: (eq (c-beginning-of-statement-1 lim) 'label)))
1451: (goto-char placeholder)
1452: (if (looking-at c-label-kwds-regexp)
1453: (c-add-syntax 'block-close (point))
1454: (goto-char containing-sexp)
1455: ;; c-backward-to-block-anchor not necessary here; those
1456: ;; situations are handled in case 16E above.
1457: (c-add-stmt-syntax 'block-close nil t lim paren-state)))
1458:
1459: ;; CASE 16D: Only top level defun close left.
1460: (t
1461: (goto-char containing-sexp)
1462: (c-backward-to-decl-anchor lim)
1463: (c-add-stmt-syntax 'defun-close nil nil
1464: (c-most-enclosing-brace paren-state)
1465: paren-state))
1466: ))
1467:
1468: ;; CASE 17: Statement or defun catchall.
1469: (t
1470: (goto-char indent-point)
1471: ;; Back up statements until we find one that starts at boi.
1472: (while (let* ((prev-point (point))
1473: (last-step-type (c-beginning-of-statement-1
1474: containing-sexp)))
1475: (if (= (point) prev-point)
1476: (progn
1477: (setq step-type (or step-type last-step-type))
1478: nil)
1479: (setq step-type last-step-type)
1480: (/= (point) (c-point 'boi)))))
1481: (cond
1482:
1483: ;; CASE 17B: continued statement
1484: ((and (eq step-type 'same)
1485: (/= (point) indent-point))
1486: (c-add-stmt-syntax 'statement-cont nil nil
1487: containing-sexp paren-state))
1488:
1489: ;; CASE 17A: After a case/default label?
1490: ((progn
1491: (while (and (eq step-type 'label)
1492: (not (looking-at c-label-kwds-regexp)))
1493: (setq step-type
1494: (c-beginning-of-statement-1 containing-sexp)))
1495: (eq step-type 'label))
1496: (c-add-stmt-syntax (if (eq char-after-ip ?{)
1497: 'statement-case-open
1498: 'statement-case-intro)
1499: nil t containing-sexp paren-state))
1500:
1501: ;; CASE 17D: any old statement
1502: ((progn
1503: (while (eq step-type 'label)
1504: (setq step-type
1505: (c-beginning-of-statement-1 containing-sexp)))
1506: (eq step-type 'previous))
1507: (c-add-stmt-syntax 'statement nil t
1508: containing-sexp paren-state)
1509: (if (eq char-after-ip ?{)
1510: (c-add-syntax 'block-open)))
1511:
1512: ;; CASE 17I: Inside a substatement block.
1513: ((progn
1514: ;; The following tests are all based on containing-sexp.
1515: (goto-char containing-sexp)
1516: ;; From here on we have the next containing sexp in lim.
1517: (setq lim (c-most-enclosing-brace paren-state containing-sexp))
1518: (c-after-conditional))
1519: (c-backward-to-block-anchor lim)
1520: (c-add-stmt-syntax 'statement-block-intro nil t
1521: lim paren-state)
1522: (if (eq char-after-ip ?{)
1523: (c-add-syntax 'block-open)))
1524:
1525: ;; CASE 17E: first statement in an in-expression block.
1526: ;; C.f. cases 4, 7B and 16A.
1527: ((setq placeholder (c-looking-at-inexpr-block
1528: (c-safe-position containing-sexp paren-state)
1529: nil))
1530: (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
1531: 'defun-block-intro
1532: 'statement-block-intro))
1533: (back-to-indentation)
1534: (if (= containing-sexp (point))
1535: (c-add-syntax tmpsymbol (point))
1536: (goto-char (cdr placeholder))
1537: (back-to-indentation)
1538: (c-add-stmt-syntax tmpsymbol nil t
1539: (c-most-enclosing-brace c-state-cache (point))
1540: paren-state)
1541: (if (/= (point) (cdr placeholder))
1542: (c-add-syntax (car placeholder))))
1543: (if (eq char-after-ip ?{)
1544: (c-add-syntax 'block-open)))
1545:
1546: ;; CASE 17F: first statement in an inline, or first
1547: ;; statement in a top-level defun. we can tell this is it
1548: ;; if there are no enclosing braces that haven't been
1549: ;; narrowed out by a class (i.e. don't use bod here).
1550: ((save-excursion
1551: (or (not (setq placeholder (c-most-enclosing-brace
1552: paren-state)))
1553: (and (progn
1554: (goto-char placeholder)
1555: (eq (char-after) ?{))
1556: (c-looking-at-decl-block (c-most-enclosing-brace
1557: paren-state (point))
1558: nil))))
1559: (c-backward-to-decl-anchor lim)
1560: (back-to-indentation)
1561: (c-add-syntax 'defun-block-intro (point)))
1562:
1563: ;; CASE 17G: First statement in a function declared inside
1564: ;; a normal block. This can occur in Pike and with
1565: ;; e.g. the gcc extensions, but watch out for macros
1566: ;; followed by blocks. C.f. cases B.3 and 16F.
1567: ((save-excursion
1568: (and (not (c-at-statement-start-p))
1569: (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
1570: (setq placeholder (point))
1571: (let ((c-recognize-typeless-decls nil))
1572: ;; Turn off recognition of constructs that lacks
1573: ;; a type in this case, since that's more likely
1574: ;; to be a macro followed by a block.
1575: (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil))))
1576: (back-to-indentation)
1577: (if (/= (point) containing-sexp)
1578: (goto-char placeholder))
1579: (c-add-stmt-syntax 'defun-block-intro nil t
1580: lim paren-state))
1581:
1582: ;; CASE 17H: First statement in a block.
1583: (t
1584: ;; If the block is preceded by a case/switch label on the
1585: ;; same line, we anchor at the first preceding label at
1586: ;; boi. The default handling in c-add-stmt-syntax is
1587: ;; really fixes it better, but we do like this to keep the
1588: ;; indentation compatible with version 5.28 and earlier.
1589: ;; C.f. case 16C.
1590: (while (and (/= (setq placeholder (point)) (c-point 'boi))
1591: (eq (c-beginning-of-statement-1 lim) 'label)))
1592: (goto-char placeholder)
1593: (if (looking-at c-label-kwds-regexp)
1594: (c-add-syntax 'statement-block-intro (point))
1595: (goto-char containing-sexp)
1596: ;; c-backward-to-block-anchor not necessary here; those
1597: ;; situations are handled in case 17I above.
1598: (c-add-stmt-syntax 'statement-block-intro nil t
1599: lim paren-state))
1600: (if (eq char-after-ip ?{)
1601: (c-add-syntax 'block-open)))
1602: ))
1603: )
1604:
1605: ;; now we need to look at any modifiers
1606: (goto-char indent-point)
1607: (skip-chars-forward " \t")
1608:
1609: ;; are we looking at a comment only line?
1610: (when (and (looking-at c-comment-start-regexp)
1611: (/= (c-forward-token-2 0 nil (c-point 'eol)) 0))
1612: (c-append-syntax 'comment-intro))
1613:
1614: ;; we might want to give additional offset to friends (in C++).
1615: (when (and c-opt-friend-key
1616: (looking-at c-opt-friend-key))
1617: (c-append-syntax 'friend))
1618:
1619: ;; Set syntactic-relpos.
1620: (let ((p c-syntactic-context))
1621: (while (and p
1622: (if (integerp (c-langelem-pos (car p)))
1623: (progn
1624: (setq syntactic-relpos (c-langelem-pos (car p)))
1625: nil)
1626: t))
1627: (setq p (cdr p))))
1628:
1629: ;; Start of or a continuation of a preprocessor directive?
1630: (if (and macro-start
1631: (eq macro-start (c-point 'boi))
1632: (not (and (c-major-mode-is 'pike-mode)
1633: (eq (char-after (1+ macro-start)) ?\"))))
1634: (c-append-syntax 'cpp-macro)
1635: (when (and c-syntactic-indentation-in-macros macro-start)
1636: (if in-macro-expr
1637: (when (or
1638: (< syntactic-relpos macro-start)
1639: (not (or
1640: (assq 'arglist-intro c-syntactic-context)
1641: (assq 'arglist-cont c-syntactic-context)
1642: (assq 'arglist-cont-nonempty c-syntactic-context)
1643: (assq 'arglist-close c-syntactic-context))))
1644: ;; If inside a cpp expression, i.e. anywhere in a
1645: ;; cpp directive except a #define body, we only let
1646: ;; through the syntactic analysis that is internal
1647: ;; in the expression. That means the arglist
1648: ;; elements, if they are anchored inside the cpp
1649: ;; expression.
1650: (setq c-syntactic-context nil)
1651: (c-add-syntax 'cpp-macro-cont macro-start))
1652: (when (and (eq macro-start syntactic-relpos)
1653: (not (assq 'cpp-define-intro c-syntactic-context))
1654: (save-excursion
1655: (goto-char macro-start)
1656: (or (not (c-forward-to-cpp-define-body))
1657: (<= (point) (c-point 'boi indent-point)))))
1658: ;; Inside a #define body and the syntactic analysis is
1659: ;; anchored on the start of the #define. In this case
1660: ;; we add cpp-define-intro to get the extra
1661: ;; indentation of the #define body.
1662: (c-add-syntax 'cpp-define-intro)))))
1663:
1664: ;; return the syntax
1665: c-syntactic-context)))
1666:
1667: ;;;; End of `asir-c-guess-basic-syntax'
1668:
1669: (provide 'asir-mode)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>