Semantic, cedet how to force parsing of source fil

2019-04-28 11:09发布

问题:

I have been experimenting with cedet and semantic in my emacs c/c++ development setup and I am quite satisfied with it except for one small detail.

I use ede-cpp-root-project to create a project and give the root directory of my project along with the directories where include files reside like below:

(ede-cpp-root-project "My Project"
                :name "My Project"
                :file "/path/to/rootdir/AFILE"
                :include-path '( 
                "/include2"
                "/include1"
                               )

                )

This allows me to easily jump to the declarations of functions with semantic-ia-fast-jump but it does not get me to the definitions of those functions. So it seems to only be dealing with header files and totally ignore source files. Even if I go on the declaration of the function and trigger semantic-analyze-proto-impl-toggle it will tell me that no suitable implementation could be found.

If I manually open the source file where the implementation of the function is located, then and only then it is parsed by semantic and all the above mentioned functions work.

So my question is, short of manually opening all source files included underneath my project's root directory or manually including them in ede-cpp-root-project via the :spp-files argument is there any other way to force parsing of all source files under a directory?

Thanks!

回答1:

After ignoring this problem for a long time I thought I should spend some quality time reading on elisp and try to figure out a work-around. It is not the prettiest elisp code there is, since I use elisp only for my emacs needs but it does what I need.

(defvar c-files-regex ".*\\.\\(c\\|cpp\\|h\\|hpp\\)"
  "A regular expression to match any c/c++ related files under a directory")

(defun my-semantic-parse-dir (root regex)
  "
   This function is an attempt of mine to force semantic to
   parse all source files under a root directory. Arguments:
   -- root: The full path to the root directory
   -- regex: A regular expression against which to match all files in the directory
  "
  (let (
        ;;make sure that root has a trailing slash and is a dir
        (root (file-name-as-directory root))
        (files (directory-files root t ))
       )
    ;; remove current dir and parent dir from list
    (setq files (delete (format "%s." root) files))
    (setq files (delete (format "%s.." root) files))
    (while files
      (setq file (pop files))
      (if (not(file-accessible-directory-p file))
          ;;if it's a file that matches the regex we seek
          (progn (when (string-match-p regex file)
               (save-excursion
                 (semanticdb-file-table-object file))
           ))
          ;;else if it's a directory
          (my-semantic-parse-dir file regex)
      )
     )
  )
)

(defun my-semantic-parse-current-dir (regex)
  "
   Parses all files under the current directory matching regex
  "
  (my-semantic-parse-dir (file-name-directory(buffer-file-name)) regex)
)

(defun lk-parse-curdir-c ()
  "
   Parses all the c/c++ related files under the current directory
   and inputs their data into semantic
  "
  (interactive)
  (my-semantic-parse-current-dir c-files-regex)
)

(defun lk-parse-dir-c (dir)
  "Prompts the user for a directory and parses all c/c++ related files
   under the directory
  "
  (interactive (list (read-directory-name "Provide the directory to search in:")))
  (my-semantic-parse-dir (expand-file-name dir) c-files-regex)
)

(provide 'lk-file-search)

To use it either call the function directly like so: (my-semantic-parse-dir "path/to/dir/root/" ".*regex") or press M-x lk-parse-curdir-c from a buffer to recursively scan all c/c++ related files from that buferr's visiting filename directory.

An alternate and perhaps preferrable way to call the function is by invoking lk-parse-dir-c interactively which in turn will prompt you for a directory to parse.

If any elisp guru has a better solution or suggestions to improve the code I would love to hear them.



回答2:

I have implemented this for Python recently. It could be adopt for C/C++ with minor changes.

(defvar python-extention-list (list "py"))

(defun semanticdb-rescan-directory (pathname)
  (dolist (file (cddr (directory-files pathname t)))
    (if (file-directory-p file)
        (semanticdb-rescan-directory file)
      (when (member (file-name-extension file) python-extention-list)
        (message "Parsing %s file." file)
        (ignore-errors
            (semanticdb-file-table-object file))))))

(defun semantic-python-rescan-includes ()
  (interactive)
  (dolist (includes (semantic-python-get-system-include-path))
    (message "Parsing %s" includes)
    (semanticdb-rescan-directory includes)))


回答3:

Try running the command "bovinate". This can be done with the key combination Meta + X and then typing "bovinate", and hitting the "Enter" key. The "Meta" key is referred to as the "Alt" key in windows.



标签: c++ c emacs cedet