-- C3A0011.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 access-to-subprogram object whose type is declared in a
--      parent package, may be used to invoke subprograms in a child package.
--      Check that such access objects may be stored in a data structure and
--      that subprograms may be called by walking the data structure.
-- 
-- TEST DESCRIPTION:
--      In the package, declare an access to procedure type.  Declare an 
--      array of the access type.  Declare three different procedures that 
--      can be referred to by the access to procedure type.           
--
--      In the visible child package, declare two procedures that can be 
--      referred to by the access to procedure type of the parent.  Build 
--      the array by calling each procedure indirectly through the access 
--      value.
--
--
-- CHANGE HISTORY:
--      06 Dec 94   SAIC    ACVC 2.0
--      16 Dec 94   SAIC    Improved visibility of "/=" in main body
--
--!
package C3A0011_0 is -- Interpreter
   
   type Compass_Point is mod 360;
   function Heading return Compass_Point;
   -- Type accesses to any procedure
   type Action_Ptr is access procedure;
   
   -- Array of access to procedure
   type Action_Array is array (Natural range <>) of Action_Ptr;
   procedure Rotate_Left;
   procedure Rotate_Right;
   procedure Center;
private
   The_Heading : Compass_Point := Compass_Point'First;
end C3A0011_0;
-----------------------------------------------------------------------------
package body C3A0011_0 is
   function Heading return Compass_Point is
   begin
     return The_Heading;
   end Heading;
   procedure Rotate_Left is
   begin
      The_Heading := The_Heading - 90;
   end Rotate_Left;
   procedure Rotate_Right is
   begin
      The_Heading := The_Heading + 90;
   end Rotate_Right;
   procedure Center is
   begin
      The_Heading := 0;
   end Center;
end C3A0011_0;
-----------------------------------------------------------------------------
package C3A0011_0.Action is
   procedure Rotate_Front;
   procedure Rotate_Back;
end C3A0011_0.Action;
-----------------------------------------------------------------------------
package body C3A0011_0.Action is
   procedure Rotate_Front is
   begin
      The_Heading := The_Heading + 5;
   end Rotate_Front;
   procedure Rotate_Back is
   begin
      The_Heading := The_Heading - 5;
   end Rotate_Back;
end C3A0011_0.Action;
-----------------------------------------------------------------------------
with C3A0011_0.Action;
with Report;
procedure C3A0011 is
   Total_Actions   : constant := 6;
   Action_Sequence : C3A0011_0.Action_Array (1 .. Total_Actions);
   type Result_Array is array (Natural range <>) of C3A0011_0.Compass_Point;
   Action_Results  : Result_Array(1 .. Total_Actions);
   package IA renames C3A0011_0.Action;
   
begin
   Report.Test ("C3A0011", "Check that an access-to-subprogram object whose "
                         & "type is declared in a parent package, may be "
                         & "used to invoke subprograms in a child package. "
                         & "Check that such access objects may be stored in "
                         & "a data structure and that subprograms may be "
                         & "called by walking the data structure");
   -- Build the action sequence
   Action_Sequence := (C3A0011_0.Rotate_Left'Access, 
                       C3A0011_0.Center'Access,
                       C3A0011_0.Rotate_Right'Access, 
                       IA.Rotate_Front'Access,
                       C3A0011_0.Center'Access,
                       IA.Rotate_Back'Access);
   -- Build the expected result
   Action_Results := ( 270, 0, 90, 95, 0, 355 );
   -- Assign actions by invoking subprogram designated by access value
   for I in Action_Sequence'Range loop
      Action_Sequence(I).all;
      if C3A0011_0."/="( C3A0011_0.Heading, Action_Results(I) ) then
        Report.Failed ("Expecting "
                       & C3A0011_0.Compass_Point'Image(Action_Results(I))
                       & " Got"
                       & C3A0011_0.Compass_Point'Image(C3A0011_0.Heading));
      end if;
   end loop;
   Report.Result;
end C3A0011;