---------------------------------------------------------------------
-- (C) Michael A Smith 1993-2000 University of Brighton --
-- http://www.cem.brighton.ac.uk/staff/mas --
---------------------------------------------------------------------
-- Ada 95 program --
-- Version automatically created Sat 29 Apr 2000 08:50:59 PM BST --
---------------------------------------------------------------------
with Ada.Text_Io;
use Ada.Text_Io;
package Class_Line is
type Line_Status is ( Text_Line, File_Name, Unknown );
type Line is private;
procedure Get_Line( The:in out Line; Fd:in Ada.Text_Io.File_Type );
procedure Put_Line( The:in Line; Fd:in Ada.Text_Io.File_Type );
procedure Get_Fd( The:in out Line; Fd:in out Ada.Text_Io.File_Type );
function Status( The:in Line ) return Line_Status;
private
Max_Line : constant := 200;
subtype Line_Index is Integer range 0 .. Max_Line+1;
subtype Line_Range is Line_Index range 1 .. Max_Line;
subtype Line_Array is String( Line_Range );
type Line is record
Chs : Line_Array; -- Characters of line
Len : Line_Index; -- Positions used
Open: Boolean := False; -- Output file open
end record;
Name : Line_Array; -- File name from file
Name_Pos : Line_Index; -- Characters in name
end Class_Line;
with Ada.Text_Io, Ada.Characters.Handling;
use Ada.Text_Io, Ada.Characters.Handling;
package body Class_Line is
procedure Get_Line( The:in out Line; Fd:in Ada.Text_Io.File_Type ) is
Pos : Line_Index := 0;
Ch : Character;
begin
while not End_Of_Line( Fd ) loop
Get( Fd, Ch );
if Pos < Max_Line then
Pos := Pos + 1;
The.Chs(Pos) := Ch;
end if;
end loop;
The.Len := Pos;
Skip_Line( Fd );
end Get_Line;
procedure Put_Line( The:in Line; Fd:in Ada.Text_Io.File_Type ) is
begin
if The.Open then
for I in 2 .. The.Len loop
Put( Fd, The.Chs(I) );
end loop;
New_Line( Fd );
end if;
end Put_Line;
function Status( The:in Line ) return Line_Status is
Pos : Line_Index := 0;
begin
if The.Len >= 1 and then The.Chs(1) = '+' then
return Text_Line;
end if;
if The.Len >= 2 and then The.Chs(1..2) = "@@" then
for I in 3 .. The.Len-2 loop
if Is_Upper( The.Chs(I) ) or Is_Lower( The.Chs(I) ) or
Is_Digit( The.Chs(I) ) or The.Chs(I) = '_' or
The.Chs(I) = '.' then
Pos := Pos + 1;
Name(Pos) := The.Chs(I);
end if;
end loop;
Name_Pos := Pos;
Put( "Extracting file " & Name(1..Pos) ); New_Line;
return File_Name;
end if;
return Unknown;
end Status;
procedure Get_Fd( The:in out Line; Fd:in out Ada.Text_Io.File_Type ) is
begin
if The.Open then -- Output file open
Close( Fd ); The.Open := False;
end if;
Create( File=>Fd, Mode=>Out_File, -- Create file
Name=>Name(1..Name_Pos) );
The.Open := True;
exception
when Name_Error =>
Put("Exp: Can not create file " & Name(1..Name_Pos) );
New_Line;
when Status_Error =>
Put("Exp: " & Name(1..Name_Pos) & " all ready open" );
New_Line;
when others =>
Put("Exp: " & Name(1..Name_Pos) & " unknown error" );
New_Line;
end;
end Class_Line;
with Ada.Text_Io, Ada.Command_Line, Class_Line;
use Ada.Text_Io, Ada.Command_Line, Class_Line;
procedure Main is
I_Fd : Ada.Text_Io.File_Type; -- File descriptor
O_Fd : Ada.Text_Io.File_Type; -- File descriptor
A_Line : Class_Line.Line;
begin
if Argument_Count >= 1 then
for I in 1 .. Argument_Count loop -- Repeat for each file
begin
Open( File=>I_Fd, Mode=>In_File, -- Open file
Name=>Argument(I) );
while not End_Of_File(I_Fd) loop -- For each Line
Get_Line( A_Line, I_Fd );
case Status(A_Line) is
when Text_Line => -- Write to file
Put_Line( A_Line, O_Fd );
when File_Name => -- Get file name
Get_Fd( A_Line, O_Fd );
when Unknown => -- Ignore
null;
end case;
end loop;
Close(I_Fd); -- Close file
exception
when Name_Error =>
Put("Exp: " & Argument(I) & " no such file" );
New_Line;
when Status_Error =>
Put("Exp: " & Argument(I) & " all ready open" );
New_Line;
when others =>
Put("Exp: " & Argument(I) & " unknow error" );
New_Line;
end;
end loop;
else
Put("Usage: Exp file1 ... "); New_Line;
end if;
end Main;
|
© M.A.Smith University of Brighton.
Created March 2000 Last modified March 2000 Version 1.1
Comments, suggestions, etc. M.A.Smith at brighton dot ac dot uk [Home page] Printed / Displayed |