blob: aee0b094ce5394e5640ad59e5c86433667e6dd03 [file] [log] [blame]
-- CB41003.A
--
-- Grant of Unlimited Rights
--
-- Under contracts F33600-87-D-0337, F33600-84-D-0280, MDA903-79-C-0687,
-- F08630-91-C-0015, and DCA100-97-D-0025, the U.S. Government obtained
-- unlimited rights in the software and documentation contained herein.
-- Unlimited rights are defined in DFAR 252.227-7013(a)(19). By making
-- this public release, the Government intends to confer upon all
-- recipients unlimited rights equal to those held by the Government.
-- These rights include rights to use, duplicate, release or disclose the
-- released technical data and computer software in whole or in part, in
-- any manner and for any purpose whatsoever, and to have or permit others
-- to do so.
--
-- DISCLAIMER
--
-- ALL MATERIALS OR INFORMATION HEREIN RELEASED, MADE AVAILABLE OR
-- DISCLOSED ARE AS IS. THE GOVERNMENT MAKES NO EXPRESS OR IMPLIED
-- WARRANTY AS TO ANY MATTER WHATSOEVER, INCLUDING THE CONDITIONS OF THE
-- SOFTWARE, DOCUMENTATION OR OTHER INFORMATION RELEASED, MADE AVAILABLE
-- OR DISCLOSED, OR THE OWNERSHIP, MERCHANTABILITY, OR FITNESS FOR A
-- PARTICULAR PURPOSE OF SAID MATERIAL.
--*
--
-- OBJECTIVE:
-- Check that an exception occurrence can be saved into an object of
-- type Exception_Occurrence using the procedure Save_Occurrence.
-- Check that a saved exception occurrence can be used to reraise
-- another occurrence of the same exception using the procedure
-- Reraise_Occurrence. Check that the function Save_Occurrence will
-- allocate a new object of type Exception_Occurrence_Access, and saves
-- the source exception to the new object which is returned as the
-- function result.
--
-- TEST DESCRIPTION:
-- This test verifies that an occurrence of an exception can be saved,
-- using either of two overloaded versions of Save_Occurrence. The
-- procedure version of Save_Occurrence is used to save an occurrence
-- of a user defined exception into an object of type
-- Exception_Occurrence. This object is then used as an input
-- parameter to procedure Reraise_Occurrence, the expected exception is
-- handled, and the exception id of the handled exception is compared
-- to the id of the originally raised exception.
-- The function version of Save_Occurrence returns a result of
-- Exception_Occurrence_Access, and is used to store the value of another
-- occurrence of the user defined exception. The resulting access value
-- is dereferenced and used as an input to Reraise_Occurrence. The
-- resulting exception is handled, and the exception id of the handled
-- exception is compared to the id of the originally raised exception.
--
--
-- CHANGE HISTORY:
-- 06 Dec 94 SAIC ACVC 2.0
--
--!
with Report;
with Ada.Exceptions;
procedure CB41003 is
begin
Report.Test ("CB41003", "Check that an exception occurrence can " &
"be saved into an object of type " &
"Exception_Occurrence using the procedure " &
"Save_Occurrence");
Test_Block:
declare
use Ada.Exceptions;
User_Exception_1,
User_Exception_2 : Exception;
Saved_Occurrence : Exception_Occurrence;
Occurrence_Ptr : Exception_Occurrence_Access;
User_Message : constant String := -- 200 character string.
"The string returned by Exception_Message may be tr" &
"uncated (to no less then 200 characters) by the Sa" &
"ve_Occurrence procedure (not the function), the Re" &
"raise_Occurrence proc, and the re-raise statement.";
begin
Raise_And_Save_Block_1 :
begin
-- This nested exception structure is designed to ensure that the
-- appropriate exception occurrence is saved using the
-- Save_Occurrence procedure.
raise Program_Error;
Report.Failed("Program_Error not raised");
exception
when Program_Error =>
begin
-- Use the procedure Raise_Exception, along with the 'Identity
-- attribute to raise the first user defined exception. Note
-- that a 200 character message is included in the call.
Raise_Exception(User_Exception_1'Identity, User_Message);
Report.Failed("User_Exception_1 not raised");
exception
when Exc : User_Exception_1 =>
-- This exception occurrence is saved into a variable using
-- procedure Save_Occurrence. This saved occurrence should
-- not be confused with the raised occurrence of
-- Program_Error above.
Save_Occurrence(Target => Saved_Occurrence, Source => Exc);
when others =>
Report.Failed("Unexpected exception handled, expecting " &
"User_Exception_1");
end;
when others =>
Report.Failed("Incorrect exception generated by raise statement");
end Raise_And_Save_Block_1;
Reraise_And_Handle_Saved_Exception_1 :
begin
-- Reraise the exception that was saved in the previous block.
Reraise_Occurrence(X => Saved_Occurrence);
exception
when Exc : User_Exception_1 => -- Expected exception.
-- Check the exception id of the handled id by using the
-- Exception_Identity function, and compare with the id of the
-- originally raised exception.
if User_Exception_1'Identity /= Exception_Identity(Exc) then
Report.Failed("Exception_Ids do not match - 1");
end if;
-- Check that the message associated with this exception occurrence
-- has not been truncated (it was originally 200 characters).
if User_Message /= Exception_Message(Exc) then
Report.Failed("Exception messages do not match - 1");
end if;
when others =>
Report.Failed
("Incorrect exception raised by Reraise_Occurrence - 1");
end Reraise_And_Handle_Saved_Exception_1;
Raise_And_Save_Block_2 :
begin
Raise_Exception(User_Exception_2'Identity, User_Message);
Report.Failed("User_Exception_2 not raised");
exception
when Exc : User_Exception_2 =>
-- This exception occurrence is saved into an access object
-- using function Save_Occurrence.
Occurrence_Ptr := Save_Occurrence(Source => Exc);
when others =>
Report.Failed("Unexpected exception handled, expecting " &
"User_Exception_2");
end Raise_And_Save_Block_2;
Reraise_And_Handle_Saved_Exception_2 :
begin
-- Reraise the exception that was saved in the previous block.
-- Dereference the access object for use as input parameter.
Reraise_Occurrence(X => Occurrence_Ptr.all);
exception
when Exc : User_Exception_2 => -- Expected exception.
-- Check the exception id of the handled id by using the
-- Exception_Identity function, and compare with the id of the
-- originally raised exception.
if User_Exception_2'Identity /= Exception_Identity(Exc) then
Report.Failed("Exception_Ids do not match - 2");
end if;
-- Check that the message associated with this exception occurrence
-- has not been truncated (it was originally 200 characters).
if User_Message /= Exception_Message(Exc) then
Report.Failed("Exception messages do not match - 2");
end if;
when others =>
Report.Failed
("Incorrect exception raised by Reraise_Occurrence - 2");
end Reraise_And_Handle_Saved_Exception_2;
-- Another example of the use of saving an exception occurrence
-- is demonstrated in the following block, where the ability to
-- save an occurrence into a data structure, for later processing,
-- is modeled.
Store_And_Handle_Block:
declare
Exc_Number : constant := 3;
Exception_1,
Exception_2,
Exception_3 : exception;
Exception_Storage : array (1..Exc_Number) of Exception_Occurrence;
Messages : array (1..Exc_Number) of String(1..9) :=
("Message 1", "Message 2", "Message 3");
begin
Outer_Block:
begin
Inner_Block:
begin
for i in 1..Exc_Number loop
begin
begin
-- Exceptions all raised in a deep scope.
if i = 1 then
Raise_Exception(Exception_1'Identity, Messages(i));
elsif i = 2 then
Raise_Exception(Exception_2'Identity, Messages(i));
elsif i = 3 then
Raise_Exception(Exception_3'Identity, Messages(i));
end if;
Report.Failed("Exception not raised on loop #" &
Integer'Image(i));
end;
Report.Failed("Exception not propagated on loop #" &
Integer'Image(i));
exception
when Exc : others =>
-- Save each occurrence into a storage array for
-- later processing.
Save_Occurrence(Exception_Storage(i), Exc);
end;
end loop;
end Inner_Block;
end Outer_Block;
-- Raise the exceptions from the stored occurrences, and handle.
for i in 1..Exc_Number loop
begin
Reraise_Occurrence(Exception_Storage(i));
Report.Failed("No exception reraised for " &
"exception #" & Integer'Image(i));
exception
when Exc : others =>
-- The following sequence of checks ensures that the
-- correct occurrence was stored, and the associated
-- exception was raised and handled in the proper order.
if i = 1 then
if Exception_1'Identity /= Exception_Identity(Exc) then
Report.Failed("Exception_1 not raised");
end if;
elsif i = 2 then
if Exception_2'Identity /= Exception_Identity(Exc) then
Report.Failed("Exception_2 not raised");
end if;
elsif i = 3 then
if Exception_3'Identity /= Exception_Identity(Exc) then
Report.Failed("Exception_3 not raised");
end if;
end if;
if Exception_Message(Exc) /= Messages(i) then
Report.Failed("Incorrect message associated with " &
"exception #" & Integer'Image(i));
end if;
end;
end loop;
exception
when others =>
Report.Failed("Unexpected exception in Store_And_Handle_Block");
end Store_And_Handle_Block;
Reraise_Out_Of_Scope:
declare
TC_Value : constant := 5;
The_Exception : exception;
Saved_Exc_Occ : Exception_Occurrence;
procedure Handle_It (Exc_Occ : in Exception_Occurrence) is
Must_Be_Raised : exception;
begin
if Exception_Identity(Exc_Occ) = The_Exception'Identity then
raise Must_Be_Raised;
Report.Failed("Exception Must_Be_Raised was not raised");
else
Report.Failed("Incorrect exception handled in " &
"Procedure Handle_It");
end if;
end Handle_It;
begin
if Report.Ident_Int(5) = TC_Value then
raise The_Exception;
end if;
exception
when Exc : others =>
Save_Occurrence (Saved_Exc_Occ, Exc);
begin
Handle_It(Saved_Exc_Occ); -- Raise another exception, in a
exception -- different scope.
when others => -- Handle this new exception.
begin
Reraise_Occurrence (Saved_Exc_Occ); -- Reraise the
-- original excptn.
Report.Failed("Saved Exception was not raised");
exception
when Exc_2 : others =>
if Exception_Identity (Exc_2) /=
The_Exception'Identity
then
Report.Failed
("Incorrect exception occurrence reraised");
end if;
end;
end;
end Reraise_Out_Of_Scope;
exception
when others => Report.Failed ("Exception raised in Test_Block");
end Test_Block;
Report.Result;
end CB41003;