cb40005.a

来自「linux下编程用 编译软件」· A 代码 · 共 340 行

A
340
字号
-- CB40005.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 exceptions raised in non-generic code can be handled by--      a procedure in a generic package.  Check that the exception identity--      can be properly retrieved from the generic code and used by the--      non-generic code.---- TEST DESCRIPTION:--      This test models a possible usage paradigm for the type:--        Ada.Exceptions.Exception_Occurrence.----      A generic package takes access to procedure types (allowing it to--      be used at any accessibility level) and defines a "fail soft"--      procedure that takes designators to a procedure to call, a--      procedure to call in the event that it fails, and a function to--      call to determine the next action.----      In the event an exception occurs on the call to the first procedure,--      the exception is stored in a stack; along with the designator to the--      procedure that caused it; allowing the procedure to be called again, --      or the exception to be re-raised.----      A full implementation of such a tool would use a more robust storage--      mechanism, and would provide a more flexible interface.------ CHANGE HISTORY:--      29 MAR 96   SAIC   Initial version--      12 NOV 96   SAIC   Revised for 2.1 release----!----------------------------------------------------------------- CB40005_0with Ada.Exceptions;generic  type Proc_Pointer is access procedure;  type Func_Pointer is access function return Proc_Pointer;package CB40005_0 is -- Fail_Soft  procedure Fail_Soft_Call( Proc_To_Call : Proc_Pointer;                            Proc_To_Call_On_Exception : Proc_Pointer := null;                            Retry_Routine : Func_Pointer := null );  function Top_Event_Exception return Ada.Exceptions.Exception_Occurrence;  function Top_Event_Procedure return Proc_Pointer;  procedure Pop_Event;  function Event_Stack_Size return Natural;end CB40005_0; -- Fail_Soft-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- CB40005_0with Report;package body CB40005_0 is  type History_Event is record    Exception_Event  : Ada.Exceptions.Exception_Occurrence_Access;    Procedure_Called : Proc_Pointer;  end record;  procedure Store_Event( Proc_Called : Proc_Pointer;                         Error       : Ada.Exceptions.Exception_Occurrence );  procedure Fail_Soft_Call( Proc_To_Call : Proc_Pointer;                            Proc_To_Call_On_Exception : Proc_Pointer := null;                            Retry_Routine : Func_Pointer := null ) is    Current_Proc_To_Call : Proc_Pointer := Proc_To_Call;  begin    while Current_Proc_To_Call /= null loop      begin        Current_Proc_To_Call.all;  -- call procedure through pointer        Current_Proc_To_Call := null;      exception        when Capture: others =>          Store_Event( Current_Proc_To_Call, Capture );          if Proc_To_Call_On_Exception /= null then            Proc_To_Call_On_Exception.all;          end if;          if Retry_Routine /= null then            Current_Proc_To_Call := Retry_Routine.all;          else            Current_Proc_To_Call := null;          end if;      end;    end loop;  end Fail_Soft_Call;    Stack : array(1..10) of History_Event;  -- minimal, sufficient for testing  Stack_Top : Natural := 0;  procedure Store_Event( Proc_Called : Proc_Pointer;                         Error       : Ada.Exceptions.Exception_Occurrence )  is  begin    Stack_Top := Stack_Top +1;    Stack(Stack_Top) := ( Ada.Exceptions.Save_Occurrence(Error),                          Proc_Called );  end Store_Event;  function Top_Event_Exception return Ada.Exceptions.Exception_Occurrence is  begin    if Stack_Top > 0 then      return Stack(Stack_Top).Exception_Event.all;    else      return Ada.Exceptions.Null_Occurrence;    end if;  end Top_Event_Exception;  function Top_Event_Procedure return Proc_Pointer is  begin    if Stack_Top > 0 then      return Stack(Stack_Top).Procedure_Called;    else      return null;    end if;  end Top_Event_Procedure;  procedure Pop_Event is  begin    if Stack_Top > 0 then      Stack_Top := Stack_Top -1;    else      Report.Failed("Stack Error");    end if;  end Pop_Event;  function Event_Stack_Size return Natural is  begin    return Stack_Top;  end Event_Stack_Size;end CB40005_0;------------------------------------------------------------------- CB40005with Report;with TCTouch;with CB40005_0;with Ada.Exceptions;procedure CB40005 is  type Proc_Pointer is access procedure;  type Func_Pointer is access function return Proc_Pointer;  package Fail_Soft is new CB40005_0(Proc_Pointer, Func_Pointer);  procedure Cause_Standard_Exception;  procedure Cause_Visible_Exception;  procedure Cause_Invisible_Exception;  Exception_Procedure_Pointer : Proc_Pointer;  Visible_Exception : exception;  procedure Action_On_Exception;  function Retry_Procedure return Proc_Pointer;  Raise_Error : Boolean;  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  procedure Cause_Standard_Exception is  begin    TCTouch.Touch('S');  --------------------------------------------------- S    if Raise_Error then      raise Constraint_Error;    end if;  end Cause_Standard_Exception;  procedure Cause_Visible_Exception is  begin    TCTouch.Touch('V');  --------------------------------------------------- V    if Raise_Error then      raise Visible_Exception;    end if;  end Cause_Visible_Exception;  procedure Cause_Invisible_Exception is    Invisible_Exception : exception;  begin    TCTouch.Touch('I');  --------------------------------------------------- I    if Raise_Error then      raise Invisible_Exception;    end if;  end Cause_Invisible_Exception;  procedure Action_On_Exception is  begin    TCTouch.Touch('A');  --------------------------------------------------- A  end Action_On_Exception;  function Retry_Procedure return Proc_Pointer is  begin    TCTouch.Touch('R');  --------------------------------------------------- R    return Action_On_Exception'Access;  end Retry_Procedure;         -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- begin  -- Main test procedure.  Report.Test ("CB40005", "Check that exceptions raised in non-generic " &                          "code can be handled by a procedure in a generic " &                          "package.  Check that the exception identity can " &                          "be properly retrieved from the generic code and " &                          "used by the non-generic code" );  -- first, check that the no exception cases cause no action on the stack  Raise_Error := False;  Fail_Soft.Fail_Soft_Call( Cause_Standard_Exception'Access );    -- S  Fail_Soft.Fail_Soft_Call( Cause_Visible_Exception'Access,       -- V                            Action_On_Exception'Access,                            Retry_Procedure'Access );  Fail_Soft.Fail_Soft_Call( Cause_Invisible_Exception'Access,     -- I                            null,                            Retry_Procedure'Access );  TCTouch.Assert( Fail_Soft.Event_Stack_Size = 0, "Empty stack");  TCTouch.Validate( "SVI", "Non error case check" );  -- second, check that error cases add to the stack  Raise_Error := True;  Fail_Soft.Fail_Soft_Call( Cause_Standard_Exception'Access );    -- S  Fail_Soft.Fail_Soft_Call( Cause_Visible_Exception'Access,       -- V                            Action_On_Exception'Access,           -- A                            Retry_Procedure'Access );             -- RA  Fail_Soft.Fail_Soft_Call( Cause_Invisible_Exception'Access,     -- I                            null,                            Retry_Procedure'Access );             -- RA  TCTouch.Assert( Fail_Soft.Event_Stack_Size = 3, "Stack = 3");  TCTouch.Validate( "SVARAIRA", "Error case check" );  -- check that the exceptions and procedure were stored correctly  -- on the stack  Raise_Error := False;  -- return procedure pointer from top of stack and call the procedure  -- through that pointer:  Fail_Soft.Top_Event_Procedure.all;  TCTouch.Validate( "I", "Invisible case unwind" );  begin    Ada.Exceptions.Raise_Exception(       Ada.Exceptions.Exception_Identity(Fail_Soft.Top_Event_Exception) );    Report.Failed("1: Exception not raised");  exception    when Constraint_Error  => Report.Failed("1: Raised Constraint_Error");    when Visible_Exception => Report.Failed("1: Raised Visible_Exception");    when others            => null; -- expected case  end;  Fail_Soft.Pop_Event;  -- return procedure pointer from top of stack and call the procedure  -- through that pointer:  Fail_Soft.Top_Event_Procedure.all;  TCTouch.Validate( "V", "Visible case unwind" );  begin    Ada.Exceptions.Raise_Exception(       Ada.Exceptions.Exception_Identity(Fail_Soft.Top_Event_Exception) );    Report.Failed("2: Exception not raised");  exception    when Constraint_Error  => Report.Failed("2: Raised Constraint_Error");    when Visible_Exception => null; -- expected case    when others            => Report.Failed("2: Raised Invisible_Exception");  end;  Fail_Soft.Pop_Event;  Fail_Soft.Top_Event_Procedure.all;  TCTouch.Validate( "S", "Standard case unwind" );  begin    Ada.Exceptions.Raise_Exception(       Ada.Exceptions.Exception_Identity(Fail_Soft.Top_Event_Exception) );    Report.Failed("3: Exception not raised");  exception    when Constraint_Error  => null; -- expected case    when Visible_Exception => Report.Failed("3: Raised Visible_Exception");    when others            => Report.Failed("3: Raised Invisible_Exception");  end;  Fail_Soft.Pop_Event;  TCTouch.Assert( Fail_Soft.Event_Stack_Size = 0, "Stack empty after pops");  Report.Result;end CB40005;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?