Class: PreprocessinatorLineMarkerIncludesExtractor

Inherits:
Object
  • Object
show all
Defined in:
lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb

Overview

Parse GCC preprocessor output (from -fdirectives-only) to extract system include directives

Constant Summary collapse

LINE_MARKER_REGEX =
/^#\s+(\d+)\s+"([^"]+)"(?:\s+(\d+(?:\s+\d+)*))?$/
SYSTEM =
:system
USER =
:user

Instance Method Summary collapse

Instance Method Details

#extract_includes_from_file(filepath, type, max_depth = nil) ⇒ Array<UserInclude, SystemInclude>

Parse preprocessor output from a file (production use)

Parameters:

  • filepath (String)

    Path to the preprocessor output file

Returns:



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb', line 95

def extract_includes_from_file(filepath, type, max_depth=nil)
  validate_type_argument( type )
  includes = []
  begin
    # Open in binary mode: GCC output under a non-C locale contains non-ASCII bytes
    # (e.g. <組み込み> for <built-in> under ja_JP). Text mode would interpret those
    # bytes using the locale-dependent external encoding (e.g. Windows-31J on ja_JP
    # Windows), raising an encoding error on read. Binary mode bypasses that translation.
    # LINE_MARKER_REGEX uses only ASCII delimiters and is safe in binary mode.
    # The filepath.start_with?('<') guard correctly skips localized markers because
    # their first byte is 0x3C — ASCII '<' — regardless of the surrounding encoding.
    # NOTE: binary mode means \r\n line endings are NOT translated on Windows; the
    # extract_includes method calls line.chomp! before regex matching to handle this.
    File.open(filepath, 'rb') do |file|
      includes = extract_includes(io: file, filepath: filepath, type: type, max_depth: max_depth)
    end
  rescue StandardError => e
    raise CeedlingException.new("Failed to extract #{type} includes from preprocessor output file '#{filepath}' ⏩️ #{e.message}")
  end
  return includes
end

#extract_includes_from_string(content, filepath, type, max_depth = nil) ⇒ Array<UserInclude, SystemInclude>

Parse preprocessor output from a string (testing use)

Parameters:

  • content (String)

    Preprocessor output as a string

Returns:



120
121
122
123
124
125
# File 'lib/ceedling/preprocess/preprocessinator_line_marker_includes_extractor.rb', line 120

def extract_includes_from_string(content, filepath, type, max_depth=nil)
  validate_type_argument( type )
  require 'stringio'
  io = StringIO.new(content)
  return extract_includes(io: io, filepath: filepath, type: type, max_depth: max_depth)
end