Class: PreprocessinatorFileHandler
- Defined in:
- lib/ceedling/preprocessinator_file_handler.rb
Instance Method Summary collapse
- #assemble_preprocessed_header_file(filename:, preprocessed_filepath:, contents:, extras:, includes:) ⇒ Object
- #assemble_preprocessed_test_file(filename:, preprocessed_filepath:, contents:, extras:, includes:) ⇒ Object
- #collect_header_file_contents(source_filepath:, test:, flags:, defines:, include_paths:, extras:) ⇒ Object
- #collect_test_file_contents(source_filepath:, test:, flags:, defines:, include_paths:) ⇒ Object
Instance Method Details
#assemble_preprocessed_header_file(filename:, preprocessed_filepath:, contents:, extras:, includes:) ⇒ Object
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 |
# File 'lib/ceedling/preprocessinator_file_handler.rb', line 77 def assemble_preprocessed_header_file(filename:, preprocessed_filepath:, contents:, extras:, includes:) _contents = [] # Add #include guards for header files # Note: These aren't truly needed as preprocessed header files are only ingested by CMock. # They're created for sake of completeness and just in case... # ---------------------------------------------------- # abc-XYZ.h --> _ABC_XYZ_H_ guardname = '_' + filename.gsub(/\W/, '_').upcase + '_' forward_guards = [ "#ifndef #{guardname} // Ceedling-generated include guard", "#define #{guardname}", '' ] # Insert Ceedling notice # ---------------------------------------------------- comment = "// CEEDLING NOTICE: This generated file only to be consumed by CMock" _contents += [comment, ''] # Add guards to beginning of file contents _contents += forward_guards # Blank line _contents << '' # Reinsert #include statements into stripped down file includes.each{ |include| _contents << "#include \"#{include}\"" } # Blank line _contents << '' # Add in any macro defintions or prgamas extras.each do |ex| if ex.class == String _contents << ex elsif ex.class == Array _contents += ex end # Blank line _contents << '' end _contents += contents _contents += ['', "#endif // #{guardname}", ''] # Rear guard # Write file, collapsing any repeated blank lines # ---------------------------------------------------- _contents = _contents.join("\n") _contents.gsub!( /(\h*\n){3,}/, "\n\n" ) # Remove paths from expanded #include directives # ---------------------------------------------------- # - We rely on search paths at compilation rather than explicit #include paths # - Match (#include ")((path/)+)(file") and reassemble string using first and last matching groups _contents.gsub!( /(#include\s+")(([^\/]+\/)+)(.+")/, '\1\4' ) # Write contents of final preprocessed file @file_wrapper.write( preprocessed_filepath, _contents ) end |
#assemble_preprocessed_test_file(filename:, preprocessed_filepath:, contents:, extras:, includes:) ⇒ Object
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/ceedling/preprocessinator_file_handler.rb', line 191 def assemble_preprocessed_test_file(filename:, preprocessed_filepath:, contents:, extras:, includes:) _contents = [] # Insert Ceedling notice # ---------------------------------------------------- comment = "// CEEDLING NOTICE: This generated file only to be consumed for test runner creation" _contents += [comment, ''] # Blank line _contents << '' # Reinsert #include statements into stripped down file includes.each{ |include| _contents << "#include \"#{include}\"" } # Blank line _contents << '' # Add in test directive macro calls extras.each {|ex| _contents << ex} # Blank line _contents << '' _contents += contents # Write file, doing some prettyifying along the way # ---------------------------------------------------- _contents = _contents.join("\n") _contents.gsub!( /^\s*;/, '' ) # Drop blank lines with semicolons left over from macro expansion + trailing semicolon _contents.gsub!( /\)\s+\{/, ")\n{" ) # Collapse any unnecessary white space between closing argument paren and opening function bracket _contents.gsub!( /\{(\n){2,}/, "{\n" ) # Collapse any unnecessary white space between opening function bracket and code _contents.gsub!( /(\n){2,}\}/, "\n}" ) # Collapse any unnecessary white space between code and closing function bracket _contents.gsub!( /(\h*\n){3,}/, "\n\n" ) # Collapse repeated blank lines # Write contents of final preprocessed file @file_wrapper.write( preprocessed_filepath, _contents ) end |
#collect_header_file_contents(source_filepath:, test:, flags:, defines:, include_paths:, extras:) ⇒ Object
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 |
# File 'lib/ceedling/preprocessinator_file_handler.rb', line 14 def collect_header_file_contents(source_filepath:, test:, flags:, defines:, include_paths:, extras:) contents = [] # Our extra file content to be preserved # Leave these empty if :extras is false pragmas = [] macro_defs = [] preprocessed_filepath = @file_path_utils.form_preprocessed_file_full_expansion_filepath( source_filepath, test ) # Run GCC with full preprocessor expansion command = @tool_executor.build_command_line( @configurator.tools_test_file_full_preprocessor, flags, source_filepath, preprocessed_filepath, defines, include_paths ) @tool_executor.exec( command ) @file_wrapper.open( preprocessed_filepath, 'r' ) do |file| contents = @preprocessinator_extractor.extract_file_as_array_from_expansion( file, preprocessed_filepath ) end # Bail out, skipping directives-only preprocessing if no extras are required return contents, (pragmas + macro_defs) if !extras preprocessed_filepath = @file_path_utils.form_preprocessed_file_directives_only_filepath( source_filepath, test ) # Run GCC with directives-only preprocessor expansion command = @tool_executor.build_command_line( @configurator.tools_test_file_directives_only_preprocessor, flags, source_filepath, preprocessed_filepath, defines, include_paths ) @tool_executor.exec( command ) # Try to find an #include guard in the first 2k of the file text. # An #include guard is one macro from the original file we don't want to preserve if we can help it. # We create our own #include guard in the header file we create. # It's possible preserving the macro from the original file's #include guard could trip something up. # Of course, it's also possible some header conditional compilation feature is dependent on it. # ¯\_(ツ)_/¯ include_guard = @preprocessinator_extractor.extract_include_guard( @file_wrapper.read( source_filepath, 2048 ) ) @file_wrapper.open( preprocessed_filepath, 'r' ) do |file| # Get code contents of preprocessed directives-only file as a string # TODO: Modify to process line-at-a-time for memory savings & performance boost _contents = @preprocessinator_extractor.extract_file_as_string_from_expansion( file, preprocessed_filepath ) # Extract pragmas and macros from pragmas = @preprocessinator_extractor.extract_pragmas( _contents ) macro_defs = @preprocessinator_extractor.extract_macro_defs( _contents, include_guard ) end return contents, (pragmas + macro_defs) end |
#collect_test_file_contents(source_filepath:, test:, flags:, defines:, include_paths:) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/ceedling/preprocessinator_file_handler.rb', line 143 def collect_test_file_contents(source_filepath:, test:, flags:, defines:, include_paths:) contents = [] # TEST_SOURCE_FILE() and TEST_INCLUDE_PATH() test_directives = [] preprocessed_filepath = @file_path_utils.form_preprocessed_file_full_expansion_filepath( source_filepath, test ) # Run GCC with full preprocessor expansion command = @tool_executor.build_command_line( @configurator.tools_test_file_full_preprocessor, flags, source_filepath, preprocessed_filepath, defines, include_paths ) @tool_executor.exec( command ) @file_wrapper.open( preprocessed_filepath, 'r' ) do |file| contents = @preprocessinator_extractor.extract_file_as_array_from_expansion( file, preprocessed_filepath ) end preprocessed_filepath = @file_path_utils.form_preprocessed_file_directives_only_filepath( source_filepath, test ) # Run GCC with directives-only preprocessor expansion command = @tool_executor.build_command_line( @configurator.tools_test_file_directives_only_preprocessor, flags, source_filepath, preprocessed_filepath, defines, include_paths ) @tool_executor.exec( command ) @file_wrapper.open( preprocessed_filepath, 'r' ) do |file| # Get code contents of preprocessed directives-only file as a string # TODO: Modify to process line-at-a-time for memory savings & performance boost _contents = @preprocessinator_extractor.extract_file_as_string_from_expansion( file, preprocessed_filepath ) # Extract TEST_SOURCE_FILE() and TEST_INCLUDE_PATH() test_directives = @preprocessinator_extractor.extract_test_directive_macro_calls( _contents ) end return contents, test_directives end |