diff --git a/cxxheaderparser/options.py b/cxxheaderparser/options.py index 6e0930c..82a59f6 100644 --- a/cxxheaderparser/options.py +++ b/cxxheaderparser/options.py @@ -2,7 +2,7 @@ from typing import Callable, Optional #: arguments are (filename, content) -PreprocessorFunction = Callable[[str, str], str] +PreprocessorFunction = Callable[[str, Optional[str]], str] @dataclass diff --git a/cxxheaderparser/parser.py b/cxxheaderparser/parser.py index a2c031a..18614c5 100644 --- a/cxxheaderparser/parser.py +++ b/cxxheaderparser/parser.py @@ -74,9 +74,10 @@ class CxxParser: def __init__( self, filename: str, - content: str, + content: typing.Optional[str], visitor: CxxVisitor, options: typing.Optional[ParserOptions] = None, + encoding: typing.Optional[str] = None, ) -> None: self.visitor = visitor self.filename = filename @@ -85,6 +86,13 @@ def __init__( if options and options.preprocessor is not None: content = options.preprocessor(filename, content) + if content is None: + if encoding is None: + encoding = "utf-8-sig" + + with open(filename, "r", encoding=encoding) as fp: + content = fp.read() + self.lex: lexer.TokenStream = lexer.LexerTokenStream(filename, content) global_ns = NamespaceDecl([], False) diff --git a/cxxheaderparser/preprocessor.py b/cxxheaderparser/preprocessor.py index 1e5719b..99a19ba 100644 --- a/cxxheaderparser/preprocessor.py +++ b/cxxheaderparser/preprocessor.py @@ -74,7 +74,7 @@ def make_gcc_preprocessor( if not encoding: encoding = "utf-8" - def _preprocess_file(filename: str, content: str) -> str: + def _preprocess_file(filename: str, content: typing.Optional[str]) -> str: cmd = gcc_args + ["-w", "-E", "-C"] for p in include_paths: @@ -86,6 +86,8 @@ def _preprocess_file(filename: str, content: str) -> str: if filename == "": cmd.append("-") filename = "" + if content is None: + raise PreprocessorError("no content specified for stdin") kwargs["input"] = content else: cmd.append(filename) @@ -191,7 +193,7 @@ def make_pcpp_preprocessor( if pcpp is None: raise PreprocessorError("pcpp is not installed") - def _preprocess_file(filename: str, content: str) -> str: + def _preprocess_file(filename: str, content: typing.Optional[str]) -> str: pp = _CustomPreprocessor(encoding, passthru_includes) if include_paths: for p in include_paths: @@ -203,6 +205,10 @@ def _preprocess_file(filename: str, content: str) -> str: if not retain_all_content: pp.line_directive = "#line" + if content is None: + with open(filename, "r", encoding=encoding) as fp: + content = fp.read() + pp.parse(content, filename) if pp.errors: diff --git a/cxxheaderparser/simple.py b/cxxheaderparser/simple.py index 421666b..3efb048 100644 --- a/cxxheaderparser/simple.py +++ b/cxxheaderparser/simple.py @@ -348,7 +348,10 @@ def parse_file( if filename == "-": content = sys.stdin.read() else: - with open(filename, encoding=encoding) as fp: - content = fp.read() + content = None - return parse_string(content, filename=filename, options=options) + visitor = SimpleCxxVisitor() + parser = CxxParser(filename, content, visitor, options) + parser.parse() + + return visitor.data