spat_1.3.0_4ad4ab14/src/util/spat-string_tables.adb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
------------------------------------------------------------------------------
--  Copyright (C) 2020 by Heisenbug Ltd. (gh+spat@heisenbug.eu)
--
--  This work is free. You can redistribute it and/or modify it under the
--  terms of the Do What The Fuck You Want To Public License, Version 2,
--  as published by Sam Hocevar. See the LICENSE file for more details.
------------------------------------------------------------------------------
pragma License (Unrestricted);

package body SPAT.String_Tables is

   type Lengths is array (1 .. Columns) of Ada.Text_IO.Count;
   type Column_Positions is array (1 .. Columns) of Ada.Text_IO.Positive_Count;

   ---------------------------------------------------------------------------
   --  Put
   ---------------------------------------------------------------------------
   procedure Put
     (File : in Ada.Text_IO.File_Type := Ada.Text_IO.Standard_Output;
      Item : in Row_Vectors.Vector)
   is
      Col_Length : Lengths          := (others => 0);
      Start_Col  : Column_Positions := (others => 1);
      use type Ada.Text_IO.Count;
   begin
      --  Retrieve maximum length of each column.
      for Row of Item loop
         for Col in Col_Length'Range loop
            Col_Length (Col) :=
              Ada.Text_IO.Count'Max
                (Col_Length (Col),
                 (if
                    Col = Col_Length'First and then
                    Col /= Col_Length'Last and then
                    Ada.Strings.Unbounded.Length (Row (Col + 1)) = 0
                  then 0
                  --  Ignore length of first field if no other field follows.
                  else Ada.Text_IO.Count (Ada.Strings.Unbounded.Length (Row (Col)))));
         end loop;
      end loop;

      --  Now each Length entry contains the maximum length of each item.
      --  Let's turn these length into absolute positions.
      for Col in Col_Length'Range loop
         Start_Col (Col) :=
           (if Col = Col_Length'First
            then 1
            else Start_Col (Col - 1) + Col_Length (Col - 1));
      end loop;

      --  Finally print each entry.
      for Row of Item loop
         for Col in Row'Range loop
            if Ada.Strings.Unbounded.Length (Row (Col)) > 0 then
               Ada.Text_IO.Set_Col (File => File,
                                    To   => Start_Col (Col));
               Ada.Text_IO.Put
                 (File => File,
                  Item => Ada.Strings.Unbounded.To_String (Row (Col)));
            end if;
         end loop;

         Ada.Text_IO.New_Line (File => File);
      end loop;
   end Put;

end SPAT.String_Tables;