blob: ee053608e7c5528444387803f802dd7eaa81cfd0 [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",
167 "Evaluate a C/ObjC/C++ expression in the current program context, using variables currently in scope.",
168 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\
183Examples: \n\
Chris Lattner24943d22010-06-08 16:52:24 +0000184\n\
185 expr my_struct->a = my_array[3] \n\
186 expr -f bin -- (index * 8) + 5 \n\
187 expr char c[] = \"foo\"; c[0]\n");
Caroline Tice43b014a2010-10-04 22:28:36 +0000188
189 CommandArgumentEntry arg;
190 CommandArgumentData expression_arg;
191
192 // Define the first (and only) variant of this arg.
193 expression_arg.arg_type = eArgTypeExpression;
194 expression_arg.arg_repetition = eArgRepeatPlain;
195
196 // There is only one variant this argument could be; put it into the argument entry.
197 arg.push_back (expression_arg);
198
199 // Push the data for the first argument into the m_arguments vector.
200 m_arguments.push_back (arg);
Greg Claytona42880a2011-10-25 06:44:01 +0000201
Greg Clayton24a6bd92011-10-27 17:55:14 +0000202 // Add the "--format" and "--gdb-format"
203 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 +0000204 m_option_group.Append (&m_command_options);
205 m_option_group.Finalize();
Chris Lattner24943d22010-06-08 16:52:24 +0000206}
207
208CommandObjectExpression::~CommandObjectExpression ()
209{
210}
211
212Options *
213CommandObjectExpression::GetOptions ()
214{
Greg Claytona42880a2011-10-25 06:44:01 +0000215 return &m_option_group;
Chris Lattner24943d22010-06-08 16:52:24 +0000216}
217
Chris Lattner24943d22010-06-08 16:52:24 +0000218size_t
219CommandObjectExpression::MultiLineExpressionCallback
220(
221 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000222 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000223 lldb::InputReaderAction notification,
224 const char *bytes,
225 size_t bytes_len
226)
227{
Chris Lattner24943d22010-06-08 16:52:24 +0000228 CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
Caroline Tice892fadd2011-06-16 16:27:19 +0000229 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
230
Chris Lattner24943d22010-06-08 16:52:24 +0000231 switch (notification)
232 {
233 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +0000234 if (!batch_mode)
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000235 {
Greg Clayton234981a2011-07-20 03:41:06 +0000236 StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
237 if (async_strm_sp)
238 {
239 async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
240 async_strm_sp->Flush();
241 }
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000242 }
Chris Lattner24943d22010-06-08 16:52:24 +0000243 // Fall through
244 case eInputReaderReactivate:
Chris Lattner24943d22010-06-08 16:52:24 +0000245 break;
246
247 case eInputReaderDeactivate:
248 break;
249
Caroline Tice4a348082011-05-02 20:41:46 +0000250 case eInputReaderAsynchronousOutputWritten:
251 break;
252
Chris Lattner24943d22010-06-08 16:52:24 +0000253 case eInputReaderGotToken:
254 ++cmd_object_expr->m_expr_line_count;
255 if (bytes && bytes_len)
256 {
257 cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
258 }
259
260 if (bytes_len == 0)
Greg Clayton63094e02010-06-23 01:19:29 +0000261 reader.SetIsDone(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000262 break;
263
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000264 case eInputReaderInterrupt:
265 cmd_object_expr->m_expr_lines.clear();
266 reader.SetIsDone (true);
Caroline Tice892fadd2011-06-16 16:27:19 +0000267 if (!batch_mode)
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000268 {
Greg Clayton234981a2011-07-20 03:41:06 +0000269 StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
270 if (async_strm_sp)
271 {
272 async_strm_sp->PutCString("Expression evaluation cancelled.\n");
273 async_strm_sp->Flush();
274 }
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000275 }
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000276 break;
277
278 case eInputReaderEndOfFile:
279 reader.SetIsDone (true);
280 break;
281
Chris Lattner24943d22010-06-08 16:52:24 +0000282 case eInputReaderDone:
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000283 if (cmd_object_expr->m_expr_lines.size() > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000284 {
Caroline Tice87e1f772011-06-13 20:20:29 +0000285 StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
286 StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
Chris Lattner24943d22010-06-08 16:52:24 +0000287 cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
Caroline Tice87e1f772011-06-13 20:20:29 +0000288 output_stream.get(),
289 error_stream.get());
290 output_stream->Flush();
291 error_stream->Flush();
Chris Lattner24943d22010-06-08 16:52:24 +0000292 }
293 break;
294 }
295
296 return bytes_len;
297}
298
299bool
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000300CommandObjectExpression::EvaluateExpression
301(
302 const char *expr,
Caroline Tice87e1f772011-06-13 20:20:29 +0000303 Stream *output_stream,
304 Stream *error_stream,
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000305 CommandReturnObject *result
306)
Chris Lattner24943d22010-06-08 16:52:24 +0000307{
Greg Claytonf75e3912012-01-27 18:18:23 +0000308 Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
Sean Callananf35a96c2011-10-27 21:22:25 +0000309
310 if (!target)
311 target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
312
Greg Clayton567e7f32011-09-22 04:58:26 +0000313 if (target)
Chris Lattner24943d22010-06-08 16:52:24 +0000314 {
Greg Clayton427f2902010-12-14 02:59:59 +0000315 lldb::ValueObjectSP result_valobj_sp;
Greg Clayton11730f32010-10-06 03:09:11 +0000316
Greg Claytonb3448432011-03-24 21:19:54 +0000317 ExecutionResults exe_results;
Sean Callanan6a925532011-01-13 08:53:35 +0000318
319 bool keep_in_memory = true;
Jim Ingham10de7d12011-05-04 03:43:18 +0000320 lldb::DynamicValueType use_dynamic;
Jim Inghame41494a2011-04-16 00:01:13 +0000321 // If use dynamic is not set, get it from the target:
Greg Claytona42880a2011-10-25 06:44:01 +0000322 switch (m_command_options.use_dynamic)
Jim Inghame41494a2011-04-16 00:01:13 +0000323 {
324 case eLazyBoolCalculate:
Greg Clayton567e7f32011-09-22 04:58:26 +0000325 use_dynamic = target->GetPreferDynamicValue();
Jim Inghame41494a2011-04-16 00:01:13 +0000326 break;
327 case eLazyBoolYes:
Jim Ingham10de7d12011-05-04 03:43:18 +0000328 use_dynamic = lldb::eDynamicCanRunTarget;
Jim Inghame41494a2011-04-16 00:01:13 +0000329 break;
330 case eLazyBoolNo:
Jim Ingham10de7d12011-05-04 03:43:18 +0000331 use_dynamic = lldb::eNoDynamicValues;
Jim Inghame41494a2011-04-16 00:01:13 +0000332 break;
333 }
Sean Callanan6a925532011-01-13 08:53:35 +0000334
Jim Ingham47beabb2012-10-16 21:41:58 +0000335 EvaluateExpressionOptions options;
Enrico Granatad27026e2012-09-05 20:41:26 +0000336 options.SetCoerceToId(m_command_options.print_object)
337 .SetUnwindOnError(m_command_options.unwind_on_error)
338 .SetKeepInMemory(keep_in_memory)
339 .SetUseDynamic(use_dynamic)
Jim Ingham47beabb2012-10-16 21:41:58 +0000340 .SetRunOthers(m_command_options.try_all_threads)
341 .SetTimeoutUsec(m_command_options.timeout);
Enrico Granatad27026e2012-09-05 20:41:26 +0000342
Greg Clayton567e7f32011-09-22 04:58:26 +0000343 exe_results = target->EvaluateExpression (expr,
Greg Claytonf75e3912012-01-27 18:18:23 +0000344 m_interpreter.GetExecutionContext().GetFramePtr(),
Enrico Granata6cca9692012-07-16 23:10:35 +0000345 result_valobj_sp,
Enrico Granatad27026e2012-09-05 20:41:26 +0000346 options);
Greg Clayton427f2902010-12-14 02:59:59 +0000347
Greg Claytona42880a2011-10-25 06:44:01 +0000348 if (exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error)
Jim Ingham360f53f2010-11-30 02:22:11 +0000349 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000350 uint32_t start_frame = 0;
351 uint32_t num_frames = 1;
352 uint32_t num_frames_with_source = 0;
Greg Claytonf75e3912012-01-27 18:18:23 +0000353 Thread *thread = m_interpreter.GetExecutionContext().GetThreadPtr();
Greg Clayton567e7f32011-09-22 04:58:26 +0000354 if (thread)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000355 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000356 thread->GetStatus (result->GetOutputStream(),
357 start_frame,
358 num_frames,
359 num_frames_with_source);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000360 }
Greg Clayton567e7f32011-09-22 04:58:26 +0000361 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000362 {
Greg Claytonf75e3912012-01-27 18:18:23 +0000363 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
Greg Clayton567e7f32011-09-22 04:58:26 +0000364 if (process)
365 {
366 bool only_threads_with_stop_reason = true;
367 process->GetThreadStatus (result->GetOutputStream(),
368 only_threads_with_stop_reason,
369 start_frame,
370 num_frames,
371 num_frames_with_source);
372 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000373 }
Greg Clayton427f2902010-12-14 02:59:59 +0000374 }
Sean Callanan96abc622012-08-08 17:35:10 +0000375
Greg Clayton427f2902010-12-14 02:59:59 +0000376 if (result_valobj_sp)
377 {
Sean Callanan96abc622012-08-08 17:35:10 +0000378 Format format = m_format_options.GetFormat();
379
Greg Clayton427f2902010-12-14 02:59:59 +0000380 if (result_valobj_sp->GetError().Success())
381 {
Sean Callanan96abc622012-08-08 17:35:10 +0000382 if (format != eFormatVoid)
383 {
384 if (format != eFormatDefault)
385 result_valobj_sp->SetFormat (format);
Greg Clayton427f2902010-12-14 02:59:59 +0000386
Sean Callanan96abc622012-08-08 17:35:10 +0000387 ValueObject::DumpValueObjectOptions options;
388 options.SetMaximumPointerDepth(0)
389 .SetMaximumDepth(UINT32_MAX)
390 .SetShowLocation(false)
391 .SetShowTypes(m_command_options.show_types)
392 .SetUseObjectiveC(m_command_options.print_object)
393 .SetUseDynamicType(use_dynamic)
394 .SetScopeChecked(true)
395 .SetFlatOutput(false)
396 .SetUseSyntheticValue(true)
397 .SetIgnoreCap(false)
398 .SetFormat(format)
399 .SetSummary()
Enrico Granata12213582012-08-09 16:51:25 +0000400 .SetShowSummary(!m_command_options.print_object)
401 .SetHideRootType(m_command_options.print_object);
Sean Callanan96abc622012-08-08 17:35:10 +0000402
403 ValueObject::DumpValueObject (*(output_stream),
404 result_valobj_sp.get(), // Variable object to dump
405 options);
406 if (result)
407 result->SetStatus (eReturnStatusSuccessFinishResult);
408 }
Greg Clayton427f2902010-12-14 02:59:59 +0000409 }
410 else
411 {
Sean Callanan24312442011-08-23 21:20:51 +0000412 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000413 {
Sean Callanan1e1e6cb2012-08-09 18:18:47 +0000414 if (format != eFormatVoid && m_interpreter.GetDebugger().GetNotifyVoid())
Sean Callanan96abc622012-08-08 17:35:10 +0000415 {
Sean Callanan1e1e6cb2012-08-09 18:18:47 +0000416 error_stream->PutCString("(void)\n");
Sean Callanan96abc622012-08-08 17:35:10 +0000417 }
Sean Callanan1e1e6cb2012-08-09 18:18:47 +0000418
419 if (result)
420 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000421 }
422 else
423 {
Sean Callanan24312442011-08-23 21:20:51 +0000424 const char *error_cstr = result_valobj_sp->GetError().AsCString();
425 if (error_cstr && error_cstr[0])
426 {
427 int error_cstr_len = strlen (error_cstr);
428 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
429 if (strstr(error_cstr, "error:") != error_cstr)
430 error_stream->PutCString ("error: ");
431 error_stream->Write(error_cstr, error_cstr_len);
432 if (!ends_with_newline)
433 error_stream->EOL();
434 }
435 else
436 {
437 error_stream->PutCString ("error: unknown error\n");
438 }
439
440 if (result)
441 result->SetStatus (eReturnStatusFailed);
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000442 }
Jim Ingham360f53f2010-11-30 02:22:11 +0000443 }
444 }
Greg Clayton427f2902010-12-14 02:59:59 +0000445 }
446 else
447 {
Caroline Tice87e1f772011-06-13 20:20:29 +0000448 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton427f2902010-12-14 02:59:59 +0000449 return false;
Sean Callanan841026f2010-07-23 00:16:21 +0000450 }
Sean Callanan82b74c82010-08-12 01:56:52 +0000451
Sean Callanan841026f2010-07-23 00:16:21 +0000452 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000453}
454
455bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000456CommandObjectExpression::DoExecute
Chris Lattner24943d22010-06-08 16:52:24 +0000457(
458 const char *command,
Chris Lattner24943d22010-06-08 16:52:24 +0000459 CommandReturnObject &result
460)
461{
Greg Claytona42880a2011-10-25 06:44:01 +0000462 m_option_group.NotifyOptionParsingStarting();
Chris Lattner24943d22010-06-08 16:52:24 +0000463
464 const char * expr = NULL;
465
466 if (command[0] == '\0')
467 {
468 m_expr_lines.clear();
469 m_expr_line_count = 0;
470
Greg Clayton238c0a12010-09-18 01:14:36 +0000471 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
Chris Lattner24943d22010-06-08 16:52:24 +0000472 if (reader_sp)
473 {
474 Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
475 this, // baton
476 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton63094e02010-06-23 01:19:29 +0000477 NULL, // end token
Chris Lattner24943d22010-06-08 16:52:24 +0000478 NULL, // prompt
479 true)); // echo input
480 if (err.Success())
481 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000482 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000483 result.SetStatus (eReturnStatusSuccessFinishNoResult);
484 }
485 else
486 {
487 result.AppendError (err.AsCString());
488 result.SetStatus (eReturnStatusFailed);
489 }
490 }
491 else
492 {
493 result.AppendError("out of memory");
494 result.SetStatus (eReturnStatusFailed);
495 }
496 return result.Succeeded();
497 }
498
499 if (command[0] == '-')
500 {
501 // We have some options and these options MUST end with --.
502 const char *end_options = NULL;
503 const char *s = command;
504 while (s && s[0])
505 {
506 end_options = ::strstr (s, "--");
507 if (end_options)
508 {
509 end_options += 2; // Get past the "--"
510 if (::isspace (end_options[0]))
511 {
512 expr = end_options;
513 while (::isspace (*expr))
514 ++expr;
515 break;
516 }
517 }
518 s = end_options;
519 }
520
521 if (end_options)
522 {
Greg Clayton63094e02010-06-23 01:19:29 +0000523 Args args (command, end_options - command);
Greg Clayton238c0a12010-09-18 01:14:36 +0000524 if (!ParseOptions (args, result))
Chris Lattner24943d22010-06-08 16:52:24 +0000525 return false;
Greg Clayton143fcc32011-04-13 00:18:08 +0000526
Greg Claytona42880a2011-10-25 06:44:01 +0000527 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Clayton143fcc32011-04-13 00:18:08 +0000528 if (error.Fail())
529 {
530 result.AppendError (error.AsCString());
531 result.SetStatus (eReturnStatusFailed);
532 return false;
533 }
Chris Lattner24943d22010-06-08 16:52:24 +0000534 }
535 }
536
Chris Lattner24943d22010-06-08 16:52:24 +0000537 if (expr == NULL)
538 expr = command;
Sean Callanan46b62492010-06-24 00:16:27 +0000539
Caroline Tice87e1f772011-06-13 20:20:29 +0000540 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Johnny Chen0deefc72010-08-13 00:42:30 +0000541 return true;
542
543 result.SetStatus (eReturnStatusFailed);
544 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000545}
546