OSDN Git Service

PR other/52438
[pf3gnuchains/gcc-fork.git] / gcc / ada / prj-env.adb
index d58f87e..23d2cbf 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2001-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 2001-2012, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -102,14 +102,6 @@ package body Prj.Env is
    --  Add Object_Dir to object path table. Make sure it is not duplicate
    --  and it is the last one in the current table.
 
-   procedure Set_Path_File_Var (Name : String; Value : String);
-   --  Call Setenv, after calling To_Host_File_Spec
-
-   function Ultimate_Extension_Of
-     (Project : Project_Id) return Project_Id;
-   --  Return a project that is either Project or an extended ancestor of
-   --  Project that itself is not extended.
-
    ----------------------
    -- Ada_Include_Path --
    ----------------------
@@ -280,15 +272,15 @@ package body Prj.Env is
    begin
       --  Check if the directory is already in the table
 
-      for Index in Object_Path_Table.First ..
-                   Object_Path_Table.Last (Object_Paths)
+      for Index in
+        Object_Path_Table.First .. Object_Path_Table.Last (Object_Paths)
       loop
 
          --  If it is, remove it, and add it as the last one
 
          if Object_Paths.Table (Index) = Object_Dir then
-            for Index2 in Index + 1 ..
-                          Object_Path_Table.Last (Object_Paths)
+            for Index2 in
+              Index + 1 .. Object_Path_Table.Last (Object_Paths)
             loop
                Object_Paths.Table (Index2 - 1) := Object_Paths.Table (Index2);
             end loop;
@@ -430,8 +422,8 @@ package body Prj.Env is
 
          --  Check if the source directory is already in the table
 
-         for Index in Source_Path_Table.First ..
-                      Source_Path_Table.Last (Source_Paths)
+         for Index in
+           Source_Path_Table.First .. Source_Path_Table.Last (Source_Paths)
          loop
             --  If it is already, no need to add it
 
@@ -466,6 +458,7 @@ package body Prj.Env is
          Table_Low_Bound      => 1,
          Table_Initial        => 5,
          Table_Increment      => 100);
+
       Default_Naming : constant Naming_Id := Naming_Table.First;
       Namings        : Naming_Table.Instance;
       --  Table storing the naming data for gnatmake/gprmake
@@ -476,9 +469,7 @@ package body Prj.Env is
       File_Name : Path_Name_Type  := No_Path;
       File      : File_Descriptor := Invalid_FD;
 
-      Current_Naming  : Naming_Id;
-      Iter            : Source_Iterator;
-      Source          : Source_Id;
+      Current_Naming : Naming_Id;
 
       procedure Check
         (Project : Project_Id;
@@ -509,11 +500,13 @@ package body Prj.Env is
          In_Tree : Project_Tree_Ref;
          State   : in out Integer)
       is
-         pragma Unreferenced (State, In_Tree);
+         pragma Unreferenced (State);
 
          Lang   : constant Language_Ptr :=
                     Get_Language_From_Name (Project, "ada");
          Naming : Lang_Naming_Data;
+         Iter   : Source_Iterator;
+         Source : Source_Id;
 
       begin
          if Current_Verbosity = High then
@@ -528,6 +521,23 @@ package body Prj.Env is
             return;
          end if;
 
+         --  Visit all the files and process those that need an SFN pragma
+
+         Iter := For_Each_Source (In_Tree, Project);
+         while Element (Iter) /= No_Source loop
+            Source := Element (Iter);
+
+            if not Source.Locally_Removed
+              and then Source.Unit /= null
+              and then
+                (Source.Index >= 1 or else Source.Naming_Exception /= No)
+            then
+               Put (Source);
+            end if;
+
+            Next (Iter);
+         end loop;
+
          Naming := Lang.Config.Naming_Data;
 
          --  Is the naming scheme of this project one that we know?
@@ -692,22 +702,6 @@ package body Prj.Env is
          Check_Imported_Projects
            (For_Project, In_Tree, Dummy, Imported_First => False);
 
