-- Instrumentation file to use with Ada83. -- Replace the string "YourCommandHere" with -- the name of your binary file. package Audit_Instrum is -- to be called once for the application procedure Audit_Init_Application (Appli : String; Data : String; Max_Func : Natural); -- to be called for each instrumented function -- and each called extern function procedure Audit_Init_Function (Func_Id : Positive; Func_Name : String; Func_Date : String; Nb_Bran : Natural; Nb_Calls : Natural; Nb_Mcdcs : Natural); -- called at the beginning of each instrumented function function Audit_Start_Func (Func_Id : Positive; Vect_Size : Natural) return Boolean; -- called for each branch of a function procedure Audit_Set_Branch (Func_Id : Positive; Bran_Id : Natural); -- called for each call in a function procedure Audit_Set_Call (Func_Id : Positive; Called_Func_Id : Positive); -- called for each call in a function function Audit_Set_Call (Func_Id : Positive; Called_Func_Id : Positive) return Boolean; -- called for each MCDC in a function function Audit_Set_Mcdc (Func_Id : Positive; Mcdc_Id : Positive; Nb_Cond : Positive; Exp : Boolean) return Boolean; -- called for each single condition in a MCDC function Audit_Set_Sgl_Cond (Func_Id : Positive; Mcdc_Id : Positive; Index : Positive; Exp : Boolean) return Boolean; -- instrumentation of a boolean expression in an exit when statement function Audit_Set_Bool_Exp (Func_Id : Positive; Bran_T, Bran_F : Natural; Exp : Boolean) return Boolean; -- to be called when the instrumentation dump must be done procedure Audit_Stop; end Audit_Instrum; with Text_Io; with Calendar; use Calendar; package body Audit_Instrum is type String_Acc is access String; -- table of branches in a function type Audit_Bran_Tab is array (Natural range <>) of Natural; type Audit_Bran_Tab_Acc is access Audit_Bran_Tab; type Audit_Chars; type Audit_Chars_Acc is access Audit_Chars; type Audit_Chars is record Str : String_Acc; Flag_Line : Boolean; Succ : Audit_Chars_Acc; Prec : Audit_Chars_Acc; end record; -- type for a function call type Audit_Call is record Called_Func_Id : Positive; -- id of the called function Nb_Calls : Natural; -- number of calls to this function end record; type Audit_Call_Acc is access Audit_Call; -- table of calls in a function type Audit_Call_Tab is array (Natural range <>) of Audit_Call_Acc; type Audit_Call_Tab_Acc is access Audit_Call_Tab; -- table of true or false vectors for a MCDC type Audit_Vect_Tab is array (Positive range <>) of String_Acc; type Audit_Vect_Tab_Acc is access Audit_Vect_Tab; -- type for a MCDC in a function type Audit_Mcdc is record Nb_Vect_T : Natural; Vects_T : Audit_Vect_Tab_Acc; Nb_Vect_F : Natural; Vects_F : Audit_Vect_Tab_Acc; end record; type Audit_Mcdc_Acc is access Audit_Mcdc; -- table of MCDCs in a function type Audit_Mcdc_Tab is array (Positive range <>) of Audit_Mcdc_Acc; type Audit_Mcdc_Tab_Acc is access Audit_Mcdc_Tab; -- type for a function type Audit_Func is record Func_Id : Positive; -- id of the function in the application Func_Name : String_Acc; -- function name Func_Date : String_Acc; -- function date Nb_Bran : Natural; -- number of branches in the function Branches : Audit_Bran_Tab_Acc;-- table of branches of the function Nb_Calls : Natural; -- number of distincts calls Calls : Audit_Call_Tab_Acc; -- table of calls from the function Nb_Mcdcs : Natural; -- number of MCDCs in the function Mcdcs : Audit_Mcdc_Tab_Acc; -- table of MCDCs of the function Mcdc_Vects : Audit_Vect_Tab_Acc; -- table of MCDC vectors for the func end record; type Audit_Func_Acc is access Audit_Func; -- table of functions in the application type Audit_Func_Tab is array (Positive range <>) of Audit_Func_Acc; type Audit_Func_Tab_Acc is access Audit_Func_Tab; Result_Fp : Text_Io.File_Type; -- file for the coverage dump Version : constant String := "VD2.0"; -- version of the coverage file Max_Line_Length : constant := 80; -- maximum number of characters per line Cur_Line_Length : Natural := 0; -- current number of characters on a line Cur_Test_Num : Natural := 0; Adt_Funcs : Audit_Func_Tab_Acc; -- table of the functions of the application Adt_Max_Func : Natural := 0; -- maximum id of functions in the application Adt_Application : String_Acc; -- application name Adt_Data : String_Acc; -- application data directory Adt_Dummy: Boolean; Adt_First_Chars : Audit_Chars_Acc; Adt_Next_Chars : Audit_Chars_Acc; procedure Audit_Init_Application (Appli : String; Data : String; Max_Func : Natural) is begin Adt_Application := new String'(Appli); Adt_Data := new String'(Data); Adt_Max_Func := Max_Func; Adt_Funcs := new Audit_Func_Tab'(1 .. Max_Func => null); end Audit_Init_Application; procedure Audit_Init_Function (Func_Id : Positive; Func_Name : String; Func_Date : String; Nb_Bran : Natural; Nb_Calls : Natural; Nb_Mcdcs : Natural) is Adt_Bran : Audit_Bran_Tab_Acc := new Audit_Bran_Tab'(0 .. Nb_Bran - 1 => 0); Adt_Call : Audit_Call_Tab_Acc := new Audit_Call_Tab'(1 .. Nb_Calls => null); Adt_Mcdc : Audit_Mcdc_Tab_Acc := new Audit_Mcdc_Tab'(1 .. Nb_Mcdcs => null); Mcdc_Vects : Audit_Vect_Tab_Acc := new Audit_Vect_Tab'(1 .. Nb_Mcdcs => null); begin Adt_Funcs(Func_Id) := new Audit_Func'(Func_Id, new String'(Func_Name), new String'(Func_Date), Nb_Bran, Adt_Bran, 0, Adt_Call, Nb_Mcdcs, Adt_Mcdc, Mcdc_Vects); end Audit_Init_Function; function Audit_Start_Func (Func_Id : Positive; Vect_Size : Natural) return Boolean is Adt_Func : Audit_Func_Acc := Adt_Funcs(Func_Id); begin Audit_Set_Branch(Func_Id, 0); if (Vect_Size > 0) then for I in 1 .. Adt_Func.Nb_Mcdcs loop Adt_Func.Mcdc_Vects(I) := new String'(1 .. Vect_Size => '-'); end loop; end if; return True; end Audit_Start_Func; procedure Audit_Set_Branch (Func_Id : Positive; Bran_Id : Natural) is Adt_Func : Audit_Func_Acc := Adt_Funcs(Func_Id); begin Adt_Func.Branches(Bran_Id) := 1; end Audit_Set_Branch; procedure Audit_Set_Call (Func_Id : Positive; Called_Func_Id : Positive) is Adt_Func : Audit_Func_Acc := Adt_Funcs(Func_Id); Found : Boolean := False; begin for I in 1 .. Adt_Func.Nb_Calls loop if Adt_Func.Calls(I).Called_Func_Id = Called_Func_Id then Adt_Func.Calls(I).Nb_Calls := Adt_Func.Calls(I).Nb_Calls + 1; Found := True; exit; end if; end loop; if not Found then Adt_Func.Nb_Calls := Adt_Func.Nb_Calls + 1; Adt_Func.Calls(Adt_Func.Nb_Calls) := new Audit_Call'(Called_Func_Id, 1); end if; end Audit_Set_Call; function Audit_Set_Call (Func_Id : Positive; Called_Func_Id : Positive) return Boolean is begin Audit_Set_Call(Func_Id, Called_Func_Id); return True; end Audit_Set_Call; function Audit_Set_Bool_Exp (Func_Id : Positive; Bran_T, Bran_F : Natural; Exp : Boolean) return Boolean is begin if Exp then Audit_Set_Branch(Func_Id, Bran_T); else Audit_Set_Branch(Func_Id, Bran_F); end if; return Exp; end Audit_Set_Bool_Exp; function Audit_Set_Mcdc (Func_Id : Positive; Mcdc_Id : Positive; Nb_Cond : Positive; Exp : Boolean) return Boolean is Adt_Func : Audit_Func_Acc := Adt_Funcs (Func_Id); Adt_Mcdc : Audit_Mcdc_Acc := Adt_Func.Mcdcs (Mcdc_Id); Vect_Id : Natural := 0; Mcdc_Vect : String := Adt_Func.Mcdc_Vects(Mcdc_Id).all(1 .. Nb_Cond); begin if (Adt_Mcdc = null) then Adt_Func.Mcdcs (Mcdc_Id) := new Audit_Mcdc'(0, new Audit_Vect_Tab'(1 .. 2**Nb_Cond => null), 0, new Audit_Vect_Tab'(1 .. 2**Nb_Cond => null)); Adt_Mcdc := Adt_Func.Mcdcs (Mcdc_Id); end if; if (Exp) then for I in 1 .. Adt_Mcdc.Nb_Vect_T loop if Adt_Mcdc.Vects_T(I).all = Mcdc_Vect then Vect_Id := I; exit; end if; end loop; if (Vect_Id = 0) then Adt_Mcdc.Nb_Vect_T := Adt_Mcdc.Nb_Vect_T + 1; Adt_Mcdc.Vects_T(Adt_Mcdc.Nb_Vect_T) := new String'(Mcdc_Vect); end if; else for I in 1 .. Adt_Mcdc.Nb_Vect_F loop if Adt_Mcdc.Vects_F(I).all = Mcdc_Vect then Vect_Id := I; exit; end if; end loop; if (Vect_Id = 0) then Adt_Mcdc.Nb_Vect_F := Adt_Mcdc.Nb_Vect_F + 1; Adt_Mcdc.Vects_F(Adt_Mcdc.Nb_Vect_F) := new String'(Mcdc_Vect); end if; end if; Adt_Func.Mcdc_Vects(Mcdc_Id).all := (others => '-'); return (Exp); end Audit_Set_Mcdc; function Audit_Set_Sgl_Cond (Func_Id : Positive; Mcdc_Id : Positive; Index : Positive; Exp : Boolean) return Boolean is Adt_Func : Audit_Func_Acc := Adt_Funcs (Func_Id); begin if Exp then Adt_Func.Mcdc_Vects(Mcdc_Id).all(Index) := '1'; else Adt_Func.Mcdc_Vects(Mcdc_Id).all(Index) := '0'; end if; return Exp; end Audit_Set_Sgl_Cond; function Trunc_Image(Str : String; Beg : Positive := 2) return String is begin return Str(Beg .. Str'Length); end Trunc_Image; function Trunc_Date_Image(Str : String; Beg : Positive := 2) return String is Date : String := Str(Beg .. Str'Length); begin if Date'Length < 2 then return "0" & Date; else return Date; end if; end Trunc_Image; function Format_Time(Tm : Time) return String is Nb_Year : Natural; Nb_Month : Natural; Nb_Day : Natural; Nb_Hour : Natural; Nb_Min : Natural; Nb_Sec : Natural; begin Nb_Year := Year(Tm); Nb_Month := Month(Tm); Nb_Day := Day(Tm); Nb_Sec := Natural(Seconds(Tm)); Nb_Hour := Nb_Sec / 3600; Nb_Sec := Nb_Sec - 3600 * Nb_Hour; Nb_Min := Nb_Sec / 60; Nb_Sec := Nb_Sec - 60 * Nb_Min; return(Trunc_Date_Image(Positive'Image(Nb_Month)) & "/" & Trunc_Date_Image(Positive'Image(Nb_Day)) & "/" & Trunc_Date_Image(Positive'Image(Nb_Year), 4) & "-" & Trunc_Date_Image(Positive'Image(Nb_Hour)) & ":" & Trunc_Date_Image(Positive'Image(Nb_Min)) & ":" & Trunc_Date_Image(Positive'Image(Nb_Sec))); end Format_Time; procedure Dump_File is File_Name: constant String := "instrum.dyn"; begin Text_Io.Create(Result_Fp, Text_Io.Out_File, File_Name); Adt_Next_Chars := Adt_First_Chars; while Adt_Next_Chars.Succ /= null loop if Adt_Next_Chars.Flag_Line then Text_Io.Put_Line(Result_Fp, Adt_Next_Chars.Str.all); else Text_Io.Put(Result_Fp, Adt_Next_Chars.Str.all); end if; Adt_Next_Chars := Adt_Next_Chars.Succ; end loop; if Adt_Next_Chars.Flag_Line then Text_Io.Put_Line(Result_Fp, Adt_Next_Chars.Str.all); else Text_Io.Put(Result_Fp, Adt_Next_Chars.Str.all); end if; Text_Io.Close(Result_Fp); end Dump_File; procedure Init_Line (Str : String) is begin Adt_First_Chars := new Audit_Chars'(new String'(Str), True, null, null); Adt_Next_Chars := Adt_First_Chars; end Init_Line; procedure Put_Line (Str : String) is Line_Length : Natural; begin if Cur_Line_Length + Str'Length > Max_Line_Length then Adt_Next_Chars.succ := new Audit_Chars'(new String'(Str(Str'First .. Str'First + Max_Line_Length - Cur_Line_Length - 2) & '\'), True, null, Adt_Next_Chars); Adt_Next_Chars := Adt_Next_Chars.Succ; Line_Length := Cur_Line_Length; Cur_Line_Length := 0; Put_Line(Str(Str'First + Max_Line_Length - Line_Length - 1 .. Str'Last)); else Adt_Next_Chars.succ := new Audit_Chars'(new String'(Str), True, null, Adt_Next_Chars); Adt_Next_Chars := Adt_Next_Chars.Succ; end if; Cur_Line_Length := 0; end Put_Line; procedure Remove_Line is begin Adt_Next_Chars := Adt_Next_Chars.Prec; end Remove_Line; function Remove_Line return String is begin Adt_Next_Chars := Adt_Next_Chars.Prec; return Adt_Next_Chars.Succ.Str.all; end; procedure Put (Str : String) is begin if Cur_Line_Length + Str'Length >= Max_Line_Length then Adt_Next_Chars.succ := new Audit_Chars'(new String'("\"), True, null, Adt_Next_Chars); Adt_Next_Chars := Adt_Next_Chars.Succ; Adt_Next_Chars.succ := new Audit_Chars'(new String'(Str), False, null, Adt_Next_Chars); Adt_Next_Chars := Adt_Next_Chars.Succ; Cur_Line_Length := Str'Length; else Adt_Next_Chars.succ := new Audit_Chars'(new String'(Str), False, null, Adt_Next_Chars); Adt_Next_Chars := Adt_Next_Chars.Succ; Cur_Line_Length := Cur_Line_Length + Str'Length; end if; end Put; procedure Close is begin Text_Io.Close(Result_Fp); exception when Text_Io.Status_Error => null; end Close; function Get_Cov return Boolean is File_Name: constant String := "instrum.dyn"; Line : String(1 .. Max_Line_Length + 1); Last : Natural; begin Text_Io.Open(Result_Fp, Text_Io.In_File, File_Name); Text_Io.Get_Line(Result_Fp, Line, Last); if Line(1..Last) /= "" then Text_Io.Put_Line("BAD INSTRUM.DYN FILE"); Close; return False; else return True; end if; exception when Text_Io.Status_Error | Text_Io.Name_Error | Text_Io.Use_Error => Close; return(False); end Get_Cov; procedure Start is Now: Time := Clock; begin Init_Line(""); Put_Line("*NA*"); Put_Line("Application_Courante"); Put_Line("*CV*"); Put_Line("CURRENT_SUITE"); Put_Line("*CM*"); Put_Line("CURRENT_SUITE"); Put_Line("TEST_1 " & Format_Time(Now)); Put_Line("*MO*"); Put_Line("TEST_1 " & Format_Time(Now)); Cur_Test_Num := 1; end; function Get_Test_Num(Str : String) return Natural is begin if Str(1..5) = "TEST_" then for I in 6 .. Str'Length loop if Str(I) = ' ' then return Positive'Value(Str(6..I)); end if; end loop; end if; return 0; exception when Constraint_Error => return 0; end Get_Test_Num; procedure Purge_Last_Test (Test_Num : Natural) is Line : String(1 .. Max_Line_Length + 1); Last : Natural := 0; Test_Str : constant String := "TEST_" & Trunc_Image(Natural'Image(Test_Num)); Str_Length : constant Natural := Test_Str'Length; begin while not Text_Io.End_Of_File(Result_Fp) loop Text_Io.Get_Line(Result_Fp, Line, Last); exit when (Last >= Str_Length) and then (Line(1..Str_Length) = Test_Str); Put_Line(Line(1..Last)); end loop; while not Text_Io.End_Of_File(Result_Fp) loop Text_Io.Get_Line(Result_Fp, Line, Last); exit when Line(1..Last) = "*FI*"; end loop; end Purge_Last_Test; procedure Start_Append is Line : String(1 .. Max_Line_Length + 1); Last : Natural := 0; Now: Time := Clock; begin Init_Line(""); while not Text_Io.End_Of_File(Result_Fp) loop Text_Io.Get_Line(Result_Fp, Line, Last); exit when Line(1..Last) = "*MO*"; Put_Line(Line(1..Last)); end loop; if Cur_Test_Num > 0 then -- a test has already been dumped Remove_Line; Put_Line("TEST_" & Trunc_Image(Natural'Image(Cur_Test_Num)) & " " & Format_Time(Now)); Put_Line(Line(1..Last)); Purge_Last_Test(Cur_Test_Num); Put_Line("TEST_" & Trunc_Image(Natural'Image(Cur_Test_Num)) & " " & Format_Time(Now)); else Cur_Test_Num := Get_Test_Num(Adt_Next_Chars.Str.all) + 1; Put_Line("TEST_" & Trunc_Image(Natural'Image(Cur_Test_Num)) & " " & Format_Time(Now)); Put_Line(Line(1..Last)); while not Text_Io.End_Of_File(Result_Fp) loop Text_Io.Get_Line(Result_Fp, Line, Last); exit when Line(1..Last) = "*FI*"; Put_Line(Line(1..Last)); end loop; Put_line("*MO*"); Put_Line("TEST_" & Trunc_Image(Natural'Image(Cur_Test_Num)) & " " & Format_Time(Now)); end if; end Start_Append; procedure Dump_Function_Nm (Func : Audit_Func_Acc) is begin Put(Trunc_Image(Positive'Image(Func.Func_Id))); Put_Line(" " & Func.Func_Name.all & " " & Func.Func_Date.all); end Dump_Function_Nm; procedure Dump_Function_Cc (Func : Audit_Func_Acc) is begin if (Func.Nb_Bran > 0) then Put(Trunc_Image(Positive'Image(Func.Func_Id))); for I in 0 .. Func.Nb_Bran - 1 loop Put(Natural'Image(Func.Branches(I))); end loop; Put_Line(""); end if; end Dump_Function_Cc; procedure Dump_Function_Mc (Func : Audit_Func_Acc) is Nb_Vect : Natural; begin for I in 1 .. Func.Nb_Mcdcs loop Put(Trunc_Image(Positive'Image(Func.Func_Id))); if (Func.Mcdcs(I) = null) then Put(" 0 0"); else Nb_Vect := Func.Mcdcs(I).Nb_Vect_T; Put(Natural'Image(Nb_Vect)); if (Nb_Vect > 0) then Put(" "); for J in 1 .. Nb_Vect loop Put(Func.Mcdcs(I).Vects_T(J).all); end loop; end if; Nb_Vect := Func.Mcdcs(I).Nb_Vect_F; Put(Natural'Image(Nb_Vect)); if (Nb_Vect > 0) then Put(" "); for J in 1 .. Nb_Vect loop Put(Func.Mcdcs(I).Vects_F(J).all); end loop; end if; end if; Put_Line(Positive'Image(I)); end loop; end Dump_Function_Mc; procedure Dump_Function_Ca (Func : Audit_Func_Acc) is begin for I in 1 .. Func.Nb_Calls loop Put(Trunc_Image(Positive'Image(Func.Func_Id)) & Positive'Image(Func.Calls(I).Called_Func_Id) & Natural'Image(Func.Calls(I).Nb_Calls) & " "); end loop; end Dump_Function_Ca; procedure Dump_Nm is begin Put_Line(".NM."); for I in 1 .. Adt_Max_Func loop if Adt_Funcs(I) /= null then Dump_Function_Nm(Adt_Funcs(I)); end if; end loop; end Dump_Nm; procedure Dump_Cc is begin Put_Line(".CC."); for I in 1 .. Adt_Max_Func loop if Adt_Funcs(I) /= null then Dump_Function_Cc(Adt_Funcs(I)); end if; end loop; end Dump_Cc; procedure Dump_Mc is begin Put_Line(".MC."); for I in 1 .. Adt_Max_Func loop if Adt_Funcs(I) /= null then Dump_Function_Mc(Adt_Funcs(I)); end if; end loop; end Dump_Mc; procedure Dump_Ca is begin Put_Line(".CA."); for I in 1 .. Adt_Max_Func loop if Adt_Funcs(I) /= null then Dump_Function_Ca(Adt_Funcs(I)); end if; end loop; Put_Line(""); end Dump_Ca; function Code_Str (Str : String) return String is New_Str : String(1 .. 2*Str'Length); Cnt : Natural := 0; begin for I in 1 .. Str'Length loop Cnt := Cnt + 1; New_Str(Cnt) := Str(I); if Str(I) = '\' then Cnt := Cnt + 1; New_Str(Cnt) := '\'; end if; end loop; return New_Str(1 .. Cnt); end Code_Str; function Get_Test_Line (Test_Num : Natural) return String is begin return ("{" & Trunc_Image(Natural'Image(Test_Num)) & ", ""TEST_" & Trunc_Image(Natural'Image(Test_Num)) & """, """ & Code_Str("YourCommandHere") & """, """", """", """ & Code_Str(Adt_Data.all) & """, 0, f}"); end Get_Test_Line; procedure Stop_Purge (Test_Num : Natural) is Line : String(1 .. Max_Line_Length + 1); Last : Natural := 0; Test_Str : constant String := "{" & Trunc_Image(Natural'Image(Test_Num)); Str_Length : constant Natural := Test_Str'Length; begin Put_Line("*FI*"); while not Text_Io.End_Of_File(Result_Fp) loop Text_Io.Get_Line(Result_Fp, Line, Last); exit when (Last >= Str_Length) and then (Line(1..Str_Length) = Test_Str); Put_Line(Line(1..Last)); end loop; Put_Line(Get_Test_Line(Test_Num)); Put_Line("}"); Put_Line("END"); Text_Io.Close(Result_Fp); end Stop_Purge; procedure Stop_Append (Test_Num : Natural) is Line : String(1 .. Max_Line_Length + 1); Last : Natural := 0; begin Put_Line("*FI*"); while not Text_Io.End_Of_File(Result_Fp) loop Text_Io.Get_Line(Result_Fp, Line, Last); exit when Line(1..Last) = "END"; Put_Line(Line(1..Last)); end loop; Remove_Line; Put_Line(Remove_Line & ","); Put_Line(Get_Test_Line(Test_Num)); Put_Line("}"); Put_Line("END"); Text_Io.Close(Result_Fp); end Stop_Append; procedure Stop is begin Put_Line("*FI*"); Put_Line("Entities_Definitions DEFINITIONS ::= BEGIN"); Put_Line("test_description ::= SEQUENCE OF {"); Put_Line(" SEQUENCE {"); Put_Line(" key integer,"); Put_Line(" name string,"); Put_Line(" command string,"); Put_Line(" parameters string,"); Put_Line(" description string,"); Put_Line(" working_dir string,"); Put_Line(" exec_status integer,"); Put_Line(" exec_16bits boolean"); Put_Line(" }"); Put_Line("}"); Put_Line("test_description ::= {"); Put_Line(Get_Test_Line(1)); Put_Line("}"); Put_Line("END"); end Stop; function Audit_Start return Boolean is begin null; end Audit_Start; procedure Audit_Stop is Flag_Cov : Boolean := False; Test_Num : Natural := Cur_Test_Num; begin if Get_Cov then Flag_Cov := True; Start_Append; else Start; end if; Dump_Nm; Dump_Cc; Put_Line(".SC."); Dump_Mc; Dump_Ca; Put_Line(".SA."); if Flag_Cov then if Test_Num > 0 then Stop_Purge(Cur_Test_Num); else Stop_Append(Cur_Test_Num); end if; else Stop; end if; Dump_File; exception when Text_Io.Status_Error => Put_Line("STATUS ERROR"); when Text_Io.Name_Error => Put_Line("NAME ERROR"); when Text_Io.Device_Error => Put_Line("DEVICE ERROR"); when Text_Io.End_Error => Put_Line("END ERROR"); when Text_Io.Data_Error => Put_Line("DATA ERROR"); when Text_Io.Layout_Error => Put_Line("LAYOUT ERROR"); when others => Put_Line("UNKNOWN ERROR"); end; begin Adt_Dummy := Audit_Start; end Audit_Instrum;