Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding and modifying function definitions (C++) via bash-script

Tags:

c++

bash

parsing

Currently I am working on a fairly large project. In order to increase the quality of our code, we decided to enforce the treatement of return values (Error Codes) for every function. GCC supports a warning concerning the return value of a function, however the function definition has to be preceeded by the following flag.

static __attribute__((warn_unused_result)) ErrorCode test() { /* code goes here */ }

I want to implement a bashscript that parses the entire source code and issues a warning in case the

__attribute__((warn_unused_result))

is missing. Note that all functions that require this kind of modification return a type called ErrorCode. Do you think this is possible via a bash script ?

like image 837
Flo Ryan Avatar asked Aug 20 '15 13:08

Flo Ryan


2 Answers

Maybe you can use sed with regular expressions. The following worked for me on a couple of test files I tried:

sed -r "s/ErrorCode\s+\w+\s*(.*)\s*\{/__attribute__((warn_unused_result)) \0/g" test.cpp

If you're not familiar with regex, the pattern basically translates into:

ErrorCode, some whitespace, some alphanumerics (function name), maybe some whitespace, open parenthesis, anything (arguments), close parenthesis, maybe some whitespace, open curly brace.

If this pattern is found, it is prefixed by __attribute__((warn_unused_result)). Note that this only works if you are putting the open curly brace always in the same line as the arguments and you don't have line breaks in your function declarations.

like image 115
Jonas Greitemann Avatar answered Oct 18 '22 18:10

Jonas Greitemann


An easy way I could imagine is via ctags. You create a tag file over all your source code, and then parse the tags file. However, I'm not quite sure about the format of the tags file. The variant I'm using here (Exuberant Ctags 5.8) seems to put an "f" in the fourth column, if the tag represents a function. So in this case I would use awk to filter all tags that represent functions, and then grep to throw away all lines without __attribute__((warn_unused_result)).

So, in a nutshell, first you do

$ ctags **/*.c

This creates a file called "tags" in the current directory. The command might also be ctags-exuberant, depending on your variant. The **/*.c is a glob pattern that might work in your shell - if it doesn't, you have to supply your source files in another way (look at the ctagsoptions).

Then you filter the funktions:

$ cat tags | awk -F '\t' '$4 == "f" {print $0}' | grep -v "__attribute__((warn_unused_result))"
like image 21
Georg P. Avatar answered Oct 18 '22 18:10

Georg P.