OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [prj.adb] - Blame information for rev 768

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
------------------------------------------------------------------------------
2
--                                                                          --
3
--                         GNAT COMPILER COMPONENTS                         --
4
--                                                                          --
5
--                                  P R J                                   --
6
--                                                                          --
7
--                                 B o d y                                  --
8
--                                                                          --
9
--          Copyright (C) 2001-2012, 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 Debug;
27
with Opt;
28
with Osint;    use Osint;
29
with Output;   use Output;
30
with Prj.Attr;
31
with Prj.Com;
32
with Prj.Err;  use Prj.Err;
33
with Snames;   use Snames;
34
with Uintp;    use Uintp;
35
 
36
with Ada.Characters.Handling;    use Ada.Characters.Handling;
37
with Ada.Containers.Ordered_Sets;
38
with Ada.Unchecked_Deallocation;
39
 
40
with GNAT.Case_Util;            use GNAT.Case_Util;
41
with GNAT.Directory_Operations; use GNAT.Directory_Operations;
42
with GNAT.HTable;
43
 
44
package body Prj is
45
 
46
   type Restricted_Lang;
47
   type Restricted_Lang_Access is access Restricted_Lang;
48
   type Restricted_Lang is record
49
      Name : Name_Id;
50
      Next : Restricted_Lang_Access;
51
   end record;
52
 
53
   Restricted_Languages : Restricted_Lang_Access := null;
54
   --  When null, all languages are allowed, otherwise only the languages in
55
   --  the list are allowed.
56
 
57
   Object_Suffix : constant String := Get_Target_Object_Suffix.all;
58
   --  File suffix for object files
59
 
60
   Initial_Buffer_Size : constant := 100;
61
   --  Initial size for extensible buffer used in Add_To_Buffer
62
 
63
   The_Empty_String : Name_Id := No_Name;
64
 
65
   Debug_Level : Integer := 0;
66
   --  Current indentation level for debug traces
67
 
68
   type Cst_String_Access is access constant String;
69
 
70
   All_Lower_Case_Image : aliased constant String := "lowercase";
71
   All_Upper_Case_Image : aliased constant String := "UPPERCASE";
72
   Mixed_Case_Image     : aliased constant String := "MixedCase";
73
 
74
   The_Casing_Images : constant array (Known_Casing) of Cst_String_Access :=
