makeutl.ads (Main_Config_Project): Moved to gpr_util.ads
[gcc.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-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 with Ada.Characters.Handling; use Ada.Characters.Handling;
27
28 with Debug;
29 with Output; use Output;
30 with Osint; use Osint;
31 with Prj.Attr;
32 with Prj.Env;
33 with Prj.Err; use Prj.Err;
34 with Snames; use Snames;
35 with Uintp; use Uintp;
36
37 with System.Case_Util; use System.Case_Util;
38
39 package body Prj is
40
41 Object_Suffix : constant String := Get_Target_Object_Suffix.all;
42 -- File suffix for object files
43
44 Initial_Buffer_Size : constant := 100;
45 -- Initial size for extensible buffer used in Add_To_Buffer
46
47 Current_Mode : Mode := Ada_Only;
48
49 Configuration_Mode : Boolean := False;
50
51 The_Empty_String : Name_Id;
52
53 Name_C_Plus_Plus : Name_Id;
54
55 Default_Ada_Spec_Suffix_Id : File_Name_Type;
56 Default_Ada_Body_Suffix_Id : File_Name_Type;
57 Slash_Id : Path_Name_Type;
58 -- Initialized in Prj.Initialize, then never modified
59
60 subtype Known_Casing is Casing_Type range All_Upper_Case .. Mixed_Case;
61
62 The_Casing_Images : constant array (Known_Casing) of String_Access :=
63 (All_Lower_Case => new String'("lowercase"),
64 All_Upper_Case => new String'("UPPERCASE"),
65 Mixed_Case => new String'("MixedCase"));
66
67 Initialized : Boolean := False;
68
69 Standard_Dot_Replacement : constant File_Name_Type :=
70 File_Name_Type
71 (First_Name_Id + Character'Pos ('-'));
72
73 Std_Naming_Data : constant Naming_Data :=
74 (Dot_Replacement => Standard_Dot_Replacement,
75 Dot_Repl_Loc => No_Location,
76 Casing => All_Lower_Case,
77 Spec_Suffix => No_Array_Element,
78 Ada_Spec_Suffix_Loc => No_Location,
79 Body_Suffix => No_Array_Element,
80 Ada_Body_Suffix_Loc => No_Location,
81 Separate_Suffix => No_File,
82 Sep_Suffix_Loc => No_Location,
83 Specs => No_Array_Element,
84 Bodies => No_Array_Element,
85 Specification_Exceptions => No_Array_Element,
86 Implementation_Exceptions => No_Array_Element,
87 Impl_Suffixes => No_Impl_Suffixes,
88 Supp_Suffixes => No_Supp_Language_Index);
89
90 Project_Empty : constant Project_Data :=
91 (Externally_Built => False,
92 Config => Default_Project_Config,
93 Languages => No_Name_List,
94 First_Referred_By => No_Project,
95 Name => No_Name,
96 Display_Name => No_Name,
97 Path_Name => No_Path,
98 Display_Path_Name => No_Path,
99 Virtual => False,
100 Location => No_Location,
101 Mains => Nil_String,
102 Directory => No_Path,
103 Display_Directory => No_Path,
104 Dir_Path => null,
105 Library => False,
106 Library_Dir => No_Path,
107 Display_Library_Dir => No_Path,
108 Library_Src_Dir => No_Path,
109 Display_Library_Src_Dir => No_Path,
110 Library_ALI_Dir => No_Path,
111 Display_Library_ALI_Dir => No_Path,
112 Library_Name => No_Name,
113 Library_Kind => Static,
114 Lib_Internal_Name => No_Name,
115 Standalone_Library => False,
116 Lib_Interface_ALIs => Nil_String,
117 Lib_Auto_Init => False,
118 Libgnarl_Needed => Unknown,
119 Symbol_Data => No_Symbols,
120 Ada_Sources => Nil_String,
121 Sources => Nil_String,
122 First_Source => No_Source,
123 Last_Source => No_Source,
124 Unit_Based_Language_Name => No_Name,
125 Unit_Based_Language_Index => No_Language_Index,
126 Imported_Directories_Switches => null,
127 Include_Path => null,
128 Include_Data_Set => False,
129 Include_Language => No_Language_Index,
130 Source_Dirs => Nil_String,
131 Known_Order_Of_Source_Dirs => True,
132 Object_Directory => No_Path,
133 Display_Object_Dir => No_Path,
134 Library_TS => Empty_Time_Stamp,
135 Exec_Directory => No_Path,
136 Display_Exec_Dir => No_Path,
137 Extends => No_Project,
138 Extended_By => No_Project,
139 Naming => Std_Naming_Data,
140 First_Language_Processing => No_Language_Index,
141 Decl => No_Declarations,
142 Imported_Projects => Empty_Project_List,
143 All_Imported_Projects => Empty_Project_List,
144 Ada_Include_Path => null,
145 Ada_Objects_Path => null,
146 Objects_Path => null,
147 Include_Path_File => No_Path,
148 Objects_Path_File_With_Libs => No_Path,
149 Objects_Path_File_Without_Libs => No_Path,
150 Config_File_Name => No_Path,
151 Config_File_Temp => False,
152 Linker_Name => No_File,
153 Linker_Path => No_Path,
154 Minimum_Linker_Options => No_Name_List,
155 Config_Checked => False,
156 Checked => False,
157 Seen => False,
158 Need_To_Build_Lib => False,
159 Depth => 0,
160 Unkept_Comments => False,
161 Langs => No_Languages,
162 Supp_Languages => No_Supp_Language_Index,
163 Ada_Sources_Present => True,
164 Other_Sources_Present => True,
165 First_Other_Source => No_Other_Source,
166 Last_Other_Source => No_Other_Source,
167 First_Lang_Processing => Default_First_Language_Processing_Data,
168 Supp_Language_Processing => No_Supp_Language_Index);
169
170 package Temp_Files is new Table.Table
171 (Table_Component_Type => Path_Name_Type,
172 Table_Index_Type => Integer,
173 Table_Low_Bound => 1,
174 Table_Initial => 20,
175 Table_Increment => 100,
176 Table_Name => "Makegpr.Temp_Files");
177 -- Table to store the path name of all the created temporary files, so that
178 -- they can be deleted at the end, or when the program is interrupted.
179
180 -----------------------
181 -- Add_Language_Name --
182 -----------------------
183
184 procedure Add_Language_Name (Name : Name_Id) is
185 begin
186 Last_Language_Index := Last_Language_Index + 1;
187 Language_Indexes.Set (Name, Last_Language_Index);
188 Language_Names.Increment_Last;
189 Language_Names.Table (Last_Language_Index) := Name;
190 end Add_Language_Name;
191
192 -------------------
193 -- Add_To_Buffer --
194 -------------------
195
196 procedure Add_To_Buffer
197 (S : String;
198 To : in out String_Access;
199 Last : in out Natural)
200 is
201 begin
202 if To = null then
203 To := new String (1 .. Initial_Buffer_Size);
204 Last := 0;
205 end if;
206
207 -- If Buffer is too small, double its size
208
209 while Last + S'Length > To'Last loop
210 declare
211 New_Buffer : constant String_Access :=
212 new String (1 .. 2 * Last);
213
214 begin
215 New_Buffer (1 .. Last) := To (1 .. Last);
216 Free (To);
217 To := New_Buffer;
218 end;
219 end loop;
220
221 To (Last + 1 .. Last + S'Length) := S;
222 Last := Last + S'Length;
223 end Add_To_Buffer;
224
225 -----------------------
226 -- Body_Suffix_Id_Of --
227 -----------------------
228
229 function Body_Suffix_Id_Of
230 (In_Tree : Project_Tree_Ref;
231 Language : String;
232 Naming : Naming_Data) return File_Name_Type
233 is
234 Language_Id : Name_Id;
235 Element_Id : Array_Element_Id;
236 Element : Array_Element;
237 Suffix : File_Name_Type := No_File;
238 Lang : Language_Index;
239
240 begin
241 Name_Len := 0;
242 Add_Str_To_Name_Buffer (Language);
243 To_Lower (Name_Buffer (1 .. Name_Len));
244 Language_Id := Name_Find;
245
246 Element_Id := Naming.Body_Suffix;
247 while Element_Id /= No_Array_Element loop
248 Element := In_Tree.Array_Elements.Table (Element_Id);
249
250 if Element.Index = Language_Id then
251 return File_Name_Type (Element.Value.Value);
252 end if;
253
254 Element_Id := Element.Next;
255 end loop;
256
257 if Current_Mode = Multi_Language then
258 Lang := In_Tree.First_Language;
259 while Lang /= No_Language_Index loop
260 if In_Tree.Languages_Data.Table (Lang).Name = Language_Id then
261 Suffix :=
262 In_Tree.Languages_Data.Table
263 (Lang).Config.Naming_Data.Body_Suffix;
264 exit;
265 end if;
266
267 Lang := In_Tree.Languages_Data.Table (Lang).Next;
268 end loop;
269 end if;
270
271 return Suffix;
272 end Body_Suffix_Id_Of;
273
274 --------------------
275 -- Body_Suffix_Of --
276 --------------------
277
278 function Body_Suffix_Of
279 (In_Tree : Project_Tree_Ref;
280 Language : String;
281 Naming : Naming_Data) return String
282 is
283 Language_Id : Name_Id;
284 Element_Id : Array_Element_Id;
285 Element : Array_Element;
286 Suffix : File_Name_Type := No_File;
287 Lang : Language_Index;
288
289 begin
290 Name_Len := 0;
291 Add_Str_To_Name_Buffer (Language);
292 To_Lower (Name_Buffer (1 .. Name_Len));
293 Language_Id := Name_Find;
294
295 Element_Id := Naming.Body_Suffix;
296 while Element_Id /= No_Array_Element loop
297 Element := In_Tree.Array_Elements.Table (Element_Id);
298
299 if Element.Index = Language_Id then
300 return Get_Name_String (Element.Value.Value);
301 end if;
302
303 Element_Id := Element.Next;
304 end loop;
305
306 if Current_Mode = Multi_Language then
307 Lang := In_Tree.First_Language;
308 while Lang /= No_Language_Index loop
309 if In_Tree.Languages_Data.Table (Lang).Name = Language_Id then
310 Suffix :=
311 File_Name_Type
312 (In_Tree.Languages_Data.Table
313 (Lang).Config.Naming_Data.Body_Suffix);
314 exit;
315 end if;
316
317 Lang := In_Tree.Languages_Data.Table (Lang).Next;
318 end loop;
319
320 if Suffix /= No_File then
321 return Get_Name_String (Suffix);
322 end if;
323 end if;
324
325 return "";
326 end Body_Suffix_Of;
327
328 function Body_Suffix_Of
329 (Language : Language_Index;
330 In_Project : Project_Data;
331 In_Tree : Project_Tree_Ref) return String
332 is
333 Suffix_Id : constant File_Name_Type :=
334 Suffix_Of (Language, In_Project, In_Tree);
335 begin
336 if Suffix_Id /= No_File then
337 return Get_Name_String (Suffix_Id);
338 else
339 return "." & Get_Name_String (Language_Names.Table (Language));
340 end if;
341 end Body_Suffix_Of;
342
343 -----------------------------
344 -- Default_Ada_Body_Suffix --
345 -----------------------------
346
347 function Default_Ada_Body_Suffix return File_Name_Type is
348 begin
349 return Default_Ada_Body_Suffix_Id;
350 end Default_Ada_Body_Suffix;
351
352 -----------------------------
353 -- Default_Ada_Spec_Suffix --
354 -----------------------------
355
356 function Default_Ada_Spec_Suffix return File_Name_Type is
357 begin
358 return Default_Ada_Spec_Suffix_Id;
359 end Default_Ada_Spec_Suffix;
360
361 ---------------------------
362 -- Delete_All_Temp_Files --
363 ---------------------------
364
365 procedure Delete_All_Temp_Files is
366 Dont_Care : Boolean;
367 begin
368 if not Debug.Debug_Flag_N then
369 for Index in 1 .. Temp_Files.Last loop
370 Delete_File
371 (Get_Name_String (Temp_Files.Table (Index)), Dont_Care);
372 end loop;
373 end if;
374 end Delete_All_Temp_Files;
375
376 ---------------------
377 -- Dependency_Name --
378 ---------------------
379
380 function Dependency_Name
381 (Source_File_Name : File_Name_Type;
382 Dependency : Dependency_File_Kind) return File_Name_Type
383 is
384 begin
385 case Dependency is
386 when None =>
387 return No_File;
388
389 when Makefile =>
390 return
391 File_Name_Type
392 (Extend_Name
393 (Source_File_Name, Makefile_Dependency_Suffix));
394
395 when ALI_File =>
396 return
397 File_Name_Type
398 (Extend_Name
399 (Source_File_Name, ALI_Dependency_Suffix));
400 end case;
401 end Dependency_Name;
402
403 ---------------------------
404 -- Display_Language_Name --
405 ---------------------------
406
407 procedure Display_Language_Name
408 (In_Tree : Project_Tree_Ref;
409 Language : Language_Index)
410 is
411 begin
412 Get_Name_String (In_Tree.Languages_Data.Table (Language).Display_Name);
413 Write_Str (Name_Buffer (1 .. Name_Len));
414 end Display_Language_Name;
415
416 ---------------------------
417 -- Display_Language_Name --
418 ---------------------------
419
420 procedure Display_Language_Name (Language : Language_Index) is
421 begin
422 Get_Name_String (Language_Names.Table (Language));
423 To_Upper (Name_Buffer (1 .. 1));
424 Write_Str (Name_Buffer (1 .. Name_Len));
425 end Display_Language_Name;
426
427 ----------------
428 -- Empty_File --
429 ----------------
430
431 function Empty_File return File_Name_Type is
432 begin
433 return File_Name_Type (The_Empty_String);
434 end Empty_File;
435
436 -------------------
437 -- Empty_Project --
438 -------------------
439
440 function Empty_Project (Tree : Project_Tree_Ref) return Project_Data is
441 Value : Project_Data;
442
443 begin
444 Prj.Initialize (Tree => No_Project_Tree);
445 Value := Project_Empty;
446 Value.Naming := Tree.Private_Part.Default_Naming;
447
448 return Value;
449 end Empty_Project;
450
451 ------------------
452 -- Empty_String --
453 ------------------
454
455 function Empty_String return Name_Id is
456 begin
457 return The_Empty_String;
458 end Empty_String;
459
460 ------------
461 -- Expect --
462 ------------
463
464 procedure Expect (The_Token : Token_Type; Token_Image : String) is
465 begin
466 if Token /= The_Token then
467 Error_Msg (Token_Image & " expected", Token_Ptr);
468 end if;
469 end Expect;
470
471 -----------------
472 -- Extend_Name --
473 -----------------
474
475 function Extend_Name
476 (File : File_Name_Type;
477 With_Suffix : String) return File_Name_Type
478 is
479 Last : Positive;
480
481 begin
482 Get_Name_String (File);
483 Last := Name_Len + 1;
484
485 while Name_Len /= 0 and then Name_Buffer (Name_Len) /= '.' loop
486 Name_Len := Name_Len - 1;
487 end loop;
488
489 if Name_Len <= 1 then
490 Name_Len := Last;
491 end if;
492
493 for J in With_Suffix'Range loop
494 Name_Buffer (Name_Len) := With_Suffix (J);
495 Name_Len := Name_Len + 1;
496 end loop;
497
498 Name_Len := Name_Len - 1;
499 return Name_Find;
500
501 end Extend_Name;
502
503 --------------------------------
504 -- For_Every_Project_Imported --
505 --------------------------------
506
507 procedure For_Every_Project_Imported
508 (By : Project_Id;
509 In_Tree : Project_Tree_Ref;
510 With_State : in out State)
511 is
512
513 procedure Recursive_Check (Project : Project_Id);
514 -- Check if a project has already been seen. If not seen, mark it as
515 -- Seen, Call Action, and check all its imported projects.
516
517 ---------------------
518 -- Recursive_Check --
519 ---------------------
520
521 procedure Recursive_Check (Project : Project_Id) is
522 List : Project_List;
523 begin
524 if not In_Tree.Projects.Table (Project).Seen then
525 In_Tree.Projects.Table (Project).Seen := True;
526 Action (Project, With_State);
527
528 List :=
529 In_Tree.Projects.Table (Project).Imported_Projects;
530 while List /= Empty_Project_List loop
531 Recursive_Check (In_Tree.Project_Lists.Table (List).Project);
532 List := In_Tree.Project_Lists.Table (List).Next;
533 end loop;
534 end if;
535 end Recursive_Check;
536
537 -- Start of processing for For_Every_Project_Imported
538
539 begin
540 for Project in Project_Table.First ..
541 Project_Table.Last (In_Tree.Projects)
542 loop
543 In_Tree.Projects.Table (Project).Seen := False;
544 end loop;
545
546 Recursive_Check (Project => By);
547 end For_Every_Project_Imported;
548
549 --------------
550 -- Get_Mode --
551 --------------
552
553 function Get_Mode return Mode is
554 begin
555 return Current_Mode;
556 end Get_Mode;
557
558 ----------
559 -- Hash --
560 ----------
561
562 function Hash (Name : File_Name_Type) return Header_Num is
563 begin
564 return Hash (Get_Name_String (Name));
565 end Hash;
566
567 function Hash (Name : Name_Id) return Header_Num is
568 begin
569 return Hash (Get_Name_String (Name));
570 end Hash;
571
572 function Hash (Name : Path_Name_Type) return Header_Num is
573 begin
574 return Hash (Get_Name_String (Name));
575 end Hash;
576
577 -----------
578 -- Image --
579 -----------
580
581 function Image (Casing : Casing_Type) return String is
582 begin
583 return The_Casing_Images (Casing).all;
584 end Image;
585
586 ----------------------
587 -- In_Configuration --
588 ----------------------
589
590 function In_Configuration return Boolean is
591 begin
592 return Configuration_Mode;
593 end In_Configuration;
594
595 ----------------
596 -- Initialize --
597 ----------------
598
599 procedure Initialize (Tree : Project_Tree_Ref) is
600 begin
601 if not Initialized then
602 Initialized := True;
603 Uintp.Initialize;
604 Name_Len := 0;
605 The_Empty_String := Name_Find;
606 Empty_Name := The_Empty_String;
607 Name_Len := 4;
608 Name_Buffer (1 .. 4) := ".ads";
609 Default_Ada_Spec_Suffix_Id := Name_Find;
610 Name_Len := 4;
611 Name_Buffer (1 .. 4) := ".adb";
612 Default_Ada_Body_Suffix_Id := Name_Find;
613 Name_Len := 1;
614 Name_Buffer (1) := '/';
615 Slash_Id := Name_Find;
616 Name_Len := 3;
617 Name_Buffer (1 .. 3) := "c++";
618 Name_C_Plus_Plus := Name_Find;
619
620 Prj.Env.Initialize;
621 Prj.Attr.Initialize;
622 Set_Name_Table_Byte (Name_Project, Token_Type'Pos (Tok_Project));
623 Set_Name_Table_Byte (Name_Extends, Token_Type'Pos (Tok_Extends));
624 Set_Name_Table_Byte (Name_External, Token_Type'Pos (Tok_External));
625
626 Language_Indexes.Reset;
627 Last_Language_Index := No_Language_Index;
628 Language_Names.Init;
629 Add_Language_Name (Name_Ada);
630 Add_Language_Name (Name_C);
631 Add_Language_Name (Name_C_Plus_Plus);
632 end if;
633
634 if Tree /= No_Project_Tree then
635 Reset (Tree);
636 end if;
637 end Initialize;
638
639 -------------------
640 -- Is_A_Language --
641 -------------------
642
643 function Is_A_Language
644 (Tree : Project_Tree_Ref;
645 Data : Project_Data;
646 Language_Name : String) return Boolean
647 is
648 Lang_Id : Name_Id;
649
650 begin
651 Name_Len := 0;
652 Add_Str_To_Name_Buffer (Language_Name);
653 To_Lower (Name_Buffer (1 .. Name_Len));
654 Lang_Id := Name_Find;
655
656 if Get_Mode = Ada_Only then
657 declare
658 List : Name_List_Index := Data.Languages;
659
660 begin
661 while List /= No_Name_List loop
662 if Tree.Name_Lists.Table (List).Name = Lang_Id then
663 return True;
664
665 else
666 List := Tree.Name_Lists.Table (List).Next;
667 end if;
668 end loop;
669 end;
670
671 else
672 declare
673 Lang_Ind : Language_Index;
674 Lang_Data : Language_Data;
675
676 begin
677 Lang_Ind := Data.First_Language_Processing;
678 while Lang_Ind /= No_Language_Index loop
679 Lang_Data := Tree.Languages_Data.Table (Lang_Ind);
680
681 if Lang_Data.Name = Lang_Id then
682 return True;
683 end if;
684
685 Lang_Ind := Lang_Data.Next;
686 end loop;
687 end;
688 end if;
689
690 return False;
691 end Is_A_Language;
692
693 ------------------
694 -- Is_Extending --
695 ------------------
696
697 function Is_Extending
698 (Extending : Project_Id;
699 Extended : Project_Id;
700 In_Tree : Project_Tree_Ref) return Boolean
701 is
702 Proj : Project_Id;
703
704 begin
705 Proj := Extending;
706 while Proj /= No_Project loop
707 if Proj = Extended then
708 return True;
709 end if;
710
711 Proj := In_Tree.Projects.Table (Proj).Extends;
712 end loop;
713
714 return False;
715 end Is_Extending;
716
717 ----------------
718 -- Is_Present --
719 ----------------
720
721 function Is_Present
722 (Language : Language_Index;
723 In_Project : Project_Data;
724 In_Tree : Project_Tree_Ref) return Boolean
725 is
726 begin
727 case Language is
728 when No_Language_Index =>
729 return False;
730
731 when First_Language_Indexes =>
732 return In_Project.Langs (Language);
733
734 when others =>
735 declare
736 Supp : Supp_Language;
737 Supp_Index : Supp_Language_Index := In_Project.Supp_Languages;
738
739 begin
740 while Supp_Index /= No_Supp_Language_Index loop
741 Supp := In_Tree.Present_Languages.Table (Supp_Index);
742
743 if Supp.Index = Language then
744 return Supp.Present;
745 end if;
746
747 Supp_Index := Supp.Next;
748 end loop;
749
750 return False;
751 end;
752 end case;
753 end Is_Present;
754
755 ---------------------------------
756 -- Language_Processing_Data_Of --
757 ---------------------------------
758
759 function Language_Processing_Data_Of
760 (Language : Language_Index;
761 In_Project : Project_Data;
762 In_Tree : Project_Tree_Ref) return Language_Processing_Data
763 is
764 begin
765 case Language is
766 when No_Language_Index =>
767 return Default_Language_Processing_Data;
768
769 when First_Language_Indexes =>
770 return In_Project.First_Lang_Processing (Language);
771
772 when others =>
773 declare
774 Supp : Supp_Language_Data;
775 Supp_Index : Supp_Language_Index :=
776 In_Project.Supp_Language_Processing;
777
778 begin
779 while Supp_Index /= No_Supp_Language_Index loop
780 Supp := In_Tree.Supp_Languages.Table (Supp_Index);
781
782 if Supp.Index = Language then
783 return Supp.Data;
784 end if;
785
786 Supp_Index := Supp.Next;
787 end loop;
788
789 return Default_Language_Processing_Data;
790 end;
791 end case;
792 end Language_Processing_Data_Of;
793
794 -----------------------
795 -- Objects_Exist_For --
796 -----------------------
797
798 function Objects_Exist_For
799 (Language : String;
800 In_Tree : Project_Tree_Ref) return Boolean
801 is
802 Language_Id : Name_Id;
803 Lang : Language_Index;
804
805 begin
806 if Current_Mode = Multi_Language then
807 Name_Len := 0;
808 Add_Str_To_Name_Buffer (Language);
809 To_Lower (Name_Buffer (1 .. Name_Len));
810 Language_Id := Name_Find;
811
812 Lang := In_Tree.First_Language;
813
814 while Lang /= No_Language_Index loop
815 if In_Tree.Languages_Data.Table (Lang).Name = Language_Id then
816 return
817 In_Tree.Languages_Data.Table
818 (Lang).Config.Objects_Generated;
819 end if;
820
821 Lang := In_Tree.Languages_Data.Table (Lang).Next;
822 end loop;
823 end if;
824
825 return True;
826 end Objects_Exist_For;
827
828 -----------------
829 -- Object_Name --
830 -----------------
831
832 function Object_Name
833 (Source_File_Name : File_Name_Type)
834 return File_Name_Type
835 is
836 begin
837 return Extend_Name (Source_File_Name, Object_Suffix);
838 end Object_Name;
839
840 ----------------------
841 -- Record_Temp_File --
842 ----------------------
843
844 procedure Record_Temp_File (Path : Path_Name_Type) is
845 begin
846 Temp_Files.Increment_Last;
847 Temp_Files.Table (Temp_Files.Last) := Path;
848 end Record_Temp_File;
849
850 ------------------------------------
851 -- Register_Default_Naming_Scheme --
852 ------------------------------------
853
854 procedure Register_Default_Naming_Scheme
855 (Language : Name_Id;
856 Default_Spec_Suffix : File_Name_Type;
857 Default_Body_Suffix : File_Name_Type;
858 In_Tree : Project_Tree_Ref)
859 is
860 Lang : Name_Id;
861 Suffix : Array_Element_Id;
862 Found : Boolean := False;
863 Element : Array_Element;
864
865 begin
866 -- Get the language name in small letters
867
868 Get_Name_String (Language);
869 Name_Buffer (1 .. Name_Len) := To_Lower (Name_Buffer (1 .. Name_Len));
870 Lang := Name_Find;
871
872 Suffix := In_Tree.Private_Part.Default_Naming.Spec_Suffix;
873 Found := False;
874
875 -- Look for an element of the spec sufix array indexed by the language
876 -- name. If one is found, put the default value.
877
878 while Suffix /= No_Array_Element and then not Found loop
879 Element := In_Tree.Array_Elements.Table (Suffix);
880
881 if Element.Index = Lang then
882 Found := True;
883 Element.Value.Value := Name_Id (Default_Spec_Suffix);
884 In_Tree.Array_Elements.Table (Suffix) := Element;
885
886 else
887 Suffix := Element.Next;
888 end if;
889 end loop;
890
891 -- If none can be found, create a new one
892
893 if not Found then
894 Element :=
895 (Index => Lang,
896 Src_Index => 0,
897 Index_Case_Sensitive => False,
898 Value => (Project => No_Project,
899 Kind => Single,
900 Location => No_Location,
901 Default => False,
902 Value => Name_Id (Default_Spec_Suffix),
903 Index => 0),
904 Next => In_Tree.Private_Part.Default_Naming.Spec_Suffix);
905 Array_Element_Table.Increment_Last (In_Tree.Array_Elements);
906 In_Tree.Array_Elements.Table
907 (Array_Element_Table.Last (In_Tree.Array_Elements)) :=
908 Element;
909 In_Tree.Private_Part.Default_Naming.Spec_Suffix :=
910 Array_Element_Table.Last (In_Tree.Array_Elements);
911 end if;
912
913 Suffix := In_Tree.Private_Part.Default_Naming.Body_Suffix;
914 Found := False;
915
916 -- Look for an element of the body sufix array indexed by the language
917 -- name. If one is found, put the default value.
918
919 while Suffix /= No_Array_Element and then not Found loop
920 Element := In_Tree.Array_Elements.Table (Suffix);
921
922 if Element.Index = Lang then
923 Found := True;
924 Element.Value.Value := Name_Id (Default_Body_Suffix);
925 In_Tree.Array_Elements.Table (Suffix) := Element;
926
927 else
928 Suffix := Element.Next;
929 end if;
930 end loop;
931
932 -- If none can be found, create a new one
933
934 if not Found then
935 Element :=
936 (Index => Lang,
937 Src_Index => 0,
938 Index_Case_Sensitive => False,
939 Value => (Project => No_Project,
940 Kind => Single,
941 Location => No_Location,
942 Default => False,
943 Value => Name_Id (Default_Body_Suffix),
944 Index => 0),
945 Next => In_Tree.Private_Part.Default_Naming.Body_Suffix);
946 Array_Element_Table.Increment_Last
947 (In_Tree.Array_Elements);
948 In_Tree.Array_Elements.Table
949 (Array_Element_Table.Last (In_Tree.Array_Elements))
950 := Element;
951 In_Tree.Private_Part.Default_Naming.Body_Suffix :=
952 Array_Element_Table.Last (In_Tree.Array_Elements);
953 end if;
954 end Register_Default_Naming_Scheme;
955
956 -----------
957 -- Reset --
958 -----------
959
960 procedure Reset (Tree : Project_Tree_Ref) is
961
962 -- Def_Lang : constant Name_Node :=
963 -- (Name => Name_Ada,
964 -- Next => No_Name_List);
965 -- Why is the above commented out ???
966
967 begin
968 Prj.Env.Initialize;
969
970 -- gprmake tables
971
972 Present_Language_Table.Init (Tree.Present_Languages);
973 Supp_Suffix_Table.Init (Tree.Supp_Suffixes);
974 Supp_Language_Table.Init (Tree.Supp_Languages);
975 Other_Source_Table.Init (Tree.Other_Sources);
976
977 -- Visible tables
978
979 Language_Data_Table.Init (Tree.Languages_Data);
980 Name_List_Table.Init (Tree.Name_Lists);
981 String_Element_Table.Init (Tree.String_Elements);
982 Variable_Element_Table.Init (Tree.Variable_Elements);
983 Array_Element_Table.Init (Tree.Array_Elements);
984 Array_Table.Init (Tree.Arrays);
985 Package_Table.Init (Tree.Packages);
986 Project_List_Table.Init (Tree.Project_Lists);
987 Project_Table.Init (Tree.Projects);
988 Source_Data_Table.Init (Tree.Sources);
989 Alternate_Language_Table.Init (Tree.Alt_Langs);
990 Unit_Table.Init (Tree.Units);
991 Units_Htable.Reset (Tree.Units_HT);
992 Files_Htable.Reset (Tree.Files_HT);
993 Source_Paths_Htable.Reset (Tree.Source_Paths_HT);
994
995 -- Private part table
996
997 Naming_Table.Init (Tree.Private_Part.Namings);
998 Naming_Table.Increment_Last (Tree.Private_Part.Namings);
999 Tree.Private_Part.Namings.Table
1000 (Naming_Table.Last (Tree.Private_Part.Namings)) := Std_Naming_Data;
1001 Path_File_Table.Init (Tree.Private_Part.Path_Files);
1002 Source_Path_Table.Init (Tree.Private_Part.Source_Paths);
1003 Object_Path_Table.Init (Tree.Private_Part.Object_Paths);
1004 Tree.Private_Part.Default_Naming := Std_Naming_Data;
1005
1006 if Current_Mode = Ada_Only then
1007 Register_Default_Naming_Scheme
1008 (Language => Name_Ada,
1009 Default_Spec_Suffix => Default_Ada_Spec_Suffix,
1010 Default_Body_Suffix => Default_Ada_Body_Suffix,
1011 In_Tree => Tree);
1012 Tree.Private_Part.Default_Naming.Separate_Suffix :=
1013 Default_Ada_Body_Suffix;
1014 end if;
1015 end Reset;
1016
1017 ------------------------
1018 -- Same_Naming_Scheme --
1019 ------------------------
1020
1021 function Same_Naming_Scheme
1022 (Left, Right : Naming_Data) return Boolean
1023 is
1024 begin
1025 return Left.Dot_Replacement = Right.Dot_Replacement
1026 and then Left.Casing = Right.Casing
1027 and then Left.Separate_Suffix = Right.Separate_Suffix;
1028 end Same_Naming_Scheme;
1029
1030 ---------
1031 -- Set --
1032 ---------
1033
1034 procedure Set
1035 (Language : Language_Index;
1036 Present : Boolean;
1037 In_Project : in out Project_Data;
1038 In_Tree : Project_Tree_Ref)
1039 is
1040 begin
1041 case Language is
1042 when No_Language_Index =>
1043 null;
1044
1045 when First_Language_Indexes =>
1046 In_Project.Langs (Language) := Present;
1047
1048 when others =>
1049 declare
1050 Supp : Supp_Language;
1051 Supp_Index : Supp_Language_Index := In_Project.Supp_Languages;
1052
1053 begin
1054 while Supp_Index /= No_Supp_Language_Index loop
1055 Supp := In_Tree.Present_Languages.Table
1056 (Supp_Index);
1057
1058 if Supp.Index = Language then
1059 In_Tree.Present_Languages.Table
1060 (Supp_Index).Present := Present;
1061 return;
1062 end if;
1063
1064 Supp_Index := Supp.Next;
1065 end loop;
1066
1067 Supp := (Index => Language, Present => Present,
1068 Next => In_Project.Supp_Languages);
1069 Present_Language_Table.Increment_Last
1070 (In_Tree.Present_Languages);
1071 Supp_Index := Present_Language_Table.Last
1072 (In_Tree.Present_Languages);
1073 In_Tree.Present_Languages.Table (Supp_Index) :=
1074 Supp;
1075 In_Project.Supp_Languages := Supp_Index;
1076 end;
1077 end case;
1078 end Set;
1079
1080 procedure Set
1081 (Language_Processing : Language_Processing_Data;
1082 For_Language : Language_Index;
1083 In_Project : in out Project_Data;
1084 In_Tree : Project_Tree_Ref)
1085 is
1086 begin
1087 case For_Language is
1088 when No_Language_Index =>
1089 null;
1090
1091 when First_Language_Indexes =>
1092 In_Project.First_Lang_Processing (For_Language) :=
1093 Language_Processing;
1094
1095 when others =>
1096 declare
1097 Supp : Supp_Language_Data;
1098 Supp_Index : Supp_Language_Index;
1099
1100 begin
1101 Supp_Index := In_Project.Supp_Language_Processing;
1102 while Supp_Index /= No_Supp_Language_Index loop
1103 Supp := In_Tree.Supp_Languages.Table (Supp_Index);
1104
1105 if Supp.Index = For_Language then
1106 In_Tree.Supp_Languages.Table
1107 (Supp_Index).Data := Language_Processing;
1108 return;
1109 end if;
1110
1111 Supp_Index := Supp.Next;
1112 end loop;
1113
1114 Supp := (Index => For_Language, Data => Language_Processing,
1115 Next => In_Project.Supp_Language_Processing);
1116 Supp_Language_Table.Increment_Last
1117 (In_Tree.Supp_Languages);
1118 Supp_Index := Supp_Language_Table.Last
1119 (In_Tree.Supp_Languages);
1120 In_Tree.Supp_Languages.Table (Supp_Index) := Supp;
1121 In_Project.Supp_Language_Processing := Supp_Index;
1122 end;
1123 end case;
1124 end Set;
1125
1126 procedure Set
1127 (Suffix : File_Name_Type;
1128 For_Language : Language_Index;
1129 In_Project : in out Project_Data;
1130 In_Tree : Project_Tree_Ref)
1131 is
1132 begin
1133 case For_Language is
1134 when No_Language_Index =>
1135 null;
1136
1137 when First_Language_Indexes =>
1138 In_Project.Naming.Impl_Suffixes (For_Language) := Suffix;
1139
1140 when others =>
1141 declare
1142 Supp : Supp_Suffix;
1143 Supp_Index : Supp_Language_Index :=
1144 In_Project.Naming.Supp_Suffixes;
1145
1146 begin
1147 while Supp_Index /= No_Supp_Language_Index loop
1148 Supp := In_Tree.Supp_Suffixes.Table
1149 (Supp_Index);
1150
1151 if Supp.Index = For_Language then
1152 In_Tree.Supp_Suffixes.Table
1153 (Supp_Index).Suffix := Suffix;
1154 return;
1155 end if;
1156
1157 Supp_Index := Supp.Next;
1158 end loop;
1159
1160 Supp := (Index => For_Language, Suffix => Suffix,
1161 Next => In_Project.Naming.Supp_Suffixes);
1162 Supp_Suffix_Table.Increment_Last
1163 (In_Tree.Supp_Suffixes);
1164 Supp_Index := Supp_Suffix_Table.Last
1165 (In_Tree.Supp_Suffixes);
1166 In_Tree.Supp_Suffixes.Table (Supp_Index) := Supp;
1167 In_Project.Naming.Supp_Suffixes := Supp_Index;
1168 end;
1169 end case;
1170 end Set;
1171
1172 ---------------------
1173 -- Set_Body_Suffix --
1174 ---------------------
1175
1176 procedure Set_Body_Suffix
1177 (In_Tree : Project_Tree_Ref;
1178 Language : String;
1179 Naming : in out Naming_Data;
1180 Suffix : File_Name_Type)
1181 is
1182 Language_Id : Name_Id;
1183 Element : Array_Element;
1184
1185 begin
1186 Name_Len := 0;
1187 Add_Str_To_Name_Buffer (Language);
1188 To_Lower (Name_Buffer (1 .. Name_Len));
1189 Language_Id := Name_Find;
1190
1191 Element :=
1192 (Index => Language_Id,
1193 Src_Index => 0,
1194 Index_Case_Sensitive => False,
1195 Value =>
1196 (Kind => Single,
1197 Project => No_Project,
1198 Location => No_Location,
1199 Default => False,
1200 Value => Name_Id (Suffix),
1201 Index => 0),
1202 Next => Naming.Body_Suffix);
1203
1204 Array_Element_Table.Increment_Last (In_Tree.Array_Elements);
1205 Naming.Body_Suffix :=
1206 Array_Element_Table.Last (In_Tree.Array_Elements);
1207 In_Tree.Array_Elements.Table (Naming.Body_Suffix) := Element;
1208 end Set_Body_Suffix;
1209
1210 --------------------------
1211 -- Set_In_Configuration --
1212 --------------------------
1213
1214 procedure Set_In_Configuration (Value : Boolean) is
1215 begin
1216 Configuration_Mode := Value;
1217 end Set_In_Configuration;
1218
1219 --------------
1220 -- Set_Mode --
1221 --------------
1222
1223 procedure Set_Mode (New_Mode : Mode) is
1224 begin
1225 Current_Mode := New_Mode;
1226 end Set_Mode;
1227
1228 ---------------------
1229 -- Set_Spec_Suffix --
1230 ---------------------
1231
1232 procedure Set_Spec_Suffix
1233 (In_Tree : Project_Tree_Ref;
1234 Language : String;
1235 Naming : in out Naming_Data;
1236 Suffix : File_Name_Type)
1237 is
1238 Language_Id : Name_Id;
1239 Element : Array_Element;
1240
1241 begin
1242 Name_Len := 0;
1243 Add_Str_To_Name_Buffer (Language);
1244 To_Lower (Name_Buffer (1 .. Name_Len));
1245 Language_Id := Name_Find;
1246
1247 Element :=
1248 (Index => Language_Id,
1249 Src_Index => 0,
1250 Index_Case_Sensitive => False,
1251 Value =>
1252 (Kind => Single,
1253 Project => No_Project,
1254 Location => No_Location,
1255 Default => False,
1256 Value => Name_Id (Suffix),
1257 Index => 0),
1258 Next => Naming.Spec_Suffix);
1259
1260 Array_Element_Table.Increment_Last (In_Tree.Array_Elements);
1261 Naming.Spec_Suffix :=
1262 Array_Element_Table.Last (In_Tree.Array_Elements);
1263 In_Tree.Array_Elements.Table (Naming.Spec_Suffix) := Element;
1264 end Set_Spec_Suffix;
1265
1266 -----------
1267 -- Slash --
1268 -----------
1269
1270 function Slash return Path_Name_Type is
1271 begin
1272 return Slash_Id;
1273 end Slash;
1274
1275 -----------------------
1276 -- Spec_Suffix_Id_Of --
1277 -----------------------
1278
1279 function Spec_Suffix_Id_Of
1280 (In_Tree : Project_Tree_Ref;
1281 Language : String;
1282 Naming : Naming_Data) return File_Name_Type
1283 is
1284 Language_Id : Name_Id;
1285 Element_Id : Array_Element_Id;
1286 Element : Array_Element;
1287 Suffix : File_Name_Type := No_File;
1288 Lang : Language_Index;
1289
1290 begin
1291 Name_Len := 0;
1292 Add_Str_To_Name_Buffer (Language);
1293 To_Lower (Name_Buffer (1 .. Name_Len));
1294 Language_Id := Name_Find;
1295
1296 Element_Id := Naming.Spec_Suffix;
1297
1298 while Element_Id /= No_Array_Element loop
1299 Element := In_Tree.Array_Elements.Table (Element_Id);
1300
1301 if Element.Index = Language_Id then
1302 return File_Name_Type (Element.Value.Value);
1303 end if;
1304
1305 Element_Id := Element.Next;
1306 end loop;
1307
1308 if Current_Mode = Multi_Language then
1309 Lang := In_Tree.First_Language;
1310
1311 while Lang /= No_Language_Index loop
1312 if In_Tree.Languages_Data.Table (Lang).Name = Language_Id then
1313 Suffix :=
1314 In_Tree.Languages_Data.Table
1315 (Lang).Config.Naming_Data.Spec_Suffix;
1316 exit;
1317 end if;
1318
1319 Lang := In_Tree.Languages_Data.Table (Lang).Next;
1320 end loop;
1321 end if;
1322
1323 return Suffix;
1324 end Spec_Suffix_Id_Of;
1325
1326 --------------------
1327 -- Spec_Suffix_Of --
1328 --------------------
1329
1330 function Spec_Suffix_Of
1331 (In_Tree : Project_Tree_Ref;
1332 Language : String;
1333 Naming : Naming_Data) return String
1334 is
1335 Language_Id : Name_Id;
1336 Element_Id : Array_Element_Id;
1337 Element : Array_Element;
1338 Suffix : File_Name_Type := No_File;
1339 Lang : Language_Index;
1340
1341 begin
1342 Name_Len := 0;
1343 Add_Str_To_Name_Buffer (Language);
1344 To_Lower (Name_Buffer (1 .. Name_Len));
1345 Language_Id := Name_Find;
1346
1347 Element_Id := Naming.Spec_Suffix;
1348
1349 while Element_Id /= No_Array_Element loop
1350 Element := In_Tree.Array_Elements.Table (Element_Id);
1351
1352 if Element.Index = Language_Id then
1353 return Get_Name_String (Element.Value.Value);
1354 end if;
1355
1356 Element_Id := Element.Next;
1357 end loop;
1358
1359 if Current_Mode = Multi_Language then
1360 Lang := In_Tree.First_Language;
1361
1362 while Lang /= No_Language_Index loop
1363 if In_Tree.Languages_Data.Table (Lang).Name = Language_Id then
1364 Suffix :=
1365 File_Name_Type
1366 (In_Tree.Languages_Data.Table
1367 (Lang).Config.Naming_Data.Spec_Suffix);
1368 exit;
1369 end if;
1370
1371 Lang := In_Tree.Languages_Data.Table (Lang).Next;
1372 end loop;
1373
1374 if Suffix /= No_File then
1375 return Get_Name_String (Suffix);
1376 end if;
1377 end if;
1378
1379 return "";
1380 end Spec_Suffix_Of;
1381
1382 --------------------------
1383 -- Standard_Naming_Data --
1384 --------------------------
1385
1386 function Standard_Naming_Data
1387 (Tree : Project_Tree_Ref := No_Project_Tree) return Naming_Data
1388 is
1389 begin
1390 if Tree = No_Project_Tree then
1391 Prj.Initialize (Tree => No_Project_Tree);
1392 return Std_Naming_Data;
1393
1394 else
1395 return Tree.Private_Part.Default_Naming;
1396 end if;
1397 end Standard_Naming_Data;
1398
1399 ---------------
1400 -- Suffix_Of --
1401 ---------------
1402
1403 function Suffix_Of
1404 (Language : Language_Index;
1405 In_Project : Project_Data;
1406 In_Tree : Project_Tree_Ref) return File_Name_Type
1407 is
1408 begin
1409 case Language is
1410 when No_Language_Index =>
1411 return No_File;
1412
1413 when First_Language_Indexes =>
1414 return In_Project.Naming.Impl_Suffixes (Language);
1415
1416 when others =>
1417 declare
1418 Supp : Supp_Suffix;
1419 Supp_Index : Supp_Language_Index :=
1420 In_Project.Naming.Supp_Suffixes;
1421
1422 begin
1423 while Supp_Index /= No_Supp_Language_Index loop
1424 Supp := In_Tree.Supp_Suffixes.Table (Supp_Index);
1425
1426 if Supp.Index = Language then
1427 return Supp.Suffix;
1428 end if;
1429
1430 Supp_Index := Supp.Next;
1431 end loop;
1432
1433 return No_File;
1434 end;
1435 end case;
1436 end Suffix_Of;
1437
1438 -------------------
1439 -- Switches_Name --
1440 -------------------
1441
1442 function Switches_Name
1443 (Source_File_Name : File_Name_Type) return File_Name_Type
1444 is
1445 begin
1446 return Extend_Name (Source_File_Name, Switches_Dependency_Suffix);
1447 end Switches_Name;
1448
1449 ---------------------------
1450 -- There_Are_Ada_Sources --
1451 ---------------------------
1452
1453 function There_Are_Ada_Sources
1454 (In_Tree : Project_Tree_Ref;
1455 Project : Project_Id) return Boolean
1456 is
1457 Prj : Project_Id;
1458
1459 begin
1460 Prj := Project;
1461 while Prj /= No_Project loop
1462 if In_Tree.Projects.Table (Prj).Ada_Sources /= Nil_String then
1463 return True;
1464 end if;
1465
1466 Prj := In_Tree.Projects.Table (Prj).Extends;
1467 end loop;
1468
1469 return False;
1470 end There_Are_Ada_Sources;
1471
1472 -----------
1473 -- Value --
1474 -----------
1475
1476 function Value (Image : String) return Casing_Type is
1477 begin
1478 for Casing in The_Casing_Images'Range loop
1479 if To_Lower (Image) = To_Lower (The_Casing_Images (Casing).all) then
1480 return Casing;
1481 end if;
1482 end loop;
1483
1484 raise Constraint_Error;
1485 end Value;
1486
1487 begin
1488 -- Make sure that the standard config and user project file extensions are
1489 -- compatible with canonical case file naming.
1490
1491 Canonical_Case_File_Name (Config_Project_File_Extension);
1492 Canonical_Case_File_Name (Project_File_Extension);
1493 end Prj;