[Lldb-commits] [lldb] r200860 - Fixed an issue where "command source" would not do the right thing:

Greg Clayton gclayton at apple.com
Wed Feb 5 09:57:57 PST 2014


Author: gclayton
Date: Wed Feb  5 11:57:57 2014
New Revision: 200860

URL: http://llvm.org/viewvc/llvm-project?rev=200860&view=rev
Log:
Fixed an issue where "command source" would not do the right thing:
- empty lines in init files would repeat previous command and cause errors to be displayed
- all options to control showing the command, its output, if it should stop on error or continue, weren't being obeyed.


Modified:
    lldb/trunk/include/lldb/Core/IOHandler.h
    lldb/trunk/include/lldb/Host/File.h
    lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
    lldb/trunk/source/Commands/CommandObjectCommands.cpp
    lldb/trunk/source/Core/IOHandler.cpp
    lldb/trunk/source/Host/common/File.cpp
    lldb/trunk/source/Interpreter/CommandInterpreter.cpp

Modified: lldb/trunk/include/lldb/Core/IOHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/IOHandler.h?rev=200860&r1=200859&r2=200860&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/IOHandler.h (original)
+++ lldb/trunk/include/lldb/Core/IOHandler.h Wed Feb  5 11:57:57 2014
@@ -18,6 +18,7 @@
 #include "lldb/lldb-enumerations.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Error.h"
+#include "lldb/Core/Flags.h"
 #include "lldb/Core/StringList.h"
 #include "lldb/Core/ValueObjectList.h"
 #include "lldb/Host/Mutex.h"
@@ -38,7 +39,8 @@ namespace lldb_private {
         IOHandler (Debugger &debugger,
                    const lldb::StreamFileSP &input_sp,
                    const lldb::StreamFileSP &output_sp,
-                   const lldb::StreamFileSP &error_sp);
+                   const lldb::StreamFileSP &error_sp,
+                   uint32_t flags);
 
         virtual
         ~IOHandler ();
@@ -162,11 +164,45 @@ namespace lldb_private {
             m_user_data = user_data;
         }
 
+        Flags &
+        GetFlags ()
+        {
+            return m_flags;
+        }
+
+        const Flags &
+        GetFlags () const
+        {
+            return m_flags;
+        }
+
+        //------------------------------------------------------------------
+        /// Check if the input is being supplied interactively by a user
+        ///
+        /// This will return true if the input stream is a terminal (tty or
+        /// pty) and can cause IO handlers to do different things (like
+        /// for a comfirmation when deleting all breakpoints).
+        //------------------------------------------------------------------
+        bool
+        GetIsInteractive ();
+
+        //------------------------------------------------------------------
+        /// Check if the input is coming from a real terminal.
+        ///
+        /// A real terminal has a valid size with a certain number of rows
+        /// and colums. If this function returns true, then terminal escape
+        /// sequences are expected to work (cursor movement escape sequences,
+        /// clearning lines, etc).
+        //------------------------------------------------------------------
+        bool
+        GetIsRealTerminal ();
+
     protected:
         Debugger &m_debugger;
         lldb::StreamFileSP m_input_sp;
         lldb::StreamFileSP m_output_sp;
         lldb::StreamFileSP m_error_sp;
+        Flags m_flags;
         void *m_user_data;
         bool m_done;
         bool m_active;
