blob: e2ce4b2cf89fe521c5ed7b31e77ce43551826916 [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{
53 { 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."},
54 { 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."},
55 { LLDB_OPT_SET_2 , false, "object-description", 'o', no_argument, NULL, 0, eArgTypeNone, "Print the object description of the value resulting from the expression."},
56};
57
58
59uint32_t
60CommandObjectExpression::CommandOptions::GetNumDefinitions ()
61{
62 return sizeof(g_option_table)/sizeof(OptionDefinition);
63}
64
Chris Lattner24943d22010-06-08 16:52:24 +000065Error
Greg Claytona42880a2011-10-25 06:44:01 +000066CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
67 uint32_t option_idx,
68 const char *option_arg)
Chris Lattner24943d22010-06-08 16:52:24 +000069{
70 Error error;
71
Greg Claytona42880a2011-10-25 06:44:01 +000072 const char short_option = (char) g_option_table[option_idx].short_option;
Chris Lattner24943d22010-06-08 16:52:24 +000073
74 switch (short_option)
75 {
Caroline Ticec1ad82e2010-09-07 22:38:08 +000076 //case 'l':
77 //if (language.SetLanguageFromCString (option_arg) == false)
78 //{
Greg Clayton9c236732011-10-26 00:56:27 +000079 // error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
Caroline Ticec1ad82e2010-09-07 22:38:08 +000080 //}
81 //break;
Chris Lattner24943d22010-06-08 16:52:24 +000082
Jim Ingham324067b2010-09-30 00:54:27 +000083 case 'o':
84 print_object = true;
85 break;
Jim Inghamea9d4262010-11-05 19:25:48 +000086
Jim Inghame41494a2011-04-16 00:01:13 +000087 case 'd':
88 {
89 bool success;
90 bool result;
91 result = Args::StringToBoolean(option_arg, true, &success);
92 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +000093 error.SetErrorStringWithFormat("invalid dynamic value setting: \"%s\"", option_arg);
Jim Inghame41494a2011-04-16 00:01:13 +000094 else
95 {
96 if (result)
Greg Clayton82f07462011-05-30 00:49:24 +000097 use_dynamic = eLazyBoolYes;
Jim Inghame41494a2011-04-16 00:01:13 +000098 else
99 use_dynamic = eLazyBoolNo;
100 }
101 }
102 break;
103
Jim Inghamea9d4262010-11-05 19:25:48 +0000104 case 'u':
Sean Callanan47dc4572011-09-15 02:13:07 +0000105 {
106 bool success;
107 unwind_on_error = Args::StringToBoolean(option_arg, true, &success);
108 if (!success)
Greg Clayton9c236732011-10-26 00:56:27 +0000109 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
Sean Callanan47dc4572011-09-15 02:13:07 +0000110 break;
111 }
Chris Lattner24943d22010-06-08 16:52:24 +0000112 default:
Greg Clayton9c236732011-10-26 00:56:27 +0000113 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Chris Lattner24943d22010-06-08 16:52:24 +0000114 break;
115 }
116
117 return error;
118}
119
120void
Greg Claytona42880a2011-10-25 06:44:01 +0000121CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
Chris Lattner24943d22010-06-08 16:52:24 +0000122{
Jim Inghame41494a2011-04-16 00:01:13 +0000123 use_dynamic = eLazyBoolCalculate;
Greg Claytona42880a2011-10-25 06:44:01 +0000124 print_object = false;
Jim Inghamea9d4262010-11-05 19:25:48 +0000125 unwind_on_error = true;
Chris Lattner24943d22010-06-08 16:52:24 +0000126 show_types = true;
127 show_summary = true;
128}
129
Greg Claytonb3448432011-03-24 21:19:54 +0000130const OptionDefinition*
Chris Lattner24943d22010-06-08 16:52:24 +0000131CommandObjectExpression::CommandOptions::GetDefinitions ()
132{
133 return g_option_table;
134}
135
Greg Clayton238c0a12010-09-18 01:14:36 +0000136CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
137 CommandObject (interpreter,
138 "expression",
Johnny Chen106a7372010-09-30 18:16:58 +0000139 "Evaluate a C/ObjC/C++ expression in the current program context, using variables currently in scope.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000140 NULL),
Greg Claytona42880a2011-10-25 06:44:01 +0000141 m_option_group (interpreter),
142 m_format_options (eFormatDefault),
143 m_command_options (),
Johnny Chencc112ac2010-09-30 18:30:25 +0000144 m_expr_line_count (0),
Chris Lattner24943d22010-06-08 16:52:24 +0000145 m_expr_lines ()
146{
147 SetHelpLong(
148"Examples: \n\
149\n\
150 expr my_struct->a = my_array[3] \n\
151 expr -f bin -- (index * 8) + 5 \n\
152 expr char c[] = \"foo\"; c[0]\n");
Caroline Tice43b014a2010-10-04 22:28:36 +0000153
154 CommandArgumentEntry arg;
155 CommandArgumentData expression_arg;
156
157 // Define the first (and only) variant of this arg.
158 expression_arg.arg_type = eArgTypeExpression;
159 expression_arg.arg_repetition = eArgRepeatPlain;
160
161 // There is only one variant this argument could be; put it into the argument entry.
162 arg.push_back (expression_arg);
163
164 // Push the data for the first argument into the m_arguments vector.
165 m_arguments.push_back (arg);
Greg Claytona42880a2011-10-25 06:44:01 +0000166
Greg Clayton24a6bd92011-10-27 17:55:14 +0000167 // Add the "--format" and "--gdb-format"
168 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 +0000169 m_option_group.Append (&m_command_options);
170 m_option_group.Finalize();
Chris Lattner24943d22010-06-08 16:52:24 +0000171}
172
173CommandObjectExpression::~CommandObjectExpression ()
174{
175}
176
177Options *
178CommandObjectExpression::GetOptions ()
179{
Greg Claytona42880a2011-10-25 06:44:01 +0000180 return &m_option_group;
Chris Lattner24943d22010-06-08 16:52:24 +0000181}
182
183
184bool
185CommandObjectExpression::Execute
186(
187 Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000188 CommandReturnObject &result
189)
190{
191 return false;
192}
193
194
195size_t
196CommandObjectExpression::MultiLineExpressionCallback
197(
198 void *baton,
Greg Clayton63094e02010-06-23 01:19:29 +0000199 InputReader &reader,
Chris Lattner24943d22010-06-08 16:52:24 +0000200 lldb::InputReaderAction notification,
201 const char *bytes,
202 size_t bytes_len
203)
204{
Chris Lattner24943d22010-06-08 16:52:24 +0000205 CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
Caroline Tice892fadd2011-06-16 16:27:19 +0000206 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
207
Chris Lattner24943d22010-06-08 16:52:24 +0000208 switch (notification)
209 {
210 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +0000211 if (!batch_mode)
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000212 {
Greg Clayton234981a2011-07-20 03:41:06 +0000213 StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
214 if (async_strm_sp)
215 {
216 async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
217 async_strm_sp->Flush();
218 }
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000219 }
Chris Lattner24943d22010-06-08 16:52:24 +0000220 // Fall through
221 case eInputReaderReactivate:
Chris Lattner24943d22010-06-08 16:52:24 +0000222 break;
223
224 case eInputReaderDeactivate:
225 break;
226
Caroline Tice4a348082011-05-02 20:41:46 +0000227 case eInputReaderAsynchronousOutputWritten:
228 break;
229
Chris Lattner24943d22010-06-08 16:52:24 +0000230 case eInputReaderGotToken:
231 ++cmd_object_expr->m_expr_line_count;
232 if (bytes && bytes_len)
233 {
234 cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
235 }
236
237 if (bytes_len == 0)
Greg Clayton63094e02010-06-23 01:19:29 +0000238 reader.SetIsDone(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000239 break;
240
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000241 case eInputReaderInterrupt:
242 cmd_object_expr->m_expr_lines.clear();
243 reader.SetIsDone (true);
Caroline Tice892fadd2011-06-16 16:27:19 +0000244 if (!batch_mode)
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000245 {
Greg Clayton234981a2011-07-20 03:41:06 +0000246 StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
247 if (async_strm_sp)
248 {
249 async_strm_sp->PutCString("Expression evaluation cancelled.\n");
250 async_strm_sp->Flush();
251 }
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000252 }
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000253 break;
254
255 case eInputReaderEndOfFile:
256 reader.SetIsDone (true);
257 break;
258
Chris Lattner24943d22010-06-08 16:52:24 +0000259 case eInputReaderDone:
Caroline Ticec4f55fe2010-11-19 20:47:54 +0000260 if (cmd_object_expr->m_expr_lines.size() > 0)
Chris Lattner24943d22010-06-08 16:52:24 +0000261 {
Caroline Tice87e1f772011-06-13 20:20:29 +0000262 StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
263 StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
Chris Lattner24943d22010-06-08 16:52:24 +0000264 cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
Caroline Tice87e1f772011-06-13 20:20:29 +0000265 output_stream.get(),
266 error_stream.get());
267 output_stream->Flush();
268 error_stream->Flush();
Chris Lattner24943d22010-06-08 16:52:24 +0000269 }
270 break;
271 }
272
273 return bytes_len;
274}
275
276bool
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000277CommandObjectExpression::EvaluateExpression
278(
279 const char *expr,
Caroline Tice87e1f772011-06-13 20:20:29 +0000280 Stream *output_stream,
281 Stream *error_stream,
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000282 CommandReturnObject *result
283)
Chris Lattner24943d22010-06-08 16:52:24 +0000284{
Greg Clayton567e7f32011-09-22 04:58:26 +0000285 Target *target = m_exe_ctx.GetTargetPtr();
Sean Callananf35a96c2011-10-27 21:22:25 +0000286
287 if (!target)
288 target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
289
Greg Clayton567e7f32011-09-22 04:58:26 +0000290 if (target)
Chris Lattner24943d22010-06-08 16:52:24 +0000291 {
Greg Clayton427f2902010-12-14 02:59:59 +0000292 lldb::ValueObjectSP result_valobj_sp;
Greg Clayton11730f32010-10-06 03:09:11 +0000293
Greg Claytonb3448432011-03-24 21:19:54 +0000294 ExecutionResults exe_results;
Sean Callanan6a925532011-01-13 08:53:35 +0000295
296 bool keep_in_memory = true;
Jim Ingham10de7d12011-05-04 03:43:18 +0000297 lldb::DynamicValueType use_dynamic;
Jim Inghame41494a2011-04-16 00:01:13 +0000298 // If use dynamic is not set, get it from the target:
Greg Claytona42880a2011-10-25 06:44:01 +0000299 switch (m_command_options.use_dynamic)
Jim Inghame41494a2011-04-16 00:01:13 +0000300 {
301 case eLazyBoolCalculate:
Greg Clayton567e7f32011-09-22 04:58:26 +0000302 use_dynamic = target->GetPreferDynamicValue();
Jim Inghame41494a2011-04-16 00:01:13 +0000303 break;
304 case eLazyBoolYes:
Jim Ingham10de7d12011-05-04 03:43:18 +0000305 use_dynamic = lldb::eDynamicCanRunTarget;
Jim Inghame41494a2011-04-16 00:01:13 +0000306 break;
307 case eLazyBoolNo:
Jim Ingham10de7d12011-05-04 03:43:18 +0000308 use_dynamic = lldb::eNoDynamicValues;
Jim Inghame41494a2011-04-16 00:01:13 +0000309 break;
310 }
Sean Callanan6a925532011-01-13 08:53:35 +0000311
Greg Clayton567e7f32011-09-22 04:58:26 +0000312 exe_results = target->EvaluateExpression (expr,
313 m_exe_ctx.GetFramePtr(),
314 eExecutionPolicyOnlyWhenNeeded,
Sean Callanandaa6efe2011-12-21 22:22:58 +0000315 m_command_options.print_object,
Greg Claytona42880a2011-10-25 06:44:01 +0000316 m_command_options.unwind_on_error,
Greg Clayton567e7f32011-09-22 04:58:26 +0000317 keep_in_memory,
318 use_dynamic,
319 result_valobj_sp);
Greg Clayton427f2902010-12-14 02:59:59 +0000320
Greg Claytona42880a2011-10-25 06:44:01 +0000321 if (exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error)
Jim Ingham360f53f2010-11-30 02:22:11 +0000322 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000323 uint32_t start_frame = 0;
324 uint32_t num_frames = 1;
325 uint32_t num_frames_with_source = 0;
Greg Clayton567e7f32011-09-22 04:58:26 +0000326 Thread *thread = m_exe_ctx.GetThreadPtr();
327 if (thread)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000328 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000329 thread->GetStatus (result->GetOutputStream(),
330 start_frame,
331 num_frames,
332 num_frames_with_source);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000333 }
Greg Clayton567e7f32011-09-22 04:58:26 +0000334 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000335 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000336 Process *process = m_exe_ctx.GetProcessPtr();
337 if (process)
338 {
339 bool only_threads_with_stop_reason = true;
340 process->GetThreadStatus (result->GetOutputStream(),
341 only_threads_with_stop_reason,
342 start_frame,
343 num_frames,
344 num_frames_with_source);
345 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000346 }
Greg Clayton427f2902010-12-14 02:59:59 +0000347 }
348
349 if (result_valobj_sp)
350 {
351 if (result_valobj_sp->GetError().Success())
352 {
Greg Claytona42880a2011-10-25 06:44:01 +0000353 Format format = m_format_options.GetFormat();
354 if (format != eFormatDefault)
355 result_valobj_sp->SetFormat (format);
Greg Clayton427f2902010-12-14 02:59:59 +0000356
Caroline Tice87e1f772011-06-13 20:20:29 +0000357 ValueObject::DumpValueObject (*(output_stream),
Greg Clayton427f2902010-12-14 02:59:59 +0000358 result_valobj_sp.get(), // Variable object to dump
359 result_valobj_sp->GetName().GetCString(),// Root object name
360 0, // Pointer depth to traverse (zero means stop at pointers)
361 0, // Current depth, this is the top most, so zero...
362 UINT32_MAX, // Max depth to go when dumping concrete types, dump everything...
Greg Claytona42880a2011-10-25 06:44:01 +0000363 m_command_options.show_types, // Show types when dumping?
Greg Clayton427f2902010-12-14 02:59:59 +0000364 false, // Show locations of variables, no since this is a host address which we don't care to see
Greg Claytona42880a2011-10-25 06:44:01 +0000365 m_command_options.print_object, // Print the objective C object?
Jim Inghame41494a2011-04-16 00:01:13 +0000366 use_dynamic,
Enrico Granatae4e3e2c2011-07-22 00:16:08 +0000367 true, // Use synthetic children if available
Greg Clayton427f2902010-12-14 02:59:59 +0000368 true, // Scope is already checked. Const results are always in scope.
Enrico Granata7f163b32011-07-16 01:22:04 +0000369 false, // Don't flatten output
Enrico Granata018921d2011-08-12 02:00:06 +0000370 0, // Always use summaries (you might want an option --no-summary like there is for frame variable)
371 false); // Do not show more children than settings allow
Greg Clayton427f2902010-12-14 02:59:59 +0000372 if (result)
373 result->SetStatus (eReturnStatusSuccessFinishResult);
374 }
375 else
376 {
Sean Callanan24312442011-08-23 21:20:51 +0000377 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000378 {
Sean Callanan24312442011-08-23 21:20:51 +0000379 error_stream->PutCString("<no result>\n");
380
381 if (result)
382 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000383 }
384 else
385 {
Sean Callanan24312442011-08-23 21:20:51 +0000386 const char *error_cstr = result_valobj_sp->GetError().AsCString();
387 if (error_cstr && error_cstr[0])
388 {
389 int error_cstr_len = strlen (error_cstr);
390 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
391 if (strstr(error_cstr, "error:") != error_cstr)
392 error_stream->PutCString ("error: ");
393 error_stream->Write(error_cstr, error_cstr_len);
394 if (!ends_with_newline)
395 error_stream->EOL();
396 }
397 else
398 {
399 error_stream->PutCString ("error: unknown error\n");
400 }
401
402 if (result)
403 result->SetStatus (eReturnStatusFailed);
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000404 }
Jim Ingham360f53f2010-11-30 02:22:11 +0000405 }
406 }
Greg Clayton427f2902010-12-14 02:59:59 +0000407 }
408 else
409 {
Caroline Tice87e1f772011-06-13 20:20:29 +0000410 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton427f2902010-12-14 02:59:59 +0000411 return false;
Sean Callanan841026f2010-07-23 00:16:21 +0000412 }
Sean Callanan82b74c82010-08-12 01:56:52 +0000413
Sean Callanan841026f2010-07-23 00:16:21 +0000414 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000415}
416
417bool
418CommandObjectExpression::ExecuteRawCommandString
419(
420 const char *command,
Chris Lattner24943d22010-06-08 16:52:24 +0000421 CommandReturnObject &result
422)
423{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000424 m_exe_ctx = m_interpreter.GetExecutionContext();
Chris Lattner24943d22010-06-08 16:52:24 +0000425
Greg Claytona42880a2011-10-25 06:44:01 +0000426 m_option_group.NotifyOptionParsingStarting();
Chris Lattner24943d22010-06-08 16:52:24 +0000427
428 const char * expr = NULL;
429
430 if (command[0] == '\0')
431 {
432 m_expr_lines.clear();
433 m_expr_line_count = 0;
434
Greg Clayton238c0a12010-09-18 01:14:36 +0000435 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
Chris Lattner24943d22010-06-08 16:52:24 +0000436 if (reader_sp)
437 {
438 Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
439 this, // baton
440 eInputReaderGranularityLine, // token size, to pass to callback function
Greg Clayton63094e02010-06-23 01:19:29 +0000441 NULL, // end token
Chris Lattner24943d22010-06-08 16:52:24 +0000442 NULL, // prompt
443 true)); // echo input
444 if (err.Success())
445 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000446 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000447 result.SetStatus (eReturnStatusSuccessFinishNoResult);
448 }
449 else
450 {
451 result.AppendError (err.AsCString());
452 result.SetStatus (eReturnStatusFailed);
453 }
454 }
455 else
456 {
457 result.AppendError("out of memory");
458 result.SetStatus (eReturnStatusFailed);
459 }
460 return result.Succeeded();
461 }
462
463 if (command[0] == '-')
464 {
465 // We have some options and these options MUST end with --.
466 const char *end_options = NULL;
467 const char *s = command;
468 while (s && s[0])
469 {
470 end_options = ::strstr (s, "--");
471 if (end_options)
472 {
473 end_options += 2; // Get past the "--"
474 if (::isspace (end_options[0]))
475 {
476 expr = end_options;
477 while (::isspace (*expr))
478 ++expr;
479 break;
480 }
481 }
482 s = end_options;
483 }
484
485 if (end_options)
486 {
Greg Clayton63094e02010-06-23 01:19:29 +0000487 Args args (command, end_options - command);
Greg Clayton238c0a12010-09-18 01:14:36 +0000488 if (!ParseOptions (args, result))
Chris Lattner24943d22010-06-08 16:52:24 +0000489 return false;
Greg Clayton143fcc32011-04-13 00:18:08 +0000490
Greg Claytona42880a2011-10-25 06:44:01 +0000491 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Clayton143fcc32011-04-13 00:18:08 +0000492 if (error.Fail())
493 {
494 result.AppendError (error.AsCString());
495 result.SetStatus (eReturnStatusFailed);
496 return false;
497 }
Chris Lattner24943d22010-06-08 16:52:24 +0000498 }
499 }
500
Chris Lattner24943d22010-06-08 16:52:24 +0000501 if (expr == NULL)
502 expr = command;
Sean Callanan46b62492010-06-24 00:16:27 +0000503
Caroline Tice87e1f772011-06-13 20:20:29 +0000504 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Johnny Chen0deefc72010-08-13 00:42:30 +0000505 return true;
506
507 result.SetStatus (eReturnStatusFailed);
508 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000509}
510