-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
227 additions
and
123 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# ========================================================================= | ||
# Ceedling - Test-Centered Build System for C | ||
# ThrowTheSwitch.org | ||
# Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams | ||
# SPDX-License-Identifier: MIT | ||
# ========================================================================= | ||
|
||
require 'ceedling/encodinator' | ||
|
||
# This is a collection of parsing aids to be used in other modules | ||
class ParsingParcels | ||
|
||
# This parser accepts a collection of lines which it will sweep through and tidy, giving the purified | ||
# lines to the block (one line at a time) for further analysis. It analyzes a single line at a time, | ||
# which is far more memory efficient and faster for large files. However, this requires it to also | ||
# handle backslash line continuations as a single line at this point. | ||
def code_lines(input) | ||
comment_block = false | ||
full_line = '' | ||
input.each_line do |line| | ||
m = line.match /(.*)\\\s*$/ | ||
if (!m.nil?) | ||
full_line += m[1] | ||
elsif full_line.empty? | ||
_line, comment_block = clean_code_line( line, comment_block ) | ||
yield( _line ) | ||
else | ||
_line, comment_block = clean_code_line( full_line + line, comment_block ) | ||
yield( _line ) | ||
full_line = '' | ||
end | ||
end | ||
end | ||
|
||
private ###################################################################### | ||
|
||
def clean_code_line(line, comment_block) | ||
_line = line.clean_encoding | ||
|
||
# Remove line comments | ||
_line.gsub!(/\/\/.*$/, '') | ||
|
||
# Handle end of previously begun comment block | ||
if comment_block | ||
if _line.include?( '*/' ) | ||
# Turn off comment block handling state | ||
comment_block = false | ||
|
||
# Remove everything up to end of comment block | ||
_line.gsub!(/^.*\*\//, '') | ||
else | ||
# Ignore contents of the line if its entirely within a comment block | ||
return '', comment_block | ||
end | ||
|
||
end | ||
|
||
# Block comments inside a C string are valid C, but we remove to simplify other parsing. | ||
# No code we care about will be inside a C string. | ||
# Note that we're not attempting the complex case of multiline string enclosed comment blocks | ||
_line.gsub!(/"\s*\/\*.*"/, '') | ||
|
||
# Remove single-line block comments | ||
_line.gsub!(/\/\*.*\*\//, '') | ||
|
||
# Handle beginning of any remaining multiline comment block | ||
if _line.include?( '/*' ) | ||
comment_block = true | ||
|
||
# Remove beginning of block comment | ||
_line.gsub!(/\/\*.*/, '') | ||
end | ||
|
||
return _line, comment_block | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# ========================================================================= | ||
# Ceedling - Test-Centered Build System for C | ||
# ThrowTheSwitch.org | ||
# Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams | ||
# SPDX-License-Identifier: MIT | ||
# ========================================================================= | ||
|
||
require 'spec_helper' | ||
require 'ceedling/parsing_parcels' | ||
|
||
describe ParsingParcels do | ||
before(:each) do | ||
|
||
@parsing_parcels = described_class.new() | ||
end | ||
|
||
context "#code_lines" do | ||
it "should clean code of encoding problems and comments" do | ||
file_contents = <<~CONTENTS | ||
/* TEST_SOURCE_FILE("foo.c") */ // Eliminate single line comment block | ||
// TEST_SOURCE_FILE("bar.c") // Eliminate single line comment | ||
Some text⛔️ | ||
/* // /* // Eliminate tricky comment block enclosing comments | ||
TEST_SOURCE_FILE("boom.c") | ||
*/ // // Eliminate trailing single line comment following block comment | ||
More text | ||
#define STR1 "/* comment " // Strip out (single line) C string containing block comment | ||
#define STR2 " /* comment " // Strip out (single line) C string containing block comment | ||
CONTENTS | ||
|
||
got = [] | ||
|
||
@parsing_parcels.code_lines( StringIO.new( file_contents ) ) do |line| | ||
line.strip! | ||
got << line if !line.empty? | ||
end | ||
|
||
expected = [ | ||
'Some text', # ⛔️ removed with encoding sanitizing | ||
'More text', | ||
"#define STR1", | ||
"#define STR2" | ||
] | ||
|
||
expect( got ).to eq expected | ||
end | ||
|
||
it "should treat continuations as a single line" do | ||
file_contents = "// TEST_SOURCE_FILE(\"foo.c\") \\ \nTEST_SOURCE_FILE(\"bar.c\")\nSome text⛔️ \\\nMore text\n" | ||
got = [] | ||
|
||
@parsing_parcels.code_lines( StringIO.new( file_contents ) ) do |line| | ||
line.strip! | ||
got << line if !line.empty? | ||
end | ||
|
||
expected = [ | ||
'Some text More text' | ||
] | ||
|
||
expect( got ).to eq expected | ||
end | ||
|
||
end | ||
|
||
end |
Oops, something went wrong.