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

Subversion Repositories openrisc

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

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 O S C O N S                               --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 2008-2009, 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 program generates the spec of System.OS_Constants (s-oscons.ads)
27
 
28
--  It works in conjunction with a C template file which must be pre-processed
29
--  and compiled using the cross compiler. Two input files are used:
30
--    - the preprocessed C file: s-oscons-tmplt.i
31
--    - the generated assembly file: s-oscons-tmplt.s
32
 
33
--  The contents of s-oscons.ads is written on standard output
34
 
35
with Ada.Characters.Handling; use Ada.Characters.Handling;
36
with Ada.Exceptions;          use Ada.Exceptions;
37
with Ada.Strings.Fixed;       use Ada.Strings.Fixed;
38
with Ada.Text_IO;             use Ada.Text_IO;
39
with Ada.Streams.Stream_IO;   use Ada.Streams.Stream_IO;
40
 
41
pragma Warnings (Off);
42
--  System.Unsigned_Types is an internal GNAT unit
43
with System.Unsigned_Types;   use System.Unsigned_Types;
44
pragma Warnings (On);
45
 
46
with GNAT.Table;
47
 
48
with XUtil;                   use XUtil;
49
 
50
procedure XOSCons is
51
 
52
   use ASCII;
53
   use Ada.Strings;
54
 
55
   Unit_Name : constant String := "s-oscons";
56
   Tmpl_Name : constant String := Unit_Name & "-tmplt";
57
 
58
   -------------------------------------------------
59
   -- Information retrieved from assembly listing --
60
   -------------------------------------------------
61
 
62
   type String_Access is access all String;
63
   --  Note: we can't use GNAT.Strings for this definition, since that unit
64
   --  is not available in older base compilers.
65
 
66
   --  We need to deal with integer values that can be signed or unsigned, so
67
   --  we need to accommodate the maximum range of both cases.
68
 
69
   type Int_Value_Type is record
70
      Positive  : Boolean;
71
      Abs_Value : Long_Unsigned := 0;
72
   end record;
73
 
74
   type Asm_Info_Kind is
75
     (CND,     --  Named number (decimal)
76
      CNS,     --  Named number (freeform text)
77
      C,       --  Constant object
78
      TXT);    --  Literal text
79
   --  Recognized markers found in assembly file. These markers are produced by
80
   --  the same-named macros from the C template.
81
 
82
   subtype Named_Number is Asm_Info_Kind range CND .. CNS;
83
 
84
   type Asm_Info (Kind : Asm_Info_Kind := TXT) is record
85
      Line_Number   : Integer;
86
      --  Line number in C source file
87
 
88
      Constant_Name : String_Access;
89
      --  Name of constant to be defined
90
 
91
      Constant_Type : String_Access;
92
      --  Type of constant (case of Kind = C)
93
 
94
      Value_Len     : Natural := 0;
95
      --  Length of text representation of constant's value
96
 
97
      Text_Value    : String_Access;
98
      --  Value for CNS / C constant
99
 
100
      Int_Value     : Int_Value_Type;
101
      --  Value for CND constant
102
 
103
      Comment       : String_Access;
104
      --  Additional descriptive comment for constant, or free-form text (TXT)
105
   end record;
106
 
107
   package Asm_Infos is new GNAT.Table
108
     (Table_Component_Type => Asm_Info,
109
      Table_Index_Type     => Integer,
110
      Table_Low_Bound      => 1,
111
      Table_Initial        => 100,
112
      Table_Increment      => 10);
113
 
114
   Max_Constant_Name_Len  : Natural := 0;
115
   Max_Constant_Value_Len : Natural := 0;
116
   Max_Constant_Type_Len  : Natural := 0;
117
   --  Lengths of longest name and longest value
118
 
119
   type Language is (Lang_Ada, Lang_C);
120
 
121
   procedure Output_Info
122
     (Lang       : Language;
123
      OFile      : Sfile;
124
      Info_Index : Integer);
125
   --  Output information from the indicated asm info line
126
 
127
   procedure Parse_Asm_Line (Line : String);
128
   --  Parse one information line from the assembly source
