Convert the ScriptInterpreter system to a plugin-based one.

Previously embedded interpreters were handled as ad-hoc source
files compiled into source/Interpreter.  This made it hard to
disable a specific interpreter, or to add support for other
interpreters and allow the developer to choose which interpreter(s)
were enabled for a particular build.

This patch converts script interpreters over to a plugin-based system.
Script interpreters now live in source/Plugins/ScriptInterpreter, and
the canonical LLDB interpreter, ScriptInterpreterPython, is moved there
as well.

Any new code interfacing with the Python C API must live in this location
from here on out.  Additionally, generic code should never need to
reference or make assumptions about the presence of a specific interpreter
going forward.

Differential Revision: http://reviews.llvm.org/D11431
Reviewed By: Greg Clayton

llvm-svn: 243681
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index 7d91653..ac892d2 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -1764,6 +1764,110 @@
     return NULL;
 }
 
+#pragma mark ScriptInterpreter
+
+struct ScriptInterpreterInstance
+{
+    ScriptInterpreterInstance()
+        : name()
+        , language(lldb::eScriptLanguageNone)
+        , description()
+        , create_callback(NULL)
+    {
+    }
+
+    ConstString name;
+    lldb::ScriptLanguage language;
+    std::string description;
+    ScriptInterpreterCreateInstance create_callback;
+};
+
+typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
+
+static Mutex &
+GetScriptInterpreterMutex()
+{
+    static Mutex g_instances_mutex(Mutex::eMutexTypeRecursive);
+    return g_instances_mutex;
+}
+
+static ScriptInterpreterInstances &
+GetScriptInterpreterInstances()
+{
+    static ScriptInterpreterInstances g_instances;
+    return g_instances;
+}
+
+bool
+PluginManager::RegisterPlugin(const ConstString &name, const char *description, lldb::ScriptLanguage script_language,
+                              ScriptInterpreterCreateInstance create_callback)
+{
+    if (!create_callback)
+        return false;
+    ScriptInterpreterInstance instance;
+    assert((bool)name);
+    instance.name = name;
+    if (description && description[0])
+        instance.description = description;
+    instance.create_callback = create_callback;
+    instance.language = script_language;
+    Mutex::Locker locker(GetScriptInterpreterMutex());
+    GetScriptInterpreterInstances().push_back(instance);
+    return false;
+}
+
+bool
+PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)
+{
+    if (!create_callback)
+        return false;
+    Mutex::Locker locker(GetScriptInterpreterMutex());
+    ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
+
+    ScriptInterpreterInstances::iterator pos, end = instances.end();
+    for (pos = instances.begin(); pos != end; ++pos)
+    {
+        if (pos->create_callback != create_callback)
+            continue;
+
+        instances.erase(pos);
+        return true;
+    }
+    return false;
+}
+
+ScriptInterpreterCreateInstance
+PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)
+{
+    Mutex::Locker locker(GetScriptInterpreterMutex());
+    ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
+    if (idx < instances.size())
+        return instances[idx].create_callback;
+    return nullptr;
+}
+
+lldb::ScriptInterpreterSP
+PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter)
+{
+    Mutex::Locker locker(GetScriptInterpreterMutex());
+    ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
+
+    ScriptInterpreterInstances::iterator pos, end = instances.end();
+    ScriptInterpreterCreateInstance none_instance = nullptr;
+    for (pos = instances.begin(); pos != end; ++pos)
+    {
+        if (pos->language == lldb::eScriptLanguageNone)
+            none_instance = pos->create_callback;
+
+        if (script_lang == pos->language)
+            return pos->create_callback(interpreter);
+    }
+
+    // If we didn't find one, return the ScriptInterpreter for the null language.
+    assert(none_instance != nullptr);
+    return none_instance(interpreter);
+}
+
 #pragma mark SymbolFile
 
 struct SymbolFileInstance