1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
# Creates mock files from parsed header files that can be linked into applications.
# The mocks created are compatible with CMock for use with Ceedling.
class FffMockGenerator
def self.create_mock_header(module_name, mock_name, parsed_header, pre_includes=nil,
post_includes=nil)
output = StringIO.new
write_opening_include_guard(mock_name, output)
output.puts
write_extra_includes(pre_includes, output)
write_header_includes(module_name, output)
write_extra_includes(post_includes, output)
output.puts
write_typedefs(parsed_header, output)
output.puts
write_function_declarations(parsed_header, output)
output.puts
write_control_function_prototypes(mock_name, output)
output.puts
write_closing_include_guard(mock_name, output)
output.string
end
def self.create_mock_source (mock_name, parsed_header, pre_includes=nil,
post_includes=nil)
output = StringIO.new
write_extra_includes(pre_includes, output)
write_source_includes(mock_name, output)
write_extra_includes(post_includes, output)
output.puts
write_function_definitions(parsed_header, output)
output.puts
write_control_function_definitions(mock_name, parsed_header, output)
output.string
end
private
# Header file generation functions.
def self.write_opening_include_guard(mock_name, output)
output.puts "#ifndef #{mock_name}_H"
output.puts "#define #{mock_name}_H"
end
def self.write_header_includes(module_name, output)
output.puts %{#include "fff.h"}
output.puts %{#include "fff_unity_helper.h"}
output.puts %{#include "#{module_name}.h"}
end
def self.write_typedefs(parsed_header, output)
return unless parsed_header.key?(:typedefs)
parsed_header[:typedefs].each do |typedef|
output.puts typedef
end
end
def self.write_function_declarations(parsed_header, output)
write_function_macros("DECLARE", parsed_header, output)
end
def self.write_control_function_prototypes(mock_name, output)
output.puts "void #{mock_name}_Init(void);"
output.puts "void #{mock_name}_Verify(void);"
output.puts "void #{mock_name}_Destroy(void);"
end
def self.write_closing_include_guard(mock_name, output)
output.puts "#endif // #{mock_name}_H"
end
# Source file generation functions.
def self.write_source_includes (mock_name, output)
output.puts "#include <string.h>"
output.puts %{#include "fff.h"}
output.puts %{#include "#{mock_name}.h"}
end
def self.write_function_definitions(parsed_header, output)
write_function_macros("DEFINE", parsed_header, output)
end
def self.write_control_function_definitions(mock_name, parsed_header, output)
output.puts "void #{mock_name}_Init(void)"
output.puts "{"
# In the init function, reset the FFF globals. These are used for things
# like the call history.
output.puts " FFF_RESET_HISTORY();"
# Also, reset all of the fakes.
if parsed_header[:functions]
parsed_header[:functions].each do |function|
output.puts " RESET_FAKE(#{function[:name]})"
end
end
output.puts "}"
output.puts "void #{mock_name}_Verify(void)"
output.puts "{"
output.puts "}"
output.puts "void #{mock_name}_Destroy(void)"
output.puts "{"
output.puts "}"
end
# Shared functions.
def self.write_extra_includes(includes, output)
if includes
includes.each {|inc| output.puts "#include #{inc}\n"}
end
end
def self.write_function_macros(macro_type, parsed_header, output)
return unless parsed_header.key?(:functions)
parsed_header[:functions].each do |function|
name = function[:name]
return_type = function[:return][:type]
if function.has_key? :modifier
# Prepend any modifier. If there isn't one, trim any leading whitespace.
return_type = "#{function[:modifier]} #{return_type}".lstrip
end
arg_count = function[:args].size
# Check for variable arguments.
var_arg_suffix = ""
if function[:var_arg]
# If there are are variable arguments, then we need to add this argument
# to the count, update the suffix that will get added to the macro.
arg_count += 1
var_arg_suffix = "_VARARG"
end
# Generate the correct macro.
if return_type == 'void'
output.print "#{macro_type}_FAKE_VOID_FUNC#{arg_count}#{var_arg_suffix}(#{name}"
else
output.print "#{macro_type}_FAKE_VALUE_FUNC#{arg_count}#{var_arg_suffix}(#{return_type}, #{name}"
end
# Append each argument type.
function[:args].each do |arg|
output.print ", "
if arg[:const?]
output.print "const "
end
output.print "#{arg[:type]}"
end
# If this argument list ends with a variable argument, add it here at the end.
if function[:var_arg]
output.print ", ..."
end
# Close the declaration.
output.puts ");"
end
end
end
|