OSDN Git Service

2007-12-06 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / 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-2007, 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 --  Note: this program assumes that sinfo.ads has passed the error checks
39 --  which are carried out by the CSinfo utility, so it does not duplicate
40 --  these checks and assumes the soruce is correct.
41
42 --  An optional argument allows the specification of an output file name to
43 --  override the default sinfo.h file name for the generated output file.
44
45 with Ada.Command_Line;              use Ada.Command_Line;
46 with Ada.Strings.Unbounded;         use Ada.Strings.Unbounded;
47 with Ada.Strings.Unbounded.Text_IO; use Ada.Strings.Unbounded.Text_IO;
48 with Ada.Text_IO;                   use Ada.Text_IO;
49
50 with GNAT.Spitbol;                  use GNAT.Spitbol;
51 with GNAT.Spitbol.Patterns;         use GNAT.Spitbol.Patterns;
52
53 procedure XSinfo is
54
55    Done : exception;
56    Err  : exception;
57
58    pragma Warnings (Off);
59    --  Below variables are referenced using * operator
60
61    A         : VString := Nul;
62    Arg       : VString := Nul;
63    Comment   : VString := Nul;
64    Line      : VString := Nul;
65    N         : VString := Nul;
66    N1, N2    : VString := Nul;
67    Nam       : VString := Nul;
68    Rtn       : VString := Nul;
69    Term      : VString := Nul;
70
71    pragma Warnings (On);
72
73    InS       : File_Type;
74    Ofile     : File_Type;
75
76    wsp     : constant Pattern := Span (' ' & ASCII.HT);
77    Wsp_For : constant Pattern := wsp & "for";
78    Is_Cmnt : constant Pattern := wsp & "--";
79    Typ_Nod : constant Pattern := wsp * A & "type Node_Kind is";
80    Get_Nam : constant Pattern := wsp * A & "N_" &  Break (",)") * Nam
81                                  & Len (1) * Term;
82    Sub_Typ : constant Pattern := wsp * A & "subtype " &  Break (' ') * N;
83    No_Cont : constant Pattern := wsp & Break (' ') * N1
84                                  & " .. " & Break (';') * N2;
85    Cont_N1 : constant Pattern := wsp & Break (' ') * N1 & " .." & Rpos (0);
86    Cont_N2 : constant Pattern := Span (' ') & Break (';') * N2;
87    Is_Func : constant Pattern := wsp * A & "function " & Rest * Nam;
88    Get_Arg : constant Pattern := wsp & "(N : " & Break (')') * Arg
89                                  & ") return " & Break (';') * Rtn
90                                  & ';' & wsp & "--" & wsp & Rest * Comment;
91
92    NKV : Natural;
93
94    M : Match_Result;
95
96    procedure Getline;
97    --  Get non-comment, non-blank line. Also skips "for " rep clauses
98
99    -------------
100    -- Getline --
101    -------------
102
103    procedure Getline is
104    begin
105       loop
106          Line := Get_Line (InS);
107
108          if Line /= ""
109            and then not Match (Line, Wsp_For)
110            and then not Match (Line, Is_Cmnt)
111          then
112             return;
113
114          elsif Match (Line, "   --  End functions (note") then
115             raise Done;
116          end if;
117       end loop;
118    end Getline;
119
120 --  Start of processing for XSinfo
121
122 begin
123    Set_Exit_Status (1);
124    Anchored_Mode := True;
125
126    if Argument_Count > 0 then
127       Create (Ofile, Out_File, Argument (1));
128    else
129       Create (Ofile, Out_File, "sinfo.h");
130    end if;
131
132    Open (InS, In_File, "sinfo.ads");
133
134    --  Write header to output file
135
136    loop
137       Line := Get_Line (InS);
138       exit when Line = "";
139
140       Match
141         (Line,
142          "--                                 S p e c       ",
143          "--                              C Header File    ");
144
145       Match (Line, "--", "/*");
146       Match (Line, Rtab (2) * A & "--", M);
147       Replace (M, A & "*/");
148       Put_Line (Ofile, Line);
149    end loop;
150
151    --  Skip to package line
152
153    loop
154       Getline;
155       exit when Match (Line, "package");
156    end loop;
157
158    --  Skip to first node kind line
159
160    loop
161       Getline;
162       exit when Match (Line, Typ_Nod);
163       Put_Line (Ofile, Line);
164    end loop;
165
166    Put_Line (Ofile, "");
167    NKV := 0;
168
169    --  Loop through node kind codes
170
171    loop
172       Getline;
173
174       if Match (Line, Get_Nam) then
175          Put_Line (Ofile, A & "#define N_" & Nam & ' ' & NKV);
176          NKV := NKV + 1;
177          exit when not Match (Term, ",");
178
179       else
180          Put_Line (Ofile, Line);
181       end if;
182    end loop;
183
184    Put_Line (Ofile, "");
185    Put_Line (Ofile, A & "#define Number_Node_Kinds " & NKV);
186
187    --  Loop through subtype declarations
188
189    loop
190       Getline;
191
192       if not Match (Line, Sub_Typ) then
193          exit when Match (Line, "   function");
194          Put_Line (Ofile, Line);
195
196       else
197          Put_Line (Ofile, A & "SUBTYPE (" & N & ", Node_Kind, ");
198          Getline;
199
200          --  Normal case
201
202          if Match (Line, No_Cont) then
203             Put_Line (Ofile, A & "   " & N1 & ", " & N2 & ')');
204
205          --  Continuation case
206
207          else
208             if not Match (Line, Cont_N1) then
209                raise Err;
210             end if;
211
212             Getline;
213
214             if not Match (Line, Cont_N2) then
215                raise Err;
216             end if;
217
218             Put_Line (Ofile,  A & "   " & N1 & ',');
219             Put_Line (Ofile,  A & "   " & N2 & ')');
220          end if;
221       end if;
222    end loop;
223
224    --  Loop through functions. Note that this loop is terminated by
225    --  the call to Getfile encountering the end of functions sentinel
226
227    loop
228       if Match (Line, Is_Func) then
229          Getline;
230             if not Match (Line, Get_Arg) then
231                raise Err;
232             end if;
233          Put_Line
234            (Ofile,
235             A &  "INLINE " & Rpad (Rtn, 9)
236             & ' ' & Rpad (Nam, 30) & " (" & Arg & " N)");
237
238          Put_Line (Ofile,  A & "   { return " & Comment & " (N); }");
239
240       else
241          Put_Line (Ofile, Line);
242       end if;
243
244       Getline;
245    end loop;
246
247 exception
248    when Done =>
249       Put_Line (Ofile, "");
250       Set_Exit_Status (0);
251
252 end XSinfo;