aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric M. Ludlam2010-09-20 22:42:53 -0400
committerChong Yidong2010-09-20 22:42:53 -0400
commitcb85c0d8be968992eef85e633133f65a3996830d (patch)
tree48fcc9800f8ba92bd03ca769466fbb202a09a5f5
parent9e0d4f9ef1cd4d7149c84475df5cef4d408743b6 (diff)
downloademacs-cb85c0d8be968992eef85e633133f65a3996830d.tar.gz
emacs-cb85c0d8be968992eef85e633133f65a3996830d.zip
Synch EDE to CEDET 1.0.
* cedet-idutils.el (cedet-idutils-make-command): New option. (cedet-idutils-mkid-call): (cedet-idutils-create/update-database): New functions. * cedet-cscope.el (cedet-cscope-create): (cedet-cscope-create/update-database): New functions. (cedet-cscope-support-for-directory): Make interactive. * cedet-global.el (cedet-global-gtags-command): New option. (cedet-gnu-global-gtags-call) (cedet-gnu-global-create/update-database): New functions. * ede.el (ede-save-cache): Fix recentf-exclude expression. (ede-make-dist): Always use toplevel project. (ede-buffer-object): If we fail to find an object in the current project, loop upward looking for a match. If no target is found, use most local project. (ede-buffer-belongs-to-target-p) (ede-buffer-belongs-to-project-p): New functions. (ede-initialize-state-current-buffer): New function. (ede-target-forms-menu, ede-project-buffers): Use them. (ede-minor-mode, ede-reset-all-buffers): Use it. (project-interactive-select-target, project-add-file): Don't use ede-project-force-load. (ede-buffer-object): New arg PROJSYM. (ede-minor-mode): Remove ede-directory-project-p test. (ede-initialize-state-current-buffer): Don't test for ede-directory-project-p if there is a matching open project. (ede-customize-forms-menu): Prevent error if there is no project. (ede-load-project-file): Set ede-constructing to the thing being constructed, instead of t. (ede-project-force-load): Deleted. * ede/base.el: * ede/auto.el: * ede/custom.el: New files. * ede/autoconf-edit.el (autoconf-find-last-macro) (autoconf-parameters-for-macro): Parse multiline parameters of macros. Optionally ignore case and at bol for macro. (autoconf-parameter-strip): Use greedy match for newlines. (autoconf-new-automake-string): Deleted. (autoconf-new-program): Use SRecode to fill an empty file. * ede/cpp-root.el (ede-create-lots-of-projects-under-dir): New function. * ede/files.el (ede-flush-project-hash): New command. (ede-convert-path): Add optional PROJECT arg. (ede-directory-project-p): Obey ".ede-ignore". (ede-expand-filename-local) (ede-expand-filename-impl-via-subproj): New methods. (ede-expand-filename-impl): Use them. (ede-project-root, ede-project-root-directory): Move to ede/auto.el. * ede/locate.el (ede-locate-flush-hash): (ede-locate-create/update-root-database): New methods. (initialize-instance): Use ede-locate-flush-hash. * ede/pmake.el (ede-proj-makefile-insert-variables): If this is the top project and not a metasubproject, set TOP to CURDIR. (ede-proj-makefile-insert-variables): Output a target's object list whether or not the vars are already in the Makefile. (ede-pmake-insert-variable-once): New macro. * ede/project-am.el (project-am-with-makefile-current): Add recentf-exclude. (project-am-load-makefile): Obey an optional suggested name. (project-am-expand-subdirlist): New function. (project-am-makefile::project-rescan): Use it. Combine SUBDIRS and DIST_SUBDIRS. (project-am-meta-type-alist): A list to scan better Makefile.am (project-am-scan-for-targets): Scan also over project-am-meta-type-alist. (ede-system-include-path): Simple implementation. (ede-find-target): Deleted. EDE core takes care of this. (ede-buffer-mine): Create the searched filename as relative. (project-am-load): Simplify, using autoconf-edit. (project-am-extract-package-info): Fix separators. * ede/proj.el (project-run-target): New method. (project-make-dist, project-compile-project): Use ede-proj-automake-p to determine which kind of compile to use. (project-rescan): Call ede-load-project-file. (ede-buffer-mine): Add more file names that belong to the project. (ede-proj-compilers): Improve error message. * ede/proj-obj.el (ede-ld-linker): Use the LDDEPS variable. (ede-source-c++): Add more C++ extensions. (ede-proj-target-makefile-objectcode): Quote initforms. Support lex and yacc. * ede/proj-prog.el (ede-proj-makefile-insert-rules): Removed. (ede-proj-makefile-insert-variables): New, add LDDEPS. (ede-proj-makefile-insert-automake-post-variables): Add LDADD variable. Use ldlibs-local slot. Add a -l to ldlibs strings. (ede-proj-target-makefile-program): Swap order of two slots so they show up in the same order as in the command line. (ede-proj-target-makefile-program): Add ldlibs-local slot. * ede/proj-shared.el (ede-g++-libtool-shared-compiler): Fix inference rule to use cpp files. (ede-proj-target-makefile-shared-object): Quote initforms. * ede/proj-misc.el (ede-proj-target-makefile-miscelaneous): * ede/proj-info.el (ede-proj-target-makefile-info): * ede/proj-aux.el (ede-proj-target-aux): * ede/proj-archive.el (ede-proj-target-makefile-archive): * ede/proj-elisp.el (ede-proj-target-elisp) (ede-proj-target-elisp-autoloads): Quote initforms. * ede/srecode.el (ede-srecode-setup): Load autoconf templates. * ede/shell.el (ede-shell-buffer): Fix buffer name. * ede/pconf.el (ede-proj-configure-synchronize): If user events occur while waiting for the compile process to finish, pull them in and discard those events.
-rw-r--r--lisp/cedet/ChangeLog124
-rw-r--r--lisp/cedet/cedet-cscope.el26
-rw-r--r--lisp/cedet/cedet-global.el31
-rw-r--r--lisp/cedet/cedet-idutils.el25
-rw-r--r--lisp/cedet/ede.el947
-rw-r--r--lisp/cedet/ede/auto.el128
-rw-r--r--lisp/cedet/ede/autoconf-edit.el64
-rw-r--r--lisp/cedet/ede/base.el636
-rw-r--r--lisp/cedet/ede/cpp-root.el27
-rw-r--r--lisp/cedet/ede/custom.el215
-rw-r--r--lisp/cedet/ede/dired.el2
-rw-r--r--lisp/cedet/ede/emacs.el14
-rw-r--r--lisp/cedet/ede/files.el147
-rw-r--r--lisp/cedet/ede/generic.el442
-rw-r--r--lisp/cedet/ede/linux.el14
-rw-r--r--lisp/cedet/ede/locate.el28
-rw-r--r--lisp/cedet/ede/pconf.el6
-rw-r--r--lisp/cedet/ede/pmake.el27
-rw-r--r--lisp/cedet/ede/proj-archive.el2
-rw-r--r--lisp/cedet/ede/proj-aux.el2
-rw-r--r--lisp/cedet/ede/proj-elisp.el6
-rw-r--r--lisp/cedet/ede/proj-info.el6
-rw-r--r--lisp/cedet/ede/proj-misc.el4
-rw-r--r--lisp/cedet/ede/proj-obj.el90
-rw-r--r--lisp/cedet/ede/proj-prog.el64
-rw-r--r--lisp/cedet/ede/proj-shared.el20
-rw-r--r--lisp/cedet/ede/proj.el38
-rw-r--r--lisp/cedet/ede/project-am.el435
-rw-r--r--lisp/cedet/ede/shell.el2
-rw-r--r--lisp/cedet/ede/simple.el12
-rw-r--r--lisp/cedet/ede/speedbar.el2
-rw-r--r--lisp/cedet/ede/srecode.el4
32 files changed, 2318 insertions, 1272 deletions
diff --git a/lisp/cedet/ChangeLog b/lisp/cedet/ChangeLog
index 9d3c35c829d..cdd5568dffc 100644
--- a/lisp/cedet/ChangeLog
+++ b/lisp/cedet/ChangeLog
@@ -1,3 +1,127 @@
12010-09-21 Eric Ludlam <zappo@gnu.org>
2
3 Synch EDE to CEDET 1.0.
4
5 * cedet-idutils.el (cedet-idutils-make-command): New option.
6 (cedet-idutils-mkid-call):
7 (cedet-idutils-create/update-database): New functions.
8
9 * cedet-cscope.el (cedet-cscope-create):
10 (cedet-cscope-create/update-database): New functions.
11 (cedet-cscope-support-for-directory): Make interactive.
12
13 * cedet-global.el (cedet-global-gtags-command): New option.
14 (cedet-gnu-global-gtags-call)
15 (cedet-gnu-global-create/update-database): New functions.
16
17 * ede.el (ede-save-cache): Fix recentf-exclude expression.
18 (ede-make-dist): Always use toplevel project.
19 (ede-buffer-object): If we fail to find an object in the current
20 project, loop upward looking for a match. If no target is found,
21 use most local project.
22 (ede-buffer-belongs-to-target-p)
23 (ede-buffer-belongs-to-project-p): New functions.
24 (ede-initialize-state-current-buffer): New function.
25 (ede-target-forms-menu, ede-project-buffers): Use them.
26 (ede-minor-mode, ede-reset-all-buffers): Use it.
27 (project-interactive-select-target, project-add-file): Don't use
28 ede-project-force-load.
29 (ede-buffer-object): New arg PROJSYM.
30 (ede-minor-mode): Remove ede-directory-project-p test.
31 (ede-initialize-state-current-buffer): Don't test for
32 ede-directory-project-p if there is a matching open project.
33 (ede-customize-forms-menu): Prevent error if there is no project.
34 (ede-load-project-file): Set ede-constructing to the thing being
35 constructed, instead of t.
36 (ede-project-force-load): Deleted.
37
38 * ede/base.el:
39 * ede/auto.el:
40 * ede/custom.el: New files.
41
42 * ede/autoconf-edit.el (autoconf-find-last-macro)
43 (autoconf-parameters-for-macro): Parse multiline parameters of
44 macros. Optionally ignore case and at bol for macro.
45 (autoconf-parameter-strip): Use greedy match for newlines.
46 (autoconf-new-automake-string): Deleted.
47 (autoconf-new-program): Use SRecode to fill an empty file.
48
49 * ede/cpp-root.el (ede-create-lots-of-projects-under-dir): New
50 function.
51
52 * ede/files.el (ede-flush-project-hash): New command.
53 (ede-convert-path): Add optional PROJECT arg.
54 (ede-directory-project-p): Obey ".ede-ignore".
55 (ede-expand-filename-local)
56 (ede-expand-filename-impl-via-subproj): New methods.
57 (ede-expand-filename-impl): Use them.
58 (ede-project-root, ede-project-root-directory): Move to
59 ede/auto.el.
60
61 * ede/locate.el (ede-locate-flush-hash):
62 (ede-locate-create/update-root-database): New methods.
63 (initialize-instance): Use ede-locate-flush-hash.
64
65 * ede/pmake.el (ede-proj-makefile-insert-variables): If this is
66 the top project and not a metasubproject, set TOP to CURDIR.
67 (ede-proj-makefile-insert-variables): Output a target's object
68 list whether or not the vars are already in the Makefile.
69 (ede-pmake-insert-variable-once): New macro.
70
71 * ede/project-am.el (project-am-with-makefile-current): Add
72 recentf-exclude.
73 (project-am-load-makefile): Obey an optional suggested name.
74 (project-am-expand-subdirlist): New function.
75 (project-am-makefile::project-rescan): Use it. Combine SUBDIRS
76 and DIST_SUBDIRS.
77 (project-am-meta-type-alist): A list to scan better Makefile.am
78 (project-am-scan-for-targets): Scan also over
79 project-am-meta-type-alist.
80 (ede-system-include-path): Simple implementation.
81 (ede-find-target): Deleted. EDE core takes care of this.
82 (ede-buffer-mine): Create the searched filename as relative.
83 (project-am-load): Simplify, using autoconf-edit.
84 (project-am-extract-package-info): Fix separators.
85
86 * ede/proj.el (project-run-target): New method.
87 (project-make-dist, project-compile-project): Use
88 ede-proj-automake-p to determine which kind of compile to use.
89 (project-rescan): Call ede-load-project-file.
90 (ede-buffer-mine): Add more file names that belong to the project.
91 (ede-proj-compilers): Improve error message.
92
93 * ede/proj-obj.el (ede-ld-linker): Use the LDDEPS variable.
94 (ede-source-c++): Add more C++ extensions.
95 (ede-proj-target-makefile-objectcode): Quote initforms. Support
96 lex and yacc.
97
98 * ede/proj-prog.el (ede-proj-makefile-insert-rules): Removed.
99 (ede-proj-makefile-insert-variables): New, add LDDEPS.
100 (ede-proj-makefile-insert-automake-post-variables): Add LDADD
101 variable. Use ldlibs-local slot. Add a -l to ldlibs strings.
102 (ede-proj-target-makefile-program): Swap order of two slots so
103 they show up in the same order as in the command line.
104 (ede-proj-target-makefile-program): Add ldlibs-local slot.
105
106 * ede/proj-shared.el (ede-g++-libtool-shared-compiler): Fix
107 inference rule to use cpp files.
108 (ede-proj-target-makefile-shared-object): Quote initforms.
109
110 * ede/proj-misc.el (ede-proj-target-makefile-miscelaneous):
111 * ede/proj-info.el (ede-proj-target-makefile-info):
112 * ede/proj-aux.el (ede-proj-target-aux):
113 * ede/proj-archive.el (ede-proj-target-makefile-archive):
114 * ede/proj-elisp.el (ede-proj-target-elisp)
115 (ede-proj-target-elisp-autoloads): Quote initforms.
116
117 * ede/srecode.el (ede-srecode-setup): Load autoconf templates.
118
119 * ede/shell.el (ede-shell-buffer): Fix buffer name.
120
121 * ede/pconf.el (ede-proj-configure-synchronize): If user events
122 occur while waiting for the compile process to finish, pull them
123 in and discard those events.
124
12010-09-19 Eric Ludlam <zappo@gnu.org> 1252010-09-19 Eric Ludlam <zappo@gnu.org>
2 126
3 Synch Semantic to CEDET 1.0. 127 Synch Semantic to CEDET 1.0.
diff --git a/lisp/cedet/cedet-cscope.el b/lisp/cedet/cedet-cscope.el
index bff80222f78..33bbc612d79 100644
--- a/lisp/cedet/cedet-cscope.el
+++ b/lisp/cedet/cedet-cscope.el
@@ -72,6 +72,12 @@ SCOPE is the scope of the search, such as 'project or 'subdirs."
72 ) 72 )
73 (cedet-cscope-call (list "-d" "-L" idx searchtext)))) 73 (cedet-cscope-call (list "-d" "-L" idx searchtext))))
74 74
75(defun cedet-cscope-create (flags)
76 "Create a CScope database at the current directory.
77FLAGS are additional flags to pass to cscope beyond the
78options -cR."
79 (cedet-cscope-call (append (list "-cR") flags)))
80
75(defun cedet-cscope-call (flags) 81(defun cedet-cscope-call (flags)
76 "Call CScope with the list of FLAGS." 82 "Call CScope with the list of FLAGS."
77 (let ((b (get-buffer-create "*CEDET CScope*")) 83 (let ((b (get-buffer-create "*CEDET CScope*"))
@@ -112,13 +118,19 @@ Return a fully qualified filename."
112If DIR is not supplied, use the current default directory. 118If DIR is not supplied, use the current default directory.
113This works by running cscope on a bogus symbol, and looking for 119This works by running cscope on a bogus symbol, and looking for
114the error code." 120the error code."
121 (interactive "DDirectory: ")
115 (save-excursion 122 (save-excursion
116 (let ((default-directory (or dir default-directory))) 123 (let ((default-directory (or dir default-directory)))
117 (set-buffer (cedet-cscope-call (list "-d" "-L" "-7" "moose"))) 124 (set-buffer (cedet-cscope-call (list "-d" "-L" "-7" "moose")))
118 (goto-char (point-min)) 125 (goto-char (point-min))
119 (if (looking-at "[^ \n]*cscope: ") 126 (let ((ans (looking-at "[^ \n]*cscope: ")))
120 nil 127 (if (called-interactively-p 'interactive)
121 t)))) 128 (if ans
129 (message "No support for CScope in %s" default-directory)
130 (message "CScope is supported in %s" default-directory))
131 (if ans
132 nil
133 t))))))
122 134
123(defun cedet-cscope-version-check (&optional noerror) 135(defun cedet-cscope-version-check (&optional noerror)
124 "Check the version of the installed CScope command. 136 "Check the version of the installed CScope command.
@@ -150,6 +162,14 @@ return nil."
150 (message "CScope %s - Good enough for CEDET." rev)) 162 (message "CScope %s - Good enough for CEDET." rev))
151 t))))) 163 t)))))
152 164
165(defun cedet-cscope-create/update-database (&optional dir)
166 "Create a CScope database in DIR.
167CScope will automatically choose incremental rebuild if
168there is already a database in DIR."
169 (interactive "DDirectory: ")
170 (let ((default-directory dir))
171 (cedet-cscope-create nil)))
172
153(provide 'cedet-cscope) 173(provide 'cedet-cscope)
154 174
155;; arch-tag: 9973f1ad-f13b-4399-bc67-7f488478d78d 175;; arch-tag: 9973f1ad-f13b-4399-bc67-7f488478d78d
diff --git a/lisp/cedet/cedet-global.el b/lisp/cedet/cedet-global.el
index 3a34ca44e25..cedd1dd1162 100644
--- a/lisp/cedet/cedet-global.el
+++ b/lisp/cedet/cedet-global.el
@@ -33,6 +33,12 @@
33 :type 'string 33 :type 'string
34 :group 'cedet) 34 :group 'cedet)
35 35
36(defcustom cedet-global-gtags-command "gtags"
37 "Command name for the GNU Global gtags executable.
38GTAGS is used to create the tags table queried by the 'global' command."
39 :type 'string
40 :group 'cedet)
41
36;;; Code: 42;;; Code:
37(defun cedet-gnu-global-search (searchtext texttype type scope) 43(defun cedet-gnu-global-search (searchtext texttype type scope)
38 "Perform a search with GNU Global, return the created buffer. 44 "Perform a search with GNU Global, return the created buffer.
@@ -75,6 +81,19 @@ SCOPE is the scope of the search, such as 'project or 'subdirs."
75 flags) 81 flags)
76 b)) 82 b))
77 83
84(defun cedet-gnu-global-gtags-call (flags)
85 "Create GNU Global TAGS using gtags with FLAGS."
86 (let ((b (get-buffer-create "*CEDET Global gtags*"))
87 (cd default-directory)
88 )
89 (with-current-buffer b
90 (setq default-directory cd)
91 (erase-buffer))
92 (apply 'call-process cedet-global-gtags-command
93 nil b nil
94 flags)
95 b))
96
78(defun cedet-gnu-global-expand-filename (filename) 97(defun cedet-gnu-global-expand-filename (filename)
79 "Expand the FILENAME with GNU Global. 98 "Expand the FILENAME with GNU Global.
80Return a fully qualified filename." 99Return a fully qualified filename."
@@ -152,6 +171,18 @@ return nil."
152 ;; Return the results 171 ;; Return the results
153 (nreverse hits)))) 172 (nreverse hits))))
154 173
174(defun cedet-gnu-global-create/update-database (&optional dir)
175 "Create a GNU Global database in DIR.
176If a database already exists, then just update it."
177 (interactive "DDirectory: ")
178 (let ((root (cedet-gnu-global-root dir)))
179 (if root (setq dir root))
180 (let ((default-directory dir))
181 (cedet-gnu-global-gtags-call
182 (when root
183 '("-i");; Incremental update flag.
184 )))))
185
155(provide 'cedet-global) 186(provide 'cedet-global)
156 187
157;; arch-tag: 0d0d3ac2-91ef-4820-bb2b-1d59ccf38392 188;; arch-tag: 0d0d3ac2-91ef-4820-bb2b-1d59ccf38392
diff --git a/lisp/cedet/cedet-idutils.el b/lisp/cedet/cedet-idutils.el
index 562749dda00..7abf3c3320b 100644
--- a/lisp/cedet/cedet-idutils.el
+++ b/lisp/cedet/cedet-idutils.el
@@ -43,6 +43,11 @@
43 :type 'string 43 :type 'string
44 :group 'cedet) 44 :group 'cedet)
45 45
46(defcustom cedet-idutils-make-command "mkid"
47 "Command name for the ID Utils executable for creating token databases."
48 :type 'string
49 :group 'cedet)
50
46(defun cedet-idutils-search (searchtext texttype type scope) 51(defun cedet-idutils-search (searchtext texttype type scope)
47 "Perform a search with ID Utils, return the created buffer. 52 "Perform a search with ID Utils, return the created buffer.
48SEARCHTEXT is text to find. 53SEARCHTEXT is text to find.
@@ -104,6 +109,20 @@ Return the created buffer with with program output."
104 flags) 109 flags)
105 b)) 110 b))
106 111
112(defun cedet-idutils-mkid-call (flags)
113 "Call ID Utils mkid with the list of FLAGS.
114Return the created buffer with with program output."
115 (let ((b (get-buffer-create "*CEDET mkid*"))
116 (cd default-directory)
117 )
118 (with-current-buffer b
119 (setq default-directory cd)
120 (erase-buffer))
121 (apply 'call-process cedet-idutils-make-command
122 nil b nil
123 flags)
124 b))
125
107;;; UTIL CALLS 126;;; UTIL CALLS
108;; 127;;
109(defun cedet-idutils-expand-filename (filename) 128(defun cedet-idutils-expand-filename (filename)
@@ -171,6 +190,12 @@ return nil."
171 (message "ID Utils %s - Good enough for CEDET." rev)) 190 (message "ID Utils %s - Good enough for CEDET." rev))
172 t))))) 191 t)))))
173 192
193(defun cedet-idutils-create/update-database (&optional dir)
194 "Create an IDUtils database in DIR.
195IDUtils must start from scratch when updating a database."
196 (interactive "DDirectory: ")
197 (let ((default-directory dir))
198 (cedet-idutils-mkid-call nil)))
174 199
175(provide 'cedet-idutils) 200(provide 'cedet-idutils)
176 201
diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el
index 46fcdb000f8..43212b626e7 100644
--- a/lisp/cedet/ede.el
+++ b/lisp/cedet/ede.el
@@ -43,24 +43,24 @@
43(require 'eieio) 43(require 'eieio)
44(require 'eieio-speedbar) 44(require 'eieio-speedbar)
45(require 'ede/source) 45(require 'ede/source)
46(require 'ede/base)
47(require 'ede/auto)
48
46(load "ede/loaddefs" nil 'nomessage) 49(load "ede/loaddefs" nil 'nomessage)
47 50
51(declare-function ede-commit-project "ede/custom")
48(declare-function ede-convert-path "ede/files") 52(declare-function ede-convert-path "ede/files")
49(declare-function ede-directory-get-open-project "ede/files") 53(declare-function ede-directory-get-open-project "ede/files")
50(declare-function ede-directory-get-toplevel-open-project "ede/files") 54(declare-function ede-directory-get-toplevel-open-project "ede/files")
51(declare-function ede-directory-project-p "ede/files") 55(declare-function ede-directory-project-p "ede/files")
52(declare-function ede-find-subproject-for-directory "ede/files") 56(declare-function ede-find-subproject-for-directory "ede/files")
53(declare-function ede-project-directory-remove-hash "ede/files") 57(declare-function ede-project-directory-remove-hash "ede/files")
54(declare-function ede-project-root "ede/files")
55(declare-function ede-project-root-directory "ede/files")
56(declare-function ede-toplevel "ede/files") 58(declare-function ede-toplevel "ede/files")
57(declare-function ede-toplevel-project "ede/files") 59(declare-function ede-toplevel-project "ede/files")
58(declare-function ede-up-directory "ede/files") 60(declare-function ede-up-directory "ede/files")
59(declare-function data-debug-new-buffer "data-debug")
60(declare-function data-debug-insert-object-slots "eieio-datadebug")
61(declare-function semantic-lex-make-spp-table "semantic/lex-spp") 61(declare-function semantic-lex-make-spp-table "semantic/lex-spp")
62 62
63(defconst ede-version "1.0pre7" 63(defconst ede-version "1.0"
64 "Current version of the Emacs EDE.") 64 "Current version of the Emacs EDE.")
65 65
66;;; Code: 66;;; Code:
@@ -94,314 +94,6 @@ target willing to take the file. 'never means never perform the check."
94 :group 'ede 94 :group 'ede
95 :type 'sexp) ; make this be a list of options some day 95 :type 'sexp) ; make this be a list of options some day
96 96
97
98;;; Top level classes for projects and targets
99
100(defclass ede-project-autoload ()
101 ((name :initarg :name
102 :documentation "Name of this project type")
103 (file :initarg :file
104 :documentation "The lisp file belonging to this class.")
105 (proj-file :initarg :proj-file
106 :documentation "Name of a project file of this type.")
107 (proj-root :initarg :proj-root
108 :type function
109 :documentation "A function symbol to call for the project root.
110This function takes no arguments, and returns the current directories
111root, if available. Leave blank to use the EDE directory walking
112routine instead.")
113 (initializers :initarg :initializers
114 :initform nil
115 :documentation
116 "Initializers passed to the project object.
117These are used so there can be multiple types of projects
118associated with a single object class, based on the initilizeres used.")
119 (load-type :initarg :load-type
120 :documentation "Fn symbol used to load this project file.")
121 (class-sym :initarg :class-sym
122 :documentation "Symbol representing the project class to use.")
123 (new-p :initarg :new-p
124 :initform t
125 :documentation
126 "Non-nil if this is an option when a user creates a project.")
127 )
128 "Class representing minimal knowledge set to run preliminary EDE functions.
129When more advanced functionality is needed from a project type, that projects
130type is required and the load function used.")
131
132(defvar ede-project-class-files
133 (list
134 (ede-project-autoload "edeproject-makefile"
135 :name "Make" :file 'ede/proj
136 :proj-file "Project.ede"
137 :load-type 'ede-proj-load
138 :class-sym 'ede-proj-project)
139 (ede-project-autoload "edeproject-automake"
140 :name "Automake" :file 'ede/proj
141 :proj-file "Project.ede"
142 :initializers '(:makefile-type Makefile.am)
143 :load-type 'ede-proj-load
144 :class-sym 'ede-proj-project)
145 (ede-project-autoload "automake"
146 :name "automake" :file 'ede/project-am
147 :proj-file "Makefile.am"
148 :load-type 'project-am-load
149 :class-sym 'project-am-makefile
150 :new-p nil)
151 (ede-project-autoload "cpp-root"
152 :name "CPP ROOT" :file 'ede/cpp-root
153 :proj-file 'ede-cpp-root-project-file-for-dir
154 :proj-root 'ede-cpp-root-project-root
155 :load-type 'ede-cpp-root-load
156 :class-sym 'ede-cpp-root
157 :new-p nil)
158 (ede-project-autoload "emacs"
159 :name "EMACS ROOT" :file 'ede/emacs
160 :proj-file "src/emacs.c"
161 :proj-root 'ede-emacs-project-root
162 :load-type 'ede-emacs-load
163 :class-sym 'ede-emacs-project
164 :new-p nil)
165 (ede-project-autoload "linux"
166 :name "LINUX ROOT" :file 'ede/linux
167 :proj-file "scripts/ver_linux"
168 :proj-root 'ede-linux-project-root
169 :load-type 'ede-linux-load
170 :class-sym 'ede-linux-project
171 :new-p nil)
172 (ede-project-autoload "simple-overlay"
173 :name "Simple" :file 'ede/simple
174 :proj-file 'ede-simple-projectfile-for-dir
175 :load-type 'ede-simple-load
176 :class-sym 'ede-simple-project))
177 "List of vectors defining how to determine what type of projects exist.")
178
179;;; Generic project information manager objects
180
181(defclass ede-target (eieio-speedbar-directory-button)
182 ((buttonface :initform speedbar-file-face) ;override for superclass
183 (name :initarg :name
184 :type string
185 :custom string
186 :label "Name"
187 :group (default name)
188 :documentation "Name of this target.")
189 ;; @todo - I think this should be "dir", and not "path".
190 (path :initarg :path
191 :type string
192 ;:custom string
193 ;:label "Path to target"
194 ;:group (default name)
195 :documentation "The path to the sources of this target.
196Relative to the path of the project it belongs to.")
197 (source :initarg :source
198 :initform nil
199 ;; I'd prefer a list of strings.
200 :type list
201 :custom (repeat (string :tag "File"))
202 :label "Source Files"
203 :group (default source)
204 :documentation "Source files in this target.")
205 (versionsource :initarg :versionsource
206 :initform nil
207 :type list
208 :custom (repeat (string :tag "File"))
209 :label "Source Files with Version String"
210 :group (source)
211 :documentation
212 "Source files with a version string in them.
213These files are checked for a version string whenever the EDE version
214of the master project is changed. When strings are found, the version
215previously there is updated.")
216 ;; Class level slots
217 ;;
218; (takes-compile-command :allocation :class
219; :initarg :takes-compile-command
220; :type boolean
221; :initform nil
222; :documentation
223; "Non-nil if this target requires a user approved command.")
224 (sourcetype :allocation :class
225 :type list ;; list of symbols
226 :documentation
227 "A list of `ede-sourcecode' objects this class will handle.
228This is used to match target objects with the compilers they can use, and
229which files this object is interested in."
230 :accessor ede-object-sourcecode)
231 (keybindings :allocation :class
232 :initform (("D" . ede-debug-target))
233 :documentation
234"Keybindings specialized to this type of target."
235 :accessor ede-object-keybindings)
236 (menu :allocation :class
237 :initform ( [ "Debug target" ede-debug-target
238 (and ede-object
239 (obj-of-class-p ede-object ede-target)) ]
240 )
241 [ "Run target" ede-run-target
242 (and ede-object
243 (obj-of-class-p ede-object ede-target)) ]
244 :documentation "Menu specialized to this type of target."
245 :accessor ede-object-menu)
246 )
247 "A top level target to build.")
248
249(defclass ede-project-placeholder (eieio-speedbar-directory-button)
250 ((name :initarg :name
251 :initform "Untitled"
252 :type string
253 :custom string
254 :label "Name"
255 :group (default name)
256 :documentation "The name used when generating distribution files.")
257 (version :initarg :version
258 :initform "1.0"
259 :type string
260 :custom string
261 :label "Version"
262 :group (default name)
263 :documentation "The version number used when distributing files.")
264 (directory :type string
265 :initarg :directory
266 :documentation "Directory this project is associated with.")
267 (dirinode :documentation "The inode id for :directory.")
268 (file :type string
269 :initarg :file
270 :documentation "File name where this project is stored.")
271 (rootproject ; :initarg - no initarg, don't save this slot!
272 :initform nil
273 :type (or null ede-project-placeholder-child)
274 :documentation "Pointer to our root project.")
275 )
276 "Placeholder object for projects not loaded into memory.
277Projects placeholders will be stored in a user specific location
278and querying them will cause the actual project to get loaded.")
279
280(defclass ede-project (ede-project-placeholder)
281 ((subproj :initform nil
282 :type list
283 :documentation "Sub projects controlled by this project.
284For Automake based projects, each directory is treated as a project.")
285 (targets :initarg :targets
286 :type list
287 :custom (repeat (object :objectcreatefcn ede-new-target-custom))
288 :label "Local Targets"
289 :group (targets)
290 :documentation "List of top level targets in this project.")
291 (locate-obj :type (or null ede-locate-base-child)
292 :documentation
293 "A locate object to use as a backup to `ede-expand-filename'.")
294 (tool-cache :initarg :tool-cache
295 :type list
296 :custom (repeat object)
297 :label "Tool: "
298 :group tools
299 :documentation "List of tool cache configurations in this project.
300This allows any tool to create, manage, and persist project-specific settings.")
301 (mailinglist :initarg :mailinglist
302 :initform ""
303 :type string
304 :custom string
305 :label "Mailing List Address"
306 :group name
307 :documentation
308 "An email address where users might send email for help.")
309 (web-site-url :initarg :web-site-url
310 :initform ""
311 :type string
312 :custom string
313 :label "Web Site URL"
314 :group name
315 :documentation "URL to this projects web site.
316This is a URL to be sent to a web site for documentation.")
317 (web-site-directory :initarg :web-site-directory
318 :initform ""
319 :custom string
320 :label "Web Page Directory"
321 :group name
322 :documentation
323 "A directory where web pages can be found by Emacs.
324For remote locations use a path compatible with ange-ftp or EFS.
325You can also use TRAMP for use with rcp & scp.")
326 (web-site-file :initarg :web-site-file
327 :initform ""
328 :custom string
329 :label "Web Page File"
330 :group name
331 :documentation
332 "A file which contains the home page for this project.
333This file can be relative to slot `web-site-directory'.
334This can be a local file, use ange-ftp, EFS, or TRAMP.")
335 (ftp-site :initarg :ftp-site
336 :initform ""
337 :type string
338 :custom string
339 :label "FTP site"
340 :group name
341 :documentation
342 "FTP site where this project's distribution can be found.
343This FTP site should be in Emacs form, as needed by `ange-ftp', but can
344also be of a form used by TRAMP for use with scp, or rcp.")
345 (ftp-upload-site :initarg :ftp-upload-site
346 :initform ""
347 :type string
348 :custom string
349 :label "FTP Upload site"
350 :group name
351 :documentation
352 "FTP Site to upload new distributions to.
353This FTP site should be in Emacs form as needed by `ange-ftp'.
354If this slot is nil, then use `ftp-site' instead.")
355 (configurations :initarg :configurations
356 :initform ("debug" "release")
357 :type list
358 :custom (repeat string)
359 :label "Configuration Options"
360 :group (settings)
361 :documentation "List of available configuration types.
362Individual target/project types can form associations between a configuration,
363and target specific elements such as build variables.")
364 (configuration-default :initarg :configuration-default
365 :initform "debug"
366 :custom string
367 :label "Current Configuration"
368 :group (settings)
369 :documentation "The default configuration.")
370 (local-variables :initarg :local-variables
371 :initform nil
372 :custom (repeat (cons (sexp :tag "Variable")
373 (sexp :tag "Value")))
374 :label "Project Local Variables"
375 :group (settings)
376 :documentation "Project local variables")
377 (keybindings :allocation :class
378 :initform (("D" . ede-debug-target)
379 ("R" . ede-run-target))
380 :documentation "Keybindings specialized to this type of target."
381 :accessor ede-object-keybindings)
382 (menu :allocation :class
383 :initform
384 (
385 [ "Update Version" ede-update-version ede-object ]
386 [ "Version Control Status" ede-vc-project-directory ede-object ]
387 [ "Edit Project Homepage" ede-edit-web-page
388 (and ede-object (oref (ede-toplevel) web-site-file)) ]
389 [ "Browse Project URL" ede-web-browse-home
390 (and ede-object
391 (not (string= "" (oref (ede-toplevel) web-site-url)))) ]
392 "--"
393 [ "Rescan Project Files" ede-rescan-toplevel t ]
394 [ "Edit Projectfile" ede-edit-file-target
395 (and ede-object
396 (or (listp ede-object)
397 (not (obj-of-class-p ede-object ede-project)))) ]
398 )
399 :documentation "Menu specialized to this type of target."
400 :accessor ede-object-menu)
401 )
402 "Top level EDE project specification.
403All specific project types must derive from this project."
404 :method-invocation-order :depth-first)
405 97
406;;; Management variables 98;;; Management variables
407 99
@@ -430,109 +122,13 @@ This object's class determines how to compile and debug from a buffer.")
430If `ede-object' is nil, then commands will operate on this object.") 122If `ede-object' is nil, then commands will operate on this object.")
431 123
432(defvar ede-constructing nil 124(defvar ede-constructing nil
433 "Non nil when constructing a project hierarchy.") 125 "Non nil when constructing a project hierarchy.
126If the project is being constructed from an autoload, then the
127value is the autoload object being used.")
434 128
435(defvar ede-deep-rescan nil 129(defvar ede-deep-rescan nil
436 "Non nil means scan down a tree, otherwise rescans are top level only. 130 "Non nil means scan down a tree, otherwise rescans are top level only.
437Do not set this to non-nil globally. It is used internally.") 131Do not set this to non-nil globally. It is used internally.")
438
439;;; The EDE persistent cache.
440;;
441(defcustom ede-project-placeholder-cache-file
442 (locate-user-emacs-file "ede-projects.el" ".projects.ede")
443 "File containing the list of projects EDE has viewed."
444 :group 'ede
445 :type 'file)
446
447(defvar ede-project-cache-files nil
448 "List of project files EDE has seen before.")
449
450(defun ede-save-cache ()
451 "Save a cache of EDE objects that Emacs has seen before."
452 (interactive)
453 (let ((p ede-projects)
454 (c ede-project-cache-files)
455 (recentf-exclude '(ignore))
456 )
457 (condition-case nil
458 (progn
459 (set-buffer (find-file-noselect ede-project-placeholder-cache-file t))
460 (erase-buffer)
461 (insert ";; EDE project cache file.
462;; This contains a list of projects you have visited.\n(")
463 (while p
464 (when (and (car p) (ede-project-p p))
465 (let ((f (oref (car p) file)))
466 (when (file-exists-p f)
467 (insert "\n \"" f "\""))))
468 (setq p (cdr p)))
469 (while c
470 (insert "\n \"" (car c) "\"")
471 (setq c (cdr c)))
472 (insert "\n)\n")
473 (condition-case nil
474 (save-buffer 0)
475 (error
476 (message "File %s could not be saved."
477 ede-project-placeholder-cache-file)))
478 (kill-buffer (current-buffer))
479 )
480 (error
481 (message "File %s could not be read."
482 ede-project-placeholder-cache-file))
483
484 )))
485
486(defun ede-load-cache ()
487 "Load the cache of EDE projects."
488 (save-excursion
489 (let ((cachebuffer nil))
490 (condition-case nil
491 (progn
492 (setq cachebuffer
493 (find-file-noselect ede-project-placeholder-cache-file t))
494 (set-buffer cachebuffer)
495 (goto-char (point-min))
496 (let ((c (read (current-buffer)))
497 (new nil)
498 (p ede-projects))
499 ;; Remove loaded projects from the cache.
500 (while p
501 (setq c (delete (oref (car p) file) c))
502 (setq p (cdr p)))
503 ;; Remove projects that aren't on the filesystem
504 ;; anymore.
505 (while c
506 (when (file-exists-p (car c))
507 (setq new (cons (car c) new)))
508 (setq c (cdr c)))
509 ;; Save it
510 (setq ede-project-cache-files (nreverse new))))
511 (error nil))
512 (when cachebuffer (kill-buffer cachebuffer))
513 )))
514
515;;; Important macros for doing commands.
516;;
517(defmacro ede-with-projectfile (obj &rest forms)
518 "For the project in which OBJ resides, execute FORMS."
519 (list 'save-window-excursion
520 (list 'let* (list
521 (list 'pf
522 (list 'if (list 'obj-of-class-p
523 obj 'ede-target)
524 ;; @todo -I think I can change
525 ;; this to not need ede-load-project-file
526 ;; but I'm not sure how to test well.
527 (list 'ede-load-project-file
528 (list 'oref obj 'path))
529 obj))
530 '(dbka (get-file-buffer (oref pf file))))
531 '(if (not dbka) (find-file (oref pf file))
532 (switch-to-buffer dbka))
533 (cons 'progn forms)
534 '(if (not dbka) (kill-buffer (current-buffer))))))
535(put 'ede-with-projectfile 'lisp-indent-function 1)
536 132
537 133
538;;; Prompting 134;;; Prompting
@@ -610,6 +206,18 @@ Argument LIST-O-O is the list of objects to choose from."
610 :enable ede-object 206 :enable ede-object
611 :visible global-ede-mode)) 207 :visible global-ede-mode))
612 208
209(defun ede-buffer-belongs-to-target-p ()
210 "Return non-nil if this buffer belongs to at least one target."
211 (let ((obj ede-object))
212 (if (consp obj)
213 (setq obj (car obj)))
214 (and obj (obj-of-class-p obj ede-target))))
215
216(defun ede-buffer-belongs-to-project-p ()
217 "Return non-nil if this buffer belongs to at least one target."
218 (if (or (null ede-object) (consp ede-object)) nil
219 (obj-of-class-p ede-object ede-project)))
220
613(defun ede-menu-obj-of-class-p (class) 221(defun ede-menu-obj-of-class-p (class)
614 "Return non-nil if some member of `ede-object' is a child of CLASS." 222 "Return non-nil if some member of `ede-object' is a child of CLASS."
615 (if (listp ede-object) 223 (if (listp ede-object)
@@ -671,9 +279,7 @@ Argument MENU-DEF is the menu definition to use."
671 (and (ede-current-project) 279 (and (ede-current-project)
672 (oref (ede-current-project) targets)) ] 280 (oref (ede-current-project) targets)) ]
673 [ "Remove File" ede-remove-file 281 [ "Remove File" ede-remove-file
674 (and ede-object 282 (ede-buffer-belongs-to-project-p) ]
675 (or (listp ede-object)
676 (not (obj-of-class-p ede-object ede-project)))) ]
677 "-") 283 "-")
678 (if (not obj) 284 (if (not obj)
679 nil 285 nil
@@ -717,7 +323,7 @@ Argument MENU-DEF is the definition of the current menu."
717 (let* ((obj (ede-current-project)) 323 (let* ((obj (ede-current-project))
718 targ) 324 targ)
719 (when obj 325 (when obj
720 (setq targ (when (slot-boundp obj 'targets) 326 (setq targ (when (and obj (slot-boundp obj 'targets))
721 (oref obj targets))) 327 (oref obj targets)))
722 ;; Make custom menus for everything here. 328 ;; Make custom menus for everything here.
723 (append (list 329 (append (list
@@ -803,31 +409,49 @@ provided `global-ede-mode' is enabled."
803 (eq major-mode 'vc-dired-mode)) 409 (eq major-mode 'vc-dired-mode))
804 (ede-dired-minor-mode (if ede-minor-mode 1 -1))) 410 (ede-dired-minor-mode (if ede-minor-mode 1 -1)))
805 (ede-minor-mode 411 (ede-minor-mode
806 (if (and (not ede-constructing) 412 (if (not ede-constructing)
807 (ede-directory-project-p default-directory t)) 413 (ede-initialize-state-current-buffer)
808 (let* ((ROOT nil)
809 (proj (ede-directory-get-open-project default-directory
810 'ROOT)))
811 (when (not proj)
812 ;; @todo - this could be wasteful.
813 (setq proj (ede-load-project-file default-directory 'ROOT)))
814 (setq ede-object-project proj)
815 (setq ede-object-root-project
816 (or ROOT (ede-project-root proj)))
817 (setq ede-object (ede-buffer-object))
818 (if (and (not ede-object) ede-object-project)
819 (ede-auto-add-to-target))
820 (ede-apply-target-options))
821 ;; If we fail to have a project here, turn it back off. 414 ;; If we fail to have a project here, turn it back off.
822 (ede-minor-mode -1))))) 415 (ede-minor-mode -1)))))
823 416
417(defun ede-initialize-state-current-buffer ()
418 "Initialize the current buffer's state for EDE.
419Sets buffer local variables for EDE."
420 (let* ((ROOT nil)
421 (proj (ede-directory-get-open-project default-directory
422 'ROOT)))
423 (when (or proj ROOT
424 (ede-directory-project-p default-directory t))
425
426 (when (not proj)
427 ;; @todo - this could be wasteful.
428 (setq proj (ede-load-project-file default-directory 'ROOT)))
429
430 (setq ede-object (ede-buffer-object (current-buffer)
431 'ede-object-project))
432
433 (setq ede-object-root-project
434 (or ROOT (ede-project-root ede-object-project)))
435
436 (if (and (not ede-object) ede-object-project)
437 (ede-auto-add-to-target))
438
439 (ede-apply-target-options))))
440
824(defun ede-reset-all-buffers (onoff) 441(defun ede-reset-all-buffers (onoff)
825 "Reset all the buffers due to change in EDE. 442 "Reset all the buffers due to change in EDE.
826ONOFF indicates enabling or disabling the mode." 443ONOFF indicates enabling or disabling the mode."
827 (let ((b (buffer-list))) 444 (let ((b (buffer-list)))
828 (while b 445 (while b
829 (when (buffer-file-name (car b)) 446 (when (buffer-file-name (car b))
830 (ede-buffer-object (car b)) 447 (with-current-buffer (car b)
448 ;; Reset all state variables
449 (setq ede-object nil
450 ede-object-project nil
451 ede-object-root-project nil)
452 ;; Now re-initialize this buffer.
453 (ede-initialize-state-current-buffer)
454 )
831 ) 455 )
832 (setq b (cdr b))))) 456 (setq b (cdr b)))))
833 457
@@ -966,6 +590,7 @@ Optional argument NAME is the name to give this project."
966 r) 590 r)
967 ) 591 )
968 nil t))) 592 nil t)))
593 (require 'ede/custom)
969 ;; Make sure we have a valid directory 594 ;; Make sure we have a valid directory
970 (when (not (file-exists-p default-directory)) 595 (when (not (file-exists-p default-directory))
971 (error "Cannot create project in non-existent directory %s" default-directory)) 596 (error "Cannot create project in non-existent directory %s" default-directory))
@@ -1013,20 +638,6 @@ Optional argument NAME is the name to give this project."
1013 "Add into PROJ-A, the subproject PROJ-B." 638 "Add into PROJ-A, the subproject PROJ-B."
1014 (oset proj-a subproj (cons proj-b (oref proj-a subproj)))) 639 (oset proj-a subproj (cons proj-b (oref proj-a subproj))))
1015 640
1016(defmethod ede-subproject-relative-path ((proj ede-project) &optional parent-in)
1017 "Get a path name for PROJ which is relative to the parent project.
1018If PARENT is specified, then be relative to the PARENT project.
1019Specifying PARENT is useful for sub-sub projects relative to the root project."
1020 (let* ((parent (or parent-in (ede-parent-project proj)))
1021 (dir (file-name-directory (oref proj file))))
1022 (if (and parent (not (eq parent proj)))
1023 (file-relative-name dir (file-name-directory (oref parent file)))
1024 "")))
1025
1026(defmethod ede-subproject-p ((proj ede-project))
1027 "Return non-nil if PROJ is a sub project."
1028 (ede-parent-project proj))
1029
1030(defun ede-invoke-method (sym &rest args) 641(defun ede-invoke-method (sym &rest args)
1031 "Invoke method SYM on the current buffer's project object. 642 "Invoke method SYM on the current buffer's project object.
1032ARGS are additional arguments to pass to method sym." 643ARGS are additional arguments to pass to method sym."
@@ -1161,175 +772,9 @@ Optional argument FORCE forces the file to be removed without asking."
1161(defun ede-make-dist () 772(defun ede-make-dist ()
1162 "Create a distribution from the current project." 773 "Create a distribution from the current project."
1163 (interactive) 774 (interactive)
1164 (let ((ede-object (ede-current-project))) 775 (let ((ede-object (ede-toplevel)))
1165 (ede-invoke-method 'project-make-dist))) 776 (ede-invoke-method 'project-make-dist)))
1166 777
1167;;; Customization
1168;;
1169;; Routines for customizing projects and targets.
1170
1171(defvar eieio-ede-old-variables nil
1172 "The old variables for a project.")
1173
1174(defalias 'customize-project 'ede-customize-project)
1175(defun ede-customize-project (&optional group)
1176 "Edit fields of the current project through EIEIO & Custom.
1177Optional GROUP specifies the subgroup of slots to customize."
1178 (interactive "P")
1179 (require 'eieio-custom)
1180 (let* ((ov (oref (ede-current-project) local-variables))
1181 (cp (ede-current-project))
1182 (group (if group (eieio-read-customization-group cp))))
1183 (eieio-customize-object cp group)
1184 (make-local-variable 'eieio-ede-old-variables)
1185 (setq eieio-ede-old-variables ov)))
1186
1187(defalias 'customize-target 'ede-customize-current-target)
1188(defun ede-customize-current-target(&optional group)
1189 "Edit fields of the current target through EIEIO & Custom.
1190Optional argument OBJ is the target object to customize.
1191Optional argument GROUP is the slot group to display."
1192 (interactive "P")
1193 (require 'eieio-custom)
1194 (if (not (obj-of-class-p ede-object ede-target))
1195 (error "Current file is not part of a target"))
1196 (let ((group (if group (eieio-read-customization-group ede-object))))
1197 (ede-customize-target ede-object group)))
1198
1199(defun ede-customize-target (obj group)
1200 "Edit fields of the current target through EIEIO & Custom.
1201Optional argument OBJ is the target object to customize.
1202Optional argument GROUP is the slot group to display."
1203 (require 'eieio-custom)
1204 (if (and obj (not (obj-of-class-p obj ede-target)))
1205 (error "No logical target to customize"))
1206 (eieio-customize-object obj (or group 'default)))
1207;;; Target Sorting
1208;;
1209;; Target order can be important, but custom doesn't support a way
1210;; to resort items in a list. This function by David Engster allows
1211;; targets to be re-arranged.
1212
1213(defvar ede-project-sort-targets-order nil
1214 "Variable for tracking target order in `ede-project-sort-targets'.")
1215
1216(defun ede-project-sort-targets ()
1217 "Create a custom-like buffer for sorting targets of current project."
1218 (interactive)
1219 (let ((proj (ede-current-project))
1220 (count 1)
1221 current order)
1222 (switch-to-buffer (get-buffer-create "*EDE sort targets*"))
1223 (erase-buffer)
1224 (setq ede-object-project proj)
1225 (widget-create 'push-button
1226 :notify (lambda (&rest ignore)
1227 (let ((targets (oref ede-object-project targets))
1228 cur newtargets)
1229 (while (setq cur (pop ede-project-sort-targets-order))
1230 (setq newtargets (append newtargets
1231 (list (nth cur targets)))))
1232 (oset ede-object-project targets newtargets))
1233 (ede-commit-project ede-object-project)
1234 (kill-buffer))
1235 " Accept ")
1236 (widget-insert " ")
1237 (widget-create 'push-button
1238 :notify (lambda (&rest ignore)
1239 (kill-buffer))
1240 " Cancel ")
1241 (widget-insert "\n\n")
1242 (setq ede-project-sort-targets-order nil)
1243 (mapc (lambda (x)
1244 (add-to-ordered-list
1245 'ede-project-sort-targets-order
1246 x x))
1247 (number-sequence 0 (1- (length (oref proj targets)))))
1248 (ede-project-sort-targets-list)
1249 (use-local-map widget-keymap)
1250 (widget-setup)
1251 (goto-char (point-min))))
1252
1253(defun ede-project-sort-targets-list ()
1254 "Sort the target list while using `ede-project-sort-targets'."
1255 (save-excursion
1256 (let ((count 0)
1257 (targets (oref ede-object-project targets))
1258 (inhibit-read-only t)
1259 (inhibit-modification-hooks t))
1260 (goto-char (point-min))
1261 (forward-line 2)
1262 (delete-region (point) (point-max))
1263 (while (< count (length targets))
1264 (if (> count 0)
1265 (widget-create 'push-button
1266 :notify `(lambda (&rest ignore)
1267 (let ((cur ede-project-sort-targets-order))
1268 (add-to-ordered-list
1269 'ede-project-sort-targets-order
1270 (nth ,count cur)
1271 (1- ,count))
1272 (add-to-ordered-list
1273 'ede-project-sort-targets-order
1274 (nth (1- ,count) cur) ,count))
1275 (ede-project-sort-targets-list))
1276 " Up ")
1277 (widget-insert " "))
1278 (if (< count (1- (length targets)))
1279 (widget-create 'push-button
1280 :notify `(lambda (&rest ignore)
1281 (let ((cur ede-project-sort-targets-order))
1282 (add-to-ordered-list
1283 'ede-project-sort-targets-order
1284 (nth ,count cur) (1+ ,count))
1285 (add-to-ordered-list
1286 'ede-project-sort-targets-order
1287 (nth (1+ ,count) cur) ,count))
1288 (ede-project-sort-targets-list))
1289 " Down ")
1290 (widget-insert " "))
1291 (widget-insert (concat " " (number-to-string (1+ count)) ".: "
1292 (oref (nth (nth count ede-project-sort-targets-order)
1293 targets) name) "\n"))
1294 (setq count (1+ count))))))
1295
1296;;; Customization hooks
1297;;
1298;; These hooks are used when finishing up a customization.
1299(defmethod eieio-done-customizing ((proj ede-project))
1300 "Call this when a user finishes customizing PROJ."
1301 (let ((ov eieio-ede-old-variables)
1302 (nv (oref proj local-variables)))
1303 (setq eieio-ede-old-variables nil)
1304 (while ov
1305 (if (not (assoc (car (car ov)) nv))
1306 (save-excursion
1307 (mapc (lambda (b)
1308 (set-buffer b)
1309 (kill-local-variable (car (car ov))))
1310 (ede-project-buffers proj))))
1311 (setq ov (cdr ov)))
1312 (mapc (lambda (b) (ede-set-project-variables proj b))
1313 (ede-project-buffers proj))))
1314
1315(defmethod eieio-done-customizing ((target ede-target))
1316 "Call this when a user finishes customizing TARGET."
1317 nil)
1318
1319(defmethod ede-commit-project ((proj ede-project))
1320 "Commit any change to PROJ to its file."
1321 nil
1322 )
1323
1324
1325;;; EDE project placeholder methods
1326;;
1327(defmethod ede-project-force-load ((this ede-project-placeholder))
1328 "Make sure the placeholder THIS is replaced with the real thing.
1329Return the new object created in its place."
1330 this
1331 )
1332
1333 778
1334;;; EDE project target baseline methods. 779;;; EDE project target baseline methods.
1335;; 780;;
@@ -1342,9 +787,9 @@ Return the new object created in its place."
1342;; methods based on those below. 787;; methods based on those below.
1343 788
1344(defmethod project-interactive-select-target ((this ede-project-placeholder) prompt) 789(defmethod project-interactive-select-target ((this ede-project-placeholder) prompt)
1345 ; checkdoc-params: (prompt) 790 ; checkdoc-params: (prompt)
1346 "Make sure placeholder THIS is replaced with the real thing, and pass through." 791 "Make sure placeholder THIS is replaced with the real thing, and pass through."
1347 (project-interactive-select-target (ede-project-force-load this) prompt)) 792 (project-interactive-select-target this prompt))
1348 793
1349(defmethod project-interactive-select-target ((this ede-project) prompt) 794(defmethod project-interactive-select-target ((this ede-project) prompt)
1350 "Interactively query for a target that exists in project THIS. 795 "Interactively query for a target that exists in project THIS.
@@ -1353,9 +798,9 @@ Argument PROMPT is the prompt to use when querying the user for a target."
1353 (cdr (assoc (completing-read prompt ob nil t) ob)))) 798 (cdr (assoc (completing-read prompt ob nil t) ob))))
1354 799
1355(defmethod project-add-file ((this ede-project-placeholder) file) 800(defmethod project-add-file ((this ede-project-placeholder) file)
1356 ; checkdoc-params: (file) 801 ; checkdoc-params: (file)
1357 "Make sure placeholder THIS is replaced with the real thing, and pass through." 802 "Make sure placeholder THIS is replaced with the real thing, and pass through."
1358 (project-add-file (ede-project-force-load this) file)) 803 (project-add-file this file))
1359 804
1360(defmethod project-add-file ((ot ede-target) file) 805(defmethod project-add-file ((ot ede-target) file)
1361 "Add the current buffer into project project target OT. 806 "Add the current buffer into project project target OT.
@@ -1412,132 +857,6 @@ Argument COMMAND is the command to use for compiling the target."
1412(defmethod project-rescan ((this ede-project)) 857(defmethod project-rescan ((this ede-project))
1413 "Rescan the EDE proj project THIS." 858 "Rescan the EDE proj project THIS."
1414 (error "Rescanning a project is not supported by %s" (object-name this))) 859 (error "Rescanning a project is not supported by %s" (object-name this)))
1415
1416;;; Default methods for EDE classes
1417;;
1418;; These are methods which you might want to override, but there is
1419;; no need to in most situations because they are either a) simple, or
1420;; b) cosmetic.
1421
1422(defmethod ede-name ((this ede-target))
1423 "Return the name of THIS target."
1424 (oref this name))
1425
1426(defmethod ede-target-name ((this ede-target))
1427 "Return the name of THIS target, suitable for make or debug style commands."
1428 (oref this name))
1429
1430(defmethod ede-name ((this ede-project))
1431 "Return a short-name for THIS project file.
1432Do this by extracting the lowest directory name."
1433 (oref this name))
1434
1435(defmethod ede-description ((this ede-project))
1436 "Return a description suitable for the minibuffer about THIS."
1437 (format "Project %s: %d subprojects, %d targets."
1438 (ede-name this) (length (oref this subproj))
1439 (length (oref this targets))))
1440
1441(defmethod ede-description ((this ede-target))
1442 "Return a description suitable for the minibuffer about THIS."
1443 (format "Target %s: with %d source files."
1444 (ede-name this) (length (oref this source))))
1445
1446(defmethod ede-want-file-p ((this ede-target) file)
1447 "Return non-nil if THIS target wants FILE."
1448 ;; By default, all targets reference the source object, and let it decide.
1449 (let ((src (ede-target-sourcecode this)))
1450 (while (and src (not (ede-want-file-p (car src) file)))
1451 (setq src (cdr src)))
1452 src))
1453
1454(defmethod ede-want-file-source-p ((this ede-target) file)
1455 "Return non-nil if THIS target wants FILE."
1456 ;; By default, all targets reference the source object, and let it decide.
1457 (let ((src (ede-target-sourcecode this)))
1458 (while (and src (not (ede-want-file-source-p (car src) file)))
1459 (setq src (cdr src)))
1460 src))
1461
1462(defun ede-header-file ()
1463 "Return the header file for the current buffer.
1464Not all buffers need headers, so return nil if no applicable."
1465 (if ede-object
1466 (ede-buffer-header-file ede-object (current-buffer))
1467 nil))
1468
1469(defmethod ede-buffer-header-file ((this ede-project) buffer)
1470 "Return nil, projects don't have header files."
1471 nil)
1472
1473(defmethod ede-buffer-header-file ((this ede-target) buffer)
1474 "There are no default header files in EDE.
1475Do a quick check to see if there is a Header tag in this buffer."
1476 (with-current-buffer buffer
1477 (if (re-search-forward "::Header:: \\([a-zA-Z0-9.]+\\)" nil t)
1478 (buffer-substring-no-properties (match-beginning 1)
1479 (match-end 1))
1480 (let ((src (ede-target-sourcecode this))
1481 (found nil))
1482 (while (and src (not found))
1483 (setq found (ede-buffer-header-file (car src) (buffer-file-name))
1484 src (cdr src)))
1485 found))))
1486
1487(defun ede-documentation-files ()
1488 "Return the documentation files for the current buffer.
1489Not all buffers need documentations, so return nil if no applicable.
1490Some projects may have multiple documentation files, so return a list."
1491 (if ede-object
1492 (ede-buffer-documentation-files ede-object (current-buffer))
1493 nil))
1494
1495(defmethod ede-buffer-documentation-files ((this ede-project) buffer)
1496 "Return all documentation in project THIS based on BUFFER."
1497 ;; Find the info node.
1498 (ede-documentation this))
1499
1500(defmethod ede-buffer-documentation-files ((this ede-target) buffer)
1501 "Check for some documentation files for THIS.
1502Also do a quick check to see if there is a Documentation tag in this BUFFER."
1503 (with-current-buffer buffer
1504 (if (re-search-forward "::Documentation:: \\([a-zA-Z0-9.]+\\)" nil t)
1505 (buffer-substring-no-properties (match-beginning 1)
1506 (match-end 1))
1507 ;; Check the master project
1508 (let ((cp (ede-toplevel)))
1509 (ede-buffer-documentation-files cp (current-buffer))))))
1510
1511(defmethod ede-documentation ((this ede-project))
1512 "Return a list of files that provide documentation.
1513Documentation is not for object THIS, but is provided by THIS for other
1514files in the project."
1515 (let ((targ (oref this targets))
1516 (proj (oref this subproj))
1517 (found nil))
1518 (while targ
1519 (setq found (append (ede-documentation (car targ)) found)
1520 targ (cdr targ)))
1521 (while proj
1522 (setq found (append (ede-documentation (car proj)) found)
1523 proj (cdr proj)))
1524 found))
1525
1526(defmethod ede-documentation ((this ede-target))
1527 "Return a list of files that provide documentation.
1528Documentation is not for object THIS, but is provided by THIS for other
1529files in the project."
1530 nil)
1531
1532(defun ede-html-documentation-files ()
1533 "Return a list of HTML documentation files associated with this project."
1534 (ede-html-documentation (ede-toplevel))
1535 )
1536
1537(defmethod ede-html-documentation ((this ede-project))
1538 "Return a list of HTML files provided by project THIS."
1539
1540 )
1541 860
1542(defun ede-ecb-project-paths () 861(defun ede-ecb-project-paths ()
1543 "Return a list of all paths for all active EDE projects. 862 "Return a list of all paths for all active EDE projects.
@@ -1549,24 +868,8 @@ This functions is meant for use with ECB."
1549 d) 868 d)
1550 p (cdr p))) 869 p (cdr p)))
1551 d)) 870 d))
1552 871
1553;;; EDE project-autoload methods 872;;; PROJECT LOADING/TRACKING
1554;;
1555(defmethod ede-dir-to-projectfile ((this ede-project-autoload) dir)
1556 "Return a full file name of project THIS found in DIR.
1557Return nil if the project file does not exist."
1558 (let* ((d (file-name-as-directory dir))
1559 (root (ede-project-root-directory this d))
1560 (pf (oref this proj-file))
1561 (f (cond ((stringp pf)
1562 (expand-file-name pf (or root d)))
1563 ((and (symbolp pf) (fboundp pf))
1564 (funcall pf (or root d)))))
1565 )
1566 (when (and f (file-exists-p f))
1567 f)))
1568
1569;;; EDE basic functions
1570;; 873;;
1571(defun ede-add-project-to-global-list (proj) 874(defun ede-add-project-to-global-list (proj)
1572 "Add the project PROJ to the master list of projects. 875 "Add the project PROJ to the master list of projects.
@@ -1602,7 +905,7 @@ Optional ROOTRETURN will return the root project for DIR."
1602 (if p (ede-load-project-file p) 905 (if p (ede-load-project-file p)
1603 nil) 906 nil)
1604 ;; recomment as we go 907 ;; recomment as we go
1605 ;nil 908 ;;nil
1606 )) 909 ))
1607 ;; Do nothing if we are buiding an EDE project already 910 ;; Do nothing if we are buiding an EDE project already
1608 (ede-constructing 911 (ede-constructing
@@ -1611,7 +914,7 @@ Optional ROOTRETURN will return the root project for DIR."
1611 (t 914 (t
1612 (setq toppath (ede-toplevel-project path)) 915 (setq toppath (ede-toplevel-project path))
1613 ;; We found the top-most directory. Check to see if we already 916 ;; We found the top-most directory. Check to see if we already
1614 ;; have an object defining it's project. 917 ;; have an object defining its project.
1615 (setq pfc (ede-directory-project-p toppath t)) 918 (setq pfc (ede-directory-project-p toppath t))
1616 919
1617 ;; See if it's been loaded before 920 ;; See if it's been loaded before
@@ -1619,7 +922,7 @@ Optional ROOTRETURN will return the root project for DIR."
1619 ede-projects)) 922 ede-projects))
1620 (if (not o) 923 (if (not o)
1621 ;; If not, get it now. 924 ;; If not, get it now.
1622 (let ((ede-constructing t)) 925 (let ((ede-constructing pfc))
1623 (setq o (funcall (oref pfc load-type) toppath)) 926 (setq o (funcall (oref pfc load-type) toppath))
1624 (when (not o) 927 (when (not o)
1625 (error "Project type error: :load-type failed to create a project")) 928 (error "Project type error: :load-type failed to create a project"))
@@ -1648,9 +951,14 @@ Optional ROOTRETURN will return the root project for DIR."
1648 (delete (oref found file) ede-project-cache-files))) 951 (delete (oref found file) ede-project-cache-files)))
1649 found))))) 952 found)))))
1650 953
954;;; PROJECT ASSOCIATIONS
955;;
956;; Moving between relative projects. Associating between buffers and
957;; projects.
958
1651(defun ede-parent-project (&optional obj) 959(defun ede-parent-project (&optional obj)
1652 "Return the project belonging to the parent directory. 960 "Return the project belonging to the parent directory.
1653Returns nil if there is no previous directory. 961Return nil if there is no previous directory.
1654Optional argument OBJ is an object to find the parent of." 962Optional argument OBJ is an object to find the parent of."
1655 (let* ((proj (or obj ede-object-project)) ;; Current project. 963 (let* ((proj (or obj ede-object-project)) ;; Current project.
1656 (root (if obj (ede-project-root obj) 964 (root (if obj (ede-project-root obj)
@@ -1700,17 +1008,38 @@ If optional DIR is provided, get the project for DIR instead."
1700 ;; Return what we found. 1008 ;; Return what we found.
1701 ans)) 1009 ans))
1702 1010
1703(defun ede-buffer-object (&optional buffer) 1011(defun ede-buffer-object (&optional buffer projsym)
1704 "Return the target object for BUFFER. 1012 "Return the target object for BUFFER.
1705This function clears cached values and recalculates." 1013This function clears cached values and recalculates.
1014Optional PROJSYM is a symbol, which will be set to the project
1015that contains the target that becomes buffer's object."
1706 (save-excursion 1016 (save-excursion
1707 (if (not buffer) (setq buffer (current-buffer))) 1017 (if (not buffer) (setq buffer (current-buffer)))
1708 (set-buffer buffer) 1018 (set-buffer buffer)
1709 (setq ede-object nil) 1019 (setq ede-object nil)
1710 (let ((po (ede-current-project))) 1020 (let* ((localpo (ede-current-project))
1711 (if po (setq ede-object (ede-find-target po buffer)))) 1021 (po localpo)
1712 (if (= (length ede-object) 1) 1022 (top (ede-toplevel po)))
1713 (setq ede-object (car ede-object))) 1023 (if po (setq ede-object (ede-find-target po buffer)))
1024 ;; If we get nothing, go with the backup plan of slowly
1025 ;; looping upward
1026 (while (and (not ede-object) (not (eq po top)))
1027 (setq po (ede-parent-project po))
1028 (if po (setq ede-object (ede-find-target po buffer))))
1029 ;; Filter down to 1 project if there are dups.
1030 (if (= (length ede-object) 1)
1031 (setq ede-object (car ede-object)))
1032 ;; Track the project, if needed.
1033 (when (and projsym (symbolp projsym))
1034 (if ede-object
1035 ;; If we found a target, then PO is the
1036 ;; project to use.
1037 (set projsym po)
1038 ;; If there is no ede-object, then the projsym
1039 ;; is whichever part of the project is most local.
1040 (set projsym localpo))
1041 ))
1042 ;; Return our findings.
1714 ede-object)) 1043 ede-object))
1715 1044
1716(defmethod ede-target-in-project-p ((proj ede-project) target) 1045(defmethod ede-target-in-project-p ((proj ede-project) target)
@@ -1737,14 +1066,6 @@ could become slow in time."
1737 projs (cdr projs))) 1066 projs (cdr projs)))
1738 ans)) 1067 ans))
1739 1068
1740(defun ede-maybe-checkout (&optional buffer)
1741 "Check BUFFER out of VC if necessary."
1742 (save-excursion
1743 (if buffer (set-buffer buffer))
1744 (if (and buffer-read-only vc-mode
1745 (y-or-n-p "Checkout Makefile.am from VC? "))
1746 (vc-toggle-read-only))))
1747
1748(defmethod ede-find-target ((proj ede-project) buffer) 1069(defmethod ede-find-target ((proj ede-project) buffer)
1749 "Fetch the target in PROJ belonging to BUFFER or nil." 1070 "Fetch the target in PROJ belonging to BUFFER or nil."
1750 (with-current-buffer buffer 1071 (with-current-buffer buffer
@@ -1785,7 +1106,7 @@ This includes buffers controlled by a specific target of PROJECT."
1785 (pl nil)) 1106 (pl nil))
1786 (while bl 1107 (while bl
1787 (with-current-buffer (car bl) 1108 (with-current-buffer (car bl)
1788 (if (and ede-object (eq (ede-current-project) project)) 1109 (if (ede-buffer-belongs-to-project-p)
1789 (setq pl (cons (car bl) pl)))) 1110 (setq pl (cons (car bl) pl))))
1790 (setq bl (cdr bl))) 1111 (setq bl (cdr bl)))
1791 pl)) 1112 pl))
@@ -1856,6 +1177,16 @@ See also `ede-map-subprojects'."
1856Return the first non-nil value returned by PROC." 1177Return the first non-nil value returned by PROC."
1857 (eval (cons 'or (ede-map-targets this proc)))) 1178 (eval (cons 'or (ede-map-targets this proc))))
1858 1179
1180;;; VC Handling
1181;;
1182(defun ede-maybe-checkout (&optional buffer)
1183 "Check BUFFER out of VC if necessary."
1184 (save-excursion
1185 (if buffer (set-buffer buffer))
1186 (if (and buffer-read-only vc-mode
1187 (y-or-n-p "Checkout Makefile.am from VC? "))
1188 (vc-toggle-read-only))))
1189
1859 1190
1860;;; Some language specific methods. 1191;;; Some language specific methods.
1861;; 1192;;
@@ -1912,7 +1243,7 @@ Return the first non-nil value returned by PROC."
1912 (with-current-buffer buffer 1243 (with-current-buffer buffer
1913 (dolist (v (oref project local-variables)) 1244 (dolist (v (oref project local-variables))
1914 (make-local-variable (car v)) 1245 (make-local-variable (car v))
1915 ;; set it's value here? 1246 ;; set its value here?
1916 (set (car v) (cdr v))))) 1247 (set (car v) (cdr v)))))
1917 1248
1918(defun ede-set (variable value &optional proj) 1249(defun ede-set (variable value &optional proj)
@@ -1935,60 +1266,6 @@ is the project to use, instead of `ede-current-project'."
1935 "Commit change to local variables in PROJ." 1266 "Commit change to local variables in PROJ."
1936 nil) 1267 nil)
1937 1268
1938
1939;;; Accessors for more complex types where oref is inappropriate.
1940;;
1941(defmethod ede-target-sourcecode ((this ede-target))
1942 "Return the sourcecode objects which THIS permits."
1943 (let ((sc (oref this sourcetype))
1944 (rs nil))
1945 (while (and (listp sc) sc)
1946 (setq rs (cons (symbol-value (car sc)) rs)
1947 sc (cdr sc)))
1948 rs))
1949
1950
1951;;; Debugging.
1952
1953(defun ede-adebug-project ()
1954 "Run adebug against the current EDE project.
1955Display the results as a debug list."
1956 (interactive)
1957 (require 'data-debug)
1958 (when (ede-current-project)
1959 (data-debug-new-buffer "*Analyzer ADEBUG*")
1960 (data-debug-insert-object-slots (ede-current-project) "")
1961 ))
1962
1963(defun ede-adebug-project-parent ()
1964 "Run adebug against the current EDE parent project.
1965Display the results as a debug list."
1966 (interactive)
1967 (require 'data-debug)
1968 (when (ede-parent-project)
1969 (data-debug-new-buffer "*Analyzer ADEBUG*")
1970 (data-debug-insert-object-slots (ede-parent-project) "")
1971 ))
1972
1973(defun ede-adebug-project-root ()
1974 "Run adebug against the current EDE parent project.
1975Display the results as a debug list."
1976 (interactive)
1977 (require 'data-debug)
1978 (when (ede-toplevel)
1979 (data-debug-new-buffer "*Analyzer ADEBUG*")
1980 (data-debug-insert-object-slots (ede-toplevel) "")
1981 ))
1982
1983;;; Hooks & Autoloads
1984;;
1985;; These let us watch various activities, and respond appropriately.
1986
1987;; (add-hook 'edebug-setup-hook
1988;; (lambda ()
1989;; (def-edebug-spec ede-with-projectfile
1990;; (form def-body))))
1991
1992(provide 'ede) 1269(provide 'ede)
1993 1270
1994;; Include this last because it depends on ede. 1271;; Include this last because it depends on ede.
diff --git a/lisp/cedet/ede/auto.el b/lisp/cedet/ede/auto.el
new file mode 100644
index 00000000000..52e0e3c3cf3
--- /dev/null
+++ b/lisp/cedet/ede/auto.el
@@ -0,0 +1,128 @@
1;;; ede/auto.el --- Autoload features 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;; EDE Autoloads are a way to refer to different project types without
25;; loading those projects into Emacs.
26;;
27;; These routines are used to detect a project in a filesystem before
28;; handing over control to the usual EDE project system.
29
30;;; Code:
31
32(require 'eieio)
33
34(defclass ede-project-autoload ()
35 ((name :initarg :name
36 :documentation "Name of this project type")
37 (file :initarg :file
38 :documentation "The lisp file belonging to this class.")
39 (proj-file :initarg :proj-file
40 :documentation "Name of a project file of this type.")
41 (proj-root :initarg :proj-root
42 :type function
43 :documentation "A function symbol to call for the project root.
44This function takes no arguments, and returns the current directories
45root, if available. Leave blank to use the EDE directory walking
46routine instead.")
47 (initializers :initarg :initializers
48 :initform nil
49 :documentation
50 "Initializers passed to the project object.
51These are used so there can be multiple types of projects
52associated with a single object class, based on the initilizeres used.")
53 (load-type :initarg :load-type
54 :documentation "Fn symbol used to load this project file.")
55 (class-sym :initarg :class-sym
56 :documentation "Symbol representing the project class to use.")
57 (new-p :initarg :new-p
58 :initform t
59 :documentation
60 "Non-nil if this is an option when a user creates a project.")
61 )
62 "Class representing minimal knowledge set to run preliminary EDE functions.
63When more advanced functionality is needed from a project type, that projects
64type is required and the load function used.")
65
66(defvar ede-project-class-files
67 (list
68 (ede-project-autoload "edeproject-makefile"
69 :name "Make" :file 'ede/proj
70 :proj-file "Project.ede"
71 :load-type 'ede-proj-load
72 :class-sym 'ede-proj-project)
73 (ede-project-autoload "edeproject-automake"
74 :name "Automake" :file 'ede/proj
75 :proj-file "Project.ede"
76 :initializers '(:makefile-type Makefile.am)
77 :load-type 'ede-proj-load
78 :class-sym 'ede-proj-project)
79 (ede-project-autoload "automake"
80 :name "automake" :file 'ede/project-am
81 :proj-file "Makefile.am"
82 :load-type 'project-am-load
83 :class-sym 'project-am-makefile
84 :new-p nil))
85 "List of vectors defining how to determine what type of projects exist.")
86
87;;; EDE project-autoload methods
88;;
89(defmethod ede-project-root ((this ede-project-autoload))
90 "If a project knows its root, return it here.
91Allows for one-project-object-for-a-tree type systems."
92 nil)
93
94(defmethod ede-project-root-directory ((this ede-project-autoload)
95 &optional file)
96 "If a project knows its root, return it here.
97Allows for one-project-object-for-a-tree type systems.
98Optional FILE is the file to test. If there is no FILE, use
99the current buffer."
100 (when (not file)
101 (setq file default-directory))
102 (when (slot-boundp this :proj-root)
103 (let ((rootfcn (oref this proj-root)))
104 (when rootfcn
105 (condition-case nil
106 (funcall rootfcn file)
107 (error
108 (funcall rootfcn)))
109 ))))
110
111(defmethod ede-dir-to-projectfile ((this ede-project-autoload) dir)
112 "Return a full file name of project THIS found in DIR.
113Return nil if the project file does not exist."
114 (let* ((d (file-name-as-directory dir))
115 (root (ede-project-root-directory this d))
116 (pf (oref this proj-file))
117 (f (cond ((stringp pf)
118 (expand-file-name pf (or root d)))
119 ((and (symbolp pf) (fboundp pf))
120 (funcall pf (or root d)))))
121 )
122 (when (and f (file-exists-p f))
123 f)))
124
125
126(provide 'ede/auto)
127
128;;; ede/auto.el ends here
diff --git a/lisp/cedet/ede/autoconf-edit.el b/lisp/cedet/ede/autoconf-edit.el
index 3973fc7f6af..df976bf17af 100644
--- a/lisp/cedet/ede/autoconf-edit.el
+++ b/lisp/cedet/ede/autoconf-edit.el
@@ -27,20 +27,8 @@
27 27
28;;; Code: 28;;; Code:
29(require 'autoconf) 29(require 'autoconf)
30 30(declare-function ede-srecode-setup "ede/srecode")
31(defvar autoconf-new-automake-string 31(declare-function ede-srecode-insert "ede/srecode")
32 "dnl Process this file with autoconf to produce a configure script
33
34AC_INIT(%s)
35AM_INIT_AUTOMAKE([%s], 0)
36AM_CONFIG_HEADER(config.h)
37
38dnl End the configure script.
39AC_OUTPUT(Makefile, [date > stamp-h] )\n"
40 "This string is used to initialize a new configure.in.
41The default is designed to be used with automake.
42The first %s will be filled with the test file.
43The second %s will be filled with the program name.")
44 32
45(defun autoconf-new-program (rootdir program testfile) 33(defun autoconf-new-program (rootdir program testfile)
46 "Initialize a new configure.in in ROOTDIR for PROGRAM using TESTFILE. 34 "Initialize a new configure.in in ROOTDIR for PROGRAM using TESTFILE.
@@ -49,6 +37,7 @@ PROGRAM is the program to be configured.
49TESTFILE is the file used with AC_INIT. 37TESTFILE is the file used with AC_INIT.
50configure the initial configure script using `autoconf-new-automake-string'" 38configure the initial configure script using `autoconf-new-automake-string'"
51 (interactive "DRoot Dir: \nsProgram: \nsTest File: ") 39 (interactive "DRoot Dir: \nsProgram: \nsTest File: ")
40 (require 'ede/srecode)
52 (if (bufferp rootdir) 41 (if (bufferp rootdir)
53 (set-buffer rootdir) 42 (set-buffer rootdir)
54 (let ((cf1 (expand-file-name "configure.in" rootdir)) 43 (let ((cf1 (expand-file-name "configure.in" rootdir))
@@ -62,7 +51,12 @@ configure the initial configure script using `autoconf-new-automake-string'"
62 (find-file cf2))) 51 (find-file cf2)))
63 ;; Note, we only ask about overwrite if a string/path is specified. 52 ;; Note, we only ask about overwrite if a string/path is specified.
64 (erase-buffer) 53 (erase-buffer)
65 (insert (format autoconf-new-automake-string testfile program))) 54 (ede-srecode-setup)
55 (ede-srecode-insert
56 "file:ede-empty"
57 "TEST_FILE" testfile
58 "PROGRAM" program)
59 )
66 60
67(defvar autoconf-preferred-macro-order 61(defvar autoconf-preferred-macro-order
68 '("AC_INIT" 62 '("AC_INIT"
@@ -151,42 +145,44 @@ From the autoconf manual:
151 (beginning-of-line) 145 (beginning-of-line)
152 (looking-at (concat "\\(A[CM]_" macro "\\|" macro "\\)")))) 146 (looking-at (concat "\\(A[CM]_" macro "\\|" macro "\\)"))))
153 147
154(defun autoconf-find-last-macro (macro) 148(defun autoconf-find-last-macro (macro &optional ignore-bol)
155 "Move to the last occurrence of MACRO in FILE, and return that point. 149 "Move to the last occurrence of MACRO in FILE, and return that point.
156The last macro is usually the one in which we would like to insert more 150The last macro is usually the one in which we would like to insert more
157items such as CHECK_HEADERS." 151items such as CHECK_HEADERS."
158 (let ((op (point))) 152 (let ((op (point)) (atbol (if ignore-bol "" "^")))
159 (goto-char (point-max)) 153 (goto-char (point-max))
160 (if (re-search-backward (concat "^" (regexp-quote macro) "\\s-*\\((\\|$\\)") nil t) 154 (if (re-search-backward (concat atbol (regexp-quote macro) "\\s-*\\((\\|$\\)") nil t)
161 (progn 155 (progn
162 (beginning-of-line) 156 (unless ignore-bol (beginning-of-line))
163 (point)) 157 (point))
164 (goto-char op) 158 (goto-char op)
165 nil))) 159 nil)))
166 160
167(defun autoconf-parameter-strip (param) 161(defun autoconf-parameter-strip (param)
168 "Strip the parameter PARAM of whitespace and miscellaneous characters." 162 "Strip the parameter PARAM of whitespace and miscellaneous characters."
169 (when (string-match "^\\s-*\\[?\\s-*" param) 163 ;; force greedy match for \n.
164 (when (string-match "\\`\n*\\s-*\\[?\\s-*" param)
170 (setq param (substring param (match-end 0)))) 165 (setq param (substring param (match-end 0))))
171 (when (string-match "\\s-*\\]?\\s-*$" param) 166 (when (string-match "\\s-*\\]?\\s-*\\'" param)
172 (setq param (substring param 0 (match-beginning 0)))) 167 (setq param (substring param 0 (match-beginning 0))))
173 param) 168 param)
174 169
175(defun autoconf-parameters-for-macro (macro) 170(defun autoconf-parameters-for-macro (macro &optional ignore-bol ignore-case)
176 "Retrieve the parameters to MACRO. 171 "Retrieve the parameters to MACRO.
177Returns a list of the arguments passed into MACRO as strings." 172Returns a list of the arguments passed into MACRO as strings."
178 (save-excursion 173 (let ((case-fold-search ignore-case))
179 (when (autoconf-find-last-macro macro) 174 (save-excursion
180 (forward-sexp 1) 175 (when (autoconf-find-last-macro macro ignore-bol)
181 (mapcar 176 (forward-sexp 1)
182 #'autoconf-parameter-strip 177 (mapcar
183 (when (looking-at "(") 178 #'autoconf-parameter-strip
184 (let* ((start (+ (point) 1)) 179 (when (looking-at "(")
185 (end (save-excursion 180 (let* ((start (+ (point) 1))
186 (forward-sexp 1) 181 (end (save-excursion
187 (- (point) 1))) 182 (forward-sexp 1)
188 (ans (buffer-substring-no-properties start end))) 183 (- (point) 1)))
189 (split-string ans "," t))))))) 184 (ans (buffer-substring-no-properties start end)))
185 (split-string ans "," t))))))))
190 186
191(defun autoconf-position-for-macro (macro) 187(defun autoconf-position-for-macro (macro)
192 "Position the cursor where a new MACRO could be inserted. 188 "Position the cursor where a new MACRO could be inserted.
diff --git a/lisp/cedet/ede/base.el b/lisp/cedet/ede/base.el
new file mode 100644
index 00000000000..f1f24ed339f
--- /dev/null
+++ b/lisp/cedet/ede/base.el
@@ -0,0 +1,636 @@
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.
63Relative 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.
80These files are checked for a version string whenever the EDE version
81of the master project is changed. When strings are found, the version
82previously 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.
89This is used to match target objects with the compilers they can use, and
90which 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.
107Targets, as with 'Make', is an entity that will manage a file set
108and knows how to compile or otherwise transform those files into some
109other 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.
145Projects placeholders will be stored in a user specific location
146and 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.
164For 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.
180This 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.
196This 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.
204For remote locations use a path compatible with ange-ftp or EFS.
205You 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.
213This file can be relative to slot `web-site-directory'.
214This 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.
223This FTP site should be in Emacs form, as needed by `ange-ftp', but can
224also 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.
233This FTP site should be in Emacs form as needed by `ange-ftp'.
234If 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.
242Individual target/project types can form associations between a configuration,
243and 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.
281All 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.
405If PARENT is specified, then be relative to the PARENT project.
406Specifying 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.
436Do 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.
459Not 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.
470Do 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.
484Not all buffers need documentations, so return nil if no applicable.
485Some 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.
497Also 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.
508Documentation is not for object THIS, but is provided by THIS for other
509files 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.
523Documentation is not for object THIS, but is provided by THIS for other
524files 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.
572Display 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.
582Display 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.
592Display 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.
609Optional argument SUBPROJ indicates a subproject to start from
610instead 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
diff --git a/lisp/cedet/ede/cpp-root.el b/lisp/cedet/ede/cpp-root.el
index cae4d090a39..5ef3323cfd5 100644
--- a/lisp/cedet/ede/cpp-root.el
+++ b/lisp/cedet/ede/cpp-root.el
@@ -237,6 +237,18 @@ ROOTPROJ is nil, since there is only one project."
237 ;; Snoop through our master list. 237 ;; Snoop through our master list.
238 (ede-cpp-root-file-existing dir)) 238 (ede-cpp-root-file-existing dir))
239 239
240;;;###autoload
241(add-to-list 'ede-project-class-files
242 (ede-project-autoload "cpp-root"
243 :name "CPP ROOT"
244 :file 'ede-cpp-root
245 :proj-file 'ede-cpp-root-project-file-for-dir
246 :proj-root 'ede-cpp-root-project-root
247 :load-type 'ede-cpp-root-load
248 :class-sym 'ede-cpp-root
249 :new-p nil)
250 t)
251
240;;; CLASSES 252;;; CLASSES
241;; 253;;
242;; EDE sets up projects with two kinds of objects. 254;; EDE sets up projects with two kinds of objects.
@@ -504,6 +516,21 @@ Also set up the lexical preprocessor map."
504 "Get the pre-processor map for project THIS." 516 "Get the pre-processor map for project THIS."
505 (ede-preprocessor-map (ede-target-parent this))) 517 (ede-preprocessor-map (ede-target-parent this)))
506 518
519;;; Quick Hack
520(defun ede-create-lots-of-projects-under-dir (dir projfile &rest attributes)
521 "Create a bunch of projects under directory DIR.
522PROJFILE is a file name sans directory that indicates a subdirectory
523is a project directory.
524Generic ATTRIBUTES, such as :include-path can be added.
525Note: This needs some work."
526 (let ((files (directory-files dir t)))
527 (dolist (F files)
528 (if (file-exists-p (expand-file-name projfile F))
529 `(ede-cpp-root-project (file-name-nondirectory F)
530 :name (file-name-nondirectory F)
531 :file (expand-file-name projfile F)
532 attributes)))))
533
507(provide 'ede/cpp-root) 534(provide 'ede/cpp-root)
508 535
509;; Local variables: 536;; Local variables:
diff --git a/lisp/cedet/ede/custom.el b/lisp/cedet/ede/custom.el
new file mode 100644
index 00000000000..d823e015840
--- /dev/null
+++ b/lisp/cedet/ede/custom.el
@@ -0,0 +1,215 @@
1;;; ede.el --- customization of EDE projects.
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;; Customization commands/hooks for EDE.
25;;
26;; EIEIO supports customizing objects, and EDE uses this to allow
27;; users to change basic settings in their projects.
28;;
29
30;;; Code:
31;;; Customization
32;;
33;; Routines for customizing projects and targets.
34
35(require 'ede)
36(eval-when-compile (require 'eieio-custom))
37
38(defvar eieio-ede-old-variables nil
39 "The old variables for a project.")
40
41;;; Customization Commands
42;;
43;; These commands initialize custoization of EDE control objects.
44
45;;;###autoload
46(defun ede-customize-project ()
47 "Edit fields of the current project through EIEIO & Custom."
48 (interactive)
49 (require 'eieio-custom)
50 (let* ((ov (oref (ede-current-project) local-variables))
51 (cp (ede-current-project)))
52 (ede-customize cp)
53 (make-local-variable 'eieio-ede-old-variables)
54 (setq eieio-ede-old-variables ov)))
55
56;;;###autoload
57(defalias 'customize-project 'ede-customize-project)
58
59;;;###autoload
60(defun ede-customize-current-target()
61 "Edit fields of the current target through EIEIO & Custom."
62 (interactive)
63 (require 'eieio-custom)
64 (if (not (obj-of-class-p ede-object ede-target))
65 (error "Current file is not part of a target"))
66 (ede-customize-target ede-object))
67
68;;;###autoload
69(defalias 'customize-target 'ede-customize-current-target)
70
71(defun ede-customize-target (obj)
72 "Edit fields of the current target through EIEIO & Custom.
73OBJ is the target object to customize."
74 (require 'eieio-custom)
75 (if (and obj (not (obj-of-class-p obj ede-target)))
76 (error "No logical target to customize"))
77 (ede-customize obj))
78
79(defmethod ede-customize ((proj ede-project))
80 "Customize the EDE project PROJ."
81 (eieio-customize-object proj 'default))
82
83(defmethod ede-customize ((target ede-target))
84 "Customize the EDE TARGET."
85 (eieio-customize-object target 'default))
86
87;;; Target Sorting
88;;
89;; Target order can be important, but custom doesn't support a way
90;; to resort items in a list. This function by David Engster allows
91;; targets to be re-arranged.
92
93(defvar ede-project-sort-targets-order nil
94 "Variable for tracking target order in `ede-project-sort-targets'.")
95
96;;;###autoload
97(defun ede-project-sort-targets ()
98 "Create a custom-like buffer for sorting targets of current project."
99 (interactive)
100 (let ((proj (ede-current-project))
101 (count 1)
102 current order)
103 (switch-to-buffer (get-buffer-create "*EDE sort targets*"))
104 (erase-buffer)
105 (setq ede-object-project proj)
106 (widget-create 'push-button
107 :notify (lambda (&rest ignore)
108 (let ((targets (oref ede-object-project targets))
109 cur newtargets)
110 (while (setq cur (pop ede-project-sort-targets-order))
111 (setq newtargets (append newtargets
112 (list (nth cur targets)))))
113 (oset ede-object-project targets newtargets))
114 (ede-commit-project ede-object-project)
115 (kill-buffer))
116 " Accept ")
117 (widget-insert " ")
118 (widget-create 'push-button
119 :notify (lambda (&rest ignore)
120 (kill-buffer))
121 " Cancel ")
122 (widget-insert "\n\n")
123 (setq ede-project-sort-targets-order nil)
124 (mapc (lambda (x)
125 (add-to-ordered-list
126 'ede-project-sort-targets-order
127 x x))
128 (number-sequence 0 (1- (length (oref proj targets)))))
129 (ede-project-sort-targets-list)
130 (use-local-map widget-keymap)
131 (widget-setup)
132 (goto-char (point-min))))
133
134(defun ede-project-sort-targets-list ()
135 "Sort the target list while using `ede-project-sort-targets'."
136 (save-excursion
137 (let ((count 0)
138 (targets (oref ede-object-project targets))
139 (inhibit-read-only t)
140 (inhibit-modification-hooks t))
141 (goto-char (point-min))
142 (forward-line 2)
143 (delete-region (point) (point-max))
144 (while (< count (length targets))
145 (if (> count 0)
146 (widget-create 'push-button
147 :notify `(lambda (&rest ignore)
148 (let ((cur ede-project-sort-targets-order))
149 (add-to-ordered-list
150 'ede-project-sort-targets-order
151 (nth ,count cur)
152 (1- ,count))
153 (add-to-ordered-list
154 'ede-project-sort-targets-order
155 (nth (1- ,count) cur) ,count))
156 (ede-project-sort-targets-list))
157 " Up ")
158 (widget-insert " "))
159 (if (< count (1- (length targets)))
160 (widget-create 'push-button
161 :notify `(lambda (&rest ignore)
162 (let ((cur ede-project-sort-targets-order))
163 (add-to-ordered-list
164 'ede-project-sort-targets-order
165 (nth ,count cur) (1+ ,count))
166 (add-to-ordered-list
167 'ede-project-sort-targets-order
168 (nth (1+ ,count) cur) ,count))
169 (ede-project-sort-targets-list))
170 " Down ")
171 (widget-insert " "))
172 (widget-insert (concat " " (number-to-string (1+ count)) ".: "
173 (oref (nth (nth count ede-project-sort-targets-order)
174 targets) name) "\n"))
175 (setq count (1+ count))))))
176
177;;; Customization hooks
178;;
179;; These hooks are used when finishing up a customization.
180(defmethod eieio-done-customizing ((proj ede-project))
181 "Call this when a user finishes customizing PROJ."
182 (let ((ov eieio-ede-old-variables)
183 (nv (oref proj local-variables)))
184 (setq eieio-ede-old-variables nil)
185 (while ov
186 (if (not (assoc (car (car ov)) nv))
187 (save-excursion
188 (mapc (lambda (b)
189 (set-buffer b)
190 (kill-local-variable (car (car ov))))
191 (ede-project-buffers proj))))
192 (setq ov (cdr ov)))
193 (mapc (lambda (b) (ede-set-project-variables proj b))
194 (ede-project-buffers proj))))
195
196;; These two methods should be implemented by subclasses of
197;; project and targets in order to account for user specified
198;; changes.
199(defmethod eieio-done-customizing ((target ede-target))
200 "Call this when a user finishes customizing TARGET."
201 nil)
202
203(defmethod ede-commit-project ((proj ede-project))
204 "Commit any change to PROJ to its file."
205 nil
206 )
207
208(provide 'ede/custom)
209
210;; Local variables:
211;; generated-autoload-file: "loaddefs.el"
212;; generated-autoload-load-name: "ede/custom"
213;; End:
214
215;;; ede/custom.el ends here
diff --git a/lisp/cedet/ede/dired.el b/lisp/cedet/ede/dired.el
index ede30287723..b6c5ca7c721 100644
--- a/lisp/cedet/ede/dired.el
+++ b/lisp/cedet/ede/dired.el
@@ -88,7 +88,7 @@ negative, force off."
88 (let ((files (dired-get-marked-files t))) 88 (let ((files (dired-get-marked-files t)))
89 (while files 89 (while files
90 (project-add-file target (car files)) 90 (project-add-file target (car files))
91 ;; Find the buffer for this files, and set it's ede-object 91 ;; Find the buffer for this files, and set its ede-object
92 (if (get-file-buffer (car files)) 92 (if (get-file-buffer (car files))
93 (with-current-buffer (get-file-buffer (car files)) 93 (with-current-buffer (get-file-buffer (car files))
94 (setq ede-object nil) 94 (setq ede-object nil)
diff --git a/lisp/cedet/ede/emacs.el b/lisp/cedet/ede/emacs.el
index 45cbce27409..7038a78f892 100644
--- a/lisp/cedet/ede/emacs.el
+++ b/lisp/cedet/ede/emacs.el
@@ -133,6 +133,18 @@ ROOTPROJ is nil, since there is only one project."
133 ) 133 )
134 ) 134 )
135 135
136;;;###autoload
137(add-to-list 'ede-project-class-files
138 (ede-project-autoload "emacs"
139 :name "EMACS ROOT"
140 :file 'ede-emacs
141 :proj-file "src/emacs.c"
142 :proj-root 'ede-emacs-project-root
143 :load-type 'ede-emacs-load
144 :class-sym 'ede-emacs-project
145 :new-p nil)
146 t)
147
136(defclass ede-emacs-target-c (ede-target) 148(defclass ede-emacs-target-c (ede-target)
137 () 149 ()
138 "EDE Emacs Project target for C code. 150 "EDE Emacs Project target for C code.
@@ -150,7 +162,7 @@ All directories need at least one target.")
150 162
151(defmethod initialize-instance ((this ede-emacs-project) 163(defmethod initialize-instance ((this ede-emacs-project)
152 &rest fields) 164 &rest fields)
153 "Make sure the :file is fully expanded." 165 "Make sure the targets slot is bound."
154 (call-next-method) 166 (call-next-method)
155 (unless (slot-boundp this 'targets) 167 (unless (slot-boundp this 'targets)
156 (oset this :targets nil))) 168 (oset this :targets nil)))
diff --git a/lisp/cedet/ede/files.el b/lisp/cedet/ede/files.el
index 2f86b766158..87145d8c8a1 100644
--- a/lisp/cedet/ede/files.el
+++ b/lisp/cedet/ede/files.el
@@ -38,6 +38,7 @@
38(declare-function ede-locate-file-in-hash "ede/locate") 38(declare-function ede-locate-file-in-hash "ede/locate")
39(declare-function ede-locate-add-file-to-hash "ede/locate") 39(declare-function ede-locate-add-file-to-hash "ede/locate")
40(declare-function ede-locate-file-in-project "ede/locate") 40(declare-function ede-locate-file-in-project "ede/locate")
41(declare-function ede-locate-flush-hash "ede/locate")
41 42
42(defvar ede--disable-inode nil 43(defvar ede--disable-inode nil
43 "Set to 't' to simulate systems w/out inode support.") 44 "Set to 't' to simulate systems w/out inode support.")
@@ -57,44 +58,29 @@ the current EDE project."
57 (ede-project-root-directory (ede-current-project)))) 58 (ede-project-root-directory (ede-current-project))))
58 (find-file fname))) 59 (find-file fname)))
59 60
61(defun ede-flush-project-hash ()
62 "Flush the file locate hash for the current project."
63 (interactive)
64 (require 'ede/locate)
65 (let* ((loc (ede-get-locator-object (ede-current-project))))
66 (ede-locate-flush-hash loc)))
67
60;;; Placeholders for ROOT directory scanning on base objects 68;;; Placeholders for ROOT directory scanning on base objects
61;; 69;;
62(defmethod ede-project-root ((this ede-project-placeholder)) 70(defmethod ede-project-root ((this ede-project-placeholder))
63 "If a project knows it's root, return it here. 71 "If a project knows its root, return it here.
64Allows for one-project-object-for-a-tree type systems." 72Allows for one-project-object-for-a-tree type systems."
65 (oref this rootproject)) 73 (oref this rootproject))
66 74
67(defmethod ede-project-root-directory ((this ede-project-placeholder) 75(defmethod ede-project-root-directory ((this ede-project-placeholder)
68 &optional file) 76 &optional file)
69 "If a project knows it's root, return it here. 77 "If a project knows its root, return it here.
70Allows for one-project-object-for-a-tree type systems. 78Allows for one-project-object-for-a-tree type systems.
71Optional FILE is the file to test. It is ignored in preference 79Optional FILE is the file to test. It is ignored in preference
72of the anchor file for the project." 80of the anchor file for the project."
73 (file-name-directory (expand-file-name (oref this file)))) 81 (file-name-directory (expand-file-name (oref this file))))
74 82
75 83
76(defmethod ede-project-root ((this ede-project-autoload))
77 "If a project knows it's root, return it here.
78Allows for one-project-object-for-a-tree type systems."
79 nil)
80
81(defmethod ede-project-root-directory ((this ede-project-autoload)
82 &optional file)
83 "If a project knows it's root, return it here.
84Allows for one-project-object-for-a-tree type systems.
85Optional FILE is the file to test. If there is no FILE, use
86the current buffer."
87 (when (not file)
88 (setq file default-directory))
89 (when (slot-boundp this :proj-root)
90 (let ((rootfcn (oref this proj-root)))
91 (when rootfcn
92 (condition-case nil
93 (funcall rootfcn file)
94 (error
95 (funcall rootfcn)))
96 ))))
97
98(defmethod ede--project-inode ((proj ede-project-placeholder)) 84(defmethod ede--project-inode ((proj ede-project-placeholder))
99 "Get the inode of the directory project PROJ is in." 85 "Get the inode of the directory project PROJ is in."
100 (if (slot-boundp proj 'dirinode) 86 (if (slot-boundp proj 'dirinode)
@@ -262,27 +248,30 @@ Do this whenever a new project is created, as opposed to loaded."
262(defun ede-directory-project-p (dir &optional force) 248(defun ede-directory-project-p (dir &optional force)
263 "Return a project description object if DIR has a project. 249 "Return a project description object if DIR has a project.
264Optional argument FORCE means to ignore a hash-hit of 'nomatch. 250Optional argument FORCE means to ignore a hash-hit of 'nomatch.
265This depends on an up to date `ede-project-class-files' variable." 251This depends on an up to date `ede-project-class-files' variable.
266 (let* ((dirtest (expand-file-name dir)) 252Any directory that contains the file .ede-ignore will allways
267 (match (ede-directory-project-from-hash dirtest))) 253return nil."
268 (cond 254 (when (not (file-exists-p (expand-file-name ".ede-ignore" dir)))
269 ((and (eq match 'nomatch) (not force)) 255 (let* ((dirtest (expand-file-name dir))
270 nil) 256 (match (ede-directory-project-from-hash dirtest)))
271 ((and match (not (eq match 'nomatch))) 257 (cond
272 match) 258 ((and (eq match 'nomatch) (not force))
273 (t 259 nil)
274 (let ((types ede-project-class-files) 260 ((and match (not (eq match 'nomatch)))
275 (ret nil)) 261 match)
276 ;; Loop over all types, loading in the first type that we find. 262 (t
277 (while (and types (not ret)) 263 (let ((types ede-project-class-files)
278 (if (ede-dir-to-projectfile (car types) dirtest) 264 (ret nil))
279 (progn 265 ;; Loop over all types, loading in the first type that we find.
280 ;; We found one! Require it now since we will need it. 266 (while (and types (not ret))
281 (require (oref (car types) file)) 267 (if (ede-dir-to-projectfile (car types) dirtest)
282 (setq ret (car types)))) 268 (progn
283 (setq types (cdr types))) 269 ;; We found one! Require it now since we will need it.
284 (ede-directory-project-add-description-to-hash dirtest (or ret 'nomatch)) 270 (require (oref (car types) file))
285 ret))))) 271 (setq ret (car types))))
272 (setq types (cdr types)))
273 (ede-directory-project-add-description-to-hash dirtest (or ret 'nomatch))
274 ret))))))
286 275
287;;; TOPLEVEL 276;;; TOPLEVEL
288;; 277;;
@@ -324,7 +313,7 @@ nil is returned if the current directory is not a part of a project."
324 ;; If PROJ didn't know, or there is no PROJ, then 313 ;; If PROJ didn't know, or there is no PROJ, then
325 314
326 ;; Loop up to the topmost project, and then load that single 315 ;; Loop up to the topmost project, and then load that single
327 ;; project, and it's sub projects. When we are done, identify the 316 ;; project, and its sub projects. When we are done, identify the
328 ;; sub-project object belonging to file. 317 ;; sub-project object belonging to file.
329 (while (and (not ans) newpath proj) 318 (while (and (not ans) newpath proj)
330 (setq toppath newpath 319 (setq toppath newpath
@@ -338,24 +327,6 @@ nil is returned if the current directory is not a part of a project."
338 ) 327 )
339 (or ans toppath)))))) 328 (or ans toppath))))))
340 329
341;;; TOPLEVEL PROJECT
342;;
343;; The toplevel project is a way to identify the EDE structure that belongs
344;; to the top of a project.
345
346(defun ede-toplevel (&optional subproj)
347 "Return the ede project which is the root of the current project.
348Optional argument SUBPROJ indicates a subproject to start from
349instead of the current project."
350 (or ede-object-root-project
351 (let* ((cp (or subproj (ede-current-project)))
352 )
353 (or (and cp (ede-project-root cp))
354 (progn
355 (while (ede-parent-project cp)
356 (setq cp (ede-parent-project cp)))
357 cp)))))
358
359;;; DIRECTORY CONVERSION STUFF 330;;; DIRECTORY CONVERSION STUFF
360;; 331;;
361(defmethod ede-convert-path ((this ede-project) path) 332(defmethod ede-convert-path ((this ede-project) path)
@@ -372,11 +343,13 @@ Argument THIS is the project to convert PATH to."
372 (substring fptf (match-end 0)) 343 (substring fptf (match-end 0))
373 (error "Cannot convert relativize path %s" fp)))))) 344 (error "Cannot convert relativize path %s" fp))))))
374 345
375(defmethod ede-convert-path ((this ede-target) path) 346(defmethod ede-convert-path ((this ede-target) path &optional project)
376 "Convert path in a standard way for a given project. 347 "Convert path in a standard way for a given project.
377Default to making it project relative. 348Default to making it project relative.
378Argument THIS is the project to convert PATH to." 349Argument THIS is the project to convert PATH to.
379 (let ((proj (ede-target-parent this))) 350Optional PROJECT is the project that THIS belongs to. Associating
351a target to a project is expensive, so using this can speed things up."
352 (let ((proj (or project (ede-target-parent this))))
380 (if proj 353 (if proj
381 (let ((p (ede-convert-path proj path)) 354 (let ((p (ede-convert-path proj path))
382 (lp (or (oref this path) ""))) 355 (lp (or (oref this path) "")))
@@ -406,7 +379,8 @@ FILENAME should be just a filename which occurs in a directory controlled
406by this project. 379by this project.
407Optional argument FORCE forces the default filename to be provided even if it 380Optional argument FORCE forces the default filename to be provided even if it
408doesn't exist. 381doesn't exist.
409If FORCE equals 'newfile, then the cache is ignored." 382If FORCE equals 'newfile, then the cache is ignored and a new file in THIS
383is returned."
410 (require 'ede/locate) 384 (require 'ede/locate)
411 (let* ((loc (ede-get-locator-object this)) 385 (let* ((loc (ede-get-locator-object this))
412 (ha (ede-locate-file-in-hash loc filename)) 386 (ha (ede-locate-file-in-hash loc filename))
@@ -467,17 +441,8 @@ doesn't exist."
467 (proj (oref this subproj)) 441 (proj (oref this subproj))
468 (found nil)) 442 (found nil))
469 ;; find it Locally. 443 ;; find it Locally.
470 (setq found 444 (setq found (or (ede-expand-filename-local this filename)
471 (cond ((file-exists-p (expand-file-name filename path)) 445 (ede-expand-filename-impl-via-subproj this filename)))
472 (expand-file-name filename path))
473 ((file-exists-p (expand-file-name (concat "include/" filename) path))
474 (expand-file-name (concat "include/" filename) path))
475 (t
476 (while (and (not found) proj)
477 (setq found (when (car proj)
478 (ede-expand-filename (car proj) filename))
479 proj (cdr proj)))
480 found)))
481 ;; Use an external locate tool. 446 ;; Use an external locate tool.
482 (when (not found) 447 (when (not found)
483 (require 'ede/locate) 448 (require 'ede/locate)
@@ -485,6 +450,30 @@ doesn't exist."
485 ;; Return it 450 ;; Return it
486 found)) 451 found))
487 452
453(defmethod ede-expand-filename-local ((this ede-project) filename)
454 "Expand filename locally to project THIS with filesystem tests."
455 (let ((path (ede-project-root-directory this)))
456 (cond ((file-exists-p (expand-file-name filename path))
457 (expand-file-name filename path))
458 ((file-exists-p (expand-file-name (concat "include/" filename) path))
459 (expand-file-name (concat "include/" filename) path)))))
460
461(defmethod ede-expand-filename-impl-via-subproj ((this ede-project) filename)
462 "Return a fully qualified file name based on project THIS.
463FILENAME should be just a filename which occurs in a directory controlled
464by this project."
465 (let ((proj (list (ede-toplevel this)))
466 (found nil))
467 ;; find it Locally.
468 (while (and (not found) proj)
469 (let ((thisproj (car proj)))
470 (setq proj (append (cdr proj) (oref thisproj subproj)))
471 (setq found (when thisproj
472 (ede-expand-filename-local thisproj filename)))
473 ))
474 ;; Return it
475 found))
476
488(defmethod ede-expand-filename ((this ede-target) filename &optional force) 477(defmethod ede-expand-filename ((this ede-target) filename &optional force)
489 "Return a fully qualified file name based on target THIS. 478 "Return a fully qualified file name based on target THIS.
490FILENAME should be a filename which occurs in a directory in which THIS works. 479FILENAME should be a filename which occurs in a directory in which THIS works.
diff --git a/lisp/cedet/ede/generic.el b/lisp/cedet/ede/generic.el
new file mode 100644
index 00000000000..68517f27b6a
--- /dev/null
+++ b/lisp/cedet/ede/generic.el
@@ -0,0 +1,442 @@
1;;; ede/generic.el --- Base Support for generic build systems
2
3;; Copyright (C) 2010 Free Software Foundation, Inc.
4
5;; Author: Eric M. Ludlam <eric@siege-engine.com>
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;; There are a lot of build systems out there, and EDE can't support
25;; them all fully. The ede-generic.el system is the base for
26;; supporting alternate build systems in a simple way, automatically.
27;;
28;; The structure is for the ede-generic baseclass, which is augmented
29;; by simple sub-classes that can be created by users on an as needed
30;; basis. The generic system will have targets for many language
31;; types, and create the targets on an as needed basis. All
32;; sub-project types will recycle the same generic target types.
33;;
34;; The generic target types will only be implemented for languages
35;; where having EDE support actually matters, with a single MISC to
36;; represent anything else.
37;;
38;; TOO MANY PROJECTS DETECTED:
39;;
40;; If enabling ede-generic support starts identifying too many
41;; projects, drop a file called `.ede-ignore' into any directory where
42;; you do not want a project to be.
43;;
44;; Customization:
45;;
46;; Since these projects are all so increadibly generic, a user will
47;; need to configure some aspects of the project by hand. In order to
48;; enable this without configuring the project objects directly (which
49;; are auto-generated) a special ede-generic-confg object is defined to
50;; hold the basics. Generic projects will identify and use these
51;; config files.
52;;
53;; Adding support for new projects:
54;;
55;; To add support to EDE Generic for new project types is very quick.
56;; See the end of this file for examples such as CMake and SCons.
57;;
58;; Support consists of one class for your project, specifying the file
59;; name used by the project system you want to support. It also
60;; should implement th method `ede-generic-setup-configuration' to
61;; prepopulate the configurable portion of the generic project with
62;; build details.
63;;
64;; Lastly, call `ede-generic-new-autoloader' to setup your project so
65;; EDE can use it.
66;;
67;; Adding support for new types of source code:
68;;
69;; Sources of different types are supported with a simple class which
70;; subclasses `ede-generic-target'. The slots `shortname' and
71;; `extension' should be given new initial values.
72;;
73;; Optionally, any target method used by EDE can then be overriden.
74;; The ede-generic-target-c-cpp has some example methods setting up
75;; the pre-processor map and system include path.
76;;
77;; NOTE: It is not necessary to modify ede-generic.el to add any of
78;; the above described support features.
79
80(require 'eieio-opt)
81(require 'ede)
82(require 'semantic/db)
83
84;;; Code:
85;;
86;; Start with the configuration system
87(defclass ede-generic-config (eieio-persistent)
88 ((extension :initform ".ede")
89 (file-header-line :initform ";; EDE Generic Project Configuration")
90 (project :initform nil
91 :documentation
92 "The project this config is bound to.")
93 ;; Generic customizations
94 (build-command :initarg :build-command
95 :initform "make -k"
96 :type string
97 :custom string
98 :group (default build)
99 :documentation
100 "Command used for building this project.")
101 (debug-command :initarg :debug-command
102 :initform "gdb "
103 :type string
104 :custom string
105 :group (default build)
106 :documentation
107 "Command used for debugging this project.")
108 ;; C target customixations
109 (c-include-path :initarg :c-include-path
110 :initform nil
111 :type list
112 :custom (repeat (string :tag "Path"))
113 :group c
114 :documentation
115 "The include path used by C/C++ projects.")
116 (c-preprocessor-table :initarg :c-preprocessor-table
117 :initform nil
118 :type list
119 :custom (repeat (cons (string :tag "Macro")
120 (string :tag "Value")))
121 :group c
122 :documentation
123 "Preprocessor Symbols for this project.")
124 (c-preprocessor-files :initarg :c-preprocessor-files
125 :initform nil
126 :type list
127 :custom (repeat (string :tag "Include File")))
128 )
129 "User Configuration object for a generic project.")
130
131(defun ede-generic-load (dir &optional rootproj)
132 "Return a Generic Project object if there is a match.
133Return nil if there isn't one.
134Argument DIR is the directory it is created for.
135ROOTPROJ is nil, since there is only one project."
136 ;; Doesn't already exist, so lets make one.
137 (let* ((alobj ede-constructing)
138 (this nil))
139 (when (not alobj) (error "Cannot load generic project without the autoload instance"))
140
141 (setq this
142 (funcall (oref alobj class-sym)
143 (symbol-name (oref alobj class-sym))
144 :name (file-name-nondirectory
145 (directory-file-name dir))
146 :version "1.0"
147 :directory (file-name-as-directory dir)
148 :file (expand-file-name (oref alobj :proj-file)) ))
149 (ede-add-project-to-global-list this)
150 ))
151
152;;; Base Classes for the system
153(defclass ede-generic-target (ede-target)
154 ((shortname :initform ""
155 :type string
156 :allocation :class
157 :documentation
158 "Something prepended to the target name.")
159 (extension :initform ""
160 :type string
161 :allocation :class
162 :documentation
163 "Regular expression representing the extension used for this target.
164subclasses of this base target will override the default value.")
165 )
166 "Baseclass for all targets belonging to the generic ede system."
167 :abstract t)
168
169(defclass ede-generic-project (ede-project)
170 ((buildfile :initform ""
171 :type string
172 :allocation :class
173 :documentation "The file name that identifies a project of this type.
174The class allocated value is replace by different sub classes.")
175 (config :initform nil
176 :type (or null ede-generic-config)
177 :documentation
178 "The configuration object for this project.")
179 )
180 "The baseclass for all generic EDE project types."
181 :abstract t)
182
183(defmethod initialize-instance ((this ede-generic-project)
184 &rest fields)
185 "Make sure the targets slot is bound."
186 (call-next-method)
187 (unless (slot-boundp this 'targets)
188 (oset this :targets nil))
189 )
190
191(defmethod ede-generic-get-configuration ((proj ede-generic-project))
192 "Return the configuration for the project PROJ."
193 (let ((config (oref proj config)))
194 (when (not config)
195 (let ((fname (expand-file-name "EDEConfig.el"
196 (oref proj :directory))))
197 (if (file-exists-p fname)
198 ;; Load in the configuration
199 (setq config (eieio-persistent-read fname))
200 ;; Create a new one.
201 (setq config (ede-generic-config
202 "Configuration"
203 :file fname))
204 ;; Set initial values based on project.
205 (ede-generic-setup-configuration proj config))
206 ;; Link things together.
207 (oset proj config config)
208 (oset config project proj)))
209 config))
210
211(defmethod ede-generic-setup-configuration ((proj ede-generic-project) config)
212 "Default configuration setup method."
213 nil)
214
215(defmethod ede-commit-project ((proj ede-generic-project))
216 "Commit any change to PROJ to its file."
217 (let ((config (ede-generic-get-configuration proj)))
218 (ede-commit config)))
219
220;;; A list of different targets
221(defclass ede-generic-target-c-cpp (ede-generic-target)
222 ((shortname :initform "C/C++")
223 (extension :initform "\\([ch]\\(pp\\|xx\\|\\+\\+\\)?\\|cc\\|hh\\|CC?\\)"))
224 "EDE Generic Project target for C and C++ code.
225All directories need at least one target.")
226
227(defclass ede-generic-target-el (ede-generic-target)
228 ((shortname :initform "ELisp")
229 (extension :initform "el"))
230 "EDE Generic Project target for Emacs Lisp code.
231All directories need at least one target.")
232
233(defclass ede-generic-target-fortran (ede-generic-target)
234 ((shortname :initform "Fortran")
235 (extension :initform "[fF]9[05]\\|[fF]\\|for"))
236 "EDE Generic Project target for Fortran code.
237All directories need at least one target.")
238
239(defclass ede-generic-target-texi (ede-generic-target)
240 ((shortname :initform "Texinfo")
241 (extension :initform "texi"))
242 "EDE Generic Project target for texinfo code.
243All directories need at least one target.")
244
245;; MISC must always be last since it will always match the file.
246(defclass ede-generic-target-misc (ede-generic-target)
247 ((shortname :initform "Misc")
248 (extension :initform ""))
249 "EDE Generic Project target for Misc files.
250All directories need at least one target.")
251
252;;; Automatic target aquisition.
253(defun ede-generic-find-matching-target (class dir targets)
254 "Find a target that is a CLASS and is in DIR in the list of TARGETS."
255 (let ((match nil))
256 (dolist (T targets)
257 (when (and (object-of-class-p T class)
258 (string= (oref T :path) dir))
259 (setq match T)
260 ))
261 match))
262
263(defmethod ede-find-target ((proj ede-generic-project) buffer)
264 "Find an EDE target in PROJ for BUFFER.
265If one doesn't exist, create a new one for this directory."
266 (let* ((ext (file-name-extension (buffer-file-name buffer)))
267 (classes (eieio-build-class-alist 'ede-generic-target t))
268 (cls nil)
269 (targets (oref proj targets))
270 (dir default-directory)
271 (ans nil)
272 )
273 ;; Pick a matching class type.
274 (when ext
275 (dolist (C classes)
276 (let* ((classsym (intern (car C)))
277 (extreg (oref classsym extension)))
278 (when (and (not (string= extreg ""))
279 (string-match (concat "^" extreg "$") ext))
280 (setq cls classsym)))))
281 (when (not cls) (setq cls 'ede-generic-target-misc))
282 ;; find a pre-existing matching target
283 (setq ans (ede-generic-find-matching-target cls dir targets))
284 ;; Create a new instance if there wasn't one
285 (when (not ans)
286 (setq ans (make-instance
287 cls
288 :name (oref cls shortname)
289 :path dir
290 :source nil))
291 (object-add-to-list proj :targets ans)
292 )
293 ans))
294
295;;; C/C++ support
296(defmethod ede-preprocessor-map ((this ede-generic-target-c-cpp))
297 "Get the pre-processor map for some generic C code."
298 (let* ((proj (ede-target-parent this))
299 (root (ede-project-root proj))
300 (config (ede-generic-get-configuration proj))
301 filemap
302 )
303 ;; Preprocessor files
304 (dolist (G (oref config :c-preprocessor-files))
305 (let ((table (semanticdb-file-table-object
306 (ede-expand-filename root G))))
307 (when table
308 (when (semanticdb-needs-refresh-p table)
309 (semanticdb-refresh-table table))
310 (setq filemap (append filemap (oref table lexical-table)))
311 )))
312 ;; The core table
313 (setq filemap (append filemap (oref config :c-preprocessor-table)))
314
315 filemap
316 ))
317
318(defmethod ede-system-include-path ((this ede-generic-target-c-cpp))
319 "Get the system include path used by project THIS."
320 (let* ((proj (ede-target-parent this))
321 (config (ede-generic-get-configuration proj)))
322 (oref config c-include-path)))
323
324;;; Customization
325;;
326(defmethod ede-customize ((proj ede-generic-project))
327 "Customize the EDE project PROJ."
328 (let ((config (ede-generic-get-configuration proj)))
329 (eieio-customize-object config)))
330
331(defmethod ede-customize ((target ede-generic-target))
332 "Customize the EDE TARGET."
333 ;; Nothing unique for the targets, use the project.
334 (ede-customize-project))
335
336(defmethod eieio-done-customizing ((config ede-generic-config))
337 "Called when EIEIO is done customizing the configuration object.
338We need to go back through the old buffers, and update them with
339the new configuration."
340 (ede-commit config)
341 ;; Loop over all the open buffers, and re-apply.
342 (ede-map-targets
343 (oref config project)
344 (lambda (target)
345 (ede-map-target-buffers
346 target
347 (lambda (b)
348 (with-current-buffer b
349 (ede-apply-target-options)))))))
350
351(defmethod ede-commit ((config ede-generic-config))
352 "Commit all changes to the configuration to disk."
353 (eieio-persistent-save config))
354
355;;; Creating Derived Projects:
356;;
357;; Derived projects need an autoloader so that EDE can find the
358;; different projects on disk.
359(defun ede-generic-new-autoloader (internal-name external-name
360 projectfile class)
361 "Add a new EDE Autoload instance for identifying a generic project.
362INTERNAL-NAME is a long name that identifies thsi project type.
363EXTERNAL-NAME is a shorter human readable name to describe the project.
364PROJECTFILE is a file name that identifies a project of this type to EDE, such as
365a Makefile, or SConstruct file.
366CLASS is the EIEIO class that is used to track this project. It should subclass
367the class `ede-generic-project' project."
368 (add-to-list 'ede-project-class-files
369 (ede-project-autoload internal-name
370 :name external-name
371 :file 'ede-generic
372 :proj-file projectfile
373 :load-type 'ede-generic-load
374 :class-sym class
375 :new-p nil)
376 ;; Generics must go at the end, since more specific types
377 ;; can create Makefiles also.
378 t))
379
380;;;###autoload
381(defun ede-enable-generic-projects ()
382 "Enable generic project loaders."
383 (interactive)
384 (ede-generic-new-autoloader "edeproject-makefile" "Make"
385 "Makefile" 'ede-generic-makefile-project)
386 (ede-generic-new-autoloader "edeproject-scons" "SCons"
387 "SConstruct" 'ede-generic-scons-project)
388 (ede-generic-new-autoloader "edeproject-cmake" "CMake"
389 "CMakeLists" 'ede-generic-cmake-project)
390 )
391
392
393;;; SPECIFIC TYPES OF GENERIC BUILDS
394;;
395
396;;; MAKEFILE
397
398(defclass ede-generic-makefile-project (ede-generic-project)
399 ((buildfile :initform "Makefile")
400 )
401 "Generic Project for makefiles.")
402
403(defmethod ede-generic-setup-configuration ((proj ede-generic-makefile-project) config)
404 "Setup a configuration for Make."
405 (oset config build-command "make -k")
406 (oset config debug-command "gdb ")
407 )
408
409
410;;; SCONS
411(defclass ede-generic-scons-project (ede-generic-project)
412 ((buildfile :initform "SConstruct")
413 )
414 "Generic Project for scons.")
415
416(defmethod ede-generic-setup-configuration ((proj ede-generic-scons-project) config)
417 "Setup a configuration for SCONS."
418 (oset config build-command "scons")
419 (oset config debug-command "gdb ")
420 )
421
422
423;;; CMAKE
424(defclass ede-generic-cmake-project (ede-generic-project)
425 ((buildfile :initform "CMakeLists")
426 )
427 "Generic Project for cmake.")
428
429(defmethod ede-generic-setup-configuration ((proj ede-generic-cmake-project) config)
430 "Setup a configuration for CMake."
431 (oset config build-command "cmake")
432 (oset config debug-command "gdb ")
433 )
434
435(provide 'ede/generic)
436
437;; Local variables:
438;; generated-autoload-file: "loaddefs.el"
439;; generated-autoload-load-name: "ede/generic"
440;; End:
441
442;;; ede/generic.el ends here
diff --git a/lisp/cedet/ede/linux.el b/lisp/cedet/ede/linux.el
index 451c1ea5212..456a0e552d9 100644
--- a/lisp/cedet/ede/linux.el
+++ b/lisp/cedet/ede/linux.el
@@ -112,6 +112,18 @@ ROOTPROJ is nil, since there is only one project."
112 ) 112 )
113 ) 113 )
114 114
115;;;###autoload
116(add-to-list 'ede-project-class-files
117 (ede-project-autoload "linux"
118 :name "LINUX ROOT"
119 :file 'ede-linux
120 :proj-file "scripts/ver_linux"
121 :proj-root 'ede-linux-project-root
122 :load-type 'ede-linux-load
123 :class-sym 'ede-linux-project
124 :new-p nil)
125 t)
126
115(defclass ede-linux-target-c (ede-target) 127(defclass ede-linux-target-c (ede-target)
116 () 128 ()
117 "EDE Linux Project target for C code. 129 "EDE Linux Project target for C code.
@@ -124,7 +136,7 @@ All directories need at least one target.")
124 136
125(defmethod initialize-instance ((this ede-linux-project) 137(defmethod initialize-instance ((this ede-linux-project)
126 &rest fields) 138 &rest fields)
127 "Make sure the :file is fully expanded." 139 "Make sure the targets slot is bound."
128 (call-next-method) 140 (call-next-method)
129 (unless (slot-boundp this 'targets) 141 (unless (slot-boundp this 'targets)
130 (oset this :targets nil))) 142 (oset this :targets nil)))
diff --git a/lisp/cedet/ede/locate.el b/lisp/cedet/ede/locate.el
index 099e193f010..c2ca81c668b 100644
--- a/lisp/cedet/ede/locate.el
+++ b/lisp/cedet/ede/locate.el
@@ -121,7 +121,7 @@ based on `ede-locate-setup-options'."
121 ;; Basic setup. 121 ;; Basic setup.
122 (call-next-method) 122 (call-next-method)
123 ;; Make sure we have a hash table. 123 ;; Make sure we have a hash table.
124 (oset loc hash (make-hash-table :test 'equal)) 124 (ede-locate-flush-hash loc)
125 ) 125 )
126 126
127(defmethod ede-locate-ok-in-project :static ((loc ede-locate-base) 127(defmethod ede-locate-ok-in-project :static ((loc ede-locate-base)
@@ -129,6 +129,10 @@ based on `ede-locate-setup-options'."
129 "Is it ok to use this project type under ROOT." 129 "Is it ok to use this project type under ROOT."
130 t) 130 t)
131 131
132(defmethod ede-locate-flush-hash ((loc ede-locate-base))
133 "For LOC, flush hashtable and start from scratch."
134 (oset loc hash (make-hash-table :test 'equal)))
135
132(defmethod ede-locate-file-in-hash ((loc ede-locate-base) 136(defmethod ede-locate-file-in-hash ((loc ede-locate-base)
133 filestring) 137 filestring)
134 "For LOC, is the file FILESTRING in our hashtable?" 138 "For LOC, is the file FILESTRING in our hashtable?"
@@ -160,6 +164,13 @@ that created this EDE locate object."
160 nil 164 nil
161 ) 165 )
162 166
167(defmethod ede-locate-create/update-root-database :STATIC
168 ((loc ede-locate-base) root)
169 "Create or update the database for the current project.
170You cannot create projects for the baseclass."
171 (error "Cannot create/update a database of type %S"
172 (object-name loc)))
173
163;;; LOCATE 174;;; LOCATE
164;; 175;;
165;; Using the standard unix "locate" command. 176;; Using the standard unix "locate" command.
@@ -242,6 +253,11 @@ that created this EDE locate object."
242 (let ((default-directory (oref loc root))) 253 (let ((default-directory (oref loc root)))
243 (cedet-gnu-global-expand-filename filesubstring))) 254 (cedet-gnu-global-expand-filename filesubstring)))
244 255
256(defmethod ede-locate-create/update-root-database :STATIC
257 ((loc ede-locate-global) root)
258 "Create or update the GNU Global database for the current project."
259 (cedet-gnu-global-create/update-database root))
260
245;;; IDUTILS 261;;; IDUTILS
246;; 262;;
247(defclass ede-locate-idutils (ede-locate-base) 263(defclass ede-locate-idutils (ede-locate-base)
@@ -280,6 +296,11 @@ that created this EDE locate object."
280 (let ((default-directory (oref loc root))) 296 (let ((default-directory (oref loc root)))
281 (cedet-idutils-expand-filename filesubstring))) 297 (cedet-idutils-expand-filename filesubstring)))
282 298
299(defmethod ede-locate-create/update-root-database :STATIC
300 ((loc ede-locate-idutils) root)
301 "Create or update the GNU Global database for the current project."
302 (cedet-idutils-create/update-database root))
303
283;;; CSCOPE 304;;; CSCOPE
284;; 305;;
285(defclass ede-locate-cscope (ede-locate-base) 306(defclass ede-locate-cscope (ede-locate-base)
@@ -315,6 +336,11 @@ that created this EDE locate object."
315 (let ((default-directory (oref loc root))) 336 (let ((default-directory (oref loc root)))
316 (cedet-cscope-expand-filename filesubstring))) 337 (cedet-cscope-expand-filename filesubstring)))
317 338
339(defmethod ede-locate-create/update-root-database :STATIC
340 ((loc ede-locate-cscope) root)
341 "Create or update the GNU Global database for the current project."
342 (cedet-cscope-create/update-database root))
343
318(provide 'ede/locate) 344(provide 'ede/locate)
319 345
320;; Local variables: 346;; Local variables:
diff --git a/lisp/cedet/ede/pconf.el b/lisp/cedet/ede/pconf.el
index f9a1fb44f15..0983aeb16b8 100644
--- a/lisp/cedet/ede/pconf.el
+++ b/lisp/cedet/ede/pconf.el
@@ -126,7 +126,11 @@ don't do it. A value of nil means to just do it.")
126 126
127 (while compilation-in-progress 127 (while compilation-in-progress
128 (accept-process-output) 128 (accept-process-output)
129 (sit-for 1)) 129 ;; If sit for indicates that input is waiting, then
130 ;; read and discard whatever it is that is going on.
131 (when (not (sit-for 1))
132 (read-event nil nil .1)
133 ))
130 134
131 (with-current-buffer "*compilation*" 135 (with-current-buffer "*compilation*"
132 (goto-char (point-max)) 136 (goto-char (point-max))
diff --git a/lisp/cedet/ede/pmake.el b/lisp/cedet/ede/pmake.el
index 19c4b26edcd..94874d031b7 100644
--- a/lisp/cedet/ede/pmake.el
+++ b/lisp/cedet/ede/pmake.el
@@ -262,6 +262,18 @@ Execute BODY in a location where a value can be placed."
262 (goto-char (point-max)))) 262 (goto-char (point-max))))
263(put 'ede-pmake-insert-variable-shared 'lisp-indent-function 1) 263(put 'ede-pmake-insert-variable-shared 'lisp-indent-function 1)
264 264
265(defmacro ede-pmake-insert-variable-once (varname &rest body)
266 "Add VARNAME into the current Makefile if it doesn't exist.
267Execute BODY in a location where a value can be placed."
268 `(let ((addcr t) (v ,varname))
269 (unless (re-search-backward (concat "^" v "\\s-*=") nil t)
270 (insert v "=")
271 ,@body
272 (if addcr (insert "\n"))
273 (goto-char (point-max)))
274 ))
275(put 'ede-pmake-insert-variable-once 'lisp-indent-function 1)
276
265;;; SOURCE VARIABLE NAME CONSTRUCTION 277;;; SOURCE VARIABLE NAME CONSTRUCTION
266 278
267(defsubst ede-pmake-varname (obj) 279(defsubst ede-pmake-varname (obj)
@@ -369,10 +381,14 @@ NOTE: Not yet in use! This is part of an SRecode conversion of
369 conf-table)) 381 conf-table))
370 (let* ((top "") 382 (let* ((top "")
371 (tmp this)) 383 (tmp this))
384 ;; Use relative paths for subdirs.
372 (while (ede-parent-project tmp) 385 (while (ede-parent-project tmp)
373 (setq tmp (ede-parent-project tmp) 386 (setq tmp (ede-parent-project tmp)
374 top (concat "../" top))) 387 top (concat "../" top)))
375 (insert "\ntop=" top)) 388 ;; If this is the top, then use CURDIR.
389 (if (and (not (oref this metasubproject)) (string= top ""))
390 (insert "\ntop=\"$(CURDIR)\"/")
391 (insert "\ntop=" top)))
376 (insert "\nede_FILES=" (file-name-nondirectory (oref this file)) " " 392 (insert "\nede_FILES=" (file-name-nondirectory (oref this file)) " "
377 (file-name-nondirectory (ede-proj-dist-makefile this)) "\n")) 393 (file-name-nondirectory (ede-proj-dist-makefile this)) "\n"))
378 394
@@ -425,14 +441,13 @@ sources variable."
425 (link (ede-proj-linkers this)) 441 (link (ede-proj-linkers this))
426 (name (ede-proj-makefile-target-name this)) 442 (name (ede-proj-makefile-target-name this))
427 (src (oref this source))) 443 (src (oref this source)))
444 (ede-proj-makefile-insert-object-variables (car comp) name src)
428 (dolist (obj comp) 445 (dolist (obj comp)
429 (ede-compiler-only-once obj 446 (ede-compiler-only-once obj
430 (ede-proj-makefile-insert-variables obj))) 447 (ede-proj-makefile-insert-variables obj)))
431 (ede-proj-makefile-insert-object-variables (car comp) name src) 448 (dolist (linker link)
432 (while link 449 (ede-linker-only-once linker
433 (ede-linker-only-once (car link) 450 (ede-proj-makefile-insert-variables linker)))))
434 (ede-proj-makefile-insert-variables (car link)))
435 (setq link (cdr link)))))
436 451
437(defmethod ede-proj-makefile-insert-automake-pre-variables 452(defmethod ede-proj-makefile-insert-automake-pre-variables
438 ((this ede-proj-target)) 453 ((this ede-proj-target))
diff --git a/lisp/cedet/ede/proj-archive.el b/lisp/cedet/ede/proj-archive.el
index 3057f967b0f..2d4620ea47c 100644
--- a/lisp/cedet/ede/proj-archive.el
+++ b/lisp/cedet/ede/proj-archive.el
@@ -29,7 +29,7 @@
29 29
30(defclass ede-proj-target-makefile-archive 30(defclass ede-proj-target-makefile-archive
31 (ede-proj-target-makefile-objectcode) 31 (ede-proj-target-makefile-objectcode)
32 ((availablelinkers :initform (ede-archive-linker))) 32 ((availablelinkers :initform '(ede-archive-linker)))
33 "This target generates an object code archive.") 33 "This target generates an object code archive.")
34 34
35(defvar ede-archive-linker 35(defvar ede-archive-linker
diff --git a/lisp/cedet/ede/proj-aux.el b/lisp/cedet/ede/proj-aux.el
index 26bc9540e82..4f00d6ea60b 100644
--- a/lisp/cedet/ede/proj-aux.el
+++ b/lisp/cedet/ede/proj-aux.el
@@ -29,7 +29,7 @@
29 29
30;;; Code: 30;;; Code:
31(defclass ede-proj-target-aux (ede-proj-target) 31(defclass ede-proj-target-aux (ede-proj-target)
32 ((sourcetype :initform (ede-aux-source))) 32 ((sourcetype :initform '(ede-aux-source)))
33 "This target consists of aux files such as READMEs and COPYING.") 33 "This target consists of aux files such as READMEs and COPYING.")
34 34
35(defvar ede-aux-source 35(defvar ede-aux-source
diff --git a/lisp/cedet/ede/proj-elisp.el b/lisp/cedet/ede/proj-elisp.el
index ecdefb2a522..879f36ff4e2 100644
--- a/lisp/cedet/ede/proj-elisp.el
+++ b/lisp/cedet/ede/proj-elisp.el
@@ -36,8 +36,8 @@
36 ((menu :initform nil) 36 ((menu :initform nil)
37 (keybindings :initform nil) 37 (keybindings :initform nil)
38 (phony :initform t) 38 (phony :initform t)
39 (sourcetype :initform (ede-source-emacs)) 39 (sourcetype :initform '(ede-source-emacs))
40 (availablecompilers :initform (ede-emacs-compiler ede-xemacs-compiler)) 40 (availablecompilers :initform '(ede-emacs-compiler ede-xemacs-compiler))
41 (aux-packages :initarg :aux-packages 41 (aux-packages :initarg :aux-packages
42 :initform nil 42 :initform nil
43 :type list 43 :type list
@@ -259,7 +259,7 @@ is found, such as a `-version' variable, or the standard header."
259;; Autoload generators 259;; Autoload generators
260;; 260;;
261(defclass ede-proj-target-elisp-autoloads (ede-proj-target-elisp) 261(defclass ede-proj-target-elisp-autoloads (ede-proj-target-elisp)
262 ((availablecompilers :initform (ede-emacs-cedet-autogen-compiler)) 262 ((availablecompilers :initform '(ede-emacs-cedet-autogen-compiler))
263 (aux-packages :initform ("cedet-autogen")) 263 (aux-packages :initform ("cedet-autogen"))
264 (phony :initform t) 264 (phony :initform t)
265 (autoload-file :initarg :autoload-file 265 (autoload-file :initarg :autoload-file
diff --git a/lisp/cedet/ede/proj-info.el b/lisp/cedet/ede/proj-info.el
index 667d6d0bff9..1e9060fe315 100644
--- a/lisp/cedet/ede/proj-info.el
+++ b/lisp/cedet/ede/proj-info.el
@@ -31,9 +31,9 @@
31(defclass ede-proj-target-makefile-info (ede-proj-target-makefile) 31(defclass ede-proj-target-makefile-info (ede-proj-target-makefile)
32 ((menu :initform nil) 32 ((menu :initform nil)
33 (keybindings :initform nil) 33 (keybindings :initform nil)
34 (availablecompilers :initform (ede-makeinfo-compiler 34 (availablecompilers :initform '(ede-makeinfo-compiler
35 ede-texi2html-compiler)) 35 ede-texi2html-compiler))
36 (sourcetype :initform (ede-makeinfo-source)) 36 (sourcetype :initform '(ede-makeinfo-source))
37 (mainmenu :initarg :mainmenu 37 (mainmenu :initarg :mainmenu
38 :initform "" 38 :initform ""
39 :type string 39 :type string
diff --git a/lisp/cedet/ede/proj-misc.el b/lisp/cedet/ede/proj-misc.el
index 9c25dafe102..34a10859fdd 100644
--- a/lisp/cedet/ede/proj-misc.el
+++ b/lisp/cedet/ede/proj-misc.el
@@ -35,8 +35,8 @@
35 35
36;; FIXME this isn't how you spell "miscellaneous". :( 36;; FIXME this isn't how you spell "miscellaneous". :(
37(defclass ede-proj-target-makefile-miscelaneous (ede-proj-target-makefile) 37(defclass ede-proj-target-makefile-miscelaneous (ede-proj-target-makefile)
38 ((sourcetype :initform (ede-misc-source)) 38 ((sourcetype :initform '(ede-misc-source))
39 (availablecompilers :initform (ede-misc-compile)) 39 (availablecompilers :initform '(ede-misc-compile))
40 (submakefile :initarg :submakefile 40 (submakefile :initarg :submakefile
41 :initform "" 41 :initform ""
42 :type string 42 :type string
diff --git a/lisp/cedet/ede/proj-obj.el b/lisp/cedet/ede/proj-obj.el
index 241ace2f167..6be76f1f11b 100644
--- a/lisp/cedet/ede/proj-obj.el
+++ b/lisp/cedet/ede/proj-obj.el
@@ -39,28 +39,32 @@
39 (configuration-variables :initform ("debug" . (("CFLAGS" . "-g") 39 (configuration-variables :initform ("debug" . (("CFLAGS" . "-g")
40 ("LDFLAGS" . "-g")))) 40 ("LDFLAGS" . "-g"))))
41 ;; @TODO - add an include path. 41 ;; @TODO - add an include path.
42 (availablecompilers :initform (ede-gcc-compiler 42 (availablecompilers :initform '(ede-gcc-compiler
43 ede-g++-compiler 43 ede-g++-compiler
44 ede-gfortran-compiler 44 ede-gfortran-compiler
45 ede-gfortran-module-compiler 45 ede-gfortran-module-compiler
46 ;; More C and C++ compilers, plus 46 ede-lex-compiler
47 ;; fortran or pascal can be added here 47 ede-yacc-compiler
48 )) 48 ;; More C and C++ compilers, plus
49 (availablelinkers :initform (ede-g++-linker 49 ;; fortran or pascal can be added here
50 ede-cc-linker 50 ))
51 ede-gfortran-linker 51 (availablelinkers :initform '(ede-g++-linker
52 ede-ld-linker 52 ede-cc-linker
53 ;; Add more linker thingies here. 53 ede-ld-linker
54 )) 54 ede-gfortran-linker
55 (sourcetype :initform (ede-source-c 55 ;; Add more linker thingies here.
56 ede-source-c++ 56 ))
57 ede-source-f77 57 (sourcetype :initform '(ede-source-c
58 ede-source-f90 58 ede-source-c++
59 ;; ede-source-other 59 ede-source-f77
60 ;; This object should take everything that 60 ede-source-f90
61 ;; gets compiled into objects like fortran 61 ede-source-lex
62 ;; and pascal. 62 ede-source-yacc
63 )) 63 ;; ede-source-other
64 ;; This object should take everything that
65 ;; gets compiled into objects like fortran
66 ;; and pascal.
67 ))
64 ) 68 )
65 "Abstract class for Makefile based object code generating targets. 69 "Abstract class for Makefile based object code generating targets.
66Belonging to this group assumes you could make a .o from an element source 70Belonging to this group assumes you could make a .o from an element source
@@ -115,15 +119,15 @@ file.")
115 :name "cc" 119 :name "cc"
116 :sourcetype '(ede-source-c) 120 :sourcetype '(ede-source-c)
117 :variables '(("C_LINK" . "$(CC) $(CFLAGS) $(LDFLAGS) -L.")) 121 :variables '(("C_LINK" . "$(CC) $(CFLAGS) $(LDFLAGS) -L."))
118 :commands '("$(C_LINK) -o $@ $^") 122 :commands '("$(C_LINK) -o $@ $^ $(LDDEPS)")
119 :objectextention "") 123 :objectextention "")
120 "Linker for C sourcecode.") 124 "Linker for C sourcecode.")
121 125
122(defvar ede-source-c++ 126(defvar ede-source-c++
123 (ede-sourcecode "ede-source-c++" 127 (ede-sourcecode "ede-source-c++"
124 :name "C++" 128 :name "C++"
125 :sourcepattern "\\.\\(cpp\\|cc\\|cxx\\)$" 129 :sourcepattern "\\.\\(c\\(pp?\\|c\\|xx\\|++\\)\\|C\\\(PP\\)?\\)$"
126 :auxsourcepattern "\\.\\(hpp\\|hh?\\|hxx\\)$" 130 :auxsourcepattern "\\.\\(hpp?\\|hh?\\|hxx\\|H\\)$"
127 :garbagepattern '("*.o" "*.obj" ".deps/*.P" ".lo")) 131 :garbagepattern '("*.o" "*.obj" ".deps/*.P" ".lo"))
128 "C++ source code definition.") 132 "C++ source code definition.")
129 133
@@ -158,11 +162,43 @@ file.")
158 ;; Only use this linker when c++ exists. 162 ;; Only use this linker when c++ exists.
159 :sourcetype '(ede-source-c++) 163 :sourcetype '(ede-source-c++)
160 :variables '(("CXX_LINK" . "$(CXX) $(CFLAGS) $(LDFLAGS) -L.")) 164 :variables '(("CXX_LINK" . "$(CXX) $(CFLAGS) $(LDFLAGS) -L."))
161 :commands '("$(CXX_LINK) -o $@ $^") 165 :commands '("$(CXX_LINK) -o $@ $^ $(LDDEPS)")
162 :autoconf '("AC_PROG_CXX") 166 :autoconf '("AC_PROG_CXX")
163 :objectextention "") 167 :objectextention "")
164 "Linker needed for c++ programs.") 168 "Linker needed for c++ programs.")
165 169
170;;; LEX
171(defvar ede-source-lex
172 (ede-sourcecode "ede-source-lex"
173 :name "lex"
174 :sourcepattern "\\.l\\(l\\|pp\\|++\\)")
175 "Lex source code definition.
176No garbage pattern since it creates C or C++ code.")
177
178(defvar ede-lex-compiler
179 (ede-object-compiler
180 "ede-lex-compiler"
181 ;; Can we support regular makefiles too??
182 :autoconf '("AC_PROG_LEX")
183 :sourcetype '(ede-source-lex))
184 "Compiler used for Lexical source.")
185
186;;; YACC
187(defvar ede-source-yacc
188 (ede-sourcecode "ede-source-yacc"
189 :name "yacc"
190 :sourcepattern "\\.y\\(y\\|pp\\|++\\)")
191 "Yacc source code definition.
192No garbage pattern since it creates C or C++ code.")
193
194(defvar ede-yacc-compiler
195 (ede-object-compiler
196 "ede-yacc-compiler"
197 ;; Can we support regular makefiles too??
198 :autoconf '("AC_PROG_YACC")
199 :sourcetype '(ede-source-yacc))
200 "Compiler used for yacc/bison grammar files source.")
201
166;;; Fortran Compiler/Linker 202;;; Fortran Compiler/Linker
167;; 203;;
168;; Contributed by David Engster 204;; Contributed by David Engster
@@ -233,7 +269,7 @@ file.")
233 :name "ld" 269 :name "ld"
234 :variables '(("LD" . "ld") 270 :variables '(("LD" . "ld")
235 ("LD_LINK" . "$(LD) $(LDFLAGS) -L.")) 271 ("LD_LINK" . "$(LD) $(LDFLAGS) -L."))
236 :commands '("$(LD_LINK) -o $@ $^") 272 :commands '("$(LD_LINK) -o $@ $^ $(LDDEPS)")
237 :objectextention "") 273 :objectextention "")
238 "Linker needed for c++ programs.") 274 "Linker needed for c++ programs.")
239 275
diff --git a/lisp/cedet/ede/proj-prog.el b/lisp/cedet/ede/proj-prog.el
index 2c0237e41c2..9b06dc007b3 100644
--- a/lisp/cedet/ede/proj-prog.el
+++ b/lisp/cedet/ede/proj-prog.el
@@ -34,14 +34,14 @@
34;;; Code: 34;;; Code:
35(defclass ede-proj-target-makefile-program 35(defclass ede-proj-target-makefile-program
36 (ede-proj-target-makefile-objectcode) 36 (ede-proj-target-makefile-objectcode)
37 ((ldlibs :initarg :ldlibs 37 ((ldlibs-local :initarg :ldlibs-local
38 :initform nil 38 :initform nil
39 :type list 39 :type list
40 :custom (repeat (string :tag "Library")) 40 :custom (repeat (string :tag "Local Library"))
41 :documentation 41 :documentation
42 "Libraries, such as \"m\" or \"Xt\" which this program depends on. 42 "Libraries that are part of this project.
43The linker flag \"-l\" is automatically prepended. Do not include a \"lib\" 43The full path to these libraries should be specified, such as:
44prefix, or a \".so\" suffix. 44../lib/libMylib.la or ../ar/myArchive.a
45 45
46Note: Currently only used for Automake projects." 46Note: Currently only used for Automake projects."
47 ) 47 )
@@ -51,10 +51,21 @@ Note: Currently only used for Automake projects."
51 :custom (repeat (string :tag "Link Flag")) 51 :custom (repeat (string :tag "Link Flag"))
52 :documentation 52 :documentation
53 "Additional flags to add when linking this target. 53 "Additional flags to add when linking this target.
54Use ldlibs to add addition libraries. Use this to specify specific 54Use this to specify specific options to the linker.
55options to the linker. 55A Common use may be to add -L to specify in-project locations of libraries
56specified with ldlibs.")
57 (ldlibs :initarg :ldlibs
58 :initform nil
59 :type list
60 :custom (repeat (string :tag "Library"))
61 :documentation
62 "Libraries, such as \"m\" or \"Xt\" which this program depends on.
63The linker flag \"-l\" is automatically prepended. Do not include a \"lib\"
64prefix, or a \".so\" suffix.
65Use the 'ldflags' slot to specify where in-project libraries might be.
56 66
57Note: Not currently used. This bug needs to be fixed.") 67Note: Currently only used for Automake projects."
68 )
58 ) 69 )
59 "This target is an executable program.") 70 "This target is an executable program.")
60 71
@@ -70,27 +81,24 @@ Note: Not currently used. This bug needs to be fixed.")
70 "Insert bin_PROGRAMS variables needed by target THIS." 81 "Insert bin_PROGRAMS variables needed by target THIS."
71 (ede-pmake-insert-variable-shared 82 (ede-pmake-insert-variable-shared
72 (concat (ede-name this) "_LDADD") 83 (concat (ede-name this) "_LDADD")
73 (mapc (lambda (c) (insert " -l" c)) (oref this ldlibs))) 84 (mapc (lambda (l) (insert " " l)) (oref this ldlibs-local))
74 ;; For other targets THIS depends on 85 (mapc (lambda (c) (insert " " c)) (oref this ldflags))
75 ;; 86 (when (oref this ldlibs)
76 ;; NOTE: FIX THIS 87 (mapc (lambda (d) (insert " -l" d)) (oref this ldlibs)))
77 ;; 88 )
78 ;;(ede-pmake-insert-variable-shared
79 ;; (concat (ede-name this) "_DEPENDENCIES")
80 ;; (mapcar (lambda (d) (insert d)) (oref this FOOOOOOOO)))
81 (call-next-method)) 89 (call-next-method))
82 90
83(defmethod ede-proj-makefile-insert-rules ((this ede-proj-target-makefile-program)) 91(defmethod ede-proj-makefile-insert-variables ((this ede-proj-target-makefile-program))
84 "Insert rules needed by THIS target." 92 "Insert variables needed by the compiler THIS."
85 (let ((ede-proj-compiler-object-linkflags 93 (call-next-method)
86 (mapconcat 'identity (oref this ldflags) " "))) 94 (let ((lf (mapconcat 'identity (oref this ldflags) " ")))
87 (with-slots (ldlibs) this 95 (with-slots (ldlibs) this
88 (if ldlibs 96 (if ldlibs
89 (setq ede-proj-compiler-object-linkflags 97 (setq lf
90 (concat ede-proj-compiler-object-linkflags 98 (concat lf " -l" (mapconcat 'identity ldlibs " -l")))))
91 " -l" 99 ;; LDFLAGS as needed.
92 (mapconcat 'identity ldlibs " -l"))))) 100 (when (and lf (not (string= "" lf)))
93 (call-next-method))) 101 (ede-pmake-insert-variable-once "LDDEPS" (insert lf)))))
94 102
95(defmethod project-debug-target ((obj ede-proj-target-makefile-program)) 103(defmethod project-debug-target ((obj ede-proj-target-makefile-program))
96 "Debug a program target OBJ." 104 "Debug a program target OBJ."
diff --git a/lisp/cedet/ede/proj-shared.el b/lisp/cedet/ede/proj-shared.el
index 46a8a480b52..e1111f9f38b 100644
--- a/lisp/cedet/ede/proj-shared.el
+++ b/lisp/cedet/ede/proj-shared.el
@@ -34,15 +34,15 @@
34;;; Code: 34;;; Code:
35(defclass ede-proj-target-makefile-shared-object 35(defclass ede-proj-target-makefile-shared-object
36 (ede-proj-target-makefile-program) 36 (ede-proj-target-makefile-program)
37 ((availablecompilers :initform (ede-gcc-libtool-shared-compiler 37 ((availablecompilers :initform '(ede-gcc-libtool-shared-compiler
38 ;;ede-gcc-shared-compiler 38 ;;ede-gcc-shared-compiler
39 ede-g++-libtool-shared-compiler 39 ede-g++-libtool-shared-compiler
40 ;;ede-g++-shared-compiler 40 ;;ede-g++-shared-compiler
41 )) 41 ))
42 (availablelinkers :initform (ede-cc-linker-libtool 42 (availablelinkers :initform '(ede-cc-linker-libtool
43 ede-g++-linker-libtool 43 ede-g++-linker-libtool
44 ;; Add more linker thingies here. 44 ;; Add more linker thingies here.
45 )) 45 ))
46 (ldflags :custom (repeat (string :tag "Libtool flag")) 46 (ldflags :custom (repeat (string :tag "Libtool flag"))
47 :documentation 47 :documentation
48 "Additional flags to add when linking this shared library. 48 "Additional flags to add when linking this shared library.
@@ -124,7 +124,7 @@ Use ldlibs to add addition libraries.")
124 :rules (list (ede-makefile-rule 124 :rules (list (ede-makefile-rule
125 "c++-inference-rule-libtool" 125 "c++-inference-rule-libtool"
126 :target "%.o" 126 :target "%.o"
127 :dependencies "%.c" 127 :dependencies "%.cpp"
128 :rules '("@echo '$(LTCOMPILE) -o $@ $<'; \\" 128 :rules '("@echo '$(LTCOMPILE) -o $@ $<'; \\"
129 "$(LTCOMPILE) -o $@ $<" 129 "$(LTCOMPILE) -o $@ $<"
130 ) 130 )
diff --git a/lisp/cedet/ede/proj.el b/lisp/cedet/ede/proj.el
index 3cdf42dc841..41887431d31 100644
--- a/lisp/cedet/ede/proj.el
+++ b/lisp/cedet/ede/proj.el
@@ -29,7 +29,6 @@
29;; rebuild. The targets provided in ede-proj can be augmented with 29;; rebuild. The targets provided in ede-proj can be augmented with
30;; additional target types inherited directly from `ede-proj-target'. 30;; additional target types inherited directly from `ede-proj-target'.
31 31
32;; (eval-and-compile '(require 'ede))
33(require 'ede/proj-comp) 32(require 'ede/proj-comp)
34(require 'ede/make) 33(require 'ede/make)
35 34
@@ -336,7 +335,9 @@ Argument TARGET is the project we are completing customization on."
336 (or (string= (file-name-nondirectory (oref this file)) f) 335 (or (string= (file-name-nondirectory (oref this file)) f)
337 (string= (ede-proj-dist-makefile this) f) 336 (string= (ede-proj-dist-makefile this) f)
338 (string-match "Makefile\\(\\.\\(in\\|am\\)\\)?$" f) 337 (string-match "Makefile\\(\\.\\(in\\|am\\)\\)?$" f)
339 (string-match "config\\(ure\\.in\\|\\.stutus\\)?$" f) 338 (string-match "config\\(ure\\.\\(in\\|ac\\)\\|\\.status\\)?$" f)
339 (string-match "config.h\\(\\.in\\)?" f)
340 (member f '("AUTHORS" "NEWS" "COPYING" "INSTALL" "README"))
340 ))) 341 )))
341 342
342(defmethod ede-buffer-mine ((this ede-proj-target) buffer) 343(defmethod ede-buffer-mine ((this ede-proj-target) buffer)
@@ -398,11 +399,11 @@ Argument TARGET is the project we are completing customization on."
398 :source nil))) 399 :source nil)))
399 400
400(defmethod project-delete-target ((this ede-proj-target)) 401(defmethod project-delete-target ((this ede-proj-target))
401 "Delete the current target THIS from it's parent project." 402 "Delete the current target THIS from its parent project."
402 (let ((p (ede-current-project)) 403 (let ((p (ede-current-project))
403 (ts (oref this source))) 404 (ts (oref this source)))
404 ;; Loop across all sources. If it exists in a buffer, 405 ;; Loop across all sources. If it exists in a buffer,
405 ;; clear it's object. 406 ;; clear its object.
406 (while ts 407 (while ts
407 (let* ((default-directory (oref this path)) 408 (let* ((default-directory (oref this path))
408 (b (get-file-buffer (car ts)))) 409 (b (get-file-buffer (car ts))))
@@ -413,7 +414,7 @@ Argument TARGET is the project we are completing customization on."
413 (setq ede-object nil) 414 (setq ede-object nil)
414 (ede-apply-object-keymap)))))) 415 (ede-apply-object-keymap))))))
415 (setq ts (cdr ts))) 416 (setq ts (cdr ts)))
416 ;; Remove THIS from it's parent. 417 ;; Remove THIS from its parent.
417 ;; The two vectors should be pointer equivalent. 418 ;; The two vectors should be pointer equivalent.
418 (oset p targets (delq this (oref p targets))) 419 (oset p targets (delq this (oref p targets)))
419 (ede-proj-save (ede-current-project)))) 420 (ede-proj-save (ede-current-project))))
@@ -447,15 +448,13 @@ FILE must be massaged by `ede-convert-path'."
447 448
448(defmethod project-make-dist ((this ede-proj-project)) 449(defmethod project-make-dist ((this ede-proj-project))
449 "Build a distribution for the project based on THIS target." 450 "Build a distribution for the project based on THIS target."
450 ;; I'm a lazy bum, so I'll make a makefile for doing this sort
451 ;; of thing, and rely only on that small section of code.
452 (let ((pm (ede-proj-dist-makefile this)) 451 (let ((pm (ede-proj-dist-makefile this))
453 (df (project-dist-files this))) 452 (df (project-dist-files this)))
454 (if (and (file-exists-p (car df)) 453 (if (and (file-exists-p (car df))
455 (not (y-or-n-p "Dist file already exists. Rebuild? "))) 454 (not (y-or-n-p "Dist file already exists. Rebuild? ")))
456 (error "Try `ede-update-version' before making a distribution")) 455 (error "Try `ede-update-version' before making a distribution"))
457 (ede-proj-setup-buildenvironment this) 456 (ede-proj-setup-buildenvironment this)
458 (if (string= (file-name-nondirectory pm) "Makefile.am") 457 (if (ede-proj-automake-p this)
459 (setq pm (expand-file-name "Makefile" 458 (setq pm (expand-file-name "Makefile"
460 (file-name-directory pm)))) 459 (file-name-directory pm))))
461 (compile (concat ede-make-command " -f " pm " dist")))) 460 (compile (concat ede-make-command " -f " pm " dist"))))
@@ -473,7 +472,7 @@ Argument COMMAND is the command to use when compiling."
473 (let ((pm (ede-proj-dist-makefile proj)) 472 (let ((pm (ede-proj-dist-makefile proj))
474 (default-directory (file-name-directory (oref proj file)))) 473 (default-directory (file-name-directory (oref proj file))))
475 (ede-proj-setup-buildenvironment proj) 474 (ede-proj-setup-buildenvironment proj)
476 (if (string= (file-name-nondirectory pm) "Makefile.am") 475 (if (ede-proj-automake-p proj)
477 (setq pm (expand-file-name "Makefile" 476 (setq pm (expand-file-name "Makefile"
478 (file-name-directory pm)))) 477 (file-name-directory pm))))
479 (compile (concat ede-make-command" -f " pm " all")))) 478 (compile (concat ede-make-command" -f " pm " all"))))
@@ -539,7 +538,15 @@ Converts all symbols into the objects to be used."
539 (if (ede-want-any-source-files-p (symbol-value (car st)) sources) 538 (if (ede-want-any-source-files-p (symbol-value (car st)) sources)
540 (let ((c (ede-proj-find-compiler avail (car st)))) 539 (let ((c (ede-proj-find-compiler avail (car st))))
541 (if c (setq comp (cons c comp))))) 540 (if c (setq comp (cons c comp)))))
542 (setq st (cdr st))))) 541 (setq st (cdr st)))
542 ;; Provide a good error msg.
543 (unless comp
544 (error "Could not find compiler match for source code extension \"%s\".
545You may need to add support for this type of file."
546 (if sources
547 (file-name-extension (car sources))
548 "")))
549 ))
543 ;; Return the disovered compilers 550 ;; Return the disovered compilers
544 comp))) 551 comp)))
545 552
@@ -664,18 +671,9 @@ Optional argument FORCE will force items to be regenerated."
664 (let ((root (or (ede-project-root this) this)) 671 (let ((root (or (ede-project-root this) this))
665 ) 672 )
666 (setq ede-projects (delq root ede-projects)) 673 (setq ede-projects (delq root ede-projects))
667 (ede-proj-load (ede-project-root-directory root)) 674 (ede-load-project-file (ede-project-root-directory root))
668 )) 675 ))
669 676
670(defmethod project-rescan ((this ede-proj-target) readstream)
671 "Rescan target THIS from the read list READSTREAM."
672 (setq readstream (cdr (cdr readstream))) ;; constructor/name
673 (while readstream
674 (let ((tag (car readstream))
675 (val (car (cdr readstream))))
676 (eieio-oset this tag val))
677 (setq readstream (cdr (cdr readstream)))))
678
679(provide 'ede/proj) 677(provide 'ede/proj)
680 678
681;; arch-tag: eb8a40f8-0d2c-41c4-b273-af04101d1cdf 679;; arch-tag: eb8a40f8-0d2c-41c4-b273-af04101d1cdf
diff --git a/lisp/cedet/ede/project-am.el b/lisp/cedet/ede/project-am.el
index e126e4c0175..a76ea7138a8 100644
--- a/lisp/cedet/ede/project-am.el
+++ b/lisp/cedet/ede/project-am.el
@@ -30,27 +30,19 @@
30;; fashion. 30;; fashion.
31;; 31;;
32;; project-am uses the structure defined in all good GNU projects with 32;; project-am uses the structure defined in all good GNU projects with
33;; the Automake file as it's base template, and then maintains that 33;; the Automake file as its base template, and then maintains that
34;; information during edits, automatically updating the automake file 34;; information during edits, automatically updating the automake file
35;; where appropriate. 35;; where appropriate.
36 36
37
38;; (eval-and-compile
39;; ;; Compatibility for makefile mode.
40;; (condition-case nil
41;; (require 'makefile "make-mode")
42;; (error (require 'make-mode "make-mode")))
43
44;; ;; Requiring the .el files prevents incomplete builds.
45;; (require 'eieio "eieio.el")
46;; (require 'ede "ede.el"))
47
48(require 'make-mode) 37(require 'make-mode)
49(require 'ede) 38(require 'ede)
50(require 'ede/make) 39(require 'ede/make)
51(require 'ede/makefile-edit) 40(require 'ede/makefile-edit)
41(require 'semantic/find) ;; for semantic-find-tags-by-...
42(require 'ede/autoconf-edit)
52 43
53(declare-function autoconf-parameters-for-macro "ede/autoconf-edit") 44(declare-function autoconf-parameters-for-macro "ede/autoconf-edit")
45(declare-function ede-shell-run-something "ede/shell")
54(eval-when-compile (require 'compile)) 46(eval-when-compile (require 'compile))
55 47
56;;; Code: 48;;; Code:
@@ -104,7 +96,7 @@
104 ;; ("ltlibcustom" project-am-lib ".*?_LTLIBRARIES" t) 96 ;; ("ltlibcustom" project-am-lib ".*?_LTLIBRARIES" t)
105 ) 97 )
106 "Alist of type names and the type of object to create for them. 98 "Alist of type names and the type of object to create for them.
107Each entry is of th form: 99Each entry is of the form:
108 (EMACSNAME CLASS AUTOMAKEVAR INDIRECT) 100 (EMACSNAME CLASS AUTOMAKEVAR INDIRECT)
109where EMACSNAME is a name for Emacs to use. 101where EMACSNAME is a name for Emacs to use.
110CLASS is the EDE target class to represent the target. 102CLASS is the EDE target class to represent the target.
@@ -113,6 +105,23 @@ AUTOMAKEVAR is the Automake variable to identify. This cannot be a
113INDIRECT is optional. If it is non-nil, then the variable in 105INDIRECT is optional. If it is non-nil, then the variable in
114question lists other variables that need to be looked up.") 106question lists other variables that need to be looked up.")
115 107
108
109(defconst project-am-meta-type-alist
110 '((project-am-program "_PROGRAMS$" t)
111 (project-am-lib "_\\(LIBS\\|LIBRARIES\\|LTLIBRARIES\\)$" t)
112
113 ;; direct primary target use a dummy object (man target)
114 ;; update to: * 3.3 Uniform in automake-1.11 info node.
115 (project-am-man "_\\(DATA\\|HEADERS\\|PYTHON\\|JAVA\\|SCRIPTS\\|MANS\\|TEXINFOS\\)$" nil)
116 )
117 "Alist of meta-target type, each entry has form:
118 (CLASS REGEXPVAR INDIRECT)
119where CLASS is the EDE target class for target.
120REGEXPVAR is the regexp used in `semantic-find-tags-by-name-regexp'.
121INDIRECT is optional. If it is non-nil, then the variable in it have
122other meta-variable based on this name.")
123
124
116(defclass project-am-target (ede-target) 125(defclass project-am-target (ede-target)
117 nil 126 nil
118 "Base target class for everything in project-am.") 127 "Base target class for everything in project-am.")
@@ -291,16 +300,6 @@ buffer being in order to provide a smart default target type."
291 ;; Rescan the object in this makefile. 300 ;; Rescan the object in this makefile.
292 (project-rescan ede-object)))) 301 (project-rescan ede-object))))
293 302
294;(defun project-am-rescan-toplevel ()
295; "Rescan all projects in which the current buffer resides."
296; (interactive)
297; (let* ((tlof (project-am-find-topmost-level default-directory))
298; (tlo (project-am-load tlof))
299; (ede-deep-rescan t)) ; scan deep in this case.
300; ;; tlo is the top level object for whatever file we are in
301; ;; or nil. If we have an object, call the rescan method.
302; (if tlo (project-am-rescan tlo))))
303
304;; 303;;
305;; NOTE TO SELF 304;; NOTE TO SELF
306;; 305;;
@@ -404,6 +403,7 @@ Argument COMMAND is the command to use for compiling the target."
404 403
405(defmethod project-run-target ((obj project-am-objectcode)) 404(defmethod project-run-target ((obj project-am-objectcode))
406 "Run the current project target in comint buffer." 405 "Run the current project target in comint buffer."
406 (require 'ede/shell)
407 (let ((tb (get-buffer-create " *padt*")) 407 (let ((tb (get-buffer-create " *padt*"))
408 (dd (oref obj path)) 408 (dd (oref obj path))
409 (cmd nil)) 409 (cmd nil))
@@ -427,45 +427,17 @@ Argument COMMAND is the command to use for compiling the target."
427 427
428;;; Project loading and saving 428;;; Project loading and saving
429;; 429;;
430(defun project-am-load (project &optional rootproj) 430(defun project-am-load (directory &optional rootproj)
431 "Read an automakefile PROJECT into our data structure. 431 "Read an automakefile DIRECTORY into our data structure.
432Make sure that the tree down to our makefile is complete so that there
433is cohesion in the project. Return the project file (or sub-project).
434If a given set of projects has already been loaded, then do nothing 432If a given set of projects has already been loaded, then do nothing
435but return the project for the directory given. 433but return the project for the directory given.
436Optional ROOTPROJ is the root EDE project." 434Optional ROOTPROJ is the root EDE project."
437 ;; @TODO - rationalize this to the newer EDE way of doing things. 435 (let* ((ede-constructiong t)
438 (setq project (expand-file-name project)) 436 (amo (object-assoc (expand-file-name "Makefile.am" directory)
439 (let* ((ede-constructing t) 437 'file ede-projects)))
440 (fn (project-am-find-topmost-level (file-name-as-directory project))) 438 (when (not amo)
441 (amo nil) 439 (setq amo (project-am-load-makefile directory)))
442 (trimmed (if (string-match (regexp-quote fn) 440 amo))
443 project)
444 (replace-match "" t t project)
445 ""))
446 (subdir nil))
447 (setq amo (object-assoc (expand-file-name "Makefile.am" fn)
448 'file ede-projects))
449 (if amo
450 (error "Synchronous error in ede/project-am objects")
451 (let ((project-am-constructing t))
452 (setq amo (project-am-load-makefile fn))))
453 (if (not amo)
454 nil
455 ;; Now scan down from amo, and find the current directory
456 ;; from the PROJECT file.
457 (while (< 0 (length trimmed))
458 (if (string-match "\\([a-zA-Z0-9.-]+\\)/" trimmed)
459 (setq subdir (match-string 0 trimmed)
460 trimmed (replace-match "" t t trimmed))
461 (error "Error scanning down path for project"))
462 (setq amo (project-am-subtree
463 amo
464 (expand-file-name "Makefile.am"
465 (expand-file-name subdir fn)))
466 fn (expand-file-name subdir fn)))
467 amo)
468 ))
469 441
470(defun project-am-find-topmost-level (dir) 442(defun project-am-find-topmost-level (dir)
471 "Find the topmost automakefile starting with DIR." 443 "Find the topmost automakefile starting with DIR."
@@ -486,17 +458,19 @@ Kill the makefile if it was not loaded before the load."
486 (fb nil) 458 (fb nil)
487 (kb (get-file-buffer fn))) 459 (kb (get-file-buffer fn)))
488 (if (not (file-exists-p fn)) 460 (if (not (file-exists-p fn))
489 nil 461 nil
490 (save-excursion 462 (save-excursion
491 (if kb (setq fb kb) 463 (if kb (setq fb kb)
492 ;; We need to find-file this thing, but don't use 464 ;; We need to find-file this thing, but don't use
493 ;; any semantic features. 465 ;; any semantic features.
494 (let ((semantic-init-hook nil)) 466 (let ((semantic-init-hook nil)
495 (setq fb (find-file-noselect fn))) 467 (recentf-exclude '( (lambda (f) t) ))
496 ) 468 )
497 (set-buffer fb) 469 (setq fb (find-file-noselect fn)))
498 (prog1 ,@forms 470 )
499 (if (not kb) (kill-buffer (current-buffer)))))))) 471 (set-buffer fb)
472 (prog1 ,@forms
473 (if (not kb) (kill-buffer (current-buffer))))))))
500(put 'project-am-with-makefile-current 'lisp-indent-function 1) 474(put 'project-am-with-makefile-current 'lisp-indent-function 1)
501 475
502(add-hook 'edebug-setup-hook 476(add-hook 'edebug-setup-hook
@@ -505,14 +479,18 @@ Kill the makefile if it was not loaded before the load."
505 (form def-body)))) 479 (form def-body))))
506 480
507 481
508(defun project-am-load-makefile (path) 482(defun project-am-load-makefile (path &optional suggestedname)
509 "Convert PATH into a project Makefile, and return its project object. 483 "Convert PATH into a project Makefile, and return its project object.
510It does not check for existing project objects. Use `project-am-load'." 484It does not check for existing project objects. Use `project-am-load'.
485Optional argument SUGGESTEDNAME will be the project name.
486This is used when subprojects are made in named subdirectories."
511 (project-am-with-makefile-current path 487 (project-am-with-makefile-current path
512 (if (and ede-object (project-am-makefile-p ede-object)) 488 (if (and ede-object (project-am-makefile-p ede-object))
513 ede-object 489 ede-object
514 (let* ((pi (project-am-package-info path)) 490 (let* ((pi (project-am-package-info path))
515 (pn (or (nth 0 pi) (project-am-last-dir fn))) 491 (sfn (when suggestedname
492 (project-am-last-dir suggestedname)))
493 (pn (or sfn (nth 0 pi) (project-am-last-dir fn)))
516 (ver (or (nth 1 pi) "0.0")) 494 (ver (or (nth 1 pi) "0.0"))
517 (bug (nth 2 pi)) 495 (bug (nth 2 pi))
518 (cof (nth 3 pi)) 496 (cof (nth 3 pi))
@@ -530,21 +508,6 @@ It does not check for existing project objects. Use `project-am-load'."
530 ampf)))) 508 ampf))))
531 509
532;;; Methods: 510;;; Methods:
533(defmethod ede-find-target ((amf project-am-makefile) buffer)
534 "Fetch the target belonging to BUFFER."
535 (or (call-next-method)
536 (let ((targ (oref amf targets))
537 (sobj (oref amf subproj))
538 (obj nil))
539 (while (and targ (not obj))
540 (if (ede-buffer-mine (car targ) buffer)
541 (setq obj (car targ)))
542 (setq targ (cdr targ)))
543 (while (and sobj (not obj))
544 (setq obj (project-am-buffer-object (car sobj) buffer)
545 sobj (cdr sobj)))
546 obj)))
547
548(defmethod project-targets-for-file ((proj project-am-makefile)) 511(defmethod project-targets-for-file ((proj project-am-makefile))
549 "Return a list of targets the project PROJ." 512 "Return a list of targets the project PROJ."
550 (oref proj targets)) 513 (oref proj targets))
@@ -554,44 +517,110 @@ It does not check for existing project objects. Use `project-am-load'."
554CURRPROJ is the current project being scanned. 517CURRPROJ is the current project being scanned.
555DIR is the directory to apply to new targets." 518DIR is the directory to apply to new targets."
556 (let* ((otargets (oref currproj targets)) 519 (let* ((otargets (oref currproj targets))
520 ;; `ntargets' results in complete targets list
521 ;; not only the new targets by diffing.
557 (ntargets nil) 522 (ntargets nil)
558 (tmp nil) 523 (tmp nil)
559 ) 524 )
560 (mapc 525
561 ;; Map all the different types 526 (mapc
562 (lambda (typecar) 527 ;; Map all the different types
563 (let ((macro (nth 2 typecar)) 528 (lambda (typecar)
564 (class (nth 1 typecar)) 529 (let ((macro (nth 2 typecar))
565 (indirect (nth 3 typecar)) 530 (class (nth 1 typecar))
566 ;(name (car typecar)) 531 (indirect (nth 3 typecar))
567 )
568 (if indirect
569 ;; Map all the found objects
570 (mapc (lambda (lstcar)
571 (setq tmp (object-assoc lstcar 'name otargets))
572 (when (not tmp)
573 (setq tmp (apply class lstcar :name lstcar
574 :path dir nil)))
575 (project-rescan tmp)
576 (setq ntargets (cons tmp ntargets)))
577 (makefile-macro-file-list macro))
578 ;; Non-indirect will have a target whos sources
579 ;; are actual files, not names of other targets.
580 (let ((files (makefile-macro-file-list macro)))
581 (when files
582 (setq tmp (object-assoc macro 'name otargets))
583 (when (not tmp)
584 (setq tmp (apply class macro :name macro
585 :path dir nil)))
586 (project-rescan tmp)
587 (setq ntargets (cons tmp ntargets))
588 ))
589 ) 532 )
590 )) 533 (if indirect
591 project-am-type-alist) 534 ;; Map all the found objects
592 ntargets)) 535 (mapc (lambda (lstcar)
536 (setq tmp (object-assoc lstcar 'name otargets))
537 (when (not tmp)
538 (setq tmp (apply class lstcar :name lstcar
539 :path dir nil)))
540 (project-rescan tmp)
541 (setq ntargets (cons tmp ntargets)))
542 (makefile-macro-file-list macro))
543 ;; Non-indirect will have a target whos sources
544 ;; are actual files, not names of other targets.
545 (let ((files (makefile-macro-file-list macro)))
546 (when files
547 (setq tmp (object-assoc macro 'name otargets))
548 (when (not tmp)
549 (setq tmp (apply class macro :name macro
550 :path dir nil)))
551 (project-rescan tmp)
552 (setq ntargets (cons tmp ntargets))
553 ))
554 )
555 ))
556 project-am-type-alist)
557
558 ;; At now check variables for meta-target regexp
559 ;; We have to check ntargets to avoid useless rescan.
560 ;; Also we have check otargets to prevent duplication.
561 (mapc
562 (lambda (typecar)
563 (let ((class (nth 0 typecar))
564 (metaregex (nth 1 typecar))
565 (indirect (nth 2 typecar)))
566 (if indirect
567 ;; Map all the found objects
568 (mapc
569 (lambda (lstcar)
570 (unless (object-assoc lstcar 'name ntargets)
571 (or
572 (setq tmp (object-assoc lstcar 'name otargets))
573 (setq tmp (apply class lstcar :name lstcar
574 :path dir nil)))
575 (project-rescan tmp)
576 (setq ntargets (cons tmp ntargets))))
577 ;; build a target list to map over
578 (let (atargets)
579 (dolist (TAG
580 (semantic-find-tags-by-name-regexp
581 metaregex (semantic-find-tags-by-class
582 'variable (semantic-fetch-tags))))
583 ;; default-value have to be a list
584 (when (cadr (assoc ':default-value TAG))
585 (setq atargets
586 (append
587 (nreverse (cadr (assoc ':default-value TAG)))
588 atargets))))
589 (nreverse atargets)))
590
591 ;; else not indirect, TODO: FIX various direct meta type in a sane way.
592 (dolist (T (semantic-find-tags-by-name-regexp
593 metaregex (semantic-find-tags-by-class
594 'variable (semantic-fetch-tags))))
595 (unless (setq tmp (object-assoc (car T) 'name ntargets))
596 (or (setq tmp (object-assoc (car T) 'name otargets))
597 ;; we are really new
598 (setq tmp (apply class (car T) :name (car T)
599 :path dir nil)))
600 (project-rescan tmp)
601 (setq ntargets (cons tmp ntargets))))
602 )))
603 project-am-meta-type-alist)
604 ntargets))
605
606(defun project-am-expand-subdirlist (place subdirs)
607 "Store in PLACE the SUBDIRS expanded from variables.
608Strip out duplicates, and recurse on variables."
609 (mapc (lambda (sp)
610 (let ((var (makefile-extract-varname-from-text sp)))
611 (if var
612 ;; If it is a variable, expand that variable, and keep going.
613 (project-am-expand-subdirlist
614 place (makefile-macro-file-list var))
615 ;; Else, add SP in if it isn't a dup.
616 (if (member sp (symbol-value place))
617 nil ; don't do it twice.
618 (set place (cons sp (symbol-value place))) ;; add
619 ))))
620 subdirs)
621 )
593 622
594(defmethod project-rescan ((this project-am-makefile)) 623(defmethod project-rescan ((this project-am-makefile) &optional suggestedname)
595 "Rescan the makefile for all targets and sub targets." 624 "Rescan the makefile for all targets and sub targets."
596 (project-am-with-makefile-current (file-name-directory (oref this file)) 625 (project-am-with-makefile-current (file-name-directory (oref this file))
597 ;;(message "Scanning %s..." (oref this file)) 626 ;;(message "Scanning %s..." (oref this file))
@@ -601,10 +630,10 @@ DIR is the directory to apply to new targets."
601 (bug (nth 2 pi)) 630 (bug (nth 2 pi))
602 (cof (nth 3 pi)) 631 (cof (nth 3 pi))
603 (osubproj (oref this subproj)) 632 (osubproj (oref this subproj))
604 (csubproj (or 633 ;; 1/30/10 - We need to append these two lists together,
605 ;; If DIST_SUBDIRS doesn't exist, then go for the 634 ;; then strip out duplicates. Expanding this list (via
606 ;; static list of SUBDIRS. The DIST version should 635 ;; references to other variables should also strip out dups
607 ;; contain SUBDIRS plus extra stuff. 636 (csubproj (append
608 (makefile-macro-file-list "DIST_SUBDIRS") 637 (makefile-macro-file-list "DIST_SUBDIRS")
609 (makefile-macro-file-list "SUBDIRS"))) 638 (makefile-macro-file-list "SUBDIRS")))
610 (csubprojexpanded nil) 639 (csubprojexpanded nil)
@@ -615,79 +644,57 @@ DIR is the directory to apply to new targets."
615 (tmp nil) 644 (tmp nil)
616 (ntargets (project-am-scan-for-targets this dir)) 645 (ntargets (project-am-scan-for-targets this dir))
617 ) 646 )
618 647 (if suggestedname
619 (and pn (string= (directory-file-name 648 (oset this name (project-am-last-dir suggestedname))
620 (oref this directory)) 649 ;; Else, setup toplevel project info.
621 (directory-file-name 650 (and pn (string= (directory-file-name
622 (project-am-find-topmost-level 651 (oref this directory))
623 (oref this directory)))) 652 (directory-file-name
624 (oset this name pn) 653 (project-am-find-topmost-level
625 (and pv (oset this version pv)) 654 (oref this directory))))
626 (and bug (oset this mailinglist bug)) 655 (oset this name pn)
627 (oset this configureoutputfiles cof)) 656 (and pv (oset this version pv))
628 657 (and bug (oset this mailinglist bug))
629; ;; LISP is different. Here there is only one kind of lisp (that I know of 658 (oset this configureoutputfiles cof)))
630; ;; anyway) so it doesn't get mapped when it is found.
631; (if (makefile-move-to-macro "lisp_LISP")
632; (let ((tmp (project-am-lisp "lisp"
633; :name "lisp"
634; :path dir)))
635; (project-rescan tmp)
636; (setq ntargets (cons tmp ntargets))))
637;
638 ;; Now that we have this new list, chuck the old targets 659 ;; Now that we have this new list, chuck the old targets
639 ;; and replace it with the new list of targets I just created. 660 ;; and replace it with the new list of targets I just created.
640 (oset this targets (nreverse ntargets)) 661 (oset this targets (nreverse ntargets))
641 ;; We still have a list of targets. For all buffers, make sure 662 ;; We still have a list of targets. For all buffers, make sure
642 ;; their object still exists! 663 ;; their object still exists!
643
644 ;; FIGURE THIS OUT 664 ;; FIGURE THIS OUT
645 665 (project-am-expand-subdirlist 'csubprojexpanded csubproj)
646 (mapc (lambda (sp)
647 (let ((var (makefile-extract-varname-from-text sp))
648 )
649 (if (not var)
650 (setq csubprojexpanded (cons sp csubprojexpanded))
651 ;; If it is a variable, expand that variable, and keep going.
652 (let ((varexp (makefile-macro-file-list var)))
653 (dolist (V varexp)
654 (setq csubprojexpanded (cons V csubprojexpanded)))))
655 ))
656 csubproj)
657
658 ;; Ok, now lets look at all our sub-projects. 666 ;; Ok, now lets look at all our sub-projects.
659 (mapc (lambda (sp) 667 (mapc (lambda (sp)
660 (let* ((subdir (file-name-as-directory 668 (let* ((subdir (file-name-as-directory
661 (expand-file-name 669 (expand-file-name
662 sp (file-name-directory (oref this :file))))) 670 sp (file-name-directory (oref this :file)))))
663 (submake (expand-file-name 671 (submake (expand-file-name
664 "Makefile.am" 672 "Makefile.am"
665 subdir))) 673 subdir)))
666 (if (string= submake (oref this :file)) 674 (if (string= submake (oref this :file))
667 nil ;; don't recurse.. please! 675 nil ;; don't recurse.. please!
668 676 ;; For each project id found, see if we need to recycle,
669 ;; For each project id found, see if we need to recycle, 677 ;; and if we do not, then make a new one. Check the deep
670 ;; and if we do not, then make a new one. Check the deep 678 ;; rescan value for behavior patterns.
671 ;; rescan value for behavior patterns. 679 (setq tmp (object-assoc
672 (setq tmp (object-assoc 680 submake
673 submake 681 'file osubproj))
674 'file osubproj)) 682 (if (not tmp)
675 (if (not tmp) 683 (setq tmp
676 (setq tmp 684 (condition-case nil
677 (condition-case nil 685 ;; In case of problem, ignore it.
678 ;; In case of problem, ignore it. 686 (project-am-load-makefile subdir subdir)
679 (project-am-load-makefile subdir) 687 (error nil)))
680 (error nil))) 688 ;; If we have tmp, then rescan it only if deep mode.
681 ;; If we have tmp, then rescan it only if deep mode. 689 (if ede-deep-rescan
682 (if ede-deep-rescan 690 (project-rescan tmp subdir)))
683 (project-rescan tmp))) 691 ;; Tac tmp onto our list of things to keep, but only
684 ;; Tac tmp onto our list of things to keep, but only 692 ;; if tmp was found.
685 ;; if tmp was found. 693 (when tmp
686 (when tmp 694 ;;(message "Adding %S" (object-print tmp))
687 ;;(message "Adding %S" (object-print tmp)) 695 (setq nsubproj (cons tmp nsubproj)))))
688 (setq nsubproj (cons tmp nsubproj))))) 696 )
689 ) 697 (nreverse csubprojexpanded))
690 (nreverse csubprojexpanded))
691 (oset this subproj nsubproj) 698 (oset this subproj nsubproj)
692 ;; All elements should be updated now. 699 ;; All elements should be updated now.
693 ))) 700 )))
@@ -696,12 +703,16 @@ DIR is the directory to apply to new targets."
696(defmethod project-rescan ((this project-am-program)) 703(defmethod project-rescan ((this project-am-program))
697 "Rescan object THIS." 704 "Rescan object THIS."
698 (oset this :source (makefile-macro-file-list (project-am-macro this))) 705 (oset this :source (makefile-macro-file-list (project-am-macro this)))
706 (unless (oref this :source)
707 (oset this :source (list (concat (oref this :name) ".c"))))
699 (oset this :ldadd (makefile-macro-file-list 708 (oset this :ldadd (makefile-macro-file-list
700 (concat (oref this :name) "_LDADD")))) 709 (concat (oref this :name) "_LDADD"))))
701 710
702(defmethod project-rescan ((this project-am-lib)) 711(defmethod project-rescan ((this project-am-lib))
703 "Rescan object THIS." 712 "Rescan object THIS."
704 (oset this :source (makefile-macro-file-list (project-am-macro this)))) 713 (oset this :source (makefile-macro-file-list (project-am-macro this)))
714 (unless (oref this :source)
715 (oset this :source (list (concat (file-name-sans-extension (oref this :name)) ".c")))))
705 716
706(defmethod project-rescan ((this project-am-texinfo)) 717(defmethod project-rescan ((this project-am-texinfo))
707 "Rescan object THIS." 718 "Rescan object THIS."
@@ -726,19 +737,6 @@ DIR is the directory to apply to new targets."
726(defmethod project-rescan ((this project-am-extra-dist)) 737(defmethod project-rescan ((this project-am-extra-dist))
727 "Rescan object THIS." 738 "Rescan object THIS."
728 (oset this :source (makefile-macro-file-list "EXTRA_DIST"))) 739 (oset this :source (makefile-macro-file-list "EXTRA_DIST")))
729 ;; NOTE: The below calls 'file' then checks that it is some sort of
730 ;; text file. The file command may not be available on all platforms
731 ;; and some files may not exist yet. (ie - auto-generated)
732
733 ;;(mapc
734 ;; (lambda (f)
735 ;; ;; prevent garbage to be parsed, could we use :aux ?
736 ;; (if (and (not (member f (oref this :source)))
737 ;; (string-match-p "ASCII\\|text"
738 ;; (shell-command-to-string
739 ;; (concat "file " f))))
740 ;; (oset this :source (cons f (oref this :source)))))
741 ;; (makefile-macro-file-list "EXTRA_DIST")))
742 740
743(defmethod project-am-macro ((this project-am-objectcode)) 741(defmethod project-am-macro ((this project-am-objectcode))
744 "Return the default macro to 'edit' for this object type." 742 "Return the default macro to 'edit' for this object type."
@@ -808,22 +806,24 @@ nil means that this buffer belongs to no-one."
808 806
809(defmethod ede-buffer-mine ((this project-am-objectcode) buffer) 807(defmethod ede-buffer-mine ((this project-am-objectcode) buffer)
810 "Return t if object THIS lays claim to the file in BUFFER." 808 "Return t if object THIS lays claim to the file in BUFFER."
811 (member (file-name-nondirectory (buffer-file-name buffer)) 809 (member (file-relative-name (buffer-file-name buffer) (oref this :path))
812 (oref this :source))) 810 (oref this :source)))
813 811
814(defmethod ede-buffer-mine ((this project-am-texinfo) buffer) 812(defmethod ede-buffer-mine ((this project-am-texinfo) buffer)
815 "Return t if object THIS lays claim to the file in BUFFER." 813 "Return t if object THIS lays claim to the file in BUFFER."
816 (let ((bfn (buffer-file-name buffer))) 814 (let ((bfn (file-relative-name (buffer-file-name buffer)
817 (or (string= (oref this :name) (file-name-nondirectory bfn)) 815 (oref this :path))))
818 (member (file-name-nondirectory bfn) (oref this :include))))) 816 (or (string= (oref this :name) bfn)
817 (member bfn (oref this :include)))))
819 818
820(defmethod ede-buffer-mine ((this project-am-man) buffer) 819(defmethod ede-buffer-mine ((this project-am-man) buffer)
821 "Return t if object THIS lays claim to the file in BUFFER." 820 "Return t if object THIS lays claim to the file in BUFFER."
822 (string= (oref this :name) (buffer-file-name buffer))) 821 (string= (oref this :name)
822 (file-relative-name (buffer-file-name buffer) (oref this :path))))
823 823
824(defmethod ede-buffer-mine ((this project-am-lisp) buffer) 824(defmethod ede-buffer-mine ((this project-am-lisp) buffer)
825 "Return t if object THIS lays claim to the file in BUFFER." 825 "Return t if object THIS lays claim to the file in BUFFER."
826 (member (file-name-nondirectory (buffer-file-name buffer)) 826 (member (file-relative-name (buffer-file-name buffer) (oref this :path))
827 (oref this :source))) 827 (oref this :source)))
828 828
829(defmethod project-am-subtree ((ampf project-am-makefile) subdir) 829(defmethod project-am-subtree ((ampf project-am-makefile) subdir)
@@ -954,7 +954,6 @@ Kill the Configure buffer if it was not already in a buffer."
954 (cond 954 (cond
955 ;; Try configure.in or configure.ac 955 ;; Try configure.in or configure.ac
956 (conf-in 956 (conf-in
957 (require 'ede/autoconf-edit)
958 (project-am-with-config-current conf-in 957 (project-am-with-config-current conf-in
959 (let ((aci (autoconf-parameters-for-macro "AC_INIT")) 958 (let ((aci (autoconf-parameters-for-macro "AC_INIT"))
960 (aia (autoconf-parameters-for-macro "AM_INIT_AUTOMAKE")) 959 (aia (autoconf-parameters-for-macro "AM_INIT_AUTOMAKE"))
@@ -980,7 +979,7 @@ Kill the Configure buffer if it was not already in a buffer."
980 (t acf)))) 979 (t acf))))
981 (if (> (length outfiles) 1) 980 (if (> (length outfiles) 1)
982 (setq configfiles outfiles) 981 (setq configfiles outfiles)
983 (setq configfiles (split-string (car outfiles) " " t))) 982 (setq configfiles (split-string (car outfiles) "\\s-" t)))
984 ) 983 )
985 )) 984 ))
986 ) 985 )
@@ -1005,6 +1004,18 @@ Calculates the info with `project-am-extract-package-info'."
1005 (when top (setq dir (oref top :directory))) 1004 (when top (setq dir (oref top :directory)))
1006 (project-am-extract-package-info dir))) 1005 (project-am-extract-package-info dir)))
1007 1006
1007;; for simple per project include path extension
1008(defmethod ede-system-include-path ((this project-am-makefile))
1009 "Return `project-am-localvars-include-path', usually local variable
1010per file or in .dir-locals.el or similar."
1011 (bound-and-true-p project-am-localvars-include-path))
1012
1013(defmethod ede-system-include-path ((this project-am-target))
1014 "Return `project-am-localvars-include-path', usually local variable
1015per file or in .dir-locals.el or similar."
1016 (bound-and-true-p project-am-localvars-include-path))
1017
1018
1008(provide 'ede/project-am) 1019(provide 'ede/project-am)
1009 1020
1010;; arch-tag: 528db935-f186-4240-b647-e305c5b784a2 1021;; arch-tag: 528db935-f186-4240-b647-e305c5b784a2
diff --git a/lisp/cedet/ede/shell.el b/lisp/cedet/ede/shell.el
index edc75f42dee..d967a878350 100644
--- a/lisp/cedet/ede/shell.el
+++ b/lisp/cedet/ede/shell.el
@@ -70,7 +70,7 @@ COMMAND is a text string representing the thing to be run."
70(defmethod ede-shell-buffer ((target ede-target)) 70(defmethod ede-shell-buffer ((target ede-target))
71 "Get the buffer for running shell commands for TARGET." 71 "Get the buffer for running shell commands for TARGET."
72 (let ((name (ede-name target))) 72 (let ((name (ede-name target)))
73 (get-buffer-create (format "*EDE Shell %s" name)))) 73 (get-buffer-create (format "*EDE Shell %s*" name))))
74 74
75(provide 'ede/shell) 75(provide 'ede/shell)
76 76
diff --git a/lisp/cedet/ede/simple.el b/lisp/cedet/ede/simple.el
index e0a526e9ead..a1ac52c29a1 100644
--- a/lisp/cedet/ede/simple.el
+++ b/lisp/cedet/ede/simple.el
@@ -21,6 +21,10 @@
21 21
22;;; Commentary: 22;;; Commentary:
23;; 23;;
24;; NOTE: EDE Simple Projects are considered obsolete. Use generic
25;; projects instead. They have much better automatic support and
26;; simpler configuration.
27;;
24;; A vast majority of projects use non-EDE project techniques, such 28;; A vast majority of projects use non-EDE project techniques, such
25;; as hand written Makefiles, or other IDE's. 29;; as hand written Makefiles, or other IDE's.
26;; 30;;
@@ -41,6 +45,14 @@
41 45
42;;; Code: 46;;; Code:
43 47
48(add-to-list 'ede-project-class-files
49 (ede-project-autoload "simple-overlay"
50 :name "Simple" :file 'ede-simple
51 :proj-file 'ede-simple-projectfile-for-dir
52 :load-type 'ede-simple-load
53 :class-sym 'ede-simple-project)
54 t)
55
44(defcustom ede-simple-save-directory "~/.ede" 56(defcustom ede-simple-save-directory "~/.ede"
45 "*Directory where simple EDE project overlays are saved." 57 "*Directory where simple EDE project overlays are saved."
46 :group 'ede 58 :group 'ede
diff --git a/lisp/cedet/ede/speedbar.el b/lisp/cedet/ede/speedbar.el
index 3a961787f9a..466705175ed 100644
--- a/lisp/cedet/ede/speedbar.el
+++ b/lisp/cedet/ede/speedbar.el
@@ -108,7 +108,7 @@ Argument DIR is the directory from which to derive the list of objects."
108;;; Some special commands useful in EDE 108;;; Some special commands useful in EDE
109;; 109;;
110(defun ede-speedbar-remove-file-from-target () 110(defun ede-speedbar-remove-file-from-target ()
111 "Remove the file at point from it's target." 111 "Remove the file at point from its target."
112 (interactive) 112 (interactive)
113 (if (stringp (speedbar-line-token)) 113 (if (stringp (speedbar-line-token))
114 (progn 114 (progn
diff --git a/lisp/cedet/ede/srecode.el b/lisp/cedet/ede/srecode.el
index d68c620a1ab..3b131dd3753 100644
--- a/lisp/cedet/ede/srecode.el
+++ b/lisp/cedet/ede/srecode.el
@@ -43,7 +43,9 @@
43 (srecode-map-update-map t) 43 (srecode-map-update-map t)
44 ;; We don't call this unless we need it. Load in the templates. 44 ;; We don't call this unless we need it. Load in the templates.
45 (srecode-load-tables-for-mode 'makefile-mode) 45 (srecode-load-tables-for-mode 'makefile-mode)
46 (srecode-load-tables-for-mode 'makefile-mode 'ede)) 46 (srecode-load-tables-for-mode 'makefile-mode 'ede)
47 (srecode-load-tables-for-mode 'autoconf-mode)
48 (srecode-load-tables-for-mode 'autoconf-mode 'ede))
47 49
48(defmacro ede-srecode-insert-with-dictionary (template &rest forms) 50(defmacro ede-srecode-insert-with-dictionary (template &rest forms)
49 "Insert TEMPLATE after executing FORMS with a dictionary. 51 "Insert TEMPLATE after executing FORMS with a dictionary.