Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find functions in a cpp file that contain a specific word

Tags:

grep

vim

using grep, vim's grep, or another unix shell command, I'd like to find the functions in a large cpp file that contain a specific word in their body.

In the files that I'm working with the word I'm looking for is on an indented line, the corresponding function header is the first line above the indented line that starts at position 0 and is not a '{'.

For example searching for JOHN_DOE in the following code snippet

int foo ( int arg1 ) 
{
    /// code 
}
void bar ( std::string arg2  )
{
    /// code
    aFunctionCall( JOHN_DOE );
    /// more code
}

should give me

void bar ( std::string arg2  )

The algorithm that I hope to catch in grep/vim/unix shell scripts would probably best use the indentation and formatting assumptions, rather than attempting to parse C/C++.

Thanks for your suggestions.

like image 616
andreas buykx Avatar asked May 06 '09 13:05

andreas buykx


3 Answers

I'll probably get voted down for this!

I am an avid (G)VIM user but when I want to review or understand some code I use Source Insight. I almost never use it as an actual editor though.

It does exactly what you want in this case, e.g. show all the functions/methods that use some highlighted data type/define/constant/etc... in a relations window...

gif of the relations window from the source insight website
(source: sourceinsight.com)

Ouch! There goes my rep.

like image 188
Simon Peverett Avatar answered Oct 08 '22 17:10

Simon Peverett


As far as I know, this can't be done. Here's why:

First, you have to search across lines. No problem, in vim adding a _ to a character class tells it to include new lines. so {_.*} would match everything between those brackets across multiple lines.

So now you need to match whatever the pattern is for a function header(brittle even if you get it to work), then , and here's the problem, whatever lines are between it and your search string, and finally match your search string. So you might have a regex like

/^\(void \+\a\+ *(.*)\)\_.*JOHN_DOE

But what happens is the first time vim finds a function header, it starts matching. It then matches every character until it finds JOHN_DOE. Which includes all the function headers in the file.

So the problem is that, as far as I know, there's no way to tell vim to match every character except for this regex pattern. And even if there was, a regex is not the tool for this job. It's like opening a beer with a hammer. What we should do is write a simple script that gives you this info, and I have.

fun! FindMyFunction(searchPattern, funcPattern)
  call search(a:searchPattern)
  let lineNumber = line(".")
  let lineNumber = lineNumber - 1
  "call setpos(".", [0,  lineNumber, 0, 0])

  let lineString = getline(lineNumber)
  while lineString !~ a:funcPattern
    let lineNumber = lineNumber - 1
    if lineNumber < 0
      echo "Function not found :/"
    endif
    let lineString = getline(lineNumber)
  endwhile

  echo lineString

endfunction

That should give you the result you want and it's way easier to share, debug, and repurpose than a regular expression spit from the mouth of Cthulhu himself.

like image 43
Whaledawg Avatar answered Oct 08 '22 19:10

Whaledawg


Tough call, although as a starting point I would suggest this wonderful VIM Regex Tutorial.

like image 31
Robert S. Barnes Avatar answered Oct 08 '22 18:10

Robert S. Barnes