barryscott has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys. I have a large .cat file made up from hundreds of c source files. I have a list of functions in the project, collated from another perl tool I have written, and these are in a hash. What I need to do is for each function, find the definition (not calls, or declarations) in the cat file, and extract that that for further analysis. The functions are fairly well behaved, for example;
uint8_t foo_function (uint16_t foo, char bar) { /*some code here*/ }
but I'm having serious trouble getting it done with regexs. I haven't slept in a while and have nearly thrown my laptop out of the window a couple of time, so help would be very much appreciated guys ;oD

Replies are listed 'Best First'.
Re: pattern matching c-style function definitions :o(
by jettero (Monsignor) on Jan 07, 2008 at 11:57 UTC
    Depending on how well behaved your source files are, you may be able to teach h2xs to do it. Short of that, I think you need a C parser or a brilliant heuristic that acts like one.

    -Paul

Re: pattern matching c-style function definitions :o(
by bunch (Sexton) on Jan 07, 2008 at 12:24 UTC
    Take a look at Inline::C, it already has some code for detecting function definitions. Maybe you'll be able to adapt it to your needs.
Re: pattern matching c-style function definitions :o(
by planetscape (Chancellor) on Jan 07, 2008 at 14:38 UTC

    Depending on what you are trying to do, you may wish to take a look at a tool called Doxygen.

    HTH,

    planetscape
Re: pattern matching c-style function definitions :o(
by pc88mxer (Vicar) on Jan 07, 2008 at 18:10 UTC
    What about a line processing approach? If function declarations always begin with a left brace at column 0 and end with a right brace at column 0, the following should work:
    my ($prev, $type, $func, $args, $body); while (<>) { if (/^\{/) { # maybe check for structs/classes here if necessary ($type, $func, $args) = split(' ', $prev, 3); $body = ''; } elsif (/^\}/) { # ... process the function here ... $func = undef; } else { if (defined($func)) { $body .= $_; } else { $prev = $_; } } }
    As noted in the code, you might have to check for structs and/or classes.
      Thanks for the help everyone. What I basically need is to collect a list of all arguments and local variables in each function, which I'm then matching against known sizes from the map file to automatically calculate the worst case stack depth, after extract the call charts with cflow. Fairly ambitious for my limited perl knowhow, but the above will get me a step closer.