-         --  Visit all the files and process those that need an SFN pragma
-
-         Iter := For_Each_Source (In_Tree, For_Project);
-         while Element (Iter) /= No_Source loop
-            Source := Element (Iter);
-
-            if Source.Index >= 1
-              and then not Source.Locally_Removed
-              and then Source.Unit /= null
-            then
-               Put (Source);
-            end if;
-
-            Next (Iter);
-         end loop;
-
          --  If there are no non standard naming scheme, issue the GNAT
          --  standard naming scheme. This will tell the compiler that
          --  a project file is used and will forbid any pragma SFN.
@@ -784,10 +778,9 @@ package body Prj.Env is
       In_Tree  : Project_Tree_Ref;
       Name     : out Path_Name_Type)
    is
-      File   : File_Descriptor := Invalid_FD;
-
-      Buffer : String_Access := new String (1 .. Buffer_Initial);
-      Buffer_Last : Natural := 0;
+      File        : File_Descriptor := Invalid_FD;
+      Buffer      : String_Access   := new String (1 .. Buffer_Initial);
+      Buffer_Last : Natural         := 0;
 
       procedure Put_Name_Buffer;
       --  Put the line contained in the Name_Buffer in the global buffer
@@ -829,6 +822,7 @@ package body Prj.Env is
          Iter   : Source_Iterator;
 
       begin
+         Debug_Output ("Add mapping for project", Project.Name);
          Iter := For_Each_Source (In_Tree, Project, Language => Language);
 
          loop
@@ -837,12 +831,27 @@ package body Prj.Env is
 
             if Source.Replaced_By = No_Source
               and then Source.Path.Name /= No_Path
-              and then
-                (Source.Language.Config.Kind = File_Based
-                  or else Source.Unit /= No_Unit_Index)
+              and then (Source.Language.Config.Kind = File_Based
+                         or else Source.Unit /= No_Unit_Index)
             then
                if Source.Unit /= No_Unit_Index then
-                  Get_Name_String (Source.Unit.Name);
+
+                  --  Put the encoded unit name in the name buffer
+
+                  declare
+                     Uname : constant String :=
+                               Get_Name_String (Source.Unit.Name);
+
+                  begin
+                     Name_Len := 0;
+                     for J in Uname'Range loop
+                        if Uname (J) in Upper_Half_Character then
+                           Store_Encoded_Character (Get_Char_Code (Uname (J)));
+                        else
+                           Add_Char_To_Name_Buffer (Uname (J));
+                        end if;
+                     end loop;
+                  end;
 
                   if Source.Language.Config.Kind = Unit_Based then
 
@@ -868,8 +877,7 @@ package body Prj.Env is
                      end case;
 
                      if Suffix /= No_File then
-                        Add_Str_To_Name_Buffer
-                          (Get_Name_String (Suffix));
+                        Add_Str_To_Name_Buffer (Get_Name_String (Suffix));
                      end if;
                   end if;
 
@@ -896,18 +904,25 @@ package body Prj.Env is
       procedure For_Every_Imported_Project is new
         For_Every_Project_Imported (State => Integer, Action => Process);
 
+      --  Local variables
+
       Dummy : Integer := 0;
 
    --  Start of processing for Create_Mapping_File
 
    begin
-      Create_Temp_File (In_Tree, File, Name, "mapping");
+      if Current_Verbosity = High then
+         Debug_Output ("Create mapping file for", Debug_Name (In_Tree));
+      end if;
+
+      Create_Temp_File (In_Tree.Shared, File, Name, "mapping");
 
       if Current_Verbosity = High then
          Debug_Increase_Indent ("Create mapping file ", Name_Id (Name));
       end if;
 
-      For_Every_Imported_Project (Project, In_Tree, Dummy);
+      For_Every_Imported_Project
+        (Project, In_Tree, Dummy, Include_Aggregated => False);
 
       declare
          Last   : Natural;
