blob: 28fd322109e797031ca06c3d4c5cfa002bf21db0 [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
Sean Callananebf77072010-07-23 00:16:21 +000018#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/Value.h"
Jim Ingham6c68fb42010-09-30 00:54:27 +000020#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000021#include "lldb/DataFormatters/ValueObjectPrinter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Expression/ClangExpressionVariable.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000023#include "lldb/Expression/ClangUserExpression.h"
Stephen Wilsonebb84b22010-07-23 21:47:22 +000024#include "lldb/Expression/ClangFunction.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Expression/DWARFExpression.h"
26#include "lldb/Host/Host.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"
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{
Virgile Belloe2607b52013-09-05 16:42:23 +000062 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, 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, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
64 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, 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, 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)."},
Greg Clayton62afb9f2013-11-04 19:35:17 +000066 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument , 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)."},
Enrico Granata4d93b8c2013-09-30 19:11:51 +000067 { LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, 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 +000068};
69
70
71uint32_t
72CommandObjectExpression::CommandOptions::GetNumDefinitions ()
73{
74 return sizeof(g_option_table)/sizeof(OptionDefinition);
75}
76
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077Error
Greg Clayton1deb7962011-10-25 06:44:01 +000078CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
79 uint32_t option_idx,
80 const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081{
82 Error error;
83
Greg Clayton3bcdfc02012-12-04 00:32:51 +000084 const int short_option = g_option_table[option_idx].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000085
86 switch (short_option)
87 {
Caroline Tice3f4c09c2010-09-07 22:38:08 +000088 //case 'l':
89 //if (language.SetLanguageFromCString (option_arg) == false)
90 //{
Greg Clayton86edbf42011-10-26 00:56:27 +000091 // error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
Caroline Tice3f4c09c2010-09-07 22:38:08 +000092 //}
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;
121 result = Args::StringToUInt32(option_arg, 0, 0, &success);
122 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;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000184 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185}
186
Greg Claytone0d378b2011-03-24 21:19:54 +0000187const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188CommandObjectExpression::CommandOptions::GetDefinitions ()
189{
190 return g_option_table;
191}
192
Greg Claytona7015092010-09-18 01:14:36 +0000193CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000194 CommandObjectRaw (interpreter,
195 "expression",
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000196 "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 +0000197 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000198 eFlagProcessMustBePaused | eFlagTryTargetAPILock),
Greg Clayton44d93782014-01-27 23:43:24 +0000199 IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
Greg Clayton1deb7962011-10-25 06:44:01 +0000200 m_option_group (interpreter),
201 m_format_options (eFormatDefault),
202 m_command_options (),
Johnny Chenf7edb1c2010-09-30 18:30:25 +0000203 m_expr_line_count (0),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204 m_expr_lines ()
205{
206 SetHelpLong(
Jim Ingham35e1bda2012-10-16 21:41:58 +0000207"Timeouts:\n\
208 If the expression can be evaluated statically (without runnning code) then it will be.\n\
209 Otherwise, by default the expression will run on the current thread with a short timeout:\n\
210 currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted\n\
211 and resumed with all threads running. You can use the -a option to disable retrying on all\n\
212 threads. You can use the -t option to set a shorter timeout.\n\
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000213\n\
214User defined variables:\n\
215 You can define your own variables for convenience or to be used in subsequent expressions.\n\
216 You define them the same way you would define variables in C. If the first character of \n\
217 your user defined variable is a $, then the variable's value will be available in future\n\
218 expressions, otherwise it will just be available in the current expression.\n\
219\n\
Jim Ingham35e1bda2012-10-16 21:41:58 +0000220Examples: \n\
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221\n\
222 expr my_struct->a = my_array[3] \n\
223 expr -f bin -- (index * 8) + 5 \n\
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000224 expr unsigned int $foo = 5\n\
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000225 expr char c[] = \"foo\"; c[0]\n");
Caroline Tice405fe672010-10-04 22:28:36 +0000226
227 CommandArgumentEntry arg;
228 CommandArgumentData expression_arg;
229
230 // Define the first (and only) variant of this arg.
231 expression_arg.arg_type = eArgTypeExpression;
232 expression_arg.arg_repetition = eArgRepeatPlain;
233
234 // There is only one variant this argument could be; put it into the argument entry.
235 arg.push_back (expression_arg);
236
237 // Push the data for the first argument into the m_arguments vector.
238 m_arguments.push_back (arg);
Greg Clayton1deb7962011-10-25 06:44:01 +0000239
Greg Clayton5009f9d2011-10-27 17:55:14 +0000240 // Add the "--format" and "--gdb-format"
241 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 +0000242 m_option_group.Append (&m_command_options);
Enrico Granatab576bba2013-01-09 20:12:53 +0000243 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 +0000244 m_option_group.Finalize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245}
246
247CommandObjectExpression::~CommandObjectExpression ()
248{
249}
250
251Options *
252CommandObjectExpression::GetOptions ()
253{
Greg Clayton1deb7962011-10-25 06:44:01 +0000254 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255}
256
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257bool
Greg Clayton1d3afba2010-10-05 00:00:42 +0000258CommandObjectExpression::EvaluateExpression
259(
260 const char *expr,
Caroline Tice6e8dc332011-06-13 20:20:29 +0000261 Stream *output_stream,
262 Stream *error_stream,
Greg Clayton1d3afba2010-10-05 00:00:42 +0000263 CommandReturnObject *result
264)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265{
Greg Claytonba7b8e22013-01-26 23:54:29 +0000266 // Don't use m_exe_ctx as this might be called asynchronously
267 // after the command object DoExecute has finished when doing
268 // multi-line expression that use an input reader...
269 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
270
271 Target *target = exe_ctx.GetTargetPtr();
Sean Callananc0a6e062011-10-27 21:22:25 +0000272
273 if (!target)
274 target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
275
Greg Claytonc14ee322011-09-22 04:58:26 +0000276 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000278 lldb::ValueObjectSP result_valobj_sp;
Greg Clayton32c40852010-10-06 03:09:11 +0000279
Sean Callanan92adcac2011-01-13 08:53:35 +0000280 bool keep_in_memory = true;
Enrico Granatab576bba2013-01-09 20:12:53 +0000281
Jim Ingham35e1bda2012-10-16 21:41:58 +0000282 EvaluateExpressionOptions options;
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000283 options.SetCoerceToId(m_varobj_options.use_objc);
284 options.SetUnwindOnError(m_command_options.unwind_on_error);
285 options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
286 options.SetKeepInMemory(keep_in_memory);
287 options.SetUseDynamic(m_varobj_options.use_dynamic);
288 options.SetTryAllThreads(m_command_options.try_all_threads);
289 options.SetDebug(m_command_options.debug);
Greg Clayton62afb9f2013-11-04 19:35:17 +0000290
Greg Clayton23f8c952014-03-24 23:10:19 +0000291 // If there is any chance we are going to stop and want to see
292 // what went wrong with our expression, we should generate debug info
293 if (!m_command_options.ignore_breakpoints ||
294 !m_command_options.unwind_on_error)
295 options.SetGenerateDebugInfo(true);
296
Greg Clayton62afb9f2013-11-04 19:35:17 +0000297 if (m_command_options.timeout > 0)
298 options.SetTimeoutUsec(m_command_options.timeout);
Jim Ingham6f78f382014-01-17 20:09:23 +0000299 else
300 options.SetTimeoutUsec(0);
Arnaud A. de Grandmaison62e5f4d2014-03-22 20:23:26 +0000301
302 target->EvaluateExpression(expr, exe_ctx.GetFramePtr(),
303 result_valobj_sp, options);
Sean Callanan4b388c92013-07-30 19:54:09 +0000304
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000305 if (result_valobj_sp)
306 {
Sean Callananbf154da2012-08-08 17:35:10 +0000307 Format format = m_format_options.GetFormat();
308
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000309 if (result_valobj_sp->GetError().Success())
310 {
Sean Callananbf154da2012-08-08 17:35:10 +0000311 if (format != eFormatVoid)
312 {
313 if (format != eFormatDefault)
314 result_valobj_sp->SetFormat (format);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000315
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000316 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
Enrico Granatab576bba2013-01-09 20:12:53 +0000317
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000318 result_valobj_sp->Dump(*output_stream,options);
319
Sean Callananbf154da2012-08-08 17:35:10 +0000320 if (result)
321 result->SetStatus (eReturnStatusSuccessFinishResult);
322 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000323 }
324 else
325 {
Sean Callananbccce812011-08-23 21:20:51 +0000326 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
Greg Clayton5fd05902011-06-24 22:31:10 +0000327 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000328 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
Sean Callananbf154da2012-08-08 17:35:10 +0000329 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000330 error_stream->PutCString("(void)\n");
Sean Callananbf154da2012-08-08 17:35:10 +0000331 }
Sean Callananbcf897f2012-08-09 18:18:47 +0000332
333 if (result)
334 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Clayton5fd05902011-06-24 22:31:10 +0000335 }
336 else
337 {
Sean Callananbccce812011-08-23 21:20:51 +0000338 const char *error_cstr = result_valobj_sp->GetError().AsCString();
339 if (error_cstr && error_cstr[0])
340 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000341 const size_t error_cstr_len = strlen (error_cstr);
Sean Callananbccce812011-08-23 21:20:51 +0000342 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
343 if (strstr(error_cstr, "error:") != error_cstr)
344 error_stream->PutCString ("error: ");
345 error_stream->Write(error_cstr, error_cstr_len);
346 if (!ends_with_newline)
347 error_stream->EOL();
348 }
349 else
350 {
351 error_stream->PutCString ("error: unknown error\n");
352 }
353
354 if (result)
355 result->SetStatus (eReturnStatusFailed);
Greg Clayton5fd05902011-06-24 22:31:10 +0000356 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000357 }
358 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000359 }
360 else
361 {
Caroline Tice6e8dc332011-06-13 20:20:29 +0000362 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000363 return false;
Sean Callananebf77072010-07-23 00:16:21 +0000364 }
Sean Callanand1e5b432010-08-12 01:56:52 +0000365
Sean Callananebf77072010-07-23 00:16:21 +0000366 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367}
368
Greg Clayton44d93782014-01-27 23:43:24 +0000369void
Greg Clayton44d93782014-01-27 23:43:24 +0000370CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
371{
372 io_handler.SetIsDone(true);
373// StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
374// StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
375 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
376 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
377
378 EvaluateExpression (line.c_str(),
379 output_sp.get(),
380 error_sp.get());
381 if (output_sp)
382 output_sp->Flush();
383 if (error_sp)
384 error_sp->Flush();
385}
386
387LineStatus
388CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
389 StringList &lines,
390 uint32_t line_idx,
391 Error &error)
392{
393 if (line_idx == UINT32_MAX)
394 {
395 // Remove the last line from "lines" so it doesn't appear
396 // in our final expression
397 lines.PopBack();
398 error.Clear();
399 return LineStatus::Done;
400 }
401 else if (line_idx + 1 == lines.GetSize())
402 {
403 // The last line was edited, if this line is empty, then we are done
404 // getting our multiple lines.
405 if (lines[line_idx].empty())
406 return LineStatus::Done;
407 }
408 return LineStatus::Success;
409}
410
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000411void
412CommandObjectExpression::GetMultilineExpression ()
413{
414 m_expr_lines.clear();
415 m_expr_line_count = 0;
416
417 Debugger &debugger = GetCommandInterpreter().GetDebugger();
418 const bool multiple_lines = true; // Get multiple lines
419 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
420 "lldb-expr", // Name of input reader for history
421 NULL, // No prompt
422 multiple_lines,
423 1, // Show line numbers starting at 1
424 *this));
425
426 StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
427 if (output_sp)
428 {
429 output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
430 output_sp->Flush();
431 }
432 debugger.PushIOHandler(io_handler_sp);
433}
434
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435bool
Jim Ingham5a988412012-06-08 21:56:10 +0000436CommandObjectExpression::DoExecute
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437(
438 const char *command,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439 CommandReturnObject &result
440)
441{
Greg Clayton1deb7962011-10-25 06:44:01 +0000442 m_option_group.NotifyOptionParsingStarting();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443
444 const char * expr = NULL;
445
446 if (command[0] == '\0')
447 {
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000448 GetMultilineExpression ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000449 return result.Succeeded();
450 }
451
452 if (command[0] == '-')
453 {
454 // We have some options and these options MUST end with --.
455 const char *end_options = NULL;
456 const char *s = command;
457 while (s && s[0])
458 {
459 end_options = ::strstr (s, "--");
460 if (end_options)
461 {
462 end_options += 2; // Get past the "--"
463 if (::isspace (end_options[0]))
464 {
465 expr = end_options;
466 while (::isspace (*expr))
467 ++expr;
468 break;
469 }
470 }
471 s = end_options;
472 }
473
474 if (end_options)
475 {
Greg Clayton66111032010-06-23 01:19:29 +0000476 Args args (command, end_options - command);
Greg Claytona7015092010-09-18 01:14:36 +0000477 if (!ParseOptions (args, result))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478 return false;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000479
Greg Clayton1deb7962011-10-25 06:44:01 +0000480 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Claytonf6b8b582011-04-13 00:18:08 +0000481 if (error.Fail())
482 {
483 result.AppendError (error.AsCString());
484 result.SetStatus (eReturnStatusFailed);
485 return false;
486 }
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000487
488 // No expression following options
Greg Clayton05da458c2014-03-13 23:48:40 +0000489 if (expr == NULL || expr[0] == '\0')
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000490 {
491 GetMultilineExpression ();
492 return result.Succeeded();
493 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494 }
495 }
496
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000497 if (expr == NULL)
498 expr = command;
Sean Callanan16ad5fa2010-06-24 00:16:27 +0000499
Caroline Tice6e8dc332011-06-13 20:20:29 +0000500 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Johnny Chenfcd43b72010-08-13 00:42:30 +0000501 return true;
502
503 result.SetStatus (eReturnStatusFailed);
504 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000505}
506