First squash all multiline macro's, it makes parsing easier. Otherwise
the regex to remove the macro would become more comples if we have to
deal with newlines etc.
When we have a match, we check if the last line in the pre_match is
the beginning of a macro declaration.
If it is, we remove the beginning of this macro
declaration (#define<space>) and remove the body of the macro from the
post_match, which is basically everything until the next newline.
There is a possible edge case (pretty unlikely but still):
if there is no newline in the post_match, meaning it is a macro at the
end of the line, we should delete it as well, hence the '[\n]?' in the
post match regex.
Add a random struct in between to make sure we are not touching it
+
multiple newlines are allowed in the function declaration before the
semicolon, add a test to make sure we handle this.
When a inline function was declared in a file, we would find the
declaration and remove the function body. However, since it is a
declaration, there is NO function body, so we were deleting a random
piece of code that was between square brackets in the file.
To properly handle this, we have to detect if we are dealing with a
function declaration or a function definition.
If we are dealing with a function declaration, a semicolon
will come BEFORE the first square bracket.
If we are dealing with a function definition, a square bracket will
come BEFORE the first semicolon (the first semicolon will be in the
inline function body, so between the square brackets).
So we determine the location of the first semicolon and the first
square bracket after the function name and apply the logic described
above to handle function declarations.
If we are dealing with a function declaration, we don't do anything,
we just move to the next match.
This will result in redeclarations of the inline function, but this is
allowed in C and I'd rather not touch the file anymore than necessary.
It didn't add direct comparisons only for pointer arguments, but
also other types of arguments like structs, which can't be compared
with '==' and cause a compiler error instead.
To reproduce, just enable the :array plugin in
system/test_interactions/expect_and_return_custom_types.yml:
In function ‘foo’:
error: invalid operands to binary != (have ‘EXAMPLE_STRUCT_T’ {aka
‘struct _EXAMPLE_STRUCT_T’} and ‘EXAMPLE_STRUCT_T’ {aka ‘struct
_EXAMPLE_STRUCT_T’})
59 | if (cmock_call_instance->Expected_a != a) {
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^~
This reverts commit 4df532afcc.
- If inlines are included, we don't do anything since they are
disguised already as normal functions
- If inlines are NOT included, we remove anything that has inline in
it
- We set the defaults but the user is free to add his own.
This will overwrite our defaults but they will be added to the
documentation as reference for the user
- Just looking for static|inline in the gsub is a bit too aggressive.
Instead, look for the "static inline" and parse it:
- Everything before the match should just be copied, we don't want
to touch anything but the inline functions.
- Remove the implementation of the inline function (this is enclosed
in square brackets) and replace it with ";" to complete the
transformation to normal/non-inline function.
- Copy everything after the inline function implementation
Repeat the above step until we can't find "static inline" anymore
- To remove the inline implementation,
we count the number of square-bracket 'levels' in the inline function
and remove every pair. This ensures that constructs like:
inline void func(void) {
if (...) {
//NOP
}
else
{
//NOP
}
}
will not end up leaving the 'else' keyword unremoved:
inline void func(void);
else
If we count the number of levels, we don't end up in this scenario
since we remove 3 'pairs', the if-one, the else-one and finally the
main body.
- This way, @normalized_source will always be defined, which it should
because we are referencing it a few lines down, thanks to
@mvandervoord for the suggestion