[Lldb-commits] [lldb] r135916 - in /lldb/trunk: include/lldb/Core/ include/lldb/Interpreter/ source/Commands/ source/Core/ source/Interpreter/ test/functionalities/data-formatter/data-formatter-python-synth/

Enrico Granata granata.enrico at gmail.com
Mon Jul 25 09:59:05 PDT 2011


Author: enrico
Date: Mon Jul 25 11:59:05 2011
New Revision: 135916

URL: http://llvm.org/viewvc/llvm-project?rev=135916&view=rev
Log:
new flag -P to type synth add lets you type a Python class interactively
added a final newline to fooSynthProvider.py
new option to automatically save user input in InputReaderEZ
checking for NULL pointers in several new places

Modified:
    lldb/trunk/include/lldb/Core/FormatClasses.h
    lldb/trunk/include/lldb/Core/InputReader.h
    lldb/trunk/include/lldb/Core/InputReaderEZ.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
    lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
    lldb/trunk/source/Commands/CommandObjectType.cpp
    lldb/trunk/source/Commands/CommandObjectType.h
    lldb/trunk/source/Core/FormatClasses.cpp
    lldb/trunk/source/Core/InputReader.cpp
    lldb/trunk/source/Core/InputReaderEZ.cpp
    lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
    lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py

Modified: lldb/trunk/include/lldb/Core/FormatClasses.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatClasses.h?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatClasses.h (original)
+++ lldb/trunk/include/lldb/Core/FormatClasses.h Mon Jul 25 11:59:05 2011
@@ -303,7 +303,7 @@
         virtual uint32_t
         CalculateNumChildren()
         {
-            if (m_wrapper == NULL)
+            if (m_wrapper == NULL || m_interpreter == NULL)
                 return 0;
             return m_interpreter->CalculateNumChildren(m_wrapper);
         }
@@ -311,7 +311,7 @@
         virtual lldb::ValueObjectSP
         GetChildAtIndex (uint32_t idx, bool can_create)
         {
-            if (m_wrapper == NULL)
+            if (m_wrapper == NULL || m_interpreter == NULL)
                 return lldb::ValueObjectSP();
             
             PyObject* py_return = (PyObject*)m_interpreter->GetChildAtIndex(m_wrapper, idx);
@@ -323,7 +323,7 @@
             
             lldb::SBValue *sb_ptr = m_interpreter->CastPyObjectToSBValue(py_return);
             
-            if (py_return == NULL)
+            if (py_return == NULL || sb_ptr == NULL)
                 return lldb::ValueObjectSP();
             
             return sb_ptr->m_opaque_sp;
@@ -332,7 +332,7 @@
         virtual uint32_t
         GetIndexOfChildWithName (const ConstString &name)
         {
-            if (m_wrapper == NULL)
+            if (m_wrapper == NULL || m_interpreter == NULL)
                 return UINT32_MAX;
             return m_interpreter->GetIndexOfChildWithName(m_wrapper, name.GetCString());
         }

Modified: lldb/trunk/include/lldb/Core/InputReader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/InputReader.h?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/InputReader.h (original)
+++ lldb/trunk/include/lldb/Core/InputReader.h Mon Jul 25 11:59:05 2011
@@ -15,6 +15,7 @@
 #include "lldb/lldb-public.h"
 #include "lldb/lldb-enumerations.h"
 #include "lldb/Core/Error.h"
+#include "lldb/Core/StringList.h"
 #include "lldb/Host/Predicate.h"
 
 
@@ -63,11 +64,13 @@
         char* m_end_token;
         char* m_prompt;
         bool m_echo;
+        bool m_save_user_input;
     public:
         InitializationParameters() :
         m_baton(NULL),
         m_token_size(lldb::eInputReaderGranularityLine),
-        m_echo(true)
+        m_echo(true),
+        m_save_user_input(false)
         {
             SetEndToken("DONE");
             SetPrompt("> ");
@@ -81,6 +84,13 @@
         }
         
         InitializationParameters&
+        SetSaveUserInput(bool s)
+        {
+            m_save_user_input = s;
+            return *this;
+        }
+        
+        InitializationParameters&
         SetBaton(void* b)
         {
             m_baton = b;
@@ -191,6 +201,18 @@
     {
         return m_echo;
     }
+    
+    StringList&
+    GetUserInput()
+    {
+        return m_user_input;
+    }
+    
+    virtual bool
+    GetSaveUserInput()
+    {
+        return false;
+    }
 
     // Subclasses _can_ override this function to get input as it comes in
     // without any granularity
@@ -239,6 +261,8 @@
     bool m_echo;
     bool m_active;
     Predicate<bool> m_reader_done;
+    StringList m_user_input;
+    bool m_save_user_input;
 
 private:
     DISALLOW_COPY_AND_ASSIGN (InputReader);

Modified: lldb/trunk/include/lldb/Core/InputReaderEZ.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/InputReaderEZ.h?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/InputReaderEZ.h (original)
+++ lldb/trunk/include/lldb/Core/InputReaderEZ.h Mon Jul 25 11:59:05 2011
@@ -75,6 +75,12 @@
     virtual void
     DoneHandler(HandlerData&) {}
     
+    virtual bool
+    GetSaveUserInput()
+    {
+        return m_save_user_input;
+    }
+    
 protected:
     friend class Debugger;
 

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreter.h Mon Jul 25 11:59:05 2011
@@ -101,6 +101,12 @@
         return false;
     }
     
+    virtual bool
+    GenerateTypeSynthClass (StringList &input, StringList &output)
+    {
+        return false;
+    }
+    
     virtual void*
     CreateSyntheticScriptedProvider (std::string class_name,
                                      lldb::ValueObjectSP valobj)

Modified: lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h (original)
+++ lldb/trunk/include/lldb/Interpreter/ScriptInterpreterPython.h Mon Jul 25 11:59:05 2011
@@ -52,6 +52,9 @@
     bool
     GenerateTypeScriptFunction (StringList &input, StringList &output);
     
+    bool
+    GenerateTypeSynthClass (StringList &input, StringList &output);
+    
     // use this if the function code is just a one-liner script
     bool
     GenerateTypeScriptFunction (const char* oneliner, StringList &output);

Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Mon Jul 25 11:59:05 2011
@@ -691,7 +691,6 @@
         result.AppendError("out of memory");
         result.SetStatus (eReturnStatusFailed);
     }
