Merge pull request #62 from robotpy/fix-line-directives

Fix #line directives
This commit is contained in:
Dustin Spicuzza 2023-08-22 10:09:19 -04:00 committed by GitHub
commit 1ba625a13b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 8 deletions

View File

@ -19,7 +19,7 @@ if sys.version_info >= (3, 8):
else: else:
Protocol = object Protocol = object
_line_re = re.compile(r'^#line (\d+) "(.*)"') _line_re = re.compile(r'^\#[\t ]*line (\d+) "(.*)"')
_multicomment_re = re.compile("\n[\\s]+\\*") _multicomment_re = re.compile("\n[\\s]+\\*")
@ -176,7 +176,6 @@ class PlyLexer:
# Comments # Comments
"COMMENT_SINGLELINE", "COMMENT_SINGLELINE",
"COMMENT_MULTILINE", "COMMENT_MULTILINE",
"LINE_DIRECTIVE",
"PRAGMA_DIRECTIVE", "PRAGMA_DIRECTIVE",
"INCLUDE_DIRECTIVE", "INCLUDE_DIRECTIVE",
"PP_DIRECTIVE", "PP_DIRECTIVE",
@ -438,12 +437,6 @@ class PlyLexer:
t.type = t.value t.type = t.value
return t return t
@TOKEN(r'\#[\t ]*line (\d+) "(.*)"')
def t_LINE_DIRECTIVE(self, t: LexToken) -> None:
m = t.lexmatch
self.filename = m.group(2)
self.line_offset = 1 + self.lex.lineno - int(m.group(1))
@TOKEN(r"\#[\t ]*pragma") @TOKEN(r"\#[\t ]*pragma")
def t_PRAGMA_DIRECTIVE(self, t: LexToken) -> LexToken: def t_PRAGMA_DIRECTIVE(self, t: LexToken) -> LexToken:
return t return t
@ -454,6 +447,12 @@ class PlyLexer:
@TOKEN(r"\#(.*)") @TOKEN(r"\#(.*)")
def t_PP_DIRECTIVE(self, t: LexToken): def t_PP_DIRECTIVE(self, t: LexToken):
# handle line macros
m = _line_re.match(t.value)
if m:
self.filename = m.group(2)
self.line_offset = 1 + self.lex.lineno - int(m.group(1))
return None
# ignore C++23 warning directive # ignore C++23 warning directive
if t.value.startswith("#warning"): if t.value.startswith("#warning"):
return return

View File

@ -1,5 +1,6 @@
# Note: testcases generated via `python -m cxxheaderparser.gentest` # Note: testcases generated via `python -m cxxheaderparser.gentest`
from cxxheaderparser.errors import CxxParseError
from cxxheaderparser.types import ( from cxxheaderparser.types import (
BaseClass, BaseClass,
ClassDecl, ClassDecl,
@ -22,6 +23,8 @@ from cxxheaderparser.simple import (
ParsedData, ParsedData,
) )
import pytest
# #
# minimal preprocessor support # minimal preprocessor support
# #
@ -93,6 +96,19 @@ def test_pragma_more() -> None:
) )
def test_line_and_define() -> None:
content = """
// this should work + change line number of error
#line 40 "filename.h"
// this should fail
#define 1
"""
with pytest.raises(CxxParseError) as e:
parse_string(content, cleandoc=True)
assert "filename.h:41" in str(e.value)
# #
# extern "C" # extern "C"
# #