--  GHDL Run Time (GRT) -  VHDL files subprograms.
--  Copyright (C) 2002 - 2014 Tristan Gingold
--
--  GHDL 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.
--
--  GHDL is distributed in the hope that it will be useful, but WITHOUT 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
--  along with GCC; see the 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.

with Interfaces;

with Grt.Types; use Grt.Types;
with Grt.Stdio;

package Grt.Files_Operations is
   type Ghdl_File_Index is new Interfaces.Integer_32;

   --  File open mode.
   Read_Mode   : constant Ghdl_I32 := 0;
   Write_Mode  : constant Ghdl_I32 := 1;
   Append_Mode : constant Ghdl_I32 := 2;

   --  file_open_status.
   Open_Ok      : constant Ghdl_I32 := 0;
   Status_Error : constant Ghdl_I32 := 1;
   Name_Error   : constant Ghdl_I32 := 2;
   Mode_Error   : constant Ghdl_I32 := 3;

   type Op_Status is
     (
      Op_Ok,

      --  Correspond to file_open_status.
      Op_Status_Error,
      Op_Name_Error,
      Op_Mode_Error,

      --  For endfile: end of file reached (as if endfile returns True).
      Op_End_Of_File,

      --  Failed to call ungetc in endfile.
      Op_Ungetc_Error,

      --  Operation on a non-open file.
      Op_Not_Open,

      --  Try to read from a write-only file.
      Op_Read_Write_File,

      --  Try to write to a read-only file.
      Op_Write_Read_File,

      --  Internal error: incorrect file index.
      Op_Bad_Index,

      --  Internal error: binary operation on text file, or text operation
      --  on binary file.
      Op_Bad_Mode,

      --  Internal error: destroy a file that is still open.
      Op_Not_Closed,

      --  System error during write.
      Op_Write_Error,

      --  System error during read.
      Op_Read_Error,

      --  System error during close.
      Op_Close_Error,

      --  Incorrect file name (too long).
      Op_Filename_Error,

      --  Incorrect file type.
      Op_Signature_Error

     );

   --  General files.
   procedure Ghdl_File_Endfile
     (File : Ghdl_File_Index; Status : out Op_Status);

   --  Elaboration.
   function Ghdl_Text_File_Elaborate return Ghdl_File_Index;
   function Ghdl_File_Elaborate (Sig : Ghdl_C_String) return Ghdl_File_Index;

   --  Finalization.
   procedure Ghdl_Text_File_Finalize
     (File : Ghdl_File_Index; Status : out Op_Status);
   procedure Ghdl_File_Finalize
     (File : Ghdl_File_Index; Status : out Op_Status);

   --  Subprograms.
   procedure Ghdl_Text_File_Open (File : Ghdl_File_Index;
                                  Mode : Ghdl_I32;
                                  Name : Ghdl_C_String;
                                  Status : out Op_Status);
   procedure Ghdl_File_Open (File : Ghdl_File_Index;
                             Mode : Ghdl_I32;
                             Name : Ghdl_C_String;
                             Status : out Op_Status);

   procedure Ghdl_Text_Write (File : Ghdl_File_Index;
                              Str : Std_String_Ptr;
                              Status : out Op_Status);
   procedure Ghdl_Write_Scalar (File : Ghdl_File_Index;
                                Ptr : Ghdl_Ptr;
                                Length : Ghdl_Index_Type;
                                Status : out Op_Status);

   procedure Ghdl_Read_Scalar (File : Ghdl_File_Index;
                               Ptr : Ghdl_Ptr;
                               Length : Ghdl_Index_Type;
                               Status : out Op_Status);

   procedure Ghdl_Text_Read_Length (File : Ghdl_File_Index;
                                    Str : Std_String_Ptr;
                                    Status : out Op_Status;
                                    Length : out Std_Integer);

   procedure Ghdl_Untruncated_Text_Read (File : Ghdl_File_Index;
                                         Buf : Ghdl_C_String;
                                         Len : in out Std_Integer;
                                         Status : out Op_Status);

   procedure Ghdl_Text_File_Close (File : Ghdl_File_Index;
                                   Status : out Op_Status);
   procedure Ghdl_File_Close (File : Ghdl_File_Index;
                              Status : out Op_Status);

   procedure Ghdl_File_Flush (File : Ghdl_File_Index; Status : out Op_Status);

   type Open_Handler_Acc is access function
     (Name : Ghdl_C_String; Mode : Ghdl_C_String) return Grt.Stdio.FILEs;

   --  Like fopen(3)
   function Simple_Open (Name : Ghdl_C_String; Mode : Ghdl_C_String)
                        return Grt.Stdio.FILEs;

   --  Function called to open a file.  This hook can be used to search a file
   --  on a path.
   Open_Handler : Open_Handler_Acc := Simple_Open'Access;
end Grt.Files_Operations;