130fdc8d8SChris Lattner //===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "CommandObjectExpression.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner #include "lldb/Core/Value.h" 176c68fb45SJim Ingham #include "lldb/Core/ValueObjectVariable.h" 184d93b8cdSEnrico Granata #include "lldb/DataFormatters/ValueObjectPrinter.h" 1930e33974SSean Callanan #include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h" 201a8d4093SSean Callanan #include "lldb/Expression/ClangUserExpression.h" 21ebb84b24SStephen Wilson #include "lldb/Expression/ClangFunction.h" 2230fdc8d8SChris Lattner #include "lldb/Expression/DWARFExpression.h" 2330fdc8d8SChris Lattner #include "lldb/Host/Host.h" 245275aaa0SVince Harron #include "lldb/Host/StringConvert.h" 25ebf7707eSSean Callanan #include "lldb/Core/Debugger.h" 266611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 2730fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 280e0984eeSJim Ingham #include "lldb/Target/Language.h" 2930fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h" 3030fdc8d8SChris Lattner #include "lldb/Symbol/Variable.h" 3130fdc8d8SChris Lattner #include "lldb/Target/Process.h" 32b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h" 3330fdc8d8SChris Lattner #include "lldb/Target/Target.h" 347260f620SGreg Clayton #include "lldb/Target/Thread.h" 3528606954SSaleem Abdulrasool #include "llvm/ADT/STLExtras.h" 36ebf7707eSSean Callanan #include "llvm/ADT/StringRef.h" 3730fdc8d8SChris Lattner 3830fdc8d8SChris Lattner using namespace lldb; 3930fdc8d8SChris Lattner using namespace lldb_private; 4030fdc8d8SChris Lattner 411deb7962SGreg Clayton CommandObjectExpression::CommandOptions::CommandOptions () : 421deb7962SGreg Clayton OptionGroup() 4330fdc8d8SChris Lattner { 4430fdc8d8SChris Lattner } 4530fdc8d8SChris Lattner 4630fdc8d8SChris Lattner 4730fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::~CommandOptions () 4830fdc8d8SChris Lattner { 4930fdc8d8SChris Lattner } 5030fdc8d8SChris Lattner 514d93b8cdSEnrico Granata static OptionEnumValueElement g_description_verbosity_type[] = 524d93b8cdSEnrico Granata { 534d93b8cdSEnrico Granata { eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"}, 544d93b8cdSEnrico Granata { eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", "Show the full output, including persistent variable's name and type"}, 554d93b8cdSEnrico Granata { 0, NULL, NULL } 564d93b8cdSEnrico Granata }; 574d93b8cdSEnrico Granata 581deb7962SGreg Clayton OptionDefinition 591deb7962SGreg Clayton CommandObjectExpression::CommandOptions::g_option_table[] = 601deb7962SGreg Clayton { 61d37221dcSZachary Turner { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."}, 62d37221dcSZachary Turner { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"}, 63d37221dcSZachary Turner { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."}, 64d37221dcSZachary Turner { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."}, 65d37221dcSZachary Turner { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."}, 6615663c53SDawn Perchik { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language setting is used." }, 67d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, NULL, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."}, 681deb7962SGreg Clayton }; 691deb7962SGreg Clayton 701deb7962SGreg Clayton 711deb7962SGreg Clayton uint32_t 721deb7962SGreg Clayton CommandObjectExpression::CommandOptions::GetNumDefinitions () 731deb7962SGreg Clayton { 7428606954SSaleem Abdulrasool return llvm::array_lengthof(g_option_table); 751deb7962SGreg Clayton } 761deb7962SGreg Clayton 7730fdc8d8SChris Lattner Error 781deb7962SGreg Clayton CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter, 791deb7962SGreg Clayton uint32_t option_idx, 801deb7962SGreg Clayton const char *option_arg) 8130fdc8d8SChris Lattner { 8230fdc8d8SChris Lattner Error error; 8330fdc8d8SChris Lattner 843bcdfc0eSGreg Clayton const int short_option = g_option_table[option_idx].short_option; 8530fdc8d8SChris Lattner 8630fdc8d8SChris Lattner switch (short_option) 8730fdc8d8SChris Lattner { 8815663c53SDawn Perchik case 'l': 890e0984eeSJim Ingham language = Language::GetLanguageTypeFromString (option_arg); 9015663c53SDawn Perchik if (language == eLanguageTypeUnknown) 9115663c53SDawn Perchik error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", option_arg); 9215663c53SDawn Perchik break; 9330fdc8d8SChris Lattner 9435e1bda6SJim Ingham case 'a': 9535e1bda6SJim Ingham { 9635e1bda6SJim Ingham bool success; 9735e1bda6SJim Ingham bool result; 9835e1bda6SJim Ingham result = Args::StringToBoolean(option_arg, true, &success); 9935e1bda6SJim Ingham if (!success) 10035e1bda6SJim Ingham error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg); 10135e1bda6SJim Ingham else 10235e1bda6SJim Ingham try_all_threads = result; 10335e1bda6SJim Ingham } 1046c68fb45SJim Ingham break; 1056c68fb45SJim Ingham 106184e9811SJim Ingham case 'i': 107184e9811SJim Ingham { 108184e9811SJim Ingham bool success; 109184e9811SJim Ingham bool tmp_value = Args::StringToBoolean(option_arg, true, &success); 110184e9811SJim Ingham if (success) 111184e9811SJim Ingham ignore_breakpoints = tmp_value; 112184e9811SJim Ingham else 113184e9811SJim Ingham error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg); 114184e9811SJim Ingham break; 115184e9811SJim Ingham } 11635e1bda6SJim Ingham case 't': 11735e1bda6SJim Ingham { 11835e1bda6SJim Ingham bool success; 11935e1bda6SJim Ingham uint32_t result; 1205275aaa0SVince Harron result = StringConvert::ToUInt32(option_arg, 0, 0, &success); 12135e1bda6SJim Ingham if (success) 12235e1bda6SJim Ingham timeout = result; 12335e1bda6SJim Ingham else 12435e1bda6SJim Ingham error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg); 12535e1bda6SJim Ingham } 12635e1bda6SJim Ingham break; 12735e1bda6SJim Ingham 128399f1cafSJim Ingham case 'u': 1293bfdaa2aSSean Callanan { 130399f1cafSJim Ingham bool success; 131184e9811SJim Ingham bool tmp_value = Args::StringToBoolean(option_arg, true, &success); 132184e9811SJim Ingham if (success) 133184e9811SJim Ingham unwind_on_error = tmp_value; 134184e9811SJim Ingham else 13586edbf41SGreg Clayton error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg); 136399f1cafSJim Ingham break; 1373bfdaa2aSSean Callanan } 1384d93b8cdSEnrico Granata 1394d93b8cdSEnrico Granata case 'v': 1404d93b8cdSEnrico Granata if (!option_arg) 1414d93b8cdSEnrico Granata { 1424d93b8cdSEnrico Granata m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull; 1434d93b8cdSEnrico Granata break; 1444d93b8cdSEnrico Granata } 1454d93b8cdSEnrico Granata m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 1464d93b8cdSEnrico Granata if (!error.Success()) 1474d93b8cdSEnrico Granata error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg); 1484d93b8cdSEnrico Granata break; 1494d93b8cdSEnrico Granata 15062afb9f6SGreg Clayton case 'g': 15162afb9f6SGreg Clayton debug = true; 15262afb9f6SGreg Clayton unwind_on_error = false; 15362afb9f6SGreg Clayton ignore_breakpoints = false; 15462afb9f6SGreg Clayton break; 15562afb9f6SGreg Clayton 15630fdc8d8SChris Lattner default: 15786edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 15830fdc8d8SChris Lattner break; 15930fdc8d8SChris Lattner } 16030fdc8d8SChris Lattner 16130fdc8d8SChris Lattner return error; 16230fdc8d8SChris Lattner } 16330fdc8d8SChris Lattner 16430fdc8d8SChris Lattner void 1651deb7962SGreg Clayton CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter) 16630fdc8d8SChris Lattner { 167184e9811SJim Ingham Process *process = interpreter.GetExecutionContext().GetProcessPtr(); 168184e9811SJim Ingham if (process != NULL) 169184e9811SJim Ingham { 170184e9811SJim Ingham ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions(); 171184e9811SJim Ingham unwind_on_error = process->GetUnwindOnErrorInExpressions(); 172184e9811SJim Ingham } 173184e9811SJim Ingham else 174184e9811SJim Ingham { 175fc03f8fcSGreg Clayton ignore_breakpoints = true; 176399f1cafSJim Ingham unwind_on_error = true; 177184e9811SJim Ingham } 178184e9811SJim Ingham 17930fdc8d8SChris Lattner show_summary = true; 18035e1bda6SJim Ingham try_all_threads = true; 18135e1bda6SJim Ingham timeout = 0; 18262afb9f6SGreg Clayton debug = false; 18315663c53SDawn Perchik language = eLanguageTypeUnknown; 1844d93b8cdSEnrico Granata m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact; 18530fdc8d8SChris Lattner } 18630fdc8d8SChris Lattner 187e0d378b3SGreg Clayton const OptionDefinition* 18830fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::GetDefinitions () 18930fdc8d8SChris Lattner { 19030fdc8d8SChris Lattner return g_option_table; 19130fdc8d8SChris Lattner } 19230fdc8d8SChris Lattner 193a7015092SGreg Clayton CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) : 1945a988416SJim Ingham CommandObjectRaw (interpreter, 19530fdc8d8SChris Lattner "expression", 19615663c53SDawn Perchik "Evaluate an expression in the current program context, using user defined variables and variables currently in scope.", 1975a988416SJim Ingham NULL, 198e87764f2SEnrico Granata eCommandProcessMustBePaused | eCommandTryTargetAPILock), 19944d93782SGreg Clayton IOHandlerDelegate (IOHandlerDelegate::Completion::Expression), 2001deb7962SGreg Clayton m_option_group (interpreter), 2011deb7962SGreg Clayton m_format_options (eFormatDefault), 2021deb7962SGreg Clayton m_command_options (), 20330fdc8d8SChris Lattner m_expr_line_count (0), 20430fdc8d8SChris Lattner m_expr_lines () 20530fdc8d8SChris Lattner { 20630fdc8d8SChris Lattner SetHelpLong( 207ea671fbdSKate Stone R"( 208ea671fbdSKate Stone Timeouts: 209ea671fbdSKate Stone 210ea671fbdSKate Stone )" " If the expression can be evaluated statically (without running code) then it will be. \ 211ea671fbdSKate Stone Otherwise, by default the expression will run on the current thread with a short timeout: \ 212ea671fbdSKate Stone currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted \ 213ea671fbdSKate Stone and resumed with all threads running. You can use the -a option to disable retrying on all \ 214ea671fbdSKate Stone threads. You can use the -t option to set a shorter timeout." R"( 215ea671fbdSKate Stone 216ea671fbdSKate Stone User defined variables: 217ea671fbdSKate Stone 218ea671fbdSKate Stone )" " You can define your own variables for convenience or to be used in subsequent expressions. \ 219ea671fbdSKate Stone You define them the same way you would define variables in C. If the first character of \ 220ea671fbdSKate Stone your user defined variable is a $, then the variable's value will be available in future \ 221ea671fbdSKate Stone expressions, otherwise it will just be available in the current expression." R"( 222ea671fbdSKate Stone 223ea671fbdSKate Stone Continuing evaluation after a breakpoint: 224ea671fbdSKate Stone 225ea671fbdSKate Stone )" " If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \ 226ea671fbdSKate Stone you are done with your investigation, you can either remove the expression execution frames \ 227ea671fbdSKate Stone from the stack with \"thread return -x\" or if you are still interested in the expression result \ 228ea671fbdSKate Stone you can issue the \"continue\" command and the expression evaluation will complete and the \ 229ea671fbdSKate Stone expression result will be available using the \"thread.completed-expression\" key in the thread \ 230ea671fbdSKate Stone format." R"( 231ea671fbdSKate Stone 232ea671fbdSKate Stone Examples: 233ea671fbdSKate Stone 234ea671fbdSKate Stone expr my_struct->a = my_array[3] 235ea671fbdSKate Stone expr -f bin -- (index * 8) + 5 236ea671fbdSKate Stone expr unsigned int $foo = 5 237ea671fbdSKate Stone expr char c[] = \"foo\"; c[0])" 238ea671fbdSKate Stone ); 239405fe67fSCaroline Tice 240405fe67fSCaroline Tice CommandArgumentEntry arg; 241405fe67fSCaroline Tice CommandArgumentData expression_arg; 242405fe67fSCaroline Tice 243405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 244405fe67fSCaroline Tice expression_arg.arg_type = eArgTypeExpression; 245405fe67fSCaroline Tice expression_arg.arg_repetition = eArgRepeatPlain; 246405fe67fSCaroline Tice 247405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 248405fe67fSCaroline Tice arg.push_back (expression_arg); 249405fe67fSCaroline Tice 250405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 251405fe67fSCaroline Tice m_arguments.push_back (arg); 2521deb7962SGreg Clayton 2535009f9d5SGreg Clayton // Add the "--format" and "--gdb-format" 2545009f9d5SGreg Clayton m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1); 2551deb7962SGreg Clayton m_option_group.Append (&m_command_options); 256b576bba2SEnrico Granata m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2); 2571deb7962SGreg Clayton m_option_group.Finalize(); 25830fdc8d8SChris Lattner } 25930fdc8d8SChris Lattner 26030fdc8d8SChris Lattner CommandObjectExpression::~CommandObjectExpression () 26130fdc8d8SChris Lattner { 26230fdc8d8SChris Lattner } 26330fdc8d8SChris Lattner 26430fdc8d8SChris Lattner Options * 26530fdc8d8SChris Lattner CommandObjectExpression::GetOptions () 26630fdc8d8SChris Lattner { 2671deb7962SGreg Clayton return &m_option_group; 26830fdc8d8SChris Lattner } 26930fdc8d8SChris Lattner 27030fdc8d8SChris Lattner bool 2711d3afba3SGreg Clayton CommandObjectExpression::EvaluateExpression 2721d3afba3SGreg Clayton ( 2731d3afba3SGreg Clayton const char *expr, 2746e8dc334SCaroline Tice Stream *output_stream, 2756e8dc334SCaroline Tice Stream *error_stream, 2761d3afba3SGreg Clayton CommandReturnObject *result 2771d3afba3SGreg Clayton ) 27830fdc8d8SChris Lattner { 279ba7b8e2cSGreg Clayton // Don't use m_exe_ctx as this might be called asynchronously 280ba7b8e2cSGreg Clayton // after the command object DoExecute has finished when doing 281ba7b8e2cSGreg Clayton // multi-line expression that use an input reader... 282ba7b8e2cSGreg Clayton ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 283ba7b8e2cSGreg Clayton 284ba7b8e2cSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 285c0a6e061SSean Callanan 286c0a6e061SSean Callanan if (!target) 287893c932aSJim Ingham target = GetDummyTarget(); 288c0a6e061SSean Callanan 289c14ee32dSGreg Clayton if (target) 2906961e878SSean Callanan { 2918b2fe6dcSGreg Clayton lldb::ValueObjectSP result_valobj_sp; 29292adcac9SSean Callanan bool keep_in_memory = true; 293*009d110dSDawn Perchik StackFrame *frame = exe_ctx.GetFramePtr(); 29492adcac9SSean Callanan 29535e1bda6SJim Ingham EvaluateExpressionOptions options; 2966fbc48bcSJim Ingham options.SetCoerceToId(m_varobj_options.use_objc); 2976fbc48bcSJim Ingham options.SetUnwindOnError(m_command_options.unwind_on_error); 2986fbc48bcSJim Ingham options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints); 2996fbc48bcSJim Ingham options.SetKeepInMemory(keep_in_memory); 3006fbc48bcSJim Ingham options.SetUseDynamic(m_varobj_options.use_dynamic); 3016fbc48bcSJim Ingham options.SetTryAllThreads(m_command_options.try_all_threads); 3026fbc48bcSJim Ingham options.SetDebug(m_command_options.debug); 30362afb9f6SGreg Clayton 304*009d110dSDawn Perchik // If the language was not specified in the expression command, 305*009d110dSDawn Perchik // set it to the language in the target's properties if 306*009d110dSDawn Perchik // specified, else default to the langage for the frame. 30715663c53SDawn Perchik if (m_command_options.language != eLanguageTypeUnknown) 30815663c53SDawn Perchik options.SetLanguage(m_command_options.language); 309*009d110dSDawn Perchik else if (target->GetLanguage() != eLanguageTypeUnknown) 31015663c53SDawn Perchik options.SetLanguage(target->GetLanguage()); 311*009d110dSDawn Perchik else if (frame) 312*009d110dSDawn Perchik options.SetLanguage(frame->GetLanguage()); 31315663c53SDawn Perchik 31423f8c95aSGreg Clayton // If there is any chance we are going to stop and want to see 31523f8c95aSGreg Clayton // what went wrong with our expression, we should generate debug info 31623f8c95aSGreg Clayton if (!m_command_options.ignore_breakpoints || 31723f8c95aSGreg Clayton !m_command_options.unwind_on_error) 31823f8c95aSGreg Clayton options.SetGenerateDebugInfo(true); 31923f8c95aSGreg Clayton 32062afb9f6SGreg Clayton if (m_command_options.timeout > 0) 32162afb9f6SGreg Clayton options.SetTimeoutUsec(m_command_options.timeout); 3226f78f386SJim Ingham else 3236f78f386SJim Ingham options.SetTimeoutUsec(0); 324d4439aa9SEnrico Granata 325*009d110dSDawn Perchik target->EvaluateExpression(expr, frame, result_valobj_sp, options); 3268b2fe6dcSGreg Clayton 3278b2fe6dcSGreg Clayton if (result_valobj_sp) 3288b2fe6dcSGreg Clayton { 329bf154daeSSean Callanan Format format = m_format_options.GetFormat(); 330bf154daeSSean Callanan 331b71f3844SGreg Clayton if (result_valobj_sp->GetError().Success()) 33230fdc8d8SChris Lattner { 333bf154daeSSean Callanan if (format != eFormatVoid) 334bf154daeSSean Callanan { 3351deb7962SGreg Clayton if (format != eFormatDefault) 3361deb7962SGreg Clayton result_valobj_sp->SetFormat (format); 33732c4085bSGreg Clayton 3384d93b8cdSEnrico Granata DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format)); 339770eb05aSEnrico Granata 3404d93b8cdSEnrico Granata result_valobj_sp->Dump(*output_stream,options); 3414d93b8cdSEnrico Granata 342fcd43b71SJohnny Chen if (result) 343fcd43b71SJohnny Chen result->SetStatus (eReturnStatusSuccessFinishResult); 34430fdc8d8SChris Lattner } 345bf154daeSSean Callanan } 34630fdc8d8SChris Lattner else 34730fdc8d8SChris Lattner { 348bccce813SSean Callanan if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult) 349bccce813SSean Callanan { 350bcf897faSSean Callanan if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid()) 351bf154daeSSean Callanan { 352bcf897faSSean Callanan error_stream->PutCString("(void)\n"); 353bcf897faSSean Callanan } 354bccce813SSean Callanan 355bccce813SSean Callanan if (result) 356bccce813SSean Callanan result->SetStatus (eReturnStatusSuccessFinishResult); 357bccce813SSean Callanan } 358bccce813SSean Callanan else 359bccce813SSean Callanan { 3605fd05903SGreg Clayton const char *error_cstr = result_valobj_sp->GetError().AsCString(); 3615fd05903SGreg Clayton if (error_cstr && error_cstr[0]) 3625fd05903SGreg Clayton { 363c7bece56SGreg Clayton const size_t error_cstr_len = strlen (error_cstr); 3645fd05903SGreg Clayton const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n'; 3655fd05903SGreg Clayton if (strstr(error_cstr, "error:") != error_cstr) 3665fd05903SGreg Clayton error_stream->PutCString ("error: "); 3675fd05903SGreg Clayton error_stream->Write(error_cstr, error_cstr_len); 3685fd05903SGreg Clayton if (!ends_with_newline) 3695fd05903SGreg Clayton error_stream->EOL(); 3705fd05903SGreg Clayton } 3715fd05903SGreg Clayton else 3725fd05903SGreg Clayton { 3735fd05903SGreg Clayton error_stream->PutCString ("error: unknown error\n"); 3745fd05903SGreg Clayton } 3755fd05903SGreg Clayton 376fcd43b71SJohnny Chen if (result) 377b71f3844SGreg Clayton result->SetStatus (eReturnStatusFailed); 37830fdc8d8SChris Lattner } 3798b2fe6dcSGreg Clayton } 3808b2fe6dcSGreg Clayton } 381bccce813SSean Callanan } 3828b2fe6dcSGreg Clayton else 3838b2fe6dcSGreg Clayton { 3846e8dc334SCaroline Tice error_stream->Printf ("error: invalid execution context for expression\n"); 3858b2fe6dcSGreg Clayton return false; 3868b2fe6dcSGreg Clayton } 38730fdc8d8SChris Lattner 38816ad5faeSSean Callanan return true; 38930fdc8d8SChris Lattner } 39030fdc8d8SChris Lattner 39144d93782SGreg Clayton void 39244d93782SGreg Clayton CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line) 39344d93782SGreg Clayton { 39444d93782SGreg Clayton io_handler.SetIsDone(true); 39544d93782SGreg Clayton // StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream(); 39644d93782SGreg Clayton // StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream(); 39744d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 39844d93782SGreg Clayton StreamFileSP error_sp(io_handler.GetErrorStreamFile()); 39944d93782SGreg Clayton 40044d93782SGreg Clayton EvaluateExpression (line.c_str(), 40144d93782SGreg Clayton output_sp.get(), 40244d93782SGreg Clayton error_sp.get()); 40344d93782SGreg Clayton if (output_sp) 40444d93782SGreg Clayton output_sp->Flush(); 40544d93782SGreg Clayton if (error_sp) 40644d93782SGreg Clayton error_sp->Flush(); 40744d93782SGreg Clayton } 40844d93782SGreg Clayton 40944d93782SGreg Clayton LineStatus 41044d93782SGreg Clayton CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler, 41144d93782SGreg Clayton StringList &lines, 41244d93782SGreg Clayton uint32_t line_idx, 41344d93782SGreg Clayton Error &error) 41444d93782SGreg Clayton { 41544d93782SGreg Clayton if (line_idx == UINT32_MAX) 41644d93782SGreg Clayton { 41744d93782SGreg Clayton // Remove the last line from "lines" so it doesn't appear 41844d93782SGreg Clayton // in our final expression 41944d93782SGreg Clayton lines.PopBack(); 42044d93782SGreg Clayton error.Clear(); 42144d93782SGreg Clayton return LineStatus::Done; 42244d93782SGreg Clayton } 42344d93782SGreg Clayton else if (line_idx + 1 == lines.GetSize()) 42444d93782SGreg Clayton { 42544d93782SGreg Clayton // The last line was edited, if this line is empty, then we are done 42644d93782SGreg Clayton // getting our multiple lines. 42744d93782SGreg Clayton if (lines[line_idx].empty()) 42844d93782SGreg Clayton return LineStatus::Done; 42944d93782SGreg Clayton } 43044d93782SGreg Clayton return LineStatus::Success; 43144d93782SGreg Clayton } 43244d93782SGreg Clayton 433cf28a8b7SGreg Clayton void 434cf28a8b7SGreg Clayton CommandObjectExpression::GetMultilineExpression () 43530fdc8d8SChris Lattner { 43630fdc8d8SChris Lattner m_expr_lines.clear(); 43730fdc8d8SChris Lattner m_expr_line_count = 0; 43830fdc8d8SChris Lattner 43944d93782SGreg Clayton Debugger &debugger = GetCommandInterpreter().GetDebugger(); 440e30f11d9SKate Stone bool color_prompt = debugger.GetUseColor(); 44144d93782SGreg Clayton const bool multiple_lines = true; // Get multiple lines 44244d93782SGreg Clayton IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 443e30f11d9SKate Stone IOHandler::Type::Expression, 44444d93782SGreg Clayton "lldb-expr", // Name of input reader for history 44544d93782SGreg Clayton NULL, // No prompt 446e30f11d9SKate Stone NULL, // Continuation prompt 44744d93782SGreg Clayton multiple_lines, 448e30f11d9SKate Stone color_prompt, 449f6913cd7SGreg Clayton 1, // Show line numbers starting at 1 45044d93782SGreg Clayton *this)); 451b6892508SGreg Clayton 452b6892508SGreg Clayton StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile()); 453b6892508SGreg Clayton if (output_sp) 454b6892508SGreg Clayton { 455b6892508SGreg Clayton output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n"); 456b6892508SGreg Clayton output_sp->Flush(); 457b6892508SGreg Clayton } 45844d93782SGreg Clayton debugger.PushIOHandler(io_handler_sp); 459cf28a8b7SGreg Clayton } 460cf28a8b7SGreg Clayton 461cf28a8b7SGreg Clayton bool 462cf28a8b7SGreg Clayton CommandObjectExpression::DoExecute 463cf28a8b7SGreg Clayton ( 464cf28a8b7SGreg Clayton const char *command, 465cf28a8b7SGreg Clayton CommandReturnObject &result 466cf28a8b7SGreg Clayton ) 467cf28a8b7SGreg Clayton { 468cf28a8b7SGreg Clayton m_option_group.NotifyOptionParsingStarting(); 469cf28a8b7SGreg Clayton 470cf28a8b7SGreg Clayton const char * expr = NULL; 471cf28a8b7SGreg Clayton 472cf28a8b7SGreg Clayton if (command[0] == '\0') 473cf28a8b7SGreg Clayton { 474cf28a8b7SGreg Clayton GetMultilineExpression (); 47530fdc8d8SChris Lattner return result.Succeeded(); 47630fdc8d8SChris Lattner } 47730fdc8d8SChris Lattner 47830fdc8d8SChris Lattner if (command[0] == '-') 47930fdc8d8SChris Lattner { 48030fdc8d8SChris Lattner // We have some options and these options MUST end with --. 48130fdc8d8SChris Lattner const char *end_options = NULL; 48230fdc8d8SChris Lattner const char *s = command; 48330fdc8d8SChris Lattner while (s && s[0]) 48430fdc8d8SChris Lattner { 48530fdc8d8SChris Lattner end_options = ::strstr (s, "--"); 48630fdc8d8SChris Lattner if (end_options) 48730fdc8d8SChris Lattner { 48830fdc8d8SChris Lattner end_options += 2; // Get past the "--" 48930fdc8d8SChris Lattner if (::isspace (end_options[0])) 49030fdc8d8SChris Lattner { 49130fdc8d8SChris Lattner expr = end_options; 49230fdc8d8SChris Lattner while (::isspace (*expr)) 49330fdc8d8SChris Lattner ++expr; 49430fdc8d8SChris Lattner break; 49530fdc8d8SChris Lattner } 49630fdc8d8SChris Lattner } 49730fdc8d8SChris Lattner s = end_options; 49830fdc8d8SChris Lattner } 49930fdc8d8SChris Lattner 50030fdc8d8SChris Lattner if (end_options) 50130fdc8d8SChris Lattner { 50200b7f95bSPavel Labath Args args (llvm::StringRef(command, end_options - command)); 503a7015092SGreg Clayton if (!ParseOptions (args, result)) 50430fdc8d8SChris Lattner return false; 505f6b8b581SGreg Clayton 5061deb7962SGreg Clayton Error error (m_option_group.NotifyOptionParsingFinished()); 507f6b8b581SGreg Clayton if (error.Fail()) 508f6b8b581SGreg Clayton { 509f6b8b581SGreg Clayton result.AppendError (error.AsCString()); 510f6b8b581SGreg Clayton result.SetStatus (eReturnStatusFailed); 511f6b8b581SGreg Clayton return false; 512f6b8b581SGreg Clayton } 513cf28a8b7SGreg Clayton 514cf28a8b7SGreg Clayton // No expression following options 51505da458cSGreg Clayton if (expr == NULL || expr[0] == '\0') 516cf28a8b7SGreg Clayton { 517cf28a8b7SGreg Clayton GetMultilineExpression (); 518cf28a8b7SGreg Clayton return result.Succeeded(); 519cf28a8b7SGreg Clayton } 52030fdc8d8SChris Lattner } 52130fdc8d8SChris Lattner } 52230fdc8d8SChris Lattner 52330fdc8d8SChris Lattner if (expr == NULL) 52430fdc8d8SChris Lattner expr = command; 52530fdc8d8SChris Lattner 5266e8dc334SCaroline Tice if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result)) 527fcd43b71SJohnny Chen return true; 528fcd43b71SJohnny Chen 529fcd43b71SJohnny Chen result.SetStatus (eReturnStatusFailed); 530fcd43b71SJohnny Chen return false; 53130fdc8d8SChris Lattner } 53230fdc8d8SChris Lattner 533