blob: 89edf42f3f08660957909d25ab7a93fe5d43bb23 [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"
20#include "lldb/Core/InputReader.h"
Jim Ingham6c68fb42010-09-30 00:54:27 +000021#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000022#include "lldb/DataFormatters/ValueObjectPrinter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Expression/ClangExpressionVariable.h"
Sean Callanan1a8d4092010-08-27 01:01:44 +000024#include "lldb/Expression/ClangUserExpression.h"
Stephen Wilsonebb84b22010-07-23 21:47:22 +000025#include "lldb/Expression/ClangFunction.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Expression/DWARFExpression.h"
27#include "lldb/Host/Host.h"
Sean Callananebf77072010-07-23 00:16:21 +000028#include "lldb/Core/Debugger.h"
Greg Clayton66111032010-06-23 01:19:29 +000029#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Interpreter/CommandReturnObject.h"
Jim Ingham6c68fb42010-09-30 00:54:27 +000031#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Symbol/ObjectFile.h"
33#include "lldb/Symbol/Variable.h"
34#include "lldb/Target/Process.h"
Jason Molendaf23bf742013-11-02 02:23:02 +000035#include "lldb/Target/Frame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036#include "lldb/Target/Target.h"
Greg Clayton7260f622011-04-18 08:33:37 +000037#include "lldb/Target/Thread.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{
Virgile Belloe2607b52013-09-05 16:42:23 +000063 { 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."},
64 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
65 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, 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, 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)."},
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;
150
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000151 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000152 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153 break;
154 }
155
156 return error;
157}
158
159void
Greg Clayton1deb7962011-10-25 06:44:01 +0000160CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161{
Jim Ingham184e9812013-01-15 02:47:48 +0000162 Process *process = interpreter.GetExecutionContext().GetProcessPtr();
163 if (process != NULL)
164 {
165 ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
166 unwind_on_error = process->GetUnwindOnErrorInExpressions();
167 }
168 else
169 {
170 ignore_breakpoints = false;
171 unwind_on_error = true;
172 }
173
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174 show_summary = true;
Jim Ingham35e1bda2012-10-16 21:41:58 +0000175 try_all_threads = true;
176 timeout = 0;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000177 m_verbosity = eLanguageRuntimeDescriptionDisplayVerbosityCompact;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000178}
179
Greg Claytone0d378b2011-03-24 21:19:54 +0000180const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181CommandObjectExpression::CommandOptions::GetDefinitions ()
182{
183 return g_option_table;
184}
185
Greg Claytona7015092010-09-18 01:14:36 +0000186CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000187 CommandObjectRaw (interpreter,
188 "expression",
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000189 "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 +0000190 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000191 eFlagProcessMustBePaused | eFlagTryTargetAPILock),
Greg Clayton1deb7962011-10-25 06:44:01 +0000192 m_option_group (interpreter),
193 m_format_options (eFormatDefault),
194 m_command_options (),
Johnny Chenf7edb1c2010-09-30 18:30:25 +0000195 m_expr_line_count (0),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196 m_expr_lines ()
197{
198 SetHelpLong(
Jim Ingham35e1bda2012-10-16 21:41:58 +0000199"Timeouts:\n\
200 If the expression can be evaluated statically (without runnning code) then it will be.\n\
201 Otherwise, by default the expression will run on the current thread with a short timeout:\n\
202 currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted\n\
203 and resumed with all threads running. You can use the -a option to disable retrying on all\n\
204 threads. You can use the -t option to set a shorter timeout.\n\
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000205\n\
206User defined variables:\n\
207 You can define your own variables for convenience or to be used in subsequent expressions.\n\
208 You define them the same way you would define variables in C. If the first character of \n\
209 your user defined variable is a $, then the variable's value will be available in future\n\
210 expressions, otherwise it will just be available in the current expression.\n\
211\n\
Jim Ingham35e1bda2012-10-16 21:41:58 +0000212Examples: \n\
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213\n\
214 expr my_struct->a = my_array[3] \n\
215 expr -f bin -- (index * 8) + 5 \n\
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000216 expr unsigned int $foo = 5\n\
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217 expr char c[] = \"foo\"; c[0]\n");
Caroline Tice405fe672010-10-04 22:28:36 +0000218
219 CommandArgumentEntry arg;
220 CommandArgumentData expression_arg;
221
222 // Define the first (and only) variant of this arg.
223 expression_arg.arg_type = eArgTypeExpression;
224 expression_arg.arg_repetition = eArgRepeatPlain;
225
226 // There is only one variant this argument could be; put it into the argument entry.
227 arg.push_back (expression_arg);
228
229 // Push the data for the first argument into the m_arguments vector.
230 m_arguments.push_back (arg);
Greg Clayton1deb7962011-10-25 06:44:01 +0000231
Greg Clayton5009f9d2011-10-27 17:55:14 +0000232 // Add the "--format" and "--gdb-format"
233 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 +0000234 m_option_group.Append (&m_command_options);
Enrico Granatab576bba2013-01-09 20:12:53 +0000235 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 +0000236 m_option_group.Finalize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237}
238
239CommandObjectExpression::~CommandObjectExpression ()
240{
241}
242
243Options *
244CommandObjectExpression::GetOptions ()
245{
Greg Clayton1deb7962011-10-25 06:44:01 +0000246 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000247}
248
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249size_t
250CommandObjectExpression::MultiLineExpressionCallback
251(
252 void *baton,
Greg Clayton66111032010-06-23 01:19:29 +0000253 InputReader &reader,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000254 lldb::InputReaderAction notification,
255 const char *bytes,
256 size_t bytes_len
257)
258{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259 CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
Caroline Ticed61c10b2011-06-16 16:27:19 +0000260 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
261
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262 switch (notification)
263 {
264 case eInputReaderActivate:
Caroline Ticed61c10b2011-06-16 16:27:19 +0000265 if (!batch_mode)
Caroline Tice15356e72011-06-15 19:35:17 +0000266 {
Greg Clayton07e66e32011-07-20 03:41:06 +0000267 StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
268 if (async_strm_sp)
269 {
270 async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
271 async_strm_sp->Flush();
272 }
Caroline Tice15356e72011-06-15 19:35:17 +0000273 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000274 // Fall through
275 case eInputReaderReactivate:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000276 break;
277
278 case eInputReaderDeactivate:
279 break;
280
Caroline Tice969ed3d2011-05-02 20:41:46 +0000281 case eInputReaderAsynchronousOutputWritten:
282 break;
283
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284 case eInputReaderGotToken:
285 ++cmd_object_expr->m_expr_line_count;
286 if (bytes && bytes_len)
287 {
288 cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
289 }
290
291 if (bytes_len == 0)
Greg Clayton66111032010-06-23 01:19:29 +0000292 reader.SetIsDone(true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293 break;
294
Caroline Ticeefed6132010-11-19 20:47:54 +0000295 case eInputReaderInterrupt:
296 cmd_object_expr->m_expr_lines.clear();
297 reader.SetIsDone (true);
Caroline Ticed61c10b2011-06-16 16:27:19 +0000298 if (!batch_mode)
Caroline Tice15356e72011-06-15 19:35:17 +0000299 {
Greg Clayton07e66e32011-07-20 03:41:06 +0000300 StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
301 if (async_strm_sp)
302 {
303 async_strm_sp->PutCString("Expression evaluation cancelled.\n");
304 async_strm_sp->Flush();
305 }
Caroline Tice15356e72011-06-15 19:35:17 +0000306 }
Caroline Ticeefed6132010-11-19 20:47:54 +0000307 break;
308
309 case eInputReaderEndOfFile:
310 reader.SetIsDone (true);
311 break;
312
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 case eInputReaderDone:
Caroline Ticeefed6132010-11-19 20:47:54 +0000314 if (cmd_object_expr->m_expr_lines.size() > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315 {
Caroline Tice6e8dc332011-06-13 20:20:29 +0000316 StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
317 StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318 cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
Caroline Tice6e8dc332011-06-13 20:20:29 +0000319 output_stream.get(),
320 error_stream.get());
321 output_stream->Flush();
322 error_stream->Flush();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000323 }
324 break;
325 }
326
327 return bytes_len;
328}
329
330bool
Greg Clayton1d3afba2010-10-05 00:00:42 +0000331CommandObjectExpression::EvaluateExpression
332(
333 const char *expr,
Caroline Tice6e8dc332011-06-13 20:20:29 +0000334 Stream *output_stream,
335 Stream *error_stream,
Greg Clayton1d3afba2010-10-05 00:00:42 +0000336 CommandReturnObject *result
337)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000338{
Greg Claytonba7b8e22013-01-26 23:54:29 +0000339 // Don't use m_exe_ctx as this might be called asynchronously
340 // after the command object DoExecute has finished when doing
341 // multi-line expression that use an input reader...
342 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
343
344 Target *target = exe_ctx.GetTargetPtr();
Sean Callananc0a6e062011-10-27 21:22:25 +0000345
346 if (!target)
347 target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
348
Greg Claytonc14ee322011-09-22 04:58:26 +0000349 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000351 lldb::ValueObjectSP result_valobj_sp;
Greg Clayton32c40852010-10-06 03:09:11 +0000352
Greg Claytone0d378b2011-03-24 21:19:54 +0000353 ExecutionResults exe_results;
Sean Callanan92adcac2011-01-13 08:53:35 +0000354
355 bool keep_in_memory = true;
Enrico Granatab576bba2013-01-09 20:12:53 +0000356
Jim Ingham35e1bda2012-10-16 21:41:58 +0000357 EvaluateExpressionOptions options;
Enrico Granatab576bba2013-01-09 20:12:53 +0000358 options.SetCoerceToId(m_varobj_options.use_objc)
Enrico Granatad4439aa2012-09-05 20:41:26 +0000359 .SetUnwindOnError(m_command_options.unwind_on_error)
Jim Ingham184e9812013-01-15 02:47:48 +0000360 .SetIgnoreBreakpoints (m_command_options.ignore_breakpoints)
Enrico Granatad4439aa2012-09-05 20:41:26 +0000361 .SetKeepInMemory(keep_in_memory)
Enrico Granatab576bba2013-01-09 20:12:53 +0000362 .SetUseDynamic(m_varobj_options.use_dynamic)
Jim Ingham35e1bda2012-10-16 21:41:58 +0000363 .SetRunOthers(m_command_options.try_all_threads)
364 .SetTimeoutUsec(m_command_options.timeout);
Enrico Granatad4439aa2012-09-05 20:41:26 +0000365
Greg Claytonc14ee322011-09-22 04:58:26 +0000366 exe_results = target->EvaluateExpression (expr,
Greg Claytonba7b8e22013-01-26 23:54:29 +0000367 exe_ctx.GetFramePtr(),
Enrico Granata3372f582012-07-16 23:10:35 +0000368 result_valobj_sp,
Enrico Granatad4439aa2012-09-05 20:41:26 +0000369 options);
Sean Callanan4b388c92013-07-30 19:54:09 +0000370
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000371 if (result_valobj_sp)
372 {
Sean Callananbf154da2012-08-08 17:35:10 +0000373 Format format = m_format_options.GetFormat();
374
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000375 if (result_valobj_sp->GetError().Success())
376 {
Sean Callananbf154da2012-08-08 17:35:10 +0000377 if (format != eFormatVoid)
378 {
379 if (format != eFormatDefault)
380 result_valobj_sp->SetFormat (format);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000381
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000382 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(m_command_options.m_verbosity,format));
Enrico Granatab576bba2013-01-09 20:12:53 +0000383
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000384 result_valobj_sp->Dump(*output_stream,options);
385
Sean Callananbf154da2012-08-08 17:35:10 +0000386 if (result)
387 result->SetStatus (eReturnStatusSuccessFinishResult);
388 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000389 }
390 else
391 {
Sean Callananbccce812011-08-23 21:20:51 +0000392 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
Greg Clayton5fd05902011-06-24 22:31:10 +0000393 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000394 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
Sean Callananbf154da2012-08-08 17:35:10 +0000395 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000396 error_stream->PutCString("(void)\n");
Sean Callananbf154da2012-08-08 17:35:10 +0000397 }
Sean Callananbcf897f2012-08-09 18:18:47 +0000398
399 if (result)
400 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Clayton5fd05902011-06-24 22:31:10 +0000401 }
402 else
403 {
Sean Callananbccce812011-08-23 21:20:51 +0000404 const char *error_cstr = result_valobj_sp->GetError().AsCString();
405 if (error_cstr && error_cstr[0])
406 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000407 const size_t error_cstr_len = strlen (error_cstr);
Sean Callananbccce812011-08-23 21:20:51 +0000408 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
409 if (strstr(error_cstr, "error:") != error_cstr)
410 error_stream->PutCString ("error: ");
411 error_stream->Write(error_cstr, error_cstr_len);
412 if (!ends_with_newline)
413 error_stream->EOL();
414 }
415 else
416 {
417 error_stream->PutCString ("error: unknown error\n");
418 }
419
420 if (result)
421 result->SetStatus (eReturnStatusFailed);
Greg Clayton5fd05902011-06-24 22:31:10 +0000422 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000423 }
424 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000425 }
426 else
427 {
Caroline Tice6e8dc332011-06-13 20:20:29 +0000428 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000429 return false;
Sean Callananebf77072010-07-23 00:16:21 +0000430 }
Sean Callanand1e5b432010-08-12 01:56:52 +0000431
Sean Callananebf77072010-07-23 00:16:21 +0000432 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000433}
434
435bool
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 {
448 m_expr_lines.clear();
449 m_expr_line_count = 0;
450
Greg Claytona7015092010-09-18 01:14:36 +0000451 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000452 if (reader_sp)
453 {
454 Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
455 this, // baton
456 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton66111032010-06-23 01:19:29 +0000457 NULL, // end token
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458 NULL, // prompt
459 true)); // echo input
460 if (err.Success())
461 {
Greg Claytona7015092010-09-18 01:14:36 +0000462 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463 result.SetStatus (eReturnStatusSuccessFinishNoResult);
464 }
465 else
466 {
467 result.AppendError (err.AsCString());
468 result.SetStatus (eReturnStatusFailed);
469 }
470 }
471 else
472 {
473 result.AppendError("out of memory");
474 result.SetStatus (eReturnStatusFailed);
475 }
476 return result.Succeeded();
477 }
478
479 if (command[0] == '-')
480 {
481 // We have some options and these options MUST end with --.
482 const char *end_options = NULL;
483 const char *s = command;
484 while (s && s[0])
485 {
486 end_options = ::strstr (s, "--");
487 if (end_options)
488 {
489 end_options += 2; // Get past the "--"
490 if (::isspace (end_options[0]))
491 {
492 expr = end_options;
493 while (::isspace (*expr))
494 ++expr;
495 break;
496 }
497 }
498 s = end_options;
499 }
500
501 if (end_options)
502 {
Greg Clayton66111032010-06-23 01:19:29 +0000503 Args args (command, end_options - command);
Greg Claytona7015092010-09-18 01:14:36 +0000504 if (!ParseOptions (args, result))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000505 return false;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000506
Greg Clayton1deb7962011-10-25 06:44:01 +0000507 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Claytonf6b8b582011-04-13 00:18:08 +0000508 if (error.Fail())
509 {
510 result.AppendError (error.AsCString());
511 result.SetStatus (eReturnStatusFailed);
512 return false;
513 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514 }
515 }
516
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517 if (expr == NULL)
518 expr = command;
Sean Callanan16ad5fa2010-06-24 00:16:27 +0000519
Caroline Tice6e8dc332011-06-13 20:20:29 +0000520 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Johnny Chenfcd43b72010-08-13 00:42:30 +0000521 return true;
522
523 result.SetStatus (eReturnStatusFailed);
524 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525}
526