OSDN Git Service

* sysdep.c: Problem discovered during IA64 VMS port.
[pf3gnuchains/gcc-fork.git] / gcc / ada / prj.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                                  P R J                                   --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --             Copyright (C) 2001-2003 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 2,  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 COPYING.  If not, write --
19 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
20 -- MA 02111-1307, USA.                                                      --
21 --                                                                          --
22 -- GNAT was originally developed  by the GNAT team at  New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
24 --                                                                          --
25 ------------------------------------------------------------------------------
26
27 with Ada.Characters.Handling; use Ada.Characters.Handling;
28
29 with Namet;    use Namet;
30 with Osint;    use Osint;
31 with Prj.Attr;
32 with Prj.Com;
33 with Prj.Env;
34 with Prj.Err;  use Prj.Err;
35 with Scans;    use Scans;
36 with Snames;   use Snames;
37
38 with GNAT.OS_Lib; use GNAT.OS_Lib;
39
40 package body Prj is
41
42    The_Empty_String : Name_Id;
43
44    Ada_Language     : constant Name_Id := Name_Ada;
45
46    subtype Known_Casing is Casing_Type range All_Upper_Case .. Mixed_Case;
47
48    The_Casing_Images : constant array (Known_Casing) of String_Access :=
49      (All_Lower_Case => new String'("lowercase"),
50       All_Upper_Case => new String'("UPPERCASE"),
51       Mixed_Case     => new String'("MixedCase"));
52
53    Initialized : Boolean := False;
54
55    Standard_Dot_Replacement      : constant Name_Id :=
56      First_Name_Id + Character'Pos ('-');
57
58    Std_Naming_Data : Naming_Data :=
59      (Current_Language          => No_Name,
60       Dot_Replacement           => Standard_Dot_Replacement,
61       Dot_Repl_Loc              => No_Location,
62       Casing                    => All_Lower_Case,
63       Spec_Suffix               => No_Array_Element,
64       Current_Spec_Suffix       => No_Name,
65       Spec_Suffix_Loc           => No_Location,
66       Body_Suffix               => No_Array_Element,
67       Current_Body_Suffix       => No_Name,
68       Body_Suffix_Loc           => No_Location,
69       Separate_Suffix           => No_Name,
70       Sep_Suffix_Loc            => No_Location,
71       Specs                     => No_Array_Element,
72       Bodies                    => No_Array_Element,
73       Specification_Exceptions  => No_Array_Element,
74       Implementation_Exceptions => No_Array_Element);
75
76    Project_Empty : constant Project_Data :=
77      (First_Referred_By              => No_Project,
78       Name                           => No_Name,
79       Path_Name                      => No_Name,
80       Display_Path_Name              => No_Name,
81       Location                       => No_Location,
82       Mains                          => Nil_String,
83       Directory                      => No_Name,
84       Display_Directory              => No_Name,
85       Dir_Path                       => null,
86       Library                        => False,
87       Library_Dir                    => No_Name,
88       Display_Library_Dir            => No_Name,
89       Library_Src_Dir                => No_Name,
90       Display_Library_Src_Dir        => No_Name,
91       Library_Name                   => No_Name,
92       Library_Kind                   => Static,
93       Lib_Internal_Name              => No_Name,
94       Lib_Elaboration                => False,
95       Standalone_Library             => False,
96       Lib_Interface_ALIs             => Nil_String,
97       Lib_Auto_Init                  => False,
98       Sources_Present                => True,
99       Sources                        => Nil_String,
100       Source_Dirs                    => Nil_String,
101       Known_Order_Of_Source_Dirs     => True,
102       Object_Directory               => No_Name,
103       Display_Object_Dir             => No_Name,
104       Exec_Directory                 => No_Name,
105       Display_Exec_Dir               => No_Name,
106       Extends                        => No_Project,
107       Extended_By                    => No_Project,
108       Naming                         => Std_Naming_Data,
109       Decl                           => No_Declarations,
110       Imported_Projects              => Empty_Project_List,
111       Ada_Include_Path               => null,
112       Ada_Objects_Path               => null,
113       Include_Path_File              => No_Name,
114       Objects_Path_File_With_Libs    => No_Name,
115       Objects_Path_File_Without_Libs => No_Name,
116       Config_File_Name               => No_Name,
117       Config_File_Temp               => False,
118       Config_Checked                 => False,
119       Language_Independent_Checked   => False,
120       Checked                        => False,
121       Seen                           => False,
122       Flag1                          => False,
123       Flag2                          => False,
124       Depth                          => 0);
125
126    -------------------
127    -- Add_To_Buffer --
128    -------------------
129
130    procedure Add_To_Buffer (S : String) is
131    begin
132       --  If Buffer is too small, double its size
133
134       if Buffer_Last + S'Length > Buffer'Last then
135          declare
136             New_Buffer : constant  String_Access :=
137                            new String (1 .. 2 * Buffer'Last);
138
139          begin
140             New_Buffer (1 .. Buffer_Last) := Buffer (1 .. Buffer_Last);
141             Free (Buffer);
142             Buffer := New_Buffer;
143          end;
144       end if;
145
146       Buffer (Buffer_Last + 1 .. Buffer_Last + S'Length) := S;
147       Buffer_Last := Buffer_Last + S'Length;
148    end Add_To_Buffer;
149
150    -------------------
151    -- Empty_Project --
152    -------------------
153
154    function Empty_Project return Project_Data is
155    begin
156       Initialize;
157       return Project_Empty;
158    end Empty_Project;
159
160    ------------------
161    -- Empty_String --
162    ------------------
163
164    function Empty_String return Name_Id is
165    begin
166       return The_Empty_String;
167    end Empty_String;
168
169    ------------
170    -- Expect --
171    ------------
172
173    procedure Expect (The_Token : Token_Type; Token_Image : String) is
174    begin
175       if Token /= The_Token then
176          Error_Msg (Token_Image & " expected", Token_Ptr);
177       end if;
178    end Expect;
179
180    --------------------------------
181    -- For_Every_Project_Imported --
182    --------------------------------
183
184    procedure For_Every_Project_Imported
185      (By         : Project_Id;
186       With_State : in out State)
187    is
188
189       procedure Check (Project : Project_Id);
190       --  Check if a project has already been seen.
191       --  If not seen, mark it as seen, call Action,
192       --  and check all its imported projects.
193
194       procedure Check (Project : Project_Id) is
195          List : Project_List;
196
197       begin
198          if not Projects.Table (Project).Seen then
199             Projects.Table (Project).Seen := True;
200             Action (Project, With_State);
201
202             List := Projects.Table (Project).Imported_Projects;
203             while List /= Empty_Project_List loop
204                Check (Project_Lists.Table (List).Project);
205                List := Project_Lists.Table (List).Next;
206             end loop;
207          end if;
208       end Check;
209
210    begin
211       for Project in Projects.First .. Projects.Last loop
212          Projects.Table (Project).Seen := False;
213       end loop;
214
215       Check (Project => By);
216    end For_Every_Project_Imported;
217
218    -----------
219    -- Image --
220    -----------
221
222    function Image (Casing : Casing_Type) return String is
223    begin
224       return The_Casing_Images (Casing).all;
225    end Image;
226
227    ----------------
228    -- Initialize --
229    ----------------
230
231    procedure Initialize is
232    begin
233       if not Initialized then
234          Initialized := True;
235          Name_Len := 0;
236          The_Empty_String := Name_Find;
237          Empty_Name := The_Empty_String;
238          Name_Len := 4;
239          Name_Buffer (1 .. 4) := ".ads";
240          Default_Ada_Spec_Suffix := Name_Find;
241          Name_Len := 4;
242          Name_Buffer (1 .. 4) := ".adb";
243          Default_Ada_Body_Suffix := Name_Find;
244          Name_Len := 1;
245          Name_Buffer (1) := '/';
246          Slash := Name_Find;
247          Std_Naming_Data.Current_Spec_Suffix := Default_Ada_Spec_Suffix;
248          Std_Naming_Data.Current_Body_Suffix := Default_Ada_Body_Suffix;
249          Std_Naming_Data.Separate_Suffix     := Default_Ada_Body_Suffix;
250          Register_Default_Naming_Scheme
251            (Language            => Ada_Language,
252             Default_Spec_Suffix => Default_Ada_Spec_Suffix,
253             Default_Body_Suffix => Default_Ada_Body_Suffix);
254          Prj.Env.Initialize;
255          Prj.Attr.Initialize;
256          Set_Name_Table_Byte (Name_Project,  Token_Type'Pos (Tok_Project));
257          Set_Name_Table_Byte (Name_Extends,  Token_Type'Pos (Tok_Extends));
258          Set_Name_Table_Byte (Name_External, Token_Type'Pos (Tok_External));
259       end if;
260    end Initialize;
261
262    ------------------------------------
263    -- Register_Default_Naming_Scheme --
264    ------------------------------------
265
266    procedure Register_Default_Naming_Scheme
267      (Language            : Name_Id;
268       Default_Spec_Suffix : Name_Id;
269       Default_Body_Suffix : Name_Id)
270    is
271       Lang : Name_Id;
272       Suffix : Array_Element_Id;
273       Found : Boolean := False;
274       Element : Array_Element;
275
276    begin
277       --  Get the language name in small letters
278
279       Get_Name_String (Language);
280       Name_Buffer (1 .. Name_Len) := To_Lower (Name_Buffer (1 .. Name_Len));
281       Lang := Name_Find;
282
283       Suffix := Std_Naming_Data.Spec_Suffix;
284       Found := False;
285
286       --  Look for an element of the spec sufix array indexed by the language
287       --  name. If one is found, put the default value.
288
289       while Suffix /= No_Array_Element and then not Found loop
290          Element := Array_Elements.Table (Suffix);
291
292          if Element.Index = Lang then
293             Found := True;
294             Element.Value.Value := Default_Spec_Suffix;
295             Array_Elements.Table (Suffix) := Element;
296
297          else
298             Suffix := Element.Next;
299          end if;
300       end loop;
301
302       --  If none can be found, create a new one.
303
304       if not Found then
305          Element :=
306            (Index => Lang,
307             Index_Case_Sensitive => False,
308             Value => (Kind     => Single,
309                       Location => No_Location,
310                       Default  => False,
311                       Value    => Default_Spec_Suffix),
312             Next  => Std_Naming_Data.Spec_Suffix);
313          Array_Elements.Increment_Last;
314          Array_Elements.Table (Array_Elements.Last) := Element;
315          Std_Naming_Data.Spec_Suffix := Array_Elements.Last;
316       end if;
317
318       Suffix := Std_Naming_Data.Body_Suffix;
319       Found := False;
320
321       --  Look for an element of the body sufix array indexed by the language
322       --  name. If one is found, put the default value.
323
324       while Suffix /= No_Array_Element and then not Found loop
325          Element := Array_Elements.Table (Suffix);
326
327          if Element.Index = Lang then
328             Found := True;
329             Element.Value.Value := Default_Body_Suffix;
330             Array_Elements.Table (Suffix) := Element;
331
332          else
333             Suffix := Element.Next;
334          end if;
335       end loop;
336
337       --  If none can be found, create a new one.
338
339       if not Found then
340          Element :=
341            (Index => Lang,
342             Index_Case_Sensitive => False,
343             Value => (Kind     => Single,
344                       Location => No_Location,
345                       Default  => False,
346                       Value    => Default_Body_Suffix),
347             Next  => Std_Naming_Data.Body_Suffix);
348          Array_Elements.Increment_Last;
349          Array_Elements.Table (Array_Elements.Last) := Element;
350          Std_Naming_Data.Body_Suffix := Array_Elements.Last;
351       end if;
352    end Register_Default_Naming_Scheme;
353
354    ------------
355    --  Reset --
356    ------------
357
358    procedure Reset is
359    begin
360       Projects.Init;
361       Project_Lists.Init;
362       Packages.Init;
363       Arrays.Init;
364       Variable_Elements.Init;
365       String_Elements.Init;
366       Prj.Com.Units.Init;
367       Prj.Com.Units_Htable.Reset;
368    end Reset;
369
370    ------------------------
371    -- Same_Naming_Scheme --
372    ------------------------
373
374    function Same_Naming_Scheme
375      (Left, Right : Naming_Data)
376       return        Boolean
377    is
378    begin
379       return Left.Dot_Replacement = Right.Dot_Replacement
380         and then Left.Casing = Right.Casing
381         and then Left.Current_Spec_Suffix = Right.Current_Spec_Suffix
382         and then Left.Current_Body_Suffix = Right.Current_Body_Suffix
383         and then Left.Separate_Suffix = Right.Separate_Suffix;
384    end Same_Naming_Scheme;
385
386    ----------
387    -- Scan --
388    ----------
389
390    procedure Scan is
391    begin
392       Scanner.Scan;
393    end Scan;
394
395    --------------------------
396    -- Standard_Naming_Data --
397    --------------------------
398
399    function Standard_Naming_Data return Naming_Data is
400    begin
401       Initialize;
402       return Std_Naming_Data;
403    end Standard_Naming_Data;
404
405    -----------
406    -- Value --
407    -----------
408
409    function Value (Image : String) return Casing_Type is
410    begin
411       for Casing in The_Casing_Images'Range loop
412          if To_Lower (Image) = To_Lower (The_Casing_Images (Casing).all) then
413             return Casing;
414          end if;
415       end loop;
416
417       raise Constraint_Error;
418    end Value;
419
420 begin
421    --  Make sure that the standard project file extension is compatible
422    --  with canonical case file naming.
423
424    Canonical_Case_File_Name (Project_File_Extension);
425 end Prj;