Class: GeneratorPartials
- Defined in:
- lib/ceedling/generators/generator_partials.rb
Instance Method Summary collapse
- #generate_implementation(test:, name:, function_definitions:, source_includes:, header_includes:, c_module:, output_path:) ⇒ Object
- #generate_interface(test:, name:, function_declarations:, includes:, c_module:, output_path:) ⇒ Object
-
#generate_types(name:, c_module:, output_path:) ⇒ String?
A module's typedefs and aggregate (struct/enum/union) definitions are the same regardless of which functions a given test file chooses to test versus mock, so they're generated once here into their own header rather than by generate_header itself.
Instance Method Details
#generate_implementation(test:, name:, function_definitions:, source_includes:, header_includes:, c_module:, output_path:) ⇒ Object
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 |
# File 'lib/ceedling/generators/generator_partials.rb', line 17 def generate_implementation( test:, name:, function_definitions:, source_includes:, header_includes:, c_module:, output_path: ) source = @file_path_utils.form_partial_implementation_source_filename(name) header = @file_path_utils.form_partial_implementation_header_filename(name) header_filepath = File.join(output_path, header) source_filepath = File.join(output_path, source) # Binary mode: the function bodies written below may already contain their # own line endings verbatim. Windows text mode rewrites every "\n" on # write, which would alter any line ending already present in that # content instead of passing it through unchanged. @file_wrapper.open(header_filepath, 'wb') do |file| generate_header(file, header, header_includes, function_definitions, c_module, true) end @file_wrapper.open(source_filepath, 'wb') do |file| generate_source(file, source_includes, function_definitions, c_module) end return source_filepath end |
#generate_interface(test:, name:, function_declarations:, includes:, c_module:, output_path:) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/ceedling/generators/generator_partials.rb', line 47 def generate_interface(test:, name:, function_declarations:, includes:, c_module:, output_path:) header = @file_path_utils.form_partial_interface_header_filename(name) filepath = File.join(output_path, header) # Binary mode: see generate_implementation above. @file_wrapper.open(filepath, 'wb') do |file| generate_header(file, header, includes, function_declarations, c_module, false) end return filepath end |
#generate_types(name:, c_module:, output_path:) ⇒ String?
A module's typedefs and aggregate (struct/enum/union) definitions are the same regardless of which functions a given test file chooses to test versus mock, so they're generated once here into their own header rather than by generate_header itself. Both the implementation and interface headers then simply #include this file, which means a module tested and mocked in the same test file -- each side producing its own generated header -- never ends up with two separate C definitions of the same type in one translation unit. Nothing is written and nil is returned when a module has no such content, since there's then nothing to share.
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 |
# File 'lib/ceedling/generators/generator_partials.rb', line 72 def generate_types(name:, c_module:, output_path:) return nil if c_module.type_definitions.empty? && c_module.aggregate_definitions.empty? header = @file_path_utils.form_partial_types_header_filename(name) filepath = File.join(output_path, header) # Binary mode: see generate_implementation above. @file_wrapper.open(filepath, 'wb') do |file| guard = FileWrapper.generate_include_guard(header) file << "#ifndef #{guard}\n" file << "#define #{guard}\n\n" anything_emitted = false pending_macros = [] c_module.element_sequence.each do |item| next unless item.is_a?(CExtractorTypes::CStatement) if c_module.macro_definitions.include?(item) pending_macros << item next end next unless type_defining?(item, c_module) # A typedef/struct/enum moved here may depend on a macro (e.g. an array-size # constant) that preceded it in the original source -- this header is #included # before any macro generate_header later emits inline into the non-shared # header, so that macro would otherwise be undefined here. Carrying it forward # is safe: an identical #define may legally repeat, so generate_header's own # unmodified inline copy causes no redefinition conflict. pending_macros.each { |macro| file << macro.text << "\n" } pending_macros.clear file << item.text << "\n" anything_emitted = true end file << "\n" if anything_emitted file << "#endif // #{guard}\n\n" end return header end |