@@ -937,7 +952,7 @@ package body Prj.Env is
    ----------------------
 
    procedure Create_Temp_File
-     (In_Tree   : Project_Tree_Ref;
+     (Shared    : Shared_Project_Tree_Data_Access;
       Path_FD   : out File_Descriptor;
       Path_Name : out Path_Name_Type;
       File_Use  : String)
@@ -951,7 +966,7 @@ package body Prj.Env is
                         & Get_Name_String (Path_Name));
          end if;
 
-         Record_Temp_File (In_Tree, Path_Name);
+         Record_Temp_File (Shared, Path_Name);
 
       else
          Prj.Com.Fail
@@ -964,12 +979,12 @@ package body Prj.Env is
    --------------------------
 
    procedure Create_New_Path_File
-     (In_Tree   : Project_Tree_Ref;
+     (Shared    : Shared_Project_Tree_Data_Access;
       Path_FD   : out File_Descriptor;
       Path_Name : out Path_Name_Type)
    is
    begin
-      Create_Temp_File (In_Tree, Path_FD, Path_Name, "path file");
+      Create_Temp_File (Shared, Path_FD, Path_Name, "path file");
    end Create_New_Path_File;
 
    ------------------------------------
@@ -983,12 +998,12 @@ package body Prj.Env is
       Main_Project_Only : Boolean := True;
       Full_Path         : Boolean := False) return String
    is
+
+      Lang          : constant Language_Ptr :=
+                        Get_Language_From_Name (Project, "ada");
       The_Project   : Project_Id := Project;
       Original_Name : String := Name;
 
-      Lang   : constant Language_Ptr :=
-        Get_Language_From_Name (Project, "ada");
-
       Unit              : Unit_Index;
       The_Original_Name : Name_Id;
       The_Spec_Name     : Name_Id;
@@ -1124,10 +1139,8 @@ package body Prj.Env is
             --  Check for spec
 
             if not Main_Project_Only
-              or else
-                (Unit.File_Names (Spec) /= null
-                 and then Unit.File_Names (Spec).Project =
-                   The_Project)
+              or else (Unit.File_Names (Spec) /= null
+                        and then Unit.File_Names (Spec).Project = The_Project)
             then
                declare
                   Current_Name : File_Name_Type;
@@ -1280,7 +1293,7 @@ package body Prj.Env is
          --  If there are Ada sources, call action with the name of every
          --  source directory.
 
-         if Has_Ada_Sources (Project) then
+         if Has_Ada_Sources (Prj) then
             while Current /= Nil_String loop
                The_String := In_Tree.Shared.String_Elements.Table (Current);
                Action (Get_Name_String (The_String.Display_Value));
@@ -1328,19 +1341,20 @@ package body Prj.Env is
 
          while Unit /= null loop
             if Unit.File_Names (Spec) /= null
+              and then not Unit.File_Names (Spec).Locally_Removed
               and then Unit.File_Names (Spec).File /= No_File
               and then
                 (Namet.Get_Name_String
-                     (Unit.File_Names (Spec).File) = Original_Name
-                 or else (Unit.File_Names (Spec).Path /=
-                            No_Path_Information
+                   (Unit.File_Names (Spec).File) = Original_Name
+                 or else (Unit.File_Names (Spec).Path /= No_Path_Information
                           and then
                             Namet.Get_Name_String
-                              (Unit.File_Names (Spec).Path.Name) =
-                            Original_Name))
+                               (Unit.File_Names (Spec).Path.Name) =
+                                                           Original_Name))
             then
-               Project := Ultimate_Extension_Of
-                          (Project => Unit.File_Names (Spec).Project);
+               Project :=
+                 Ultimate_Extending_Project_Of
+                   (Unit.File_Names (Spec).Project);
                Path := Unit.File_Names (Spec).Path.Display_Name;
 
                if Current_Verbosity > Default then
