blob: 3ec585ee33d923ab4bb5945aa81d9f98230c1066 [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();
286 if (target)
Chris Lattner24943d22010-06-08 16:52:24 +0000287 {
Greg Clayton427f2902010-12-14 02:59:59 +0000288 lldb::ValueObjectSP result_valobj_sp;
Greg Clayton11730f32010-10-06 03:09:11 +0000289
Greg Claytonb3448432011-03-24 21:19:54 +0000290 ExecutionResults exe_results;
Sean Callanan6a925532011-01-13 08:53:35 +0000291
292 bool keep_in_memory = true;
Jim Ingham10de7d12011-05-04 03:43:18 +0000293 lldb::DynamicValueType use_dynamic;
Jim Inghame41494a2011-04-16 00:01:13 +0000294 // If use dynamic is not set, get it from the target:
Greg Claytona42880a2011-10-25 06:44:01 +0000295 switch (m_command_options.use_dynamic)
Jim Inghame41494a2011-04-16 00:01:13 +0000296 {
297 case eLazyBoolCalculate:
Greg Clayton567e7f32011-09-22 04:58:26 +0000298 use_dynamic = target->GetPreferDynamicValue();
Jim Inghame41494a2011-04-16 00:01:13 +0000299 break;
300 case eLazyBoolYes:
Jim Ingham10de7d12011-05-04 03:43:18 +0000301 use_dynamic = lldb::eDynamicCanRunTarget;
Jim Inghame41494a2011-04-16 00:01:13 +0000302 break;
303 case eLazyBoolNo:
Jim Ingham10de7d12011-05-04 03:43:18 +0000304 use_dynamic = lldb::eNoDynamicValues;
Jim Inghame41494a2011-04-16 00:01:13 +0000305 break;
306 }
Sean Callanan6a925532011-01-13 08:53:35 +0000307
Greg Clayton567e7f32011-09-22 04:58:26 +0000308 exe_results = target->EvaluateExpression (expr,
309 m_exe_ctx.GetFramePtr(),
310 eExecutionPolicyOnlyWhenNeeded,
Greg Claytona42880a2011-10-25 06:44:01 +0000311 m_command_options.unwind_on_error,
Greg Clayton567e7f32011-09-22 04:58:26 +0000312 keep_in_memory,
313 use_dynamic,
314 result_valobj_sp);
Greg Clayton427f2902010-12-14 02:59:59 +0000315
Greg Claytona42880a2011-10-25 06:44:01 +0000316 if (exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error)
Jim Ingham360f53f2010-11-30 02:22:11 +0000317 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000318 uint32_t start_frame = 0;
319 uint32_t num_frames = 1;
320 uint32_t num_frames_with_source = 0;
Greg Clayton567e7f32011-09-22 04:58:26 +0000321 Thread *thread = m_exe_ctx.GetThreadPtr();
322 if (thread)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000323 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000324 thread->GetStatus (result->GetOutputStream(),
325 start_frame,
326 num_frames,
327 num_frames_with_source);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000328 }
Greg Clayton567e7f32011-09-22 04:58:26 +0000329 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000330 {
Greg Clayton567e7f32011-09-22 04:58:26 +0000331 Process *process = m_exe_ctx.GetProcessPtr();
332 if (process)
333 {
334 bool only_threads_with_stop_reason = true;
335 process->GetThreadStatus (result->GetOutputStream(),
336 only_threads_with_stop_reason,
337 start_frame,
338 num_frames,
339 num_frames_with_source);
340 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000341 }
Greg Clayton427f2902010-12-14 02:59:59 +0000342 }
343
344 if (result_valobj_sp)
345 {
346 if (result_valobj_sp->GetError().Success())
347 {
Greg Claytona42880a2011-10-25 06:44:01 +0000348 Format format = m_format_options.GetFormat();
349 if (format != eFormatDefault)
350 result_valobj_sp->SetFormat (format);
Greg Clayton427f2902010-12-14 02:59:59 +0000351
Caroline Tice87e1f772011-06-13 20:20:29 +0000352 ValueObject::DumpValueObject (*(output_stream),
Greg Clayton427f2902010-12-14 02:59:59 +0000353 result_valobj_sp.get(), // Variable object to dump
354 result_valobj_sp->GetName().GetCString(),// Root object name
355 0, // Pointer depth to traverse (zero means stop at pointers)
356 0, // Current depth, this is the top most, so zero...
357 UINT32_MAX, // Max depth to go when dumping concrete types, dump everything...
Greg Claytona42880a2011-10-25 06:44:01 +0000358 m_command_options.show_types, // Show types when dumping?
Greg Clayton427f2902010-12-14 02:59:59 +0000359 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 +0000360 m_command_options.print_object, // Print the objective C object?
Jim Inghame41494a2011-04-16 00:01:13 +0000361 use_dynamic,
Enrico Granatae4e3e2c2011-07-22 00:16:08 +0000362 true, // Use synthetic children if available
Greg Clayton427f2902010-12-14 02:59:59 +0000363 true, // Scope is already checked. Const results are always in scope.
Enrico Granata7f163b32011-07-16 01:22:04 +0000364 false, // Don't flatten output
Enrico Granata018921d2011-08-12 02:00:06 +0000365 0, // Always use summaries (you might want an option --no-summary like there is for frame variable)
366 false); // Do not show more children than settings allow
Greg Clayton427f2902010-12-14 02:59:59 +0000367 if (result)
368 result->SetStatus (eReturnStatusSuccessFinishResult);
369 }
370 else
371 {
Sean Callanan24312442011-08-23 21:20:51 +0000372 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000373 {
Sean Callanan24312442011-08-23 21:20:51 +0000374 error_stream->PutCString("<no result>\n");
375
376 if (result)
377 result->SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000378 }
379 else
380 {
Sean Callanan24312442011-08-23 21:20:51 +0000381 const char *error_cstr = result_valobj_sp->GetError().AsCString();
382 if (error_cstr && error_cstr[0])
383 {
384 int error_cstr_len = strlen (error_cstr);
385 const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
386 if (strstr(error_cstr, "error:") != error_cstr)
387 error_stream->PutCString ("error: ");
388 error_stream->Write(error_cstr, error_cstr_len);
389 if (!ends_with_newline)
390 error_stream->EOL();
391 }
392 else
393 {
394 error_stream->PutCString ("error: unknown error\n");
395 }
396
397 if (result)
398 result->SetStatus (eReturnStatusFailed);
Greg Claytonfe1b47d2011-06-24 22:31:10 +0000399 }
Jim Ingham360f53f2010-11-30 02:22:11 +0000400 }
401 }
Greg Clayton427f2902010-12-14 02:59:59 +0000402 }
403 else
404 {
Caroline Tice87e1f772011-06-13 20:20:29 +0000405 error_stream->Printf ("error: invalid execution context for expression\n");
Greg Clayton427f2902010-12-14 02:59:59 +0000406 return false;
Sean Callanan841026f2010-07-23 00:16:21 +0000407 }
Sean Callanan82b74c82010-08-12 01:56:52 +0000408
Sean Callanan841026f2010-07-23 00:16:21 +0000409 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000410}
411
412bool
413CommandObjectExpression::ExecuteRawCommandString
414(
415 const char *command,
Chris Lattner24943d22010-06-08 16:52:24 +0000416 CommandReturnObject &result
417)
418{
Greg Claytonb72d0f02011-04-12 05:54:46 +0000419 m_exe_ctx = m_interpreter.GetExecutionContext();
Chris Lattner24943d22010-06-08 16:52:24 +0000420
Greg Claytona42880a2011-10-25 06:44:01 +0000421 m_option_group.NotifyOptionParsingStarting();
Chris Lattner24943d22010-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 Clayton238c0a12010-09-18 01:14:36 +0000430 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
Chris Lattner24943d22010-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 Clayton63094e02010-06-23 01:19:29 +0000436 NULL, // end token
Chris Lattner24943d22010-06-08 16:52:24 +0000437 NULL, // prompt
438 true)); // echo input
439 if (err.Success())
440 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000441 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Chris Lattner24943d22010-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 Clayton63094e02010-06-23 01:19:29 +0000482 Args args (command, end_options - command);
Greg Clayton238c0a12010-09-18 01:14:36 +0000483 if (!ParseOptions (args, result))
Chris Lattner24943d22010-06-08 16:52:24 +0000484 return false;
Greg Clayton143fcc32011-04-13 00:18:08 +0000485
Greg Claytona42880a2011-10-25 06:44:01 +0000486 Error error (m_option_group.NotifyOptionParsingFinished());
Greg Clayton143fcc32011-04-13 00:18:08 +0000487 if (error.Fail())
488 {
489 result.AppendError (error.AsCString());
490 result.SetStatus (eReturnStatusFailed);
491 return false;
492 }
Chris Lattner24943d22010-06-08 16:52:24 +0000493 }
494 }
495
Chris Lattner24943d22010-06-08 16:52:24 +0000496 if (expr == NULL)
497 expr = command;
Sean Callanan46b62492010-06-24 00:16:27 +0000498
Caroline Tice87e1f772011-06-13 20:20:29 +0000499 if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
Johnny Chen0deefc72010-08-13 00:42:30 +0000500 return true;
501
502 result.SetStatus (eReturnStatusFailed);
503 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000504}
505