OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [xeinfo.adb] - Blame information for rev 756

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                          GNAT SYSTEM UTILITIES                           --
4
--                                                                          --
5
--                               X E 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 a-einfo.h (C version of einfo.ads spec)
27
--  for use by Gigi. This header file contains all definitions and access
28
--  functions, but does not contain set procedures, since Gigi is not allowed
29
--  to modify the GNAT tree)
30
 
31
--    Input files:
32
 
33
--       einfo.ads     spec of Einfo package
34
--       einfo.adb     body of Einfo package
35
 
36
--    Output files:
37
 
38
--       a-einfo.h     Corresponding c header file
39
 
40
--  Note: It is assumed that the input files have been compiled without errors
41
 
42
--  An optional argument allows the specification of an output file name to
43
--  override the default a-einfo.h file name for the generated output file.
44
 
45
--  Most, but not all of the functions in Einfo can be inlined in the C header.
46
--  They are the functions identified by pragma Inline in the spec. Functions
47
--  that cannot be inlined are simply defined in the header.
48
 
49
with Ada.Command_Line;              use Ada.Command_Line;
50
with Ada.Strings.Unbounded;         use Ada.Strings.Unbounded;
51
with Ada.Strings.Unbounded.Text_IO; use Ada.Strings.Unbounded.Text_IO;
52
with Ada.Strings.Maps;              use Ada.Strings.Maps;
53
with Ada.Strings.Maps.Constants;    use Ada.Strings.Maps.Constants;
54
with Ada.Text_IO;                   use Ada.Text_IO;
55
 
56
with GNAT.Spitbol;                  use GNAT.Spitbol;
57
with GNAT.Spitbol.Patterns;         use GNAT.Spitbol.Patterns;
58
with GNAT.Spitbol.Table_Boolean;    use GNAT.Spitbol.Table_Boolean;
59
 
60
with CEinfo;
61
 
62
procedure XEinfo is
63
 
64
   package TB renames GNAT.Spitbol.Table_Boolean;
65
 
66
   Err : exception;
67
 
68
   A         : VString := Nul;
69
   B         : VString := Nul;
70
   C         : VString := Nul;
71
   Expr      : VString := Nul;
72
   Filler    : VString := Nul;
73
   Fline     : VString := Nul;
74
   Formal    : VString := Nul;
75
   Formaltyp : VString := Nul;
76
   FN        : VString := Nul;
77
   Line      : VString := Nul;
78
   N         : VString := Nul;
79
   N1        : VString := Nul;
80
   N2        : VString := Nul;
81
   N3        : VString := Nul;
82
   Nam       : VString := Nul;
83
   Name      : VString := Nul;
84
   NewS      : VString := Nul;
85
   Nextlin   : VString := Nul;
86
   OldS      : VString := Nul;
87
   Rtn       : VString := Nul;
88
   Term      : VString := Nul;
89
 
90
   InB : File_Type;
91
   --  Used to read initial header from body
92
 
93
   InF   : File_Type;
94
   --  Used to read full text of both spec and body
95
 
96
   Ofile : File_Type;
97
   --  Used to write output file
98
 
99
   wsp      : constant Pattern := NSpan (' ' & ASCII.HT);
100
   Comment  : constant Pattern := wsp & "--";
101
   For_Rep  : constant Pattern := wsp & "for";
102
   Get_Func : constant Pattern := wsp * A & "function" & wsp
103
                                  & Break (' ') * Name;
104
   Inline   : constant Pattern := wsp & "pragma Inline (" & Break (')') * Name;
105
   Get_Pack : constant Pattern := wsp & "package ";
106
   Get_Enam : constant Pattern := wsp & Break (',') * N & ',';
107
   Find_Fun : constant Pattern := wsp & "function";
108
   F_Subtyp : constant Pattern := wsp * A & "subtype " & Break (' ') * N;
109
   G_Subtyp : constant Pattern := wsp & "subtype" & wsp & Break (' ') * NewS
110
                                  & wsp & "is" & wsp & Break (" ;") * OldS
111
                                  & wsp & ';' & wsp & Rtab (0);
112
   F_Typ    : constant Pattern := wsp * A & "type " & Break (' ') * N &
113
                                  " is (";
114
   Get_Nam  : constant Pattern := wsp * A & Break (",)") * Nam
115
                                  & Len (1) * Term;
116
   Get_Styp : constant Pattern := wsp * A & "subtype " & Break (' ') * N;
117
   Get_N1   : constant Pattern := wsp & Break (' ') * N1;
