Handle user defined inline macro's

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.
This commit is contained in:
laurensmiers
2020-01-14 22:18:17 +01:00
parent 3254aef5e5
commit cfe1b4ef3d
2 changed files with 47 additions and 0 deletions
+14
View File
@@ -120,6 +120,10 @@ class CMockHeaderParser
# let's clean up the encoding in case they've done anything weird with the characters we might find
source = source.force_encoding("ISO-8859-1").encode("utf-8", :replace => nil)
# smush multiline macros into single line (checking for continuation character at end of line '\')
# If the user uses a define to declare an inline function, it's easier to remove later
source.gsub!(/\s*\\\s*/m, ' ')
# - Just looking for static|inline in the gsub is a bit too aggressive (functions that are named like this, ...), so we try to be a bit smarter
# Instead, look for "static inline" and parse it:
# - Everything before the match should just be copied, we don't want
@@ -156,6 +160,16 @@ class CMockHeaderParser
puts inline_function_match.post_match
puts
# Determine if we are dealing with a user defined macro to declare inline functions
if /(#define\s*)\z/ === inline_function_match.pre_match
puts "DEFINE, REMOVE"
stripped_pre_match = inline_function_match.pre_match.sub(/(#define\s*)\z/,'')
stripped_post_match = inline_function_match.post_match.sub(/\A(.*[\n]?)/,'')
source = stripped_pre_match + stripped_post_match
puts source
next
end
# Determine if we are dealing with a declaration or a function definition
first_open_bracket = inline_function_match.post_match.index("{")
first_semicolon = inline_function_match.post_match.index(";")
+33
View File
@@ -2154,4 +2154,37 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
assert_equal(expected, @parser.transform_inline_functions(source))
end
it "Transform inline functions TODO" do
source =
"#define INLINE static __inline__ __attribute__ ((always_inline))\n" +
"#define INLINE_TWO \\\nstatic\\\ninline\n" +
"INLINE uint16_t _somefunc (uint32_t a)\n" +
"{\n" +
" return _someotherfunc (a);\n" +
"}\n" +
"static __inline__ uint16_t _somefunc_0 (uint32_t a)\n" +
"{\n" +
" return (uint16_t) a;\n" +
"}\n" +
"static __inline__ __attribute__ \(\(always_inline\)\) uint16_t _somefunc_1 (uint32_t a)\n" +
"{\n" +
" return (uint16_t) a;\n" +
"}\n" +
"INLINE_TWO uint16_t _somefunc_2(uint32_t a)\n" +
"{\n" +
" return (uint16_t) a;\n" +
"}\n" +
"#define INLINE_THREE \\\nstatic\\\ninline"
expected =
"uint16_t _somefunc (uint32_t a);\n" +
"uint16_t _somefunc_0 (uint32_t a);\n" +
"uint16_t _somefunc_1 (uint32_t a);\n" +
"uint16_t _somefunc_2(uint32_t a);\n"
@parser.treat_inlines = :include
@parser.inline_function_patterns = ['INLINE_THREE', 'INLINE_TWO', 'INLINE', 'static __inline__ __attribute__ \(\(always_inline\)\)', 'static __inline__']
assert_equal(expected, @parser.transform_inline_functions(source))
end
end