this patch addresses several issues with "command script" subcommands:
 a) adds a new --synchronicity (-s) setting for "command script add" that allows the user to decide if scripted commands should run synchronously or asynchronously (which can make a difference in how events are handled)
 b) clears up several error messages
 c) adds a new --allow-reload (-r) setting for "command script import" that allows the user to reload a module even if it has already been imported before
 d) allows filename completion for "command script import" (much like what happens for "target create")
 e) prevents "command script add" from replacing built-in commands with scripted commands
 f) changes AddUserCommand() to take an std::string instead of a const char* (for performance reasons)
plus, it fixes an issue in "type summary add" command handling which caused several test suite errors


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@144035 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index b94c409..73a7085 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -516,19 +516,23 @@
 }
 
 bool
-CommandInterpreter::AddUserCommand (const char *name, 
+CommandInterpreter::AddUserCommand (std::string name, 
                                     const lldb::CommandObjectSP &cmd_sp,
                                     bool can_replace)
 {
-    if (name && name[0])
+    if (!name.empty())
     {
-        std::string name_sstr(name);
-        if (!can_replace)
-        {
-            if (m_user_dict.find (name_sstr) != m_user_dict.end())
-                return false;
-        }
-        m_user_dict[name_sstr] = cmd_sp;
+        
+        const char* name_cstr = name.c_str();
+        
+        // do not allow replacement of internal commands
+        if (CommandExists(name_cstr))
+            return false;
+        
+        if (can_replace == false && UserCommandExists(name_cstr))
+            return false;
+
+        m_user_dict[name] = cmd_sp;
         return true;
     }
     return false;
diff --git a/source/Interpreter/CommandObject.cpp b/source/Interpreter/CommandObject.cpp
index 7a8c88b..2743012 100644
--- a/source/Interpreter/CommandObject.cpp
+++ b/source/Interpreter/CommandObject.cpp
@@ -881,6 +881,7 @@
     { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { NULL, false }, "A regular expression." },
     { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { NULL, false }, "Arguments to be passed to the target program when it starts executing." },
     { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
+    { eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { NULL, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." },
     { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { NULL, false }, "The scripting language to be used for script-based commands.  Currently only Python is valid." },
     { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { NULL, false }, "The word for which you wish to search for information about." },
     { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { NULL, false }, "An Objective-C selector name." },
diff --git a/source/Interpreter/ScriptInterpreterPython.cpp b/source/Interpreter/ScriptInterpreterPython.cpp
index 213a69e..241f081 100644
--- a/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/source/Interpreter/ScriptInterpreterPython.cpp
@@ -1745,6 +1745,7 @@
 
 bool
 ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
+                                              bool can_reload,
                                               lldb_private::Error& error)
 {
     if (!pathname || !pathname[0])
@@ -1802,8 +1803,9 @@
         int refcount = 0;
         // this call will fail if the module does not exist (because the parameter to it is not a string
         // but an actual Python module object, which is non-existant if the module was not imported before)
-        if (ExecuteOneLineWithReturn(command_stream.GetData(),
-                                                         ScriptInterpreterPython::eScriptReturnTypeInt, &refcount) && refcount > 0)
+        bool was_imported = (ExecuteOneLineWithReturn(command_stream.GetData(),
+                                                      ScriptInterpreterPython::eScriptReturnTypeInt, &refcount) && refcount > 0);
+        if (was_imported == true && can_reload == false)
         {
             error.SetErrorString("module already imported");
             return false;
@@ -1831,9 +1833,28 @@
     }
 }
 
+ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler (lldb::DebuggerSP debugger_sp,
+                                                                     ScriptedCommandSynchronicity synchro) :
+    m_debugger_sp(debugger_sp),
+    m_synch_wanted(synchro),
+    m_old_asynch(debugger_sp->GetAsyncExecution())
+{
+    if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous)
+        m_debugger_sp->SetAsyncExecution(false);
+    else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous)
+        m_debugger_sp->SetAsyncExecution(true);
+}
+
+ScriptInterpreterPython::SynchronicityHandler::~SynchronicityHandler()
+{
+    if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
+        m_debugger_sp->SetAsyncExecution(m_old_asynch);
+}
+
 bool
 ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
                                                const char* args,
+                                               ScriptedCommandSynchronicity synchronicity,
                                                lldb_private::CommandReturnObject& cmd_retobj,
                                                Error& error)
 {
@@ -1850,13 +1871,22 @@
     }
     
     lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().GetSP();
+
+    if (!debugger_sp.get())
+    {
+        error.SetErrorString("invalid Debugger pointer");
+        return false;
+    }
     
     bool ret_val;
     
     std::string err_msg;
-    
+
     {
         Locker py_lock(this);
+        SynchronicityHandler synch_handler(debugger_sp,
+                                           synchronicity);
+        
         ret_val = g_swig_call_command       (impl_function,
                                              m_dictionary_name.c_str(),
                                              debugger_sp,
@@ -1864,17 +1894,13 @@
                                              err_msg,
                                              cmd_retobj);
     }
-    
+
     if (!ret_val)
         error.SetErrorString(err_msg.c_str());
     else
         error.Clear();
-        
+    
     return ret_val;
-
-    
-    return true;
-    
 }
 
 // in Python, a special attribute __doc__ contains the docstring