130fdc8d8SChris Lattner //===-- CommandObjectExpression.cpp -----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "CommandObjectExpression.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
16ebf7707eSSean Callanan #include "lldb/Interpreter/Args.h"
1730fdc8d8SChris Lattner #include "lldb/Core/Value.h"
1830fdc8d8SChris Lattner #include "lldb/Core/InputReader.h"
196c68fb45SJim Ingham #include "lldb/Core/ValueObjectVariable.h"
2030fdc8d8SChris Lattner #include "lldb/Expression/ClangExpressionVariable.h"
211a8d4093SSean Callanan #include "lldb/Expression/ClangUserExpression.h"
22ebb84b24SStephen Wilson #include "lldb/Expression/ClangFunction.h"
2330fdc8d8SChris Lattner #include "lldb/Expression/DWARFExpression.h"
2430fdc8d8SChris Lattner #include "lldb/Host/Host.h"
25ebf7707eSSean Callanan #include "lldb/Core/Debugger.h"
266611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2730fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
286c68fb45SJim Ingham #include "lldb/Target/ObjCLanguageRuntime.h"
2930fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
3030fdc8d8SChris Lattner #include "lldb/Symbol/Variable.h"
3130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
3230fdc8d8SChris Lattner #include "lldb/Target/StackFrame.h"
3330fdc8d8SChris Lattner #include "lldb/Target/Target.h"
347260f620SGreg Clayton #include "lldb/Target/Thread.h"
35ebf7707eSSean Callanan #include "llvm/ADT/StringRef.h"
3630fdc8d8SChris Lattner 
3730fdc8d8SChris Lattner using namespace lldb;
3830fdc8d8SChris Lattner using namespace lldb_private;
3930fdc8d8SChris Lattner 
401deb7962SGreg Clayton CommandObjectExpression::CommandOptions::CommandOptions () :
411deb7962SGreg Clayton     OptionGroup()
4230fdc8d8SChris Lattner {
4330fdc8d8SChris Lattner }
4430fdc8d8SChris Lattner 
4530fdc8d8SChris Lattner 
4630fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::~CommandOptions ()
4730fdc8d8SChris Lattner {
4830fdc8d8SChris Lattner }
4930fdc8d8SChris Lattner 
501deb7962SGreg Clayton OptionDefinition
511deb7962SGreg Clayton CommandObjectExpression::CommandOptions::g_option_table[] =
521deb7962SGreg Clayton {
531deb7962SGreg Clayton     { 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."},
541deb7962SGreg Clayton     { 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."},
551deb7962SGreg Clayton     { LLDB_OPT_SET_2                 , false, "object-description", 'o', no_argument,       NULL, 0, eArgTypeNone,       "Print the object description of the value resulting from the expression."},
561deb7962SGreg Clayton };
571deb7962SGreg Clayton 
581deb7962SGreg Clayton 
591deb7962SGreg Clayton uint32_t
601deb7962SGreg Clayton CommandObjectExpression::CommandOptions::GetNumDefinitions ()
611deb7962SGreg Clayton {
621deb7962SGreg Clayton     return sizeof(g_option_table)/sizeof(OptionDefinition);
631deb7962SGreg Clayton }
641deb7962SGreg Clayton 
6530fdc8d8SChris Lattner Error
661deb7962SGreg Clayton CommandObjectExpression::CommandOptions::SetOptionValue (CommandInterpreter &interpreter,
671deb7962SGreg Clayton                                                          uint32_t option_idx,
681deb7962SGreg Clayton                                                          const char *option_arg)
6930fdc8d8SChris Lattner {
7030fdc8d8SChris Lattner     Error error;
7130fdc8d8SChris Lattner 
721deb7962SGreg Clayton     const char short_option = (char) g_option_table[option_idx].short_option;
7330fdc8d8SChris Lattner 
7430fdc8d8SChris Lattner     switch (short_option)
7530fdc8d8SChris Lattner     {
763f4c09c1SCaroline Tice       //case 'l':
773f4c09c1SCaroline Tice       //if (language.SetLanguageFromCString (option_arg) == false)
783f4c09c1SCaroline Tice       //{
7986edbf41SGreg Clayton       //    error.SetErrorStringWithFormat("invalid language option argument '%s'", option_arg);
803f4c09c1SCaroline Tice       //}
813f4c09c1SCaroline Tice       //break;
8230fdc8d8SChris Lattner 
836c68fb45SJim Ingham     case 'o':
846c68fb45SJim Ingham         print_object = true;
856c68fb45SJim Ingham         break;
866c68fb45SJim Ingham 
8778a685aaSJim Ingham     case 'd':
8878a685aaSJim Ingham         {
8978a685aaSJim Ingham             bool success;
9078a685aaSJim Ingham             bool result;
9178a685aaSJim Ingham             result = Args::StringToBoolean(option_arg, true, &success);
9278a685aaSJim Ingham             if (!success)
9386edbf41SGreg Clayton                 error.SetErrorStringWithFormat("invalid dynamic value setting: \"%s\"", option_arg);
9478a685aaSJim Ingham             else
9578a685aaSJim Ingham             {
9678a685aaSJim Ingham                 if (result)
9778a685aaSJim Ingham                     use_dynamic = eLazyBoolYes;
9878a685aaSJim Ingham                 else
9978a685aaSJim Ingham                     use_dynamic = eLazyBoolNo;
10078a685aaSJim Ingham             }
10178a685aaSJim Ingham         }
10278a685aaSJim Ingham         break;
10378a685aaSJim Ingham 
104399f1cafSJim Ingham     case 'u':
1053bfdaa2aSSean Callanan         {
106399f1cafSJim Ingham             bool success;
107399f1cafSJim Ingham             unwind_on_error = Args::StringToBoolean(option_arg, true, &success);
108399f1cafSJim Ingham             if (!success)
10986edbf41SGreg Clayton                 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
110399f1cafSJim Ingham             break;
1113bfdaa2aSSean Callanan         }
11230fdc8d8SChris Lattner     default:
11386edbf41SGreg Clayton         error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
11430fdc8d8SChris Lattner         break;
11530fdc8d8SChris Lattner     }
11630fdc8d8SChris Lattner 
11730fdc8d8SChris Lattner     return error;
11830fdc8d8SChris Lattner }
11930fdc8d8SChris Lattner 
12030fdc8d8SChris Lattner void
1211deb7962SGreg Clayton CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
12230fdc8d8SChris Lattner {
12378a685aaSJim Ingham     use_dynamic = eLazyBoolCalculate;
1241deb7962SGreg Clayton     print_object = false;
125399f1cafSJim Ingham     unwind_on_error = true;
12630fdc8d8SChris Lattner     show_types = true;
12730fdc8d8SChris Lattner     show_summary = true;
12830fdc8d8SChris Lattner }
12930fdc8d8SChris Lattner 
130e0d378b3SGreg Clayton const OptionDefinition*
13130fdc8d8SChris Lattner CommandObjectExpression::CommandOptions::GetDefinitions ()
13230fdc8d8SChris Lattner {
13330fdc8d8SChris Lattner     return g_option_table;
13430fdc8d8SChris Lattner }
13530fdc8d8SChris Lattner 
136a7015092SGreg Clayton CommandObjectExpression::CommandObjectExpression (CommandInterpreter &interpreter) :
1375a988416SJim Ingham     CommandObjectRaw (interpreter,
13830fdc8d8SChris Lattner                       "expression",
139a9a764e6SJohnny Chen                       "Evaluate a C/ObjC/C++ expression in the current program context, using variables currently in scope.",
1405a988416SJim Ingham                       NULL,
1415a988416SJim Ingham                       eFlagProcessMustBePaused),
1421deb7962SGreg Clayton     m_option_group (interpreter),
1431deb7962SGreg Clayton     m_format_options (eFormatDefault),
1441deb7962SGreg Clayton     m_command_options (),
14530fdc8d8SChris Lattner     m_expr_line_count (0),
14630fdc8d8SChris Lattner     m_expr_lines ()
14730fdc8d8SChris Lattner {
14830fdc8d8SChris Lattner   SetHelpLong(
14930fdc8d8SChris Lattner "Examples: \n\
15030fdc8d8SChris Lattner \n\
15130fdc8d8SChris Lattner    expr my_struct->a = my_array[3] \n\
15230fdc8d8SChris Lattner    expr -f bin -- (index * 8) + 5 \n\
15330fdc8d8SChris Lattner    expr char c[] = \"foo\"; c[0]\n");
154405fe67fSCaroline Tice 
155405fe67fSCaroline Tice     CommandArgumentEntry arg;
156405fe67fSCaroline Tice     CommandArgumentData expression_arg;
157405fe67fSCaroline Tice 
158405fe67fSCaroline Tice     // Define the first (and only) variant of this arg.
159405fe67fSCaroline Tice     expression_arg.arg_type = eArgTypeExpression;
160405fe67fSCaroline Tice     expression_arg.arg_repetition = eArgRepeatPlain;
161405fe67fSCaroline Tice 
162405fe67fSCaroline Tice     // There is only one variant this argument could be; put it into the argument entry.
163405fe67fSCaroline Tice     arg.push_back (expression_arg);
164405fe67fSCaroline Tice 
165405fe67fSCaroline Tice     // Push the data for the first argument into the m_arguments vector.
166405fe67fSCaroline Tice     m_arguments.push_back (arg);
1671deb7962SGreg Clayton 
1685009f9d5SGreg Clayton     // Add the "--format" and "--gdb-format"
1695009f9d5SGreg Clayton     m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
1701deb7962SGreg Clayton     m_option_group.Append (&m_command_options);
1711deb7962SGreg Clayton     m_option_group.Finalize();
17230fdc8d8SChris Lattner }
17330fdc8d8SChris Lattner 
17430fdc8d8SChris Lattner CommandObjectExpression::~CommandObjectExpression ()
17530fdc8d8SChris Lattner {
17630fdc8d8SChris Lattner }
17730fdc8d8SChris Lattner 
17830fdc8d8SChris Lattner Options *
17930fdc8d8SChris Lattner CommandObjectExpression::GetOptions ()
18030fdc8d8SChris Lattner {
1811deb7962SGreg Clayton     return &m_option_group;
18230fdc8d8SChris Lattner }
18330fdc8d8SChris Lattner 
18430fdc8d8SChris Lattner size_t
18530fdc8d8SChris Lattner CommandObjectExpression::MultiLineExpressionCallback
18630fdc8d8SChris Lattner (
18730fdc8d8SChris Lattner     void *baton,
1886611103cSGreg Clayton     InputReader &reader,
18930fdc8d8SChris Lattner     lldb::InputReaderAction notification,
19030fdc8d8SChris Lattner     const char *bytes,
19130fdc8d8SChris Lattner     size_t bytes_len
19230fdc8d8SChris Lattner )
19330fdc8d8SChris Lattner {
19430fdc8d8SChris Lattner     CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
195d61c10bcSCaroline Tice     bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
19630fdc8d8SChris Lattner 
19730fdc8d8SChris Lattner     switch (notification)
19830fdc8d8SChris Lattner     {
19930fdc8d8SChris Lattner     case eInputReaderActivate:
200d61c10bcSCaroline Tice         if (!batch_mode)
20115356e7fSCaroline Tice         {
20207e66e3eSGreg Clayton             StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
20307e66e3eSGreg Clayton             if (async_strm_sp)
20407e66e3eSGreg Clayton             {
20507e66e3eSGreg Clayton                 async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
20607e66e3eSGreg Clayton                 async_strm_sp->Flush();
20707e66e3eSGreg Clayton             }
20815356e7fSCaroline Tice         }
20930fdc8d8SChris Lattner         // Fall through
21030fdc8d8SChris Lattner     case eInputReaderReactivate:
21130fdc8d8SChris Lattner         break;
21230fdc8d8SChris Lattner 
21330fdc8d8SChris Lattner     case eInputReaderDeactivate:
21430fdc8d8SChris Lattner         break;
21530fdc8d8SChris Lattner 
216969ed3d1SCaroline Tice     case eInputReaderAsynchronousOutputWritten:
217969ed3d1SCaroline Tice         break;
218969ed3d1SCaroline Tice 
21930fdc8d8SChris Lattner     case eInputReaderGotToken:
22030fdc8d8SChris Lattner         ++cmd_object_expr->m_expr_line_count;
22130fdc8d8SChris Lattner         if (bytes && bytes_len)
22230fdc8d8SChris Lattner         {
22330fdc8d8SChris Lattner             cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
22430fdc8d8SChris Lattner         }
22530fdc8d8SChris Lattner 
22630fdc8d8SChris Lattner         if (bytes_len == 0)
2276611103cSGreg Clayton             reader.SetIsDone(true);
22830fdc8d8SChris Lattner         break;
22930fdc8d8SChris Lattner 
230efed6131SCaroline Tice     case eInputReaderInterrupt:
231efed6131SCaroline Tice         cmd_object_expr->m_expr_lines.clear();
232efed6131SCaroline Tice         reader.SetIsDone (true);
233d61c10bcSCaroline Tice         if (!batch_mode)
23415356e7fSCaroline Tice         {
23507e66e3eSGreg Clayton             StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
23607e66e3eSGreg Clayton             if (async_strm_sp)
23707e66e3eSGreg Clayton             {
23807e66e3eSGreg Clayton                 async_strm_sp->PutCString("Expression evaluation cancelled.\n");
23907e66e3eSGreg Clayton                 async_strm_sp->Flush();
24007e66e3eSGreg Clayton             }
24115356e7fSCaroline Tice         }
242efed6131SCaroline Tice         break;
243efed6131SCaroline Tice 
244efed6131SCaroline Tice     case eInputReaderEndOfFile:
245efed6131SCaroline Tice         reader.SetIsDone (true);
246efed6131SCaroline Tice         break;
247efed6131SCaroline Tice 
24830fdc8d8SChris Lattner     case eInputReaderDone:
249efed6131SCaroline Tice 		if (cmd_object_expr->m_expr_lines.size() > 0)
25030fdc8d8SChris Lattner         {
2516e8dc334SCaroline Tice             StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
2526e8dc334SCaroline Tice             StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
25330fdc8d8SChris Lattner             cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
2546e8dc334SCaroline Tice                                                  output_stream.get(),
2556e8dc334SCaroline Tice                                                  error_stream.get());
2566e8dc334SCaroline Tice             output_stream->Flush();
2576e8dc334SCaroline Tice             error_stream->Flush();
25830fdc8d8SChris Lattner         }
25930fdc8d8SChris Lattner         break;
26030fdc8d8SChris Lattner     }
26130fdc8d8SChris Lattner 
26230fdc8d8SChris Lattner     return bytes_len;
26330fdc8d8SChris Lattner }
26430fdc8d8SChris Lattner 
26530fdc8d8SChris Lattner bool
2661d3afba3SGreg Clayton CommandObjectExpression::EvaluateExpression
2671d3afba3SGreg Clayton (
2681d3afba3SGreg Clayton     const char *expr,
2696e8dc334SCaroline Tice     Stream *output_stream,
2706e8dc334SCaroline Tice     Stream *error_stream,
2711d3afba3SGreg Clayton     CommandReturnObject *result
2721d3afba3SGreg Clayton )
27330fdc8d8SChris Lattner {
274a73d2692SGreg Clayton     Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
275c0a6e061SSean Callanan 
276c0a6e061SSean Callanan     if (!target)
277c0a6e061SSean Callanan         target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
278c0a6e061SSean Callanan 
279c14ee32dSGreg Clayton     if (target)
2806961e878SSean Callanan     {
2818b2fe6dcSGreg Clayton         lldb::ValueObjectSP result_valobj_sp;
2828b2fe6dcSGreg Clayton 
283e0d378b3SGreg Clayton         ExecutionResults exe_results;
28492adcac9SSean Callanan 
28592adcac9SSean Callanan         bool keep_in_memory = true;
2862837b766SJim Ingham         lldb::DynamicValueType use_dynamic;
28778a685aaSJim Ingham         // If use dynamic is not set, get it from the target:
2881deb7962SGreg Clayton         switch (m_command_options.use_dynamic)
28978a685aaSJim Ingham         {
29078a685aaSJim Ingham         case eLazyBoolCalculate:
291c14ee32dSGreg Clayton             use_dynamic = target->GetPreferDynamicValue();
29278a685aaSJim Ingham             break;
29378a685aaSJim Ingham         case eLazyBoolYes:
2942837b766SJim Ingham             use_dynamic = lldb::eDynamicCanRunTarget;
29578a685aaSJim Ingham             break;
29678a685aaSJim Ingham         case eLazyBoolNo:
2972837b766SJim Ingham             use_dynamic = lldb::eNoDynamicValues;
29878a685aaSJim Ingham             break;
29978a685aaSJim Ingham         }
30092adcac9SSean Callanan 
301c14ee32dSGreg Clayton         exe_results = target->EvaluateExpression (expr,
302a73d2692SGreg Clayton                                                   m_interpreter.GetExecutionContext().GetFramePtr(),
3033bfdaa2aSSean Callanan                                                   eExecutionPolicyOnlyWhenNeeded,
30420bb3aa5SSean Callanan                                                   m_command_options.print_object,
3051deb7962SGreg Clayton                                                   m_command_options.unwind_on_error,
3063bfdaa2aSSean Callanan                                                   keep_in_memory,
3073bfdaa2aSSean Callanan                                                   use_dynamic,
3083372f581SEnrico Granata                                                   result_valobj_sp,
3093372f581SEnrico Granata                                                   0 /* no timeout */);
3108b2fe6dcSGreg Clayton 
3111deb7962SGreg Clayton         if (exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error)
3128b2fe6dcSGreg Clayton         {
3137260f620SGreg Clayton             uint32_t start_frame = 0;
3147260f620SGreg Clayton             uint32_t num_frames = 1;
3157260f620SGreg Clayton             uint32_t num_frames_with_source = 0;
316a73d2692SGreg Clayton             Thread *thread = m_interpreter.GetExecutionContext().GetThreadPtr();
317c14ee32dSGreg Clayton             if (thread)
3187260f620SGreg Clayton             {
319c14ee32dSGreg Clayton                 thread->GetStatus (result->GetOutputStream(),
3207260f620SGreg Clayton                                    start_frame,
3217260f620SGreg Clayton                                    num_frames,
3227260f620SGreg Clayton                                    num_frames_with_source);
3237260f620SGreg Clayton             }
324c14ee32dSGreg Clayton             else
325c14ee32dSGreg Clayton             {
326a73d2692SGreg Clayton                 Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
327c14ee32dSGreg Clayton                 if (process)
3287260f620SGreg Clayton                 {
3297260f620SGreg Clayton                     bool only_threads_with_stop_reason = true;
330c14ee32dSGreg Clayton                     process->GetThreadStatus (result->GetOutputStream(),
3317260f620SGreg Clayton                                               only_threads_with_stop_reason,
3327260f620SGreg Clayton                                               start_frame,
3337260f620SGreg Clayton                                               num_frames,
3347260f620SGreg Clayton                                               num_frames_with_source);
3357260f620SGreg Clayton                 }
3366961e878SSean Callanan             }
337c14ee32dSGreg Clayton         }
3386961e878SSean Callanan 
3398b2fe6dcSGreg Clayton         if (result_valobj_sp)
3408b2fe6dcSGreg Clayton         {
341*bf154daeSSean Callanan             Format format = m_format_options.GetFormat();
342*bf154daeSSean Callanan 
343b71f3844SGreg Clayton             if (result_valobj_sp->GetError().Success())
34430fdc8d8SChris Lattner             {
345*bf154daeSSean Callanan                 if (format != eFormatVoid)
346*bf154daeSSean Callanan                 {
3471deb7962SGreg Clayton                     if (format != eFormatDefault)
3481deb7962SGreg Clayton                         result_valobj_sp->SetFormat (format);
34932c4085bSGreg Clayton 
3500c489f58SEnrico Granata                     ValueObject::DumpValueObjectOptions options;
3510c489f58SEnrico Granata                     options.SetMaximumPointerDepth(0)
3520c489f58SEnrico Granata                     .SetMaximumDepth(UINT32_MAX)
3530c489f58SEnrico Granata                     .SetShowLocation(false)
3540c489f58SEnrico Granata                     .SetShowTypes(m_command_options.show_types)
3550c489f58SEnrico Granata                     .SetUseObjectiveC(m_command_options.print_object)
3560c489f58SEnrico Granata                     .SetUseDynamicType(use_dynamic)
3570c489f58SEnrico Granata                     .SetScopeChecked(true)
3580c489f58SEnrico Granata                     .SetFlatOutput(false)
35986cc9829SEnrico Granata                     .SetUseSyntheticValue(true)
3600c489f58SEnrico Granata                     .SetIgnoreCap(false)
3610c489f58SEnrico Granata                     .SetFormat(format)
362770eb05aSEnrico Granata                     .SetSummary()
363770eb05aSEnrico Granata                     .SetShowSummary(!m_command_options.print_object);
364770eb05aSEnrico Granata 
3656e8dc334SCaroline Tice                     ValueObject::DumpValueObject (*(output_stream),
3660184f019SGreg Clayton                                                   result_valobj_sp.get(),   // Variable object to dump
3670c489f58SEnrico Granata                                                   options);
368fcd43b71SJohnny Chen                     if (result)
369fcd43b71SJohnny Chen                         result->SetStatus (eReturnStatusSuccessFinishResult);
37030fdc8d8SChris Lattner                 }
371*bf154daeSSean Callanan             }
37230fdc8d8SChris Lattner             else
37330fdc8d8SChris Lattner             {
374bccce813SSean Callanan                 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
375bccce813SSean Callanan                 {
376*bf154daeSSean Callanan                     if (format != eFormatVoid)
377*bf154daeSSean Callanan                     {
378bccce813SSean Callanan                         error_stream->PutCString("<no result>\n");
379bccce813SSean Callanan 
380bccce813SSean Callanan                         if (result)
381bccce813SSean Callanan                             result->SetStatus (eReturnStatusSuccessFinishResult);
382bccce813SSean Callanan                     }
383*bf154daeSSean Callanan                 }
384bccce813SSean Callanan                 else
385bccce813SSean Callanan                 {
3865fd05903SGreg Clayton                     const char *error_cstr = result_valobj_sp->GetError().AsCString();
3875fd05903SGreg Clayton                     if (error_cstr && error_cstr[0])
3885fd05903SGreg Clayton                     {
3895fd05903SGreg Clayton                         int error_cstr_len = strlen (error_cstr);
3905fd05903SGreg Clayton                         const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
3915fd05903SGreg Clayton                         if (strstr(error_cstr, "error:") != error_cstr)
3925fd05903SGreg Clayton                             error_stream->PutCString ("error: ");
3935fd05903SGreg Clayton                         error_stream->Write(error_cstr, error_cstr_len);
3945fd05903SGreg Clayton                         if (!ends_with_newline)
3955fd05903SGreg Clayton                             error_stream->EOL();
3965fd05903SGreg Clayton                     }
3975fd05903SGreg Clayton                     else
3985fd05903SGreg Clayton                     {
3995fd05903SGreg Clayton                         error_stream->PutCString ("error: unknown error\n");
4005fd05903SGreg Clayton                     }
4015fd05903SGreg Clayton 
402fcd43b71SJohnny Chen                     if (result)
403b71f3844SGreg Clayton                         result->SetStatus (eReturnStatusFailed);
40430fdc8d8SChris Lattner                 }
4058b2fe6dcSGreg Clayton             }
4068b2fe6dcSGreg Clayton         }
407bccce813SSean Callanan     }
4088b2fe6dcSGreg Clayton     else
4098b2fe6dcSGreg Clayton     {
4106e8dc334SCaroline Tice         error_stream->Printf ("error: invalid execution context for expression\n");
4118b2fe6dcSGreg Clayton         return false;
4128b2fe6dcSGreg Clayton     }
41330fdc8d8SChris Lattner 
41416ad5faeSSean Callanan     return true;
41530fdc8d8SChris Lattner }
41630fdc8d8SChris Lattner 
41730fdc8d8SChris Lattner bool
4185a988416SJim Ingham CommandObjectExpression::DoExecute
41930fdc8d8SChris Lattner (
42030fdc8d8SChris Lattner     const char *command,
42130fdc8d8SChris Lattner     CommandReturnObject &result
42230fdc8d8SChris Lattner )
42330fdc8d8SChris Lattner {
4241deb7962SGreg Clayton     m_option_group.NotifyOptionParsingStarting();
42530fdc8d8SChris Lattner 
42630fdc8d8SChris Lattner     const char * expr = NULL;
42730fdc8d8SChris Lattner 
42830fdc8d8SChris Lattner     if (command[0] == '\0')
42930fdc8d8SChris Lattner     {
43030fdc8d8SChris Lattner         m_expr_lines.clear();
43130fdc8d8SChris Lattner         m_expr_line_count = 0;
43230fdc8d8SChris Lattner 
433a7015092SGreg Clayton         InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
43430fdc8d8SChris Lattner         if (reader_sp)
43530fdc8d8SChris Lattner         {
43630fdc8d8SChris Lattner             Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
43730fdc8d8SChris Lattner                                               this,                         // baton
43830fdc8d8SChris Lattner                                               eInputReaderGranularityLine,  // token size, to pass to callback function
43930fdc8d8SChris Lattner                                               NULL,                         // end token
44030fdc8d8SChris Lattner                                               NULL,                         // prompt
44130fdc8d8SChris Lattner                                               true));                       // echo input
44230fdc8d8SChris Lattner             if (err.Success())
44330fdc8d8SChris Lattner             {
444a7015092SGreg Clayton                 m_interpreter.GetDebugger().PushInputReader (reader_sp);
44530fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
44630fdc8d8SChris Lattner             }
44730fdc8d8SChris Lattner             else
44830fdc8d8SChris Lattner             {
44930fdc8d8SChris Lattner                 result.AppendError (err.AsCString());
45030fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
45130fdc8d8SChris Lattner             }
45230fdc8d8SChris Lattner         }
45330fdc8d8SChris Lattner         else
45430fdc8d8SChris Lattner         {
45530fdc8d8SChris Lattner             result.AppendError("out of memory");
45630fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
45730fdc8d8SChris Lattner         }
45830fdc8d8SChris Lattner         return result.Succeeded();
45930fdc8d8SChris Lattner     }
46030fdc8d8SChris Lattner 
46130fdc8d8SChris Lattner     if (command[0] == '-')
46230fdc8d8SChris Lattner     {
46330fdc8d8SChris Lattner         // We have some options and these options MUST end with --.
46430fdc8d8SChris Lattner         const char *end_options = NULL;
46530fdc8d8SChris Lattner         const char *s = command;
46630fdc8d8SChris Lattner         while (s && s[0])
46730fdc8d8SChris Lattner         {
46830fdc8d8SChris Lattner             end_options = ::strstr (s, "--");
46930fdc8d8SChris Lattner             if (end_options)
47030fdc8d8SChris Lattner             {
47130fdc8d8SChris Lattner                 end_options += 2; // Get past the "--"
47230fdc8d8SChris Lattner                 if (::isspace (end_options[0]))
47330fdc8d8SChris Lattner                 {
47430fdc8d8SChris Lattner                     expr = end_options;
47530fdc8d8SChris Lattner                     while (::isspace (*expr))
47630fdc8d8SChris Lattner                         ++expr;
47730fdc8d8SChris Lattner                     break;
47830fdc8d8SChris Lattner                 }
47930fdc8d8SChris Lattner             }
48030fdc8d8SChris Lattner             s = end_options;
48130fdc8d8SChris Lattner         }
48230fdc8d8SChris Lattner 
48330fdc8d8SChris Lattner         if (end_options)
48430fdc8d8SChris Lattner         {
48530fdc8d8SChris Lattner             Args args (command, end_options - command);
486a7015092SGreg Clayton             if (!ParseOptions (args, result))
48730fdc8d8SChris Lattner                 return false;
488f6b8b581SGreg Clayton 
4891deb7962SGreg Clayton             Error error (m_option_group.NotifyOptionParsingFinished());
490f6b8b581SGreg Clayton             if (error.Fail())
491f6b8b581SGreg Clayton             {
492f6b8b581SGreg Clayton                 result.AppendError (error.AsCString());
493f6b8b581SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
494f6b8b581SGreg Clayton                 return false;
495f6b8b581SGreg Clayton             }
49630fdc8d8SChris Lattner         }
49730fdc8d8SChris Lattner     }
49830fdc8d8SChris Lattner 
49930fdc8d8SChris Lattner     if (expr == NULL)
50030fdc8d8SChris Lattner         expr = command;
50130fdc8d8SChris Lattner 
5026e8dc334SCaroline Tice     if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
503fcd43b71SJohnny Chen         return true;
504fcd43b71SJohnny Chen 
505fcd43b71SJohnny Chen     result.SetStatus (eReturnStatusFailed);
506fcd43b71SJohnny Chen     return false;
50730fdc8d8SChris Lattner }
50830fdc8d8SChris Lattner 
509