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

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 ?

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.

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))"

No, it is not possible in the general case. The C++ grammar is the most complex of all the languages I know of, and C++ is not parsable via regular expressions in the general case. You might succeed if you limit yourself to a very narrow set of uses, but I am not sure how feasible it is in your case.
I also do not think the excersise is worth the effort, since sometimes ignoring the result of the function is an OK thing.

Related

What is the best way to specify a wildcard or regex in a "test" statement in configure.ac?

I am writing a configure.ac script for gnu autotools. In my code I have some if test statements where I want to set flags based on the compiler name. My original test looked like this:
if test "x$NETCDF_FC" = xifort; then
but sometimes the compiler name is more complicated (e.g., mpifort, mpiifort, path prepended, etc...), and so I want to check if the string ifort is contained anywhere within the variable $NETCDF_FC.
As far as I can understand, to set up a comparison using a wildcard or regex, I cannot use test but instead need to use the double brackets [[ ]]. But when configure.ac is parsed by autoconf to create configure, square brackets are treated like quotes and so one level of them is stripped from the output. The only solution I could get to work is to use triple brackets in my configure.ac, like this:
if [[[ $NETCDF_FC =~ ifort ]]]; then
Am I doing this correctly? Would this be considered best practices for configure.ac or is there another way?
Use a case statement. Either directly as shell code:
case "$NETCDF_FC" in
*ifort*)
do_whatever
;;
*)
do_something_else
;;
esac
or as m4sh code:
AS_CASE([$NETCDF_FC],
[*ifort*], [do_whatever],
[do_something_else])
I would not want to rely on a shell capable of interpreting [[ ]] or [[[ ]]] being present at configure runtime (you need to escape those a bit with [] to have the double or triple brackets make it into configure).
If you need a character class within a case pattern (such as e.g. *[a-z]ifort*), I would advise you to check the generated configure file for the case statement patterns which actually end up being used until you have enough [] quotes added around the pattern in the source configure.ac file.
Note that the explicit case statements often contain # ( shell comments at the end of the lines directly before the ) patterns to avoid editors becoming confused about non-matching opening/closing parentheses.

Using egrep to find a multi-line definition in a file, matching all content within {}

