views:

285

answers:

1

I need to find all occurrences of a function call in a c++ file using python, and extract the arguments for each call.
I'm playing with the pygccxml package, and extracting the arguments given a string with the function call is extremely easy:

from pygccxml.declarations import call_invocation

def test_is_call_invocation(call):
    if call_invocation.is_call_invocation(call):
        print call_invocation.name(call)
        for arg in call_invocation.args(call):
            print "   ",arg
    else:
        print "not a function invocation"

What I couldn't find is a way of getting the calls parsing a file:

from pygccxml import parser
from pygccxml import declarations

decls = parser.parse( ['main.cpp'] )
# ...

Is there a way to find the calls to a certain function using the pygccxml package?
Or maybe that package is an overkill for what I'm trying to do :) and there's a much simpler way? Finding the function calls with a regular expression is, I'm afraid, much trickier than it might look at a first sight...

+2  A: 

XML-GCC can't do that, because it only reports the data types (and function signatures). It ignores the function bodies. To see that, create a.cc:

void foo()
{}

void bar()
{
        foo();
}

and then run gccxml a.cc -fxml=a.xml. Look at the generated a.xml, to see that the only mentioning of foo (or its id) is in the declaration of foo.

An alternative might be available in codeviz (http://www.csn.ul.ie/~mel/projects/codeviz/). It consists of a patch to gcc 3.4.6 that generates call dependency information - plus some perl scripts that generate graphwiz input; the latter you can safely ignore.

As yet another alternative (which doesn't need gcc modifications) you could copy the approach from egypt (http://www.gson.org/egypt/); this parses GCC RTL dumps. It should work with any recent GCC, however, it might be that you don't get calls to inline functions.

In any case, with these approaches, you won't get "calls" to macros, but that might be actually the better choice.

Martin v. Löwis