view gcc/ada/spark_xrefs_test.adb @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children
line wrap: on
line source

------------------------------------------------------------------------------
--                                                                          --
--                          GNAT SYSTEM UTILITIES                           --
--                                                                          --
--                     S P A R K _ X R E F S _ T E S T                      --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 2011-2013, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

--  This utility program is used to test proper operation of the
--  Get_SPARK_Xrefs and Put_SPARK_Xrefs units. To run it, compile any source
--  file with switch -gnatd.E or -gnatd.F to get an ALI file file.ALI
--  containing SPARK information. Then run this utility using:

--     spark_xrefs_test file.ali

--  This test will read the SPARK cross-reference information from the ALI
--  file, and use Get_SPARK_Xrefs to store this in binary form in the internal
--  tables in SPARK_Xrefs. Then Put_SPARK_Xrefs is used to write the
--  information from these tables back into text form. This output is compared
--  with the original SPARK cross-reference information in the ALI file and the
--  two should be identical. If not an error message is output.

with Get_SPARK_Xrefs;
with Put_SPARK_Xrefs;

with SPARK_Xrefs;           use SPARK_Xrefs;
with Types;                 use Types;

with Ada.Command_Line;      use Ada.Command_Line;
with Ada.Streams;           use Ada.Streams;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Text_IO;

with GNAT.OS_Lib;           use GNAT.OS_Lib;

procedure SPARK_Xrefs_Test is
   Infile    : File_Type;
   Name1     : String_Access;
   Outfile_1 : File_Type;
   Name2     : String_Access;
   Outfile_2 : File_Type;
   C         : Character;

   Stop : exception;
   --  Terminate execution

   Diff_Exec   : constant String_Access := Locate_Exec_On_Path ("diff");
   Diff_Result : Integer;

   use ASCII;

