Mercurial > emacs
comparison lisp/cedet/ede/project-am.el @ 110526:b150a06c6999
Synch EDE to CEDET 1.0.
* cedet-idutils.el (cedet-idutils-make-command): New option.
(cedet-idutils-mkid-call):
(cedet-idutils-create/update-database): New functions.
* cedet-cscope.el (cedet-cscope-create):
(cedet-cscope-create/update-database): New functions.
(cedet-cscope-support-for-directory): Make interactive.
* cedet-global.el (cedet-global-gtags-command): New option.
(cedet-gnu-global-gtags-call)
(cedet-gnu-global-create/update-database): New functions.
* ede.el (ede-save-cache): Fix recentf-exclude expression.
(ede-make-dist): Always use toplevel project.
(ede-buffer-object): If we fail to find an object in the current
project, loop upward looking for a match. If no target is found,
use most local project.
(ede-buffer-belongs-to-target-p)
(ede-buffer-belongs-to-project-p): New functions.
(ede-initialize-state-current-buffer): New function.
(ede-target-forms-menu, ede-project-buffers): Use them.
(ede-minor-mode, ede-reset-all-buffers): Use it.
(project-interactive-select-target, project-add-file): Don't use
ede-project-force-load.
(ede-buffer-object): New arg PROJSYM.
(ede-minor-mode): Remove ede-directory-project-p test.
(ede-initialize-state-current-buffer): Don't test for
ede-directory-project-p if there is a matching open project.
(ede-customize-forms-menu): Prevent error if there is no project.
(ede-load-project-file): Set ede-constructing to the thing being
constructed, instead of t.
(ede-project-force-load): Deleted.
* ede/base.el:
* ede/auto.el:
* ede/custom.el: New files.
* ede/autoconf-edit.el (autoconf-find-last-macro)
(autoconf-parameters-for-macro): Parse multiline parameters of
macros. Optionally ignore case and at bol for macro.
(autoconf-parameter-strip): Use greedy match for newlines.
(autoconf-new-automake-string): Deleted.
(autoconf-new-program): Use SRecode to fill an empty file.
* ede/cpp-root.el (ede-create-lots-of-projects-under-dir): New
function.
* ede/files.el (ede-flush-project-hash): New command.
(ede-convert-path): Add optional PROJECT arg.
(ede-directory-project-p): Obey ".ede-ignore".
(ede-expand-filename-local)
(ede-expand-filename-impl-via-subproj): New methods.
(ede-expand-filename-impl): Use them.
(ede-project-root, ede-project-root-directory): Move to
ede/auto.el.
* ede/locate.el (ede-locate-flush-hash):
(ede-locate-create/update-root-database): New methods.
(initialize-instance): Use ede-locate-flush-hash.
* ede/pmake.el (ede-proj-makefile-insert-variables): If this is
the top project and not a metasubproject, set TOP to CURDIR.
(ede-proj-makefile-insert-variables): Output a target's object
list whether or not the vars are already in the Makefile.
(ede-pmake-insert-variable-once): New macro.
* ede/project-am.el (project-am-with-makefile-current): Add
recentf-exclude.
(project-am-load-makefile): Obey an optional suggested name.
(project-am-expand-subdirlist): New function.
(project-am-makefile::project-rescan): Use it. Combine SUBDIRS
and DIST_SUBDIRS.
(project-am-meta-type-alist): A list to scan better Makefile.am
(project-am-scan-for-targets): Scan also over
project-am-meta-type-alist.
(ede-system-include-path): Simple implementation.
(ede-find-target): Deleted. EDE core takes care of this.
(ede-buffer-mine): Create the searched filename as relative.
(project-am-load): Simplify, using autoconf-edit.
(project-am-extract-package-info): Fix separators.
* ede/proj.el (project-run-target): New method.
(project-make-dist, project-compile-project): Use
ede-proj-automake-p to determine which kind of compile to use.
(project-rescan): Call ede-load-project-file.
(ede-buffer-mine): Add more file names that belong to the project.
(ede-proj-compilers): Improve error message.
* ede/proj-obj.el (ede-ld-linker): Use the LDDEPS variable.
(ede-source-c++): Add more C++ extensions.
(ede-proj-target-makefile-objectcode): Quote initforms. Support
lex and yacc.
* ede/proj-prog.el (ede-proj-makefile-insert-rules): Removed.
(ede-proj-makefile-insert-variables): New, add LDDEPS.
(ede-proj-makefile-insert-automake-post-variables): Add LDADD
variable. Use ldlibs-local slot. Add a -l to ldlibs strings.
(ede-proj-target-makefile-program): Swap order of two slots so
they show up in the same order as in the command line.
(ede-proj-target-makefile-program): Add ldlibs-local slot.
* ede/proj-shared.el (ede-g++-libtool-shared-compiler): Fix
inference rule to use cpp files.
(ede-proj-target-makefile-shared-object): Quote initforms.
* ede/proj-misc.el (ede-proj-target-makefile-miscelaneous):
* ede/proj-info.el (ede-proj-target-makefile-info):
* ede/proj-aux.el (ede-proj-target-aux):
* ede/proj-archive.el (ede-proj-target-makefile-archive):
* ede/proj-elisp.el (ede-proj-target-elisp)
(ede-proj-target-elisp-autoloads): Quote initforms.
* ede/srecode.el (ede-srecode-setup): Load autoconf templates.
* ede/shell.el (ede-shell-buffer): Fix buffer name.
* ede/pconf.el (ede-proj-configure-synchronize): If user events
occur while waiting for the compile process to finish, pull them
in and discard those events.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Mon, 20 Sep 2010 22:42:53 -0400 |
parents | 1d1d5d9bd884 |
children | b799d38f522a 376148b31b5e |
comparison
equal
deleted
inserted
replaced
110525:e950143ab9e0 | 110526:b150a06c6999 |
---|---|
28 ;; good project management system. It provides a simple and concise | 28 ;; good project management system. It provides a simple and concise |
29 ;; look at what is actually in a project, and records it in a simple | 29 ;; look at what is actually in a project, and records it in a simple |
30 ;; fashion. | 30 ;; fashion. |
31 ;; | 31 ;; |
32 ;; project-am uses the structure defined in all good GNU projects with | 32 ;; project-am uses the structure defined in all good GNU projects with |
33 ;; the Automake file as it's base template, and then maintains that | 33 ;; the Automake file as its base template, and then maintains that |
34 ;; information during edits, automatically updating the automake file | 34 ;; information during edits, automatically updating the automake file |
35 ;; where appropriate. | 35 ;; where appropriate. |
36 | |
37 | |
38 ;; (eval-and-compile | |
39 ;; ;; Compatibility for makefile mode. | |
40 ;; (condition-case nil | |
41 ;; (require 'makefile "make-mode") | |
42 ;; (error (require 'make-mode "make-mode"))) | |
43 | |
44 ;; ;; Requiring the .el files prevents incomplete builds. | |
45 ;; (require 'eieio "eieio.el") | |
46 ;; (require 'ede "ede.el")) | |
47 | 36 |
48 (require 'make-mode) | 37 (require 'make-mode) |
49 (require 'ede) | 38 (require 'ede) |
50 (require 'ede/make) | 39 (require 'ede/make) |
51 (require 'ede/makefile-edit) | 40 (require 'ede/makefile-edit) |
41 (require 'semantic/find) ;; for semantic-find-tags-by-... | |
42 (require 'ede/autoconf-edit) | |
52 | 43 |
53 (declare-function autoconf-parameters-for-macro "ede/autoconf-edit") | 44 (declare-function autoconf-parameters-for-macro "ede/autoconf-edit") |
45 (declare-function ede-shell-run-something "ede/shell") | |
54 (eval-when-compile (require 'compile)) | 46 (eval-when-compile (require 'compile)) |
55 | 47 |
56 ;;; Code: | 48 ;;; Code: |
57 (defgroup project-am nil | 49 (defgroup project-am nil |
58 "File and tag browser frame." | 50 "File and tag browser frame." |
102 ("extradist" project-am-extra-dist "EXTRA_DIST") | 94 ("extradist" project-am-extra-dist "EXTRA_DIST") |
103 ;; Custom libraries targets? | 95 ;; Custom libraries targets? |
104 ;; ("ltlibcustom" project-am-lib ".*?_LTLIBRARIES" t) | 96 ;; ("ltlibcustom" project-am-lib ".*?_LTLIBRARIES" t) |
105 ) | 97 ) |
106 "Alist of type names and the type of object to create for them. | 98 "Alist of type names and the type of object to create for them. |
107 Each entry is of th form: | 99 Each entry is of the form: |
108 (EMACSNAME CLASS AUTOMAKEVAR INDIRECT) | 100 (EMACSNAME CLASS AUTOMAKEVAR INDIRECT) |
109 where EMACSNAME is a name for Emacs to use. | 101 where EMACSNAME is a name for Emacs to use. |
110 CLASS is the EDE target class to represent the target. | 102 CLASS is the EDE target class to represent the target. |
111 AUTOMAKEVAR is the Automake variable to identify. This cannot be a | 103 AUTOMAKEVAR is the Automake variable to identify. This cannot be a |
112 regular expression. | 104 regular expression. |
113 INDIRECT is optional. If it is non-nil, then the variable in | 105 INDIRECT is optional. If it is non-nil, then the variable in |
114 question lists other variables that need to be looked up.") | 106 question lists other variables that need to be looked up.") |
107 | |
108 | |
109 (defconst project-am-meta-type-alist | |
110 '((project-am-program "_PROGRAMS$" t) | |
111 (project-am-lib "_\\(LIBS\\|LIBRARIES\\|LTLIBRARIES\\)$" t) | |
112 | |
113 ;; direct primary target use a dummy object (man target) | |
114 ;; update to: * 3.3 Uniform in automake-1.11 info node. | |
115 (project-am-man "_\\(DATA\\|HEADERS\\|PYTHON\\|JAVA\\|SCRIPTS\\|MANS\\|TEXINFOS\\)$" nil) | |
116 ) | |
117 "Alist of meta-target type, each entry has form: | |
118 (CLASS REGEXPVAR INDIRECT) | |
119 where CLASS is the EDE target class for target. | |
120 REGEXPVAR is the regexp used in `semantic-find-tags-by-name-regexp'. | |
121 INDIRECT is optional. If it is non-nil, then the variable in it have | |
122 other meta-variable based on this name.") | |
123 | |
115 | 124 |
116 (defclass project-am-target (ede-target) | 125 (defclass project-am-target (ede-target) |
117 nil | 126 nil |
118 "Base target class for everything in project-am.") | 127 "Base target class for everything in project-am.") |
119 | 128 |
289 (insert " " (ede-target-name ot)) | 298 (insert " " (ede-target-name ot)) |
290 (save-buffer) | 299 (save-buffer) |
291 ;; Rescan the object in this makefile. | 300 ;; Rescan the object in this makefile. |
292 (project-rescan ede-object)))) | 301 (project-rescan ede-object)))) |
293 | 302 |
294 ;(defun project-am-rescan-toplevel () | |
295 ; "Rescan all projects in which the current buffer resides." | |
296 ; (interactive) | |
297 ; (let* ((tlof (project-am-find-topmost-level default-directory)) | |
298 ; (tlo (project-am-load tlof)) | |
299 ; (ede-deep-rescan t)) ; scan deep in this case. | |
300 ; ;; tlo is the top level object for whatever file we are in | |
301 ; ;; or nil. If we have an object, call the rescan method. | |
302 ; (if tlo (project-am-rescan tlo)))) | |
303 | |
304 ;; | 303 ;; |
305 ;; NOTE TO SELF | 304 ;; NOTE TO SELF |
306 ;; | 305 ;; |
307 ;; This should be handled at the EDE level, calling a method of the | 306 ;; This should be handled at the EDE level, calling a method of the |
308 ;; top most project. | 307 ;; top most project. |
402 (funcall project-am-debug-target-function cmd)) | 401 (funcall project-am-debug-target-function cmd)) |
403 (kill-buffer tb)))) | 402 (kill-buffer tb)))) |
404 | 403 |
405 (defmethod project-run-target ((obj project-am-objectcode)) | 404 (defmethod project-run-target ((obj project-am-objectcode)) |
406 "Run the current project target in comint buffer." | 405 "Run the current project target in comint buffer." |
406 (require 'ede/shell) | |
407 (let ((tb (get-buffer-create " *padt*")) | 407 (let ((tb (get-buffer-create " *padt*")) |
408 (dd (oref obj path)) | 408 (dd (oref obj path)) |
409 (cmd nil)) | 409 (cmd nil)) |
410 (unwind-protect | 410 (unwind-protect |
411 (progn | 411 (progn |
425 (project-compile-project this (concat project-am-compile-project-command | 425 (project-compile-project this (concat project-am-compile-project-command |
426 " dist"))) | 426 " dist"))) |
427 | 427 |
428 ;;; Project loading and saving | 428 ;;; Project loading and saving |
429 ;; | 429 ;; |
430 (defun project-am-load (project &optional rootproj) | 430 (defun project-am-load (directory &optional rootproj) |
431 "Read an automakefile PROJECT into our data structure. | 431 "Read an automakefile DIRECTORY into our data structure. |
432 Make sure that the tree down to our makefile is complete so that there | |
433 is cohesion in the project. Return the project file (or sub-project). | |
434 If a given set of projects has already been loaded, then do nothing | 432 If a given set of projects has already been loaded, then do nothing |
435 but return the project for the directory given. | 433 but return the project for the directory given. |
436 Optional ROOTPROJ is the root EDE project." | 434 Optional ROOTPROJ is the root EDE project." |
437 ;; @TODO - rationalize this to the newer EDE way of doing things. | 435 (let* ((ede-constructiong t) |
438 (setq project (expand-file-name project)) | 436 (amo (object-assoc (expand-file-name "Makefile.am" directory) |
439 (let* ((ede-constructing t) | 437 'file ede-projects))) |
440 (fn (project-am-find-topmost-level (file-name-as-directory project))) | 438 (when (not amo) |
441 (amo nil) | 439 (setq amo (project-am-load-makefile directory))) |
442 (trimmed (if (string-match (regexp-quote fn) | 440 amo)) |
443 project) | |
444 (replace-match "" t t project) | |
445 "")) | |
446 (subdir nil)) | |
447 (setq amo (object-assoc (expand-file-name "Makefile.am" fn) | |
448 'file ede-projects)) | |
449 (if amo | |
450 (error "Synchronous error in ede/project-am objects") | |
451 (let ((project-am-constructing t)) | |
452 (setq amo (project-am-load-makefile fn)))) | |
453 (if (not amo) | |
454 nil | |
455 ;; Now scan down from amo, and find the current directory | |
456 ;; from the PROJECT file. | |
457 (while (< 0 (length trimmed)) | |
458 (if (string-match "\\([a-zA-Z0-9.-]+\\)/" trimmed) | |
459 (setq subdir (match-string 0 trimmed) | |
460 trimmed (replace-match "" t t trimmed)) | |
461 (error "Error scanning down path for project")) | |
462 (setq amo (project-am-subtree | |
463 amo | |
464 (expand-file-name "Makefile.am" | |
465 (expand-file-name subdir fn))) | |
466 fn (expand-file-name subdir fn))) | |
467 amo) | |
468 )) | |
469 | 441 |
470 (defun project-am-find-topmost-level (dir) | 442 (defun project-am-find-topmost-level (dir) |
471 "Find the topmost automakefile starting with DIR." | 443 "Find the topmost automakefile starting with DIR." |
472 (let ((newdir dir)) | 444 (let ((newdir dir)) |
473 (while (or (file-exists-p (concat newdir "Makefile.am")) | 445 (while (or (file-exists-p (concat newdir "Makefile.am")) |
484 Kill the makefile if it was not loaded before the load." | 456 Kill the makefile if it was not loaded before the load." |
485 `(let* ((fn (expand-file-name "Makefile.am" ,dir)) | 457 `(let* ((fn (expand-file-name "Makefile.am" ,dir)) |
486 (fb nil) | 458 (fb nil) |
487 (kb (get-file-buffer fn))) | 459 (kb (get-file-buffer fn))) |
488 (if (not (file-exists-p fn)) | 460 (if (not (file-exists-p fn)) |
489 nil | 461 nil |
490 (save-excursion | 462 (save-excursion |
491 (if kb (setq fb kb) | 463 (if kb (setq fb kb) |
492 ;; We need to find-file this thing, but don't use | 464 ;; We need to find-file this thing, but don't use |
493 ;; any semantic features. | 465 ;; any semantic features. |
494 (let ((semantic-init-hook nil)) | 466 (let ((semantic-init-hook nil) |
495 (setq fb (find-file-noselect fn))) | 467 (recentf-exclude '( (lambda (f) t) )) |
496 ) | 468 ) |
497 (set-buffer fb) | 469 (setq fb (find-file-noselect fn))) |
498 (prog1 ,@forms | 470 ) |
499 (if (not kb) (kill-buffer (current-buffer)))))))) | 471 (set-buffer fb) |
472 (prog1 ,@forms | |
473 (if (not kb) (kill-buffer (current-buffer)))))))) | |
500 (put 'project-am-with-makefile-current 'lisp-indent-function 1) | 474 (put 'project-am-with-makefile-current 'lisp-indent-function 1) |
501 | 475 |
502 (add-hook 'edebug-setup-hook | 476 (add-hook 'edebug-setup-hook |
503 (lambda () | 477 (lambda () |
504 (def-edebug-spec project-am-with-makefile-current | 478 (def-edebug-spec project-am-with-makefile-current |
505 (form def-body)))) | 479 (form def-body)))) |
506 | 480 |
507 | 481 |
508 (defun project-am-load-makefile (path) | 482 (defun project-am-load-makefile (path &optional suggestedname) |
509 "Convert PATH into a project Makefile, and return its project object. | 483 "Convert PATH into a project Makefile, and return its project object. |
510 It does not check for existing project objects. Use `project-am-load'." | 484 It does not check for existing project objects. Use `project-am-load'. |
485 Optional argument SUGGESTEDNAME will be the project name. | |
486 This is used when subprojects are made in named subdirectories." | |
511 (project-am-with-makefile-current path | 487 (project-am-with-makefile-current path |
512 (if (and ede-object (project-am-makefile-p ede-object)) | 488 (if (and ede-object (project-am-makefile-p ede-object)) |
513 ede-object | 489 ede-object |
514 (let* ((pi (project-am-package-info path)) | 490 (let* ((pi (project-am-package-info path)) |
515 (pn (or (nth 0 pi) (project-am-last-dir fn))) | 491 (sfn (when suggestedname |
492 (project-am-last-dir suggestedname))) | |
493 (pn (or sfn (nth 0 pi) (project-am-last-dir fn))) | |
516 (ver (or (nth 1 pi) "0.0")) | 494 (ver (or (nth 1 pi) "0.0")) |
517 (bug (nth 2 pi)) | 495 (bug (nth 2 pi)) |
518 (cof (nth 3 pi)) | 496 (cof (nth 3 pi)) |
519 (ampf (project-am-makefile | 497 (ampf (project-am-makefile |
520 pn :name pn | 498 pn :name pn |
528 ;; Move the rescan after we set ede-object to prevent recursion | 506 ;; Move the rescan after we set ede-object to prevent recursion |
529 (project-rescan ampf) | 507 (project-rescan ampf) |
530 ampf)))) | 508 ampf)))) |
531 | 509 |
532 ;;; Methods: | 510 ;;; Methods: |
533 (defmethod ede-find-target ((amf project-am-makefile) buffer) | |
534 "Fetch the target belonging to BUFFER." | |
535 (or (call-next-method) | |
536 (let ((targ (oref amf targets)) | |
537 (sobj (oref amf subproj)) | |
538 (obj nil)) | |
539 (while (and targ (not obj)) | |
540 (if (ede-buffer-mine (car targ) buffer) | |
541 (setq obj (car targ))) | |
542 (setq targ (cdr targ))) | |
543 (while (and sobj (not obj)) | |
544 (setq obj (project-am-buffer-object (car sobj) buffer) | |
545 sobj (cdr sobj))) | |
546 obj))) | |
547 | |
548 (defmethod project-targets-for-file ((proj project-am-makefile)) | 511 (defmethod project-targets-for-file ((proj project-am-makefile)) |
549 "Return a list of targets the project PROJ." | 512 "Return a list of targets the project PROJ." |
550 (oref proj targets)) | 513 (oref proj targets)) |
551 | 514 |
552 (defun project-am-scan-for-targets (currproj dir) | 515 (defun project-am-scan-for-targets (currproj dir) |
553 "Scan the current Makefile.am for targets. | 516 "Scan the current Makefile.am for targets. |
554 CURRPROJ is the current project being scanned. | 517 CURRPROJ is the current project being scanned. |
555 DIR is the directory to apply to new targets." | 518 DIR is the directory to apply to new targets." |
556 (let* ((otargets (oref currproj targets)) | 519 (let* ((otargets (oref currproj targets)) |
520 ;; `ntargets' results in complete targets list | |
521 ;; not only the new targets by diffing. | |
557 (ntargets nil) | 522 (ntargets nil) |
558 (tmp nil) | 523 (tmp nil) |
559 ) | 524 ) |
560 (mapc | 525 |
561 ;; Map all the different types | 526 (mapc |
562 (lambda (typecar) | 527 ;; Map all the different types |
563 (let ((macro (nth 2 typecar)) | 528 (lambda (typecar) |
564 (class (nth 1 typecar)) | 529 (let ((macro (nth 2 typecar)) |
565 (indirect (nth 3 typecar)) | 530 (class (nth 1 typecar)) |
566 ;(name (car typecar)) | 531 (indirect (nth 3 typecar)) |
567 ) | 532 ) |
568 (if indirect | 533 (if indirect |
569 ;; Map all the found objects | 534 ;; Map all the found objects |
570 (mapc (lambda (lstcar) | 535 (mapc (lambda (lstcar) |
571 (setq tmp (object-assoc lstcar 'name otargets)) | 536 (setq tmp (object-assoc lstcar 'name otargets)) |
572 (when (not tmp) | 537 (when (not tmp) |
573 (setq tmp (apply class lstcar :name lstcar | 538 (setq tmp (apply class lstcar :name lstcar |
574 :path dir nil))) | 539 :path dir nil))) |
575 (project-rescan tmp) | 540 (project-rescan tmp) |
576 (setq ntargets (cons tmp ntargets))) | 541 (setq ntargets (cons tmp ntargets))) |
577 (makefile-macro-file-list macro)) | 542 (makefile-macro-file-list macro)) |
578 ;; Non-indirect will have a target whos sources | 543 ;; Non-indirect will have a target whos sources |
579 ;; are actual files, not names of other targets. | 544 ;; are actual files, not names of other targets. |
580 (let ((files (makefile-macro-file-list macro))) | 545 (let ((files (makefile-macro-file-list macro))) |
581 (when files | 546 (when files |
582 (setq tmp (object-assoc macro 'name otargets)) | 547 (setq tmp (object-assoc macro 'name otargets)) |
583 (when (not tmp) | 548 (when (not tmp) |
584 (setq tmp (apply class macro :name macro | 549 (setq tmp (apply class macro :name macro |
550 :path dir nil))) | |
551 (project-rescan tmp) | |
552 (setq ntargets (cons tmp ntargets)) | |
553 )) | |
554 ) | |
555 )) | |
556 project-am-type-alist) | |
557 | |
558 ;; At now check variables for meta-target regexp | |
559 ;; We have to check ntargets to avoid useless rescan. | |
560 ;; Also we have check otargets to prevent duplication. | |
561 (mapc | |
562 (lambda (typecar) | |
563 (let ((class (nth 0 typecar)) | |
564 (metaregex (nth 1 typecar)) | |
565 (indirect (nth 2 typecar))) | |
566 (if indirect | |
567 ;; Map all the found objects | |
568 (mapc | |
569 (lambda (lstcar) | |
570 (unless (object-assoc lstcar 'name ntargets) | |
571 (or | |
572 (setq tmp (object-assoc lstcar 'name otargets)) | |
573 (setq tmp (apply class lstcar :name lstcar | |
585 :path dir nil))) | 574 :path dir nil))) |
586 (project-rescan tmp) | 575 (project-rescan tmp) |
587 (setq ntargets (cons tmp ntargets)) | 576 (setq ntargets (cons tmp ntargets)))) |
588 )) | 577 ;; build a target list to map over |
589 ) | 578 (let (atargets) |
590 )) | 579 (dolist (TAG |
591 project-am-type-alist) | 580 (semantic-find-tags-by-name-regexp |
592 ntargets)) | 581 metaregex (semantic-find-tags-by-class |
593 | 582 'variable (semantic-fetch-tags)))) |
594 (defmethod project-rescan ((this project-am-makefile)) | 583 ;; default-value have to be a list |
584 (when (cadr (assoc ':default-value TAG)) | |
585 (setq atargets | |
586 (append | |
587 (nreverse (cadr (assoc ':default-value TAG))) | |
588 atargets)))) | |
589 (nreverse atargets))) | |
590 | |
591 ;; else not indirect, TODO: FIX various direct meta type in a sane way. | |
592 (dolist (T (semantic-find-tags-by-name-regexp | |
593 metaregex (semantic-find-tags-by-class | |
594 'variable (semantic-fetch-tags)))) | |
595 (unless (setq tmp (object-assoc (car T) 'name ntargets)) | |
596 (or (setq tmp (object-assoc (car T) 'name otargets)) | |
597 ;; we are really new | |
598 (setq tmp (apply class (car T) :name (car T) | |
599 :path dir nil))) | |
600 (project-rescan tmp) | |
601 (setq ntargets (cons tmp ntargets)))) | |
602 ))) | |
603 project-am-meta-type-alist) | |
604 ntargets)) | |
605 | |
606 (defun project-am-expand-subdirlist (place subdirs) | |
607 "Store in PLACE the SUBDIRS expanded from variables. | |
608 Strip out duplicates, and recurse on variables." | |
609 (mapc (lambda (sp) | |
610 (let ((var (makefile-extract-varname-from-text sp))) | |
611 (if var | |
612 ;; If it is a variable, expand that variable, and keep going. | |
613 (project-am-expand-subdirlist | |
614 place (makefile-macro-file-list var)) | |
615 ;; Else, add SP in if it isn't a dup. | |
616 (if (member sp (symbol-value place)) | |
617 nil ; don't do it twice. | |
618 (set place (cons sp (symbol-value place))) ;; add | |
619 )))) | |
620 subdirs) | |
621 ) | |
622 | |
623 (defmethod project-rescan ((this project-am-makefile) &optional suggestedname) | |
595 "Rescan the makefile for all targets and sub targets." | 624 "Rescan the makefile for all targets and sub targets." |
596 (project-am-with-makefile-current (file-name-directory (oref this file)) | 625 (project-am-with-makefile-current (file-name-directory (oref this file)) |
597 ;;(message "Scanning %s..." (oref this file)) | 626 ;;(message "Scanning %s..." (oref this file)) |
598 (let* ((pi (project-am-package-info (oref this directory))) | 627 (let* ((pi (project-am-package-info (oref this directory))) |
599 (pn (nth 0 pi)) | 628 (pn (nth 0 pi)) |
600 (pv (nth 1 pi)) | 629 (pv (nth 1 pi)) |
601 (bug (nth 2 pi)) | 630 (bug (nth 2 pi)) |
602 (cof (nth 3 pi)) | 631 (cof (nth 3 pi)) |
603 (osubproj (oref this subproj)) | 632 (osubproj (oref this subproj)) |
604 (csubproj (or | 633 ;; 1/30/10 - We need to append these two lists together, |
605 ;; If DIST_SUBDIRS doesn't exist, then go for the | 634 ;; then strip out duplicates. Expanding this list (via |
606 ;; static list of SUBDIRS. The DIST version should | 635 ;; references to other variables should also strip out dups |
607 ;; contain SUBDIRS plus extra stuff. | 636 (csubproj (append |
608 (makefile-macro-file-list "DIST_SUBDIRS") | 637 (makefile-macro-file-list "DIST_SUBDIRS") |
609 (makefile-macro-file-list "SUBDIRS"))) | 638 (makefile-macro-file-list "SUBDIRS"))) |
610 (csubprojexpanded nil) | 639 (csubprojexpanded nil) |
611 (nsubproj nil) | 640 (nsubproj nil) |
612 ;; Targets are excluded here because they require | 641 ;; Targets are excluded here because they require |
613 ;; special attention. | 642 ;; special attention. |
614 (dir (expand-file-name default-directory)) | 643 (dir (expand-file-name default-directory)) |
615 (tmp nil) | 644 (tmp nil) |
616 (ntargets (project-am-scan-for-targets this dir)) | 645 (ntargets (project-am-scan-for-targets this dir)) |
617 ) | 646 ) |
618 | 647 (if suggestedname |
619 (and pn (string= (directory-file-name | 648 (oset this name (project-am-last-dir suggestedname)) |
620 (oref this directory)) | 649 ;; Else, setup toplevel project info. |
621 (directory-file-name | 650 (and pn (string= (directory-file-name |
622 (project-am-find-topmost-level | 651 (oref this directory)) |
623 (oref this directory)))) | 652 (directory-file-name |
624 (oset this name pn) | 653 (project-am-find-topmost-level |
625 (and pv (oset this version pv)) | 654 (oref this directory)))) |
626 (and bug (oset this mailinglist bug)) | 655 (oset this name pn) |
627 (oset this configureoutputfiles cof)) | 656 (and pv (oset this version pv)) |
628 | 657 (and bug (oset this mailinglist bug)) |
629 ; ;; LISP is different. Here there is only one kind of lisp (that I know of | 658 (oset this configureoutputfiles cof))) |
630 ; ;; anyway) so it doesn't get mapped when it is found. | |
631 ; (if (makefile-move-to-macro "lisp_LISP") | |
632 ; (let ((tmp (project-am-lisp "lisp" | |
633 ; :name "lisp" | |
634 ; :path dir))) | |
635 ; (project-rescan tmp) | |
636 ; (setq ntargets (cons tmp ntargets)))) | |
637 ; | |
638 ;; Now that we have this new list, chuck the old targets | 659 ;; Now that we have this new list, chuck the old targets |
639 ;; and replace it with the new list of targets I just created. | 660 ;; and replace it with the new list of targets I just created. |
640 (oset this targets (nreverse ntargets)) | 661 (oset this targets (nreverse ntargets)) |
641 ;; We still have a list of targets. For all buffers, make sure | 662 ;; We still have a list of targets. For all buffers, make sure |
642 ;; their object still exists! | 663 ;; their object still exists! |
643 | |
644 ;; FIGURE THIS OUT | 664 ;; FIGURE THIS OUT |
645 | 665 (project-am-expand-subdirlist 'csubprojexpanded csubproj) |
646 (mapc (lambda (sp) | |
647 (let ((var (makefile-extract-varname-from-text sp)) | |
648 ) | |
649 (if (not var) | |
650 (setq csubprojexpanded (cons sp csubprojexpanded)) | |
651 ;; If it is a variable, expand that variable, and keep going. | |
652 (let ((varexp (makefile-macro-file-list var))) | |
653 (dolist (V varexp) | |
654 (setq csubprojexpanded (cons V csubprojexpanded))))) | |
655 )) | |
656 csubproj) | |
657 | |
658 ;; Ok, now lets look at all our sub-projects. | 666 ;; Ok, now lets look at all our sub-projects. |
659 (mapc (lambda (sp) | 667 (mapc (lambda (sp) |
660 (let* ((subdir (file-name-as-directory | 668 (let* ((subdir (file-name-as-directory |
661 (expand-file-name | 669 (expand-file-name |
662 sp (file-name-directory (oref this :file))))) | 670 sp (file-name-directory (oref this :file))))) |
663 (submake (expand-file-name | 671 (submake (expand-file-name |
664 "Makefile.am" | 672 "Makefile.am" |
665 subdir))) | 673 subdir))) |
666 (if (string= submake (oref this :file)) | 674 (if (string= submake (oref this :file)) |
667 nil ;; don't recurse.. please! | 675 nil ;; don't recurse.. please! |
668 | 676 ;; For each project id found, see if we need to recycle, |
669 ;; For each project id found, see if we need to recycle, | 677 ;; and if we do not, then make a new one. Check the deep |
670 ;; and if we do not, then make a new one. Check the deep | 678 ;; rescan value for behavior patterns. |
671 ;; rescan value for behavior patterns. | 679 (setq tmp (object-assoc |
672 (setq tmp (object-assoc | 680 submake |
673 submake | 681 'file osubproj)) |
674 'file osubproj)) | 682 (if (not tmp) |
675 (if (not tmp) | 683 (setq tmp |
676 (setq tmp | 684 (condition-case nil |
677 (condition-case nil | 685 ;; In case of problem, ignore it. |
678 ;; In case of problem, ignore it. | 686 (project-am-load-makefile subdir subdir) |
679 (project-am-load-makefile subdir) | 687 (error nil))) |
680 (error nil))) | 688 ;; If we have tmp, then rescan it only if deep mode. |
681 ;; If we have tmp, then rescan it only if deep mode. | 689 (if ede-deep-rescan |
682 (if ede-deep-rescan | 690 (project-rescan tmp subdir))) |
683 (project-rescan tmp))) | 691 ;; Tac tmp onto our list of things to keep, but only |
684 ;; Tac tmp onto our list of things to keep, but only | 692 ;; if tmp was found. |
685 ;; if tmp was found. | 693 (when tmp |
686 (when tmp | 694 ;;(message "Adding %S" (object-print tmp)) |
687 ;;(message "Adding %S" (object-print tmp)) | 695 (setq nsubproj (cons tmp nsubproj))))) |
688 (setq nsubproj (cons tmp nsubproj))))) | 696 ) |
689 ) | 697 (nreverse csubprojexpanded)) |
690 (nreverse csubprojexpanded)) | |
691 (oset this subproj nsubproj) | 698 (oset this subproj nsubproj) |
692 ;; All elements should be updated now. | 699 ;; All elements should be updated now. |
693 ))) | 700 ))) |
694 | 701 |
695 | 702 |
696 (defmethod project-rescan ((this project-am-program)) | 703 (defmethod project-rescan ((this project-am-program)) |
697 "Rescan object THIS." | 704 "Rescan object THIS." |
698 (oset this :source (makefile-macro-file-list (project-am-macro this))) | 705 (oset this :source (makefile-macro-file-list (project-am-macro this))) |
706 (unless (oref this :source) | |
707 (oset this :source (list (concat (oref this :name) ".c")))) | |
699 (oset this :ldadd (makefile-macro-file-list | 708 (oset this :ldadd (makefile-macro-file-list |
700 (concat (oref this :name) "_LDADD")))) | 709 (concat (oref this :name) "_LDADD")))) |
701 | 710 |
702 (defmethod project-rescan ((this project-am-lib)) | 711 (defmethod project-rescan ((this project-am-lib)) |
703 "Rescan object THIS." | 712 "Rescan object THIS." |
704 (oset this :source (makefile-macro-file-list (project-am-macro this)))) | 713 (oset this :source (makefile-macro-file-list (project-am-macro this))) |
714 (unless (oref this :source) | |
715 (oset this :source (list (concat (file-name-sans-extension (oref this :name)) ".c"))))) | |
705 | 716 |
706 (defmethod project-rescan ((this project-am-texinfo)) | 717 (defmethod project-rescan ((this project-am-texinfo)) |
707 "Rescan object THIS." | 718 "Rescan object THIS." |
708 (oset this :include (makefile-macro-file-list (project-am-macro this)))) | 719 (oset this :include (makefile-macro-file-list (project-am-macro this)))) |
709 | 720 |
724 (oset this :source (makefile-macro-file-list "BUILT_SOURCES"))) | 735 (oset this :source (makefile-macro-file-list "BUILT_SOURCES"))) |
725 | 736 |
726 (defmethod project-rescan ((this project-am-extra-dist)) | 737 (defmethod project-rescan ((this project-am-extra-dist)) |
727 "Rescan object THIS." | 738 "Rescan object THIS." |
728 (oset this :source (makefile-macro-file-list "EXTRA_DIST"))) | 739 (oset this :source (makefile-macro-file-list "EXTRA_DIST"))) |
729 ;; NOTE: The below calls 'file' then checks that it is some sort of | |
730 ;; text file. The file command may not be available on all platforms | |
731 ;; and some files may not exist yet. (ie - auto-generated) | |
732 | |
733 ;;(mapc | |
734 ;; (lambda (f) | |
735 ;; ;; prevent garbage to be parsed, could we use :aux ? | |
736 ;; (if (and (not (member f (oref this :source))) | |
737 ;; (string-match-p "ASCII\\|text" | |
738 ;; (shell-command-to-string | |
739 ;; (concat "file " f)))) | |
740 ;; (oset this :source (cons f (oref this :source))))) | |
741 ;; (makefile-macro-file-list "EXTRA_DIST"))) | |
742 | 740 |
743 (defmethod project-am-macro ((this project-am-objectcode)) | 741 (defmethod project-am-macro ((this project-am-objectcode)) |
744 "Return the default macro to 'edit' for this object type." | 742 "Return the default macro to 'edit' for this object type." |
745 (concat (subst-char-in-string ?- ?_ (oref this :name)) "_SOURCES")) | 743 (concat (subst-char-in-string ?- ?_ (oref this :name)) "_SOURCES")) |
746 | 744 |
806 ans) | 804 ans) |
807 ))) | 805 ))) |
808 | 806 |
809 (defmethod ede-buffer-mine ((this project-am-objectcode) buffer) | 807 (defmethod ede-buffer-mine ((this project-am-objectcode) buffer) |
810 "Return t if object THIS lays claim to the file in BUFFER." | 808 "Return t if object THIS lays claim to the file in BUFFER." |
811 (member (file-name-nondirectory (buffer-file-name buffer)) | 809 (member (file-relative-name (buffer-file-name buffer) (oref this :path)) |
812 (oref this :source))) | 810 (oref this :source))) |
813 | 811 |
814 (defmethod ede-buffer-mine ((this project-am-texinfo) buffer) | 812 (defmethod ede-buffer-mine ((this project-am-texinfo) buffer) |
815 "Return t if object THIS lays claim to the file in BUFFER." | 813 "Return t if object THIS lays claim to the file in BUFFER." |
816 (let ((bfn (buffer-file-name buffer))) | 814 (let ((bfn (file-relative-name (buffer-file-name buffer) |
817 (or (string= (oref this :name) (file-name-nondirectory bfn)) | 815 (oref this :path)))) |
818 (member (file-name-nondirectory bfn) (oref this :include))))) | 816 (or (string= (oref this :name) bfn) |
817 (member bfn (oref this :include))))) | |
819 | 818 |
820 (defmethod ede-buffer-mine ((this project-am-man) buffer) | 819 (defmethod ede-buffer-mine ((this project-am-man) buffer) |
821 "Return t if object THIS lays claim to the file in BUFFER." | 820 "Return t if object THIS lays claim to the file in BUFFER." |
822 (string= (oref this :name) (buffer-file-name buffer))) | 821 (string= (oref this :name) |
822 (file-relative-name (buffer-file-name buffer) (oref this :path)))) | |
823 | 823 |
824 (defmethod ede-buffer-mine ((this project-am-lisp) buffer) | 824 (defmethod ede-buffer-mine ((this project-am-lisp) buffer) |
825 "Return t if object THIS lays claim to the file in BUFFER." | 825 "Return t if object THIS lays claim to the file in BUFFER." |
826 (member (file-name-nondirectory (buffer-file-name buffer)) | 826 (member (file-relative-name (buffer-file-name buffer) (oref this :path)) |
827 (oref this :source))) | 827 (oref this :source))) |
828 | 828 |
829 (defmethod project-am-subtree ((ampf project-am-makefile) subdir) | 829 (defmethod project-am-subtree ((ampf project-am-makefile) subdir) |
830 "Return the sub project in AMPF specified by SUBDIR." | 830 "Return the sub project in AMPF specified by SUBDIR." |
831 (object-assoc (expand-file-name subdir) 'file (oref ampf subproj))) | 831 (object-assoc (expand-file-name subdir) 'file (oref ampf subproj))) |
952 (configfiles nil) | 952 (configfiles nil) |
953 ) | 953 ) |
954 (cond | 954 (cond |
955 ;; Try configure.in or configure.ac | 955 ;; Try configure.in or configure.ac |
956 (conf-in | 956 (conf-in |
957 (require 'ede/autoconf-edit) | |
958 (project-am-with-config-current conf-in | 957 (project-am-with-config-current conf-in |
959 (let ((aci (autoconf-parameters-for-macro "AC_INIT")) | 958 (let ((aci (autoconf-parameters-for-macro "AC_INIT")) |
960 (aia (autoconf-parameters-for-macro "AM_INIT_AUTOMAKE")) | 959 (aia (autoconf-parameters-for-macro "AM_INIT_AUTOMAKE")) |
961 (acf (autoconf-parameters-for-macro "AC_CONFIG_FILES")) | 960 (acf (autoconf-parameters-for-macro "AC_CONFIG_FILES")) |
962 (aco (autoconf-parameters-for-macro "AC_OUTPUT")) | 961 (aco (autoconf-parameters-for-macro "AC_OUTPUT")) |
978 ;; particular TARGET. | 977 ;; particular TARGET. |
979 (let ((outfiles (cond (aco (list (car aco))) | 978 (let ((outfiles (cond (aco (list (car aco))) |
980 (t acf)))) | 979 (t acf)))) |
981 (if (> (length outfiles) 1) | 980 (if (> (length outfiles) 1) |
982 (setq configfiles outfiles) | 981 (setq configfiles outfiles) |
983 (setq configfiles (split-string (car outfiles) " " t))) | 982 (setq configfiles (split-string (car outfiles) "\\s-" t))) |
984 ) | 983 ) |
985 )) | 984 )) |
986 ) | 985 ) |
987 ;; Else, try the script | 986 ;; Else, try the script |
988 ((file-exists-p conf-sh) | 987 ((file-exists-p conf-sh) |
1003 Calculates the info with `project-am-extract-package-info'." | 1002 Calculates the info with `project-am-extract-package-info'." |
1004 (let ((top (ede-toplevel))) | 1003 (let ((top (ede-toplevel))) |
1005 (when top (setq dir (oref top :directory))) | 1004 (when top (setq dir (oref top :directory))) |
1006 (project-am-extract-package-info dir))) | 1005 (project-am-extract-package-info dir))) |
1007 | 1006 |
1007 ;; for simple per project include path extension | |
1008 (defmethod ede-system-include-path ((this project-am-makefile)) | |
1009 "Return `project-am-localvars-include-path', usually local variable | |
1010 per file or in .dir-locals.el or similar." | |
1011 (bound-and-true-p project-am-localvars-include-path)) | |
1012 | |
1013 (defmethod ede-system-include-path ((this project-am-target)) | |
1014 "Return `project-am-localvars-include-path', usually local variable | |
1015 per file or in .dir-locals.el or similar." | |
1016 (bound-and-true-p project-am-localvars-include-path)) | |
1017 | |
1018 | |
1008 (provide 'ede/project-am) | 1019 (provide 'ede/project-am) |
1009 | 1020 |
1010 ;; arch-tag: 528db935-f186-4240-b647-e305c5b784a2 | 1021 ;; arch-tag: 528db935-f186-4240-b647-e305c5b784a2 |
1011 ;;; ede/project-am.el ends here | 1022 ;;; ede/project-am.el ends here |