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, mocks) ⇒ 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
filepathString-
C 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 = [] all_mocks = [] 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 new_deps, new_to_process, all_mocks = extract_includes_helper(target, include_paths, ignore_list, all_mocks) 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, mocks) ⇒ 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 |
# File 'lib/ceedling/preprocessinator_includes_handler.rb', line 92 def extract_includes_helper(filepath, include_paths, ignore_list, mocks) # Extract the dependencies from the make rule make_rule = self.form_shallow_dependencies_rule(filepath) target_file = make_rule.split[0].gsub(':', '').gsub('\\','/') base = File.basename(target_file, File.extname(target_file)) make_rule_dependencies = make_rule.gsub(/.*#{Regexp.escape(base)}\S*/, '').gsub(/\\$/, '') # Extract the headers dependencies from the make rule hdr_ext = @configurator.extension_header headers_dependencies = make_rule_dependencies.split.find_all {|path| path.end_with?(hdr_ext) }.uniq headers_dependencies.map! {|hdr| hdr.gsub('\\','/') } full_path_headers_dependencies = extract_full_path_dependencies(headers_dependencies) # Extract the sources dependencies from the make rule src_ext = @configurator.extension_source sources_dependencies = make_rule_dependencies.split.find_all {|path| path.end_with?(src_ext) }.uniq sources_dependencies.map! {|src| src.gsub('\\','/') } full_path_sources_dependencies = extract_full_path_dependencies(sources_dependencies) list = full_path_headers_dependencies + full_path_sources_dependencies to_process = [] if @configurator.project_config_hash.has_key?(:project_auto_link_deep_dependencies) && @configurator.project_config_hash[:project_auto_link_deep_dependencies] mock_prefix = @configurator.project_config_hash[:cmock_mock_prefix] # Creating list of mocks mocks += full_path_headers_dependencies.find_all do |header| File.basename(header) =~ /^#{mock_prefix}.*$/ end.compact # Creating list of headers that should be recursively pre-processed # Skipping mocks and vendor headers headers_to_deep_link = full_path_headers_dependencies.select do |hdr| !(mocks.include? hdr) and (hdr.match(/^(.*\/)(#{VENDORS_FILES.join('|')}) + #{Regexp.escape(hdr_ext)}$/).nil?) end headers_to_deep_link.map! {|hdr| File.(hdr) } headers_to_deep_link.compact! # ignore real file when both mock and real file exist mocks.each do |mock| list.each do |filename| if File.basename(filename) == File.basename(mock).sub(mock_prefix, '') ignore_list << filename end 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 src = @file_finder.find_compilation_input_file(hdr, :ignore) to_process << src if src end end end end return list, to_process, mocks 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
filepathString-
Path 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
159 160 161 |
# File 'lib/ceedling/preprocessinator_includes_handler.rb', line 159 def write_shallow_includes_list(filepath, list) @yaml_wrapper.dump(filepath, list) end |