Mercurial > emacs
comparison lisp/cedet/semantic/db-ebrowse.el @ 104420:2e15afd37998
cedet/semantic/adebug.el, cedet/semantic/chart.el,
cedet/semantic/db-debug.el, cedet/semantic/db-ebrowse.el,
cedet/semantic/db-el.el, cedet/semantic/db-file.el,
cedet/semantic/db-javascript.el, cedet/semantic/db-search.el,
cedet/semantic/db-typecache.el, cedet/semantic/dep.el,
cedet/semantic/ia.el, cedet/semantic/tag-file.el,
cedet/semantic/tag-ls.el: New files.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Sat, 29 Aug 2009 19:32:33 +0000 |
parents | |
children | 36f56620b2ae |
comparison
equal
deleted
inserted
replaced
104419:b1ac14799f78 | 104420:2e15afd37998 |
---|---|
1 ;;; db-ebrowse.el --- Semanticdb backend using ebrowse. | |
2 | |
3 ;;; Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. | |
4 | |
5 ;; Authors: Eric M. Ludlam <zappo@gnu.org>, Joakim Verona | |
6 ;; Keywords: tags | |
7 | |
8 ;; This file is part of GNU Emacs. | |
9 | |
10 ;; GNU Emacs is free software: you can redistribute it and/or modify | |
11 ;; it under the terms of the GNU General Public License as published by | |
12 ;; the Free Software Foundation, either version 3 of the License, or | |
13 ;; (at your option) any later version. | |
14 | |
15 ;; GNU Emacs is distributed in the hope that it will be useful, | |
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 ;; GNU General Public License for more details. | |
19 | |
20 ;; You should have received a copy of the GNU General Public License | |
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
22 | |
23 ;;; Commentary: | |
24 ;; | |
25 ;; This program was started by Eric Ludlam, and Joakim Verona finished | |
26 ;; the implementation by adding searches and fixing bugs. | |
27 ;; | |
28 ;; Read in custom-created ebrowse BROWSE files into a semanticdb back | |
29 ;; end. | |
30 ;; | |
31 ;; Add these databases to the 'system' search. | |
32 ;; Possibly use ebrowse for local parsing too. | |
33 ;; | |
34 ;; When real details are needed out of the tag system from ebrowse, | |
35 ;; we will need to delve into the originating source and parse those | |
36 ;; files the usual way. | |
37 ;; | |
38 ;; COMMANDS: | |
39 ;; `semanticdb-create-ebrowse-database' - Call EBROWSE to create a | |
40 ;; system database for some directory. In general, use this for | |
41 ;; system libraries, such as /usr/include, or include directories | |
42 ;; large software projects. | |
43 ;; Customize `semanticdb-ebrowse-file-match' to make sure the correct | |
44 ;; file extensions are matched. | |
45 ;; | |
46 ;; `semanticdb-load-ebrowse-caches' - Load all the EBROWSE caches from | |
47 ;; your semanticdb system database directory. Once they are | |
48 ;; loaded, they become searchable as omnipotent databases for | |
49 ;; all C++ files. This is called automatically by semantic-load. | |
50 ;; Call it a second time to refresh the Emacs DB with the file. | |
51 ;; | |
52 | |
53 (eval-when-compile | |
54 ;; For generic function searching. | |
55 (require 'eieio) | |
56 (require 'eieio-opt) | |
57 ) | |
58 (require 'semantic/db-file) | |
59 | |
60 (eval-and-compile | |
61 ;; Hopefully, this will allow semanticdb-ebrowse to compile under | |
62 ;; XEmacs, it just won't run if a user attempts to use it. | |
63 (condition-case nil | |
64 (require 'ebrowse) | |
65 (error nil))) | |
66 | |
67 ;;; Code: | |
68 (defvar semanticdb-ebrowse-default-file-name "BROWSE" | |
69 "The EBROWSE file name used for system caches.") | |
70 | |
71 (defcustom semanticdb-ebrowse-file-match "\\.\\(hh?\\|HH?\\|hpp\\)" | |
72 "Regular expression matching file names for ebrowse to parse. | |
73 This expression should exclude C++ headers that have no extension. | |
74 By default, include only headers since the semantic use of EBrowse | |
75 is only for searching via semanticdb, and thus only headers would | |
76 be searched." | |
77 :group 'semanticdb | |
78 :type 'string) | |
79 | |
80 (defun semanticdb-ebrowse-C-file-p (file) | |
81 "Is FILE a C or C++ file?" | |
82 (or (string-match semanticdb-ebrowse-file-match file) | |
83 (and (string-match "/\\w+$" file) | |
84 (not (file-directory-p file)) | |
85 (let ((tmp (get-buffer-create "*semanticdb-ebrowse-tmp*"))) | |
86 (save-excursion | |
87 (set-buffer tmp) | |
88 (condition-case nil | |
89 (insert-file-contents file nil 0 100 t) | |
90 (error (insert-file-contents file nil nil nil t))) | |
91 (goto-char (point-min)) | |
92 (looking-at "\\s-*/\\(\\*\\|/\\)") | |
93 )) | |
94 ))) | |
95 | |
96 (defun semanticdb-create-ebrowse-database (dir) | |
97 "Create an EBROSE database for directory DIR. | |
98 The database file is stored in ~/.semanticdb, or whichever directory | |
99 is specified by `semanticdb-default-save-directory'." | |
100 (interactive "DDirectory: ") | |
101 (setq dir (file-name-as-directory dir)) ;; for / on end | |
102 (let* ((savein (semanticdb-ebrowse-file-for-directory dir)) | |
103 (filebuff (get-buffer-create "*SEMANTICDB EBROWSE TMP*")) | |
104 (files (directory-files (expand-file-name dir) t)) | |
105 (mma auto-mode-alist) | |
106 (regexp nil) | |
107 ) | |
108 ;; Create the input to the ebrowse command | |
109 (save-excursion | |
110 (set-buffer filebuff) | |
111 (buffer-disable-undo filebuff) | |
112 (setq default-directory (expand-file-name dir)) | |
113 | |
114 ;;; @TODO - convert to use semanticdb-collect-matching-filenames | |
115 ;; to get the file names. | |
116 | |
117 | |
118 (mapcar (lambda (f) | |
119 (when (semanticdb-ebrowse-C-file-p f) | |
120 (insert f) | |
121 (insert "\n"))) | |
122 files) | |
123 ;; Cleanup the ebrowse output buffer. | |
124 (save-excursion | |
125 (set-buffer (get-buffer-create "*EBROWSE OUTPUT*")) | |
126 (erase-buffer)) | |
127 ;; Call the EBROWSE command. | |
128 (message "Creating ebrowse file: %s ..." savein) | |
129 (call-process-region (point-min) (point-max) | |
130 "ebrowse" nil "*EBROWSE OUTPUT*" nil | |
131 (concat "--output-file=" savein) | |
132 "--very-verbose") | |
133 ) | |
134 ;; Create a short LOADER program for loading in this database. | |
135 (let* ((lfn (concat savein "-load.el")) | |
136 (lf (find-file-noselect lfn))) | |
137 (save-excursion | |
138 (set-buffer lf) | |
139 (erase-buffer) | |
140 (insert "(semanticdb-ebrowse-load-helper \"" | |
141 (expand-file-name dir) | |
142 "\")\n") | |
143 (save-buffer) | |
144 (kill-buffer (current-buffer))) | |
145 (message "Creating ebrowse file: %s ... done" savein) | |
146 ;; Reload that database | |
147 (load lfn nil t) | |
148 ))) | |
149 | |
150 (defun semanticdb-load-ebrowse-caches () | |
151 "Load all semanticdb controlled EBROWSE caches." | |
152 (interactive) | |
153 (let ((f (directory-files semanticdb-default-save-directory | |
154 t (concat semanticdb-ebrowse-default-file-name "-load.el$") t))) | |
155 (while f | |
156 (load (car f) nil t) | |
157 (setq f (cdr f))) | |
158 )) | |
159 | |
160 (defun semanticdb-ebrowse-load-helper (directory) | |
161 "Create the semanticdb database via ebrowse for directory. | |
162 If DIRECTORY is found to be defunct, it won't load the DB, and will | |
163 warn instead." | |
164 (if (file-directory-p directory) | |
165 (semanticdb-create-database semanticdb-project-database-ebrowse | |
166 directory) | |
167 (let* ((BF (semanticdb-ebrowse-file-for-directory directory)) | |
168 (BFL (concat BF "-load.el")) | |
169 (BFLB (concat BF "-load.el~"))) | |
170 (save-window-excursion | |
171 (with-output-to-temp-buffer "*FILES TO DELETE*" | |
172 (princ "The following BROWSE files are obsolete.\n\n") | |
173 (princ BF) | |
174 (princ "\n") | |
175 (princ BFL) | |
176 (princ "\n") | |
177 (when (file-exists-p BFLB) | |
178 (princ BFLB) | |
179 (princ "\n")) | |
180 ) | |
181 (when (y-or-n-p (format | |
182 "Warning: Obsolete BROWSE file for: %s\nDelete? " | |
183 directory)) | |
184 (delete-file BF) | |
185 (delete-file BFL) | |
186 (when (file-exists-p BFLB) | |
187 (delete-file BFLB)) | |
188 ))))) | |
189 | |
190 ;;; SEMANTIC Database related Code | |
191 ;;; Classes: | |
192 (defclass semanticdb-table-ebrowse (semanticdb-table) | |
193 ((major-mode :initform c++-mode) | |
194 (ebrowse-tree :initform nil | |
195 :initarg :ebrowse-tree | |
196 :documentation | |
197 "The raw ebrowse tree for this file." | |
198 ) | |
199 (global-extract :initform nil | |
200 :initarg :global-extract | |
201 :documentation | |
202 "Table of ebrowse tags specific to this file. | |
203 This table is compisited from the ebrowse *Globals* section.") | |
204 ) | |
205 "A table for returning search results from ebrowse.") | |
206 | |
207 (defclass semanticdb-project-database-ebrowse | |
208 (semanticdb-project-database) | |
209 ((new-table-class :initform semanticdb-table-ebrowse | |
210 :type class | |
211 :documentation | |
212 "New tables created for this database are of this class.") | |
213 (system-include-p :initform nil | |
214 :initarg :system-include | |
215 :documentation | |
216 "Flag indicating this database represents a system include directory.") | |
217 (ebrowse-struct :initform nil | |
218 :initarg :ebrowse-struct | |
219 ) | |
220 ) | |
221 "Semantic Database deriving tags using the EBROWSE tool. | |
222 EBROWSE is a C/C++ parser for use with `ebrowse' Emacs program.") | |
223 | |
224 ;JAVE this just instantiates a default empty ebrowse struct? | |
225 ; how would new instances wind up here? | |
226 ; the ebrowse class isnt singleton, unlike the emacs lisp one | |
227 (defvar-mode-local c++-mode semanticdb-project-system-databases | |
228 () | |
229 "Search Ebrowse for symbols.") | |
230 | |
231 (defmethod semanticdb-needs-refresh-p ((table semanticdb-table-ebrowse)) | |
232 "EBROWSE database do not need to be refreshed. | |
233 | |
234 JAVE: stub for needs-refresh, because, how do we know if BROWSE files | |
235 are out of date? | |
236 | |
237 EML: Our database should probably remember the timestamp/checksum of | |
238 the most recently read EBROWSE file, and use that." | |
239 nil | |
240 ) | |
241 | |
242 | |
243 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
244 | |
245 | |
246 | |
247 ;;; EBROWSE code | |
248 ;; | |
249 ;; These routines deal with part of the ebrowse interface. | |
250 (defun semanticdb-ebrowse-file-for-directory (dir) | |
251 "Return the file name for DIR where the ebrowse BROWSE file is. | |
252 This file should reside in `semanticdb-default-save-directory'." | |
253 (let* ((semanticdb-default-save-directory | |
254 semanticdb-default-save-directory) | |
255 (B (semanticdb-file-name-directory | |
256 'semanticdb-project-database-file | |
257 (concat (expand-file-name dir) | |
258 semanticdb-ebrowse-default-file-name))) | |
259 ) | |
260 B)) | |
261 | |
262 (defun semanticdb-ebrowse-get-ebrowse-structure (dir) | |
263 "Return the ebrowse structure for directory DIR. | |
264 This assumes semantic manages the BROWSE files, so they are assumed to live | |
265 where semantic cache files live, depending on your settings. | |
266 | |
267 For instance: /home/<username>/.semanticdb/!usr!include!BROWSE" | |
268 (let* ((B (semanticdb-ebrowse-file-for-directory dir)) | |
269 (buf (get-buffer-create "*semanticdb ebrowse*"))) | |
270 (message "semanticdb-ebrowse %s" B) | |
271 (when (file-exists-p B) | |
272 (set-buffer buf) | |
273 (buffer-disable-undo buf) | |
274 (erase-buffer) | |
275 (insert-file-contents B) | |
276 (let ((ans nil) | |
277 (efcn (symbol-function 'ebrowse-show-progress))) | |
278 (fset 'ebrowse-show-progress #'(lambda (&rest junk) nil)) | |
279 (unwind-protect ;; Protect against errors w/ ebrowse | |
280 (setq ans (list B (ebrowse-read))) | |
281 ;; These items must always happen | |
282 (erase-buffer) | |
283 (fset 'ebrowse-show-fcn efcn) | |
284 ) | |
285 ans)))) | |
286 | |
287 ;;; Methods for creating a database or tables | |
288 ;; | |
289 (defmethod semanticdb-create-database :STATIC ((dbeC semanticdb-project-database-ebrowse) | |
290 directory) | |
291 "Create a new semantic database for DIRECTORY based on ebrowse. | |
292 If there is no database for DIRECTORY available, then | |
293 {not implemented yet} create one. Return nil if that is not possible." | |
294 ;; MAKE SURE THAT THE FILE LOADED DOESN'T ALREADY EXIST. | |
295 (let ((dbs semanticdb-database-list) | |
296 (found nil)) | |
297 (while (and (not found) dbs) | |
298 (when (semanticdb-project-database-ebrowse-p (car dbs)) | |
299 (when (string= (oref (car dbs) reference-directory) directory) | |
300 (setq found (car dbs)))) | |
301 (setq dbs (cdr dbs))) | |
302 ;;STATIC means DBE cant be used as object, only as a class | |
303 (let* ((ebrowse-data (semanticdb-ebrowse-get-ebrowse-structure directory)) | |
304 (dat (car (cdr ebrowse-data))) | |
305 (ebd (car dat)) | |
306 (db nil) | |
307 (default-directory directory) | |
308 ) | |
309 (if found | |
310 (setq db found) | |
311 (setq db (make-instance | |
312 dbeC | |
313 directory | |
314 :ebrowse-struct ebd | |
315 )) | |
316 (oset db reference-directory directory)) | |
317 | |
318 ;; Once we recycle or make a new DB, refresh the | |
319 ;; contents from the BROWSE file. | |
320 (oset db tables nil) | |
321 ;; only possible after object creation, tables inited to nil. | |
322 (semanticdb-ebrowse-strip-trees db dat) | |
323 | |
324 ;; Once our database is loaded, if we are a system DB, we | |
325 ;; add ourselves to the include list for C++. | |
326 (semantic-add-system-include directory 'c++-mode) | |
327 (semantic-add-system-include directory 'c-mode) | |
328 | |
329 db))) | |
330 | |
331 (defmethod semanticdb-ebrowse-strip-trees ((dbe semanticdb-project-database-ebrowse) | |
332 data) | |
333 "For the ebrowse database DBE, strip all tables from DATA." | |
334 ;JAVE what it actually seems to do is split the original tree in "tables" associated with files | |
335 ; im not sure it actually works: | |
336 ; the filename slot sometimes gets to be nil, | |
337 ; apparently for classes which definition cant be found, yet needs to be included in the tree | |
338 ; like library baseclasses | |
339 ; a file can define several classes | |
340 (let ((T (car (cdr data))));1st comes a header, then the tree | |
341 (while T | |
342 | |
343 (let* ((tree (car T)) | |
344 (class (ebrowse-ts-class tree)); root class of tree | |
345 ;; Something funny going on with this file thing... | |
346 (filename (or (ebrowse-cs-source-file class) | |
347 (ebrowse-cs-file class))) | |
348 ) | |
349 (cond | |
350 ((ebrowse-globals-tree-p tree) | |
351 ;; We have the globals tree.. save this special. | |
352 (semanticdb-ebrowse-add-globals-to-table dbe tree) | |
353 ) | |
354 (t | |
355 ;; ebrowse will collect all the info from multiple files | |
356 ;; into one tree. Semantic wants all the bits to be tied | |
357 ;; into different files. We need to do a full dissociation | |
358 ;; into semantic parsable tables. | |
359 (semanticdb-ebrowse-add-tree-to-table dbe tree) | |
360 )) | |
361 (setq T (cdr T)))) | |
362 )) | |
363 | |
364 ;;; Filename based methods | |
365 ;; | |
366 (defun semanticdb-ebrowse-add-globals-to-table (dbe tree) | |
367 "For database DBE, add the ebrowse TREE into the table." | |
368 (if (or (not (ebrowse-ts-p tree)) | |
369 (not (ebrowse-globals-tree-p tree))) | |
370 (signal 'wrong-type-argument (list 'ebrowse-ts-p tree))) | |
371 | |
372 (let* ((class (ebrowse-ts-class tree)) | |
373 (fname (or (ebrowse-cs-source-file class) | |
374 (ebrowse-cs-file class) | |
375 ;; Not def'd here, assume our current | |
376 ;; file | |
377 (concat default-directory "/unknown-proxy.hh"))) | |
378 (vars (ebrowse-ts-member-functions tree)) | |
379 (fns (ebrowse-ts-member-variables tree)) | |
380 (toks nil) | |
381 ) | |
382 (while vars | |
383 (let ((nt (semantic-tag (ebrowse-ms-name (car vars)) | |
384 'variable)) | |
385 (defpoint (ebrowse-bs-point class))) | |
386 (when defpoint | |
387 (semantic--tag-set-overlay nt | |
388 (vector defpoint defpoint))) | |
389 (setq toks (cons nt toks))) | |
390 (setq vars (cdr vars))) | |
391 (while fns | |
392 (let ((nt (semantic-tag (ebrowse-ms-name (car fns)) | |
393 'function)) | |
394 (defpoint (ebrowse-bs-point class))) | |
395 (when defpoint | |
396 (semantic--tag-set-overlay nt | |
397 (vector defpoint defpoint))) | |
398 (setq toks (cons nt toks))) | |
399 (setq fns (cdr fns))) | |
400 | |
401 )) | |
402 | |
403 (defun semanticdb-ebrowse-add-tree-to-table (dbe tree &optional fname baseclasses) | |
404 "For database DBE, add the ebrowse TREE into the table for FNAME. | |
405 Optional argument BASECLASSES specifyies a baseclass to the tree being provided." | |
406 (if (not (ebrowse-ts-p tree)) | |
407 (signal 'wrong-type-argument (list 'ebrowse-ts-p tree))) | |
408 | |
409 ;; Strategy overview: | |
410 ;; 1) Calculate the filename for this tree. | |
411 ;; 2) Find a matching namespace in TAB, or create a new one. | |
412 ;; 3) Fabricate a tag proxy for CLASS | |
413 ;; 4) Add it to the namespace | |
414 ;; 5) Add subclasses | |
415 | |
416 ;; 1 - Find the filename | |
417 (if (not fname) | |
418 (setq fname (or (ebrowse-cs-source-file (ebrowse-ts-class tree)) | |
419 (ebrowse-cs-file (ebrowse-ts-class tree)) | |
420 ;; Not def'd here, assume our current | |
421 ;; file | |
422 (concat default-directory "/unknown-proxy.hh")))) | |
423 | |
424 (let* ((tab (or (semanticdb-file-table dbe fname) | |
425 (semanticdb-create-table dbe fname))) | |
426 (class (ebrowse-ts-class tree)) | |
427 (scope (ebrowse-cs-scope class)) | |
428 (ns (when scope (cedet-split-string scope ":" t))) | |
429 (nst nil) | |
430 (cls nil) | |
431 ) | |
432 | |
433 ;; 2 - Get the namespace tag | |
434 (when ns | |
435 (let ((taglst (if (slot-boundp tab 'tags) (oref tab tags) nil))) | |
436 (setq nst (semantic-find-first-tag-by-name (car ns) taglst)) | |
437 (when (not nst) | |
438 (setq nst (semantic-tag (car ns) 'type :type "namespace")) | |
439 (oset tab tags (cons nst taglst)) | |
440 ))) | |
441 | |
442 ;; 3 - Create a proxy tg. | |
443 (setq cls (semantic-tag (ebrowse-cs-name class) | |
444 'type | |
445 :type "class" | |
446 :superclasses baseclasses | |
447 :faux t | |
448 :filename fname | |
449 )) | |
450 (let ((defpoint (ebrowse-bs-point class))) | |
451 (when defpoint | |
452 (semantic--tag-set-overlay cls | |
453 (vector defpoint defpoint)))) | |
454 | |
455 ;; 4 - add to namespace | |
456 (if nst | |
457 (semantic-tag-put-attribute | |
458 nst :members (cons cls (semantic-tag-get-attribute nst :members))) | |
459 (oset tab tags (cons cls (when (slot-boundp tab 'tags) | |
460 (oref tab tags))))) | |
461 | |
462 ;; 5 - Subclasses | |
463 (let* ((subclass (ebrowse-ts-subclasses tree)) | |
464 (pname (ebrowse-cs-name class))) | |
465 (when (ebrowse-cs-scope class) | |
466 (setq pname (concat (mapconcat (lambda (a) a) (cdr ns) "::") "::" pname))) | |
467 | |
468 (while subclass | |
469 (let* ((scc (ebrowse-ts-class (car subclass))) | |
470 (fname (or (ebrowse-cs-source-file scc) | |
471 (ebrowse-cs-file scc) | |
472 ;; Not def'd here, assume our current | |
473 ;; file | |
474 fname | |
475 ))) | |
476 (when fname | |
477 (semanticdb-ebrowse-add-tree-to-table | |
478 dbe (car subclass) fname pname))) | |
479 (setq subclass (cdr subclass)))) | |
480 )) | |
481 | |
482 ;;; | |
483 ;; Overload for converting the simple faux tag into something better. | |
484 ;; | |
485 (defmethod semanticdb-normalize-tags ((obj semanticdb-table-ebrowse) tags) | |
486 "Convert in Ebrowse database OBJ a list of TAGS into a complete tag. | |
487 The default tag provided by searches exclude many features of a | |
488 semantic parsed tag. Look up the file for OBJ, and match TAGS | |
489 against a semantic parsed tag that has all the info needed, and | |
490 return that." | |
491 (let ((tagret nil) | |
492 ) | |
493 ;; SemanticDB will automatically create a regular database | |
494 ;; on top of the file just loaded by ebrowse during the set | |
495 ;; buffer. Fetch that table, and use it's tag list to look | |
496 ;; up the tag we just got, and thus turn it into a full semantic | |
497 ;; tag. | |
498 (while tags | |
499 (let ((tag (car tags))) | |
500 (save-excursion | |
501 (semanticdb-set-buffer obj) | |
502 (let ((ans nil)) | |
503 ;; Gee, it would be nice to do this, but ebrowse LIES. Oi. | |
504 (when (semantic-tag-with-position-p tag) | |
505 (goto-char (semantic-tag-start tag)) | |
506 (let ((foundtag (semantic-current-tag))) | |
507 ;; Make sure the discovered tag is the same as what we started with. | |
508 (when (string= (semantic-tag-name tag) | |
509 (semantic-tag-name foundtag)) | |
510 ;; We have a winner! | |
511 (setq ans foundtag)))) | |
512 ;; Sometimes ebrowse lies. Do a generic search | |
513 ;; to find it within this file. | |
514 (when (not ans) | |
515 ;; We might find multiple hits for this tag, and we have no way | |
516 ;; of knowing which one the user wanted. Return the first one. | |
517 (setq ans (semantic-deep-find-tags-by-name | |
518 (semantic-tag-name tag) | |
519 (semantic-fetch-tags)))) | |
520 (if (semantic-tag-p ans) | |
521 (setq tagret (cons ans tagret)) | |
522 (setq tagret (append ans tagret))) | |
523 )) | |
524 (setq tags (cdr tags)))) | |
525 tagret)) | |
526 | |
527 (defmethod semanticdb-normalize-one-tag ((obj semanticdb-table-ebrowse) tag) | |
528 "Convert in Ebrowse database OBJ one TAG into a complete tag. | |
529 The default tag provided by searches exclude many features of a | |
530 semantic parsed tag. Look up the file for OBJ, and match TAG | |
531 against a semantic parsed tag that has all the info needed, and | |
532 return that." | |
533 (let ((tagret nil) | |
534 (objret nil)) | |
535 ;; SemanticDB will automatically create a regular database | |
536 ;; on top of the file just loaded by ebrowse during the set | |
537 ;; buffer. Fetch that table, and use it's tag list to look | |
538 ;; up the tag we just got, and thus turn it into a full semantic | |
539 ;; tag. | |
540 (save-excursion | |
541 (semanticdb-set-buffer obj) | |
542 (setq objret semanticdb-current-table) | |
543 (when (not objret) | |
544 ;; What to do?? | |
545 (debug)) | |
546 (let ((ans nil)) | |
547 ;; Gee, it would be nice to do this, but ebrowse LIES. Oi. | |
548 (when (semantic-tag-with-position-p tag) | |
549 (goto-char (semantic-tag-start tag)) | |
550 (let ((foundtag (semantic-current-tag))) | |
551 ;; Make sure the discovered tag is the same as what we started with. | |
552 (when (string= (semantic-tag-name tag) | |
553 (semantic-tag-name foundtag)) | |
554 ;; We have a winner! | |
555 (setq ans foundtag)))) | |
556 ;; Sometimes ebrowse lies. Do a generic search | |
557 ;; to find it within this file. | |
558 (when (not ans) | |
559 ;; We might find multiple hits for this tag, and we have no way | |
560 ;; of knowing which one the user wanted. Return the first one. | |
561 (setq ans (semantic-deep-find-tags-by-name | |
562 (semantic-tag-name tag) | |
563 (semantic-fetch-tags)))) | |
564 (if (semantic-tag-p ans) | |
565 (setq tagret ans) | |
566 (setq tagret (car ans))) | |
567 )) | |
568 (cons objret tagret))) | |
569 | |
570 ;;; Search Overrides | |
571 ;; | |
572 ;; NOTE WHEN IMPLEMENTING: Be sure to add doc-string updates explaining | |
573 ;; how your new search routines are implemented. | |
574 ;; | |
575 (defmethod semanticdb-find-tags-by-name-method | |
576 ((table semanticdb-table-ebrowse) name &optional tags) | |
577 "Find all tags named NAME in TABLE. | |
578 Return a list of tags." | |
579 ;;(message "semanticdb-find-tags-by-name-method name -- %s" name) | |
580 (if tags | |
581 ;; If TAGS are passed in, then we don't need to do work here. | |
582 (call-next-method) | |
583 ;; If we ever need to do something special, add here. | |
584 ;; Since ebrowse tags are converted into semantic tags, we can | |
585 ;; get away with this sort of thing. | |
586 (call-next-method) | |
587 ) | |
588 ) | |
589 | |
590 (defmethod semanticdb-find-tags-by-name-regexp-method | |
591 ((table semanticdb-table-ebrowse) regex &optional tags) | |
592 "Find all tags with name matching REGEX in TABLE. | |
593 Optional argument TAGS is a list of tags to search. | |
594 Return a list of tags." | |
595 (if tags (call-next-method) | |
596 ;; YOUR IMPLEMENTATION HERE | |
597 (call-next-method) | |
598 )) | |
599 | |
600 (defmethod semanticdb-find-tags-for-completion-method | |
601 ((table semanticdb-table-ebrowse) prefix &optional tags) | |
602 "In TABLE, find all occurances of tags matching PREFIX. | |
603 Optional argument TAGS is a list of tags to search. | |
604 Returns a table of all matching tags." | |
605 (if tags (call-next-method) | |
606 ;; YOUR IMPLEMENTATION HERE | |
607 (call-next-method) | |
608 )) | |
609 | |
610 (defmethod semanticdb-find-tags-by-class-method | |
611 ((table semanticdb-table-ebrowse) class &optional tags) | |
612 "In TABLE, find all occurances of tags of CLASS. | |
613 Optional argument TAGS is a list of tags to search. | |
614 Returns a table of all matching tags." | |
615 (if tags (call-next-method) | |
616 (call-next-method))) | |
617 | |
618 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
619 | |
620 ;;; Deep Searches | |
621 ;; | |
622 ;; If your language does not have a `deep' concept, these can be left | |
623 ;; alone, otherwise replace with implementations similar to those | |
624 ;; above. | |
625 ;; | |
626 | |
627 (defmethod semanticdb-deep-find-tags-by-name-method | |
628 ((table semanticdb-table-ebrowse) name &optional tags) | |
629 "Find all tags name NAME in TABLE. | |
630 Optional argument TAGS is a list of tags t | |
631 Like `semanticdb-find-tags-by-name-method' for ebrowse." | |
632 ;;(semanticdb-find-tags-by-name-method table name tags) | |
633 (call-next-method)) | |
634 | |
635 (defmethod semanticdb-deep-find-tags-by-name-regexp-method | |
636 ((table semanticdb-table-ebrowse) regex &optional tags) | |
637 "Find all tags with name matching REGEX in TABLE. | |
638 Optional argument TAGS is a list of tags to search. | |
639 Like `semanticdb-find-tags-by-name-method' for ebrowse." | |
640 ;;(semanticdb-find-tags-by-name-regexp-method table regex tags) | |
641 (call-next-method)) | |
642 | |
643 (defmethod semanticdb-deep-find-tags-for-completion-method | |
644 ((table semanticdb-table-ebrowse) prefix &optional tags) | |
645 "In TABLE, find all occurances of tags matching PREFIX. | |
646 Optional argument TAGS is a list of tags to search. | |
647 Like `semanticdb-find-tags-for-completion-method' for ebrowse." | |
648 ;;(semanticdb-find-tags-for-completion-method table prefix tags) | |
649 (call-next-method)) | |
650 | |
651 ;;; Advanced Searches | |
652 ;; | |
653 (defmethod semanticdb-find-tags-external-children-of-type-method | |
654 ((table semanticdb-table-ebrowse) type &optional tags) | |
655 "Find all nonterminals which are child elements of TYPE | |
656 Optional argument TAGS is a list of tags to search. | |
657 Return a list of tags." | |
658 (if tags (call-next-method) | |
659 ;; Ebrowse collects all this type of stuff together for us. | |
660 ;; but we can't use it.... yet. | |
661 nil | |
662 )) | |
663 | |
664 ;;; TESTING | |
665 ;; | |
666 ;; This is a complex bit of stuff. Here are some tests for the | |
667 ;; system. | |
668 | |
669 (defun semanticdb-ebrowse-run-tests () | |
670 "Run some tests of the semanticdb-ebrowse system. | |
671 All systems are different. Ask questions along the way." | |
672 (interactive) | |
673 (let ((doload nil)) | |
674 (when (y-or-n-p "Create a system database to test with? ") | |
675 (call-interactively 'semanticdb-create-ebrowse-database) | |
676 (setq doload t)) | |
677 ;; Should we load in caches | |
678 (when (if doload | |
679 (y-or-n-p "New database created. Reload system databases? ") | |
680 (y-or-n-p "Load in all system databases? ")) | |
681 (semanticdb-load-ebrowse-caches))) | |
682 ;; Ok, databases were creatd. Lets try some searching. | |
683 (when (not (or (eq major-mode 'c-mode) | |
684 (eq major-mode 'c++-mode))) | |
685 (error "Please make your default buffer be a C or C++ file, then | |
686 run the test again..") | |
687 ) | |
688 | |
689 ) | |
690 | |
691 (defun semanticdb-ebrowse-dump () | |
692 "Find the first loaded ebrowse table, and dump out the contents." | |
693 (interactive) | |
694 (let ((db semanticdb-database-list) | |
695 (ab nil)) | |
696 (while db | |
697 (when (semanticdb-project-database-ebrowse-p (car db)) | |
698 (setq ab (data-debug-new-buffer "*EBROWSE Database*")) | |
699 (data-debug-insert-thing (car db) "*" "") | |
700 (setq db nil) | |
701 ) | |
702 (setq db (cdr db))))) | |
703 | |
704 (provide 'semantic/db-ebrowse) | |
705 | |
706 ;;; semanticdb-ebrowse.el ends here |