118
   Get_N2   : constant Pattern := wsp & "-- " & Rest * N2;
119
   Get_N3   : constant Pattern := wsp & Break (';') * N3;
120
   Get_FN   : constant Pattern := wsp * C & "function" & wsp
121
                                  & Break (" (") * FN;
122
   Is_Rturn : constant Pattern := BreakX ('r') & "return";
123
   Is_Begin : constant Pattern := wsp & "begin";
124
   Get_Asrt : constant Pattern := wsp & "pragma Assert";
125
   Semicoln : constant Pattern := BreakX (';');
126
   Get_Cmnt : constant Pattern := BreakX ('-') * A & "--";
127
   Get_Expr : constant Pattern := wsp & "return " & Break (';') * Expr;
128
   Chek_End : constant Pattern := wsp & "end" & BreakX (';') & ';';
129
   Get_B1   : constant Pattern := BreakX (' ') * A & " in " & Rest * B;
130
   Get_B2   : constant Pattern := BreakX (' ') * A & " = " & Rest * B;
131
   Get_B3   : constant Pattern := BreakX (' ') * A & " /= " & Rest * B;
132
   To_Paren : constant Pattern := wsp * Filler & '(';
133
   Get_Fml  : constant Pattern := Break (" :") * Formal & wsp & ':' & wsp
134
                                  & BreakX (" );") * Formaltyp;
135
   Nxt_Fml  : constant Pattern := wsp & "; ";
136
   Get_Rtn  : constant Pattern := wsp & "return" & wsp & BreakX (" ;") * Rtn;
137
   Rem_Prn  : constant Pattern := wsp & ')';
138
 
139
   M : Match_Result;
140
 
141
   Lineno : Natural := 0;
142
   --  Line number in spec
143
 
144
   V   : Natural;
145
   Ctr : Natural;
146
 
147
   Inlined : TB.Table (200);
148
   --  Inlined<N> = True for inlined function, False otherwise
149
 
150
   Lastinlined : Boolean;
151
 
152
   procedure Badfunc;
153
   --  Signal bad function in body
154
 
155
   function Getlin return VString;
156
   --  Get non-comment line (comment lines skipped, also skips FOR rep clauses)
157
   --  Fatal error (raises End_Error exception) if end of file encountered
158
 
159
   procedure Must (B : Boolean);
160
   --  Raises Err if the argument (a Match) call, returns False
161
 
162
   procedure Sethead (Line : in out VString; Term : String);
163
   --  Process function header into C
164
 
165
   -------------
166
   -- Badfunc --
167
   -------------
168
 
169
   procedure Badfunc is
170
   begin
171
      Put_Line
172
        (Standard_Error,
173
         "Body for function " & FN & " does not meet requirements");
174
      raise Err;
175
   end Badfunc;
176
 
177
   -------------
178
   -- Getlin --
179
   -------------
180
 
181
   function Getlin return VString is
182
      Lin : VString;
183
 
184
   begin
185
      loop
186
         Lin := Get_Line (InF);
187
         Lineno := Lineno + 1;
188
 
189
         if Lin /= ""
190
           and then not Match (Lin, Comment)
191
           and then not Match (Lin, For_Rep)
192
         then
193
            return Lin;
194
         end if;
195
      end loop;
196
   end Getlin;
197
 
198
   ----------
199
   -- Must --
200
   ----------
201
 
202
   procedure Must (B : Boolean) is
203
   begin
204
      if not B then
205
         raise Err;
206
      end if;
207
   end Must;
208
 
209
   -------------
210
   -- Sethead --
211
   -------------
212
 
213
   procedure Sethead (Line : in out VString; Term : String) is
214
      Args : VString;
215
 
216
   begin
217
      Must (Match (Line, Get_Func, ""));
218
      Args := Nul;
219
 
220
      if Match (Line, To_Paren, "") then
221
         Args := Filler & '(';
222
 
223
         loop
224
            Must (Match (Line, Get_Fml, ""));
225
            Append (Args, Formaltyp & ' ' & Formal);
226
            exit when not Match (Line, Nxt_Fml);
227
            Append (Args, ",");
228
         end loop;
229
 
230
         Match (Line, Rem_Prn, "");
231
         Append (Args, ')');
232
      end if;
233
 
234
      Must (Match (Line, Get_Rtn));
235
 
236
      if Present (Inlined, Name) then
237
         Put_Line (Ofile, A & "INLINE " & Rtn & ' ' & Name & Args & Term);
238
      else