@@ -1352,17 +1366,18 @@ package body Prj.Env is
 
             elsif Unit.File_Names (Impl) /= null
               and then Unit.File_Names (Impl).File /= No_File
+              and then not Unit.File_Names (Impl).Locally_Removed
               and then
                 (Namet.Get_Name_String
                    (Unit.File_Names (Impl).File) = Original_Name
-                 or else (Unit.File_Names (Impl).Path /=
-                            No_Path_Information
-                          and then Namet.Get_Name_String
-                            (Unit.File_Names (Impl).Path.Name) =
-                            Original_Name))
+                  or else (Unit.File_Names (Impl).Path /= No_Path_Information
+                            and then Namet.Get_Name_String
+                                       (Unit.File_Names (Impl).Path.Name) =
+                                                              Original_Name))
             then
-               Project := Ultimate_Extension_Of
-                            (Project => Unit.File_Names (Impl).Project);
+               Project :=
+                 Ultimate_Extending_Project_Of
+                   (Unit.File_Names (Impl).Project);
                Path := Unit.File_Names (Impl).Path.Display_Name;
 
                if Current_Verbosity > Default then
@@ -1386,14 +1401,53 @@ package body Prj.Env is
       end if;
    end Get_Reference;
 
+   ----------------------
+   -- Get_Runtime_Path --
+   ----------------------
+
+   function Get_Runtime_Path
+     (Self : Project_Search_Path;
+      Name : String) return String_Access
+   is
+      function Is_Base_Name (Path : String) return Boolean;
+      --  Returns True if Path has no directory separator
+
+      ------------------
+      -- Is_Base_Name --
+      ------------------
+
+      function Is_Base_Name (Path : String) return Boolean is
+      begin
+         for J in Path'Range loop
+            if Path (J) = Directory_Separator or else Path (J) = '/' then
+               return False;
+            end if;
+         end loop;
+
+         return True;
+      end Is_Base_Name;
+
+      function Find_Rts_In_Path is new Prj.Env.Find_Name_In_Path
+        (Check_Filename => Is_Directory);
+
+      --  Start of processing for Get_Runtime_Path
+
+   begin
+      if not Is_Base_Name (Name) then
+         return Find_Rts_In_Path (Self, Name);
+      else
+         return null;
+      end if;
+   end Get_Runtime_Path;
+
    ----------------
    -- Initialize --
    ----------------
 
    procedure Initialize (In_Tree : Project_Tree_Ref) is
    begin
-      In_Tree.Private_Part.Current_Source_Path_File := No_Path;
-      In_Tree.Private_Part.Current_Object_Path_File := No_Path;
+      In_Tree.Shared.Private_Part.Current_Source_Path_File := No_Path;
+      In_Tree.Shared.Private_Part.Current_Object_Path_File := No_Path;
    end Initialize;
 
    -------------------
@@ -1550,15 +1604,7 @@ package body Prj.Env is
          Unit := Units_Htable.Get_Next (In_Tree.Units_HT);
       end loop;
 
-      --  Get the ultimate extending project
-
-      if Result /= No_Project then
-         while Result.Extended_By /= No_Project loop
-            Result := Result.Extended_By;
-         end loop;
-      end if;
-
-      return Result;
+      return Ultimate_Extending_Project_Of (Result);
    end Project_Of;
 
    -------------------
@@ -1573,6 +1619,8 @@ package body Prj.Env is
       Objects_Path        : Boolean := True)
 
    is
+      Shared : constant Shared_Project_Tree_Data_Access := In_Tree.Shared;
+
       Source_Paths : Source_Path_Table.Instance;
       Object_Paths : Object_Path_Table.Instance;
       --  List of source or object dirs. Only computed the first time this
@@ -1609,7 +1657,7 @@ package body Prj.Env is
          In_Tree : Project_Tree_Ref;
          Dummy   : in out Boolean)
       is
-         pragma Unreferenced (Dummy);
+         pragma Unreferenced (Dummy, In_Tree);
 
          Path : Path_Name_Type;
 
