diff options
21 files changed, 695 insertions, 404 deletions
diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h b/lldb/include/lldb/API/SBCommandReturnObject.h index 9058122c030..f2b530174e6 100644 --- a/lldb/include/lldb/API/SBCommandReturnObject.h +++ b/lldb/include/lldb/API/SBCommandReturnObject.h @@ -76,6 +76,12 @@ public: void SetImmediateErrorFile (FILE *fh); + void + PutCString(const char* string, int len = -1); + + size_t + Printf(const char* format, ...); + protected: friend class SBCommandInterpreter; friend class SBOptions; diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h index 8680c1dd3be..dd883a7e76a 100644 --- a/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -46,6 +46,14 @@ public: eUnwarnedTruncation = 1, // truncated but did not notify eWarnedTruncation = 2 // truncated and notified }; + + enum CommandTypes + { + eCommandTypesBuiltin = 0x0001, // native commands such as "frame" + eCommandTypesUserDef = 0x0002, // scripted commands + eCommandTypesAliases = 0x0004, // aliases such as "po" + eCommandTypesAllThem = 0xFFFF // all commands + }; void SourceInitFile (bool in_cwd, @@ -63,6 +71,11 @@ public: const lldb::CommandObjectSP &cmd_sp, bool can_replace); + bool + AddUserCommand (const char *name, + const lldb::CommandObjectSP &cmd_sp, + bool can_replace); + lldb::CommandObjectSP GetCommandSPExact (const char *cmd, bool include_aliases); @@ -93,6 +106,12 @@ public: bool RemoveUser (const char *alias_name); + + void + RemoveAllUser () + { + m_user_dict.clear(); + } OptionArgVectorSP GetAliasOptions (const char *alias_name); @@ -239,7 +258,8 @@ public: StringList &matches); void - GetHelp (CommandReturnObject &result); + GetHelp (CommandReturnObject &result, + CommandTypes types = eCommandTypesAllThem); void GetAliasHelp (const char *alias_name, diff --git a/lldb/include/lldb/Interpreter/CommandObject.h b/lldb/include/lldb/Interpreter/CommandObject.h index f14ff605b5c..525fc454eef 100644 --- a/lldb/include/lldb/Interpreter/CommandObject.h +++ b/lldb/include/lldb/Interpreter/CommandObject.h @@ -120,6 +120,12 @@ public: virtual bool IsCrossRefObject () { return false; } + // override this to return true if you want to enable the user to delete + // the Command object from the Command dictionary (aliases have their own + // deletion scheme, so they do not need to care about this) + virtual bool + IsRemovable() { return false; } + bool IsAlias () { return m_is_alias; } diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h index 51f0b2a0906..a2e620d6f61 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -49,7 +49,7 @@ public: lldb::DebuggerSP& debugger, const char* args, std::string& err_msg, - lldb::SBStream& stream); + lldb_private::CommandReturnObject& cmd_retobj); typedef enum { @@ -186,7 +186,7 @@ public: virtual bool RunScriptBasedCommand(const char* impl_function, const char* args, - lldb::SBStream& stream, + lldb_private::CommandReturnObject& cmd_retobj, Error& error) { return false; diff --git a/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h b/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h index 79c2bde0136..feb65eb98be 100644 --- a/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h +++ b/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h @@ -84,7 +84,7 @@ public: virtual bool RunScriptBasedCommand(const char* impl_function, const char* args, - lldb::SBStream& stream, + lldb_private::CommandReturnObject& cmd_retobj, Error& error); bool diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index 870fe0cb3a5..5cd7ddc741b 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -405,8 +405,6 @@ 94611EB213CCA4A4003A22AF /* RefCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94611EB113CCA4A4003A22AF /* RefCounter.cpp */; }; 9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */; }; 9467E65213C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */; }; - 94A075BB13F9F58500D97961 /* CommandObjectPythonFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A075B913F9F58500D97961 /* CommandObjectPythonFunction.cpp */; }; - 94A075BC13F9F58500D97961 /* CommandObjectPythonFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 94A075BA13F9F58500D97961 /* CommandObjectPythonFunction.h */; }; 94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */; }; 9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9A19A6B01163BBB300E0D453 /* SBValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A19A6AD1163BB9800E0D453 /* SBValue.cpp */; }; @@ -1176,8 +1174,6 @@ 9463D4CE13B179A500C230D4 /* CommandObjectType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CommandObjectType.h; path = source/Commands/CommandObjectType.h; sourceTree = "<group>"; }; 9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeHierarchyNavigator.cpp; path = source/Symbol/TypeHierarchyNavigator.cpp; sourceTree = "<group>"; }; 9467E65413C3D98900B3B6F3 /* TypeHierarchyNavigator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeHierarchyNavigator.h; path = include/lldb/Symbol/TypeHierarchyNavigator.h; sourceTree = "<group>"; }; - 94A075B913F9F58500D97961 /* CommandObjectPythonFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectPythonFunction.cpp; path = source/Commands/CommandObjectPythonFunction.cpp; sourceTree = "<group>"; }; - 94A075BA13F9F58500D97961 /* CommandObjectPythonFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectPythonFunction.h; path = source/Commands/CommandObjectPythonFunction.h; sourceTree = "<group>"; }; 94A9112B13D5DEF80046D8A6 /* FormatClasses.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatClasses.h; path = include/lldb/Core/FormatClasses.h; sourceTree = "<group>"; }; 94A9112D13D5DF210046D8A6 /* FormatClasses.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatClasses.cpp; path = source/Core/FormatClasses.cpp; sourceTree = "<group>"; }; 94B6E76013D8833C005F417F /* ValueObjectSyntheticFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectSyntheticFilter.h; path = include/lldb/Core/ValueObjectSyntheticFilter.h; sourceTree = "<group>"; }; @@ -2127,8 +2123,6 @@ 26879CE71333F58B0012C1F8 /* CommandObjectPlatform.cpp */, 26BC7D1F10F1B76300F91463 /* CommandObjectProcess.h */, 26BC7E3810F1B84700F91463 /* CommandObjectProcess.cpp */, - 94A075BA13F9F58500D97961 /* CommandObjectPythonFunction.h */, - 94A075B913F9F58500D97961 /* CommandObjectPythonFunction.cpp */, 26BC7D2010F1B76300F91463 /* CommandObjectQuit.h */, 26BC7E3910F1B84700F91463 /* CommandObjectQuit.cpp */, 26BC7D2210F1B76300F91463 /* CommandObjectRegister.h */, @@ -2664,7 +2658,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 94A075BC13F9F58500D97961 /* CommandObjectPythonFunction.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3257,7 +3250,6 @@ 26D7E45D13D5E30A007FD12B /* SocketAddress.cpp in Sources */, B271B11413D6139300C3FEDB /* FormatClasses.cpp in Sources */, 94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */, - 94A075BB13F9F58500D97961 /* CommandObjectPythonFunction.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lldb/scripts/Python/interface/SBCommandReturnObject.i b/lldb/scripts/Python/interface/SBCommandReturnObject.i index 48d7bc24554..51d8ca8a77f 100644 --- a/lldb/scripts/Python/interface/SBCommandReturnObject.i +++ b/lldb/scripts/Python/interface/SBCommandReturnObject.i @@ -70,6 +70,13 @@ public: void SetImmediateErrorFile (FILE *fh); + + void + PutCString(const char* string, int len = -1); + + size_t + Printf(const char* format, ...); + }; } // namespace lldb diff --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig index 0843af126d1..02691047861 100644 --- a/lldb/scripts/Python/python-wrapper.swig +++ b/lldb/scripts/Python/python-wrapper.swig @@ -590,19 +590,21 @@ LLDBSwigPythonCallCommand lldb::DebuggerSP& debugger, const char* args, std::string& err_msg, - lldb::SBStream& stream + lldb_private::CommandReturnObject& cmd_retobj ) { + not_owning_ap<lldb_private::CommandReturnObject> auto_cmd_retobj(&cmd_retobj); + bool retval = false; PyObject *DebuggerObj_PyObj = SWIG_NewPointerObj((void *) &debugger, SWIGTYPE_p_lldb__SBDebugger, 0); - PyObject *StreamObj_PyObj = SWIG_NewPointerObj((void *) &stream, SWIGTYPE_p_lldb__SBStream, 0); + PyObject *CmdRetObj_PyObj = SWIG_NewPointerObj((void *) &auto_cmd_retobj, SWIGTYPE_p_lldb__SBCommandReturnObject, 0); if (DebuggerObj_PyObj == NULL) return retval; - if (StreamObj_PyObj == NULL) + if (CmdRetObj_PyObj == NULL) return retval; if (!python_function_name || !session_dictionary_name) @@ -676,7 +678,7 @@ LLDBSwigPythonCallCommand PyTuple_SetItem (pargs, 0, DebuggerObj_PyObj); // This "steals" a reference to DebuggerObj_PyObj PyTuple_SetItem (pargs, 1, PyString_FromString(args)); - PyTuple_SetItem (pargs, 2, StreamObj_PyObj); // This "steals" a reference to StreamObj_PyObj + PyTuple_SetItem (pargs, 2, CmdRetObj_PyObj); // This "steals" a reference to CmdRetObj_PyObj PyTuple_SetItem (pargs, 3, session_dict); // This "steals" a reference to session_dict pvalue = PyObject_CallObject (pfunc, pargs); Py_DECREF (pargs); diff --git a/lldb/scripts/lldb.swig b/lldb/scripts/lldb.swig index affbebb935a..8f18bf33fd4 100644 --- a/lldb/scripts/lldb.swig +++ b/lldb/scripts/lldb.swig @@ -78,6 +78,25 @@ o SBLineEntry: Specifies an association with a contiguous range of instructions #include "lldb/API/SBValueList.h" %} +%{ +template<class T> +class not_owning_ap +{ +private: + std::auto_ptr<T> m_auto_ptr; +public: + explicit not_owning_ap (T* p=0) : m_auto_ptr(p) {} + not_owning_ap (not_owning_ap& a) : m_auto_ptr(a.m_auto_ptr) {} + template<class Y> + not_owning_ap (not_owning_ap<Y>& a) : m_auto_ptr(a.m_auto_ptr) {} + not_owning_ap (const not_owning_ap<T>& r) : m_auto_ptr(r.m_auto_ptr) {} + ~not_owning_ap() { m_auto_ptr.release(); } + T* get() const { return m_auto_ptr.get(); } + T& operator*() const { return *m_auto_ptr; } + void reset (T* p=0) { m_auto_ptr.release(); m_auto_ptr.reset(p); } +}; +%} + /* Various liblldb typedefs that SWIG needs to know about. */ #define __extension__ /* Undefine GCC keyword to make Swig happy when processing glibc's stdint.h. */ %include <stdint.h> diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp index cd7cefd198d..5b3371b62bc 100644 --- a/lldb/source/API/SBCommandInterpreter.cpp +++ b/lldb/source/API/SBCommandInterpreter.cpp @@ -344,7 +344,7 @@ extern "C" bool LLDBSwigPythonCallCommand lldb::DebuggerSP& debugger, const char* args, std::string& err_msg, - lldb::SBStream& stream + lldb_private::CommandReturnObject& cmd_retobj ); diff --git a/lldb/source/API/SBCommandReturnObject.cpp b/lldb/source/API/SBCommandReturnObject.cpp index 8377c1fc3a1..8550b5d45c6 100644 --- a/lldb/source/API/SBCommandReturnObject.cpp +++ b/lldb/source/API/SBCommandReturnObject.cpp @@ -248,3 +248,27 @@ SBCommandReturnObject::SetImmediateErrorFile (FILE *fh) if (m_opaque_ap.get()) m_opaque_ap->SetImmediateErrorFile (fh); } + +void +SBCommandReturnObject::PutCString(const char* string, int len) +{ + if (m_opaque_ap.get()) + { + m_opaque_ap->AppendMessage(string, len); + } +} + +size_t +SBCommandReturnObject::Printf(const char* format, ...) +{ + if (m_opaque_ap.get()) + { + va_list args; + va_start (args, format); + size_t result = m_opaque_ap->GetOutputStream().PrintfVarArg(format, args); + va_end (args); + return result; + } + return 0; +} + diff --git a/lldb/source/Commands/CommandObjectCommands.cpp b/lldb/source/Commands/CommandObjectCommands.cpp index 09ac12b726a..6c12126d4f5 100644 --- a/lldb/source/Commands/CommandObjectCommands.cpp +++ b/lldb/source/Commands/CommandObjectCommands.cpp @@ -15,7 +15,6 @@ #include "llvm/ADT/StringRef.h" // Project includes -#include "CommandObjectPythonFunction.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/InputReader.h" #include "lldb/Core/InputReaderEZ.h" @@ -311,128 +310,12 @@ CommandObjectCommandsSource::CommandOptions::g_option_table[] = static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" "You must define a Python function with this signature:\n" - "def my_command_impl(debugger, args, stream, dict):"; + "def my_command_impl(debugger, args, result, dict):"; class CommandObjectCommandsAlias : public CommandObject { - class PythonAliasReader : public InputReaderEZ - { - private: - CommandInterpreter& m_interpreter; - std::string m_cmd_name; - StringList m_user_input; - DISALLOW_COPY_AND_ASSIGN (PythonAliasReader); - public: - PythonAliasReader(Debugger& debugger, - CommandInterpreter& interpreter, - std::string cmd_name) : - InputReaderEZ(debugger), - m_interpreter(interpreter), - m_cmd_name(cmd_name), - m_user_input() - {} - - virtual - ~PythonAliasReader() - { - } - - virtual void ActivateHandler(HandlerData& data) - { - StreamSP out_stream = data.GetOutStream(); - bool batch_mode = data.GetBatchMode(); - if (!batch_mode) - { - out_stream->Printf ("%s\n", g_python_command_instructions); - if (data.reader.GetPrompt()) - out_stream->Printf ("%s", data.reader.GetPrompt()); - out_stream->Flush(); - } - } - - virtual void ReactivateHandler(HandlerData& data) - { - StreamSP out_stream = data.GetOutStream(); - bool batch_mode = data.GetBatchMode(); - if (data.reader.GetPrompt() && !batch_mode) - { - out_stream->Printf ("%s", data.reader.GetPrompt()); - out_stream->Flush(); - } - } - virtual void GotTokenHandler(HandlerData& data) - { - StreamSP out_stream = data.GetOutStream(); - bool batch_mode = data.GetBatchMode(); - if (data.bytes && data.bytes_len) - { - m_user_input.AppendString(data.bytes, data.bytes_len); - } - if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) - { - out_stream->Printf ("%s", data.reader.GetPrompt()); - out_stream->Flush(); - } - } - virtual void InterruptHandler(HandlerData& data) - { - StreamSP out_stream = data.GetOutStream(); - bool batch_mode = data.GetBatchMode(); - data.reader.SetIsDone (true); - if (!batch_mode) - { - out_stream->Printf ("Warning: No command attached to breakpoint.\n"); - out_stream->Flush(); - } - } - virtual void EOFHandler(HandlerData& data) - { - data.reader.SetIsDone (true); - } - virtual void DoneHandler(HandlerData& data) - { - StreamSP out_stream = data.GetOutStream(); - - ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); - if (!interpreter) - { - out_stream->Printf ("Internal error #1: no script attached.\n"); - out_stream->Flush(); - return; - } - StringList funct_name_sl; - if (!interpreter->GenerateScriptAliasFunction (m_user_input, - funct_name_sl)) - { - out_stream->Printf ("Internal error #2: no script attached.\n"); - out_stream->Flush(); - return; - } - if (funct_name_sl.GetSize() == 0) - { - out_stream->Printf ("Internal error #3: no script attached.\n"); - out_stream->Flush(); - return; - } - const char *funct_name = funct_name_sl.GetStringAtIndex(0); - if (!funct_name || !funct_name[0]) - { - out_stream->Printf ("Internal error #4: no script attached.\n"); - out_stream->Flush(); - return; - } - - // everything should be fine now, let's add this alias - - CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter, - m_cmd_name, - funct_name)); - - m_interpreter.AddAlias(m_cmd_name.c_str(), command_obj_sp); - } - }; public: CommandObjectCommandsAlias (CommandInterpreter &interpreter) : @@ -552,98 +435,6 @@ public: const std::string alias_command = args.GetArgumentAtIndex (0); - if ( - (strcmp("--python",alias_command.c_str()) == 0) || - (strcmp("-P",alias_command.c_str()) == 0) - ) - { - - if (argc < 3) - { - // this is a definition of the form - // command alias --python foo_cmd - // and the user will type foo_cmd_impl by hand - std::string cmd_name = args.GetArgumentAtIndex(1); - // Verify that the command is alias-able. - if (m_interpreter.CommandExists (cmd_name.c_str())) - { - result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", - cmd_name.c_str()); - result.SetStatus (eReturnStatusFailed); - return false; - } - if (m_interpreter.AliasExists (cmd_name.c_str()) - || m_interpreter.UserCommandExists (cmd_name.c_str())) - { - result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", - cmd_name.c_str()); - } - - - InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(), - m_interpreter, - cmd_name)); - - if (reader_sp) - { - - InputReaderEZ::InitializationParameters ipr; - - Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" "))); - if (err.Success()) - { - m_interpreter.GetDebugger().PushInputReader (reader_sp); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendError (err.AsCString()); - result.SetStatus (eReturnStatusFailed); - } - } - else - { - result.AppendError("out of memory"); - result.SetStatus (eReturnStatusFailed); - } - - result.SetStatus (eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); - } - else - { - // this is a definition of the form - // command alias --python foo_cmd funct_impl_foo - std::string cmd_name = args.GetArgumentAtIndex(1); - std::string funct_name = args.GetArgumentAtIndex(2); - - // Verify that the command is alias-able. - if (m_interpreter.CommandExists (cmd_name.c_str())) - { - result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", - cmd_name.c_str()); - result.SetStatus (eReturnStatusFailed); - return false; - } - - CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter, - cmd_name, - funct_name)); - - if (m_interpreter.AliasExists (cmd_name.c_str()) - || m_interpreter.UserCommandExists (cmd_name.c_str())) - { - result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", - cmd_name.c_str()); - } - - m_interpreter.AddAlias(cmd_name.c_str(), command_obj_sp); - - result.SetStatus (eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); - } - } - // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which // does the stripping itself. size_t pos = raw_command_string.find (alias_command); @@ -1348,6 +1139,535 @@ CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = }; +class CommandObjectPythonFunction : public CommandObject +{ +private: + std::string m_function_name; + +public: + + CommandObjectPythonFunction (CommandInterpreter &interpreter, + std::string name, + std::string funct) : + CommandObject (interpreter, + name.c_str(), + (std::string("Run Python function ") + funct).c_str(), + NULL), + m_function_name(funct) + { + } + + virtual + ~CommandObjectPythonFunction () + { + } + + virtual bool + ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result) + { + ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); + + Error error; + + if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), + raw_command_line, + result, + error) == false) + { + result.AppendError(error.AsCString()); + result.SetStatus(eReturnStatusFailed); + } + else + result.SetStatus(eReturnStatusSuccessFinishNoResult); + + return result.Succeeded(); + } + + virtual bool + WantsRawCommandString () + { + return true; + } + + bool + Execute (Args& command, + CommandReturnObject &result) + { + std::string cmd_string; + command.GetCommandString(cmd_string); + return ExecuteRawCommandString(cmd_string.c_str(), result); + } + + virtual bool + IsRemovable() { return true; } + +}; + + +//------------------------------------------------------------------------- +// CommandObjectCommandsScriptAdd +//------------------------------------------------------------------------- + +class CommandObjectCommandsScriptAdd : public CommandObject +{ +private: + + 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; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'f': + m_funct_name = std::string(option_arg); + break; + default: + error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_funct_name = ""; + } + + 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. + + std::string m_funct_name; + }; + + CommandOptions m_options; + + virtual Options * + GetOptions () + { + return &m_options; + } + + class PythonAliasReader : public InputReaderEZ + { + private: + CommandInterpreter& m_interpreter; + std::string m_cmd_name; + StringList m_user_input; + DISALLOW_COPY_AND_ASSIGN (PythonAliasReader); + public: + PythonAliasReader(Debugger& debugger, + CommandInterpreter& interpreter, + std::string cmd_name) : + InputReaderEZ(debugger), + m_interpreter(interpreter), + m_cmd_name(cmd_name), + m_user_input() + {} + + virtual + ~PythonAliasReader() + { + } + + virtual void ActivateHandler(HandlerData& data) + { + StreamSP out_stream = data.GetOutStream(); + bool batch_mode = data.GetBatchMode(); + if (!batch_mode) + { + out_stream->Printf ("%s\n", g_python_command_instructions); + if (data.reader.GetPrompt()) + out_stream->Printf ("%s", data.reader.GetPrompt()); + out_stream->Flush(); + } + } + + virtual void ReactivateHandler(HandlerData& data) + { + StreamSP out_stream = data.GetOutStream(); + bool batch_mode = data.GetBatchMode(); + if (data.reader.GetPrompt() && !batch_mode) + { + out_stream->Printf ("%s", data.reader.GetPrompt()); + out_stream->Flush(); + } + } + virtual void GotTokenHandler(HandlerData& data) + { + StreamSP out_stream = data.GetOutStream(); + bool batch_mode = data.GetBatchMode(); + if (data.bytes && data.bytes_len) + { + m_user_input.AppendString(data.bytes, data.bytes_len); + } + if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) + { + out_stream->Printf ("%s", data.reader.GetPrompt()); + out_stream->Flush(); + } + } + virtual void InterruptHandler(HandlerData& data) + { + StreamSP out_stream = data.GetOutStream(); + bool batch_mode = data.GetBatchMode(); + data.reader.SetIsDone (true); + if (!batch_mode) + { + out_stream->Printf ("Warning: No command attached to breakpoint.\n"); + out_stream->Flush(); + } + } + virtual void EOFHandler(HandlerData& data) + { + data.reader.SetIsDone (true); + } + virtual void DoneHandler(HandlerData& data) + { + StreamSP out_stream = data.GetOutStream(); + + ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); + if (!interpreter) + { + out_stream->Printf ("Internal error #1: no script attached.\n"); + out_stream->Flush(); + return; + } + StringList funct_name_sl; + if (!interpreter->GenerateScriptAliasFunction (m_user_input, + funct_name_sl)) + { + out_stream->Printf ("Internal error #2: no script attached.\n"); + out_stream->Flush(); + return; + } + if (funct_name_sl.GetSize() == 0) + { + out_stream->Printf ("Internal error #3: no script attached.\n"); + out_stream->Flush(); + return; + } + const char *funct_name = funct_name_sl.GetStringAtIndex(0); + if (!funct_name || !funct_name[0]) + { + out_stream->Printf ("Internal error #4: no script attached.\n"); + out_stream->Flush(); + return; + } + + // everything should be fine now, let's add this alias + + CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter, + m_cmd_name, + funct_name)); + + if (!m_interpreter.AddUserCommand(m_cmd_name.c_str(), command_obj_sp, true)) + { + out_stream->Printf ("Internal error #5: no script attached.\n"); + out_stream->Flush(); + return; + } + } + }; + +public: + CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : + CommandObject (interpreter, + "command script add", + "Add a scripted function as an LLDB command.", + NULL), + m_options (interpreter) + { + CommandArgumentEntry arg1; + CommandArgumentData cmd_arg; + + // Define the first (and only) variant of this arg. + cmd_arg.arg_type = eArgTypeCommandName; + cmd_arg.arg_repetition = eArgRepeatPlain; + + // There is only one variant this argument could be; put it into the argument entry. + arg1.push_back (cmd_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back (arg1); + } + + ~CommandObjectCommandsScriptAdd () + { + } + + bool + Execute + ( + Args& args, + CommandReturnObject &result + ) + { + size_t argc = args.GetArgumentCount(); + + if (argc != 1) + { + result.AppendError ("'command script add' requires one argument"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + std::string cmd_name = args.GetArgumentAtIndex(0); + + if (m_options.m_funct_name.empty()) + { + InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(), + m_interpreter, + cmd_name)); + + if (reader_sp) + { + + InputReaderEZ::InitializationParameters ipr; + + Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" "))); + if (err.Success()) + { + m_interpreter.GetDebugger().PushInputReader (reader_sp); + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + else + { + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError("out of memory"); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, cmd_name, m_options.m_funct_name)); + if (m_interpreter.AddUserCommand(cmd_name.c_str(), new_cmd, true)) + { + result.SetStatus (eReturnStatusSuccessFinishNoResult); + } + else + { + result.AppendError("cannot add command"); + result.SetStatus (eReturnStatusFailed); + } + } + + return result.Succeeded(); + + } +}; + +OptionDefinition +CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypeName, "Name of a Python function to use."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + +//------------------------------------------------------------------------- +// CommandObjectCommandsScriptList +//------------------------------------------------------------------------- + +class CommandObjectCommandsScriptList : public CommandObject +{ +private: + +public: + CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : + CommandObject (interpreter, + "command script list", + "List defined scripted commands.", + NULL) + { + } + + ~CommandObjectCommandsScriptList () + { + } + + bool + Execute + ( + Args& args, + CommandReturnObject &result + ) + { + + m_interpreter.GetHelp(result, + CommandInterpreter::eCommandTypesUserDef); + + result.SetStatus (eReturnStatusSuccessFinishResult); + + return true; + + + } +}; + +//------------------------------------------------------------------------- +// CommandObjectCommandsScriptClear +//------------------------------------------------------------------------- + +class CommandObjectCommandsScriptClear : public CommandObject +{ +private: + +public: + CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : + CommandObject (interpreter, + "command script clear", + "Delete all scripted commands.", + NULL) + { + } + + ~CommandObjectCommandsScriptClear () + { + } + + bool + Execute + ( + Args& args, + CommandReturnObject &result + ) + { + + m_interpreter.RemoveAllUser(); + + result.SetStatus (eReturnStatusSuccessFinishResult); + + return true; + + + } +}; + +//------------------------------------------------------------------------- +// CommandObjectCommandsScriptDelete +//------------------------------------------------------------------------- + +class CommandObjectCommandsScriptDelete : public CommandObject +{ +private: + +public: + CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : + CommandObject (interpreter, + "command script delete", + "Delete a scripted command.", + NULL) + { + CommandArgumentEntry arg1; + CommandArgumentData cmd_arg; + + // Define the first (and only) variant of this arg. + cmd_arg.arg_type = eArgTypeCommandName; + cmd_arg.arg_repetition = eArgRepeatPlain; + + // There is only one variant this argument could be; put it into the argument entry. + arg1.push_back (cmd_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back (arg1); + } + + ~CommandObjectCommandsScriptDelete () + { + } + + bool + Execute + ( + Args& args, + CommandReturnObject &result + ) + { + + size_t argc = args.GetArgumentCount(); + + if (argc != 1) + { + result.AppendError ("'command script delete' requires one argument"); + result.SetStatus (eReturnStatusFailed); + return false; + } + + const char* cmd_name = args.GetArgumentAtIndex(0); + + if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) + { + m_interpreter.RemoveUser(cmd_name); + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendErrorWithFormat ("command %s not found", cmd_name); + result.SetStatus (eReturnStatusFailed); + } + + return result.Succeeded(); + + } +}; + +#pragma mark CommandObjectMultiwordCommandsScript + +//------------------------------------------------------------------------- +// CommandObjectMultiwordCommandsScript +//------------------------------------------------------------------------- + +class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword +{ +public: + CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "command script", + "A set of commands for managing or customizing script commands.", + "command script <subcommand> [<subcommand-options>]") + { + LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); + LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); + LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); + LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); + } + + ~CommandObjectMultiwordCommandsScript () + { + } + +}; + + #pragma mark CommandObjectMultiwordCommands //------------------------------------------------------------------------- @@ -1365,6 +1685,7 @@ CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpret LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); + LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); } CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () diff --git a/lldb/source/Commands/CommandObjectHelp.cpp b/lldb/source/Commands/CommandObjectHelp.cpp index bbf1552e7e3..0c94ff262cb 100644 --- a/lldb/source/Commands/CommandObjectHelp.cpp +++ b/lldb/source/Commands/CommandObjectHelp.cpp @@ -49,7 +49,6 @@ CommandObjectHelp::~CommandObjectHelp() { } - bool CommandObjectHelp::Execute (Args& command, CommandReturnObject &result) { diff --git a/lldb/source/Commands/CommandObjectPythonFunction.cpp b/lldb/source/Commands/CommandObjectPythonFunction.cpp deleted file mode 100644 index b1bb2af8a51..00000000000 --- a/lldb/source/Commands/CommandObjectPythonFunction.cpp +++ /dev/null @@ -1,88 +0,0 @@ -//===-- CommandObjectPythonFunction.cpp --------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CommandObjectPythonFunction.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes - -#include "lldb/API/SBStream.h" - -#include "lldb/Core/Debugger.h" - -#include "lldb/Interpreter/Args.h" -#include "lldb/Interpreter/Options.h" - -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandReturnObject.h" - -#include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Interpreter/ScriptInterpreterPython.h" - -using namespace lldb; -using namespace lldb_private; - -//------------------------------------------------------------------------- -// CommandObjectApropos -//------------------------------------------------------------------------- - -CommandObjectPythonFunction::CommandObjectPythonFunction (CommandInterpreter &interpreter, - std::string name, - std::string funct) : - CommandObject (interpreter, - name.c_str(), - (std::string("Run Python function ") + funct).c_str(), - NULL), - m_function_name(funct) -{ - CommandArgumentEntry arg; - CommandArgumentData search_word_arg; - - // Define the first (and only) variant of this arg. - search_word_arg.arg_type = eArgTypeSearchWord; - search_word_arg.arg_repetition = eArgRepeatPlain; - - // There is only one variant this argument could be; put it into the argument entry. - arg.push_back (search_word_arg); - - // Push the data for the first argument into the m_arguments vector. - m_arguments.push_back (arg); -} - -CommandObjectPythonFunction::~CommandObjectPythonFunction() -{ -} - -bool -CommandObjectPythonFunction::ExecuteRawCommandString (const char *raw_command_line, - CommandReturnObject &result) -{ - ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); - - Error error; - - lldb::SBStream stream; - - if (scripter->RunScriptBasedCommand(m_function_name.c_str(), - raw_command_line, - stream, - error) == false) - { - result.AppendError(error.AsCString()); - result.SetStatus(eReturnStatusFailed); - } - else - result.SetStatus(eReturnStatusSuccessFinishNoResult); - - result.GetOutputStream() << stream.GetData(); - - return result.Succeeded(); -} diff --git a/lldb/source/Commands/CommandObjectPythonFunction.h b/lldb/source/Commands/CommandObjectPythonFunction.h deleted file mode 100644 index 4af857dccd5..00000000000 --- a/lldb/source/Commands/CommandObjectPythonFunction.h +++ /dev/null @@ -1,62 +0,0 @@ -//===-- CommandObjectPythonFunction.h -----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_CommandObjectPythonFunction_h_ -#define liblldb_CommandObjectPythonFunction_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Interpreter/CommandObject.h" - -namespace lldb_private { - -//------------------------------------------------------------------------- -// CommandObjectApropos -//------------------------------------------------------------------------- - -class CommandObjectPythonFunction : public CommandObject -{ -private: - std::string m_function_name; - -public: - - CommandObjectPythonFunction (CommandInterpreter &interpreter, - std::string name, - std::string funct); - - virtual - ~CommandObjectPythonFunction (); - - virtual bool - ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result); - - virtual bool - WantsRawCommandString () - { - return true; - } - - bool - Execute (Args& command, - CommandReturnObject &result) - { - std::string cmd_string; - command.GetCommandString(cmd_string); - return ExecuteRawCommandString(cmd_string.c_str(), result); - } - - -}; - -} // namespace lldb_private - -#endif // liblldb_CommandObjectPythonFunction_h_ diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index ab50edf9526..d2e3a5b6da2 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -264,7 +264,7 @@ CommandInterpreter::LoadCommandDictionary () m_command_dict["source"] = CommandObjectSP (new CommandObjectMultiwordSource (*this)); m_command_dict["target"] = CommandObjectSP (new CommandObjectMultiwordTarget (*this)); m_command_dict["thread"] = CommandObjectSP (new CommandObjectMultiwordThread (*this)); - m_command_dict["type"] = CommandObjectSP (new CommandObjectType (*this)); + m_command_dict["type"] = CommandObjectSP (new CommandObjectType (*this)); m_command_dict["version"] = CommandObjectSP (new CommandObjectVersion (*this)); std::auto_ptr<CommandObjectRegexCommand> @@ -457,6 +457,24 @@ CommandInterpreter::AddCommand (const char *name, const lldb::CommandObjectSP &c return false; } +bool +CommandInterpreter::AddUserCommand (const char *name, + const lldb::CommandObjectSP &cmd_sp, + bool can_replace) +{ + if (name && name[0]) + { + std::string name_sstr(name); + if (!can_replace) + { + if (m_user_dict.find (name_sstr) != m_user_dict.end()) + return false; + } + m_user_dict[name_sstr] = cmd_sp; + return true; + } + return false; +} CommandObjectSP CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliases) @@ -682,21 +700,28 @@ CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict) } void -CommandInterpreter::GetHelp (CommandReturnObject &result) +CommandInterpreter::GetHelp (CommandReturnObject &result, + CommandTypes cmd_types) { CommandObject::CommandMap::const_iterator pos; - result.AppendMessage("The following is a list of built-in, permanent debugger commands:"); - result.AppendMessage(""); uint32_t max_len = FindLongestCommandWord (m_command_dict); - - for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) + + if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin ) { - OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), - max_len); + + result.AppendMessage("The following is a list of built-in, permanent debugger commands:"); + result.AppendMessage(""); + + for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) + { + OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), + max_len); + } + result.AppendMessage(""); + } - result.AppendMessage(""); - if (m_alias_dict.size() > 0) + if (m_alias_dict.size() > 0 && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases )) { result.AppendMessage("The following is a list of your current command abbreviations " "(see 'help command alias' for more info):"); @@ -718,13 +743,15 @@ CommandInterpreter::GetHelp (CommandReturnObject &result) result.AppendMessage(""); } - if (m_user_dict.size() > 0) + if (m_user_dict.size() > 0 && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef )) { result.AppendMessage ("The following is a list of your current user-defined commands:"); result.AppendMessage(""); + max_len = FindLongestCommandWord (m_user_dict); for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) { - result.AppendMessageWithFormat ("%s -- %s\n", pos->first.c_str(), pos->second->GetHelp()); + OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), + max_len); } result.AppendMessage(""); } diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp index e0a88cbc338..4db56d4ac23 100644 --- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp +++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp @@ -1909,7 +1909,7 @@ ScriptInterpreterPython::CastPyObjectToSBValue (void* data) bool ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function, const char* args, - lldb::SBStream& stream, + lldb_private::CommandReturnObject& cmd_retobj, Error& error) { if (!impl_function) @@ -1941,7 +1941,7 @@ ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function, debugger_sp, args, err_msg, - stream); + cmd_retobj); python_interpreter->LeaveSession (); } else @@ -1955,7 +1955,7 @@ ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function, debugger_sp, args, err_msg, - stream); + cmd_retobj); python_interpreter->LeaveSession (); ReleasePythonLock (); } diff --git a/lldb/test/functionalities/abbreviation/TestAbbreviations.py b/lldb/test/functionalities/abbreviation/TestAbbreviations.py index 71add6f3881..31073af1e4e 100644 --- a/lldb/test/functionalities/abbreviation/TestAbbreviations.py +++ b/lldb/test/functionalities/abbreviation/TestAbbreviations.py @@ -34,7 +34,7 @@ class AbbreviationsTestCase(TestBase): startstr = "The following is a list of built-in, permanent debugger commands:") - self.expect("com s ./change_prompt.lldb", + self.expect("com sou ./change_prompt.lldb", patterns = ["Executing commands in '.*change_prompt.lldb'"]) self.expect("settings show prompt", diff --git a/lldb/test/functionalities/alias/TestAliases.py b/lldb/test/functionalities/alias/TestAliases.py index 4e700077e20..4f43136f24d 100644 --- a/lldb/test/functionalities/alias/TestAliases.py +++ b/lldb/test/functionalities/alias/TestAliases.py @@ -135,10 +135,10 @@ class AliasTestCase(TestBase): self.expect('welcome Enrico', substrs = ['Hello Enrico, welcome to LLDB']); - self.runCmd("command unalias welcome"); + self.runCmd("command script delete welcome"); self.expect('welcome Enrico', matching=False, error=True, - substrs = ['Hello Enrico, welcome to LLDB']); + substrs = ['Hello Enrico, welcome to LLDB']); self.expect('targetname', substrs = ['a.out']) @@ -146,7 +146,7 @@ class AliasTestCase(TestBase): self.expect('targetname fail', error=True, substrs = ['a test for error in command']) - self.expect('help', + self.expect('command script list', substrs = ['targetname', 'Run Python function target_name_impl']) @@ -155,6 +155,14 @@ class AliasTestCase(TestBase): 'This command takes \'raw\' input', 'quote stuff']) + self.expect("longwait", + substrs = ['Done; if you saw the delays I am doing OK']) + + self.runCmd("command script clear") + + self.expect('command script list', matching=False, + substrs = ['targetname', + 'longwait']) if __name__ == '__main__': import atexit diff --git a/lldb/test/functionalities/alias/py_import b/lldb/test/functionalities/alias/py_import index 5a562a2d997..9deba49e8f4 100644 --- a/lldb/test/functionalities/alias/py_import +++ b/lldb/test/functionalities/alias/py_import @@ -1,5 +1,6 @@ script import sys, os script sys.path.append(os.path.join(os.getcwd(), os.pardir)) script from welcome import * -command alias --python welcome welcome_impl -command alias --python targetname target_name_impl
\ No newline at end of file +command script add welcome --function welcome_impl +command script add targetname --function target_name_impl +command script add longwait --function print_wait_impl diff --git a/lldb/test/functionalities/alias/welcome.py b/lldb/test/functionalities/alias/welcome.py index 6754851c833..db90e89ee4e 100644 --- a/lldb/test/functionalities/alias/welcome.py +++ b/lldb/test/functionalities/alias/welcome.py @@ -1,14 +1,23 @@ import sys -def welcome_impl(debugger, args, stream, dict): - stream.Printf('Hello ' + args + ', welcome to LLDB'); +def welcome_impl(debugger, args, result, dict): + result.Printf('Hello ' + args + ', welcome to LLDB'); return None; -def target_name_impl(debugger, args, stream, dict): +def target_name_impl(debugger, args, result, dict): target = debugger.GetSelectedTarget() file = target.GetExecutable() - stream.Printf('Current target ' + file.GetFilename()) + result.PutCString('Current target ' + file.GetFilename()) if args == 'fail': return 'a test for error in command' else: - return None
\ No newline at end of file + return None + +def print_wait_impl(debugger, args, result, dict): + print 'Trying to do long task..'; + import time + time.sleep(1) + print 'Still doing long task..'; + time.sleep(1) + result.PutCString('Done; if you saw the delays I am doing OK') + return None
\ No newline at end of file |