Merge pull request #75 from seladb/do-not-skip-headers-in-preprocessor

Add option to retain #include directives in preprocessor
This commit is contained in:
Dustin Spicuzza 2023-10-06 02:38:34 -04:00 committed by GitHub
commit 2a17b27225
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 3 deletions

View File

@ -16,10 +16,15 @@ class PreprocessorError(Exception):
class _CustomPreprocessor(Preprocessor): 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) Preprocessor.__init__(self)
self.errors: typing.List[str] = [] self.errors: typing.List[str] = []
self.assume_encoding = encoding self.assume_encoding = encoding
self.passthru_includes = passthru_includes
def on_error(self, file, line, msg): def on_error(self, file, line, msg):
self.errors.append(f"{file}:{line} error: {msg}") self.errors.append(f"{file}:{line} error: {msg}")
@ -58,12 +63,15 @@ def make_pcpp_preprocessor(
include_paths: typing.List[str] = [], include_paths: typing.List[str] = [],
retain_all_content: bool = False, retain_all_content: bool = False,
encoding: typing.Optional[str] = None, encoding: typing.Optional[str] = None,
passthru_includes: typing.Optional["re.Pattern"] = None,
) -> PreprocessorFunction: ) -> PreprocessorFunction:
""" """
Creates a preprocessor function that uses pcpp (which must be installed Creates a preprocessor function that uses pcpp (which must be installed
separately) to preprocess the input text. separately) to preprocess the input text.
:param encoding: If specified any include files are opened with this encoding :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 .. code-block:: python
@ -75,7 +83,7 @@ def make_pcpp_preprocessor(
""" """
def _preprocess_file(filename: str, content: str) -> str: def _preprocess_file(filename: str, content: str) -> str:
pp = _CustomPreprocessor(encoding) pp = _CustomPreprocessor(encoding, passthru_includes)
if include_paths: if include_paths:
for p in include_paths: for p in include_paths:
pp.add_path(p) pp.add_path(p)

View File

@ -1,9 +1,16 @@
import os import os
import pathlib import pathlib
import re
from cxxheaderparser.options import ParserOptions from cxxheaderparser.options import ParserOptions
from cxxheaderparser.preprocessor import make_pcpp_preprocessor 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 ( from cxxheaderparser.types import (
FundamentalSpecifier, FundamentalSpecifier,
NameSpecifier, 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"')]
)