@@ -340,6 +376,7 @@ namespace lldb_private {
                            const lldb::StreamFileSP &input_sp,
                            const lldb::StreamFileSP &output_sp,
                            const lldb::StreamFileSP &error_sp,
+                           uint32_t flags,
                            const char *editline_name, // Used for saving history files
                            const char *prompt,
                            bool multi_line,
@@ -408,9 +445,7 @@ namespace lldb_private {
         std::unique_ptr<Editline> m_editline_ap;
         IOHandlerDelegate &m_delegate;
         std::string m_prompt;
-        bool m_multi_line;
-        bool m_interactive;
-        
+        bool m_multi_line;        
     };
     
     class IOHandlerConfirm :

Modified: lldb/trunk/include/lldb/Host/File.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/File.h?rev=200860&r1=200859&r2=200860&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/File.h (original)
+++ lldb/trunk/include/lldb/Host/File.h Wed Feb  5 11:57:57 2014
@@ -52,7 +52,9 @@ public:
         m_stream (kInvalidStream),
         m_options (0),
         m_own_stream (false),
-        m_own_descriptor (false)
+        m_own_descriptor (false),
+        m_is_interactive (eLazyBoolCalculate),
+        m_is_real_terminal (eLazyBoolCalculate)
     {
     }
     
@@ -61,7 +63,9 @@ public:
         m_stream (fh),
         m_options (0),
         m_own_stream (transfer_ownership),
-        m_own_descriptor (false)
+        m_own_descriptor (false),
+        m_is_interactive (eLazyBoolCalculate),
+        m_is_real_terminal (eLazyBoolCalculate)
     {
     }
 
@@ -462,6 +466,32 @@ public:
     static uint32_t
     GetPermissions (const char *path, Error &error);
 
+    
+    //------------------------------------------------------------------
+    /// Return true if this file is interactive.
+    ///
+    /// @return
+    ///     True if this file is a terminal (tty or pty), false
+    ///     otherwise.
+    //------------------------------------------------------------------
+    bool
+    GetIsInteractive ();
+    
+    //------------------------------------------------------------------
+    /// Return true if this file from a real terminal.
+    ///
+    /// Just knowing a file is a interactive isn't enough, we also need
+    /// to know if the terminal has a width and height so we can do
+    /// cursor movement and other terminal maninpulations by sending
+    /// escape sequences.
+    ///
+    /// @return
+    ///     True if this file is a terminal (tty, not a pty) that has
+    ///     a non-zero width and height, false otherwise.
+    //------------------------------------------------------------------
+    bool
+    GetIsRealTerminal ();
+
     //------------------------------------------------------------------
     /// Output printf formatted output to the stream.
     ///
@@ -501,6 +531,9 @@ protected:
         return m_stream != kInvalidStream;
     }
     
+    void
+    CalculateInteractiveAndTerminal ();
+    
     //------------------------------------------------------------------
     // Member variables
     //------------------------------------------------------------------
@@ -509,6 +542,8 @@ protected:
     uint32_t m_options;
     bool m_own_stream;
     bool m_own_descriptor;
+    LazyBool m_is_interactive;
+    LazyBool m_is_real_terminal;
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=200860&r1=200859&r2=200860&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Wed Feb  5 11:57:57 2014
@@ -215,10 +215,10 @@ public:
     void
     HandleCommandsFromFile (FileSpec &file, 
                             ExecutionContext *context, 
-                            bool stop_on_continue, 
-                            bool stop_on_error, 
-                            bool echo_commands,
-                            bool print_results,
+                            LazyBool stop_on_continue, 
+                            LazyBool stop_on_error,
+                            LazyBool echo_commands,
+                            LazyBool print_results,
                             LazyBool add_to_history,
                             CommandReturnObject &result);
 
@@ -515,6 +515,7 @@ private:
     bool m_batch_command_mode;
     ChildrenTruncatedWarningStatus m_truncation_warning;    // Whether we truncated children and whether the user has been told
     uint32_t m_command_source_depth;
+    std::vector<uint32_t> m_command_source_flags;
     
 };
 

Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=200860&r1=200859&r2=200860&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Wed Feb  5 11:57:57 2014
@@ -308,7 +308,9 @@ protected:
 
         CommandOptions (CommandInterpreter &interpreter) :
             Options (interpreter),
-            m_stop_on_error (true)
+            m_stop_on_error (true),
+            m_silent_run (false),
+            m_stop_on_continue (true)
         {
         }
 
