views:

256

answers:

5

At my last job (legacy FORTRAN 77 code), we had files of cross references that list what subroutines called other subroutines, in what files subroutines were defined, what common blocks held what variables, what subroutines included what common blocks, etc. These were then used by shell scripts that grepped the cross reference files and would tell you things about the design of the program.

I'm now at a new company (C++ code), and I've found ctags to replace some of that functionality. The one thing I miss the most is a command we called "who.calls" that lists what subroutines (I mean functions or methods, gotta get used to the OO-speak) call a given subroutine. For example, if the subroutine foo calls the subroutine bar:

>who.calls bar
foo

Any suggestions for how to do this without re-engineering the programming environment from my old company? I'm looking for a super regex or some other method that I can use at the command line, but I'm open to other methods that take some totally different approach to give me the same information. I basically want to discover a debug function stack without running the debugger.

+4  A: 

You might want to consider using Doxygen. It can produce web pages that show you the entire call tree and class structure, as well as pulling out properly formatted comments to document the classes and methods just like Javadocs do for java.

Another possibility is to start using an IDE. After 25 years of using vi (and then gvim) and ctags, I've recently joined the 21st century and started using Eclipse (I'm doing Java, but I've seen C++ plugins for Eclipse). As well as being able to do everything that tags can do, it can also take you to all the callers of the current method. And on top of that, it has a damn good interactive debugger built in.

Paul Tomblin
I <3 Doxygen.
spoulson
Thanks for the edit, @J.F - I've given you a +1 on one where you had 9 votes, to get you the badge.
Paul Tomblin
+1  A: 

SlickEdit can tag every symbol in your project, including libraries, for display in "show references." It will be who.calls plus one, where the plus one is the definition. It's source based.

Thomas L Holaday
+3  A: 

For command line use, try cscope; it should be able to answer this question and more:

  • Allows searching code for:
    • all references to a symbol
    • global definitions
    • functions called by a function
    • functions calling a function
    • text string
    • regular expression pattern
    • a file
    • files including a file

it is not written for C++ but may be able to handle searching a C++ codebase (with some caveats).

If you are looking for a web-based interface, consider OpenGrok which runs on a server and indexes your revision control system. It doesn't have the search you are looking for in particular, but it can approximate it with a symbol search.

Emil
+2  A: 

GNU Global does the job for me on Unix based systems.

JeffFoster
What would you type to get a who.calls functionality with this? I think it's close to being what I want.
Scottie T
This tells me what files contain a function call. I want to know the names of the functions in those files that call my function.
Scottie T
They have a web demo with the Linux kernel code - you can click on a function declaration and it will take you to the callers.
Paul Tomblin
export LESSGLOBALTAGS=globalless -t functionnameIt does both references and where functions are defined. The above is for function definitions, but it does references too. Have a read of the tutorial.
JeffFoster
A: 

A langauge-sensitive source code search engine can be found at SD Source Code Search Engine. It can handle many languages at the same time. Searches can be performed for patterns in a specific langauge, or patterns across languages (such as "find identifiers involving TAX"). By being sensitive to langauge tokens, the number of false positives is reduced, saving time for the user. It understands C, C++, C#, COBOL, Java, ECMAScript, Java, XML, Verilog, VHDL, and a number of other languages, specifically including FORTRAN.

Its easy to find who calls X in Fortran with this tool; simply search for all identifiers 'X'. The actual query you have type is this: I=X ("any identifier named X"). That finds all references across the entire souce code base.

Ira Baxter