[Lldb-commits] [lldb] r136957 - in /lldb/trunk: include/lldb/Core/FormatManager.h source/Commands/CommandObjectType.cpp source/Commands/CommandObjectType.h test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py test/functionalities/data-formatter/data-formatter-python-synth/main.cpp

Enrico Granata granata.enrico at gmail.com
Thu Aug 4 18:32:50 PDT 2011


Author: enrico
Date: Thu Aug  4 20:32:50 2011
New Revision: 136957

URL: http://llvm.org/viewvc/llvm-project?rev=136957&view=rev
Log:
Option --regex (-x) now also works for synthetic children:
 - Added a test case in python-synth
Minor code improvements in categories, making them ready for adding new element types

Modified:
    lldb/trunk/include/lldb/Core/FormatManager.h
    lldb/trunk/source/Commands/CommandObjectType.cpp
    lldb/trunk/source/Commands/CommandObjectType.h
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp

Modified: lldb/trunk/include/lldb/Core/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=136957&r1=136956&r2=136957&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatManager.h (original)
+++ lldb/trunk/include/lldb/Core/FormatManager.h Thu Aug  4 20:32:50 2011
@@ -632,6 +632,17 @@
     
 public:
     
+    enum FormatCategoryItem
+    {
+        eSummary =         0x0001,
+        eRegexSummary =    0x1001,
+        eFilter =          0x0002,
+        eRegexFilter =     0x1002,
+    };
+    
+    typedef uint16_t FormatCategoryItems;
+    static const uint16_t ALL_ITEM_TYPES = 0xFFFF;
+    
     typedef SummaryNavigator::SharedPointer SummaryNavigatorSP;
     typedef RegexSummaryNavigator::SharedPointer RegexSummaryNavigatorSP;
     typedef FilterNavigator::SharedPointer FilterNavigatorSP;
@@ -715,24 +726,59 @@
     void
     ClearSummaries()
     {
-        m_summary_nav->Clear();
-        m_regex_summary_nav->Clear();
+        Clear(eSummary | eRegexSummary);
     }
     
     // just a shortcut for (Summary()->Delete(name) || RegexSummary()->Delete(name))
     bool
     DeleteSummaries(const char* name)
     {
-        bool del_sum = m_summary_nav->Delete(name);
-        bool del_rex = m_regex_summary_nav->Delete(name);
-        
-        return (del_sum || del_rex);
+        return Delete(name, (eSummary | eRegexSummary));
+    }
+    
+    
+    void
+    Clear(FormatCategoryItems items = ALL_ITEM_TYPES)
+    {
+        if ( (items & eSummary) )
+            m_summary_nav->Clear();
+        if ( (items & eRegexSummary) )
+            m_regex_summary_nav->Clear();
+        if ( (items & eFilter) )
+            m_filter_nav->Clear();
+        if ( (items & eRegexFilter) )
+            m_regex_filter_nav->Clear();
+    }
+    
+    bool
+    Delete(const char* name,
+           FormatCategoryItems items = ALL_ITEM_TYPES)
+    {
+        bool success = false;
+        if ( (items & eSummary) )
+            success = m_summary_nav->Delete(name) || success;
+        if ( (items & eRegexSummary) )
+            success = m_regex_summary_nav->Delete(name) || success;
+        if ( (items & eFilter) )
+            success = m_filter_nav->Delete(name) || success;
+        if ( (items & eRegexFilter) )
+            success = m_regex_filter_nav->Delete(name) || success;
+        return success;
     }
     
     uint32_t
-    GetCount()
+    GetCount(FormatCategoryItems items = ALL_ITEM_TYPES)
     {
-        return Summary()->GetCount() + RegexSummary()->GetCount();
+        uint32_t count = 0;
+        if ( (items & eSummary) )
+            count += m_summary_nav->GetCount();
+        if ( (items & eRegexSummary) )
+            count += m_regex_summary_nav->GetCount();
+        if ( (items & eFilter) )
+            count += m_filter_nav->GetCount();
+        if ( (items & eRegexFilter) )
+            count += m_regex_filter_nav->GetCount();
+        return count;
     }
     
     std::string

Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=136957&r1=136956&r2=136957&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Thu Aug  4 20:32:50 2011
@@ -1168,8 +1168,7 @@
                         const FormatCategory::SharedPointer& cate)
     {
         const char* name = (const char*)param;
-        cate->Summary()->Delete(name);
-        cate->RegexSummary()->Delete(name);
+        cate->Delete(name, FormatCategory::eSummary | FormatCategory::eRegexSummary);
         return true;
     }
 