239
         Put_Line (Ofile, A &  Rtn & ' ' & Name & Args & Term);
240
      end if;
241
   end Sethead;
242
 
243
--  Start of processing for XEinfo
244
 
245
begin
246
   --  First run CEinfo to check for errors. Note that CEinfo is also a
247
   --  stand-alone program that can be run separately.
248
 
249
   CEinfo;
250
 
251
   Anchored_Mode := True;
252
 
253
   if Argument_Count > 0 then
254
      Create (Ofile, Out_File, Argument (1));
255
   else
256
      Create (Ofile, Out_File, "a-einfo.h");
257
   end if;
258
 
259
   Open (InB, In_File, "einfo.adb");
260
   Open (InF, In_File, "einfo.ads");
261
 
262
   Lineno := 0;
263
   loop
264
      Line := Get_Line (InF);
265
      Lineno := Lineno + 1;
266
      exit when Line = "";
267
 
268
      Match (Line,
269
             "--                                 S p e c       ",
270
             "--                              C Header File    ");
271
      Match (Line, "--", "/*");
272
      Match (Line, Rtab (2) * A & "--", M);
273
      Replace (M, A & "*/");
274
      Put_Line (Ofile, Line);
275
   end loop;
276
 
277
   Put_Line (Ofile, "");
278
 
279
   Put_Line (Ofile, "#ifdef __cplusplus");
280
   Put_Line (Ofile, "extern ""C"" {");
281
   Put_Line (Ofile, "#endif");
282
 
283
   --  Find and record pragma Inlines
284
 
285
   loop
286
      Line := Get_Line (InF);
287
      exit when Match (Line, "   --  END XEINFO INLINES");
288
 
289
      if Match (Line, Inline) then
290
         Set (Inlined, Name, True);
291
      end if;
292
   end loop;
293
 
294
   --  Skip to package line
295
 
296
   Reset (InF, In_File);
297
   Lineno := 0;
298
 
299
   loop
300
      Line := Getlin;
301
      exit when Match (Line, Get_Pack);
302
   end loop;
303
 
304
   V := 0;
305
   Line := Getlin;
306
   Must (Match (Line, wsp & "type Entity_Kind"));
307
 
308
   --  Process entity kind code definitions
309
 
310
   loop
311
      Line := Getlin;
312
      exit when not Match (Line, Get_Enam);
313
      Put_Line (Ofile, "   #define " & Rpad (N, 32) & " " & V);
314
      V := V + 1;
315
   end loop;
316
 
317
   Must (Match (Line, wsp & Rest * N));
318
   Put_Line (Ofile, "   #define " & Rpad (N, 32) & ' ' & V);
319
   Line := Getlin;
320
 
321
   Must (Match (Line, wsp & ");"));
322
   Put_Line (Ofile, "");
323
 
324
   --  Loop through subtype and type declarations
325
 
326
   loop
327
      Line := Getlin;
328
      exit when Match (Line, Find_Fun);
329
 
330
      --  Case of a subtype declaration
331
 
332
      if Match (Line, F_Subtyp) then
333
 
334
         --  Case of a subtype declaration that is an abbreviation of the
335
         --  form subtype x is y, and if so generate the appropriate typedef
336
 
337
         if Match (Line, G_Subtyp) then
338
            Put_Line (Ofile, A & "typedef " & OldS & ' ' & NewS & ';');
339
 
340
         --  Otherwise the subtype must be declaring a subrange of Entity_Id
341
 
342
         else
343
            Must (Match (Line, Get_Styp));
344
            Line := Getlin;
345
            Must (Match (Line, Get_N1));
346
 
347
            loop
348
               Line := Get_Line (InF);
349
               Lineno := Lineno + 1;
350
               exit when not Match (Line, Get_N2);
351
            end loop;
352
 
353
            Must (Match (Line, Get_N3));
354
            Put_Line (Ofile, A & "SUBTYPE (" & N & ", Entity_Kind, ");
355
            Put_Line (Ofile, A & "   " & N1 & ", " & N3 & ')');
356
            Put_Line (Ofile, "");
357
         end if;
358
 
359
      --  Case of type declaration
360
 
361
      elsif Match (Line, F_Typ) then
362
 
363
         --  Process type declaration (must be enumeration type)
364
 
365
         Ctr := 0;
366
         Put_Line (Ofile, A & "typedef char " & N & ';');
367
 
368
         loop
369
            Line := Getlin;
370
            Must (Match (Line, Get_Nam));
