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       //{
79*86edbf41SGreg 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)
93*86edbf41SGreg 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)
109*86edbf41SGreg Clayton                 error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
110399f1cafSJim Ingham             break;
1113bfdaa2aSSean Callanan         }
11230fdc8d8SChris Lattner     default:
113*86edbf41SGreg 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) :
137a7015092SGreg Clayton     CommandObject (interpreter,
13830fdc8d8SChris Lattner                    "expression",
139a9a764e6SJohnny Chen                    "Evaluate a C/ObjC/C++ expression in the current program context, using variables currently in scope.",
140405fe67fSCaroline Tice                    NULL),
1411deb7962SGreg Clayton     m_option_group (interpreter),
1421deb7962SGreg Clayton     m_format_options (eFormatDefault),
1431deb7962SGreg Clayton     m_command_options (),
14430fdc8d8SChris Lattner     m_expr_line_count (0),
14530fdc8d8SChris Lattner     m_expr_lines ()
14630fdc8d8SChris Lattner {
14730fdc8d8SChris Lattner   SetHelpLong(
14830fdc8d8SChris Lattner "Examples: \n\
14930fdc8d8SChris Lattner \n\
15030fdc8d8SChris Lattner    expr my_struct->a = my_array[3] \n\
15130fdc8d8SChris Lattner    expr -f bin -- (index * 8) + 5 \n\
15230fdc8d8SChris Lattner    expr char c[] = \"foo\"; c[0]\n");
153405fe67fSCaroline Tice 
154405fe67fSCaroline Tice     CommandArgumentEntry arg;
155405fe67fSCaroline Tice     CommandArgumentData expression_arg;
156405fe67fSCaroline Tice 
157405fe67fSCaroline Tice     // Define the first (and only) variant of this arg.
158405fe67fSCaroline Tice     expression_arg.arg_type = eArgTypeExpression;
159405fe67fSCaroline Tice     expression_arg.arg_repetition = eArgRepeatPlain;
160405fe67fSCaroline Tice 
161405fe67fSCaroline Tice     // There is only one variant this argument could be; put it into the argument entry.
162405fe67fSCaroline Tice     arg.push_back (expression_arg);
163405fe67fSCaroline Tice 
164405fe67fSCaroline Tice     // Push the data for the first argument into the m_arguments vector.
165405fe67fSCaroline Tice     m_arguments.push_back (arg);
1661deb7962SGreg Clayton 
1671deb7962SGreg Clayton     // Add the "--format" and "--count" options to group 1 and 3
1681deb7962SGreg Clayton     m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
1691deb7962SGreg Clayton     m_option_group.Append (&m_command_options);
1701deb7962SGreg Clayton     m_option_group.Finalize();
17130fdc8d8SChris Lattner }
17230fdc8d8SChris Lattner 
17330fdc8d8SChris Lattner CommandObjectExpression::~CommandObjectExpression ()
17430fdc8d8SChris Lattner {
17530fdc8d8SChris Lattner }
17630fdc8d8SChris Lattner 
17730fdc8d8SChris Lattner Options *
17830fdc8d8SChris Lattner CommandObjectExpression::GetOptions ()
17930fdc8d8SChris Lattner {
1801deb7962SGreg Clayton     return &m_option_group;
18130fdc8d8SChris Lattner }
18230fdc8d8SChris Lattner 
18330fdc8d8SChris Lattner 
18430fdc8d8SChris Lattner bool
18530fdc8d8SChris Lattner CommandObjectExpression::Execute
18630fdc8d8SChris Lattner (
18730fdc8d8SChris Lattner     Args& command,
18830fdc8d8SChris Lattner     CommandReturnObject &result
18930fdc8d8SChris Lattner )
19030fdc8d8SChris Lattner {
19130fdc8d8SChris Lattner     return false;
19230fdc8d8SChris Lattner }
19330fdc8d8SChris Lattner 
19430fdc8d8SChris Lattner 
19530fdc8d8SChris Lattner size_t
19630fdc8d8SChris Lattner CommandObjectExpression::MultiLineExpressionCallback
19730fdc8d8SChris Lattner (
19830fdc8d8SChris Lattner     void *baton,
1996611103cSGreg Clayton     InputReader &reader,
20030fdc8d8SChris Lattner     lldb::InputReaderAction notification,
20130fdc8d8SChris Lattner     const char *bytes,
20230fdc8d8SChris Lattner     size_t bytes_len
20330fdc8d8SChris Lattner )
20430fdc8d8SChris Lattner {
20530fdc8d8SChris Lattner     CommandObjectExpression *cmd_object_expr = (CommandObjectExpression *) baton;
206d61c10bcSCaroline Tice     bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
20730fdc8d8SChris Lattner 
20830fdc8d8SChris Lattner     switch (notification)
20930fdc8d8SChris Lattner     {
21030fdc8d8SChris Lattner     case eInputReaderActivate:
211d61c10bcSCaroline Tice         if (!batch_mode)
21215356e7fSCaroline Tice         {
21307e66e3eSGreg Clayton             StreamSP async_strm_sp(reader.GetDebugger().GetAsyncOutputStream());
21407e66e3eSGreg Clayton             if (async_strm_sp)
21507e66e3eSGreg Clayton             {
21607e66e3eSGreg Clayton                 async_strm_sp->PutCString("Enter expressions, then terminate with an empty line to evaluate:\n");
21707e66e3eSGreg Clayton                 async_strm_sp->Flush();
21807e66e3eSGreg Clayton             }
21915356e7fSCaroline Tice         }
22030fdc8d8SChris Lattner         // Fall through
22130fdc8d8SChris Lattner     case eInputReaderReactivate:
22230fdc8d8SChris Lattner         break;
22330fdc8d8SChris Lattner 
22430fdc8d8SChris Lattner     case eInputReaderDeactivate:
22530fdc8d8SChris Lattner         break;
22630fdc8d8SChris Lattner 
227969ed3d1SCaroline Tice     case eInputReaderAsynchronousOutputWritten:
228969ed3d1SCaroline Tice         break;
229969ed3d1SCaroline Tice 
23030fdc8d8SChris Lattner     case eInputReaderGotToken:
23130fdc8d8SChris Lattner         ++cmd_object_expr->m_expr_line_count;
23230fdc8d8SChris Lattner         if (bytes && bytes_len)
23330fdc8d8SChris Lattner         {
23430fdc8d8SChris Lattner             cmd_object_expr->m_expr_lines.append (bytes, bytes_len + 1);
23530fdc8d8SChris Lattner         }
23630fdc8d8SChris Lattner 
23730fdc8d8SChris Lattner         if (bytes_len == 0)
2386611103cSGreg Clayton             reader.SetIsDone(true);
23930fdc8d8SChris Lattner         break;
24030fdc8d8SChris Lattner 
241efed6131SCaroline Tice     case eInputReaderInterrupt:
242efed6131SCaroline Tice         cmd_object_expr->m_expr_lines.clear();
243efed6131SCaroline Tice         reader.SetIsDone (true);
244d61c10bcSCaroline Tice         if (!batch_mode)
24515356e7fSCaroline Tice         {
24607e66e3eSGreg Clayton             StreamSP async_strm_sp (reader.GetDebugger().GetAsyncOutputStream());
24707e66e3eSGreg Clayton             if (async_strm_sp)
24807e66e3eSGreg Clayton             {
24907e66e3eSGreg Clayton                 async_strm_sp->PutCString("Expression evaluation cancelled.\n");
25007e66e3eSGreg Clayton                 async_strm_sp->Flush();
25107e66e3eSGreg Clayton             }
25215356e7fSCaroline Tice         }
253efed6131SCaroline Tice         break;
254efed6131SCaroline Tice 
255efed6131SCaroline Tice     case eInputReaderEndOfFile:
256efed6131SCaroline Tice         reader.SetIsDone (true);
257efed6131SCaroline Tice         break;
258efed6131SCaroline Tice 
25930fdc8d8SChris Lattner     case eInputReaderDone:
260efed6131SCaroline Tice 		if (cmd_object_expr->m_expr_lines.size() > 0)
26130fdc8d8SChris Lattner         {
2626e8dc334SCaroline Tice             StreamSP output_stream = reader.GetDebugger().GetAsyncOutputStream();
2636e8dc334SCaroline Tice             StreamSP error_stream = reader.GetDebugger().GetAsyncErrorStream();
26430fdc8d8SChris Lattner             cmd_object_expr->EvaluateExpression (cmd_object_expr->m_expr_lines.c_str(),
2656e8dc334SCaroline Tice                                                  output_stream.get(),
2666e8dc334SCaroline Tice                                                  error_stream.get());
2676e8dc334SCaroline Tice             output_stream->Flush();
2686e8dc334SCaroline Tice             error_stream->Flush();
26930fdc8d8SChris Lattner         }
27030fdc8d8SChris Lattner         break;
27130fdc8d8SChris Lattner     }
27230fdc8d8SChris Lattner 
27330fdc8d8SChris Lattner     return bytes_len;
27430fdc8d8SChris Lattner }
27530fdc8d8SChris Lattner 
27630fdc8d8SChris Lattner bool
2771d3afba3SGreg Clayton CommandObjectExpression::EvaluateExpression
2781d3afba3SGreg Clayton (
2791d3afba3SGreg Clayton     const char *expr,
2806e8dc334SCaroline Tice     Stream *output_stream,
2816e8dc334SCaroline Tice     Stream *error_stream,
2821d3afba3SGreg Clayton     CommandReturnObject *result
2831d3afba3SGreg Clayton )
28430fdc8d8SChris Lattner {
285c14ee32dSGreg Clayton     Target *target = m_exe_ctx.GetTargetPtr();
286c14ee32dSGreg Clayton     if (target)
2876961e878SSean Callanan     {
2888b2fe6dcSGreg Clayton         lldb::ValueObjectSP result_valobj_sp;
2898b2fe6dcSGreg Clayton 
290e0d378b3SGreg Clayton         ExecutionResults exe_results;
29192adcac9SSean Callanan 
29292adcac9SSean Callanan         bool keep_in_memory = true;
2932837b766SJim Ingham         lldb::DynamicValueType use_dynamic;
29478a685aaSJim Ingham         // If use dynamic is not set, get it from the target:
2951deb7962SGreg Clayton         switch (m_command_options.use_dynamic)
29678a685aaSJim Ingham         {
29778a685aaSJim Ingham         case eLazyBoolCalculate:
298c14ee32dSGreg Clayton             use_dynamic = target->GetPreferDynamicValue();
29978a685aaSJim Ingham             break;
30078a685aaSJim Ingham         case eLazyBoolYes:
3012837b766SJim Ingham             use_dynamic = lldb::eDynamicCanRunTarget;
30278a685aaSJim Ingham             break;
30378a685aaSJim Ingham         case eLazyBoolNo:
3042837b766SJim Ingham             use_dynamic = lldb::eNoDynamicValues;
30578a685aaSJim Ingham             break;
30678a685aaSJim Ingham         }
30792adcac9SSean Callanan 
308c14ee32dSGreg Clayton         exe_results = target->EvaluateExpression (expr,
309c14ee32dSGreg Clayton                                                   m_exe_ctx.GetFramePtr(),
3103bfdaa2aSSean Callanan                                                   eExecutionPolicyOnlyWhenNeeded,
3111deb7962SGreg Clayton                                                   m_command_options.unwind_on_error,
3123bfdaa2aSSean Callanan                                                   keep_in_memory,
3133bfdaa2aSSean Callanan                                                   use_dynamic,
3143bfdaa2aSSean Callanan                                                   result_valobj_sp);
3158b2fe6dcSGreg Clayton 
3161deb7962SGreg Clayton         if (exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error)
3178b2fe6dcSGreg Clayton         {
3187260f620SGreg Clayton             uint32_t start_frame = 0;
3197260f620SGreg Clayton             uint32_t num_frames = 1;
3207260f620SGreg Clayton             uint32_t num_frames_with_source = 0;
321c14ee32dSGreg Clayton             Thread *thread = m_exe_ctx.GetThreadPtr();
322c14ee32dSGreg Clayton             if (thread)
3237260f620SGreg Clayton             {
324c14ee32dSGreg Clayton                 thread->GetStatus (result->GetOutputStream(),
3257260f620SGreg Clayton                                    start_frame,
3267260f620SGreg Clayton                                    num_frames,
3277260f620SGreg Clayton                                    num_frames_with_source);
3287260f620SGreg Clayton             }
329c14ee32dSGreg Clayton             else
330c14ee32dSGreg Clayton             {
331c14ee32dSGreg Clayton                 Process *process = m_exe_ctx.GetProcessPtr();
332c14ee32dSGreg Clayton                 if (process)
3337260f620SGreg Clayton                 {
3347260f620SGreg Clayton                     bool only_threads_with_stop_reason = true;
335c14ee32dSGreg Clayton                     process->GetThreadStatus (result->GetOutputStream(),
3367260f620SGreg Clayton                                               only_threads_with_stop_reason,
3377260f620SGreg Clayton                                               start_frame,
3387260f620SGreg Clayton                                               num_frames,
3397260f620SGreg Clayton                                               num_frames_with_source);
3407260f620SGreg Clayton                 }
3416961e878SSean Callanan             }
342c14ee32dSGreg Clayton         }
3436961e878SSean Callanan 
3448b2fe6dcSGreg Clayton         if (result_valobj_sp)
3458b2fe6dcSGreg Clayton         {
346b71f3844SGreg Clayton             if (result_valobj_sp->GetError().Success())
34730fdc8d8SChris Lattner             {
3481deb7962SGreg Clayton                 Format format = m_format_options.GetFormat();
3491deb7962SGreg Clayton                 if (format != eFormatDefault)
3501deb7962SGreg Clayton                     result_valobj_sp->SetFormat (format);
35132c4085bSGreg Clayton 
3526e8dc334SCaroline Tice                 ValueObject::DumpValueObject (*(output_stream),
3530184f019SGreg Clayton                                               result_valobj_sp.get(),   // Variable object to dump
3548b2fe6dcSGreg Clayton                                               result_valobj_sp->GetName().GetCString(),// Root object name
3551d3afba3SGreg Clayton                                               0,                        // Pointer depth to traverse (zero means stop at pointers)
3561d3afba3SGreg Clayton                                               0,                        // Current depth, this is the top most, so zero...
3571d3afba3SGreg Clayton                                               UINT32_MAX,               // Max depth to go when dumping concrete types, dump everything...
3581deb7962SGreg Clayton                                               m_command_options.show_types,     // Show types when dumping?
3591d3afba3SGreg Clayton                                               false,                    // Show locations of variables, no since this is a host address which we don't care to see
3601deb7962SGreg Clayton                                               m_command_options.print_object,   // Print the objective C object?
36178a685aaSJim Ingham                                               use_dynamic,
362d55546b2SEnrico Granata                                               true,                     // Use synthetic children if available
3638f92f0a3SGreg Clayton                                               true,                     // Scope is already checked. Const results are always in scope.
3640c5ef693SEnrico Granata                                               false,                    // Don't flatten output
36522c55d18SEnrico Granata                                               0,                        // Always use summaries (you might want an option --no-summary like there is for frame variable)
36622c55d18SEnrico Granata                                               false);                   // Do not show more children than settings allow
367fcd43b71SJohnny Chen                 if (result)
368fcd43b71SJohnny Chen                     result->SetStatus (eReturnStatusSuccessFinishResult);
36930fdc8d8SChris Lattner             }
37030fdc8d8SChris Lattner             else
37130fdc8d8SChris Lattner             {
372bccce813SSean Callanan                 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
373bccce813SSean Callanan                 {
374bccce813SSean Callanan                     error_stream->PutCString("<no result>\n");
375bccce813SSean Callanan 
376bccce813SSean Callanan                     if (result)
377bccce813SSean Callanan                         result->SetStatus (eReturnStatusSuccessFinishResult);
378bccce813SSean Callanan                 }
379bccce813SSean Callanan                 else
380bccce813SSean Callanan                 {
3815fd05903SGreg Clayton                     const char *error_cstr = result_valobj_sp->GetError().AsCString();
3825fd05903SGreg Clayton                     if (error_cstr && error_cstr[0])
3835fd05903SGreg Clayton                     {
3845fd05903SGreg Clayton                         int error_cstr_len = strlen (error_cstr);
3855fd05903SGreg Clayton                         const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
3865fd05903SGreg Clayton                         if (strstr(error_cstr, "error:") != error_cstr)
3875fd05903SGreg Clayton                             error_stream->PutCString ("error: ");
3885fd05903SGreg Clayton                         error_stream->Write(error_cstr, error_cstr_len);
3895fd05903SGreg Clayton                         if (!ends_with_newline)
3905fd05903SGreg Clayton                             error_stream->EOL();
3915fd05903SGreg Clayton                     }
3925fd05903SGreg Clayton                     else
3935fd05903SGreg Clayton                     {
3945fd05903SGreg Clayton                         error_stream->PutCString ("error: unknown error\n");
3955fd05903SGreg Clayton                     }
3965fd05903SGreg Clayton 
397fcd43b71SJohnny Chen                     if (result)
398b71f3844SGreg Clayton                         result->SetStatus (eReturnStatusFailed);
39930fdc8d8SChris Lattner                 }
4008b2fe6dcSGreg Clayton             }
4018b2fe6dcSGreg Clayton         }
402bccce813SSean Callanan     }
4038b2fe6dcSGreg Clayton     else
4048b2fe6dcSGreg Clayton     {
4056e8dc334SCaroline Tice         error_stream->Printf ("error: invalid execution context for expression\n");
4068b2fe6dcSGreg Clayton         return false;
4078b2fe6dcSGreg Clayton     }
40830fdc8d8SChris Lattner 
40916ad5faeSSean Callanan     return true;
41030fdc8d8SChris Lattner }
41130fdc8d8SChris Lattner 
41230fdc8d8SChris Lattner bool
41330fdc8d8SChris Lattner CommandObjectExpression::ExecuteRawCommandString
41430fdc8d8SChris Lattner (
41530fdc8d8SChris Lattner     const char *command,
41630fdc8d8SChris Lattner     CommandReturnObject &result
41730fdc8d8SChris Lattner )
41830fdc8d8SChris Lattner {
4198b82f087SGreg Clayton     m_exe_ctx = m_interpreter.GetExecutionContext();
42030fdc8d8SChris Lattner 
4211deb7962SGreg Clayton     m_option_group.NotifyOptionParsingStarting();
42230fdc8d8SChris Lattner 
42330fdc8d8SChris Lattner     const char * expr = NULL;
42430fdc8d8SChris Lattner 
42530fdc8d8SChris Lattner     if (command[0] == '\0')
42630fdc8d8SChris Lattner     {
42730fdc8d8SChris Lattner         m_expr_lines.clear();
42830fdc8d8SChris Lattner         m_expr_line_count = 0;
42930fdc8d8SChris Lattner 
430a7015092SGreg Clayton         InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
43130fdc8d8SChris Lattner         if (reader_sp)
43230fdc8d8SChris Lattner         {
43330fdc8d8SChris Lattner             Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
43430fdc8d8SChris Lattner                                               this,                         // baton
43530fdc8d8SChris Lattner                                               eInputReaderGranularityLine,  // token size, to pass to callback function
43630fdc8d8SChris Lattner                                               NULL,                         // end token
43730fdc8d8SChris Lattner                                               NULL,                         // prompt
43830fdc8d8SChris Lattner                                               true));                       // echo input
43930fdc8d8SChris Lattner             if (err.Success())
44030fdc8d8SChris Lattner             {
441a7015092SGreg Clayton                 m_interpreter.GetDebugger().PushInputReader (reader_sp);
44230fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
44330fdc8d8SChris Lattner             }
44430fdc8d8SChris Lattner             else
44530fdc8d8SChris Lattner             {
44630fdc8d8SChris Lattner                 result.AppendError (err.AsCString());
44730fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
44830fdc8d8SChris Lattner             }
44930fdc8d8SChris Lattner         }
45030fdc8d8SChris Lattner         else
45130fdc8d8SChris Lattner         {
45230fdc8d8SChris Lattner             result.AppendError("out of memory");
45330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
45430fdc8d8SChris Lattner         }
45530fdc8d8SChris Lattner         return result.Succeeded();
45630fdc8d8SChris Lattner     }
45730fdc8d8SChris Lattner 
45830fdc8d8SChris Lattner     if (command[0] == '-')
45930fdc8d8SChris Lattner     {
46030fdc8d8SChris Lattner         // We have some options and these options MUST end with --.
46130fdc8d8SChris Lattner         const char *end_options = NULL;
46230fdc8d8SChris Lattner         const char *s = command;
46330fdc8d8SChris Lattner         while (s && s[0])
46430fdc8d8SChris Lattner         {
46530fdc8d8SChris Lattner             end_options = ::strstr (s, "--");
46630fdc8d8SChris Lattner             if (end_options)
46730fdc8d8SChris Lattner             {
46830fdc8d8SChris Lattner                 end_options += 2; // Get past the "--"
46930fdc8d8SChris Lattner                 if (::isspace (end_options[0]))
47030fdc8d8SChris Lattner                 {
47130fdc8d8SChris Lattner                     expr = end_options;
47230fdc8d8SChris Lattner                     while (::isspace (*expr))
47330fdc8d8SChris Lattner                         ++expr;
47430fdc8d8SChris Lattner                     break;
47530fdc8d8SChris Lattner                 }
47630fdc8d8SChris Lattner             }
47730fdc8d8SChris Lattner             s = end_options;
47830fdc8d8SChris Lattner         }
47930fdc8d8SChris Lattner 
48030fdc8d8SChris Lattner         if (end_options)
48130fdc8d8SChris Lattner         {
48230fdc8d8SChris Lattner             Args args (command, end_options - command);
483a7015092SGreg Clayton             if (!ParseOptions (args, result))
48430fdc8d8SChris Lattner                 return false;
485f6b8b581SGreg Clayton 
4861deb7962SGreg Clayton             Error error (m_option_group.NotifyOptionParsingFinished());
487f6b8b581SGreg Clayton             if (error.Fail())
488f6b8b581SGreg Clayton             {
489f6b8b581SGreg Clayton                 result.AppendError (error.AsCString());
490f6b8b581SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
491f6b8b581SGreg Clayton                 return false;
492f6b8b581SGreg Clayton             }
49330fdc8d8SChris Lattner         }
49430fdc8d8SChris Lattner     }
49530fdc8d8SChris Lattner 
49630fdc8d8SChris Lattner     if (expr == NULL)
49730fdc8d8SChris Lattner         expr = command;
49830fdc8d8SChris Lattner 
4996e8dc334SCaroline Tice     if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
500fcd43b71SJohnny Chen         return true;
501fcd43b71SJohnny Chen 
502fcd43b71SJohnny Chen     result.SetStatus (eReturnStatusFailed);
503fcd43b71SJohnny Chen     return false;
50430fdc8d8SChris Lattner }
50530fdc8d8SChris Lattner 
506