aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Engster2014-11-10 01:04:30 +0100
committerDavid Engster2014-11-10 01:04:30 +0100
commit5d4da32d4ec662febf3a2f59b713229867f743cb (patch)
tree2ea5eb48dd6dee72f4bbb56bb22922454a91c9a4
parentd3dba954b3fbbbad3d858756999752328ab6cee6 (diff)
downloademacs-5d4da32d4ec662febf3a2f59b713229867f743cb.tar.gz
emacs-5d4da32d4ec662febf3a2f59b713229867f743cb.zip
Update from CEDET trunk.
* grammars/c.by (template-type): Add :template-specifier and :typevar to capture extra details about the template. (opt-post-fcn-modifiers): Splice in the found symbol into the return value correctly. (QUESTION): New punctuation. (expression): Add ternary conditional support. * grammars/scheme.by (MODULE): New token. (scheme): Handle expanding the MODULE tag. (scheme-list): Remove closeparen required match. (scheme-in-list): Remove extraneous matches for DEFINE. Add support for MODULE Simplify matching for code & make work. (name-args, name-arg-list, name-arg-expand): Make it work. * semantic.el (semantic-mode): Add/remove 3 completion-at-point-functions. (semantic-completion-at-point-function): Removed. (semantic-analyze-completion-at-point-function) (semantic-analyze-notc-completion-at-point-function) (semantic-analyze-nolongprefix-completion-at-point-function): New completion at point functions. * semantic/doc.el (semantic-doc-snarf-comment-for-tag): Fix case when comment-end is empty string. * semantic/debug.el (semantic-debug-parser-debugger-source): New buffer local variable. (semantic-debug-interface): Add 'nil' initform to overlays. (semantic-debug-mode): Remove read-only tags from buffers on exit. (semantic-debug): Add autoload cookie. Force the language specific debugger to load. * semantic/db.el (generic::semanticdb-full-filename): New generic method to allow this method to be used on buffer names via an associated database. * semantic/symref.el (semantic-symref-cleanup-recent-buffers-fcn): When cleaning up buffers, don't clean up buffers that are being used (i.e., in a window) when the hook fires. (semantic-symref-recently-opened-buffers): New tracking variable. (semantic-symref-cleanup-recent-buffers-fcn): New hook fcn. (semantic-symref-result-get-tags): Move logic into `semantic-symref-hit-to-tag-via-buffer', and cleanup buffers via the symref cleanup function in post-command-hook. (semantic-symref-hit-to-tag-via-buffer): Logic that used to be from above. (semantic-symref-hit-to-tag-via-db): New. * semantic/analyze.el: (semantic-analyze-find-tag-sequence-default): If first entry in sequence is the only one, apply tagclass filter. (semantic-analyze-princ-sequence): Show slot even if empty. (semantic-analyze-find-tag-sequence) (semantic-analyze-find-tag-sequence-default): Add flags argument. Add support for forcing the final entry of the sequence to be of class variable. (semantic-analyze-find-tag): Fix bug where input class filter was ignored if there was a typecache match. (semantic-analyze-current-context-default): For assignments, the assignee now must be of class variable. * semantic/analyze/complete.el (semantic-analyze-possible-completions-default): Add 'no-longprefix' flag. When used, the prefix and prefixtypes are shortened to just the last symbol. * semantic/bovine/c.el (semantic-c-do-lex-if): Catch errors from 'hideif', and push to the parser warning stack. (semantic-lex-cpp-define): When a comment is at the end of a macro, do not subtract an extra 1 from the found position. Fixes bug with: #define foo (a)/**/ adding an extra ')' to the stream. * semantic/bovine/scm.el (semantic-lex-scheme-symbol): Allow symbols to be one char long. * semantic/bovine/grammar.el (bovine-grammar-calculate-source-on-path): New. (bovine-grammar-setupcode-builder): Use it. * ede.el (ede/detect): New require. (ede-version): Bump version (ede-initialize-state-current-buffer): Use new `ede-detect-directory-for-project' to detect projects first instead of depending on currente dir only. (ede-delete-project-from-global-list): New. (ede-flush-deleted-projects): Use above. (ede-check-project-query-fcn): New variable (ede-check-project-directory): Use above when querying the user. Added to support unit testing of this security measure. (ede-initialize-state-current-buffer): Use `ede-directory-project-cons' instead of the -detect- fcn to take advantage of the cache. Pass found project into `ede-load-project-file'. (ede-load-project-file): Add new input DETECTIN. (ede-rescan-toplevel): Get the proj root a better way. (ede-load-project-file): Return the loaded object. When asking for existing project, ask for an exact match. (ede-initialize-state-current-buffer): Simplify some conditional logic. (ede-load-project-file): Simplify conditional logic. (ede-global-list-sanity-check): New Testing fcn. (ede-parent-project): Replace old code with call to faster `ede-find-subproject-for-directory'. (ede-load-project-file): Use `ede-directory-get-toplevel-open-project' instead of above deleted. Rename "pfc" to "autoloader". Use `ede-directory-project-cons' to detect a project. Delete no project found case where we search up the tree. * ede/auto.el (ede-project-autoload): Fix doc typo. Add `:root-only' slot. (ede-auto-load-project): Doc update: warn to not use. (ede-dir-to-projectfile): Deleted. (ede-project-autoload-dirmatch): Add subdir-only slot. Make configdatastash unbound by default. (ede-do-dirmatch): If subdir-only is true, then don't allow exact matches. Account for configdatastash as unbound. Assume value of nil means no tool installed. Make sure loaded path matches from beginning. Stash the regexp, not the raw string. (ede-project-class-files): Note that makefile and automake are not root only. (ede-auto-detect-in-dir): New (for use with `ede/detect.el'). (ede-project-dirmatch-p): Deleted. (ede-project-root-directory): Remove body, return nil. (ede-project-autoload): :proj-root-dirmatch can be null & doc fix. (ede-auto-detect-in-dir): If there is no :proj-file, check for a dirmatch. * ede/generic.el (ede/config): Replace require of ede. (ede-generic-new-autoloader): Generic projects are now safe by default. Note this is NOT a root only project. (project-rescan, ede-project-root, ede-generic-target-java) (ede-java-classpath, ede-find-subproject-for-directory): New. (ede-enable-generic-projects): Add new autoloaders for git, bzr, hg, sv, CVS. (ede-generic-vc-project) (ede-generic-vc-project::ede-generic-setup-configuration): New. (ede-generic-config): Remove slots: c-include-path, c-preprocessor-table, c-preprocessor-files, classpath, build-command, debug-command, run command. Inherit from ede-extra-config-build, ede-extra-config-program. Make run-command :value match :custom so only strings are accepted. Add some more :group slot specifiers. (ede-generic-project): Add mixins `ede-project-with-config-c' and `ede-project-with-config-java'. Inherit from `ede-project-with-config-build', `ede-project-with-config-program'. Subclass `ede-project-with-config'. Remove duplication from new baseclass. (ede-generic-target): Inherit from `ede-target-with-config-build', `ede-target-with-config-program'. Subclass `ede-target-with-config'. (ede-generic-target-c-cpp): Add mixin `ede-target-with-config-c'. (ede-generic-target-java): Add mixin `ede-target-with-config-java'. (ede-preprocessor-map, ede-system-include-path) (edejava-classpath): Deleted, moved to config.el. (project-compile-project, project-compile-target) (project-debug-target, project-run-target): Deleted. (ede-generic-get-configuration, ede-generic-setup-configuration) (ede-commit-project, project-rescan) (ede-generic-project::ede-customize) (ede-generic-target::ede-customize) (ede-generic-config::eieio-done-customizing) (ede-generic-config::ede-commit): Deleted. Subsumed by new baseclass. (ede-preprocessor-map, ede-system-include-path) (project-debug-target, project-run-target): Call new `ede-config-get-configuration' instead of old version. (ede-generic-load): Do not add to global list here. * ede/files.el (ede-find-project-root) (ede-files-find-existing) (ede-directory-get-toplevel-open-project-new): Deleted. (ede-project-root-directory): Use `ede-project-root' first. (ede-project-directory-remove-hash) (ede--directory-project-from-hash) (ede--directory-project-add-description-to-hash): Rename to make internal symbols (via --). Expand input dir first. (ede-directory-project-p): Doc fix (note obsoleted.) (ede-toplevel-project-or-nil): Alias to `ede-toplevel-project'. (ede-toplevel-project): Doc Fix. Delete commented out old code. Simplify returning result from ede-detect-directory-for-project. (ede-directory-get-open-project): Support when inodes are disabled. If disabled to str compare on root project. (ede-directory-get-toplevel-open-project): Enabled nested projects. When doing directory name matching, save the 'short' version of an answer (non-exact match) and eventually select the shortest answer at the end. Expand the filename of tested projects. Better support for when inodes are disabled. Add 'exact' option so that it will return a project that is an exact match. (ede-find-subproject-for-directory): Small optimization to run `file-truename' less often. (ede-directory-project-p): Move content, then use `ede-directory-project-cons'. Use `ede-detect-directory-for-project', replacing old detection loop. (ede-directory-project-cons): New, from above. (ede-toplevel-project): Toss old scanning code. Use `ede-detect-directory-for-project' instead. (ede-directory-get-toplevel-open-project-new): New. * ede/linux.el (ede-linux-project-root): Deleted. (ede-project-autoload): Remove dirmatch entry - it is no longer needed. * lisp/cedet/ede/proj.el (project-rescan): Replace direct manipulation of `ede-projects' with equivalent and better functions. (ede-proj-load): Replace call to test if dir has project to explicity ask filesystem if Project.ede is there. * ede/config.el: * ede/detect.el: New files. * ede/project-am.el (project-run-target): Add "./" to program to run for systems where '.' isn't in PATH. (project-am-load): Remove old code regarding `ede-constructing'. Just read in the makefiles. * ede/linux.el (ede-linux-load): Do not add to global list here. Don't check for existing anymore. (project-rescan): New. (ede-linux-project-list, ede-linux-file-existing): Deleted. (ede-linux-project-root): Delete body. Need symbol for autoloads for now. (ede-linux-project): No longer instance tracker. (ede-project-autoload): Don't provide :proj-root * ede/emacs.el (ede-emacs-load): Do not add project to global list here. Don't look for existing first. (ede-project-autoload): Remove dirmatch entry - it is no longer needed. Don't provide proj-root anymore. (ede-emacs-project-list, ede-emacs-file-existing): Delete. (ede-emacs-project-root): Remove body (need symbol for loaddefs still). (ede-emacs-project): Do not instance track anymore. * ede/cpp-root.el (initialize-instance): Remove commented code. Add note about why we are adding the project to the master list. Make sure if we are replacing a prev version, remove from global list. (ede-cpp-root-file-existing) (ede-cpp-root-project-file-for-dir) (ede-cpp-root-count, ede-cpp-root-project-root, ede-cpp-root-load) (ede-project-autoload cpp-root): Deleted. (ede-project-root-directory): Return :directory instead of calculating from :file. (project-rescan): New. * ede/base.el (ede-toplevel): Only use buffer cached value if subproj not passed in. * srecode/java.el (srecode-semantic-handle-:java): Fix case when an EDE project didn't support java paths. * lisp/cedet/ede/proj-elisp.el (ede-proj-target-elisp::ede-proj-tweak-autoconf): Kill buffer after saving modified elisp-comp script, as to avoid "file has changed on disk; really edit the buffer" questions when script gets rewritten. * emacs-lisp/eieio-custom.el (eieio-customize-object): Set eieio-cog (current group) to g, which is an improved form of input group. * srecode/doc-cpp.srt (mode): Set to c mode so this works with both C and C++.
-rw-r--r--admin/ChangeLog25
-rw-r--r--admin/grammars/c.by9
-rw-r--r--admin/grammars/scheme.by38
-rw-r--r--etc/ChangeLog5
-rw-r--r--etc/srecode/doc-cpp.srt2
-rw-r--r--lisp/ChangeLog6
-rw-r--r--lisp/cedet/ChangeLog251
-rw-r--r--lisp/cedet/cedet-global.el13
-rw-r--r--lisp/cedet/ede.el245
-rw-r--r--lisp/cedet/ede/auto.el182
-rw-r--r--lisp/cedet/ede/autoconf-edit.el1
-rw-r--r--lisp/cedet/ede/base.el2
-rw-r--r--lisp/cedet/ede/config.el416
-rw-r--r--lisp/cedet/ede/cpp-root.el110
-rw-r--r--lisp/cedet/ede/detect.el210
-rw-r--r--lisp/cedet/ede/emacs.el66
-rw-r--r--lisp/cedet/ede/files.el322
-rw-r--r--lisp/cedet/ede/generic.el278
-rw-r--r--lisp/cedet/ede/linux.el83
-rw-r--r--lisp/cedet/ede/pconf.el5
-rw-r--r--lisp/cedet/ede/proj-elisp.el3
-rw-r--r--lisp/cedet/ede/proj.el7
-rw-r--r--lisp/cedet/ede/project-am.el10
-rw-r--r--lisp/cedet/ede/shell.el13
-rw-r--r--lisp/cedet/semantic.el71
-rw-r--r--lisp/cedet/semantic/analyze.el121
-rw-r--r--lisp/cedet/semantic/analyze/complete.el12
-rw-r--r--lisp/cedet/semantic/bovine/c.el10
-rw-r--r--lisp/cedet/semantic/bovine/grammar.el19
-rw-r--r--lisp/cedet/semantic/bovine/scm.el2
-rw-r--r--lisp/cedet/semantic/db.el12
-rw-r--r--lisp/cedet/semantic/debug.el13
-rw-r--r--lisp/cedet/semantic/doc.el3
-rw-r--r--lisp/cedet/semantic/symref.el202
-rw-r--r--lisp/cedet/srecode/java.el9
-rw-r--r--lisp/emacs-lisp/eieio-custom.el2
-rw-r--r--lisp/emacs-lisp/eieio.el2
37 files changed, 1863 insertions, 917 deletions
diff --git a/admin/ChangeLog b/admin/ChangeLog
index 303da8c020a..e85c21a6cf9 100644
--- a/admin/ChangeLog
+++ b/admin/ChangeLog
@@ -1,3 +1,28 @@
12014-11-09 Eric Ludlam <zappo@gnu.org>
2
3 * grammars/c.by (template-type): Add :template-specifier and
4 :typevar to capture extra details about the template.
5 (opt-post-fcn-modifiers): Splice in the found symbol into the
6 return value correctly.
7 (QUESTION): New punctuation.
8 (expression): Add ternary conditional support.
9
10 * grammars/scheme.by (MODULE): New token.
11 (scheme): Handle expanding the MODULE tag.
12 (scheme-list): Remove closeparen required match.
13 (scheme-in-list): Remove extraneous matches for DEFINE. Add
14 support for MODULE Simplify matching for code & make work.
15 (name-args, name-arg-list, name-arg-expand): Make it work.
16
172014-11-09 David Engster <dengste@eml.cc>
18
19 * lisp/cedet/sematic/bovine/c.by
20 (opt-brackets-after-symbol): New.
21 (multi-stage-dereference): Use it. Add rules for explicit
22 matching the last dereference. We cannot just juse
23 'namespace-symbol' as a single rule, since this would match too
24 greedy and mess with parsing default values of variables.
25
12014-11-09 Glenn Morris <rgm@gnu.org> 262014-11-09 Glenn Morris <rgm@gnu.org>
2 27
3 * admin.el (make-manuals-dist-output-variables) 28 * admin.el (make-manuals-dist-output-variables)
diff --git a/admin/grammars/c.by b/admin/grammars/c.by
index 0fd8a33f25a..f6015490939 100644
--- a/admin/grammars/c.by
+++ b/admin/grammars/c.by
@@ -64,6 +64,7 @@
64%token <punctuation> PLUS "\\`[+]\\'" 64%token <punctuation> PLUS "\\`[+]\\'"
65%token <punctuation> MINUS "\\`[-]\\'" 65%token <punctuation> MINUS "\\`[-]\\'"
66%token <punctuation> BANG "\\`[!]\\'" 66%token <punctuation> BANG "\\`[!]\\'"
67%token <punctuation> QUESTION "\\`[?]\\'"
67%token <punctuation> EQUAL "\\`[=]\\'" 68%token <punctuation> EQUAL "\\`[=]\\'"
68%token <punctuation> LESS "\\`[<]\\'" 69%token <punctuation> LESS "\\`[<]\\'"
69%token <punctuation> GREATER "\\`[>]\\'" 70%token <punctuation> GREATER "\\`[>]\\'"
@@ -590,10 +591,12 @@ template-type
590 | declmods typeformbase cv-declmods opt-stars 591 | declmods typeformbase cv-declmods opt-stars
591 opt-ref variablearg-opt-name 592 opt-ref variablearg-opt-name
592 (TYPE-TAG (car $2) nil nil nil 593 (TYPE-TAG (car $2) nil nil nil
594 :template-specifier (plist-get (nth 2 $2) :template-specifier)
593 :constant-flag (if (member "const" (append $1 $3)) t nil) 595 :constant-flag (if (member "const" (append $1 $3)) t nil)
594 :typemodifiers (delete "const" (append $1 $3)) 596 :typemodifiers (delete "const" (append $1 $3))
595 :reference (car ,$5) 597 :reference (car ,$5)
596 :pointer (car $4) 598 :pointer (car $4)
599 :typevar (car $6)
597 ) 600 )
598 ; 601 ;
599 602
@@ -832,7 +835,7 @@ opt-initializers
832 835
833opt-post-fcn-modifiers 836opt-post-fcn-modifiers
834 : post-fcn-modifiers opt-post-fcn-modifiers 837 : post-fcn-modifiers opt-post-fcn-modifiers
835 ( ,(cons ,$1 $2) ) 838 ( ,(cons ,(car $1) $2) )
836 | ;;EMPTY 839 | ;;EMPTY
837 ( nil ) 840 ( nil )
838 ; 841 ;
@@ -1206,7 +1209,9 @@ expr-binop
1206;; Use expression for parsing only. Don't actually return anything 1209;; Use expression for parsing only. Don't actually return anything
1207;; for now. Hopefully we can fix this later. 1210;; for now. Hopefully we can fix this later.
1208expression 1211expression
1209 : unaryexpression expr-binop unaryexpression 1212 : unaryexpression QUESTION unaryexpression COLON unaryexpression
1213 ( (identity start) (identity end) )
1214 | unaryexpression expr-binop unaryexpression
1210 ( (identity start) (identity end) ) 1215 ( (identity start) (identity end) )
1211 | unaryexpression 1216 | unaryexpression
1212 ( (identity start) (identity end) ) 1217 ( (identity start) (identity end) )
diff --git a/admin/grammars/scheme.by b/admin/grammars/scheme.by
index cceec0914f6..16b67a3db4b 100644
--- a/admin/grammars/scheme.by
+++ b/admin/grammars/scheme.by
@@ -25,6 +25,7 @@
25 25
26%token DEFINE "define" 26%token DEFINE "define"
27%token DEFINE-MODULE "define-module" 27%token DEFINE-MODULE "define-module"
28%token MODULE "module"
28%token LOAD "load" 29%token LOAD "load"
29 30
30%put DEFINE summary "Function: (define symbol expression)" 31%put DEFINE summary "Function: (define symbol expression)"
@@ -37,36 +38,50 @@
37%% 38%%
38 39
39scheme : semantic-list 40scheme : semantic-list
40 (EXPAND $1 scheme-list) 41 ( ,(let ((expand (EXPAND $1 scheme-list)))
42 (cond
43 ((semantic-tag-of-class-p expand 'module)
44 (TYPE-TAG (semantic-tag-name expand)
45 "module"
46 (EXPANDFULL $1 scheme)
47 nil) ;; Module contains more definitions like a type
48 )
49 (t
50 expand))))
41 ; 51 ;
42 52
43scheme-list : OPENPAREN scheme-in-list CLOSEPAREN 53scheme-list : OPENPAREN scheme-in-list
44 ( ,$2 ) 54 ( ,$2 )
45 ; 55 ;
46 56
57
47scheme-in-list: DEFINE symbol expression 58scheme-in-list: DEFINE symbol expression
48 (VARIABLE-TAG $2 nil $3 ) 59 (VARIABLE-TAG $2 nil $3 )
49 | DEFINE name-args opt-doc sequence 60 | DEFINE name-args opt-doc
50 (FUNCTION-TAG (car ,$2) nil (cdr ,$2) ) 61 (FUNCTION-TAG (car ,$2) nil (cdr ,$2) )
51 | DEFINE-MODULE name-args 62 | DEFINE-MODULE name-args
52 (PACKAGE-TAG (nth (length $2) $2 ) nil) 63 (PACKAGE-TAG (nth (length $2) $2 ) nil)
64 | MODULE symbol
65 (TAG $1 'module :members nil)
53 | LOAD string 66 | LOAD string
54 (INCLUDE-TAG (file-name-nondirectory (read $2)) (read $2) ) 67 (INCLUDE-TAG (file-name-nondirectory (read $2)) (read $2) )
55 | symbol 68 | symbol sequence
56 (CODE-TAG $1 nil) 69 (CODE-TAG $1 nil)
57 ; 70 ;
58 71
59name-args: semantic-list 72name-args: semantic-list
60 (EXPAND $1 name-arg-expand) 73 (EXPAND $1 name-arg-list)
61 ; 74 ;
62 75
63name-arg-expand : open-paren name-arg-expand 76name-arg-list : OPENPAREN name-arg-expand
64 ( ,$2 ) 77 ( ,$2 )
65 | symbol name-arg-expand 78 ;
66 ( ,(cons $1 ,$2) ) 79
67 | ;; EMPTY 80name-arg-expand: symbol name-arg-expand
68 ( ) 81 ( ,(cons $1 ,$2) )
69 ; 82 | ;; EMPTY
83 ( )
84 ;
70 85
71opt-doc : string 86opt-doc : string
72 | ;; EMPTY 87 | ;; EMPTY
@@ -83,3 +98,4 @@ expression : symbol
83 ; 98 ;
84 99
85;;; scheme.by ends here 100;;; scheme.by ends here
101
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 876d99dbef2..c46b103be23 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,8 @@
12014-11-09 Eric Ludlam <zappo@gnu.org>
2
3 * srecode/doc-cpp.srt (mode): Set to c mode so this works with
4 both C and C++.
5
12014-11-05 Teodor Zlatanov <tzz@lifelogs.com> 62014-11-05 Teodor Zlatanov <tzz@lifelogs.com>
2 7
3 * NEWS: Mention `url-user-agent'. (Bug#16498) 8 * NEWS: Mention `url-user-agent'. (Bug#16498)
diff --git a/etc/srecode/doc-cpp.srt b/etc/srecode/doc-cpp.srt
index 520f3f7d8c6..60f0947082e 100644
--- a/etc/srecode/doc-cpp.srt
+++ b/etc/srecode/doc-cpp.srt
@@ -19,7 +19,7 @@
19;; You should have received a copy of the GNU General Public License 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/>. 20;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
21 21
22set mode "c++-mode" 22set mode "c-mode"
23 23
24set application "document" 24set application "document"
25context declaration 25context declaration
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c8fc5086817..a01dadad706 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,9 @@
12014-11-09 Eric Ludlam <zappo@gnu.org>
2
3 * emacs-lisp/eieio-custom.el (eieio-customize-object): Set
4 eieio-cog (current group) to g, which is an improved form of input
5 group.
6
12014-11-09 Juri Linkov <juri@jurta.org> 72014-11-09 Juri Linkov <juri@jurta.org>
2 8
3 * isearch.el (isearch-message-prefix): Show "Multi-file" and 9 * isearch.el (isearch-message-prefix): Show "Multi-file" and
diff --git a/lisp/cedet/ChangeLog b/lisp/cedet/ChangeLog
index 8e911cfe6d6..d797132dd34 100644
--- a/lisp/cedet/ChangeLog
+++ b/lisp/cedet/ChangeLog
@@ -1,3 +1,254 @@
12014-11-09 Eric Ludlam <zappo@gnu.org>
2
3 * semantic.el (semantic-mode): Add/remove 3
4 completion-at-point-functions.
5 (semantic-completion-at-point-function): Removed.
6 (semantic-analyze-completion-at-point-function)
7 (semantic-analyze-notc-completion-at-point-function)
8 (semantic-analyze-nolongprefix-completion-at-point-function): New
9 completion at point functions.
10
11 * semantic/doc.el (semantic-doc-snarf-comment-for-tag): Fix case
12 when comment-end is empty string.
13
14 * semantic/debug.el
15 (semantic-debug-parser-debugger-source): New buffer local
16 variable.
17 (semantic-debug-interface): Add 'nil' initform to overlays.
18 (semantic-debug-mode): Remove read-only tags from buffers on exit.
19 (semantic-debug): Add autoload cookie. Force the language
20 specific debugger to load.
21
22 * semantic/db.el (generic::semanticdb-full-filename): New generic
23 method to allow this method to be used on buffer names via an
24 associated database.
25
26 * semantic/symref.el
27 (semantic-symref-cleanup-recent-buffers-fcn): When cleaning up
28 buffers, don't clean up buffers that are being used (i.e., in a
29 window) when the hook fires.
30 (semantic-symref-recently-opened-buffers): New tracking variable.
31 (semantic-symref-cleanup-recent-buffers-fcn): New hook fcn.
32 (semantic-symref-result-get-tags): Move logic into
33 `semantic-symref-hit-to-tag-via-buffer', and cleanup buffers via
34 the symref cleanup function in post-command-hook.
35 (semantic-symref-hit-to-tag-via-buffer): Logic that used to be
36 from above.
37 (semantic-symref-hit-to-tag-via-db): New.
38
39 * semantic/analyze.el:
40 (semantic-analyze-find-tag-sequence-default): If first entry in
41 sequence is the only one, apply tagclass filter.
42 (semantic-analyze-princ-sequence): Show slot even if empty.
43 (semantic-analyze-find-tag-sequence)
44 (semantic-analyze-find-tag-sequence-default): Add flags argument.
45 Add support for forcing the final entry of the sequence to be of
46 class variable.
47 (semantic-analyze-find-tag): Fix bug where input class filter was
48 ignored if there was a typecache match.
49 (semantic-analyze-current-context-default): For assignments, the
50 assignee now must be of class variable.
51
52 * semantic/analyze/complete.el
53 (semantic-analyze-possible-completions-default): Add
54 'no-longprefix' flag. When used, the prefix and prefixtypes are
55 shortened to just the last symbol.
56
57 * semantic/bovine/c.el (semantic-c-do-lex-if): Catch errors from
58 'hideif', and push to the parser warning stack.
59 (semantic-lex-cpp-define): When a comment is at the end of a
60 macro, do not subtract an extra 1 from the found position. Fixes
61 bug with: #define foo (a)/**/ adding an extra ')' to the stream.
62
63 * semantic/bovine/scm.el (semantic-lex-scheme-symbol): Allow
64 symbols to be one char long.
65
66 * semantic/bovine/grammar.el
67 (bovine-grammar-calculate-source-on-path): New.
68 (bovine-grammar-setupcode-builder): Use it.
69
70 * ede.el (ede/detect): New require.
71 (ede-version): Bump version
72 (ede-initialize-state-current-buffer): Use new
73 `ede-detect-directory-for-project' to detect projects first
74 instead of depending on currente dir only.
75 (ede-delete-project-from-global-list): New.
76 (ede-flush-deleted-projects): Use above.
77 (ede-check-project-query-fcn): New variable
78 (ede-check-project-directory): Use above when querying the user.
79 Added to support unit testing of this security measure.
80 (ede-initialize-state-current-buffer): Use
81 `ede-directory-project-cons' instead of the -detect- fcn to take
82 advantage of the cache. Pass found project into
83 `ede-load-project-file'.
84 (ede-load-project-file): Add new input DETECTIN.
85 (ede-rescan-toplevel): Get the proj root a better way.
86 (ede-load-project-file): Return the loaded object. When asking
87 for existing project, ask for an exact match.
88 (ede-initialize-state-current-buffer): Simplify some conditional
89 logic.
90 (ede-load-project-file): Simplify conditional logic.
91 (ede-global-list-sanity-check): New Testing fcn.
92 (ede-parent-project): Replace old code with call to faster
93 `ede-find-subproject-for-directory'.
94 (ede-load-project-file): Use
95 `ede-directory-get-toplevel-open-project' instead of above
96 deleted. Rename "pfc" to "autoloader". Use
97 `ede-directory-project-cons' to detect a project. Delete no
98 project found case where we search up the tree.
99
100 * ede/auto.el (ede-project-autoload): Fix doc typo. Add
101 `:root-only' slot.
102 (ede-auto-load-project): Doc update: warn to not use.
103 (ede-dir-to-projectfile): Deleted.
104 (ede-project-autoload-dirmatch): Add subdir-only slot. Make
105 configdatastash unbound by default.
106 (ede-do-dirmatch): If subdir-only is true, then don't allow exact
107 matches. Account for configdatastash as unbound. Assume value of
108 nil means no tool installed. Make sure loaded path matches from
109 beginning. Stash the regexp, not the raw string.
110 (ede-project-class-files): Note that makefile and automake are not
111 root only.
112 (ede-auto-detect-in-dir): New (for use with `ede/detect.el').
113 (ede-project-dirmatch-p): Deleted.
114 (ede-project-root-directory): Remove body, return nil.
115 (ede-project-autoload): :proj-root-dirmatch can be null & doc fix.
116 (ede-auto-detect-in-dir): If there is no :proj-file, check for a
117 dirmatch.
118
119 * ede/generic.el (ede/config): Replace require of ede.
120 (ede-generic-new-autoloader): Generic projects are now safe by
121 default. Note this is NOT a root only project.
122 (project-rescan, ede-project-root, ede-generic-target-java)
123 (ede-java-classpath, ede-find-subproject-for-directory): New.
124 (ede-enable-generic-projects): Add new autoloaders for git, bzr,
125 hg, sv, CVS.
126 (ede-generic-vc-project)
127 (ede-generic-vc-project::ede-generic-setup-configuration): New.
128 (ede-generic-config): Remove slots: c-include-path,
129 c-preprocessor-table, c-preprocessor-files, classpath,
130 build-command, debug-command, run command. Inherit from
131 ede-extra-config-build, ede-extra-config-program. Make
132 run-command :value match :custom so only strings are accepted.
133 Add some more :group slot specifiers.
134 (ede-generic-project): Add mixins `ede-project-with-config-c' and
135 `ede-project-with-config-java'. Inherit from
136 `ede-project-with-config-build',
137 `ede-project-with-config-program'. Subclass
138 `ede-project-with-config'. Remove duplication from new baseclass.
139 (ede-generic-target): Inherit from `ede-target-with-config-build',
140 `ede-target-with-config-program'. Subclass `ede-target-with-config'.
141 (ede-generic-target-c-cpp): Add mixin `ede-target-with-config-c'.
142 (ede-generic-target-java): Add mixin `ede-target-with-config-java'.
143 (ede-preprocessor-map, ede-system-include-path)
144 (edejava-classpath): Deleted, moved to config.el.
145 (project-compile-project, project-compile-target)
146 (project-debug-target, project-run-target): Deleted.
147 (ede-generic-get-configuration, ede-generic-setup-configuration)
148 (ede-commit-project, project-rescan)
149 (ede-generic-project::ede-customize)
150 (ede-generic-target::ede-customize)
151 (ede-generic-config::eieio-done-customizing)
152 (ede-generic-config::ede-commit): Deleted. Subsumed by new
153 baseclass.
154 (ede-preprocessor-map, ede-system-include-path)
155 (project-debug-target, project-run-target): Call new
156 `ede-config-get-configuration' instead of old version.
157 (ede-generic-load): Do not add to global list here.
158
159 * ede/files.el (ede-find-project-root)
160 (ede-files-find-existing)
161 (ede-directory-get-toplevel-open-project-new): Deleted.
162 (ede-project-root-directory): Use `ede-project-root' first.
163 (ede-project-directory-remove-hash)
164 (ede--directory-project-from-hash)
165 (ede--directory-project-add-description-to-hash): Rename to make
166 internal symbols (via --). Expand input dir first.
167 (ede-directory-project-p): Doc fix (note obsoleted.)
168 (ede-toplevel-project-or-nil): Alias to `ede-toplevel-project'.
169 (ede-toplevel-project): Doc Fix. Delete commented out old code.
170 Simplify returning result from ede-detect-directory-for-project.
171 (ede-directory-get-open-project): Support when
172 inodes are disabled. If disabled to str compare on root project.
173 (ede-directory-get-toplevel-open-project): Enabled nested
174 projects. When doing directory name matching, save the 'short'
175 version of an answer (non-exact match) and eventually select the
176 shortest answer at the end. Expand the filename of tested
177 projects. Better support for when inodes are disabled. Add
178 'exact' option so that it will return a project that is an exact
179 match.
180 (ede-find-subproject-for-directory): Small optimization to run
181 `file-truename' less often.
182 (ede-directory-project-p): Move content, then use
183 `ede-directory-project-cons'. Use
184 `ede-detect-directory-for-project', replacing old detection loop.
185 (ede-directory-project-cons): New, from above.
186 (ede-toplevel-project): Toss old scanning code. Use
187 `ede-detect-directory-for-project' instead.
188 (ede-directory-get-toplevel-open-project-new): New.
189
190 * ede/linux.el (ede-linux-project-root): Deleted.
191 (ede-project-autoload): Remove dirmatch entry - it is no longer
192 needed.
193
194 * lisp/cedet/ede/proj.el (project-rescan): Replace direct
195 manipulation of `ede-projects' with equivalent and better
196 functions.
197 (ede-proj-load): Replace call to test if dir has project to
198 explicity ask filesystem if Project.ede is there.
199
200 * ede/config.el:
201 * ede/detect.el: New files.
202
203 * ede/project-am.el (project-run-target): Add "./" to program to
204 run for systems where '.' isn't in PATH.
205 (project-am-load): Remove old code regarding `ede-constructing'.
206 Just read in the makefiles.
207
208 * ede/linux.el (ede-linux-load): Do not add to global list here.
209 Don't check for existing anymore.
210 (project-rescan): New.
211 (ede-linux-project-list, ede-linux-file-existing): Deleted.
212 (ede-linux-project-root): Delete body. Need symbol for autoloads
213 for now.
214 (ede-linux-project): No longer instance tracker.
215 (ede-project-autoload): Don't provide :proj-root
216
217 * ede/emacs.el (ede-emacs-load): Do not add project to global list
218 here. Don't look for existing first.
219 (ede-project-autoload): Remove dirmatch entry - it is no longer
220 needed. Don't provide proj-root anymore.
221 (ede-emacs-project-list, ede-emacs-file-existing): Delete.
222 (ede-emacs-project-root): Remove body (need symbol for loaddefs
223 still).
224 (ede-emacs-project): Do not instance track anymore.
225
226 * ede/cpp-root.el (initialize-instance): Remove commented code.
227 Add note about why we are adding the project to the master list.
228 Make sure if we are replacing a prev version, remove from global
229 list.
230 (ede-cpp-root-file-existing)
231 (ede-cpp-root-project-file-for-dir)
232 (ede-cpp-root-count, ede-cpp-root-project-root, ede-cpp-root-load)
233 (ede-project-autoload cpp-root): Deleted.
234 (ede-project-root-directory): Return :directory instead of
235 calculating from :file.
236 (project-rescan): New.
237
238 * ede/base.el (ede-toplevel): Only use buffer cached value if
239 subproj not passed in.
240
241 * srecode/java.el (srecode-semantic-handle-:java): Fix case when
242 an EDE project didn't support java paths.
243
2442014-11-09 David Engster <dengste@eml.cc>
245
246 * lisp/cedet/ede/proj-elisp.el
247 (ede-proj-target-elisp::ede-proj-tweak-autoconf): Kill buffer
248 after saving modified elisp-comp script, as to avoid "file has
249 changed on disk; really edit the buffer" questions when script
250 gets rewritten.
251
12014-10-29 Paul Eggert <eggert@cs.ucla.edu> 2522014-10-29 Paul Eggert <eggert@cs.ucla.edu>
2 253
3 Simplify use of current-time and friends. 254 Simplify use of current-time and friends.
diff --git a/lisp/cedet/cedet-global.el b/lisp/cedet/cedet-global.el
index ee1b5ce7cc8..494c41b0efe 100644
--- a/lisp/cedet/cedet-global.el
+++ b/lisp/cedet/cedet-global.el
@@ -93,6 +93,13 @@ SCOPE is the scope of the search, such as 'project or 'subdirs."
93 (apply 'call-process cedet-global-gtags-command 93 (apply 'call-process cedet-global-gtags-command
94 nil b nil 94 nil b nil
95 flags) 95 flags)
96
97 ;; Check for warnings.
98 (with-current-buffer b
99 (goto-char (point-min))
100 (when (re-search-forward "Error\\|Warning" nil t)
101 (error "Output:\n%S" (buffer-string))))
102
96 b)) 103 b))
97 104
98(defun cedet-gnu-global-expand-filename (filename) 105(defun cedet-gnu-global-expand-filename (filename)
@@ -181,8 +188,10 @@ If a database already exists, then just update it."
181 (let ((default-directory dir)) 188 (let ((default-directory dir))
182 (cedet-gnu-global-gtags-call 189 (cedet-gnu-global-gtags-call
183 (when root 190 (when root
184 '("-i");; Incremental update flag. 191 '("-u");; Incremental update flag.
185 ))))) 192 ))
193 )
194 ))
186 195
187(provide 'cedet-global) 196(provide 'cedet-global)
188 197
diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el
index a9a53d776e2..55dff1ac441 100644
--- a/lisp/cedet/ede.el
+++ b/lisp/cedet/ede.el
@@ -45,6 +45,7 @@
45(require 'ede/source) 45(require 'ede/source)
46(require 'ede/base) 46(require 'ede/base)
47(require 'ede/auto) 47(require 'ede/auto)
48(require 'ede/detect)
48 49
49(eval-and-compile 50(eval-and-compile
50 (load "ede/loaddefs" nil 'nomessage)) 51 (load "ede/loaddefs" nil 'nomessage))
@@ -61,7 +62,7 @@
61(declare-function ede-up-directory "ede/files") 62(declare-function ede-up-directory "ede/files")
62(declare-function semantic-lex-make-spp-table "semantic/lex-spp") 63(declare-function semantic-lex-make-spp-table "semantic/lex-spp")
63 64
64(defconst ede-version "1.2" 65(defconst ede-version "2.0"
65 "Current version of the Emacs EDE.") 66 "Current version of the Emacs EDE.")
66 67
67;;; Code: 68;;; Code:
@@ -500,42 +501,50 @@ Sets buffer local variables for EDE."
500 ;; Init the buffer. 501 ;; Init the buffer.
501 (let* ((ROOT nil) 502 (let* ((ROOT nil)
502 (proj (ede-directory-get-open-project default-directory 503 (proj (ede-directory-get-open-project default-directory
503 'ROOT)) 504 'ROOT)))
504 (projauto nil)) 505
505 506 (when (not proj)
506 (when (or proj ROOT 507 ;; If there is no open project, look up the project
507 ;; If there is no open project, look up the project 508 ;; autoloader to see if we should initialize.
508 ;; autoloader to see if we should initialize. 509 (let ((projdetect (ede-directory-project-cons default-directory)))
509 (setq projauto (ede-directory-project-p default-directory t))) 510
510 511 (when projdetect
511 (when (and (not proj) projauto) 512 ;; No project was loaded, but we have a project description
512 513 ;; object. This means that we try to load it.
513 ;; No project was loaded, but we have a project description 514 ;;
514 ;; object. This means that we can check if it is a safe 515 ;; Before loading, we need to check if it is a safe
515 ;; project to load before requesting it to be loaded. 516 ;; project to load before requesting it to be loaded.
516 517
517 (when (or (oref projauto safe-p) 518 (when (or (oref (cdr projdetect) safe-p)
518 ;; The project style is not safe, so check if it is 519 ;; The project style is not safe, so check if it is
519 ;; in `ede-project-directories'. 520 ;; in `ede-project-directories'.
520 (let ((top (ede-toplevel-project default-directory))) 521 (let ((top (car projdetect)))
521 (ede-directory-safe-p top))) 522 (ede-directory-safe-p top)))
522 523
523 ;; The project is safe, so load it in. 524 ;; The project is safe, so load it in.
524 (setq proj (ede-load-project-file default-directory 'ROOT)))) 525 (setq proj (ede-load-project-file default-directory projdetect 'ROOT))))))
525 526
526 ;; Only initialize EDE state in this buffer if we found a project. 527 ;; If PROJ is now loaded in, we can initialize our buffer to it.
527 (when proj 528 (when proj
528 529
529 (setq ede-object (ede-buffer-object (current-buffer) 530 ;; ede-object represents the specific EDE related class that best
531 ;; represents this buffer. It could be a project (for a project file)
532 ;; or a target. Also save off ede-object-project, the project that
533 ;; the buffer belongs to for the case where ede-object is a target.
534 (setq ede-object (ede-buffer-object (current-buffer)
530 'ede-object-project)) 535 'ede-object-project))
531 536
532 (setq ede-object-root-project 537 ;; Every project has a root. It might be the same as ede-object.
533 (or ROOT (ede-project-root ede-object-project))) 538 ;; Cache that also as the root is a very common thing to need.
539 (setq ede-object-root-project
540 (or ROOT (ede-project-root ede-object-project)))
534 541
535 (if (and (not ede-object) ede-object-project) 542 ;; Check to see if we want to add this buffer to a target.
536 (ede-auto-add-to-target)) 543 (if (and (not ede-object) ede-object-project)
544 (ede-auto-add-to-target))
537 545
538 (ede-apply-target-options))))) 546 ;; Apply any options from the found target.
547 (ede-apply-target-options))))
539 548
540(defun ede-reset-all-buffers () 549(defun ede-reset-all-buffers ()
541 "Reset all the buffers due to change in EDE." 550 "Reset all the buffers due to change in EDE."
@@ -679,6 +688,7 @@ Otherwise, create a new project for DIR."
679 (if (ede-check-project-directory dir) 688 (if (ede-check-project-directory dir)
680 (progn 689 (progn
681 ;; Load the project in DIR, or make one. 690 ;; Load the project in DIR, or make one.
691 ;; @TODO - IS THIS REAL?
682 (ede-load-project-file dir) 692 (ede-load-project-file dir)
683 693
684 ;; Check if we loaded anything on the previous line. 694 ;; Check if we loaded anything on the previous line.
@@ -700,6 +710,10 @@ Otherwise, create a new project for DIR."
700 (error "%s is not an allowed project directory in `ede-project-directories'" 710 (error "%s is not an allowed project directory in `ede-project-directories'"
701 dir))) 711 dir)))
702 712
713(defvar ede-check-project-query-fcn 'y-or-n-p
714 "Function used to ask the user if they want to permit a project to load.
715This is abstracted out so that tests can answer this question.")
716
703(defun ede-check-project-directory (dir) 717(defun ede-check-project-directory (dir)
704 "Check if DIR should be in `ede-project-directories'. 718 "Check if DIR should be in `ede-project-directories'.
705If it is not, try asking the user if it should be added; if so, 719If it is not, try asking the user if it should be added; if so,
@@ -712,9 +726,10 @@ Return nil if DIR should not be in `ede-project-directories'."
712 ;; If `ede-project-directories' is a list, maybe add it. 726 ;; If `ede-project-directories' is a list, maybe add it.
713 (when (listp ede-project-directories) 727 (when (listp ede-project-directories)
714 (or (member dir ede-project-directories) 728 (or (member dir ede-project-directories)
715 (when (y-or-n-p (format "`%s' is not listed in `ede-project-directories'. 729 (when (funcall ede-check-project-query-fcn
730 (format "`%s' is not listed in `ede-project-directories'.
716Add it to the list of allowed project directories? " 731Add it to the list of allowed project directories? "
717 dir)) 732 dir))
718 (push dir ede-project-directories) 733 (push dir ede-project-directories)
719 ;; If possible, save `ede-project-directories'. 734 ;; If possible, save `ede-project-directories'.
720 (if (or custom-file user-init-file) 735 (if (or custom-file user-init-file)
@@ -782,7 +797,9 @@ Optional argument NAME is the name to give this project."
782 (error 797 (error
783 "Unknown file name specifier %S" 798 "Unknown file name specifier %S"
784 pf))) 799 pf)))
785 :targets nil))) 800 :targets nil)
801
802 ))
786 (inits (oref obj initializers))) 803 (inits (oref obj initializers)))
787 ;; Force the name to match for new objects. 804 ;; Force the name to match for new objects.
788 (eieio-object-set-name-string nobj (oref nobj :name)) 805 (eieio-object-set-name-string nobj (oref nobj :name))
@@ -821,16 +838,17 @@ ARGS are additional arguments to pass to method SYM."
821(defun ede-rescan-toplevel () 838(defun ede-rescan-toplevel ()
822 "Rescan all project files." 839 "Rescan all project files."
823 (interactive) 840 (interactive)
824 (if (not (ede-directory-get-open-project default-directory)) 841 (when (not (ede-toplevel))
825 ;; This directory isn't open. Can't rescan. 842 ;; This directory isn't open. Can't rescan.
826 (error "Attempt to rescan a project that isn't open") 843 (error "Attempt to rescan a project that isn't open"))
827 844
828 ;; Continue 845 ;; Continue
829 (let ((toppath (ede-toplevel-project default-directory)) 846 (let ((root (ede-toplevel))
830 (ede-deep-rescan t)) 847 (ede-deep-rescan t))
831 848
832 (project-rescan (ede-load-project-file toppath)) 849 (project-rescan root)
833 (ede-reset-all-buffers)))) 850 (ede-reset-all-buffers)
851 ))
834 852
835(defun ede-new-target (&rest args) 853(defun ede-new-target (&rest args)
836 "Create a new target specific to this type of project file. 854 "Create a new target specific to this type of project file.
@@ -918,6 +936,8 @@ Optional argument FORCE forces the file to be removed without asking."
918 (interactive) 936 (interactive)
919 (ede-invoke-method 'project-edit-file-target)) 937 (ede-invoke-method 'project-edit-file-target))
920 938
939;;; Compilation / Debug / Run
940;;
921(defun ede-compile-project () 941(defun ede-compile-project ()
922 "Compile the current project." 942 "Compile the current project."
923 (interactive) 943 (interactive)
@@ -1063,6 +1083,10 @@ On success, return the added project."
1063 (add-to-list 'ede-projects proj) 1083 (add-to-list 'ede-projects proj)
1064 proj) 1084 proj)
1065 1085
1086(defun ede-delete-project-from-global-list (proj)
1087 "Remove project PROJ from the master list of projects."
1088 (setq ede-projects (remove proj ede-projects)))
1089
1066(defun ede-flush-deleted-projects () 1090(defun ede-flush-deleted-projects ()
1067 "Scan the projects list for projects which no longer exist. 1091 "Scan the projects list for projects which no longer exist.
1068Flush the dead projects from the project cache." 1092Flush the dead projects from the project cache."
@@ -1072,80 +1096,83 @@ Flush the dead projects from the project cache."
1072 (when (not (file-exists-p (oref P :file))) 1096 (when (not (file-exists-p (oref P :file)))
1073 (add-to-list 'dead P))) 1097 (add-to-list 'dead P)))
1074 (dolist (D dead) 1098 (dolist (D dead)
1075 (setq ede-projects (remove D ede-projects))) 1099 (ede-delete-project-from-global-list D))
1076 )) 1100 ))
1077 1101
1078(defun ede-load-project-file (dir &optional rootreturn) 1102(defun ede-global-list-sanity-check ()
1103 "Perform a sanity check to make sure there are no duplicate projects."
1104 (interactive)
1105 (let ((scanned nil))
1106 (dolist (P ede-projects)
1107 (if (member (oref P :directory) scanned)
1108 (error "Duplicate project (by dir) found in %s!" (oref P :directory))
1109 (push (oref P :directory) scanned)))
1110 (unless ede--disable-inode
1111 (setq scanned nil)
1112 (dolist (P ede-projects)
1113 (if (member (ede--project-inode P) scanned)
1114 (error "Duplicate project (by inode) found in %s!" (ede--project-inode P))
1115 (push (ede--project-inode P) scanned))))
1116 (message "EDE by directory %sis still sane." (if ede--disable-inode "" "& inode "))))
1117
1118(defun ede-load-project-file (dir &optional detectin rootreturn)
1079 "Project file independent way to read a project in from DIR. 1119 "Project file independent way to read a project in from DIR.
1120Optional DETECTIN is an autoload cons from `ede-detect-directory-for-project'
1121which can be passed in to save time.
1080Optional ROOTRETURN will return the root project for DIR." 1122Optional ROOTRETURN will return the root project for DIR."
1081 ;; Only load if something new is going on. Flush the dirhash. 1123 ;; Don't do anything if we are in the process of
1082 (ede-project-directory-remove-hash dir) 1124 ;; constructing an EDE object.
1083 ;; Do the load 1125 ;;
1084 ;;(message "EDE LOAD : %S" file) 1126 ;; Prevent recursion.
1085 (let* ((file dir) 1127 (unless ede-constructing
1086 (path (file-name-as-directory (expand-file-name dir))) 1128
1087 (pfc (ede-directory-project-p path)) 1129 ;; Only load if something new is going on. Flush the dirhash.
1088 (toppath nil) 1130 (ede-project-directory-remove-hash dir)
1089 (o nil)) 1131
1090 (cond 1132 ;; Do the load
1091 ((not pfc) 1133 ;;(message "EDE LOAD : %S" file)
1092 ;; @TODO - Do we really need to scan? Is this a waste of time? 1134 (let* ((file dir)
1093 ;; Scan upward for a the next project file style. 1135 (path (file-name-as-directory (expand-file-name dir)))
1094 (let ((p path)) 1136 (detect (or detectin (ede-directory-project-cons path)))
1095 (while (and p (not (ede-directory-project-p p))) 1137 (autoloader nil)
1096 (setq p (ede-up-directory p))) 1138 (toppath nil)
1097 (if p (ede-load-project-file p) 1139 (o nil))
1098 nil) 1140
1099 ;; recomment as we go 1141 (when detect
1100 ;;nil 1142 (setq toppath (car detect))
1101 )) 1143 (setq autoloader (cdr detect))
1102 ;; Do nothing if we are building an EDE project already. 1144
1103 (ede-constructing 1145 ;; See if it's been loaded before. Use exact matching since
1104 nil) 1146 ;; know that 'toppath' is the root of the project.
1105 ;; Load in the project in question. 1147 (setq o (ede-directory-get-toplevel-open-project toppath 'exact))
1106 (t 1148
1107 (setq toppath (ede-toplevel-project path)) 1149 ;; If not open yet, load it.
1108 ;; We found the top-most directory. Check to see if we already 1150 (unless o
1109 ;; have an object defining its project. 1151 ;; NOTE: We set ede-constructing to the autoloader we are using.
1110 (setq pfc (ede-directory-project-p toppath t)) 1152 ;; Some project types have one class, but many autoloaders
1111 1153 ;; and this is how we tell the instantiation which kind of
1112 ;; See if it's been loaded before 1154 ;; project to make.
1113 (setq o (object-assoc (ede-dir-to-projectfile pfc toppath) 'file 1155 (let ((ede-constructing autoloader))
1114 ede-projects)) 1156
1115 1157 ;; This is the only place `ede-auto-load-project' should be called.
1116 ;; If not open yet, load it. 1158
1117 (unless o 1159 (setq o (ede-auto-load-project autoloader toppath))))
1118 (let ((ede-constructing pfc)) 1160
1119 (setq o (ede-auto-load-project pfc toppath)))) 1161 ;; Return the found root project.
1120 1162 (when rootreturn (set rootreturn o))
1121 ;; Return the found root project. 1163
1122 (when rootreturn (set rootreturn o)) 1164 ;; The project has been found (in the global list) or loaded from
1123 1165 ;; disk (via autoloader.) We can now search for the project asked
1124 (let (tocheck found) 1166 ;; for from DIR in the sub-list.
1125 ;; Now find the project file belonging to FILE! 1167 (ede-find-subproject-for-directory o path)
1126 (setq tocheck (list o)) 1168
1127 (setq file (ede-dir-to-projectfile pfc (expand-file-name path))) 1169 ;; Return the project.
1128 (while (and tocheck (not found)) 1170 o))))
1129 (let ((newbits nil))
1130 (when (car tocheck)
1131 (if (string= file (oref (car tocheck) file))
1132 (setq found (car tocheck)))
1133 (setq newbits (oref (car tocheck) subproj)))
1134 (setq tocheck
1135 (append (cdr tocheck) newbits))))
1136 (if (not found)
1137 (message "No project for %s, but passes project-p test" file)
1138 ;; Now that the file has been reset inside the project object, do
1139 ;; the cache maintenance.
1140 (setq ede-project-cache-files
1141 (delete (oref found file) ede-project-cache-files)))
1142 found)))))
1143 1171
1144;;; PROJECT ASSOCIATIONS 1172;;; PROJECT ASSOCIATIONS
1145;; 1173;;
1146;; Moving between relative projects. Associating between buffers and 1174;; Moving between relative projects. Associating between buffers and
1147;; projects. 1175;; projects.
1148
1149(defun ede-parent-project (&optional obj) 1176(defun ede-parent-project (&optional obj)
1150 "Return the project belonging to the parent directory. 1177 "Return the project belonging to the parent directory.
1151Return nil if there is no previous directory. 1178Return nil if there is no previous directory.
diff --git a/lisp/cedet/ede/auto.el b/lisp/cedet/ede/auto.el
index 337cd77b4e6..63e0504689f 100644
--- a/lisp/cedet/ede/auto.el
+++ b/lisp/cedet/ede/auto.el
@@ -47,8 +47,13 @@
47 :initform nil 47 :initform nil
48 :documentation 48 :documentation
49 "An index into the match-data of `configregex'.") 49 "An index into the match-data of `configregex'.")
50 (configdatastash :initform nil 50 (subdir-only :initarg :subdir-only
51 :documentation 51 :initform t
52 :documentation
53 "Non-nil means an exact match to the found directory is a non-match.
54This implies projects exist only in subdirectories of the configuration path.
55If `:subdir-only' is nil, then the directory from the configuration file is the project.")
56 (configdatastash :documentation
52 "Save discovered match string.") 57 "Save discovered match string.")
53 ) 58 )
54 "Support complex matches for projects that live in named directories. 59 "Support complex matches for projects that live in named directories.
@@ -80,8 +85,11 @@ into memory.")
80 ;; If the thing to match is stored in a config file. 85 ;; If the thing to match is stored in a config file.
81 ((stringp fc) 86 ((stringp fc)
82 (when (file-exists-p fc) 87 (when (file-exists-p fc)
83 (let ((matchstring (oref dirmatch configdatastash))) 88 (let ((matchstring
84 (unless matchstring 89 (if (slot-boundp dirmatch 'configdatastash)
90 (oref dirmatch configdatastash)
91 nil)))
92 (when (and (not matchstring) (not (slot-boundp dirmatch 'configdatastash)))
85 (save-current-buffer 93 (save-current-buffer
86 (let* ((buff (get-file-buffer fc)) 94 (let* ((buff (get-file-buffer fc))
87 (readbuff 95 (readbuff
@@ -94,12 +102,27 @@ into memory.")
94 (setq matchstring 102 (setq matchstring
95 (match-string (or (oref dirmatch configregexidx) 0))))) 103 (match-string (or (oref dirmatch configregexidx) 0)))))
96 (if (not buff) (kill-buffer readbuff)))) 104 (if (not buff) (kill-buffer readbuff))))
97 ;; Save what we find in our cache. 105 (when matchstring
98 (oset dirmatch configdatastash matchstring)) 106 ;; If this dirmatch only finds subdirs of matchstring, then
107 ;; force matchstring to be a directory.
108 (when (oref dirmatch subdir-only)
109 (setq matchstring (file-name-as-directory matchstring)))
110 ;; Convert matchstring to a regexp
111 (setq matchstring (concat "^" (regexp-quote matchstring)))
112 ;; Stash it for later.
113 (oset dirmatch configdatastash matchstring))
114 ;; Debug
115 ;;(message "Stashing config data for dirmatch %S as %S" (eieio-object-name dirmatch) matchstring)
116 )
117 ;;(message "dirmatch %s against %s" matchstring (expand-file-name file))
99 ;; Match against our discovered string 118 ;; Match against our discovered string
100 (and matchstring (string-match (regexp-quote matchstring) file)) 119 (setq file (file-name-as-directory (expand-file-name file)))
120 (and matchstring (string-match matchstring (expand-file-name file))
121 (or (not (oref dirmatch subdir-only))
122 (not (= (match-end 0) (length file))))
123 )
101 ))) 124 )))
102 125
103 ;; Add new matches here 126 ;; Add new matches here
104 ;; ((stringp somenewslot ...) 127 ;; ((stringp somenewslot ...)
105 ;; ) 128 ;; )
@@ -119,13 +142,21 @@ into memory.")
119 :documentation "The lisp file belonging to this class.") 142 :documentation "The lisp file belonging to this class.")
120 (proj-file :initarg :proj-file 143 (proj-file :initarg :proj-file
121 :documentation "Name of a project file of this type.") 144 :documentation "Name of a project file of this type.")
145 (root-only :initarg :root-only
146 :initform t ;; Default - majority case.
147 :documentation
148 "Non-nil if project detection only finds proj-file @ project root.")
122 (proj-root-dirmatch :initarg :proj-root-dirmatch 149 (proj-root-dirmatch :initarg :proj-root-dirmatch
123 :initform "" 150 :initform nil
124 :type (or string ede-project-autoload-dirmatch) 151 :type (or null string ede-project-autoload-dirmatch)
125 :documentation 152 :documentation
126 "To avoid loading a project, check if the directory matches this. 153 "To avoid loading a project, check if the directory matches this.
127For projects that use directory name matches, a function would load that project. 154Specifying this matcher object will allow EDE to perform a complex
128Specifying this matcher will allow EDE to check without loading the project.") 155check without loading the project.
156
157NOTE: If you use dirmatch, you may need to set :root-only to `nil'.
158While it may be a root based project, all subdirs will happen to return
159true for the dirmatch, so for scanning purposes, set it to `nil'.")
129 (proj-root :initarg :proj-root 160 (proj-root :initarg :proj-root
130 :type function 161 :type function
131 :documentation "A function symbol to call for the project root. 162 :documentation "A function symbol to call for the project root.
@@ -168,12 +199,14 @@ type is required and the load function used.")
168 (ede-project-autoload "edeproject-makefile" 199 (ede-project-autoload "edeproject-makefile"
169 :name "Make" :file 'ede/proj 200 :name "Make" :file 'ede/proj
170 :proj-file "Project.ede" 201 :proj-file "Project.ede"
202 :root-only nil
171 :load-type 'ede-proj-load 203 :load-type 'ede-proj-load
172 :class-sym 'ede-proj-project 204 :class-sym 'ede-proj-project
173 :safe-p nil) 205 :safe-p nil)
174 (ede-project-autoload "edeproject-automake" 206 (ede-project-autoload "edeproject-automake"
175 :name "Automake" :file 'ede/proj 207 :name "Automake" :file 'ede/proj
176 :proj-file "Project.ede" 208 :proj-file "Project.ede"
209 :root-only nil
177 :initializers '(:makefile-type Makefile.am) 210 :initializers '(:makefile-type Makefile.am)
178 :load-type 'ede-proj-load 211 :load-type 'ede-proj-load
179 :class-sym 'ede-proj-project 212 :class-sym 'ede-proj-project
@@ -181,6 +214,7 @@ type is required and the load function used.")
181 (ede-project-autoload "automake" 214 (ede-project-autoload "automake"
182 :name "automake" :file 'ede/project-am 215 :name "automake" :file 'ede/project-am
183 :proj-file "Makefile.am" 216 :proj-file "Makefile.am"
217 :root-only nil
184 :load-type 'project-am-load 218 :load-type 'project-am-load
185 :class-sym 'project-am-makefile 219 :class-sym 'project-am-makefile
186 :new-p nil 220 :new-p nil
@@ -233,97 +267,33 @@ added. Possible values are:
233 ;; Splice into the list. 267 ;; Splice into the list.
234 (setcdr prev (cons projauto next)))))))) 268 (setcdr prev (cons projauto next))))))))
235 269
236;;; EDE project-autoload methods 270;;; Project Autoload Methods
237;; 271;;
238(defmethod ede-project-root ((this ede-project-autoload))
239 "If a project knows its root, return it here.
240Allows for one-project-object-for-a-tree type systems."
241 nil)
242
243(defun ede-project-dirmatch-p (file dirmatch)
244 "Return non-nil if FILE matches DIRMATCH.
245DIRMATCH could be nil (no match), a string (regexp match),
246or an `ede-project-autoload-dirmatch' object."
247 ;; If dirmatch is a string, then we simply match it against
248 ;; the file we are testing.
249 (if (stringp dirmatch)
250 (string-match dirmatch file)
251 ;; if dirmatch is instead a dirmatch object, we test against
252 ;; that object instead.
253 (if (ede-project-autoload-dirmatch-p dirmatch)
254 (ede-do-dirmatch dirmatch file)
255 (error "Unknown project directory match type."))
256 ))
257 272
258(defmethod ede-project-root-directory ((this ede-project-autoload) 273;; New method using detect.el
259 &optional file) 274(defmethod ede-auto-detect-in-dir ((this ede-project-autoload) dir)
260 "If a project knows its root, return it here. 275 "Return non-nil if THIS project autoload is found in DIR."
261Allows for one-project-object-for-a-tree type systems.
262Optional FILE is the file to test. If there is no FILE, use
263the current buffer."
264 (when (not file)
265 (setq file default-directory))
266 (when (slot-boundp this :proj-root)
267 (let ((dirmatch (oref this proj-root-dirmatch))
268 (rootfcn (oref this proj-root))
269 (callfcn t))
270 (when rootfcn
271 (if ;; If the dirmatch (an object) is not installed, then we
272 ;; always skip doing a match.
273 (and (ede-project-autoload-dirmatch-p dirmatch)
274 (not (ede-dirmatch-installed dirmatch)))
275 (setq callfcn nil)
276 ;; Other types of dirmatch:
277 (when (and
278 ;; If the Emacs Lisp file handling this project hasn't
279 ;; been loaded, we will use the quick dirmatch feature.
280 (not (featurep (oref this file)))
281 ;; If the dirmatch is an empty string, then we always
282 ;; skip doing a match.
283 (not (and (stringp dirmatch) (string= dirmatch "")))
284 )
285 ;; If this file DOES NOT match dirmatch, we set the callfcn
286 ;; to nil, meaning don't load the ede support file for this
287 ;; type of project. If it does match, we will load the file
288 ;; and use a more accurate programmatic match from there.
289 (unless (ede-project-dirmatch-p file dirmatch)
290 (setq callfcn nil))))
291 ;; Call into the project support file for a match.
292 (when callfcn
293 (condition-case nil
294 (funcall rootfcn file)
295 (error
296 (funcall rootfcn))))
297 ))))
298
299(defmethod ede-dir-to-projectfile ((this ede-project-autoload) dir)
300 "Return a full file name of project THIS found in DIR.
301Return nil if the project file does not exist."
302 (let* ((d (file-name-as-directory dir)) 276 (let* ((d (file-name-as-directory dir))
303 (root (ede-project-root-directory this d))
304 (pf (oref this proj-file)) 277 (pf (oref this proj-file))
305 (dm (oref this proj-root-dirmatch)) 278 (f (when (stringp pf) (expand-file-name pf d))))
306 (f (cond ((stringp pf) 279 (if f
307 (expand-file-name pf (or root d))) 280 (and f (file-exists-p f))
308 ((and (symbolp pf) (fboundp pf)) 281 (let ((dirmatch (oref this proj-root-dirmatch)))
309 ;; If there is a symbol to call, lets make extra 282 (cond
310 ;; sure we really can call it without loading in 283 ((stringp dirmatch)
311 ;; other EDE projects. This happens if the file is 284 nil) ; <- do something here - maybe obsolete the option?
312 ;; already loaded, or if there is a dirmatch, but 285 ((ede-project-autoload-dirmatch-p dirmatch)
313 ;; root is empty. 286 (if (and dirmatch (ede-dirmatch-installed dirmatch))
314 (when (and (featurep (oref this file)) 287 (ede-do-dirmatch dirmatch dir)
315 (or (not (stringp dm)) 288 ;(message "Dirmatch %S not installed." dirmatch)
316 (not (string= dm ""))) 289 )))))))
317 root)
318 (funcall pf (or root d))))))
319 )
320 (when (and f (file-exists-p f))
321 f)))
322 290
323(defmethod ede-auto-load-project ((this ede-project-autoload) dir) 291(defmethod ede-auto-load-project ((this ede-project-autoload) dir)
324 "Load in the project associated with THIS project autoload description. 292 "Load in the project associated with THIS project autoload description.
325THIS project description should be valid for DIR, where the project will 293THIS project description should be valid for DIR, where the project will
326be loaded." 294be loaded.
295
296NOTE: Do not call this - it should only be called from `ede-load-project-file'."
327 ;; Last line of defense: don't load unsafe projects. 297 ;; Last line of defense: don't load unsafe projects.
328 (when (not (or (oref this :safe-p) 298 (when (not (or (oref this :safe-p)
329 (ede-directory-safe-p dir))) 299 (ede-directory-safe-p dir)))
@@ -332,7 +302,27 @@ be loaded."
332 (let ((o (funcall (oref this load-type) dir))) 302 (let ((o (funcall (oref this load-type) dir)))
333 (when (not o) 303 (when (not o)
334 (error "Project type error: :load-type failed to create a project")) 304 (error "Project type error: :load-type failed to create a project"))
335 (ede-add-project-to-global-list o))) 305 (ede-add-project-to-global-list o)
306 ;; @TODO - Add to hash over at `ede-inode-directory-hash'.
307 ))
308
309
310
311
312
313
314;;; -------- Old Methods
315;; See if we can do without them.
316
317;; @FIXME - delete from loaddefs to remove this.
318(defmethod ede-project-root ((this ede-project-autoload))
319 "If a project knows its root, return it here.
320Allows for one-project-object-for-a-tree type systems."
321 nil)
322
323;; @FIXME - delete from loaddefs to remove this.
324(defmethod ede-project-root-directory ((this ede-project-autoload) &optional file)
325 "" nil)
336 326
337(provide 'ede/auto) 327(provide 'ede/auto)
338 328
diff --git a/lisp/cedet/ede/autoconf-edit.el b/lisp/cedet/ede/autoconf-edit.el
index 3ac6949fbb6..0e829def562 100644
--- a/lisp/cedet/ede/autoconf-edit.el
+++ b/lisp/cedet/ede/autoconf-edit.el
@@ -60,6 +60,7 @@ configure the initial configure script using `autoconf-new-automake-string'"
60 60
61(defvar autoconf-preferred-macro-order 61(defvar autoconf-preferred-macro-order
62 '("AC_INIT" 62 '("AC_INIT"
63 "AC_CONFIG_SRCDIR"
63 "AM_INIT_AUTOMAKE" 64 "AM_INIT_AUTOMAKE"
64 "AM_CONFIG_HEADER" 65 "AM_CONFIG_HEADER"
65 ;; Arg parsing 66 ;; Arg parsing
diff --git a/lisp/cedet/ede/base.el b/lisp/cedet/ede/base.el
index 283f9dccac7..4183ff4c61a 100644
--- a/lisp/cedet/ede/base.el
+++ b/lisp/cedet/ede/base.el
@@ -605,7 +605,7 @@ Display the results as a debug list."
605 "Return the ede project which is the root of the current project. 605 "Return the ede project which is the root of the current project.
606Optional argument SUBPROJ indicates a subproject to start from 606Optional argument SUBPROJ indicates a subproject to start from
607instead of the current project." 607instead of the current project."
608 (or ede-object-root-project 608 (or (when (not subproj) ede-object-root-project)
609 (let* ((cp (or subproj (ede-current-project)))) 609 (let* ((cp (or subproj (ede-current-project))))
610 (or (and cp (ede-project-root cp)) 610 (or (and cp (ede-project-root cp))
611 (progn 611 (progn
diff --git a/lisp/cedet/ede/config.el b/lisp/cedet/ede/config.el
new file mode 100644
index 00000000000..3ac3c06f335
--- /dev/null
+++ b/lisp/cedet/ede/config.el
@@ -0,0 +1,416 @@
1;;; ede/config.el --- Configuration Handler baseclass
2
3;; Copyright (C) 2014 Free Software Foundation, Inc.
4
5;; Author: Eric 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;; Some auto-detecting projects (such as the 'generic' project type)
25;; can be enhanced by also saving a configuration file that is EDE
26;; specific. EDE will be able to load that configuration from the save
27;; file as a way of augmenting what is normally already detected.
28;;
29;; How To Use:
30;;
31;; Subclass `ede-extra-config', and add the features you want to use.
32;; Several mixins are available for adding in C++ or Java support. Bring
33;; in the pieces you need.
34;;
35;; Your project and targets should all have a common baseclass from
36;; `ede-project-with-config' or `ede-target-with-config'. When
37;; subclassing the project, be sure to override the class allocated
38;; slots for the `config-class'. This will tie your new project to
39;; the new configuration type.
40;;
41;; You can also override the file name used to save the configuration
42;; object in.
43;;
44;; If you need to take special action in `project-rescan' be sure to also
45;; call `call-next-method' to also get the configuration rescanned.
46;;
47;; Note on config file safety:
48;;
49;; Normally an EDE project that loads a save file should have it's
50;; autoload slot :safe-p set to nil. Projects who save data via
51;; config.el can mark their project as :safe-p t. The config system will
52;; do the queries needed to protect the user. This allows a generic
53;; project to become active in cases where no save file exists, nor is
54;; needed.
55
56;;; Code:
57(require 'ede)
58
59;;; CONFIG
60;;
61;; This is the base of a configuration class supported by the
62;; `ede-project-with-config' baseclass.
63;;
64(defclass ede-extra-config (eieio-persistent)
65 ((extension :initform ".ede")
66 (file-header-line :initform ";; EDE Project Configuration")
67 (project :type ede-project-with-config-child
68 :documentation
69 "The project this config is bound to.")
70 (ignored-file :initform nil
71 :type (or null symbol)
72 :documentation
73 "Set to non-nil if this was created and an on-disk file
74was ignored. Use this to warn the user that they might want to load in
75an on-disk version.")
76 )
77 "Baseclass for auxilliary configuration files for EDE.
78This should be subclassed by projects that auto detect a project
79and also want to save some extra level of configuration.")
80
81;;; PROJECT BASECLASS
82;;
83;; Subclass this baseclass if you want your EDE project to also
84;; support saving an extra configuration file of unique data
85;; needed for this project.
86;;
87(defclass ede-project-with-config (ede-project)
88 ((menu :initform nil)
89 (config-file-basename
90 :initform "Config.ede"
91 :allocation :class
92 :type string
93 :documentation
94 "The filename to use for saving the configuration.
95This filename excludes the directory name and is used to
96initalize the :file slot of the persistent baseclass.")
97 (config-class
98 :initform ede-extra-config
99 :allocation :class
100 :type class
101 :documentation
102 "The class of the configuration used by this project.")
103 (config :initform nil
104 :type (or null ede-extra-config-child)
105 :documentation
106 "The configuration object for this project.")
107 )
108 "Baseclass for projects that save a configuration.")
109
110(defclass ede-target-with-config (ede-target)
111 ()
112 "Baseclass for targetes of classes that use a config object.")
113
114;;; Rescanning
115
116(defmethod project-rescan ((this ede-project-with-config))
117 "Rescan this generic project from the sources."
118 ;; Force the config to be rescanned.
119 (oset this config nil)
120 ;; Ask if it is safe to load the config from disk.
121 (ede-config-get-configuration this t)
122 )
123
124;;; Project Methods for configuration
125
126(defmethod ede-config-get-configuration ((proj ede-project-with-config) &optional loadask)
127 "Return the configuration for the project PROJ.
128If optional LOADASK is non-nil, then if a project file exists, and if
129the directory isn't on the `safe' list, ask to add it to the safe list."
130 (let ((config (oref proj config)))
131
132 ;; If the request is coming at a time when we want to ask the user,
133 ;; and there already is a configuration, AND the last time we ignored
134 ;; the on-file version we did so automatically (without asking) then
135 ;; in theory there are NO mods to this config, and we should re-ask,
136 ;; and possibly re-load.
137 (when (and loadask config (eq (oref config ignored-file) 'auto))
138 (setq config nil))
139
140 (when (not config)
141 (let* ((top (oref proj :directory))
142 (fname (expand-file-name (oref proj config-file-basename) top))
143 (class (oref proj config-class))
144 (ignore-type nil))
145 (if (and (file-exists-p fname)
146 (or (ede-directory-safe-p top)
147 ;; Only force the load if someone asked.
148 (and loadask (ede-check-project-directory top))))
149 ;; Load in the configuration
150 (setq config (eieio-persistent-read fname class))
151 ;; If someone said not to load stuff from here then
152 ;; pop up a warning.
153 (when (file-exists-p fname)
154 (message "Ignoring EDE config file for now and creating a new one. Use C-c . g to load it.")
155 ;; Set how it was ignored.
156 (if loadask
157 (setq ignore-type 'manual)
158 (setq ignore-type 'auto))
159 )
160 ;; Create a new one.
161 (setq config (make-instance class
162 "Configuration"
163 :file fname))
164 (oset config ignored-file ignore-type)
165
166 ;; Set initial values based on project.
167 (ede-config-setup-configuration proj config))
168 ;; Link things together.
169 (oset proj config config)
170 (oset config project proj)))
171 config))
172
173(defmethod ede-config-setup-configuration ((proj ede-project-with-config) config)
174 "Default configuration setup method."
175 nil)
176
177(defmethod ede-commit-project ((proj ede-project-with-config))
178 "Commit any change to PROJ to its file."
179 (let ((config (ede-config-get-configuration proj)))
180 (ede-commit config)))
181
182;;; Customization
183;;
184(defmethod ede-customize ((proj ede-project-with-config))
185 "Customize the EDE project PROJ by actually configuring the config object."
186 (let ((config (ede-config-get-configuration proj t)))
187 (eieio-customize-object config)))
188
189(defmethod ede-customize ((target ede-target-with-config))
190 "Customize the EDE TARGET by actually configuring the config object."
191 ;; Nothing unique for the targets, use the project.
192 (ede-customize-project))
193
194(defmethod eieio-done-customizing ((config ede-extra-config))
195 "Called when EIEIO is done customizing the configuration object.
196We need to go back through the old buffers, and update them with
197the new configuration."
198 (ede-commit config)
199 ;; Loop over all the open buffers, and re-apply.
200 (ede-map-targets
201 (oref config project)
202 (lambda (target)
203 (ede-map-target-buffers
204 target
205 (lambda (b)
206 (with-current-buffer b
207 (ede-apply-target-options)))))))
208
209(defmethod ede-commit ((config ede-extra-config))
210 "Commit all changes to the configuration to disk."
211 ;; So long as the user is trying to safe this config, make sure they can
212 ;; get at it again later.
213 (let ((dir (file-name-directory (oref config file))))
214 (ede-check-project-directory dir))
215
216 (eieio-persistent-save config))
217
218;;; PROJECT MIXINS
219;;
220;; These are project part mixins. Use multiple inheritence for each
221;; piece of these configuration optiosn you would like to have as part
222;; of your project.
223
224;;; PROGRAM
225;; If there is a program that can be run or debugged that is unknown
226;; and needs to be configured.
227(defclass ede-extra-config-program ()
228 ((debug-command :initarg :debug-command
229 :initform "gdb "
230 :type string
231 :group commands
232 :custom string
233 :group (default build)
234 :documentation
235 "Command used for debugging this project.")
236 (run-command :initarg :run-command
237 :initform ""
238 :type string
239 :group commands
240 :custom string
241 :group (default build)
242 :documentation
243 "Command used to run something related to this project."))
244 "Class to mix into a configuration for debug/run of programs.")
245
246(defclass ede-project-with-config-program ()
247 ()
248 "Class to mix into a project with configuration for programs.")
249
250(defclass ede-target-with-config-program ()
251 ()
252 "Class to mix into a project with configuration for programs.
253This class brings in method overloads for running and debugging
254programs from a project.")
255
256(defmethod project-debug-target ((target ede-target-with-config-program))
257 "Run the current project derived from TARGET in a debugger."
258 (let* ((proj (ede-target-parent target))
259 (config (ede-config-get-configuration proj t))
260 (debug (oref config :debug-command))
261 (cmd (read-from-minibuffer
262 "Debug Command: "
263 debug))
264 (cmdsplit (split-string cmd " " t))
265 ;; @TODO - this depends on the user always typing in something good
266 ;; like "gdb" or "dbx" which also exists as a useful Emacs command.
267 ;; Is there a better way?
268 (cmdsym (intern-soft (car cmdsplit))))
269 (call-interactively cmdsym t)))
270
271(defmethod project-run-target ((target ede-target-with-config-program))
272 "Run the current project derived from TARGET."
273 (let* ((proj (ede-target-parent target))
274 (config (ede-config-get-configuration proj t))
275 (run (concat "./" (oref config :run-command)))
276 (cmd (read-from-minibuffer "Run (like this): " run)))
277 (ede-shell-run-something target cmd)))
278
279;;; BUILD
280;; If the build style is unknown and needs to be configured.
281(defclass ede-extra-config-build ()
282 ((build-command :initarg :build-command
283 :initform "make -k"
284 :type string
285 :group commands
286 :custom string
287 :group (default build)
288 :documentation
289 "Command used for building this project."))
290 "Class to mix into a configuration for compilation.")
291
292(defclass ede-project-with-config-build ()
293 ()
294 "Class to mix into a project with configuration for builds.
295This class brings in method overloads for building.")
296
297(defclass ede-target-with-config-build ()
298 ()
299 "Class to mix into a project with configuration for builds.
300This class brings in method overloads for for building.")
301
302(defmethod project-compile-project ((proj ede-project-with-config-build) &optional command)
303 "Compile the entire current project PROJ.
304Argument COMMAND is the command to use when compiling."
305 (let* ((config (ede-config-get-configuration proj t))
306 (comp (oref config :build-command)))
307 (compile comp)))
308
309(defmethod project-compile-target ((obj ede-target-with-config-build) &optional command)
310 "Compile the current target OBJ.
311Argument COMMAND is the command to use for compiling the target."
312 (project-compile-project (ede-current-project) command))
313
314;;; C / C++
315;; Configure includes and preprocessor symbols for C/C++ needed by
316;; Semantic.
317(defclass ede-extra-config-c ()
318 ((c-include-path :initarg :c-include-path
319 :initform nil
320 :type list
321 :custom (repeat (string :tag "Path"))
322 :group c
323 :documentation
324 "The include path used by C/C++ projects.
325The include path is used when searching for symbols.")
326 (c-preprocessor-table :initarg :c-preprocessor-table
327 :initform nil
328 :type list
329 :custom (repeat (cons (string :tag "Macro")
330 (string :tag "Value")))
331 :group c
332 :documentation
333 "Preprocessor Symbols for this project.
334When files within this project are parsed by CEDET, these symbols will be
335used to resolve macro occurrences in source fies.
336If you modify this slot, you will need to force your source files to be
337parsed again.")
338 (c-preprocessor-files :initarg :c-preprocessor-files
339 :initform nil
340 :type list
341 :group c
342 :custom (repeat (string :tag "Include File"))
343 :documentation
344 "Files parsed and used to populate preprocessor tables.
345When files within this project are parsed by CEDET, these symbols will be used to
346resolve macro occurences in source files.
347If you modify this slot, you will need to force your source files to be
348parsed again."))
349 "Class to mix into a configuration for compilation.")
350
351(defclass ede-project-with-config-c ()
352 ()
353 "Class to mix into a project for C/C++ support.")
354
355(defclass ede-target-with-config-c ()
356 ()
357 "Class to mix into a project for C/C++ support.
358This target brings in methods used by Semantic to query
359the preprocessor map, and include paths.")
360
361(defmethod ede-preprocessor-map ((this ede-target-with-config-c))
362 "Get the pre-processor map for some generic C code."
363 (let* ((proj (ede-target-parent this))
364 (root (ede-project-root proj))
365 (config (ede-config-get-configuration proj))
366 filemap
367 )
368 ;; Preprocessor files
369 (dolist (G (oref config :c-preprocessor-files))
370 (let ((table (semanticdb-file-table-object
371 (ede-expand-filename root G))))
372 (when table
373 (when (semanticdb-needs-refresh-p table)
374 (semanticdb-refresh-table table))
375 (setq filemap (append filemap (oref table lexical-table)))
376 )))
377 ;; The core table
378 (setq filemap (append filemap (oref config :c-preprocessor-table)))
379
380 filemap
381 ))
382
383(defmethod ede-system-include-path ((this ede-target-with-config-c))
384 "Get the system include path used by project THIS."
385 (let* ((proj (ede-target-parent this))
386 (config (ede-config-get-configuration proj)))
387 (oref config c-include-path)))
388
389;;; Java
390;; Configuration needed for programming with Java.
391(defclass ede-extra-config-java ()
392 ()
393 "Class to mix into a configuration for compilation.")
394
395(defclass ede-project-with-config-java ()
396 ()
397 "Class to mix into a project to support java.
398This brings in methods to support Semantic querying the
399java class path.")
400
401(defclass ede-target-with-config-java ()
402 ()
403 "Class to mix into a project to support java.")
404
405(defmethod ede-java-classpath ((proj ede-project-with-config-java))
406 "Return the classpath for this project."
407 (oref (ede-config-get-configuration proj) :classpath))
408
409;; Local variables:
410;; generated-autoload-file: "loaddefs.el"
411;; generated-autoload-load-name: "ede/config"
412;; End:
413
414(provide 'ede/config)
415
416;;; ede/config.el ends here
diff --git a/lisp/cedet/ede/cpp-root.el b/lisp/cedet/ede/cpp-root.el
index bf5c8257c90..7ea92364f28 100644
--- a/lisp/cedet/ede/cpp-root.el
+++ b/lisp/cedet/ede/cpp-root.el
@@ -116,11 +116,6 @@
116;; <write your code here, or return nil> 116;; <write your code here, or return nil>
117;; ) 117;; )
118;; 118;;
119;; (defun MY-ROOT-FCN ()
120;; "Return the root directory for `default-directory'"
121;; ;; You might be able to use `ede-cpp-root-project-root'.
122;; )
123;;
124;; (defun MY-LOAD (dir) 119;; (defun MY-LOAD (dir)
125;; "Load a project of type `cpp-root' for the directory DIR. 120;; "Load a project of type `cpp-root' for the directory DIR.
126;; Return nil if there isn't one." 121;; Return nil if there isn't one."
@@ -128,16 +123,14 @@
128;; :locate-fcn 'MYFCN) 123;; :locate-fcn 'MYFCN)
129;; ) 124;; )
130;; 125;;
131;; (add-to-list 'ede-project-class-files 126;; (ede-add-project-autoload
132;; (ede-project-autoload "cpp-root" 127;; (ede-project-autoload "cpp-root"
133;; :name "CPP ROOT" 128;; :name "CPP ROOT"
134;; :file 'ede/cpp-root 129;; :file 'ede/cpp-root
135;; :proj-file 'MY-FILE-FOR-DIR 130;; :proj-file 'MY-FILE-FOR-DIR
136;; :proj-root 'MY-ROOT-FCN
137;; :load-type 'MY-LOAD 131;; :load-type 'MY-LOAD
138;; :class-sym 'ede-cpp-root-project 132;; :class-sym 'ede-cpp-root-project
139;; :safe-p t) 133;; :safe-p t))
140;; t)
141;; 134;;
142;;; TODO 135;;; TODO
143;; 136;;
@@ -168,91 +161,13 @@
168 161
169;;; PROJECT CACHE: 162;;; PROJECT CACHE:
170;; 163;;
171;; cpp-root projects are created in a .emacs or other config file, but 164;; cpp-root projects are created in a .emacs or other config file. We
172;; there still needs to be a way for a particular file to be 165;; need to cache them so if the user re-loads a lisp file with the
173;; identified against it. The cache is where we look to map a file 166;; config in it, we can flush out the old one and replace it.
174;; against a project.
175;;
176;; Setting up a simple in-memory cache of active projects allows the
177;; user to re-load their configuration file several times without
178;; messing up the active project set.
179;; 167;;
180(defvar ede-cpp-root-project-list nil 168(defvar ede-cpp-root-project-list nil
181 "List of projects created by option `ede-cpp-root-project'.") 169 "List of projects created by option `ede-cpp-root-project'.")
182 170
183(defun ede-cpp-root-file-existing (dir)
184 "Find a cpp-root project in the list of cpp-root projects.
185DIR is the directory to search from."
186 (let ((projs ede-cpp-root-project-list)
187 (ans nil))
188 (while (and projs (not ans))
189 (let ((root (ede-project-root-directory (car projs))))
190 (when (string-match (concat "^" (regexp-quote root)) dir)
191 (setq ans (car projs))))
192 (setq projs (cdr projs)))
193 ans))
194
195;;; PROJECT AUTOLOAD CONFIG
196;;
197;; Each project type registers itself into the project-class list.
198;; This way, each time a file is loaded, EDE can map that file to a
199;; project. This project type checks files against the internal cache
200;; of projects created by the user.
201;;
202;; EDE asks two kinds of questions. One is, does this DIR belong to a
203;; project. If it does, it then asks, what is the ROOT directory to
204;; the project in DIR. This is easy for cpp-root projects, but more
205;; complex for multiply nested projects.
206;;
207;; If EDE finds out that a project exists for DIR, it then loads that
208;; project. The LOAD routine can either create a new project object
209;; (if it needs to load it off disk) or more likely can return an
210;; existing object for the discovered directory. cpp-root always uses
211;; the second case.
212
213(defun ede-cpp-root-project-file-for-dir (&optional dir)
214 "Return a full file name to the project file stored in DIR."
215 (let ((proj (ede-cpp-root-file-existing dir)))
216 (when proj (oref proj :file))))
217
218(defvar ede-cpp-root-count 0
219 "Count number of hits to the cpp root thing.
220This is a debugging variable to test various optimizations in file
221lookup in the main EDE logic.")
222
223;;;###autoload
224(defun ede-cpp-root-project-root (&optional dir)
225 "Get the root directory for DIR."
226 (let ((projfile (ede-cpp-root-project-file-for-dir
227 (or dir default-directory))))
228 (setq ede-cpp-root-count (1+ ede-cpp-root-count))
229 ;(debug)
230 (when projfile
231 (file-name-directory projfile))))
232
233(defun ede-cpp-root-load (dir &optional rootproj)
234 "Return a CPP root object if you created one.
235Return nil if there isn't one.
236Argument DIR is the directory it is created for.
237ROOTPROJ is nil, since there is only one project."
238 ;; Snoop through our master list.
239 (ede-cpp-root-file-existing dir))
240
241;;;###autoload
242(ede-add-project-autoload
243 (ede-project-autoload "cpp-root"
244 :name "CPP ROOT"
245 :file 'ede/cpp-root
246 :proj-file 'ede-cpp-root-project-file-for-dir
247 :proj-root 'ede-cpp-root-project-root
248 :load-type 'ede-cpp-root-load
249 :class-sym 'ede-cpp-root-project
250 :new-p nil
251 :safe-p t)
252 ;; When a user creates one of these, it should override any other project
253 ;; type that might happen to be in this directory, so force this to the
254 ;; very front.
255 'unique)
256 171
257;;; CLASSES 172;;; CLASSES
258;; 173;;
@@ -372,6 +287,7 @@ Each directory needs a project file to control it.")
372 :directory 'ede-cpp-root-project-list))) 287 :directory 'ede-cpp-root-project-list)))
373 ;; This is safe, because :directory isn't filled in till later. 288 ;; This is safe, because :directory isn't filled in till later.
374 (when (and old (not (eq old this))) 289 (when (and old (not (eq old this)))
290 (ede-delete-project-from-global-list old)
375 (delete-instance old))) 291 (delete-instance old)))
376 ;; Basic initialization. 292 ;; Basic initialization.
377 (when (or (not (file-exists-p f)) 293 (when (or (not (file-exists-p f))
@@ -381,11 +297,13 @@ Each directory needs a project file to control it.")
381 (oset this :file f) 297 (oset this :file f)
382 (oset this :directory (file-name-directory f)) 298 (oset this :directory (file-name-directory f))
383 (ede-project-directory-remove-hash (file-name-directory f)) 299 (ede-project-directory-remove-hash (file-name-directory f))
300 ;; NOTE: We must add to global list here because these classes are not
301 ;; created via the typial loader, but instead via calls from a .emacs
302 ;; file.
384 (ede-add-project-to-global-list this) 303 (ede-add-project-to-global-list this)
304
385 (unless (slot-boundp this 'targets) 305 (unless (slot-boundp this 'targets)
386 (oset this :targets nil)) 306 (oset this :targets nil))
387 ;; We need to add ourselves to the master list.
388 ;;(setq ede-projects (cons this ede-projects))
389 )) 307 ))
390 308
391;;; SUBPROJ Management. 309;;; SUBPROJ Management.
@@ -465,7 +383,7 @@ This knows details about or source tree."
465 383
466(defmethod ede-project-root-directory ((this ede-cpp-root-project)) 384(defmethod ede-project-root-directory ((this ede-cpp-root-project))
467 "Return my root." 385 "Return my root."
468 (file-name-directory (oref this file))) 386 (oref this directory))
469 387
470;;; C/CPP SPECIFIC CODE 388;;; C/CPP SPECIFIC CODE
471;; 389;;
@@ -558,6 +476,10 @@ Argument COMMAND is the command to use for compiling the target."
558 (project-compile-project (oref obj :project) command))) 476 (project-compile-project (oref obj :project) command)))
559 477
560 478
479(defmethod project-rescan ((this ede-cpp-root-project))
480 "Don't rescan this project from the sources."
481 (message "cpp-root has nothing to rescan."))
482
561;;; Quick Hack 483;;; Quick Hack
562(defun ede-create-lots-of-projects-under-dir (dir projfile &rest attributes) 484(defun ede-create-lots-of-projects-under-dir (dir projfile &rest attributes)
563 "Create a bunch of projects under directory DIR. 485 "Create a bunch of projects under directory DIR.
diff --git a/lisp/cedet/ede/detect.el b/lisp/cedet/ede/detect.el
new file mode 100644
index 00000000000..2b329185c84
--- /dev/null
+++ b/lisp/cedet/ede/detect.el
@@ -0,0 +1,210 @@
1;;; ede/detect.el --- EDE project detection and file associations
2
3;; Copyright (C) 2014 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;; Project detection for EDE;
25;;
26;; Detection comes in multiple forms:
27;;
28;; `ede-detect-scan-directory-for-project' -
29;; Scan for a project via the file system.
30;; `ede-detect-directory-for-project' -
31;; Check our file cache for a project. If that failes, use
32;; the scan fcn above.
33
34;;; Code:
35
36(require 'ede/auto) ;; Autoload settings.
37
38(when (or (<= emacs-major-version 23)
39 ;; predicate as name added in Emacs 24.2
40 (and (= emacs-major-version 24)
41 (< emacs-minor-version 2)))
42 (message "Loading CEDET fallback autoload library.")
43 (require 'cedet/dominate
44 (expand-file-name "../../../etc/fallback-libraries/dominate.el"
45 (file-name-directory load-file-name))))
46
47
48;;; BASIC PROJECT SCAN
49;;
50(defun ede--detect-stop-scan-p (dir)
51 "Return non-nil if we need to stop scanning upward in DIR."
52 ;;(let ((stop
53 (file-exists-p (expand-file-name ".ede_stop_scan" dir)))
54;;)
55;;(when stop
56;;(message "Stop Scan at %s" dir))
57;;stop))
58
59(defvar ede--detect-found-project nil
60 "When searching for a project, temporarilly save that file.")
61
62(defun ede--detect-ldf-predicate (dir)
63 "Non-nil if DIR contain any known EDE project types."
64 (if (ede--detect-stop-scan-p dir)
65 (throw 'stopscan nil)
66 (let ((types ede-project-class-files))
67 ;; Loop over all types, loading in the first type that we find.
68 (while (and types (not ede--detect-found-project))
69 (if (ede-auto-detect-in-dir (car types) dir)
70 (progn
71 ;; We found one!
72 (setq ede--detect-found-project (car types)))
73 (setq types (cdr types)))
74 )
75 ede--detect-found-project)))
76
77(defun ede--detect-scan-directory-for-project (directory)
78 "Detect an EDE project for the current DIRECTORY by scanning.
79This function ALWAYS scans files and directories and DOES NOT
80use any file caches.
81Return a cons cell:
82 ( ROOTDIR . PROJECT-AUTOLOAD)"
83 (let* ((ede--detect-found-project nil)
84 (root
85 (catch 'stopscan
86 (locate-dominating-file directory
87 'ede--detect-ldf-predicate))))
88 (when root
89 (cons root ede--detect-found-project))))
90
91;;; Root Only project detect
92;;
93;; For projects that only have a detectible ROOT file, but may in fact
94;; contain a generic file such as a Makefile, we need to do a second scan
95;; to make sure we don't miss-match.
96(defun ede--detect-ldf-rootonly-predicate (dir)
97 "Non-nil if DIR contain any known EDE project types."
98 (if (ede--detect-stop-scan-p dir)
99 (throw 'stopscan nil)
100 (let ((types ede-project-class-files))
101 ;; Loop over all types, loading in the first type that we find.
102 (while (and types (not ede--detect-found-project))
103 (if (and
104 (oref (car types) root-only)
105 (ede-auto-detect-in-dir (car types) dir))
106 (progn
107 ;; We found one!
108 (setq ede--detect-found-project (car types)))
109 (setq types (cdr types)))
110 )
111 ede--detect-found-project)))
112
113(defun ede--detect-scan-directory-for-rootonly-project (directory)
114 "Detect an EDE project for the current DIRECTORY by scanning.
115This function ALWAYS scans files and directories and DOES NOT
116use any file caches.
117Return a cons cell:
118 ( ROOTDIR . PROJECT-AUTOLOAD)"
119 (let* ((ede--detect-found-project nil)
120 (root
121 (catch 'stopscan
122 (locate-dominating-file directory
123 'ede--detect-ldf-rootonly-predicate))))
124 (when root
125 (cons root ede--detect-found-project))))
126
127
128;;; NESTED PROJECT SCAN
129;;
130;; For projects that can have their dominating file exist in all their
131;; sub-directories as well.
132
133(defvar ede--detect-nomatch-auto nil
134 "An ede autoload that needs to be un-matched.")
135
136(defun ede--detect-ldf-root-predicate (dir)
137 "Non-nil if DIR no longer match `ede--detect-nomatch-auto'."
138 (or (ede--detect-stop-scan-p dir)
139 ;; To know if DIR is at the top, we need to look just above
140 ;; to see if there is a match.
141 (let ((updir (file-name-directory (directory-file-name dir))))
142 (if (equal updir dir)
143 ;; If it didn't change, then obviously this must be the top.
144 t
145 ;; If it is different, check updir for the file.
146 (not (ede-auto-detect-in-dir ede--detect-nomatch-auto updir))))))
147
148(defun ede--detect-scan-directory-for-project-root (directory auto)
149 "If DIRECTORY has already been detected with AUTO, find the root.
150Some projects have their dominating file in all their directories, such
151as Project.ede. In that case we will detect quickly, but then need
152to scan upward to find the topmost occurance of that file."
153 (let* ((ede--detect-nomatch-auto auto)
154 (root (locate-dominating-file directory
155 'ede--detect-ldf-root-predicate)))
156 root))
157
158;;; TOP LEVEL SCAN
159;;
160;; This function for combining the above scans.
161(defun ede-detect-directory-for-project (directory)
162 "Detect an EDE project for the current DIRECTORY.
163Scan the filesystem for a project.
164Return a cons cell:
165 ( ROOTDIR . PROJECT-AUTOLOAD)"
166 (let* ((scan (ede--detect-scan-directory-for-project directory))
167 (root (car scan))
168 (auto (cdr scan)))
169 (when scan
170 ;; If what we found is already a root-only project, return it.
171 (if (oref auto root-only)
172 scan
173
174 ;; If what we found is a generic project, check to make sure we aren't
175 ;; in some other kind of root project.
176 (if (oref auto generic-p)
177 (let ((moreroot (ede--detect-scan-directory-for-rootonly-project root)))
178 ;; If we found a rootier project, return that.
179 (if moreroot
180 moreroot
181
182 ;; If we didn't find a root from the generic project, then
183 ;; we need to rescan upward.
184 (cons (ede--detect-scan-directory-for-project-root root auto) auto)))
185
186 ;; Non-generic non-root projects also need to rescan upward.
187 (cons (ede--detect-scan-directory-for-project-root root auto) auto)))
188
189 )))
190
191;;; TEST
192;;
193;; A quick interactive testing fcn.
194(defun ede-detect-qtest ()
195 "Run a quick test for autodetecting on BUFFER."
196 (interactive)
197 (let ((start (current-time))
198 (ans (ede-detect-directory-for-project default-directory))
199 (end (current-time)))
200 (if ans
201 (message "Project found in %d sec @ %s of type %s"
202 (float-time (time-subtract end start))
203 (car ans)
204 (eieio-object-name-string (cdr ans)))
205 (message "No Project found.") )))
206
207
208(provide 'ede/detect)
209
210;;; ede/detect.el ends here
diff --git a/lisp/cedet/ede/emacs.el b/lisp/cedet/ede/emacs.el
index 76925a66713..88df1d2963f 100644
--- a/lisp/cedet/ede/emacs.el
+++ b/lisp/cedet/ede/emacs.el
@@ -38,37 +38,12 @@
38(declare-function semanticdb-refresh-table "semantic/db") 38(declare-function semanticdb-refresh-table "semantic/db")
39 39
40;;; Code: 40;;; Code:
41(defvar ede-emacs-project-list nil
42 "List of projects created by option `ede-emacs-project'.")
43
44(defun ede-emacs-file-existing (dir)
45 "Find a Emacs project in the list of Emacs projects.
46DIR is the directory to search from."
47 (let ((projs ede-emacs-project-list)
48 (ans nil))
49 (while (and projs (not ans))
50 (let ((root (ede-project-root-directory (car projs))))
51 (when (string-match (concat "^" (regexp-quote root))
52 (file-name-as-directory dir))
53 (setq ans (car projs))))
54 (setq projs (cdr projs)))
55 ans))
56 41
57;;;###autoload 42;; @TODO - get rid of this. Stuck in loaddefs right now.
43
58(defun ede-emacs-project-root (&optional dir) 44(defun ede-emacs-project-root (&optional dir)
59 "Get the root directory for DIR." 45 "Get the root directory for DIR."
60 (when (not dir) (setq dir default-directory)) 46 nil)
61 (let ((case-fold-search t)
62 (proj (ede-files-find-existing dir ede-emacs-project-list)))
63 (if proj
64 (ede-up-directory (file-name-directory
65 (oref proj :file)))
66 ;; No pre-existing project. Let's take a wild-guess if we have
67 ;; an Emacs project here.
68 (when (string-match "emacs[^/]*" dir)
69 (let ((base (substring dir 0 (match-end 0))))
70 (when (file-exists-p (expand-file-name "src/emacs.c" base))
71 base))))))
72 47
73(defun ede-emacs-version (dir) 48(defun ede-emacs-version (dir)
74 "Find the Emacs version for the Emacs src in DIR. 49 "Find the Emacs version for the Emacs src in DIR.
@@ -118,8 +93,8 @@ m4_define(\\[SXEM4CS_BETA_VERSION\\], \\[\\([0-9]+\\)\\])")
118 ;; Return a tuple 93 ;; Return a tuple
119 (cons emacs ver)))) 94 (cons emacs ver))))
120 95
121(defclass ede-emacs-project (ede-project eieio-instance-tracker) 96(defclass ede-emacs-project (ede-project)
122 ((tracking-symbol :initform 'ede-emacs-project-list) 97 (
123 ) 98 )
124 "Project Type for the Emacs source code." 99 "Project Type for the Emacs source code."
125 :method-invocation-order :depth-first) 100 :method-invocation-order :depth-first)
@@ -129,17 +104,15 @@ m4_define(\\[SXEM4CS_BETA_VERSION\\], \\[\\([0-9]+\\)\\])")
129Return nil if there isn't one. 104Return nil if there isn't one.
130Argument DIR is the directory it is created for. 105Argument DIR is the directory it is created for.
131ROOTPROJ is nil, since there is only one project." 106ROOTPROJ is nil, since there is only one project."
132 (or (ede-files-find-existing dir ede-emacs-project-list) 107 ;; Doesn't already exist, so let's make one.
133 ;; Doesn't already exist, so let's make one. 108 (let* ((vertuple (ede-emacs-version dir)))
134 (let* ((vertuple (ede-emacs-version dir)) 109 (ede-emacs-project
135 (proj (ede-emacs-project 110 (car vertuple)
136 (car vertuple) 111 :name (car vertuple)
137 :name (car vertuple) 112 :version (cdr vertuple)
138 :version (cdr vertuple) 113 :directory (file-name-as-directory dir)
139 :directory (file-name-as-directory dir) 114 :file (expand-file-name "src/emacs.c"
140 :file (expand-file-name "src/emacs.c" 115 dir))))
141 dir))))
142 (ede-add-project-to-global-list proj))))
143 116
144;;;###autoload 117;;;###autoload
145(ede-add-project-autoload 118(ede-add-project-autoload
@@ -147,8 +120,6 @@ ROOTPROJ is nil, since there is only one project."
147 :name "EMACS ROOT" 120 :name "EMACS ROOT"
148 :file 'ede/emacs 121 :file 'ede/emacs
149 :proj-file "src/emacs.c" 122 :proj-file "src/emacs.c"
150 :proj-root-dirmatch "emacs[^/]*"
151 :proj-root 'ede-emacs-project-root
152 :load-type 'ede-emacs-load 123 :load-type 'ede-emacs-load
153 :class-sym 'ede-emacs-project 124 :class-sym 'ede-emacs-project
154 :new-p nil 125 :new-p nil
@@ -302,6 +273,15 @@ Knows about how the Emacs source tree is organized."
302 (ede-emacs-find-in-directories name dir dirs)) 273 (ede-emacs-find-in-directories name dir dirs))
303 )) 274 ))
304 275
276;;; Command Support
277;;
278(defmethod project-rescan ((this ede-emacs-project))
279 "Rescan this Emacs project from the sources."
280 (let ((ver (ede-emacs-version (ede-project-root-directory this))))
281 (oset this name (car ver))
282 (oset this version (cdr ver))
283 ))
284
305(provide 'ede/emacs) 285(provide 'ede/emacs)
306 286
307;; Local variables: 287;; Local variables:
diff --git a/lisp/cedet/ede/files.el b/lisp/cedet/ede/files.el
index ac245cf61bd..1a97bfc4a5d 100644
--- a/lisp/cedet/ede/files.el
+++ b/lisp/cedet/ede/files.el
@@ -80,46 +80,15 @@ Allows for one-project-object-for-a-tree type systems."
80Allows for one-project-object-for-a-tree type systems. 80Allows for one-project-object-for-a-tree type systems.
81Optional FILE is the file to test. It is ignored in preference 81Optional FILE is the file to test. It is ignored in preference
82of the anchor file for the project." 82of the anchor file for the project."
83 (file-name-directory (expand-file-name (oref this file)))) 83 (let ((root (or (ede-project-root this) this)))
84 (file-name-directory (expand-file-name (oref this file)))))
84 85
85 86
86(defmethod ede--project-inode ((proj ede-project-placeholder)) 87;; Why INODEs?
87 "Get the inode of the directory project PROJ is in." 88;; An inode represents is a unique id that trancends symlinks, hardlinks, etc
88 (if (slot-boundp proj 'dirinode) 89;; so when we cache an inode in a project, and hash directories to inodes, we
89 (oref proj dirinode) 90;; can avoid costly filesystem queries and regex matches.
90 (oset proj dirinode (ede--inode-for-dir (oref proj :directory)))))
91
92(defmethod ede-find-subproject-for-directory ((proj ede-project-placeholder)
93 dir)
94 "Find a subproject of PROJ that corresponds to DIR."
95 (if ede--disable-inode
96 (let ((ans nil))
97 ;; Try to find the right project w/out inodes.
98 (ede-map-subprojects
99 proj
100 (lambda (SP)
101 (when (not ans)
102 (if (string= (file-truename dir) (oref SP :directory))
103 (setq ans SP)
104 (ede-find-subproject-for-directory SP dir)))))
105 ans)
106 ;; We can use inodes, so let's try it.
107 (let ((ans nil)
108 (inode (ede--inode-for-dir dir)))
109 (ede-map-subprojects
110 proj
111 (lambda (SP)
112 (when (not ans)
113 (if (equal (ede--project-inode SP) inode)
114 (setq ans SP)
115 (setq ans (ede-find-subproject-for-directory SP dir))))))
116 ans)))
117 91
118;;; DIRECTORY IN OPEN PROJECT
119;;
120;; These routines match some directory name to one of the many pre-existing
121;; open projects. This should avoid hitting the disk, or asking lots of questions
122;; if used throughout the other routines.
123(defvar ede-inode-directory-hash (make-hash-table 92(defvar ede-inode-directory-hash (make-hash-table
124 ;; Note on test. Can we compare inodes or something? 93 ;; Note on test. Can we compare inodes or something?
125 :test 'equal) 94 :test 'equal)
@@ -147,6 +116,32 @@ of the anchor file for the project."
147 (ede--put-inode-dir-hash dir (nth 10 fattr)) 116 (ede--put-inode-dir-hash dir (nth 10 fattr))
148 ))))) 117 )))))
149 118
119(defmethod ede--project-inode ((proj ede-project-placeholder))
120 "Get the inode of the directory project PROJ is in."
121 (if (slot-boundp proj 'dirinode)
122 (oref proj dirinode)
123 (oset proj dirinode (ede--inode-for-dir (oref proj :directory)))))
124
125(defun ede--inode-get-toplevel-open-project (inode)
126 "Return an already open toplevel project that is managing INODE.
127Does not check subprojects."
128 (when (or (and (numberp inode) (/= inode 0))
129 (consp inode))
130 (let ((all ede-projects)
131 (found nil)
132 )
133 (while (and all (not found))
134 (when (equal inode (ede--project-inode (car all)))
135 (setq found (car all)))
136 (setq all (cdr all)))
137 found)))
138
139;;; DIRECTORY IN OPEN PROJECT
140;;
141;; These routines match some directory name to one of the many pre-existing
142;; open projects. This should avoid hitting the disk, or asking lots of questions
143;; if used throughout the other routines.
144
150(defun ede-directory-get-open-project (dir &optional rootreturn) 145(defun ede-directory-get-open-project (dir &optional rootreturn)
151 "Return an already open project that is managing DIR. 146 "Return an already open project that is managing DIR.
152Optional ROOTRETURN specifies a symbol to set to the root project. 147Optional ROOTRETURN specifies a symbol to set to the root project.
@@ -156,66 +151,105 @@ If DIR is the root project, then it is the same."
156 (proj (ede--inode-get-toplevel-open-project inode)) 151 (proj (ede--inode-get-toplevel-open-project inode))
157 (ans nil)) 152 (ans nil))
158 ;; Try file based search. 153 ;; Try file based search.
159 (when (not proj) 154 (when (or ede--disable-inode (not proj))
160 (setq proj (ede-directory-get-toplevel-open-project ft))) 155 (setq proj (ede-directory-get-toplevel-open-project ft)))
161 ;; Default answer is this project 156 ;; Default answer is this project
162 (setq ans proj) 157 (setq ans proj)
163 ;; Save. 158 ;; Save.
164 (when rootreturn (set rootreturn proj)) 159 (when rootreturn (set rootreturn proj))
165 ;; Find subprojects. 160 ;; Find subprojects.
166 (when (and proj (or ede--disable-inode 161 (when (and proj (if ede--disable-inode
167 (not (equal inode (ede--project-inode proj))))) 162 (not (string= ft (expand-file-name (oref proj :directory))))
163 (not (equal inode (ede--project-inode proj)))))
168 (setq ans (ede-find-subproject-for-directory proj ft))) 164 (setq ans (ede-find-subproject-for-directory proj ft)))
169 ans)) 165 ans))
170 166
171(defun ede--inode-get-toplevel-open-project (inode) 167;; Force all users to switch to `ede-directory-get-open-project'
172 "Return an already open toplevel project that is managing INODE. 168;; for performance reasons.
173Does not check subprojects." 169(defun ede-directory-get-toplevel-open-project (dir &optional exact)
174 (when (or (and (numberp inode) (/= inode 0)) 170 "Return an already open toplevel project that is managing DIR.
175 (consp inode)) 171If optional EXACT is non-nil, only return exact matches for DIR."
176 (let ((all ede-projects)
177 (found nil)
178 )
179 (while (and all (not found))
180 (when (equal inode (ede--project-inode (car all)))
181 (setq found (car all)))
182 (setq all (cdr all)))
183 found)))
184
185(defun ede-directory-get-toplevel-open-project (dir)
186 "Return an already open toplevel project that is managing DIR."
187 (let ((ft (file-name-as-directory (expand-file-name dir))) 172 (let ((ft (file-name-as-directory (expand-file-name dir)))
188 (all ede-projects) 173 (all ede-projects)
189 (ans nil)) 174 (ans nil)
175 (shortans nil))
190 (while (and all (not ans)) 176 (while (and all (not ans))
191 ;; Do the check. 177 ;; Do the check.
192 (let ((pd (oref (car all) :directory)) 178 (let ((pd (expand-file-name (oref (car all) :directory)))
193 ) 179 )
194 (cond 180 (cond
195 ;; Exact text match. 181 ;; Exact text match.
196 ((string= pd ft) 182 ((string= pd ft)
197 (setq ans (car all))) 183 (setq ans (car all)))
198 ;; Some sub-directory 184 ;; Some sub-directory
199 ((string-match (concat "^" (regexp-quote pd)) ft) 185 ((and (not exact) (string-match (concat "^" (regexp-quote pd)) ft))
200 (setq ans (car all))) 186 (if (not shortans)
187 (setq shortans (car all))
188 ;; We already have a short answer, so see if pd (the match we found)
189 ;; is longer. If it is longer, then it is more precise.
190 (when (< (length (oref shortans :directory))
191 (length pd))
192 (setq shortans (car all))))
193 )
201 ;; Exact inode match. Useful with symlinks or complex automounters. 194 ;; Exact inode match. Useful with symlinks or complex automounters.
202 ((let ((pin (ede--project-inode (car all))) 195 ((and (not ede--disable-inode)
203 (inode (ede--inode-for-dir dir))) 196 (let ((pin (ede--project-inode (car all)))
204 (and (not (eql pin 0)) (equal pin inode))) 197 (inode (ede--inode-for-dir dir)))
205 (setq ans (car all))) 198 (and (not (eql pin 0)) (equal pin inode))))
199 (setq ans (car all)))
206 ;; Subdir via truename - slower by far, but faster than a traditional lookup. 200 ;; Subdir via truename - slower by far, but faster than a traditional lookup.
207 ((let ((ftn (file-truename ft)) 201 ;; Note that we must resort to truename in order to resolve issues such as
208 (ptd (file-truename (oref (car all) :directory)))) 202 ;; cross-symlink projects.
209 (string-match (concat "^" (regexp-quote ptd)) ftn)) 203 ((and (not exact)
210 (setq ans (car all))) 204 (let ((ftn (file-truename ft))
211 )) 205 (ptd (file-truename pd)))
206 (string-match (concat "^" (regexp-quote ptd)) ftn)))
207 (if (not shortans)
208 (setq shortans (car all))
209 ;; We already have a short answer, so see if pd (the match we found)
210 ;; is longer. If it is longer, then it is more precise.
211 (when (< (length (expand-file-name (oref shortans :directory)))
212 (length pd))
213 (setq shortans (car all))))
214 )))
212 (setq all (cdr all))) 215 (setq all (cdr all)))
213 ans)) 216 ;; If we have an exact answer, use that, otherwise use
217 ;; the short answer we found -> ie - we are in a subproject.
218 (or ans shortans)))
219
220(defmethod ede-find-subproject-for-directory ((proj ede-project-placeholder)
221 dir)
222 "Find a subproject of PROJ that corresponds to DIR."
223 (if ede--disable-inode
224 (let ((ans nil)
225 (fulldir (file-truename dir)))
226 ;; Try to find the right project w/out inodes.
227 (ede-map-subprojects
228 proj
229 (lambda (SP)
230 (when (not ans)
231 (if (string= fulldir (file-truename (oref SP :directory)))
232 (setq ans SP)
233 (ede-find-subproject-for-directory SP dir)))))
234 ans)
235 ;; We can use inodes, so let's try it.
236 (let ((ans nil)
237 (inode (ede--inode-for-dir dir)))
238 (ede-map-subprojects
239 proj
240 (lambda (SP)
241 (when (not ans)
242 (if (equal (ede--project-inode SP) inode)
243 (setq ans SP)
244 (setq ans (ede-find-subproject-for-directory SP dir))))))
245 ans)))
214 246
215;;; DIRECTORY-PROJECT-P 247;;; DIRECTORY HASH
216;; 248;;
217;; For a fresh buffer, or for a path w/ no open buffer, use this 249;; The directory hash matches expanded directory names to already detected
218;; routine to determine if there is a known project type here. 250;; projects. By hashing projects to directories, we can detect projects in
251;; places we have been before much more quickly.
252
219(defvar ede-project-directory-hash (make-hash-table 253(defvar ede-project-directory-hash (make-hash-table
220 ;; Note on test. Can we compare inodes or something? 254 ;; Note on test. Can we compare inodes or something?
221 :test 'equal) 255 :test 'equal)
@@ -237,7 +271,7 @@ Do this only when developing new projects that are incorrectly putting
237 "Reset the directory hash for DIR. 271 "Reset the directory hash for DIR.
238Do this whenever a new project is created, as opposed to loaded." 272Do this whenever a new project is created, as opposed to loaded."
239 ;; TODO - Use maphash, and delete by regexp, not by dir searching! 273 ;; TODO - Use maphash, and delete by regexp, not by dir searching!
240 274 (setq dir (expand-file-name dir))
241 (when (fboundp 'remhash) 275 (when (fboundp 'remhash)
242 (remhash (file-name-as-directory dir) ede-project-directory-hash) 276 (remhash (file-name-as-directory dir) ede-project-directory-hash)
243 ;; Look for all subdirs of D, and remove them. 277 ;; Look for all subdirs of D, and remove them.
@@ -248,98 +282,95 @@ Do this whenever a new project is created, as opposed to loaded."
248 ede-project-directory-hash)) 282 ede-project-directory-hash))
249 )) 283 ))
250 284
251(defun ede-directory-project-from-hash (dir) 285(defun ede--directory-project-from-hash (dir)
252 "If there is an already loaded project for DIR, return it from the hash." 286 "If there is an already loaded project for DIR, return it from the hash."
253 (when (fboundp 'gethash) 287 (when (fboundp 'gethash)
288 (setq dir (expand-file-name dir))
254 (gethash dir ede-project-directory-hash nil))) 289 (gethash dir ede-project-directory-hash nil)))
255 290
256(defun ede-directory-project-add-description-to-hash (dir desc) 291(defun ede--directory-project-add-description-to-hash (dir desc)
257 "Add to the EDE project hash DIR associated with DESC." 292 "Add to the EDE project hash DIR associated with DESC."
258 (when (fboundp 'puthash) 293 (when (fboundp 'puthash)
294 (setq dir (expand-file-name dir))
259 (puthash dir desc ede-project-directory-hash) 295 (puthash dir desc ede-project-directory-hash)
260 desc)) 296 desc))
261 297
298;;; DIRECTORY-PROJECT-P, -CONS
299;;
300;; These routines are useful for detecting if a project exists
301;; in a provided directory.
302;;
303;; Note that -P provides less information than -CONS, so use -CONS
304;; instead so that -P can be obsoleted.
262(defun ede-directory-project-p (dir &optional force) 305(defun ede-directory-project-p (dir &optional force)
263 "Return a project description object if DIR has a project. 306 "Return a project description object if DIR is in a project.
264Optional argument FORCE means to ignore a hash-hit of 'nomatch. 307Optional argument FORCE means to ignore a hash-hit of 'nomatch.
265This depends on an up to date `ede-project-class-files' variable. 308This depends on an up to date `ede-project-class-files' variable.
266Any directory that contains the file .ede-ignore will always 309Any directory that contains the file .ede-ignore will always
267return nil." 310return nil.
311
312Consider using `ede-directory-project-cons' instead if the next
313question you want to ask is where the root of found project is."
314 ;; @TODO - We used to have a full impl here, but moved it all
315 ;; to ede-directory-project-cons, and now hash contains only
316 ;; the results of detection which includes the root dir.
317 ;; Perhaps we can eventually remove this fcn?
318 (let ((detect (ede-directory-project-cons dir force)))
319 (cdr detect)))
320
321(defun ede-directory-project-cons (dir &optional force)
322 "Return a project CONS (ROOTDIR . AUTOLOAD) for DIR.
323If there is no project in DIR, return nil.
324Optional FORCE means to ignore the hash of known directories."
268 (when (not (file-exists-p (expand-file-name ".ede-ignore" dir))) 325 (when (not (file-exists-p (expand-file-name ".ede-ignore" dir)))
269 (let* ((dirtest (expand-file-name dir)) 326 (let* ((dirtest (expand-file-name dir))
270 (match (ede-directory-project-from-hash dirtest))) 327 (match (ede--directory-project-from-hash dirtest)))
271 (cond 328 (cond
272 ((and (eq match 'nomatch) (not force)) 329 ((and (eq match 'nomatch) (not force))
273 nil) 330 nil)
274 ((and match (not (eq match 'nomatch))) 331 ((and match (not (eq match 'nomatch)))
275 match) 332 match)
276 (t 333 (t
277 (let ((types ede-project-class-files) 334 ;; First time here? Use the detection code to identify if we have
278 (ret nil)) 335 ;; a project here.
279 ;; Loop over all types, loading in the first type that we find. 336 (let* ((detect (ede-detect-directory-for-project dirtest))
280 (while (and types (not ret)) 337 (autoloader (cdr detect))) ;; autoloader
281 (if (ede-dir-to-projectfile (car types) dirtest) 338 (when autoloader (require (oref autoloader file)))
282 (progn 339 (ede--directory-project-add-description-to-hash dirtest (or detect 'nomatch))
283 ;; We found one! Require it now since we will need it. 340 detect)
284 (require (oref (car types) file)) 341 )))))
285 (setq ret (car types)))) 342
286 (setq types (cdr types)))
287 (ede-directory-project-add-description-to-hash dirtest (or ret 'nomatch))
288 ret))))))
289 343
290;;; TOPLEVEL 344;;; TOPLEVEL
291;; 345;;
292;; These utilities will identify the "toplevel" of a project. 346;; These utilities will identify the "toplevel" of a project.
293;; 347;;
294(defun ede-toplevel-project-or-nil (dir) 348;; NOTE: These two -toplevel- functions return a directory even though
295 "Starting with DIR, find the toplevel project directory, or return nil. 349;; the function name implies a project.
296nil is returned if the current directory is not a part of a project."
297 (let* ((ans (ede-directory-get-toplevel-open-project dir)))
298 (if ans
299 (oref ans :directory)
300 (if (ede-directory-project-p dir)
301 (ede-toplevel-project dir)
302 nil))))
303 350
304(defun ede-toplevel-project (dir) 351(defun ede-toplevel-project (dir)
305 "Starting with DIR, find the toplevel project directory." 352 "Starting with DIR, find the toplevel project directory.
306 (if (and (string= dir default-directory) 353If DIR is not part of a project, return nil."
354 (let ((ans nil))
355
356 (cond
357 ;; Check if it is cached in the current buffer.
358 ((and (string= dir default-directory)
307 ede-object-root-project) 359 ede-object-root-project)
308 ;; Try the local buffer cache first. 360 ;; Try the local buffer cache first.
309 (oref ede-object-root-project :directory) 361 (oref ede-object-root-project :directory))
310 ;; Otherwise do it the hard way. 362
311 (let* ((thisdir (ede-directory-project-p dir)) 363 ;; See if there is an existing project in DIR.
312 (ans (ede-directory-get-toplevel-open-project dir))) 364 ((setq ans (ede-directory-get-toplevel-open-project dir))
313 (if (and ans ;; We have an answer 365 (oref ans :directory))
314 (or (not thisdir) ;; this dir isn't setup 366
315 (and (object-of-class-p ;; Same as class for this dir? 367 ;; Detect using our file system detector.
316 ans (oref thisdir :class-sym))) 368 ((setq ans (ede-detect-directory-for-project dir))
317 )) 369 (car ans))
318 (oref ans :directory) 370
319 (let* ((toppath (expand-file-name dir)) 371 (t nil))))
320 (newpath toppath) 372
321 (proj (ede-directory-project-p dir)) 373(defalias 'ede-toplevel-project-or-nil 'ede-toplevel-project)
322 (ans nil))
323 (if proj
324 ;; If we already have a project, ask it what the root is.
325 (setq ans (ede-project-root-directory proj)))
326
327 ;; If PROJ didn't know, or there is no PROJ, then
328
329 ;; Loop up to the topmost project, and then load that single
330 ;; project, and its sub projects. When we are done, identify the
331 ;; sub-project object belonging to file.
332 (while (and (not ans) newpath proj)
333 (setq toppath newpath
334 newpath (ede-up-directory toppath))
335 (when newpath
336 (setq proj (ede-directory-project-p newpath)))
337
338 (when proj
339 ;; We can home someone in the middle knows too.
340 (setq ans (ede-project-root-directory proj)))
341 )
342 (or ans toppath))))))
343 374
344;;; DIRECTORY CONVERSION STUFF 375;;; DIRECTORY CONVERSION STUFF
345;; 376;;
@@ -509,25 +540,6 @@ Argument DIR is the directory to trim upwards."
509 nil 540 nil
510 fnd))) 541 fnd)))
511 542
512(defun ede-find-project-root (prj-file-name &optional dir)
513 "Tries to find directory with given project file"
514 (let ((prj-dir (locate-dominating-file (or dir default-directory)
515 prj-file-name)))
516 (when prj-dir
517 (expand-file-name prj-dir))))
518
519(defun ede-files-find-existing (dir prj-list)
520 "Find a project in the list of projects stored in given variable.
521DIR is the directory to search from."
522 (let ((projs prj-list)
523 (ans nil))
524 (while (and projs (not ans))
525 (let ((root (ede-project-root-directory (car projs))))
526 (when (string-match (concat "^" (regexp-quote root)) dir)
527 (setq ans (car projs))))
528 (setq projs (cdr projs)))
529 ans))
530
531 543
532(provide 'ede/files) 544(provide 'ede/files)
533 545
diff --git a/lisp/cedet/ede/generic.el b/lisp/cedet/ede/generic.el
index d6f0385cf97..f0314cb7f22 100644
--- a/lisp/cedet/ede/generic.el
+++ b/lisp/cedet/ede/generic.el
@@ -78,61 +78,18 @@
78;; the above described support features. 78;; the above described support features.
79 79
80(require 'eieio-opt) 80(require 'eieio-opt)
81(require 'ede) 81(require 'ede/config)
82(require 'ede/shell) 82(require 'ede/shell)
83(require 'semantic/db) 83(require 'semantic/db)
84 84
85;;; Code: 85;;; Code:
86;; 86;;
87;; Start with the configuration system 87;; Start with the configuration system
88(defclass ede-generic-config (eieio-persistent) 88(defclass ede-generic-config (ede-extra-config
89 ((extension :initform ".ede") 89 ede-extra-config-build
90 (file-header-line :initform ";; EDE Generic Project Configuration") 90 ede-extra-config-program
91 (project :initform nil 91 ede-extra-config-c)
92 :documentation 92 ((file-header-line :initform ";; EDE Generic Project Configuration")
93 "The project this config is bound to.")
94 ;; Generic customizations
95 (build-command :initarg :build-command
96 :initform "make -k"
97 :type string
98 :custom string
99 :group (default build)
100 :documentation
101 "Command used for building this project.")
102 (debug-command :initarg :debug-command
103 :initform "gdb "
104 :type string
105 :custom string
106 :group (default build)
107 :documentation
108 "Command used for debugging this project.")
109 (run-command :initarg :run-command
110 :initform nil
111 :type (or null string)
112 :custom string
113 :group (default build)
114 :documentation
115 "Command used to run something related to this project.")
116 ;; C target customizations
117 (c-include-path :initarg :c-include-path
118 :initform nil
119 :type list
120 :custom (repeat (string :tag "Path"))
121 :group c
122 :documentation
123 "The include path used by C/C++ projects.")
124 (c-preprocessor-table :initarg :c-preprocessor-table
125 :initform nil
126 :type list
127 :custom (repeat (cons (string :tag "Macro")
128 (string :tag "Value")))
129 :group c
130 :documentation
131 "Preprocessor Symbols for this project.")
132 (c-preprocessor-files :initarg :c-preprocessor-files
133 :initform nil
134 :type list
135 :custom (repeat (string :tag "Include File")))
136 ) 93 )
137 "User Configuration object for a generic project.") 94 "User Configuration object for a generic project.")
138 95
@@ -142,23 +99,24 @@ Return nil if there isn't one.
142Argument DIR is the directory it is created for. 99Argument DIR is the directory it is created for.
143ROOTPROJ is nil, since there is only one project." 100ROOTPROJ is nil, since there is only one project."
144 ;; Doesn't already exist, so let's make one. 101 ;; Doesn't already exist, so let's make one.
145 (let* ((alobj ede-constructing) 102 (let* ((alobj ede-constructing))
146 (this nil))
147 (when (not alobj) (error "Cannot load generic project without the autoload instance")) 103 (when (not alobj) (error "Cannot load generic project without the autoload instance"))
148 104 ;;;
149 (setq this 105 ;; TODO - find the root dir.
150 (funcall (oref alobj class-sym) 106 (let ((rootdir dir))
151 (symbol-name (oref alobj class-sym)) 107 (funcall (oref alobj class-sym)
152 :name (file-name-nondirectory 108 (symbol-name (oref alobj class-sym))
153 (directory-file-name dir)) 109 :name (file-name-nondirectory (directory-file-name dir))
154 :version "1.0" 110 :version "1.0"
155 :directory (file-name-as-directory dir) 111 :directory (file-name-as-directory rootdir)
156 :file (expand-file-name (oref alobj :proj-file)) )) 112 :file (expand-file-name (oref alobj :proj-file)
157 (ede-add-project-to-global-list this) 113 rootdir)))
158 )) 114 ))
159 115
160;;; Base Classes for the system 116;;; Base Classes for the system
161(defclass ede-generic-target (ede-target) 117(defclass ede-generic-target (ede-target-with-config
118 ede-target-with-config-build
119 ede-target-with-config-program)
162 ((shortname :initform "" 120 ((shortname :initform ""
163 :type string 121 :type string
164 :allocation :class 122 :allocation :class
@@ -174,16 +132,18 @@ subclasses of this base target will override the default value.")
174 "Baseclass for all targets belonging to the generic ede system." 132 "Baseclass for all targets belonging to the generic ede system."
175 :abstract t) 133 :abstract t)
176 134
177(defclass ede-generic-project (ede-project) 135(defclass ede-generic-project (ede-project-with-config
178 ((buildfile :initform "" 136 ede-project-with-config-build
137 ede-project-with-config-program
138 ede-project-with-config-c
139 ede-project-with-config-java)
140 ((config-class :initform ede-generic-config)
141 (config-file-basename :initform "EDEConfig.el")
142 (buildfile :initform ""
179 :type string 143 :type string
180 :allocation :class 144 :allocation :class
181 :documentation "The file name that identifies a project of this type. 145 :documentation "The file name that identifies a project of this type.
182The class allocated value is replace by different sub classes.") 146The class allocated value is replace by different sub classes.")
183 (config :initform nil
184 :type (or null ede-generic-config)
185 :documentation
186 "The configuration object for this project.")
187 ) 147 )
188 "The baseclass for all generic EDE project types." 148 "The baseclass for all generic EDE project types."
189 :abstract t) 149 :abstract t)
@@ -196,37 +156,18 @@ The class allocated value is replace by different sub classes.")
196 (oset this :targets nil)) 156 (oset this :targets nil))
197 ) 157 )
198 158
199(defmethod ede-generic-get-configuration ((proj ede-generic-project)) 159(defmethod ede-project-root ((this ede-generic-project))
200 "Return the configuration for the project PROJ." 160 "Return my root."
201 (let ((config (oref proj config))) 161 this)
202 (when (not config) 162
203 (let ((fname (expand-file-name "EDEConfig.el" 163(defmethod ede-find-subproject-for-directory ((proj ede-generic-project)
204 (oref proj :directory)))) 164 dir)
205 (if (file-exists-p fname) 165 "Return PROJ, for handling all subdirs below DIR."
206 ;; Load in the configuration 166 proj)
207 (setq config (eieio-persistent-read fname 'ede-generic-config))
208 ;; Create a new one.
209 (setq config (ede-generic-config
210 "Configuration"
211 :file fname))
212 ;; Set initial values based on project.
213 (ede-generic-setup-configuration proj config))
214 ;; Link things together.
215 (oset proj config config)
216 (oset config project proj)))
217 config))
218
219(defmethod ede-generic-setup-configuration ((proj ede-generic-project) config)
220 "Default configuration setup method."
221 nil)
222
223(defmethod ede-commit-project ((proj ede-generic-project))
224 "Commit any change to PROJ to its file."
225 (let ((config (ede-generic-get-configuration proj)))
226 (ede-commit config)))
227 167
228;;; A list of different targets 168;;; A list of different targets
229(defclass ede-generic-target-c-cpp (ede-generic-target) 169(defclass ede-generic-target-c-cpp (ede-generic-target
170 ede-target-with-config-c)
230 ((shortname :initform "C/C++") 171 ((shortname :initform "C/C++")
231 (extension :initform "\\([ch]\\(pp\\|xx\\|\\+\\+\\)?\\|cc\\|hh\\|CC?\\)")) 172 (extension :initform "\\([ch]\\(pp\\|xx\\|\\+\\+\\)?\\|cc\\|hh\\|CC?\\)"))
232 "EDE Generic Project target for C and C++ code. 173 "EDE Generic Project target for C and C++ code.
@@ -250,6 +191,13 @@ All directories need at least one target.")
250 "EDE Generic Project target for texinfo code. 191 "EDE Generic Project target for texinfo code.
251All directories need at least one target.") 192All directories need at least one target.")
252 193
194(defclass ede-generic-target-java (ede-generic-target
195 ede-target-with-config-java)
196 ((shortname :initform "Java")
197 (extension :initform "java"))
198 "EDE Generic Project target for texinfo code.
199All directories need at least one target.")
200
253;; MISC must always be last since it will always match the file. 201;; MISC must always be last since it will always match the file.
254(defclass ede-generic-target-misc (ede-generic-target) 202(defclass ede-generic-target-misc (ede-generic-target)
255 ((shortname :initform "Misc") 203 ((shortname :initform "Misc")
@@ -300,103 +248,6 @@ If one doesn't exist, create a new one for this directory."
300 ) 248 )
301 ans)) 249 ans))
302 250
303;;; C/C++ support
304(defmethod ede-preprocessor-map ((this ede-generic-target-c-cpp))
305 "Get the pre-processor map for some generic C code."
306 (let* ((proj (ede-target-parent this))
307 (root (ede-project-root proj))
308 (config (ede-generic-get-configuration proj))
309 filemap
310 )
311 ;; Preprocessor files
312 (dolist (G (oref config :c-preprocessor-files))
313 (let ((table (semanticdb-file-table-object
314 (ede-expand-filename root G))))
315 (when table
316 (when (semanticdb-needs-refresh-p table)
317 (semanticdb-refresh-table table))
318 (setq filemap (append filemap (oref table lexical-table)))
319 )))
320 ;; The core table
321 (setq filemap (append filemap (oref config :c-preprocessor-table)))
322
323 filemap
324 ))
325
326(defmethod ede-system-include-path ((this ede-generic-target-c-cpp))
327 "Get the system include path used by project THIS."
328 (let* ((proj (ede-target-parent this))
329 (config (ede-generic-get-configuration proj)))
330 (oref config c-include-path)))
331
332;;; Commands
333;;
334(defmethod project-compile-project ((proj ede-generic-project) &optional command)
335 "Compile the entire current project PROJ.
336Argument COMMAND is the command to use when compiling."
337 (let* ((config (ede-generic-get-configuration proj))
338 (comp (oref config :build-command)))
339 (compile comp)))
340
341(defmethod project-compile-target ((obj ede-generic-target) &optional command)
342 "Compile the current target OBJ.
343Argument COMMAND is the command to use for compiling the target."
344 (project-compile-project (ede-current-project) command))
345
346(defmethod project-debug-target ((target ede-generic-target))
347 "Run the current project derived from TARGET in a debugger."
348 (let* ((proj (ede-target-parent target))
349 (config (ede-generic-get-configuration proj))
350 (debug (oref config :debug-command))
351 (cmd (read-from-minibuffer
352 "Debug Command: "
353 debug))
354 (cmdsplit (split-string cmd " " t))
355 ;; @TODO - this depends on the user always typing in something good
356 ;; like "gdb" or "dbx" which also exists as a useful Emacs command.
357 ;; Is there a better way?
358 (cmdsym (intern-soft (car cmdsplit))))
359 (call-interactively cmdsym t)))
360
361(defmethod project-run-target ((target ede-generic-target))
362 "Run the current project derived from TARGET."
363 (let* ((proj (ede-target-parent target))
364 (config (ede-generic-get-configuration proj))
365 (run (concat "./" (oref config :run-command)))
366 (cmd (read-from-minibuffer "Run (like this): " run)))
367 (ede-shell-run-something target cmd)))
368
369;;; Customization
370;;
371(defmethod ede-customize ((proj ede-generic-project))
372 "Customize the EDE project PROJ."
373 (let ((config (ede-generic-get-configuration proj)))
374 (eieio-customize-object config)))
375
376(defmethod ede-customize ((target ede-generic-target))
377 "Customize the EDE TARGET."
378 ;; Nothing unique for the targets, use the project.
379 (ede-customize-project))
380
381(defmethod eieio-done-customizing ((config ede-generic-config))
382 "Called when EIEIO is done customizing the configuration object.
383We need to go back through the old buffers, and update them with
384the new configuration."
385 (ede-commit config)
386 ;; Loop over all the open buffers, and re-apply.
387 (ede-map-targets
388 (oref config project)
389 (lambda (target)
390 (ede-map-target-buffers
391 target
392 (lambda (b)
393 (with-current-buffer b
394 (ede-apply-target-options)))))))
395
396(defmethod ede-commit ((config ede-generic-config))
397 "Commit all changes to the configuration to disk."
398 (eieio-persistent-save config))
399
400;;; Creating Derived Projects: 251;;; Creating Derived Projects:
401;; 252;;
402;; Derived projects need an autoloader so that EDE can find the 253;; Derived projects need an autoloader so that EDE can find the
@@ -415,13 +266,16 @@ the class `ede-generic-project' project."
415 :name external-name 266 :name external-name
416 :file 'ede/generic 267 :file 'ede/generic
417 :proj-file projectfile 268 :proj-file projectfile
269 :root-only nil
418 :load-type 'ede-generic-load 270 :load-type 'ede-generic-load
419 :class-sym class 271 :class-sym class
420 :new-p nil 272 :new-p nil
421 :safe-p nil) ; @todo - could be 273 ;; NOTE: This project type is SAFE because it handles
422 ; safe if we do something 274 ;; the user-query before loading its config file. These
423 ; about the loading of the 275 ;; project types are useful without the config file so
424 ; generic config file. 276 ;; do the safe part until the user creates a saved config
277 ;; file for it.
278 :safe-p t)
425 ;; Generics must go at the end, since more specific types 279 ;; Generics must go at the end, since more specific types
426 ;; can create Makefiles also. 280 ;; can create Makefiles also.
427 'generic)) 281 'generic))
@@ -436,6 +290,25 @@ the class `ede-generic-project' project."
436 "SConstruct" 'ede-generic-scons-project) 290 "SConstruct" 'ede-generic-scons-project)
437 (ede-generic-new-autoloader "generic-cmake" "CMake" 291 (ede-generic-new-autoloader "generic-cmake" "CMake"
438 "CMakeLists" 'ede-generic-cmake-project) 292 "CMakeLists" 'ede-generic-cmake-project)
293
294 ;; Super Generic found via revision control tags.
295 (ede-generic-new-autoloader "generic-git" "Git"
296 ".git" 'ede-generic-vc-project)
297 (ede-generic-new-autoloader "generic-bzr" "Bazaar"
298 ".bzr" 'ede-generic-vc-project)
299 (ede-generic-new-autoloader "generic-hg" "Mercurial"
300 ".hg" 'ede-generic-vc-project)
301 (ede-generic-new-autoloader "generic-svn" "Subversions"
302 ".svn" 'ede-generic-vc-project)
303 (ede-generic-new-autoloader "generic-cvs" "CVS"
304 "CVS" 'ede-generic-vc-project)
305
306 ;; Take advantage of existing 'projectile' based projects.
307 ;; @TODO - if projectile supports compile commands etc, can we
308 ;; read that out? Howto if projectile is not part of core emacs.
309 (ede-generic-new-autoloader "generic-projectile" ".projectile"
310 ".projectile" 'ede-generic-vc-project)
311
439 ) 312 )
440 313
441 314
@@ -481,6 +354,15 @@ the class `ede-generic-project' project."
481 (oset config debug-command "gdb ") 354 (oset config debug-command "gdb ")
482 ) 355 )
483 356
357;;; Generic Version Control System
358(defclass ede-generic-vc-project (ede-generic-project)
359 ()
360 "Generic project found via Version Control files.")
361
362(defmethod ede-generic-setup-configuration ((proj ede-generic-vc-project) config)
363 "Setup a configuration for projects identified by revision control."
364 )
365
484(provide 'ede/generic) 366(provide 'ede/generic)
485 367
486;; Local variables: 368;; Local variables:
diff --git a/lisp/cedet/ede/linux.el b/lisp/cedet/ede/linux.el
index 4e8a06ef110..b28301d777f 100644
--- a/lisp/cedet/ede/linux.el
+++ b/lisp/cedet/ede/linux.el
@@ -73,37 +73,6 @@
73 :group 'project-linux 73 :group 'project-linux
74 :type 'string) 74 :type 'string)
75 75
76(defvar ede-linux-project-list nil
77 "List of projects created by option `ede-linux-project'.")
78
79(defun ede-linux-file-existing (dir)
80 "Find a Linux project in the list of Linux projects.
81DIR is the directory to search from."
82 (let ((projs ede-linux-project-list)
83 (ans nil))
84 (while (and projs (not ans))
85 (let ((root (ede-project-root-directory (car projs))))
86 (when (string-match (concat "^" (regexp-quote root)) dir)
87 (setq ans (car projs))))
88 (setq projs (cdr projs)))
89 ans))
90
91;;;###autoload
92(defun ede-linux-project-root (&optional dir)
93 "Get the root directory for DIR."
94 (when (not dir) (setq dir default-directory))
95 (let ((case-fold-search t)
96 (proj (ede-linux-file-existing dir)))
97 (if proj
98 (ede-up-directory (file-name-directory
99 (oref proj :file)))
100 ;; No pre-existing project. Let's take a wild-guess if we have
101 ;; an Linux project here.
102 (when (string-match "linux[^/]*" dir)
103 (let ((base (substring dir 0 (match-end 0))))
104 (when (file-exists-p (expand-file-name "scripts/ver_linux" base))
105 base))))))
106
107(defun ede-linux-version (dir) 76(defun ede-linux-version (dir)
108 "Find the Linux version for the Linux src in DIR." 77 "Find the Linux version for the Linux src in DIR."
109 (let ((buff (get-buffer-create " *linux-query*"))) 78 (let ((buff (get-buffer-create " *linux-query*")))
@@ -124,9 +93,8 @@ DIR is the directory to search from."
124 (kill-buffer buff) 93 (kill-buffer buff)
125 ))))) 94 )))))
126 95
127(defclass ede-linux-project (ede-project eieio-instance-tracker) 96(defclass ede-linux-project (ede-project)
128 ((tracking-symbol :initform 'ede-linux-project-list) 97 ((build-directory :initarg :build-directory
129 (build-directory :initarg :build-directory
130 :type string 98 :type string
131 :documentation "Build directory.") 99 :documentation "Build directory.")
132 (architecture :initarg :architecture 100 (architecture :initarg :architecture
@@ -226,22 +194,20 @@ until Linux is built for the first time."
226Return nil if there isn't one. 194Return nil if there isn't one.
227Argument DIR is the directory it is created for. 195Argument DIR is the directory it is created for.
228ROOTPROJ is nil, since there is only one project." 196ROOTPROJ is nil, since there is only one project."
229 (or (ede-linux-file-existing dir) 197 ;; Doesn't already exist, so let's make one.
230 ;; Doesn't already exist, so let's make one. 198 (let* ((bdir (ede-linux--get-build-directory dir))
231 (let* ((bdir (ede-linux--get-build-directory dir)) 199 (arch (ede-linux--get-architecture dir bdir))
232 (arch (ede-linux--get-architecture dir bdir)) 200 (include-path (ede-linux--include-path dir bdir arch)))
233 (include-path (ede-linux--include-path dir bdir arch)) 201 (ede-linux-project
234 (proj (ede-linux-project 202 "Linux"
235 "Linux" 203 :name "Linux"
236 :name "Linux" 204 :version (ede-linux-version dir)
237 :version (ede-linux-version dir) 205 :directory (file-name-as-directory dir)
238 :directory (file-name-as-directory dir) 206 :file (expand-file-name "scripts/ver_linux"
239 :file (expand-file-name "scripts/ver_linux" 207 dir)
240 dir) 208 :build-directory bdir
241 :build-directory bdir 209 :architecture arch
242 :architecture arch 210 :include-path include-path)))
243 :include-path include-path)))
244 (ede-add-project-to-global-list proj))))
245 211
246;;;###autoload 212;;;###autoload
247(ede-add-project-autoload 213(ede-add-project-autoload
@@ -249,8 +215,6 @@ ROOTPROJ is nil, since there is only one project."
249 :name "LINUX ROOT" 215 :name "LINUX ROOT"
250 :file 'ede/linux 216 :file 'ede/linux
251 :proj-file "scripts/ver_linux" 217 :proj-file "scripts/ver_linux"
252 :proj-root-dirmatch "linux[^/]*"
253 :proj-root 'ede-linux-project-root
254 :load-type 'ede-linux-load 218 :load-type 'ede-linux-load
255 :class-sym 'ede-linux-project 219 :class-sym 'ede-linux-project
256 :new-p nil 220 :new-p nil
@@ -376,6 +340,8 @@ Knows about how the Linux source tree is organized."
376 (t nil)))) 340 (t nil))))
377 (or F (call-next-method)))) 341 (or F (call-next-method))))
378 342
343;;; Command Support
344;;
379(defmethod project-compile-project ((proj ede-linux-project) 345(defmethod project-compile-project ((proj ede-linux-project)
380 &optional command) 346 &optional command)
381 "Compile the entire current project. 347 "Compile the entire current project.
@@ -412,6 +378,19 @@ Argument COMMAND is the command to use for compiling the target."
412 378
413 (compile command))) 379 (compile command)))
414 380
381(defmethod project-rescan ((this ede-linux-project))
382 "Rescan this Linux project from the sources."
383 (let* ((dir (ede-project-root-directory this))
384 (bdir (ede-linux--get-build-directory dir))
385 (arch (ede-linux--get-architecture dir bdir))
386 (inc (ede-linux--include-path dir bdir arch))
387 (ver (ede-linux-version dir)))
388 (oset this version ver)
389 (oset this :build-directory bdir)
390 (oset this :architecture arch)
391 (oset this :include-path inc)
392 ))
393
415(provide 'ede/linux) 394(provide 'ede/linux)
416 395
417;; Local variables: 396;; Local variables:
diff --git a/lisp/cedet/ede/pconf.el b/lisp/cedet/ede/pconf.el
index dca4b33131a..1fa2a1c4343 100644
--- a/lisp/cedet/ede/pconf.el
+++ b/lisp/cedet/ede/pconf.el
@@ -100,7 +100,7 @@ don't do it. A value of nil means to just do it.")
100 (ede-map-targets this 'ede-proj-tweak-autoconf))) 100 (ede-map-targets this 'ede-proj-tweak-autoconf)))
101 ;; Now save 101 ;; Now save
102 (save-buffer) 102 (save-buffer)
103 (setq postcmd "autoreconf -i;") 103 (setq postcmd "autoreconf -f -i;")
104 104
105 ;; Verify a bunch of files that are required by automake. 105 ;; Verify a bunch of files that are required by automake.
106 (ede-proj-configure-test-required-file this "AUTHORS") 106 (ede-proj-configure-test-required-file this "AUTHORS")
@@ -173,11 +173,14 @@ By flushing, remove any cruft that may be in the file. Subsequent
173calls to `ede-proj-tweak-autoconf' can restore items removed by flush." 173calls to `ede-proj-tweak-autoconf' can restore items removed by flush."
174 nil) 174 nil)
175 175
176
177;; @TODO - No-one calls this ???
176(defmethod ede-proj-configure-add-missing ((this ede-proj-target)) 178(defmethod ede-proj-configure-add-missing ((this ede-proj-target))
177 "Query if any files needed by THIS provided by automake are missing. 179 "Query if any files needed by THIS provided by automake are missing.
178Results in --add-missing being passed to automake." 180Results in --add-missing being passed to automake."
179 nil) 181 nil)
180 182
183;; @TODO - No-one implements this yet.
181(defmethod ede-proj-configure-create-missing ((this ede-proj-target)) 184(defmethod ede-proj-configure-create-missing ((this ede-proj-target))
182 "Add any missing files for THIS by creating them." 185 "Add any missing files for THIS by creating them."
183 nil) 186 nil)
diff --git a/lisp/cedet/ede/proj-elisp.el b/lisp/cedet/ede/proj-elisp.el
index f27ae8adf74..8d5a174b271 100644
--- a/lisp/cedet/ede/proj-elisp.el
+++ b/lisp/cedet/ede/proj-elisp.el
@@ -267,7 +267,8 @@ is found, such as a `-version' variable, or the standard header."
267 (while paths 267 (while paths
268 (ede-proj-elisp-add-path (car paths)) 268 (ede-proj-elisp-add-path (car paths))
269 (setq paths (cdr paths)))) 269 (setq paths (cdr paths))))
270 (save-buffer)) ))) 270 (save-buffer)
271 (kill-buffer)))))
271 272
272(defmethod ede-proj-flush-autoconf ((this ede-proj-target-elisp)) 273(defmethod ede-proj-flush-autoconf ((this ede-proj-target-elisp))
273 "Flush the configure file (current buffer) to accommodate THIS." 274 "Flush the configure file (current buffer) to accommodate THIS."
diff --git a/lisp/cedet/ede/proj.el b/lisp/cedet/ede/proj.el
index e3c2ea4b914..7f3b186f504 100644
--- a/lisp/cedet/ede/proj.el
+++ b/lisp/cedet/ede/proj.el
@@ -310,7 +310,7 @@ the PROJECT being read in is the root project."
310 (let ((sd (file-name-as-directory 310 (let ((sd (file-name-as-directory
311 (expand-file-name (car subdirs) project)))) 311 (expand-file-name (car subdirs) project))))
312 (if (and (file-directory-p sd) 312 (if (and (file-directory-p sd)
313 (ede-directory-project-p sd)) 313 (file-exists-p (expand-file-name "Project.ede" sd)))
314 (oset ret subproj 314 (oset ret subproj
315 (cons (ede-proj-load sd (or rootproj ret)) 315 (cons (ede-proj-load sd (or rootproj ret))
316 (oref ret subproj)))) 316 (oref ret subproj))))
@@ -690,7 +690,10 @@ Optional argument FORCE will force items to be regenerated."
690 "Rescan the EDE proj project THIS." 690 "Rescan the EDE proj project THIS."
691 (let ((root (or (ede-project-root this) this)) 691 (let ((root (or (ede-project-root this) this))
692 ) 692 )
693 (setq ede-projects (delq root ede-projects)) 693 ;; @TODO - VERIFY THE BELOW WORKS
694 (ede-project-directory-remove-hash
695 (file-name-directory (ede-project-root-directory root)))
696 (ede-delete-project-from-global-list root)
694 ;; NOTE : parent function double-checks that this dir was 697 ;; NOTE : parent function double-checks that this dir was
695 ;; already in memory once. 698 ;; already in memory once.
696 (ede-load-project-file (ede-project-root-directory root)) 699 (ede-load-project-file (ede-project-root-directory root))
diff --git a/lisp/cedet/ede/project-am.el b/lisp/cedet/ede/project-am.el
index 43482ce0582..3e7a97cc94c 100644
--- a/lisp/cedet/ede/project-am.el
+++ b/lisp/cedet/ede/project-am.el
@@ -409,7 +409,7 @@ Argument COMMAND is the command to use for compiling the target."
409 (setq default-directory dd) 409 (setq default-directory dd)
410 (setq cmd (read-from-minibuffer 410 (setq cmd (read-from-minibuffer
411 "Run (like this): " 411 "Run (like this): "
412 (concat (ede-target-name obj)))) 412 (concat "./" (ede-target-name obj))))
413 (ede-shell-run-something obj cmd)) 413 (ede-shell-run-something obj cmd))
414 (kill-buffer tb)))) 414 (kill-buffer tb))))
415 415
@@ -428,12 +428,8 @@ Argument COMMAND is the command to use for compiling the target."
428If a given set of projects has already been loaded, then do nothing 428If a given set of projects has already been loaded, then do nothing
429but return the project for the directory given. 429but return the project for the directory given.
430Optional ROOTPROJ is the root EDE project." 430Optional ROOTPROJ is the root EDE project."
431 (let* ((ede-constructing t) 431 ;; Just jump into creating the project from the Makefiles.
432 (amo (object-assoc (expand-file-name "Makefile.am" directory) 432 (project-am-load-makefile directory))
433 'file ede-projects)))
434 (when (not amo)
435 (setq amo (project-am-load-makefile directory)))
436 amo))
437 433
438(defun project-am-find-topmost-level (dir) 434(defun project-am-find-topmost-level (dir)
439 "Find the topmost automakefile starting with DIR." 435 "Find the topmost automakefile starting with DIR."
diff --git a/lisp/cedet/ede/shell.el b/lisp/cedet/ede/shell.el
index 3d6eb194e42..d28977bd14f 100644
--- a/lisp/cedet/ede/shell.el
+++ b/lisp/cedet/ede/shell.el
@@ -42,10 +42,15 @@ COMMAND is a text string representing the thing to be run."
42 ;; Show the new buffer. 42 ;; Show the new buffer.
43 (when (not (get-buffer-window buff)) 43 (when (not (get-buffer-window buff))
44 (switch-to-buffer-other-window buff t)) 44 (switch-to-buffer-other-window buff t))
45 ;; Force a shell into the buffer. 45 ;; Force a shell into the buffer, but only if the buffer
46 (shell buff) 46 ;; doesn't already have a shell in it.
47 (while (eq (point-min) (point)) 47 ;; Newer versions of `shell' pop the window forward.
48 (accept-process-output)) 48 (set-buffer buff)
49 (when (not (eq major-mode 'shell-mode))
50 (shell buff)
51 ;; Make sure the shell has started.
52 (while (eq (point-min) (point))
53 (accept-process-output)))
49 ;; Change the default directory 54 ;; Change the default directory
50 (if (not (string= (file-name-as-directory (expand-file-name default-directory)) 55 (if (not (string= (file-name-as-directory (expand-file-name default-directory))
51 (file-name-as-directory (expand-file-name dd)))) 56 (file-name-as-directory (expand-file-name dd))))
diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el
index 5fc51e02a02..7eddf827e49 100644
--- a/lisp/cedet/semantic.el
+++ b/lisp/cedet/semantic.el
@@ -382,7 +382,7 @@ Arguments START and END bound the time being calculated."
382(defun bovinate (&optional clear) 382(defun bovinate (&optional clear)
383 "Parse the current buffer. Show output in a temp buffer. 383 "Parse the current buffer. Show output in a temp buffer.
384Optional argument CLEAR will clear the cache before parsing. 384Optional argument CLEAR will clear the cache before parsing.
385If CLEAR is negative, it will do a full reparse, and also not display 385If CLEAR is negative, it will do a full reparse, and also display
386the output buffer." 386the output buffer."
387 (interactive "P") 387 (interactive "P")
388 (if clear (semantic-clear-toplevel-cache)) 388 (if clear (semantic-clear-toplevel-cache))
@@ -392,7 +392,8 @@ the output buffer."
392 (end (current-time))) 392 (end (current-time)))
393 (message "Retrieving tags took %.2f seconds." 393 (message "Retrieving tags took %.2f seconds."
394 (semantic-elapsed-time start end)) 394 (semantic-elapsed-time start end))
395 (when (or (null clear) (not (listp clear))) 395 (when (or (null clear) (not (listp clear))
396 (and (numberp clear) (< 0 clear)))
396 (pop-to-buffer "*Parser Output*") 397 (pop-to-buffer "*Parser Output*")
397 (require 'pp) 398 (require 'pp)
398 (erase-buffer) 399 (erase-buffer)
@@ -1126,8 +1127,16 @@ Semantic mode.
1126 ;; Add semantic-ia-complete-symbol to 1127 ;; Add semantic-ia-complete-symbol to
1127 ;; completion-at-point-functions, so that it is run from 1128 ;; completion-at-point-functions, so that it is run from
1128 ;; M-TAB. 1129 ;; M-TAB.
1130 ;;
1131 ;; Note: The first entry added is the last entry run, so the
1132 ;; most specific entry should be last.
1129 (add-hook 'completion-at-point-functions 1133 (add-hook 'completion-at-point-functions
1130 'semantic-completion-at-point-function) 1134 'semantic-analyze-nolongprefix-completion-at-point-function)
1135 (add-hook 'completion-at-point-functions
1136 'semantic-analyze-notc-completion-at-point-function)
1137 (add-hook 'completion-at-point-functions
1138 'semantic-analyze-completion-at-point-function)
1139
1131 (if global-ede-mode 1140 (if global-ede-mode
1132 (define-key cedet-menu-map [cedet-menu-separator] '("--"))) 1141 (define-key cedet-menu-map [cedet-menu-separator] '("--")))
1133 (dolist (b (buffer-list)) 1142 (dolist (b (buffer-list))
@@ -1139,7 +1148,12 @@ Semantic mode.
1139 ;; Semantic can be re-activated cleanly. 1148 ;; Semantic can be re-activated cleanly.
1140 (remove-hook 'mode-local-init-hook 'semantic-new-buffer-fcn) 1149 (remove-hook 'mode-local-init-hook 'semantic-new-buffer-fcn)
1141 (remove-hook 'completion-at-point-functions 1150 (remove-hook 'completion-at-point-functions
1142 'semantic-completion-at-point-function) 1151 'semantic-analyze-completion-at-point-function)
1152 (remove-hook 'completion-at-point-functions
1153 'semantic-analyze-notc-completion-at-point-function)
1154 (remove-hook 'completion-at-point-functions
1155 'semantic-analyze-nolongprefix-completion-at-point-function)
1156
1143 (remove-hook 'after-change-functions 1157 (remove-hook 'after-change-functions
1144 'semantic-change-function) 1158 'semantic-change-function)
1145 (define-key cedet-menu-map [cedet-menu-separator] nil) 1159 (define-key cedet-menu-map [cedet-menu-separator] nil)
@@ -1155,8 +1169,53 @@ Semantic mode.
1155 ;; re-activated. 1169 ;; re-activated.
1156 (setq semantic-new-buffer-fcn-was-run nil))) 1170 (setq semantic-new-buffer-fcn-was-run nil)))
1157 1171
1158(defun semantic-completion-at-point-function () 1172;;; Completion At Point functions
1159 'semantic-ia-complete-symbol) 1173(defun semantic-analyze-completion-at-point-function ()
1174 "Return possible analasis completions at point.
1175The completions provided are via `semantic-analyze-possible-completions'.
1176This function can be used by `completion-at-point-functions'."
1177 (let* ((ctxt (semantic-analyze-current-context))
1178 (possible (semantic-analyze-possible-completions ctxt)))
1179
1180 ;; The return from this is either:
1181 ;; nil - not applicable here.
1182 ;; A list: (START END COLLECTION . PROPS)
1183 (when possible
1184 (list (car (oref ctxt bounds))
1185 (cdr (oref ctxt bounds))
1186 possible))
1187 ))
1188
1189(defun semantic-analyze-notc-completion-at-point-function ()
1190 "Return possible analasis completions at point.
1191The completions provided are via `semantic-analyze-possible-completions',
1192but with the 'no-tc option passed in, which means constraints based
1193on what is being assigned to are ignored.
1194This function can be used by `completion-at-point-functions'."
1195 (let* ((ctxt (semantic-analyze-current-context))
1196 (possible (semantic-analyze-possible-completions ctxt 'no-tc)))
1197
1198 (when possible
1199 (list (car (oref ctxt bounds))
1200 (cdr (oref ctxt bounds))
1201 possible))
1202 ))
1203
1204(defun semantic-analyze-nolongprefix-completion-at-point-function ()
1205 "Return possible analasis completions at point.
1206The completions provided are via `semantic-analyze-possible-completions',
1207but with the 'no-tc and 'no-longprefix option passed in, which means
1208constraints resulting in a long multi-symbol dereference are ignored.
1209This function can be used by `completion-at-point-functions'."
1210 (let* ((ctxt (semantic-analyze-current-context))
1211 (possible (semantic-analyze-possible-completions
1212 ctxt 'no-tc 'no-longprefix)))
1213
1214 (when possible
1215 (list (car (oref ctxt bounds))
1216 (cdr (oref ctxt bounds))
1217 possible))
1218 ))
1160 1219
1161;;; Autoload some functions that are not in semantic/loaddefs 1220;;; Autoload some functions that are not in semantic/loaddefs
1162 1221
diff --git a/lisp/cedet/semantic/analyze.el b/lisp/cedet/semantic/analyze.el
index ffc2c327c5a..77e091721c8 100644
--- a/lisp/cedet/semantic/analyze.el
+++ b/lisp/cedet/semantic/analyze.el
@@ -226,8 +226,8 @@ Optional argument DESIRED-TYPE may be a non-type tag to analyze."
226;; by an application that doesn't need to calculate the full 226;; by an application that doesn't need to calculate the full
227;; context. 227;; context.
228 228
229(define-overloadable-function semantic-analyze-find-tag-sequence (sequence &optional 229(define-overloadable-function semantic-analyze-find-tag-sequence
230 scope typereturn throwsym) 230 (sequence &optional scope typereturn throwsym &rest flags)
231 "Attempt to find all tags in SEQUENCE. 231 "Attempt to find all tags in SEQUENCE.
232Optional argument LOCALVAR is the list of local variables to use when 232Optional argument LOCALVAR is the list of local variables to use when
233finding the details on the first element of SEQUENCE in case 233finding the details on the first element of SEQUENCE in case
@@ -237,53 +237,67 @@ scoped. These are not local variables, but symbols available in a structure
237which doesn't need to be dereferenced. 237which doesn't need to be dereferenced.
238Optional argument TYPERETURN is a symbol in which the types of all found 238Optional argument TYPERETURN is a symbol in which the types of all found
239will be stored. If nil, that data is thrown away. 239will be stored. If nil, that data is thrown away.
240Optional argument THROWSYM specifies a symbol the throw on non-recoverable error.") 240Optional argument THROWSYM specifies a symbol the throw on non-recoverable error.
241Remaining arguments FLAGS are additional flags to apply when searching.")
241 242
242(defun semantic-analyze-find-tag-sequence-default (sequence &optional 243(defun semantic-analyze-find-tag-sequence-default
243 scope typereturn 244 ;; Note: overloadable fcn uses &rest, but it is a list already, so we don't need
244 throwsym) 245 ;; to do that in the -default.
246 (sequence &optional scope typereturn throwsym flags)
245 "Attempt to find all tags in SEQUENCE. 247 "Attempt to find all tags in SEQUENCE.
246SCOPE are extra tags which are in scope. 248SCOPE are extra tags which are in scope.
247TYPERETURN is a symbol in which to place a list of tag classes that 249TYPERETURN is a symbol in which to place a list of tag classes that
248are found in SEQUENCE. 250are found in SEQUENCE.
249Optional argument THROWSYM specifies a symbol the throw on non-recoverable error." 251Optional argument THROWSYM specifies a symbol the throw on non-recoverable error.
252Remaining arguments FLAGS are additional flags to apply when searching.
253This function knows of flags:
254 'mustbeclassvariable"
250 (let ((s sequence) ; copy of the sequence 255 (let ((s sequence) ; copy of the sequence
251 (tmp nil) ; tmp find variable 256 (tmp nil) ; tmp find variable
252 (tag nil) ; tag return list 257 (tag nil) ; tag return list
253 (tagtype nil) ; tag types return list 258 (tagtype nil) ; tag types return list
254 (fname nil) 259 (fname nil)
255 (miniscope (when scope (clone scope))) 260 (miniscope (when scope (clone scope)))
261 (tagclass (if (memq 'mustbeclassvariable flags)
262 'variable nil))
256 ) 263 )
257 ;; First order check. Is this wholly contained in the typecache? 264 ;; First order check. Is this wholly contained in the typecache?
258 (setq tmp (semanticdb-typecache-find sequence)) 265 (setq tmp (semanticdb-typecache-find sequence))
259 266
260 (if tmp 267 (when tmp
261 (progn 268 (if (or (not tagclass) (semantic-tag-of-class-p tmp tagclass))
262 ;; We are effectively done... 269 ;; We are effectively done...
263 (setq s nil) 270 (setq s nil
264 (setq tag (list tmp))) 271 tag (list tmp))
265 272 ;; tagclass doesn't match, so fail this.
266 ;; For the first entry, it better be a variable, but it might 273 (setq tmp nil)))
267 ;; be in the local context too. 274
268 ;; NOTE: Don't forget c++ namespace foo::bar. 275 (unless tmp
269 (setq tmp (or 276 ;; For tag class filtering, only apply the filter if the first entry
270 ;; Is this tag within our scope. Scopes can sometimes 277 ;; is also the only entry.
271 ;; shadow other things, so it goes first. 278 (let ((lftagclass (if (= (length s) 1) tagclass)))
272 (and scope (semantic-scope-find (car s) nil scope)) 279
273 ;; Find the tag out there... somewhere, but not in scope 280 ;; For the first entry, it better be a variable, but it might
274 (semantic-analyze-find-tag (car s)) 281 ;; be in the local context too.
275 )) 282 ;; NOTE: Don't forget c++ namespace foo::bar.
276 283 (setq tmp (or
277 (if (and (listp tmp) (semantic-tag-p (car tmp))) 284 ;; Is this tag within our scope. Scopes can sometimes
278 (setq tmp (semantic-analyze-select-best-tag tmp))) 285 ;; shadow other things, so it goes first.
279 (if (not (semantic-tag-p tmp)) 286 (and scope (semantic-scope-find (car s) lftagclass scope))
280 (if throwsym 287 ;; Find the tag out there... somewhere, but not in scope
281 (throw throwsym "Cannot find definition") 288 (semantic-analyze-find-tag (car s) lftagclass)
282 (error "Cannot find definition for \"%s\"" (car s)))) 289 ))
283 (setq s (cdr s)) 290
284 (setq tag (cons tmp tag)) ; tag is nil here... 291 (if (and (listp tmp) (semantic-tag-p (car tmp)))
285 (setq fname (semantic-tag-file-name tmp)) 292 (setq tmp (semantic-analyze-select-best-tag tmp lftagclass)))
286 ) 293 (if (not (semantic-tag-p tmp))
294 (if throwsym
295 (throw throwsym "Cannot find definition")
296 (error "Cannot find definition for \"%s\"" (car s))))
297 (setq s (cdr s))
298 (setq tag (cons tmp tag)) ; tag is nil here...
299 (setq fname (semantic-tag-file-name tmp))
300 ))
287 301
288 ;; For the middle entries 302 ;; For the middle entries
289 (while s 303 (while s
@@ -382,7 +396,8 @@ searches use the same arguments."
382 ;; Search in the typecache. First entries in a sequence are 396 ;; Search in the typecache. First entries in a sequence are
383 ;; often there. 397 ;; often there.
384 (setq retlist (semanticdb-typecache-find name)) 398 (setq retlist (semanticdb-typecache-find name))
385 (if retlist 399 (if (and retlist (or (not tagclass)
400 (semantic-tag-of-class-p retlist 'tagclass)))
386 retlist 401 retlist
387 (semantic-analyze-select-best-tag 402 (semantic-analyze-select-best-tag
388 (semanticdb-strip-find-results 403 (semanticdb-strip-find-results
@@ -647,7 +662,7 @@ Returns an object based on symbol `semantic-analyze-context'."
647 ;; We have some sort of an assignment 662 ;; We have some sort of an assignment
648 (condition-case err 663 (condition-case err
649 (setq asstag (semantic-analyze-find-tag-sequence 664 (setq asstag (semantic-analyze-find-tag-sequence
650 assign scope)) 665 assign scope nil nil 'mustbeclassvariable))
651 (error (semantic-analyze-push-error err) 666 (error (semantic-analyze-push-error err)
652 nil))) 667 nil)))
653 668
@@ -746,22 +761,26 @@ Some useful functions are found in `semantic-format-tag-functions'."
746 "Send the tag SEQUENCE to standard out. 761 "Send the tag SEQUENCE to standard out.
747Use PREFIX as a label. 762Use PREFIX as a label.
748Use BUFF as a source of override methods." 763Use BUFF as a source of override methods."
764 ;; If there is no sequence, at least show the field as being empty.
765 (unless sequence (princ prefix) (princ "<none>\n"))
766
767 ;; Display the sequence column aligned.
749 (while sequence 768 (while sequence
750 (princ prefix) 769 (princ prefix)
751 (cond 770 (cond
752 ((semantic-tag-p (car sequence)) 771 ((semantic-tag-p (car sequence))
753 (princ (funcall semantic-analyze-summary-function 772 (princ (funcall semantic-analyze-summary-function
754 (car sequence)))) 773 (car sequence))))
755 ((stringp (car sequence)) 774 ((stringp (car sequence))
756 (princ "\"") 775 (princ "\"")
757 (princ (semantic--format-colorize-text (car sequence) 'variable)) 776 (princ (semantic--format-colorize-text (car sequence) 'variable))
758 (princ "\"")) 777 (princ "\""))
759 (t 778 (t
760 (princ (format "'%S" (car sequence))))) 779 (princ (format "'%S" (car sequence)))))
761 (princ "\n") 780 (princ "\n")
762 (setq sequence (cdr sequence)) 781 (setq sequence (cdr sequence))
763 (setq prefix (make-string (length prefix) ? )) 782 (setq prefix (make-string (length prefix) ? ))
764 )) 783 ))
765 784
766(defmethod semantic-analyze-show ((context semantic-analyze-context)) 785(defmethod semantic-analyze-show ((context semantic-analyze-context))
767 "Insert CONTEXT into the current buffer in a nice way." 786 "Insert CONTEXT into the current buffer in a nice way."
diff --git a/lisp/cedet/semantic/analyze/complete.el b/lisp/cedet/semantic/analyze/complete.el
index 0d2d5f998b5..9fa400122f7 100644
--- a/lisp/cedet/semantic/analyze/complete.el
+++ b/lisp/cedet/semantic/analyze/complete.el
@@ -112,8 +112,9 @@ in a buffer."
112Argument CONTEXT is an object specifying the locally derived context. 112Argument CONTEXT is an object specifying the locally derived context.
113The optional argument FLAGS changes which return options are returned. 113The optional argument FLAGS changes which return options are returned.
114FLAGS can be any number of: 114FLAGS can be any number of:
115 'no-tc - do not apply data-type constraint. 115 'no-tc - do not apply data-type constraint.
116 'no-unique - do not apply unique by name filtering." 116 'no-longprefix - ignore long multi-symbol prefixes.
117 'no-unique - do not apply unique by name filtering."
117 (let* ((a context) 118 (let* ((a context)
118 (desired-type (semantic-analyze-type-constraint a)) 119 (desired-type (semantic-analyze-type-constraint a))
119 (desired-class (oref a prefixclass)) 120 (desired-class (oref a prefixclass))
@@ -127,9 +128,16 @@ FLAGS can be any number of:
127 (c nil) 128 (c nil)
128 (any nil) 129 (any nil)
129 (do-typeconstraint (not (memq 'no-tc flags))) 130 (do-typeconstraint (not (memq 'no-tc flags)))
131 (do-longprefix (not (memq 'no-longprefix flags)))
130 (do-unique (not (memq 'no-unique flags))) 132 (do-unique (not (memq 'no-unique flags)))
131 ) 133 )
132 134
135 (when (not do-longprefix)
136 ;; If we are not doing the long prefix, shorten all the key
137 ;; elements.
138 (setq prefix (list (car (reverse prefix)))
139 prefixtypes nil))
140
133 ;; Calculate what our prefix string is so that we can 141 ;; Calculate what our prefix string is so that we can
134 ;; find all our matching text. 142 ;; find all our matching text.
135 (setq completetext (car (reverse prefix))) 143 (setq completetext (car (reverse prefix)))
diff --git a/lisp/cedet/semantic/bovine/c.el b/lisp/cedet/semantic/bovine/c.el
index e9715cc1bb0..9aceca8af1b 100644
--- a/lisp/cedet/semantic/bovine/c.el
+++ b/lisp/cedet/semantic/bovine/c.el
@@ -270,7 +270,7 @@ Return the defined symbol as a special spp lex token."
270 (if (looking-back "/\\*.*" beginning-of-define) 270 (if (looking-back "/\\*.*" beginning-of-define)
271 (progn 271 (progn
272 (goto-char (match-beginning 0)) 272 (goto-char (match-beginning 0))
273 (1- (point))) 273 (point))
274 (point))))) 274 (point)))))
275 ) 275 )
276 276
@@ -501,7 +501,13 @@ code to parse."
501 (hif-canonicalize) 501 (hif-canonicalize)
502 (error nil)))) 502 (error nil))))
503 503
504 (let ((eval-form (eval parsedtokelist))) 504 (let ((eval-form (condition-case err
505 (eval parsedtokelist)
506 (error
507 (semantic-push-parser-warning
508 (format "Hideif forms produced an error. Assuming false.\n%S" err)
509 (point) (1+ (point)))
510 nil))))
505 (if (or (not eval-form) 511 (if (or (not eval-form)
506 (and (numberp eval-form) 512 (and (numberp eval-form)
507 (equal eval-form 0)));; ifdef line resulted in false 513 (equal eval-form 0)));; ifdef line resulted in false
diff --git a/lisp/cedet/semantic/bovine/grammar.el b/lisp/cedet/semantic/bovine/grammar.el
index 46765789351..55df00245ff 100644
--- a/lisp/cedet/semantic/bovine/grammar.el
+++ b/lisp/cedet/semantic/bovine/grammar.el
@@ -395,16 +395,33 @@ manual."
395 (insert ")\n") 395 (insert ")\n")
396 (buffer-string)))) 396 (buffer-string))))
397 397
398(defun bovine-grammar-calculate-source-on-path ()
399 "Calculate the location of the source for current buffer.
400The source directory is relative to some root in the load path."
401 (condition-case nil
402 (let* ((dir (nreverse (split-string (buffer-file-name) "/")))
403 (newdir (car dir)))
404 (setq dir (cdr dir))
405 ;; Keep trying the file name until it is on the path.
406 (while (and (not (locate-library newdir)) dir)
407 (setq newdir (concat (car dir) "/" newdir)
408 dir (cdr dir)))
409 (if (not dir)
410 (buffer-name)
411 newdir))
412 (error (buffer-name))))
413
398(defun bovine-grammar-setupcode-builder () 414(defun bovine-grammar-setupcode-builder ()
399 "Return the text of the setup code." 415 "Return the text of the setup code."
400 (format 416 (format
401 "(setq semantic--parse-table %s\n\ 417 "(setq semantic--parse-table %s\n\
402 semantic-debug-parser-source %S\n\ 418 semantic-debug-parser-source %S\n\
403 semantic-debug-parser-class 'semantic-bovine-debug-parser 419 semantic-debug-parser-class 'semantic-bovine-debug-parser
420 semantic-debug-parser-debugger-source 'semantic/bovine/debug
404 semantic-flex-keywords-obarray %s\n\ 421 semantic-flex-keywords-obarray %s\n\
405 %s)" 422 %s)"
406 (semantic-grammar-parsetable) 423 (semantic-grammar-parsetable)
407 (buffer-name) 424 (bovine-grammar-calculate-source-on-path)
408 (semantic-grammar-keywordtable) 425 (semantic-grammar-keywordtable)
409 (let ((mode (semantic-grammar-languagemode))) 426 (let ((mode (semantic-grammar-languagemode)))
410 ;; Is there more than one major mode? 427 ;; Is there more than one major mode?
diff --git a/lisp/cedet/semantic/bovine/scm.el b/lisp/cedet/semantic/bovine/scm.el
index 4fa34dfcc36..4e01c33cf6d 100644
--- a/lisp/cedet/semantic/bovine/scm.el
+++ b/lisp/cedet/semantic/bovine/scm.el
@@ -69,7 +69,7 @@ Attempts a simple prototype for calling or using TAG."
69;; Note: Analyzer from Henry S. Thompson 69;; Note: Analyzer from Henry S. Thompson
70(define-lex-regex-analyzer semantic-lex-scheme-symbol 70(define-lex-regex-analyzer semantic-lex-scheme-symbol
71 "Detect and create symbol and keyword tokens." 71 "Detect and create symbol and keyword tokens."
72 "\\(\\sw\\([:]\\|\\sw\\|\\s_\\)+\\)" 72 "\\(\\sw\\([:]\\|\\sw\\|\\s_\\)*\\)"
73 ;; (message (format "symbol: %s" (match-string 0))) 73 ;; (message (format "symbol: %s" (match-string 0)))
74 (semantic-lex-push-token 74 (semantic-lex-push-token
75 (semantic-lex-token 75 (semantic-lex-token
diff --git a/lisp/cedet/semantic/db.el b/lisp/cedet/semantic/db.el
index 76a49ddc548..12be66225a1 100644
--- a/lisp/cedet/semantic/db.el
+++ b/lisp/cedet/semantic/db.el
@@ -124,6 +124,18 @@ for a new table not associated with a buffer."
124If the buffer is not in memory, load it with `find-file-noselect'." 124If the buffer is not in memory, load it with `find-file-noselect'."
125 nil) 125 nil)
126 126
127;; This generic method allows for sloppier coding. Many
128;; functions treat "table" as something that could be a buffer,
129;; file name, or other. This makes use of table more robust.
130(defmethod semanticdb-full-filename (buffer-or-string)
131 "Fetch the full filename that BUFFER-OR-STRING referrs to.
132This uses semanticdb to get a better file name."
133 (cond ((bufferp buffer-or-string)
134 (with-current-buffer buffer-or-string
135 (semanticdb-full-filename semanticdb-current-table)))
136 ((and (stringp buffer-or-string) (file-exists-p buffer-or-string))
137 (expand-file-name buffer-or-string))))
138
127(defmethod semanticdb-full-filename ((obj semanticdb-abstract-table)) 139(defmethod semanticdb-full-filename ((obj semanticdb-abstract-table))
128 "Fetch the full filename that OBJ refers to. 140 "Fetch the full filename that OBJ refers to.
129Abstract tables do not have file names associated with them." 141Abstract tables do not have file names associated with them."
diff --git a/lisp/cedet/semantic/debug.el b/lisp/cedet/semantic/debug.el
index 80081efd239..91819b89bd1 100644
--- a/lisp/cedet/semantic/debug.el
+++ b/lisp/cedet/semantic/debug.el
@@ -57,6 +57,12 @@ to one of the parser generators.")
57;;;###autoload 57;;;###autoload
58(make-variable-buffer-local 'semantic-debug-parser-class) 58(make-variable-buffer-local 'semantic-debug-parser-class)
59 59
60;;;###autoload
61(defvar semantic-debug-parser-debugger-source nil
62 "Location of the debug parser class.")
63;;;###autoload
64(make-variable-buffer-local 'semantic-debug-parser-source)
65
60(defvar semantic-debug-enabled nil 66(defvar semantic-debug-enabled nil
61 "Non-nil when debugging a parser.") 67 "Non-nil when debugging a parser.")
62 68
@@ -104,6 +110,7 @@ These buffers are brought into view when layout occurs.")
104 "The currently displayed frame.") 110 "The currently displayed frame.")
105 (overlays :type list 111 (overlays :type list
106 :initarg nil 112 :initarg nil
113 :initform nil
107 :documentation 114 :documentation
108 "Any active overlays being used to show the debug position.") 115 "Any active overlays being used to show the debug position.")
109 ) 116 )
@@ -323,15 +330,18 @@ Argument ONOFF is non-nil when we are entering debug mode.
323 (oref semantic-debug-current-interface parser-buffer) 330 (oref semantic-debug-current-interface parser-buffer)
324 (use-local-map 331 (use-local-map
325 (oref semantic-debug-current-interface parser-local-map)) 332 (oref semantic-debug-current-interface parser-local-map))
333 (setq buffer-read-only nil)
326 ) 334 )
327 (with-current-buffer 335 (with-current-buffer
328 (oref semantic-debug-current-interface source-buffer) 336 (oref semantic-debug-current-interface source-buffer)
329 (use-local-map 337 (use-local-map
330 (oref semantic-debug-current-interface source-local-map)) 338 (oref semantic-debug-current-interface source-local-map))
339 (setq buffer-read-only nil)
331 ) 340 )
332 (run-hooks 'semantic-debug-exit-hook) 341 (run-hooks 'semantic-debug-exit-hook)
333 ))) 342 )))
334 343
344;;;###autoload
335(defun semantic-debug () 345(defun semantic-debug ()
336 "Parse the current buffer and run in debug mode." 346 "Parse the current buffer and run in debug mode."
337 (interactive) 347 (interactive)
@@ -341,6 +351,9 @@ Argument ONOFF is non-nil when we are entering debug mode.
341 (error "This major mode does not support parser debugging")) 351 (error "This major mode does not support parser debugging"))
342 ;; Clear the cache to force a full reparse. 352 ;; Clear the cache to force a full reparse.
343 (semantic-clear-toplevel-cache) 353 (semantic-clear-toplevel-cache)
354 ;; Load in the debugger for this file.
355 (when semantic-debug-parser-debugger-source
356 (require semantic-debug-parser-debugger-source))
344 ;; Do the parse 357 ;; Do the parse
345 (let ((semantic-debug-enabled t) 358 (let ((semantic-debug-enabled t)
346 ;; Create an interface 359 ;; Create an interface
diff --git a/lisp/cedet/semantic/doc.el b/lisp/cedet/semantic/doc.el
index 2f9a570eb31..fdaeb95d001 100644
--- a/lisp/cedet/semantic/doc.el
+++ b/lisp/cedet/semantic/doc.el
@@ -118,7 +118,8 @@ If NOSNARF is 'lex, then return the lex token."
118 (setq ct (concat (substring ct 0 (match-beginning 0)) 118 (setq ct (concat (substring ct 0 (match-beginning 0))
119 (substring ct (match-end 0))))) 119 (substring ct (match-end 0)))))
120 ;; Remove comment delimiter at the end of the string. 120 ;; Remove comment delimiter at the end of the string.
121 (when (string-match (concat (regexp-quote comment-end) "$") ct) 121 (when (and comment-end (not (string= comment-end ""))
122 (string-match (concat (regexp-quote comment-end) "$") ct))
122 (setq ct (substring ct 0 (match-beginning 0))))) 123 (setq ct (substring ct 0 (match-beginning 0)))))
123 ;; Now return the text. 124 ;; Now return the text.
124 ct)))) 125 ct))))
diff --git a/lisp/cedet/semantic/symref.el b/lisp/cedet/semantic/symref.el
index 994d85c7b2c..d9513981bc0 100644
--- a/lisp/cedet/semantic/symref.el
+++ b/lisp/cedet/semantic/symref.el
@@ -333,6 +333,25 @@ Use the `semantic-symref-hit-tags' method to get this list.")
333 ) 333 )
334 )) 334 ))
335 335
336(defvar semantic-symref-recently-opened-buffers nil
337 "List of buffers opened by `semantic-symref-result-get-tags'.")
338
339(defun semantic-symref-cleanup-recent-buffers-fcn ()
340 "Hook function to be used in 'post-command-hook' to cleanup buffers.
341Buffers collected during symref can result in some files being
342opened multiple times for one operation. This will keep buffers open
343until the next command is executed."
344 ;;(message "To Clean Up: %S" semantic-symref-recently-opened-buffers)
345 (mapc (lambda (buff)
346 ;; Don't delete any buffers which are being used
347 ;; upon completion of some command.
348 (when (not (get-buffer-window buff))
349 (kill-buffer buff)))
350 semantic-symref-recently-opened-buffers)
351 (setq semantic-symref-recently-opened-buffers nil)
352 (remove-hook 'post-command-hook 'semantic-symref-cleanup-recent-buffers-fcn)
353 )
354
336(defmethod semantic-symref-result-get-tags ((result semantic-symref-result) 355(defmethod semantic-symref-result-get-tags ((result semantic-symref-result)
337 &optional open-buffers) 356 &optional open-buffers)
338 "Get the list of tags from the symref result RESULT. 357 "Get the list of tags from the symref result RESULT.
@@ -347,75 +366,19 @@ already."
347 (txt (oref (oref result :created-by) :searchfor)) 366 (txt (oref (oref result :created-by) :searchfor))
348 (searchtype (oref (oref result :created-by) :searchtype)) 367 (searchtype (oref (oref result :created-by) :searchtype))
349 (ans nil) 368 (ans nil)
350 (out nil) 369 (out nil))
351 (buffs-to-kill nil))
352 (save-excursion 370 (save-excursion
353 (setq 371 (setq ans (mapcar
354 ans 372 (lambda (hit)
355 (mapcar 373 (semantic-symref-hit-to-tag-via-buffer
356 (lambda (hit) 374 hit txt searchtype open-buffers))
357 (let* ((line (car hit)) 375 lines)))
358 (file (cdr hit))
359 (buff (find-buffer-visiting file))
360 (tag nil)
361 )
362 (cond
363 ;; We have a buffer already. Check it out.
364 (buff
365 (set-buffer buff))
366
367 ;; We have a table, but it needs a refresh.
368 ;; This means we should load in that buffer.
369 (t
370 (let ((kbuff
371 (if open-buffers
372 ;; Even if we keep the buffers open, don't
373 ;; let EDE ask lots of questions.
374 (let ((ede-auto-add-method 'never))
375 (find-file-noselect file t))
376 ;; When not keeping the buffers open, then
377 ;; don't setup all the fancy froo-froo features
378 ;; either.
379 (semantic-find-file-noselect file t))))
380 (set-buffer kbuff)
381 (setq buffs-to-kill (cons kbuff buffs-to-kill))
382 (semantic-fetch-tags)
383 ))
384 )
385
386 ;; Too much baggage in goto-line
387 ;; (goto-line line)
388 (goto-char (point-min))
389 (forward-line (1- line))
390
391 ;; Search forward for the matching text
392 (when (re-search-forward (regexp-quote txt)
393 (point-at-eol)
394 t)
395 (goto-char (match-beginning 0))
396 )
397
398 (setq tag (semantic-current-tag))
399
400 ;; If we are searching for a tag, but bound the tag we are looking
401 ;; for, see if it resides in some other parent tag.
402 ;;
403 ;; If there is no parent tag, then we still need to hang the originator
404 ;; in our list.
405 (when (and (eq searchtype 'symbol)
406 (string= (semantic-tag-name tag) txt))
407 (setq tag (or (semantic-current-tag-parent) tag)))
408
409 ;; Copy the tag, which adds a :filename property.
410 (when tag
411 (setq tag (semantic-tag-copy tag nil t))
412 ;; Ad this hit to the tag.
413 (semantic--tag-put-property tag :hit (list line)))
414 tag))
415 lines)))
416 ;; Kill off dead buffers, unless we were requested to leave them open. 376 ;; Kill off dead buffers, unless we were requested to leave them open.
417 (when (not open-buffers) 377 (if (not open-buffers)
418 (mapc 'kill-buffer buffs-to-kill)) 378 (add-hook 'post-command-hook 'semantic-symref-cleanup-recent-buffers-fcn)
379 ;; Else, just clear the saved buffers so they aren't deleted later.
380 (setq semantic-symref-recently-opened-buffers nil)
381 )
419 ;; Strip out duplicates. 382 ;; Strip out duplicates.
420 (dolist (T ans) 383 (dolist (T ans)
421 (if (and T (not (semantic-equivalent-tag-p (car out) T))) 384 (if (and T (not (semantic-equivalent-tag-p (car out) T)))
@@ -429,6 +392,111 @@ already."
429 ;; Out is reversed... twice 392 ;; Out is reversed... twice
430 (oset result :hit-tags (nreverse out))))) 393 (oset result :hit-tags (nreverse out)))))
431 394
395(defun semantic-symref-hit-to-tag-via-db (hit searchtxt searchtype)
396 "Convert the symref HIT into a TAG by looking up the tag via a database.
397Return the Semantic tag associated with HIT.
398SEARCHTXT is the text that is being searched for.
399Used to narrow the in-buffer search.
400SEARCHTYPE is the type of search (such as 'symbol or 'tagname).
401If there is no database, of if the searchtype is wrong, return nil."
402 ;; Allowed search types for this mechanism:
403 ;; tagname, tagregexp, tagcompletions
404 (if (not (memq searchtype '(tagname tagregexp tagcompletions)))
405 nil
406 (let* ((line (car hit))
407 (file (cdr hit))
408 ;; FAIL here vv - don't load is not obeyed if no table found.
409 (db (semanticdb-file-table-object file t))
410 (found nil)
411 (hit nil)
412 )
413 (cond ((eq searchtype 'tagname)
414 (setq found (semantic-find-tags-by-name searchtxt db)))
415 ((eq searchtype 'tagregexp)
416 (setq found (semantic-find-tags-by-name-regexp searchtxt db)))
417 ((eq searchtype 'tagcompletions)
418 (setq found (semantic-find-tags-for-completion searchtxt db)))
419 )
420 ;; Loop over FOUND to see if we can line up a match with a line number.
421 (when (= (length found) 1)
422 (setq hit (car found)))
423
424 ;; FAIL here ^^ - symref finds line numbers, but our DB uses character locations.
425 ;; as such, this is a cheat and we will need to give up.
426 hit)))
427
428(defun semantic-symref-hit-to-tag-via-buffer (hit searchtxt searchtype &optional open-buffers)
429 "Convert the symref HIT into a TAG by looking up the tag via a buffer.
430Return the Semantic tag associated with HIT.
431SEARCHTXT is the text that is being searched for.
432Used to narrow the in-buffer search.
433SEARCHTYPE is the type of search (such as 'symbol or 'tagname).
434Optional OPEN-BUFFERS, when nil will use a faster version of
435`find-file' when a file needs to be opened. If non-nil, then
436normal buffer initialization will be used.
437This function will leave buffers loaded from a file open, but
438will add buffers that must be opened to `semantic-symref-recently-opened-buffers'.
439Any caller MUST deal with that variable, either clearing it, or deleting the
440buffers that were opened."
441 (let* ((line (car hit))
442 (file (cdr hit))
443 (buff (find-buffer-visiting file))
444 (tag nil)
445 )
446 (cond
447 ;; We have a buffer already. Check it out.
448 (buff
449 (set-buffer buff))
450
451 ;; We have a table, but it needs a refresh.
452 ;; This means we should load in that buffer.
453 (t
454 (let ((kbuff
455 (if open-buffers
456 ;; Even if we keep the buffers open, don't
457 ;; let EDE ask lots of questions.
458 (let ((ede-auto-add-method 'never))
459 (find-file-noselect file t))
460 ;; When not keeping the buffers open, then
461 ;; don't setup all the fancy froo-froo features
462 ;; either.
463 (semantic-find-file-noselect file t))))
464 (set-buffer kbuff)
465 (push kbuff semantic-symref-recently-opened-buffers)
466 (semantic-fetch-tags)
467 ))
468 )
469
470 ;; Too much baggage in goto-line
471 ;; (goto-line line)
472 (goto-char (point-min))
473 (forward-line (1- line))
474
475 ;; Search forward for the matching text
476 (when (re-search-forward (regexp-quote searchtxt)
477 (point-at-eol)
478 t)
479 (goto-char (match-beginning 0))
480 )
481
482 (setq tag (semantic-current-tag))
483
484 ;; If we are searching for a tag, but bound the tag we are looking
485 ;; for, see if it resides in some other parent tag.
486 ;;
487 ;; If there is no parent tag, then we still need to hang the originator
488 ;; in our list.
489 (when (and (eq searchtype 'symbol)
490 (string= (semantic-tag-name tag) searchtxt))
491 (setq tag (or (semantic-current-tag-parent) tag)))
492
493 ;; Copy the tag, which adds a :filename property.
494 (when tag
495 (setq tag (semantic-tag-copy tag nil t))
496 ;; Ad this hit to the tag.
497 (semantic--tag-put-property tag :hit (list line)))
498 tag))
499
432;;; SYMREF TOOLS 500;;; SYMREF TOOLS
433;; 501;;
434;; The base symref tool provides something to hang new tools off of 502;; The base symref tool provides something to hang new tools off of
diff --git a/lisp/cedet/srecode/java.el b/lisp/cedet/srecode/java.el
index f6cd3f893da..1b1c184fe87 100644
--- a/lisp/cedet/srecode/java.el
+++ b/lisp/cedet/srecode/java.el
@@ -40,16 +40,15 @@ FILENAME_AS_CLASS - file converted to a Java class name."
40 (fnox (file-name-sans-extension fsym)) 40 (fnox (file-name-sans-extension fsym))
41 (dir (file-name-directory (buffer-file-name))) 41 (dir (file-name-directory (buffer-file-name)))
42 (fpak fsym) 42 (fpak fsym)
43 (proj (ede-current-project))
44 (pths (ede-source-paths proj 'java-mode))
43 ) 45 )
44 (while (string-match "\\.\\| " fpak) 46 (while (string-match "\\.\\| " fpak)
45 (setq fpak (replace-match "_" t t fpak))) 47 (setq fpak (replace-match "_" t t fpak)))
46 ;; We can extract package from: 48 ;; We can extract package from:
47 ;; 1) a java EDE project source paths, 49 ;; 1) a java EDE project source paths,
48 (cond ((ede-current-project) 50 (cond ((and proj pths)
49 (let* ((proj (ede-current-project)) 51 (let* ((pth) (res))
50 (pths (ede-source-paths proj 'java-mode))
51 (pth)
52 (res))
53 (while (and (not res) 52 (while (and (not res)
54 (setq pth (expand-file-name (car pths)))) 53 (setq pth (expand-file-name (car pths))))
55 (when (string-match pth dir) 54 (when (string-match pth dir)
diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el
index cbb35fee3f6..df153eefd0e 100644
--- a/lisp/emacs-lisp/eieio-custom.el
+++ b/lisp/emacs-lisp/eieio-custom.el
@@ -383,7 +383,7 @@ These groups are specified with the `:group' slot flag."
383 (make-local-variable 'eieio-co) 383 (make-local-variable 'eieio-co)
384 (setq eieio-co obj) 384 (setq eieio-co obj)
385 (make-local-variable 'eieio-cog) 385 (make-local-variable 'eieio-cog)
386 (setq eieio-cog group))) 386 (setq eieio-cog g)))
387 387
388(defmethod eieio-custom-object-apply-reset ((obj eieio-default-superclass)) 388(defmethod eieio-custom-object-apply-reset ((obj eieio-default-superclass))
389 "Insert an Apply and Reset button into the object editor. 389 "Insert an Apply and Reset button into the object editor.
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el
index df2ce0f984b..c8330d5b695 100644
--- a/lisp/emacs-lisp/eieio.el
+++ b/lisp/emacs-lisp/eieio.el
@@ -895,7 +895,7 @@ variable PRINT-FUNCTION. Optional argument NOESCAPE is passed to
895 895
896;;; Start of automatically extracted autoloads. 896;;; Start of automatically extracted autoloads.
897 897
898;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "5b0e7b1beea11f9e9de6887279f75d61") 898;;;### (autoloads nil "eieio-custom" "eieio-custom.el" "ab711689b2bae8a7d8c4b1e99c892306")
899;;; Generated autoloads from eieio-custom.el 899;;; Generated autoloads from eieio-custom.el
900 900
901(autoload 'customize-object "eieio-custom" "\ 901(autoload 'customize-object "eieio-custom" "\