@@ -320,23 +322,21 @@ protected:
         {
             Error error;
             const int short_option = m_getopt_table[option_idx].val;
-            bool success;
             
             switch (short_option)
             {
                 case 'e':
                     error = m_stop_on_error.SetValueFromCString(option_arg);
                     break;
+
                 case 'c':
-                    m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
-                    if (!success)
-                        error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg);
+                    error = m_stop_on_continue.SetValueFromCString(option_arg);
                     break;
+
                 case 's':
-                    m_silent_run = Args::StringToBoolean(option_arg, true, &success);
-                    if (!success)
-                        error.SetErrorStringWithFormat("invalid value for silent-run: %s", option_arg);
+                    error = m_silent_run.SetValueFromCString(option_arg);
                     break;
+
                 default:
                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
                     break;
@@ -349,8 +349,8 @@ protected:
         OptionParsingStarting ()
         {
             m_stop_on_error.Clear();
-            m_silent_run = false;
-            m_stop_on_continue = true;
+            m_silent_run.Clear();
+            m_stop_on_continue.Clear();
         }
 
         const OptionDefinition*
@@ -366,8 +366,8 @@ protected:
         // Instance variables to hold the values for command options.
 
         OptionValueBoolean m_stop_on_error;
-	    bool m_silent_run;
-        bool m_stop_on_continue;
+	    OptionValueBoolean m_silent_run;
+        OptionValueBoolean m_stop_on_continue;
     };
     
     bool
@@ -378,23 +378,42 @@ protected:
         {
             const char *filename = command.GetArgumentAtIndex(0);
 
-            if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
-                result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
+            result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
 
             FileSpec cmd_file (filename, true);
             ExecutionContext *exe_ctx = NULL;  // Just use the default context.
-            bool echo_commands    = !m_options.m_silent_run;
-            bool print_results    = true;
-            bool stop_on_error = m_options.m_stop_on_error.OptionWasSet() ? (bool)m_options.m_stop_on_error : m_interpreter.GetStopCmdSourceOnError();
-
-            m_interpreter.HandleCommandsFromFile (cmd_file,
-                                                  exe_ctx, 
-                                                  m_options.m_stop_on_continue, 
-                                                  stop_on_error, 
-                                                  echo_commands, 
-                                                  print_results,
-                                                  eLazyBoolCalculate,
-                                                  result);
+            
+            // If any options were set, then use them
+            if (m_options.m_stop_on_error.OptionWasSet()    ||
+                m_options.m_silent_run.OptionWasSet()       ||
+                m_options.m_stop_on_continue.OptionWasSet())
+            {
+                // Use user set settings
+                LazyBool print_command = m_options.m_silent_run.GetCurrentValue() ? eLazyBoolNo : eLazyBoolYes;
+                m_interpreter.HandleCommandsFromFile (cmd_file,
+                                                      exe_ctx,
+                                                      m_options.m_stop_on_continue.GetCurrentValue() ? eLazyBoolYes : eLazyBoolNo, // Stop on continue
+                                                      m_options.m_stop_on_error.GetCurrentValue() ? eLazyBoolYes : eLazyBoolNo, // Stop on error
+                                                      print_command,        // Echo command
+                                                      print_command,        // Print command output
+                                                      eLazyBoolCalculate,   // Add to history
+                                                      result);
+                
+            }
+            else
+            {
+                // No options were set, inherit any settings from nested "command source" commands,
+                // or set to sane default settings...
+                m_interpreter.HandleCommandsFromFile (cmd_file,
+                                                      exe_ctx,
+                                                      eLazyBoolCalculate, // Stop on continue
+                                                      eLazyBoolCalculate, // Stop on error
+                                                      eLazyBoolCalculate, // Echo command
+                                                      eLazyBoolCalculate, // Print command output
+                                                      eLazyBoolCalculate, // Add to history
+                                                      result);
+                
+            }
         }
         else
         {

Modified: lldb/trunk/source/Core/IOHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/IOHandler.cpp?rev=200860&r1=200859&r2=200860&view=diff
==============================================================================
--- lldb/trunk/source/Core/IOHandler.cpp (original)
+++ lldb/trunk/source/Core/IOHandler.cpp Wed Feb  5 11:57:57 2014
@@ -10,12 +10,6 @@
 
 #include "lldb/lldb-python.h"
 
-#include <stdio.h>	/* ioctl, TIOCGWINSZ */
-
-#ifndef _MSC_VER
-#include <sys/ioctl.h>	/* ioctl, TIOCGWINSZ */
-#endif
-
 #include <string>
 
 #include "lldb/Breakpoint/BreakpointLocation.h"
@@ -43,9 +37,10 @@ using namespace lldb_private;
 
 IOHandler::IOHandler (Debugger &debugger) :
     IOHandler (debugger,
-               StreamFileSP(), // Adopt STDIN from top input reader
-               StreamFileSP(), // Adopt STDOUT from top input reader
-               StreamFileSP()) // Adopt STDERR from top input reader
+               StreamFileSP(),  // Adopt STDIN from top input reader
+               StreamFileSP(),  // Adopt STDOUT from top input reader
+               StreamFileSP(),  // Adopt STDERR from top input reader
+               0)               // Flags
 {
 }
 
