diff mbox series

[COMMITTED] ada: Transfer fix for pretty-printed parentheses from GNATprove to GNAT

Message ID 20230523080752.1873021-1-poulhies@adacore.com
State New
Headers show
Series [COMMITTED] ada: Transfer fix for pretty-printed parentheses from GNATprove to GNAT | expand

Commit Message

Marc Poulhiès May 23, 2023, 8:07 a.m. UTC
From: Piotr Trojanek <trojanek@adacore.com>

Expressions with parentheses are notoriously problematic to
pretty-print. In GNATprove we had a post-processing fix for them,
but it is better to have this fix in the GNAT frontend repository
and apply it for CodePeer as well.

gcc/ada/

	* pprint.adb (Expression_Image): Move Count_Parentheses and
	Fix_Parentheses routines from GNATprove and apply them before
	returning the slice of a source code buffer.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/pprint.adb | 70 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 69 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/gcc/ada/pprint.adb b/gcc/ada/pprint.adb
index 8add10c8f22..bcc7a257630 100644
--- a/gcc/ada/pprint.adb
+++ b/gcc/ada/pprint.adb
@@ -64,6 +64,19 @@  package body Pprint is
       --  Expand_Type is True and Expr is a type, try to expand Expr (an
       --  internally generated type) into a user understandable name.
 
+      function Count_Parentheses (S : String; C : Character) return Natural
+        with Pre => C in '(' | ')';
+      --  Returns the number of times parenthesis character C should be added
+      --  to string S for getting a correctly parenthesized result. For C = '('
+      --  this means prepending the character, for C = ')' this means appending
+      --  the character.
+
+      function Fix_Parentheses (S : String) return String;
+      --  Counts the number of required opening and closing parentheses in S to
+      --  respectively prepend and append for getting correct parentheses. Then
+      --  returns S with opening parentheses prepended and closing parentheses
+      --  appended so that the result is correctly parenthesized.
+
       Max_List_Depth : constant := 3;
       --  Limit number of nested lists to print
 
@@ -650,6 +663,61 @@  package body Pprint is
          end case;
       end Expr_Name;
 
+      -----------------------
+      -- Count_Parentheses --
+      -----------------------
+
+      function Count_Parentheses (S : String; C : Character) return Natural is
+
+         procedure Next_Char (Count : in out Natural; C, D, Ch : Character);
+         --  Process next character Ch and update the number Count of C
+         --  characters to add for correct parenthesizing, where D is the
+         --  opposite parenthesis.
+
+         ---------------
+         -- Next_Char --
+         ---------------
+
+         procedure Next_Char (Count : in out Natural; C, D, Ch : Character) is
+         begin
+            if Ch = D then
+               Count := Count + 1;
+            elsif Ch = C and then Count > 0 then
+               Count := Count - 1;
+            end if;
+         end Next_Char;
+
+         --  Local variables
+
+         Count : Natural := 0;
+
+      --  Start of processing for Count_Parentheses
+
+      begin
+         if C = '(' then
+            for Ch of reverse S loop
+               Next_Char (Count, C, ')', Ch);
+            end loop;
+         else
+            for Ch of S loop
+               Next_Char (Count, C, '(', Ch);
+            end loop;
+         end if;
+
+         return Count;
+      end Count_Parentheses;
+
+      ---------------------
+      -- Fix_Parentheses --
+      ---------------------
+
+      function Fix_Parentheses (S : String) return String is
+         Count_Open  : constant Natural := Count_Parentheses (S, '(');
+         Count_Close : constant Natural := Count_Parentheses (S, ')');
+      begin
+         return (1 .. Count_Open => '(') & S & (1 .. Count_Close => ')');
+      end Fix_Parentheses;
+
       --  Local variables
 
       Left, Right : Source_Ptr;
@@ -775,7 +843,7 @@  package body Pprint is
             Scn := Scn + 1;
          end loop;
 
-         return Buffer (1 .. Index);
+         return Fix_Parentheses (Buffer (1 .. Index));
       end;
    end Expression_Image;