------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                              G N A T . A W K                             --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                     Copyright (C) 2000-2026, AdaCore                     --
--                                                                          --
-- 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 3,  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.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

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;

   -----------------------
   -- Local subprograms --
   -----------------------

   --  The following two subprograms provide a functional interface to the
   --  two special session variables, that are manipulated explicitly by
   --  Finalize, but must be declared after Finalize to prevent static
   --  elaboration warnings.

   function Get_Def return Session_Data_Access;
   procedure Set_Cur;

   ----------------
   -- 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 current line of Session using split mode S

      ------------------------
      -- 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 file names 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 limited 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);

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

   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 /= Get_Def then
         --  Release separators

         Free (Session.Data.Separators);

         Free (Session.Data);

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

         Set_Cur;
      end if;
   end Finalize;

   ----------------
   -- 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 --
   -----------------------

   Def_Session : Session_Type;
   Cur_Session : Session_Type;

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

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

   function Apply_Filters
     (Session : Session_Type) 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);
   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;
         Seps   : constant Maps.Character_Set := Maps.To_Set (S.Separators);

         Start  : Natural;
         Stop   : Natural;

      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)
   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;

   procedure Add_File
     (Filename : String)
   is

   begin
      Add_File (Filename, Cur_Session);
   end Add_File;

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

   procedure Add_Files
     (Directory             : String;
      Filenames             : String;
      Number_Of_Files_Added : out Natural;
      Session               : Session_Type)
   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 scanning directory " & Directory
            & " for files " & Filenames & '.',
            Session);
   end Add_Files;

   procedure Add_Files
     (Directory             : String;
      Filenames             : String;
      Number_Of_Files_Added : out Natural)
   is

   begin
      Add_Files (Directory, Filenames, Number_Of_Files_Added, Cur_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) 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 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 not null access Session_Type is
   begin
      return Cur_Session.Self;
   end Current_Session;

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

   function Default_Session return not null access Session_Type is
   begin
      return Def_Session.Self;
   end Default_Session;

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

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

   function Discrete_Field_Current_Session
     (Rank    : Count) return Discrete is
      function Do_It is new Discrete_Field (Discrete);
   begin
      return Do_It (Rank, Cur_Session);
   end Discrete_Field_Current_Session;

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

   function End_Of_Data
     (Session : Session_Type) 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;

   function End_Of_Data
     return Boolean
   is
   begin
      return End_Of_Data (Cur_Session);
   end End_Of_Data;

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

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

   function End_Of_File
     return Boolean
   is
   begin
      return End_Of_File (Cur_Session);
   end End_Of_File;

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

   function Field
     (Rank    : Count;
      Session : Session_Type) 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) return String
   is
   begin
      return Field (Rank, Cur_Session);
   end Field;

   function Field
     (Rank    : Count;
      Session : Session_Type) 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) return Integer
   is
   begin
      return Field (Rank, Cur_Session);
   end Field;

   function Field
     (Rank    : Count;
      Session : Session_Type) 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;

   function Field
     (Rank    : Count) return Float
   is
   begin
      return Field (Rank, Cur_Session);
   end Field;

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

   function File
     (Session : Session_Type) 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;

   function File
     return String
   is
   begin
      return File (Cur_Session);
   end File;

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

   procedure For_Every_Line
     (Separators : String        := Use_Current;
      Filename   : String        := Use_Current;
      Callbacks  : Callback_Mode := None;
      Session    : Session_Type)
   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;
            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;

   procedure For_Every_Line_Current_Session
     (Separators : String        := Use_Current;
      Filename   : String        := Use_Current;
      Callbacks  : Callback_Mode := None)
   is
      procedure Do_It is new For_Every_Line (Action);
   begin
      Do_It (Separators, Filename, Callbacks, Cur_Session);
   end For_Every_Line_Current_Session;

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

   procedure Get_Line
     (Callbacks : Callback_Mode := None;
      Session   : Session_Type)
   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;

   procedure Get_Line
     (Callbacks : Callback_Mode := None)
   is
   begin
      Get_Line (Callbacks, Cur_Session);
   end Get_Line;

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

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

   function Number_Of_Fields
     return Count
   is
   begin
      return Number_Of_Fields (Cur_Session);
   end Number_Of_Fields;

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

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

   function Number_Of_File_Lines
     return Count
   is
   begin
      return Number_Of_File_Lines (Cur_Session);
   end Number_Of_File_Lines;

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

   function Number_Of_Files
     (Session : Session_Type) return Natural
   is
      Files : File_Table.Instance renames Session.Data.Files;
   begin
      return File_Table.Last (Files);
   end Number_Of_Files;

   function Number_Of_Files
     return Natural
   is
   begin
      return Number_Of_Files (Cur_Session);
   end Number_Of_Files;

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

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

   function Number_Of_Lines
     return Count
   is
   begin
      return Number_Of_Lines (Cur_Session);
   end Number_Of_Lines;

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

   procedure Open
     (Separators : String       := Use_Current;
      Filename   : String       := Use_Current;
      Session    : Session_Type)
   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;

   procedure Open
     (Separators : String       := Use_Current;
      Filename   : String       := Use_Current)
   is
   begin
      Open (Separators, Filename, Cur_Session);
   end Open;

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

   procedure Open_Next_File
     (Session : Session_Type)
   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)
   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;

   procedure Parse
     (Separators : String       := Use_Current;
      Filename   : String       := Use_Current)
   is
   begin
      Parse (Separators, Filename, Cur_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 this information 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);
   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;

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

      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)
   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 : String;
      Action  : Action_Callback)
   is
   begin
      Register (Field, Pattern, Action, Cur_Session);
   end Register;

   procedure Register
     (Field   : Count;
      Pattern : GNAT.Regpat.Pattern_Matcher;
      Action  : Action_Callback;
      Session : Session_Type)
   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  : Action_Callback)
   is
   begin
      Register (Field, Pattern, Action, Cur_Session);
   end Register;

   procedure Register
     (Field   : Count;
      Pattern : GNAT.Regpat.Pattern_Matcher;
      Action  : Match_Action_Callback;
      Session : Session_Type)
   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
     (Field   : Count;
      Pattern : GNAT.Regpat.Pattern_Matcher;
      Action  : Match_Action_Callback)
   is
   begin
      Register (Field, Pattern, Action, Cur_Session);
   end Register;

   procedure Register
     (Pattern : Pattern_Callback;
      Action  : Action_Callback;
      Session : Session_Type)
   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
     (Pattern : Pattern_Callback;
      Action  : Action_Callback)
   is
   begin
      Register (Pattern, Action, Cur_Session);
   end Register;

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

   procedure Register
     (Action  : Action_Callback)
   is
   begin
      Register (Action, Cur_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)
   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;

   procedure Set_Field_Separators
     (Separators : String       := Default_Separators)
   is
   begin
      Set_Field_Separators (Separators, Cur_Session);
   end Set_Field_Separators;

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

   procedure Set_Field_Widths
     (Field_Widths : Widths_Set;
      Session      : Session_Type)
   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;

   procedure Set_Field_Widths
     (Field_Widths : Widths_Set)
   is
   begin
      Set_Field_Widths (Field_Widths, Cur_Session);
   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;

   -------------
   -- Get_Def --
   -------------

   function Get_Def return Session_Data_Access is
   begin
      return Def_Session.Data;
   end Get_Def;

   -------------
   -- Set_Cur --
   -------------

   procedure Set_Cur is
   begin
      Cur_Session.Data := Def_Session.Data;
   end Set_Cur;

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;
