diff mbox

[Ada] Create the Find_Name_In_Path helper

Message ID 20111104134549.GA7496@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Nov. 4, 2011, 1:45 p.m. UTC
This is a preliminary work.
Add a subprogram in the Prj.Env package so that it is possible to search in
a project path.
No functional change.

Tested on x86_64-pc-linux-gnu, committed on trunk

2011-11-04  Tristan Gingold  <gingold@adacore.com>

	* prj-env.adb, prj-env.ads (Find_Name_In_Path): New function, from
	Find_Project.Try_Path_Name.
	(Find_Project): Use Find_Name_In_Path to implement Try_Path_Name.
diff mbox

Patch

Index: prj-env.adb
===================================================================
--- prj-env.adb	(revision 180934)
+++ prj-env.adb	(working copy)
@@ -2058,91 +2058,92 @@ 
       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)
-   is
-      File : constant String := Project_File_Name;
-      --  Have to do a copy, in case the parameter is Name_Buffer, which we
-      --  modify below
+   function Find_Name_In_Path (Self : Project_Search_Path;
+                               Path : String) return String_Access is
+      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.
+            Last := First;
+            while Last < Self.Path'Last
+              and then Self.Path (Last + 1) /= Path_Separator
+            loop
+               Last := Last + 1;
+            end loop;
 
-            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;
+            Name_Len := 0;
 
-               exit when First > Self.Path'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);
+            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));
+            Add_Char_To_Name_Buffer (Directory_Separator);
+            Add_Str_To_Name_Buffer (Path);
 
-               Name_Len := 0;
+            if Current_Verbosity = High then
+               Debug_Output ("Testing file " & Name_Buffer (1 .. Name_Len));
+            end if;
 
-               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;
+            if Check_Filename (Name_Buffer (1 .. Name_Len)) then
+               return new String'(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);
+            First := Last + 1;
+         end loop;
+      end if;
 
-               if Current_Verbosity = High then
-                  Debug_Output ("Testing file " & Name_Buffer (1 .. Name_Len));
-               end if;
+      return null;
+   end Find_Name_In_Path;
 
-               if Is_Regular_File (Name_Buffer (1 .. Name_Len)) then
-                  Result := new String'(Name_Buffer (1 .. Name_Len));
-                  exit;
-               end if;
+   ------------------
+   -- Find_Project --
+   ------------------
 
-               First := Last + 1;
-            end loop;
-         end if;
+   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
 
-         return Result;
-      end Try_Path_Name;
+      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
 
@@ -2194,27 +2195,30 @@ 
 
          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
Index: prj-env.ads
===================================================================
--- prj-env.ads	(revision 180934)
+++ prj-env.ads	(working copy)
@@ -210,6 +210,16 @@ 
    --  Override the value of the project path. This also removes the implicit
    --  default search directories.
 
+   generic
+      with function Check_Filename (Name : String) return Boolean;
+   function Find_Name_In_Path (Self : Project_Search_Path;
+                               Path : String) return String_Access;
+   --  Find a name in the project search path of Self. Check_Filename is
+   --  the predicate to valid the search.  If Path is an absolute filename,
+   --  simply calls the predicate with Path. Otherwise, calls the predicate
+   --  for each component of the path. Stops as soon as the predicate
+   --  returns True and returns the name, or returns null in case of failure.
+
    procedure Find_Project
      (Self               : in out Project_Search_Path;
       Project_File_Name  : String;