File : xsinfo.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                          GNAT SYSTEM UTILITIES                           --
   4 --                                                                          --
   5 --                               X S I N F O                                --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 1992-2011, 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 --  Program to construct C header file sinfo.h (C version of sinfo.ads spec,
  27 --  for use by Gigi, contains all definitions and access functions, but does
  28 --  not contain set procedures, since Gigi never modifies the GNAT tree)
  29 
  30 --    Input files:
  31 
  32 --       sinfo.ads     Spec of Sinfo package
  33 
  34 --    Output files:
  35 
  36 --       sinfo.h       Corresponding c header file
  37 
  38 --  An optional argument allows the specification of an output file name to
  39 --  override the default sinfo.h file name for the generated output file.
  40 
  41 with Ada.Command_Line;              use Ada.Command_Line;
  42 with Ada.Strings.Unbounded;         use Ada.Strings.Unbounded;
  43 with Ada.Strings.Unbounded.Text_IO; use Ada.Strings.Unbounded.Text_IO;
  44 with Ada.Text_IO;                   use Ada.Text_IO;
  45 
  46 with GNAT.Spitbol;                  use GNAT.Spitbol;
  47 with GNAT.Spitbol.Patterns;         use GNAT.Spitbol.Patterns;
  48 
  49 with CSinfo;
  50 
  51 procedure XSinfo is
  52 
  53    Done : exception;
  54    Err  : exception;
  55 
  56    A         : VString := Nul;
  57    Arg       : VString := Nul;
  58    Comment   : VString := Nul;
  59    Line      : VString := Nul;
  60    N         : VString := Nul;
  61    N1, N2    : VString := Nul;
  62    Nam       : VString := Nul;
  63    Rtn       : VString := Nul;
  64    Term      : VString := Nul;
  65 
  66    InS   : File_Type;
  67    Ofile : File_Type;
  68 
  69    wsp     : constant Pattern := Span (' ' & ASCII.HT);
  70    Wsp_For : constant Pattern := wsp & "for";
  71    Is_Cmnt : constant Pattern := wsp & "--";
  72    Typ_Nod : constant Pattern := wsp * A & "type Node_Kind is";
  73    Get_Nam : constant Pattern := wsp * A & "N_" &  Break (",)") * Nam
  74                                  & Len (1) * Term;
  75    Sub_Typ : constant Pattern := wsp * A & "subtype " &  Break (' ') * N;
  76    No_Cont : constant Pattern := wsp & Break (' ') * N1
  77                                  & " .. " & Break (';') * N2;
  78    Cont_N1 : constant Pattern := wsp & Break (' ') * N1 & " .." & Rpos (0);
  79    Cont_N2 : constant Pattern := Span (' ') & Break (';') * N2;
  80    Is_Func : constant Pattern := wsp * A & "function " & Rest * Nam;
  81    Get_Arg : constant Pattern := wsp & "(N : " & Break (')') * Arg
  82                                  & ") return " & Break (';') * Rtn
  83                                  & ';' & wsp & "--" & wsp & Rest * Comment;
  84 
  85    NKV : Natural;
  86 
  87    M : Match_Result;
  88 
  89    procedure Getline;
  90    --  Get non-comment, non-blank line. Also skips "for " rep clauses
  91 
  92    -------------
  93    -- Getline --
  94    -------------
  95 
  96    procedure Getline is
  97    begin
  98       loop
  99          Line := Get_Line (InS);
 100 
 101          if Line /= ""
 102            and then not Match (Line, Wsp_For)
 103            and then not Match (Line, Is_Cmnt)
 104          then
 105             return;
 106 
 107          elsif Match (Line, "   --  End functions (note") then
 108             raise Done;
 109          end if;
 110       end loop;
 111    end Getline;
 112 
 113 --  Start of processing for XSinfo
 114 
 115 begin
 116    --  First run CSinfo to check for errors. Note that CSinfo is also a
 117    --  stand-alone program that can be run separately.
 118 
 119    CSinfo;
 120 
 121    Set_Exit_Status (1);
 122    Anchored_Mode := True;
 123 
 124    if Argument_Count > 0 then
 125       Create (Ofile, Out_File, Argument (1));
 126    else
 127       Create (Ofile, Out_File, "sinfo.h");
 128    end if;
 129 
 130    Open (InS, In_File, "sinfo.ads");
 131 
 132    --  Write header to output file
 133 
 134    loop
 135       Line := Get_Line (InS);
 136       exit when Line = "";
 137 
 138       Match
 139         (Line,
 140          "--                                 S p e c       ",
 141          "--                              C Header File    ");
 142 
 143       Match (Line, "--", "/*");
 144       Match (Line, Rtab (2) * A & "--", M);
 145       Replace (M, A & "*/");
 146       Put_Line (Ofile, Line);
 147    end loop;
 148 
 149    --  Skip to package line
 150 
 151    loop
 152       Getline;
 153       exit when Match (Line, "package");
 154    end loop;
 155 
 156    --  Skip to first node kind line
 157 
 158    loop
 159       Getline;
 160       exit when Match (Line, Typ_Nod);
 161       Put_Line (Ofile, Line);
 162    end loop;
 163 
 164    Put_Line (Ofile, "");
 165 
 166    Put_Line (Ofile, "#ifdef __cplusplus");
 167    Put_Line (Ofile, "extern ""C"" {");
 168    Put_Line (Ofile, "#endif");
 169 
 170    NKV := 0;
 171 
 172    --  Loop through node kind codes
 173 
 174    loop
 175       Getline;
 176 
 177       if Match (Line, Get_Nam) then
 178          Put_Line (Ofile, A & "#define N_" & Nam & ' ' & NKV);
 179          NKV := NKV + 1;
 180          exit when not Match (Term, ",");
 181 
 182       else
 183          Put_Line (Ofile, Line);
 184       end if;
 185    end loop;
 186 
 187    Put_Line (Ofile, "");
 188    Put_Line (Ofile, A & "#define Number_Node_Kinds " & NKV);
 189 
 190    --  Loop through subtype declarations
 191 
 192    loop
 193       Getline;
 194 
 195       if not Match (Line, Sub_Typ) then
 196          exit when Match (Line, "   function");
 197          Put_Line (Ofile, Line);
 198 
 199       else
 200          Put_Line (Ofile, A & "SUBTYPE (" & N & ", Node_Kind, ");
 201          Getline;
 202 
 203          --  Normal case
 204 
 205          if Match (Line, No_Cont) then
 206             Put_Line (Ofile, A & "   " & N1 & ", " & N2 & ')');
 207 
 208          --  Continuation case
 209 
 210          else
 211             if not Match (Line, Cont_N1) then
 212                raise Err;
 213             end if;
 214 
 215             Getline;
 216 
 217             if not Match (Line, Cont_N2) then
 218                raise Err;
 219             end if;
 220 
 221             Put_Line (Ofile,  A & "   " & N1 & ',');
 222             Put_Line (Ofile,  A & "   " & N2 & ')');
 223          end if;
 224       end if;
 225    end loop;
 226 
 227    --  Loop through functions. Note that this loop is terminated by
 228    --  the call to Getfile encountering the end of functions sentinel
 229 
 230    loop
 231       if Match (Line, Is_Func) then
 232          Getline;
 233             if not Match (Line, Get_Arg) then
 234                raise Err;
 235             end if;
 236          Put_Line
 237            (Ofile,
 238             A &  "INLINE " & Rpad (Rtn, 9)
 239             & ' ' & Rpad (Nam, 30) & " (" & Arg & " N)");
 240 
 241          Put_Line (Ofile,  A & "   { return " & Comment & " (N); }");
 242 
 243       else
 244          Put_Line (Ofile, Line);
 245       end if;
 246 
 247       Getline;
 248    end loop;
 249 
 250    --  Can't get here since above loop only left via raise
 251 
 252 exception
 253    when Done =>
 254       Close (InS);
 255       Put_Line (Ofile, "");
 256       Put_Line (Ofile, "#ifdef __cplusplus");
 257       Put_Line (Ofile, "}");
 258       Put_Line (Ofile, "#endif");
 259       Close (Ofile);
 260       Set_Exit_Status (0);
 261 
 262 end XSinfo;