@@ -2733,8 +2733,9 @@ uint64_t replace_all(std::string &str, const std::string &oldStr,
2733
2733
2734
2734
bool ScriptInterpreterPythonImpl::LoadScriptingModule (
2735
2735
const char *pathname, bool init_session, lldb_private::Status &error,
2736
- StructuredData::ObjectSP *module_sp) {
2736
+ StructuredData::ObjectSP *module_sp, FileSpec extra_search_dir ) {
2737
2737
namespace fs = llvm::sys::fs;
2738
+ namespace path = llvm::sys::path;
2738
2739
2739
2740
if (!pathname || !pathname[0 ]) {
2740
2741
error.SetErrorString (" invalid pathname" );
@@ -2743,44 +2744,23 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
2743
2744
2744
2745
lldb::DebuggerSP debugger_sp = m_debugger.shared_from_this ();
2745
2746
2746
- FileSpec target_file (pathname);
2747
- FileSystem::Instance ().Resolve (target_file);
2748
- FileSystem::Instance ().Collect (target_file);
2749
- std::string basename (target_file.GetFilename ().GetCString ());
2750
-
2751
- StreamString command_stream;
2752
-
2753
2747
// Before executing Python code, lock the GIL.
2754
2748
Locker py_lock (this ,
2755
2749
Locker::AcquireLock |
2756
2750
(init_session ? Locker::InitSession : 0 ) | Locker::NoSTDIN,
2757
2751
Locker::FreeAcquiredLock |
2758
2752
(init_session ? Locker::TearDownSession : 0 ));
2759
- fs::file_status st;
2760
- std::error_code ec = status (target_file.GetPath (), st);
2761
-
2762
- if (ec || st.type () == fs::file_type::status_error ||
2763
- st.type () == fs::file_type::type_unknown ||
2764
- st.type () == fs::file_type::file_not_found) {
2765
- // if not a valid file of any sort, check if it might be a filename still
2766
- // dot can't be used but / and \ can, and if either is found, reject
2767
- if (strchr (pathname, ' \\ ' ) || strchr (pathname, ' /' )) {
2768
- error.SetErrorString (" invalid pathname" );
2769
- return false ;
2770
- }
2771
- basename = pathname; // not a filename, probably a package of some sort,
2772
- // let it go through
2773
- } else if (is_directory (st) || is_regular_file (st)) {
2774
- if (target_file.GetDirectory ().IsEmpty ()) {
2775
- error.SetErrorString (" invalid directory name" );
2776
- return false ;
2753
+
2754
+ auto ExtendSysPath = [this ](std::string directory) -> llvm::Error {
2755
+ if (directory.empty ()) {
2756
+ return llvm::make_error<llvm::StringError>(
2757
+ " invalid directory name" , llvm::inconvertibleErrorCode ());
2777
2758
}
2778
2759
2779
- std::string directory = target_file.GetDirectory ().GetCString ();
2780
2760
replace_all (directory, " \\ " , " \\\\ " );
2781
2761
replace_all (directory, " '" , " \\ '" );
2782
2762
2783
- // now make sure that Python has "directory" in the search path
2763
+ // Make sure that Python has "directory" in the search path.
2784
2764
StreamString command_stream;
2785
2765
command_stream.Printf (" if not (sys.path.__contains__('%s')):\n "
2786
2766
" sys.path.insert(1,'%s');\n\n " ,
@@ -2792,27 +2772,68 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
2792
2772
.SetSetLLDBGlobals (false ))
2793
2773
.Success ();
2794
2774
if (!syspath_retval) {
2795
- error. SetErrorString ( " Python sys.path handling failed " );
2796
- return false ;
2775
+ return llvm::make_error<llvm::StringError>(
2776
+ " Python sys.path handling failed " , llvm::inconvertibleErrorCode ()) ;
2797
2777
}
2798
2778
2779
+ return llvm::Error::success ();
2780
+ };
2781
+
2782
+ std::string module_name (pathname);
2783
+
2784
+ if (extra_search_dir) {
2785
+ if (llvm::Error e = ExtendSysPath (extra_search_dir.GetPath ())) {
2786
+ error = std::move (e);
2787
+ return false ;
2788
+ }
2799
2789
} else {
2800
- error.SetErrorString (" no known way to import this module specification" );
2801
- return false ;
2790
+ FileSpec module_file (pathname);
2791
+ FileSystem::Instance ().Resolve (module_file);
2792
+ FileSystem::Instance ().Collect (module_file);
2793
+
2794
+ fs::file_status st;
2795
+ std::error_code ec = status (module_file.GetPath (), st);
2796
+
2797
+ if (ec || st.type () == fs::file_type::status_error ||
2798
+ st.type () == fs::file_type::type_unknown ||
2799
+ st.type () == fs::file_type::file_not_found) {
2800
+ // if not a valid file of any sort, check if it might be a filename still
2801
+ // dot can't be used but / and \ can, and if either is found, reject
2802
+ if (strchr (pathname, ' \\ ' ) || strchr (pathname, ' /' )) {
2803
+ error.SetErrorString (" invalid pathname" );
2804
+ return false ;
2805
+ }
2806
+ // Not a filename, probably a package of some sort, let it go through.
2807
+ } else if (is_directory (st) || is_regular_file (st)) {
2808
+ if (module_file.GetDirectory ().IsEmpty ()) {
2809
+ error.SetErrorString (" invalid directory name" );
2810
+ return false ;
2811
+ }
2812
+ if (llvm::Error e =
2813
+ ExtendSysPath (module_file.GetDirectory ().GetCString ())) {
2814
+ error = std::move (e);
2815
+ return false ;
2816
+ }
2817
+ module_name = module_file.GetFilename ().GetCString ();
2818
+ } else {
2819
+ error.SetErrorString (" no known way to import this module specification" );
2820
+ return false ;
2821
+ }
2802
2822
}
2803
2823
2804
2824
// Strip .py or .pyc extension
2805
- llvm::StringRef extension = target_file. GetFileNameExtension (). GetCString ( );
2825
+ llvm::StringRef extension = llvm::sys::path::extension (module_name );
2806
2826
if (!extension.empty ()) {
2807
2827
if (extension == " .py" )
2808
- basename .resize (basename .length () - 3 );
2828
+ module_name .resize (module_name .length () - 3 );
2809
2829
else if (extension == " .pyc" )
2810
- basename .resize (basename .length () - 4 );
2830
+ module_name .resize (module_name .length () - 4 );
2811
2831
}
2812
2832
2813
2833
// check if the module is already import-ed
2834
+ StreamString command_stream;
2814
2835
command_stream.Clear ();
2815
- command_stream.Printf (" sys.modules.__contains__('%s')" , basename .c_str ());
2836
+ command_stream.Printf (" sys.modules.__contains__('%s')" , module_name .c_str ());
2816
2837
bool does_contain = false ;
2817
2838
// this call will succeed if the module was ever imported in any Debugger
2818
2839
// in the lifetime of the process in which this LLDB framework is living
@@ -2827,9 +2848,9 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
2827
2848
// this call will fail if the module was not imported in this Debugger
2828
2849
// before
2829
2850
command_stream.Clear ();
2830
- command_stream.Printf (" sys.getrefcount(%s)" , basename .c_str ());
2851
+ command_stream.Printf (" sys.getrefcount(%s)" , module_name .c_str ());
2831
2852
bool was_imported_locally = GetSessionDictionary ()
2832
- .GetItemForKey (PythonString (basename ))
2853
+ .GetItemForKey (PythonString (module_name ))
2833
2854
.IsAllocated ();
2834
2855
2835
2856
bool was_imported = (was_imported_globally || was_imported_locally);
@@ -2839,12 +2860,12 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
2839
2860
2840
2861
if (was_imported) {
2841
2862
if (!was_imported_locally)
2842
- command_stream.Printf (" import %s ; reload_module(%s)" , basename. c_str (),
2843
- basename .c_str ());
2863
+ command_stream.Printf (" import %s ; reload_module(%s)" ,
2864
+ module_name. c_str (), module_name .c_str ());
2844
2865
else
2845
- command_stream.Printf (" reload_module(%s)" , basename .c_str ());
2866
+ command_stream.Printf (" reload_module(%s)" , module_name .c_str ());
2846
2867
} else
2847
- command_stream.Printf (" import %s" , basename .c_str ());
2868
+ command_stream.Printf (" import %s" , module_name .c_str ());
2848
2869
2849
2870
error = ExecuteMultipleLines (command_stream.GetData (),
2850
2871
ScriptInterpreter::ExecuteScriptOptions ()
@@ -2855,16 +2876,16 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule(
2855
2876
2856
2877
// if we are here, everything worked
2857
2878
// call __lldb_init_module(debugger,dict)
2858
- if (!LLDBSwigPythonCallModuleInit (basename. c_str (), m_dictionary_name .c_str (),
2859
- debugger_sp)) {
2879
+ if (!LLDBSwigPythonCallModuleInit (module_name .c_str (),
2880
+ m_dictionary_name. c_str (), debugger_sp)) {
2860
2881
error.SetErrorString (" calling __lldb_init_module failed" );
2861
2882
return false ;
2862
2883
}
2863
2884
2864
2885
if (module_sp) {
2865
2886
// everything went just great, now set the module object
2866
2887
command_stream.Clear ();
2867
- command_stream.Printf (" %s" , basename .c_str ());
2888
+ command_stream.Printf (" %s" , module_name .c_str ());
2868
2889
void *module_pyobj = nullptr ;
2869
2890
if (ExecuteOneLineWithReturn (
2870
2891
command_stream.GetData (),
0 commit comments