]>
Commit | Line | Data |
---|---|---|
19235870 RK |
1 | ------------------------------------------------------------------------------ |
2 | -- -- | |
3 | -- GNAT COMPILER COMPONENTS -- | |
4 | -- -- | |
5 | -- P R J -- | |
6 | -- -- | |
7 | -- B o d y -- | |
8 | -- -- | |
fbf5a39b | 9 | -- Copyright (C) 2001-2003 Free Software Foundation, Inc. -- |
19235870 RK |
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. -- | |
71ff80dc | 23 | -- Extensive contributions were provided by Ada Core Technologies Inc. -- |
19235870 RK |
24 | -- -- |
25 | ------------------------------------------------------------------------------ | |
26 | ||
27 | with Ada.Characters.Handling; use Ada.Characters.Handling; | |
fbf5a39b AC |
28 | |
29 | with Namet; use Namet; | |
30 | with Osint; use Osint; | |
19235870 RK |
31 | with Prj.Attr; |
32 | with Prj.Com; | |
33 | with Prj.Env; | |
fbf5a39b AC |
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; | |
19235870 RK |
39 | |
40 | package body Prj is | |
41 | ||
fbf5a39b | 42 | The_Empty_String : Name_Id; |
07fc65c4 GB |
43 | |
44 | Ada_Language : constant Name_Id := Name_Ada; | |
b30668b7 | 45 | |
19235870 RK |
46 | subtype Known_Casing is Casing_Type range All_Upper_Case .. Mixed_Case; |
47 | ||
fbf5a39b | 48 | The_Casing_Images : constant array (Known_Casing) of String_Access := |
19235870 RK |
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 ('-'); | |
19235870 RK |
57 | |
58 | Std_Naming_Data : Naming_Data := | |
b30668b7 VC |
59 | (Current_Language => No_Name, |
60 | Dot_Replacement => Standard_Dot_Replacement, | |
61 | Dot_Repl_Loc => No_Location, | |
62 | Casing => All_Lower_Case, | |
fbf5a39b | 63 | Spec_Suffix => No_Array_Element, |
b30668b7 VC |
64 | Current_Spec_Suffix => No_Name, |
65 | Spec_Suffix_Loc => No_Location, | |
fbf5a39b AC |
66 | Body_Suffix => No_Array_Element, |
67 | Current_Body_Suffix => No_Name, | |
68 | Body_Suffix_Loc => No_Location, | |
b30668b7 VC |
69 | Separate_Suffix => No_Name, |
70 | Sep_Suffix_Loc => No_Location, | |
fbf5a39b | 71 | Specs => No_Array_Element, |
b30668b7 VC |
72 | Bodies => No_Array_Element, |
73 | Specification_Exceptions => No_Array_Element, | |
74 | Implementation_Exceptions => No_Array_Element); | |
75 | ||
76 | Project_Empty : constant Project_Data := | |
fbf5a39b AC |
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; | |
b30668b7 | 149 | |
19235870 RK |
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 | ||
fbf5a39b | 164 | function Empty_String return Name_Id is |
19235870 RK |
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 | |
fbf5a39b | 176 | Error_Msg (Token_Image & " expected", Token_Ptr); |
19235870 RK |
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 | |
07fc65c4 | 199 | Projects.Table (Project).Seen := True; |
19235870 RK |
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; | |
fbf5a39b AC |
235 | Name_Len := 0; |
236 | The_Empty_String := Name_Find; | |
237 | Empty_Name := The_Empty_String; | |
19235870 RK |
238 | Name_Len := 4; |
239 | Name_Buffer (1 .. 4) := ".ads"; | |
b30668b7 VC |
240 | Default_Ada_Spec_Suffix := Name_Find; |
241 | Name_Len := 4; | |
242 | Name_Buffer (1 .. 4) := ".adb"; | |
fbf5a39b AC |
243 | Default_Ada_Body_Suffix := Name_Find; |
244 | Name_Len := 1; | |
245 | Name_Buffer (1) := '/'; | |
246 | Slash := Name_Find; | |
b30668b7 | 247 | Std_Naming_Data.Current_Spec_Suffix := Default_Ada_Spec_Suffix; |
fbf5a39b AC |
248 | Std_Naming_Data.Current_Body_Suffix := Default_Ada_Body_Suffix; |
249 | Std_Naming_Data.Separate_Suffix := Default_Ada_Body_Suffix; | |
07fc65c4 GB |
250 | Register_Default_Naming_Scheme |
251 | (Language => Ada_Language, | |
252 | Default_Spec_Suffix => Default_Ada_Spec_Suffix, | |
fbf5a39b | 253 | Default_Body_Suffix => Default_Ada_Body_Suffix); |
19235870 RK |
254 | Prj.Env.Initialize; |
255 | Prj.Attr.Initialize; | |
fbc9a404 VC |
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)); | |
19235870 RK |
259 | end if; |
260 | end Initialize; | |
261 | ||
07fc65c4 GB |
262 | ------------------------------------ |
263 | -- Register_Default_Naming_Scheme -- | |
264 | ------------------------------------ | |
265 | ||
266 | procedure Register_Default_Naming_Scheme | |
267 | (Language : Name_Id; | |
268 | Default_Spec_Suffix : Name_Id; | |
fbf5a39b | 269 | Default_Body_Suffix : Name_Id) |
07fc65c4 GB |
270 | is |
271 | Lang : Name_Id; | |
272 | Suffix : Array_Element_Id; | |
273 | Found : Boolean := False; | |
274 | Element : Array_Element; | |
275 | ||
07fc65c4 | 276 | begin |
fbf5a39b | 277 | -- Get the language name in small letters |
07fc65c4 GB |
278 | |
279 | Get_Name_String (Language); | |
280 | Name_Buffer (1 .. Name_Len) := To_Lower (Name_Buffer (1 .. Name_Len)); | |
281 | Lang := Name_Find; | |
282 | ||
fbf5a39b | 283 | Suffix := Std_Naming_Data.Spec_Suffix; |
07fc65c4 GB |
284 | Found := False; |
285 | ||
fbf5a39b AC |
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 | ||
07fc65c4 GB |
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; | |
fbf5a39b | 294 | Element.Value.Value := Default_Spec_Suffix; |
07fc65c4 GB |
295 | Array_Elements.Table (Suffix) := Element; |
296 | ||
297 | else | |
298 | Suffix := Element.Next; | |
299 | end if; | |
300 | end loop; | |
301 | ||
fbf5a39b AC |
302 | -- If none can be found, create a new one. |
303 | ||
07fc65c4 GB |
304 | if not Found then |
305 | Element := | |
306 | (Index => Lang, | |
fbf5a39b | 307 | Index_Case_Sensitive => False, |
07fc65c4 GB |
308 | Value => (Kind => Single, |
309 | Location => No_Location, | |
310 | Default => False, | |
fbf5a39b AC |
311 | Value => Default_Spec_Suffix), |
312 | Next => Std_Naming_Data.Spec_Suffix); | |
07fc65c4 GB |
313 | Array_Elements.Increment_Last; |
314 | Array_Elements.Table (Array_Elements.Last) := Element; | |
fbf5a39b | 315 | Std_Naming_Data.Spec_Suffix := Array_Elements.Last; |
07fc65c4 GB |
316 | end if; |
317 | ||
fbf5a39b | 318 | Suffix := Std_Naming_Data.Body_Suffix; |
07fc65c4 GB |
319 | Found := False; |
320 | ||
fbf5a39b AC |
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 | ||
07fc65c4 GB |
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; | |
fbf5a39b | 329 | Element.Value.Value := Default_Body_Suffix; |
07fc65c4 GB |
330 | Array_Elements.Table (Suffix) := Element; |
331 | ||
332 | else | |
333 | Suffix := Element.Next; | |
334 | end if; | |
335 | end loop; | |
336 | ||
fbf5a39b AC |
337 | -- If none can be found, create a new one. |
338 | ||
07fc65c4 GB |
339 | if not Found then |
340 | Element := | |
341 | (Index => Lang, | |
fbf5a39b | 342 | Index_Case_Sensitive => False, |
07fc65c4 GB |
343 | Value => (Kind => Single, |
344 | Location => No_Location, | |
345 | Default => False, | |
fbf5a39b AC |
346 | Value => Default_Body_Suffix), |
347 | Next => Std_Naming_Data.Body_Suffix); | |
07fc65c4 GB |
348 | Array_Elements.Increment_Last; |
349 | Array_Elements.Table (Array_Elements.Last) := Element; | |
fbf5a39b | 350 | Std_Naming_Data.Body_Suffix := Array_Elements.Last; |
07fc65c4 GB |
351 | end if; |
352 | end Register_Default_Naming_Scheme; | |
353 | ||
19235870 RK |
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 | |
b30668b7 | 381 | and then Left.Current_Spec_Suffix = Right.Current_Spec_Suffix |
fbf5a39b | 382 | and then Left.Current_Body_Suffix = Right.Current_Body_Suffix |
b30668b7 | 383 | and then Left.Separate_Suffix = Right.Separate_Suffix; |
19235870 RK |
384 | end Same_Naming_Scheme; |
385 | ||
386 | ---------- | |
387 | -- Scan -- | |
388 | ---------- | |
389 | ||
390 | procedure Scan is | |
391 | begin | |
fbf5a39b | 392 | Scanner.Scan; |
19235870 RK |
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 | ||
07fc65c4 GB |
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); | |
19235870 | 425 | end Prj; |