110526
|
1 ;;; ede/base.el --- Baseclasses for EDE.
|
|
2
|
|
3 ;; Copyright (C) 2010 Free Software Foundation, Inc.
|
|
4
|
|
5 ;; Author: Eric M. Ludlam <zappo@gnu.org>
|
|
6
|
|
7 ;; This file is part of GNU Emacs.
|
|
8
|
|
9 ;; GNU Emacs is free software: you can redistribute it and/or modify
|
|
10 ;; it under the terms of the GNU General Public License as published by
|
|
11 ;; the Free Software Foundation, either version 3 of the License, or
|
|
12 ;; (at your option) any later version.
|
|
13
|
|
14 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
17 ;; GNU General Public License for more details.
|
|
18
|
|
19 ;; You should have received a copy of the GNU General Public License
|
|
20 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
|
22 ;;; Commentary:
|
|
23 ;;
|
|
24 ;; Baseclasses for EDE.
|
|
25 ;;
|
|
26 ;; Contains all the base structures needed by EDE.
|
|
27
|
|
28 ;;; Code:
|
|
29 (require 'eieio)
|
|
30 (require 'eieio-speedbar)
|
|
31 (require 'ede/auto)
|
|
32
|
|
33 ;; Defined in ede.el:
|
|
34 (defvar ede-projects)
|
|
35 (defvar ede-object)
|
|
36 (defvar ede-object-root-project)
|
|
37
|
|
38 (declare-function data-debug-new-buffer "data-debug")
|
|
39 (declare-function data-debug-insert-object-slots "eieio-datadebug")
|
|
40 (declare-function ede-parent-project "ede" (&optional obj))
|
|
41 (declare-function ede-current-project "ede" (&optional dir))
|
|
42
|
|
43 ;;; TARGET
|
|
44 ;;
|
|
45 ;; The TARGET is an entity in a project that knows about files
|
|
46 ;; and features of those files.
|
|
47
|
|
48 (defclass ede-target (eieio-speedbar-directory-button)
|
|
49 ((buttonface :initform speedbar-file-face) ;override for superclass
|
|
50 (name :initarg :name
|
|
51 :type string
|
|
52 :custom string
|
|
53 :label "Name"
|
|
54 :group (default name)
|
|
55 :documentation "Name of this target.")
|
|
56 ;; @todo - I think this should be "dir", and not "path".
|
|
57 (path :initarg :path
|
|
58 :type string
|
|
59 ;:custom string
|
|
60 ;:label "Path to target"
|
|
61 ;:group (default name)
|
|
62 :documentation "The path to the sources of this target.
|
|
63 Relative to the path of the project it belongs to.")
|
|
64 (source :initarg :source
|
|
65 :initform nil
|
|
66 ;; I'd prefer a list of strings.
|
|
67 :type list
|
|
68 :custom (repeat (string :tag "File"))
|
|
69 :label "Source Files"
|
|
70 :group (default source)
|
|
71 :documentation "Source files in this target.")
|
|
72 (versionsource :initarg :versionsource
|
|
73 :initform nil
|
|
74 :type list
|
|
75 :custom (repeat (string :tag "File"))
|
|
76 :label "Source Files with Version String"
|
|
77 :group (source)
|
|
78 :documentation
|
|
79 "Source files with a version string in them.
|
|
80 These files are checked for a version string whenever the EDE version
|
|
81 of the master project is changed. When strings are found, the version
|
|
82 previously there is updated.")
|
|
83 ;; Class level slots
|
|
84 ;;
|
|
85 (sourcetype :allocation :class
|
|
86 :type list ;; list of symbols
|
|
87 :documentation
|
|
88 "A list of `ede-sourcecode' objects this class will handle.
|
|
89 This is used to match target objects with the compilers they can use, and
|
|
90 which files this object is interested in."
|
|
91 :accessor ede-object-sourcecode)
|
|
92 (keybindings :allocation :class
|
|
93 :initform (("D" . ede-debug-target))
|
|
94 :documentation
|
|
95 "Keybindings specialized to this type of target."
|
|
96 :accessor ede-object-keybindings)
|
|
97 (menu :allocation :class
|
|
98 :initform ( [ "Debug target" ede-debug-target
|
|
99 (ede-buffer-belongs-to-target-p) ]
|
|
100 [ "Run target" ede-run-target
|
|
101 (ede-buffer-belongs-to-target-p) ]
|
|
102 )
|
|
103 :documentation "Menu specialized to this type of target."
|
|
104 :accessor ede-object-menu)
|
|
105 )
|
|
106 "A target is a structure that describes a file set that produces something.
|
|
107 Targets, as with 'Make', is an entity that will manage a file set
|
|
108 and knows how to compile or otherwise transform those files into some
|
|
109 other desired outcome.")
|
|
110
|
|
111 ;;; PROJECT/PLACEHOLDER
|
|
112 ;;
|
|
113 ;; Project placeholders are minimum parts of a project used
|
|
114 ;; by the project cache. The project cache can refer to these placeholders,
|
|
115 ;; and swap them out with the real-deal when that project is loaded.
|
|
116 ;;
|
|
117 (defclass ede-project-placeholder (eieio-speedbar-directory-button)
|
|
118 ((name :initarg :name
|
|
119 :initform "Untitled"
|
|
120 :type string
|
|
121 :custom string
|
|
122 :label "Name"
|
|
123 :group (default name)
|
|
124 :documentation "The name used when generating distribution files.")
|
|
125 (version :initarg :version
|
|
126 :initform "1.0"
|
|
127 :type string
|
|
128 :custom string
|
|
129 :label "Version"
|
|
130 :group (default name)
|
|
131 :documentation "The version number used when distributing files.")
|
|
132 (directory :type string
|
|
133 :initarg :directory
|
|
134 :documentation "Directory this project is associated with.")
|
|
135 (dirinode :documentation "The inode id for :directory.")
|
|
136 (file :type string
|
|
137 :initarg :file
|
|
138 :documentation "File name where this project is stored.")
|
|
139 (rootproject ; :initarg - no initarg, don't save this slot!
|
|
140 :initform nil
|
|
141 :type (or null ede-project-placeholder-child)
|
|
142 :documentation "Pointer to our root project.")
|
|
143 )
|
|
144 "Placeholder object for projects not loaded into memory.
|
|
145 Projects placeholders will be stored in a user specific location
|
|
146 and querying them will cause the actual project to get loaded.")
|
|
147
|
|
148 ;;; PROJECT
|
|
149 ;;
|
|
150 ;; An EDE project controls a set of TARGETS, and can also contain
|
|
151 ;; multiple SUBPROJECTS.
|
|
152 ;;
|
|
153 ;; The project defines a set of features that need to be built from
|
|
154 ;; files, in addition as to controlling what to do with the file set,
|
|
155 ;; such as creating distributions, compilation, and web sites.
|
|
156 ;;
|
|
157 ;; Projects can also affect how EDE works, by changing what appears in
|
|
158 ;; the EDE menu, or how some keys are bound.
|
|
159 ;;
|
|
160 (defclass ede-project (ede-project-placeholder)
|
|
161 ((subproj :initform nil
|
|
162 :type list
|
|
163 :documentation "Sub projects controlled by this project.
|
|
164 For Automake based projects, each directory is treated as a project.")
|
|
165 (targets :initarg :targets
|
|
166 :type list
|
|
167 :custom (repeat (object :objectcreatefcn ede-new-target-custom))
|
|
168 :label "Local Targets"
|
|
169 :group (targets)
|
|
170 :documentation "List of top level targets in this project.")
|
|
171 (locate-obj :type (or null ede-locate-base-child)
|
|
172 :documentation
|
|
173 "A locate object to use as a backup to `ede-expand-filename'.")
|
|
174 (tool-cache :initarg :tool-cache
|
|
175 :type list
|
|
176 :custom (repeat object)
|
|
177 :label "Tool: "
|
|
178 :group tools
|
|
179 :documentation "List of tool cache configurations in this project.
|
|
180 This allows any tool to create, manage, and persist project-specific settings.")
|
|
181 (mailinglist :initarg :mailinglist
|
|
182 :initform ""
|
|
183 :type string
|
|
184 :custom string
|
|
185 :label "Mailing List Address"
|
|
186 :group name
|
|
187 :documentation
|
|
188 "An email address where users might send email for help.")
|
|
189 (web-site-url :initarg :web-site-url
|
|
190 :initform ""
|
|
191 :type string
|
|
192 :custom string
|
|
193 :label "Web Site URL"
|
|
194 :group name
|
|
195 :documentation "URL to this projects web site.
|
|
196 This is a URL to be sent to a web site for documentation.")
|
|
197 (web-site-directory :initarg :web-site-directory
|
|
198 :initform ""
|
|
199 :custom string
|
|
200 :label "Web Page Directory"
|
|
201 :group name
|
|
202 :documentation
|
|
203 "A directory where web pages can be found by Emacs.
|
|
204 For remote locations use a path compatible with ange-ftp or EFS.
|
|
205 You can also use TRAMP for use with rcp & scp.")
|
|
206 (web-site-file :initarg :web-site-file
|
|
207 :initform ""
|
|
208 :custom string
|
|
209 :label "Web Page File"
|
|
210 :group name
|
|
211 :documentation
|
|
212 "A file which contains the home page for this project.
|
|
213 This file can be relative to slot `web-site-directory'.
|
|
214 This can be a local file, use ange-ftp, EFS, or TRAMP.")
|
|
215 (ftp-site :initarg :ftp-site
|
|
216 :initform ""
|
|
217 :type string
|
|
218 :custom string
|
|
219 :label "FTP site"
|
|
220 :group name
|
|
221 :documentation
|
|
222 "FTP site where this project's distribution can be found.
|
|
223 This FTP site should be in Emacs form, as needed by `ange-ftp', but can
|
|
224 also be of a form used by TRAMP for use with scp, or rcp.")
|
|
225 (ftp-upload-site :initarg :ftp-upload-site
|
|
226 :initform ""
|
|
227 :type string
|
|
228 :custom string
|
|
229 :label "FTP Upload site"
|
|
230 :group name
|
|
231 :documentation
|
|
232 "FTP Site to upload new distributions to.
|
|
233 This FTP site should be in Emacs form as needed by `ange-ftp'.
|
|
234 If this slot is nil, then use `ftp-site' instead.")
|
|
235 (configurations :initarg :configurations
|
|
236 :initform ("debug" "release")
|
|
237 :type list
|
|
238 :custom (repeat string)
|
|
239 :label "Configuration Options"
|
|
240 :group (settings)
|
|
241 :documentation "List of available configuration types.
|
|
242 Individual target/project types can form associations between a configuration,
|
|
243 and target specific elements such as build variables.")
|
|
244 (configuration-default :initarg :configuration-default
|
|
245 :initform "debug"
|
|
246 :custom string
|
|
247 :label "Current Configuration"
|
|
248 :group (settings)
|
|
249 :documentation "The default configuration.")
|
|
250 (local-variables :initarg :local-variables
|
|
251 :initform nil
|
|
252 :custom (repeat (cons (sexp :tag "Variable")
|
|
253 (sexp :tag "Value")))
|
|
254 :label "Project Local Variables"
|
|
255 :group (settings)
|
|
256 :documentation "Project local variables")
|
|
257 (keybindings :allocation :class
|
|
258 :initform (("D" . ede-debug-target)
|
|
259 ("R" . ede-run-target))
|
|
260 :documentation "Keybindings specialized to this type of target."
|
|
261 :accessor ede-object-keybindings)
|
|
262 (menu :allocation :class
|
|
263 :initform
|
|
264 (
|
|
265 [ "Update Version" ede-update-version ede-object ]
|
|
266 [ "Version Control Status" ede-vc-project-directory ede-object ]
|
|
267 [ "Edit Project Homepage" ede-edit-web-page
|
|
268 (and ede-object (oref (ede-toplevel) web-site-file)) ]
|
|
269 [ "Browse Project URL" ede-web-browse-home
|
|
270 (and ede-object
|
|
271 (not (string= "" (oref (ede-toplevel) web-site-url)))) ]
|
|
272 "--"
|
|
273 [ "Rescan Project Files" ede-rescan-toplevel t ]
|
|
274 [ "Edit Projectfile" ede-edit-file-target
|
|
275 (ede-buffer-belongs-to-project-p) ]
|
|
276 )
|
|
277 :documentation "Menu specialized to this type of target."
|
|
278 :accessor ede-object-menu)
|
|
279 )
|
|
280 "Top level EDE project specification.
|
|
281 All specific project types must derive from this project."
|
|
282 :method-invocation-order :depth-first)
|
|
283
|
|
284 ;;; Important macros for doing commands.
|
|
285 ;;
|
|
286 (defmacro ede-with-projectfile (obj &rest forms)
|
|
287 "For the project in which OBJ resides, execute FORMS."
|
|
288 (list 'save-window-excursion
|
|
289 (list 'let* (list
|
|
290 (list 'pf
|
|
291 (list 'if (list 'obj-of-class-p
|
|
292 obj 'ede-target)
|
|
293 ;; @todo -I think I can change
|
|
294 ;; this to not need ede-load-project-file
|
|
295 ;; but I'm not sure how to test well.
|
|
296 (list 'ede-load-project-file
|
|
297 (list 'oref obj 'path))
|
|
298 obj))
|
|
299 '(dbka (get-file-buffer (oref pf file))))
|
|
300 '(if (not dbka) (find-file (oref pf file))
|
|
301 (switch-to-buffer dbka))
|
|
302 (cons 'progn forms)
|
|
303 '(if (not dbka) (kill-buffer (current-buffer))))))
|
|
304 (put 'ede-with-projectfile 'lisp-indent-function 1)
|
|
305
|
|
306 ;;; The EDE persistent cache.
|
|
307 ;;
|
|
308 ;; The cache is a way to mark where all known projects live without
|
|
309 ;; loading those projects into memory, or scanning for them each time
|
|
310 ;; emacs starts.
|
|
311 ;;
|
|
312 (defcustom ede-project-placeholder-cache-file
|
|
313 (locate-user-emacs-file "ede-projects.el" ".projects.ede")
|
|
314 "File containing the list of projects EDE has viewed."
|
|
315 :group 'ede
|
|
316 :type 'file)
|
|
317
|
|
318 (defvar ede-project-cache-files nil
|
|
319 "List of project files EDE has seen before.")
|
|
320
|
|
321 (defun ede-save-cache ()
|
|
322 "Save a cache of EDE objects that Emacs has seen before."
|
|
323 (interactive)
|
|
324 (let ((p ede-projects)
|
|
325 (c ede-project-cache-files)
|
|
326 (recentf-exclude '( (lambda (f) t) ))
|
|
327 )
|
|
328 (condition-case nil
|
|
329 (progn
|
|
330 (set-buffer (find-file-noselect ede-project-placeholder-cache-file t))
|
|
331 (erase-buffer)
|
|
332 (insert ";; EDE project cache file.
|
|
333 ;; This contains a list of projects you have visited.\n(")
|
|
334 (while p
|
|
335 (when (and (car p) (ede-project-p p))
|
|
336 (let ((f (oref (car p) file)))
|
|
337 (when (file-exists-p f)
|
|
338 (insert "\n \"" f "\""))))
|
|
339 (setq p (cdr p)))
|
|
340 (while c
|
|
341 (insert "\n \"" (car c) "\"")
|
|
342 (setq c (cdr c)))
|
|
343 (insert "\n)\n")
|
|
344 (condition-case nil
|
|
345 (save-buffer 0)
|
|
346 (error
|
|
347 (message "File %s could not be saved."
|
|
348 ede-project-placeholder-cache-file)))
|
|
349 (kill-buffer (current-buffer))
|
|
350 )
|
|
351 (error
|
|
352 (message "File %s could not be read."
|
|
353 ede-project-placeholder-cache-file))
|
|
354
|
|
355 )))
|
|
356
|
|
357 (defun ede-load-cache ()
|
|
358 "Load the cache of EDE projects."
|
|
359 (save-excursion
|
|
360 (let ((cachebuffer nil))
|
|
361 (condition-case nil
|
|
362 (progn
|
|
363 (setq cachebuffer
|
|
364 (find-file-noselect ede-project-placeholder-cache-file t))
|
|
365 (set-buffer cachebuffer)
|
|
366 (goto-char (point-min))
|
|
367 (let ((c (read (current-buffer)))
|
|
368 (new nil)
|
|
369 (p ede-projects))
|
|
370 ;; Remove loaded projects from the cache.
|
|
371 (while p
|
|
372 (setq c (delete (oref (car p) file) c))
|
|
373 (setq p (cdr p)))
|
|
374 ;; Remove projects that aren't on the filesystem
|
|
375 ;; anymore.
|
|
376 (while c
|
|
377 (when (file-exists-p (car c))
|
|
378 (setq new (cons (car c) new)))
|
|
379 (setq c (cdr c)))
|
|
380 ;; Save it
|
|
381 (setq ede-project-cache-files (nreverse new))))
|
|
382 (error nil))
|
|
383 (when cachebuffer (kill-buffer cachebuffer))
|
|
384 )))
|
|
385
|
|
386 ;;; Get the cache usable.
|
|
387
|
|
388 ;; @TODO - Remove this cache setup, or use this for something helpful.
|
|
389 ;;(add-hook 'kill-emacs-hook 'ede-save-cache)
|
|
390 ;;(when (not noninteractive)
|
|
391 ;; ;; No need to load the EDE cache if we aren't interactive.
|
|
392 ;; ;; This occurs during batch byte-compiling of other tools.
|
|
393 ;; (ede-load-cache))
|
|
394
|
|
395
|
|
396 ;;; METHODS
|
|
397 ;;
|
|
398 ;; The methods in ede-base handle project related behavior, and DO NOT
|
|
399 ;; related to EDE mode commands directory, such as keybindings.
|
|
400 ;;
|
|
401 ;; Mode related methods are in ede.el. These methods are related
|
|
402 ;; project specific activities not directly tied to a keybinding.
|
|
403 (defmethod ede-subproject-relative-path ((proj ede-project) &optional parent-in)
|
|
404 "Get a path name for PROJ which is relative to the parent project.
|
|
405 If PARENT is specified, then be relative to the PARENT project.
|
|
406 Specifying PARENT is useful for sub-sub projects relative to the root project."
|
|
407 (let* ((parent (or parent-in (ede-parent-project proj)))
|
|
408 (dir (file-name-directory (oref proj file))))
|
|
409 (if (and parent (not (eq parent proj)))
|
|
410 (file-relative-name dir (file-name-directory (oref parent file)))
|
|
411 "")))
|
|
412
|
|
413 (defmethod ede-subproject-p ((proj ede-project))
|
|
414 "Return non-nil if PROJ is a sub project."
|
|
415 ;; @TODO - Use this in more places, and also pay attention to
|
|
416 ;; metasubproject in ede-proj.el
|
|
417 (ede-parent-project proj))
|
|
418
|
|
419
|
|
420 ;;; Default descriptive methods for EDE classes
|
|
421 ;;
|
|
422 ;; These are methods which you might want to override, but there is
|
|
423 ;; no need to in most situations because they are either a) simple, or
|
|
424 ;; b) cosmetic.
|
|
425
|
|
426 (defmethod ede-name ((this ede-target))
|
|
427 "Return the name of THIS target."
|
|
428 (oref this name))
|
|
429
|
|
430 (defmethod ede-target-name ((this ede-target))
|
|
431 "Return the name of THIS target, suitable for make or debug style commands."
|
|
432 (oref this name))
|
|
433
|
|
434 (defmethod ede-name ((this ede-project))
|
|
435 "Return a short-name for THIS project file.
|
|
436 Do this by extracting the lowest directory name."
|
|
437 (oref this name))
|
|
438
|
|
439 (defmethod ede-description ((this ede-project))
|
|
440 "Return a description suitable for the minibuffer about THIS."
|
|
441 (format "Project %s: %d subprojects, %d targets."
|
|
442 (ede-name this) (length (oref this subproj))
|
|
443 (length (oref this targets))))
|
|
444
|
|
445 (defmethod ede-description ((this ede-target))
|
|
446 "Return a description suitable for the minibuffer about THIS."
|
|
447 (format "Target %s: with %d source files."
|
|
448 (ede-name this) (length (oref this source))))
|
|
449
|
|
450 ;;; HEADERS/DOC
|
|
451 ;;
|
|
452 ;; Targets and projects are often associated with other files, such as
|
|
453 ;; header files, documentation files and the like. Have strong
|
|
454 ;; associations can make useful user commands to quickly navigate
|
|
455 ;; between the files base on their assocaitions.
|
|
456 ;;
|
|
457 (defun ede-header-file ()
|
|
458 "Return the header file for the current buffer.
|
|
459 Not all buffers need headers, so return nil if no applicable."
|
|
460 (if ede-object
|
|
461 (ede-buffer-header-file ede-object (current-buffer))
|
|
462 nil))
|
|
463
|
|
464 (defmethod ede-buffer-header-file ((this ede-project) buffer)
|
|
465 "Return nil, projects don't have header files."
|
|
466 nil)
|
|
467
|
|
468 (defmethod ede-buffer-header-file ((this ede-target) buffer)
|
|
469 "There are no default header files in EDE.
|
|
470 Do a quick check to see if there is a Header tag in this buffer."
|
|
471 (with-current-buffer buffer
|
|
472 (if (re-search-forward "::Header:: \\([a-zA-Z0-9.]+\\)" nil t)
|
|
473 (buffer-substring-no-properties (match-beginning 1)
|
|
474 (match-end 1))
|
|
475 (let ((src (ede-target-sourcecode this))
|
|
476 (found nil))
|
|
477 (while (and src (not found))
|
|
478 (setq found (ede-buffer-header-file (car src) (buffer-file-name))
|
|
479 src (cdr src)))
|
|
480 found))))
|
|
481
|
|
482 (defun ede-documentation-files ()
|
|
483 "Return the documentation files for the current buffer.
|
|
484 Not all buffers need documentations, so return nil if no applicable.
|
|
485 Some projects may have multiple documentation files, so return a list."
|
|
486 (if ede-object
|
|
487 (ede-buffer-documentation-files ede-object (current-buffer))
|
|
488 nil))
|
|
489
|
|
490 (defmethod ede-buffer-documentation-files ((this ede-project) buffer)
|
|
491 "Return all documentation in project THIS based on BUFFER."
|
|
492 ;; Find the info node.
|
|
493 (ede-documentation this))
|
|
494
|
|
495 (defmethod ede-buffer-documentation-files ((this ede-target) buffer)
|
|
496 "Check for some documentation files for THIS.
|
|
497 Also do a quick check to see if there is a Documentation tag in this BUFFER."
|
|
498 (with-current-buffer buffer
|
|
499 (if (re-search-forward "::Documentation:: \\([a-zA-Z0-9.]+\\)" nil t)
|
|
500 (buffer-substring-no-properties (match-beginning 1)
|
|
501 (match-end 1))
|
|
502 ;; Check the master project
|
|
503 (let ((cp (ede-toplevel)))
|
|
504 (ede-buffer-documentation-files cp (current-buffer))))))
|
|
505
|
|
506 (defmethod ede-documentation ((this ede-project))
|
|
507 "Return a list of files that provide documentation.
|
|
508 Documentation is not for object THIS, but is provided by THIS for other
|
|
509 files in the project."
|
|
510 (let ((targ (oref this targets))
|
|
511 (proj (oref this subproj))
|
|
512 (found nil))
|
|
513 (while targ
|
|
514 (setq found (append (ede-documentation (car targ)) found)
|
|
515 targ (cdr targ)))
|
|
516 (while proj
|
|
517 (setq found (append (ede-documentation (car proj)) found)
|
|
518 proj (cdr proj)))
|
|
519 found))
|
|
520
|
|
521 (defmethod ede-documentation ((this ede-target))
|
|
522 "Return a list of files that provide documentation.
|
|
523 Documentation is not for object THIS, but is provided by THIS for other
|
|
524 files in the project."
|
|
525 nil)
|
|
526
|
|
527 (defun ede-html-documentation-files ()
|
|
528 "Return a list of HTML documentation files associated with this project."
|
|
529 (ede-html-documentation (ede-toplevel))
|
|
530 )
|
|
531
|
|
532 (defmethod ede-html-documentation ((this ede-project))
|
|
533 "Return a list of HTML files provided by project THIS."
|
|
534
|
|
535 )
|
|
536
|
|
537 ;;; Default "WANT" methods.
|
|
538 ;;
|
|
539 ;; These methods are used to determine if a target "wants", or could
|
|
540 ;; somehow handle a file, or some source type.
|
|
541 ;;
|
|
542 (defmethod ede-want-file-p ((this ede-target) file)
|
|
543 "Return non-nil if THIS target wants FILE."
|
|
544 ;; By default, all targets reference the source object, and let it decide.
|
|
545 (let ((src (ede-target-sourcecode this)))
|
|
546 (while (and src (not (ede-want-file-p (car src) file)))
|
|
547 (setq src (cdr src)))
|
|
548 src))
|
|
549
|
|
550 (defmethod ede-want-file-source-p ((this ede-target) file)
|
|
551 "Return non-nil if THIS target wants FILE."
|
|
552 ;; By default, all targets reference the source object, and let it decide.
|
|
553 (let ((src (ede-target-sourcecode this)))
|
|
554 (while (and src (not (ede-want-file-source-p (car src) file)))
|
|
555 (setq src (cdr src)))
|
|
556 src))
|
|
557
|
|
558 (defmethod ede-target-sourcecode ((this ede-target))
|
|
559 "Return the sourcecode objects which THIS permits."
|
|
560 (let ((sc (oref this sourcetype))
|
|
561 (rs nil))
|
|
562 (while (and (listp sc) sc)
|
|
563 (setq rs (cons (symbol-value (car sc)) rs)
|
|
564 sc (cdr sc)))
|
|
565 rs))
|
|
566
|
|
567
|
|
568 ;;; Debugging.
|
|
569 ;;
|
|
570 (defun ede-adebug-project ()
|
|
571 "Run adebug against the current EDE project.
|
|
572 Display the results as a debug list."
|
|
573 (interactive)
|
|
574 (require 'data-debug)
|
|
575 (when (ede-current-project)
|
|
576 (data-debug-new-buffer "*Analyzer ADEBUG*")
|
|
577 (data-debug-insert-object-slots (ede-current-project) "")
|
|
578 ))
|
|
579
|
|
580 (defun ede-adebug-project-parent ()
|
|
581 "Run adebug against the current EDE parent project.
|
|
582 Display the results as a debug list."
|
|
583 (interactive)
|
|
584 (require 'data-debug)
|
|
585 (when (ede-parent-project)
|
|
586 (data-debug-new-buffer "*Analyzer ADEBUG*")
|
|
587 (data-debug-insert-object-slots (ede-parent-project) "")
|
|
588 ))
|
|
589
|
|
590 (defun ede-adebug-project-root ()
|
|
591 "Run adebug against the current EDE parent project.
|
|
592 Display the results as a debug list."
|
|
593 (interactive)
|
|
594 (require 'data-debug)
|
|
595 (when (ede-toplevel)
|
|
596 (data-debug-new-buffer "*Analyzer ADEBUG*")
|
|
597 (data-debug-insert-object-slots (ede-toplevel) "")
|
|
598 ))
|
|
599
|
|
600
|
|
601
|
|
602 ;;; TOPLEVEL PROJECT
|
|
603 ;;
|
|
604 ;; The toplevel project is a way to identify the EDE structure that belongs
|
|
605 ;; to the top of a project.
|
|
606
|
|
607 (defun ede-toplevel (&optional subproj)
|
|
608 "Return the ede project which is the root of the current project.
|
|
609 Optional argument SUBPROJ indicates a subproject to start from
|
|
610 instead of the current project."
|
|
611 (or ede-object-root-project
|
|
612 (let* ((cp (or subproj (ede-current-project))))
|
|
613 (or (and cp (ede-project-root cp))
|
|
614 (progn
|
|
615 (while (ede-parent-project cp)
|
|
616 (setq cp (ede-parent-project cp)))
|
|
617 cp)))))
|
|
618
|
|
619
|
|
620 ;;; Hooks & Autoloads
|
|
621 ;;
|
|
622 ;; These let us watch various activities, and respond appropriately.
|
|
623
|
|
624 ;; (add-hook 'edebug-setup-hook
|
|
625 ;; (lambda ()
|
|
626 ;; (def-edebug-spec ede-with-projectfile
|
|
627 ;; (form def-body))))
|
|
628
|
|
629 (provide 'ede/base)
|
|
630
|
|
631 ;; Local variables:
|
|
632 ;; generated-autoload-file: "loaddefs.el"
|
|
633 ;; generated-autoload-load-name: "ede/base"
|
|
634 ;; End:
|
|
635
|
|
636 ;;; ede/base.el ends here
|