-    
 }
 
 bool
@@ -2372,6 +2371,148 @@
 // CommandObjectTypeSynthAdd
 //-------------------------------------------------------------------------
 
+static const char *g_synth_addreader_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
+                                                      "You must define a Python class with three methods:\n"
+                                                      "def __init__(self, valobj, dict):\n"
+                                                      "def get_child_at_index(self, index):\n"
+                                                      "def get_child_index(self, name):\n"
+                                                      "class synthProvider:";
+
+class TypeSynthAddInputReader : public InputReaderEZ
+{
+private:
+    DISALLOW_COPY_AND_ASSIGN (TypeSynthAddInputReader);
+public:
+    TypeSynthAddInputReader(Debugger& debugger) : 
+    InputReaderEZ(debugger)
+    {}
+    
+    virtual
+    ~TypeSynthAddInputReader()
+    {
+    }
+    
+    virtual void ActivateHandler(HandlerData& data)
+    {
+        StreamSP out_stream = data.GetOutStream();
+        bool batch_mode = data.GetBatchMode();
+        if (!batch_mode)
+        {
+            out_stream->Printf ("%s\n", g_synth_addreader_instructions);
+            if (data.reader.GetPrompt())
+                out_stream->Printf ("%s", data.reader.GetPrompt());
+            out_stream->Flush();
+        }
+    }
+    
+    virtual void ReactivateHandler(HandlerData& data)
+    {
+        StreamSP out_stream = data.GetOutStream();
+        bool batch_mode = data.GetBatchMode();
+        if (data.reader.GetPrompt() && !batch_mode)
+        {
+            out_stream->Printf ("%s", data.reader.GetPrompt());
+            out_stream->Flush();
+        }
+    }
+    virtual void GotTokenHandler(HandlerData& data)
+    {
+        StreamSP out_stream = data.GetOutStream();
+        bool batch_mode = data.GetBatchMode();
+        if (data.bytes && data.bytes_len && data.baton)
+        {
+            ((SynthAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len);
+        }
+        if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
+        {
+            out_stream->Printf ("%s", data.reader.GetPrompt());
+            out_stream->Flush();
+        }
+    }
+    virtual void InterruptHandler(HandlerData& data)
+    {
+        StreamSP out_stream = data.GetOutStream();
+        bool batch_mode = data.GetBatchMode();
+        data.reader.SetIsDone (true);
+        if (!batch_mode)
+        {
+            out_stream->Printf ("Warning: No command attached to breakpoint.\n");
+            out_stream->Flush();
+        }
+    }
+    virtual void EOFHandler(HandlerData& data)
+    {
+        data.reader.SetIsDone (true);
+    }
+    virtual void DoneHandler(HandlerData& data)
+    {
+        StreamSP out_stream = data.GetOutStream();
+        SynthAddOptions *options_ptr = ((SynthAddOptions*)data.baton);
+        if (!options_ptr)
+        {
+            out_stream->Printf ("Internal error #1: no script attached.\n");
+            out_stream->Flush();
+            return;
+        }
+        
+        SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
+        
+        ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+        if (!interpreter)
+        {
+            out_stream->Printf ("Internal error #2: no script attached.\n");
+            out_stream->Flush();
+            return;
+        }
+        StringList class_name_sl;
+        if (!interpreter->GenerateTypeSynthClass (options->m_user_source, 
+                                                  class_name_sl))
+        {
+            out_stream->Printf ("Internal error #3: no script attached.\n");
+            out_stream->Flush();
+            return;
+        }
+        if (class_name_sl.GetSize() == 0)
+        {
+            out_stream->Printf ("Internal error #4: no script attached.\n");
+            out_stream->Flush();
+            return;
+        }
+        const char *class_name = class_name_sl.GetStringAtIndex(0);
+        if (!class_name || !class_name[0])
+        {
+            out_stream->Printf ("Internal error #5: no script attached.\n");
+            out_stream->Flush();
+            return;
+        }
+
+        // everything should be fine now, let's add the synth provider class
+        
+        SyntheticChildrenSP synth_provider;
+        synth_provider.reset(new SyntheticScriptProvider(options->m_cascade,
+                                                         options->m_skip_pointers,
+                                                         options->m_skip_references,
+                                                         std::string(class_name)));
+        
+        
+        lldb::FormatCategorySP category;
+        Debugger::Formatting::Categories::Get(ConstString(options->m_category), category);
+        
+        for (size_t i = 0; i < options->m_target_types.GetSize(); i++) {
+            const char *type_name = options->m_target_types.GetStringAtIndex(i);
+            ConstString typeCS(type_name);
+            if (typeCS)
+                category->Filter()->Add(typeCS.GetCString(), synth_provider);
+            else
+            {
+                out_stream->Printf ("Internal error #6: no script attached.\n");
+                out_stream->Flush();
+                return;
+            }
+        }
+    }
+};
+
 class CommandObjectTypeSynthAdd : public CommandObject
 {
     
@@ -2406,6 +2547,10 @@
                     break;
                 case 'c':
                     m_expr_paths.push_back(option_arg);
+                    has_child_list = true;
+                    break;
+                case 'P':
+                    handwrite_python = true;
                     break;
                 case 'l':
                     m_class_name = std::string(option_arg);
@@ -2438,6 +2583,8 @@
             m_category = NULL;
             m_expr_paths.clear();
             is_class_based = false;
+            handwrite_python = false;
+            has_child_list = false;
         }
         
         const OptionDefinition*
@@ -2462,6 +2609,10 @@
         
         bool is_class_based;
         
+        bool handwrite_python;
+        
+        bool has_child_list;
+        
         typedef option_vector::iterator ExpressionPathsIterator;
     };
     
