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