Source file : rezip.adb
------------------------------------------------------------------------------
-- File: rezip.adb
-- Description: Recompression tool to make archives smaller.
-- Author: Gautier de Montmollin
------------------------------------------------------------------------------
with Rezip_lib, Comp_Zip_Prc, Zip;
with Show_License;
with Ada.Command_Line,
Ada.Characters.Handling,
Ada.Strings.Unbounded,
Ada.Text_IO;
procedure ReZip is
procedure Blurb is
use Ada.Text_IO;
begin
Put_Line ("ReZip * Zip file recompression tool.");
Put_Line ("Author: Gautier de Montmollin");
Put_Line ("Library version " & Zip.version & " dated " & Zip.reference);
Put_Line ("URL: " & Zip.web);
Show_License (Current_Output, "zip.ads");
end Blurb;
procedure Usage is
use Ada.Text_IO;
begin
Put_Line ("Usage: rezip [options] archive(s)[.zip]");
New_Line;
Put_Line ("Options: -defl : repack archive only with the Deflate");
Put_Line (" subformat (most compatible)");
Put_Line (" -fast_dec : repack archive only with fast decompressing subformats");
Put_Line (" -int : use internal Zip-Ada algorithms only, no external call");
Put_Line (" -touch : set time stamps to now");
Put_Line (" -lower : set full file names to lower case");
Put_Line (" -del_comm : delete comment");
Put_Line (" -comp : compare original and repacked archives (paranoid mode)");
Put_Line (" -rs=n : loop many times over a single compression approach");
Put_Line (" having randomization, and keep optimum when its");
Put_Line (" size is stable after n attempts in a row");
Put_Line (" -temp=x : set alternative radix for temp files");
Put_Line (" for instance: ""y:\ram_temp\rz_"" or ""rz_""");
New_Line;
Put_Line ("External programs (available for Windows and Linux) are used, except");
Put_Line ("when ReZip is called with the ""-int"" option.");
Put_Line ("The external programs must be callable through the ""path"".");
Put_Line ("List of external programs:");
New_Line;
Rezip_lib.Show_external_packer_list;
New_Line;
Put ("Press Return");
Skip_Line;
end Usage;
function Add_zip_ext (s : String) return String is
begin
if Zip.Exists (s) then
return s;
else
return s & ".zip";
-- Maybe the file doesn't exist, but we tried our best...
end if;
end Add_zip_ext;
function Get_ext (s : String) return String is
dot : Integer := s'Last;
begin
for i in reverse s'Range loop
if s (i) = '.' then
dot := i;
exit;
end if;
end loop;
if s = "" or dot = s'Last then -- no extension in all cases:
return "zip"; -- "", "xxx." or "xxx"
else
return s (dot + 1 .. s'Last);
end if;
end Get_ext;
function Remove_ext (s : String) return String is
dot : Integer := s'Last + 1;
begin
if s = "" then
return s;
end if;
for i in reverse s'Range loop
if s (i) = '.' then
dot := i;
exit;
end if;
end loop;
return s (s'First .. dot - 1);
-- "xxx" returned in all cases: "xxx.ext", "xxx." or "xxx"
end Remove_ext;
use Rezip_lib;
touch, lower, del_comment, compare, internal : Boolean := False;
rand_stable : Positive := 1;
format_choice : Zip_format_set := all_formats;
total_differences : Natural;
use Ada.Command_Line, Ada.Characters.Handling, Ada.Strings.Unbounded;
alt_temp : Unbounded_String;
begin
Blurb;
if Argument_Count = 0 then
Usage;
return;
end if;
for i in 1 .. Argument_Count loop
declare
arg : constant String := Argument (i);
arg_zip : constant String := Add_zip_ext (arg);
ext : constant String := Get_ext (arg_zip);
arg_nozip : constant String := Remove_ext (arg_zip);
arg_rezip : constant String := arg_nozip & ".repacked." & ext;
arg_rpt : constant String := arg_nozip & ".ReZip.html";
arg_log : constant String := arg_nozip & ".ReZip.log";
info_original_zip,
info_rezipped_zip : Zip.Zip_Info;
begin
if arg (arg'First) = '-' or arg (arg'First) = '/' then
-- Options
declare
opt : constant String := To_Lower (arg (arg'First + 1 .. arg'Last));
begin
if opt = "defl" then
format_choice := deflate_or_store;
elsif opt = "fast_dec" then
format_choice := fast_decompression;
elsif opt = "int" then
internal := True;
elsif opt = "comp" then
compare := True;
elsif opt = "touch" then
touch := True;
elsif opt = "lower" then
lower := True;
elsif opt = "del_comm" then
del_comment := True;
elsif opt'Length > 12 and then
opt (opt'First .. opt'First + 11) = "rand_stable=" -- old / long version of this option
then
rand_stable := Integer'Value (opt (opt'First + 12 .. opt'Last));
elsif opt'Length > 3 and then
opt (opt'First .. opt'First + 2) = "rs="
then
rand_stable := Integer'Value (opt (opt'First + 3 .. opt'Last));
elsif opt'Length > 5 and then
opt (opt'First .. opt'First + 4) = "temp="
then
alt_temp := To_Unbounded_String (opt (opt'First + 5 .. opt'Last));
end if;
end;
elsif Zip.Exists (arg_zip) then
Rezip_lib.Rezip (
from_zip_file => arg_zip,
to_zip_file => arg_rezip,
format_choice => format_choice,
touch => touch,
lower => lower,
delete_comment => del_comment,
randomized_stable => rand_stable,
log_file => arg_log,
html_report => arg_rpt,
alt_tmp_file_radix => To_String (alt_temp),
internal_only => internal
);
if compare then
Zip.Load (info_original_zip, arg_zip);
Zip.Load (info_rezipped_zip, arg_rezip);
Comp_Zip_Prc (
info_original_zip, info_rezipped_zip,
quiet => 2,
total_differences => total_differences);
end if;
else
Ada.Text_IO.Put_Line (" ** Error: archive not found: " & arg_zip);
end if;
end;
end loop;
exception
when External_Tool_Failed => null; -- Messages have been already issued.
end ReZip;
Zip-Ada: Ada library for zip archive files (.zip).
Ada programming.
Some news about Zip-Ada and other Ada projects
on Gautier's blog.