@@ -53,11 +48,13 @@ IOHandler::IOHandler (Debugger &debugger
 IOHandler::IOHandler (Debugger &debugger,
                       const lldb::StreamFileSP &input_sp,
                       const lldb::StreamFileSP &output_sp,
-                      const lldb::StreamFileSP &error_sp) :
+                      const lldb::StreamFileSP &error_sp,
+                      uint32_t flags) :
     m_debugger (debugger),
     m_input_sp (input_sp),
     m_output_sp (output_sp),
     m_error_sp (error_sp),
+    m_flags (flags),
     m_user_data (NULL),
     m_done (false),
     m_active (false)
@@ -141,6 +138,17 @@ IOHandler::GetErrorStreamFile()
     return m_error_sp;
 }
 
+bool
+IOHandler::GetIsInteractive ()
+{
+    return GetInputStreamFile()->GetFile().GetIsInteractive ();
+}
+
+bool
+IOHandler::GetIsRealTerminal ()
+{
+    return GetInputStreamFile()->GetFile().GetIsRealTerminal();
+}
 
 IOHandlerConfirm::IOHandlerConfirm (Debugger &debugger,
                                     const char *prompt,
@@ -308,6 +316,7 @@ IOHandlerEditline::IOHandlerEditline (De
                       StreamFileSP(), // Inherit input from top input reader
                       StreamFileSP(), // Inherit output from top input reader
                       StreamFileSP(), // Inherit error from top input reader
+                      0,              // Flags
                       editline_name,  // Used for saving history files
                       prompt,
                       multi_line,
@@ -319,32 +328,23 @@ IOHandlerEditline::IOHandlerEditline (De
                                       const lldb::StreamFileSP &input_sp,
                                       const lldb::StreamFileSP &output_sp,
                                       const lldb::StreamFileSP &error_sp,
+                                      uint32_t flags,
                                       const char *editline_name, // Used for saving history files
                                       const char *prompt,
                                       bool multi_line,
                                       IOHandlerDelegate &delegate) :
-    IOHandler (debugger, input_sp, output_sp, error_sp),
+    IOHandler (debugger, input_sp, output_sp, error_sp, flags),
     m_editline_ap (),
     m_delegate (delegate),
     m_prompt (),
-    m_multi_line (multi_line),
-    m_interactive (false)
+    m_multi_line (multi_line)
 {
     SetPrompt(prompt);
 
     bool use_editline = false;
+    
 #ifndef _MSC_VER
-    const int in_fd = GetInputFD();
-    struct winsize window_size;
-    if (isatty (in_fd))
-    {
-        m_interactive = true;
-        if (::ioctl (in_fd, TIOCGWINSZ, &window_size) == 0)
-        {
-            if (window_size.ws_col > 0)
-                use_editline = true;
-        }
-    }
+    use_editline = m_input_sp->GetFile().GetIsRealTerminal();
 #else
     use_editline = true;
 #endif
@@ -382,7 +382,7 @@ IOHandlerEditline::GetLine (std::string
         FILE *in = GetInputFILE();
         if (in)
         {
-            if (m_interactive)
+            if (GetIsInteractive())
             {
                 const char *prompt = GetPrompt();
                 if (prompt && prompt[0])
@@ -432,7 +432,7 @@ IOHandlerEditline::GetLine (std::string
             // No more input file, we are done...
             SetIsDone(true);
         }
-        return !line.empty();
+        return false;
     }
 }
 

Modified: lldb/trunk/source/Host/common/File.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/File.cpp?rev=200860&r1=200859&r2=200860&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/File.cpp (original)
+++ lldb/trunk/source/Host/common/File.cpp Wed Feb  5 11:57:57 2014
@@ -13,7 +13,9 @@
 #include <fcntl.h>
 #include <limits.h>
 #include <stdarg.h>
+#include <stdio.h>
 #include <sys/stat.h>
+#include <sys/ioctl.h>
 
 #ifdef _WIN32
 #include "lldb/Host/windows/windows.h"
@@ -78,7 +80,9 @@ File::File(const char *path, uint32_t op
     m_stream (kInvalidStream),
     m_options (),
     m_own_stream (false),
-    m_own_descriptor (false)
+    m_own_descriptor (false),
+    m_is_interactive (eLazyBoolCalculate),
+    m_is_real_terminal (eLazyBoolCalculate)
 {
     Open (path, options, permissions);
 }
@@ -90,7 +94,10 @@ File::File (const FileSpec& filespec,
     m_stream (kInvalidStream),
     m_options (0),
     m_own_stream (false),
-    m_own_descriptor (false)
+    m_own_descriptor (false),
+    m_is_interactive (eLazyBoolCalculate),
+    m_is_real_terminal (eLazyBoolCalculate)
+
 {
     if (filespec)
     {
@@ -103,7 +110,9 @@ File::File (const File &rhs) :
     m_stream (kInvalidStream),
     m_options (0),
     m_own_stream (false),
-    m_own_descriptor (false)
+    m_own_descriptor (false),
+    m_is_interactive (eLazyBoolCalculate),
+    m_is_real_terminal (eLazyBoolCalculate)
 {
     Duplicate (rhs);
 }
@@ -371,6 +380,8 @@ File::Close ()
     m_options = 0;
     m_own_stream = false;
     m_own_descriptor = false;
+    m_is_interactive = eLazyBoolCalculate;
+    m_is_real_terminal = eLazyBoolCalculate;
     return error;
 }
 
@@ -866,3 +877,41 @@ File::ConvertOpenOptionsForPOSIXOpen (ui
 
     return mode;
 }
+
+void
+File::CalculateInteractiveAndTerminal ()
+{
+    const int fd = GetDescriptor();
+    if (fd >= 0)
+    {
+        m_is_interactive = eLazyBoolNo;
+        m_is_real_terminal = eLazyBoolNo;
+        if (isatty(fd))
+        {
+            m_is_interactive = eLazyBoolYes;
+            struct winsize window_size;
+            if (::ioctl (fd, TIOCGWINSZ, &window_size) == 0)
+            {
+                if (window_size.ws_col > 0)
+                    m_is_real_terminal = eLazyBoolYes;
+            }
+        }
+    }
+}
+
+bool
+File::GetIsInteractive ()
+{
+    if (m_is_interactive == eLazyBoolCalculate)
+        CalculateInteractiveAndTerminal ();
+    return m_is_interactive == eLazyBoolYes;
+}
+
+bool
+File::GetIsRealTerminal ()
+{
+    if (m_is_real_terminal == eLazyBoolCalculate)
+        CalculateInteractiveAndTerminal();
+    return m_is_real_terminal == eLazyBoolYes;
+}
+

Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=200860&r1=200859&r2=200860&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Wed Feb  5 11:57:57 2014
@@ -2390,14 +2390,15 @@ CommandInterpreter::SourceInitFile (bool
 
     if (init_file.Exists())
     {
-        ExecutionContext *exe_ctx = NULL;  // We don't have any context yet.
-        bool stop_on_continue = true;
-        bool stop_on_error    = false;
-        bool echo_commands    = false;
-        bool print_results    = false;
-        
         const bool saved_batch = SetBatchCommandMode (true);
-        HandleCommandsFromFile (init_file, exe_ctx, stop_on_continue, stop_on_error, echo_commands, print_results, eLazyBoolNo, result);
+        HandleCommandsFromFile (init_file,
+                                NULL,           // Execution context
+                                eLazyBoolYes,   // Stop on continue
+                                eLazyBoolNo,    // Stop on error
+                                eLazyBoolNo,    // Don't echo commands
+                                eLazyBoolNo,    // Don't print command output
+                                eLazyBoolNo,    // Don't add the commands that are sourced into the history buffer
+                                result);
         SetBatchCommandMode (saved_batch);
     }
     else
@@ -2546,13 +2547,21 @@ CommandInterpreter::HandleCommands (cons
     return;
 }
 
+// Make flags that we can pass into the IOHandler so our delegates can do the right thing
+enum {
+    eHandleCommandFlagStopOnContinue = (1u << 0),
+    eHandleCommandFlagStopOnError    = (1u << 1),
+    eHandleCommandFlagEchoCommand    = (1u << 2),
+    eHandleCommandFlagPrintResult    = (1u << 3)
+};
+
 void
 CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file, 
                                             ExecutionContext *context, 
-                                            bool stop_on_continue,
-                                            bool stop_on_error,
-                                            bool echo_command,
-                                            bool print_result,
+                                            LazyBool stop_on_continue,
+                                            LazyBool stop_on_error,
+                                            LazyBool echo_command,
+                                            LazyBool print_result,
                                             LazyBool add_to_history,
                                             CommandReturnObject &result)
 {
@@ -2567,15 +2576,93 @@ CommandInterpreter::HandleCommandsFromFi
         {
             Debugger &debugger = GetDebugger();
 
+            uint32_t flags = 0;
+
+            if (stop_on_continue == eLazyBoolCalculate)
+            {
+                if (m_command_source_flags.empty())
+                {
+                    // Echo command by default
+                    flags |= eHandleCommandFlagStopOnContinue;
+                }
+                else if (m_command_source_flags.back() & eHandleCommandFlagStopOnContinue)
+                {
+                    flags |= eHandleCommandFlagStopOnContinue;
+                }
+            }
+            else if (stop_on_continue == eLazyBoolYes)
+            {
+                flags |= eHandleCommandFlagStopOnContinue;
+            }
+
+            if (stop_on_error == eLazyBoolCalculate)
+            {
+                if (m_command_source_flags.empty())
+                {
+                    if (GetStopCmdSourceOnError())
+                        flags |= eHandleCommandFlagStopOnError;
+                }
+                else if (m_command_source_flags.back() & eHandleCommandFlagStopOnError)
+                {
+                    flags |= eHandleCommandFlagStopOnError;
+                }
+            }
+            else if (stop_on_error == eLazyBoolYes)
+            {
+                flags |= eHandleCommandFlagStopOnError;
+            }
+
+            if (echo_command == eLazyBoolCalculate)
+            {
+                if (m_command_source_flags.empty())
+                {
+                    // Echo command by default
+                    flags |= eHandleCommandFlagEchoCommand;
+                }
+                else if (m_command_source_flags.back() & eHandleCommandFlagEchoCommand)
+                {
+                    flags |= eHandleCommandFlagEchoCommand;
+                }
+            }
+            else if (echo_command == eLazyBoolYes)
+            {
+                flags |= eHandleCommandFlagEchoCommand;
+            }
+
+            if (print_result == eLazyBoolCalculate)
+            {
+                if (m_command_source_flags.empty())
+                {
+                    // Echo command by default
+                    flags |= eHandleCommandFlagEchoCommand;
+                }
+                else if (m_command_source_flags.back() & eHandleCommandFlagEchoCommand)
+                {
+                    flags |= eHandleCommandFlagEchoCommand;
+                }
+            }
+            else if (print_result == eLazyBoolYes)
+            {
+                flags |= eHandleCommandFlagEchoCommand;
+            }
+
+            // Used for inheriting the right settings when "command source" might have
+            // nested "command source" commands
+            m_command_source_flags.push_back(flags);
             IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
                                                               input_file_sp,
                                                               debugger.GetOutputFile(),
                                                               debugger.GetErrorFile(),
+                                                              flags,
                                                               NULL, // Pass in NULL for "editline_name" so no history is saved, or written
                                                               m_debugger.GetPrompt(),
                                                               false, // Not multi-line
                                                               *this));
+            m_command_source_depth++;
             m_debugger.RunIOHandler(io_handler_sp);
+            if (!m_command_source_flags.empty())
+                m_command_source_flags.pop_back();
+            m_command_source_depth--;
             result.SetStatus (eReturnStatusSuccessFinishNoResult);
         }
         else
@@ -2583,21 +2670,6 @@ CommandInterpreter::HandleCommandsFromFi
             result.AppendErrorWithFormat ("error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(), error.AsCString());
             result.SetStatus (eReturnStatusFailed);
         }
-        
-#if 0
-        bool success;
-        StringList commands;
-        success = commands.ReadFileLines(cmd_file);
-        if (!success)
-        {
-            result.AppendErrorWithFormat ("Error reading commands from file: %s.\n", cmd_file.GetFilename().AsCString());
-            result.SetStatus (eReturnStatusFailed);
-            return;
-        }
-        m_command_source_depth++;
-        HandleCommands (commands, context, stop_on_continue, stop_on_error, echo_command, print_result, add_to_history, result);
-        m_command_source_depth--;
-#endif
     }
     else
     {
@@ -2886,31 +2958,59 @@ CommandInterpreter::GetProcessOutput ()
 void
 CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
 {
+    const bool is_interactive = io_handler.GetIsInteractive();
+    if (is_interactive == false)
+    {
+        // When we are not interactive, don't execute blank lines. This will happen
+        // sourcing a commands file. We don't want blank lines to repeat the previous
+        // command and cause any errors to occur (like redefining an alias, get an error
+        // and stop parsing the commands file).
+        if (line.empty())
+            return;
+        
+        // When using a non-interactive file handle (like when sourcing commands from a file)
+        // we need to echo the command out so we don't just see the command output and no
+        // command...
+        if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand))
+            io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), line.c_str());
+    }
+
     lldb_private::CommandReturnObject result;
     HandleCommand(line.c_str(), eLazyBoolCalculate, result);
     
-    // Display any STDOUT/STDERR _prior_ to emitting the command result text
-    GetProcessOutput ();
-    
     // Now emit the command output text from the command we just executed
-    const char *output = result.GetOutputData();
-    if (output && output[0])
-        io_handler.GetOutputStreamFile()->PutCString(output);
-    
-    // Now emit the command error text from the command we just executed
-    const char *error = result.GetErrorData();
-    if (error && error[0])
-        io_handler.GetErrorStreamFile()->PutCString(error);
+    if (io_handler.GetFlags().Test(eHandleCommandFlagPrintResult))
+    {
+        // Display any STDOUT/STDERR _prior_ to emitting the command result text
+        GetProcessOutput ();
+        
+        const char *output = result.GetOutputData();
+        if (output && output[0])
+            io_handler.GetOutputStreamFile()->PutCString(output);
+    
+        // Now emit the command error text from the command we just executed
+        const char *error = result.GetErrorData();
+        if (error && error[0])
+            io_handler.GetErrorStreamFile()->PutCString(error);
+    }
     
     switch (result.GetStatus())
     {
         case eReturnStatusInvalid:
         case eReturnStatusSuccessFinishNoResult:
         case eReturnStatusSuccessFinishResult:
+        case eReturnStatusStarted:
+            break;
+
         case eReturnStatusSuccessContinuingNoResult:
         case eReturnStatusSuccessContinuingResult:
-        case eReturnStatusStarted:
+            if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnContinue))
+                io_handler.SetIsDone(true);
+            break;
+
         case eReturnStatusFailed:
+            if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError))
+                io_handler.SetIsDone(true);
             break;
             
         case eReturnStatusQuit:
@@ -2984,6 +3084,7 @@ CommandInterpreter::RunCommandInterprete
                                                              m_debugger.GetInputFile(),
                                                              m_debugger.GetOutputFile(),
                                                              m_debugger.GetErrorFile(),
+                                                             eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult,
                                                              "lldb",
                                                              m_debugger.GetPrompt(),
                                                              multiple_lines,





More information about the lldb-commits mailing list