Merge pull request #141 from jlindgren90/fix-const-parsing

Fix const determination for pointer-to-pointer types. (Thanks John! (@jlindgren90) )
This commit is contained in:
Mark VanderVoord
2017-09-08 13:03:27 -04:00
committed by GitHub
2 changed files with 118 additions and 29 deletions
+17 -26
View File
@@ -146,44 +146,35 @@ class CMockHeaderParser
return args if (arg =~ /^\s*((\.\.\.)|(void))\s*$/) # we're done if we reach void by itself or ...
arg_array = arg.split
arg_elements = arg_array - @c_attributes # split up words and remove known attributes
args << { :type => (arg_type = arg_elements[0..-2].join(' ')),
args << { :type => arg_elements[0..-2].join(' '),
:name => arg_elements[-1]
}.merge(divine_ptr_and_const(arg))
end
return args
end
def divine_ptr(arg_type)
return false unless arg_type.include? '*'
return false if arg_type.gsub(/(const|char|\*|\s)+/,'').empty?
def divine_ptr(arg)
return false unless arg.include? '*'
# treat "const char *" and similar as a string, not a pointer
return false if /(^|\s)(const\s+)?char(\s+const)?\s*\*(?!.*\*)/ =~ arg
return true
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
@@ -237,8 +228,8 @@ class CMockHeaderParser
#process function attributes, return type, and name
descriptors = regex_match[1]
descriptors.gsub!(/\s+\*/,'*') #remove space to place asterisks with return type (where they belong)
descriptors.gsub!(/\*(\w)/,'* \1') #pull asterisks away from function name to place asterisks with return type (where they belong)
descriptors.gsub!(/(\w)\*/,'\1 *') #pull asterisks away from preceding word
descriptors.gsub!(/\*(\w)/,'* \1') #pull asterisks away from following word
descriptors = descriptors.split #array of all descriptor strings
#grab name
@@ -258,7 +249,7 @@ class CMockHeaderParser
end
end
decl[:modifier] = decl[:modifier].join(' ')
rettype = rettype.join(' ')
rettype = rettype.join(' ').gsub(/\s+\*/,'*') #remove space before asterisks
rettype = 'void' if (@local_as_void.include?(rettype.strip))
decl[:return] = { :type => rettype,
:name => 'cmock_to_return',