diff --git a/cxxheaderparser/preprocessor.py b/cxxheaderparser/preprocessor.py index 33f7771..e1c720c 100644 --- a/cxxheaderparser/preprocessor.py +++ b/cxxheaderparser/preprocessor.py @@ -16,10 +16,15 @@ class PreprocessorError(Exception): class _CustomPreprocessor(Preprocessor): - def __init__(self, encoding: typing.Optional[str]): + def __init__( + self, + encoding: typing.Optional[str], + passthru_includes: typing.Optional["re.Pattern"], + ): Preprocessor.__init__(self) self.errors: typing.List[str] = [] self.assume_encoding = encoding + self.passthru_includes = passthru_includes def on_error(self, file, line, msg): self.errors.append(f"{file}:{line} error: {msg}") @@ -58,12 +63,15 @@ def make_pcpp_preprocessor( include_paths: typing.List[str] = [], retain_all_content: bool = False, encoding: typing.Optional[str] = None, + passthru_includes: typing.Optional["re.Pattern"] = None, ) -> PreprocessorFunction: """ Creates a preprocessor function that uses pcpp (which must be installed separately) to preprocess the input text. :param encoding: If specified any include files are opened with this encoding + :param passthru_includes: If specified any #include directives that match the + compiled regex pattern will be part of the output. .. code-block:: python @@ -75,7 +83,7 @@ def make_pcpp_preprocessor( """ def _preprocess_file(filename: str, content: str) -> str: - pp = _CustomPreprocessor(encoding) + pp = _CustomPreprocessor(encoding, passthru_includes) if include_paths: for p in include_paths: pp.add_path(p) diff --git a/tests/test_preprocessor.py b/tests/test_preprocessor.py index df2e76f..2e0e591 100644 --- a/tests/test_preprocessor.py +++ b/tests/test_preprocessor.py @@ -1,9 +1,16 @@ import os import pathlib +import re from cxxheaderparser.options import ParserOptions from cxxheaderparser.preprocessor import make_pcpp_preprocessor -from cxxheaderparser.simple import NamespaceScope, ParsedData, parse_file, parse_string +from cxxheaderparser.simple import ( + NamespaceScope, + ParsedData, + parse_file, + parse_string, + Include, +) from cxxheaderparser.types import ( FundamentalSpecifier, NameSpecifier, @@ -135,3 +142,23 @@ def test_preprocessor_encoding(tmp_path: pathlib.Path) -> None: ] ) ) + + +def test_preprocessor_passthru_includes(tmp_path: pathlib.Path) -> None: + """Ensure that all #include pass through""" + h_content = '#include "t2.h"\n' + + with open(tmp_path / "t1.h", "w") as fp: + fp.write(h_content) + + with open(tmp_path / "t2.h", "w") as fp: + fp.write("") + + options = ParserOptions( + preprocessor=make_pcpp_preprocessor(passthru_includes=re.compile(".+")) + ) + data = parse_file(tmp_path / "t1.h", options=options) + + assert data == ParsedData( + namespace=NamespaceScope(), includes=[Include(filename='"t2.h"')] + )