Class: PreprocessinatorIncludesHandler
- Defined in:
- lib/ceedling/preprocessinator_includes_handler.rb
Constant Summary collapse
- @@makefile_cache =
{}
Instance Method Summary collapse
-
#extract_includes(filepath) ⇒ Object
Extract the headers that are directly included by a source file using the provided, annotated Make dependency rule.
- #extract_includes_helper(filepath, include_paths, ignore_list) ⇒ Object
-
#form_shallow_dependencies_rule(filepath) ⇒ Object
Ask the preprocessor for a make-style dependency rule of only the headers the source file immediately includes.
-
#invoke_shallow_includes_list(filepath) ⇒ Object
shallow includes: only those headers a source file explicitly includes.
- #write_shallow_includes_list(filepath, list) ⇒ Object
Instance Method Details
#extract_includes(filepath) ⇒ Object
Extract the headers that are directly included by a source file using the provided, annotated Make dependency rule.
Arguments
filepathStringC source or header file to extract includes for.
Return
- Array of String
Array of the direct dependencies for the source file.
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 |
# File 'lib/ceedling/preprocessinator_includes_handler.rb', line 64 def extract_includes(filepath) to_process = [filepath] ignore_list = [] list = [] include_paths = @configurator.project_config_hash[:collection_paths_include] include_paths = [] if include_paths.nil? include_paths.map! {|path| File.(path)} while to_process.length > 0 target = to_process.shift() ignore_list << target # puts "[HELL] Processing: \t\t#{target}" new_deps, new_to_process = extract_includes_helper(target, include_paths, ignore_list) list += new_deps to_process += new_to_process if (!@configurator.project_config_hash.has_key?(:project_auto_link_deep_dependencies) or !@configurator.project_config_hash[:project_auto_link_deep_dependencies]) break else list = list.uniq() to_process = to_process.uniq() end end return list end |
#extract_includes_helper(filepath, include_paths, ignore_list) ⇒ Object
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 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/ceedling/preprocessinator_includes_handler.rb', line 92 def extract_includes_helper(filepath, include_paths, ignore_list) # Extract the dependencies from the make rule hdr_ext = @configurator.extension_header make_rule = self.form_shallow_dependencies_rule(filepath) dependencies = make_rule.split.find_all {|path| path.end_with?(hdr_ext) }.uniq dependencies.map! {|hdr| hdr.gsub('\\','/') } # Separate the real files form the annotated ones and remove the '@@@@' annotated_headers, real_headers = dependencies.partition {|hdr| hdr =~ /^@@@@/ } annotated_headers.map! {|hdr| hdr.gsub('@@@@','') } # Matching annotated_headers values against real_headers to ensure that # annotated_headers contain full path entries (as returned by make rule) annotated_headers.map! {|hdr| real_headers.find {|real_hdr| !real_hdr.match(/(.*\/)?#{Regexp.escape(hdr)}/).nil? } } annotated_headers = annotated_headers.compact # Find which of our annotated headers are "real" dependencies. This is # intended to weed out dependencies that have been removed due to build # options defined in the project yaml and/or in the headers themselves. list = annotated_headers.find_all do |annotated_header| # find the index of the "real" include that matches the annotated one. idx = real_headers.find_index do |real_header| real_header =~ /^(.*\/)?#{Regexp.escape(annotated_header)}$/ end # If we found a real include, delete it from the array and return it, # otherwise return nil. Since nil is falsy this has the effect of making # find_all return only the annotated headers for which a real include was # found/deleted idx ? real_headers.delete_at(idx) : nil end.compact # Extract direct dependencies that were also added src_ext = @configurator.extension_source sdependencies = make_rule.split.find_all {|path| path.end_with?(src_ext) }.uniq sdependencies.map! {|hdr| hdr.gsub('\\','/') } list += sdependencies to_process = [] if @configurator.project_config_hash.has_key?(:project_auto_link_deep_dependencies) && @configurator.project_config_hash[:project_auto_link_deep_dependencies] # Creating list of mocks mocks = annotated_headers.find_all do |annotated_header| File.basename(annotated_header) =~ /^#{@configurator.project_config_hash[:cmock_mock_prefix]}.*$/ end.compact # Creating list of headers that should be recursively pre-processed # Skipping mocks and unity.h headers_to_deep_link = annotated_headers.select do |annotated_header| !(mocks.include? annotated_header) and (annotated_header.match(/^(.*\/)?unity\.h$/).nil?) end headers_to_deep_link.map! {|hdr| File.(hdr)} mocks.each do |mock| dirname = File.dirname(mock) #basename = File.basename(mock).delete_prefix(@configurator.project_config_hash[:cmock_mock_prefix]) basename = File.basename(mock).sub(@configurator.project_config_hash[:cmock_mock_prefix], '') if dirname != "." ignore_list << File.join(dirname, basename) else ignore_list << basename end end.compact # Filtering list of final includes to only include mocks and anything that is NOT in the ignore_list list = list.select do |item| mocks.include? item or !(ignore_list.any? { |ignore_item| !item.match(/^(.*\/)?#{Regexp.escape(ignore_item)}$/).nil? }) end headers_to_deep_link.each do |hdr| if (ignore_list.none? {|ignore_header| hdr.match(/^(.*\/)?#{Regexp.escape(ignore_header)}$/)} and include_paths.none? {|include_path| hdr =~ /^#{include_path}\.*/}) if File.exist?(hdr) to_process << hdr #source_file = hdr.delete_suffix(hdr_ext) + src_ext source_file = hdr.chomp(hdr_ext) + src_ext if source_file != hdr and File.exist?(source_file) to_process << source_file end end end end end return list, to_process end |
#form_shallow_dependencies_rule(filepath) ⇒ Object
Ask the preprocessor for a make-style dependency rule of only the headers the source file immediately includes.
Arguments
filepathStringPath to the test file to process.
Return
- String
The text of the dependency rule generated by the preprocessor.
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 |
# File 'lib/ceedling/preprocessinator_includes_handler.rb', line 23 def form_shallow_dependencies_rule(filepath) if @@makefile_cache.has_key?(filepath) return @@makefile_cache[filepath] end # change filename (prefix of '_') to prevent preprocessor from finding # include files in temp directory containing file it's scanning temp_filepath = @file_path_utils.form_temp_path(filepath, '_') # read the file and replace all include statements with a decorated version # (decorating the names creates file names that don't exist, thus preventing # the preprocessor from snaking out and discovering the entire include path # that winds through the code). The decorated filenames indicate files that # are included directly by the test file. contents = @file_wrapper.read(filepath) if !contents.valid_encoding? contents = contents.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8') end contents.gsub!( /^\s*#include\s+[\"<]\s*(\S+)\s*[\">]/, "#include \"\\1\"\n#include \"@@@@\\1\"" ) contents.gsub!( /^\s*TEST_FILE\(\s*\"\s*(\S+)\s*\"\s*\)/, "#include \"\\1\"\n#include \"@@@@\\1\"") @file_wrapper.write( temp_filepath, contents ) # extract the make-style dependency rule telling the preprocessor to # ignore the fact that it can't find the included files command = @tool_executor.build_command_line(@configurator.tools_test_includes_preprocessor, [], temp_filepath) shell_result = @tool_executor.exec(command[:line], command[:options]) @@makefile_cache[filepath] = shell_result[:output] return shell_result[:output] end |
#invoke_shallow_includes_list(filepath) ⇒ Object
shallow includes: only those headers a source file explicitly includes
10 11 12 |
# File 'lib/ceedling/preprocessinator_includes_handler.rb', line 10 def invoke_shallow_includes_list(filepath) @task_invoker.invoke_test_shallow_include_lists( [@file_path_utils.form_preprocessed_includes_list_filepath(filepath)] ) end |
#write_shallow_includes_list(filepath, list) ⇒ Object
178 179 180 |
# File 'lib/ceedling/preprocessinator_includes_handler.rb', line 178 def write_shallow_includes_list(filepath, list) @yaml_wrapper.dump(filepath, list) end |