cpp runfiles library: compute manifest/dir paths

Use the new codepath (Runfiles::PathsFrom) to
compute the paths of the runfiles manifest file
and runfiles directory.

This method considers the RUNFILES_* envvars but
also the argv0 value, and tries hard to discover
where the runfiles manifest or directory is.

See https://github.com/bazelbuild/bazel/issues/4460

Change-Id: I041b9d12f5c4138853fac1c2bf48873af8e2bd93

Closes #5216.

Change-Id: I041b9d12f5c4138853fac1c2bf48873af8e2bd93
PiperOrigin-RevId: 197146764
diff --git a/tools/cpp/runfiles/runfiles.cc b/tools/cpp/runfiles/runfiles.cc
index 1e6f058..4032ed9 100644
--- a/tools/cpp/runfiles/runfiles.cc
+++ b/tools/cpp/runfiles/runfiles.cc
@@ -156,38 +156,27 @@
 Runfiles* RunfilesImpl::Create(const string& argv0,
                                function<string(const string&)> env_lookup,
                                string* error) {
-  string manifest(std::move(env_lookup("RUNFILES_MANIFEST_FILE")));
+  string manifest, directory;
+  if (!Runfiles::PathsFrom(
+          argv0, env_lookup("RUNFILES_MANIFEST_FILE"),
+          env_lookup("RUNFILES_DIR"),
+          [](const string& path) { return IsReadableFile(path); },
+          [](const string& path) { return IsDirectory(path); }, &manifest,
+          &directory)) {
+    if (error) {
+      std::ostringstream err;
+      err << "ERROR: " << __FILE__ << "(" << __LINE__
+          << "): cannot find runfiles (argv0=\"" << argv0 << "\")";
+      *error = err.str();
+    }
+    return nullptr;
+  }
+
   if (!manifest.empty()) {
     return ManifestBased::Create(manifest, error);
-  }
-
-  string directory(std::move(env_lookup("RUNFILES_DIR")));
-  if (!directory.empty()) {
+  } else {
     return new DirectoryBased(directory);
   }
-
-  manifest = argv0 + ".runfiles_manifest";
-  if (IsReadableFile(manifest)) {
-    return CreateManifestBased(manifest, error);
-  }
-
-  manifest = argv0 + ".runfiles/MANIFEST";
-  if (IsReadableFile(manifest)) {
-    return CreateManifestBased(manifest, error);
-  }
-
-  directory = argv0 + ".runfiles";
-  if (IsDirectory(directory)) {
-    return CreateDirectoryBased(std::move(directory), error);
-  }
-
-  if (error) {
-    std::ostringstream err;
-    err << "ERROR: " << __FILE__ << "(" << __LINE__
-        << "): cannot find runfiles (argv0=\"" << argv0 << "\")";
-    *error = err.str();
-  }
-  return nullptr;
 }
 
 bool IsAbsolute(const string& path) {
@@ -348,15 +337,12 @@
   return new DirectoryBased(directory_path);
 }
 
-bool Runfiles::PathsFrom(const string& argv0,
-                         function<string(string)> env_lookup,
+bool Runfiles::PathsFrom(const string& argv0, string mf, string dir,
                          function<bool(const string&)> is_runfiles_manifest,
                          function<bool(const string&)> is_runfiles_directory,
                          string* out_manifest, string* out_directory) {
   out_manifest->clear();
   out_directory->clear();
-  string mf = env_lookup("RUNFILES_MANIFEST_FILE");
-  string dir = env_lookup("RUNFILES_DIR");
 
   bool mfValid = is_runfiles_manifest(mf);
   bool dirValid = is_runfiles_directory(dir);