diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2b82ff7..5e58abf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -22,6 +22,15 @@ Added in the ``--define-mode`` option. +Fixed +----- + +* Resync linemarker now always emitted after eval directives (``$:``, ``@:``, + inline ``#{...}#``) when line-numbering is active. Previously the marker + was omitted for single-line calls, causing downstream Fortran preprocessors + to attribute subsequent source lines to wrong locations when the expanded + macro body contained ``#ifdef``/``#endif`` blocks. + Changed ------- diff --git a/src/fypp.py b/src/fypp.py index 9118534..5dad050 100755 --- a/src/fypp.py +++ b/src/fypp.py @@ -1847,20 +1847,11 @@ def _postprocess_eval_line(self, evalline, fname, span): if trailing_newline: trailing = '\n' if self._linenums: - # Last line was folded, but no linenums were generated for - # the continuation lines -> current line position is not - # in sync with the one calculated from the last line number - unsync = ( - len(foldedlines) and len(foldedlines[-1]) > 1 - and not self._contlinenums) - # Eval directive in source consists of more than one line - multiline = span[1] - span[0] > 1 - if unsync or multiline: - # For inline eval directives span[0] == span[1] - # -> next line is span[0] + 1 and not span[1] as for - # line eval directives - nextline = max(span[1], span[0] + 1) - trailing += self._linenumdir(nextline, fname) + # For inline eval directives span[0] == span[1] + # -> next line is span[0] + 1 and not span[1] as for + # line eval directives + nextline = max(span[1], span[0] + 1) + trailing += self._linenumdir(nextline, fname) else: trailing = '' return result + trailing diff --git a/test/test_fypp.py b/test/test_fypp.py index 6e7a741..180c3c4 100644 --- a/test/test_fypp.py +++ b/test/test_fypp.py @@ -2000,7 +2000,7 @@ def _importmodule(module): ('linesub_oneline', ([_LINENUM_FLAG], 'A\n$: 1 + 1\nB\n', - _linenum(0) + 'A\n2\nB\n' + _linenum(0) + 'A\n2\n' + _linenum(2) + 'B\n' ) ), ('linesub_contlines', @@ -2024,7 +2024,7 @@ def _importmodule(module): ('exprsub_multi_line', ([_LINENUM_FLAG], '${"line1\\nline2"}$\nDone\n', - _linenum(0) + 'line1\n' + _linenum(0) + 'line2\nDone\n' + _linenum(0) + 'line1\n' + _linenum(0) + 'line2\n' + _linenum(1) + 'Done\n' ) ), ('macrosubs', @@ -2044,7 +2044,7 @@ def _importmodule(module): '#:def macro(c)\nMACRO1|${c}$|\nMACRO2|${c}$|\n#:enddef\n${macro(\'A\')}$' '\n', _linenum(0) + _linenum(4) + 'MACRO1|A|\n' + _linenum(4) - + 'MACRO2|A|\n' + + 'MACRO2|A|\n' + _linenum(5) ) ), ('recursive_macrosubs_multiline', @@ -2052,7 +2052,7 @@ def _importmodule(module): '#:def f(c)\nLINE1|${c}$|\nLINE2|${c}$|\n#:enddef\n$: f(f("A"))\n', (_linenum(0) + _linenum(4) + 'LINE1|LINE1|A|\n' + _linenum(4) + 'LINE2|A||\n' + _linenum(4) + 'LINE2|LINE1|A|\n' + - _linenum(4) + 'LINE2|A||\n') + _linenum(4) + 'LINE2|A||\n' + _linenum(5)) ) ), ('multiline_macrocall', @@ -2073,26 +2073,26 @@ def _importmodule(module): ('for', ([_LINENUM_FLAG], '#:for i in (1, 2)\n${i}$\n#:endfor\nDone\n', - (_linenum(0) + _linenum(1) + '1\n' + _linenum(1) + '2\n' - + _linenum(3) + 'Done\n') + (_linenum(0) + _linenum(1) + '1\n' + _linenum(2) + _linenum(1) + '2\n' + + _linenum(2) + _linenum(3) + 'Done\n') ) ), ('inline_for', ([_LINENUM_FLAG], '#{for i in (1, 2)}#${i}$#{endfor}#Done\n', - _linenum(0) + '12Done\n' + _linenum(0) + '12Done\n' + _linenum(1) ) ), ('set', ([_LINENUM_FLAG], '#:set x = 2\n$: x\n', - _linenum(0) + _linenum(1) + '2\n', + _linenum(0) + _linenum(1) + '2\n' + _linenum(2), ) ), ('inline_set', ([_LINENUM_FLAG], '#{set x = 2}#${x}$Done\n', - _linenum(0) + '2Done\n', + _linenum(0) + '2Done\n' + _linenum(1), ) ), ('comment_single', @@ -2110,14 +2110,14 @@ def _importmodule(module): ('mute', ([_LINENUM_FLAG], 'A\n#:mute\nB\n#:set VAR = 2\n#:endmute\nVAR=${VAR}$\n', - _linenum(0) + 'A\n' + _linenum(5) + 'VAR=2\n' + _linenum(0) + 'A\n' + _linenum(5) + 'VAR=2\n' + _linenum(6) ) ), ('direct_call', ([_LINENUM_FLAG], '#:def mymacro(val)\n|${val}$|\n#:enddef\n'\ '@:mymacro( a < b )\n', - _linenum(0) + _linenum(3) + '|a < b|\n', + _linenum(0) + _linenum(3) + '|a < b|\n' + _linenum(4), ) ), ('direct_call_contline', @@ -2144,7 +2144,7 @@ def _importmodule(module): ([_LINENUM_FLAG, _linelen(15), _indentation(4), _folding('smart')], ' ${3}$456 89 123456 8\nDone\n', _linenum(0) + ' 3456 89&\n' + _linenum(0) - + ' & 123456&\n' + _linenum(0) + ' & 8\n' + 'Done\n' + + ' & 123456&\n' + _linenum(0) + ' & 8\n' + _linenum(1) + 'Done\n' ) ), ('smart_folding_nocontlines', @@ -2155,6 +2155,17 @@ def _importmodule(module): + ' & 8\n' + _linenum(1) + 'Done\n' ) ), + ('eval_resync_after_preprocessor_block', + ([_LINENUM_FLAG], + '#:def GUARD()\n#ifdef NEVER\n! stripped\n#endif\n#:enddef\nA\n$:GUARD()\nB\n', + _linenum(0) + + _linenum(5) + 'A\n' + + '#ifdef NEVER\n' + + _linenum(6) + '! stripped\n' + + _linenum(6) + '#endif\n' + + _linenum(7) + 'B\n' + ) + ), ] @@ -2194,7 +2205,8 @@ def _importmodule(module): (_linenum(0) + _linenum(0, 'include/fypp1.inc', flag=_NEW_FILE) + 'INCL1\n' + _linenum(4, 'include/fypp1.inc') - + 'INCL5\n' + _linenum(1, flag=_RETURN_TO_FILE) + 'INCMACRO(1)\n') + + 'INCL5\n' + _linenum(1, flag=_RETURN_TO_FILE) + 'INCMACRO(1)\n' + + _linenum(2)) ) ), ('nested_include_in_incpath_linenum',