Remove non-free old and crusty clearcase pkg
[packages] / xemacs-packages / semantic / semantic-tag-file.el
1 ;;; semantic-tag-file.el --- Routines that find files based on tags.
2
3 ;;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Eric M. Ludlam
4
5 ;; Author: Eric M. Ludlam <zappo@gnu.org>
6 ;; Keywords: syntax
7 ;; X-RCS: $Id: semantic-tag-file.el,v 1.1 2007-11-26 15:10:43 michaels Exp $
8
9 ;; This file is not part of GNU Emacs.
10
11 ;; Semantic is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15
16 ;; This software is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
25
26 ;;; Commentary:
27 ;;
28 ;; A tag, by itself, can have representations in several files.
29 ;; These routines will find those files.
30
31 (require 'semantic-tag)
32
33 ;;; Code:
34
35 ;;; Location a TAG came from.
36 ;;
37 ;;;###autoload
38 (define-overload semantic-go-to-tag (tag &optional parent)
39   "Go to the location of TAG.
40 TAG may be a stripped element, in which case PARENT specifies a
41 parent tag that has position information.
42 Different behaviors are provided depending on the type of tag.
43 For example, dependencies (includes) will seek out the file that is
44 depended on (see `semantic-dependency-tag-file'."
45   (:override
46    (unless (and (eq (semantic-tag-class tag) 'include)
47                 (let ((f (semantic-dependency-tag-file tag)))
48                   (when f
49                     (set-buffer (find-file-noselect f))
50                     (point))))
51      (cond ((semantic-tag-buffer tag)
52             ;; We have a linked tag, go to that buffer.
53             (set-buffer (semantic-tag-buffer tag)))
54            ((semantic-tag-file-name tag)
55             ;; If it didn't have a buffer, but does have a file
56             ;; name, then we need to get to that file so the tag
57             ;; location is made accurate.
58             (set-buffer (find-file-noselect (semantic-tag-file-name tag))))
59            ((and parent (semantic-tag-p parent) (semantic-tag-buffer parent))
60             ;; The tag had nothing useful, but we have a parent with
61             ;; a buffer, then go there.
62             (set-buffer (semantic-tag-buffer parent)))
63            ((and parent (semantic-tag-p parent) (semantic-tag-file-name parent))
64             ;; Tag had nothing, and the parent only has a file-name, then
65             ;; find that file, and switch to that buffer.
66             (set-buffer (find-file-noselect (semantic-tag-file-name parent))))
67            (t
68             ;; Well, just assume things are in the current buffer.
69             nil
70             ))
71      ;; We should be in the correct buffer now, try and figure out
72      ;; where the tag is.
73      (cond ((semantic-tag-with-position-p tag)
74             ;; If it's a number, go there
75             (goto-char (semantic-tag-start tag)))
76            ((semantic-tag-with-position-p parent)
77             ;; Otherwise, it's a trimmed vector, such as a parameter,
78             ;; or a structure part.  If there is a parent, we can use it
79             ;; as a bounds for searching.
80             (goto-char (semantic-tag-start parent))
81             ;; Here we make an assumption that the text returned by
82             ;; the parser and concocted by us actually exists
83             ;; in the buffer.
84             (re-search-forward (semantic-tag-name tag)
85                                (semantic-tag-end parent)
86                                t))
87            (t
88             ;; Take a guess that the tag has a unique name, and just
89             ;; search for it from the beginning of the buffer.
90             (goto-char (point-min))
91             (re-search-forward (semantic-tag-name tag) nil t)))
92      ))
93   )
94
95 (make-obsolete-overload 'semantic-find-nonterminal
96                         'semantic-go-to-tag)
97
98 ;;; Dependencies
99 ;;
100 ;; A tag which is of type 'include specifies a dependency.
101 ;; Dependencies usually represent a file of some sort.
102 ;; Find the file described by a dependency.
103 ;;; Code:
104 ;;;###autoload
105 (defvar semantic-dependency-include-path nil
106   "Defines the include path used when searching for files.
107 This should be a list of directories to search which is specific
108 to the file being included.
109
110 If `semantic-dependency-tag-file' is overridden for a given
111 language, this path is most likely ignored.
112
113 This function, reguardless of being overriden, caches the located
114 dependency file location in the tag property `dependency-file'.
115 If you override this function, you do not need to implement your
116 own cache.  Each time the buffer is fully reparsed, the cache
117 will be reset.
118
119 TODO: use ffap.el to locate such items.")
120 (make-variable-buffer-local `semantic-dependency-include-path)
121
122 ;;;###autoload
123 (define-overload semantic-dependency-tag-file (&optional tag)
124   "Find the filename represented from TAG.
125 Depends on `semantic-dependency-include-path' for searching.  Always searches
126 `.' first, then searches additional paths."
127   (or tag (setq tag (car (semantic-find-tag-by-overlay nil))))
128   (unless (semantic-tag-of-class-p tag 'include)
129     (signal 'wrong-type-argument (list tag 'include)))
130   (save-excursion
131     (cond ((semantic-tag-buffer tag)
132            ;; If the tag has an overlay and buffer associated with it,
133            ;; switch to that buffer so that we get the right override metohds.
134            (set-buffer (semantic-tag-buffer tag)))
135           ((semantic-tag-file-name tag)
136            ;; If it didn't have a buffer, but does have a file
137            ;; name, then we need to get to that file so the tag
138            ;; location is made accurate.
139            (set-buffer (find-file-noselect (semantic-tag-file-name tag)))))
140     ;; First, see if this file exists in the current EDE project
141     (if (and (fboundp 'ede-expand-filename) ede-minor-mode
142              (ede-expand-filename (ede-toplevel)
143                                   (semantic-tag-name tag)))
144         (ede-expand-filename (ede-toplevel)
145                              (semantic-tag-name tag))
146       (let
147           ((result
148             (if (semantic--tag-get-property tag 'dependency-file)
149                 (semantic--tag-get-property tag 'dependency-file)
150               (:override
151                (save-excursion
152                  (let* ((name (semantic-tag-name tag)))
153                    (semantic-dependency-find-file-on-path
154                     name (semantic-tag-include-system-p tag)))))
155               )))
156         (if (stringp result)
157             (progn
158               (semantic--tag-put-property tag 'dependency-file result)
159               result)
160           ;; @todo: Do something to make this get flushed w/
161           ;;        when the path is changed.
162           (semantic--tag-put-property tag 'dependency-file 'none)
163           nil)
164         ))))
165
166 (make-obsolete-overload 'semantic-find-dependency
167                         'semantic-dependency-tag-file)
168
169 ;;; PROTOTYPE FILE
170 ;;
171 ;; In C, a function in the .c file often has a representation in a
172 ;; corresponding .h file.  This routine attempts to find the
173 ;; prototype file a given source file would be associated with.
174 ;; This can be used by prototype manager programs.
175 ;;;###autoload
176 (define-overload semantic-prototype-file (buffer)
177   "Return a file in which prototypes belonging to BUFFER should be placed.
178 Default behavior (if not overridden) looks for a token specifying the
179 prototype file, or the existence of an EDE variable indicating which
180 file prototypes belong in."
181   (:override
182    ;; Perform some default behaviors
183    (if (and (fboundp 'ede-header-file) ede-minor-mode)
184        (save-excursion
185          (set-buffer buffer)
186          (ede-header-file))
187      ;; No EDE options for a quick answer.  Search.
188      (save-excursion
189        (set-buffer buffer)
190        (if (re-search-forward "::Header:: \\([a-zA-Z0-9.]+\\)" nil t)
191            (match-string 1))))))
192
193 (semantic-alias-obsolete 'semantic-find-nonterminal
194                          'semantic-go-to-tag)
195
196 (semantic-alias-obsolete 'semantic-find-dependency
197                          'semantic-dependency-tag-file)
198
199
200 (provide 'semantic-tag-file)
201
202 ;;; semantic-tag-file.el ends here