Skip to content

Validate that we don't forget linemarks #275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions py/dml/ctree.py
Original file line number Diff line number Diff line change
Expand Up @@ -5167,9 +5167,10 @@ def toc(self):
path = self.site.filename()
(ident, h_path) = dmldir_macro(path)
out('#define %s "%s"\n' % (ident, quote_filename(h_path)))
if dml.globals.linemarks:
linemark(self.site.lineno, path)
out(self.text)
for (i, line) in enumerate(self.text.splitlines(keepends=True)):
if dml.globals.linemarks:
linemark(self.site.lineno + i, path)
out(line)
if not output.current().bol:
out('\n')
if dml.globals.linemarks:
Expand Down
12 changes: 12 additions & 0 deletions py/dml/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def __init__(self, indent=0):
self.bol = True
self.redirected_filename = None
self.redirected_lineno = None
self.linemark_is_fresh = False

def write(self, s):
assert False
Expand All @@ -55,6 +56,7 @@ def linemark(self, lineno, filename):
% (lineno, quote_filename(filename)))
self.redirected_filename = filename
self.redirected_lineno = lineno
self.linemark_is_fresh = True

def reset_line_directive(self):
assert self.filename is not None
Expand All @@ -72,6 +74,12 @@ def indeterminate_line_directive(self):

def out(self, output, preindent = 0, postindent = 0):
self.indent += preindent * indent_level
if (self.bol and self.redirected_lineno is not None
and not self.linemark_is_fresh):
raise ICE(SimpleSite(f'{self.redirected_filename}'
f':{self.redirected_lineno}'),
'missing linemark')
self.linemark_is_fresh = False
if output == '\n':
# Don't indent empty lines...
self.write('\n')
Expand All @@ -84,6 +92,10 @@ def out(self, output, preindent = 0, postindent = 0):
self.write(output)
self.bol = (output.endswith('\n'))
no_lines = output.count('\n')
if no_lines > 1 and self.redirected_lineno is not None:
raise ICE(SimpleSite(f'{self.redirected_filename}'
f':{self.redirected_lineno}'),
'missing linemark')
self.indent += postindent * indent_level
self.lineno += no_lines
if self.redirected_lineno is not None:
Expand Down
19 changes: 19 additions & 0 deletions py/dml/output_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import unittest

from dml import output, logging

class TestOutput(unittest.TestCase):
def test_linemark_validation(self):
out = output.StrOutput()
out.linemark(3, 'foo')
out.out('foo')
# ok, not beginning of line
out.out('bar\n')
out.linemark(4, 'foo')
out.out('foo')
out.out('bar\n')
with self.assertRaisesRegex(logging.ICE, '.*missing linemark'):
out.out('foo')
out.linemark(5, 'foo')
with self.assertRaisesRegex(logging.ICE, '.*missing linemark'):
out.out('foo\nbar\n')