CScopeAndEmacs

Last edit

Added:

> [new]
> I think the cscope-do-not-update-database variable does not exist anymore in recent versions of xcscope, in version 1.0 packaged in debian it's cscope-option-do-not-update-database. Good to know if you work on a big codebase.


This page needs info on how to actually use these tools. I believe I’ve installed the pieces correctly, but now I need to know how to actually use them. An intro on some of the basic commands would be greatly appreciated.

cscope

Cscope http://cscope.sf.net is a program that generates index tables from C and C++ source files. It is also a client program that knows how to use the generated index tables to answer questions such as where is a symbol defined, where is a symbol referenced, etc.

It works fine with GNU Emacs 21.2 under Debian GNU/Linux as well as under Windows XP (and probably other Windows OS’es) if cscope is compiled using Cygwin http://www.cygwin.com provided GNU tools, i.e., typical “./configure; make; make install” steps work fine.

It does not compile using MSYS on MS Windows.

xcscope.el

Darryl Okahata’s xcscope.el comes with the cscope package. This package is stable, and development is continuing in its own tree (https://github.com/dkogan/xcscope.el). This tree fixes various bugs and adds various features. Most significantly, multiple results are now displayed in the cscope buffer at a time. This makes management of multiple searches dramatically better. The full change log is available in the README at the above link. This xcscope.el package is currently available on MELPA and in Debian and in Ubuntu (package name is “xcscope-el”). Following comments are about Darryl’s original xcscope.el. I’ll review (and possibly absort) the patches mentioned here shortly.

I don’t know cscope.el, but I discovered xcscope.el recently – and this is really practical! Don’t use M-x grep anymore!

mmc: I have this problem with xcscope.el: When i invoke a long time lasting search, and go into minibuffer (think M-x), when cscope finishes its job, xcsope will present the found file inside the minibuffer. I have made this fix:

  (defun cscope-process-sentinel (process event)
    (let*   (.....)
    ;; Don't present the new buffer (file) inside minibuffer!
    (if (minibuffer-window-active-p old-buffer-window)
        (setq old-buffer-window 
              (next-window old-buffer-window)))
    ....

GP: I unsuccessfully tried modifying xcscope.el so that it uses the “cscope -b -q -k” options, I want the -q option on my large code base, so that symbol search becomes quicker. Does anyone have suggestion on how I should make xcscope.el work with the “-q” option?

Just touch the file cscope.po.out and cscope.in.out after finishing index. It works for me. And try google bscope, you will find a new cscope interface faster than xscope. – highfly22 at gmail dot com

Thank Darryl for bringing us such an amazing tool. However, despite much convenience it provides there are still some guys, including me ☺, asking for certain new feature now and then on news groups: going back and forth the search history.

I think the primary benifit of this feature is to give us a clue how we gotten into current position. I used to ask myself “how I get into function?” since the code I’m reading has really deep call stacks and I can’t keep them all in my mind. The other benifit is that, for large projects, cscope-ing sometimes could be time-consuming.

I hacked the code for that feature (http://sourceforge.net/tracker/index.php?func=detail&aid=1839942&group_id=4664&atid=304664). Your comments are appreciated.

USAGE: For basic usage refer to original comments. To view previous search result, call cscope-history-backward (’C-c s v’ or just ‘v’ in cscope buffer) or cscope-history-forward (’V’).

Latest changes are: Change behavior of history ring to (which i think is) a more reasonable flavor. Change/Add key-bindings Add function cscope-history-clear Fix bug of can’t call history related functions except in cscope buffer.

Chris: I have been looking to get xcscope.el and emacs to cooperate under windows XP without cygwin. I found this native win32 version of cscope (http://code.google.com/p/cscope-win32/). Unfortunately xcscope.el uses a bash script (cscope-indexer) to generate the cscope database. Not finding a windows compatible version, I decided to come up with my own port. This is the cscope-indexer.bat I came up with. Feel free to use/modify/debug it. Place cscope-indexer.bat in your PATH and it should be working with xcscope.

cscope-indexer.bat:

@echo off & setlocal enableextensions
REM ******************************************************************
REM Not responsible for any loss resulting from the use of this script
REM ******************************************************************
REM sed and grep should be installed and in PATH
REM those windows version can be installed via MSYS package (http://www.mingw.org/wiki/MSYS)

set n=0
set recursive=0
set listonly=0
set verbose=0

set LIST_FILE=""
set DATABASE_FILE=""
set param="%*%"

:LOOP
if "%~1" == "" goto PROCESS
if "%~1" == "-r" goto RECURSE
if "%~1" == "-i" goto LISTFILE
if "%~1" == "-f" goto CSCOPEOUT
if "%~1" == "-l" goto LISTONLY
if "%~1" == "-v" goto VERBOSE
shift
goto LOOP

:RECURSE
set recursive=1
shift
goto LOOP

:LISTFILE
shift
set LIST_FILE="%~1"
shift
goto LOOP

:CSCOPEOUT
shift
set DATABASE_FILE="%~1"
shift
goto LOOP

:LISTONLY
set listonly=1
shift
goto LOOP

:VERBOSE
set verbose=1
shift
goto LOOP

:PROCESS
IF %verbose%==1 echo cscope-indexer args: %param%
IF %recursive%==1 goto GET_RECURSE_SRC
dir /B > %LIST_FILE%.tmp
goto CSCOPE

:GET_RECURSE_SRC
dir /S /B > %LIST_FILE%.tmp
goto CSCOPE

:CSCOPE
IF %listonly%==1 goto ALMOST_DONE

grep -i -E "\.([chly](xx|pp)*|cc|hh)$" %LIST_FILE%.tmp | sed -e "s/^/\"/;s/$/\"/" > %LIST_FILE%
cscope -b -i %LIST_FILE% -f %DATABASE_FILE%
goto DONE

:ALMOST_DONE
grep -i -E "\.([chly](xx|pp)*|cc|hh)$"  %LIST_FILE%.tmp > %LIST_FILE%
goto DONE

:DONE
del "%LIST_FILE%.tmp"
echo Done

Here is a patch created from revision 1.14 of contrib/xcscope/xcscope.el in the official cscope CVS repository on SourceForge? that fixes a bug causing databases to be skipped over when using ‘cscope-database-regexps’ if they are contained in the same directory. I emailed Darryl Okahata with the patch but I do not know if he is still reachable.

--- xcscope.el.cvs	2011-09-23 10:31:31.874724475 -0400
+++ xcscope.el	2011-09-23 10:35:11.423813160 -0400
@@ -1012,9 +1012,9 @@
 (make-variable-buffer-local 'cscope-search-list)
 
 
-(defvar cscope-searched-dirs nil
-  "The list of database directories already searched.")
-(make-variable-buffer-local 'cscope-searched-dirs)
+(defvar cscope-searched-databases nil
+  "The list of databases already searched.")
+(make-variable-buffer-local 'cscope-searched-databases)
 
 
 (defvar cscope-filter-func nil
@@ -1925,17 +1925,20 @@
 		    (progn
 		      ;; Handle the case where `cscope-directory' is really
 		      ;; a full path name to a cscope database.
-		      (setq base-database-file-name
+		      (setq database-file cscope-directory
+			    base-database-file-name
 			    (file-name-nondirectory cscope-directory)
 			    cscope-directory
 			    (file-name-directory cscope-directory))
-		      ))
+		      )
+		  ;; Else set database-file to default name
+		  (setq database-file (concat cscope-directory base-database-file-name)))
 		(setq cscope-directory 
 		      (file-name-as-directory cscope-directory))
-		(if (not (member cscope-directory cscope-searched-dirs))
+		(if (not (member database-file cscope-searched-databases))
 		    (progn
-		      (setq cscope-searched-dirs (cons cscope-directory
-						       cscope-searched-dirs)
+		      (setq cscope-searched-databases (cons database-file
+						       cscope-searched-databases)
 			    done t)
 		      ))
 		)
@@ -1958,8 +1961,8 @@
 	(if cscope-command-args
 	    (setq options (append options cscope-command-args)))
 	(setq database-file (concat cscope-directory base-database-file-name)
-	      cscope-searched-dirs (cons cscope-directory
-					 cscope-searched-dirs)
+	      cscope-searched-databases (cons database-file
+					 cscope-searched-databases)
 	      )
 
 	;; The database file and the directory containing the database file
@@ -2041,7 +2044,7 @@
       (setq default-directory directory
 	    cscope-start-directory nil
 	    cscope-search-list (cscope-find-info directory)
-	    cscope-searched-dirs nil
+	    cscope-searched-databases nil
 	    cscope-command-args args
 	    cscope-filter-func filter-func
 	    cscope-sentinel-func sentinel-func

I got the original cscope-indexer script to work by copying it to the bin folder of an installed MinGW and the following trivial patch for xcscope.el. Your PATH has to be set accordingly, though.

--- xcscope.el	(revision 9370)
+++ xcscope.el	(working copy)
@@ -2123,7 +2123,7 @@
       (setq cscope-unix-index-process
 	    (apply 'start-process "cscope-indexer"
 		   cscope-unix-index-process-buffer
-		   cscope-indexing-script args))
+		   "sh" cscope-indexing-script args))
       (set-process-sentinel cscope-unix-index-process
 			    'cscope-unix-index-files-sentinel)
       (process-kill-without-query cscope-unix-index-process)

xcscope.el comments

More on cscope and Windows: for versions up to 1.54, binaries compiled with DJGPP are provided (e.g., csc154b.zip). xcscope.el is not included and is obtained separately by downloading the source. Update the global PATH variable with the location of cscope.exe, put xcscope.el in the site-lisp directory, and add the following lines to .emacs:

 (require 'xcscope)
 (setq cscope-do-not-update-database t)

By default, xcscope.el does automatic indexing by use of a Bash script (cscope-indexer). As Windows lacks Bash support, automatic indexing is here disabled (although the MSYS project does include a sh.exe executable which can run such scripts). To index manually and recursively, in the uppermost directory run

 cscope -bR

The -b flag tells cscope to just build the database and then exit. Otherwise, cscope is terminated by Ctrl-D.

This seems to work adequately with GNU Emacs 22.1.

a possibly handy hack:

 (defun my-find-tag(&optional prefix)
  "union of `find-tag' alternatives. decides upon major-mode"
  (interactive "P")
  (if (and (boundp 'cscope-minor-mode)
           cscope-minor-mode)
      (progn
        (ring-insert find-tag-marker-ring (point-marker))
        (call-interactively
         (if prefix
             'cscope-find-this-symbol
           'cscope-find-global-definition-no-prompting
           )))
    (call-interactively 'find-tag)))
 (substitute-key-definition 'find-tag 'my-find-tag  global-map)

Chris: I like this native win32 cscope version: http://code.google.com/p/cscope-win32. See the xcscope.el section for integration under windows.

I think the cscope-do-not-update-database variable does not exist anymore in recent versions of xcscope, in version 1.0 packaged in debian it’s cscope-option-do-not-update-database. Good to know if you work on a big codebase.

ascope.el

ascope is an improvement over xcscope that runs all queries through a single cscope process, instead of starting a new process and reloading the database for each query. It was made by Staton Sun as a merge between xscope and another single-process interface, bscope (not listed here) Original ML post. A copy of the file is made available here: Lisp:ascope.el

I just ran some benchmarks, and I’m pretty sure the performance benefits of this are way overblown: http://notes.secretsauce.net/notes/2014/03/25_cscope-benchmarks.html . If I’m wrong about something here, please tell me.

cscope.el

Bill Carpenter’s cscope.el mode is available from this wiki:

Lisp:cscope.el

xcscope+

Here’s another that I found on emacswiki; I have no idea how it compares to the others: http://emacswiki.org/xcscope+.el

cscope-fu

There is another cscope.el out there. To get it, visit this MercurialMode repository: http://hg.serpentine.com/cscope-fu. (Link down 2010-04-18) (To get the latest version of cscope.el, click on the manifest-link, then the cscope.el filename and finally raw to download the file.)

CEDET

The CEDET (CollectionOfEmacsDevelopmentEnvironmentTools) suite can use cscope as a backend for several tasks. These include:

rscope.el

rscope is a new implementation taking its roots from ascope, thus running a single cscope process for each cscope database. It’s a bit more versatile than ascope because it copes with multiple cscope databases (and hence spawns one cscope process per database once).

It was developped by Robert Jarzmik and is in rscope's github repository. The page explains the usage, which is globally very close to xscope in terms of key bindings.


CategoryProgrammerUtils CategoryNavigation