Fix const determination for pointer-to-pointer types.

For example, consider: void function(const int **ret_ptr).
This function stores a (const int *) at the address passed in.
We'd want to test it with function_ReturnThruPtr_ret_ptr, but
CMock was incorrectly considering the (const int **) a constant
argument, and thus did not generate the ReturnThruPtr function.

Add a test to ensure that all permutations of constants and
pointers work as expected.
This commit is contained in:
John Lindgren
2017-08-31 16:33:21 -04:00
parent 46f609efee
commit 693c658780
2 changed files with 43 additions and 19 deletions
+9 -19
View File
@@ -160,30 +160,20 @@ class CMockHeaderParser
end
def divine_const(arg)
return false if !(/(?:^|\s|\*)const(?:\*|\s|$)/ =~ arg) # check for const as part of a larger word
return true if (/const(?:\w|\s)*\*/ =~ arg) # check const comes before * indicating const data
return false if (/\*\s*const/ =~ arg) # check const comes after * indicating const ptr
return true
# a non-pointer arg containing "const" is a constant
# an arg containing "const" before the last * is a pointer to a constant
return ( arg.include?('*') ? (/(^|\s|\*)const(\s(\w|\s)*)?\*(?!.*\*)/ =~ arg)
: (/(^|\s)const(\s|$)/ =~ arg) ) ? true : false
end
def divine_ptr_and_const(arg)
divination = { :ptr? => false, :const? => false, :const_ptr? => false }
divination = {}
#first check if there is a pointer present and that it's not part of a C string or function definition
#divination[:ptr?] = (arg.split[0..-2].join.include?('*') && !arg.gsub(/(const|char|\*|\s)+/,'').empty?)
divination[:ptr?] = (arg.include?('*') && !arg.gsub(/(const|char|\*|\s)+/,'').empty?)
divination[:ptr?] = divine_ptr(arg)
divination[:const?] = divine_const(arg)
#if there isn't a const that isn't part of a larger word, we're done
return divination if !(/(?:^|\s|\*)const(?:\*|\s|$)/ =~ arg)
divination[:const?] = true
# check const comes after * indicating const ptr
if (/\*\s*const/ =~ arg)
divination[:const_ptr?] = true
#check const comes before * indicating also const data
divination[:const?] = (/const(?:\w|\s)*\*/ =~ arg) ? true : false
end
# an arg containing "const" after the last * is a constant pointer
divination[:const_ptr?] = (/\*(?!.*\*)\s*const(\s|$)/ =~ arg) ? true : false
return divination
end
+34
View File
@@ -1510,4 +1510,38 @@ describe CMockHeaderParser, "Verify CMockHeaderParser Module" do
assert_equal(expected, @parser.parse("module", source)[:functions])
end
it "divines all permutations of ptr, const, and const_ptr correctly" do
truth_table = [
# argument ptr const const_ptr
[ "constNOTconst constNOTconst", false, false, false ],
[ "const constNOTconst constNOTconst", false, true, false ],
[ "constNOTconst const constNOTconst", false, true, false ],
[ "constNOTconst *constNOTconst", true, false, false ],
[ "const constNOTconst *constNOTconst", true, true, false ],
[ "constNOTconst const *constNOTconst", true, true, false ],
[ "constNOTconst *const constNOTconst", true, false, true ],
[ "const constNOTconst *const constNOTconst", true, true, true ],
[ "constNOTconst const *const constNOTconst", true, true, true ],
[ "constNOTconst **constNOTconst", true, false, false ],
[ "const constNOTconst **constNOTconst", true, false, false ],
[ "constNOTconst const **constNOTconst", true, false, false ],
[ "constNOTconst *const *constNOTconst", true, true, false ],
[ "const constNOTconst *const *constNOTconst", true, true, false ],
[ "constNOTconst const *const *constNOTconst", true, true, false ],
[ "constNOTconst **const constNOTconst", true, false, true ],
[ "const constNOTconst **const constNOTconst", true, false, true ],
[ "constNOTconst const **const constNOTconst", true, false, true ],
[ "constNOTconst *const *const constNOTconst", true, true, true ],
[ "const constNOTconst *const *const constNOTconst", true, true, true ],
[ "constNOTconst const *const *const constNOTconst", true, true, true ]
]
truth_table.each do |entry|
assert_equal(@parser.divine_ptr(entry[0]), entry[1])
assert_equal(@parser.divine_const(entry[0]), entry[2])
assert_equal(@parser.divine_ptr_and_const(entry[0]),
{ ptr?: entry[1], const?: entry[2], const_ptr?: entry[3] })
end
end
end