129
 
130
   function Contains_Template_Name (S : String) return Boolean;
131
   --  True if S contains Tmpl_Name, possibly with different casing
132
 
133
   function Spaces (Count : Integer) return String;
134
   --  If Count is positive, return a string of Count spaces, else return an
135
   --  empty string.
136
 
137
   ----------------------------
138
   -- Contains_Template_Name --
139
   ----------------------------
140
 
141
   function Contains_Template_Name (S : String) return Boolean is
142
   begin
143
      if Index (Source => To_Lower (S), Pattern => Tmpl_Name) > 0 then
144
         return True;
145
      else
146
         return False;
147
      end if;
148
   end Contains_Template_Name;
149
 
150
   -----------------
151
   -- Output_Info --
152
   -----------------
153
 
154
   procedure Output_Info
155
     (Lang       : Language;
156
      OFile      : Sfile;
157
      Info_Index : Integer)
158
   is
159
      Info : Asm_Info renames Asm_Infos.Table (Info_Index);
160
 
161
      procedure Put (S : String);
162
      --  Write S to OFile
163
 
164
      ---------
165
      -- Put --
166
      ---------
167
 
168
      procedure Put (S : String) is
169
      begin
170
         Put (OFile, S);
171
      end Put;
172
 
173
   begin
174
      if Info.Kind /= TXT then
175
         --  TXT case is handled by the common code below
176
 
177
         case Lang is
178
            when Lang_Ada =>
179
               Put ("   " & Info.Constant_Name.all);
