diff --git a/lldb/include/lldb/API/SBFileSpec.h b/lldb/include/lldb/API/SBFileSpec.h index 95eeb1544bba..ffbeba87a81f 100644 --- a/lldb/include/lldb/API/SBFileSpec.h +++ b/lldb/include/lldb/API/SBFileSpec.h @@ -36,6 +36,9 @@ public: bool Exists () const; + bool + ResolveExecutableLocation (); + const char * GetFilename() const; diff --git a/lldb/include/lldb/Core/FileSpec.h b/lldb/include/lldb/Core/FileSpec.h index 22ab298f33c2..bea03f3b60aa 100644 --- a/lldb/include/lldb/Core/FileSpec.h +++ b/lldb/include/lldb/Core/FileSpec.h @@ -261,6 +261,21 @@ public: bool Exists () const; + + //------------------------------------------------------------------ + /// Expanded existence test. + /// + /// Call into the Host to see if it can help find the file (e.g. by + /// searching paths set in the environment, etc.). + /// + /// If found, sets the value of m_directory to the directory where the file was found. + /// + /// @return + /// \b true if was able to find the file using expanded search methods, \b false otherwise. + //------------------------------------------------------------------ + bool + ResolveExecutableLocation (); + uint64_t GetByteSize() const; diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h index 7774ba83cac4..6f8a4e4a08b7 100644 --- a/lldb/include/lldb/Host/Host.h +++ b/lldb/include/lldb/Host/Host.h @@ -258,6 +258,9 @@ public: static bool ResolveExecutableInBundle (FileSpec *file); + + static bool + ResolveExecutableLocation (ConstString &directory_name, const ConstString &filename); static uint32_t ListProcessesMatchingName (const char *name, StringList &matches, std::vector &pids); diff --git a/lldb/source/API/SBFileSpec.cpp b/lldb/source/API/SBFileSpec.cpp index e1a83999f031..5ec93f3b4fff 100644 --- a/lldb/source/API/SBFileSpec.cpp +++ b/lldb/source/API/SBFileSpec.cpp @@ -61,6 +61,13 @@ SBFileSpec::Exists () const return false; } +bool +SBFileSpec::ResolveExecutableLocation () +{ + if (m_opaque_ap.get()) + return m_opaque_ap->ResolveExecutableLocation (); + return false; +} int SBFileSpec::ResolvePath (const char *src_path, char *dst_path, size_t dst_len) diff --git a/lldb/source/Commands/CommandObjectFile.cpp b/lldb/source/Commands/CommandObjectFile.cpp index 9db40b029047..54bd975a07ee 100644 --- a/lldb/source/Commands/CommandObjectFile.cpp +++ b/lldb/source/Commands/CommandObjectFile.cpp @@ -117,7 +117,7 @@ CommandObjectFile::Execute { FileSpec file_spec (file_path); - if (! file_spec.Exists()) + if (! file_spec.Exists() && !file_spec.ResolveExecutableLocation()) { result.AppendErrorWithFormat ("File '%s' does not exist.\n", file_path); result.SetStatus (eReturnStatusFailed); diff --git a/lldb/source/Core/FileSpec.cpp b/lldb/source/Core/FileSpec.cpp index 7e2e087a545b..b4aea9c888aa 100644 --- a/lldb/source/Core/FileSpec.cpp +++ b/lldb/source/Core/FileSpec.cpp @@ -22,6 +22,7 @@ #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataBufferMemoryMap.h" #include "lldb/Core/Stream.h" +#include "lldb/Host/Host.h" using namespace lldb; using namespace lldb_private; @@ -414,6 +415,12 @@ FileSpec::Exists () const return GetFileStats (this, &file_stats); } +bool +FileSpec::ResolveExecutableLocation () +{ + return Host::ResolveExecutableLocation (m_directory, m_filename); +} + uint64_t FileSpec::GetByteSize() const { diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index 00ba8468c7cd..f0d476532215 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -727,3 +727,59 @@ Host::OpenFileInExternalEditor (FileSpec &file_spec, uint32_t line_no) return false; } #endif + +bool +Host::ResolveExecutableLocation (ConstString &directory_name, const ConstString &filename) +{ + // If the user specified just a plain filename, there may be additional ways to find the + // file, such as searching the PATH environment variable on UNIX systems. This is the location + // to implement such additional searches. + + // For now the only search we are implementing is search $PATH, which makes no sense if + // the user already specified a directory. + + if (directory_name.GetLength() > 0) + return false; + + std::string search_path (getenv ("PATH")); + char dir_separator = ':'; + + bool done = false; + bool found = false; + size_t start = 0; + while (!done && !found) + { + size_t end = search_path.find (dir_separator, start); + size_t length; + if (end == std::string::npos) + { + done = true; + length = search_path.length() - start; + } + else + length = end - start; + + std::string directory_str = search_path.substr (start, length); + + if (directory_str.length() > 0) + { + StreamString tmp_full_path_name; + if (directory_str[directory_str.length()-1] == '/') + tmp_full_path_name.Printf ("%s%s", directory_str.c_str(), filename.AsCString()); + else + tmp_full_path_name.Printf ("%s/%s", directory_str.c_str(), filename.AsCString()); + + struct stat sb; + + if (::stat (tmp_full_path_name.GetData(), &sb) == 0) + { + found = true; + directory_name.SetCString (directory_str.c_str()); + } + } + + if (!done) + start = end + 1; + } + return found; +} diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp index d128d04040ff..a4adf3f32fb7 100644 --- a/lldb/source/Target/TargetList.cpp +++ b/lldb/source/Target/TargetList.cpp @@ -71,6 +71,10 @@ TargetList::CreateTarget { ModuleSP exe_module_sp; FileSpec resolved_file(file); + + if (!resolved_file.Exists()) + resolved_file.ResolveExecutableLocation (); + if (!Host::ResolveExecutableInBundle (&resolved_file)) resolved_file = file; diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 10ab1a113593..10911da73f05 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -527,6 +527,13 @@ Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit) SBFileSpec file(optarg); if (file.Exists()) m_option_data.m_filename = optarg; + else if (file.ResolveExecutableLocation()) + { + char path[PATH_MAX]; + int path_len; + file.GetPath (path, path_len); + m_option_data.m_filename = path; + } else error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg); } @@ -550,6 +557,14 @@ Driver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit) SBFileSpec file(optarg); if (file.Exists()) m_option_data.m_source_command_files.push_back (optarg); + else if (file.ResolveExecutableLocation()) + { + char final_path[PATH_MAX]; + size_t path_len; + file.GetPath (final_path, path_len); + std::string path_str (final_path); + m_option_data.m_source_command_files.push_back (path_str); + } else error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg); }