@@ -1892,6 +1891,7 @@
 //-------------------------------------------------------------------------
 
 bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticFilter::SharedPointer& entry);
+bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticFilter::SharedPointer& entry);
 
 class CommandObjectTypeSynthList;
 
@@ -2044,6 +2044,12 @@
         
         cate->Filter()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp);
         
+        if (cate->RegexFilter()->GetCount() > 0)
+        {
+            result->GetOutputStream().Printf("Regex-based filters (slower):\n");
+            cate->RegexFilter()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp);
+        }
+        
         return true;
     }
     
@@ -2059,6 +2065,7 @@
     }
     
     friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticFilter::SharedPointer& entry);
+    friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticFilter::SharedPointer& entry);
 };
 
 bool
@@ -2070,6 +2077,15 @@
     return param->self->LoopCallback(type, entry, param->regex, param->result);
 }
 
+bool
+CommandObjectTypeSynthRXList_LoopCallback (void* pt2self,
+                                         lldb::RegularExpressionSP regex,
+                                         const SyntheticFilter::SharedPointer& entry)
+{
+    CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
+    return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
+}
+
 
 OptionDefinition
 CommandObjectTypeSynthList::CommandOptions::g_option_table[] =
@@ -2157,8 +2173,7 @@
                         const FormatCategory::SharedPointer& cate)
     {
         const char* name = (const char*)param;
-        cate->Filter()->Delete(name);
-        return true;
+        return cate->Delete(name, FormatCategory::eFilter | FormatCategory::eRegexFilter);
     }
     
 public:
@@ -2217,6 +2232,7 @@
         Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
         
         bool delete_category = category->Filter()->Delete(typeCS.GetCString());
+        delete_category = category->RegexFilter()->Delete(typeCS.GetCString()) || delete_category;
         
         if (delete_category)
         {
@@ -2315,7 +2331,7 @@
                         const char* cate_name,
                         const FormatCategory::SharedPointer& cate)
     {
-        cate->Filter()->Clear();
+        cate->Clear(FormatCategory::eFilter | FormatCategory::eRegexFilter);
         return true;
         
     }
@@ -2352,6 +2368,7 @@
             else
                 Debugger::Formatting::Categories::Get(ConstString(NULL), category);
             category->Filter()->Clear();
+            category->RegexFilter()->Clear();
         }
         
         result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -2506,7 +2523,11 @@
             const char *type_name = options->m_target_types.GetStringAtIndex(i);
             ConstString typeCS(type_name);
             if (typeCS)
-                category->Filter()->Add(typeCS.GetCString(), synth_provider);
+                CommandObjectTypeSynthAdd::AddSynth(typeCS,
+                                                    synth_provider,
+                                                    options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
+                                                    options->m_category,
+                                                    NULL);
             else
             {
                 out_stream->Printf ("Internal error #6: no script attached.\n");
@@ -2517,319 +2538,242 @@
     }
 };
 
-class CommandObjectTypeSynthAdd : public CommandObject
+void
+CommandObjectTypeSynthAdd::CollectPythonScript (SynthAddOptions *options,
+                                                CommandReturnObject &result)
 {
-    
-private:
-    
-    class CommandOptions : public Options
+    InputReaderSP reader_sp (new TypeSynthAddInputReader(m_interpreter.GetDebugger()));
+    if (reader_sp && options)
     {
-        typedef std::vector<std::string> option_vector;
-    public:
         
-        CommandOptions (CommandInterpreter &interpreter) :
-        Options (interpreter)
-        {
-        }
+        InputReaderEZ::InitializationParameters ipr;
         
-        virtual
-        ~CommandOptions (){}
-        
-        virtual Error
-        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt("     ")));
+        if (err.Success())
         {
-            Error error;
-            char short_option = (char) m_getopt_table[option_idx].val;
-            bool success;
-            
-            switch (short_option)
-            {
-                case 'C':
-                    m_cascade = Args::StringToBoolean(option_arg, true, &success);
-                    if (!success)
-                        error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
-                    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);
-                    is_class_based = true;
-                    break;
-                case 'p':
-                    m_skip_pointers = true;
-                    break;
-                case 'r':
-                    m_skip_references = true;
-                    break;
-                case 'w':
-                    m_category = ConstString(option_arg).GetCString();
-                    break;
-                default:
-                    error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
-                    break;
-            }
-            
-            return error;
+            m_interpreter.GetDebugger().PushInputReader (reader_sp);
+            result.SetStatus (eReturnStatusSuccessFinishNoResult);
         }
