;;; semantic-dep.el --- Methods for tracking dependencies (include files) ;;; Copyright (C) 2006, 2007 Eric M. Ludlam ;; Author: Eric M. Ludlam ;; Keywords: syntax ;; X-RCS: $Id: semantic-dep.el,v 1.4 2007/05/17 01:41:20 zappo Exp $ ;; This file is not part of GNU Emacs. ;; Semantic is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; This software is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. ;;; Commentary: ;; ;; Include tags (dependencies for a given source file) usually have ;; some short name. The target file that it is dependent on is ;; generally found on some sort of path controlled by the compiler or ;; project. ;; ;; EDE or even ECB can control our project dependencies, and help us ;; find file within the setting of a given project. For system ;; dependencies, we need to depend on user supplied lists, which can ;; manifest themselves in the form of system datatabases (from ;; semanticdb.) ;; ;; Provide ways to track these different files here. (require 'semantic-tag) ;;; Code: ;;;###autoload (defvar semantic-dependency-include-path nil "Defines the include path used when searching for files. This should be a list of directories to search which is specific to the file being included. If `semantic-dependency-tag-file' is overridden for a given language, this path is most likely ignored. The above function, reguardless of being overriden, caches the located dependency file location in the tag property `dependency-file'. If you override this function, you do not need to implement your own cache. Each time the buffer is fully reparsed, the cache will be reset. TODO: use ffap.el to locate such items? NOTE: Obsolete this, or use as special user") (make-variable-buffer-local `semantic-dependency-include-path) ;;;###autoload (defvar semantic-dependency-system-include-path nil "Defines the system include path. This should be set with either `defvar-mode-local', or with `semantic-add-system-include'. When searching for a file associated with a name found in an tag of class include, this path will be inspected for includes of type `system'. Some include tags are agnostic to this setting and will check both the project and system directories.") (make-variable-buffer-local `semantic-dependency-include-path) ;;; PATH MANAGEMENT ;; ;; Some fcns to manage paths for a give mode. ;;;###autoload (defun semantic-add-system-include (dir &optional mode) "Add a system include DIR to path for MODE. Modifies a mode-local version of `semantic-dependency-system-include-path'." (interactive "DDirectory: ") (if (not mode) (setq mode major-mode)) (let ((dirtmp (file-name-as-directory dir)) (value (mode-local-value mode 'semantic-dependency-system-include-path)) ) (add-to-list 'value dirtmp t) (eval `(setq-mode-local ,mode semantic-dependency-system-include-path value)) )) ;;;###autoload (defun semantic-remove-system-include (dir &optional mode) "Add a system include DIR to path for MODE. Modifies a mode-local version of `semantic-dependency-system-include-path'." (interactive (list (completing-read "Directory to Remove: " semantic-dependency-system-include-path)) ) (if (not mode) (setq mode major-mode)) (let ((dirtmp (file-name-as-directory dir)) (value (mode-local-value mode 'semantic-dependency-system-include-path)) ) (setq value (delete dirtmp value)) (eval `(setq-mode-local ,mode semantic-dependency-system-include-path value)) )) ;;;###autoload (defun semantic-reset-system-include (&optional mode) "Reset the system include list to empty for MODE. Modifies a mode-local version of `semantic-dependency-system-include-path'." (interactive) (if (not mode) (setq mode major-mode)) (eval `(setq-mode-local ,mode semantic-dependency-system-include-path nil)) ) ;;; PATH SEARCH ;; ;; methods for finding files on a provided path. (defun semantic--dependency-find-file-on-path (file path) "Return an expanded file name for FILE on PATH." (let ((p path) (found nil)) (while (and p (not found)) (let ((f (expand-file-name file (car p)))) (if (file-exists-p f) (setq found f))) (setq p (cdr p))) found)) ;;;###autoload (defun semantic-dependency-find-file-on-path (file systemp &optional mode) "Return an expanded file name for FILE on available paths. If SYSTEMP is true, then only search system paths. If optional argument MODE is non-nil, then derive paths from the provided mode, not from the current major mode." (if (not mode) (setq mode major-mode)) (let ((sysp (mode-local-value mode 'semantic-dependency-system-include-path)) (locp (mode-local-value mode 'semantic-dependency-include-path)) (found nil)) (when (file-exists-p file) (setq found file)) (when (and (not found) (not systemp)) (setq found (semantic--dependency-find-file-on-path file locp))) (when (not found) (setq found (semantic--dependency-find-file-on-path file sysp))) (if found (expand-file-name found)))) (provide 'semantic-dep) ;;; semantic-dep.el ends here