@@ -2473,6 +2624,61 @@
         return &m_options;
     }
     
+    void
+    CollectPythonScript (SynthAddOptions *options,
+                                                      CommandReturnObject &result)
+    {
+        InputReaderSP reader_sp (new TypeSynthAddInputReader(m_interpreter.GetDebugger()));
+        if (reader_sp && options)
+        {
+            
+            InputReaderEZ::InitializationParameters ipr;
+            
+            Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt("     ")));
+            if (err.Success())
+            {
+                m_interpreter.GetDebugger().PushInputReader (reader_sp);
+                result.SetStatus (eReturnStatusSuccessFinishNoResult);
+            }
+            else
+            {
+                result.AppendError (err.AsCString());
+                result.SetStatus (eReturnStatusFailed);
+            }
+        }
+        else
+        {
+            result.AppendError("out of memory");
+            result.SetStatus (eReturnStatusFailed);
+        }
+    }
+    
+    bool
+    Execute_HandwritePython (Args& command, CommandReturnObject &result)
+    {
+        SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers,
+                                                         m_options.m_skip_references,
+                                                         m_options.m_cascade,
+                                                         m_options.m_category);
+        
+        const size_t argc = command.GetArgumentCount();
+        
+        for (size_t i = 0; i < argc; i++) {
+            const char* typeA = command.GetArgumentAtIndex(i);
+            if (typeA && *typeA)
+                options->m_target_types << typeA;
+            else
+            {
+                result.AppendError("empty typenames not allowed");
+                result.SetStatus(eReturnStatusFailed);
+                return false;
+            }
+        }
+        
+        CollectPythonScript(options,result);
+        return result.Succeeded();
+    }
+    
     bool
     Execute_ChildrenList (Args& command, CommandReturnObject &result)
     {
@@ -2606,10 +2812,18 @@
     bool
     Execute (Args& command, CommandReturnObject &result)
     {
-        if (m_options.is_class_based)
+        if (m_options.handwrite_python)
+            return Execute_HandwritePython(command, result);
+        else if (m_options.is_class_based)
             return Execute_PythonClass(command, result);
-        else
+        else if (m_options.has_child_list)
             return Execute_ChildrenList(command, result);
+        else
+        {
+            result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
+        }
     }
 };
 