@@ -1622,8 +1670,7 @@ package body Prj.Env is
             --  Ada sources.
 
             if Has_Ada_Sources (Project) then
-               Add_To_Source_Path
-                 (Project.Source_Dirs, In_Tree.Shared, Source_Paths);
+               Add_To_Source_Path (Project.Source_Dirs, Shared, Source_Paths);
             end if;
          end if;
 
@@ -1653,8 +1700,7 @@ package body Prj.Env is
       if Include_Path and then Project.Include_Path_File = No_Path then
          Source_Path_Table.Init (Source_Paths);
          Process_Source_Dirs := True;
-         Create_New_Path_File
-           (In_Tree, Source_FD, Project.Include_Path_File);
+         Create_New_Path_File (Shared, Source_FD, Project.Include_Path_File);
       end if;
 
       --  For the object path, we make a distinction depending on
@@ -1665,7 +1711,7 @@ package body Prj.Env is
             Object_Path_Table.Init (Object_Paths);
             Process_Object_Dirs := True;
             Create_New_Path_File
-              (In_Tree, Object_FD, Project.Objects_Path_File_With_Libs);
+              (Shared, Object_FD, Project.Objects_Path_File_With_Libs);
          end if;
 
       elsif Objects_Path then
@@ -1673,7 +1719,7 @@ package body Prj.Env is
             Object_Path_Table.Init (Object_Paths);
             Process_Object_Dirs := True;
             Create_New_Path_File
-              (In_Tree, Object_FD, Project.Objects_Path_File_Without_Libs);
+              (Shared, Object_FD, Project.Objects_Path_File_Without_Libs);
          end if;
       end if;
 
@@ -1691,8 +1737,8 @@ package body Prj.Env is
       if Source_FD /= Invalid_FD then
          Buffer_Last := 0;
 
-         for Index in Source_Path_Table.First ..
-                      Source_Path_Table.Last (Source_Paths)
+         for Index in
+           Source_Path_Table.First .. Source_Path_Table.Last (Source_Paths)
          loop
             Get_Name_String (Source_Paths.Table (Index));
             Name_Len := Name_Len + 1;
@@ -1717,8 +1763,8 @@ package body Prj.Env is
       if Object_FD /= Invalid_FD then
          Buffer_Last := 0;
 
-         for Index in Object_Path_Table.First ..
-                      Object_Path_Table.Last (Object_Paths)
+         for Index in
+           Object_Path_Table.First .. Object_Path_Table.Last (Object_Paths)
          loop
             Get_Name_String (Object_Paths.Table (Index));
             Name_Len := Name_Len + 1;
@@ -1742,40 +1788,41 @@ package body Prj.Env is
       --  Set the env vars, if they need to be changed, and set the
       --  corresponding flags.
 
-      if Include_Path and then
-         In_Tree.Private_Part.Current_Source_Path_File /=
-           Project.Include_Path_File
+      if Include_Path
+        and then
+          Shared.Private_Part.Current_Source_Path_File /=
+            Project.Include_Path_File
       then
-         In_Tree.Private_Part.Current_Source_Path_File :=
+         Shared.Private_Part.Current_Source_Path_File :=
            Project.Include_Path_File;
          Set_Path_File_Var
            (Project_Include_Path_File,
-            Get_Name_String (In_Tree.Private_Part.Current_Source_Path_File));
+            Get_Name_String (Shared.Private_Part.Current_Source_Path_File));
       end if;
 
       if Objects_Path then
          if Including_Libraries then
-            if In_Tree.Private_Part.Current_Object_Path_File /=
+            if Shared.Private_Part.Current_Object_Path_File /=
               Project.Objects_Path_File_With_Libs
             then
