Class: PartializerUtils
- Includes:
- Partials
- Defined in:
- lib/ceedling/partials/partializer_utils.rb
Constant Summary
Constants included from Partials
Partials::ACCUMULATE, Partials::DEDUCT, Partials::MOCK_PRIVATE, Partials::MOCK_PUBLIC, Partials::PRIVATE, Partials::PUBLIC, Partials::TEST_PRIVATE, Partials::TEST_PUBLIC
Instance Method Summary collapse
-
#format_line_number_list(funcs) ⇒ Array<String>
Format per-function line-number results as a list of human-readable strings.
-
#locate_function_in_source(code_block:, filepath:) ⇒ Integer?
Locate a function's line number by searching the original C source file.
-
#locate_function_via_preprocessed(code_block:, filepath:, preprocessed_filepath:) ⇒ Integer?
Locate a function's line number using preprocessed output with C source fallback.
-
#matches_visibility?(decorators, visibility) ⇒ Boolean
Check if function decorators match the desired visibility.
-
#rename_c_identifier(text, old_name, new_name) ⇒ String
Rename a C identifier throughout a text block with token-bounded substitution.
-
#replace_compound_declaration_with_noops(text, original_decl, placeholder, count) ⇒ String
Replace a C compound variable declaration with N no-op expressions and a single comment.
-
#replace_declaration_with_noop(text, original_decl, placeholder) ⇒ String
Replace a C variable declaration in a text block with a no-op expression.
- #setup ⇒ Object
-
#stamp_source_filepaths(funcs, filepath) ⇒ Object
Stamp the originating source filepath onto each function in a collection.
-
#transform_function(func, signature, output_type) ⇒ Object
Transform function to appropriate output format
FunctionDefinitionorFunctionDeclaration.
Methods included from Partials
manufacture_function_declaration, manufacture_function_definition
Instance Method Details
#format_line_number_list(funcs) ⇒ Array<String>
Format per-function line-number results as a list of human-readable strings.
Produces one entry per function in the form "name(): <line_num>".
Functions with no resolved line number are rendered with 'N/A'.
The returned array is passed directly to @loginator.log_list for debug output.
177 178 179 180 181 |
# File 'lib/ceedling/partials/partializer_utils.rb', line 177 def format_line_number_list(funcs) funcs.map do |func| "#{func.name}(): #{func.line_num.nil? ? 'N/A' : func.line_num.to_s()}" end end |
#locate_function_in_source(code_block:, filepath:) ⇒ Integer?
Locate a function's line number by searching the original C source file.
Used when the global fallback mode is active — i.e., preprocessed output is
unavailable for all functions in the current context. Delegates directly to
code_finder.find_in_c_file.
143 144 145 |
# File 'lib/ceedling/partials/partializer_utils.rb', line 143 def locate_function_in_source(code_block:, filepath:) @code_finder.find_in_c_file(filepath, code_block) end |
#locate_function_via_preprocessed(code_block:, filepath:, preprocessed_filepath:) ⇒ Integer?
Locate a function's line number using preprocessed output with C source fallback.
Two-strategy lookup for a single function:
1. Try the GCC-preprocessed directives-only file — exact match preserving line markers.
2. If that yields nil, fall back to the original C source file.
Returns line number or nil if neither approach succeeds.
159 160 161 162 163 164 165 166 167 |
# File 'lib/ceedling/partials/partializer_utils.rb', line 159 def locate_function_via_preprocessed(code_block:, filepath:, preprocessed_filepath:) line_num = @code_finder.find_in_preprpocessed_file(preprocessed_filepath, code_block) return line_num unless line_num.nil? msg = "Using fallback C function location search for #{filepath}" @loginator.log( msg, Verbosity::OBNOXIOUS, LogLabels::WARNING ) return @code_finder.find_in_c_file(filepath, code_block) end |
#matches_visibility?(decorators, visibility) ⇒ Boolean
Check if function decorators match the desired visibility
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/ceedling/partials/partializer_utils.rb', line 24 def matches_visibility?(decorators, visibility) case visibility when PUBLIC return !is_function_private?(decorators) when PRIVATE return is_function_private?(decorators) else PartializerRuntime.raise_on_option(visibility) end end |
#rename_c_identifier(text, old_name, new_name) ⇒ String
Rename a C identifier throughout a text block with token-bounded substitution.
Replaces all occurrences of old_name that are bounded by C identifier boundaries
with new_name. Token boundaries use Ruby \b (word boundary between
\w = [a-zA-Z0-9_] and \W), which exactly matches C identifier boundaries.
For example, renaming count:
- Matches: `count = 0`, `(count)`, `count==5`, `*count`, `count[0]`
- No match: `count_down`, `up_count`, `recount`
Note: This method has no comment-awareness. Callers that need comment content
preserved verbatim (e.g., no-op placeholders) should use replace_declaration_with_noop
with an opaque placeholder and restore the original text after renaming.
118 119 120 |
# File 'lib/ceedling/partials/partializer_utils.rb', line 118 def rename_c_identifier(text, old_name, new_name) text.gsub(/\b#{Regexp.escape(old_name)}\b/, new_name) end |
#replace_compound_declaration_with_noops(text, original_decl, placeholder, count) ⇒ String
Replace a C compound variable declaration with N no-op expressions and a single comment.
Generates count (void)0; expressions where the final one carries a comment
containing placeholder. The result replaces the first occurrence of original_decl
in text. The caller supplies count = number of variables in the compound statement
and a single unique placeholder token. After all variable renames are complete, the
caller restores original_decl by replacing the placeholder with the original text.
Block form of sub is used so that \ and & in the declaration are not interpreted
as regex replacement backreferences.
95 96 97 98 99 |
# File 'lib/ceedling/partials/partializer_utils.rb', line 95 def replace_compound_declaration_with_noops(text, original_decl, placeholder, count) noops = "(void)0; " * (count - 1) comment = "(void)0; /* `#{placeholder}` replaced with no-op plus variable renamed & promoted to module-scope */" text.sub(original_decl) { noops + comment } end |
#replace_declaration_with_noop(text, original_decl, placeholder) ⇒ String
Replace a C variable declaration in a text block with a no-op expression.
Substitutes the first occurrence of original_decl in text with:
(void)0; /* <placeholder> */
The caller supplies a unique placeholder token for the comment slot. This
allows subsequent rename operations (which use simple token-bounded substitution
with no comment awareness) to run without touching the comment. After all renames
are complete, the caller restores original_decl by replacing the placeholder.
Block form of sub is used so that \ and & in the declaration are not
interpreted as regex replacement backreferences.
75 76 77 |
# File 'lib/ceedling/partials/partializer_utils.rb', line 75 def replace_declaration_with_noop(text, original_decl, placeholder) replace_compound_declaration_with_noops(text, original_decl, placeholder, 1) end |
#setup ⇒ Object
18 19 20 21 |
# File 'lib/ceedling/partials/partializer_utils.rb', line 18 def setup() # Aliases @code_finder = @preprocessinator_code_finder end |
#stamp_source_filepaths(funcs, filepath) ⇒ Object
Stamp the originating source filepath onto each function in a collection.
Mutates each element of funcs in place by assigning filepath to its
source_filepath field. Called before any line-number search so the field
is always populated regardless of whether a line number is ultimately found.
130 131 132 |
# File 'lib/ceedling/partials/partializer_utils.rb', line 130 def stamp_source_filepaths(funcs, filepath) funcs.each { |func| func.source_filepath = filepath } end |
#transform_function(func, signature, output_type) ⇒ Object
Transform function to appropriate output format FunctionDefinition or FunctionDeclaration
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/ceedling/partials/partializer_utils.rb', line 36 def transform_function(func, signature, output_type) case output_type when :impl # Strip decorators from the front of code_block and count how many newlines were removed. # Adjust line_num upward so that emitted #line directives remain accurate. new_code_block, stripped_newlines = extract_code_block(func.code_block, func.decorators) Partials.manufacture_function_definition( name: func.name, signature: signature, source_filepath: func.source_filepath, line_num: adjust_line_num(func.line_num, stripped_newlines), code_block: new_code_block ) when :interface Partials.manufacture_function_declaration( name: func.name, signature: signature ) else PartializerRuntime.raise_on_option(output_type) end end |