371
            Put_Line (Ofile, A & "#define " & Rpad (Nam, 25) & Ctr);
372
            Ctr := Ctr + 1;
373
            exit when Term /= ",";
374
         end loop;
375
 
376
         Put_Line (Ofile, "");
377
 
378
      --  Neither subtype nor type declaration
379
 
380
      else
381
         raise Err;
382
      end if;
383
   end loop;
384
 
385
   --  Process function declarations
386
 
387
   --  Note: Lastinlined used to control blank lines
388
 
389
   Put_Line (Ofile, "");
390
   Lastinlined := True;
391
 
392
   --  Loop through function declarations
393
 
394
   while Match (Line, Get_FN) loop
395
 
396
      --  Non-inlined function
397
 
398
      if not Present (Inlined, FN) then
399
         Put_Line (Ofile, "");
400
         Put_Line
401
           (Ofile,
402
            "   #define " & FN & " einfo__" & Translate (FN, Lower_Case_Map));
403
 
404
      --  Inlined function
405
 
406
      else
407
         if not Lastinlined then
408
            Put_Line (Ofile, "");
409
         end if;
410
      end if;
411
 
412
      --  Merge here to output spec
413
 
414
      Sethead (Line, ";");
415
      Lastinlined := Get (Inlined, FN);
416
      Line := Getlin;
417
   end loop;
418
 
419
   Put_Line (Ofile, "");
420
 
421
   --  Read body to find inlined functions
422
 
423
   Close (InB);
424
   Close (InF);
425
   Open (InF, In_File, "einfo.adb");
426
   Lineno := 0;
427
 
428
   --  Loop through input lines to find bodies of inlined functions
429
 
430
   while not End_Of_File (InF) loop
431
      Fline := Get_Line (InF);
432
 
433
      if Match (Fline, Get_FN)
434
        and then Get (Inlined, FN)
435
      then
436
         --  Here we have an inlined function
437
 
438
         if not Match (Fline, Is_Rturn) then
439
            Line := Fline;
440
            Badfunc;
441
         end if;
442
 
443
         Line := Getlin;
444
 
445
         if not Match (Line, Is_Begin) then
446
            Badfunc;
447
         end if;
448
 
449
         --  Skip past pragma Asserts
450
 
451
         loop
452
            Line := Getlin;
453
            exit when not Match (Line, Get_Asrt);
454
 
455
            --  Pragma assert found, get its continuation lines
456
 
457
            loop
458
               exit when Match (Line, Semicoln);
459
               Line := Getlin;
460
            end loop;
461
         end loop;
462
 
463
         --  Process return statement
464
 
465
         Match (Line, Get_Cmnt, M);
466
         Replace (M, A);
467
 
468
         --  Get continuations of return statement
469
 
470
         while not Match (Line, Semicoln) loop
471
            Nextlin := Getlin;
472
            Match (Nextlin, wsp, " ");
473
            Append (Line, Nextlin);
474
         end loop;
475
 
476
         if not Match (Line, Get_Expr) then
477
            Badfunc;
478
         end if;
479
 
480
         Line := Getlin;
481
 
482
         if not Match (Line, Chek_End) then
483
            Badfunc;
484
         end if;
485
 
486
         Match (Expr, Get_B1, M);
487
         Replace (M, "IN (" & A & ", " & B & ')');
488
         Match (Expr, Get_B2, M);
489
         Replace (M, A & " == " & B);
490
         Match (Expr, Get_B3, M);
491
         Replace (M, A & " != " & B);
492
         Put_Line (Ofile, "");
493
         Sethead (Fline, "");
494
         Put_Line (Ofile, C & "   { return " & Expr & "; }");
495
      end if;
496
   end loop;
497
 
498
   Put_Line (Ofile, "");
499
 
500
   Put_Line (Ofile, "#ifdef __cplusplus");
501
   Put_Line (Ofile, "}");
502
   Put_Line (Ofile, "#endif");
503
 
504
   Put_Line
505
     (Ofile,
506
      "/* End of einfo.h (C version of Einfo package specification) */");
507
 
508
   Close (InF);
509
   Close (Ofile);
510
 
511
exception
512
   when Err =>
513
      Put_Line (Standard_Error, Lineno & ".  " & Line);
514
      Put_Line (Standard_Error, "**** fatal error ****");
515
      Set_Exit_Status (1);
516
 
517
   when End_Error =>
518
      Put_Line (Standard_Error, "unexpected end of file");
519
      Put_Line (Standard_Error, "**** fatal error ****");
520
 
521
end XEinfo;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.