Fix preprocessor option to retain content

This commit is contained in:
Dustin Spicuzza 2023-09-02 21:03:15 -04:00
parent a60bb7fd18
commit de4d06defe
2 changed files with 47 additions and 13 deletions

View File

@ -3,6 +3,7 @@ Contains optional preprocessor support via pcpp
"""
import io
import os
from os.path import relpath
import typing
from .options import PreprocessorFunction
@ -17,7 +18,7 @@ class PreprocessorError(Exception):
class _CustomPreprocessor(Preprocessor):
def __init__(self):
Preprocessor.__init__(self)
self.errors = []
self.errors: typing.List[str] = []
def on_error(self, file, line, msg):
self.errors.append(f"{file}:{line} error: {msg}")
@ -34,21 +35,15 @@ def _filter_self(fname: str, fp: typing.TextIO) -> str:
# isn't what a typical user of cxxheaderparser would want, so we strip out
# the line directives and any content that isn't in our original file
# Compute the filename to match based on how pcpp does it
try:
relfname = relpath(fname)
except Exception:
relfname = fname
relfname = relfname.replace("\\", "/")
relfname += '"\n'
# pcpp always emits line directives that match whatever is passed in to it
line_ending = f'{fname}"\n'
new_output = io.StringIO()
keep = True
for line in fp:
if line.startswith("#line"):
keep = line.endswith(relfname)
keep = line.endswith(line_ending)
if keep:
new_output.write(line)

View File

@ -1,7 +1,17 @@
import pathlib
from cxxheaderparser.options import ParserOptions
from cxxheaderparser.preprocessor import make_pcpp_preprocessor
from cxxheaderparser.simple import NamespaceScope, ParsedData, parse_string
from cxxheaderparser.types import FundamentalSpecifier, NameSpecifier, PQName, Token, Type, Value, Variable
from cxxheaderparser.simple import NamespaceScope, ParsedData, parse_file, parse_string
from cxxheaderparser.types import (
FundamentalSpecifier,
NameSpecifier,
PQName,
Token,
Type,
Value,
Variable,
)
def test_basic_preprocessor() -> None:
@ -24,4 +34,33 @@ def test_basic_preprocessor() -> None:
)
]
)
)
)
def test_preprocessor_omit_content(tmp_path: pathlib.Path) -> None:
"""Ensure that content in other headers is omitted"""
h_content = '#include "t2.h"' "\n" "int x = X;\n"
h2_content = "#define X 2\n" "int omitted = 1;\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(h2_content)
options = ParserOptions(preprocessor=make_pcpp_preprocessor())
data = parse_file(tmp_path / "t1.h", options=options)
assert data == ParsedData(
namespace=NamespaceScope(
variables=[
Variable(
name=PQName(segments=[NameSpecifier(name="x")]),
type=Type(
typename=PQName(segments=[FundamentalSpecifier(name="int")])
),
value=Value(tokens=[Token(value="2")]),
)
]
)
)