Add the ability to disable individual log categories, rather
than just the entire log channel.

Add checks, where appropriate, to make sure a log channel/category has 
not been disabled before attempting to write to it.

llvm-svn: 117715
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index be8aaf7..d53bf81 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -209,11 +209,14 @@
 
     while (state == eStateRunning)
     {
+        log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
         if (log)
             log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...)", __FUNCTION__);
 
         if (WaitForPacket (response, (TimeValue*)NULL))
         {
+            log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
+            async_log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_ASYNC);
             if (response.Empty())
                 state = eStateInvalid;
             else
@@ -344,11 +347,13 @@
         }
         else
         {
+            log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
             if (log)
                 log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
             state = eStateInvalid;
         }
     }
+    log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
     if (log)
         log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
     response.SetFilePos(0);
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 4fca6f0..2cc9e0a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1212,6 +1212,7 @@
     StringExtractorGDBRemote response;
     if (m_gdb_comm.SendPacketAndWaitForResponse("k", response, 2, false))
     {
+        log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
         if (log)
         {
             if (response.IsOKPacket())
@@ -2101,6 +2102,7 @@
         bool done = false;
         while (!done)
         {
+            log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
             if (log)
                 log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
             if (listener.WaitForEvent (NULL, event_sp))
@@ -2116,6 +2118,7 @@
                             {
                                 const char *continue_cstr = (const char *)continue_packet->GetBytes ();
                                 const size_t continue_cstr_len = continue_packet->GetByteSize ();
+                                log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
                                 if (log)
                                     log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
 
@@ -2153,12 +2156,14 @@
                         break;
 
                     case eBroadcastBitAsyncThreadShouldExit:
+                        log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
                         if (log)
                             log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
                         done = true;
                         break;
 
                     default:
+                        log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
                         if (log)
                             log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
                         done = true;
@@ -2167,6 +2172,7 @@
             }
             else
             {
+                log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
                 if (log)
                     log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
                 done = true;
@@ -2174,6 +2180,7 @@
         }
     }
 
+    log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS);
     if (log)
         log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
 
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
index 5a73486..776ffeb 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
@@ -35,7 +35,7 @@
 }
 
 void
-ProcessGDBRemoteLog::DisableLog ()
+ProcessGDBRemoteLog::DeleteLog ()
 {
     if (g_log)
     {
@@ -44,10 +44,53 @@
     }
 }
 
+void
+ProcessGDBRemoteLog::DisableLog (Args &args, Stream *feedback_strm)
+{
+    if (g_log)
+    {
+        uint32_t flag_bits = g_log->GetMask().Get();
+        const size_t argc = args.GetArgumentCount ();
+        for (size_t i = 0; i < argc; ++i)
+        {
+            const char *arg = args.GetArgumentAtIndex (i);
+            
+
+            if      (::strcasecmp (arg, "all")        == 0   ) flag_bits &= ~GDBR_LOG_ALL;
+            else if (::strcasecmp (arg, "async")      == 0   ) flag_bits &= ~GDBR_LOG_ASYNC;
+            else if (::strcasestr (arg, "break")      == arg ) flag_bits &= ~GDBR_LOG_BREAKPOINTS;
+            else if (::strcasestr (arg, "comm")       == arg ) flag_bits &= ~GDBR_LOG_COMM;
+            else if (::strcasecmp (arg, "default")    == 0   ) flag_bits &= ~GDBR_LOG_DEFAULT;
+            else if (::strcasecmp (arg, "packets")    == 0   ) flag_bits &= ~GDBR_LOG_PACKETS;
+            else if (::strcasecmp (arg, "memory")     == 0   ) flag_bits &= ~GDBR_LOG_MEMORY;
+            else if (::strcasecmp (arg, "data-short") == 0   ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_SHORT;
+            else if (::strcasecmp (arg, "data-long")  == 0   ) flag_bits &= ~GDBR_LOG_MEMORY_DATA_LONG;
+            else if (::strcasecmp (arg, "process")    == 0   ) flag_bits &= ~GDBR_LOG_PROCESS;
+            else if (::strcasecmp (arg, "step")       == 0   ) flag_bits &= ~GDBR_LOG_STEP;
+            else if (::strcasecmp (arg, "thread")     == 0   ) flag_bits &= ~GDBR_LOG_THREAD;
+            else if (::strcasecmp (arg, "verbose")    == 0   ) flag_bits &= ~GDBR_LOG_VERBOSE;
+            else if (::strcasestr (arg, "watch")      == arg ) flag_bits &= ~GDBR_LOG_WATCHPOINTS;
+            else
+            {
+                feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+                ListLogCategories (feedback_strm);
+            }
+            
+        }
+        
+        if (flag_bits == 0)
+            DeleteLog();
+        else
+            g_log->GetMask().Reset (flag_bits);
+    }
+    
+    return;
+}
+
 Log *
 ProcessGDBRemoteLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, Args &args, Stream *feedback_strm)
 {
-    DisableLog ();
+    DeleteLog ();
     g_log = new Log (log_stream_sp);
     if (g_log)
     {
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
index c053d29..2dbd94f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
@@ -39,8 +39,11 @@
     GetLogIfAllCategoriesSet(uint32_t mask = 0);
 
     static void
-    DisableLog ();
+    DisableLog (lldb_private::Args &args, lldb_private::Stream *feedback_strm);
 
+    static void
+    DeleteLog ();
+    
     static lldb_private::Log *
     EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, lldb_private::Args &args, lldb_private::Stream *feedback_strm);