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) :
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 
1675009f9d5SGreg Clayton     // Add the "--format" and "--gdb-format"
1685009f9d5SGreg Clayton     m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, 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();
286c0a6e061SSean Callanan 
287c0a6e061SSean Callanan     if (!target)
288c0a6e061SSean Callanan         target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
289c0a6e061SSean Callanan 
290c14ee32dSGreg Clayton     if (target)
2916961e878SSean Callanan     {
2928b2fe6dcSGreg Clayton         lldb::ValueObjectSP result_valobj_sp;
2938b2fe6dcSGreg Clayton 
294e0d378b3SGreg Clayton         ExecutionResults exe_results;
29592adcac9SSean Callanan 
29692adcac9SSean Callanan         bool keep_in_memory = true;
2972837b766SJim Ingham         lldb::DynamicValueType use_dynamic;
29878a685aaSJim Ingham         // If use dynamic is not set, get it from the target:
2991deb7962SGreg Clayton         switch (m_command_options.use_dynamic)
30078a685aaSJim Ingham         {
30178a685aaSJim Ingham         case eLazyBoolCalculate:
302c14ee32dSGreg Clayton             use_dynamic = target->GetPreferDynamicValue();
30378a685aaSJim Ingham             break;
30478a685aaSJim Ingham         case eLazyBoolYes:
3052837b766SJim Ingham             use_dynamic = lldb::eDynamicCanRunTarget;
30678a685aaSJim Ingham             break;
30778a685aaSJim Ingham         case eLazyBoolNo:
3082837b766SJim Ingham             use_dynamic = lldb::eNoDynamicValues;
30978a685aaSJim Ingham             break;
31078a685aaSJim Ingham         }
31192adcac9SSean Callanan 
312c14ee32dSGreg Clayton         exe_results = target->EvaluateExpression (expr,
313c14ee32dSGreg Clayton                                                   m_exe_ctx.GetFramePtr(),
3143bfdaa2aSSean Callanan                                                   eExecutionPolicyOnlyWhenNeeded,
315*20bb3aa5SSean Callanan                                                   m_command_options.print_object,
3161deb7962SGreg Clayton                                                   m_command_options.unwind_on_error,
3173bfdaa2aSSean Callanan                                                   keep_in_memory,
3183bfdaa2aSSean Callanan                                                   use_dynamic,
3193bfdaa2aSSean Callanan                                                   result_valobj_sp);
3208b2fe6dcSGreg Clayton 
3211deb7962SGreg Clayton         if (exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error)
3228b2fe6dcSGreg Clayton         {
3237260f620SGreg Clayton             uint32_t start_frame = 0;
3247260f620SGreg Clayton             uint32_t num_frames = 1;
3257260f620SGreg Clayton             uint32_t num_frames_with_source = 0;
326c14ee32dSGreg Clayton             Thread *thread = m_exe_ctx.GetThreadPtr();
327c14ee32dSGreg Clayton             if (thread)
3287260f620SGreg Clayton             {
329c14ee32dSGreg Clayton                 thread->GetStatus (result->GetOutputStream(),
3307260f620SGreg Clayton                                    start_frame,
3317260f620SGreg Clayton                                    num_frames,
3327260f620SGreg Clayton                                    num_frames_with_source);
3337260f620SGreg Clayton             }
334c14ee32dSGreg Clayton             else
335c14ee32dSGreg Clayton             {
336c14ee32dSGreg Clayton                 Process *process = m_exe_ctx.GetProcessPtr();
337c14ee32dSGreg Clayton                 if (process)
3387260f620SGreg Clayton                 {
3397260f620SGreg Clayton                     bool only_threads_with_stop_reason = true;
340c14ee32dSGreg Clayton                     process->GetThreadStatus (result->GetOutputStream(),
3417260f620SGreg Clayton                                               only_threads_with_stop_reason,
3427260f620SGreg Clayton                                               start_frame,
3437260f620SGreg Clayton                                               num_frames,
3447260f620SGreg Clayton                                               num_frames_with_source);
3457260f620SGreg Clayton                 }
3466961e878SSean Callanan             }
347c14ee32dSGreg Clayton         }
3486961e878SSean Callanan 
3498b2fe6dcSGreg Clayton         if (result_valobj_sp)
3508b2fe6dcSGreg Clayton         {
351b71f3844SGreg Clayton             if (result_valobj_sp->GetError().Success())
35230fdc8d8SChris Lattner             {
3531deb7962SGreg Clayton                 Format format = m_format_options.GetFormat();
3541deb7962SGreg Clayton                 if (format != eFormatDefault)
3551deb7962SGreg Clayton                     result_valobj_sp->SetFormat (format);
35632c4085bSGreg Clayton 
3576e8dc334SCaroline Tice                 ValueObject::DumpValueObject (*(output_stream),
3580184f019SGreg Clayton                                               result_valobj_sp.get(),   // Variable object to dump
3598b2fe6dcSGreg Clayton                                               result_valobj_sp->GetName().GetCString(),// Root object name
3601d3afba3SGreg Clayton                                               0,                        // Pointer depth to traverse (zero means stop at pointers)
3611d3afba3SGreg Clayton                                               0,                        // Current depth, this is the top most, so zero...
3621d3afba3SGreg Clayton                                               UINT32_MAX,               // Max depth to go when dumping concrete types, dump everything...
3631deb7962SGreg Clayton                                               m_command_options.show_types,     // Show types when dumping?
3641d3afba3SGreg Clayton                                               false,                    // Show locations of variables, no since this is a host address which we don't care to see
3651deb7962SGreg Clayton                                               m_command_options.print_object,   // Print the objective C object?
36678a685aaSJim Ingham                                               use_dynamic,
367d55546b2SEnrico Granata                                               true,                     // Use synthetic children if available
3688f92f0a3SGreg Clayton                                               true,                     // Scope is already checked. Const results are always in scope.
3690c5ef693SEnrico Granata                                               false,                    // Don't flatten output
37022c55d18SEnrico Granata                                               0,                        // Always use summaries (you might want an option --no-summary like there is for frame variable)
37122c55d18SEnrico Granata                                               false);                   // Do not show more children than settings allow
372fcd43b71SJohnny Chen                 if (result)
373fcd43b71SJohnny Chen                     result->SetStatus (eReturnStatusSuccessFinishResult);
37430fdc8d8SChris Lattner             }
37530fdc8d8SChris Lattner             else
37630fdc8d8SChris Lattner             {
377bccce813SSean Callanan                 if (result_valobj_sp->GetError().GetError() == ClangUserExpression::kNoResult)
378bccce813SSean Callanan                 {
379bccce813SSean Callanan                     error_stream->PutCString("<no result>\n");
380bccce813SSean Callanan 
381bccce813SSean Callanan                     if (result)
382bccce813SSean Callanan                         result->SetStatus (eReturnStatusSuccessFinishResult);
383bccce813SSean 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
41830fdc8d8SChris Lattner CommandObjectExpression::ExecuteRawCommandString
41930fdc8d8SChris Lattner (
42030fdc8d8SChris Lattner     const char *command,
42130fdc8d8SChris Lattner     CommandReturnObject &result
42230fdc8d8SChris Lattner )
42330fdc8d8SChris Lattner {
4248b82f087SGreg Clayton     m_exe_ctx = m_interpreter.GetExecutionContext();
42530fdc8d8SChris Lattner 
4261deb7962SGreg Clayton     m_option_group.NotifyOptionParsingStarting();
42730fdc8d8SChris Lattner 
42830fdc8d8SChris Lattner     const char * expr = NULL;
42930fdc8d8SChris Lattner 
43030fdc8d8SChris Lattner     if (command[0] == '\0')
43130fdc8d8SChris Lattner     {
43230fdc8d8SChris Lattner         m_expr_lines.clear();
43330fdc8d8SChris Lattner         m_expr_line_count = 0;
43430fdc8d8SChris Lattner 
435a7015092SGreg Clayton         InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
43630fdc8d8SChris Lattner         if (reader_sp)
43730fdc8d8SChris Lattner         {
43830fdc8d8SChris Lattner             Error err (reader_sp->Initialize (CommandObjectExpression::MultiLineExpressionCallback,
43930fdc8d8SChris Lattner                                               this,                         // baton
44030fdc8d8SChris Lattner                                               eInputReaderGranularityLine,  // token size, to pass to callback function
44130fdc8d8SChris Lattner                                               NULL,                         // end token
44230fdc8d8SChris Lattner                                               NULL,                         // prompt
44330fdc8d8SChris Lattner                                               true));                       // echo input
44430fdc8d8SChris Lattner             if (err.Success())
44530fdc8d8SChris Lattner             {
446a7015092SGreg Clayton                 m_interpreter.GetDebugger().PushInputReader (reader_sp);
44730fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
44830fdc8d8SChris Lattner             }
44930fdc8d8SChris Lattner             else
45030fdc8d8SChris Lattner             {
45130fdc8d8SChris Lattner                 result.AppendError (err.AsCString());
45230fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
45330fdc8d8SChris Lattner             }
45430fdc8d8SChris Lattner         }
45530fdc8d8SChris Lattner         else
45630fdc8d8SChris Lattner         {
45730fdc8d8SChris Lattner             result.AppendError("out of memory");
45830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
45930fdc8d8SChris Lattner         }
46030fdc8d8SChris Lattner         return result.Succeeded();
46130fdc8d8SChris Lattner     }
46230fdc8d8SChris Lattner 
46330fdc8d8SChris Lattner     if (command[0] == '-')
46430fdc8d8SChris Lattner     {
46530fdc8d8SChris Lattner         // We have some options and these options MUST end with --.
46630fdc8d8SChris Lattner         const char *end_options = NULL;
46730fdc8d8SChris Lattner         const char *s = command;
46830fdc8d8SChris Lattner         while (s && s[0])
46930fdc8d8SChris Lattner         {
47030fdc8d8SChris Lattner             end_options = ::strstr (s, "--");
47130fdc8d8SChris Lattner             if (end_options)
47230fdc8d8SChris Lattner             {
47330fdc8d8SChris Lattner                 end_options += 2; // Get past the "--"
47430fdc8d8SChris Lattner                 if (::isspace (end_options[0]))
47530fdc8d8SChris Lattner                 {
47630fdc8d8SChris Lattner                     expr = end_options;
47730fdc8d8SChris Lattner                     while (::isspace (*expr))
47830fdc8d8SChris Lattner                         ++expr;
47930fdc8d8SChris Lattner                     break;
48030fdc8d8SChris Lattner                 }
48130fdc8d8SChris Lattner             }
48230fdc8d8SChris Lattner             s = end_options;
48330fdc8d8SChris Lattner         }
48430fdc8d8SChris Lattner 
48530fdc8d8SChris Lattner         if (end_options)
48630fdc8d8SChris Lattner         {
48730fdc8d8SChris Lattner             Args args (command, end_options - command);
488a7015092SGreg Clayton             if (!ParseOptions (args, result))
48930fdc8d8SChris Lattner                 return false;
490f6b8b581SGreg Clayton 
4911deb7962SGreg Clayton             Error error (m_option_group.NotifyOptionParsingFinished());
492f6b8b581SGreg Clayton             if (error.Fail())
493f6b8b581SGreg Clayton             {
494f6b8b581SGreg Clayton                 result.AppendError (error.AsCString());
495f6b8b581SGreg Clayton                 result.SetStatus (eReturnStatusFailed);
496f6b8b581SGreg Clayton                 return false;
497f6b8b581SGreg Clayton             }
49830fdc8d8SChris Lattner         }
49930fdc8d8SChris Lattner     }
50030fdc8d8SChris Lattner 
50130fdc8d8SChris Lattner     if (expr == NULL)
50230fdc8d8SChris Lattner         expr = command;
50330fdc8d8SChris Lattner 
5046e8dc334SCaroline Tice     if (EvaluateExpression (expr, &(result.GetOutputStream()), &(result.GetErrorStream()), &result))
505fcd43b71SJohnny Chen         return true;
506fcd43b71SJohnny Chen 
507fcd43b71SJohnny Chen     result.SetStatus (eReturnStatusFailed);
508fcd43b71SJohnny Chen     return false;
50930fdc8d8SChris Lattner }
51030fdc8d8SChris Lattner 
511