------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                                 F M A P                                  --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 2001-2023, Free Software Foundation, 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 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.  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 COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Opt;    use Opt;
with Osint;  use Osint;
with Output; use Output;
with Table;
with Types;  use Types;

pragma Warnings (Off);
--  This package is used also by gnatcoll
with System.OS_Lib; use System.OS_Lib;
pragma Warnings (On);

with GNAT.HTable;

package body Fmap is

   No_Mapping_File : Boolean := False;
   --  Set to True when the specified mapping file cannot be read in
   --  procedure Initialize, so that no attempt is made to open the mapping
   --  file in procedure Update_Mapping_File.

   Max_Buffer : constant := 1_500;
   Buffer : String (1 .. Max_Buffer);
   --  Used to buffer output when writing to a new mapping file

   Buffer_Last : Natural := 0;
   --  Index of last valid character in Buffer

   type Mapping is record
      Uname : Unit_Name_Type;
      Fname : File_Name_Type;
   end record;

   package File_Mapping is new Table.Table (
     Table_Component_Type => Mapping,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 0,
     Table_Initial        => 1_000,
     Table_Increment      => 1_000,
     Table_Name           => "Fmap.File_Mapping");
   --  Mapping table to map unit names to file names

   package Path_Mapping is new Table.Table (
     Table_Component_Type => Mapping,
     Table_Index_Type     => Int,
     Table_Low_Bound      => 0,
     Table_Initial        => 1_000,
     Table_Increment      => 1_000,
     Table_Name           => "Fmap.Path_Mapping");
   --  Mapping table to map file names to path names

   type Header_Num is range 0 .. 1_000;

   function Hash (F : Unit_Name_Type) return Header_Num;
   --  Function used to compute hash of unit name

   No_Entry : constant Int := -1;
   --  Signals no entry in following table

   package Unit_Hash_Table is new GNAT.HTable.Simple_HTable (
     Header_Num => Header_Num,
     Element    => Int,
     No_Element => No_Entry,
     Key        => Unit_Name_Type,
     Hash       => Hash,
     Equal      => "=");
   --  Hash table to map unit names to file names. Used in conjunction with
   --  table File_Mapping above.

   function Hash (F : File_Name_Type) return Header_Num;
   --  Function used to compute hash of file name

   package File_Hash_Table is new GNAT.HTable.Simple_HTable (
     Header_Num => Header_Num,
     Element    => Int,
     No_Element => No_Entry,
     Key        => File_Name_Type,
     Hash       => Hash,
     Equal      => "=");
   --  Hash table to map file names to path names. Used in conjunction with
   --  table Path_Mapping above.

   Last_In_Table : Int := 0;

   package Forbidden_Names is new GNAT.HTable.Simple_HTable (
     Header_Num => Header_Num,
     Element    => Boolean,
     No_Element => False,
     Key        => File_Name_Type,
     Hash       => Hash,
     Equal      => "=");

   -----------------------------
   -- Add_Forbidden_File_Name --
   -----------------------------

   procedure Add_Forbidden_File_Name (Name : File_Name_Type) is
   begin
      Forbidden_Names.Set (Name, True);
   end Add_Forbidden_File_Name;

   ---------------------
   -- Add_To_File_Map --
   ---------------------

   procedure Add_To_File_Map
     (Unit_Name : Unit_Name_Type;
      File_Name : File_Name_Type;
      Path_Name : File_Name_Type)
   is
      Unit_Entry : constant Int := Unit_Hash_Table.Get (Unit_Name);
      File_Entry : constant Int := File_Hash_Table.Get (File_Name);
   begin
      if Unit_Entry = No_Entry or else
        File_Mapping.Table (Unit_Entry).Fname /= File_Name
      then
         File_Mapping.Increment_Last;
         Unit_Hash_Table.Set (Unit_Name, File_Mapping.Last);
         File_Mapping.Table (File_Mapping.Last) :=
           (Uname => Unit_Name, Fname => File_Name);
      end if;

      if File_Entry = No_Entry or else
        Path_Mapping.Table (File_Entry).Fname /= Path_Name
      then
         Path_Mapping.Increment_Last;
         File_Hash_Table.Set (File_Name, Path_Mapping.Last);
         Path_Mapping.Table (Path_Mapping.Last) :=
           (Uname => Unit_Name, Fname => Path_Name);
      end if;
   end Add_To_File_Map;

   ----------
   -- Hash --
   ----------

   function Hash (F : File_Name_Type) return Header_Num is
   begin
      return Header_Num (Int (F) mod Header_Num'Range_Length);
   end Hash;

   function Hash (F : Unit_Name_Type) return Header_Num is
   begin
      return Header_Num (Int (F) mod Header_Num'Range_Length);
   end Hash;

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

   procedure Initialize (File_Name : String) is
      FD  : File_Descriptor;
      Src : Source_Buffer_Ptr;
      Hi  : Source_Ptr;

      First : Source_Ptr := 1;
      Last  : Source_Ptr := 0;

      Uname : Unit_Name_Type;
      Fname : File_Name_Type;
      Pname : File_Name_Type;

      procedure Empty_Tables;
      --  Remove all entries in case of incorrect mapping file

      function Find_File_Name return File_Name_Type;
      --  Return Error_File_Name if the name buffer contains "/", otherwise
      --  call Name_Find. "/" is the path name in the mapping file to indicate
      --  that a source has been suppressed, and thus should not be found by
      --  the compiler.

      function Find_Unit_Name return Unit_Name_Type;
      --  Return the unit name in the name buffer. Return Error_Unit_Name if
      --  the name buffer contains "/".

      procedure Get_Line;
      --  Get a line from the mapping file, where a line is Src (First .. Last)

      procedure Report_Truncated;
      --  Report a warning when the mapping file is truncated
      --  (number of lines is not a multiple of 3).

      ------------------
      -- Empty_Tables --
      ------------------

      procedure Empty_Tables is
      begin
         Unit_Hash_Table.Reset;
         File_Hash_Table.Reset;
         Path_Mapping.Set_Last (0);
         File_Mapping.Set_Last (0);
         Last_In_Table := 0;
      end Empty_Tables;

      --------------------
      -- Find_File_Name --
      --------------------

      function Find_File_Name return File_Name_Type is
      begin
         if Name_Buffer (1 .. Name_Len) = "/" then

            --  A path name of "/" is the indication that the source has been
            --  "suppressed". Return Error_File_Name so that the compiler does
            --  not find the source, even if it is in the include path.

            return Error_File_Name;

         else
            return Name_Find;
         end if;
      end Find_File_Name;

      --------------------
      -- Find_Unit_Name --
      --------------------

      function Find_Unit_Name return Unit_Name_Type is
      begin
         return Unit_Name_Type (Find_File_Name);
      end Find_Unit_Name;

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

      procedure Get_Line is
         use ASCII;

      begin
         First := Last + 1;

         --  If not at the end of file, skip the end of line

         while First < Src'Last
           and then (Src (First) = CR
                      or else Src (First) = LF
                      or else Src (First) = EOF)
         loop
            First := First + 1;
         end loop;

         --  If not at the end of file, find the end of this new line

         if First < Src'Last and then Src (First) /= EOF then
            Last := First;

            while Last < Src'Last
              and then Src (Last + 1) /= CR
              and then Src (Last + 1) /= LF
              and then Src (Last + 1) /= EOF
            loop
               Last := Last + 1;
            end loop;

         end if;
      end Get_Line;

      ----------------------
      -- Report_Truncated --
      ----------------------

      procedure Report_Truncated is
      begin
         Write_Str ("warning: mapping file """);
         Write_Str (File_Name);
         Write_Line (""" is truncated");
      end Report_Truncated;

   --  Start of processing for Initialize

   begin
      Empty_Tables;
      Read_Source_File (Name_Enter (File_Name), 1, Hi, Src, FD, Config);

      if Null_Source_Buffer_Ptr (Src) then
         if FD = Osint.Null_FD then
            Write_Str ("warning: could not locate mapping file """);
         else
            Write_Str ("warning: no read access for mapping file """);
         end if;

         Write_Str (File_Name);
         Write_Line ("""");
         No_Mapping_File := True;

      else
         loop
            --  Get the unit name

            Get_Line;

            --  Exit if end of file has been reached

            exit when First > Last;

            if Last < First + 2 or else Src (Last - 1) /= '%'
              or else (Src (Last) /= 's' and then Src (Last) /= 'b')
            then
               Write_Line
                 ("warning: mapping file """ & File_Name &
                  """ is incorrectly formatted");
               Write_Line ("Line = """ & String (Src (First .. Last)) & '"');
               Empty_Tables;
               return;
            end if;

            Name_Len := Integer (Last - First + 1);
            Name_Buffer (1 .. Name_Len) := String (Src (First .. Last));
            Uname := Find_Unit_Name;

            --  Get the file name

            Get_Line;

            --  If end of line has been reached, file is truncated

            if First > Last then
               Report_Truncated;
               Empty_Tables;
               return;
            end if;

            Name_Len := Integer (Last - First + 1);
            Name_Buffer (1 .. Name_Len) := String (Src (First .. Last));
            Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
            Fname := Find_File_Name;

            --  Get the path name

            Get_Line;

            --  If end of line has been reached, file is truncated

            if First > Last then
               Report_Truncated;
               Empty_Tables;
               return;
            end if;

            Name_Len := Integer (Last - First + 1);
            Name_Buffer (1 .. Name_Len) := String (Src (First .. Last));
            Pname := Find_File_Name;

            --  Add the mappings for this unit name

            Add_To_File_Map (Uname, Fname, Pname);
         end loop;
      end if;

      --  Record the length of the two mapping tables

      Last_In_Table := File_Mapping.Last;
   end Initialize;

   ----------------------
   -- Mapped_File_Name --
   ----------------------

   function Mapped_File_Name (Unit : Unit_Name_Type) return File_Name_Type is
      The_Index : constant Int := Unit_Hash_Table.Get (Unit);

   begin
      if The_Index = No_Entry then
         return No_File;
      else
         return File_Mapping.Table (The_Index).Fname;
      end if;
   end Mapped_File_Name;

   ----------------------
   -- Mapped_Path_Name --
   ----------------------

   function Mapped_Path_Name (File : File_Name_Type) return File_Name_Type is
      Index : Int := No_Entry;

   begin
      if Forbidden_Names.Get (File) then
         return Error_File_Name;
      end if;

      Index := File_Hash_Table.Get (File);

      if Index = No_Entry then
         return No_File;
      else
         return Path_Mapping.Table (Index).Fname;
      end if;
   end Mapped_Path_Name;

   ------------------
   -- Reset_Tables --
   ------------------

   procedure Reset_Tables is
   begin
      File_Mapping.Init;
      Path_Mapping.Init;
      Unit_Hash_Table.Reset;
      File_Hash_Table.Reset;
      Forbidden_Names.Reset;
      Last_In_Table := 0;
   end Reset_Tables;

   -------------------------
   -- Update_Mapping_File --
   -------------------------

   procedure Update_Mapping_File (File_Name : String) is
      File    : File_Descriptor;
      N_Bytes : Integer;

      File_Entry : Int;

      Status : Boolean;
      --  For the call to Close

      procedure Put_Line (Name : Name_Id);
      --  Put Name as a line in the Mapping File

      --------------
      -- Put_Line --
      --------------

      procedure Put_Line (Name : Name_Id) is
      begin
         Get_Name_String (Name);

         --  If the Buffer is full, write it to the file

         if Buffer_Last + Name_Len + 1 > Buffer'Last then
            N_Bytes := Write (File, Buffer (1)'Address, Buffer_Last);

            if N_Bytes < Buffer_Last then
               Fail ("disk full");
            end if;

            Buffer_Last := 0;
         end if;

         --  Add the line to the Buffer

         Buffer (Buffer_Last + 1 .. Buffer_Last + Name_Len) :=
           Name_Buffer (1 .. Name_Len);
         Buffer_Last := Buffer_Last + Name_Len + 1;
         Buffer (Buffer_Last) := ASCII.LF;
      end Put_Line;

   --  Start of processing for Update_Mapping_File

   begin
      --  If the mapping file could not be read, then it will not be possible
      --  to update it.

      if No_Mapping_File then
         return;
      end if;
      --  Only Update if there are new entries in the mappings

      if Last_In_Table < File_Mapping.Last then

         File := Open_Read_Write (Name => File_Name, Fmode => Binary);

         if File /= Invalid_FD then
            if Last_In_Table > 0 then
               Lseek (File, 0, Seek_End);
            end if;

            for Unit in Last_In_Table + 1 .. File_Mapping.Last loop
               Put_Line (Name_Id (File_Mapping.Table (Unit).Uname));
               Put_Line (Name_Id (File_Mapping.Table (Unit).Fname));
               File_Entry :=
                 File_Hash_Table.Get (File_Mapping.Table (Unit).Fname);
               Put_Line (Name_Id (Path_Mapping.Table (File_Entry).Fname));
            end loop;

            --  Before closing the file, write the buffer to the file. It is
            --  guaranteed that the Buffer is not empty, because Put_Line has
            --  been called at least 3 times, and after a call to Put_Line, the
            --  Buffer is not empty.

            N_Bytes := Write (File, Buffer (1)'Address, Buffer_Last);

            if N_Bytes < Buffer_Last then
               Fail ("disk full");
            end if;

            Close (File, Status);

            if not Status then
               Fail ("disk full");
            end if;

         elsif not Quiet_Output then
            Write_Str ("warning: could not open mapping file """);
            Write_Str (File_Name);
            Write_Line (""" for update");
         end if;

      end if;
   end Update_Mapping_File;

end Fmap;
