diff options
Diffstat (limited to 'lisp/cedet/ede')
-rw-r--r-- | lisp/cedet/ede/auto.el | 198 | ||||
-rw-r--r-- | lisp/cedet/ede/autoconf-edit.el | 50 | ||||
-rw-r--r-- | lisp/cedet/ede/base.el | 7 | ||||
-rw-r--r-- | lisp/cedet/ede/cpp-root.el | 40 | ||||
-rw-r--r-- | lisp/cedet/ede/dired.el | 2 | ||||
-rw-r--r-- | lisp/cedet/ede/emacs.el | 52 | ||||
-rw-r--r-- | lisp/cedet/ede/files.el | 26 | ||||
-rw-r--r-- | lisp/cedet/ede/generic.el | 80 | ||||
-rw-r--r-- | lisp/cedet/ede/linux.el | 95 | ||||
-rw-r--r-- | lisp/cedet/ede/makefile-edit.el | 3 | ||||
-rw-r--r-- | lisp/cedet/ede/pmake.el | 13 | ||||
-rw-r--r-- | lisp/cedet/ede/proj-comp.el | 21 | ||||
-rw-r--r-- | lisp/cedet/ede/proj-elisp.el | 92 | ||||
-rw-r--r-- | lisp/cedet/ede/proj.el | 87 | ||||
-rw-r--r-- | lisp/cedet/ede/project-am.el | 2 | ||||
-rw-r--r-- | lisp/cedet/ede/util.el | 2 |
16 files changed, 596 insertions, 174 deletions
diff --git a/lisp/cedet/ede/auto.el b/lisp/cedet/ede/auto.el index a5ea8178858..f6446db9108 100644 --- a/lisp/cedet/ede/auto.el +++ b/lisp/cedet/ede/auto.el @@ -34,6 +34,84 @@ (declare-function ede-directory-safe-p "ede") (declare-function ede-add-project-to-global-list "ede") +(defclass ede-project-autoload-dirmatch () + ((fromconfig :initarg :fromconfig + :initform nil + :documentation + "A config file within which the match pattern lives.") + (configregex :initarg :configregex + :initform nil + :documentation + "A regexp to identify the dirmatch pattern.") + (configregexidx :initarg :configregexidx + :initform nil + :documentation + "An index into the match-data of `configregex'.") + (configdatastash :initform nil + :documentation + "Save discovered match string.") + ) + "Support complex matches for projects that live in named directories. +For most cases, a simple string is sufficient. If, however, a project +location is varied dependent on other complex criteria, this class +can be used to define that match without loading the specific project +into memory.") + +(defmethod ede-dirmatch-installed ((dirmatch ede-project-autoload-dirmatch)) + "Return non-nil if the tool DIRMATCH might match is installed on the system." + (let ((fc (oref dirmatch fromconfig))) + + (cond + ;; If the thing to match is stored in a config file. + ((stringp fc) + (file-exists-p fc)) + + ;; Add new types of dirmatches here. + + ;; Error for wierd stuff + (t (error "Unknown dirmatch type."))))) + + +(defmethod ede-do-dirmatch ((dirmatch ede-project-autoload-dirmatch) file) + "Does DIRMATCH match the filename FILE." + (let ((fc (oref dirmatch fromconfig))) + + (cond + ;; 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 + (save-current-buffer + (let* ((buff (get-file-buffer fc)) + (readbuff + (let ((find-file-hook nil)) ;; Disable ede from recursing + (find-file-noselect fc)))) + (set-buffer readbuff) + (save-excursion + (goto-char (point-min)) + (when (re-search-forward (oref dirmatch configregex) nil t) + (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)) + ;; Match against our discovered string + (and matchstring (string-match (regexp-quote matchstring) file)) + ))) + + ;; Add new matches here + ;; ((stringp somenewslot ...) + ;; ) + + ;; Error if none others known + (t + (error "Unknown dirmatch object match style."))) + )) + +(declare-function ede-directory-safe-p "ede") +(declare-function ede-add-project-to-global-list "ede") + (defclass ede-project-autoload () ((name :initarg :name :documentation "Name of this project type") @@ -41,6 +119,13 @@ :documentation "The lisp file belonging to this class.") (proj-file :initarg :proj-file :documentation "Name of a project file of this type.") + (proj-root-dirmatch :initarg :proj-root-dirmatch + :initform "" + :type (or 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.") (proj-root :initarg :proj-root :type function :documentation "A function symbol to call for the project root. @@ -57,6 +142,11 @@ associated with a single object class, based on the initializers used.") :documentation "Fn symbol used to load this project file.") (class-sym :initarg :class-sym :documentation "Symbol representing the project class to use.") + (generic-p :initform nil + :documentation + "Generic projects are added to the project list at the end. +The add routine will set this to non-nil so that future non-generic placement will +be successful.") (new-p :initarg :new-p :initform t :documentation @@ -93,11 +183,56 @@ type is required and the load function used.") :proj-file "Makefile.am" :load-type 'project-am-load :class-sym 'project-am-makefile - :new-p nil)) + :new-p nil + :safe-p t) + ) "List of vectors defining how to determine what type of projects exist.") (put 'ede-project-class-files 'risky-local-variable t) +(defun ede-add-project-autoload (projauto &optional flag) + "Add PROJAUTO, an EDE autoload definition to `ede-project-class-files'. +Optional argument FLAG indicates how this autoload should be +added. Possible values are: + 'generic - A generic project type. Keep this at the very end. + 'unique - A unique project type for a specific project. Keep at the very + front of the list so more generic projects don't get priority." + ;; First, can we identify PROJAUTO as already in the list? If so, replace. + (let ((projlist ede-project-class-files) + (projname (object-name-string projauto))) + (while (and projlist (not (string= (object-name-string (car projlist)) projname))) + (setq projlist (cdr projlist))) + + (if projlist + ;; Stick the new one into the old slot. + (setcar projlist projauto) + + ;; Else, see where to insert it. + (cond ((and flag (eq flag 'unique)) + ;; Unique items get stuck right onto the front. + (setq ede-project-class-files + (cons projauto ede-project-class-files))) + + ;; Generic Projects go at the very end of the list. + ((and flag (eq flag 'generic)) + (oset projauto generic-p t) + (setq ede-project-class-files + (append ede-project-class-files + (list projauto)))) + + ;; Normal projects go at the end of the list, but + ;; before the generic projects. + (t + (let ((prev nil) + (next ede-project-class-files)) + (while (and next (not (oref (car next) generic-p))) + (setq prev next + next (cdr next))) + (when (not prev) + (error "ede-project-class-files not initialized")) + ;; Splice into the list. + (setcdr prev (cons projauto next)))))))) + ;;; EDE project-autoload methods ;; (defmethod ede-project-root ((this ede-project-autoload)) @@ -105,6 +240,21 @@ type is required and the load function used.") 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. @@ -114,12 +264,36 @@ the current buffer." (when (not file) (setq file default-directory)) (when (slot-boundp this :proj-root) - (let ((rootfcn (oref this proj-root))) + (let ((dirmatch (oref this proj-root-dirmatch)) + (rootfcn (oref this proj-root)) + (callfcn t)) (when rootfcn - (condition-case nil - (funcall rootfcn file) - (error - (funcall 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 programatic 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) @@ -128,10 +302,20 @@ Return nil if the project file does not exist." (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)) - (funcall pf (or root d))))) + ;; 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))) diff --git a/lisp/cedet/ede/autoconf-edit.el b/lisp/cedet/ede/autoconf-edit.el index e3c9d2cb4f8..8144b135ac5 100644 --- a/lisp/cedet/ede/autoconf-edit.el +++ b/lisp/cedet/ede/autoconf-edit.el @@ -165,6 +165,9 @@ items such as CHECK_HEADERS." (setq param (substring param (match-end 0)))) (when (string-match "\\s-*\\]?\\s-*\\'" param) (setq param (substring param 0 (match-beginning 0)))) + ;; Look for occurances of backslash newline + (while (string-match "\\s-*\\\\\\s-*\n\\s-*" param) + (setq param (replace-match " " t t param))) param) (defun autoconf-parameters-for-macro (macro &optional ignore-bol ignore-case) @@ -373,6 +376,38 @@ Optional argument BODY is the code to execute which edits the autoconf file." (string= autoconf-deleted-text autoconf-inserted-text)) (set-buffer-modified-p nil)))) +(defun autoconf-parameter-count () + "Return the number of parameters to the function on the current line." + (save-excursion + (beginning-of-line) + (let* ((end-of-cmd + (save-excursion + (if (re-search-forward "(" (point-at-eol) t) + (progn + (forward-char -1) + (forward-sexp 1) + (point)) + ;; Else, just return EOL. + (point-at-eol)))) + (cnt 0)) + (save-restriction + (narrow-to-region (point-at-bol) end-of-cmd) + (condition-case nil + (progn + (down-list 1) + (while (re-search-forward ", ?" end-of-cmd t) + (setq cnt (1+ cnt))) + (cond ((> cnt 1) + ;; If the # is > 1, then there is one fewer , than args. + (1+ cnt)) + ((not (looking-at "\\s-*)")) + ;; If there are 0 args, then we have to see if there is one arg. + (1+ cnt)) + (t + ;; Else, just return the 0. + cnt))) + (error 0)))))) + (defun autoconf-delete-parameter (index) "Delete the INDEXth parameter from the macro starting on the current line. Leaves the cursor where a new parameter can be inserted. @@ -396,12 +431,19 @@ INDEX starts at 1." "Set the version used with automake to VERSION." (if (not (stringp version)) (signal 'wrong-type-argument '(stringp version))) - (if (not (autoconf-find-last-macro "AM_INIT_AUTOMAKE")) - (error "Cannot update version") - ;; Move to correct position. + (if (and (autoconf-find-last-macro "AM_INIT_AUTOMAKE") + (>= (autoconf-parameter-count) 2)) + ;; We can edit right here. + nil + ;; Else, look for AC init instead. + (if (not (and (autoconf-find-last-macro "AC_INIT") + (>= (autoconf-parameter-count) 2))) + (error "Cannot update version"))) + + ;; Perform the edit. (autoconf-edit-cycle (autoconf-delete-parameter 2) - (autoconf-insert version)))) + (autoconf-insert (concat "[" version "]")))) (defun autoconf-set-output (outputlist) "Set the files created in AC_OUTPUT to OUTPUTLIST. diff --git a/lisp/cedet/ede/base.el b/lisp/cedet/ede/base.el index ce3d4a036f3..fe12720500b 100644 --- a/lisp/cedet/ede/base.el +++ b/lisp/cedet/ede/base.el @@ -163,7 +163,7 @@ and querying them will cause the actual project to get loaded.") :documentation "Sub projects controlled by this project. For Automake based projects, each directory is treated as a project.") (targets :initarg :targets - :type list + :type ede-target-list :custom (repeat (object :objectcreatefcn ede-new-target-custom)) :label "Local Targets" :group (targets) @@ -287,10 +287,7 @@ All specific project types must derive from this project." "For the project in which OBJ resides, execute FORMS." `(save-window-excursion (let* ((pf (if (obj-of-class-p ,obj ede-target) - ;; @todo -I think I can change - ;; this to not need ede-load-project-file - ;; but I'm not sure how to test well. - (ede-load-project-file (oref ,obj path)) + (ede-target-parent ,obj) ,obj)) (dbka (get-file-buffer (oref pf file)))) (if (not dbka) (find-file (oref pf file)) diff --git a/lisp/cedet/ede/cpp-root.el b/lisp/cedet/ede/cpp-root.el index e6fd92759de..48b83f30bb0 100644 --- a/lisp/cedet/ede/cpp-root.el +++ b/lisp/cedet/ede/cpp-root.el @@ -85,7 +85,7 @@ ;; file name for a header in your project where most of your CPP ;; macros reside. Doing this can be easier than listing everything in ;; the :spp-table option. The files listed in :spp-files should not -;; start with a /, and are relative to something in :include-path.;; +;; start with a /, and are relative to something in :include-path. ;; ;; If you want to override the file-finding tool with your own ;; function you can do this: @@ -135,7 +135,8 @@ ;; :proj-file 'MY-FILE-FOR-DIR ;; :proj-root 'MY-ROOT-FCN ;; :load-type 'MY-LOAD -;; :class-sym 'ede-cpp-root) +;; :class-sym 'ede-cpp-root-project +;; :safe-p t) ;; t) ;; ;;; TODO @@ -238,16 +239,20 @@ ROOTPROJ is nil, since there is only one project." (ede-cpp-root-file-existing dir)) ;;;###autoload -(add-to-list 'ede-project-class-files - (ede-project-autoload "cpp-root" - :name "CPP ROOT" - :file 'ede/cpp-root - :proj-file 'ede-cpp-root-project-file-for-dir - :proj-root 'ede-cpp-root-project-root - :load-type 'ede-cpp-root-load - :class-sym 'ede-cpp-root - :new-p nil) - t) +(ede-add-project-autoload + (ede-project-autoload "cpp-root" + :name "CPP ROOT" + :file 'ede-cpp-root + :proj-file 'ede-cpp-root-project-file-for-dir + :proj-root 'ede-cpp-root-project-root + :load-type 'ede-cpp-root-load + :class-sym 'ede-cpp-root + :new-p nil + :safe-p t) + ;; When a user creates one of these, it should override any other project + ;; type that might happen to be in this directory, so force this to the + ;; very front. + 'unique) ;;; CLASSES ;; @@ -439,6 +444,7 @@ This knows details about or source tree." ;; Else, do the usual. (setq ans (call-next-method))) ))) + ;; TODO - does this call-next-method happen twice. Is that bad?? Why is it here? (or ans (call-next-method)))) (defmethod ede-project-root ((this ede-cpp-root-project)) @@ -500,16 +506,16 @@ Also set up the lexical preprocessor map." (table (when expfile (semanticdb-file-table-object expfile))) ) - (when (not table) - (message "Cannot find file %s in project." F)) - (when (and table (semanticdb-needs-refresh-p table)) - (semanticdb-refresh-table table) + (if (not table) + (message "Cannot find file %s in project." F) + (when (semanticdb-needs-refresh-p table) + (semanticdb-refresh-table table)) (setq spp (append spp (oref table lexical-table)))))) (oref this spp-files)) spp)) (defmethod ede-system-include-path ((this ede-cpp-root-target)) - "Get the system include path used by project THIS." + "Get the system include path used by target THIS." (ede-system-include-path (ede-target-parent this))) (defmethod ede-preprocessor-map ((this ede-cpp-root-target)) diff --git a/lisp/cedet/ede/dired.el b/lisp/cedet/ede/dired.el index bf9ab272785..fa56a9ac5ca 100644 --- a/lisp/cedet/ede/dired.el +++ b/lisp/cedet/ede/dired.el @@ -64,7 +64,7 @@ negative, force off." (setq ede-dired-minor-mode nil) (error "Not in DIRED mode")) (unless (or (ede-directory-project-p default-directory) - (interactive-p)) + (called-interactively-p 'any)) (setq ede-dired-minor-mode nil))) (defun ede-dired-add-to-target (target) diff --git a/lisp/cedet/ede/emacs.el b/lisp/cedet/ede/emacs.el index e3afe30063c..e3a5789cf3b 100644 --- a/lisp/cedet/ede/emacs.el +++ b/lisp/cedet/ede/emacs.el @@ -99,6 +99,17 @@ emacs_beta_version=\\([0-9]+\\)") (match-string 2) "." (match-string 3))) ) + ((file-exists-p "sxemacs.pc.in") + (setq emacs "SXEmacs") + (insert-file-contents "sxemacs_version.m4") + (goto-char (point-min)) + (re-search-forward "m4_define(\\[SXEM4CS_MAJOR_VERSION\\], \\[\\([0-9]+\\)\\]) +m4_define(\\[SXEM4CS_MINOR_VERSION\\], \\[\\([0-9]+\\)\\]) +m4_define(\\[SXEM4CS_BETA_VERSION\\], \\[\\([0-9]+\\)\\])") + (setq ver (concat (match-string 1) "." + (match-string 2) "." + (match-string 3))) + ) ;; Insert other Emacs here... ;; Vaguely recent version of GNU Emacs? @@ -125,28 +136,29 @@ Argument DIR is the directory it is created for. ROOTPROJ is nil, since there is only one project." (or (ede-emacs-file-existing dir) ;; Doesn't already exist, so let's make one. - (let* ((vertuple (ede-emacs-version dir))) - (ede-emacs-project (car vertuple) - :name (car vertuple) - :version (cdr vertuple) - :directory (file-name-as-directory dir) - :file (expand-file-name "src/emacs.c" - dir))) - (ede-add-project-to-global-list this) - ) - ) + (let* ((vertuple (ede-emacs-version dir)) + (proj (ede-emacs-project + (car vertuple) + :name (car vertuple) + :version (cdr vertuple) + :directory (file-name-as-directory dir) + :file (expand-file-name "src/emacs.c" + dir)))) + (ede-add-project-to-global-list proj)))) ;;;###autoload -(add-to-list 'ede-project-class-files - (ede-project-autoload "emacs" - :name "EMACS ROOT" - :file 'ede/emacs - :proj-file "src/emacs.c" - :proj-root 'ede-emacs-project-root - :load-type 'ede-emacs-load - :class-sym 'ede-emacs-project - :new-p nil) - t) +(ede-add-project-autoload + (ede-project-autoload "emacs" + :name "EMACS ROOT" + :file 'ede/emacs + :proj-file "src/emacs.c" + :proj-root-dirmatch "emacs[^/]*" + :proj-root 'ede-emacs-project-root + :load-type 'ede-emacs-load + :class-sym 'ede-emacs-project + :new-p nil + :safe-p t) + 'unique) (defclass ede-emacs-target-c (ede-target) () diff --git a/lisp/cedet/ede/files.el b/lisp/cedet/ede/files.el index 02aeffc5e2b..e5d75234b49 100644 --- a/lisp/cedet/ede/files.el +++ b/lisp/cedet/ede/files.el @@ -63,7 +63,8 @@ the current EDE project." (interactive) (require 'ede/locate) (let* ((loc (ede-get-locator-object (ede-current-project)))) - (ede-locate-flush-hash loc))) + (when loc + (ede-locate-flush-hash loc)))) ;;; Placeholders for ROOT directory scanning on base objects ;; @@ -110,7 +111,7 @@ of the anchor file for the project." (when (not ans) (if (equal (ede--project-inode SP) inode) (setq ans SP) - (ede-find-subproject-for-directory SP dir))))) + (setq ans (ede-find-subproject-for-directory SP dir)))))) ans))) ;;; DIRECTORY IN OPEN PROJECT @@ -219,6 +220,18 @@ Does not check subprojects." :test 'equal) "A hash of directory names and associated EDE objects.") +(defun ede-flush-directory-hash () + "Flush the project directory hash. +Do this only when developing new projects that are incorrectly putting +'nomatch tokens into the hash." + (interactive) + (setq ede-project-directory-hash (make-hash-table :test 'equal)) + ;; Also slush the current project's locator hash. + (let ((loc (ede-get-locator-object ede-object))) + (when loc + (ede-locate-flush-hash loc))) + ) + (defun ede-project-directory-remove-hash (dir) "Reset the directory hash for DIR. Do this whenever a new project is created, as opposed to loaded." @@ -368,10 +381,11 @@ Get it from the toplevel project. If it doesn't have one, make one." ;; Make sure we have a location object available for ;; caching values, and for locating things more robustly. (let ((top (ede-toplevel proj))) - (when (not (slot-boundp top 'locate-obj)) - (ede-enable-locate-on-project top)) - (oref top locate-obj) - )) + (when top + (when (not (slot-boundp top 'locate-obj)) + (ede-enable-locate-on-project top)) + (oref top locate-obj) + ))) (defmethod ede-expand-filename ((this ede-project) filename &optional force) "Return a fully qualified file name based on project THIS. diff --git a/lisp/cedet/ede/generic.el b/lisp/cedet/ede/generic.el index 67ef63f662e..c4fc5c6b6a9 100644 --- a/lisp/cedet/ede/generic.el +++ b/lisp/cedet/ede/generic.el @@ -79,6 +79,7 @@ (require 'eieio-opt) (require 'ede) +(require 'ede/shell) (require 'semantic/db) ;;; Code: @@ -105,6 +106,13 @@ :group (default build) :documentation "Command used for debugging this project.") + (run-command :initarg :run-command + :initform nil + :type (or null string) + :custom string + :group (default build) + :documentation + "Command used to run something related to this project.") ;; C target customizations (c-include-path :initarg :c-include-path :initform nil @@ -196,7 +204,7 @@ The class allocated value is replace by different sub classes.") (oref proj :directory)))) (if (file-exists-p fname) ;; Load in the configuration - (setq config (eieio-persistent-read fname)) + (setq config (eieio-persistent-read fname 'ede-generic-config)) ;; Create a new one. (setq config (ede-generic-config "Configuration" @@ -321,6 +329,44 @@ If one doesn't exist, create a new one for this directory." (config (ede-generic-get-configuration proj))) (oref config c-include-path))) +;;; Commands +;; +(defmethod project-compile-project ((proj ede-generic-project) &optional command) + "Compile the entire current project PROJ. +Argument COMMAND is the command to use when compiling." + (let* ((config (ede-generic-get-configuration proj)) + (comp (oref config :build-command))) + (compile comp))) + +(defmethod project-compile-target ((obj ede-generic-target) &optional command) + "Compile the current target OBJ. +Argument COMMAND is the command to use for compiling the target." + (project-compile-project (ede-current-project) command)) + +(defmethod project-debug-target ((target ede-generic-target)) + "Run the current project derived from TARGET in a debugger." + (let* ((proj (ede-target-parent target)) + (config (ede-generic-get-configuration proj)) + (debug (oref config :debug-command)) + (cmd (read-from-minibuffer + "Debug Command: " + debug)) + (cmdsplit (split-string cmd " " t)) + ;; @TODO - this depends on the user always typing in something good + ;; like "gdb" or "dbx" which also exists as a useful Emacs command. + ;; Is there a better way? + (cmdsym (intern-soft (car cmdsplit)))) + (call-interactively cmdsym t))) + +(defmethod project-run-target ((target ede-generic-target)) + "Run the current project derived from TARGET." + (require 'ede-shell) + (let* ((proj (ede-target-parent target)) + (config (ede-generic-get-configuration proj)) + (run (concat "./" (oref config :run-command))) + (cmd (read-from-minibuffer "Run (like this): " run))) + (ede-shell-run-something target cmd))) + ;;; Customization ;; (defmethod ede-customize ((proj ede-generic-project)) @@ -365,27 +411,31 @@ PROJECTFILE is a file name that identifies a project of this type to EDE, such a a Makefile, or SConstruct file. CLASS is the EIEIO class that is used to track this project. It should subclass the class `ede-generic-project' project." - (add-to-list 'ede-project-class-files - (ede-project-autoload internal-name - :name external-name - :file 'ede/generic - :proj-file projectfile - :load-type 'ede-generic-load - :class-sym class - :new-p nil) - ;; Generics must go at the end, since more specific types - ;; can create Makefiles also. - t)) + (ede-add-project-autoload + (ede-project-autoload internal-name + :name external-name + :file 'ede/generic + :proj-file projectfile + :load-type 'ede-generic-load + :class-sym class + :new-p nil + :safe-p nil) ; @todo - could be + ; safe if we do something + ; about the loading of the + ; generic config file. + ;; Generics must go at the end, since more specific types + ;; can create Makefiles also. + 'generic)) ;;;###autoload (defun ede-enable-generic-projects () "Enable generic project loaders." (interactive) - (ede-generic-new-autoloader "edeproject-makefile" "Make" + (ede-generic-new-autoloader "generic-makefile" "Make" "Makefile" 'ede-generic-makefile-project) - (ede-generic-new-autoloader "edeproject-scons" "SCons" + (ede-generic-new-autoloader "generic-scons" "SCons" "SConstruct" 'ede-generic-scons-project) - (ede-generic-new-autoloader "edeproject-cmake" "CMake" + (ede-generic-new-autoloader "generic-cmake" "CMake" "CMakeLists" 'ede-generic-cmake-project) ) diff --git a/lisp/cedet/ede/linux.el b/lisp/cedet/ede/linux.el index 70cd9498f69..7cd066f8b3b 100644 --- a/lisp/cedet/ede/linux.el +++ b/lisp/cedet/ede/linux.el @@ -33,11 +33,29 @@ ;; * Add website (require 'ede) +(require 'ede/make) + (declare-function semanticdb-file-table-object "semantic/db") (declare-function semanticdb-needs-refresh-p "semantic/db") (declare-function semanticdb-refresh-table "semantic/db") ;;; Code: +(defgroup project-linux nil + "File and tag browser frame." + :group 'tools + :group 'ede + ) + +(defcustom project-linux-compile-target-command (concat ede-make-command " -k -C %s SUBDIRS=%s") + "*Default command used to compile a target." + :group 'project-linux + :type 'string) + +(defcustom project-linux-compile-project-command (concat ede-make-command " -k -C %s") + "*Default command used to compile a project." + :group 'project-linux + :type 'string) + (defvar ede-linux-project-list nil "List of projects created by option `ede-linux-project'.") @@ -95,6 +113,7 @@ DIR is the directory to search from." "Project Type for the Linux source code." :method-invocation-order :depth-first) +;;;###autoload (defun ede-linux-load (dir &optional rootproj) "Return an Linux Project object if there is a match. Return nil if there isn't one. @@ -102,27 +121,29 @@ Argument DIR is the directory it is created for. ROOTPROJ is nil, since there is only one project." (or (ede-linux-file-existing dir) ;; Doesn't already exist, so let's make one. - (ede-linux-project "Linux" - :name "Linux" - :version (ede-linux-version dir) - :directory (file-name-as-directory dir) - :file (expand-file-name "scripts/ver_linux" - dir)) - (ede-add-project-to-global-list this) - ) - ) + (let ((proj (ede-linux-project + "Linux" + :name "Linux" + :version (ede-linux-version dir) + :directory (file-name-as-directory dir) + :file (expand-file-name "scripts/ver_linux" + dir)))) + (ede-add-project-to-global-list proj)) + )) ;;;###autoload -(add-to-list 'ede-project-class-files - (ede-project-autoload "linux" - :name "LINUX ROOT" - :file 'ede/linux - :proj-file "scripts/ver_linux" - :proj-root 'ede-linux-project-root - :load-type 'ede-linux-load - :class-sym 'ede-linux-project - :new-p nil) - t) +(ede-add-project-autoload + (ede-project-autoload "linux" + :name "LINUX ROOT" + :file 'ede/linux + :proj-file "scripts/ver_linux" + :proj-root-dirmatch "linux[^/]*" + :proj-root 'ede-linux-project-root + :load-type 'ede-linux-load + :class-sym 'ede-linux-project + :new-p nil + :safe-p t) + 'unique) (defclass ede-linux-target-c (ede-target) () @@ -238,6 +259,42 @@ Knows about how the Linux source tree is organized." ) (or F (call-next-method)))) +(defmethod project-compile-project ((proj ede-linux-project) + &optional command) + "Compile the entire current project. +Argument COMMAND is the command to use when compiling." + (let* ((dir (ede-project-root-directory proj))) + + (require 'compile) + (if (not project-linux-compile-project-command) + (setq project-linux-compile-project-command compile-command)) + (if (not command) + (setq command + (format + project-linux-compile-project-command + dir))) + + (compile command))) + +(defmethod project-compile-target ((obj ede-linux-target-c) &optional command) + "Compile the current target. +Argument COMMAND is the command to use for compiling the target." + (let* ((proj (ede-target-parent obj)) + (root (ede-project-root proj)) + (dir (ede-project-root-directory root)) + (subdir (oref obj path))) + + (require 'compile) + (if (not project-linux-compile-project-command) + (setq project-linux-compile-project-command compile-command)) + (if (not command) + (setq command + (format + project-linux-compile-target-command + dir subdir))) + + (compile command))) + (provide 'ede/linux) ;; Local variables: diff --git a/lisp/cedet/ede/makefile-edit.el b/lisp/cedet/ede/makefile-edit.el index afa1c7200ec..739b774ee52 100644 --- a/lisp/cedet/ede/makefile-edit.el +++ b/lisp/cedet/ede/makefile-edit.el @@ -99,7 +99,8 @@ STOP-BEFORE is a regular expression matching a file name." "Return a list of all files in MACRO." (save-excursion (goto-char (point-min)) - (let ((lst nil)) + (let ((lst nil) + (case-fold-search nil)) (while (makefile-move-to-macro macro t) (let ((e (save-excursion (makefile-end-of-command) diff --git a/lisp/cedet/ede/pmake.el b/lisp/cedet/ede/pmake.el index bd5400bb615..c638a5f0307 100644 --- a/lisp/cedet/ede/pmake.el +++ b/lisp/cedet/ede/pmake.el @@ -265,12 +265,13 @@ Execute BODY in a location where a value can be placed." "Add VARNAME into the current Makefile if it doesn't exist. Execute BODY in a location where a value can be placed." `(let ((addcr t) (v ,varname)) - (unless (re-search-backward (concat "^" v "\\s-*=") nil t) - (insert v "=") - ,@body - (if addcr (insert "\n")) - (goto-char (point-max))) - )) + (unless + (save-excursion + (re-search-backward (concat "^" v "\\s-*=") nil t)) + (insert v "=") + ,@body + (when addcr (insert "\n")) + (goto-char (point-max))))) (put 'ede-pmake-insert-variable-once 'lisp-indent-function 1) ;;; SOURCE VARIABLE NAME CONSTRUCTION diff --git a/lisp/cedet/ede/proj-comp.el b/lisp/cedet/ede/proj-comp.el index 8277f58a5e0..87a722ef9be 100644 --- a/lisp/cedet/ede/proj-comp.el +++ b/lisp/cedet/ede/proj-comp.el @@ -319,7 +319,7 @@ Not all compilers do this." (defmethod ede-proj-makefile-insert-rules ((this ede-makefile-rule)) "Insert rules needed for THIS rule object." - (if (oref this phony) (insert ".PHONY: (oref this target)\n")) + (if (oref this phony) (insert ".PHONY: " (oref this target) "\n")) (insert (oref this target) ": " (oref this dependencies) "\n\t" (mapconcat (lambda (c) c) (oref this rules) "\n\t") "\n\n")) @@ -331,15 +331,16 @@ compiler it decides to use after inserting in the rule." (when (slot-boundp this 'commands) (with-slots (commands) this (mapc - (lambda (obj) (insert "\t" - (cond ((stringp obj) - obj) - ((and (listp obj) - (eq (car obj) 'lambda)) - (funcall obj)) - (t - (format "%S" obj))) - "\n")) + (lambda (obj) (insert + (if (bolp) "\t" " ") + (cond ((stringp obj) + obj) + ((and (listp obj) + (eq (car obj) 'lambda)) + (funcall obj)) + (t + (format "%S" obj))) + "\n")) commands)) (insert "\n"))) diff --git a/lisp/cedet/ede/proj-elisp.el b/lisp/cedet/ede/proj-elisp.el index 78200acff7d..db8803fa002 100644 --- a/lisp/cedet/ede/proj-elisp.el +++ b/lisp/cedet/ede/proj-elisp.el @@ -45,10 +45,37 @@ There should only be one toplevel package per auxiliary tool needed. These packages location is found, and added to the compile time load path." - )) + ) + (pre-load-packages :initarg :pre-load-packages + :initform nil + :type list + :custom (repeat string) + :documentation "Additional packages to pre-load. +Each package name will be loaded with `require'. +Each package's directory should also appear in :aux-packages via a package name.") + ) "This target consists of a group of lisp files. A lisp target may be one general program with many separate lisp files in it.") +(defmethod ede-proj-makefile-insert-rules :after ((this ede-proj-target-elisp)) + "Insert rules needed by THIS target. +This inserts the PRELOADS target-local variable." + (let ((preloads (oref this pre-load-packages))) + (when preloads + (insert (format "%s: PRELOADS=%s\n" + (oref this name) + (mapconcat 'identity preloads " "))))) + (insert "\n")) + +(defmethod ede-proj-makefile-dependencies ((this ede-proj-target-elisp)) + "Return a string representing the dependencies for THIS. +Some compilers only use the first element in the dependencies, others +have a list of intermediates (object files), and others don't care. +This allows customization of how these elements appear. +For Emacs Lisp, return addsuffix command on source files." + (format "$(addsuffix c, $(%s))" + (ede-proj-makefile-sourcevar this))) + (defvar ede-source-emacs (ede-sourcecode "ede-emacs-source" :name "Emacs Lisp" @@ -61,18 +88,17 @@ A lisp target may be one general program with many separate lisp files in it.") "ede-emacs-compiler" :name "emacs" :variables '(("EMACS" . "emacs") - ("EMACSFLAGS" . "-batch --no-site-file")) - :commands - '("@echo \"(add-to-list 'load-path nil)\" > $@-compile-script" - "for loadpath in . ${LOADPATH}; do \\" - " echo \"(add-to-list 'load-path \\\"$$loadpath\\\")\" >> $@-compile-script; \\" - "done;" - "@echo \"(setq debug-on-error t)\" >> $@-compile-script" - "\"$(EMACS)\" $(EMACSFLAGS) -l $@-compile-script -f batch-byte-compile $^" - ) + ("EMACSFLAGS" . "-batch --no-site-file --eval '(setq debug-on-error t)'") + ("require" . "$(foreach r,$(1),(require (quote $(r))))")) + :rules (list (ede-makefile-rule + "elisp-inference-rule" + :target "%.elc" + :dependencies "%.el" + :rules '("$(EMACS) $(EMACSFLAGS) $(addprefix -L ,$(LOADPATH)) \ +--eval '(progn $(call require, $(PRELOADS)))' -f batch-byte-compile $^"))) :autoconf '("AM_PATH_LISPDIR") :sourcetype '(ede-source-emacs) -; :objectextention ".elc" + :objectextention ".elc" ) "Compile Emacs Lisp programs.") @@ -112,7 +138,7 @@ Lays claim to all .elc files that match .el files in this target." (full nil) ) ;; Make sure the relative name isn't to far off - (when (string-match "^\\.\\./\\.\\./\\.\\./\\.\\." rel) + (when (string-match "^\\.\\./\\.\\./\\.\\./\\.\\./\\.\\." rel) (setq full fnd)) ;; Do the setup. (setq paths (cons (or full rel) paths) @@ -129,9 +155,20 @@ Bonus: Return a cons cell: (COMPILED . UPTODATE)." (mapc (lambda (src) (let* ((fsrc (expand-file-name src dir)) (elc (concat (file-name-sans-extension fsrc) ".elc"))) - (if (eq (byte-recompile-file fsrc nil 0) t) - (setq comp (1+ comp)) - (setq utd (1+ utd))))) + (with-no-warnings + (if (< emacs-major-version 24) + ;; Does not have `byte-recompile-file' + (if (or (not (file-exists-p elc)) + (file-newer-than-file-p fsrc elc)) + (progn + (setq comp (1+ comp)) + (byte-compile-file fsrc)) + (setq utd (1+ utd))) + + (if (eq (byte-recompile-file fsrc nil 0) t) + (setq comp (1+ comp)) + (setq utd (1+ utd))))))) + (oref obj source)) (message "All Emacs Lisp sources are up to date in %s" (object-name obj)) (cons comp utd))) @@ -185,8 +222,7 @@ is found, such as a `-version' variable, or the standard header." "Insert variables needed by target THIS." (let ((newitems (if (oref this aux-packages) (ede-proj-elisp-packages-to-loadpath - (oref this aux-packages)))) - ) + (oref this aux-packages))))) (ede-proj-makefile-insert-loadpath-items newitems))) (defun ede-proj-elisp-add-path (path) @@ -211,7 +247,8 @@ is found, such as a `-version' variable, or the standard header." "Tweak the configure file (current buffer) to accommodate THIS." (call-next-method) ;; Ok, now we have to tweak the autoconf provided `elisp-comp' program. - (let ((ec (ede-expand-filename this "elisp-comp" 'newfile))) + (let ((ec (ede-expand-filename this "elisp-comp" 'newfile)) + (enable-local-variables nil)) (if (or (not ec) (not (file-exists-p ec))) (message "No elisp-comp file. There may be compile errors? Rerun a second time.") (save-excursion @@ -235,7 +272,7 @@ is found, such as a `-version' variable, or the standard header." "Flush the configure file (current buffer) to accommodate THIS." ;; Remove crufty old paths from elisp-compile (let ((ec (ede-expand-filename this "elisp-comp" 'newfile)) - ) + (enable-local-variables nil)) (if (and ec (file-exists-p ec)) (with-current-buffer (find-file-noselect ec t) (goto-char (point-min)) @@ -251,8 +288,8 @@ is found, such as a `-version' variable, or the standard header." ;; (defclass ede-proj-target-elisp-autoloads (ede-proj-target-elisp) ((availablecompilers :initform '(ede-emacs-cedet-autogen-compiler)) - (aux-packages :initform ("cedet-autogen")) (phony :initform t) + (rules :initform nil) (autoload-file :initarg :autoload-file :initform "loaddefs.el" :type string @@ -287,15 +324,14 @@ Lays claim to all .elc files that match .el files in this target." (ede-compiler "ede-emacs-autogen-compiler" :name "emacs" - :variables '(("EMACS" . "emacs")) + :variables '(("EMACS" . "emacs") + ("EMACSFLAGS" . "-batch --no-site-file --eval '(setq debug-on-error t)'") + ("require" . "$(foreach r,$(1),(require (quote $(r))))")) :commands - '("@echo \"(add-to-list 'load-path nil)\" > $@-compile-script" - "for loadpath in . ${LOADPATH}; do \\" - " echo \"(add-to-list 'load-path \\\"$$loadpath\\\")\" >> $@-compile-script; \\" - "done;" - "@echo \"(require 'cedet-autogen)\" >> $@-compile-script" - "\"$(EMACS)\" -batch --no-site-file -l $@-compile-script -f cedet-batch-update-autoloads $(LOADDEFS) $(LOADDIRS)" - ) + '("$(EMACS) $(EMACSFLAGS) $(addprefix -L ,$(LOADPATH)) \ +--eval '(setq generated-autoload-file \"$(abspath $(LOADDEFS))\")' \ +-f batch-update-autoloads $(abspath $(LOADDIRS))") + :rules (list (ede-makefile-rule "clean-autoloads" :target "clean-autoloads" :phony t :rules '("rm -f $(LOADDEFS)"))) :sourcetype '(ede-source-emacs) ) "Build an autoloads file.") diff --git a/lisp/cedet/ede/proj.el b/lisp/cedet/ede/proj.el index a8afe9ec804..8d81b825565 100644 --- a/lisp/cedet/ede/proj.el +++ b/lisp/cedet/ede/proj.el @@ -53,6 +53,39 @@ (autoload 'ede-proj-target-makefile-info "ede/proj-info" "Target class for info files." nil nil) +(eieio-defclass-autoload 'ede-proj-target-aux '(ede-proj-target) + "ede/proj-aux" + "Target class for a group of lisp files.") +(eieio-defclass-autoload 'ede-proj-target-elisp '(ede-proj-target-makefile) + "ede/proj-elisp" + "Target class for a group of lisp files.") +(eieio-defclass-autoload 'ede-proj-target-elisp-autoloads '(ede-proj-target-elisp) + "ede/proj-elisp" + "Target class for generating autoload files.") +(eieio-defclass-autoload 'ede-proj-target-scheme '(ede-proj-target) + "ede/proj-scheme" + "Target class for a group of lisp files.") +(eieio-defclass-autoload 'ede-proj-target-makefile-miscelaneous '(ede-proj-target-makefile) + "ede/proj-misc" + "Target class for a group of miscellaneous w/ a special makefile.") +(eieio-defclass-autoload 'ede-proj-target-makefile-program '(ede-proj-target-makefile-objectcode) + "ede/proj-prog" + "Target class for building a program.") +(eieio-defclass-autoload 'ede-proj-target-makefile-archive '(ede-proj-target-makefile-objectcode) + "ede/proj-archive" + "Target class for building an archive of object code.") +(eieio-defclass-autoload 'ede-proj-target-makefile-shared-object '(ede-proj-target-makefile-program) + "ede/proj-shared" + "Target class for building a shared object.") +(eieio-defclass-autoload 'ede-proj-target-makefile-info '(ede-proj-target-makefile) + "ede/proj-info" + "Target class for info files.") + +;; Not in ede/ , but part of semantic. +(eieio-defclass-autoload 'semantic-ede-proj-target-grammar '(ede-proj-target-elisp) + "semantic/ede-grammar" + "Target classfor Semantic grammar files.") + ;;; Class Definitions: (defclass ede-proj-target (ede-target) ((auxsource :initarg :auxsource @@ -181,8 +214,10 @@ This enables the creation of your target type." (setq ede-proj-target-alist (cons (cons name class) ede-proj-target-alist))))) -(defclass ede-proj-project (ede-project) - ((makefile-type :initarg :makefile-type +(defclass ede-proj-project (eieio-persistent ede-project) + ((extension :initform ".ede") + (file-header-line :initform ";; EDE Project Files are auto generated: Do Not Edit") + (makefile-type :initarg :makefile-type :initform Makefile :type symbol :custom (choice (const Makefile) @@ -259,23 +294,16 @@ If optional ROOTPROJ is provided then ROOTPROJ is the root project for the tree being read in. If ROOTPROJ is nil, then assume that the PROJECT being read in is the root project." (save-excursion - (let ((ret nil) + (let ((ret (eieio-persistent-read (concat project "Project.ede") + ede-proj-project)) (subdirs (directory-files project nil "[^.].*" nil))) - (set-buffer (get-buffer-create " *tmp proj read*")) - (unwind-protect - (progn - (insert-file-contents (concat project "Project.ede") - nil nil nil t) - (goto-char (point-min)) - (setq ret (read (current-buffer))) - (if (not (eq (car ret) 'ede-proj-project)) - (error "Corrupt project file")) - (setq ret (eval ret)) - (oset ret file (concat project "Project.ede")) - (oset ret directory project) - (oset ret rootproject rootproj) - ) - (kill-buffer " *tmp proj read*")) + (if (not (object-of-class-p ret 'ede-proj-project)) + (error "Corrupt project file")) + (oset ret directory project) + (oset ret rootproject rootproj) + + ;; Load the project file of each subdirectory containing a + ;; loadable Project.ede. (while subdirs (let ((sd (file-name-as-directory (expand-file-name (car subdirs) project)))) @@ -291,22 +319,13 @@ the PROJECT being read in is the root project." "Write out object PROJECT into its file." (save-excursion (if (not project) (setq project (ede-current-project))) - (let ((b (set-buffer (get-buffer-create " *tmp proj write*"))) - (cfn (oref project file)) - (cdir (oref project directory))) + (let ((cdir (oref project directory))) (unwind-protect - (save-excursion - (erase-buffer) - (let ((standard-output (current-buffer))) - (oset project file (file-name-nondirectory cfn)) - (slot-makeunbound project :directory) - (object-write project ";; EDE project file.")) - (write-file cfn nil) - ) - ;; Restore the :file on exit. - (oset project file cfn) - (oset project directory cdir) - (kill-buffer b))))) + (progn + (slot-makeunbound project :directory) + (eieio-persistent-save project)) + ;; Restore the directory slot + (oset project directory cdir))) )) (defmethod ede-commit-local-variables ((proj ede-proj-project)) "Commit change to local variables in PROJ." @@ -670,6 +689,8 @@ Optional argument FORCE will force items to be regenerated." (let ((root (or (ede-project-root this) this)) ) (setq ede-projects (delq root ede-projects)) + ;; NOTE : parent function double-checks that this dir was + ;; already in memory once. (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 e951598ba55..5053701192e 100644 --- a/lisp/cedet/ede/project-am.el +++ b/lisp/cedet/ede/project-am.el @@ -205,7 +205,7 @@ OT is the object target. DIR is the directory to start in." (oref amf targets)) nil t)))) ;; The input target might be new. See if we can find it. - (amf (ede-load-project-file (oref ot path))) + (amf (ede-target-parent ot)) (ot (object-assoc target 'name (oref amf targets))) (ofn (file-name-nondirectory (buffer-file-name)))) (if (not ot) diff --git a/lisp/cedet/ede/util.el b/lisp/cedet/ede/util.el index 05688aa56ff..489c4d3dbf1 100644 --- a/lisp/cedet/ede/util.el +++ b/lisp/cedet/ede/util.el @@ -87,7 +87,7 @@ their sources to VERSION." If BUFFER isn't specified, use the current buffer." (save-excursion (if buffer (set-buffer buffer)) - (toggle-read-only -1))) + (setq buffer-read-only nil))) (provide 'ede/util) |