-        
-        void
-        OptionParsingStarting ()
+        else
         {
-            m_cascade = true;
-            m_class_name = "";
-            m_skip_pointers = false;
-            m_skip_references = false;
-            m_category = NULL;
-            m_expr_paths.clear();
-            is_class_based = false;
-            handwrite_python = false;
-            has_child_list = false;
+            result.AppendError (err.AsCString());
+            result.SetStatus (eReturnStatusFailed);
         }
-        
-        const OptionDefinition*
-        GetDefinitions ()
+    }
+    else
+    {
+        result.AppendError("out of memory");
+        result.SetStatus (eReturnStatusFailed);
+    }
+}
+    
+bool
+CommandObjectTypeSynthAdd::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_regex,
+                                                     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
         {
-            return g_option_table;
+            result.AppendError("empty typenames not allowed");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
         }
-        
-        // Options table: Required for subclasses of Options.
-        
-        static OptionDefinition g_option_table[];
-        
-        // Instance variables to hold the values for command options.
-        
-        bool m_cascade;
-        bool m_skip_references;
-        bool m_skip_pointers;
-        std::string m_class_name;
-        bool m_input_python;
-        option_vector m_expr_paths;
-        const char* m_category;
-        
-        bool is_class_based;
-        
-        bool handwrite_python;
-        
-        bool has_child_list;
-        
-        typedef option_vector::iterator ExpressionPathsIterator;
-    };
+    }
     
-    CommandOptions m_options;
+    CollectPythonScript(options,result);
+    return result.Succeeded();
+}
     
-    virtual Options *
-    GetOptions ()
+bool
+CommandObjectTypeSynthAdd::Execute_ChildrenList (Args& command, CommandReturnObject &result)
+{
+    const size_t argc = command.GetArgumentCount();
+    
+    if (argc < 1)
     {
-        return &m_options;
+        result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+        result.SetStatus(eReturnStatusFailed);
+        return false;
     }
     
-    void
-    CollectPythonScript (SynthAddOptions *options,
-                                                      CommandReturnObject &result)
+    if (m_options.m_expr_paths.size() == 0)
     {
-        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);
-            }
-        }
+        result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
+        result.SetStatus(eReturnStatusFailed);
+        return false;
+    }
+    
+    SyntheticChildrenSP entry;
+    
+    SyntheticFilter* impl = new SyntheticFilter(m_options.m_cascade,
+                                                m_options.m_skip_pointers,
+                                                m_options.m_skip_references);
+    
+    entry.reset(impl);
+    
+    // go through the expression paths
+    CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
+    
+    for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
+        impl->AddExpressionPath(*begin);
+    
+    
+    // now I have a valid provider, let's add it to every type
+    
+    lldb::FormatCategorySP category;
+    Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
+    
+    for (size_t i = 0; i < argc; i++) {
+        const char* typeA = command.GetArgumentAtIndex(i);
+        ConstString typeCS(typeA);
+        if (typeCS)
+            AddSynth(typeCS,
+                     entry,
+                     m_options.m_regex ? eRegexSynth : eRegularSynth,
+                     m_options.m_category,
+                     NULL);
         else
         {
-            result.AppendError("out of memory");
-            result.SetStatus (eReturnStatusFailed);
+            result.AppendError("empty typenames not allowed");
+            result.SetStatus(eReturnStatusFailed);
+            return false;
         }
     }
     
