DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: B T

⟦da8f70b3c⟧ TextFile

    Length: 36697 (0x8f59)
    Types: TextFile
    Names: »B«

Derivation

└─⟦180fe333a⟧ Bits:30000405 8mm tape, Rational 1000, SW CATALOG, 10_20_0
└─⟦180fe333a⟧ Bits:30000537 8mm tape, Rational 1000, SW Catalog 10_20_0
    └─⟦5cb1d1d7f⟧ »DATA« 
        └─⟦3b1ee7bd8⟧ 
            └─⟦this⟧ 

TextFile

with Type_Definitions, Compilation_Unit_Lists, Calendar, Text_Io,
     Time_Library_1, Time_Library_2, String_Pkg, Implementation_Dependencies;
---------------------
package body Read_Log is
    ---------------------

    --| Overview
    --| Read_Log is an input package used by the report generators for
    --| the Ada Testing and Evaluation Tools. It performs all input from the
    --| Execution Log File (ELF) that is used to dynamically record
    --| information about programs written in the Ada language. The
    --| ELF is used for output by the Run Time Monitor (RTM) to record
    --| runtime information about the execution of the Ada program being
    --| tested. It is used as input by various report generators which
    --| summarize the information and present it in a meaningful format.
    --| All output to the ELF by the Run Time Monitor is performed by the
    --| package Write_Log.

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

    --  Version         : 3.1
    --  Author          : Jeff England
    --  Initial Release : 02/27/85
    --  Last Modified   : 05/14/85

    use Type_Definitions,           --| Global type declarations common to all
                                    --| of the Ada Testing and Analysis Tools.

        Implementation_Dependencies,    --| Ada compiler dependencies

        Text_Io;                     --| The logfile is in text format

    package Int_Io is new Integer_Io (Integer);
    package New_Long_Integer_Io is new Integer_Io (Long_Integer);
    package New_Float_Io is new Float_Io (Float);
    --    package New_Long_Float_Io is new Float_Io (Long_Float);

    use Int_Io;

    type Logfile_States is (Opened, Closed);
    type Logfile_Positions is (Log_Key, Log_Data);

    Logfile : Text_Io.File_Type;

    Tool_Name : Tool_Names;       --| Name of the tool
    Timing : Boolean := False; --| Timing option is used by Profile
    Logfile_Is_Open : Boolean := False; --| Goes true when logfile is opened

    Timing_Method : Time_Library_1.Timing_Type; --| method of recording times
    Current_Key : Logfile_Keys := Program;    --| The current logfile key

    Number_Of_Compilation_Units : Natural := 0;

    Next_Logfile_Item : Logfile_Positions := Log_Key;
    Max_Line_Length : constant Integer := 255; --| Max length of logfile entry
    Temp_String : String (1 .. Max_Line_Length);

    ----------------------------
    procedure Dump_Logfile_State is

    begin

        Put ("Key      = ");
        Put (Logfile_Keys'Pos (Current_Key));
        New_Line;
        Put ("Position = ");
        Put (Logfile_Positions'Pos (Next_Logfile_Item));
        New_Line;

    end Dump_Logfile_State;


    ------------------------
    procedure Verify_Logfile
                 (--| Verify the current state of the logfile
                  Desired_State : in Logfile_States;
                  Desired_Position : in Logfile_Positions := Next_Logfile_Item;
                  First_Key : in Logfile_Keys := Logfile_Keys'First;
                  Last_Key : in Logfile_Keys := Logfile_Keys'Last

                  ) is

        --| Raises: Logfile_Access_Error, Logfile_Sequence_Error, End_of_Logfile

        --| Effects
        --| This is an internal procedure that checks the current status of the
        --| logfile for the following error conditions:
        --|
        --| Logfile State:    If the desired state is open and the logfile is
        --|                   closed then the exception Logfile_Access_Error
        --|                   is raised.
        --|
        --| Logfile Position: If the desired position does not match the current
        --|                   position then the exception Logfile_Sequence_Error
        --|                   is raised.
        --|
        --| Logfile Key:      If the current logfile key is not in the desired
        --|                   range then the exception Logfile_Sequence_Error
        --|                   is raised.
        --|
        --| End_of_File:      If the logfile is open and is currently positioned
        --|                   at the end of file then the exception
        --|                   End_of_Logfile is raised.


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

    begin

        --| Check Logfile state
        if Desired_State = Opened and not Logfile_Is_Open then
            Put_Line ("Logfile Access Error: Logfile not open");
            Dump_Logfile_State;
            raise Logfile_Access_Error;
        end if;

        if Desired_State = Closed and Logfile_Is_Open then
            Put_Line ("Logfile Access Error: Logfile already open");
            Dump_Logfile_State;
            raise Logfile_Access_Error;
        end if;

        --| Check Logfile position
        if Desired_Position /= Next_Logfile_Item then
            Put_Line ("Logfile Sequence Error - Position");
            Dump_Logfile_State;
            raise Logfile_Sequence_Error;
        end if;

        --| Check for valid Logfile key
        if Current_Key not in First_Key .. Last_Key then
            Put_Line ("Logfile Sequence Error - Key");
            Dump_Logfile_State;
            raise Logfile_Sequence_Error;
        end if;

        --| Test for unchecked End Of File
        if Logfile_Is_Open then
            if End_Of_File (Logfile) then
                Put_Line ("Error - Unchecked EOF");
                Dump_Logfile_State;
                raise End_Of_Logfile;
            end if;
        end if;

    end Verify_Logfile;


    ------------------------------
    procedure Flush_Logfile_Record
                 (--| Flush the current Logfile record

                  Key : in Logfile_Keys  --| The current logfile key

                  ) is

        --| Effects
        --| If Key is equal to the current log file key then the remainder of the
        --| current logfile record is flushed and the logfile is positioned at
        --| the beginning of the next logfile record.

        --| Requires
        --| The ELF must have been previously opened for input by the
        --| calling program via a call to the procedure Open_Log.
        --| The Logfile key for the current record must have already been
        --| read. The Key passed by the calling program must match the
        --| key for the current logfile record.

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

    begin

        --| Flush the current logfile record and reset the
        --| current logfile position to Log_Key.

        Skip_Line (Logfile);
        Next_Logfile_Item := Log_Key;

    end Flush_Logfile_Record;


    -----------------
    function Next_Key return Logfile_Keys is

        Key_Number : Natural;
        Space : Character;

    begin

        Get (Logfile, Key_Number);                    --| Get the logfile key
        Get (Logfile, Space);                         --| Discard next delimiter
        Next_Logfile_Item :=
           Log_Data;               --| Set new logfile position
        Current_Key := Logfile_Keys'Val (Key_Number); --| Convert key to a value

        return Current_Key;

    end Next_Key;


    ------------------------
    procedure Get_Ada_Name (  --| Get the next token from Logfile

                            Name : out
                            Ada_Name  --| The token is returned as a string type

                            ) is

        use String_Pkg;

        Token : String (1 .. Max_Line_Length);

    begin

        for Next_Character in 1 .. Max_Line_Length loop

            Get (Logfile, Token (Next_Character));

            if Token (Next_Character) = ' ' then
                Name := Make_Persistent (Upper
                                            (Token (1 .. Next_Character - 1)));
                exit;
            end if;

        end loop;

    end Get_Ada_Name;


    -----------------------------
    procedure Get_Unit_Identifier
                 (--| Gets unit ID for current unit from the ELF

                  Unit_Identifier : out Program_Unit_Unique_Identifier
                  --| A unique ID assigned by the Source Instrumenter

                  ) is

        --| Effects
        --| This is an internal procedure that gets and returns the
        --| program unit identifier from the ELF

        --| Requires
        --| The log file must have been previously opened by the calling
        --| program via a call to Open_Log. Tests for logfile open,
        --| logfile position, correct logfile key, and NOT end of logfile
        --| must have already been made.

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

        Compilation_Unit : Ada_Name;
        Space : Character;      --| spaces are field delimiters
        Temp_String : String (1 .. 3);
        Unit_Type : Character;

    begin

        Get_Ada_Name (Unit_Identifier.Enclosing_Unit_Identifier);
        Get (Logfile, Unit_Identifier.Program_Unit_Number);
        Unit_Identifier.Task_Type_Activation_Number := 0;
        Get (Logfile, Temp_String);
        Unit_Type := Temp_String (2);

        case Unit_Type is
            when 'P' =>
                Unit_Identifier.Unit_Type := Procedure_Type;
            when 'F' =>
                Unit_Identifier.Unit_Type := Function_Type;
            when 'G' =>
                Unit_Identifier.Unit_Type := Generic_Type;
            when 'K' =>
                Unit_Identifier.Unit_Type := Package_Type;
            when 'T' =>
                Unit_Identifier.Unit_Type := Task_Type;
                Get (Logfile, Unit_Identifier.Task_Type_Activation_Number);
                Get (Logfile, Space);                   -- delimiter
            when others =>
                null;
        end case;

    end Get_Unit_Identifier;



    -----------------------
    procedure Get_Unit_Id (--| Gets unit ID for current unit from the ELF

                           Unit_Identifier : out Program_Unit_Unique_Identifier
                           --| A unique ID assigned by the Source Instrumenter

                           ) is

        --| Effects
        --| Gets and returns the program unit id (Unit_ID) from the ELF

        --| Requires
        --| The log file must have been previously opened by the calling
        --| program via a call to Open_Log.
        --| The current log file key (i.e., the previously read key)
        --| must be in UNIT_START..UNIT_STOP.

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

    begin

        Get_Unit_Identifier (Unit_Identifier);
        Skip_Line (Logfile);
        Next_Logfile_Item := Log_Key;

    end Get_Unit_Id;



    ---------------------------------
    procedure Define_Compilation_Unit is
        --| Defines a new compilation unit

        use Compilation_Unit_Lists; --| List management package for
        --| compilation units and program units.

        Compilation_Unit : Ada_Name;
        Number_Of_Breakpoints : Breakpoint_Number_Range;

    begin

        Get_Ada_Name (Compilation_Unit);         -- get the name of the unit
        Get (Logfile,
             Number_Of_Breakpoints);    -- and the number of breakpoints
        -- add them to the unit list
        Add_Compilation_Unit (Compilation_Unit, Number_Of_Breakpoints);
        Skip_Line (Logfile);
        Next_Logfile_Item := Log_Key;           -- set the new logfile position

    end Define_Compilation_Unit;


    -----------------------------
    procedure Define_Program_Unit is
        --| Defines a new program unit

        use Compilation_Unit_Lists; --| List management package for
        --| compilation units and program units.
        use String_Pkg;             --| A string handling package for String_Type's

        Unit_Id : Program_Unit_Unique_Identifier;
        --| Assigned by Source Instrumenter

        Unit_Name : Ada_Name;       --| The name of the program unit
        Last : Natural;        --| Index to last character read

    begin

        Get_Unit_Identifier (Unit_Id);             -- get the program unit ID
        Get_Line (Logfile, Temp_String, Last);     -- get the name of the unit

        String_Pkg.Flush (Unit_Name);
        Unit_Name := Make_Persistent (Upper (Temp_String (1 .. Last)));
        Add_Program_Unit (Unit_Id,
                          Unit_Name);     -- Add this unit to the unit list
        Next_Logfile_Item :=
           Log_Key;             -- set new position for logfile

    end Define_Program_Unit;


    ------------------
    procedure Open_Log
                 ( --| Opens the ELF for input by the report generators.

                  Logfile_Name : in
                  Filename;            --| Name of the log file to be created

                  Program_Name : out
                     Ada_Name;           --| The name of the main program unit

                  Test_Ident : out
                     Test_Identifier;    --| A unique ID assigned by the tester

                  Test_Date : out
                     Calendar.Time    --| The date and time of the test

                  ) is

        --| Raises: Invalid_Log_File_Format, Logfile_Access_Error

        --| Effects
        --| This procedure opens the ELF for input by the report generators.
        --| If the file is successfully opened, it returns test configuration
        --| data recorded in the ELF by the RTM during execution of the Ada
        --| program under test. If the file is already open then the exception
        --| Logfile_Access_Error is raised. If the file is not successfully
        --| opened due to an IO error, then the standard Text_IO exceptions are
        --| allowed to pass unhandled back to the calling program. If the ELF is
        --| is determined to contain invalid or missing configuration data,
        --| then the exception Invalid_Log_File_Format is raised.

        --| Requires
        --| The ELF must contain test configuration data in the format
        --| created by the RTM via a call to the procedure Create_Log.

        --| N/A:  Modifies, Errors

        use Time_Library_1; --| for Timing_Type
        use Time_Library_2; --| for Timing_Is Get_Time and Get_Time_of_Day
        use String_Pkg;     --| for Mark, Release, Create, Substr, Make_Persistent

        Key : Logfile_Keys;
        Last : Natural;

        Program_Key : Boolean := False; -- a test configuration key
        Tool_Key : Boolean := False; -- a test configuration key
        Test_Time_Key : Boolean := False; -- a test configuration key
        Test_Id_Key : Boolean := False; -- a test configuration key

        Time_Type : Character; -- a temp variable for the timing method used
        Delimiter : Character; -- a temp variable for logfile field delimiters

    begin

        --| Verify that the logfile is not already open. If it is
        --| already open then raise the exception Logfile_Access_Error.

        Verify_Logfile (Closed);

        --| If no exception has been raised the open the logfile
        --| for input.

        Open (Logfile, In_File, Value (Logfile_Name));
        Logfile_Is_Open := True;        -- logfile is open for business

        ------------------
        Configuration_Data:
            while not End_Of_File (Logfile) loop

                case Next_Key is

                    when Program =>
                        Get_Line (Logfile, Temp_String, Last);
                        Program_Name := Make_Persistent
                                           (Upper (Temp_String (1 .. Last)));
                        Program_Key := True;

                    when Tool =>
                        Get_Line (Logfile, Temp_String, Last);
                        Tool_Key := True;
                        if Temp_String (1 .. Last) = "PROFILE_TOOL" then
                            Timing := True;
                        end if;

                    when Test_Time =>
                        Get (Logfile, Time_Type);
                        case Time_Type is
                            when 'W' =>
                                Timing_Is (Wall_Clock);
                            when 'R' =>
                                Timing_Is (Raw);
                            when others =>
                                raise Invalid_Logfile_Format;
                        end case;
                        Get (Logfile, Delimiter);       -- a field delimiter
                        Get_Time (Logfile, Test_Date);
                        Skip_Line (Logfile);
                        Test_Time_Key := True;

                    when Test_Id =>
                        Get_Line (Logfile, Temp_String, Last);
                        Test_Ident := Make_Persistent (Temp_String (1 .. Last));
                        Test_Id_Key := True;

                    when Compilation_Unit_Definition =>
                        Define_Compilation_Unit;

                    when Program_Unit_Definition =>
                        Define_Program_Unit;

                    when others =>
                        Flush_Logfile_Record (Current_Key);

                end case;

                exit
                   Configuration_Data when     -- all config keys have been read
                   Program_Key and Tool_Key and Test_Time_Key and Test_Id_Key;

            end loop Configuration_Data;

        Next_Logfile_Item := Log_Key;

        --| We have reached the end of the logfile. Verify that all configuration
        --| data has been found. If not, raise an exception.
        if not (Program_Key and Tool_Key and Test_Time_Key and Test_Id_Key) then
            raise Invalid_Logfile_Format;
        end if;

        Reset (Logfile);  --| The logfile must be reset in the event runtime
        --| execution data has been interleaved with
        --| Configuration data due to tasking or WITH'ing
        --| of instrumented packages.

    end Open_Log;


    ----------------------
    procedure Get_Next_Key (--| Gets the next log file key from the ELF

                            Key : in out
                            Logfile_Keys  --| Defines the type of data that is
                            --| contained in the current ELF record

                            ) is

        --| Effects
        --| This procedure reads the next log file key (Key) from the ELF and
        --| returns it to the calling program.

        --| Requires
        --| The ELF must have been previously opened for input by the
        --| calling program via a call to the procedure Open_Log.

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

    begin

        Key := Next_Key;  --  Get the next logfile key;

        case Key is

            when Program .. Test_Id =>
                --| This is a Configuration key. It was read when the log file
                --| was opened. Ignore it.
                Flush_Logfile_Record (Key);
                Get_Next_Key (Key);

            when Compilation_Unit_Definition =>
                --| This key defines a new compilation unit. It should have
                --| already been read when the log file was opened. Just in
                --| case try to add it to the compilation unit list. If it's
                --| already there then a little time will be lost but it's
                --| better to be safe than sorry.
                Define_Compilation_Unit;
                Get_Next_Key (Key);

            when Program_Unit_Definition =>
                --| This key defines a new program unit. It should have
                --| already been read when the log file was opened. Just in
                --| case try to add it to the program unit list for this
                --| compilation unit. If it's already there then a little
                --| time will be lost but it's better to be safe than sorry.
                Define_Program_Unit;
                Get_Next_Key (Key);

            when others =>
                --| No other keys require special processing
                null;

        end case;

    end Get_Next_Key;


    -----------------------
    procedure Get_Unit_Time
                 (--| Gets the unit ID and start/stop time from ELF

                  Unit_Identifier : out Program_Unit_Unique_Identifier;
                  --| A unique ID assigned by the Source Instrumenter

                  Logged_Time : out
                     Calendar.Day_Duration --| The time that the unit
                  --| was entered or exited
                  ) is

        --| Effects
        --| Gets and returns the program unit id (Unit_Identifier) and logged
        --| time (Log_Time)  from the ELF.

        --| Requires
        --| The log file must have been previously opened by the calling
        --| program via a call to Open_Log.
        --| The current log file key (i.e., the previously read key)
        --| must be in UNIT_START..UNIT_STOP.

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


    begin

        Get_Unit_Identifier (Unit_Identifier);
        Time_Library_2.Get_Time_Of_Day (Logfile, Logged_Time);
        Skip_Line (Logfile);
        Next_Logfile_Item := Log_Key;

    end Get_Unit_Time;


    ------------------------
    procedure Get_Breakpoint
                 ( --| Gets current breakpoint from the ELF

                  Unit_Identifier : out Program_Unit_Unique_Identifier;
                  --| A unique ID assigned by the Source Instrumenter

                  Current_Breakpoint : out Breakpoint_Number_Range
                  --| The breakpoint number assigned by the Source Instrumenter

                  ) is

        --| Effects
        --| Gets the program unit, and current breakpoint number from the
        --| Execution Log File.

        --| Requires
        --| The log file must have been previously opened by the calling
        --| program via a call to Open_Log.
        --| The current log file key (i.e., the previously read key)
        --| must be in LOOP_BREAKPOINT..OTHER_BREAKPOINT.

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

    begin

        Get_Unit_Identifier (Unit_Identifier);
        Get (Logfile, Current_Breakpoint);
        Skip_Line (Logfile);
        Next_Logfile_Item := Log_Key;

    end Get_Breakpoint;



    ------------------------
    function Call_Parameters  --| Gets AutoPath procedure call parameter list

                return User_Input_String  --| The user specified parameter list

                 is

        --| Raises:  Logfile_Access_Error, Logfile_Sequence_Error,
        --|          End_of_Log_File

        --| Effects
        --| Gets the AutoPath procedure call parameter list from the logfile
        --| for a single execution of the target Ada program.
        --| If the logfile is not open then the exception Logfile_Access_Error
        --| is raised.
        --| If an End of File (EOF) in the ELF is encountered, the exception
        --| End_of_Log_File is raised.
        --| If the current logfile key is not AUTOPATH_CALL
        --| then the exception Logfile_Sequence_Error is raised.

        --| Requires
        --| The log file must have been previously opened by the calling
        --| program via a call to Open_Log.
        --| The current log file key (i.e., the previously read key)
        --| must be AUTOPATH_CALL.

        --| N/A:  Modifies, Errors

        use String_Pkg; --| for handling of String_Type's

        Parameter_List : User_Input_String;
        Last : Natural;           --| The length of the parameter list

    begin

        --| Verify that the logfile is currently open, that the current
        --| logfile position is Log_Data, and that the current logfile
        --| key is AutoPath_Call. If any of these conditions
        --| is false then raise the appropriate exception.

        Verify_Logfile (Opened, Log_Data, Autopath_Call, Autopath_Call);

        Get_Line (Logfile, Temp_String, Last);
        String_Pkg.Flush (Parameter_List);
        Parameter_List := Make_Persistent (Upper (Temp_String (1 .. Last)));
        Next_Logfile_Item := Log_Key;

        return Parameter_List;

    end Call_Parameters;

    -------------------
    procedure Get_Value (--| Gets value of INTEGER variable from ELF

                         Unit_Identifier : out Program_Unit_Unique_Identifier;
                         --| A unique ID assigned by the Source Instrumenter

                         Variable_Name : out
                            Ada_Name;    --| The unqualified variable name

                         Value : out Integer   --| The current value of variable

                         ) is

        --| Effects
        --| Gets integer values from the execution log file.

        --| Requires
        --| The log file must have been previously opened by the calling
        --| program via a call to Open_Log.
        --| The current log file key (i.e., the previously read key)
        --| must be INTEGER_VARIABLE.

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

    begin

        Get_Unit_Identifier (Unit_Identifier);
        Get_Ada_Name (Variable_Name);
        Get (Logfile, Value);
        Skip_Line (Logfile);
        Next_Logfile_Item := Log_Key;

    end Get_Value;


    -------------------
    procedure Get_Value
                 (--| Gets value of LONG_INTEGER variable from ELF

                  Unit_Identifier : out Program_Unit_Unique_Identifier;
                  --| A unique ID assigned by the Source Instrumenter

                  Variable_Name : out
                     Ada_Name;       --| The unqualified variable name

                  Value : out Long_Integer --| The current value of variable

                  ) is

        --| Effects
        --| Gets long_integer values from the execution log file.

        --| Requires
        --| The log file must have been previously opened by the calling
        --| program via a call to Open_Log.
        --| The current log file key (i.e., the previously read key)
        --| must be LONG_INTEGER_VARIABLE.

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

        use New_Long_Integer_Io;

    begin

        Get_Unit_Identifier (Unit_Identifier);
        Get_Ada_Name (Variable_Name);
        Get (Logfile, Value);
        Skip_Line (Logfile);
        Next_Logfile_Item := Log_Key;

    end Get_Value;



    -------------------
    procedure Get_Value (--| Gets value of FLOAT variable from ELF

                         Unit_Identifier : out Program_Unit_Unique_Identifier;
                         --| A unique ID assigned by the Source Instrumenter

                         Variable_Name : out
                            Ada_Name;     --| The unqualified variable name

                         Value : out Float     --| The current value of variable

                         ) is

        --| Effects
        --| Gets floating point values from the execution log file.

        --| Requires
        --| The log file must have been previously opened by the calling
        --| program via a call to Open_Log.
        --| The current log file key (i.e., the previously read key)
        --| must be FLOAT_VARIABLE.

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

        use New_Float_Io;

    begin

        Get_Unit_Identifier (Unit_Identifier);
        Get_Ada_Name (Variable_Name);
        Get (Logfile, Value);
        Skip_Line (Logfile);
        Next_Logfile_Item := Log_Key;

    end Get_Value;



    -------------------
    --    procedure Get_Value (--| Gets value of LONG_FLOAT variable from ELF

    --                         Unit_Identifier : out Program_Unit_Unique_Identifier;
    --| A unique ID assigned by the Source Instrumenter

    --                         Variable_Name : out Ada_Name;    --| The unqualified variable name

    --                         Value : out Long_Float  --| The current value of variable

    --                         ) is

    --| Effects
    --| Gets long_float values from the execution log file.

    --| Requires
    --| The log file must have been previously opened by the calling
    --| program via a call to Open_Log.
    --| The current log file key (i.e., the previously read key)
    --| must be LONG_FLOAT_VARIABLE.

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

    --        use New_Long_Float_Io;

    --    begin

    --        Get_Unit_Identifier (Unit_Identifier);
    --        Get_Ada_Name (Variable_Name);
    --        Get (Logfile, Value);
    --        Skip_Line (Logfile);
    --        Next_Logfile_Item := Log_Key;

    --    end Get_Value;



    -------------------
    procedure Get_Value
                 (--| Gets value of STRING variable from ELF

                  Unit_Identifier : out Program_Unit_Unique_Identifier;
                  --| A unique ID assigned by the Source Instrumenter

                  Variable_Name : out
                     Ada_Name;           --| The unqualified variable name

                  String_Value : out
                     String_Variables --| current value of variable

                  ) is

        --| Effects
        --| Gets string values from the execution log file.
        --| This procedure used to get the value of
        --|        strings
        --|        characters
        --|        enumerated data types (including booleans)

        --| Requires
        --| The current log file key (i.e., the previously read key)
        --| must be STRING_VARIABLE.

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

        use String_Pkg; --| for handling of String_Type's

        Last : Natural;  --| The length of the string variable's value

    begin

        Get_Unit_Identifier (Unit_Identifier);
        Get_Ada_Name (Variable_Name);
        Get_Line (Logfile, Temp_String, Last);
        String_Value := Make_Persistent (Temp_String (1 .. Last));
        Next_Logfile_Item := Log_Key;

    end Get_Value;



    -------------------
    function End_Of_Log  --| Checks for End Of file in the ELF
                return Boolean     --| True if EOF is reached else false

                 is

        --| Raises:  Logfile_Access_Error

        --| Effects
        --| This function checks for End Of File in the ELF and returns true
        --| if an EOF has been reached.
        --| If the logfile is not open then the exception Logfile_Access_Error
        --| is raised.
        --| Text_IO exceptions that may be raised are allowed to pass, unhandled,
        --| back to the calling program.

        --| Requires
        --| The log file must have been previously opened by the calling
        --| program via a call to Open_Log.

        --| N/A:  Modifies, Errors


    begin
        if not Logfile_Is_Open then
            Put_Line ("In End_of_Log");
            Put_Line ("Logfile Access Error: Logfile not open");
            Dump_Logfile_State;
            raise Logfile_Access_Error;
        else
            return End_Of_File (Logfile);
        end if;
    end End_Of_Log;



    ------------------------
    procedure Find_Unit_Name
                 ( --| Finds the name of a program unit

                  Unit_Identifier : in Program_Unit_Unique_Identifier;
                  --| A unique ID assigned by the Source Instrumenter

                  Unit_Name : out Ada_Name  --| The name of program unit

                  ) is

        --| Raises: Undefined_Program_Unit

        --| Effects
        --| Finds the program unit unit name (Unit_Name) corresponding to the
        --| program unit ID. If no UNIT_DEF record has been previously
        --| encountered in the ELF to associate a program unit name with
        --| the specified unit ID then the Undefined_Program_Unit exception
        --| is raised.

        --| Requires
        --| A program unit name (Unit_Name) must have been previously recorded
        --| in the ELF and assosiated with the specified unit id (Unit_Identifier)
        --| by the program that originally generated the log file via a call
        --| to the procedure Define_Comp_Unit.

        --| N/A:  Modifies, Errors

        use Compilation_Unit_Lists; --| List management package for
        --| compilation units and program units.
    begin

        Get_Program_Unit_Name (Unit_Identifier, Unit_Name);

    end Find_Unit_Name;



    ------------------------------
    function Number_Of_Breakpoints (--| Finds the number of breakpoints
                                    --| in a compilation unit

                                    Compilation_Unit_Name : in
                                    Ada_Name --| The name of the compilation unit

                                    ) return Breakpoint_Number_Range is

        --| Raises: Undefined_Program_Unit

        --| Effects
        --| Gets and returns the total number of breakpoints in the
        --| specified compilation unit. If the compilation unit has
        --| not been previously defined in the logfile then the
        --| exception Undefined_Program_Unit is raised.

        --| Requires
        --| The compilation unit name must have been previously
        --| returned to the calling program in a Unit ID by the
        --| the procedure Get_Unit_ID.

        --| N/A:  Modifies, Errors

        use Compilation_Unit_Lists;  --| List management package for
        --| compilation units and program units.

        Total_Breakpoints : Breakpoint_Number_Range;

    begin

        Get_Number_Of_Breakpoints (Compilation_Unit_Name, Total_Breakpoints);
        return Total_Breakpoints;

    end Number_Of_Breakpoints;


    --------------------
    function Timing_Data  --| Returns true if the logfile contains timing data

                return Boolean

                 is

        --| Raises: Logfile_Access_Error

        --| Effects
        --| Returns true if the logfile contains timing data. Otherwise
        --| returns false. This function provides a mechanism for the
        --| calling program to determine whether or not timing data
        --| has been recorded in the logfile prior to calling other
        --| Read_Log procedures that read times from the logfile.
        --| If the logfile is not open then the exception
        --| Logfile_Access_Error is raised.

        --| Requires
        --| The target Ada program must have been executed with
        --| Tool_Name = Profile_Tool in order for timing data to have
        --| been recorded in the log file and the current log file
        --| key must be Timing_Overhead. The log file must have been
        --| previously opened by the calling program via a call to Open_Log.

        --| N/A:  Modifies, Errors


    begin

        return Timing;

    end Timing_Data;


    -----------------------------
    function Accumulated_Overhead --| Returns the Accumulated timing overhead
                                  --| calculated during test program execution

                return Calendar.Day_Duration

                 is

        --| Raises: Logfile_Access_Error

        --| Effects
        --| Gets and returns the total accumulated timing overhead
        --| calculated during execution of the target Ada program.
        --| If the logfile is not open or the current logfile key is
        --| not then the exception Logfile_Access_Error is raised.

        --| Requires
        --| The target Ada program must have been executed with
        --| Tool_Name = Profile_Tool in order for timing data to have
        --| been recorded in the log file and the current log file
        --| key must be Timing_Overhead.

        --| N/A:  Modifies, Errors

        Logged_Time : Calendar.Day_Duration;

    begin

        --| Verify that the logfile is currently open, that the current
        --| logfile position is Log_Data, and that the current logfile
        --| key is in Unit_Start..Unit_Stop. If any of these conditions
        --| is false then raise the appropriate exception.

        Verify_Logfile (Opened, Log_Data, Timing_Overhead, Timing_Overhead);

        Time_Library_2.Get_Time_Of_Day (Logfile, Logged_Time);
        Skip_Line (Logfile);
        Next_Logfile_Item := Log_Key;
        return Logged_Time;

    end Accumulated_Overhead;

    -------------------
    procedure Close_Log is
        --| Closes the execution log file

        --| Raises:  Logfile_Access_Error

        --| Effects
        --| Closes the execution log file.
        --| If the logfile is not open then the exception Logfile_Access_Error
        --| is raised.

        --| Requires
        --| The log file must have been previously opened by the calling
        --| program via a call to Open_Log.

        --| N/A:  Modifies, Errors

    begin
        if Logfile_Is_Open then
            Close (Logfile);
            Logfile_Is_Open := False;
        else
            Put_Line ("In Close_Log");
            Put_Line ("Logfile_Access_Error: Logfile already closed");
            raise Logfile_Access_Error;
        end if;
    end Close_Log;


end Read_Log;