@@ -2622,6 +2836,7 @@
     { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
     { LLDB_OPT_SET_1, false, "child", 'c', required_argument, NULL, 0, eArgTypeName,    "Include this expression path in the synthetic view."},
     { LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypeName,    "Use this Python class to produce synthetic children."},
+    { LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeBoolean,    "Type Python code to generate a class that provides synthetic children."},
     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
 };
 

Modified: lldb/trunk/source/Commands/CommandObjectType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.h?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.h (original)
+++ lldb/trunk/source/Commands/CommandObjectType.h Mon Jul 25 11:59:05 2011
@@ -70,6 +70,37 @@
     
 };
     
+class SynthAddOptions
+{
+    
+public:
+    
+    bool m_skip_pointers;
+    bool m_skip_references;
+    bool m_cascade;
+    StringList m_user_source;
+    StringList m_target_types;
+
+    const char* m_category;
+    
+    SynthAddOptions(bool sptr,
+                     bool sref,
+                     bool casc,
+                     const char* catg) :
+    m_skip_pointers(sptr),
+    m_skip_references(sref),
+    m_cascade(casc),
+    m_user_source(),
+    m_target_types(),
+    m_category(catg)
+    {
+    }
+    
+    typedef lldb::SharedPtr<SynthAddOptions>::Type SharedPointer;
+    
+};
+
+    
 class CommandObjectType : public CommandObjectMultiword
 {
 public:

Modified: lldb/trunk/source/Core/FormatClasses.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FormatClasses.cpp?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/source/Core/FormatClasses.cpp (original)
+++ lldb/trunk/source/Core/FormatClasses.cpp Mon Jul 25 11:59:05 2011
@@ -164,15 +164,26 @@
 SyntheticChildrenFrontEnd(be),
 m_python_class(pclass)
 {
+    if (be.get() == NULL)
+    {
+        m_interpreter = NULL;
+        m_wrapper = NULL;
+        return;
+    }
+    
     m_interpreter = be->GetUpdatePoint().GetTarget()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
-    m_wrapper = (PyObject*)m_interpreter->CreateSyntheticScriptedProvider(m_python_class, m_backend);
+    
+    if (m_interpreter == NULL)
+        m_wrapper = NULL;
+    else
+        m_wrapper = (PyObject*)m_interpreter->CreateSyntheticScriptedProvider(m_python_class, m_backend);
 }
 
 std::string
 SyntheticScriptProvider::GetDescription()
 {
     StreamString sstr;
-    sstr.Printf("%s%s%s Python class: %s",
+    sstr.Printf("%s%s%s Python class %s",
                 m_cascades ? "" : " (not cascading)",
                 m_skip_pointers ? " (skip pointers)" : "",
                 m_skip_references ? " (skip references)" : "",

Modified: lldb/trunk/source/Core/InputReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/InputReader.cpp?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/source/Core/InputReader.cpp (original)
+++ lldb/trunk/source/Core/InputReader.cpp Mon Jul 25 11:59:05 2011
@@ -25,7 +25,9 @@
     m_done (true),
     m_echo (true),
     m_active (false), 
-    m_reader_done (false)
+    m_reader_done (false),
+    m_user_input(),
+    m_save_user_input(false)
 {
 }
 

Modified: lldb/trunk/source/Core/InputReaderEZ.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/InputReaderEZ.cpp?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/source/Core/InputReaderEZ.cpp (original)
+++ lldb/trunk/source/Core/InputReaderEZ.cpp Mon Jul 25 11:59:05 2011
@@ -45,7 +45,11 @@
             reader.AsynchronousOutputWrittenHandler(hand_data);
             break;
         case eInputReaderGotToken:
+        {
+            if (reader.GetSaveUserInput())
+                reader.GetUserInput().AppendString(bytes, bytes_len);            
             reader.GotTokenHandler(hand_data);
+        }
             break;
         case eInputReaderInterrupt:
             reader.InterruptHandler(hand_data);
@@ -78,11 +82,13 @@
 Error
 InputReaderEZ::Initialize(InitializationParameters& params)
 {
-    return Initialize(params.m_baton,
-                      params.m_token_size,
-                      params.m_end_token,
-                      params.m_prompt,
-                      params.m_echo);
+    Error ret =  Initialize(params.m_baton,
+                            params.m_token_size,
+                            params.m_end_token,
+                            params.m_prompt,
+                            params.m_echo);
+    m_save_user_input = params.m_save_user_input;
+    return ret;
 }
 
 InputReaderEZ::~InputReaderEZ ()

Modified: lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectSyntheticFilter.cpp Mon Jul 25 11:59:05 2011
@@ -131,7 +131,7 @@
     
     if (iter == m_children_byindex.end())
     {
-        if (can_create)
+        if (can_create && m_synth_filter != NULL)
         {
             lldb::ValueObjectSP synth_guy = m_synth_filter->GetChildAtIndex (idx, can_create);
             m_children_byindex[idx]= synth_guy;
@@ -161,13 +161,16 @@
 {
     NameToIndexIterator iter = m_name_toindex.find(name.GetCString());
     
-    if (iter == m_name_toindex.end())
+    if (iter == m_name_toindex.end() && m_synth_filter != NULL)
     {
         uint32_t index = m_synth_filter->GetIndexOfChildWithName (name);
         m_name_toindex[name.GetCString()] = index;
         return index;
     }
-    return iter->second;
+    else if (iter == m_name_toindex.end() && m_synth_filter == NULL)
+        return UINT32_MAX;
+    else /*if (iter != m_name_toindex.end())*/
+        return iter->second;
 }
 
 bool

Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Mon Jul 25 11:59:05 2011
@@ -1249,6 +1249,54 @@
     return true;
 }
 
+bool
+ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, StringList &output)
+{
+    static int num_created_classes = 0;
+    user_input.RemoveBlankLines ();
+    int num_lines = user_input.GetSize ();
+    StreamString sstr;
+    
+    // Check to see if we have any data; if not, just return.
+    if (user_input.GetSize() == 0)
+        return false;
+    
+    // Wrap all user input into a Python class
+    
+    sstr.Printf ("lldb_autogen_python_type_synth_class_%d", num_created_classes);
+    ++num_created_classes;
+    std::string auto_generated_class_name = sstr.GetData();
+    
+    sstr.Clear();
+    StringList auto_generated_class;
+    
+    // Create the function name & definition string.
+    
+    sstr.Printf ("class %s:", auto_generated_class_name.c_str());
+    auto_generated_class.AppendString (sstr.GetData());
+        
+    // Wrap everything up inside the class, increasing the indentation.
+    
+    for (int i = 0; i < num_lines; ++i)
+    {
+        sstr.Clear ();
+        sstr.Printf ("     %s", user_input.GetStringAtIndex (i));
+        auto_generated_class.AppendString (sstr.GetData());
+    }
+    
+    
+    // Verify that the results are valid Python.
+    // (even though the method is ExportFunctionDefinitionToInterpreter, a class will actually be exported)
+    // (TODO: rename that method to ExportDefinitionToInterpreter)
+    if (!ExportFunctionDefinitionToInterpreter (auto_generated_class))
+        return false;
+    
+    // Store the name of the auto-generated class
+    
+    output.AppendString (auto_generated_class_name.c_str());
+    return true;
+}
+
 void*
 ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name,
                                                           lldb::ValueObjectSP valobj)

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py?rev=135916&r1=135915&r2=135916&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/fooSynthProvider.py Mon Jul 25 11:59:05 2011
@@ -13,4 +13,4 @@
          if name == 'a':
              return 1;
          else:
-             return 0;
\ No newline at end of file
+             return 0;





More information about the lldb-commits mailing list