OSDN Git Service

Daily bump.
[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-2008, 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 Table;
36 with Uintp;    use Uintp;
37
38 with System.Case_Util; use System.Case_Util;
39 with System.HTable;
40
41 package body Prj is
42
43    Object_Suffix : constant String := Get_Target_Object_Suffix.all;
44    --  File suffix for object files
45
46    Initial_Buffer_Size : constant := 100;
47    --  Initial size for extensible buffer used in Add_To_Buffer
48
49    Current_Mode : Mode := Ada_Only;
50
51    Configuration_Mode : Boolean := False;
52
53    The_Empty_String : 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
88    Project_Empty : constant Project_Data :=
89                      (Qualifier                      => Unspecified,
90                       Externally_Built               => False,
91                       Config                         => Default_Project_Config,
92                       Languages                      => No_Name_List,
93                       First_Referred_By              => No_Project,
94                       Name                           => No_Name,
95                       Display_Name                   => No_Name,
96                       Path                           => No_Path_Information,
97                       Virtual                        => False,
98                       Location                       => No_Location,
99                       Mains                          => Nil_String,
100                       Directory                      => No_Path_Information,
101                       Dir_Path                       => null,
102                       Library                        => False,
103                       Library_Dir                    => No_Path_Information,
104                       Library_Src_Dir                => No_Path_Information,
105                       Library_ALI_Dir                => No_Path_Information,
106                       Library_Name                   => No_Name,
107                       Library_Kind                   => Static,
108                       Lib_Internal_Name              => No_Name,
109                       Standalone_Library             => False,
110                       Lib_Interface_ALIs             => Nil_String,
111                       Lib_Auto_Init                  => False,
112                       Libgnarl_Needed                => Unknown,
113                       Symbol_Data                    => No_Symbols,
114                       Ada_Sources_Present            => True,
115                       Other_Sources_Present          => True,
116                       Ada_Sources                    => Nil_String,
117                       First_Source                   => No_Source,
118                       Last_Source                    => No_Source,
119                       Interfaces_Defined             => False,
120                       Unit_Based_Language_Name       => No_Name,
121                       Unit_Based_Language_Index      => No_Language_Index,
122                       Imported_Directories_Switches  => null,
123                       Include_Path                   => null,
124                       Include_Data_Set               => False,
125                       Include_Language               => No_Language_Index,
126                       Source_Dirs                    => Nil_String,
127                       Known_Order_Of_Source_Dirs     => True,
128                       Object_Directory               => No_Path_Information,
129                       Library_TS                     => Empty_Time_Stamp,
130                       Exec_Directory                 => No_Path_Information,
131                       Extends                        => No_Project,
132                       Extended_By                    => No_Project,
133                       Naming                         => Std_Naming_Data,
134                       First_Language_Processing      => No_Language_Index,
135                       Decl                           => No_Declarations,
136                       Imported_Projects              => Empty_Project_List,
137                       All_Imported_Projects          => Empty_Project_List,
138                       Ada_Include_Path               => null,
139                       Ada_Objects_Path               => null,
140                       Objects_Path                   => null,
141                       Include_Path_File              => No_Path,
142                       Objects_Path_File_With_Libs    => No_Path,
143                       Objects_Path_File_Without_Libs => No_Path,
144                       Config_File_Name               => No_Path,
145                       Config_File_Temp               => False,
146                       Config_Checked                 => False,
147                       Checked                        => False,
148                       Seen                           => False,
149                       Need_To_Build_Lib              => False,
150                       Depth                          => 0,
151                       Unkept_Comments                => False);
152
153    package Temp_Files is new Table.Table
154      (Table_Component_Type => Path_Name_Type,
155       Table_Index_Type     => Integer,
156       Table_Low_Bound      => 1,
157       Table_Initial        => 20,
158       Table_Increment      => 100,
159       Table_Name           => "Makegpr.Temp_Files");
160    --  Table to store the path name of all the created temporary files, so that
161    --  they can be deleted at the end, or when the program is interrupted.
162
163    -------------------
164    -- Add_To_Buffer --
165    -------------------
166
167    procedure Add_To_Buffer
168      (S    : String;
169       To   : in out String_Access;
170       Last : in out Natural)
171    is
172    begin
173       if To = null then
174          To := new String (1 .. Initial_Buffer_Size);
175          Last := 0;
176       end if;
177
178       --  If Buffer is too small, double its size
179
180       while Last + S'Length > To'Last loop
181          declare
182             New_Buffer : constant  String_Access :=
183                            new String (1 .. 2 * Last);
184
185          begin
186             New_Buffer (1 .. Last) := To (1 .. Last);
187             Free (To);
188             To := New_Buffer;
189          end;
190       end loop;
191
192       To (Last + 1 .. Last + S'Length) := S;
193       Last := Last + S'Length;
194    end Add_To_Buffer;
195
196    -----------------------
197    -- Body_Suffix_Id_Of --
198    -----------------------
199
200    function Body_Suffix_Id_Of
201      (In_Tree  : Project_Tree_Ref;
202       Language : String;
203       Naming   : Naming_Data) return File_Name_Type
204    is
205       Language_Id : Name_Id;
206
207    begin
208       Name_Len := 0;
209       Add_Str_To_Name_Buffer (Language);
210       To_Lower (Name_Buffer (1 .. Name_Len));
211       Language_Id := Name_Find;
212
213       return
214         Body_Suffix_Id_Of
215           (In_Tree     => In_Tree,
216            Language_Id => Language_Id,
217            Naming      => Naming);
218    end Body_Suffix_Id_Of;
219
220    -----------------------
221    -- Body_Suffix_Id_Of --
222    -----------------------
223
224    function Body_Suffix_Id_Of
225      (In_Tree     : Project_Tree_Ref;
226       Language_Id : Name_Id;
227       Naming      : Naming_Data) return File_Name_Type
228    is
229       Element_Id : Array_Element_Id;
230       Element    : Array_Element;
231       Suffix     : File_Name_Type := No_File;
232       Lang       : Language_Index;
233
234    begin
235       --  ??? This seems to be only for Ada_Only mode...
236       Element_Id := Naming.Body_Suffix;
237       while Element_Id /= No_Array_Element loop
238          Element := In_Tree.Array_Elements.Table (Element_Id);
239
240          if Element.Index = Language_Id then
241             return File_Name_Type (Element.Value.Value);
242          end if;
243
244          Element_Id := Element.Next;
245       end loop;
246
247       if Current_Mode = Multi_Language then
248          Lang := In_Tree.First_Language;
249          while Lang /= No_Language_Index loop
250             if In_Tree.Languages_Data.Table (Lang).Name = Language_Id then
251                Suffix :=
252                  In_Tree.Languages_Data.Table
253                    (Lang).Config.Naming_Data.Body_Suffix;
254                exit;
255             end if;
256
257             Lang := In_Tree.Languages_Data.Table (Lang).Next;
258          end loop;
259       end if;
260
261       return Suffix;
262    end Body_Suffix_Id_Of;
263
264    --------------------
265    -- Body_Suffix_Of --
266    --------------------
267
268    function Body_Suffix_Of
269      (In_Tree  : Project_Tree_Ref;
270       Language : String;
271       Naming   : Naming_Data) return String
272    is
273       Language_Id : Name_Id;
274       Element_Id  : Array_Element_Id;
275       Element     : Array_Element;
276       Suffix      : File_Name_Type := No_File;
277       Lang        : Language_Index;
278
279    begin
280       Name_Len := 0;
281       Add_Str_To_Name_Buffer (Language);
282       To_Lower (Name_Buffer (1 .. Name_Len));
283       Language_Id := Name_Find;
284
285       Element_Id := Naming.Body_Suffix;
286       while Element_Id /= No_Array_Element loop
287          Element := In_Tree.Array_Elements.Table (Element_Id);
288
289          if Element.Index = Language_Id then
290             return Get_Name_String (Element.Value.Value);
291          end if;
292
293          Element_Id := Element.Next;
294       end loop;
295
296       if Current_Mode = Multi_Language then
297          Lang := In_Tree.First_Language;
298          while Lang /= No_Language_Index loop
299             if In_Tree.Languages_Data.Table (Lang).Name = Language_Id then
300                Suffix :=
301                  File_Name_Type
302                    (In_Tree.Languages_Data.Table
303                         (Lang).Config.Naming_Data.Body_Suffix);
304                exit;
305             end if;
306
307             Lang := In_Tree.Languages_Data.Table (Lang).Next;
308          end loop;
309
310          if Suffix /= No_File then
311             return Get_Name_String (Suffix);
312          end if;
313       end if;
314
315       return "";
316    end Body_Suffix_Of;
317
318    -----------------------------
319    -- Default_Ada_Body_Suffix --
320    -----------------------------
321
322    function Default_Ada_Body_Suffix return File_Name_Type is
323    begin
324       return Default_Ada_Body_Suffix_Id;
325    end Default_Ada_Body_Suffix;
326
327    -----------------------------
328    -- Default_Ada_Spec_Suffix --
329    -----------------------------
330
331    function Default_Ada_Spec_Suffix return File_Name_Type is
332    begin
333       return Default_Ada_Spec_Suffix_Id;
334    end Default_Ada_Spec_Suffix;
335
336    ---------------------------
337    -- Delete_All_Temp_Files --
338    ---------------------------
339
340    procedure Delete_All_Temp_Files is
341       Dont_Care : Boolean;
342       pragma Warnings (Off, Dont_Care);
343    begin
344       if not Debug.Debug_Flag_N then
345          for Index in 1 .. Temp_Files.Last loop
346             Delete_File
347               (Get_Name_String (Temp_Files.Table (Index)), Dont_Care);
348          end loop;
349       end if;
350    end Delete_All_Temp_Files;
351
352    ---------------------
353    -- Dependency_Name --
354    ---------------------
355
356    function Dependency_Name
357      (Source_File_Name : File_Name_Type;
358       Dependency       : Dependency_File_Kind) return File_Name_Type
359    is
360    begin
361       case Dependency is
362          when None =>
363             return No_File;
364
365          when Makefile =>
366             return
367               File_Name_Type
368                 (Extend_Name
369                    (Source_File_Name, Makefile_Dependency_Suffix));
370
371          when ALI_File =>
372             return
373               File_Name_Type
374                 (Extend_Name
375                    (Source_File_Name, ALI_Dependency_Suffix));
376       end case;
377    end Dependency_Name;
378
379    ---------------------------
380    -- Display_Language_Name --
381    ---------------------------
382
383    procedure Display_Language_Name
384      (In_Tree  : Project_Tree_Ref;
385       Language : Language_Index)
386    is
387    begin
388       Get_Name_String (In_Tree.Languages_Data.Table (Language).Display_Name);
389       Write_Str (Name_Buffer (1 .. Name_Len));
390    end Display_Language_Name;
391
392    ----------------
393    -- Empty_File --
394    ----------------
395
396    function Empty_File return File_Name_Type is
397    begin
398       return File_Name_Type (The_Empty_String);
399    end Empty_File;
400
401    -------------------
402    -- Empty_Project --
403    -------------------
404
405    function Empty_Project (Tree : Project_Tree_Ref) return Project_Data is
406       Value : Project_Data;
407
408    begin
409       Prj.Initialize (Tree => No_Project_Tree);
410       Value := Project_Empty;
411       Value.Naming := Tree.Private_Part.Default_Naming;
412
413       return Value;
414    end Empty_Project;
415
416    ------------------
417    -- Empty_String --
418    ------------------
419
420    function Empty_String return Name_Id is
421    begin
422       return The_Empty_String;
423    end Empty_String;
424
425    ------------
426    -- Expect --
427    ------------
428
429    procedure Expect (The_Token : Token_Type; Token_Image : String) is
430    begin
431       if Token /= The_Token then
432          Error_Msg (Token_Image & " expected", Token_Ptr);
433       end if;
434    end Expect;
435
436    -----------------
437    -- Extend_Name --
438    -----------------
439
440    function Extend_Name
441      (File        : File_Name_Type;
442       With_Suffix : String) return File_Name_Type
443    is
444       Last : Positive;
445
446    begin
447       Get_Name_String (File);
448       Last := Name_Len + 1;
449
450       while Name_Len /= 0 and then Name_Buffer (Name_Len) /= '.' loop
451          Name_Len := Name_Len - 1;
452       end loop;
453
454       if Name_Len <= 1 then
455          Name_Len := Last;
456       end if;
457
458       for J in With_Suffix'Range loop
459          Name_Buffer (Name_Len) := With_Suffix (J);
460          Name_Len := Name_Len + 1;
461       end loop;
462
463       Name_Len := Name_Len - 1;
464       return Name_Find;
465
466    end Extend_Name;
467
468    --------------------------------
469    -- For_Every_Project_Imported --
470    --------------------------------
471
472    procedure For_Every_Project_Imported
473      (By         : Project_Id;
474       In_Tree    : Project_Tree_Ref;
475       With_State : in out State)
476    is
477
478       procedure Recursive_Check (Project : Project_Id);
479       --  Check if a project has already been seen. If not seen, mark it as
480       --  Seen, Call Action, and check all its imported projects.
481
482       ---------------------
483       -- Recursive_Check --
484       ---------------------
485
486       procedure Recursive_Check (Project : Project_Id) is
487          List : Project_List;
488       begin
489          if not In_Tree.Projects.Table (Project).Seen then
490             In_Tree.Projects.Table (Project).Seen := True;
491             Action (Project, With_State);
492
493             List := In_Tree.Projects.Table (Project).Imported_Projects;
494             while List /= Empty_Project_List loop
495                Recursive_Check (In_Tree.Project_Lists.Table (List).Project);
496                List := In_Tree.Project_Lists.Table (List).Next;
497             end loop;
498          end if;
499       end Recursive_Check;
500
501    --  Start of processing for For_Every_Project_Imported
502
503    begin
504       for Project in Project_Table.First ..
505                      Project_Table.Last (In_Tree.Projects)
506       loop
507          In_Tree.Projects.Table (Project).Seen := False;
508       end loop;
509
510       Recursive_Check (Project => By);
511    end For_Every_Project_Imported;
512
513    --------------
514    -- Get_Mode --
515    --------------
516
517    function Get_Mode return Mode is
518    begin
519       return Current_Mode;
520    end Get_Mode;
521
522    ----------
523    -- Hash --
524    ----------
525
526    function Hash is new System.HTable.Hash (Header_Num => Header_Num);
527    --  Used in implementation of other functions Hash below
528
529    function Hash (Name : File_Name_Type) return Header_Num is
530    begin
531       return Hash (Get_Name_String (Name));
532    end Hash;
533
534    function Hash (Name : Name_Id) return Header_Num is
535    begin
536       return Hash (Get_Name_String (Name));
537    end Hash;
538
539    function Hash (Name : Path_Name_Type) return Header_Num is
540    begin
541       return Hash (Get_Name_String (Name));
542    end Hash;
543
544    function Hash (Project : Project_Id) return Header_Num is
545    begin
546       return Header_Num (Project mod Max_Header_Num);
547    end Hash;
548
549    -----------
550    -- Image --
551    -----------
552
553    function Image (Casing : Casing_Type) return String is
554    begin
555       return The_Casing_Images (Casing).all;
556    end Image;
557
558    ----------------------
559    -- In_Configuration --
560    ----------------------
561
562    function In_Configuration return Boolean is
563    begin
564       return Configuration_Mode;
565    end In_Configuration;
566
567    ----------------
568    -- Initialize --
569    ----------------
570
571    procedure Initialize (Tree : Project_Tree_Ref) is
572    begin
573       if not Initialized then
574          Initialized := True;
575          Uintp.Initialize;
576          Name_Len := 0;
577          The_Empty_String := Name_Find;
578          Empty_Name := The_Empty_String;
579          Empty_File_Name := File_Name_Type (The_Empty_String);
580          Name_Len := 4;
581          Name_Buffer (1 .. 4) := ".ads";
582          Default_Ada_Spec_Suffix_Id := Name_Find;
583          Name_Len := 4;
584          Name_Buffer (1 .. 4) := ".adb";
585          Default_Ada_Body_Suffix_Id := Name_Find;
586          Name_Len := 1;
587          Name_Buffer (1) := '/';
588          Slash_Id := Name_Find;
589
590          Prj.Env.Initialize;
591          Prj.Attr.Initialize;
592          Set_Name_Table_Byte (Name_Project,  Token_Type'Pos (Tok_Project));
593          Set_Name_Table_Byte (Name_Extends,  Token_Type'Pos (Tok_Extends));
594          Set_Name_Table_Byte (Name_External, Token_Type'Pos (Tok_External));
595       end if;
596
597       if Tree /= No_Project_Tree then
598          Reset (Tree);
599       end if;
600    end Initialize;
601
602    -------------------
603    -- Is_A_Language --
604    -------------------
605
606    function Is_A_Language
607      (Tree          : Project_Tree_Ref;
608       Data          : Project_Data;
609       Language_Name : Name_Id) return Boolean
610    is
611    begin
612       if Get_Mode = Ada_Only then
613          declare
614             List : Name_List_Index := Data.Languages;
615          begin
616             while List /= No_Name_List loop
617                if Tree.Name_Lists.Table (List).Name = Language_Name then
618                   return True;
619                else
620                   List := Tree.Name_Lists.Table (List).Next;
621                end if;
622             end loop;
623          end;
624
625       else
626          declare
627             Lang_Ind  : Language_Index := Data.First_Language_Processing;
628             Lang_Data : Language_Data;
629
630          begin
631             while Lang_Ind /= No_Language_Index loop
632                Lang_Data := Tree.Languages_Data.Table (Lang_Ind);
633
634                if Lang_Data.Name = Language_Name then
635                   return True;
636                end if;
637
638                Lang_Ind := Lang_Data.Next;
639             end loop;
640          end;
641       end if;
642
643       return False;
644    end Is_A_Language;
645
646    ------------------
647    -- Is_Extending --
648    ------------------
649
650    function Is_Extending
651      (Extending : Project_Id;
652       Extended  : Project_Id;
653       In_Tree   : Project_Tree_Ref) return Boolean
654    is
655       Proj : Project_Id;
656
657    begin
658       Proj := Extending;
659       while Proj /= No_Project loop
660          if Proj = Extended then
661             return True;
662          end if;
663
664          Proj := In_Tree.Projects.Table (Proj).Extends;
665       end loop;
666
667       return False;
668    end Is_Extending;
669
670    -----------------------
671    -- Objects_Exist_For --
672    -----------------------
673
674    function Objects_Exist_For
675      (Language : String;
676       In_Tree  : Project_Tree_Ref) return Boolean
677    is
678       Language_Id : Name_Id;
679       Lang        : Language_Index;
680
681    begin
682       if Current_Mode = Multi_Language then
683          Name_Len := 0;
684          Add_Str_To_Name_Buffer (Language);
685          To_Lower (Name_Buffer (1 .. Name_Len));
686          Language_Id := Name_Find;
687
688          Lang := In_Tree.First_Language;
689          while Lang /= No_Language_Index loop
690             if In_Tree.Languages_Data.Table (Lang).Name = Language_Id then
691                return
692                  In_Tree.Languages_Data.Table
693                    (Lang).Config.Object_Generated;
694             end if;
695
696             Lang := In_Tree.Languages_Data.Table (Lang).Next;
697          end loop;
698       end if;
699
700       return True;
701    end Objects_Exist_For;
702
703    -----------------
704    -- Object_Name --
705    -----------------
706
707    function Object_Name
708      (Source_File_Name : File_Name_Type)
709       return File_Name_Type
710    is
711    begin
712       return Extend_Name (Source_File_Name, Object_Suffix);
713    end Object_Name;
714
715    ----------------------
716    -- Record_Temp_File --
717    ----------------------
718
719    procedure Record_Temp_File (Path : Path_Name_Type) is
720    begin
721       Temp_Files.Increment_Last;
722       Temp_Files.Table (Temp_Files.Last) := Path;
723    end Record_Temp_File;
724
725    ------------------------------------
726    -- Register_Default_Naming_Scheme --
727    ------------------------------------
728
729    procedure Register_Default_Naming_Scheme
730      (Language            : Name_Id;
731       Default_Spec_Suffix : File_Name_Type;
732       Default_Body_Suffix : File_Name_Type;
733       In_Tree             : Project_Tree_Ref)
734    is
735       Lang : Name_Id;
736       Suffix : Array_Element_Id;
737       Found : Boolean := False;
738       Element : Array_Element;
739
740    begin
741       --  Get the language name in small letters
742
743       Get_Name_String (Language);
744       Name_Buffer (1 .. Name_Len) := To_Lower (Name_Buffer (1 .. Name_Len));
745       Lang := Name_Find;
746
747       --  Look for an element of the spec suffix array indexed by the language
748       --  name. If one is found, put the default value.
749
750       Suffix := In_Tree.Private_Part.Default_Naming.Spec_Suffix;
751       Found := False;
752       while Suffix /= No_Array_Element and then not Found loop
753          Element := In_Tree.Array_Elements.Table (Suffix);
754
755          if Element.Index = Lang then
756             Found := True;
757             Element.Value.Value := Name_Id (Default_Spec_Suffix);
758             In_Tree.Array_Elements.Table (Suffix) := Element;
759
760          else
761             Suffix := Element.Next;
762          end if;
763       end loop;
764
765       --  If none can be found, create a new one
766
767       if not Found then
768          Element :=
769            (Index     => Lang,
770             Src_Index => 0,
771             Index_Case_Sensitive => False,
772             Value => (Project  => No_Project,
773                       Kind     => Single,
774                       Location => No_Location,
775                       Default  => False,
776                       Value    => Name_Id (Default_Spec_Suffix),
777                       Index    => 0),
778             Next  => In_Tree.Private_Part.Default_Naming.Spec_Suffix);
779          Array_Element_Table.Increment_Last (In_Tree.Array_Elements);
780          In_Tree.Array_Elements.Table
781            (Array_Element_Table.Last (In_Tree.Array_Elements)) :=
782             Element;
783          In_Tree.Private_Part.Default_Naming.Spec_Suffix :=
784            Array_Element_Table.Last (In_Tree.Array_Elements);
785       end if;
786
787       --  Look for an element of the body suffix array indexed by the language
788       --  name. If one is found, put the default value.
789
790       Suffix := In_Tree.Private_Part.Default_Naming.Body_Suffix;
791       Found := False;
792       while Suffix /= No_Array_Element and then not Found loop
793          Element := In_Tree.Array_Elements.Table (Suffix);
794
795          if Element.Index = Lang then
796             Found := True;
797             Element.Value.Value := Name_Id (Default_Body_Suffix);
798             In_Tree.Array_Elements.Table (Suffix) := Element;
799
800          else
801             Suffix := Element.Next;
802          end if;
803       end loop;
804
805       --  If none can be found, create a new one
806
807       if not Found then
808          Element :=
809            (Index     => Lang,
810             Src_Index => 0,
811             Index_Case_Sensitive => False,
812             Value => (Project  => No_Project,
813                       Kind     => Single,
814                       Location => No_Location,
815                       Default  => False,
816                       Value    => Name_Id (Default_Body_Suffix),
817                       Index    => 0),
818             Next  => In_Tree.Private_Part.Default_Naming.Body_Suffix);
819          Array_Element_Table.Increment_Last
820            (In_Tree.Array_Elements);
821          In_Tree.Array_Elements.Table
822            (Array_Element_Table.Last (In_Tree.Array_Elements))
823              := Element;
824          In_Tree.Private_Part.Default_Naming.Body_Suffix :=
825            Array_Element_Table.Last (In_Tree.Array_Elements);
826       end if;
827    end Register_Default_Naming_Scheme;
828
829    -----------
830    -- Reset --
831    -----------
832
833    procedure Reset (Tree : Project_Tree_Ref) is
834
835       --  Def_Lang : constant Name_Node :=
836       --             (Name => Name_Ada,
837       --              Next => No_Name_List);
838       --  Why is the above commented out ???
839
840    begin
841       Prj.Env.Initialize;
842
843       --  Visible tables
844
845       Language_Data_Table.Init      (Tree.Languages_Data);
846       Name_List_Table.Init          (Tree.Name_Lists);
847       String_Element_Table.Init     (Tree.String_Elements);
848       Variable_Element_Table.Init   (Tree.Variable_Elements);
849       Array_Element_Table.Init      (Tree.Array_Elements);
850       Array_Table.Init              (Tree.Arrays);
851       Package_Table.Init            (Tree.Packages);
852       Project_List_Table.Init       (Tree.Project_Lists);
853       Project_Table.Init            (Tree.Projects);
854       Source_Data_Table.Init        (Tree.Sources);
855       Alternate_Language_Table.Init (Tree.Alt_Langs);
856       Unit_Table.Init               (Tree.Units);
857       Units_Htable.Reset            (Tree.Units_HT);
858       Files_Htable.Reset            (Tree.Files_HT);
859       Source_Paths_Htable.Reset     (Tree.Source_Paths_HT);
860
861       --  Private part table
862
863       Naming_Table.Init             (Tree.Private_Part.Namings);
864       Naming_Table.Increment_Last   (Tree.Private_Part.Namings);
865       Tree.Private_Part.Namings.Table
866         (Naming_Table.Last (Tree.Private_Part.Namings)) := Std_Naming_Data;
867       Path_File_Table.Init        (Tree.Private_Part.Path_Files);
868       Source_Path_Table.Init      (Tree.Private_Part.Source_Paths);
869       Object_Path_Table.Init      (Tree.Private_Part.Object_Paths);
870       Tree.Private_Part.Default_Naming := Std_Naming_Data;
871
872       if Current_Mode = Ada_Only then
873          Register_Default_Naming_Scheme
874            (Language            => Name_Ada,
875             Default_Spec_Suffix => Default_Ada_Spec_Suffix,
876             Default_Body_Suffix => Default_Ada_Body_Suffix,
877             In_Tree             => Tree);
878          Tree.Private_Part.Default_Naming.Separate_Suffix :=
879            Default_Ada_Body_Suffix;
880       end if;
881    end Reset;
882
883    ------------------------
884    -- Same_Naming_Scheme --
885    ------------------------
886
887    function Same_Naming_Scheme
888      (Left, Right : Naming_Data) return Boolean
889    is
890    begin
891       return Left.Dot_Replacement = Right.Dot_Replacement
892         and then Left.Casing = Right.Casing
893         and then Left.Separate_Suffix = Right.Separate_Suffix;
894    end Same_Naming_Scheme;
895
896    ---------------------
897    -- Set_Body_Suffix --
898    ---------------------
899
900    procedure Set_Body_Suffix
901      (In_Tree  : Project_Tree_Ref;
902       Language : String;
903       Naming   : in out Naming_Data;
904       Suffix   : File_Name_Type)
905    is
906       Language_Id : Name_Id;
907       Element     : Array_Element;
908
909    begin
910       Name_Len := 0;
911       Add_Str_To_Name_Buffer (Language);
912       To_Lower (Name_Buffer (1 .. Name_Len));
913       Language_Id := Name_Find;
914
915       Element :=
916         (Index                => Language_Id,
917          Src_Index            => 0,
918          Index_Case_Sensitive => False,
919          Value                =>
920            (Kind     => Single,
921             Project  => No_Project,
922             Location => No_Location,
923             Default  => False,
924             Value    => Name_Id (Suffix),
925             Index    => 0),
926          Next                 => Naming.Body_Suffix);
927
928       Array_Element_Table.Increment_Last (In_Tree.Array_Elements);
929       Naming.Body_Suffix :=
930          Array_Element_Table.Last (In_Tree.Array_Elements);
931       In_Tree.Array_Elements.Table (Naming.Body_Suffix) := Element;
932    end Set_Body_Suffix;
933
934    --------------------------
935    -- Set_In_Configuration --
936    --------------------------
937
938    procedure Set_In_Configuration (Value : Boolean) is
939    begin
940       Configuration_Mode := Value;
941    end Set_In_Configuration;
942
943    --------------
944    -- Set_Mode --
945    --------------
946
947    procedure Set_Mode (New_Mode : Mode) is
948    begin
949       Current_Mode := New_Mode;
950       case New_Mode is
951          when Ada_Only =>
952             Default_Language_Is_Ada := True;
953             Must_Check_Configuration := False;
954          when Multi_Language =>
955             Default_Language_Is_Ada := False;
956             Must_Check_Configuration := True;
957       end case;
958    end Set_Mode;
959
960    ---------------------
961    -- Set_Spec_Suffix --
962    ---------------------
963
964    procedure Set_Spec_Suffix
965      (In_Tree  : Project_Tree_Ref;
966       Language : String;
967       Naming   : in out Naming_Data;
968       Suffix   : File_Name_Type)
969    is
970       Language_Id : Name_Id;
971       Element     : Array_Element;
972
973    begin
974       Name_Len := 0;
975       Add_Str_To_Name_Buffer (Language);
976       To_Lower (Name_Buffer (1 .. Name_Len));
977       Language_Id := Name_Find;
978
979       Element :=
980         (Index                => Language_Id,
981          Src_Index            => 0,
982          Index_Case_Sensitive => False,
983          Value                =>
984            (Kind     => Single,
985             Project  => No_Project,
986             Location => No_Location,
987             Default  => False,
988             Value    => Name_Id (Suffix),
989             Index    => 0),
990          Next                 => Naming.Spec_Suffix);
991
992       Array_Element_Table.Increment_Last (In_Tree.Array_Elements);
993       Naming.Spec_Suffix :=
994         Array_Element_Table.Last (In_Tree.Array_Elements);
995       In_Tree.Array_Elements.Table (Naming.Spec_Suffix) := Element;
996    end Set_Spec_Suffix;
997
998    -----------
999    -- Slash --
1000    -----------
1001
1002    function Slash return Path_Name_Type is
1003    begin
1004       return Slash_Id;
1005    end Slash;
1006
1007    -----------------------
1008    -- Spec_Suffix_Id_Of --
1009    -----------------------
1010
1011    function Spec_Suffix_Id_Of
1012      (In_Tree  : Project_Tree_Ref;
1013       Language : String;
1014       Naming   : Naming_Data) return File_Name_Type
1015    is
1016       Language_Id : Name_Id;
1017
1018    begin
1019       Name_Len := 0;
1020       Add_Str_To_Name_Buffer (Language);
1021       To_Lower (Name_Buffer (1 .. Name_Len));
1022       Language_Id := Name_Find;
1023
1024       return
1025         Spec_Suffix_Id_Of
1026           (In_Tree     => In_Tree,
1027            Language_Id => Language_Id,
1028            Naming      => Naming);
1029    end Spec_Suffix_Id_Of;
1030
1031    -----------------------
1032    -- Spec_Suffix_Id_Of --
1033    -----------------------
1034
1035    function Spec_Suffix_Id_Of
1036      (In_Tree     : Project_Tree_Ref;
1037       Language_Id : Name_Id;
1038       Naming      : Naming_Data) return File_Name_Type
1039    is
1040       Element_Id : Array_Element_Id;
1041       Element    : Array_Element;
1042       Suffix     : File_Name_Type := No_File;
1043       Lang       : Language_Index;
1044
1045    begin
1046       Element_Id := Naming.Spec_Suffix;
1047       while Element_Id /= No_Array_Element loop
1048          Element := In_Tree.Array_Elements.Table (Element_Id);
1049
1050          if Element.Index = Language_Id then
1051             return File_Name_Type (Element.Value.Value);
1052          end if;
1053
1054          Element_Id := Element.Next;
1055       end loop;
1056
1057       if Current_Mode = Multi_Language then
1058          Lang := In_Tree.First_Language;
1059          while Lang /= No_Language_Index loop
1060             if In_Tree.Languages_Data.Table (Lang).Name = Language_Id then
1061                Suffix :=
1062                  In_Tree.Languages_Data.Table
1063                    (Lang).Config.Naming_Data.Spec_Suffix;
1064                exit;
1065             end if;
1066
1067             Lang := In_Tree.Languages_Data.Table (Lang).Next;
1068          end loop;
1069       end if;
1070
1071       return Suffix;
1072    end Spec_Suffix_Id_Of;
1073
1074    --------------------
1075    -- Spec_Suffix_Of --
1076    --------------------
1077
1078    function Spec_Suffix_Of
1079      (In_Tree  : Project_Tree_Ref;
1080       Language : String;
1081       Naming   : Naming_Data) return String
1082    is
1083       Language_Id : Name_Id;
1084       Element_Id  : Array_Element_Id;
1085       Element     : Array_Element;
1086       Suffix      : File_Name_Type := No_File;
1087       Lang        : Language_Index;
1088
1089    begin
1090       Name_Len := 0;
1091       Add_Str_To_Name_Buffer (Language);
1092       To_Lower (Name_Buffer (1 .. Name_Len));
1093       Language_Id := Name_Find;
1094
1095       Element_Id := Naming.Spec_Suffix;
1096       while Element_Id /= No_Array_Element loop
1097          Element := In_Tree.Array_Elements.Table (Element_Id);
1098
1099          if Element.Index = Language_Id then
1100             return Get_Name_String (Element.Value.Value);
1101          end if;
1102
1103          Element_Id := Element.Next;
1104       end loop;
1105
1106       if Current_Mode = Multi_Language then
1107          Lang := In_Tree.First_Language;
1108          while Lang /= No_Language_Index loop
1109             if In_Tree.Languages_Data.Table (Lang).Name = Language_Id then
1110                Suffix :=
1111                  File_Name_Type
1112                    (In_Tree.Languages_Data.Table
1113                       (Lang).Config.Naming_Data.Spec_Suffix);
1114                exit;
1115             end if;
1116
1117             Lang := In_Tree.Languages_Data.Table (Lang).Next;
1118          end loop;
1119
1120          if Suffix /= No_File then
1121             return Get_Name_String (Suffix);
1122          end if;
1123       end if;
1124
1125       return "";
1126    end Spec_Suffix_Of;
1127
1128    --------------------------
1129    -- Standard_Naming_Data --
1130    --------------------------
1131
1132    function Standard_Naming_Data
1133      (Tree : Project_Tree_Ref := No_Project_Tree) return Naming_Data
1134    is
1135    begin
1136       if Tree = No_Project_Tree then
1137          Prj.Initialize (Tree => No_Project_Tree);
1138          return Std_Naming_Data;
1139       else
1140          return Tree.Private_Part.Default_Naming;
1141       end if;
1142    end Standard_Naming_Data;
1143
1144    -------------------
1145    -- Switches_Name --
1146    -------------------
1147
1148    function Switches_Name
1149      (Source_File_Name : File_Name_Type) return File_Name_Type
1150    is
1151    begin
1152       return Extend_Name (Source_File_Name, Switches_Dependency_Suffix);
1153    end Switches_Name;
1154
1155    -----------
1156    -- Value --
1157    -----------
1158
1159    function Value (Image : String) return Casing_Type is
1160    begin
1161       for Casing in The_Casing_Images'Range loop
1162          if To_Lower (Image) = To_Lower (The_Casing_Images (Casing).all) then
1163             return Casing;
1164          end if;
1165       end loop;
1166
1167       raise Constraint_Error;
1168    end Value;
1169
1170 begin
1171    --  Make sure that the standard config and user project file extensions are
1172    --  compatible with canonical case file naming.
1173
1174    Canonical_Case_File_Name (Config_Project_File_Extension);
1175    Canonical_Case_File_Name (Project_File_Extension);
1176 end Prj;