OSDN Git Service

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