4 ;; SUMMARY: OO-Browser C construct handling.
5 ;; USAGE: GNU Emacs Lisp Library
11 ;; ORIG-DATE: 3-May-95 at 16:47:05
12 ;; LAST-MOD: 10-May-01 at 05:45:05 by Bob Weiner
14 ;; Copyright (C) 1995, 1996, 1997, 1999 BeOpen.com
15 ;; See the file BR-COPY for license information.
17 ;; This file is part of the OO-Browser.
22 ;;; ************************************************************************
24 ;;; ************************************************************************
26 (defvar c-default-classes
27 '("[constant]" "[enumeration]" "[enum_label]" "[function]" "[macro]"
28 "[structure]" "[type]" "[union]" "[variable]")
29 "*List of default class names of C constructs handled by the OO-Browser.
31 If you add a class to this list, you also need to add appropriate code to
32 handle the class in \"ootags.c\".")
34 (defconst c++-function-identifier
35 (concat "[_~\<a-zA-Z][^\]\[ \t\n\r\f:\;.,~{}()
\7f]*")
36 "Regular expression matching a C++ or G++ function name.")
38 (defconst c++-operator-name-regexp
39 (format "operator ?\\(%s%s%s%s%s\\)"
42 ;; Each item in this list which contains a prefix for another item
43 ;; must precede the other item or the shorter item will be matched
44 ;; improperly, for example, "==" must precede "=".
45 '("~" "||" "|=" "|" "^=" "^" "[]" "?" ">>=" ">>" ">=" ">" "==" "="
46 "<=" "<<=" "<<" "<" "/=" "/" "->*" "->" "-=" "--" "-" "+=" "++"
47 "+" "*=" "*" "()" "&=" "&&" "&" "%=" "%" "!=" "!")
49 ;; Handles delete, new, delete[] and new[].
50 "\\|delete ?\\[?\\]?\\|new *\\[?\\]?\\|"
51 ;; Handles operator <type>, <type>* and <type>& operators.
52 c++-function-identifier " ?[*&]*"
53 ;; The next expression matches to entries such as `int operator'
54 ;; where ootags has stripped the type of operator. We still want to
55 ;; register this as a function even though its definition won't be
56 ;; found. This typically happens if a space occurs between the
57 ;; operator keyword and an `=' or `*' operator character.
59 "Regular expression matching explicitly named C++ or G++ operators within OO-Browser feature tag files.")
61 ;;; ************************************************************************
63 ;;; ************************************************************************
65 (defun c-add-default-classes ()
66 (br-add-default-classes c-default-classes))
68 (defun c-build-element-tags ()
69 "Create C constructs tags file for the current Environment.
70 Call this after building the language-specific feature tags file."
71 (if (not (and br-c-tags-flag
72 (br-member br-lang-prefix
73 '("c++-" "eif-" "java-" "objc-" "python-"))
74 (stringp br-tags-tmp-file)))
76 (cond ((and hyperb:microcruft-os-p (or (not br-shell-executable)
77 (not br-ootags-executable)))
78 (if (not br-shell-executable)
80 (message "No sh/csh/bash found, skipping C construct indexing")
82 ((not br-ootags-executable)
84 "No ootags found, skipping C construct indexing")
87 ;; If C tags have already been added to feature tags, then the
88 ;; feature tags buffer ends with ^L.
89 (br-feature-set-tags-buffer)
90 ;; Remove any old C construct tags.
91 (if (progn (goto-char (point-max))
92 (skip-chars-backward "\n")
94 (eq (following-char) ?\^L))
95 (if (and br-env-version (string-lessp br-env-version "02.11.02"))
97 (let ((c-tags-start (condition-case ()
98 (read (current-buffer))
101 (delete-region c-tags-start (point-max)))
102 (c-build-element-tags-internal)))
103 (c-build-element-tags-internal))))))
105 (defun c-build-element-tags-internal ()
106 ;; Build new C construct tags.
107 (message "Building C construct index...")
108 (if hyperb:microcruft-os-p
109 (apply 'call-process br-shell-executable
111 (expand-file-name "br-c-tags" br-directory)
112 br-ootags-executable br-tags-tmp-file
113 (mapcar 'expand-file-name
114 (delq nil (append br-sys-search-dirs
115 br-lib-search-dirs))))
116 (apply 'call-process (expand-file-name "br-c-tags" br-directory)
117 nil nil nil br-ootags-executable br-tags-tmp-file
118 (mapcar 'expand-file-name
119 (delq nil (append br-sys-search-dirs br-lib-search-dirs)))))
120 (goto-char (point-max))
121 (let ((c-tags-start (point)))
122 (if (file-readable-p br-tags-tmp-file)
123 (insert-file-contents br-tags-tmp-file))
124 (goto-char (point-max))
125 ;; Insert delimiter to mark both the start and end of C tags insertion.
126 (insert "\^L " (int-to-string c-tags-start) "\n")
127 (if (and (file-readable-p br-tags-tmp-file)
128 (file-writable-p br-tags-tmp-file))
129 (delete-file br-tags-tmp-file))
131 ;; Fix up C++ operator tags which ootags doesn't format properly.
132 (if (equal br-lang-prefix "c++-")
133 (let* ((entry-prefix-regexp
134 (format "^[^%s \n\r/\\]+%s[^%s\n\r]*%s"
135 c++-type-tag-separator c++-type-tag-separator
136 c++-type-tag-separator c++-type-tag-separator))
137 (op-regexp (format "%s\\(.*\\(%s\\).*\\)"
139 c++-operator-name-regexp))
140 (op-tag-replacement (format "[function]%s- \\2%s\\1"
141 c++-type-tag-separator
142 c++-type-tag-separator))
143 ;; This is presently the same as op-tag-replacement but may
144 ;; be changed in the future.
145 (op-unknown-tag-replacement
146 (format "[function]%s- \\2%s\\1"
147 c++-type-tag-separator c++-type-tag-separator)))
148 (goto-char c-tags-start)
149 ;; Remove any scoped entries which the OO-Browser
150 ;; handles without ootags help.
151 (delete-matching-lines (concat entry-prefix-regexp "[^\(\n\r]+::"))
152 ;; Fix up global operator entries.
153 (while (re-search-forward op-regexp nil t)
154 (if (= (match-beginning 3) (match-end 3))
155 ;; Type of operator was dropped by ootags.
156 (replace-match op-unknown-tag-replacement t)
157 (replace-match op-tag-replacement t)))))
158 (goto-char c-tags-start)
159 ;; Remove tag files which have no entries.
160 (while (re-search-forward "^\^L\n.*\n\^L\n" nil t)
161 (replace-match "\^L\n")
163 ;; Remove // style comments
164 (goto-char c-tags-start)
165 (while (re-search-forward "^\\(\\[.*\\)[ \t]*//.*" nil t)
166 (replace-match "\\1"))
167 ;; Normalize C tag entries.
168 (goto-char c-tags-start)
169 (while (re-search-forward "[ \t\r][ \t\r]+" nil t)
170 (replace-match " ")))
171 (message "Building C construct index...Done"))
173 (defun c-within-comment-p ()
174 "Return non-nil if point is within a multi-line C comment."
175 ;; Generally don't have to check whether patterns are matched on single line
176 ;; comments ( // ...) since the regexps to match to will preclude this.
177 ;; Ignore comments of the form //***, which look like C comments when
178 ;; searching backward but are actually single line comments.
180 (and (re-search-backward "\\(^\\|[^/]\\)/\\*\\|\\*/" nil t)
181 (not (looking-at "\\*/")))))