Add a --language (-l) option to type category {enable|disable} to allow people to turn on and off formatters for a given language

llvm-svn: 246884
diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp
index a50be90..f326cc1 100644
--- a/lldb/source/Commands/CommandObjectType.cpp
+++ b/lldb/source/Commands/CommandObjectType.cpp
@@ -30,6 +30,7 @@
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/Options.h"
 #include "lldb/Interpreter/OptionGroupFormat.h"
+#include "lldb/Target/Language.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
@@ -2460,12 +2461,79 @@
 
 class CommandObjectTypeCategoryEnable : public CommandObjectParsed
 {
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            const int short_option = m_getopt_table[option_idx].val;
+            
+            switch (short_option)
+            {
+                case 'l':
+                    if (option_arg)
+                    {
+                        m_language = Language::GetLanguageTypeFromString(option_arg);
+                        if (m_language == lldb::eLanguageTypeUnknown)
+                            error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
+                    }
+                    break;
+                default:
+                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_language = lldb::eLanguageTypeUnknown;
+        }
+        
+        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.
+        
+        lldb::LanguageType m_language;
+        
+    };
+    
+    CommandOptions m_options;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
 public:
     CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
         CommandObjectParsed (interpreter,
                              "type category enable",
                              "Enable a category as a source of formatters.",
-                             NULL)
+                             NULL),
+        m_options(interpreter)
     {
         CommandArgumentEntry type_arg;
         CommandArgumentData type_style_arg;
@@ -2489,9 +2557,10 @@
     {
         const size_t argc = command.GetArgumentCount();
         
-        if (argc < 1)
+        if (argc < 1 &&
+            m_options.m_language == lldb::eLanguageTypeUnknown)
         {
-            result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
+            result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
             result.SetStatus(eReturnStatusFailed);
             return false;
         }
@@ -2500,7 +2569,7 @@
         {
             DataVisualization::Categories::EnableStar();
         }
-        else
+        else if (argc > 0)
         {
             for (int i = argc - 1; i >= 0; i--)
             {
@@ -2525,12 +2594,22 @@
             }
         }
         
+        if (m_options.m_language != lldb::eLanguageTypeUnknown)
+            DataVisualization::Categories::Enable(m_options.m_language);
+        
         result.SetStatus(eReturnStatusSuccessFinishResult);
         return result.Succeeded();
     }
     
 };
 
+OptionDefinition
+CommandObjectTypeCategoryEnable::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Enable the category for this language."},
+    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+};
+
 //-------------------------------------------------------------------------
 // CommandObjectTypeCategoryDelete
 //-------------------------------------------------------------------------
@@ -2610,12 +2689,79 @@
 
 class CommandObjectTypeCategoryDisable : public CommandObjectParsed
 {
+    class CommandOptions : public Options
+    {
+    public:
+        
+        CommandOptions (CommandInterpreter &interpreter) :
+        Options (interpreter)
+        {
+        }
+        
+        virtual
+        ~CommandOptions (){}
+        
+        virtual Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            const int short_option = m_getopt_table[option_idx].val;
+            
+            switch (short_option)
+            {
+                case 'l':
+                    if (option_arg)
+                    {
+                        m_language = Language::GetLanguageTypeFromString(option_arg);
+                        if (m_language == lldb::eLanguageTypeUnknown)
+                            error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
+                    }
+                    break;
+                default:
+                    error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
+                    break;
+            }
+            
+            return error;
+        }
+        
+        void
+        OptionParsingStarting ()
+        {
+            m_language = lldb::eLanguageTypeUnknown;
+        }
+        
+        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.
+        
+        lldb::LanguageType m_language;
+        
+    };
+    
+    CommandOptions m_options;
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+
 public:
     CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
         CommandObjectParsed (interpreter,
                              "type category disable",
                              "Disable a category as a source of formatters.",
-                             NULL)
+                             NULL),
+        m_options(interpreter)
     {
         CommandArgumentEntry type_arg;
         CommandArgumentData type_style_arg;
@@ -2639,9 +2785,10 @@
     {
         const size_t argc = command.GetArgumentCount();
         
-        if (argc < 1)
+        if (argc < 1 &&
+            m_options.m_language == lldb::eLanguageTypeUnknown)
         {
-            result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
+            result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
             result.SetStatus(eReturnStatusFailed);
             return false;
         }
@@ -2650,7 +2797,7 @@
         {
             DataVisualization::Categories::DisableStar();
         }
-        else
+        else if (argc > 0)
         {
             // the order is not relevant here
             for (int i = argc - 1; i >= 0; i--)
@@ -2667,6 +2814,9 @@
                 DataVisualization::Categories::Disable(typeCS);
             }
         }
+        
+        if (m_options.m_language != lldb::eLanguageTypeUnknown)
+            DataVisualization::Categories::Disable(m_options.m_language);
 
         result.SetStatus(eReturnStatusSuccessFinishResult);
         return result.Succeeded();
@@ -2674,6 +2824,13 @@
     
 };
 
+OptionDefinition
+CommandObjectTypeCategoryDisable::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Enable the category for this language."},
+    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+};
+
 //-------------------------------------------------------------------------
 // CommandObjectTypeCategoryList
 //-------------------------------------------------------------------------
diff --git a/lldb/source/DataFormatters/DataVisualization.cpp b/lldb/source/DataFormatters/DataVisualization.cpp
index 3612541..16e6002 100644
--- a/lldb/source/DataFormatters/DataVisualization.cpp
+++ b/lldb/source/DataFormatters/DataVisualization.cpp
@@ -168,6 +168,13 @@
 }
 
 void
+DataVisualization::Categories::Enable (lldb::LanguageType lang_type)
+{
+    if (LanguageCategory* lang_category = GetFormatManager().GetCategoryForLanguage(lang_type))
+        lang_category->Enable();
+}
+
+void
 DataVisualization::Categories::Disable (const ConstString& category)
 {
     if (GetFormatManager().GetCategory(category)->IsEnabled() == true)
@@ -175,6 +182,13 @@
 }
 
 void
+DataVisualization::Categories::Disable (lldb::LanguageType lang_type)
+{
+    if (LanguageCategory* lang_category = GetFormatManager().GetCategoryForLanguage(lang_type))
+        lang_category->Disable();
+}
+
+void
 DataVisualization::Categories::Enable (const lldb::TypeCategoryImplSP& category,
                                        TypeCategoryMap::Position pos)
 {