summaryrefslogtreecommitdiff
path: root/lisp/cedet/ede/auto.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/cedet/ede/auto.el')
-rw-r--r--lisp/cedet/ede/auto.el182
1 files changed, 86 insertions, 96 deletions
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 @@
:initform nil
:documentation
"An index into the match-data of `configregex'.")
- (configdatastash :initform nil
- :documentation
+ (subdir-only :initarg :subdir-only
+ :initform t
+ :documentation
+ "Non-nil means an exact match to the found directory is a non-match.
+This implies projects exist only in subdirectories of the configuration path.
+If `:subdir-only' is nil, then the directory from the configuration file is the project.")
+ (configdatastash :documentation
"Save discovered match string.")
)
"Support complex matches for projects that live in named directories.
@@ -80,8 +85,11 @@ into memory.")
;; If the thing to match is stored in a config file.
((stringp fc)
(when (file-exists-p fc)
- (let ((matchstring (oref dirmatch configdatastash)))
- (unless matchstring
+ (let ((matchstring
+ (if (slot-boundp dirmatch 'configdatastash)
+ (oref dirmatch configdatastash)
+ nil)))
+ (when (and (not matchstring) (not (slot-boundp dirmatch 'configdatastash)))
(save-current-buffer
(let* ((buff (get-file-buffer fc))
(readbuff
@@ -94,12 +102,27 @@ into memory.")
(setq matchstring
(match-string (or (oref dirmatch configregexidx) 0)))))
(if (not buff) (kill-buffer readbuff))))
- ;; Save what we find in our cache.
- (oset dirmatch configdatastash matchstring))
+ (when matchstring
+ ;; If this dirmatch only finds subdirs of matchstring, then
+ ;; force matchstring to be a directory.
+ (when (oref dirmatch subdir-only)
+ (setq matchstring (file-name-as-directory matchstring)))
+ ;; Convert matchstring to a regexp
+ (setq matchstring (concat "^" (regexp-quote matchstring)))
+ ;; Stash it for later.
+ (oset dirmatch configdatastash matchstring))
+ ;; Debug
+ ;;(message "Stashing config data for dirmatch %S as %S" (eieio-object-name dirmatch) matchstring)
+ )
+ ;;(message "dirmatch %s against %s" matchstring (expand-file-name file))
;; Match against our discovered string
- (and matchstring (string-match (regexp-quote matchstring) file))
+ (setq file (file-name-as-directory (expand-file-name file)))
+ (and matchstring (string-match matchstring (expand-file-name file))
+ (or (not (oref dirmatch subdir-only))
+ (not (= (match-end 0) (length file))))
+ )
)))
-
+
;; Add new matches here
;; ((stringp somenewslot ...)
;; )
@@ -119,13 +142,21 @@ into memory.")
:documentation "The lisp file belonging to this class.")
(proj-file :initarg :proj-file
:documentation "Name of a project file of this type.")
+ (root-only :initarg :root-only
+ :initform t ;; Default - majority case.
+ :documentation
+ "Non-nil if project detection only finds proj-file @ project root.")
(proj-root-dirmatch :initarg :proj-root-dirmatch
- :initform ""
- :type (or string ede-project-autoload-dirmatch)
+ :initform nil
+ :type (or null string ede-project-autoload-dirmatch)
:documentation
"To avoid loading a project, check if the directory matches this.
-For projects that use directory name matches, a function would load that project.
-Specifying this matcher will allow EDE to check without loading the project.")
+Specifying this matcher object will allow EDE to perform a complex
+check without loading the project.
+
+NOTE: If you use dirmatch, you may need to set :root-only to `nil'.
+While it may be a root based project, all subdirs will happen to return
+true for the dirmatch, so for scanning purposes, set it to `nil'.")
(proj-root :initarg :proj-root
:type function
:documentation "A function symbol to call for the project root.
@@ -168,12 +199,14 @@ type is required and the load function used.")
(ede-project-autoload "edeproject-makefile"
:name "Make" :file 'ede/proj
:proj-file "Project.ede"
+ :root-only nil
:load-type 'ede-proj-load
:class-sym 'ede-proj-project
:safe-p nil)
(ede-project-autoload "edeproject-automake"
:name "Automake" :file 'ede/proj
:proj-file "Project.ede"
+ :root-only nil
:initializers '(:makefile-type Makefile.am)
:load-type 'ede-proj-load
:class-sym 'ede-proj-project
@@ -181,6 +214,7 @@ type is required and the load function used.")
(ede-project-autoload "automake"
:name "automake" :file 'ede/project-am
:proj-file "Makefile.am"
+ :root-only nil
:load-type 'project-am-load
:class-sym 'project-am-makefile
:new-p nil
@@ -233,97 +267,33 @@ added. Possible values are:
;; Splice into the list.
(setcdr prev (cons projauto next))))))))
-;;; EDE project-autoload methods
+;;; Project Autoload Methods
;;
-(defmethod ede-project-root ((this ede-project-autoload))
- "If a project knows its root, return it here.
-Allows for one-project-object-for-a-tree type systems."
- nil)
-
-(defun ede-project-dirmatch-p (file dirmatch)
- "Return non-nil if FILE matches DIRMATCH.
-DIRMATCH could be nil (no match), a string (regexp match),
-or an `ede-project-autoload-dirmatch' object."
- ;; If dirmatch is a string, then we simply match it against
- ;; the file we are testing.
- (if (stringp dirmatch)
- (string-match dirmatch file)
- ;; if dirmatch is instead a dirmatch object, we test against
- ;; that object instead.
- (if (ede-project-autoload-dirmatch-p dirmatch)
- (ede-do-dirmatch dirmatch file)
- (error "Unknown project directory match type."))
- ))
-(defmethod ede-project-root-directory ((this ede-project-autoload)
- &optional file)
- "If a project knows its root, return it here.
-Allows for one-project-object-for-a-tree type systems.
-Optional FILE is the file to test. If there is no FILE, use
-the current buffer."
- (when (not file)
- (setq file default-directory))
- (when (slot-boundp this :proj-root)
- (let ((dirmatch (oref this proj-root-dirmatch))
- (rootfcn (oref this proj-root))
- (callfcn t))
- (when rootfcn
- (if ;; If the dirmatch (an object) is not installed, then we
- ;; always skip doing a match.
- (and (ede-project-autoload-dirmatch-p dirmatch)
- (not (ede-dirmatch-installed dirmatch)))
- (setq callfcn nil)
- ;; Other types of dirmatch:
- (when (and
- ;; If the Emacs Lisp file handling this project hasn't
- ;; been loaded, we will use the quick dirmatch feature.
- (not (featurep (oref this file)))
- ;; If the dirmatch is an empty string, then we always
- ;; skip doing a match.
- (not (and (stringp dirmatch) (string= dirmatch "")))
- )
- ;; If this file DOES NOT match dirmatch, we set the callfcn
- ;; to nil, meaning don't load the ede support file for this
- ;; type of project. If it does match, we will load the file
- ;; and use a more accurate programmatic match from there.
- (unless (ede-project-dirmatch-p file dirmatch)
- (setq callfcn nil))))
- ;; Call into the project support file for a match.
- (when callfcn
- (condition-case nil
- (funcall rootfcn file)
- (error
- (funcall rootfcn))))
- ))))
-
-(defmethod ede-dir-to-projectfile ((this ede-project-autoload) dir)
- "Return a full file name of project THIS found in DIR.
-Return nil if the project file does not exist."
+;; New method using detect.el
+(defmethod ede-auto-detect-in-dir ((this ede-project-autoload) dir)
+ "Return non-nil if THIS project autoload is found in DIR."
(let* ((d (file-name-as-directory dir))
- (root (ede-project-root-directory this d))
(pf (oref this proj-file))
- (dm (oref this proj-root-dirmatch))
- (f (cond ((stringp pf)
- (expand-file-name pf (or root d)))
- ((and (symbolp pf) (fboundp pf))
- ;; If there is a symbol to call, lets make extra
- ;; sure we really can call it without loading in
- ;; other EDE projects. This happens if the file is
- ;; already loaded, or if there is a dirmatch, but
- ;; root is empty.
- (when (and (featurep (oref this file))
- (or (not (stringp dm))
- (not (string= dm "")))
- root)
- (funcall pf (or root d))))))
- )
- (when (and f (file-exists-p f))
- f)))
+ (f (when (stringp pf) (expand-file-name pf d))))
+ (if f
+ (and f (file-exists-p f))
+ (let ((dirmatch (oref this proj-root-dirmatch)))
+ (cond
+ ((stringp dirmatch)
+ nil) ; <- do something here - maybe obsolete the option?
+ ((ede-project-autoload-dirmatch-p dirmatch)
+ (if (and dirmatch (ede-dirmatch-installed dirmatch))
+ (ede-do-dirmatch dirmatch dir)
+ ;(message "Dirmatch %S not installed." dirmatch)
+ )))))))
(defmethod ede-auto-load-project ((this ede-project-autoload) dir)
"Load in the project associated with THIS project autoload description.
THIS project description should be valid for DIR, where the project will
-be loaded."
+be loaded.
+
+NOTE: Do not call this - it should only be called from `ede-load-project-file'."
;; Last line of defense: don't load unsafe projects.
(when (not (or (oref this :safe-p)
(ede-directory-safe-p dir)))
@@ -332,7 +302,27 @@ be loaded."
(let ((o (funcall (oref this load-type) dir)))
(when (not o)
(error "Project type error: :load-type failed to create a project"))
- (ede-add-project-to-global-list o)))
+ (ede-add-project-to-global-list o)
+ ;; @TODO - Add to hash over at `ede-inode-directory-hash'.
+ ))
+
+
+
+
+
+
+;;; -------- Old Methods
+;; See if we can do without them.
+
+;; @FIXME - delete from loaddefs to remove this.
+(defmethod ede-project-root ((this ede-project-autoload))
+ "If a project knows its root, return it here.
+Allows for one-project-object-for-a-tree type systems."
+ nil)
+
+;; @FIXME - delete from loaddefs to remove this.
+(defmethod ede-project-root-directory ((this ede-project-autoload) &optional file)
+ "" nil)
(provide 'ede/auto)