begin
   if Argument_Count /= 1 then
      Ada.Text_IO.Put_Line ("Usage: spark_xrefs_test FILE.ali");
      raise Stop;
   end if;

   Name1 := new String'(Argument (1) & ".1");
   Name2 := new String'(Argument (1) & ".2");

   Open   (Infile,    In_File,  Argument (1));
   Create (Outfile_1, Out_File, Name1.all);
   Create (Outfile_2, Out_File, Name2.all);

   --  Read input file till we get to first 'F' line

   Process : declare
      Output_Col : Positive := 1;

      function Get_Char (F : File_Type) return Character;
      --  Read one character from specified  file

      procedure Put_Char (F : File_Type; C : Character);
      --  Write one character to specified file

      function Get_Output_Col return Positive;
      --  Return current column in output file, where each line starts at
      --  column 1 and terminate with LF, and HT is at columns 1, 9, etc.
      --  All output is supposed to be carried through Put_Char.

      --------------
      -- Get_Char --
      --------------

      function Get_Char (F : File_Type) return Character is
         Item : Stream_Element_Array (1 .. 1);
         Last : Stream_Element_Offset;

      begin
         Read (F, Item, Last);

         if Last /= 1 then
            return Types.EOF;
         else
            return Character'Val (Item (1));
         end if;
      end Get_Char;

      --------------------
      -- Get_Output_Col --
      --------------------

      function Get_Output_Col return Positive is
      begin
         return Output_Col;
      end Get_Output_Col;

      --------------
      -- Put_Char --
      --------------

      procedure Put_Char (F : File_Type; C : Character) is
         Item : Stream_Element_Array (1 .. 1);

      begin
         if C /= CR and then C /= EOF then
            if C = LF then
               Output_Col := 1;
            elsif C = HT then
               Output_Col := ((Output_Col + 6) / 8) * 8 + 1;
            else
               Output_Col := Output_Col + 1;
            end if;

            Item (1) := Character'Pos (C);
            Write (F, Item);
         end if;
      end Put_Char;

      --  Subprograms used by Get_SPARK_Xrefs (these also copy the output to
      --  Outfile_1 for later comparison with the output generated by
      --  Put_SPARK_Xrefs).

      function  Getc  return Character;
      function  Nextc return Character;
      procedure Skipc;

      ----------
      -- Getc --
      ----------

      function Getc  return Character is
         C : Character;
      begin
         C := Get_Char (Infile);
         Put_Char (Outfile_1, C);
         return C;
      end Getc;

      -----------
      -- Nextc --
      -----------

      function Nextc return Character is
         C : Character;

      begin
         C := Get_Char (Infile);

         if C /= EOF then
            Set_Index (Infile, Index (Infile) - 1);
         end if;

         return C;
      end Nextc;

      -----------
      -- Skipc --
      -----------

      procedure Skipc is
         C : Character;
         pragma Unreferenced (C);
      begin
         C := Getc;
      end Skipc;

      --  Subprograms used by Put_SPARK_Xrefs, which write information to
      --  Outfile_2.

      function Write_Info_Col return Positive;
      procedure Write_Info_Char (C : Character);
      procedure Write_Info_Initiate (Key : Character);
      procedure Write_Info_Nat (N : Nat);
      procedure Write_Info_Terminate;

      --------------------
      -- Write_Info_Col --
      --------------------

      function Write_Info_Col return Positive is
      begin
         return Get_Output_Col;
      end Write_Info_Col;

      ---------------------
      -- Write_Info_Char --
      ---------------------

      procedure Write_Info_Char (C : Character) is
      begin
         Put_Char (Outfile_2, C);
      end Write_Info_Char;

      -------------------------
      -- Write_Info_Initiate --
      -------------------------

      procedure Write_Info_Initiate (Key : Character) is
      begin
         Write_Info_Char (Key);
      end Write_Info_Initiate;

      --------------------
      -- Write_Info_Nat --
      --------------------

      procedure Write_Info_Nat (N : Nat) is
      begin
         if N > 9 then
            Write_Info_Nat (N / 10);
         end if;

         Write_Info_Char (Character'Val (48 + N mod 10));
      end Write_Info_Nat;

      --------------------------
      -- Write_Info_Terminate --
      --------------------------

      procedure Write_Info_Terminate is
      begin
         Write_Info_Char (LF);
      end Write_Info_Terminate;

      --  Local instantiations of Put_SPARK_Xrefs and Get_SPARK_Xrefs

      procedure Get_SPARK_Xrefs_Info is new Get_SPARK_Xrefs;
      procedure Put_SPARK_Xrefs_Info is new Put_SPARK_Xrefs;

   --  Start of processing for Process

   begin
      --  Loop to skip till first 'F' line

      loop
         C := Get_Char (Infile);

         if C = EOF then
            raise Stop;

         elsif C = LF or else C = CR then
            loop
               C := Get_Char (Infile);
               exit when C /= LF and then C /= CR;
            end loop;

            exit when C = 'F';
         end if;
      end loop;

      --  Position back to initial 'F' of first 'F' line

      Set_Index (Infile, Index (Infile) - 1);

      --  Read SPARK cross-reference information to internal SPARK tables, also
      --  copying SPARK xrefs info to Outfile_1.

      Initialize_SPARK_Tables;
      Get_SPARK_Xrefs_Info;

      --  Write SPARK cross-reference information from internal SPARK tables to
      --  Outfile_2.

      Put_SPARK_Xrefs_Info;

      --  Junk blank line (see comment at end of Lib.Writ)

      Write_Info_Terminate;

      --  Flush to disk

      Close (Outfile_1);
      Close (Outfile_2);

      --  Now Outfile_1 and Outfile_2 should be identical

      Diff_Result :=
        Spawn (Diff_Exec.all,
               Argument_String_To_List
                 ("-u " & Name1.all & " " & Name2.all).all);

      if Diff_Result /= 0 then
         Ada.Text_IO.Put_Line ("diff(1) exit status" & Diff_Result'Img);
      end if;

      OS_Exit (Diff_Result);

   end Process;

exception
   when Stop =>
      null;
end SPARK_Xrefs_Test;