-    bool
-    Execute_HandwritePython (Args& command, CommandReturnObject &result)
+    result.SetStatus(eReturnStatusSuccessFinishNoResult);
+    return result.Succeeded();
+}
+    
+bool
+CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result)
+{
+    const size_t argc = command.GetArgumentCount();
+    
+    if (argc < 1)
     {
-        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();
+        result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+        result.SetStatus(eReturnStatusFailed);
+        return false;
     }
     
-    bool
-    Execute_ChildrenList (Args& command, CommandReturnObject &result)
+    if (m_options.m_class_name.empty() && !m_options.m_input_python)
     {
-        const size_t argc = command.GetArgumentCount();
-        
-        if (argc < 1)
-        {
-            result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
-            result.SetStatus(eReturnStatusFailed);
-            return false;
-        }
-        
-        if (m_options.m_expr_paths.size() == 0)
+        result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str());
+        result.SetStatus(eReturnStatusFailed);
+        return false;
+    }
+    
+    SyntheticChildrenSP entry;
+    
+    SyntheticScriptProvider* impl = new SyntheticScriptProvider(m_options.m_cascade,
+                                                                m_options.m_skip_pointers,
+                                                                m_options.m_skip_references,
+                                                                m_options.m_class_name);
+    
+    entry.reset(impl);
+    
+    // now I have a valid provider, let's add it to every type
+    
+    lldb::FormatCategorySP category;
+    Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
+    
+    for (size_t i = 0; i < argc; i++) {
+        const char* typeA = command.GetArgumentAtIndex(i);
+        ConstString typeCS(typeA);
+        if (typeCS)
+            AddSynth(typeCS,
+                     entry,
+                     m_options.m_regex ? eRegexSynth : eRegularSynth,
+                     m_options.m_category,
+                     NULL);
+        else
         {
-            result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
+            result.AppendError("empty typenames not allowed");
             result.SetStatus(eReturnStatusFailed);
             return false;
         }
-        
-        SyntheticChildrenSP entry;
-        
-        SyntheticFilter* impl = new SyntheticFilter(m_options.m_cascade,
-                                                    m_options.m_skip_pointers,
-                                                    m_options.m_skip_references);
-        
-        entry.reset(impl);
-        
-        // go through the expression paths
-        CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
-        
-        for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
-            impl->AddExpressionPath(*begin);
-        
-        
-        // now I have a valid provider, let's add it to every type
-        
-        lldb::FormatCategorySP category;
-        Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
-        
-        for (size_t i = 0; i < argc; i++) {
-            const char* typeA = command.GetArgumentAtIndex(i);
-            ConstString typeCS(typeA);
-            if (typeCS)
-                category->Filter()->Add(typeCS.GetCString(), entry);
-            else
-            {
-                result.AppendError("empty typenames not allowed");
-                result.SetStatus(eReturnStatusFailed);
-                return false;
-            }
-        }
-        
-        result.SetStatus(eReturnStatusSuccessFinishNoResult);
-        return result.Succeeded();
     }
     
-    bool
-    Execute_PythonClass (Args& command, CommandReturnObject &result)
+    result.SetStatus(eReturnStatusSuccessFinishNoResult);
+    return result.Succeeded();
+}
+    
+CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
+CommandObject (interpreter,
+               "type synth add",
+               "Add a new synthetic provider for a type.",
+               NULL), m_options (interpreter)
+{
+    CommandArgumentEntry type_arg;
+    CommandArgumentData type_style_arg;
+    
+    type_style_arg.arg_type = eArgTypeName;
+    type_style_arg.arg_repetition = eArgRepeatPlus;
+    
+    type_arg.push_back (type_style_arg);
+    
+    m_arguments.push_back (type_arg);
+    
+}
+
+bool
+CommandObjectTypeSynthAdd::AddSynth(const ConstString& type_name,
+         SyntheticChildrenSP entry,
+         SynthFormatType type,
+         const char* category_name,
+         Error* error)
+{
+    lldb::FormatCategorySP category;
+    Debugger::Formatting::Categories::Get(ConstString(category_name), category);
+    
+    if (type == eRegexSynth)
     {
-        const size_t argc = command.GetArgumentCount();
-        
-        if (argc < 1)
+        RegularExpressionSP typeRX(new RegularExpression());
+        if (!typeRX->Compile(type_name.GetCString()))
         {
-            result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
-            result.SetStatus(eReturnStatusFailed);
+            if (error)
+                error->SetErrorString("regex format error (maybe this is not really a regex?)");
             return false;
         }
         
-        if (m_options.m_class_name.empty() && !m_options.m_input_python)
-        {
-            result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str());
-            result.SetStatus(eReturnStatusFailed);
-            return false;
-        }
-        
-        SyntheticChildrenSP entry;
-        
-        SyntheticScriptProvider* impl = new SyntheticScriptProvider(m_options.m_cascade,
-                                                                    m_options.m_skip_pointers,
-                                                                    m_options.m_skip_references,
-                                                                    m_options.m_class_name);
-        
-        entry.reset(impl);
-        
-        // now I have a valid provider, let's add it to every type
-        
-        lldb::FormatCategorySP category;
-        Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category);
-        
-        for (size_t i = 0; i < argc; i++) {
-            const char* typeA = command.GetArgumentAtIndex(i);
-            ConstString typeCS(typeA);
-            if (typeCS)
-                category->Filter()->Add(typeCS.GetCString(), entry);
-            else
-            {
-                result.AppendError("empty typenames not allowed");
-                result.SetStatus(eReturnStatusFailed);
-                return false;
-            }
-        }
-        
-        result.SetStatus(eReturnStatusSuccessFinishNoResult);
-        return result.Succeeded();
-    }
-    
-public:
-        
-    CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
-    CommandObject (interpreter,
-                   "type synth add",
-                   "Add a new synthetic provider for a type.",
-                   NULL), m_options (interpreter)
-    {
-        CommandArgumentEntry type_arg;
-        CommandArgumentData type_style_arg;
-        
-        type_style_arg.arg_type = eArgTypeName;
-        type_style_arg.arg_repetition = eArgRepeatPlus;
-        
-        type_arg.push_back (type_style_arg);
-        
-        m_arguments.push_back (type_arg);
+        category->RegexFilter()->Delete(type_name.GetCString());
+        category->RegexFilter()->Add(typeRX, entry);
         
+        return true;
     }
