File : spark_xrefs_test.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                          GNAT SYSTEM UTILITIES                           --
   4 --                                                                          --
   5 --                     S P A R K _ X R E F S _ T E S T                      --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 2011-2013, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  17 -- for  more details.  You should have  received  a copy of the GNU General --
  18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
  19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
  20 --                                                                          --
  21 -- GNAT was originally developed  by the GNAT team at  New York University. --
  22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  23 --                                                                          --
  24 ------------------------------------------------------------------------------
  25 
  26 --  This utility program is used to test proper operation of the
  27 --  Get_SPARK_Xrefs and Put_SPARK_Xrefs units. To run it, compile any source
  28 --  file with switch -gnatd.E or -gnatd.F to get an ALI file file.ALI
  29 --  containing SPARK information. Then run this utility using:
  30 
  31 --     spark_xrefs_test file.ali
  32 
  33 --  This test will read the SPARK cross-reference information from the ALI
  34 --  file, and use Get_SPARK_Xrefs to store this in binary form in the internal
  35 --  tables in SPARK_Xrefs. Then Put_SPARK_Xrefs is used to write the
  36 --  information from these tables back into text form. This output is compared
  37 --  with the original SPARK cross-reference information in the ALI file and the
  38 --  two should be identical. If not an error message is output.
  39 
  40 with Get_SPARK_Xrefs;
  41 with Put_SPARK_Xrefs;
  42 
  43 with SPARK_Xrefs;           use SPARK_Xrefs;
  44 with Types;                 use Types;
  45 
  46 with Ada.Command_Line;      use Ada.Command_Line;
  47 with Ada.Streams;           use Ada.Streams;
  48 with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
  49 with Ada.Text_IO;
  50 
  51 with GNAT.OS_Lib;           use GNAT.OS_Lib;
  52 
  53 procedure SPARK_Xrefs_Test is
  54    Infile    : File_Type;
  55    Name1     : String_Access;
  56    Outfile_1 : File_Type;
  57    Name2     : String_Access;
  58    Outfile_2 : File_Type;
  59    C         : Character;
  60 
  61    Stop : exception;
  62    --  Terminate execution
  63 
  64    Diff_Exec   : constant String_Access := Locate_Exec_On_Path ("diff");
  65    Diff_Result : Integer;
  66 
  67    use ASCII;
  68 
  69 begin
  70    if Argument_Count /= 1 then
  71       Ada.Text_IO.Put_Line ("Usage: spark_xrefs_test FILE.ali");
  72       raise Stop;
  73    end if;
  74 
  75    Name1 := new String'(Argument (1) & ".1");
  76    Name2 := new String'(Argument (1) & ".2");
  77 
  78    Open   (Infile,    In_File,  Argument (1));
  79    Create (Outfile_1, Out_File, Name1.all);
  80    Create (Outfile_2, Out_File, Name2.all);
  81 
  82    --  Read input file till we get to first 'F' line
  83 
  84    Process : declare
  85       Output_Col : Positive := 1;
  86 
  87       function Get_Char (F : File_Type) return Character;
  88       --  Read one character from specified  file
  89 
  90       procedure Put_Char (F : File_Type; C : Character);
  91       --  Write one character to specified file
  92 
  93       function Get_Output_Col return Positive;
  94       --  Return current column in output file, where each line starts at
  95       --  column 1 and terminate with LF, and HT is at columns 1, 9, etc.
  96       --  All output is supposed to be carried through Put_Char.
  97 
  98       --------------
  99       -- Get_Char --
 100       --------------
 101 
 102       function Get_Char (F : File_Type) return Character is
 103          Item : Stream_Element_Array (1 .. 1);
 104          Last : Stream_Element_Offset;
 105 
 106       begin
 107          Read (F, Item, Last);
 108 
 109          if Last /= 1 then
 110             return Types.EOF;
 111          else
 112             return Character'Val (Item (1));
 113          end if;
 114       end Get_Char;
 115 
 116       --------------------
 117       -- Get_Output_Col --
 118       --------------------
 119 
 120       function Get_Output_Col return Positive is
 121       begin
 122          return Output_Col;
 123       end Get_Output_Col;
 124 
 125       --------------
 126       -- Put_Char --
 127       --------------
 128 
 129       procedure Put_Char (F : File_Type; C : Character) is
 130          Item : Stream_Element_Array (1 .. 1);
 131 
 132       begin
 133          if C /= CR and then C /= EOF then
 134             if C = LF then
 135                Output_Col := 1;
 136             elsif C = HT then
 137                Output_Col := ((Output_Col + 6) / 8) * 8 + 1;
 138             else
 139                Output_Col := Output_Col + 1;
 140             end if;
 141 
 142             Item (1) := Character'Pos (C);
 143             Write (F, Item);
 144          end if;
 145       end Put_Char;
 146 
 147       --  Subprograms used by Get_SPARK_Xrefs (these also copy the output to
 148       --  Outfile_1 for later comparison with the output generated by
 149       --  Put_SPARK_Xrefs).
 150 
 151       function  Getc  return Character;
 152       function  Nextc return Character;
 153       procedure Skipc;
 154 
 155       ----------
 156       -- Getc --
 157       ----------
 158 
 159       function Getc  return Character is
 160          C : Character;
 161       begin
 162          C := Get_Char (Infile);
 163          Put_Char (Outfile_1, C);
 164          return C;
 165       end Getc;
 166 
 167       -----------
 168       -- Nextc --
 169       -----------
 170 
 171       function Nextc return Character is
 172          C : Character;
 173 
 174       begin
 175          C := Get_Char (Infile);
 176 
 177          if C /= EOF then
 178             Set_Index (Infile, Index (Infile) - 1);
 179          end if;
 180 
 181          return C;
 182       end Nextc;
 183 
 184       -----------
 185       -- Skipc --
 186       -----------
 187 
 188       procedure Skipc is
 189          C : Character;
 190          pragma Unreferenced (C);
 191       begin
 192          C := Getc;
 193       end Skipc;
 194 
 195       --  Subprograms used by Put_SPARK_Xrefs, which write information to
 196       --  Outfile_2.
 197 
 198       function Write_Info_Col return Positive;
 199       procedure Write_Info_Char (C : Character);
 200       procedure Write_Info_Initiate (Key : Character);
 201       procedure Write_Info_Nat (N : Nat);
 202       procedure Write_Info_Terminate;
 203 
 204       --------------------
 205       -- Write_Info_Col --
 206       --------------------
 207 
 208       function Write_Info_Col return Positive is
 209       begin
 210          return Get_Output_Col;
 211       end Write_Info_Col;
 212 
 213       ---------------------
 214       -- Write_Info_Char --
 215       ---------------------
 216 
 217       procedure Write_Info_Char (C : Character) is
 218       begin
 219          Put_Char (Outfile_2, C);
 220       end Write_Info_Char;
 221 
 222       -------------------------
 223       -- Write_Info_Initiate --
 224       -------------------------
 225 
 226       procedure Write_Info_Initiate (Key : Character) is
 227       begin
 228          Write_Info_Char (Key);
 229       end Write_Info_Initiate;
 230 
 231       --------------------
 232       -- Write_Info_Nat --
 233       --------------------
 234 
 235       procedure Write_Info_Nat (N : Nat) is
 236       begin
 237          if N > 9 then
 238             Write_Info_Nat (N / 10);
 239          end if;
 240 
 241          Write_Info_Char (Character'Val (48 + N mod 10));
 242       end Write_Info_Nat;
 243 
 244       --------------------------
 245       -- Write_Info_Terminate --
 246       --------------------------
 247 
 248       procedure Write_Info_Terminate is
 249       begin
 250          Write_Info_Char (LF);
 251       end Write_Info_Terminate;
 252 
 253       --  Local instantiations of Put_SPARK_Xrefs and Get_SPARK_Xrefs
 254 
 255       procedure Get_SPARK_Xrefs_Info is new Get_SPARK_Xrefs;
 256       procedure Put_SPARK_Xrefs_Info is new Put_SPARK_Xrefs;
 257 
 258    --  Start of processing for Process
 259 
 260    begin
 261       --  Loop to skip till first 'F' line
 262 
 263       loop
 264          C := Get_Char (Infile);
 265 
 266          if C = EOF then
 267             raise Stop;
 268 
 269          elsif C = LF or else C = CR then
 270             loop
 271                C := Get_Char (Infile);
 272                exit when C /= LF and then C /= CR;
 273             end loop;
 274 
 275             exit when C = 'F';
 276          end if;
 277       end loop;
 278 
 279       --  Position back to initial 'F' of first 'F' line
 280 
 281       Set_Index (Infile, Index (Infile) - 1);
 282 
 283       --  Read SPARK cross-reference information to internal SPARK tables, also
 284       --  copying SPARK xrefs info to Outfile_1.
 285 
 286       Initialize_SPARK_Tables;
 287       Get_SPARK_Xrefs_Info;
 288 
 289       --  Write SPARK cross-reference information from internal SPARK tables to
 290       --  Outfile_2.
 291 
 292       Put_SPARK_Xrefs_Info;
 293 
 294       --  Junk blank line (see comment at end of Lib.Writ)
 295 
 296       Write_Info_Terminate;
 297 
 298       --  Flush to disk
 299 
 300       Close (Outfile_1);
 301       Close (Outfile_2);
 302 
 303       --  Now Outfile_1 and Outfile_2 should be identical
 304 
 305       Diff_Result :=
 306         Spawn (Diff_Exec.all,
 307                Argument_String_To_List
 308                  ("-u " & Name1.all & " " & Name2.all).all);
 309 
 310       if Diff_Result /= 0 then
 311          Ada.Text_IO.Put_Line ("diff(1) exit status" & Diff_Result'Img);
 312       end if;
 313 
 314       OS_Exit (Diff_Result);
 315 
 316    end Process;
 317 
 318 exception
 319    when Stop =>
 320       null;
 321 end SPARK_Xrefs_Test;