-- Zip_Dir_List shows the list of all directories appearing in a Zip archive file. -- -- Tool originally made for answering: -- -- https://stackoverflow.com/questions/32508443/how-to-get-a-list-of-directories-in-a-zip with Zip; with Show_License; with Ada.Command_Line; use Ada.Command_Line; with Ada.Containers.Ordered_Maps; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Text_IO; use Ada.Text_IO; procedure Zip_Dir_List is function S (Source : Ada.Strings.Unbounded.Unbounded_String) return String renames Ada.Strings.Unbounded.To_String; function U (Source : String) return Ada.Strings.Unbounded.Unbounded_String renames Ada.Strings.Unbounded.To_Unbounded_String; package Dir_maps is new Ada.Containers.Ordered_Maps ( Key_Type => Unbounded_String, Element_Type => Unbounded_String, "<" => "<", "=" => "=" ); dir_map : Dir_maps.Map; procedure Record_directory (n : String) is sep : Natural := 0; begin for i in n'Range loop if n (i) = '/' or n (i) = '\' then -- NB: - a Zip file should use '/' as separator, but some may have it wrong... -- - compatible with UTF-8 strings -- sep := i; end if; end loop; if sep > 0 then declare the_path : constant Unbounded_String := U (n (n'First .. sep)); use Dir_maps; begin if dir_map.Find (the_path) = No_Element then dir_map.Insert (the_path, the_path); -- We store the path as key *and* element end if; end; end if; end Record_directory; procedure Record_directories is new Zip.Traverse (Record_directory); function Try_with_zip (file_name : String) return String is begin if Zip.Exists (file_name) then return file_name; else return file_name & ".zip"; -- Maybe the file doesn't exist, but we tried our best... end if; end Try_with_zip; z : Zip.Zip_info; begin if Argument_Count < 1 then Put_Line ("Zip_Dir_List * Shows the list of all directories appearing in a Zip archive file."); Put_Line ("Demo for the Zip-Ada library, by G. de Montmollin"); Put_Line ("Library version " & Zip.version & " dated " & Zip.reference); Put_Line ("URL: " & Zip.web); Show_License (Current_Output, "zip.ads"); Put_Line ("Usage: zip_dir_list archive[.zip]"); return; end if; declare n : constant String := Try_with_zip (Argument (1)); begin Zip.Load (z, n); exception when Zip.Archive_open_error => Put ("Can't open archive [" & n & ']'); raise; end; Record_directories (z); -- -- Show results -- for d of dir_map loop Put_Line (S (d)); end loop; end Zip_Dir_List;