-    
-    ~CommandObjectTypeSynthAdd ()
+    else
     {
+        category->Filter()->Add(type_name.GetCString(), entry);
+        return true;
     }
+}
     
-    bool
-    Execute (Args& command, CommandReturnObject &result)
-    {
-        if (m_options.handwrite_python)
-            return Execute_HandwritePython(command, result);
-        else if (m_options.is_class_based)
-            return Execute_PythonClass(command, result);
-        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;
-        }
+bool
+CommandObjectTypeSynthAdd::Execute (Args& command, CommandReturnObject &result)
+{
+    if (m_options.handwrite_python)
+        return Execute_HandwritePython(command, result);
+    else if (m_options.is_class_based)
+        return Execute_PythonClass(command, result);
+    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;
     }
-};
+}
 
 OptionDefinition
 CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
@@ -2841,6 +2785,7 @@
     { 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, eArgTypeNone,    "Type Python code to generate a class that provides synthetic children."},
+    { LLDB_OPT_SET_ALL, false,  "regex", 'x', no_argument, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
     { 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=136957&r1=136956&r2=136957&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.h (original)
+++ lldb/trunk/source/Commands/CommandObjectType.h Thu Aug  4 20:32:50 2011
@@ -78,6 +78,7 @@
     bool m_skip_pointers;
     bool m_skip_references;
     bool m_cascade;
+    bool m_regex;
     StringList m_user_source;
     StringList m_target_types;
 
@@ -86,10 +87,12 @@
     SynthAddOptions(bool sptr,
                      bool sref,
                      bool casc,
+                     bool regx,
                      const char* catg) :
     m_skip_pointers(sptr),
     m_skip_references(sref),
     m_cascade(casc),
+    m_regex(regx),
     m_user_source(),
     m_target_types(),
     m_category(catg)
@@ -203,7 +206,157 @@
                const char* category,
                Error* error = NULL);
 };
-
+    
+class CommandObjectTypeSynthAdd : public CommandObject
+{
+    
+private:
+    
+    class CommandOptions : public Options
+    {
+        typedef std::vector<std::string> option_vector;
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+            bool success;
+            
+            switch (short_option)
+            {
+                case 'C':
+                    m_cascade = Args::StringToBoolean(option_arg, true, &success);
+                    if (!success)
+                        error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
+                    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);
+                    is_class_based = true;
+                    break;
+                case 'p':
+                    m_skip_pointers = true;
+                    break;
+                case 'r':
+                    m_skip_references = true;
+                    break;
+                case 'w':
+                    m_category = ConstString(option_arg).GetCString();
+                    break;
+                case 'x':
+                    m_regex = true;
+                    break;
+                default:
+                    error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_cascade = true;
+            m_class_name = "";
+            m_skip_pointers = false;
+            m_skip_references = false;
+            m_category = NULL;
+            m_expr_paths.clear();
+            is_class_based = false;
+            handwrite_python = false;
+            has_child_list = false;
+            m_regex = false;
+        }
+        
+        const OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+        
+        // Options table: Required for subclasses of Options.
+        
+        static OptionDefinition g_option_table[];
+        
+        // Instance variables to hold the values for command options.
+        
+        bool m_cascade;
+        bool m_skip_references;
+        bool m_skip_pointers;
+        std::string m_class_name;
+        bool m_input_python;
+        option_vector m_expr_paths;
+        const char* m_category;
+        
+        bool is_class_based;
+        
+        bool handwrite_python;
+        
+        bool has_child_list;
+        
+        bool m_regex;
+        
+        typedef option_vector::iterator ExpressionPathsIterator;
+    };
+    
+    CommandOptions m_options;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+    void
+    CollectPythonScript (SynthAddOptions *options,
+                         CommandReturnObject &result);    
+    bool
+    Execute_HandwritePython (Args& command, CommandReturnObject &result);    
+    bool
+    Execute_ChildrenList (Args& command, CommandReturnObject &result);    
+    bool
+    Execute_PythonClass (Args& command, CommandReturnObject &result);
+    bool
+    Execute (Args& command, CommandReturnObject &result);
+    
+public:
+    
+    enum SynthFormatType
+    {
+        eRegularSynth,
+        eRegexSynth,
+    };
+    
+    CommandObjectTypeSynthAdd (CommandInterpreter &interpreter);
+    
+    ~CommandObjectTypeSynthAdd ()
+    {
+    }
+    
+    static bool
+    AddSynth(const ConstString& type_name,
+             lldb::SyntheticChildrenSP entry,
+             SynthFormatType type,
+             const char* category_name,
+             Error* error);
+};
 
 } // namespace lldb_private
 

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py?rev=136957&r1=136956&r2=136957&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py Thu Aug  4 20:32:50 2011
@@ -300,13 +300,14 @@
                                '[3] = \"!!!\"'])
 
         # now std::map<K,V>
