with Source_Instrumenter_Declarations;
use Source_Instrumenter_Declarations;
with Simple_Paginated_Output;
with Direct_Io;
with Lists;
with String_Pkg;
use String_Pkg;

package Buffer_File_Package --| This package creates and manages the
--| files needed by the source instrumenter
--| for saving information needed for
--| tracing types and variables.

    is

    --| Overview
    --|     This package contains file management procedures needed by the
    --| Source Instrumenter for saving type and variable tracing information.
    --| The Source Instrumenter prepares programs for testing by the Ada Test
    --| and Analysis Tool Set.
    --|
    --|     A general purpose scratch file is maintained for saving procedure
    --| bodies created by the instrumenter until the end of the current
    --| declarative part, where they can then be copied into the instrumented
    --| source file.  The specifications for these procedures are added
    --| directly to the instrumented source file and do not need to be saved.
    --|
    --|     Four new files may be created for each package specification to
    --| contain the instrumenting information needed by the source instrumenter
    --| for tracing variables and types declared in the package specification.
    --| The procedures in this package manage these files and allows the Source
    --| Instrumenter to access the correct file when necessary.  A table which
    --| equates a unique filename prefix with each package name is maintained by
    --| this package, and saved in an external file when the instrumentation is
    --| finished.
    --|
    --|
    --| Requires
    --| The following declarations for file naming are used:
    --|
    --| "File_Prefix_Limit" is currently set to 8 characters, and indicates
    --| the number of characters in a filename to the left of the dot.
    --|
    --| "File_Suffix_Limit" is currently set to 4 characters; a dot and
    --| a 3 character file extension.
    --|
    --| The external file which saves the package_name - file_name information
    --| is named "PKGFILES.SII".
    --|
    --| The current extensions used for the package tracing files are:
    --|  ".PBS"  -- For the Public_Spec_File
    --|  ".PBB"  -- For the Public_Body_File
    --|  ".PVS"  -- For the Private_Spec_File
    --|  ".PVB"  -- For the Private_Body_File
    --|
    --| These may be changed if they cause conflicts or are otherwise unsuitable
    --| for the host system.

    --| N/A: Errors, Raises, Modifies


    --------------------------------------------------------------------------

    package Dio is new Direct_Io (Character);
    use Dio;

    package Spo renames Simple_Paginated_Output;

    Buffer_File,
    --| a temporary "scratch" file used by the source instrumenter
    --| to save type tracing procedure bodies until end of the
    --| current declarative part

    Public_Spec_File,
    --| file which has the package spec for tracing types and variables
    --| declared in the visible part of a package.

    Public_Body_File,
    --| the corresponding package body

    Private_Spec_File,
    --| file which has the procedure declarations for tracing types
    --| and variables declared in the private part of a package

    Private_Body_File : Dio.File_Type;
    --| the corresponding procedure bodies


    type File_Indicator is
       --| indicates which file to copy into the instrumented source file
       (Public_Spec, Public_Body, Private_Spec, Private_Body);

    type File_Group is (Public_Files, Private_Files, All_Files);
    --| used by various procedures when the operation is not always
    --| performed on all files

    File_Prefix_Limit : constant := 8;
    File_Suffix_Limit : constant := 4;

    Public_Spec_File_Suffix :
       constant String (1 .. File_Suffix_Limit) := ".PBS";
    Public_Body_File_Suffix :
       constant String (1 .. File_Suffix_Limit) := ".PBB";
    Private_Spec_File_Suffix :
       constant String (1 .. File_Suffix_Limit) := ".PVS";
    Private_Body_File_Suffix :
       constant String (1 .. File_Suffix_Limit) := ".PVB";

    External_Filename : constant String := "PKGFILES.SII";
    --| Filename extension means "Source Instrumenter Information"

    subtype Filename_Prefix_String is String (1 .. File_Prefix_Limit);
    No_Filename : constant Filename_Prefix_String := (others => ' ');


    ------------------------------------------------------------------------
    -- The following procedures manage the Buffer_File
    ------------------------------------------------------------------------

    procedure Initialize;  --| Initialize the Buffer_File

    --| Effects
    --|   This procedure initializes Buffer_File as a temporary Direct_IO file.
    --| The Source Instrumenter writes text to this file in sections which
    --| correspond to scoping levels in the source program.  Initialize
    --| also creates an Index_Stack to keep track of the Starting Indices for
    --| the sections.

    -----------------------------------------------------------------------------

    procedure Start_New_Section;  --| Starts a new section in Buffer_File

    --| Effects
    --|   This procedure marks a new section in the buffer file by pushing
    --| the current Starting_Index onto the Index_Stack and assigning the
    --| current DIO.Index to Starting_Index.

    ----------------------------------------------------------------------------

    procedure Release_Section;  --| Release the section in Buffer_File

    --| Effects
    --|   This procedure releases a section in Buffer_File by setting the Index
    --| to Starting_Index and popping the previous Starting_Index off the
    --| stack.

    -----------------------------------------------------------------------------

    procedure Writeln_To_Buffer ( --| Write a string to the specified file
                                 Dio_File : in Dio.File_Type := Buffer_File;
                                 Line_Of_Text : in String);
    --| Effects
    --|   This procedure writes the line to the specified file.  If no file
    --| is specified, the line is written to the Buffer_File.

    -----------------------------------------------------------------------------

    procedure Save_Buffer_File ( --| Save the current section of the Buffer_File
                                Po_File : in Spo.Paginated_File_Handle);

    --| Effects
    --|   This procedure saves the section starting at the current Starting_Index
    --| to the specified Simple_Paginated_Output file (the instrumented source
    --| file).



    ----------------------------------------------------------------------------
    -- The following procedures manage the package tracing files.
    ----------------------------------------------------------------------------

    procedure Create_Package_Files ( --| Create the files neccesary to
                                    --| save package information.
                                    Package_Name : in String;
                                    Which_Files : in File_Group);

    --| Effects
    --|  This procedure obtains a filename prefix based on the current package
    --| name, appends the appropriate suffix, and creates the Direct_IO files.
    --| The source instrumenter saves package tracing information in these files.
    --| The Which_Files parameter will normally be "All_Files".  However, if a
    --| package specification is nested in another package specification, then
    --| only new private files are created. The information from the public part
    --| of the nested package is included in the public files of the enclosing
    --| package.

    ----------------------------------------------------------------------------

    procedure Close_Package_Files ( --| Close the specified package files
                                   Which_Files : in File_Group);

    --| Effects
    --|  This procedure closes the specified group of package files.
    --| Usually "Which_Files" parameter will be "All_Files".  If a package is
    --| nested in another package, then the outer package's private files will
    --| be closed (temporarily) and reopened after the inner package is done.
    --|
    --|  The public information for the nested package is included in the
    --| enclosing package's public files.  Therefore, it isn't necessary to
    --| close and reopen the public_files.

    ---------------------------------------------------------------------------

    procedure Reopen_Private_Files ( --| Reopen the private files associated
                                    --| with the Package_Name
                                    Package_Name : in String);

    --| Effects
    --|  This procedure reopens the private files for the specified package,
    --| which were closed to process a nested package.  The file index is set
    --| to the end of the file so further writes to this files will be appended.

    ----------------------------------------------------------------------------

    function Package_Files_Exist ( --| Check for the existence of instrumenting
                                  --| information files for the given package
                                  Package_Name : in String;
                                  Which_Files : in File_Group) return Boolean;

    --| Effects
    --|   This function determines if the specified group of instrumenting
    --| information files exist for a package.  Both the spec and the body
    --| files must exist.  If one exists without the other, which could
    --| happed if the user deleted or misplaced one of the files, it is
    --| deleted, and False is returned.

    ----------------------------------------------------------------------------

    procedure Delete_Package_Files ( --| Delete the instrumenting information
                                    --| files for the given package, and
                                    --| remove the entry from the external file.
                                    Package_Name : in String;
                                    Which_Files : in File_Group := All_Files;
                                    Current_Filename_Prefix : in
                                       Filename_Prefix_String := No_Filename);

    --| Effects
    --|   This procedure determines the name of the external files if the
    --| Current_Filename_Prefix is not already known, and deletes the
    --| "Which_Files" group of files, if they exist.

    -----------------------------------------------------------------------------

    procedure Copy_Package_Files ( --| Copy the specified file into the
                                  --| instrumented source file
                                  Which_File : in File_Indicator;
                                  Package_Name : in String;
                                  Si_File : in Spo.Paginated_File_Handle);

    --| Effects
    --|   This procedure copies the contents of the indicated file into the
    --| specified Simple_Paginated_Output file (The instrumented source).

    ---------------------------------------------------------

    procedure Save_Spec_With_List ( --| Save the with list for the
                                   --| current package specification
                                   Unit_Name : in String;
                                   With_List : in String_List);
    --| Effects
    --|   This procecufe saves the list of library unit names that were
    --| in the with_clause for the indicated package specification.

    ---------------------------------------------------------

    function Get_Spec_With_List ( --| Retrieve the saved with list for
                                 --| current unit
                                 Unit_Name : in String) return String_List;

    --| Effects
    --|   This function retrieves the saved list of library unit names
    --| that were in the with_clause for the indicated unit and returns
    --| it to the calling procedure as a list of string_types.

    -----------------------------------------------------------------------------

    procedure Save_External_File;  --| Update the external file

    --| Effects
    --|   This procedure writes the internal table of package_name-file_name
    --| information to the permanent external table file.

    -----------------------------------------------------------------------------

end Buffer_File_Package;