75
                         (All_Lower_Case => All_Lower_Case_Image'Access,
76
                          All_Upper_Case => All_Upper_Case_Image'Access,
77
                          Mixed_Case     => Mixed_Case_Image'Access);
78
 
79
   procedure Free (Project : in out Project_Id);
80
   --  Free memory allocated for Project
81
 
82
   procedure Free_List (Languages : in out Language_Ptr);
83
   procedure Free_List (Source : in out Source_Id);
84
   procedure Free_List (Languages : in out Language_List);
85
   --  Free memory allocated for the list of languages or sources
86
 
87
   procedure Reset_Units_In_Table (Table : in out Units_Htable.Instance);
88
   --  Resets all Units to No_Unit_Index Unit.File_Names (Spec).Unit &
89
   --  Unit.File_Names (Impl).Unit in the given table.
90
 
91
   procedure Free_Units (Table : in out Units_Htable.Instance);
92
   --  Free memory allocated for unit information in the project
93
 
94
   procedure Language_Changed (Iter : in out Source_Iterator);
95
   procedure Project_Changed (Iter : in out Source_Iterator);
96
   --  Called when a new project or language was selected for this iterator
97
 
98
   function Contains_ALI_Files (Dir : Path_Name_Type) return Boolean;
99
   --  Return True if there is at least one ALI file in the directory Dir
100
 
101
   -----------------------------
102
   -- Add_Restricted_Language --
103
   -----------------------------
104
 
105
   procedure Add_Restricted_Language (Name : String) is
106
      N : String (1 .. Name'Length) := Name;
107
   begin
108
      To_Lower (N);
109
      Name_Len := 0;
110
      Add_Str_To_Name_Buffer (N);
111
      Restricted_Languages :=
112
        new Restricted_Lang'(Name => Name_Find, Next => Restricted_Languages);
113
   end Add_Restricted_Language;
114
 
115
   -------------------
116
   -- Add_To_Buffer --
117
   -------------------
118
 
119
   procedure Add_To_Buffer
120
     (S    : String;
121
      To   : in out String_Access;
122
      Last : in out Natural)
123
   is
124
   begin
125
      if To = null then
126
         To := new String (1 .. Initial_Buffer_Size);
127
         Last := 0;
128
      end if;
129
 
130
      --  If Buffer is too small, double its size
131
 
132
      while Last + S'Length > To'Last loop
133
         declare
134
            New_Buffer : constant  String_Access :=
135
                           new String (1 .. 2 * Last);
136
 
137
         begin
138
            New_Buffer (1 .. Last) := To (1 .. Last);
139
            Free (To);
140
            To := New_Buffer;
141
         end;
142
      end loop;
143
 
144
      To (Last + 1 .. Last + S'Length) := S;
145
      Last := Last + S'Length;
146
   end Add_To_Buffer;
147
 
148
   ---------------------------------
149
   -- Current_Object_Path_File_Of --
150
   ---------------------------------
151
 
152
   function Current_Object_Path_File_Of
153
     (Shared : Shared_Project_Tree_Data_Access) return Path_Name_Type
154
   is
155
   begin
156
      return Shared.Private_Part.Current_Object_Path_File;
157
   end Current_Object_Path_File_Of;
158
 
159
   ---------------------------------
160
   -- Current_Source_Path_File_Of --
161
   ---------------------------------
162
 
163
   function Current_Source_Path_File_Of
164
     (Shared : Shared_Project_Tree_Data_Access)
165
      return Path_Name_Type is
166
   begin
167
      return Shared.Private_Part.Current_Source_Path_File;
168
   end Current_Source_Path_File_Of;
169
 
170
   ---------------------------
171
   -- Delete_Temporary_File --
172
   ---------------------------
173
 
174
   procedure Delete_Temporary_File
175
     (Shared : Shared_Project_Tree_Data_Access := null;
176
      Path   : Path_Name_Type)
177
   is
178
      Dont_Care : Boolean;
179
      pragma Warnings (Off, Dont_Care);
180
 
181
   begin
182
      if not Debug.Debug_Flag_N then
183
         if Current_Verbosity = High then
184
            Write_Line ("Removing temp file: " & Get_Name_String (Path));
185
         end if;
186
 
187
         Delete_File (Get_Name_String (Path), Dont_Care);
188
 
189
         if Shared /= null then
190
            for Index in
191
              1 .. Temp_Files_Table.Last (Shared.Private_Part.Temp_Files)
192
            loop
193
               if Shared.Private_Part.Temp_Files.Table (Index) = Path then
194
                  Shared.Private_Part.Temp_Files.Table (Index) := No_Path;
195
               end if;
196
            end loop;
197
         end if;
198
      end if;
199
   end Delete_Temporary_File;
200
 
201
   ------------------------------
202
   -- Delete_Temp_Config_Files --
203
   ------------------------------
204
 
205
   procedure Delete_Temp_Config_Files (Project_Tree : Project_Tree_Ref) is
206
      Success : Boolean;
207
      pragma Warnings (Off, Success);
208
 
209
      Proj : Project_List;
210
 
211
   begin
212
      if not Debug.Debug_Flag_N then
213
         if Project_Tree /= null then
214
            Proj := Project_Tree.Projects;
215
            while Proj /= null loop
216
               if Proj.Project.Config_File_Temp then
217
                  Delete_Temporary_File
218
                    (Project_Tree.Shared, Proj.Project.Config_File_Name);
219
 
220
                  --  Make sure that we don't have a config file for this
221
                  --  project, in case there are several mains. In this case,
222
                  --  we will recreate another config file: we cannot reuse the
223
                  --  one that we just deleted!
224
 
225
                  Proj.Project.Config_Checked   := False;
226
                  Proj.Project.Config_File_Name := No_Path;
227
                  Proj.Project.Config_File_Temp := False;
228
               end if;
229
 
230
               Proj := Proj.Next;
231
            end loop;
232
         end if;
233
      end if;
234
   end Delete_Temp_Config_Files;
235
 
236
   ---------------------------
237
   -- Delete_All_Temp_Files --
238
   ---------------------------
239
 
240
   procedure Delete_All_Temp_Files
241
     (Shared : Shared_Project_Tree_Data_Access)
242
   is
243
      Dont_Care : Boolean;
244
      pragma Warnings (Off, Dont_Care);
245
 
246
      Path : Path_Name_Type;
247
 
248
   begin
249
      if not Debug.Debug_Flag_N then
250
         for Index in
251
           1 .. Temp_Files_Table.Last (Shared.Private_Part.Temp_Files)
252
         loop
253
            Path := Shared.Private_Part.Temp_Files.Table (Index);
254
 
255
            if Path /= No_Path then
256
               if Current_Verbosity = High then
257
                  Write_Line ("Removing temp file: "
258
                              & Get_Name_String (Path));
259
               end if;
260
 
261
               Delete_File (Get_Name_String (Path), Dont_Care);
262
            end if;
263
         end loop;
264
 
265
         Temp_Files_Table.Free (Shared.Private_Part.Temp_Files);
266
         Temp_Files_Table.Init (Shared.Private_Part.Temp_Files);
267
      end if;
268
 
269
      --  If any of the environment variables ADA_PRJ_INCLUDE_FILE or
270
      --  ADA_PRJ_OBJECTS_FILE has been set, then reset their value to
271
      --  the empty string. On VMS, this has the effect of deassigning
272
      --  the logical names.
273
 
274
      if Shared.Private_Part.Current_Source_Path_File /= No_Path then
275
         Setenv (Project_Include_Path_File, "");
276
      end if;
277
 
278
      if Shared.Private_Part.Current_Object_Path_File /= No_Path then
279
         Setenv (Project_Objects_Path_File, "");
280
      end if;
281
   end Delete_All_Temp_Files;
282
 
283
   ---------------------
284
   -- Dependency_Name --
285
   ---------------------
286
 
287
   function Dependency_Name
288
     (Source_File_Name : File_Name_Type;
289
      Dependency       : Dependency_File_Kind) return File_Name_Type
290
   is
291
   begin
292
      case Dependency is
293
         when None =>
294
            return No_File;
295
 
296
         when Makefile =>
297
            return Extend_Name (Source_File_Name, Makefile_Dependency_Suffix);
298
 
299
         when ALI_File =>
300
            return Extend_Name (Source_File_Name, ALI_Dependency_Suffix);
301
      end case;
302
   end Dependency_Name;
303
 
304
   ----------------
305
   -- Empty_File --
306
   ----------------
307
 
308
   function Empty_File return File_Name_Type is
309
   begin
310
      return File_Name_Type (The_Empty_String);
311
   end Empty_File;
312
 
313
   -------------------
314
   -- Empty_Project --
315
   -------------------
316
 
317
   function Empty_Project
318
     (Qualifier : Project_Qualifier) return Project_Data
319
   is
320
   begin
321
      Prj.Initialize (Tree => No_Project_Tree);
322
 
323
      declare
324
         Data : Project_Data (Qualifier => Qualifier);
325
 
326
      begin
327
         --  Only the fields for which no default value could be provided in
328
         --  prj.ads are initialized below.
329
 
330
         Data.Config := Default_Project_Config;
331
         return Data;
332
      end;
333
   end Empty_Project;
334
 
335
   ------------------
336
   -- Empty_String --
337
   ------------------
338
 
339
   function Empty_String return Name_Id is
340
   begin
341
      return The_Empty_String;
342
   end Empty_String;
343
 
344
   ------------
345
   -- Expect --
346
   ------------
347
 
348
   procedure Expect (The_Token : Token_Type; Token_Image : String) is
349
   begin
350
      if Token /= The_Token then
351
 
352
         --  ??? Should pass user flags here instead
353
 
354
         Error_Msg (Gnatmake_Flags, Token_Image & " expected", Token_Ptr);
355
      end if;
356
   end Expect;
357
 
358
   -----------------
359
   -- Extend_Name --
360
   -----------------
361
 
362
   function Extend_Name
363
     (File        : File_Name_Type;
364
      With_Suffix : String) return File_Name_Type
365
   is
366
      Last : Positive;
367
 
368
   begin
369
      Get_Name_String (File);
370
      Last := Name_Len + 1;
371
 
372
      while Name_Len /= 0 and then Name_Buffer (Name_Len) /= '.' loop
373
         Name_Len := Name_Len - 1;
374
      end loop;
375
 
376
      if Name_Len <= 1 then
377
         Name_Len := Last;
378
      end if;
379
 
380
      for J in With_Suffix'Range loop
381
         Name_Buffer (Name_Len) := With_Suffix (J);
382
         Name_Len := Name_Len + 1;
383
      end loop;
384
 
385
      Name_Len := Name_Len - 1;
386
      return Name_Find;
387
   end Extend_Name;
388
 
389
   -------------------------
390
   -- Is_Allowed_Language --
391
   -------------------------
392
 
393
   function Is_Allowed_Language (Name : Name_Id) return Boolean is
394
      R    : Restricted_Lang_Access := Restricted_Languages;
395
      Lang : constant String := Get_Name_String (Name);
396
 
397
   begin
398
      if R = null then
399
         return True;
400
 
401
      else
402
         while R /= null loop
403
            if Get_Name_String (R.Name) = Lang then
404
               return True;
405
            end if;
406
 
407
            R := R.Next;
408
         end loop;
409
 
410
         return False;
411
      end if;
412
   end Is_Allowed_Language;
413
 
414
   ---------------------
415
   -- Project_Changed --
416
   ---------------------
417
 
418
   procedure Project_Changed (Iter : in out Source_Iterator) is
419
   begin
420
      if Iter.Project /= null then
421
         Iter.Language := Iter.Project.Project.Languages;
422
         Language_Changed (Iter);
423
      end if;
424
   end Project_Changed;
425
 
426
   ----------------------
427
   -- Language_Changed --
428
   ----------------------
429
 
430
   procedure Language_Changed (Iter : in out Source_Iterator) is
431
   begin
432
      Iter.Current := No_Source;
433
 
434
      if Iter.Language_Name /= No_Name then
435
         while Iter.Language /= null
436
           and then Iter.Language.Name /= Iter.Language_Name
437
         loop
438
            Iter.Language := Iter.Language.Next;
439
         end loop;
440
      end if;
441
 
442
      --  If there is no matching language in this project, move to next
443
 
444
      if Iter.Language = No_Language_Index then
445
         if Iter.All_Projects then
446
            loop
447
               Iter.Project := Iter.Project.Next;
448
               exit when Iter.Project = null
449
                 or else Iter.Encapsulated_Libs
450
                 or else not Iter.Project.From_Encapsulated_Lib;
451
            end loop;
452
 
453
            Project_Changed (Iter);
454
         else
455
            Iter.Project := null;
456
         end if;
457
 
458
      else
459
         Iter.Current := Iter.Language.First_Source;
460
 
461
         if Iter.Current = No_Source then
462
            Iter.Language := Iter.Language.Next;
463
            Language_Changed (Iter);
464
         end if;
465
      end if;
466
   end Language_Changed;
467
 
468
   ---------------------
469
   -- For_Each_Source --
470
   ---------------------
471
 
472
   function For_Each_Source
473
     (In_Tree           : Project_Tree_Ref;
474
      Project           : Project_Id := No_Project;
475
      Language          : Name_Id := No_Name;
476
      Encapsulated_Libs : Boolean := True) return Source_Iterator
477
   is
478
      Iter : Source_Iterator;
479
   begin
480
      Iter := Source_Iterator'
481
        (In_Tree           => In_Tree,
482
         Project           => In_Tree.Projects,
483
         All_Projects      => Project = No_Project,
484
         Language_Name     => Language,
485
         Language          => No_Language_Index,
486
         Current           => No_Source,
487
         Encapsulated_Libs => Encapsulated_Libs);
488
 
489
      if Project /= null then
490
         while Iter.Project /= null
491
           and then Iter.Project.Project /= Project
492
         loop
493
            Iter.Project := Iter.Project.Next;
494
         end loop;
495
 
496
      else
497
         while not Iter.Encapsulated_Libs
498
           and then Iter.Project.From_Encapsulated_Lib
499
         loop
500
            Iter.Project := Iter.Project.Next;
501
         end loop;
502
      end if;
503
 
504
      Project_Changed (Iter);
505
 
506
      return Iter;
507
   end For_Each_Source;
508
 
509
   -------------
510
   -- Element --
511
   -------------
512
 
513
   function Element (Iter : Source_Iterator) return Source_Id is
514
   begin
515
      return Iter.Current;
516
   end Element;
517
 
518
   ----------
519
   -- Next --
520
   ----------
521
 
522
   procedure Next (Iter : in out Source_Iterator) is
523
   begin
524
      Iter.Current := Iter.Current.Next_In_Lang;
525
      if Iter.Current = No_Source then
526
         Iter.Language := Iter.Language.Next;
527
         Language_Changed (Iter);
528
      end if;
529
   end Next;
530
 
531
   --------------------------------
532
   -- For_Every_Project_Imported --
533
   --------------------------------
534
 
535
   procedure For_Every_Project_Imported_Context
536
     (By                 : Project_Id;
537
      Tree               : Project_Tree_Ref;
538
      With_State         : in out State;
539
      Include_Aggregated : Boolean := True;
540
      Imported_First     : Boolean := False)
541
   is
542
      use Project_Boolean_Htable;
543
 
544
      procedure Recursive_Check_Context
545
        (Project               : Project_Id;
546
         Tree                  : Project_Tree_Ref;
547
         In_Aggregate_Lib      : Boolean;
548
         From_Encapsulated_Lib : Boolean);
549
      --  Recursively handle the project tree creating a new context for
550
      --  keeping track about already handled projects.
551
 
552
      -----------------------------
553
      -- Recursive_Check_Context --
554
      -----------------------------
555
 
556
      procedure Recursive_Check_Context
557
        (Project               : Project_Id;
558
         Tree                  : Project_Tree_Ref;
559
         In_Aggregate_Lib      : Boolean;
560
         From_Encapsulated_Lib : Boolean)
561
      is
562
         package Name_Id_Set is
563
           new Ada.Containers.Ordered_Sets (Element_Type => Name_Id);
564
 
565
         Seen_Name : Name_Id_Set.Set;
566
         --  This set is needed to ensure that we do not haandle the same
567
         --  project twice in the context of aggregate libraries.
568
 
569
         procedure Recursive_Check
570
           (Project               : Project_Id;
571
            Tree                  : Project_Tree_Ref;
572
            In_Aggregate_Lib      : Boolean;
573
            From_Encapsulated_Lib : Boolean);
574
         --  Check if project has already been seen. If not, mark it as Seen,
575
         --  Call Action, and check all its imported and aggregated projects.
576
 
577
         ---------------------
578
         -- Recursive_Check --
579
         ---------------------
580
 
581
         procedure Recursive_Check
582
           (Project               : Project_Id;
583
            Tree                  : Project_Tree_Ref;
584
            In_Aggregate_Lib      : Boolean;
585
            From_Encapsulated_Lib : Boolean)
586
         is
587
            List : Project_List;
588
            T    : Project_Tree_Ref;
589
 
590
         begin
591
            if not Seen_Name.Contains (Project.Name) then
592
 
593
               --  Even if a project is aggregated multiple times in an
594
               --  aggregated library, we will only return it once.
595
 
596
               Seen_Name.Include (Project.Name);
597
 
598
               if not Imported_First then
599
                  Action
600
                    (Project,
601
                     Tree,
602
                     Project_Context'(In_Aggregate_Lib, From_Encapsulated_Lib),
603
                     With_State);
604
               end if;
605
 
606
               --  Visit all extended projects
607
 
608
               if Project.Extends /= No_Project then
609
                  Recursive_Check
610
                    (Project.Extends, Tree,
611
                     In_Aggregate_Lib, From_Encapsulated_Lib);
612
               end if;
613
 
614
               --  Visit all imported projects
615
 
616
               List := Project.Imported_Projects;
617
               while List /= null loop
618
                  Recursive_Check
619
                    (List.Project, Tree,
620
                     In_Aggregate_Lib,
621
                     From_Encapsulated_Lib
622
                       or else Project.Standalone_Library = Encapsulated);
623
                  List := List.Next;
624
               end loop;
625
 
626
               --  Visit all aggregated projects
627
 
628
               if Include_Aggregated
629
                 and then Project.Qualifier in Aggregate_Project
630
               then
631
                  declare
632
                     Agg : Aggregated_Project_List;
633
 
634
                  begin
635
                     Agg := Project.Aggregated_Projects;
636
                     while Agg /= null loop
637
                        pragma Assert (Agg.Project /= No_Project);
638
 
639
                        --  For aggregated libraries, the tree must be the one
640
                        --  of the aggregate library.
641
 
642
                        if Project.Qualifier = Aggregate_Library then
643
                           T := Tree;
644
                           Recursive_Check
645
                             (Agg.Project, T,
646
                              True,
647
                              From_Encapsulated_Lib
648
                                or else
649
                                  Project.Standalone_Library = Encapsulated);
650
 
651
                        else
652
                           T := Agg.Tree;
653
 
654
                           --  Use a new context as we want to returns the same
655
                           --  project in different project tree for aggregated
656
                           --  projects.
657
 
658
                           Recursive_Check_Context
659
                             (Agg.Project, T, False, False);
660
                        end if;
661
 
662
                        Agg := Agg.Next;
663
                     end loop;
664
                  end;
665
               end if;
666
 
667
               if Imported_First then
668
                  Action
669
                    (Project,
670
                     Tree,
671
                     Project_Context'(In_Aggregate_Lib, From_Encapsulated_Lib),
672
                     With_State);
673
               end if;
674
            end if;
675
         end Recursive_Check;
676
 
677
      --  Start of processing for Recursive_Check_Context
678
 
679
      begin
680
         Recursive_Check
681
           (Project, Tree, In_Aggregate_Lib, From_Encapsulated_Lib);
682
      end Recursive_Check_Context;
683
 
684
   --  Start of processing for For_Every_Project_Imported
685
 
686
   begin
687
      Recursive_Check_Context
688
        (Project               => By,
689
         Tree                  => Tree,
690
         In_Aggregate_Lib      => False,
691
         From_Encapsulated_Lib => False);
692
   end For_Every_Project_Imported_Context;
693
 
694
   procedure For_Every_Project_Imported
695
     (By                 : Project_Id;
696
      Tree               : Project_Tree_Ref;
697
      With_State         : in out State;
698
      Include_Aggregated : Boolean := True;
699
      Imported_First     : Boolean := False)
700
   is
701
      procedure Internal
702
        (Project    : Project_Id;
703
         Tree       : Project_Tree_Ref;
704
         Context    : Project_Context;
705
         With_State : in out State);
706
      --  Action wrapper for handling the context
707
 
708
      --------------
709
      -- Internal --
710
      --------------
711
 
712
      procedure Internal
713
        (Project    : Project_Id;
714
         Tree       : Project_Tree_Ref;
715
         Context    : Project_Context;
716
         With_State : in out State)
717
      is
718
         pragma Unreferenced (Context);
719
      begin
720
         Action (Project, Tree, With_State);
721
      end Internal;
722
 
723
      procedure For_Projects is
724
        new For_Every_Project_Imported_Context (State, Internal);
725
 
726
   begin
727
      For_Projects (By, Tree, With_State, Include_Aggregated, Imported_First);
728
   end For_Every_Project_Imported;
729
 
730
   -----------------
731
   -- Find_Source --
732
   -----------------
733
 
734
   function Find_Source
735
     (In_Tree          : Project_Tree_Ref;
736
      Project          : Project_Id;
737
      In_Imported_Only : Boolean := False;
738
      In_Extended_Only : Boolean := False;
739
      Base_Name        : File_Name_Type;
740
      Index            : Int := 0) return Source_Id
741
   is
742
      Result : Source_Id  := No_Source;
743
 
744
      procedure Look_For_Sources
745
        (Proj : Project_Id;
746
         Tree : Project_Tree_Ref;
747
         Src  : in out Source_Id);
748
      --  Look for Base_Name in the sources of Proj
749
 
750
      ----------------------
751
      -- Look_For_Sources --
752
      ----------------------
753
 
754
      procedure Look_For_Sources
755
        (Proj : Project_Id;
756
         Tree : Project_Tree_Ref;
757
         Src  : in out Source_Id)
758
      is
759
         Iterator : Source_Iterator;
760
 
761
      begin
762
         Iterator := For_Each_Source (In_Tree => Tree, Project => Proj);
763
         while Element (Iterator) /= No_Source loop
764
            if Element (Iterator).File = Base_Name
765
              and then (Index = 0 or else Element (Iterator).Index = Index)
766
            then
767
               Src := Element (Iterator);
768
 
769
               --  If the source has been excluded, continue looking. We will
770
               --  get the excluded source only if there is no other source
771
               --  with the same base name that is not locally removed.
772
 
773
               if not Element (Iterator).Locally_Removed then
774
                  return;
775
               end if;
776
            end if;
777
 
778
            Next (Iterator);
779
         end loop;
780
      end Look_For_Sources;
781
 
782
      procedure For_Imported_Projects is new For_Every_Project_Imported
783
        (State => Source_Id, Action => Look_For_Sources);
784
 
785
      Proj : Project_Id;
786
 
787
   --  Start of processing for Find_Source
788
 
789
   begin
790
      if In_Extended_Only then
791
         Proj := Project;
792
         while Proj /= No_Project loop
793
            Look_For_Sources (Proj, In_Tree, Result);
794
            exit when Result /= No_Source;
795
 
796
            Proj := Proj.Extends;
797
         end loop;
798
 
799
      elsif In_Imported_Only then
800
         Look_For_Sources (Project, In_Tree, Result);
801
 
802
         if Result = No_Source then
803
            For_Imported_Projects
804
              (By                 => Project,
805
               Tree               => In_Tree,
806
               Include_Aggregated => False,
807
               With_State         => Result);
808
         end if;
809
 
810
      else
811
         Look_For_Sources (No_Project, In_Tree, Result);
812
      end if;
813
 
814
      return Result;
815
   end Find_Source;
816
 
817
   ----------
818
   -- Hash --
819
   ----------
820
 
821
   function Hash is new GNAT.HTable.Hash (Header_Num => Header_Num);
822
   --  Used in implementation of other functions Hash below
823
 
824
   function Hash (Name : File_Name_Type) return Header_Num is
825
   begin
826
      return Hash (Get_Name_String (Name));
827
   end Hash;
828
 
829
   function Hash (Name : Name_Id) return Header_Num is
830
   begin
831
      return Hash (Get_Name_String (Name));
832
   end Hash;
833
 
834
   function Hash (Name : Path_Name_Type) return Header_Num is
835
   begin
836
      return Hash (Get_Name_String (Name));
837
   end Hash;
838
 
839
   function Hash (Project : Project_Id) return Header_Num is
840
   begin
841
      if Project = No_Project then
842
         return Header_Num'First;
843
      else
844
         return Hash (Get_Name_String (Project.Name));
845
      end if;
846
   end Hash;
847
 
848
   -----------
849
   -- Image --
850
   -----------
851
 
852
   function Image (The_Casing : Casing_Type) return String is
853
   begin
854
      return The_Casing_Images (The_Casing).all;
855
   end Image;
856
 
857
   -----------------------------
858
   -- Is_Standard_GNAT_Naming --
859
   -----------------------------
860
 
861
   function Is_Standard_GNAT_Naming
862
     (Naming : Lang_Naming_Data) return Boolean
863
   is
864
   begin
865
      return Get_Name_String (Naming.Spec_Suffix) = ".ads"
866
        and then Get_Name_String (Naming.Body_Suffix) = ".adb"
867
        and then Get_Name_String (Naming.Dot_Replacement) = "-";
868
   end Is_Standard_GNAT_Naming;
869
 
870
   ----------------
871
   -- Initialize --
872
   ----------------
873
 
874
   procedure Initialize (Tree : Project_Tree_Ref) is
875
   begin
876
      if The_Empty_String = No_Name then
877
         Uintp.Initialize;
878
         Name_Len := 0;
879
         The_Empty_String := Name_Find;
880
 
881
         Prj.Attr.Initialize;
882
 
883
         --  Make sure that new reserved words after Ada 95 may be used as
884
         --  identifiers.
885
 
886
         Opt.Ada_Version := Opt.Ada_95;
887
 
888
         Set_Name_Table_Byte (Name_Project,  Token_Type'Pos (Tok_Project));
889
         Set_Name_Table_Byte (Name_Extends,  Token_Type'Pos (Tok_Extends));
890
         Set_Name_Table_Byte (Name_External, Token_Type'Pos (Tok_External));
891
         Set_Name_Table_Byte
892
           (Name_External_As_List, Token_Type'Pos (Tok_External_As_List));
893
      end if;
894
 
895
      if Tree /= No_Project_Tree then
896
         Reset (Tree);
897
      end if;
898
   end Initialize;
899
 
900
   ------------------
901
   -- Is_Extending --
902
   ------------------
903
 
904
   function Is_Extending
905
     (Extending : Project_Id;
906
      Extended  : Project_Id) return Boolean
907
   is
908
      Proj : Project_Id;
909
 
910
   begin
911
      Proj := Extending;
912
      while Proj /= No_Project loop
913
         if Proj = Extended then
914
            return True;
915
         end if;
916
 
917
         Proj := Proj.Extends;
918
      end loop;
919
 
920
      return False;
921
   end Is_Extending;
922
 
923
   -----------------
924
   -- Object_Name --
925
   -----------------
926
 
927
   function Object_Name
928
     (Source_File_Name   : File_Name_Type;
929
      Object_File_Suffix : Name_Id := No_Name) return File_Name_Type
930
   is
931
   begin
932
      if Object_File_Suffix = No_Name then
933
         return Extend_Name
934
           (Source_File_Name, Object_Suffix);
935
      else
936
         return Extend_Name
937
           (Source_File_Name, Get_Name_String (Object_File_Suffix));
938
      end if;
939
   end Object_Name;
940
 
941
   function Object_Name
942
     (Source_File_Name   : File_Name_Type;
943
      Source_Index       : Int;
944
      Index_Separator    : Character;
945
      Object_File_Suffix : Name_Id := No_Name) return File_Name_Type
946
   is
947
      Index_Img : constant String := Source_Index'Img;
948
      Last      : Natural;
949
 
950
   begin
951
      Get_Name_String (Source_File_Name);
952
 
953
      Last := Name_Len;
954
      while Last > 1 and then Name_Buffer (Last) /= '.' loop
955
         Last := Last - 1;
956
      end loop;
957
 
958
      if Last > 1 then
959
         Name_Len := Last - 1;
960
      end if;
961
 
962
      Add_Char_To_Name_Buffer (Index_Separator);
963
      Add_Str_To_Name_Buffer (Index_Img (2 .. Index_Img'Last));
964
 
965
      if Object_File_Suffix = No_Name then
966
         Add_Str_To_Name_Buffer (Object_Suffix);
967
      else
968
         Add_Str_To_Name_Buffer (Get_Name_String (Object_File_Suffix));
969
      end if;
970
 
971
      return Name_Find;
972
   end Object_Name;
973
 
974
   ----------------------
975
   -- Record_Temp_File --
976
   ----------------------
977
 
978
   procedure Record_Temp_File
979
     (Shared : Shared_Project_Tree_Data_Access;
980
      Path   : Path_Name_Type)
981
   is
982
   begin
983
      Temp_Files_Table.Append (Shared.Private_Part.Temp_Files, Path);
984
   end Record_Temp_File;
985
 
986
   ----------
987
   -- Free --
988
   ----------
989
 
990
   procedure Free (List : in out Aggregated_Project_List) is
991
      procedure Unchecked_Free is new Ada.Unchecked_Deallocation
992
        (Aggregated_Project, Aggregated_Project_List);
993
      Tmp : Aggregated_Project_List;
994
   begin
995
      while List /= null loop
996
         Tmp := List.Next;
997
 
998
         Free (List.Tree);
999
 
1000
         Unchecked_Free (List);
1001
         List := Tmp;
1002
      end loop;
1003
   end Free;
1004
 
1005
   ----------------------------
1006
   -- Add_Aggregated_Project --
1007
   ----------------------------
1008
 
1009
   procedure Add_Aggregated_Project
1010
     (Project : Project_Id; Path : Path_Name_Type) is
1011
   begin
1012
      Project.Aggregated_Projects := new Aggregated_Project'
1013
        (Path    => Path,
1014
         Project => No_Project,
1015
         Tree    => null,
1016
         Next    => Project.Aggregated_Projects);
1017
   end Add_Aggregated_Project;
1018
 
1019
   ----------
1020
   -- Free --
1021
   ----------
1022
 
1023
   procedure Free (Project : in out Project_Id) is
1024
      procedure Unchecked_Free is new Ada.Unchecked_Deallocation
1025
        (Project_Data, Project_Id);
1026
 
1027
   begin
1028
      if Project /= null then
1029
         Free (Project.Ada_Include_Path);
1030
         Free (Project.Objects_Path);
1031
         Free (Project.Ada_Objects_Path);
1032
         Free_List (Project.Imported_Projects, Free_Project => False);
1033
         Free_List (Project.All_Imported_Projects, Free_Project => False);
1034
         Free_List (Project.Languages);
1035
 
1036
         case Project.Qualifier is
1037
            when Aggregate | Aggregate_Library =>
1038
               Free (Project.Aggregated_Projects);
1039
 
1040
            when others =>
1041
               null;
1042
         end case;
1043
 
1044
         Unchecked_Free (Project);
1045
      end if;
1046
   end Free;
1047
 
1048
   ---------------
1049
   -- Free_List --
1050
   ---------------
1051
 
1052
   procedure Free_List (Languages : in out Language_List) is
1053
      procedure Unchecked_Free is new Ada.Unchecked_Deallocation
1054
        (Language_List_Element, Language_List);
1055
      Tmp : Language_List;
1056
   begin
1057
      while Languages /= null loop
1058
         Tmp := Languages.Next;
1059
         Unchecked_Free (Languages);
1060
         Languages := Tmp;
1061
      end loop;
1062
   end Free_List;
1063
 
1064
   ---------------
1065
   -- Free_List --
1066
   ---------------
1067
 
1068
   procedure Free_List (Source : in out Source_Id) is
1069
      procedure Unchecked_Free is new
1070
        Ada.Unchecked_Deallocation (Source_Data, Source_Id);
1071
 
1072
      Tmp : Source_Id;
1073
 
1074
   begin
1075
      while Source /= No_Source loop
1076
         Tmp := Source.Next_In_Lang;
1077
         Free_List (Source.Alternate_Languages);
1078
 
1079
         if Source.Unit /= null
1080
           and then Source.Kind in Spec_Or_Body
1081
         then
1082
            Source.Unit.File_Names (Source.Kind) := null;
1083
         end if;
1084
 
1085
         Unchecked_Free (Source);
1086
         Source := Tmp;
1087
      end loop;
1088
   end Free_List;
1089
 
1090
   ---------------
1091
   -- Free_List --
1092
   ---------------
1093
 
1094
   procedure Free_List
1095
     (List         : in out Project_List;
1096
      Free_Project : Boolean)
1097
   is
1098
      procedure Unchecked_Free is new
1099
        Ada.Unchecked_Deallocation (Project_List_Element, Project_List);
1100
 
1101
      Tmp : Project_List;
1102
 
1103
   begin
1104
      while List /= null loop
1105
         Tmp := List.Next;
1106
 
1107
         if Free_Project then
1108
            Free (List.Project);
1109
         end if;
1110
 
1111
         Unchecked_Free (List);
1112
         List := Tmp;
1113
      end loop;
1114
   end Free_List;
1115
 
1116
   ---------------
1117
   -- Free_List --
1118
   ---------------
1119
 
1120
   procedure Free_List (Languages : in out Language_Ptr) is
1121
      procedure Unchecked_Free is new
1122
        Ada.Unchecked_Deallocation (Language_Data, Language_Ptr);
1123
 
1124
      Tmp : Language_Ptr;
1125
 
1126
   begin
1127
      while Languages /= null loop
1128
         Tmp := Languages.Next;
1129
         Free_List (Languages.First_Source);
1130
         Unchecked_Free (Languages);
1131
         Languages := Tmp;
1132
      end loop;
1133
   end Free_List;
1134
 
1135
   --------------------------
1136
   -- Reset_Units_In_Table --
1137
   --------------------------
1138
 
1139
   procedure Reset_Units_In_Table (Table : in out Units_Htable.Instance) is
1140
      Unit : Unit_Index;
1141
 
1142
   begin
1143
      Unit := Units_Htable.Get_First (Table);
1144
      while Unit /= No_Unit_Index loop
1145
         if Unit.File_Names (Spec) /= null then
1146
            Unit.File_Names (Spec).Unit := No_Unit_Index;
1147
         end if;
1148
 
1149
         if Unit.File_Names (Impl) /= null then
1150
            Unit.File_Names (Impl).Unit := No_Unit_Index;
1151
         end if;
1152
 
1153
         Unit := Units_Htable.Get_Next (Table);
1154
      end loop;
1155
   end Reset_Units_In_Table;
1156
 
1157
   ----------------
1158
   -- Free_Units --
1159
   ----------------
1160
 
1161
   procedure Free_Units (Table : in out Units_Htable.Instance) is
1162
      procedure Unchecked_Free is new
1163
        Ada.Unchecked_Deallocation (Unit_Data, Unit_Index);
1164
 
1165
      Unit : Unit_Index;
1166
 
1167
   begin
1168
      Unit := Units_Htable.Get_First (Table);
1169
      while Unit /= No_Unit_Index loop
1170
 
1171
         --  We cannot reset Unit.File_Names (Impl or Spec).Unit here as
1172
         --  Source_Data buffer is freed by the following instruction
1173
         --  Free_List (Tree.Projects, Free_Project => True);
1174
 
1175
         Unchecked_Free (Unit);
1176
         Unit := Units_Htable.Get_Next (Table);
1177
      end loop;
1178
 
1179
      Units_Htable.Reset (Table);
1180
   end Free_Units;
1181
 
1182
   ----------
1183
   -- Free --
1184
   ----------
1185
 
1186
   procedure Free (Tree : in out Project_Tree_Ref) is
1187
      procedure Unchecked_Free is new
1188
        Ada.Unchecked_Deallocation
1189
          (Project_Tree_Data, Project_Tree_Ref);
1190
 
1191
      procedure Unchecked_Free is new
1192
        Ada.Unchecked_Deallocation
1193
          (Project_Tree_Appdata'Class, Project_Tree_Appdata_Access);
1194
 
1195
   begin
1196
      if Tree /= null then
1197
         if Tree.Is_Root_Tree then
1198
            Name_List_Table.Free        (Tree.Shared.Name_Lists);
1199
            Number_List_Table.Free      (Tree.Shared.Number_Lists);
1200
            String_Element_Table.Free   (Tree.Shared.String_Elements);
1201
            Variable_Element_Table.Free (Tree.Shared.Variable_Elements);
1202
            Array_Element_Table.Free    (Tree.Shared.Array_Elements);
1203
            Array_Table.Free            (Tree.Shared.Arrays);
1204
            Package_Table.Free          (Tree.Shared.Packages);
1205
            Temp_Files_Table.Free       (Tree.Shared.Private_Part.Temp_Files);
1206
         end if;
1207
 
1208
         if Tree.Appdata /= null then
1209
            Free (Tree.Appdata.all);
1210
            Unchecked_Free (Tree.Appdata);
1211
         end if;
1212
 
1213
         Source_Paths_Htable.Reset (Tree.Source_Paths_HT);
1214
         Source_Files_Htable.Reset (Tree.Source_Files_HT);
1215
 
1216
         Reset_Units_In_Table (Tree.Units_HT);
1217
         Free_List (Tree.Projects, Free_Project => True);
1218
         Free_Units (Tree.Units_HT);
1219
 
1220
         Unchecked_Free (Tree);
1221
      end if;
1222
   end Free;
1223
 
1224
   -----------
1225
   -- Reset --
1226
   -----------
1227
 
1228
   procedure Reset (Tree : Project_Tree_Ref) is
1229
   begin
1230
      --  Visible tables
1231
 
1232
      if Tree.Is_Root_Tree then
1233
 
1234
         --  We cannot use 'Access here:
1235
         --    "illegal attribute for discriminant-dependent component"
1236
         --  However, we know this is valid since Shared and Shared_Data have
1237
         --  the same lifetime and will always exist concurrently.
1238
 
1239
         Tree.Shared := Tree.Shared_Data'Unrestricted_Access;
1240
         Name_List_Table.Init        (Tree.Shared.Name_Lists);
1241
         Number_List_Table.Init      (Tree.Shared.Number_Lists);
1242
         String_Element_Table.Init   (Tree.Shared.String_Elements);
1243
         Variable_Element_Table.Init (Tree.Shared.Variable_Elements);
1244
         Array_Element_Table.Init    (Tree.Shared.Array_Elements);
1245
         Array_Table.Init            (Tree.Shared.Arrays);
1246
         Package_Table.Init          (Tree.Shared.Packages);
1247
 
1248
         --  Private part table
1249
 
1250
         Temp_Files_Table.Init (Tree.Shared.Private_Part.Temp_Files);
1251
 
1252
         Tree.Shared.Private_Part.Current_Source_Path_File := No_Path;
1253
         Tree.Shared.Private_Part.Current_Object_Path_File := No_Path;
1254
      end if;
1255
 
1256
      Source_Paths_Htable.Reset    (Tree.Source_Paths_HT);
1257
      Source_Files_Htable.Reset    (Tree.Source_Files_HT);
1258
      Replaced_Source_HTable.Reset (Tree.Replaced_Sources);
1259
 
1260
      Tree.Replaced_Source_Number := 0;
1261
 
1262
      Reset_Units_In_Table (Tree.Units_HT);
1263
      Free_List (Tree.Projects, Free_Project => True);
1264
      Free_Units (Tree.Units_HT);
1265
   end Reset;
1266
 
1267
   -------------------------------------
1268
   -- Set_Current_Object_Path_File_Of --
1269
   -------------------------------------
1270
 
1271
   procedure Set_Current_Object_Path_File_Of
1272
     (Shared : Shared_Project_Tree_Data_Access;
1273
      To     : Path_Name_Type)
1274
   is
1275
   begin
1276
      Shared.Private_Part.Current_Object_Path_File := To;
1277
   end Set_Current_Object_Path_File_Of;
1278
 
1279
   -------------------------------------
1280
   -- Set_Current_Source_Path_File_Of --
1281
   -------------------------------------
1282
 
1283
   procedure Set_Current_Source_Path_File_Of
1284
     (Shared : Shared_Project_Tree_Data_Access;
1285
      To     : Path_Name_Type)
1286
   is
1287
   begin
1288
      Shared.Private_Part.Current_Source_Path_File := To;
1289
   end Set_Current_Source_Path_File_Of;
1290
 
1291
   -----------------------
1292
   -- Set_Path_File_Var --
1293
   -----------------------
1294
 
1295
   procedure Set_Path_File_Var (Name : String; Value : String) is
1296
      Host_Spec : String_Access := To_Host_File_Spec (Value);
1297
   begin
1298
      if Host_Spec = null then
1299
         Prj.Com.Fail
1300
           ("could not convert file name """ & Value & """ to host spec");
1301
      else
1302
         Setenv (Name, Host_Spec.all);
1303
         Free (Host_Spec);
1304
      end if;
1305
   end Set_Path_File_Var;
1306
 
1307
   -------------------
1308
   -- Switches_Name --
1309
   -------------------
1310
 
1311
   function Switches_Name
1312
     (Source_File_Name : File_Name_Type) return File_Name_Type
1313
   is
1314
   begin
1315
      return Extend_Name (Source_File_Name, Switches_Dependency_Suffix);
1316
   end Switches_Name;
1317
 
1318
   -----------
1319
   -- Value --
1320
   -----------
1321
 
1322
   function Value (Image : String) return Casing_Type is
1323
   begin
1324
      for Casing in The_Casing_Images'Range loop
1325
         if To_Lower (Image) = To_Lower (The_Casing_Images (Casing).all) then
1326
            return Casing;
1327
         end if;
1328
      end loop;
1329
 
1330
      raise Constraint_Error;
1331
   end Value;
1332
 
1333
   ---------------------
1334
   -- Has_Ada_Sources --
1335
   ---------------------
1336
 
1337
   function Has_Ada_Sources (Data : Project_Id) return Boolean is
1338
      Lang : Language_Ptr;
1339
 
1340
   begin
1341
      Lang := Data.Languages;
1342
      while Lang /= No_Language_Index loop
1343
         if Lang.Name = Name_Ada then
1344
            return Lang.First_Source /= No_Source;
1345
         end if;
1346
         Lang := Lang.Next;
1347
      end loop;
1348
 
1349
      return False;
1350
   end Has_Ada_Sources;
1351
 
1352
   ------------------------
1353
   -- Contains_ALI_Files --
1354
   ------------------------
1355
 
1356
   function Contains_ALI_Files (Dir : Path_Name_Type) return Boolean is
1357
      Dir_Name : constant String := Get_Name_String (Dir);
1358
      Direct   : Dir_Type;
1359
      Name     : String (1 .. 1_000);
1360
      Last     : Natural;
1361
      Result   : Boolean := False;
1362
 
1363
   begin
1364
      Open (Direct, Dir_Name);
1365
 
1366
      --  For each file in the directory, check if it is an ALI file
1367
 
1368
      loop
1369
         Read (Direct, Name, Last);
1370
         exit when Last = 0;
1371
         Canonical_Case_File_Name (Name (1 .. Last));
1372
         Result := Last >= 5 and then Name (Last - 3 .. Last) = ".ali";
1373
         exit when Result;
1374
      end loop;
1375
 
1376
      Close (Direct);
1377
      return Result;
1378
 
1379
   exception
1380
      --  If there is any problem, close the directory if open and return True.
1381
      --  The library directory will be added to the path.
1382
 
1383
      when others =>
1384
         if Is_Open (Direct) then
1385
            Close (Direct);
1386
         end if;
1387
 
1388
         return True;
1389
   end Contains_ALI_Files;
1390
 
1391
   --------------------------
1392
   -- Get_Object_Directory --
1393
   --------------------------
1394
 
1395
   function Get_Object_Directory
1396
     (Project             : Project_Id;
1397
      Including_Libraries : Boolean;
1398
      Only_If_Ada         : Boolean := False) return Path_Name_Type
1399
   is
1400
   begin
1401
      if (Project.Library and then Including_Libraries)
1402
        or else
1403
          (Project.Object_Directory /= No_Path_Information
1404
            and then (not Including_Libraries or else not Project.Library))
1405
      then
1406
         --  For a library project, add the library ALI directory if there is
1407
         --  no object directory or if the library ALI directory contains ALI
1408
         --  files; otherwise add the object directory.
1409
 
1410
         if Project.Library then
1411
            if Project.Object_Directory = No_Path_Information
1412
              or else Contains_ALI_Files (Project.Library_ALI_Dir.Display_Name)
1413
            then
1414
               return Project.Library_ALI_Dir.Display_Name;
1415
            else
1416
               return Project.Object_Directory.Display_Name;
1417
            end if;
1418
 
1419
            --  For a non-library project, add object directory if it is not a
1420
            --  virtual project, and if there are Ada sources in the project or
1421
            --  one of the projects it extends. If there are no Ada sources,
1422
            --  adding the object directory could disrupt the order of the
1423
            --  object dirs in the path.
1424
 
1425
         elsif not Project.Virtual then
1426
            declare
1427
               Add_Object_Dir : Boolean;
1428
               Prj            : Project_Id;
1429
 
1430
            begin
1431
               Add_Object_Dir := not Only_If_Ada;
1432
               Prj := Project;
1433
               while not Add_Object_Dir and then Prj /= No_Project loop
1434
                  if Has_Ada_Sources (Prj) then
1435
                     Add_Object_Dir := True;
1436
                  else
1437
                     Prj := Prj.Extends;
1438
                  end if;
1439
               end loop;
1440
 
1441
               if Add_Object_Dir then
1442
                  return Project.Object_Directory.Display_Name;
1443
               end if;
1444
            end;
1445
         end if;
1446
      end if;
1447
 
1448
      return No_Path;
1449
   end Get_Object_Directory;
1450
 
1451
   -----------------------------------
1452
   -- Ultimate_Extending_Project_Of --
1453
   -----------------------------------
1454
 
1455
   function Ultimate_Extending_Project_Of
1456
     (Proj : Project_Id) return Project_Id
1457
   is
1458
      Prj : Project_Id;
1459
 
1460
   begin
1461
      Prj := Proj;
1462
      while Prj /= null and then Prj.Extended_By /= No_Project loop
1463
         Prj := Prj.Extended_By;
1464
      end loop;
1465
 
1466
      return Prj;
1467
   end Ultimate_Extending_Project_Of;
1468
 
1469
   -----------------------------------
1470
   -- Compute_All_Imported_Projects --
1471
   -----------------------------------
1472
 
1473
   procedure Compute_All_Imported_Projects
1474
     (Root_Project : Project_Id;
1475
      Tree         : Project_Tree_Ref)
1476
   is
1477
      procedure Analyze_Tree
1478
        (Local_Root : Project_Id;
1479
         Local_Tree : Project_Tree_Ref;
1480
         Context    : Project_Context);
1481
      --  Process Project and all its aggregated project to analyze their own
1482
      --  imported projects.
1483
 
1484
      ------------------
1485
      -- Analyze_Tree --
1486
      ------------------
1487
 
1488
      procedure Analyze_Tree
1489
        (Local_Root : Project_Id;
1490
         Local_Tree : Project_Tree_Ref;
1491
         Context    : Project_Context)
1492
      is
1493
         pragma Unreferenced (Local_Root);
1494
 
1495
         Project : Project_Id;
1496
 
1497
         procedure Recursive_Add
1498
           (Prj     : Project_Id;
1499
            Tree    : Project_Tree_Ref;
1500
            Context : Project_Context;
1501
            Dummy   : in out Boolean);
1502
         --  Recursively add the projects imported by project Project, but not
1503
         --  those that are extended.
1504
 
1505
         -------------------
1506
         -- Recursive_Add --
1507
         -------------------
1508
 
1509
         procedure Recursive_Add
1510
           (Prj     : Project_Id;
1511
            Tree    : Project_Tree_Ref;
1512
            Context : Project_Context;
1513
            Dummy   : in out Boolean)
1514
         is
1515
            pragma Unreferenced (Dummy, Tree);
1516
 
1517
            List : Project_List;
1518
            Prj2 : Project_Id;
1519
 
1520
         begin
1521
            --  A project is not importing itself
1522
 
1523
            Prj2 := Ultimate_Extending_Project_Of (Prj);
1524
 
1525
            if Project /= Prj2 then
1526
 
1527
               --  Check that the project is not already in the list. We know
1528
               --  the one passed to Recursive_Add have never been visited
1529
               --  before, but the one passed it are the extended projects.
1530
 
1531
               List := Project.All_Imported_Projects;
1532
               while List /= null loop
1533
                  if List.Project = Prj2 then
1534
                     return;
1535
                  end if;
1536
 
1537
                  List := List.Next;
1538
               end loop;
1539
 
1540
               --  Add it to the list
1541
 
1542
               Project.All_Imported_Projects :=
1543
                 new Project_List_Element'
1544
                   (Project               => Prj2,
1545
                    From_Encapsulated_Lib =>
1546
                      Context.From_Encapsulated_Lib
1547
                        or else Analyze_Tree.Context.From_Encapsulated_Lib,
1548
                    Next                  => Project.All_Imported_Projects);
1549
            end if;
1550
         end Recursive_Add;
1551
 
1552
         procedure For_All_Projects is
1553
           new For_Every_Project_Imported_Context (Boolean, Recursive_Add);
1554
 
1555
         Dummy : Boolean := False;
1556
         List  : Project_List;
1557
 
1558
      begin
1559
         List := Local_Tree.Projects;
1560
         while List /= null loop
1561
            Project := List.Project;
1562
            Free_List
1563
              (Project.All_Imported_Projects, Free_Project => False);
1564
            For_All_Projects
1565
              (Project, Local_Tree, Dummy, Include_Aggregated => False);
1566
            List := List.Next;
1567
         end loop;
1568
      end Analyze_Tree;
1569
 
1570
      procedure For_Aggregates is
1571
        new For_Project_And_Aggregated_Context (Analyze_Tree);
1572
 
1573
   --  Start of processing for Compute_All_Imported_Projects
1574
 
1575
   begin
1576
      For_Aggregates (Root_Project, Tree);
1577
   end Compute_All_Imported_Projects;
1578
 
1579
   -------------------
1580
   -- Is_Compilable --
1581
   -------------------
1582
 
1583
   function Is_Compilable (Source : Source_Id) return Boolean is
1584
   begin
1585
      case Source.Compilable is
1586
         when Unknown =>
1587
            if Source.Language.Config.Compiler_Driver /= No_File
1588
              and then
1589
                Length_Of_Name (Source.Language.Config.Compiler_Driver) /= 0
1590
              and then not Source.Locally_Removed
1591
              and then (Source.Language.Config.Kind /= File_Based
1592
                         or else Source.Kind /= Spec)
1593
            then
1594
               --  Do not modify Source.Compilable before the source record
1595
               --  has been initialized.
1596
 
1597
               if Source.Source_TS /= Empty_Time_Stamp then
1598
                  Source.Compilable := Yes;
1599
               end if;
1600
 
1601
               return True;
1602
 
1603
            else
1604
               if Source.Source_TS /= Empty_Time_Stamp then
1605
                  Source.Compilable := No;
1606
               end if;
1607
 
1608
               return False;
1609
            end if;
1610
 
1611
         when Yes =>
1612
            return True;
1613
 
1614
         when No =>
1615
            return False;
1616
      end case;
1617
   end Is_Compilable;
1618
 
1619
   ------------------------------
1620
   -- Object_To_Global_Archive --
1621
   ------------------------------
1622
 
1623
   function Object_To_Global_Archive (Source : Source_Id) return Boolean is
1624
   begin
1625
      return Source.Language.Config.Kind = File_Based
1626
        and then Source.Kind = Impl
1627
        and then Source.Language.Config.Objects_Linked
1628
        and then Is_Compilable (Source)
1629
        and then Source.Language.Config.Object_Generated;
1630
   end Object_To_Global_Archive;
1631
 
1632
   ----------------------------
1633
   -- Get_Language_From_Name --
1634
   ----------------------------
1635
 
1636
   function Get_Language_From_Name
1637
     (Project : Project_Id;
1638
      Name    : String) return Language_Ptr
1639
   is
1640
      N      : Name_Id;
1641
      Result : Language_Ptr;
1642
 
1643
   begin
1644
      Name_Len := Name'Length;
1645
      Name_Buffer (1 .. Name_Len) := Name;
1646
      To_Lower (Name_Buffer (1 .. Name_Len));
1647
      N := Name_Find;
1648
 
1649
      Result := Project.Languages;
1650
      while Result /= No_Language_Index loop
1651
         if Result.Name = N then
1652
            return Result;
1653
         end if;
1654
 
1655
         Result := Result.Next;
1656
      end loop;
1657
 
1658
      return No_Language_Index;
1659
   end Get_Language_From_Name;
1660
 
1661
   ----------------
1662
   -- Other_Part --
1663
   ----------------
1664
 
1665
   function Other_Part (Source : Source_Id) return Source_Id is
1666
   begin
1667
      if Source.Unit /= No_Unit_Index then
1668
         case Source.Kind is
1669
            when Impl =>
1670
               return Source.Unit.File_Names (Spec);
1671
            when Spec =>
1672
               return Source.Unit.File_Names (Impl);
1673
            when Sep =>
1674
               return No_Source;
1675
         end case;
1676
      else
1677
         return No_Source;
1678
      end if;
1679
   end Other_Part;
1680
 
1681
   ------------------
1682
   -- Create_Flags --
1683
   ------------------
1684
 
1685
   function Create_Flags
1686
     (Report_Error               : Error_Handler;
1687
      When_No_Sources            : Error_Warning;
1688
      Require_Sources_Other_Lang : Boolean       := True;
1689
      Allow_Duplicate_Basenames  : Boolean       := True;
1690
      Compiler_Driver_Mandatory  : Boolean       := False;
1691
      Error_On_Unknown_Language  : Boolean       := True;
1692
      Require_Obj_Dirs           : Error_Warning := Error;
1693
      Allow_Invalid_External     : Error_Warning := Error;
1694
      Missing_Source_Files       : Error_Warning := Error;
1695
      Ignore_Missing_With        : Boolean       := False)
1696
      return Processing_Flags
1697
   is
1698
   begin
1699
      return Processing_Flags'
1700
        (Report_Error               => Report_Error,
1701
         When_No_Sources            => When_No_Sources,
1702
         Require_Sources_Other_Lang => Require_Sources_Other_Lang,
1703
         Allow_Duplicate_Basenames  => Allow_Duplicate_Basenames,
1704
         Error_On_Unknown_Language  => Error_On_Unknown_Language,
1705
         Compiler_Driver_Mandatory  => Compiler_Driver_Mandatory,
1706
         Require_Obj_Dirs           => Require_Obj_Dirs,
1707
         Allow_Invalid_External     => Allow_Invalid_External,
1708
         Missing_Source_Files       => Missing_Source_Files,
1709
         Ignore_Missing_With        => Ignore_Missing_With);
1710
   end Create_Flags;
1711
 
1712
   ------------
1713
   -- Length --
1714
   ------------
1715
 
1716
   function Length
1717
     (Table : Name_List_Table.Instance;
1718
      List  : Name_List_Index) return Natural
1719
   is
1720
      Count : Natural := 0;
1721
      Tmp   : Name_List_Index;
1722
 
1723
   begin
1724
      Tmp := List;
1725
      while Tmp /= No_Name_List loop
1726
         Count := Count + 1;
1727
         Tmp := Table.Table (Tmp).Next;
1728
      end loop;
1729
 
1730
      return Count;
1731
   end Length;
1732
 
1733
   ------------------
1734
   -- Debug_Output --
1735
   ------------------
1736
 
1737
   procedure Debug_Output (Str : String) is
1738
   begin
1739
      if Current_Verbosity > Default then
1740
         Set_Standard_Error;
1741
         Write_Line ((1 .. Debug_Level * 2 => ' ') & Str);
1742
         Set_Standard_Output;
1743
      end if;
1744
   end Debug_Output;
1745
 
1746
   ------------------
1747
   -- Debug_Indent --
1748
   ------------------
1749
 
1750
   procedure Debug_Indent is
1751
   begin
1752
      if Current_Verbosity = High then
1753
         Set_Standard_Error;
1754
         Write_Str ((1 .. Debug_Level * 2 => ' '));
1755
         Set_Standard_Output;
1756
      end if;
1757
   end Debug_Indent;
1758
 
1759
   ------------------
1760
   -- Debug_Output --
1761
   ------------------
1762
 
1763
   procedure Debug_Output (Str : String; Str2 : Name_Id) is
1764
   begin
1765
      if Current_Verbosity = High then
1766
         Debug_Indent;
1767
         Set_Standard_Error;
1768
         Write_Str (Str);
1769
 
1770
         if Str2 = No_Name then
1771
            Write_Line (" <no_name>");
1772
         else
1773
            Write_Line (" """ & Get_Name_String (Str2) & '"');
1774
         end if;
1775
 
1776
         Set_Standard_Output;
1777
      end if;
1778
   end Debug_Output;
1779
 
1780
   ---------------------------
1781
   -- Debug_Increase_Indent --
1782
   ---------------------------
1783
 
1784
   procedure Debug_Increase_Indent
1785
     (Str : String := ""; Str2 : Name_Id := No_Name)
1786
   is
1787
   begin
1788
      if Str2 /= No_Name then
1789
         Debug_Output (Str, Str2);
1790
      else
1791
         Debug_Output (Str);
1792
      end if;
1793
      Debug_Level := Debug_Level + 1;
1794
   end Debug_Increase_Indent;
1795
 
1796
   ---------------------------
1797
   -- Debug_Decrease_Indent --
1798
   ---------------------------
1799
 
1800
   procedure Debug_Decrease_Indent (Str : String := "") is
1801
   begin
1802
      if Debug_Level > 0 then
1803
         Debug_Level := Debug_Level - 1;
1804
      end if;
1805
 
1806
      if Str /= "" then
1807
         Debug_Output (Str);
1808
      end if;
1809
   end Debug_Decrease_Indent;
1810
 
1811
   ----------------
1812
   -- Debug_Name --
1813
   ----------------
1814
 
1815
   function Debug_Name (Tree : Project_Tree_Ref) return Name_Id is
1816
      P : Project_List;
1817
 
1818
   begin
1819
      Name_Len := 0;
1820
      Add_Str_To_Name_Buffer ("Tree [");
1821
 
1822
      P := Tree.Projects;
1823
      while P /= null loop
1824
         if P /= Tree.Projects then
1825
            Add_Char_To_Name_Buffer (',');
1826
         end if;
1827
 
1828
         Add_Str_To_Name_Buffer (Get_Name_String (P.Project.Name));
1829
 
1830
         P := P.Next;
1831
      end loop;
1832
 
1833
      Add_Char_To_Name_Buffer (']');
1834
 
1835
      return Name_Find;
1836
   end Debug_Name;
1837
 
1838
   ----------
1839
   -- Free --
1840
   ----------
1841
 
1842
   procedure Free (Tree : in out Project_Tree_Appdata) is
1843
      pragma Unreferenced (Tree);
1844
   begin
1845
      null;
1846
   end Free;
1847
 
1848
   --------------------------------
1849
   -- For_Project_And_Aggregated --
1850
   --------------------------------
1851
 
1852
   procedure For_Project_And_Aggregated
1853
     (Root_Project : Project_Id;
1854
      Root_Tree    : Project_Tree_Ref)
1855
   is
1856
      Agg : Aggregated_Project_List;
1857
 
1858
   begin
1859
      Action (Root_Project, Root_Tree);
1860
 
1861
      if Root_Project.Qualifier in Aggregate_Project then
1862
         Agg := Root_Project.Aggregated_Projects;
1863
         while Agg /= null loop
1864
            For_Project_And_Aggregated (Agg.Project, Agg.Tree);
1865
            Agg := Agg.Next;
1866
         end loop;
1867
      end if;
1868
   end For_Project_And_Aggregated;
1869
 
1870
   ----------------------------------------
1871
   -- For_Project_And_Aggregated_Context --
1872
   ----------------------------------------
1873
 
1874
   procedure For_Project_And_Aggregated_Context
1875
     (Root_Project : Project_Id;
1876
      Root_Tree    : Project_Tree_Ref)
1877
   is
1878
 
1879
      procedure Recursive_Process
1880
        (Project : Project_Id;
1881
         Tree    : Project_Tree_Ref;
1882
         Context : Project_Context);
1883
      --  Process Project and all aggregated projects recursively
1884
 
1885
      -----------------------
1886
      -- Recursive_Process --
1887
      -----------------------
1888
 
1889
      procedure Recursive_Process
1890
        (Project : Project_Id;
1891
         Tree    : Project_Tree_Ref;
1892
         Context : Project_Context)
1893
      is
1894
         Agg : Aggregated_Project_List;
1895
         Ctx : Project_Context;
1896
 
1897
      begin
1898
         Action (Project, Tree, Context);
1899
 
1900
         if Project.Qualifier in Aggregate_Project then
1901
            Ctx :=
1902
              (In_Aggregate_Lib      => True,
1903
               From_Encapsulated_Lib =>
1904
                 Context.From_Encapsulated_Lib
1905
                   or else Project.Standalone_Library = Encapsulated);
1906
 
1907
            Agg := Project.Aggregated_Projects;
1908
            while Agg /= null loop
1909
               Recursive_Process (Agg.Project, Agg.Tree, Ctx);
1910
               Agg := Agg.Next;
1911
            end loop;
1912
         end if;
1913
      end Recursive_Process;
1914
 
1915
   --  Start of processing for For_Project_And_Aggregated_Context
1916
 
1917
   begin
1918
      Recursive_Process
1919
        (Root_Project, Root_Tree, Project_Context'(False, False));
1920
   end For_Project_And_Aggregated_Context;
1921
 
1922
--  Package initialization for Prj
1923
 
1924
begin
1925
   --  Make sure that the standard config and user project file extensions are
1926
   --  compatible with canonical case file naming.
1927
 
1928
   Canonical_Case_File_Name (Config_Project_File_Extension);
1929
   Canonical_Case_File_Name (Project_File_Extension);
1930
end Prj;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.