with Ada.Containers.Vectors;
use Ada.Containers;
with Ada.Text_Io;
with Ada.Directories;
use Ada.Directories;
with Ada.Calendar.Formatting;
use Ada.Calendar;
with Ada.Command_Line;
use Ada.Command_Line;
with Ada.Strings.Fixed;
use Ada.Strings;
with Gnat.Directory_Operations.Iteration;
use Gnat.Directory_Operations.Iteration;
with Gnat.Os_Lib;
use Gnat.Os_Lib;
with Gnat.Command_Line;
use Gnat.Command_Line;
with Lib.Shared;
use Lib.Shared;
with PragmARC.Ansi_Tty_Control;
use PragmARC.Ansi_Tty_Control;
procedure Xls is
function "=" (Left, Right : in String_Access) return Boolean is
begin
return Left.all = Right.all;
end "=";
function "<" (Left, Right : in String_Access) return Boolean is
begin
return Left.all < Right.all;
end "<";
package Wstr_Vectors is new Vectors (Positive, String_Access, "=" );
package Sorting is new Wstr_Vectors.Generic_Sorting("<" );
use Wstr_Vectors;
use Sorting;
use Ada.Text_Io;
Target : Vector;
Dir_List : Vector;
File_Index : Natural := 0;
procedure Add_Name (Name : in String;
Num : in Positive;
Verax : in out Boolean) is
begin
Target := Target & new String ' (Name);
File_Index := File_Index + 1;
end Add_Name;
procedure Iterator is new Wildcard_Iterator (Add_Name);
white : constant String := Character'Val(27) & "[01;37m";
Magenta : constant String := Character'Val(27) & "[01;35m";
Cyan : constant String := Character'Val(27) & "[01;36m";
Blue : constant String := Character'Val(27) & "[01;34m";
Red : constant String := Character'Val(27) & "[01;31m";
Green : constant String := Character'Val(27) & "[01;32m";
Yellow : constant String := Character'Val(27) & "[01;33m";
Normal : constant String := Character'Val(27) & "[00m";
type File_Set is array (Positive range <> ) of String_Access;
Set : File_Set(1..4096);
Char_Count, Line_By_Column, Col, Top_Col, Line : Positive := 1;
Long_Option : Boolean := False;
Date : Time := Clock;
Size : Long_integer := 0;
Arguments : Vector;
Dir_Match : Search_Type;
Dir_Path : Directory_Entry_Type;
Column_By_Page : Positive := 1;
Width : Natural := 0;
Hiegh : Natural := 0;
type File_Table is array (Positive range <>, Positive range <> ) of String_Access;
L_Index : Natural := 0;
C_Index : Natural := 0;
File_Counter : Natural := 0;
begin
begin
loop
case Getopt ("l" ) is
when ASCII.NUL => exit;
when 'l' =>
if Full_Switch = "l" then
Long_Option := True;
else
Put_Line ("invalid option" );
end if;
when others =>
raise Program_Error; -- cannot occur
end case;
end loop;
loop
declare
S : constant String := Get_Argument (Do_Expansion => True);
begin
exit when S'Length = 0;
Arguments := Arguments & new String ' (S);
end;
end loop;
exception
when Invalid_Switch => Put_Line ("Invalid Switch " & Full_Switch);
when Invalid_Parameter => Put_Line ("No parameter for " & Full_Switch);
end;
if not Is_Empty(Arguments) then
for Arg in 1..Length(Arguments) loop
declare
E : String := Element(Arguments, Integer(Arg)).all;
begin
if E = ".." then
iterator("../*" );
elsif E = "." or E = "./" then
iterator("./*" );
elsif E = "*" or E = "./*" then
iterator("./*/*" );
elsif E = "../*" then
Put_Line(E);
declare
Line : String := Get_Line;
begin
null;
end;
iterator("../*/*" );
elsif not Is_Directory (E) then
iterator(E);
-- elsif Is_Directory (Containing_Directory(E)) then
-- iterator(Containing_Directory(E) & "/*" );
elsif Is_Directory (E) then
iterator(E & "/*" );
else
Put_Line(E);
declare
Line : String := Get_Line;
begin
null;
end;
iterator(base_Name(E & "/*" ));
end if;
Sort(Target);
File_Index := 0;
if not Is_Empty(Target) then
for Name in 1..Length(Target) loop
declare
File_Name : String_Access := Element(Target, Integer(Name));
begin
if Is_Directory(File_Name.all) then
Set(File_Index+1) := new String ' (Blue & Simple_Name(File_Name.all) & '/') ;
File_Index := File_Index + 1;
elsif Is_Executable_file(File_Name.all) then
Set(File_Index+1) := new String ' (Green & simple_Name(File_Name.all ));
File_Index := File_Index + 1;
elsif Extension(File_Name.all) = "tgz" or Extension(File_Name.all) = "tar" or
Extension(File_Name.all) = "zip" then
Set(File_Index+1) := new String ' (Red & base_Name(File_Name.all) & '.' & Extension(File_Name.all));
File_Index := File_Index + 1;
elsif Extension(File_Name.all) = "png" or Extension(File_Name.all) = "jpg" or
Extension(File_Name.all) = "jpeg" then
Set(File_Index+1) := new String ' (magenta & base_Name(File_Name.all) & '.' & Extension(File_Name.all));
File_Index := File_Index + 1;
elsif Extension(File_Name.all) = "iso" then
Set(File_Index+1) := new String ' (yellow & base_Name(File_Name.all) & '.' & Extension(File_Name.all));
File_Index := File_Index + 1;
elsif Is_Regular_File(File_Name.all) then
Set(File_Index+1) := new String ' (white & simple_Name(File_Name.all));
File_Index := File_Index + 1;
end if;
end;
end loop;
end if;
--
--
--
if File_Index /= 0 then
if Long_Option then
for I in 1..File_Index loop
if Is_Directory (Element(Target, Integer(I)).all) then
declare
Dir : String := Element(Target, integer(I)).all;
begin
if Dir /= "." and Dir /= ".." then
Start_Search(Dir_Match, Dir, Dir);
Get_Next_Entry(Dir_Match, Dir_Path);
Date := Ada.Directories.Modification_time(Dir_Path);
Size := Long_Integer(Ada.Directories.Size(Dir_Path));
end if;
exception
when others =>
null;
end;
else
declare
Dir : String := Element(Target, integer(I)).all;
begin
if Dir /= "." and Dir /= ".." then
Date := Ada.Directories.Modification_time(Full_Name(Dir));
Size := Long_Integer(Ada.Directories.Size(Full_Name(Dir)));
end if;
end;
end if;
if Line_Cur + Line >= 66 then
New_Line;
Put(Position(67, 1) & Formatting.Image(Date));
Put(Position(67, 20) & Long_Integer'Image(Long_Integer(Size)));
Put(Position(67, 35) & Set(I).all & Normal);
else
Put(Position(Line_Cur + Line, 1) & Formatting.Image(Date));
Put(Position(Line_Cur + Line, 20) & Long_Integer'Image(Long_Integer(Size)));
Put(Position(Line_Cur + Line, 35) & Set(I).all & Normal);
Line := Line + 1;
end if;
Size := 0;
end loop;
Line_Cur := Positive'Min(Line_Cur + Line, 67);
Put(Position(Line_Cur, 1) & white);
else
for Iter in 1..File_Index loop
if Set(Iter)'Length > Top_Col then
Top_Col := Set(Iter)'Length;
end if;
Char_Count := Char_Count + Set(Iter)'Length;
end loop;
Line_By_Column := File_index/(240/(Top_Col+4))+1;
--Line_By_Column := (240/Top_Col+4)+1;
Column_By_Page := (File_Index / Line_By_Column)+1;
declare
Table : File_Table(1..Line_By_Column, 1..Column_By_Page);
begin
for column in Table'Range(2) loop
for Line in Table'range(1) loop
Table(Line, Column) := Set(File_Counter+1);
File_Counter := File_Counter+1;
end loop;
end loop;
File_Counter := 0;
Main1 :
for Iter_L in Table'range(1) loop
for Iter_C in Table'Range(2) loop
if not Gnat.Os_Lib."="(Table(Iter_L, Iter_C), null) then
Put(Position(Line_Cur + Line + 1 , Col) & Table(Iter_L, Iter_C).all);
Col := Col + Top_Col;
File_Counter := File_Counter+1;
end if;
exit Main1 when File_Counter = File_Index;
end loop;
if Line_Cur + Line >= 66 then
New_Line;
else
Line := Line + 1;
end if;
Col := 1;
end loop main1;
end;
-- for Iter in 1..File_Index loop
-- if Set(Iter)'Length > Top_Col then
-- Top_Col := Set(Iter)'Length;
-- end if;
-- Put(Position(Line_Cur + Line + 1 , Col) & Set(Iter).all);
-- if Line_Cur + Line >= 66 then
-- New_Line;
-- end if;
-- Line := Line+1;
-- if Line+1 >= Line_By_Column then
-- Col := Col + Top_Col;
-- Line := 1;
-- end if;
-- end loop;
Line_Cur := Line_Cur + Line_By_Column+1;
Col := 1;
Top_Col := 1;
Line := 1;
end if;
end if;
end;
end loop;
else
Iterator(Current_Directory & "/*" );
Sort(Target);
File_Index := 0;
if not Is_Empty(Target) then
for Name in 1..Length(Target) loop
declare
File_Name : String_Access := Element(Target, Integer(Name));
begin
if Is_Directory(File_Name.all) then
Set(File_Index+1) := new String ' (Blue & Simple_Name(File_Name.all) & '/') ;
File_Index := File_Index + 1;
elsif Is_Executable_file(File_Name.all) then
Set(File_Index+1) := new String ' (Green & simple_Name(File_Name.all ));
File_Index := File_Index + 1;
elsif Extension(File_Name.all) = "tgz" or Extension(File_Name.all) = "tar" or
Extension(File_Name.all) = "zip" then
Set(File_Index+1) := new String ' (Red & base_Name(File_Name.all) & '.' & Extension(File_Name.all));
File_Index := File_Index + 1;
elsif Extension(File_Name.all) = "png" or Extension(File_Name.all) = "jpg" or
Extension(File_Name.all) = "jpeg" then
Set(File_Index+1) := new String ' (magenta & base_Name(File_Name.all) & '.' & Extension(File_Name.all));
File_Index := File_Index + 1;
elsif Extension(File_Name.all) = "iso" then
Set(File_Index+1) := new String ' (yellow & base_Name(File_Name.all) & '.' & Extension(File_Name.all));
File_Index := File_Index + 1;
elsif Is_Regular_File(File_Name.all) then
Set(File_Index+1) := new String ' (white & simple_Name(File_Name.all));
File_Index := File_Index + 1;
end if;
end;
end loop;
end if;
-- --
-- --
-- --
if File_Index /= 0 then
if Long_Option then
for I in 1..File_Index loop
if Is_Directory (Element(Target, Integer(I)).all) then
declare
Dir : String := Element(Target, integer(I)).all;
begin
if Dir /= "." and Dir /= ".." then
Start_Search(Dir_Match, Dir, dir);
Get_Next_Entry(Dir_Match, Dir_Path);
Date := Ada.Directories.Modification_time(Dir_Path);
Size := Long_Integer(Ada.Directories.Size(Dir_Path));
end if;
exception
when others =>
null;
end;
else
declare
Dir : String := Element(Target, integer(I)).all;
begin
if Dir /= "." and Dir /= ".." then
Date := Ada.Directories.Modification_time(Full_Name(dir));
Size := Long_Integer(Ada.Directories.Size(Full_Name(dir)));
end if;
end;
end if;
if Line_Cur + Line >= 66 then
New_Line;
Put(Position(67, 1) & Formatting.Image(Date));
Put(Position(67, 20) & Long_Integer'Image(Long_Integer(Size)));
Put(Position(67, 35) & Set(I).all & Normal);
else
Put(Position(Line_Cur + Line, 1) & Formatting.Image(Date));
Put(Position(Line_Cur + Line, 20) & Long_Integer'Image(Long_Integer(Size)));
Put(Position(Line_Cur + Line, 35) & Set(I).all & Normal);
Line := Line + 1;
end if;
Size := 0;
end loop;
Line_Cur := Positive'Min(Line_Cur + Line, 67);
Put(Position(Line_Cur, 1) & white);
else
for Iter in 1..File_Index loop
if Set(Iter)'Length > Top_Col then
Top_Col := Set(Iter)'Length;
end if;
Char_Count := Char_Count + Set(Iter)'Length;
end loop;
Line_By_Column := File_index/(240/(Top_Col+4))+1;
--Line_By_Column := (240/Top_Col+4)+1;
Column_By_Page := File_Index / Line_By_Column+1;
declare
Table : File_Table(1..Line_By_Column, 1..Column_By_Page);
begin
for column in Table'Range(2) loop
for Line in Table'range(1) loop
Table(Line, Column) := Set(File_Counter+1);
File_Counter := File_Counter+1;
end loop;
end loop;
File_Counter := 0;
Main2 :
for Iter_L in Table'range(1) loop
for Iter_C in Table'Range(2) loop
if not Gnat.Os_Lib."="(Table(Iter_L, Iter_C), null) then
Put(Position(Line_Cur + Line + 1 , Col) & Table(Iter_L, Iter_C).all);
Col := Col + Top_Col;
File_Counter := File_Counter+1;
end if;
exit Main2 when File_Counter = File_Index;
end loop;
if Line_Cur + Line >= 66 then
New_Line;
else
Line := Line + 1;
end if;
Col := 1;
end loop Main2;
end;
-- for Iter in 1..File_Index loop
-- if Set(Iter)'Length > Top_Col then
-- Top_Col := Set(Iter)'Length;
-- end if;
-- Put(Position(Line_Cur + Line + 1 , Col) & Set(Iter).all);
-- if Line >= 66 then
-- New_Line;
-- end if;
-- Line := Line+1;
-- if Line+1 >= Line_By_Column then
-- Col := Col + Top_Col;
-- Line := 1;
-- end if;
-- end loop;
Line_Cur := Line_Cur + Line_By_Column+1;
Col := 1;
Top_Col := 1;
Line := 1;
end if;
end if;
end if;
Put(Position(Line_Cur, 1));
New_Line;
end Xls;