blob: a93d4e65fa0862adb5be54771da3a46a4fbc90d7 [file] [log] [blame]
Chris Lattner24943d22010-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
Sean Callanan841026f2010-07-23 00:16:21 +000016#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/Value.h"
18#include "lldb/Core/InputReader.h"
Jim Ingham324067b2010-09-30 00:54:27 +000019#include "lldb/Core/ValueObjectVariable.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Expression/ClangExpressionVariable.h"
Sean Callanan65dafa82010-08-27 01:01:44 +000021#include "lldb/Expression/ClangUserExpression.h"
Stephen Wilson63c468c2010-07-23 21:47:22 +000022#include "lldb/Expression/ClangFunction.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Expression/DWARFExpression.h"
24#include "lldb/Host/Host.h"
Sean Callanan841026f2010-07-23 00:16:21 +000025#include "lldb/Core/Debugger.h"
Greg Clayton63094e02010-06-23 01:19:29 +000026#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Interpreter/CommandReturnObject.h"
Jim Ingham324067b2010-09-30 00:54:27 +000028#include "lldb/Target/ObjCLanguageRuntime.h"
Chris Lattner24943d22010-06-08 16:52:24 +000029#include "lldb/Symbol/ObjectFile.h"
30#include "lldb/Symbol/Variable.h"
31#include "lldb/Target/Process.h"
32#include "lldb/Target/StackFrame.h"
33#include "lldb/Target/Target.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000034#include "lldb/Target/Thread.h"
Sean Callanan841026f2010-07-23 00:16:21 +000035#include "llvm/ADT/StringRef.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036
37using namespace lldb;
38using namespace lldb_private;
39
Greg Claytona42880a2011-10-25 06:44:01 +000040CommandObjectExpression::CommandOptions::CommandOptions () :
41 OptionGroup()
Chris Lattner24943d22010-06-08 16:52:24 +000042{
Chris Lattner24943d22010-06-08 16:52:24 +000043}
44
45
46CommandObjectExpression::CommandOptions::~CommandOptions ()
47{
48}
49
Greg Claytona42880a2011-10-25 06:44:01 +000050OptionDefinition
51CommandObjectExpression::CommandOptions::g_option_table[] =
52{
Jim Ingham47beabb2012-10-16 21:41:58 +000053 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', required_argument, NULL, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."},
Greg Claytona42880a2011-10-25 06:44:01 +000054 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "dynamic-value", 'd', required_argument, NULL, 0, eArgTypeBoolean, "Upcast the value resulting from the expression to its dynamic type if available."},
Jim Ingham47beabb2012-10-16 21:41:58 +000055 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Timeout value for running the expression."},
Greg Claytona42880a2011-10-25 06:44:01 +000056 { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', required_argument, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, breakpoint hit or signal."},
57 { LLDB_OPT_SET_2 , false, "object-description", 'o', no_argument, NULL, 0, eArgTypeNone, "Print the object description of the value resulting from the expression."},
58};
59
60
61uint32_t
62CommandObjectExpression::CommandOptions::GetNumDefinitions ()
63{
64 return sizeof(g_option_table)/sizeof(OptionDefinition);
65}
66
Chris Lattner24943d22010-06-08 16:52:24 +000067Error
Greg Claytona42880a2011-10-25 06:44:01 +000068CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
69 uint32_t option_idx,
70 const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +000071{
72 Error error;
73
Greg Claytona42880a2011-10-25 06:44:01 +000074 const char short_option = (char) g_option_table[option_idx].short_option;
Chris Lattner24943d22010-06-08 16:52:24 +000075
76 switch (short_option)
77 {
Caroline Ticec1ad82e2010-09-07 22:38:08 +000078 //case 'l':
79 //if (language.SetLanguageFromCString (option_arg) == false)
80 //{
Greg Clayton9c236732011-10-26 00:56:27 +000081 // error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
Caroline Ticec1ad82e2010-09-07 22:38:08 +000082 //}
83 //break;
Chris Lattner24943d22010-06-08 16:52:24 +000084
Jim Ingham47beabb2012-10-16 21:41:58 +000085 case 'a':
86 {
87 bool success;
88 bool result;
89 result = Args::StringToBoolean(option_arg, true, &success);
90 if (!success)
91 error.SetErrorStringWithFormat("invalid all-threads value setting: \"%s\"", option_arg);
92 else
93 try_all_threads = result;
94 }
Jim Ingham324067b2010-09-30 00:54:27 +000095 break;
Jim Inghamea9d4262010-11-05 19:25:48 +000096
Jim Inghame41494a2011-04-16 00:01:13 +000097 case 'd':
98 {
99 bool success;
100 bool result;
101 result = Args::StringToBoolean(option_arg, true, &success);
102 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000103 error.SetErrorStringWithFormat("invalid dynamic value setting: \"%s\"", option_arg);
Jim Inghame41494a2011-04-16 00:01:13 +0000104 else
105 {
106 if (result)
Greg Clayton82f07462011-05-30 00:49:24 +0000107 use_dynamic = eLazyBoolYes;
Jim Inghame41494a2011-04-16 00:01:13 +0000108 else
109 use_dynamic = eLazyBoolNo;
110 }
111 }
112 break;
113
Jim Ingham47beabb2012-10-16 21:41:58 +0000114 case 'o':
115 print_object = true;
116 break;
117
118 case 't':
119 {
120 bool success;
121 uint32_t result;
122 result = Args::StringToUInt32(option_arg, 0, 0, &success);
123 if (success)
124 timeout = result;
125 else
126 error.SetErrorStringWithFormat ("invalid timeout setting \"%s\"", option_arg);
127 }
128 break;
129
Jim Inghamea9d4262010-11-05 19:25:48 +0000130 case 'u':
Sean Callanan47dc4572011-09-15 02:13:07 +0000131 {
132 bool success;
133 unwind_on_error = Args::StringToBoolean(option_arg, true, &success);
134 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000135 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
Sean Callanan47dc4572011-09-15 02:13:07 +0000136 break;
137 }
Chris Lattner24943d22010-06-08 16:52:24 +0000138 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000139 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000140 break;
141 }
142
143 return error;
144}
145
146void
Greg Claytona42880a2011-10-25 06:44:01 +0000147CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000148{
Jim Inghame41494a2011-04-16 00:01:13 +0000149 use_dynamic = eLazyBoolCalculate;
Greg Claytona42880a2011-10-25 06:44:01 +0000150 print_object = false;
Jim Inghamea9d4262010-11-05 19:25:48 +0000151 unwind_on_error = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000152 show_types = true;
153 show_summary = true;
Jim Ingham47beabb2012-10-16 21:41:58 +0000154 try_all_threads = true;
155 timeout = 0;
Chris Lattner24943d22010-06-08 16:52:24 +0000156}
157
Greg Claytonb3448432011-03-24 21:19:54 +0000158const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000159CommandObjectExpression::CommandOptions::GetDefinitions ()
160{
161 return g_option_table;
162}
163
Greg Clayton238c0a12010-09-18 01:14:36 +0000164CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000165 CommandObjectRaw (interpreter,
166 "expression",
Jim Ingham02ed2852012-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 Inghamda26bd22012-06-08 21:56:10 +0000168 NULL,
169 eFlagProcessMustBePaused),
Greg Claytona42880a2011-10-25 06:44:01 +0000170 m_option_group (interpreter),
171 m_format_options (eFormatDefault),
172 m_command_options (),
Johnny Chencc112ac2010-09-30 18:30:25 +0000173 m_expr_line_count (0),
Chris Lattner24943d22010-06-08 16:52:24 +0000174 m_expr_lines ()
175{
176 SetHelpLong(
Jim Ingham47beabb2012-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 Ingham02ed2852012-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 Ingham47beabb2012-10-16 21:41:58 +0000190Examples: \n\
Chris Lattner24943d22010-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 Ingham02ed2852012-10-25 18:11:24 +0000194 expr unsigned int $foo = 5\n\
Chris Lattner24943d22010-06-08 16:52:24 +0000195 expr char c[] = \"foo\"; c[0]\n");
Caroline Tice43b014a2010-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 Claytona42880a2011-10-25 06:44:01 +0000209
Greg Clayton24a6bd92011-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 Claytona42880a2011-10-25 06:44:01 +0000212 m_option_group.Append (&m_command_options);
213 m_option_group.Finalize();
Chris Lattner24943d22010-06-08 16:52:24 +0000214}
215
216CommandObjectExpression::~CommandObjectExpression ()
217{
218}
219
220Options *
221CommandObjectExpression::GetOptions ()
222{
Greg Claytona42880a2011-10-25 06:44:01 +0000223 return &m_option_group;
Chris Lattner24943d22010-06-08 16:52:24 +0000224}
225
Chris Lattner24943d22010-06-08 16:52:24 +0000226size_t
227CommandObjectExpression::MultiLineExpressionCallback
228(
229 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000230 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000231 lldb::InputReaderAction notification,
232 const char *bytes,
233 size_t bytes_len
234)
235{
Chris Lattner24943d22010-06-08 16:52:24 +0000236 CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
Caroline Tice892fadd2011-06-16 16:27:19 +0000237 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
238
Chris Lattner24943d22010-06-08 16:52:24 +0000239 switch (notification)
240 {
241 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +0000242 if (!batch_mode)
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000243 {
Greg Clayton234981a2011-07-20 03:41:06 +0000244 StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
245 if (async_strm_sp)
246 {
247 async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
248 async_strm_sp->Flush();
249 }
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000250 }
Chris Lattner24943d22010-06-08 16:52:24 +0000251 // Fall through
252 case eInputReaderReactivate:
Chris Lattner24943d22010-06-08 16:52:24 +0000253 break;
254
255 case eInputReaderDeactivate:
256 break;
257
Caroline Tice4a348082011-05-02 20:41:46 +0000258 case eInputReaderAsynchronousOutputWritten:
259 break;
260
Chris Lattner24943d22010-06-08 16:52:24 +0000261 case eInputReaderGotToken:
262 ++cmd_object_expr->m_expr_line_count;
263 if (bytes && bytes_len)
264 {
265 cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
266 }
267
268 if (bytes_len == 0)
Greg Clayton63094e02010-06-23 01:19:29 +0000269 reader.SetIsDone(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000270 break;
271
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000272 case eInputReaderInterrupt:
273 cmd_object_expr->m_expr_lines.clear();
274 reader.SetIsDone (true);
Caroline Tice892fadd2011-06-16 16:27:19 +0000275 if (!batch_mode)
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000276 {
Greg Clayton234981a2011-07-20 03:41:06 +0000277 StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
278 if (async_strm_sp)
279 {
280 async_strm_sp->PutCString("Expression evaluation cancelled.\n");
281 async_strm_sp->Flush();
282 }
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000283 }
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000284 break;
285
286 case eInputReaderEndOfFile:
287 reader.SetIsDone (true);
288 break;
289
Chris Lattner24943d22010-06-08 16:52:24 +0000290 case eInputReaderDone:
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000291 if (cmd_object_expr->m_expr_lines.size() > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000292 {
Caroline Tice87e1f772011-06-13 20:20:29 +0000293 StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
294 StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
Chris Lattner24943d22010-06-08 16:52:24 +0000295 cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
Caroline Tice87e1f772011-06-13 20:20:29 +0000296 output_stream.get(),
297 error_stream.get());
298 output_stream->Flush();
299 error_stream->Flush();
Chris Lattner24943d22010-06-08 16:52:24 +0000300 }
301 break;
302 }
303
304 return bytes_len;
305}
306
307bool
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000308CommandObjectExpression::EvaluateExpression
309(
310 const char *expr,
Caroline Tice87e1f772011-06-13 20:20:29 +0000311 Stream *output_stream,
312 Stream *error_stream,
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000313 CommandReturnObject *result
314)
Chris Lattner24943d22010-06-08 16:52:24 +0000315{
Greg Claytonf75e3912012-01-27 18:18:23 +0000316 Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
Sean Callananf35a96c2011-10-27 21:22:25 +0000317
318 if (!target)
319 target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
320
Greg Clayton567e7f32011-09-22 04:58:26 +0000321 if (target)
Chris Lattner24943d22010-06-08 16:52:24 +0000322 {
Greg Clayton427f2902010-12-14 02:59:59 +0000323 lldb::ValueObjectSP result_valobj_sp;
Greg Clayton11730f32010-10-06 03:09:11 +0000324
Greg Claytonb3448432011-03-24 21:19:54 +0000325 ExecutionResults exe_results;
Sean Callanan6a925532011-01-13 08:53:35 +0000326
327 bool keep_in_memory = true;
Jim Ingham10de7d12011-05-04 03:43:18 +0000328 lldb::DynamicValueType use_dynamic;
Jim Inghame41494a2011-04-16 00:01:13 +0000329 // If use dynamic is not set, get it from the target:
Greg Claytona42880a2011-10-25 06:44:01 +0000330 switch (m_command_options.use_dynamic)
Jim Inghame41494a2011-04-16 00:01:13 +0000331 {
332 case eLazyBoolCalculate:
Greg Clayton567e7f32011-09-22 04:58:26 +0000333 use_dynamic = target->GetPreferDynamicValue();
Jim Inghame41494a2011-04-16 00:01:13 +0000334 break;
335 case eLazyBoolYes:
Jim Ingham10de7d12011-05-04 03:43:18 +0000336 use_dynamic = lldb::eDynamicCanRunTarget;
Jim Inghame41494a2011-04-16 00:01:13 +0000337 break;
338 case eLazyBoolNo:
Jim Ingham10de7d12011-05-04 03:43:18 +0000339 use_dynamic = lldb::eNoDynamicValues;
Jim Inghame41494a2011-04-16 00:01:13 +0000340 break;
341 }
Sean Callanan6a925532011-01-13 08:53:35 +0000342
Jim Ingham47beabb2012-10-16 21:41:58 +0000343 EvaluateExpressionOptions options;
Enrico Granatad27026e2012-09-05 20:41:26 +0000344 options.SetCoerceToId(m_command_options.print_object)
345 .SetUnwindOnError(m_command_options.unwind_on_error)
346 .SetKeepInMemory(keep_in_memory)
347 .SetUseDynamic(use_dynamic)
Jim Ingham47beabb2012-10-16 21:41:58 +0000348 .SetRunOthers(m_command_options.try_all_threads)
349 .SetTimeoutUsec(m_command_options.timeout);
Enrico Granatad27026e2012-09-05 20:41:26 +0000350
Greg Clayton567e7f32011-09-22 04:58:26 +0000351 exe_results = target->EvaluateExpression (expr,
Greg Claytonf75e3912012-01-27 18:18:23 +0000352 m_interpreter.GetExecutionContext().GetFramePtr(),
Enrico Granata6cca9692012-07-16 23:10:35 +0000353 result_valobj_sp,
Enrico Granatad27026e2012-09-05 20:41:26 +0000354 options);
Greg Clayton427f2902010-12-14 02:59:59 +0000355
Greg Claytona42880a2011-10-25 06:44:01 +0000356 if (exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error)
Jim Ingham360f53f2010-11-30 02:22:11 +0000357 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000358 uint32_t start_frame = 0;
359 uint32_t num_frames = 1;
360 uint32_t num_frames_with_source = 0;
Greg Claytonf75e3912012-01-27 18:18:23 +0000361 Thread *thread = m_interpreter.GetExecutionContext().GetThreadPtr();
Greg Clayton567e7f32011-09-22 04:58:26 +0000362 if (thread)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000363 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000364 thread->GetStatus (result->GetOutputStream(),
365 start_frame,
366 num_frames,
367 num_frames_with_source);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000368 }
Greg Clayton567e7f32011-09-22 04:58:26 +0000369 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000370 {
Greg Claytonf75e3912012-01-27 18:18:23 +0000371 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton567e7f32011-09-22 04:58:26 +0000372 if (process)
373 {
374 bool only_threads_with_stop_reason = true;
375 process->GetThreadStatus (result->GetOutputStream(),
376 only_threads_with_stop_reason,
377 start_frame,
378 num_frames,
379 num_frames_with_source);
380 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000381 }
Greg Clayton427f2902010-12-14 02:59:59 +0000382 }
Sean Callanan96abc622012-08-08 17:35:10 +0000383
Greg Clayton427f2902010-12-14 02:59:59 +0000384 if (result_valobj_sp)
385 {
Sean Callanan96abc622012-08-08 17:35:10 +0000386 Format format = m_format_options.GetFormat();
387
Greg Clayton427f2902010-12-14 02:59:59 +0000388 if (result_valobj_sp->GetError().Success())
389 {
Sean Callanan96abc622012-08-08 17:35:10 +0000390 if (format != eFormatVoid)
391 {
392 if (format != eFormatDefault)
393 result_valobj_sp->SetFormat (format);
Greg Clayton427f2902010-12-14 02:59:59 +0000394
Sean Callanan96abc622012-08-08 17:35:10 +0000395 ValueObject::DumpValueObjectOptions options;
396 options.SetMaximumPointerDepth(0)
397 .SetMaximumDepth(UINT32_MAX)
398 .SetShowLocation(false)
399 .SetShowTypes(m_command_options.show_types)
400 .SetUseObjectiveC(m_command_options.print_object)
401 .SetUseDynamicType(use_dynamic)
402 .SetScopeChecked(true)
403 .SetFlatOutput(false)
404 .SetUseSyntheticValue(true)
405 .SetIgnoreCap(false)
406 .SetFormat(format)
407 .SetSummary()
Enrico Granata12213582012-08-09 16:51:25 +0000408 .SetShowSummary(!m_command_options.print_object)
409 .SetHideRootType(m_command_options.print_object);
Sean Callanan96abc622012-08-08 17:35:10 +0000410
411 ValueObject::DumpValueObject (*(output_stream),
412 result_valobj_sp.get(), // Variable object to dump
413 options);
414 if (result)
415 result->SetStatus (eReturnStatusSuccessFinishResult);
416 }
Greg Clayton427f2902010-12-14 02:59:59 +0000417 }
418 else
419 {
Sean Callanan24312442011-08-23 21:20:51 +0000420 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000421 {
Sean Callanan1e1e6cb2012-08-09 18:18:47 +0000422 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
Sean Callanan96abc622012-08-08 17:35:10 +0000423 {
Sean Callanan1e1e6cb2012-08-09 18:18:47 +0000424 error_stream->PutCString("(void)\n");
Sean Callanan96abc622012-08-08 17:35:10 +0000425 }
Sean Callanan1e1e6cb2012-08-09 18:18:47 +0000426
427 if (result)
428 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000429 }
430 else
431 {
Sean Callanan24312442011-08-23 21:20:51 +0000432 const char *error_cstr = result_valobj_sp->GetError().AsCString();
433 if (error_cstr && error_cstr[0])
434 {
435 int error_cstr_len = strlen (error_cstr);
436 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
437 if (strstr(error_cstr, "error:") != error_cstr)
438 error_stream->PutCString ("error: ");
439 error_stream->Write(error_cstr, error_cstr_len);
440 if (!ends_with_newline)
441 error_stream->EOL();
442 }
443 else
444 {
445 error_stream->PutCString ("error: unknown error\n");
446 }
447
448 if (result)
449 result->SetStatus (eReturnStatusFailed);
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000450 }
Jim Ingham360f53f2010-11-30 02:22:11 +0000451 }
452 }
Greg Clayton427f2902010-12-14 02:59:59 +0000453 }
454 else
455 {
Caroline Tice87e1f772011-06-13 20:20:29 +0000456 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton427f2902010-12-14 02:59:59 +0000457 return false;
Sean Callanan841026f2010-07-23 00:16:21 +0000458 }
Sean Callanan82b74c82010-08-12 01:56:52 +0000459
Sean Callanan841026f2010-07-23 00:16:21 +0000460 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000461}
462
463bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000464CommandObjectExpression::DoExecute
Chris Lattner24943d22010-06-08 16:52:24 +0000465(
466 const char *command,
Chris Lattner24943d22010-06-08 16:52:24 +0000467 CommandReturnObject &result
468)
469{
Greg Claytona42880a2011-10-25 06:44:01 +0000470 m_option_group.NotifyOptionParsingStarting();
Chris Lattner24943d22010-06-08 16:52:24 +0000471
472 const char * expr = NULL;
473
474 if (command[0] == '\0')
475 {
476 m_expr_lines.clear();
477 m_expr_line_count = 0;
478
Greg Clayton238c0a12010-09-18 01:14:36 +0000479 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
Chris Lattner24943d22010-06-08 16:52:24 +0000480 if (reader_sp)
481 {
482 Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
483 this, // baton
484 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton63094e02010-06-23 01:19:29 +0000485 NULL, // end token
Chris Lattner24943d22010-06-08 16:52:24 +0000486 NULL, // prompt
487 true)); // echo input
488 if (err.Success())
489 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000490 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000491 result.SetStatus (eReturnStatusSuccessFinishNoResult);
492 }
493 else
494 {
495 result.AppendError (err.AsCString());
496 result.SetStatus (eReturnStatusFailed);
497 }
498 }
499 else
500 {
501 result.AppendError("out of memory");
502 result.SetStatus (eReturnStatusFailed);
503 }
504 return result.Succeeded();
505 }
506
507 if (command[0] == '-')
508 {
509 // We have some options and these options MUST end with --.
510 const char *end_options = NULL;
511 const char *s = command;
512 while (s && s[0])
513 {
514 end_options = ::strstr (s, "--");
515 if (end_options)
516 {
517 end_options += 2; // Get past the "--"
518 if (::isspace (end_options[0]))
519 {
520 expr = end_options;
521 while (::isspace (*expr))
522 ++expr;
523 break;
524 }
525 }
526 s = end_options;
527 }
528
529 if (end_options)
530 {
Greg Clayton63094e02010-06-23 01:19:29 +0000531 Args args (command, end_options - command);
Greg Clayton238c0a12010-09-18 01:14:36 +0000532 if (!ParseOptions (args, result))
Chris Lattner24943d22010-06-08 16:52:24 +0000533 return false;
Greg Clayton143fcc32011-04-13 00:18:08 +0000534
Greg Claytona42880a2011-10-25 06:44:01 +0000535 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Clayton143fcc32011-04-13 00:18:08 +0000536 if (error.Fail())
537 {
538 result.AppendError (error.AsCString());
539 result.SetStatus (eReturnStatusFailed);
540 return false;
541 }
Chris Lattner24943d22010-06-08 16:52:24 +0000542 }
543 }
544
Chris Lattner24943d22010-06-08 16:52:24 +0000545 if (expr == NULL)
546 expr = command;
Sean Callanan46b62492010-06-24 00:16:27 +0000547
Caroline Tice87e1f772011-06-13 20:20:29 +0000548 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Johnny Chen0deefc72010-08-13 00:42:30 +0000549 return true;
550
551 result.SetStatus (eReturnStatusFailed);
552 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000553}
554