blob: 980d11cb1cf3bd00f1c02aac36c20bab53d6ae07 [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 Callanan30e33972015-09-03 00:48:23 +000019#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h"
Jim Ingham151c0322015-09-15 21:13:50 +000020#include "lldb/Expression/UserExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Expression/DWARFExpression.h"
22#include "lldb/Host/Host.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000023#include "lldb/Host/StringConvert.h"
Sean Callananebf77072010-07-23 00:16:21 +000024#include "lldb/Core/Debugger.h"
Greg Clayton66111032010-06-23 01:19:29 +000025#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Interpreter/CommandReturnObject.h"
Jim Ingham0e0984e2015-09-02 01:06:46 +000027#include "lldb/Target/Language.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Symbol/ObjectFile.h"
29#include "lldb/Symbol/Variable.h"
30#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000031#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Target/Target.h"
Greg Clayton7260f622011-04-18 08:33:37 +000033#include "lldb/Target/Thread.h"
Saleem Abdulrasool28606952014-06-27 05:17:41 +000034#include "llvm/ADT/STLExtras.h"
Sean Callananebf77072010-07-23 00:16:21 +000035#include "llvm/ADT/StringRef.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036
37using namespace lldb;
38using namespace lldb_private;
39
Greg Clayton1deb7962011-10-25 06:44:01 +000040CommandObjectExpression::CommandOptions::CommandOptions () :
41 OptionGroup()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042{
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043}
44
45
46CommandObjectExpression::CommandOptions::~CommandOptions ()
47{
48}
49
Enrico Granata4d93b8c2013-09-30 19:11:51 +000050static OptionEnumValueElement g_description_verbosity_type[] =
51{
52 { eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"},
53 { eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", "Show the full output, including persistent variable's name and type"},
54 { 0, NULL, NULL }
55};
56
Greg Clayton1deb7962011-10-25 06:44:01 +000057OptionDefinition
58CommandObjectExpression::CommandOptions::g_option_table[] =
59{
Zachary Turnerd37221d2014-07-09 16:31:49 +000060 { 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."},
61 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
62 { 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."},
63 { 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)."},
64 { 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 +000065 { 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 +000066 { 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 +000067};
68
69
70uint32_t
71CommandObjectExpression::CommandOptions::GetNumDefinitions ()
72{
Saleem Abdulrasool28606952014-06-27 05:17:41 +000073 return llvm::array_lengthof(g_option_table);
Greg Clayton1deb7962011-10-25 06:44:01 +000074}
75
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076Error
Greg Clayton1deb7962011-10-25 06:44:01 +000077CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
78 uint32_t option_idx,
79 const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080{
81 Error error;
82
Greg Clayton3bcdfc02012-12-04 00:32:51 +000083 const int short_option = g_option_table[option_idx].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084
85 switch (short_option)
86 {
Dawn Perchik15663c52015-07-25 00:19:39 +000087 case 'l':
Jim Ingham0e0984e2015-09-02 01:06:46 +000088 language = Language::GetLanguageTypeFromString (option_arg);
Dawn Perchik15663c52015-07-25 00:19:39 +000089 if (language == eLanguageTypeUnknown)
90 error.SetErrorStringWithFormat ("unknown language type: '%s' for expression", option_arg);
91 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000092
Jim Ingham35e1bda2012-10-16 21:41:58 +000093 case 'a':
94 {
95 bool success;
96 bool result;
97 result = Args::StringToBoolean(option_arg, true, &success);
98 if (!success)
99 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
100 else
101 try_all_threads = result;
102 }
Jim Ingham6c68fb42010-09-30 00:54:27 +0000103 break;
Jim Ingham399f1ca2010-11-05 19:25:48 +0000104
Jim Ingham184e9812013-01-15 02:47:48 +0000105 case 'i':
106 {
107 bool success;
108 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
109 if (success)
110 ignore_breakpoints = tmp_value;
111 else
112 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
113 break;
114 }
Jim Ingham35e1bda2012-10-16 21:41:58 +0000115 case 't':
116 {
117 bool success;
118 uint32_t result;
Vince Harron5275aaa2015-01-15 20:08:35 +0000119 result = StringConvert::ToUInt32(option_arg, 0, 0, &success);
Jim Ingham35e1bda2012-10-16 21:41:58 +0000120 if (success)
121 timeout = result;
122 else
123 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
124 }
125 break;
126
Jim Ingham399f1ca2010-11-05 19:25:48 +0000127 case 'u':
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000128 {
129 bool success;
Jim Ingham184e9812013-01-15 02:47:48 +0000130 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
131 if (success)
132 unwind_on_error = tmp_value;
133 else
Greg Clayton86edbf42011-10-26 00:56:27 +0000134 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000135 break;
136 }
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000137
138 case 'v':
139 if (!option_arg)
140 {
141 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityFull;
142 break;
143 }
144 m_verbosity = (LanguageRuntimeDescriptionDisplayVerbosity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
145 if (!error.Success())
146 error.SetErrorStringWithFormat ("unrecognized value for description-verbosity '%s'", option_arg);
147 break;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000148
149 case 'g':
150 debug = true;
151 unwind_on_error = false;
152 ignore_breakpoints = false;
153 break;
154
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000155 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000156 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157 break;
158 }
159
160 return error;
161}
162
163void
Greg Clayton1deb7962011-10-25 06:44:01 +0000164CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165{
Jim Ingham184e9812013-01-15 02:47:48 +0000166 Process *process = interpreter.GetExecutionContext().GetProcessPtr();
167 if (process != NULL)
168 {
169 ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
170 unwind_on_error = process->GetUnwindOnErrorInExpressions();
171 }
172 else
173 {
Greg Claytonfc03f8f2014-03-25 18:47:07 +0000174 ignore_breakpoints = true;
Jim Ingham184e9812013-01-15 02:47:48 +0000175 unwind_on_error = true;
176 }
177
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178 show_summary = true;
Jim Ingham35e1bda2012-10-16 21:41:58 +0000179 try_all_threads = true;
180 timeout = 0;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000181 debug = false;
Dawn Perchik15663c52015-07-25 00:19:39 +0000182 language = eLanguageTypeUnknown;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000183 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184}
185
Greg Claytone0d378b2011-03-24 21:19:54 +0000186const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187CommandObjectExpression::CommandOptions::GetDefinitions ()
188{
189 return g_option_table;
190}
191
Greg Claytona7015092010-09-18 01:14:36 +0000192CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000193 CommandObjectRaw (interpreter,
194 "expression",
Dawn Perchik15663c52015-07-25 00:19:39 +0000195 "Evaluate an expression in the current program context, using user defined variables and variables currently in scope.",
Jim Ingham5a988412012-06-08 21:56:10 +0000196 NULL,
Enrico Granatae87764f2015-05-27 05:04:35 +0000197 eCommandProcessMustBePaused | eCommandTryTargetAPILock),
Greg Clayton44d93782014-01-27 23:43:24 +0000198 IOHandlerDelegate (IOHandlerDelegate::Completion::Expression),
Greg Clayton1deb7962011-10-25 06:44:01 +0000199 m_option_group (interpreter),
200 m_format_options (eFormatDefault),
201 m_command_options (),
Johnny Chenf7edb1c2010-09-30 18:30:25 +0000202 m_expr_line_count (0),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000203 m_expr_lines ()
204{
Kate Stoneea671fb2015-07-14 05:48:36 +0000205 SetHelpLong(
206R"(
207Timeouts:
208
209)" " If the expression can be evaluated statically (without running code) then it will be. \
210Otherwise, by default the expression will run on the current thread with a short timeout: \
211currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted \
212and resumed with all threads running. You can use the -a option to disable retrying on all \
213threads. You can use the -t option to set a shorter timeout." R"(
214
215User defined variables:
216
217)" " You can define your own variables for convenience or to be used in subsequent expressions. \
218You define them the same way you would define variables in C. If the first character of \
219your user defined variable is a $, then the variable's value will be available in future \
220expressions, otherwise it will just be available in the current expression." R"(
221
222Continuing evaluation after a breakpoint:
223
224)" " If the \"-i false\" option is used, and execution is interrupted by a breakpoint hit, once \
225you are done with your investigation, you can either remove the expression execution frames \
226from the stack with \"thread return -x\" or if you are still interested in the expression result \
227you can issue the \"continue\" command and the expression evaluation will complete and the \
228expression result will be available using the \"thread.completed-expression\" key in the thread \
229format." R"(
230
231Examples:
232
233 expr my_struct->a = my_array[3]
234 expr -f bin -- (index * 8) + 5
235 expr unsigned int $foo = 5
236 expr char c[] = \"foo\"; c[0])"
237 );
Caroline Tice405fe672010-10-04 22:28:36 +0000238
239 CommandArgumentEntry arg;
240 CommandArgumentData expression_arg;
241
242 // Define the first (and only) variant of this arg.
243 expression_arg.arg_type = eArgTypeExpression;
244 expression_arg.arg_repetition = eArgRepeatPlain;
245
246 // There is only one variant this argument could be; put it into the argument entry.
247 arg.push_back (expression_arg);
248
249 // Push the data for the first argument into the m_arguments vector.
250 m_arguments.push_back (arg);
Greg Clayton1deb7962011-10-25 06:44:01 +0000251
Greg Clayton5009f9d2011-10-27 17:55:14 +0000252 // Add the "--format" and "--gdb-format"
253 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 +0000254 m_option_group.Append (&m_command_options);
Enrico Granatab576bba2013-01-09 20:12:53 +0000255 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 +0000256 m_option_group.Finalize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257}
258
259CommandObjectExpression::~CommandObjectExpression ()
260{
261}
262
263Options *
264CommandObjectExpression::GetOptions ()
265{
Greg Clayton1deb7962011-10-25 06:44:01 +0000266 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267}
268
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269bool
Greg Clayton1d3afba2010-10-05 00:00:42 +0000270CommandObjectExpression::EvaluateExpression
271(
272 const char *expr,
Caroline Tice6e8dc332011-06-13 20:20:29 +0000273 Stream *output_stream,
274 Stream *error_stream,
Greg Clayton1d3afba2010-10-05 00:00:42 +0000275 CommandReturnObject *result
276)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000277{
Greg Claytonba7b8e22013-01-26 23:54:29 +0000278 // Don't use m_exe_ctx as this might be called asynchronously
279 // after the command object DoExecute has finished when doing
280 // multi-line expression that use an input reader...
281 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
282
283 Target *target = exe_ctx.GetTargetPtr();
Sean Callananc0a6e062011-10-27 21:22:25 +0000284
285 if (!target)
Jim Ingham893c9322014-11-22 01:42:44 +0000286 target = GetDummyTarget();
Sean Callananc0a6e062011-10-27 21:22:25 +0000287
Greg Claytonc14ee322011-09-22 04:58:26 +0000288 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000289 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000290 lldb::ValueObjectSP result_valobj_sp;
Sean Callanan92adcac2011-01-13 08:53:35 +0000291 bool keep_in_memory = true;
Dawn Perchik009d1102015-09-04 01:02:30 +0000292 StackFrame *frame = exe_ctx.GetFramePtr();
Enrico Granatab576bba2013-01-09 20:12:53 +0000293
Jim Ingham35e1bda2012-10-16 21:41:58 +0000294 EvaluateExpressionOptions options;
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000295 options.SetCoerceToId(m_varobj_options.use_objc);
296 options.SetUnwindOnError(m_command_options.unwind_on_error);
297 options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints);
298 options.SetKeepInMemory(keep_in_memory);
299 options.SetUseDynamic(m_varobj_options.use_dynamic);
300 options.SetTryAllThreads(m_command_options.try_all_threads);
301 options.SetDebug(m_command_options.debug);
Greg Clayton62afb9f2013-11-04 19:35:17 +0000302
Dawn Perchik009d1102015-09-04 01:02:30 +0000303 // If the language was not specified in the expression command,
304 // set it to the language in the target's properties if
305 // specified, else default to the langage for the frame.
Dawn Perchik15663c52015-07-25 00:19:39 +0000306 if (m_command_options.language != eLanguageTypeUnknown)
307 options.SetLanguage(m_command_options.language);
Dawn Perchik009d1102015-09-04 01:02:30 +0000308 else if (target->GetLanguage() != eLanguageTypeUnknown)
Dawn Perchik15663c52015-07-25 00:19:39 +0000309 options.SetLanguage(target->GetLanguage());
Dawn Perchik009d1102015-09-04 01:02:30 +0000310 else if (frame)
311 options.SetLanguage(frame->GetLanguage());
Dawn Perchik15663c52015-07-25 00:19:39 +0000312
Greg Clayton23f8c952014-03-24 23:10:19 +0000313 // If there is any chance we are going to stop and want to see
314 // what went wrong with our expression, we should generate debug info
315 if (!m_command_options.ignore_breakpoints ||
316 !m_command_options.unwind_on_error)
317 options.SetGenerateDebugInfo(true);
318
Greg Clayton62afb9f2013-11-04 19:35:17 +0000319 if (m_command_options.timeout > 0)
320 options.SetTimeoutUsec(m_command_options.timeout);
Jim Ingham6f78f382014-01-17 20:09:23 +0000321 else
322 options.SetTimeoutUsec(0);
Arnaud A. de Grandmaison62e5f4d2014-03-22 20:23:26 +0000323
Dawn Perchik009d1102015-09-04 01:02:30 +0000324 target->EvaluateExpression(expr, frame, result_valobj_sp, options);
Sean Callanan4b388c92013-07-30 19:54:09 +0000325
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000326 if (result_valobj_sp)
327 {
Sean Callananbf154da2012-08-08 17:35:10 +0000328 Format format = m_format_options.GetFormat();
329
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000330 if (result_valobj_sp->GetError().Success())
331 {
Sean Callananbf154da2012-08-08 17:35:10 +0000332 if (format != eFormatVoid)
333 {
334 if (format != eFormatDefault)
335 result_valobj_sp->SetFormat (format);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000336
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000337 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
Enrico Granata73e8c4d2015-10-07 02:36:35 +0000338 options.SetVariableFormatDisplayLanguage(result_valobj_sp->GetPreferredDisplayLanguage());
Enrico Granatab576bba2013-01-09 20:12:53 +0000339
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000340 result_valobj_sp->Dump(*output_stream,options);
341
Sean Callananbf154da2012-08-08 17:35:10 +0000342 if (result)
343 result->SetStatus (eReturnStatusSuccessFinishResult);
344 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000345 }
346 else
347 {
Jim Ingham151c0322015-09-15 21:13:50 +0000348 if (result_valobj_sp->GetError().GetError() == UserExpression::kNoResult)
Greg Clayton5fd05902011-06-24 22:31:10 +0000349 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000350 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
Sean Callananbf154da2012-08-08 17:35:10 +0000351 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000352 error_stream->PutCString("(void)\n");
Sean Callananbf154da2012-08-08 17:35:10 +0000353 }
Sean Callananbcf897f2012-08-09 18:18:47 +0000354
355 if (result)
356 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Clayton5fd05902011-06-24 22:31:10 +0000357 }
358 else
359 {
Sean Callananbccce812011-08-23 21:20:51 +0000360 const char *error_cstr = result_valobj_sp->GetError().AsCString();
361 if (error_cstr && error_cstr[0])
362 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000363 const size_t error_cstr_len = strlen (error_cstr);
Sean Callananbccce812011-08-23 21:20:51 +0000364 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
365 if (strstr(error_cstr, "error:") != error_cstr)
366 error_stream->PutCString ("error: ");
367 error_stream->Write(error_cstr, error_cstr_len);
368 if (!ends_with_newline)
369 error_stream->EOL();
370 }
371 else
372 {
373 error_stream->PutCString ("error: unknown error\n");
374 }
375
376 if (result)
377 result->SetStatus (eReturnStatusFailed);
Greg Clayton5fd05902011-06-24 22:31:10 +0000378 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000379 }
380 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000381 }
382 else
383 {
Caroline Tice6e8dc332011-06-13 20:20:29 +0000384 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000385 return false;
Sean Callananebf77072010-07-23 00:16:21 +0000386 }
Sean Callanand1e5b432010-08-12 01:56:52 +0000387
Sean Callananebf77072010-07-23 00:16:21 +0000388 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389}
390
Greg Clayton44d93782014-01-27 23:43:24 +0000391void
Greg Clayton44d93782014-01-27 23:43:24 +0000392CommandObjectExpression::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
393{
394 io_handler.SetIsDone(true);
395// StreamSP output_stream = io_handler.GetDebugger().GetAsyncOutputStream();
396// StreamSP error_stream = io_handler.GetDebugger().GetAsyncErrorStream();
397 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
398 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
399
400 EvaluateExpression (line.c_str(),
401 output_sp.get(),
402 error_sp.get());
403 if (output_sp)
404 output_sp->Flush();
405 if (error_sp)
406 error_sp->Flush();
407}
408
409LineStatus
410CommandObjectExpression::IOHandlerLinesUpdated (IOHandler &io_handler,
411 StringList &lines,
412 uint32_t line_idx,
413 Error &error)
414{
415 if (line_idx == UINT32_MAX)
416 {
417 // Remove the last line from "lines" so it doesn't appear
418 // in our final expression
419 lines.PopBack();
420 error.Clear();
421 return LineStatus::Done;
422 }
423 else if (line_idx + 1 == lines.GetSize())
424 {
425 // The last line was edited, if this line is empty, then we are done
426 // getting our multiple lines.
427 if (lines[line_idx].empty())
428 return LineStatus::Done;
429 }
430 return LineStatus::Success;
431}
432
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000433void
434CommandObjectExpression::GetMultilineExpression ()
435{
436 m_expr_lines.clear();
437 m_expr_line_count = 0;
438
439 Debugger &debugger = GetCommandInterpreter().GetDebugger();
Kate Stonee30f11d2014-11-17 19:06:59 +0000440 bool color_prompt = debugger.GetUseColor();
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000441 const bool multiple_lines = true; // Get multiple lines
442 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
Kate Stonee30f11d2014-11-17 19:06:59 +0000443 IOHandler::Type::Expression,
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000444 "lldb-expr", // Name of input reader for history
445 NULL, // No prompt
Kate Stonee30f11d2014-11-17 19:06:59 +0000446 NULL, // Continuation prompt
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000447 multiple_lines,
Kate Stonee30f11d2014-11-17 19:06:59 +0000448 color_prompt,
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000449 1, // Show line numbers starting at 1
450 *this));
451
452 StreamFileSP output_sp(io_handler_sp->GetOutputStreamFile());
453 if (output_sp)
454 {
455 output_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
456 output_sp->Flush();
457 }
458 debugger.PushIOHandler(io_handler_sp);
459}
460
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461bool
Jim Ingham5a988412012-06-08 21:56:10 +0000462CommandObjectExpression::DoExecute
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463(
464 const char *command,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465 CommandReturnObject &result
466)
467{
Greg Clayton1deb7962011-10-25 06:44:01 +0000468 m_option_group.NotifyOptionParsingStarting();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469
470 const char * expr = NULL;
471
472 if (command[0] == '\0')
473 {
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000474 GetMultilineExpression ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475 return result.Succeeded();
476 }
477
478 if (command[0] == '-')
479 {
480 // We have some options and these options MUST end with --.
481 const char *end_options = NULL;
482 const char *s = command;
483 while (s && s[0])
484 {
485 end_options = ::strstr (s, "--");
486 if (end_options)
487 {
488 end_options += 2; // Get past the "--"
489 if (::isspace (end_options[0]))
490 {
491 expr = end_options;
492 while (::isspace (*expr))
493 ++expr;
494 break;
495 }
496 }
497 s = end_options;
498 }
499
500 if (end_options)
501 {
Pavel Labath00b7f952015-03-02 12:46:22 +0000502 Args args (llvm::StringRef(command, end_options - command));
Greg Claytona7015092010-09-18 01:14:36 +0000503 if (!ParseOptions (args, result))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000504 return false;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000505
Greg Clayton1deb7962011-10-25 06:44:01 +0000506 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Claytonf6b8b582011-04-13 00:18:08 +0000507 if (error.Fail())
508 {
509 result.AppendError (error.AsCString());
510 result.SetStatus (eReturnStatusFailed);
511 return false;
512 }
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000513
514 // No expression following options
Greg Clayton05da458c2014-03-13 23:48:40 +0000515 if (expr == NULL || expr[0] == '\0')
Greg Claytoncf28a8b2014-03-13 23:42:30 +0000516 {
517 GetMultilineExpression ();
518 return result.Succeeded();
519 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520 }
521 }
522
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523 if (expr == NULL)
524 expr = command;
Sean Callanan16ad5fa2010-06-24 00:16:27 +0000525
Caroline Tice6e8dc332011-06-13 20:20:29 +0000526 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Johnny Chenfcd43b72010-08-13 00:42:30 +0000527 return true;
528
529 result.SetStatus (eReturnStatusFailed);
530 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000531}
532