I know that stackexchange is filled with helpful stuff about how to do things similar to what I want to do, but I'm afraid I'm not skilled enough to extrapolate from them and solve my problem.
I'm trying to write a script that searches for specific latex definitions, contained in one or more .sty files, and then return the entire definition. The definition is contained inside curly brackets, but there may be lots of curly brackets inside of the definition.
For example, following this thread I tried the command
sed -n '/\\def\\propref\>/,/}$/p' *.sty
but this returns
\def\propref#1{%
\IfBeginWith*{#1}{prop:}
But I want it to return the entire definition, delimited by {}, i.e.,
\def\propref#1{%
\IfBeginWith*{#1}{prop:}
{Prop.~\ref{#1}}%
{Prop.~\ref{prop:#1}}}
So, the hard part for me is to locate the closing delimiter that matches the opening one. A second issue, if the solution is to use sed, is that I'd like the command to return the file name as well as the pattern, just as grep does, when searching thru multiple files. Specifically, I'll like the first line of the returned output to look grep-like
my_oneLineDefs.sty:\def\propref#1{%
Here's a snippet of the .sty file containing the definition.
\def\propref#1{%
\IfBeginWith*{#1}{prop:}
{Prop.~\ref{#1}}%
{Prop.~\ref{prop:#1}}}
\def\thmref#1{%
\IfBeginWith*{#1}{thm:}
{Thm.~\ref{#1}}%
{Thm.~\ref{thm:#1}}}
\def\secref#1{%
\IfBeginWith*{#1}{sec:}
{\S\ref{#1}}%
{\S\ref{sec:#1}}}

Search for multiline regex

I have several source file which have function definitions as follows.
ReturnType ClassName::
FunctionName(FunctionArgs...)
{
....
}
ReturnType ClassName::NestedClassName::
FunctionName(FunctionArgs...)
{
....
}
I want to grep through the files and list all the functions of first type sepeartely and second type separately. Is there a way to do it in emacs?
Note: I have tried C-q C-j from [https://emacs.stackexchange.com/questions/9548/what-is-regex-to-match-newline-character]. it didn't work.
There seem to be two inter-related pieces to this: the regexps to use, and the search method. I am making the following assumptions (sorry for not clarifying these beforehand; I don't have enough rep to comment):
You are interested in collecting just the function signature (the first two lines), not what's inside the braces.
Colons never appear in return types or class names.
No line ever ends in a double colon inside a function body.
Within Emacs, I can distinguish the two cases with the regexps
^[^:]+::\n.+$
^[^:]+::[^:]+::\n.+$
(where you would replace \n with an actual newline (via C-q C-j, for instance) in an interactive usage).
If you have all of the buffers opened in Emacs, you can just use multi-occur now. Otherwise, you can call out to grep using the grep command, or just use M-! to call grep directly.
If you're using grep, then you need a different approach (or at least I couldn't find an appropriate regexp). If you drop the second line and use the -A 1 switch (which tells grep to print the line following each match), everything seems to work properly. You also need to escape the + operator, for some reason. Here are the resulting commands:
grep -A 1 "^[^:]\+::$" files
grep -A 1 "^[^:]\+::[^:]\+::$" files

Mass replace deprecated functions in entire projects

I have a bunch of PHP coded websites that have been recently moved to a PHP 5.4 server and they're throwing deprecation warnings and errors.
Is there a way to mass find & replace function names with the proper ones? For example, I would like to be able to replace all instances of session_unregister('someVar') with unset($_SESSION['someVar'])...
Should i use regex or is there an other way?
For this particular example you could use sed like this:
echo "session_unregister('someVar')" | sed 's/session_unregister(/unset\($_SESSION[/;s/)/])/'
A bit more flexible would be to use the C preprocessor. Assume your php source file name is my.php. Add extension .h so it becomes my.php.h. At the beginning of the file, insert:
#define session_unregister(X) unset($_SESSION[X])
Assume the file contains lines like in your example: session_unregister('someVar')
Run the preprocessor like this:
cc -E my.php.h
Now you should instead see unset($_SESSION['someVar'])
(plus some extra garbage you don't want).
Note that this just answers your particular question, but I wouldn't recommend it without more detailed testing.

Global substitution for latex commands in vim

I am writing a long document and I am frequently formatting some terms to italics. After some time I realized that maybe that is now what I want so I would like to remove all the latex commands that format text to italics.
Example:
\textit{Vim} is undoubtedly one of the best editors ever made. \textit{LaTeX} is an extremely powerful, intelligent typesetter. \textbd{Vim-LaTeX} aims at bringing together the best of both these worlds
How can I run a substitution command that recognizes all the instances of \textit{whatever} and changes them to just whatever without affecting different commands such as \textbd{Vim-LaTeX} in this example?
EDIT: As technically the answer that helps is the one from Igor I will mark that one as the correct one. Nevertheless, Konrad's answer should be taken into account as it shows the proper Latex strategy to follow.
You shouldn’t use formatting commands at all in your text.
LaTeX is built around the idea of semantic markup. So instead of saying “this text should be italic” you should mark up the text using its function. For instance:
\product{Vim} is undoubtedly one of the best editors ever made. \product{LaTeX}
is an extremely powerful, intelligent typesetter. \product{Vim-LaTeX} aims at
bringing together the best of both these worlds
… and then, in your preamble, a package, or a document class, you (re-)define a macro \product to set the formatting you want. That way, you can adapt the macro whenever you deem necessary without having to change the code.
Or, if you want to remove the formatting completely, just make the macro display its bare argument:
\newcommand*\product[1]{#1}
Use this substitution command:
% s/\\textit{\([^}]*\)}/\1/
If textit can span muptiple lines:
%! perl -e 'local $/; $_=<>; s/\\textit{([^}]*)}/$1/g; print;'
And you can do this without perl also:
%s/\\textit{\(\_.\{-}\)}/\1/g
Here:
\_. -- any symbol including a newline character
\{-} -- make * non-greedy.