mirror of
https://github.com/ThrowTheSwitch/CMock.git
synced 2026-09-21 09:37:26 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user