OSDN Git Service

PR other/52438
[pf3gnuchains/gcc-fork.git] / gcc / ada / prj-env.adb
index f2c8500..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,9 +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
-
    ----------------------
    -- Ada_Include_Path --
    ----------------------
@@ -275,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;
@@ -425,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
 
@@ -461,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
@@ -529,9 +527,10 @@ package body Prj.Env is
          while Element (Iter) /= No_Source loop
             Source := Element (Iter);
 
-            if Source.Index >= 1
-              and then not Source.Locally_Removed
+            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;
@@ -779,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
@@ -833,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
 
@@ -864,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;
 
@@ -892,6 +904,8 @@ 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
@@ -984,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;
@@ -1125,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;
@@ -1329,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_Extending_Project_Of
-                          (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
@@ -1353,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_Extending_Project_Of
-                            (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
@@ -1387,6 +1401,45 @@ 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 --
    ----------------
@@ -1684,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;
@@ -1710,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;
@@ -1735,9 +1788,10 @@ 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
-        Shared.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
          Shared.Private_Part.Current_Source_Path_File :=
            Project.Include_Path_File;
@@ -1776,22 +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;
-
    ---------------------
    -- Add_Directories --
    ---------------------
@@ -1981,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;
 
    --------------
@@ -2042,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;
 
-               Add_Str_To_Name_Buffer (Self.Path (First .. Last));
+            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);
-               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
 
@@ -2178,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
@@ -2250,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;