blob: 7b4f48869b25f48ffe45fb927ed2e516d217733e [file] [log] [blame]
-- CA11D02.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 declared in a package can be raised by a
-- child of a child package. Check that it can be renamed in the
-- child of the child package and raised with the correct effect.
--
-- TEST DESCRIPTION:
-- Declare a package which defines complex number abstraction with
-- user-defined exceptions (foundation code).
--
-- Add a public child package to the above package. Declare two
-- subprograms for the parent type.
--
-- Add a public grandchild package to the foundation package. Declare
-- subprograms to raise exceptions.
--
-- In the main program, "with" the grandchild package, then check that
-- the exceptions are raised and handled as expected. Ensure that
-- exceptions are:
-- 1) raised in the public grandchild package and handled/reraised to
-- be handled by the main program.
-- 2) raised and handled locally by the "others" handler in the
-- public grandchild package.
-- 3) raised in the public grandchild and propagated to the main
-- program.
--
-- TEST FILES:
-- This test depends on the following foundation code:
--
-- FA11D00.A
--
--
-- CHANGE HISTORY:
-- 06 Dec 94 SAIC ACVC 2.0
--
--!
-- Child package of FA11D00.
package FA11D00.CA11D02_0 is -- Basic_Complex
function "+" (Left, Right : Complex_Type)
return Complex_Type; -- Add two complex numbers.
function "*" (Left, Right : Complex_Type)
return Complex_Type; -- Multiply two complex numbers.
end FA11D00.CA11D02_0; -- Basic_Complex
--=======================================================================--
package body FA11D00.CA11D02_0 is -- Basic_Complex
function "+" (Left, Right : Complex_Type) return Complex_Type is
begin
return ( (Left.Real + Right.Real, Left.Imag + Right.Imag) );
end "+";
--------------------------------------------------------------
function "*" (Left, Right : Complex_Type) return Complex_Type is
begin
return ( Real => (Left.Real * Right.Real),
Imag => (Left.Imag * Right.Imag) );
end "*";
end FA11D00.CA11D02_0; -- Basic_Complex
--=======================================================================--
-- Child package of FA11D00.CA11D02_0.
-- Grandchild package of FA11D00.
package FA11D00.CA11D02_0.CA11D02_1 is -- Array_Complex
Inverse_Error : exception renames Divide_Error; -- Reference to exception
-- in grandparent package.
Array_Size : constant := 2;
type Complex_Array_Type is
array (1 .. Array_Size) of Complex_Type; -- Reference to type
-- in parent package.
function Multiply (Left : Complex_Array_Type; -- Multiply two complex
Right : Complex_Array_Type) -- arrays.
return Complex_Array_Type;
function Add (Left, Right : Complex_Array_Type) -- Add two complex
return Complex_Array_Type; -- arrays.
procedure Inverse (Right : in Complex_Array_Type; -- Invert a complex
Left : in out Complex_Array_Type); -- array.
end FA11D00.CA11D02_0.CA11D02_1; -- Array_Complex
--=======================================================================--
with Report;
package body FA11D00.CA11D02_0.CA11D02_1 is -- Array_Complex
function Multiply (Left : Complex_Array_Type;
Right : Complex_Array_Type)
return Complex_Array_Type is
-- This procedure will raise an exception depending on the input
-- parameter. The exception will be handled locally by the
-- "others" handler.
Result : Complex_Array_Type := (others => Zero);
subtype Vector_Size is Positive range Left'Range;
begin
if Left = Result or else Right = Result then -- Do not multiply zero.
raise Multiply_Error; -- Refence to exception in
-- grandparent package.
Report.Failed ("Program control not transferred by raise");
else
for I in Vector_Size loop
Result(I) := ( Left(I) * Right(I) ); -- Basic_Complex."*".
end loop;
end if;
return (Result);
exception
when others =>
Report.Comment ("Exception is handled by others in Multiplication");
TC_Handled_In_Grandchild_Pkg_Func := true;
return (Zero, Zero);
end Multiply;
--------------------------------------------------------------
function Add (Left, Right : Complex_Array_Type)
return Complex_Array_Type is
-- This function will raise an exception depending on the input
-- parameter. The exception will be propagated and handled
-- by the caller.
Result : Complex_Array_Type := (others => Zero);
subtype Vector_Size is Positive range Left'Range;
begin
if Left = Result or Right = Result then -- Do not add zero.
raise Add_Error; -- Refence to exception in
-- grandparent package.
Report.Failed ("Program control not transferred by raise");
else
for I in Vector_Size loop
Result(I) := ( Left(I) + Right(I) ); -- Basic_Complex."+".
end loop;
end if;
return (Result);
end Add;
--------------------------------------------------------------
procedure Inverse (Right : in Complex_Array_Type;
Left : in out Complex_Array_Type) is
-- This function will raise an exception depending on the input
-- parameter. The exception will be handled/reraised to be
-- handled by the caller.
Result : Complex_Array_Type := (others => Zero);
Array_With_Zero : boolean := false;
begin
for I in 1 .. Right'Length loop
if Right(I) = Zero then -- Check for zero.
Array_With_Zero := true;
end if;
end loop;
If Array_With_Zero then
raise Inverse_Error; -- Do not inverse zero.
Report.Failed ("Program control not transferred by raise");
else
for I in 1 .. Array_Size loop
Left(I).Real := - Right(I).Real;
Left(I).Imag := - Right(I).Imag;
end loop;
end if;
exception
when Inverse_Error =>
TC_Handled_In_Grandchild_Pkg_Proc := true;
Left := Result;
raise; -- Reraise the Inverse_Error exception in the subtest.
Report.Failed ("Exception not reraised in handler");
when others =>
Report.Failed ("Unexpected exception in procedure Inverse");
end Inverse;
end FA11D00.CA11D02_0.CA11D02_1; -- Array_Complex
--=======================================================================--
with FA11D00.CA11D02_0.CA11D02_1; -- Array_Complex,
-- implicitly with Basic_Complex.
with Report;
procedure CA11D02 is
package Complex_Pkg renames FA11D00;
package Array_Complex_Pkg renames FA11D00.CA11D02_0.CA11D02_1;
use Complex_Pkg;
use Array_Complex_Pkg;
begin
Report.Test ("CA11D02", "Check that an exception declared in a package " &
"can be raised by a child of a child package");
Multiply_Complex_Subtest:
declare
Operand_1 : Complex_Array_Type
:= ( Complex (Int_Type (Report.Ident_Int (3)),
Int_Type (Report.Ident_Int (5))),
Complex (Int_Type (Report.Ident_Int (2)),
Int_Type (Report.Ident_Int (8))) );
Operand_2 : Complex_Array_Type
:= ( Complex (Int_Type (Report.Ident_Int (1)),
Int_Type (Report.Ident_Int (2))),
Complex (Int_Type (Report.Ident_Int (3)),
Int_Type (Report.Ident_Int (6))) );
Operand_3 : Complex_Array_Type := ( Zero, Zero);
Mul_Result : Complex_Array_Type
:= ( Complex (Int_Type (Report.Ident_Int (3)),
Int_Type (Report.Ident_Int (10))),
Complex (Int_Type (Report.Ident_Int (6)),
Int_Type (Report.Ident_Int (48))) );
Complex_No : Complex_Array_Type := (others => Zero);
begin
If (Multiply (Operand_1, Operand_2) /= Mul_Result) then
Report.Failed ("Incorrect results from multiplication");
end if;
-- Error is raised and exception will be handled in grandchild package.
Complex_No := Multiply (Operand_1, Operand_3);
if Complex_No /= (Zero, Zero) then
Report.Failed ("Exception was not raised in multiplication");
end if;
exception
when Multiply_Error =>
Report.Failed ("Exception raised in multiplication and " &
"propagated to caller");
TC_Handled_In_Grandchild_Pkg_Func := false;
-- Improper exception handling in caller.
when others =>
Report.Failed ("Unexpected exception in multiplication");
TC_Handled_In_Grandchild_Pkg_Func := false;
-- Improper exception handling in caller.
end Multiply_Complex_Subtest;
Add_Complex_Subtest:
declare
Operand_1 : Complex_Array_Type
:= ( Complex (Int_Type (Report.Ident_Int (2)),
Int_Type (Report.Ident_Int (7))),
Complex (Int_Type (Report.Ident_Int (5)),
Int_Type (Report.Ident_Int (8))) );
Operand_2 : Complex_Array_Type
:= ( Complex (Int_Type (Report.Ident_Int (4)),
Int_Type (Report.Ident_Int (1))),
Complex (Int_Type (Report.Ident_Int (2)),
Int_Type (Report.Ident_Int (3))) );
Operand_3 : Complex_Array_Type := ( Zero, Zero);
Add_Result : Complex_Array_Type
:= ( Complex (Int_Type (Report.Ident_Int (6)),
Int_Type (Report.Ident_Int (8))),
Complex (Int_Type (Report.Ident_Int (7)),
Int_Type (Report.Ident_Int (11))) );
Complex_No : Complex_Array_Type := (others => Zero);
begin
Complex_No := Add (Operand_1, Operand_2);
If (Complex_No /= Add_Result) then
Report.Failed ("Incorrect results from addition");
end if;
-- Error is raised in grandchild package and exception
-- will be propagated to caller.
Complex_No := Add (Operand_1, Operand_3);
if Complex_No = Add_Result then
Report.Failed ("Exception was not raised in addition");
end if;
exception
when Add_Error =>
TC_Propagated_To_Caller := true; -- Exception is propagated.
when others =>
Report.Failed ("Unexpected exception in addition subtest");
TC_Propagated_To_Caller := false; -- Improper exception handling
-- in caller.
end Add_Complex_Subtest;
Inverse_Complex_Subtest:
declare
Operand_1 : Complex_Array_Type
:= ( Complex (Int_Type (Report.Ident_Int (1)),
Int_Type (Report.Ident_Int (5))),
Complex (Int_Type (Report.Ident_Int (3)),
Int_Type (Report.Ident_Int (11))) );
Operand_3 : Complex_Array_Type
:= ( Zero, Complex (Int_Type (Report.Ident_Int (3)),
Int_Type (Report.Ident_Int (6))) );
Inv_Result : Complex_Array_Type
:= ( Complex (Int_Type (Report.Ident_Int (-1)),
Int_Type (Report.Ident_Int (-5))),
Complex (Int_Type (Report.Ident_Int (-3)),
Int_Type (Report.Ident_Int (-11))) );
Complex_No : Complex_Array_Type := (others => Zero);
begin
Inverse (Operand_1, Complex_No);
if (Complex_No /= Inv_Result) then
Report.Failed ("Incorrect results from inverse");
end if;
-- Error is raised in grandchild package and exception
-- will be handled/reraised to caller.
Inverse (Operand_3, Complex_No);
Report.Failed ("Exception was not handled in inverse");
exception
when Inverse_Error =>
if not TC_Handled_In_Grandchild_Pkg_Proc then
Report.Failed ("Exception was not raised in inverse");
else
TC_Handled_In_Caller := true; -- Exception is reraised from
-- child package.
end if;
when others =>
Report.Failed ("Unexpected exception in inverse");
TC_Handled_In_Caller := false;
-- Improper exception handling in caller.
end Inverse_Complex_Subtest;
if not (TC_Handled_In_Caller and -- Check to see that all
TC_Handled_In_Grandchild_Pkg_Proc and -- exceptions were handled
TC_Handled_In_Grandchild_Pkg_Func and -- in proper location.
TC_Propagated_To_Caller)
then
Report.Failed ("Exceptions handled in incorrect locations");
end if;
Report.Result;
end CA11D02;