[Lldb-commits] [lldb] r115546 - in /lldb/trunk: include/lldb/Core/InputReader.h include/lldb/Interpreter/CommandInterpreter.h source/Core/InputReader.cpp source/Interpreter/CommandInterpreter.cpp

Jim Ingham jingham at apple.com
Mon Oct 4 12:49:29 PDT 2010


Author: jingham
Date: Mon Oct  4 14:49:29 2010
New Revision: 115546

URL: http://llvm.org/viewvc/llvm-project?rev=115546&view=rev
Log:
Add a "Confirm" function to the CommandInterpreter so you can confirm potentially dangerous operations in a generic way.

Modified:
    lldb/trunk/include/lldb/Core/InputReader.h
    lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
    lldb/trunk/source/Core/InputReader.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp

Modified: lldb/trunk/include/lldb/Core/InputReader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/InputReader.h?rev=115546&r1=115545&r2=115546&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/InputReader.h (original)
+++ lldb/trunk/include/lldb/Core/InputReader.h Mon Oct  4 14:49:29 2010
@@ -15,6 +15,7 @@
 #include "lldb/lldb-include.h"
 #include "lldb/lldb-enumerations.h"
 #include "lldb/Core/Debugger.h"
+#include "lldb/Host/Predicate.h"
 
 
 namespace lldb_private {
@@ -88,6 +89,11 @@
 
     void
     RefreshPrompt();
+    
+    // If you want to read from an input reader synchronously, then just initialize the
+    // reader and then call WaitOnReaderIsDone, which will return when the reader is popped.
+    void
+    WaitOnReaderIsDone ();
 
 protected:
     friend class Debugger;
@@ -104,6 +110,7 @@
     bool m_done;
     bool m_echo;
     bool m_active;
+    Predicate<bool> m_reader_done;
 
 private:
     DISALLOW_COPY_AND_ASSIGN (InputReader);

Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=115546&r1=115545&r2=115546&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Mon Oct  4 14:49:29 2010
@@ -157,7 +157,16 @@
 
     void
     SetPrompt (const char *);
-
+    
+    bool Confirm (const char *message, bool default_answer);
+    
+    static size_t
+    GetConfirmationInputReaderCallback (void *baton,
+                                        InputReader &reader,
+                                        lldb::InputReaderAction action,
+                                        const char *bytes,
+                                        size_t bytes_len);
+    
     void
     LoadCommandDictionary ();
 

Modified: lldb/trunk/source/Core/InputReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/InputReader.cpp?rev=115546&r1=115545&r2=115546&view=diff
==============================================================================
--- lldb/trunk/source/Core/InputReader.cpp (original)
+++ lldb/trunk/source/Core/InputReader.cpp Mon Oct  4 14:49:29 2010
@@ -23,7 +23,8 @@
     m_granularity (eInputReaderGranularityInvalid),
     m_done (true),
     m_echo (true),
-    m_active (false)
+    m_active (false), 
+    m_reader_done (false)
 {
 }
 
@@ -315,6 +316,7 @@
     case eInputReaderActivate:
     case eInputReaderReactivate:
         m_active = true;
+        m_reader_done.SetValue(false, eBroadcastAlways);
         break;
 
     case eInputReaderDeactivate:
@@ -327,4 +329,12 @@
     }
     if (m_callback)
         m_callback (m_callback_baton, *this, notification, NULL, 0);
+    if (notification == eInputReaderDone)
+        m_reader_done.SetValue(true, eBroadcastAlways);
+}
+
+void 
+InputReader::WaitOnReaderIsDone ()
+{
+    m_reader_done.WaitForValueEqualTo (true);
 }

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=115546&r1=115545&r2=115546&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Mon Oct  4 14:49:29 2010
@@ -38,6 +38,7 @@
 
 #include "lldb/Interpreter/Args.h"
 #include "lldb/Core/Debugger.h"
+#include "lldb/Core/InputReader.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Target/Process.h"
@@ -778,6 +779,98 @@
     m_debugger.SetPrompt (new_prompt);
 }
 
+size_t
+CommandInterpreter::GetConfirmationInputReaderCallback (void *baton,
+                                    InputReader &reader,
+                                    lldb::InputReaderAction action,
+                                    const char *bytes,
+                                    size_t bytes_len)
+{
+    FILE *out_fh = reader.GetDebugger().GetOutputFileHandle();
+    bool *response_ptr = (bool *) baton;
+    
+    switch (action)
+    {
+    case eInputReaderActivate:
+        if (out_fh)
+        {
+            if (reader.GetPrompt())
+                ::fprintf (out_fh, "%s", reader.GetPrompt());
+        }
+        break;
+
+    case eInputReaderDeactivate:
+        break;
+
+    case eInputReaderReactivate:
+        if (out_fh && reader.GetPrompt())
+            ::fprintf (out_fh, "%s", reader.GetPrompt());
+        break;
+
+    case eInputReaderGotToken:
+        if (bytes_len == 0)
+        {
+            reader.SetIsDone(true);
+        }
+        else if (bytes[0] == 'y')
+        {
+            *response_ptr = true;
+            reader.SetIsDone(true);
+        }
+        else if (bytes[0] == 'n')
+        {
+            *response_ptr = false;
+            reader.SetIsDone(true);
+        }
+        else
+        {
+            if (out_fh && !reader.IsDone() && reader.GetPrompt())
+            {
+                ::fprintf (out_fh, "Please answer \"y\" or \"n\"\n");
+                ::fprintf (out_fh, "%s", reader.GetPrompt());
+            }
+        }
+        break;
+        
+    case eInputReaderDone:
+        break;
+    }
+
+    return bytes_len;
+
+}
+
+bool 
+CommandInterpreter::Confirm (const char *message, bool default_answer)
+{
+    // The default interpretation just pushes a new input reader and lets it get the answer:
+    InputReaderSP reader_sp (new InputReader(GetDebugger()));
+    bool response = default_answer;
+    if (reader_sp)
+    {
+        std::string prompt(message);
+        prompt.append(": [");
+        if (default_answer)
+            prompt.append ("Y/n] ");
+        else
+            prompt.append ("y/N] ");
+            
+        Error err (reader_sp->Initialize (CommandInterpreter::GetConfirmationInputReaderCallback,
+                                          &response,                    // baton
+                                          eInputReaderGranularityLine,  // token size, to pass to callback function
+                                          NULL,                         // end token
+                                          prompt.c_str(),               // prompt
+                                          true));                       // echo input
+        if (err.Success())
+        {
+            GetDebugger().PushInputReader (reader_sp);
+        }
+        reader_sp->WaitOnReaderIsDone();
+    }
+    return response;        
+}
+    
+
 void
 CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * object_type)
 {





More information about the lldb-commits mailing list