------------------------------------------------------------------------------
--                                                                          --
--                         GNAT RUN-TIME COMPONENTS                         --
--                                                                          --
--                  ADA.DIRECTORIES.HIERARCHICAL_FILE_NAMES                 --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 2004-2021, 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.                                     --
--                                                                          --
-- 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.               --
--                                                                          --
-- In particular,  you can freely  distribute your programs  built with the --
-- GNAT Pro compiler, including any required library run-time units,  using --
-- any licensing terms  of your choosing.  See the AdaCore Software License --
-- for full details.                                                        --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Ada.Characters.Handling;  use Ada.Characters.Handling;
with Ada.Directories.Validity; use Ada.Directories.Validity;
with Ada.Strings.Fixed;        use Ada.Strings.Fixed;
with System;                   use System;

package body Ada.Directories.Hierarchical_File_Names is

   Dir_Separator : constant Character;
   pragma Import (C, Dir_Separator, "__gnat_dir_separator");
   --  Running system default directory separator

   -----------------
   -- Subprograms --
   -----------------

   function Equivalent_File_Names
     (Left  : String;
      Right : String)
      return Boolean;
   --  Perform an OS-independent comparison between two file paths

   function Is_Absolute_Path (Name : String) return Boolean;
   --  Returns True if Name is an absolute path name, i.e. it designates a
   --  file or directory absolutely rather than relative to another directory.

   ---------------------------
   -- Equivalent_File_Names --
   ---------------------------

   function Equivalent_File_Names
     (Left  : String;
      Right : String)
      return Boolean
   is
   begin
      --  Check the validity of the input paths

      if not Is_Valid_Path_Name (Left)
        or else not Is_Valid_Path_Name (Right)
      then
         return False;
      end if;

      --  Normalize the paths by removing any trailing directory separators and
      --  perform the comparison.

      declare
         Normal_Left  : constant String :=
           (if Index (Left, Dir_Separator & "", Strings.Backward) = Left'Last
              and then not Is_Root_Directory_Name (Left)
            then
               Left (Left'First .. Left'Last - 1)
            else
               Left);

         Normal_Right : constant String :=
           (if Index (Right, Dir_Separator & "", Strings.Backward) = Right'Last
              and then not Is_Root_Directory_Name (Right)
            then
               Right (Right'First .. Right'Last - 1)
            else
               Right);
      begin
         --  Within Windows we assume case insensitivity

         if not Windows then
            return Normal_Left = Normal_Right;
         end if;

         --  Otherwise do a straight comparison

         return To_Lower (Normal_Left) = To_Lower (Normal_Right);
      end;
   end Equivalent_File_Names;

   ----------------------
   -- Is_Absolute_Path --
   ----------------------

   function Is_Absolute_Path (Name : String) return Boolean is
      function Is_Absolute_Path
        (Name   : Address;
         Length : Integer) return Integer;
      pragma Import (C, Is_Absolute_Path, "__gnat_is_absolute_path");
   begin
      return Is_Absolute_Path (Name'Address, Name'Length) /= 0;
   end Is_Absolute_Path;

   --------------------
   -- Is_Simple_Name --
   --------------------

   function Is_Simple_Name (Name : String) return Boolean is
   begin
      --  Verify the file path name is valid and that it is not a root

      if not Is_Valid_Path_Name (Name)
        or else Is_Root_Directory_Name (Name)
      then
         return False;
      end if;

      --  Check for the special paths "." and "..", which are considered simple

      if Is_Parent_Directory_Name (Name)
        or else Is_Current_Directory_Name (Name)
      then
         return True;
      end if;

      --  Perform a comparison with the calculated simple path name

      return Equivalent_File_Names (Simple_Name (Name), Name);
   end Is_Simple_Name;

   ----------------------------
   -- Is_Root_Directory_Name --
   ----------------------------

   function Is_Root_Directory_Name (Name : String) return Boolean is
   begin
      --  Check if the path name is a root directory by looking for a slash in
      --  the general case, and a drive letter in the case of Windows.

      return Name = "/"
               or else
                 (Windows
                   and then
                     (Name = "\"
                       or else
                         (Name'Length = 3
                           and then Name (Name'Last - 1) = ':'
                           and then Name (Name'Last) in '/' | '\'
                           and then (Name (Name'First) in 'a' .. 'z'
                                      or else
                                        Name (Name'First) in 'A' .. 'Z'))
                       or else
                         (Name'Length = 2
                           and then Name (Name'Last) = ':'
                           and then (Name (Name'First) in 'a' .. 'z'
                                      or else
                                        Name (Name'First) in 'A' .. 'Z'))));
   end Is_Root_Directory_Name;

   ------------------------------
   -- Is_Parent_Directory_Name --
   ------------------------------

   function Is_Parent_Directory_Name (Name : String) return Boolean is
   begin
      return Name = "..";
   end Is_Parent_Directory_Name;

   -------------------------------
   -- Is_Current_Directory_Name --
   -------------------------------

   function Is_Current_Directory_Name (Name : String) return Boolean is
   begin
      return Name = ".";
   end Is_Current_Directory_Name;

   ------------------
   -- Is_Full_Name --
   ------------------

   function Is_Full_Name (Name : String) return Boolean is
   begin
      return Equivalent_File_Names (Full_Name (Name), Name);
   end Is_Full_Name;

   ----------------------
   -- Is_Relative_Name --
   ----------------------

   function Is_Relative_Name (Name : String) return Boolean is
   begin
      return not Is_Absolute_Path (Name)
               and then Is_Valid_Path_Name (Name);
   end Is_Relative_Name;

   -----------------------
   -- Initial_Directory --
   -----------------------

   function Initial_Directory (Name : String) return String is
      Start : constant Integer := Index (Name, Dir_Separator & "");
   begin
      --  Verify path name

      if not Is_Valid_Path_Name (Name) then
         raise Name_Error with "invalid path name """ & Name & '"';
      end if;

      --  When there is no starting directory separator or the path name is a
      --  root directory then the path name is already simple - so return it.

      if Is_Root_Directory_Name (Name) or else Start = 0 then
         return Name;
      end if;

      --  When the initial directory of the path name is a root directory then
      --  the starting directory separator is part of the result so we must
      --  return it in the slice.

      if Is_Root_Directory_Name (Name (Name'First .. Start)) then
         return Name (Name'First .. Start);
      end if;

      --  Otherwise we grab a slice up to the starting directory separator

      return Name (Name'First .. Start - 1);
   end Initial_Directory;

   -------------------
   -- Relative_Name --
   -------------------

   function Relative_Name (Name : String) return String is
   begin
      --  We cannot derive a relative name if Name does not exist

      if not Is_Relative_Name (Name)
        and then not Is_Valid_Path_Name (Name)
      then
         raise Name_Error with "invalid relative path name """ & Name & '"';
      end if;

      --  Name only has a single part and thus cannot be made relative

      if Is_Simple_Name (Name)
        or else Is_Root_Directory_Name (Name)
      then
         raise Name_Error with
           "relative path name """ & Name & """ is composed of a single part";
      end if;

      --  Trim the input according to the initial directory and maintain proper
      --  directory separation due to the fact that root directories may
      --  contain separators.

      declare
         Init_Dir : constant String := Initial_Directory (Name);
      begin
         if Init_Dir (Init_Dir'Last) = Dir_Separator then
            return Name (Name'First + Init_Dir'Length .. Name'Last);
         end if;

         return Name (Name'First + Init_Dir'Length + 1 .. Name'Last);
      end;
   end Relative_Name;

   -------------
   -- Compose --
   -------------

   function Compose
     (Directory     : String := "";
      Relative_Name : String;
      Extension     : String := "") return String
   is
      --  Append a directory separator if none is present

      Separated_Dir : constant String :=
        (if    Directory = "" then ""
         elsif Directory (Directory'Last) = Dir_Separator then Directory
         else  Directory & Dir_Separator);
   begin
      --  Check that relative name is valid

      if not Is_Relative_Name (Relative_Name) then
         raise Name_Error with
           "invalid relative path name """ & Relative_Name & '"';
      end if;

      --  Check that directory is valid

      if Separated_Dir /= ""
        and then (not Is_Valid_Path_Name (Separated_Dir & Relative_Name))
      then
         raise Name_Error with
           "invalid path composition """ & Separated_Dir & Relative_Name & '"';
      end if;

      --  Check that the extension is valid

      if Extension /= ""
        and then not Is_Valid_Path_Name
                       (Separated_Dir & Relative_Name & Extension)
      then
         raise Name_Error with
           "invalid path composition """
             & Separated_Dir & Relative_Name & Extension & '"';
      end if;

      --  Concatenate the result

      return Separated_Dir & Relative_Name & Extension;
   end Compose;

end Ada.Directories.Hierarchical_File_Names;
