blob: 72a1a234e4f6408eb7ae9873e836d8477bd7f24a [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectExpression.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/Value.h"
Jim Ingham6c68fb42010-09-30 00:54:27 +000017#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000018#include "lldb/DataFormatters/ValueObjectPrinter.h"
Sean Callanane33724f2015-09-03 00:35:46 +000019#include "lldb/../../source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000020#include "lldb/Expression/ClangUserExpression.h"
Stephen Wilsonebb84b22010-07-23 21:47:22 +000021#include "lldb/Expression/ClangFunction.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Expression/DWARFExpression.h"
23#include "lldb/Host/Host.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000024#include "lldb/Host/StringConvert.h"
Sean Callananebf77072010-07-23 00:16:21 +000025#include "lldb/Core/Debugger.h"
Greg Clayton66111032010-06-23 01:19:29 +000026#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Interpreter/CommandReturnObject.h"
Jim Ingham0e0984e2015-09-02 01:06:46 +000028#include "lldb/Target/Language.h"
Jim Ingham6c68fb42010-09-30 00:54:27 +000029#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Symbol/ObjectFile.h"
31#include "lldb/Symbol/Variable.h"
32#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000033#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Target/Target.h"
Greg Clayton7260f622011-04-18 08:33:37 +000035#include "lldb/Target/Thread.h"
Saleem Abdulrasool28606952014-06-27 05:17:41 +000036#include "llvm/ADT/STLExtras.h"
Sean Callananebf77072010-07-23 00:16:21 +000037#include "llvm/ADT/StringRef.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038
39using namespace lldb;
40using namespace lldb_private;
41
Greg Clayton1deb7962011-10-25 06:44:01 +000042CommandObjectExpression::CommandOptions::CommandOptions () :
43 OptionGroup()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044{
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045}
46
47
48CommandObjectExpression::CommandOptions::~CommandOptions ()
49{
50}
51
Enrico Granata4d93b8c2013-09-30 19:11:51 +000052static OptionEnumValueElement g_description_verbosity_type[] =
53{
54 { eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"},
55 { eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", "Show the full output, including persistent variable's name and type"},
56 { 0, NULL, NULL }
57};
58
Greg Clayton1deb7962011-10-25 06:44:01 +000059OptionDefinition
60CommandObjectExpression::CommandOptions::g_option_table[] =
61{
Zachary Turnerd37221d2014-07-09 16:31:49 +000062 { 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."},
63 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
64 { 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."},
65 { 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)."},
66 { 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)."},
Dawn Perchik15663c52015-07-25 00:19:39 +000067 { 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." },
Zachary Turnerd37221d2014-07-09 16:31:49 +000068 { 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."},
Greg Clayton1deb7962011-10-25 06:44:01 +000069};
70
71
72uint32_t
73CommandObjectExpression::CommandOptions::GetNumDefinitions ()
74{
Saleem Abdulrasool28606952014-06-27 05:17:41 +000075 return llvm::array_lengthof(g_option_table);
Greg Clayton1deb7962011-10-25 06:44:01 +000076}
77
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078Error
Greg Clayton1deb7962011-10-25 06:44:01 +000079CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
80 uint32_t option_idx,
81 const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082{
83 Error error;
84
Greg Clayton3bcdfc02012-12-04 00:32:51 +000085 const int short_option = g_option_table[option_idx].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000086
87 switch (short_option)
88 {
Dawn Perchik15663c52015-07-25 00:19:39 +000089 case 'l':
Jim Ingham0e0984e2015-09-02 01:06:46 +000090 language = Language::GetLanguageTypeFromString (option_arg);
Dawn Perchik15663c52015-07-25 00:19:39 +000091 if (language == eLanguageTypeUnknown)
92 error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", option_arg);
93 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000094
Jim Ingham35e1bda2012-10-16 21:41:58 +000095 case 'a':
96 {
97 bool success;
98 bool result;
99 result = Args::StringToBoolean(option_arg, true, &success);
100 if (!success)
101 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
102 else
103 try_all_threads = result;
104 }
Jim Ingham6c68fb42010-09-30 00:54:27 +0000105 break;
Jim Ingham399f1ca2010-11-05 19:25:48 +0000106
Jim Ingham184e9812013-01-15 02:47:48 +0000107 case 'i':
108 {
109 bool success;
110 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
111 if (success)
112 ignore_breakpoints = tmp_value;
113 else
114 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
115 break;
116 }
Jim Ingham35e1bda2012-10-16 21:41:58 +0000117 case 't':
118 {
119 bool success;
120 uint32_t result;
Vince Harron5275aaa2015-01-15 20:08:35 +0000121 result = StringConvert::ToUInt32(option_arg, 0, 0, &success);
Jim Ingham35e1bda2012-10-16 21:41:58 +0000122 if (success)
123 timeout = result;
124 else
125 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
126 }
127 break;
128
Jim Ingham399f1ca2010-11-05 19:25:48 +0000129 case 'u':
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000130 {
131 bool success;
Jim Ingham184e9812013-01-15 02:47:48 +0000132 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
133 if (success)
134 unwind_on_error = tmp_value;
135 else
Greg Clayton86edbf42011-10-26 00:56:27 +0000136 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000137 break;
138 }
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000139
140 case 'v':
141 if (!option_arg)
142 {
143 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
144 break;
145 }
146 m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
147 if (!error.Success())
148 error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
149 break;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000150
151 case 'g':
152 debug = true;
153 unwind_on_error = false;
154 ignore_breakpoints = false;
155 break;
156
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000158 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159 break;
160 }
161
162 return error;
163}
164
165void
Greg Clayton1deb7962011-10-25 06:44:01 +0000166CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167{
Jim Ingham184e9812013-01-15 02:47:48 +0000168 Process *process = interpreter.GetExecutionContext().GetProcessPtr();
169 if (process != NULL)
170 {
171 ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
172 unwind_on_error = process->GetUnwindOnErrorInExpressions();
173 }
174 else
175 {
Greg Claytonfc03f8f2014-03-25 18:47:07 +0000176 ignore_breakpoints = true;
Jim Ingham184e9812013-01-15 02:47:48 +0000177 unwind_on_error = true;
178 }
179
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180 show_summary = true;
Jim Ingham35e1bda2012-10-16 21:41:58 +0000181 try_all_threads = true;
182 timeout = 0;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000183 debug = false;
Dawn Perchik15663c52015-07-25 00:19:39 +0000184 language = eLanguageTypeUnknown;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000185 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186}
187
Greg Claytone0d378b2011-03-24 21:19:54 +0000188const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000189CommandObjectExpression::CommandOptions::GetDefinitions ()
190{
191 return g_option_table;
192}
193
Greg Claytona7015092010-09-18 01:14:36 +0000194CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000195 CommandObjectRaw (interpreter,
196 "expression",
Dawn Perchik15663c52015-07-25 00:19:39 +0000197 "Evaluate an expression in the current program context, using user defined variables and variables currently in scope.",
Jim Ingham5a988412012-06-08 21:56:10 +0000198 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +0000199 eCommandProcessMustBePaused | eCommandTryTargetAPILock),
Greg Clayton44d93782014-01-27 23:43:24 +0000200 IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
Greg Clayton1deb7962011-10-25 06:44:01 +0000201 m_option_group (interpreter),
202 m_format_options (eFormatDefault),
203 m_command_options (),
Johnny Chenf7edb1c2010-09-30 18:30:25 +0000204 m_expr_line_count (0),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205 m_expr_lines ()
206{
Kate Stoneea671fb2015-07-14 05:48:36 +0000207 SetHelpLong(
208R"(
209Timeouts:
210
211)" " If the expression can be evaluated statically (without running code) then it will be. \
212Otherwise, by default the expression will run on the current thread with a short timeout: \
213currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted \
214and resumed with all threads running. You can use the -a option to disable retrying on all \
215threads. You can use the -t option to set a shorter timeout." R"(
216
217User defined variables:
218
219)" " You can define your own variables for convenience or to be used in subsequent expressions. \
220You define them the same way you would define variables in C. If the first character of \
221your user defined variable is a $, then the variable's value will be available in future \
222expressions, otherwise it will just be available in the current expression." R"(
223
224Continuing evaluation after a breakpoint:
225
226)" " If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \
227you are done with your investigation, you can either remove the expression execution frames \
228from the stack with \"thread return -x\" or if you are still interested in the expression result \
229you can issue the \"continue\" command and the expression evaluation will complete and the \
230expression result will be available using the \"thread.completed-expression\" key in the thread \
231format." R"(
232
233Examples:
234
235 expr my_struct->a = my_array[3]
236 expr -f bin -- (index * 8) + 5
237 expr unsigned int $foo = 5
238 expr char c[] = \"foo\"; c[0])"
239 );
Caroline Tice405fe672010-10-04 22:28:36 +0000240
241 CommandArgumentEntry arg;
242 CommandArgumentData expression_arg;
243
244 // Define the first (and only) variant of this arg.
245 expression_arg.arg_type = eArgTypeExpression;
246 expression_arg.arg_repetition = eArgRepeatPlain;
247
248 // There is only one variant this argument could be; put it into the argument entry.
249 arg.push_back (expression_arg);
250
251 // Push the data for the first argument into the m_arguments vector.
252 m_arguments.push_back (arg);
Greg Clayton1deb7962011-10-25 06:44:01 +0000253
Greg Clayton5009f9d2011-10-27 17:55:14 +0000254 // Add the "--format" and "--gdb-format"
255 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
Greg Clayton1deb7962011-10-25 06:44:01 +0000256 m_option_group.Append (&m_command_options);
Enrico Granatab576bba2013-01-09 20:12:53 +0000257 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
Greg Clayton1deb7962011-10-25 06:44:01 +0000258 m_option_group.Finalize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259}
260
261CommandObjectExpression::~CommandObjectExpression ()
262{
263}
264
265Options *
266CommandObjectExpression::GetOptions ()
267{
Greg Clayton1deb7962011-10-25 06:44:01 +0000268 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269}
270
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271bool
Greg Clayton1d3afba2010-10-05 00:00:42 +0000272CommandObjectExpression::EvaluateExpression
273(
274 const char *expr,
Caroline Tice6e8dc332011-06-13 20:20:29 +0000275 Stream *output_stream,
276 Stream *error_stream,
Greg Clayton1d3afba2010-10-05 00:00:42 +0000277 CommandReturnObject *result
278)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279{
Greg Claytonba7b8e22013-01-26 23:54:29 +0000280 // Don't use m_exe_ctx as this might be called asynchronously
281 // after the command object DoExecute has finished when doing
282 // multi-line expression that use an input reader...
283 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
284
285 Target *target = exe_ctx.GetTargetPtr();
Sean Callananc0a6e062011-10-27 21:22:25 +0000286
287 if (!target)
Jim Ingham893c9322014-11-22 01:42:44 +0000288 target = GetDummyTarget();
Sean Callananc0a6e062011-10-27 21:22:25 +0000289
Greg Claytonc14ee322011-09-22 04:58:26 +0000290 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000292 lldb::ValueObjectSP result_valobj_sp;
Greg Clayton32c40852010-10-06 03:09:11 +0000293
Sean Callanan92adcac2011-01-13 08:53:35 +0000294 bool keep_in_memory = true;
Enrico Granatab576bba2013-01-09 20:12:53 +0000295
Jim Ingham35e1bda2012-10-16 21:41:58 +0000296 EvaluateExpressionOptions options;
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000297 options.SetCoerceToId(m_varobj_options.use_objc);
298 options.SetUnwindOnError(m_command_options.unwind_on_error);
299 options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
300 options.SetKeepInMemory(keep_in_memory);
301 options.SetUseDynamic(m_varobj_options.use_dynamic);
302 options.SetTryAllThreads(m_command_options.try_all_threads);
303 options.SetDebug(m_command_options.debug);
Greg Clayton62afb9f2013-11-04 19:35:17 +0000304
Dawn Perchik15663c52015-07-25 00:19:39 +0000305 // If the language was not specified, set it from target's properties
306 if (m_command_options.language != eLanguageTypeUnknown)
307 options.SetLanguage(m_command_options.language);
308 else
309 options.SetLanguage(target->GetLanguage());
310
Greg Clayton23f8c952014-03-24 23:10:19 +0000311 // If there is any chance we are going to stop and want to see
312 // what went wrong with our expression, we should generate debug info
313 if (!m_command_options.ignore_breakpoints ||
314 !m_command_options.unwind_on_error)
315 options.SetGenerateDebugInfo(true);
316
Greg Clayton62afb9f2013-11-04 19:35:17 +0000317 if (m_command_options.timeout > 0)
318 options.SetTimeoutUsec(m_command_options.timeout);
Jim Ingham6f78f382014-01-17 20:09:23 +0000319 else
320 options.SetTimeoutUsec(0);
Arnaud A. de Grandmaison62e5f4d2014-03-22 20:23:26 +0000321
322 target->EvaluateExpression(expr, exe_ctx.GetFramePtr(),
323 result_valobj_sp, options);
Sean Callanan4b388c92013-07-30 19:54:09 +0000324
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000325 if (result_valobj_sp)
326 {
Sean Callananbf154da2012-08-08 17:35:10 +0000327 Format format = m_format_options.GetFormat();
328
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000329 if (result_valobj_sp->GetError().Success())
330 {
Sean Callananbf154da2012-08-08 17:35:10 +0000331 if (format != eFormatVoid)
332 {
333 if (format != eFormatDefault)
334 result_valobj_sp->SetFormat (format);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000335
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000336 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
Enrico Granatab576bba2013-01-09 20:12:53 +0000337
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000338 result_valobj_sp->Dump(*output_stream,options);
339
Sean Callananbf154da2012-08-08 17:35:10 +0000340 if (result)
341 result->SetStatus (eReturnStatusSuccessFinishResult);
342 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000343 }
344 else
345 {
Sean Callananbccce812011-08-23 21:20:51 +0000346 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
Greg Clayton5fd05902011-06-24 22:31:10 +0000347 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000348 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
Sean Callananbf154da2012-08-08 17:35:10 +0000349 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000350 error_stream->PutCString("(void)\n");
Sean Callananbf154da2012-08-08 17:35:10 +0000351 }
Sean Callananbcf897f2012-08-09 18:18:47 +0000352
353 if (result)
354 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Clayton5fd05902011-06-24 22:31:10 +0000355 }
356 else
357 {
Sean Callananbccce812011-08-23 21:20:51 +0000358 const char *error_cstr = result_valobj_sp->GetError().AsCString();
359 if (error_cstr && error_cstr[0])
360 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000361 const size_t error_cstr_len = strlen (error_cstr);
Sean Callananbccce812011-08-23 21:20:51 +0000362 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
363 if (strstr(error_cstr, "error:") != error_cstr)
364 error_stream->PutCString ("error: ");
365 error_stream->Write(error_cstr, error_cstr_len);
366 if (!ends_with_newline)
367 error_stream->EOL();
368 }
369 else
370 {
371 error_stream->PutCString ("error: unknown error\n");
372 }
373
374 if (result)
375 result->SetStatus (eReturnStatusFailed);
Greg Clayton5fd05902011-06-24 22:31:10 +0000376 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000377 }
378 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000379 }
380 else
381 {
Caroline Tice6e8dc332011-06-13 20:20:29 +0000382 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000383 return false;
Sean Callananebf77072010-07-23 00:16:21 +0000384 }
Sean Callanand1e5b432010-08-12 01:56:52 +0000385
Sean Callananebf77072010-07-23 00:16:21 +0000386 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387}
388
Greg Clayton44d93782014-01-27 23:43:24 +0000389void
Greg Clayton44d93782014-01-27 23:43:24 +0000390CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
391{
392 io_handler.SetIsDone(true);
393// StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
394// StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
395 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
396 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
397
398 EvaluateExpression (line.c_str(),
399 output_sp.get(),
400 error_sp.get());
401 if (output_sp)
402 output_sp->Flush();
403 if (error_sp)
404 error_sp->Flush();
405}
406
407LineStatus
408CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
409 StringList &lines,
410 uint32_t line_idx,
411 Error &error)
412{
413 if (line_idx == UINT32_MAX)
414 {
415 // Remove the last line from "lines" so it doesn't appear
416 // in our final expression
417 lines.PopBack();
418 error.Clear();
419 return LineStatus::Done;
420 }
421 else if (line_idx + 1 == lines.GetSize())
422 {
423 // The last line was edited, if this line is empty, then we are done
424 // getting our multiple lines.
425 if (lines[line_idx].empty())
426 return LineStatus::Done;
427 }
428 return LineStatus::Success;
429}
430
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000431void
432CommandObjectExpression::GetMultilineExpression ()
433{
434 m_expr_lines.clear();
435 m_expr_line_count = 0;
436
437 Debugger &debugger = GetCommandInterpreter().GetDebugger();
Kate Stonee30f11d2014-11-17 19:06:59 +0000438 bool color_prompt = debugger.GetUseColor();
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000439 const bool multiple_lines = true; // Get multiple lines
440 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
Kate Stonee30f11d2014-11-17 19:06:59 +0000441 IOHandler::Type::Expression,
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000442 "lldb-expr", // Name of input reader for history
443 NULL, // No prompt
Kate Stonee30f11d2014-11-17 19:06:59 +0000444 NULL, // Continuation prompt
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000445 multiple_lines,
Kate Stonee30f11d2014-11-17 19:06:59 +0000446 color_prompt,
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000447 1, // Show line numbers starting at 1
448 *this));
449
450 StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
451 if (output_sp)
452 {
453 output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
454 output_sp->Flush();
455 }
456 debugger.PushIOHandler(io_handler_sp);
457}
458
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459bool
Jim Ingham5a988412012-06-08 21:56:10 +0000460CommandObjectExpression::DoExecute
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461(
462 const char *command,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463 CommandReturnObject &result
464)
465{
Greg Clayton1deb7962011-10-25 06:44:01 +0000466 m_option_group.NotifyOptionParsingStarting();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467
468 const char * expr = NULL;
469
470 if (command[0] == '\0')
471 {
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000472 GetMultilineExpression ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000473 return result.Succeeded();
474 }
475
476 if (command[0] == '-')
477 {
478 // We have some options and these options MUST end with --.
479 const char *end_options = NULL;
480 const char *s = command;
481 while (s && s[0])
482 {
483 end_options = ::strstr (s, "--");
484 if (end_options)
485 {
486 end_options += 2; // Get past the "--"
487 if (::isspace (end_options[0]))
488 {
489 expr = end_options;
490 while (::isspace (*expr))
491 ++expr;
492 break;
493 }
494 }
495 s = end_options;
496 }
497
498 if (end_options)
499 {
Pavel Labath00b7f952015-03-02 12:46:22 +0000500 Args args (llvm::StringRef(command, end_options - command));
Greg Claytona7015092010-09-18 01:14:36 +0000501 if (!ParseOptions (args, result))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000502 return false;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000503
Greg Clayton1deb7962011-10-25 06:44:01 +0000504 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Claytonf6b8b582011-04-13 00:18:08 +0000505 if (error.Fail())
506 {
507 result.AppendError (error.AsCString());
508 result.SetStatus (eReturnStatusFailed);
509 return false;
510 }
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000511
512 // No expression following options
Greg Clayton05da458c2014-03-13 23:48:40 +0000513 if (expr == NULL || expr[0] == '\0')
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000514 {
515 GetMultilineExpression ();
516 return result.Succeeded();
517 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518 }
519 }
520
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521 if (expr == NULL)
522 expr = command;
Sean Callanan16ad5fa2010-06-24 00:16:27 +0000523
Caroline Tice6e8dc332011-06-13 20:20:29 +0000524 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Johnny Chenfcd43b72010-08-13 00:42:30 +0000525 return true;
526
527 result.SetStatus (eReturnStatusFailed);
528 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529}
530