utilada_2.8.0_0d266031/samples/src/tree.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
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
with GNAT.IO;
with Ada.Command_Line;
with Ada.Directories;
with Ada.Strings.Unbounded;
with Ada.Containers.Indefinite_Ordered_Sets;
with Ada.Strings.UTF_Encoding;
with Util.Files.Walk;
with Util.Strings;
--  with Util.Log.Loggers;
procedure Tree is

   use GNAT.IO;
   use Ada.Strings.UTF_Encoding;
   use Ada.Strings.Unbounded;

   SEP_MARKER : constant UTF_8_String := "│   ";
   MID_MARKER : constant UTF_8_String := "├── ";
   END_MARKER : constant UTF_8_String := "└── ";

   package String_Sets is
     new Ada.Containers.Indefinite_Ordered_Sets (Element_Type => String);

   subtype Filter_Context_Type is Util.Files.Walk.Filter_Context_Type;
   subtype Filter_Result is Util.Files.Walk.Filter_Result;

   type Walker_Type is new Util.Files.Walk.Walker_Type with record
      Files       : String_Sets.Set;
      Dirs        : String_Sets.Set;
      Prefix      : Unbounded_String;
      Ptr_Prefix  : Unbounded_String;
      Seg_Prefix  : Unbounded_String;
      File_Count  : Natural := 0;
      Dir_Count   : Natural := 0;
   end record;

   overriding
   function Get_Ignore_Path (Walker : Walker_Type;
                             Path   : String) return String;

   overriding
   procedure Scan_File (Walker : in out Walker_Type;
                        Path   : String);

   overriding
   procedure Scan_Subdir (Walker  : in out Walker_Type;
                          Path    : String;
                          Filter  : Filter_Context_Type;
                          Match   : Filter_Result);

   overriding
   procedure Scan_Directory (Walker : in out Walker_Type;
                             Path   : String;
                             Filter : Filter_Context_Type);

   overriding
   function Get_Ignore_Path (Walker : Walker_Type;
                             Path   : String) return String is
      pragma Unreferenced (Walker);
   begin
      return Util.Files.Compose (Path, ".gitignore");
   end Get_Ignore_Path;

   overriding
   procedure Scan_File (Walker : in out Walker_Type;
                        Path   : String) is
   begin
      Walker.Files.Include (Ada.Directories.Simple_Name (Path));
   end Scan_File;

   overriding
   procedure Scan_Subdir (Walker  : in out Walker_Type;
                          Path    : String;
                          Filter  : Filter_Context_Type;
                          Match   : Filter_Result) is
   begin
      Walker.Dirs.Include (Path);
   end Scan_Subdir;

   overriding
   procedure Scan_Directory (Walker : in out Walker_Type;
                             Path   : String;
                             Filter : Filter_Context_Type) is
      Prefix  : constant Unbounded_String := Walker.Prefix;
      Segment : constant Unbounded_String := Walker.Seg_Prefix;
   begin
      Put_Line (To_String (Prefix) & To_String (Walker.Ptr_Prefix)
                & Ada.Directories.Simple_Name (Path));
      Walker.Files.Clear;
      Walker.Dirs.Clear;
      Walker.Prefix := Prefix & Segment;
      Util.Files.Walk.Walker_Type (Walker).Scan_Directory (Path, Filter);
      declare
         Dirs       : constant String_Sets.Set := Walker.Dirs;
         Dir_Count  : constant Natural := Natural (Walker.Dirs.Length);
         File_Count : constant Natural := Natural (Walker.Files.Length);
         Pos        : Natural := 0;
      begin
         Walker.File_Count := Walker.File_Count + File_Count;
         Walker.Dir_Count := Walker.Dir_Count + Dir_Count;
         for File of Walker.Files loop
            Pos := Pos + 1;
            if Pos = File_Count + Dir_Count then
               Put_Line (To_String (Walker.Prefix) & END_MARKER & File);
            else
               Put_Line (To_String (Walker.Prefix) & MID_MARKER & File);
            end if;
         end loop;
         for Dir of Dirs loop
            Pos := Pos + 1;
            Walker.Dirs.Clear;
            if Pos = File_Count + Dir_Count then
               Walker.Seg_Prefix := To_Unbounded_String ("    ");
               Walker.Ptr_Prefix := To_Unbounded_String (END_MARKER);
            else
               Walker.Seg_Prefix := To_Unbounded_String (SEP_MARKER);
               Walker.Ptr_Prefix := To_Unbounded_String (MID_MARKER);
            end if;
            Util.Files.Walk.Walker_Type (Walker).Scan_Subdir
              (Dir, Filter, Util.Files.Walk.Path_Filter.NO_MATCH);
         end loop;
      end;
      Walker.Prefix := Prefix;
   end Scan_Directory;

   W      : Walker_Type;
   Filter : Util.Files.Walk.Filter_Type;
   Count  : constant Natural := Ada.Command_Line.Argument_Count;
begin
   --  Util.Log.Loggers.Initialize ("samples/log4j.properties");
   W.Prefix := To_Unbounded_String ("");
   W.Seg_Prefix := To_Unbounded_String ("");
   for I in 1 .. Count loop
      W.Scan (Ada.Command_Line.Argument (I), Filter);
   end loop;
   Put_Line (Util.Strings.Image (W.Dir_Count) & " directories, "
               & Util.Strings.Image (W.File_Count) & " files");
end Tree;