-               In_Tree.Private_Part.Current_Object_Path_File :=
+               Shared.Private_Part.Current_Object_Path_File :=
                  Project.Objects_Path_File_With_Libs;
                Set_Path_File_Var
                  (Project_Objects_Path_File,
                   Get_Name_String
-                    (In_Tree.Private_Part.Current_Object_Path_File));
+                    (Shared.Private_Part.Current_Object_Path_File));
             end if;
 
          else
-            if In_Tree.Private_Part.Current_Object_Path_File /=
+            if Shared.Private_Part.Current_Object_Path_File /=
               Project.Objects_Path_File_Without_Libs
             then
-               In_Tree.Private_Part.Current_Object_Path_File :=
+               Shared.Private_Part.Current_Object_Path_File :=
                  Project.Objects_Path_File_Without_Libs;
                Set_Path_File_Var
                  (Project_Objects_Path_File,
                   Get_Name_String
-                    (In_Tree.Private_Part.Current_Object_Path_File));
+                    (Shared.Private_Part.Current_Object_Path_File));
             end if;
          end if;
       end if;
@@ -1783,40 +1830,6 @@ package body Prj.Env is
       Free (Buffer);
    end Set_Ada_Paths;
 
-   -----------------------
-   -- Set_Path_File_Var --
-   -----------------------
-
-   procedure Set_Path_File_Var (Name : String; Value : String) is
-      Host_Spec : String_Access := To_Host_File_Spec (Value);
-   begin
-      if Host_Spec = null then
-         Prj.Com.Fail
-           ("could not convert file name """ & Value & """ to host spec");
-      else
-         Setenv (Name, Host_Spec.all);
-         Free (Host_Spec);
-      end if;
-   end Set_Path_File_Var;
-
-   ---------------------------
-   -- Ultimate_Extension_Of --
-   ---------------------------
-
-   function Ultimate_Extension_Of
-     (Project : Project_Id) return Project_Id
-   is
-      Result : Project_Id;
-
-   begin
-      Result := Project;
-      while Result.Extended_By /= No_Project loop
-         Result := Result.Extended_By;
-      end loop;
-
-      return Result;
-   end Ultimate_Extension_Of;
-
    ---------------------
    -- Add_Directories --
    ---------------------
@@ -1834,6 +1847,11 @@ package body Prj.Env is
          Self.Path := new String'(Tmp.all & Path_Separator & Path);
          Free (Tmp);
       end if;
+
+      if Current_Verbosity = High then
+         Debug_Output ("Adding directories to Project_Path: """
+                       & Path & '"');
+      end if;
    end Add_Directories;
 
    --------------------
@@ -2001,44 +2019,61 @@ package body Prj.Env is
 
       if Add_Default_Dir then
          declare
-            Prefix : String_Ptr := Sdefault.Search_Dir_Prefix;
+            Prefix : String_Ptr;
 
          begin
-            if Prefix = null then
+            if Sdefault.Search_Dir_Prefix = null then
+
+               --  gprbuild case
+
                Prefix := new String'(Executable_Prefix_Path);
 
-               if Prefix.all /= "" then
-                  if Target_Name /= "" then
-                     Add_Str_To_Name_Buffer
-                       (Path_Separator & Prefix.all &
-                        Target_Name & Directory_Separator &
-                        "lib" & Directory_Separator & "gnat");
-                  end if;
+            else
+               Prefix := new String'(Sdefault.Search_Dir_Prefix.all
+                                     & ".." & Dir_Separator
+                                     & ".." & Dir_Separator
+                                     & ".." & Dir_Separator
+                                     & ".." & Dir_Separator);
+            end if;
+
+            if Prefix.all /= "" then
+               if Target_Name /= "" then
+
+                  --  $prefix/$target/lib/gnat
 
                   Add_Str_To_Name_Buffer
                     (Path_Separator & Prefix.all &
-                     "share" & Directory_Separator & "gpr");
+                     Target_Name);
+
+                  --  Note: Target_Name has a trailing / when it comes from
+                  --  Sdefault.
+
+                  if Name_Buffer (Name_Len) /= '/' then
+                     Add_Char_To_Name_Buffer (Directory_Separator);
+                  end if;
+
                   Add_Str_To_Name_Buffer
