blob: 7186b9a7cb4598f08e09699dc174c174dfac5f2e [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"
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"
34#include "lldb/Target/StackFrame.h"
35#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
Greg Clayton1deb7962011-10-25 06:44:01 +000052OptionDefinition
53CommandObjectExpression::CommandOptions::g_option_table[] =
54{
Virgile Belloe2607b52013-09-05 16:42:23 +000055 { 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."},
56 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
57 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."},
58 { 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 Clayton1deb7962011-10-25 06:44:01 +000059};
60
61
62uint32_t
63CommandObjectExpression::CommandOptions::GetNumDefinitions ()
64{
65 return sizeof(g_option_table)/sizeof(OptionDefinition);
66}
67
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068Error
Greg Clayton1deb7962011-10-25 06:44:01 +000069CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
70 uint32_t option_idx,
71 const char *option_arg)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000072{
73 Error error;
74
Greg Clayton3bcdfc02012-12-04 00:32:51 +000075 const int short_option = g_option_table[option_idx].short_option;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076
77 switch (short_option)
78 {
Caroline Tice3f4c09c2010-09-07 22:38:08 +000079 //case 'l':
80 //if (language.SetLanguageFromCString (option_arg) == false)
81 //{
Greg Clayton86edbf42011-10-26 00:56:27 +000082 // error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
Caroline Tice3f4c09c2010-09-07 22:38:08 +000083 //}
84 //break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000085
Jim Ingham35e1bda2012-10-16 21:41:58 +000086 case 'a':
87 {
88 bool success;
89 bool result;
90 result = Args::StringToBoolean(option_arg, true, &success);
91 if (!success)
92 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
93 else
94 try_all_threads = result;
95 }
Jim Ingham6c68fb42010-09-30 00:54:27 +000096 break;
Jim Ingham399f1ca2010-11-05 19:25:48 +000097
Jim Ingham184e9812013-01-15 02:47:48 +000098 case 'i':
99 {
100 bool success;
101 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
102 if (success)
103 ignore_breakpoints = tmp_value;
104 else
105 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
106 break;
107 }
Jim Ingham35e1bda2012-10-16 21:41:58 +0000108 case 't':
109 {
110 bool success;
111 uint32_t result;
112 result = Args::StringToUInt32(option_arg, 0, 0, &success);
113 if (success)
114 timeout = result;
115 else
116 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
117 }
118 break;
119
Jim Ingham399f1ca2010-11-05 19:25:48 +0000120 case 'u':
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000121 {
122 bool success;
Jim Ingham184e9812013-01-15 02:47:48 +0000123 bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
124 if (success)
125 unwind_on_error = tmp_value;
126 else
Greg Clayton86edbf42011-10-26 00:56:27 +0000127 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000128 break;
129 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130 default:
Greg Clayton86edbf42011-10-26 00:56:27 +0000131 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000132 break;
133 }
134
135 return error;
136}
137
138void
Greg Clayton1deb7962011-10-25 06:44:01 +0000139CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140{
Jim Ingham184e9812013-01-15 02:47:48 +0000141 Process *process = interpreter.GetExecutionContext().GetProcessPtr();
142 if (process != NULL)
143 {
144 ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
145 unwind_on_error = process->GetUnwindOnErrorInExpressions();
146 }
147 else
148 {
149 ignore_breakpoints = false;
150 unwind_on_error = true;
151 }
152
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000153 show_summary = true;
Jim Ingham35e1bda2012-10-16 21:41:58 +0000154 try_all_threads = true;
155 timeout = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156}
157
Greg Claytone0d378b2011-03-24 21:19:54 +0000158const OptionDefinition*
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159CommandObjectExpression::CommandOptions::GetDefinitions ()
160{
161 return g_option_table;
162}
163
Greg Claytona7015092010-09-18 01:14:36 +0000164CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
Jim Ingham5a988412012-06-08 21:56:10 +0000165 CommandObjectRaw (interpreter,
166 "expression",
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000167 "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 +0000168 NULL,
Greg Claytonf9fc6092013-01-09 19:44:40 +0000169 eFlagProcessMustBePaused | eFlagTryTargetAPILock),
Greg Clayton1deb7962011-10-25 06:44:01 +0000170 m_option_group (interpreter),
171 m_format_options (eFormatDefault),
172 m_command_options (),
Johnny Chenf7edb1c2010-09-30 18:30:25 +0000173 m_expr_line_count (0),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174 m_expr_lines ()
175{
176 SetHelpLong(
Jim Ingham35e1bda2012-10-16 21:41:58 +0000177"Timeouts:\n\
178 If the expression can be evaluated statically (without runnning code) then it will be.\n\
179 Otherwise, by default the expression will run on the current thread with a short timeout:\n\
180 currently .25 seconds. If it doesn't return in that time, the evaluation will be interrupted\n\
181 and resumed with all threads running. You can use the -a option to disable retrying on all\n\
182 threads. You can use the -t option to set a shorter timeout.\n\
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000183\n\
184User defined variables:\n\
185 You can define your own variables for convenience or to be used in subsequent expressions.\n\
186 You define them the same way you would define variables in C. If the first character of \n\
187 your user defined variable is a $, then the variable's value will be available in future\n\
188 expressions, otherwise it will just be available in the current expression.\n\
189\n\
Jim Ingham35e1bda2012-10-16 21:41:58 +0000190Examples: \n\
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191\n\
192 expr my_struct->a = my_array[3] \n\
193 expr -f bin -- (index * 8) + 5 \n\
Jim Ingham5c48d5c2012-10-25 18:11:24 +0000194 expr unsigned int $foo = 5\n\
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195 expr char c[] = \"foo\"; c[0]\n");
Caroline Tice405fe672010-10-04 22:28:36 +0000196
197 CommandArgumentEntry arg;
198 CommandArgumentData expression_arg;
199
200 // Define the first (and only) variant of this arg.
201 expression_arg.arg_type = eArgTypeExpression;
202 expression_arg.arg_repetition = eArgRepeatPlain;
203
204 // There is only one variant this argument could be; put it into the argument entry.
205 arg.push_back (expression_arg);
206
207 // Push the data for the first argument into the m_arguments vector.
208 m_arguments.push_back (arg);
Greg Clayton1deb7962011-10-25 06:44:01 +0000209
Greg Clayton5009f9d2011-10-27 17:55:14 +0000210 // Add the "--format" and "--gdb-format"
211 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 +0000212 m_option_group.Append (&m_command_options);
Enrico Granatab576bba2013-01-09 20:12:53 +0000213 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 +0000214 m_option_group.Finalize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215}
216
217CommandObjectExpression::~CommandObjectExpression ()
218{
219}
220
221Options *
222CommandObjectExpression::GetOptions ()
223{
Greg Clayton1deb7962011-10-25 06:44:01 +0000224 return &m_option_group;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000225}
226
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000227size_t
228CommandObjectExpression::MultiLineExpressionCallback
229(
230 void *baton,
Greg Clayton66111032010-06-23 01:19:29 +0000231 InputReader &reader,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232 lldb::InputReaderAction notification,
233 const char *bytes,
234 size_t bytes_len
235)
236{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237 CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
Caroline Ticed61c10b2011-06-16 16:27:19 +0000238 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
239
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240 switch (notification)
241 {
242 case eInputReaderActivate:
Caroline Ticed61c10b2011-06-16 16:27:19 +0000243 if (!batch_mode)
Caroline Tice15356e72011-06-15 19:35:17 +0000244 {
Greg Clayton07e66e32011-07-20 03:41:06 +0000245 StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
246 if (async_strm_sp)
247 {
248 async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
249 async_strm_sp->Flush();
250 }
Caroline Tice15356e72011-06-15 19:35:17 +0000251 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000252 // Fall through
253 case eInputReaderReactivate:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000254 break;
255
256 case eInputReaderDeactivate:
257 break;
258
Caroline Tice969ed3d2011-05-02 20:41:46 +0000259 case eInputReaderAsynchronousOutputWritten:
260 break;
261
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262 case eInputReaderGotToken:
263 ++cmd_object_expr->m_expr_line_count;
264 if (bytes && bytes_len)
265 {
266 cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
267 }
268
269 if (bytes_len == 0)
Greg Clayton66111032010-06-23 01:19:29 +0000270 reader.SetIsDone(true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271 break;
272
Caroline Ticeefed6132010-11-19 20:47:54 +0000273 case eInputReaderInterrupt:
274 cmd_object_expr->m_expr_lines.clear();
275 reader.SetIsDone (true);
Caroline Ticed61c10b2011-06-16 16:27:19 +0000276 if (!batch_mode)
Caroline Tice15356e72011-06-15 19:35:17 +0000277 {
Greg Clayton07e66e32011-07-20 03:41:06 +0000278 StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
279 if (async_strm_sp)
280 {
281 async_strm_sp->PutCString("Expression evaluation cancelled.\n");
282 async_strm_sp->Flush();
283 }
Caroline Tice15356e72011-06-15 19:35:17 +0000284 }
Caroline Ticeefed6132010-11-19 20:47:54 +0000285 break;
286
287 case eInputReaderEndOfFile:
288 reader.SetIsDone (true);
289 break;
290
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291 case eInputReaderDone:
Caroline Ticeefed6132010-11-19 20:47:54 +0000292 if (cmd_object_expr->m_expr_lines.size() > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293 {
Caroline Tice6e8dc332011-06-13 20:20:29 +0000294 StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
295 StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296 cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
Caroline Tice6e8dc332011-06-13 20:20:29 +0000297 output_stream.get(),
298 error_stream.get());
299 output_stream->Flush();
300 error_stream->Flush();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301 }
302 break;
303 }
304
305 return bytes_len;
306}
307
308bool
Greg Clayton1d3afba2010-10-05 00:00:42 +0000309CommandObjectExpression::EvaluateExpression
310(
311 const char *expr,
Caroline Tice6e8dc332011-06-13 20:20:29 +0000312 Stream *output_stream,
313 Stream *error_stream,
Greg Clayton1d3afba2010-10-05 00:00:42 +0000314 CommandReturnObject *result
315)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316{
Greg Claytonba7b8e22013-01-26 23:54:29 +0000317 // Don't use m_exe_ctx as this might be called asynchronously
318 // after the command object DoExecute has finished when doing
319 // multi-line expression that use an input reader...
320 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
321
322 Target *target = exe_ctx.GetTargetPtr();
Sean Callananc0a6e062011-10-27 21:22:25 +0000323
324 if (!target)
325 target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
326
Greg Claytonc14ee322011-09-22 04:58:26 +0000327 if (target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000329 lldb::ValueObjectSP result_valobj_sp;
Greg Clayton32c40852010-10-06 03:09:11 +0000330
Greg Claytone0d378b2011-03-24 21:19:54 +0000331 ExecutionResults exe_results;
Sean Callanan92adcac2011-01-13 08:53:35 +0000332
333 bool keep_in_memory = true;
Enrico Granatab576bba2013-01-09 20:12:53 +0000334
Jim Ingham35e1bda2012-10-16 21:41:58 +0000335 EvaluateExpressionOptions options;
Enrico Granatab576bba2013-01-09 20:12:53 +0000336 options.SetCoerceToId(m_varobj_options.use_objc)
Enrico Granatad4439aa2012-09-05 20:41:26 +0000337 .SetUnwindOnError(m_command_options.unwind_on_error)
Jim Ingham184e9812013-01-15 02:47:48 +0000338 .SetIgnoreBreakpoints (m_command_options.ignore_breakpoints)
Enrico Granatad4439aa2012-09-05 20:41:26 +0000339 .SetKeepInMemory(keep_in_memory)
Enrico Granatab576bba2013-01-09 20:12:53 +0000340 .SetUseDynamic(m_varobj_options.use_dynamic)
Jim Ingham35e1bda2012-10-16 21:41:58 +0000341 .SetRunOthers(m_command_options.try_all_threads)
342 .SetTimeoutUsec(m_command_options.timeout);
Enrico Granatad4439aa2012-09-05 20:41:26 +0000343
Greg Claytonc14ee322011-09-22 04:58:26 +0000344 exe_results = target->EvaluateExpression (expr,
Greg Claytonba7b8e22013-01-26 23:54:29 +0000345 exe_ctx.GetFramePtr(),
Enrico Granata3372f582012-07-16 23:10:35 +0000346 result_valobj_sp,
Enrico Granatad4439aa2012-09-05 20:41:26 +0000347 options);
Sean Callanan4b388c92013-07-30 19:54:09 +0000348
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000349 if (result_valobj_sp)
350 {
Sean Callananbf154da2012-08-08 17:35:10 +0000351 Format format = m_format_options.GetFormat();
352
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000353 if (result_valobj_sp->GetError().Success())
354 {
Sean Callananbf154da2012-08-08 17:35:10 +0000355 if (format != eFormatVoid)
356 {
357 if (format != eFormatDefault)
358 result_valobj_sp->SetFormat (format);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000359
Enrico Granata9fb5ab52013-03-26 18:04:53 +0000360 ValueObject::DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(true,format));
Enrico Granatab576bba2013-01-09 20:12:53 +0000361
Sean Callananbf154da2012-08-08 17:35:10 +0000362 ValueObject::DumpValueObject (*(output_stream),
363 result_valobj_sp.get(), // Variable object to dump
364 options);
365 if (result)
366 result->SetStatus (eReturnStatusSuccessFinishResult);
367 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000368 }
369 else
370 {
Sean Callananbccce812011-08-23 21:20:51 +0000371 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
Greg Clayton5fd05902011-06-24 22:31:10 +0000372 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000373 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
Sean Callananbf154da2012-08-08 17:35:10 +0000374 {
Sean Callananbcf897f2012-08-09 18:18:47 +0000375 error_stream->PutCString("(void)\n");
Sean Callananbf154da2012-08-08 17:35:10 +0000376 }
Sean Callananbcf897f2012-08-09 18:18:47 +0000377
378 if (result)
379 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Clayton5fd05902011-06-24 22:31:10 +0000380 }
381 else
382 {
Sean Callananbccce812011-08-23 21:20:51 +0000383 const char *error_cstr = result_valobj_sp->GetError().AsCString();
384 if (error_cstr && error_cstr[0])
385 {
Greg Claytonc7bece562013-01-25 18:06:21 +0000386 const size_t error_cstr_len = strlen (error_cstr);
Sean Callananbccce812011-08-23 21:20:51 +0000387 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
388 if (strstr(error_cstr, "error:") != error_cstr)
389 error_stream->PutCString ("error: ");
390 error_stream->Write(error_cstr, error_cstr_len);
391 if (!ends_with_newline)
392 error_stream->EOL();
393 }
394 else
395 {
396 error_stream->PutCString ("error: unknown error\n");
397 }
398
399 if (result)
400 result->SetStatus (eReturnStatusFailed);
Greg Clayton5fd05902011-06-24 22:31:10 +0000401 }
Jim Inghamf48169b2010-11-30 02:22:11 +0000402 }
403 }
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000404 }
405 else
406 {
Caroline Tice6e8dc332011-06-13 20:20:29 +0000407 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000408 return false;
Sean Callananebf77072010-07-23 00:16:21 +0000409 }
Sean Callanand1e5b432010-08-12 01:56:52 +0000410
Sean Callananebf77072010-07-23 00:16:21 +0000411 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412}
413
414bool
Jim Ingham5a988412012-06-08 21:56:10 +0000415CommandObjectExpression::DoExecute
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416(
417 const char *command,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000418 CommandReturnObject &result
419)
420{
Greg Clayton1deb7962011-10-25 06:44:01 +0000421 m_option_group.NotifyOptionParsingStarting();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422
423 const char * expr = NULL;
424
425 if (command[0] == '\0')
426 {
427 m_expr_lines.clear();
428 m_expr_line_count = 0;
429
Greg Claytona7015092010-09-18 01:14:36 +0000430 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431 if (reader_sp)
432 {
433 Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
434 this, // baton
435 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton66111032010-06-23 01:19:29 +0000436 NULL, // end token
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437 NULL, // prompt
438 true)); // echo input
439 if (err.Success())
440 {
Greg Claytona7015092010-09-18 01:14:36 +0000441 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000442 result.SetStatus (eReturnStatusSuccessFinishNoResult);
443 }
444 else
445 {
446 result.AppendError (err.AsCString());
447 result.SetStatus (eReturnStatusFailed);
448 }
449 }
450 else
451 {
452 result.AppendError("out of memory");
453 result.SetStatus (eReturnStatusFailed);
454 }
455 return result.Succeeded();
456 }
457
458 if (command[0] == '-')
459 {
460 // We have some options and these options MUST end with --.
461 const char *end_options = NULL;
462 const char *s = command;
463 while (s && s[0])
464 {
465 end_options = ::strstr (s, "--");
466 if (end_options)
467 {
468 end_options += 2; // Get past the "--"
469 if (::isspace (end_options[0]))
470 {
471 expr = end_options;
472 while (::isspace (*expr))
473 ++expr;
474 break;
475 }
476 }
477 s = end_options;
478 }
479
480 if (end_options)
481 {
Greg Clayton66111032010-06-23 01:19:29 +0000482 Args args (command, end_options - command);
Greg Claytona7015092010-09-18 01:14:36 +0000483 if (!ParseOptions (args, result))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000484 return false;
Greg Claytonf6b8b582011-04-13 00:18:08 +0000485
Greg Clayton1deb7962011-10-25 06:44:01 +0000486 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Claytonf6b8b582011-04-13 00:18:08 +0000487 if (error.Fail())
488 {
489 result.AppendError (error.AsCString());
490 result.SetStatus (eReturnStatusFailed);
491 return false;
492 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000493 }
494 }
495
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 if (expr == NULL)
497 expr = command;
Sean Callanan16ad5fa2010-06-24 00:16:27 +0000498
Caroline Tice6e8dc332011-06-13 20:20:29 +0000499 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Johnny Chenfcd43b72010-08-13 00:42:30 +0000500 return true;
501
502 result.SetStatus (eReturnStatusFailed);
503 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000504}
505