Initial Commit
[packages] / xemacs-packages / oo-browser / br-c-ft.el
1 ;;!emacs
2 ;;
3 ;; FILE:         br-c-ft.el
4 ;; SUMMARY:      OO-Browser C construct handling.
5 ;; USAGE:        GNU Emacs Lisp Library
6 ;; KEYWORDS:     c, tools
7 ;;
8 ;; AUTHOR:       Bob Weiner
9 ;; ORG:          BeOpen.com
10 ;;
11 ;; ORIG-DATE:     3-May-95 at 16:47:05
12 ;; LAST-MOD:     10-May-01 at 05:45:05 by Bob Weiner
13 ;;
14 ;; Copyright (C) 1995, 1996, 1997, 1999  BeOpen.com
15 ;; See the file BR-COPY for license information.
16 ;;
17 ;; This file is part of the OO-Browser.
18 ;;
19 ;; DESCRIPTION:  
20 ;; DESCRIP-END.
21
22 ;;; ************************************************************************
23 ;;; Public variables
24 ;;; ************************************************************************
25
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.
30
31 If you add a class to this list, you also need to add appropriate code to
32 handle the class in \"ootags.c\".")
33
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.")
37
38 (defconst c++-operator-name-regexp
39   (format "operator ?\\(%s%s%s%s%s\\)"
40           (mapconcat
41            'regexp-quote
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              "+" "*=" "*" "()" "&=" "&&" "&" "%=" "%" "!=" "!")
48            "\\|")
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.
58           "\\|$")
59   "Regular expression matching explicitly named C++ or G++ operators within OO-Browser feature tag files.")
60
61 ;;; ************************************************************************
62 ;;; Public functions
63 ;;; ************************************************************************
64
65 (defun c-add-default-classes ()
66   (br-add-default-classes c-default-classes))
67
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)))
75       nil
76     (cond ((and hyperb:microcruft-os-p (or (not br-shell-executable)
77                                            (not br-ootags-executable)))
78            (if (not br-shell-executable)
79                (progn
80                  (message "No sh/csh/bash found, skipping C construct indexing")
81                  (sit-for 2))))
82           ((not br-ootags-executable)
83            (message
84             "No ootags found, skipping C construct indexing")
85            (sit-for 2))
86           (t
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")
93                       (beginning-of-line)
94                       (eq (following-char) ?\^L))
95                (if (and br-env-version (string-lessp br-env-version "02.11.02"))
96                    nil
97                  (let ((c-tags-start (condition-case ()
98                                          (read (current-buffer))
99                                        (error nil))))
100                    (if c-tags-start
101                        (delete-region c-tags-start (point-max)))
102                    (c-build-element-tags-internal)))
103              (c-build-element-tags-internal))))))
104
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
110              nil nil nil
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))
130     ;;
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\\).*\\)"
138                                   entry-prefix-regexp
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")
162       (forward-line -1))
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"))
172
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.
179   (save-excursion
180     (and (re-search-backward "\\(^\\|[^/]\\)/\\*\\|\\*/" nil t)
181          (not (looking-at "\\*/")))))
182
183 (provide 'br-c-ft)