-                    (Path_Separator & Prefix.all &
-                     "lib" & Directory_Separator & "gnat");
+                    ("lib" & Directory_Separator & "gnat");
                end if;
 
-            else
-               Self.Path :=
-                 new String'(Name_Buffer (1 .. Name_Len) & Path_Separator &
-                             Prefix.all &
-                             ".." &  Directory_Separator &
-                             ".." & Directory_Separator &
-                             ".." & Directory_Separator & "gnat");
+               --  $prefix/share/gpr
+
+               Add_Str_To_Name_Buffer
+                 (Path_Separator & Prefix.all &
+                  "share" & Directory_Separator & "gpr");
+
+               --  $prefix/lib/gnat
+
+               Add_Str_To_Name_Buffer
+                 (Path_Separator & Prefix.all &
+                  "lib" & Directory_Separator & "gnat");
             end if;
 
             Free (Prefix);
          end;
       end if;
 
-      if Self.Path = null then
-         Self.Path := new String'(Name_Buffer (1 .. Name_Len));
-      end if;
+      Self.Path := new String'(Name_Buffer (1 .. Name_Len));
    end Initialize_Default_Project_Path;
 
    --------------
@@ -2062,91 +2097,93 @@ package body Prj.Env is
       Projects_Paths.Reset (Self.Cache);
    end Set_Path;
 
-   ------------------
-   -- Find_Project --
-   ------------------
+   -----------------------
+   -- Find_Name_In_Path --
+   -----------------------
 
-   procedure Find_Project
-     (Self               : in out Project_Search_Path;
-      Project_File_Name  : String;
-      Directory          : String;
-      Path               : out Namet.Path_Name_Type)
+   function Find_Name_In_Path
+     (Self : Project_Search_Path;
+      Path : String) return String_Access
    is
-      File : constant String := Project_File_Name;
-      --  Have to do a copy, in case the parameter is Name_Buffer, which we
-      --  modify below
+      First  : Natural;
+      Last   : Natural;
 
-      function Try_Path_Name (Path : String) return String_Access;
-      pragma Inline (Try_Path_Name);
-      --  Try the specified Path
+   begin
+      if Current_Verbosity = High then
+         Debug_Output ("Trying " & Path);
+      end if;
 
-      -------------------
-      -- Try_Path_Name --
-      -------------------
+      if Is_Absolute_Path (Path) then
+         if Check_Filename (Path) then
+            return new String'(Path);
+         else
+            return null;
+         end if;
 
-      function Try_Path_Name (Path : String) return String_Access is
-         First  : Natural;
-         Last   : Natural;
-         Result : String_Access := null;
+      else
+         --  Because we don't want to resolve symbolic links, we cannot use
+         --  Locate_Regular_File. So, we try each possible path successively.
 
-      begin
-         if Current_Verbosity = High then
-            Debug_Output ("Trying " & Path);
-         end if;
+         First := Self.Path'First;
+         while First <= Self.Path'Last loop
+            while First <= Self.Path'Last
+              and then Self.Path (First) = Path_Separator
+            loop
+               First := First + 1;
+            end loop;
 
-         if Is_Absolute_Path (Path) then
-            if Is_Regular_File (Path) then
-               Result := new String'(Path);
-            end if;
+            exit when First > Self.Path'Last;
 