+        # also take a chance to test regex synth here
 
         self.runCmd("n")
         self.runCmd("frame variable ii -T")
         
         self.runCmd("script from StdMapSynthProvider import *")
-        self.runCmd("type summary add std::intint_map intint_map -f \"map has ${svar%#} items\" -e")
-        self.runCmd("type synth add std::intint_map intint_map -l StdMapSynthProvider")
+        self.runCmd("type summary add -x \"std::map<\" -f \"map has ${svar%#} items\" -e")
+        self.runCmd("type synth add -x \"std::map<\" -l StdMapSynthProvider")
 
 
         self.expect('frame variable ii',
@@ -356,8 +357,8 @@
         self.runCmd("n")
         self.runCmd("frame variable si -T")
 
-        self.runCmd("type summary add std::strint_map strint_map -f \"map has ${svar%#} items\" -e")
-        self.runCmd("type synth add std::strint_map strint_map -l StdMapSynthProvider")
+        #self.runCmd("type summary add std::strint_map strint_map -f \"map has ${svar%#} items\" -e")
+        #self.runCmd("type synth add std::strint_map strint_map -l StdMapSynthProvider")
         
         self.expect('frame variable si',
                     substrs = ['map has 0 items',
@@ -400,8 +401,8 @@
         self.runCmd("n")
         self.runCmd("frame variable is -T")
         
-        self.runCmd("type summary add std::intstr_map intstr_map -f \"map has ${svar%#} items\" -e")
-        self.runCmd("type synth add std::intstr_map intstr_map -l StdMapSynthProvider")
+        #self.runCmd("type summary add std::intstr_map intstr_map -f \"map has ${svar%#} items\" -e")
+        #self.runCmd("type synth add std::intstr_map intstr_map -l StdMapSynthProvider")
 
         self.expect('frame variable is',
                     substrs = ['map has 0 items',
@@ -433,8 +434,8 @@
         self.runCmd("n")
         self.runCmd("frame variable ss -T")
         
-        self.runCmd("type summary add std::strstr_map strstr_map -f \"map has ${svar%#} items\" -e")
-        self.runCmd("type synth add std::strstr_map strstr_map -l StdMapSynthProvider")
+        #self.runCmd("type summary add std::strstr_map strstr_map -f \"map has ${svar%#} items\" -e")
+        #self.runCmd("type synth add std::strstr_map strstr_map -l StdMapSynthProvider")
 
         self.expect('frame variable ss',
                     substrs = ['map has 0 items',

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp?rev=136957&r1=136956&r2=136957&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp Thu Aug  4 20:32:50 2011
@@ -8,10 +8,10 @@
 typedef std::list<int> int_list;
 typedef std::list<std::string> string_list;
 
-typedef std::map<int, int> intint_map;
-typedef std::map<std::string, int> strint_map;
-typedef std::map<int, std::string> intstr_map;
-typedef std::map<std::string, std::string> strstr_map;
+#define intint_map std::map<int, int> 
+#define strint_map std::map<std::string, int> 
+#define intstr_map std::map<int, std::string> 
+#define strstr_map std::map<std::string, std::string> 
 
 struct foo
 {





More information about the lldb-commits mailing list