------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              G N A T . A W K                             --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--            Copyright (C) 2000-2003 Ada Core Technologies, Inc.           --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT;  see file COPYING.  If not, write --
-- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
-- MA 02111-1307, USA.                                                      --
--                                                                          --
-- As a special exception,  if other files  instantiate  generics from this --
-- unit, or you link  this unit with other files  to produce an executable, --
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
-- covered  by the  GNU  General  Public  License.  This exception does not --
-- however invalidate  any other reasons why  the executable file  might be --
-- covered by the  GNU Public License.                                      --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

pragma Style_Checks (All_Checks);
--  Turn off alpha ordering check for subprograms, since we cannot
--  Put Finalize and Initialize in alpha order (see comments).

with Ada.Exceptions;
with Ada.Text_IO;
with Ada.Strings.Unbounded;
with Ada.Strings.Fixed;
with Ada.Strings.Maps;
with Ada.Unchecked_Deallocation;

with GNAT.Directory_Operations;
with GNAT.Dynamic_Tables;
with GNAT.OS_Lib;

package body GNAT.AWK is

   use Ada;
   use Ada.Strings.Unbounded;

   ----------------
   -- Split mode --
   ----------------

   package Split is

      type Mode is abstract tagged null record;
      --  This is the main type which is declared abstract. This type must be
      --  derived for each split style.

      type Mode_Access is access Mode'Class;

      procedure Current_Line (S : Mode; Session : Session_Type)
        is abstract;
      --  Split Session's current line using split mode.

      ------------------------
      -- Split on separator --
      ------------------------

      type Separator (Size : Positive) is new Mode with record
         Separators : String (1 .. Size);
      end record;

      procedure Current_Line
        (S       : Separator;
         Session : Session_Type);

      ---------------------
      -- Split on column --
      ---------------------

      type Column (Size : Positive) is new Mode with record
         Columns : Widths_Set (1 .. Size);
      end record;

      procedure Current_Line (S : Column; Session : Session_Type);

   end Split;

   procedure Free is new Unchecked_Deallocation
     (Split.Mode'Class, Split.Mode_Access);

   ----------------
   -- File_Table --
   ----------------

   type AWK_File is access String;

   package File_Table is
      new Dynamic_Tables (AWK_File, Natural, 1, 5, 50);
   --  List of filename associated with a Session.

   procedure Free is new Unchecked_Deallocation (String, AWK_File);

   -----------------
   -- Field_Table --
   -----------------

   type Field_Slice is record
      First : Positive;
      Last  : Natural;
   end record;
   --  This is a field slice (First .. Last) in session's current line.

   package Field_Table is
      new Dynamic_Tables (Field_Slice, Natural, 1, 10, 100);
   --  List of fields for the current line.

   --------------
   -- Patterns --
   --------------

   --  Define all patterns style : exact string, regular expression, boolean
   --  function.

   package Patterns is

      type Pattern is abstract tagged null record;
      --  This is the main type which is declared abstract. This type must be
      --  derived for each patterns style.

      type Pattern_Access is access Pattern'Class;

      function Match
        (P       : Pattern;
         Session : Session_Type)
         return    Boolean
      is abstract;
      --  Returns True if P match for the current session and False otherwise.

      procedure Release (P : in out Pattern);
      --  Release memory used by the pattern structure.

      --------------------------
      -- Exact string pattern --
      --------------------------

      type String_Pattern is new Pattern with record
         Str  : Unbounded_String;
         Rank : Count;
      end record;

      function Match
        (P       : String_Pattern;
         Session : Session_Type)
         return    Boolean;

      --------------------------------
      -- Regular expression pattern --
      --------------------------------

      type Pattern_Matcher_Access is access Regpat.Pattern_Matcher;

      type Regexp_Pattern is new Pattern with record
         Regx : Pattern_Matcher_Access;
         Rank : Count;
      end record;

      function Match
        (P       : Regexp_Pattern;
         Session : Session_Type)
         return    Boolean;

      procedure Release (P : in out Regexp_Pattern);

      ------------------------------
      -- Boolean function pattern --
      ------------------------------

      type Callback_Pattern is new Pattern with record
         Pattern : Pattern_Callback;
      end record;

      function Match
        (P       : Callback_Pattern;
         Session : Session_Type)
         return    Boolean;

   end Patterns;

   procedure Free is new Unchecked_Deallocation
     (Patterns.Pattern'Class, Patterns.Pattern_Access);

   -------------
   -- Actions --
   -------------

   --  Define all action style : simple call, call with matches

   package Actions is

      type Action is abstract tagged null record;
      --  This is the main type which is declared abstract. This type must be
      --  derived for each action style.

      type Action_Access is access Action'Class;

      procedure Call
        (A       : Action;
         Session : Session_Type)
         is abstract;
      --  Call action A as required.

      -------------------
      -- Simple action --
      -------------------

      type Simple_Action is new Action with record
         Proc : Action_Callback;
      end record;

      procedure Call
        (A       : Simple_Action;
         Session : Session_Type);

      -------------------------
      -- Action with matches --
      -------------------------

      type Match_Action is new Action with record
         Proc : Match_Action_Callback;
      end record;

      procedure Call
        (A       : Match_Action;
         Session : Session_Type);

   end Actions;

   procedure Free is new Unchecked_Deallocation
     (Actions.Action'Class, Actions.Action_Access);

   --------------------------
   -- Pattern/Action table --
   --------------------------

   type Pattern_Action is record
      Pattern : Patterns.Pattern_Access;  -- If Pattern is True
      Action  : Actions.Action_Access;    -- Action will be called
   end record;

   package Pattern_Action_Table is
      new Dynamic_Tables (Pattern_Action, Natural, 1, 5, 50);

   ------------------
   -- Session Data --
   ------------------

   type Session_Data is record
      Current_File : Text_IO.File_Type;
      Current_Line : Unbounded_String;
      Separators   : Split.Mode_Access;
      Files        : File_Table.Instance;
      File_Index   : Natural := 0;
      Fields       : Field_Table.Instance;
      Filters      : Pattern_Action_Table.Instance;
      NR           : Natural := 0;
      FNR          : Natural := 0;
      Matches      : Regpat.Match_Array (0 .. 100);
      --  latest matches for the regexp pattern
   end record;

   procedure Free is
      new Unchecked_Deallocation (Session_Data, Session_Data_Access);

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize (Session : in out Session_Type) is
   begin
      Session.Data := new Session_Data;

      --  Initialize separators

      Session.Data.Separators :=
        new Split.Separator'(Default_Separators'Length, Default_Separators);

      --  Initialize all tables

      File_Table.Init  (Session.Data.Files);
      Field_Table.Init (Session.Data.Fields);
      Pattern_Action_Table.Init (Session.Data.Filters);
   end Initialize;

   -----------------------
   -- Session Variables --
   -----------------------

   --  These must come after the body of Initialize, since they make
   --  implicit calls to Initialize at elaboration time.

   Def_Session : Session_Type;
   Cur_Session : Session_Type;

   --------------
   -- Finalize --
   --------------

   --  Note: Finalize must come after Initialize and the definition
   --  of the Def_Session and Cur_Session variables, since it references
   --  the latter.

   procedure Finalize (Session : in out Session_Type) is
   begin
      --  We release the session data only if it is not the default session.

      if Session.Data /= Def_Session.Data then
         Free (Session.Data);

         --  Since we have closed the current session, set it to point
         --  now to the default session.

         Cur_Session.Data := Def_Session.Data;
      end if;
   end Finalize;

   ----------------------
   -- Private Services --
   ----------------------

   function Always_True return Boolean;
   --  A function that always returns True.

   function Apply_Filters
     (Session : Session_Type := Current_Session)
      return    Boolean;
   --  Apply any filters for which the Pattern is True for Session. It returns
   --  True if a least one filters has been applied (i.e. associated action
   --  callback has been called).

   procedure Open_Next_File
     (Session : Session_Type := Current_Session);
   pragma Inline (Open_Next_File);
   --  Open next file for Session closing current file if needed. It raises
   --  End_Error if there is no more file in the table.

   procedure Raise_With_Info
     (E       : Exceptions.Exception_Id;
      Message : String;
      Session : Session_Type);
   pragma No_Return (Raise_With_Info);
   --  Raises exception E with the message prepended with the current line
   --  number and the filename if possible.

   procedure Read_Line (Session : Session_Type);
   --  Read a line for the Session and set Current_Line.

   procedure Split_Line (Session : Session_Type);
   --  Split session's Current_Line according to the session separators and
   --  set the Fields table. This procedure can be called at any time.

   ----------------------
   -- Private Packages --
   ----------------------

   -------------
   -- Actions --
   -------------

   package body Actions is

      ----------
      -- Call --
      ----------

      procedure Call
        (A       : Simple_Action;
         Session : Session_Type)
      is
         pragma Unreferenced (Session);

      begin
         A.Proc.all;
      end Call;

      ----------
      -- Call --
      ----------

      procedure Call
        (A       : Match_Action;
         Session : Session_Type)
      is
      begin
         A.Proc (Session.Data.Matches);
      end Call;

   end Actions;

   --------------
   -- Patterns --
   --------------

   package body Patterns is

      -----------
      -- Match --
      -----------

      function Match
        (P       : String_Pattern;
         Session : Session_Type)
         return    Boolean
      is
      begin
         return P.Str = Field (P.Rank, Session);
      end Match;

      -----------
      -- Match --
      -----------

      function Match
        (P       : Regexp_Pattern;
         Session : Session_Type)
         return    Boolean
      is
         use type Regpat.Match_Location;

      begin
         Regpat.Match
           (P.Regx.all, Field (P.Rank, Session), Session.Data.Matches);
         return Session.Data.Matches (0) /= Regpat.No_Match;
      end Match;

      -----------
      -- Match --
      -----------

      function Match
        (P       : Callback_Pattern;
         Session : Session_Type)
         return    Boolean
      is
         pragma Unreferenced (Session);

      begin
         return P.Pattern.all;
      end Match;

      -------------
      -- Release --
      -------------

      procedure Release (P : in out Pattern) is
         pragma Unreferenced (P);

      begin
         null;
      end Release;

      -------------
      -- Release --
      -------------

      procedure Release (P : in out Regexp_Pattern) is
         procedure Free is new Unchecked_Deallocation
           (Regpat.Pattern_Matcher, Pattern_Matcher_Access);

      begin
         Free (P.Regx);
      end Release;

   end Patterns;

   -----------
   -- Split --
   -----------

   package body Split is

      use Ada.Strings;

      ------------------
      -- Current_Line --
      ------------------

      procedure Current_Line (S : Separator; Session : Session_Type) is
         Line   : constant String := To_String (Session.Data.Current_Line);
         Fields : Field_Table.Instance renames Session.Data.Fields;

         Start : Natural;
         Stop  : Natural;

         Seps  : constant Maps.Character_Set := Maps.To_Set (S.Separators);

      begin
         --  First field start here

         Start := Line'First;

         --  Record the first field start position which is the first character
         --  in the line.

         Field_Table.Increment_Last (Fields);
         Fields.Table (Field_Table.Last (Fields)).First := Start;

         loop
            --  Look for next separator

            Stop := Fixed.Index
              (Source  => Line (Start .. Line'Last),
               Set     => Seps);

            exit when Stop = 0;

            Fields.Table (Field_Table.Last (Fields)).Last := Stop - 1;

            --  If separators are set to the default (space and tab) we skip
            --  all spaces and tabs following current field.

            if S.Separators = Default_Separators then
               Start := Fixed.Index
                 (Line (Stop + 1 .. Line'Last),
                  Maps.To_Set (Default_Separators),
                  Outside,
                  Strings.Forward);

               if Start = 0 then
                  Start := Stop + 1;
               end if;
            else
               Start := Stop + 1;
            end if;

            --  Record in the field table the start of this new field

            Field_Table.Increment_Last (Fields);
            Fields.Table (Field_Table.Last (Fields)).First := Start;

         end loop;

         Fields.Table (Field_Table.Last (Fields)).Last := Line'Last;
      end Current_Line;

      ------------------
      -- Current_Line --
      ------------------

      procedure Current_Line (S : Column; Session : Session_Type) is
         Line   : constant String := To_String (Session.Data.Current_Line);
         Fields : Field_Table.Instance renames Session.Data.Fields;
         Start  : Positive := Line'First;

      begin
         --  Record the first field start position which is the first character
         --  in the line.

         for C in 1 .. S.Columns'Length loop

            Field_Table.Increment_Last (Fields);

            Fields.Table (Field_Table.Last (Fields)).First := Start;

            Start := Start + S.Columns (C);

            Fields.Table (Field_Table.Last (Fields)).Last := Start - 1;

         end loop;

         --  If there is some remaining character on the line, add them in a
         --  new field.

         if Start - 1 < Line'Length then

            Field_Table.Increment_Last (Fields);

            Fields.Table (Field_Table.Last (Fields)).First := Start;

            Fields.Table (Field_Table.Last (Fields)).Last := Line'Last;
         end if;
      end Current_Line;

   end Split;

   --------------
   -- Add_File --
   --------------

   procedure Add_File
     (Filename : String;
      Session  : Session_Type := Current_Session)
   is
      Files : File_Table.Instance renames Session.Data.Files;

   begin
      if OS_Lib.Is_Regular_File (Filename) then
         File_Table.Increment_Last (Files);
         Files.Table (File_Table.Last (Files)) := new String'(Filename);
      else
         Raise_With_Info
           (File_Error'Identity,
            "File " & Filename & " not found.",
            Session);
      end if;
   end Add_File;

   ---------------
   -- Add_Files --
   ---------------

   procedure Add_Files
     (Directory             : String;
      Filenames             : String;
      Number_Of_Files_Added : out Natural;
      Session               : Session_Type := Current_Session)
   is
      use Directory_Operations;

      Dir      : Dir_Type;
      Filename : String (1 .. 200);
      Last     : Natural;

   begin
      Number_Of_Files_Added := 0;

      Open (Dir, Directory);

      loop
         Read (Dir, Filename, Last);
         exit when Last = 0;

         Add_File (Filename (1 .. Last), Session);
         Number_Of_Files_Added := Number_Of_Files_Added + 1;
      end loop;

      Close (Dir);

   exception
      when others =>
         Raise_With_Info
           (File_Error'Identity,
            "Error scaning directory " & Directory
            & " for files " & Filenames & '.',
            Session);
   end Add_Files;

   -----------------
   -- Always_True --
   -----------------

   function Always_True return Boolean is
   begin
      return True;
   end Always_True;

   -------------------
   -- Apply_Filters --
   -------------------

   function Apply_Filters
     (Session : Session_Type := Current_Session)
      return    Boolean
   is
      Filters : Pattern_Action_Table.Instance renames Session.Data.Filters;
      Results : Boolean := False;

   begin
      --  Iterate through the filters table, if pattern match call action.

      for F in 1 .. Pattern_Action_Table.Last (Filters) loop
         if Patterns.Match (Filters.Table (F).Pattern.all, Session) then
            Results := True;
            Actions.Call (Filters.Table (F).Action.all, Session);
         end if;
      end loop;

      return Results;
   end Apply_Filters;

   -----------
   -- Close --
   -----------

   procedure Close (Session : Session_Type) is
      Filters : Pattern_Action_Table.Instance renames Session.Data.Filters;
      Files   : File_Table.Instance renames Session.Data.Files;

   begin
      --  Close current file if needed

      if Text_IO.Is_Open (Session.Data.Current_File) then
         Text_IO.Close (Session.Data.Current_File);
      end if;

      --  Release separators

      Free (Session.Data.Separators);

      --  Release Filters table

      for F in 1 .. Pattern_Action_Table.Last (Filters) loop
         Patterns.Release (Filters.Table (F).Pattern.all);
         Free (Filters.Table (F).Pattern);
         Free (Filters.Table (F).Action);
      end loop;

      for F in 1 .. File_Table.Last (Files) loop
         Free (Files.Table (F));
      end loop;

      File_Table.Set_Last (Session.Data.Files, 0);
      Field_Table.Set_Last (Session.Data.Fields, 0);
      Pattern_Action_Table.Set_Last (Session.Data.Filters, 0);

      Session.Data.NR := 0;
      Session.Data.FNR := 0;
      Session.Data.File_Index := 0;
      Session.Data.Current_Line := Null_Unbounded_String;
   end Close;

   ---------------------
   -- Current_Session --
   ---------------------

   function Current_Session return Session_Type is
   begin
      return Cur_Session;
   end Current_Session;

   ---------------------
   -- Default_Session --
   ---------------------

   function Default_Session return Session_Type is
   begin
      return Def_Session;
   end Default_Session;

   --------------------
   -- Discrete_Field --
   --------------------

   function Discrete_Field
     (Rank    : Count;
      Session : Session_Type := Current_Session)
      return    Discrete
   is
   begin
      return Discrete'Value (Field (Rank, Session));
   end Discrete_Field;

   -----------------
   -- End_Of_Data --
   -----------------

   function End_Of_Data
     (Session : Session_Type := Current_Session)
      return    Boolean
   is
   begin
      return Session.Data.File_Index = File_Table.Last (Session.Data.Files)
        and then End_Of_File (Session);
   end End_Of_Data;

   -----------------
   -- End_Of_File --
   -----------------

   function End_Of_File
     (Session : Session_Type := Current_Session)
      return    Boolean
   is
   begin
      return Text_IO.End_Of_File (Session.Data.Current_File);
   end End_Of_File;

   -----------
   -- Field --
   -----------

   function Field
     (Rank    : Count;
      Session : Session_Type := Current_Session)
      return    String
   is
      Fields : Field_Table.Instance renames Session.Data.Fields;

   begin
      if Rank > Number_Of_Fields (Session) then
         Raise_With_Info
           (Field_Error'Identity,
            "Field number" & Count'Image (Rank) & " does not exist.",
            Session);

      elsif Rank = 0 then

         --  Returns the whole line, this is what $0 does under Session_Type.

         return To_String (Session.Data.Current_Line);

      else
         return Slice (Session.Data.Current_Line,
                       Fields.Table (Positive (Rank)).First,
                       Fields.Table (Positive (Rank)).Last);
      end if;
   end Field;

   function Field
     (Rank    : Count;
      Session : Session_Type := Current_Session)
      return    Integer
   is
   begin
      return Integer'Value (Field (Rank, Session));

   exception
      when Constraint_Error =>
         Raise_With_Info
           (Field_Error'Identity,
            "Field number" & Count'Image (Rank)
            & " cannot be converted to an integer.",
            Session);
   end Field;

   function Field
     (Rank    : Count;
      Session : Session_Type := Current_Session)
      return    Float
   is
   begin
      return Float'Value (Field (Rank, Session));

   exception
      when Constraint_Error =>
         Raise_With_Info
           (Field_Error'Identity,
            "Field number" & Count'Image (Rank)
            & " cannot be converted to a float.",
            Session);
   end Field;

   ----------
   -- File --
   ----------

   function File
     (Session : Session_Type := Current_Session)
      return    String
   is
      Files : File_Table.Instance renames Session.Data.Files;

   begin
      if Session.Data.File_Index = 0 then
         return "??";
      else
         return Files.Table (Session.Data.File_Index).all;
      end if;
   end File;

   --------------------
   -- For_Every_Line --
   --------------------

   procedure For_Every_Line
     (Separators : String        := Use_Current;
      Filename   : String        := Use_Current;
      Callbacks  : Callback_Mode := None;
      Session    : Session_Type  := Current_Session)
   is
      Quit : Boolean;

   begin
      Open (Separators, Filename, Session);

      while not End_Of_Data (Session) loop
         Read_Line (Session);
         Split_Line (Session);

         if Callbacks in Only .. Pass_Through then
            declare
               Discard : Boolean;
               pragma Unreferenced (Discard);
            begin
               Discard := Apply_Filters (Session);
            end;
         end if;

         if Callbacks /= Only then
            Quit := False;
            Action (Quit);
            exit when Quit;
         end if;
      end loop;

      Close (Session);
   end For_Every_Line;

   --------------
   -- Get_Line --
   --------------

   procedure Get_Line
     (Callbacks : Callback_Mode := None;
      Session   : Session_Type := Current_Session)
   is
      Filter_Active : Boolean;

   begin
      if not Text_IO.Is_Open (Session.Data.Current_File) then
         raise File_Error;
      end if;

      loop
         Read_Line (Session);
         Split_Line (Session);

         case Callbacks is

            when None =>
               exit;

            when Only =>
               Filter_Active := Apply_Filters (Session);
               exit when not Filter_Active;

            when Pass_Through =>
               Filter_Active := Apply_Filters (Session);
               exit;

         end case;
      end loop;
   end Get_Line;

   ----------------------
   -- Number_Of_Fields --
   ----------------------

   function Number_Of_Fields
     (Session : Session_Type := Current_Session)
      return    Count
   is
   begin
      return Count (Field_Table.Last (Session.Data.Fields));
   end Number_Of_Fields;

   --------------------------
   -- Number_Of_File_Lines --
   --------------------------

   function Number_Of_File_Lines
     (Session : Session_Type := Current_Session)
      return    Count
   is
   begin
      return Count (Session.Data.FNR);
   end Number_Of_File_Lines;

   ---------------------
   -- Number_Of_Files --
   ---------------------

   function Number_Of_Files
     (Session : Session_Type := Current_Session)
      return    Natural
   is
      Files : File_Table.Instance renames Session.Data.Files;

   begin
      return File_Table.Last (Files);
   end Number_Of_Files;

   ---------------------
   -- Number_Of_Lines --
   ---------------------

   function Number_Of_Lines
     (Session : Session_Type := Current_Session)
      return    Count
   is
   begin
      return Count (Session.Data.NR);
   end Number_Of_Lines;

   ----------
   -- Open --
   ----------

   procedure Open
     (Separators : String       := Use_Current;
      Filename   : String       := Use_Current;
      Session    : Session_Type := Current_Session)
   is
   begin
      if Text_IO.Is_Open (Session.Data.Current_File) then
         raise Session_Error;
      end if;

      if Filename /= Use_Current then
         File_Table.Init (Session.Data.Files);
         Add_File (Filename, Session);
      end if;

      if Separators /= Use_Current then
         Set_Field_Separators (Separators, Session);
      end if;

      Open_Next_File (Session);

   exception
      when End_Error =>
         raise File_Error;
   end Open;

   --------------------
   -- Open_Next_File --
   --------------------

   procedure Open_Next_File
     (Session : Session_Type := Current_Session)
   is
      Files : File_Table.Instance renames Session.Data.Files;

   begin
      if Text_IO.Is_Open (Session.Data.Current_File) then
         Text_IO.Close (Session.Data.Current_File);
      end if;

      Session.Data.File_Index := Session.Data.File_Index + 1;

      --  If there are no mores file in the table, raise End_Error

      if Session.Data.File_Index > File_Table.Last (Files) then
         raise End_Error;
      end if;

      Text_IO.Open
        (File => Session.Data.Current_File,
         Name => Files.Table (Session.Data.File_Index).all,
         Mode => Text_IO.In_File);
   end Open_Next_File;

   -----------
   -- Parse --
   -----------

   procedure Parse
     (Separators : String       := Use_Current;
      Filename   : String       := Use_Current;
      Session    : Session_Type := Current_Session)
   is
      Filter_Active : Boolean;
      pragma Unreferenced (Filter_Active);

   begin
      Open (Separators, Filename, Session);

      while not End_Of_Data (Session) loop
         Get_Line (None, Session);
         Filter_Active := Apply_Filters (Session);
      end loop;

      Close (Session);
   end Parse;

   ---------------------
   -- Raise_With_Info --
   ---------------------

   procedure Raise_With_Info
     (E       : Exceptions.Exception_Id;
      Message : String;
      Session : Session_Type)
   is
      function Filename return String;
      --  Returns current filename and "??" if the informations is not
      --  available.

      function Line return String;
      --  Returns current line number without the leading space

      --------------
      -- Filename --
      --------------

      function Filename return String is
         File : constant String := AWK.File (Session);

      begin
         if File = "" then
            return "??";
         else
            return File;
         end if;
      end Filename;

      ----------
      -- Line --
      ----------

      function Line return String is
         L : constant String := Natural'Image (Session.Data.FNR);

      begin
         return L (2 .. L'Last);
      end Line;

   --  Start of processing for Raise_With_Info

   begin
      Exceptions.Raise_Exception
        (E,
         '[' & Filename & ':' & Line & "] " & Message);
      raise Constraint_Error; -- to please GNAT as this is a No_Return proc
   end Raise_With_Info;

   ---------------
   -- Read_Line --
   ---------------

   procedure Read_Line (Session : Session_Type) is

      function Read_Line return String;
      --  Read a line in the current file. This implementation is recursive
      --  and does not have a limitation on the line length.

      NR  : Natural renames Session.Data.NR;
      FNR : Natural renames Session.Data.FNR;

      function Read_Line return String is
         Buffer : String (1 .. 1_024);
         Last   : Natural;

      begin
         Text_IO.Get_Line (Session.Data.Current_File, Buffer, Last);

         if Last = Buffer'Last then
            return Buffer & Read_Line;
         else
            return Buffer (1 .. Last);
         end if;
      end Read_Line;

   --  Start of processing for Read_Line

   begin
      if End_Of_File (Session) then
         Open_Next_File (Session);
         FNR := 0;
      end if;

      Session.Data.Current_Line := To_Unbounded_String (Read_Line);

      NR := NR + 1;
      FNR := FNR + 1;
   end Read_Line;

   --------------
   -- Register --
   --------------

   procedure Register
     (Field   : Count;
      Pattern : String;
      Action  : Action_Callback;
      Session : Session_Type := Current_Session)
   is
      Filters   : Pattern_Action_Table.Instance renames Session.Data.Filters;
      U_Pattern : constant Unbounded_String := To_Unbounded_String (Pattern);

   begin
      Pattern_Action_Table.Increment_Last (Filters);

      Filters.Table (Pattern_Action_Table.Last (Filters)) :=
        (Pattern => new Patterns.String_Pattern'(U_Pattern, Field),
         Action  => new Actions.Simple_Action'(Proc => Action));
   end Register;

   procedure Register
     (Field   : Count;
      Pattern : GNAT.Regpat.Pattern_Matcher;
      Action  : Action_Callback;
      Session : Session_Type := Current_Session)
   is
      Filters : Pattern_Action_Table.Instance renames Session.Data.Filters;

      A_Pattern : constant Patterns.Pattern_Matcher_Access :=
                    new Regpat.Pattern_Matcher'(Pattern);
   begin
      Pattern_Action_Table.Increment_Last (Filters);

      Filters.Table (Pattern_Action_Table.Last (Filters)) :=
        (Pattern => new Patterns.Regexp_Pattern'(A_Pattern, Field),
         Action  => new Actions.Simple_Action'(Proc => Action));
   end Register;

   procedure Register
     (Field   : Count;
      Pattern : GNAT.Regpat.Pattern_Matcher;
      Action  : Match_Action_Callback;
      Session : Session_Type := Current_Session)
   is
      Filters : Pattern_Action_Table.Instance renames Session.Data.Filters;

      A_Pattern : constant Patterns.Pattern_Matcher_Access :=
                    new Regpat.Pattern_Matcher'(Pattern);
   begin
      Pattern_Action_Table.Increment_Last (Filters);

      Filters.Table (Pattern_Action_Table.Last (Filters)) :=
        (Pattern => new Patterns.Regexp_Pattern'(A_Pattern, Field),
         Action  => new Actions.Match_Action'(Proc => Action));
   end Register;

   procedure Register
     (Pattern : Pattern_Callback;
      Action  : Action_Callback;
      Session : Session_Type := Current_Session)
   is
      Filters : Pattern_Action_Table.Instance renames Session.Data.Filters;

   begin
      Pattern_Action_Table.Increment_Last (Filters);

      Filters.Table (Pattern_Action_Table.Last (Filters)) :=
        (Pattern => new Patterns.Callback_Pattern'(Pattern => Pattern),
         Action  => new Actions.Simple_Action'(Proc => Action));
   end Register;

   procedure Register
     (Action  : Action_Callback;
      Session : Session_Type := Current_Session)
   is
   begin
      Register (Always_True'Access, Action, Session);
   end Register;

   -----------------
   -- Set_Current --
   -----------------

   procedure Set_Current (Session : Session_Type) is
   begin
      Cur_Session.Data := Session.Data;
   end Set_Current;

   --------------------------
   -- Set_Field_Separators --
   --------------------------

   procedure Set_Field_Separators
     (Separators : String       := Default_Separators;
      Session    : Session_Type := Current_Session)
   is
   begin
      Free (Session.Data.Separators);

      Session.Data.Separators :=
        new Split.Separator'(Separators'Length, Separators);

      --  If there is a current line read, split it according to the new
      --  separators.

      if Session.Data.Current_Line /= Null_Unbounded_String then
         Split_Line (Session);
      end if;
   end Set_Field_Separators;

   ----------------------
   -- Set_Field_Widths --
   ----------------------

   procedure Set_Field_Widths
     (Field_Widths : Widths_Set;
      Session      : Session_Type := Current_Session) is

   begin
      Free (Session.Data.Separators);

      Session.Data.Separators :=
        new Split.Column'(Field_Widths'Length, Field_Widths);

      --  If there is a current line read, split it according to
      --  the new separators.

      if Session.Data.Current_Line /= Null_Unbounded_String then
         Split_Line (Session);
      end if;
   end Set_Field_Widths;

   ----------------
   -- Split_Line --
   ----------------

   procedure Split_Line (Session : Session_Type) is
      Fields : Field_Table.Instance renames Session.Data.Fields;

   begin
      Field_Table.Init (Fields);

      Split.Current_Line (Session.Data.Separators.all, Session);
   end Split_Line;

begin
   --  We have declared two sessions but both should share the same data.
   --  The current session must point to the default session as its initial
   --  value. So first we release the session data then we set current
   --  session data to point to default session data.

   Free (Cur_Session.Data);
   Cur_Session.Data := Def_Session.Data;
end GNAT.AWK;