180
               Put (Spaces (Max_Constant_Name_Len
181
                              - Info.Constant_Name'Length));
182
 
183
               if Info.Kind in Named_Number then
184
                  Put (" : constant := ");
185
               else
186
                  Put (" : constant " & Info.Constant_Type.all);
187
                  Put (Spaces (Max_Constant_Type_Len
188
                                 - Info.Constant_Type'Length));
189
                  Put (" := ");
190
               end if;
191
 
192
            when Lang_C =>
193
               Put ("#define " & Info.Constant_Name.all & " ");
194
               Put (Spaces (Max_Constant_Name_Len
195
                              - Info.Constant_Name'Length));
196
         end case;
197
 
198
         if Info.Kind = CND then
199
            if not Info.Int_Value.Positive then
200
               Put ("-");
201
            end if;
202
            Put (Trim (Info.Int_Value.Abs_Value'Img, Side => Left));
203
         else
204
            declare
205
               Is_String : constant Boolean :=
206
                             Info.Kind = C
207
                               and then Info.Constant_Type.all = "String";
208
            begin
209
               if Is_String then
210
                  Put ("""");
211
               end if;
212
               Put (Info.Text_Value.all);
213
               if Is_String then
214
                  Put ("""");
215
               end if;
216
            end;
217
         end if;
218
 
219
         if Lang = Lang_Ada then
220
            Put (";");
221
 
222
            if Info.Comment'Length > 0 then
223
               Put (Spaces (Max_Constant_Value_Len - Info.Value_Len));
224
               Put (" --  ");
225
            end if;
226
         end if;
227
      end if;
228
 
229
      if Lang = Lang_Ada then
230
         Put (Info.Comment.all);
231
      end if;
232
 
233
      New_Line (OFile);
234
   end Output_Info;
235
 
236
   --------------------
237
   -- Parse_Asm_Line --
238
   --------------------
239
 
240
   procedure Parse_Asm_Line (Line : String) is
241
      Index1, Index2 : Integer := Line'First;
242
 
243
      function Field_Alloc return String_Access;
244
      --  Allocate and return a copy of Line (Index1 .. Index2 - 1)
245
 
246
      procedure Find_Colon (Index : in out Integer);
247
      --  Increment Index until the next colon in Line
248
 
249
      function Parse_Int (S : String) return Int_Value_Type;
250
      --  Parse a decimal number, preceded by an optional '$' or '#' character,
251
      --  and return its value.
252
 
253
      -----------------
254
      -- Field_Alloc --
255
      -----------------
256
 
257
      function Field_Alloc return String_Access is
258
      begin
259
         return new String'(Line (Index1 .. Index2 - 1));
260
      end Field_Alloc;
261
 
262
      ----------------
263
      -- Find_Colon --
264
      ----------------
265
 
266
      procedure Find_Colon (Index : in out Integer) is
267
      begin
268
         loop
269
            Index := Index + 1;
270
            exit when Index > Line'Last or else Line (Index) = ':';
271
         end loop;
272
      end Find_Colon;
273
 
274
      ---------------
275
      -- Parse_Int --
276
      ---------------
277
 
278
      function Parse_Int (S : String) return Int_Value_Type is
279
         First    : Integer := S'First;
280
         Positive : Boolean;
281
      begin
282
         --  On some platforms, immediate integer values are prefixed with
283
         --  a $ or # character in assembly output.
284
 
285
         if S (First) = '$' or else S (First) = '#' then
286
            First := First + 1;
287
         end if;
288
 
289
         if S (First) = '-' then
290
            Positive := False;
291
            First    := First + 1;
292
         else
293
            Positive := True;
294
         end if;
295
 
296
         return (Positive  => Positive,
297
                 Abs_Value => Long_Unsigned'Value (S (First .. S'Last)));
298
 
299
      exception
300
         when E : others =>
301
            Put_Line (Standard_Error, "can't parse decimal value: " & S);
302
            raise;
303
      end Parse_Int;
304
 
305
   --  Start of processing for Parse_Asm_Line
306
 
307
   begin
308
      Find_Colon (Index2);
309
 
310
      declare
311
         Info : Asm_Info (Kind => Asm_Info_Kind'Value
312
                                    (Line (Line'First .. Index2 - 1)));
313
      begin
314
         Index1 := Index2 + 1;
315
         Find_Colon (Index2);
316
 
317
         Info.Line_Number :=
318
           Integer (Parse_Int (Line (Index1 .. Index2 - 1)).Abs_Value);
319
 
320
         case Info.Kind is
321
            when CND | CNS | C =>
322
               Index1 := Index2 + 1;
323
               Find_Colon (Index2);
324
 
325
               Info.Constant_Name := Field_Alloc;
326
               if Info.Constant_Name'Length > Max_Constant_Name_Len then
327
                  Max_Constant_Name_Len := Info.Constant_Name'Length;
328
               end if;
329
 
330
               Index1 := Index2 + 1;
331
               Find_Colon (Index2);
332
 
333
               if Info.Kind = C then
334
                  Info.Constant_Type := Field_Alloc;
335
                  if Info.Constant_Type'Length > Max_Constant_Type_Len then
336
                     Max_Constant_Type_Len := Info.Constant_Type'Length;
337
                  end if;
338
 
339
                  Index1 := Index2 + 1;
340
                  Find_Colon (Index2);
341
               end if;
342
 
343
               if Info.Kind = CND then
344
                  Info.Int_Value := Parse_Int (Line (Index1 .. Index2 - 1));
345
                  Info.Value_Len := Index2 - Index1 - 1;
346
 
347
               else
348
                  Info.Text_Value := Field_Alloc;
349
                  Info.Value_Len  := Info.Text_Value'Length;
350
               end if;
351
 
352
            when others =>
353
               null;
354
         end case;
355
 
356
         Index1 := Index2 + 1;
357
         Index2 := Line'Last + 1;
358
         Info.Comment := Field_Alloc;
359
 
360
         if Info.Kind = TXT then
361
            Info.Text_Value := Info.Comment;
362
 
363
         --  Update Max_Constant_Value_Len, but only if this constant has a
364
         --  comment (else the value is allowed to be longer).
365
 
366
         elsif Info.Comment'Length > 0 then
367
            if Info.Value_Len > Max_Constant_Value_Len then
368
               Max_Constant_Value_Len := Info.Value_Len;
369
            end if;
370
         end if;
371
 
372
         Asm_Infos.Append (Info);
373
      end;
374
   exception
375
      when E : others =>
376
         Put_Line (Standard_Error,
377
           "can't parse " & Line);
378
         Put_Line (Standard_Error,
379
           "exception raised: " & Exception_Information (E));
380
   end Parse_Asm_Line;
381
 
382
   ------------
383
   -- Spaces --
384
   ------------
385
 
386
   function Spaces (Count : Integer) return String is
387
   begin
388
      if Count <= 0 then
389
         return "";
390
      else
391
         return (1 .. Count => ' ');
392
      end if;
393
   end Spaces;
394
 
395
   --  Local declarations
396
 
397
   --  Input files
398
 
399
   Tmpl_File_Name : constant String := Tmpl_Name & ".i";
400
   Asm_File_Name  : constant String := Tmpl_Name & ".s";
401
 
402
   --  Output files
403
 
404
   Ada_File_Name  : constant String := Unit_Name & ".ads";
405
   C_File_Name    : constant String := Unit_Name & ".h";
406
 
407
   Asm_File  : Ada.Text_IO.File_Type;
408
   Tmpl_File : Ada.Text_IO.File_Type;
409
   Ada_OFile : Sfile;
410
   C_OFile   : Sfile;
411
 
412
   Line : String (1 .. 256);
413
   Last : Integer;
414
   --  Line being processed
415
 
416
   Current_Line : Integer;
417
   Current_Info : Integer;
418
   In_Comment   : Boolean;
419
   In_Template  : Boolean;
420
 
421
--  Start of processing for XOSCons
422
 
423
begin
424
   --  Load values from assembly file
425
 
426
   Open (Asm_File, In_File, Asm_File_Name);
427
 
428
   while not End_Of_File (Asm_File) loop
429
      Get_Line (Asm_File, Line, Last);
430
      if Last > 2 and then Line (1 .. 2) = "->" then
431
         Parse_Asm_Line (Line (3 .. Last));
432
      end if;
433
   end loop;
434
 
435
   Close (Asm_File);
436
 
437
   --  Load C template and output definitions
438
 
439
   Open   (Tmpl_File, In_File,  Tmpl_File_Name);
440
   Create (Ada_OFile, Out_File, Ada_File_Name);
441
   Create (C_OFile,   Out_File, C_File_Name);
442
 
443
   Current_Line := 0;
444
   Current_Info := Asm_Infos.First;
445
   In_Comment   := False;
446
 
447
   while not End_Of_File (Tmpl_File) loop
448
      <<Get_One_Line>>
449
      Get_Line (Tmpl_File, Line, Last);
450
 
451
      if Last >= 2 and then Line (1 .. 2) = "# " then
452
         declare
453
            Index : Integer := 3;
454
         begin
455
            while Index <= Last and then Line (Index) in '0' .. '9' loop
456
               Index := Index + 1;
457
            end loop;
458
 
459
            if Contains_Template_Name (Line (Index + 1 .. Last)) then
460
               Current_Line := Integer'Value (Line (3 .. Index - 1));
461
               In_Template  := True;
462
               goto Get_One_Line;
463
            else
464
               In_Template := False;
465
            end if;
466
         end;
467
 
468
      elsif In_Template then
469
         if In_Comment then
470
            if Line (1 .. Last) = "*/" then
471
               Put_Line (C_OFile, Line (1 .. Last));
472
               In_Comment := False;
473
            else
474
               Put_Line (Ada_OFile, Line (1 .. Last));
475
               Put_Line (C_OFile, Line (1 .. Last));
476
            end if;
477
 
478
         elsif Line (1 .. Last) = "/*" then
479
            Put_Line (C_OFile, Line (1 .. Last));
480
            In_Comment := True;
481
 
482
         elsif Asm_Infos.Table (Current_Info).Line_Number = Current_Line then
483
            Output_Info (Lang_Ada, Ada_OFile, Current_Info);
484
            Output_Info (Lang_C,   C_OFile,   Current_Info);
485
            Current_Info := Current_Info + 1;
486
         end if;
487
 
488
         Current_Line := Current_Line + 1;
489
      end if;
490
   end loop;
491
 
492
   Close (Tmpl_File);
493
 
494
end XOSCons;

powered by: WebSVN 2.1.0

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