-------------------------------------------------------------------------------
--
--  <STRONG>Copyright &copy; 2001, 2002 by Thomas Wolf.</STRONG>
--  <BLOCKQUOTE>
--    This piece of software is free software; you can redistribute it and/or
--    modify it under the terms of the  GNU General Public License as published
--    by the Free Software  Foundation; either version 2, or (at your option)
--    any later version. This software is distributed in the hope that it will
--    be useful, but <EM>without any warranty</EM>; without even the implied
--    warranty of <EM>merchantability or fitness for a particular purpose.</EM>
--    See the GNU General Public License for  more details. You should have
--    received a copy of the GNU General Public License with this distribution,
--    see file "<A HREF="GPL.txt">GPL.txt</A>". If not, write to the Free
--    Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
--    USA.
--  </BLOCKQUOTE>
--  <BLOCKQUOTE>
--    As a special exception from the GPL, 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 GPL. This exception does not however invalidate any
--    other reasons why the executable file might be covered by the GPL.
--  </BLOCKQUOTE>
--
--  <AUTHOR>
--    Thomas Wolf  (TW) <E_MAIL>
--  </AUTHOR>
--
--  <PURPOSE>
--    Operations for manipulating file names. The package is intended for
--    use on Windows or Unix systems. Upon elaboration, it tries to figure
--    out the host operating system by examining the @PATH@ environment
--    variable: if that contains Windows-looking pathes (i.e., a '\' is found
--    before a any '/'), it assumes it's being used on Windows. If, on the
--    other hand, it finds a '/' first, it assumes Unix. If it finds neither,
--    it uses @GNAT.Os_Lib.Directory_Separator@ as its directory separator.
--    (If you intend to use this package on a non-GNAT system, you'll have
--    to change the body of this package as appropriate.)
--
--    All operations in this package are pur string manipulation operations.
--    There are no file system operations involved.
--  </PURPOSE>
--
--  <NOT_TASK_SAFE>
--
--  <NO_STORAGE>
--
--  <HISTORY>
--    19-MAR-2002   TW  Initial version.
--    03-MAY-2002   TW  Added 'Drive' and 'Node'.
--  </HISTORY>
-------------------------------------------------------------------------------

pragma License (Modified_GPL);

package Util.Pathes is

   pragma Elaborate_Body;

   --  A @Full_Name@ can have a path component, and a file name. Both are
   --  optional, i.e., a @Full_Name@ can also be only a path, or only a
   --  file name. A @File_Name@ may or may not contain an extension. This
   --  package considers anything beyond the last '.' in a file name the
   --  extension, unless that last period is the first character of the file
   --  name, in which case the extension is the empty string (this handles
   --  names like "@.cshrc@" as they are common on Unix-like systems).
   --
   --  This package uses a purely syntactical distinction between file and
   --  directory names: if the @Full_Name@ terminates in a directory
   --  separator, it is considered a directory name; otherwise it is taken
   --  as a file name.

   Path_Error : exception;

   function Directory_Separator
     return Character;
   --  Returns the directory separator used. Returns whatever the package
   --  elaboration concluded was the directory separator on the host
   --  environment.

   function Extension
     (Full_Name : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  Returns the extension of @Full_Name@, which may be the empty string.

   function Name
     (Full_Name : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  Returns the file name component of @Full_Name@ including a possible
   --  extension. Returns the empty string if @Full_Name@ is a path only.

   function Base_Name
     (Full_Name : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  Returns the file name component of @Full_Name@ <EM>without</EM> a
   --  possible extension. Returns the empty string if @Full_Name@ is a path
   --  only.

   function Path
     (Full_Name : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  Returns "" if @Full_Name@ does not contain a path component; otherwise
   --  it returns the path component (absolute or relative) including the
   --  final directory separator.

   function Drive
     (Full_Name : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  Returns "" if @Full_Name@ does not contain a drive component; otherwise
   --  it returns the drive specification (ending in a colon).

   function Has_Drive
     (Full_Name : in String;
      Separator : in Character := Directory_Separator)
     return Boolean;

   function Node
     (Full_Name : in String;
      Separator : in Character := Directory_Separator)
     return String;

   function Has_Node
     (Full_Name : in String;
      Separator : in Character := Directory_Separator)
     return Boolean;

   function Normalize
     (Path      : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  @Path@ is assumed to be a path only.
   --  Returns <CODE>'.' & Separator</CODE> if @Path@ is empty, otherwise
   --  returns @Path@ terminated with a @Separator@.

   function Is_Absolute_Path
     (Name      : in String;
      Separator : in Character := Directory_Separator)
     return Boolean;
   --  Returns @True@ if the name given has an absolute path component.

   function Concat
     (Path      : in String;
      File_Name : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  Concatenates the @Path@ with the @File_Name@, which may contain a
   --  relative path. Returns @Path@ if @File_Name@ = "", and @File_Name@ if
   --  @Path@ = "". Otherwise, raises @Path_Error@ if @File_Name@ contains an
   --  <EM>absolute</EM> path component. Note that @File_Name@ not necessarily
   --  must contain a file name, it may also be a relative path.

   function Replace_File_Name
     (Full_Name : in String;
      File_Name : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  Equivalent to
   --  <CODE>Concat&nbsp;(Path&nbsp;(Full_Name, Separator), File_Name,
   --  Separator)</CODE>.

   function Replace_Extension
     (Full_Name : in String;
      Extension : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  Replaces the extension of @Full_Name@. @Extension@ should not include
   --  a leading period! If @Full_Name@ has a file name component, but no
   --  extension yet, a period and the @Extension@ is appended. Raises
   --  @Path_Error@ if @Full_Name@ doesn't have a file name component at all.

   function Parent
     (Path      : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  Tries to move up one directory in @Path@, which is interpreted as a
   --  path name even if it has no trailing @Separator@. Raises @Path_Error@
   --  if @Path@ is an absolute path and specifies a root directory. If
   --  @Path@ is a relative path, the result it may start with "../". the
   --  result has a trailing @Separator@.

   function Clean
     (Full_Name : in String;
      Separator : in Character := Directory_Separator)
     return String;
   --  Cleans up @Full_name@, which is interpreted as a path even if it has
   --  no trailing @Separator@. Removes all extraneous separators and "./"
   --  sequences, and also executes "../" components. Raises @Path_Error@ if
   --  the path is invalid, e.g. execution of "../" would go beyond the root
   --  directory, if @Full_Name@ is an absolute path. If @Full_Name@ is a
   --  relative path, the resulting path may start with "./" or a sequence
   --  of "../". The result has a trailing @Separator@, unless it is a
   --  Windows relative path name consisting only of a drive letter and a
   --  colon, in which case it ends with the colon.

private

   pragma Inline (Directory_Separator);

end Util.Pathes;
