diff options
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 @@ | |||
| 1 | 2014-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 | |||
| 17 | 2014-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 | |||
| 1 | 2014-11-09 Glenn Morris <rgm@gnu.org> | 26 | 2014-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 | ||
| 833 | opt-post-fcn-modifiers | 836 | opt-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. |
| 1208 | expression | 1211 | expression |
| 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 | ||
| 39 | scheme : semantic-list | 40 | scheme : 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 | ||
| 43 | scheme-list : OPENPAREN scheme-in-list CLOSEPAREN | 53 | scheme-list : OPENPAREN scheme-in-list |
| 44 | ( ,$2 ) | 54 | ( ,$2 ) |
| 45 | ; | 55 | ; |
| 46 | 56 | ||
| 57 | |||
| 47 | scheme-in-list: DEFINE symbol expression | 58 | scheme-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 | ||
| 59 | name-args: semantic-list | 72 | name-args: semantic-list |
| 60 | (EXPAND $1 name-arg-expand) | 73 | (EXPAND $1 name-arg-list) |
| 61 | ; | 74 | ; |
| 62 | 75 | ||
| 63 | name-arg-expand : open-paren name-arg-expand | 76 | name-arg-list : OPENPAREN name-arg-expand |
| 64 | ( ,$2 ) | 77 | ( ,$2 ) |
| 65 | | symbol name-arg-expand | 78 | ; |
| 66 | ( ,(cons $1 ,$2) ) | 79 | |
| 67 | | ;; EMPTY | 80 | name-arg-expand: symbol name-arg-expand |
| 68 | ( ) | 81 | ( ,(cons $1 ,$2) ) |
| 69 | ; | 82 | | ;; EMPTY |
| 83 | ( ) | ||
| 84 | ; | ||
| 70 | 85 | ||
| 71 | opt-doc : string | 86 | opt-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 @@ | |||
| 1 | 2014-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 | |||
| 1 | 2014-11-05 Teodor Zlatanov <tzz@lifelogs.com> | 6 | 2014-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 | ||
| 22 | set mode "c++-mode" | 22 | set mode "c-mode" |
| 23 | 23 | ||
| 24 | set application "document" | 24 | set application "document" |
| 25 | context declaration | 25 | context declaration |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c8fc5086817..a01dadad706 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2014-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 | |||
| 1 | 2014-11-09 Juri Linkov <juri@jurta.org> | 7 | 2014-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 @@ | |||
| 1 | 2014-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 | |||
| 244 | 2014-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 | |||
| 1 | 2014-10-29 Paul Eggert <eggert@cs.ucla.edu> | 252 | 2014-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. | ||
| 715 | This 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'. |
| 705 | If it is not, try asking the user if it should be added; if so, | 719 | If 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'. | ||
| 716 | Add it to the list of allowed project directories? " | 731 | Add 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. |
| 1068 | Flush the dead projects from the project cache." | 1092 | Flush 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. |
| 1120 | Optional DETECTIN is an autoload cons from `ede-detect-directory-for-project' | ||
| 1121 | which can be passed in to save time. | ||
| 1080 | Optional ROOTRETURN will return the root project for DIR." | 1122 | Optional 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. |
| 1151 | Return nil if there is no previous directory. | 1178 | Return 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. | ||
| 54 | This implies projects exist only in subdirectories of the configuration path. | ||
| 55 | If `: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. |
| 127 | For projects that use directory name matches, a function would load that project. | 154 | Specifying this matcher object will allow EDE to perform a complex |
| 128 | Specifying this matcher will allow EDE to check without loading the project.") | 155 | check without loading the project. |
| 156 | |||
| 157 | NOTE: If you use dirmatch, you may need to set :root-only to `nil'. | ||
| 158 | While it may be a root based project, all subdirs will happen to return | ||
| 159 | true 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. | ||
| 240 | Allows 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. | ||
| 245 | DIRMATCH could be nil (no match), a string (regexp match), | ||
| 246 | or 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." |
| 261 | Allows for one-project-object-for-a-tree type systems. | ||
| 262 | Optional FILE is the file to test. If there is no FILE, use | ||
| 263 | the 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. | ||
| 301 | Return 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. |
| 325 | THIS project description should be valid for DIR, where the project will | 293 | THIS project description should be valid for DIR, where the project will |
| 326 | be loaded." | 294 | be loaded. |
| 295 | |||
| 296 | NOTE: 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. | ||
| 320 | Allows 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. |
| 606 | Optional argument SUBPROJ indicates a subproject to start from | 606 | Optional argument SUBPROJ indicates a subproject to start from |
| 607 | instead of the current project." | 607 | instead 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 | ||
| 74 | was ignored. Use this to warn the user that they might want to load in | ||
| 75 | an on-disk version.") | ||
| 76 | ) | ||
| 77 | "Baseclass for auxilliary configuration files for EDE. | ||
| 78 | This should be subclassed by projects that auto detect a project | ||
| 79 | and 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. | ||
| 95 | This filename excludes the directory name and is used to | ||
| 96 | initalize 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. | ||
| 128 | If optional LOADASK is non-nil, then if a project file exists, and if | ||
| 129 | the 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. | ||
| 196 | We need to go back through the old buffers, and update them with | ||
| 197 | the 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. | ||
| 253 | This class brings in method overloads for running and debugging | ||
| 254 | programs 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. | ||
| 295 | This 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. | ||
| 300 | This 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. | ||
| 304 | Argument 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. | ||
| 311 | Argument 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. | ||
| 325 | The 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. | ||
| 334 | When files within this project are parsed by CEDET, these symbols will be | ||
| 335 | used to resolve macro occurrences in source fies. | ||
| 336 | If you modify this slot, you will need to force your source files to be | ||
| 337 | parsed 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. | ||
| 345 | When files within this project are parsed by CEDET, these symbols will be used to | ||
| 346 | resolve macro occurences in source files. | ||
| 347 | If you modify this slot, you will need to force your source files to be | ||
| 348 | parsed 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. | ||
| 358 | This target brings in methods used by Semantic to query | ||
| 359 | the 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. | ||
| 398 | This brings in methods to support Semantic querying the | ||
| 399 | java 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. | ||
| 185 | DIR 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. | ||
| 220 | This is a debugging variable to test various optimizations in file | ||
| 221 | lookup 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. | ||
| 235 | Return nil if there isn't one. | ||
| 236 | Argument DIR is the directory it is created for. | ||
| 237 | ROOTPROJ 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. | ||
| 79 | This function ALWAYS scans files and directories and DOES NOT | ||
| 80 | use any file caches. | ||
| 81 | Return 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. | ||
| 115 | This function ALWAYS scans files and directories and DOES NOT | ||
| 116 | use any file caches. | ||
| 117 | Return 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. | ||
| 150 | Some projects have their dominating file in all their directories, such | ||
| 151 | as Project.ede. In that case we will detect quickly, but then need | ||
| 152 | to 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. | ||
| 163 | Scan the filesystem for a project. | ||
| 164 | Return 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. | ||
| 46 | DIR 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]+\\)\\])") | |||
| 129 | Return nil if there isn't one. | 104 | Return nil if there isn't one. |
| 130 | Argument DIR is the directory it is created for. | 105 | Argument DIR is the directory it is created for. |
| 131 | ROOTPROJ is nil, since there is only one project." | 106 | ROOTPROJ 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." | |||
| 80 | Allows for one-project-object-for-a-tree type systems. | 80 | Allows for one-project-object-for-a-tree type systems. |
| 81 | Optional FILE is the file to test. It is ignored in preference | 81 | Optional FILE is the file to test. It is ignored in preference |
| 82 | of the anchor file for the project." | 82 | of 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. | ||
| 127 | Does 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. |
| 152 | Optional ROOTRETURN specifies a symbol to set to the root project. | 147 | Optional 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. |
| 173 | Does 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)) | 171 | If 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. |
| 238 | Do this whenever a new project is created, as opposed to loaded." | 272 | Do 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. |
| 264 | Optional argument FORCE means to ignore a hash-hit of 'nomatch. | 307 | Optional argument FORCE means to ignore a hash-hit of 'nomatch. |
| 265 | This depends on an up to date `ede-project-class-files' variable. | 308 | This depends on an up to date `ede-project-class-files' variable. |
| 266 | Any directory that contains the file .ede-ignore will always | 309 | Any directory that contains the file .ede-ignore will always |
| 267 | return nil." | 310 | return nil. |
| 311 | |||
| 312 | Consider using `ede-directory-project-cons' instead if the next | ||
| 313 | question 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. | ||
| 323 | If there is no project in DIR, return nil. | ||
| 324 | Optional 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. |
| 296 | nil 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) | 353 | If 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. | ||
| 521 | DIR 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. | |||
| 142 | Argument DIR is the directory it is created for. | 99 | Argument DIR is the directory it is created for. |
| 143 | ROOTPROJ is nil, since there is only one project." | 100 | ROOTPROJ 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. |
| 182 | The class allocated value is replace by different sub classes.") | 146 | The 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. |
| 251 | All directories need at least one target.") | 192 | All 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. | ||
| 199 | All 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. | ||
| 336 | Argument 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. | ||
| 343 | Argument 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. | ||
| 383 | We need to go back through the old buffers, and update them with | ||
| 384 | the 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. | ||
| 81 | DIR 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." | |||
| 226 | Return nil if there isn't one. | 194 | Return nil if there isn't one. |
| 227 | Argument DIR is the directory it is created for. | 195 | Argument DIR is the directory it is created for. |
| 228 | ROOTPROJ is nil, since there is only one project." | 196 | ROOTPROJ 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 | |||
| 173 | calls to `ede-proj-tweak-autoconf' can restore items removed by flush." | 173 | calls 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. |
| 178 | Results in --add-missing being passed to automake." | 180 | Results 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." | |||
| 428 | If a given set of projects has already been loaded, then do nothing | 428 | If a given set of projects has already been loaded, then do nothing |
| 429 | but return the project for the directory given. | 429 | but return the project for the directory given. |
| 430 | Optional ROOTPROJ is the root EDE project." | 430 | Optional 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. |
| 384 | Optional argument CLEAR will clear the cache before parsing. | 384 | Optional argument CLEAR will clear the cache before parsing. |
| 385 | If CLEAR is negative, it will do a full reparse, and also not display | 385 | If CLEAR is negative, it will do a full reparse, and also display |
| 386 | the output buffer." | 386 | the 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. | ||
| 1175 | The completions provided are via `semantic-analyze-possible-completions'. | ||
| 1176 | This 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. | ||
| 1191 | The completions provided are via `semantic-analyze-possible-completions', | ||
| 1192 | but with the 'no-tc option passed in, which means constraints based | ||
| 1193 | on what is being assigned to are ignored. | ||
| 1194 | This 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. | ||
| 1206 | The completions provided are via `semantic-analyze-possible-completions', | ||
| 1207 | but with the 'no-tc and 'no-longprefix option passed in, which means | ||
| 1208 | constraints resulting in a long multi-symbol dereference are ignored. | ||
| 1209 | This 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. |
| 232 | Optional argument LOCALVAR is the list of local variables to use when | 232 | Optional argument LOCALVAR is the list of local variables to use when |
| 233 | finding the details on the first element of SEQUENCE in case | 233 | finding 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 | |||
| 237 | which doesn't need to be dereferenced. | 237 | which doesn't need to be dereferenced. |
| 238 | Optional argument TYPERETURN is a symbol in which the types of all found | 238 | Optional argument TYPERETURN is a symbol in which the types of all found |
| 239 | will be stored. If nil, that data is thrown away. | 239 | will be stored. If nil, that data is thrown away. |
| 240 | Optional argument THROWSYM specifies a symbol the throw on non-recoverable error.") | 240 | Optional argument THROWSYM specifies a symbol the throw on non-recoverable error. |
| 241 | Remaining 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. |
| 246 | SCOPE are extra tags which are in scope. | 248 | SCOPE are extra tags which are in scope. |
| 247 | TYPERETURN is a symbol in which to place a list of tag classes that | 249 | TYPERETURN is a symbol in which to place a list of tag classes that |
| 248 | are found in SEQUENCE. | 250 | are found in SEQUENCE. |
| 249 | Optional argument THROWSYM specifies a symbol the throw on non-recoverable error." | 251 | Optional argument THROWSYM specifies a symbol the throw on non-recoverable error. |
| 252 | Remaining arguments FLAGS are additional flags to apply when searching. | ||
| 253 | This 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. |
| 747 | Use PREFIX as a label. | 762 | Use PREFIX as a label. |
| 748 | Use BUFF as a source of override methods." | 763 | Use 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." | |||
| 112 | Argument CONTEXT is an object specifying the locally derived context. | 112 | Argument CONTEXT is an object specifying the locally derived context. |
| 113 | The optional argument FLAGS changes which return options are returned. | 113 | The optional argument FLAGS changes which return options are returned. |
| 114 | FLAGS can be any number of: | 114 | FLAGS 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. | ||
| 400 | The 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." | |||
| 124 | If the buffer is not in memory, load it with `find-file-noselect'." | 124 | If 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. | ||
| 132 | This 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. |
| 129 | Abstract tables do not have file names associated with them." | 141 | Abstract 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. | ||
| 341 | Buffers collected during symref can result in some files being | ||
| 342 | opened multiple times for one operation. This will keep buffers open | ||
| 343 | until 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. | ||
| 397 | Return the Semantic tag associated with HIT. | ||
| 398 | SEARCHTXT is the text that is being searched for. | ||
| 399 | Used to narrow the in-buffer search. | ||
| 400 | SEARCHTYPE is the type of search (such as 'symbol or 'tagname). | ||
| 401 | If 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. | ||
| 430 | Return the Semantic tag associated with HIT. | ||
| 431 | SEARCHTXT is the text that is being searched for. | ||
| 432 | Used to narrow the in-buffer search. | ||
| 433 | SEARCHTYPE is the type of search (such as 'symbol or 'tagname). | ||
| 434 | Optional OPEN-BUFFERS, when nil will use a faster version of | ||
| 435 | `find-file' when a file needs to be opened. If non-nil, then | ||
| 436 | normal buffer initialization will be used. | ||
| 437 | This function will leave buffers loaded from a file open, but | ||
| 438 | will add buffers that must be opened to `semantic-symref-recently-opened-buffers'. | ||
| 439 | Any caller MUST deal with that variable, either clearing it, or deleting the | ||
| 440 | buffers 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" "\ |