blob: 1d385eadf0b61cae06b5b31f875a1645d6783784 [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "CommandObjectExpression.h"
13
14// C Includes
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/Value.h"
Jim Ingham6c68fb42010-09-30 00:54:27 +000019#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000020#include "lldb/DataFormatters/ValueObjectPrinter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Expression/ClangExpressionVariable.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000022#include "lldb/Expression/ClangUserExpression.h"
Stephen Wilsonebb84b22010-07-23 21:47:22 +000023#include "lldb/Expression/ClangFunction.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Expression/DWARFExpression.h"
25#include "lldb/Host/Host.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000026#include "lldb/Host/StringConvert.h"
Sean Callananebf77072010-07-23 00:16:21 +000027#include "lldb/Core/Debugger.h"
Greg Clayton66111032010-06-23 01:19:29 +000028#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Interpreter/CommandReturnObject.h"
Jim Ingham6c68fb42010-09-30 00:54:27 +000030#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Symbol/ObjectFile.h"
32#include "lldb/Symbol/Variable.h"
33#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000034#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Target/Target.h"
Greg Clayton7260f622011-04-18 08:33:37 +000036#include "lldb/Target/Thread.h"
Saleem Abdulrasool28606952014-06-27 05:17:41 +000037#include "llvm/ADT/STLExtras.h"
Sean Callananebf77072010-07-23 00:16:21 +000038#include "llvm/ADT/StringRef.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039
40using namespace lldb;
41using namespace lldb_private;
42
Greg Clayton1deb7962011-10-25 06:44:01 +000043CommandObjectExpression::CommandOptions::CommandOptions () :
44 OptionGroup()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045{
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046}
47
48
49CommandObjectExpression::CommandOptions::~CommandOptions ()
50{
51}
52
Enrico Granata4d93b8c2013-09-30 19:11:51 +000053static OptionEnumValueElement g_description_verbosity_type[] =
54{
55 { eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"},
56 { eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", "Show the full output, including persistent variable's name and type"},
57 { 0, NULL, NULL }
58};
59
Greg Clayton1deb7962011-10-25 06:44:01 +000060OptionDefinition
61CommandObjectExpression::CommandOptions::g_option_table[] =
62{
Zachary Turnerd37221d2014-07-09 16:31:49 +000063 { 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."},
64 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
65 { 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."},
66 { 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)."},
67 { 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)."},
68 { 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 {
Caroline Tice3f4c09c2010-09-07 22:38:08 +000089 //case 'l':
90 //if (language.SetLanguageFromCString (option_arg) == false)
91 //{
Greg Clayton86edbf42011-10-26 00:56:27 +000092 // error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
Caroline Tice3f4c09c2010-09-07 22:38:08 +000093 //}
94 //break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095
Jim Ingham35e1bda2012-10-16 21:41:58 +000096 case 'a':
97 {
98 bool success;
99 bool result;
100 result = Args::StringToBoolean(option_arg, true, &success);
101 if (!success)
102 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
103 else
104 try_all_threads = result;
105 }
Jim Ingham6c68fb42010-09-30 00:54:27 +0000106 break;
Jim Ingham399f1ca2010-11-05 19:25:48 +0000107
Jim Ingham184e9812013-01-15 02:47:48 +0000108 case 'i':
109 {
110 bool success;
111 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
112 if (success)
113 ignore_breakpoints = tmp_value;
114 else
115 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
116 break;
117 }
Jim Ingham35e1bda2012-10-16 21:41:58 +0000118 case 't':
119 {
120 bool success;
121 uint32_t result;
Vince Harron5275aaa2015-01-15 20:08:35 +0000122 result = StringConvert::ToUInt32(option_arg, 0, 0, &success);
Jim Ingham35e1bda2012-10-16 21:41:58 +0000123 if (success)
124 timeout = result;
125 else
126 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
127 }
128 break;
129
Jim Ingham399f1ca2010-11-05 19:25:48 +0000130 case 'u':
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000131 {
132 bool success;
Jim Ingham184e9812013-01-15 02:47:48 +0000133 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
134 if (success)
135 unwind_on_error = tmp_value;
136 else
Greg Clayton86edbf42011-10-26 00:56:27 +0000137 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000138 break;
139 }
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000140
141 case 'v':
142 if (!option_arg)
143 {
144 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
145 break;
146 }
147 m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
148 if (!error.Success())
149 error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
150 break;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000151
152 case 'g':
153 debug = true;
154 unwind_on_error = false;
155 ignore_breakpoints = false;
156 break;
157
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000159 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000160 break;
161 }
162
163 return error;
164}
165
166void
Greg Clayton1deb7962011-10-25 06:44:01 +0000167CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000168{
Jim Ingham184e9812013-01-15 02:47:48 +0000169 Process *process = interpreter.GetExecutionContext().GetProcessPtr();
170 if (process != NULL)
171 {
172 ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
173 unwind_on_error = process->GetUnwindOnErrorInExpressions();
174 }
175 else
176 {
Greg Claytonfc03f8f2014-03-25 18:47:07 +0000177 ignore_breakpoints = true;
Jim Ingham184e9812013-01-15 02:47:48 +0000178 unwind_on_error = true;
179 }
180
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181 show_summary = true;
Jim Ingham35e1bda2012-10-16 21:41:58 +0000182 try_all_threads = true;
183 timeout = 0;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000184 debug = false;
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",
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000197 "Evaluate a C/ObjC/C++ 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{
207 SetHelpLong(
Jim Ingham35e1bda2012-10-16 21:41:58 +0000208"Timeouts:\n\
Bruce Mitchenerd93c4a32014-07-01 21:22:11 +0000209 If the expression can be evaluated statically (without running code) then it will be.\n\
Jim Ingham35e1bda2012-10-16 21:41:58 +0000210 Otherwise, by default the expression will run on the current thread with a short timeout:\n\
211 currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted\n\
212 and resumed with all threads running. You can use the -a option to disable retrying on all\n\
213 threads. You can use the -t option to set a shorter timeout.\n\
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000214\n\
215User defined variables:\n\
216 You can define your own variables for convenience or to be used in subsequent expressions.\n\
217 You define them the same way you would define variables in C. If the first character of \n\
218 your user defined variable is a $, then the variable's value will be available in future\n\
219 expressions, otherwise it will just be available in the current expression.\n\
220\n\
Jim Inghamc60b6ea2014-07-08 19:27:35 +0000221\n\
222Continuing evaluation after a breakpoint:\n\
223 If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once\n\
224 you are done with your investigation, you can either remove the expression execution frames\n\
225 from the stack with \"thread return -x\" or if you are still interested in the expression result\n\
226 you can issue the \"continue\" command and the expression evaluation will complete and the\n\
227 expression result will be available using the \"thread.completed-expression\" key in the thread\n\
228 format.\n\
229\n\
Jim Ingham35e1bda2012-10-16 21:41:58 +0000230Examples: \n\
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000231\n\
232 expr my_struct->a = my_array[3] \n\
233 expr -f bin -- (index * 8) + 5 \n\
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000234 expr unsigned int $foo = 5\n\
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235 expr char c[] = \"foo\"; c[0]\n");
Caroline Tice405fe672010-10-04 22:28:36 +0000236
237 CommandArgumentEntry arg;
238 CommandArgumentData expression_arg;
239
240 // Define the first (and only) variant of this arg.
241 expression_arg.arg_type = eArgTypeExpression;
242 expression_arg.arg_repetition = eArgRepeatPlain;
243
244 // There is only one variant this argument could be; put it into the argument entry.
245 arg.push_back (expression_arg);
246
247 // Push the data for the first argument into the m_arguments vector.
248 m_arguments.push_back (arg);
Greg Clayton1deb7962011-10-25 06:44:01 +0000249
Greg Clayton5009f9d2011-10-27 17:55:14 +0000250 // Add the "--format" and "--gdb-format"
251 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 +0000252 m_option_group.Append (&m_command_options);
Enrico Granatab576bba2013-01-09 20:12:53 +0000253 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 +0000254 m_option_group.Finalize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255}
256
257CommandObjectExpression::~CommandObjectExpression ()
258{
259}
260
261Options *
262CommandObjectExpression::GetOptions ()
263{
Greg Clayton1deb7962011-10-25 06:44:01 +0000264 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265}
266
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267bool
Greg Clayton1d3afba2010-10-05 00:00:42 +0000268CommandObjectExpression::EvaluateExpression
269(
270 const char *expr,
Caroline Tice6e8dc332011-06-13 20:20:29 +0000271 Stream *output_stream,
272 Stream *error_stream,
Greg Clayton1d3afba2010-10-05 00:00:42 +0000273 CommandReturnObject *result
274)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275{
Greg Claytonba7b8e22013-01-26 23:54:29 +0000276 // Don't use m_exe_ctx as this might be called asynchronously
277 // after the command object DoExecute has finished when doing
278 // multi-line expression that use an input reader...
279 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
280
281 Target *target = exe_ctx.GetTargetPtr();
Sean Callananc0a6e062011-10-27 21:22:25 +0000282
283 if (!target)
Jim Ingham893c9322014-11-22 01:42:44 +0000284 target = GetDummyTarget();
Sean Callananc0a6e062011-10-27 21:22:25 +0000285
Greg Claytonc14ee322011-09-22 04:58:26 +0000286 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000287 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000288 lldb::ValueObjectSP result_valobj_sp;
Greg Clayton32c40852010-10-06 03:09:11 +0000289
Sean Callanan92adcac2011-01-13 08:53:35 +0000290 bool keep_in_memory = true;
Enrico Granatab576bba2013-01-09 20:12:53 +0000291
Jim Ingham35e1bda2012-10-16 21:41:58 +0000292 EvaluateExpressionOptions options;
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000293 options.SetCoerceToId(m_varobj_options.use_objc);
294 options.SetUnwindOnError(m_command_options.unwind_on_error);
295 options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
296 options.SetKeepInMemory(keep_in_memory);
297 options.SetUseDynamic(m_varobj_options.use_dynamic);
298 options.SetTryAllThreads(m_command_options.try_all_threads);
299 options.SetDebug(m_command_options.debug);
Greg Clayton62afb9f2013-11-04 19:35:17 +0000300
Greg Clayton23f8c952014-03-24 23:10:19 +0000301 // If there is any chance we are going to stop and want to see
302 // what went wrong with our expression, we should generate debug info
303 if (!m_command_options.ignore_breakpoints ||
304 !m_command_options.unwind_on_error)
305 options.SetGenerateDebugInfo(true);
306
Greg Clayton62afb9f2013-11-04 19:35:17 +0000307 if (m_command_options.timeout > 0)
308 options.SetTimeoutUsec(m_command_options.timeout);
Jim Ingham6f78f382014-01-17 20:09:23 +0000309 else
310 options.SetTimeoutUsec(0);
Arnaud A. de Grandmaison62e5f4d2014-03-22 20:23:26 +0000311
312 target->EvaluateExpression(expr, exe_ctx.GetFramePtr(),
313 result_valobj_sp, options);
Sean Callanan4b388c92013-07-30 19:54:09 +0000314
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000315 if (result_valobj_sp)
316 {
Sean Callananbf154da2012-08-08 17:35:10 +0000317 Format format = m_format_options.GetFormat();
318
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000319 if (result_valobj_sp->GetError().Success())
320 {
Sean Callananbf154da2012-08-08 17:35:10 +0000321 if (format != eFormatVoid)
322 {
323 if (format != eFormatDefault)
324 result_valobj_sp->SetFormat (format);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000325
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000326 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
Enrico Granatab576bba2013-01-09 20:12:53 +0000327
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000328 result_valobj_sp->Dump(*output_stream,options);
329
Sean Callananbf154da2012-08-08 17:35:10 +0000330 if (result)
331 result->SetStatus (eReturnStatusSuccessFinishResult);
332 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000333 }
334 else
335 {
Sean Callananbccce812011-08-23 21:20:51 +0000336 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
Greg Clayton5fd05902011-06-24 22:31:10 +0000337 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000338 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
Sean Callananbf154da2012-08-08 17:35:10 +0000339 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000340 error_stream->PutCString("(void)\n");
Sean Callananbf154da2012-08-08 17:35:10 +0000341 }
Sean Callananbcf897f2012-08-09 18:18:47 +0000342
343 if (result)
344 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Clayton5fd05902011-06-24 22:31:10 +0000345 }
346 else
347 {
Sean Callananbccce812011-08-23 21:20:51 +0000348 const char *error_cstr = result_valobj_sp->GetError().AsCString();
349 if (error_cstr && error_cstr[0])
350 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000351 const size_t error_cstr_len = strlen (error_cstr);
Sean Callananbccce812011-08-23 21:20:51 +0000352 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
353 if (strstr(error_cstr, "error:") != error_cstr)
354 error_stream->PutCString ("error: ");
355 error_stream->Write(error_cstr, error_cstr_len);
356 if (!ends_with_newline)
357 error_stream->EOL();
358 }
359 else
360 {
361 error_stream->PutCString ("error: unknown error\n");
362 }
363
364 if (result)
365 result->SetStatus (eReturnStatusFailed);
Greg Clayton5fd05902011-06-24 22:31:10 +0000366 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000367 }
368 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000369 }
370 else
371 {
Caroline Tice6e8dc332011-06-13 20:20:29 +0000372 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000373 return false;
Sean Callananebf77072010-07-23 00:16:21 +0000374 }
Sean Callanand1e5b432010-08-12 01:56:52 +0000375
Sean Callananebf77072010-07-23 00:16:21 +0000376 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000377}
378
Greg Clayton44d93782014-01-27 23:43:24 +0000379void
Greg Clayton44d93782014-01-27 23:43:24 +0000380CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
381{
382 io_handler.SetIsDone(true);
383// StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
384// StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
385 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
386 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
387
388 EvaluateExpression (line.c_str(),
389 output_sp.get(),
390 error_sp.get());
391 if (output_sp)
392 output_sp->Flush();
393 if (error_sp)
394 error_sp->Flush();
395}
396
397LineStatus
398CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
399 StringList &lines,
400 uint32_t line_idx,
401 Error &error)
402{
403 if (line_idx == UINT32_MAX)
404 {
405 // Remove the last line from "lines" so it doesn't appear
406 // in our final expression
407 lines.PopBack();
408 error.Clear();
409 return LineStatus::Done;
410 }
411 else if (line_idx + 1 == lines.GetSize())
412 {
413 // The last line was edited, if this line is empty, then we are done
414 // getting our multiple lines.
415 if (lines[line_idx].empty())
416 return LineStatus::Done;
417 }
418 return LineStatus::Success;
419}
420
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000421void
422CommandObjectExpression::GetMultilineExpression ()
423{
424 m_expr_lines.clear();
425 m_expr_line_count = 0;
426
427 Debugger &debugger = GetCommandInterpreter().GetDebugger();
Kate Stonee30f11d2014-11-17 19:06:59 +0000428 bool color_prompt = debugger.GetUseColor();
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000429 const bool multiple_lines = true; // Get multiple lines
430 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
Kate Stonee30f11d2014-11-17 19:06:59 +0000431 IOHandler::Type::Expression,
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000432 "lldb-expr", // Name of input reader for history
433 NULL, // No prompt
Kate Stonee30f11d2014-11-17 19:06:59 +0000434 NULL, // Continuation prompt
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000435 multiple_lines,
Kate Stonee30f11d2014-11-17 19:06:59 +0000436 color_prompt,
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000437 1, // Show line numbers starting at 1
438 *this));
439
440 StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
441 if (output_sp)
442 {
443 output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
444 output_sp->Flush();
445 }
446 debugger.PushIOHandler(io_handler_sp);
447}
448
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000449bool
Jim Ingham5a988412012-06-08 21:56:10 +0000450CommandObjectExpression::DoExecute
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451(
452 const char *command,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453 CommandReturnObject &result
454)
455{
Greg Clayton1deb7962011-10-25 06:44:01 +0000456 m_option_group.NotifyOptionParsingStarting();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457
458 const char * expr = NULL;
459
460 if (command[0] == '\0')
461 {
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000462 GetMultilineExpression ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463 return result.Succeeded();
464 }
465
466 if (command[0] == '-')
467 {
468 // We have some options and these options MUST end with --.
469 const char *end_options = NULL;
470 const char *s = command;
471 while (s && s[0])
472 {
473 end_options = ::strstr (s, "--");
474 if (end_options)
475 {
476 end_options += 2; // Get past the "--"
477 if (::isspace (end_options[0]))
478 {
479 expr = end_options;
480 while (::isspace (*expr))
481 ++expr;
482 break;
483 }
484 }
485 s = end_options;
486 }
487
488 if (end_options)
489 {
Pavel Labath00b7f952015-03-02 12:46:22 +0000490 Args args (llvm::StringRef(command, end_options - command));
Greg Claytona7015092010-09-18 01:14:36 +0000491 if (!ParseOptions (args, result))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492 return false;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000493
Greg Clayton1deb7962011-10-25 06:44:01 +0000494 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Claytonf6b8b582011-04-13 00:18:08 +0000495 if (error.Fail())
496 {
497 result.AppendError (error.AsCString());
498 result.SetStatus (eReturnStatusFailed);
499 return false;
500 }
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000501
502 // No expression following options
Greg Clayton05da458c2014-03-13 23:48:40 +0000503 if (expr == NULL || expr[0] == '\0')
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000504 {
505 GetMultilineExpression ();
506 return result.Succeeded();
507 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000508 }
509 }
510
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511 if (expr == NULL)
512 expr = command;
Sean Callanan16ad5fa2010-06-24 00:16:27 +0000513
Caroline Tice6e8dc332011-06-13 20:20:29 +0000514 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Johnny Chenfcd43b72010-08-13 00:42:30 +0000515 return true;
516
517 result.SetStatus (eReturnStatusFailed);
518 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519}
520