-         else
-            --  Because we don't want to resolve symbolic links, we cannot use
-            --  Locate_Regular_File. So, we try each possible path
-            --  successively.
-
-            First := Self.Path'First;
-            while First <= Self.Path'Last loop
-               while First <= Self.Path'Last
-                 and then Self.Path (First) = Path_Separator
-               loop
-                  First := First + 1;
-               end loop;
-
-               exit when First > Self.Path'Last;
-
-               Last := First;
-               while Last < Self.Path'Last
-                 and then Self.Path (Last + 1) /= Path_Separator
-               loop
-                  Last := Last + 1;
-               end loop;
-
-               Name_Len := 0;
-
-               if not Is_Absolute_Path (Self.Path (First .. Last)) then
-                  Add_Str_To_Name_Buffer (Get_Current_Dir);  -- ??? System call
-                  Add_Char_To_Name_Buffer (Directory_Separator);
-               end if;
+            Last := First;
+            while Last < Self.Path'Last
+              and then Self.Path (Last + 1) /= Path_Separator
+            loop
+               Last := Last + 1;
+            end loop;
+
+            Name_Len := 0;
 
-               Add_Str_To_Name_Buffer (Self.Path (First .. Last));
+            if not Is_Absolute_Path (Self.Path (First .. Last)) then
+               Add_Str_To_Name_Buffer (Get_Current_Dir);  -- ??? System call
                Add_Char_To_Name_Buffer (Directory_Separator);
-               Add_Str_To_Name_Buffer (Path);
+            end if;
 
-               if Current_Verbosity = High then
-                  Debug_Output ("Testing file " & Name_Buffer (1 .. Name_Len));
-               end if;
+            Add_Str_To_Name_Buffer (Self.Path (First .. Last));
+            Add_Char_To_Name_Buffer (Directory_Separator);
+            Add_Str_To_Name_Buffer (Path);
 
-               if Is_Regular_File (Name_Buffer (1 .. Name_Len)) then
-                  Result := new String'(Name_Buffer (1 .. Name_Len));
-                  exit;
-               end if;
+            if Current_Verbosity = High then
+               Debug_Output ("Testing file " & Name_Buffer (1 .. Name_Len));
+            end if;
 
-               First := Last + 1;
-            end loop;
-         end if;
+            if Check_Filename (Name_Buffer (1 .. Name_Len)) then
+               return new String'(Name_Buffer (1 .. Name_Len));
+            end if;
+
+            First := Last + 1;
+         end loop;
+      end if;
 
-         return Result;
-      end Try_Path_Name;
+      return null;
+   end Find_Name_In_Path;
+
+   ------------------
+   -- Find_Project --
+   ------------------
+
+   procedure Find_Project
+     (Self               : in out Project_Search_Path;
+      Project_File_Name  : String;
+      Directory          : String;
+      Path               : out Namet.Path_Name_Type)
+   is
+      File : constant String := Project_File_Name;
+      --  Have to do a copy, in case the parameter is Name_Buffer, which we
+      --  modify below
+
+      function Try_Path_Name is new Find_Name_In_Path
+        (Check_Filename => Is_Regular_File);
+      --  Find a file in the project search path.
 
       --  Local Declarations
 
@@ -2198,27 +2235,29 @@ package body Prj.Env is
 
          if not Has_Dot then
             Result := Try_Path_Name
-              (Directory & Directory_Separator &
+              (Self,
+               Directory & Directory_Separator &
                File & Project_File_Extension);
          end if;
 
          --  Then we try <directory>/<file_name>
 
          if Result = null then
-            Result := Try_Path_Name (Directory & Directory_Separator & File);
+            Result := Try_Path_Name
+                       (Self, Directory & Directory_Separator & File);
          end if;
       end if;
 
       --  Then we try <file_name>.<extension>
 
       if Result = null and then not Has_Dot then
-         Result := Try_Path_Name (File & Project_File_Extension);
+         Result := Try_Path_Name (Self, File & Project_File_Extension);
       end if;
 
       --  Then we try <file_name>
 
       if Result = null then
-         Result := Try_Path_Name (File);
+         Result := Try_Path_Name (Self, File);
       end if;
 
       --  If we cannot find the project file, we return an empty string
@@ -2270,7 +2309,6 @@ package body Prj.Env is
       end if;
 
       --  No need to copy the Cache, it will be recomputed as needed
-
    end Copy;
 
 end Prj.Env;