|
57 | 57 | Cpp_Macro_Identifier_List, |
58 | 58 | Cpp_Undef_Stmt, |
59 | 59 | Cpp_Line_Stmt, |
| 60 | + Cpp_Linemarker_Stmt, |
60 | 61 | Cpp_Error_Stmt, |
61 | 62 | Cpp_Warning_Stmt, |
62 | 63 | Cpp_Null_Stmt, |
63 | 64 | Cpp_Pp_Tokens, |
64 | 65 | ) |
65 | | -from fparser.two.utils import NoMatchError |
| 66 | +from fparser.two.Fortran2003 import Program |
| 67 | +from fparser.two.utils import NoMatchError, walk |
66 | 68 | from fparser.api import get_reader |
67 | 69 |
|
68 | 70 |
|
@@ -366,7 +368,8 @@ def test_macro_stmt_with_whitespace(line, ref): |
366 | 368 | "#def", |
367 | 369 | "#defnie", |
368 | 370 | "#definex", |
369 | | - "#define 2a" "#define fail(...,test) test", |
| 371 | + "#define 2a", |
| 372 | + "#define fail(...,test) test", |
370 | 373 | "#define", |
371 | 374 | "#define fail(...,...)", |
372 | 375 | ], |
@@ -451,6 +454,30 @@ def test_incorrect_line_stmt(line): |
451 | 454 | assert "Cpp_Line_Stmt: '{0}'".format(line) in str(excinfo.value) |
452 | 455 |
|
453 | 456 |
|
| 457 | +@pytest.mark.usefixtures("f2003_create") |
| 458 | +@pytest.mark.parametrize( |
| 459 | + "line, ref", |
| 460 | + [ |
| 461 | + ('# 123 "file"', '# 123 "file"'), |
| 462 | + (' # 123 "file"', '# 123 "file"'), |
| 463 | + ('# 123 "file" 1 3', '# 123 "file" 1 3'), |
| 464 | + ], |
| 465 | +) |
| 466 | +def test_linemarker(line, ref): |
| 467 | + """Test that #line is recognized""" |
| 468 | + result = Cpp_Linemarker_Stmt(line) |
| 469 | + assert str(result) == ref |
| 470 | + |
| 471 | + |
| 472 | +@pytest.mark.usefixtures("f2003_create") |
| 473 | +@pytest.mark.parametrize("line", ["# abc", "", '# "bla"', "# 123 'wrong_quotes'"]) |
| 474 | +def test_incorrect_linemarker(line): |
| 475 | + """Test that incorrectly formed #line statements raise exception""" |
| 476 | + with pytest.raises(NoMatchError) as excinfo: |
| 477 | + _ = Cpp_Linemarker_Stmt(line) |
| 478 | + assert "Cpp_Linemarker_Stmt: '{0}'".format(line) in str(excinfo.value) |
| 479 | + |
| 480 | + |
454 | 481 | @pytest.mark.usefixtures("f2003_create") |
455 | 482 | @pytest.mark.parametrize("line", ["#error MSG", " # error MSG "]) |
456 | 483 | def test_error_statement_with_msg(line): |
@@ -525,3 +552,42 @@ def test_incorrect_null_stmt(line): |
525 | 552 | with pytest.raises(NoMatchError) as excinfo: |
526 | 553 | _ = Cpp_Null_Stmt(line) |
527 | 554 | assert "Cpp_Null_Stmt: '{0}'".format(line) in str(excinfo.value) |
| 555 | + |
| 556 | + |
| 557 | +@pytest.mark.usefixtures("f2003_create") |
| 558 | +@pytest.mark.parametrize( |
| 559 | + "cpp_class, cpp_directive", |
| 560 | + [ |
| 561 | + (Cpp_If_Stmt, "#if CONST"), |
| 562 | + (Cpp_Elif_Stmt, "#elif CONST"), |
| 563 | + (Cpp_Endif_Stmt, "#endif"), |
| 564 | + (Cpp_Include_Stmt, '#include "test.inc"'), |
| 565 | + (Cpp_Macro_Stmt, "#define a b"), |
| 566 | + (Cpp_Undef_Stmt, "#undef a"), |
| 567 | + (Cpp_Line_Stmt, "#line 123"), |
| 568 | + (Cpp_Linemarker_Stmt, '# 123 "test.f90"'), |
| 569 | + (Cpp_Error_Stmt, "#error 123"), |
| 570 | + (Cpp_Warning_Stmt, "#warning 123"), |
| 571 | + (Cpp_Null_Stmt, "#"), |
| 572 | + ], |
| 573 | +) |
| 574 | +def test_cpp_in_fortran(cpp_class, cpp_directive): |
| 575 | + """ |
| 576 | + Verify that all cpp directives are correctly parsed as part of |
| 577 | + a real program. |
| 578 | + """ |
| 579 | + code = f""" |
| 580 | + program test |
| 581 | + {cpp_directive} |
| 582 | + integer a |
| 583 | + a = 2 |
| 584 | + end program |
| 585 | + """ |
| 586 | + reader = get_reader(code) |
| 587 | + |
| 588 | + obj = Program(reader) |
| 589 | + all_cpp_nodes = walk(obj, cpp_class) |
| 590 | + |
| 591 | + # There must be exactly one cpp node |
| 592 | + assert len(all_cpp_nodes) == 1 |
| 593 | + assert str(all_cpp_nodes[0]) == cpp_directive |
0 commit comments