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 io
import os
from os.path import relpath from os.path import relpath
import typing import typing
from .options import PreprocessorFunction from .options import PreprocessorFunction
@ -17,7 +18,7 @@ class PreprocessorError(Exception):
class _CustomPreprocessor(Preprocessor): class _CustomPreprocessor(Preprocessor):
def __init__(self): def __init__(self):
Preprocessor.__init__(self) Preprocessor.__init__(self)
self.errors = [] self.errors: typing.List[str] = []
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}")
@ -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 # 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 # the line directives and any content that isn't in our original file
# Compute the filename to match based on how pcpp does it # pcpp always emits line directives that match whatever is passed in to it
try: line_ending = f'{fname}"\n'
relfname = relpath(fname)
except Exception:
relfname = fname
relfname = relfname.replace("\\", "/")
relfname += '"\n'
new_output = io.StringIO() new_output = io.StringIO()
keep = True keep = True
for line in fp: for line in fp:
if line.startswith("#line"): if line.startswith("#line"):
keep = line.endswith(relfname) keep = line.endswith(line_ending)
if keep: if keep:
new_output.write(line) new_output.write(line)

View File

@ -1,7 +1,17 @@
import pathlib
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_string from cxxheaderparser.simple import NamespaceScope, ParsedData, parse_file, parse_string
from cxxheaderparser.types import FundamentalSpecifier, NameSpecifier, PQName, Token, Type, Value, Variable from cxxheaderparser.types import (
FundamentalSpecifier,
NameSpecifier,
PQName,
Token,
Type,
Value,
Variable,
)
def test_basic_preprocessor() -> None: 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")]),
)
]
)
)