Skip to content

Commit

Permalink
Merge branch 'pmderodat/preprocessing' into 'master'
Browse files Browse the repository at this point in the history
Preprocessor: fix file reader when source file cannot be read

Closes #1126

See merge request eng/libadalang/libadalang!1453
  • Loading branch information
pmderodat committed Nov 7, 2023
2 parents 2742614 + d126484 commit 7a847f2
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 14 deletions.
26 changes: 12 additions & 14 deletions extensions/src/libadalang-preprocessing.adb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ package body Libadalang.Preprocessing is
exception
when Exc : File_Read_Error =>
Append (Diagnostics, Exc => Exc);
Contents := Create_Decoded_File_Contents ("");
return;
end;

Expand All @@ -143,20 +144,17 @@ package body Libadalang.Preprocessing is
Diagnostics);
Free (In_Buffer);

-- If the preprocessor returned a source buffer, decode it. If not, it
-- is supposed to have created diagnostics.

if Out_Buffer.Buffer = null then
pragma Assert (not Diagnostics.Is_Empty);
else
Decode_Buffer
(Out_Buffer.Buffer (1 .. Out_Buffer.Last),
Charset,
Read_BOM,
Contents,
Diagnostics);
Free (Out_Buffer.Buffer);
end if;
-- The preprocessor is always supposed to return a (possibly empty)
-- source buffer.

pragma Assert (Out_Buffer.Buffer /= null);
Decode_Buffer
(Out_Buffer.Buffer (1 .. Out_Buffer.Last),
Charset,
Read_BOM,
Contents,
Diagnostics);
Free (Out_Buffer.Buffer);
end Read;

-------------------
Expand Down
6 changes: 6 additions & 0 deletions testsuite/drivers/base_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,12 @@ def output_refiners(self):
if self.test_env.get("canonicalize_directory_separators", False):
result.append(Substitute("\\", "/"))

# If requested, replace occurences of the working directory
if self.test_env.get("canonicalize_working_dir", False):
result.append(
Substitute(self.working_dir(), "[working-dir]")
)

return result

@property
Expand Down
1 change: 1 addition & 0 deletions testsuite/tests/prep/errors/bad_encoding.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1 change: 1 addition & 0 deletions testsuite/tests/prep/errors/foo.adb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pragma Foo ($Foo);
3 changes: 3 additions & 0 deletions testsuite/tests/prep/errors/invalid.adb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pragma Foo;
#end if;
pragma Bar;
64 changes: 64 additions & 0 deletions testsuite/tests/prep/errors/main.adb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
with Ada.Text_IO; use Ada.Text_IO;

with GPR2.Context;
with GPR2.Path_Name;
with GPR2.Project.Tree;

with Libadalang.Analysis; use Libadalang.Analysis;
with Libadalang.Preprocessing; use Libadalang.Preprocessing;

procedure Main is

Ctx : Analysis_Context;

procedure Process (Filename : String);
-- Parse the requested file and print its diagnostics and parse tree

-------------
-- Process --
-------------

procedure Process (Filename : String) is
U : constant Analysis_Unit :=
Ctx.Get_From_File (Filename, Charset => "utf-8");
begin
Put_Line ("== " & Filename & " ==");
New_Line;
if U.Has_Diagnostics then
for D of U.Diagnostics loop
Put_Line (U.Format_GNU_Diagnostic (D));
end loop;
New_Line;
end if;
U.Root.Print;
New_Line;
end Process;

-- Create a context from the example project

Tree : GPR2.Project.Tree.Object;
begin
Tree.Load_Autoconf
(Filename => GPR2.Path_Name.Create_File
("p.gpr", GPR2.Path_Name.No_Resolution),
Context => GPR2.Context.Empty);
Ctx := Create_Context_From_Project (Tree);

-- As a sanity check, first make sure that preprocessing is active

Process ("foo.adb");

-- Then check error cases: the source file cannot be read

Process ("no_such_file.adb");

-- Preprocessing aborts because of a syntax error

Process ("invalid.adb");

-- Buffer decoding after preprocessing fails because of an encoding error

Process ("bad_encoding.bin");

Put_Line ("Done.");
end Main;
5 changes: 5 additions & 0 deletions testsuite/tests/prep/errors/p.gpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
project P is
package Compiler is
for Default_Switches ("Ada") use ("-gnateDfoo=null");
end Compiler;
end P;
42 changes: 42 additions & 0 deletions testsuite/tests/prep/errors/test.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
== foo.adb ==

PragmaNodeList[1:1-1:19]
| PragmaNode[1:1-1:19]
| |f_id:
| | Id[1:8-1:11]: Foo
| |f_args:
| | BaseAssocList[1:13-1:17]
| | | PragmaArgumentAssoc[1:13-1:17]
| | | |f_name: <null>
| | | |f_expr:
| | | | Null[1:13-1:17]: null

== no_such_file.adb ==

no_such_file.adb: Cannot open [working-dir]/no_such_file.adb

CompilationUnitList[1:1-1:1]: <empty list>

== invalid.adb ==

invalid.adb:2:2: no matching "#if"

PragmaNodeList[1:1-3:12]
| PragmaNode[1:1-1:12]
| |f_id:
| | Id[1:8-1:11]: Foo
| |f_args:
| | BaseAssocList[1:7-1:7]: <empty list>
| PragmaNode[3:1-3:12]
| |f_id:
| | Id[3:8-3:11]: Bar
| |f_args:
| | BaseAssocList[3:7-3:7]: <empty list>

== bad_encoding.bin ==

bad_encoding.bin:1:1: Could not decode source as "utf-8"

CompilationUnitList[1:1-1:1]: <empty list>

Done.
5 changes: 5 additions & 0 deletions testsuite/tests/prep/errors/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
driver: ada-api
main: main.adb
canonicalize_working_dir: true
control:
- [XFAIL, "valgrind", "Pending resolution of eng/gpr/gpr-issues#43"]

0 comments on commit 7a847f2

Please sign in to comment.