1ebc09c36SJim Ingham //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
2ebc09c36SJim Ingham //
3ebc09c36SJim Ingham //                     The LLVM Compiler Infrastructure
4ebc09c36SJim Ingham //
5ebc09c36SJim Ingham // This file is distributed under the University of Illinois Open Source
6ebc09c36SJim Ingham // License. See LICENSE.TXT for details.
7ebc09c36SJim Ingham //
8ebc09c36SJim Ingham //===----------------------------------------------------------------------===//
9ebc09c36SJim Ingham 
10ebc09c36SJim Ingham #include "CommandObjectCommands.h"
11ebc09c36SJim Ingham 
12ebc09c36SJim Ingham // C Includes
13ebc09c36SJim Ingham // C++ Includes
14ebc09c36SJim Ingham // Other libraries and framework includes
150e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h"
160e5e5a79SGreg Clayton 
17ebc09c36SJim Ingham // Project includes
18ebc09c36SJim Ingham #include "lldb/Core/Debugger.h"
1944d93782SGreg Clayton #include "lldb/Core/IOHandler.h"
20be93a35aSEnrico Granata #include "lldb/Core/StringList.h"
21de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h"
227594f14fSEnrico Granata #include "lldb/Interpreter/CommandHistory.h"
23ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h"
24de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h"
25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h"
26012d4fcaSEnrico Granata #include "lldb/Interpreter/OptionValueBoolean.h"
277594f14fSEnrico Granata #include "lldb/Interpreter/OptionValueUInt64.h"
28ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
2999f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h"
30ebc09c36SJim Ingham 
31ebc09c36SJim Ingham using namespace lldb;
32ebc09c36SJim Ingham using namespace lldb_private;
33ebc09c36SJim Ingham 
34ebc09c36SJim Ingham //-------------------------------------------------------------------------
35ebc09c36SJim Ingham // CommandObjectCommandsSource
36ebc09c36SJim Ingham //-------------------------------------------------------------------------
37ebc09c36SJim Ingham 
385a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed
39a5a97ebeSJim Ingham {
405a988416SJim Ingham public:
415a988416SJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
425a988416SJim Ingham         CommandObjectParsed (interpreter,
435a988416SJim Ingham                              "command history",
445a988416SJim Ingham                              "Dump the history of commands in this session.",
455a988416SJim Ingham                              NULL),
465a988416SJim Ingham         m_options (interpreter)
475a988416SJim Ingham     {
485a988416SJim Ingham     }
495a988416SJim Ingham 
505a988416SJim Ingham     ~CommandObjectCommandsHistory () {}
515a988416SJim Ingham 
525a988416SJim Ingham     virtual Options *
535a988416SJim Ingham     GetOptions ()
545a988416SJim Ingham     {
555a988416SJim Ingham         return &m_options;
565a988416SJim Ingham     }
575a988416SJim Ingham 
585a988416SJim Ingham protected:
59a5a97ebeSJim Ingham 
60a5a97ebeSJim Ingham     class CommandOptions : public Options
61a5a97ebeSJim Ingham     {
62a5a97ebeSJim Ingham     public:
63a5a97ebeSJim Ingham 
64a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
657594f14fSEnrico Granata             Options (interpreter),
667594f14fSEnrico Granata             m_start_idx(0),
677594f14fSEnrico Granata             m_stop_idx(0),
687594f14fSEnrico Granata             m_count(0),
6963123b64SEnrico Granata             m_clear(false)
70a5a97ebeSJim Ingham         {
71a5a97ebeSJim Ingham         }
72a5a97ebeSJim Ingham 
73a5a97ebeSJim Ingham         virtual
74a5a97ebeSJim Ingham         ~CommandOptions (){}
75a5a97ebeSJim Ingham 
76a5a97ebeSJim Ingham         virtual Error
77a5a97ebeSJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
78a5a97ebeSJim Ingham         {
79a5a97ebeSJim Ingham             Error error;
803bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
81a5a97ebeSJim Ingham 
82a5a97ebeSJim Ingham             switch (short_option)
83a5a97ebeSJim Ingham             {
84a5a97ebeSJim Ingham                 case 'c':
85c95f7e2aSPavel Labath                     error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
86a5a97ebeSJim Ingham                     break;
87a5a97ebeSJim Ingham                 case 's':
887594f14fSEnrico Granata                     if (option_arg && strcmp("end", option_arg) == 0)
897594f14fSEnrico Granata                     {
907594f14fSEnrico Granata                         m_start_idx.SetCurrentValue(UINT64_MAX);
917594f14fSEnrico Granata                         m_start_idx.SetOptionWasSet();
927594f14fSEnrico Granata                     }
937594f14fSEnrico Granata                     else
94c95f7e2aSPavel Labath                         error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
957594f14fSEnrico Granata                     break;
967594f14fSEnrico Granata                 case 'e':
97c95f7e2aSPavel Labath                     error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
987594f14fSEnrico Granata                     break;
9963123b64SEnrico Granata                 case 'C':
10063123b64SEnrico Granata                     m_clear.SetCurrentValue(true);
10163123b64SEnrico Granata                     m_clear.SetOptionWasSet();
102a5a97ebeSJim Ingham                     break;
103a5a97ebeSJim Ingham                 default:
10486edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
105a5a97ebeSJim Ingham                     break;
106a5a97ebeSJim Ingham             }
107a5a97ebeSJim Ingham 
108a5a97ebeSJim Ingham             return error;
109a5a97ebeSJim Ingham         }
110a5a97ebeSJim Ingham 
111a5a97ebeSJim Ingham         void
112a5a97ebeSJim Ingham         OptionParsingStarting ()
113a5a97ebeSJim Ingham         {
1147594f14fSEnrico Granata             m_start_idx.Clear();
1157594f14fSEnrico Granata             m_stop_idx.Clear();
1167594f14fSEnrico Granata             m_count.Clear();
11763123b64SEnrico Granata             m_clear.Clear();
118a5a97ebeSJim Ingham         }
119a5a97ebeSJim Ingham 
120a5a97ebeSJim Ingham         const OptionDefinition*
121a5a97ebeSJim Ingham         GetDefinitions ()
122a5a97ebeSJim Ingham         {
123a5a97ebeSJim Ingham             return g_option_table;
124a5a97ebeSJim Ingham         }
125a5a97ebeSJim Ingham 
126a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
127a5a97ebeSJim Ingham 
128a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
129a5a97ebeSJim Ingham 
130a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
131a5a97ebeSJim Ingham 
1327594f14fSEnrico Granata         OptionValueUInt64 m_start_idx;
1337594f14fSEnrico Granata         OptionValueUInt64 m_stop_idx;
1347594f14fSEnrico Granata         OptionValueUInt64 m_count;
13563123b64SEnrico Granata         OptionValueBoolean m_clear;
136a5a97ebeSJim Ingham     };
137a5a97ebeSJim Ingham 
138a5a97ebeSJim Ingham     bool
1395a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
140a5a97ebeSJim Ingham     {
14163123b64SEnrico Granata         if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
1427594f14fSEnrico Granata         {
1437594f14fSEnrico Granata             m_interpreter.GetCommandHistory().Clear();
1447594f14fSEnrico Granata             result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
1457594f14fSEnrico Granata         }
1467594f14fSEnrico Granata         else
1477594f14fSEnrico Granata         {
1487594f14fSEnrico Granata             if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
1497594f14fSEnrico Granata             {
1507594f14fSEnrico Granata                 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
1517594f14fSEnrico Granata                 result.SetStatus(lldb::eReturnStatusFailed);
1527594f14fSEnrico Granata             }
1537594f14fSEnrico Granata             else
1547594f14fSEnrico Granata             {
15584400ec7SVirgile Bello                 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
15684400ec7SVirgile Bello                 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
15784400ec7SVirgile Bello                 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
158a5a97ebeSJim Ingham 
1597594f14fSEnrico Granata                 const CommandHistory& history(m_interpreter.GetCommandHistory());
1607594f14fSEnrico Granata 
1617594f14fSEnrico Granata                 if (start_idx.first && start_idx.second == UINT64_MAX)
1627594f14fSEnrico Granata                 {
1637594f14fSEnrico Granata                     if (count.first)
1647594f14fSEnrico Granata                     {
1657594f14fSEnrico Granata                         start_idx.second = history.GetSize() - count.second;
1667594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1677594f14fSEnrico Granata                     }
1687594f14fSEnrico Granata                     else if (stop_idx.first)
1697594f14fSEnrico Granata                     {
1707594f14fSEnrico Granata                         start_idx.second = stop_idx.second;
1717594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1727594f14fSEnrico Granata                     }
1737594f14fSEnrico Granata                     else
1747594f14fSEnrico Granata                     {
1757594f14fSEnrico Granata                         start_idx.second = 0;
1767594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1777594f14fSEnrico Granata                     }
1787594f14fSEnrico Granata                 }
1797594f14fSEnrico Granata                 else
1807594f14fSEnrico Granata                 {
1817594f14fSEnrico Granata                     if (!start_idx.first && !stop_idx.first && !count.first)
1827594f14fSEnrico Granata                     {
1837594f14fSEnrico Granata                         start_idx.second = 0;
1847594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1857594f14fSEnrico Granata                     }
1867594f14fSEnrico Granata                     else if (start_idx.first)
1877594f14fSEnrico Granata                     {
1887594f14fSEnrico Granata                         if (count.first)
1897594f14fSEnrico Granata                         {
1907594f14fSEnrico Granata                             stop_idx.second = start_idx.second + count.second - 1;
1917594f14fSEnrico Granata                         }
1927594f14fSEnrico Granata                         else if (!stop_idx.first)
1937594f14fSEnrico Granata                         {
1947594f14fSEnrico Granata                             stop_idx.second = history.GetSize() - 1;
1957594f14fSEnrico Granata                         }
1967594f14fSEnrico Granata                     }
1977594f14fSEnrico Granata                     else if (stop_idx.first)
1987594f14fSEnrico Granata                     {
1997594f14fSEnrico Granata                         if (count.first)
2007594f14fSEnrico Granata                         {
2017594f14fSEnrico Granata                             if (stop_idx.second >= count.second)
2027594f14fSEnrico Granata                                 start_idx.second = stop_idx.second - count.second + 1;
2037594f14fSEnrico Granata                             else
2047594f14fSEnrico Granata                                 start_idx.second = 0;
2057594f14fSEnrico Granata                         }
2067594f14fSEnrico Granata                     }
2077594f14fSEnrico Granata                     else /* if (count.first) */
2087594f14fSEnrico Granata                     {
2097594f14fSEnrico Granata                         start_idx.second = 0;
2107594f14fSEnrico Granata                         stop_idx.second = count.second - 1;
2117594f14fSEnrico Granata                     }
2127594f14fSEnrico Granata                 }
2137594f14fSEnrico Granata                 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
2147594f14fSEnrico Granata             }
2157594f14fSEnrico Granata         }
216a5a97ebeSJim Ingham         return result.Succeeded();
217a5a97ebeSJim Ingham 
218a5a97ebeSJim Ingham     }
2195a988416SJim Ingham 
2205a988416SJim Ingham     CommandOptions m_options;
221a5a97ebeSJim Ingham };
222a5a97ebeSJim Ingham 
223a5a97ebeSJim Ingham OptionDefinition
224a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
225a5a97ebeSJim Ingham {
226d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
227d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,  "Index at which to start printing history commands (or end to mean tail mode)."},
228d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
229d37221dcSZachary Turner { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean,    "Clears the current command history."},
230d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
231a5a97ebeSJim Ingham };
232a5a97ebeSJim Ingham 
233a5a97ebeSJim Ingham 
234a5a97ebeSJim Ingham //-------------------------------------------------------------------------
235a5a97ebeSJim Ingham // CommandObjectCommandsSource
236a5a97ebeSJim Ingham //-------------------------------------------------------------------------
237a5a97ebeSJim Ingham 
2385a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed
239ebc09c36SJim Ingham {
2405a988416SJim Ingham public:
2415a988416SJim Ingham     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
2425a988416SJim Ingham         CommandObjectParsed (interpreter,
2435a988416SJim Ingham                              "command source",
2445a988416SJim Ingham                              "Read in debugger commands from the file <filename> and execute them.",
2455a988416SJim Ingham                              NULL),
2465a988416SJim Ingham         m_options (interpreter)
2475a988416SJim Ingham     {
2485a988416SJim Ingham         CommandArgumentEntry arg;
2495a988416SJim Ingham         CommandArgumentData file_arg;
2505a988416SJim Ingham 
2515a988416SJim Ingham         // Define the first (and only) variant of this arg.
2525a988416SJim Ingham         file_arg.arg_type = eArgTypeFilename;
2535a988416SJim Ingham         file_arg.arg_repetition = eArgRepeatPlain;
2545a988416SJim Ingham 
2555a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
2565a988416SJim Ingham         arg.push_back (file_arg);
2575a988416SJim Ingham 
2585a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
2595a988416SJim Ingham         m_arguments.push_back (arg);
2605a988416SJim Ingham     }
2615a988416SJim Ingham 
2625a988416SJim Ingham     ~CommandObjectCommandsSource () {}
2635a988416SJim Ingham 
2645a988416SJim Ingham     virtual const char*
2655a988416SJim Ingham     GetRepeatCommand (Args &current_command_args, uint32_t index)
2665a988416SJim Ingham     {
2675a988416SJim Ingham         return "";
2685a988416SJim Ingham     }
2695a988416SJim Ingham 
270c7bece56SGreg Clayton     virtual int
2715a988416SJim Ingham     HandleArgumentCompletion (Args &input,
2725a988416SJim Ingham                               int &cursor_index,
2735a988416SJim Ingham                               int &cursor_char_position,
2745a988416SJim Ingham                               OptionElementVector &opt_element_vector,
2755a988416SJim Ingham                               int match_start_point,
2765a988416SJim Ingham                               int max_return_elements,
2775a988416SJim Ingham                               bool &word_complete,
2785a988416SJim Ingham                               StringList &matches)
2795a988416SJim Ingham     {
2805a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2815a988416SJim Ingham         completion_str.erase (cursor_char_position);
2825a988416SJim Ingham 
2835a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2845a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
2855a988416SJim Ingham                                                              completion_str.c_str(),
2865a988416SJim Ingham                                                              match_start_point,
2875a988416SJim Ingham                                                              max_return_elements,
2885a988416SJim Ingham                                                              NULL,
2895a988416SJim Ingham                                                              word_complete,
2905a988416SJim Ingham                                                              matches);
2915a988416SJim Ingham         return matches.GetSize();
2925a988416SJim Ingham     }
2935a988416SJim Ingham 
2945a988416SJim Ingham     virtual Options *
2955a988416SJim Ingham     GetOptions ()
2965a988416SJim Ingham     {
2975a988416SJim Ingham         return &m_options;
2985a988416SJim Ingham     }
2995a988416SJim Ingham 
3005a988416SJim Ingham protected:
301e16c50a1SJim Ingham 
302e16c50a1SJim Ingham     class CommandOptions : public Options
303e16c50a1SJim Ingham     {
304e16c50a1SJim Ingham     public:
305e16c50a1SJim Ingham 
306eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
307012d4fcaSEnrico Granata             Options (interpreter),
308340b0309SGreg Clayton             m_stop_on_error (true),
309340b0309SGreg Clayton             m_silent_run (false),
310340b0309SGreg Clayton             m_stop_on_continue (true)
311eb0103f2SGreg Clayton         {
312eb0103f2SGreg Clayton         }
313e16c50a1SJim Ingham 
314e16c50a1SJim Ingham         virtual
315e16c50a1SJim Ingham         ~CommandOptions (){}
316e16c50a1SJim Ingham 
317e16c50a1SJim Ingham         virtual Error
318f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
319e16c50a1SJim Ingham         {
320e16c50a1SJim Ingham             Error error;
3213bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
322e16c50a1SJim Ingham 
323e16c50a1SJim Ingham             switch (short_option)
324e16c50a1SJim Ingham             {
325e16c50a1SJim Ingham                 case 'e':
326c95f7e2aSPavel Labath                     error = m_stop_on_error.SetValueFromString(option_arg);
327e16c50a1SJim Ingham                     break;
328340b0309SGreg Clayton 
329e16c50a1SJim Ingham                 case 'c':
330c95f7e2aSPavel Labath                     error = m_stop_on_continue.SetValueFromString(option_arg);
331e16c50a1SJim Ingham                     break;
332340b0309SGreg Clayton 
33360986174SMichael Sartain                 case 's':
334c95f7e2aSPavel Labath                     error = m_silent_run.SetValueFromString(option_arg);
33560986174SMichael Sartain                     break;
336340b0309SGreg Clayton 
337e16c50a1SJim Ingham                 default:
33886edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
339e16c50a1SJim Ingham                     break;
340e16c50a1SJim Ingham             }
341e16c50a1SJim Ingham 
342e16c50a1SJim Ingham             return error;
343e16c50a1SJim Ingham         }
344e16c50a1SJim Ingham 
345e16c50a1SJim Ingham         void
346f6b8b581SGreg Clayton         OptionParsingStarting ()
347e16c50a1SJim Ingham         {
348012d4fcaSEnrico Granata             m_stop_on_error.Clear();
349340b0309SGreg Clayton             m_silent_run.Clear();
350340b0309SGreg Clayton             m_stop_on_continue.Clear();
351e16c50a1SJim Ingham         }
352e16c50a1SJim Ingham 
353e0d378b3SGreg Clayton         const OptionDefinition*
354e16c50a1SJim Ingham         GetDefinitions ()
355e16c50a1SJim Ingham         {
356e16c50a1SJim Ingham             return g_option_table;
357e16c50a1SJim Ingham         }
358e16c50a1SJim Ingham 
359e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
360e16c50a1SJim Ingham 
361e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
362e16c50a1SJim Ingham 
363e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
364e16c50a1SJim Ingham 
365012d4fcaSEnrico Granata         OptionValueBoolean m_stop_on_error;
366340b0309SGreg Clayton         OptionValueBoolean m_silent_run;
367340b0309SGreg Clayton         OptionValueBoolean m_stop_on_continue;
368e16c50a1SJim Ingham     };
369e16c50a1SJim Ingham 
370ebc09c36SJim Ingham     bool
3715a988416SJim Ingham     DoExecute(Args& command, CommandReturnObject &result)
372ebc09c36SJim Ingham     {
373c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
374ebc09c36SJim Ingham         if (argc == 1)
375ebc09c36SJim Ingham         {
3765a988416SJim Ingham             const char *filename = command.GetArgumentAtIndex(0);
377ebc09c36SJim Ingham 
3781ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
379e16c50a1SJim Ingham             ExecutionContext *exe_ctx = NULL;  // Just use the default context.
380ebc09c36SJim Ingham 
381340b0309SGreg Clayton             // If any options were set, then use them
382340b0309SGreg Clayton             if (m_options.m_stop_on_error.OptionWasSet()    ||
383340b0309SGreg Clayton                 m_options.m_silent_run.OptionWasSet()       ||
384340b0309SGreg Clayton                 m_options.m_stop_on_continue.OptionWasSet())
385340b0309SGreg Clayton             {
386340b0309SGreg Clayton                 // Use user set settings
38726c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
38826c7bf93SJim Ingham                 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
38926c7bf93SJim Ingham                 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
3907d8555c4SJim Ingham                 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
3917d8555c4SJim Ingham                 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
39226c7bf93SJim Ingham 
393e16c50a1SJim Ingham                 m_interpreter.HandleCommandsFromFile (cmd_file,
394e16c50a1SJim Ingham                                                       exe_ctx,
39526c7bf93SJim Ingham                                                       options,
396e16c50a1SJim Ingham                                                       result);
397340b0309SGreg Clayton 
398340b0309SGreg Clayton             }
399340b0309SGreg Clayton             else
400340b0309SGreg Clayton             {
401340b0309SGreg Clayton                 // No options were set, inherit any settings from nested "command source" commands,
402340b0309SGreg Clayton                 // or set to sane default settings...
40326c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
404340b0309SGreg Clayton                 m_interpreter.HandleCommandsFromFile (cmd_file,
405340b0309SGreg Clayton                                                       exe_ctx,
40626c7bf93SJim Ingham                                                       options,
407340b0309SGreg Clayton                                                       result);
408340b0309SGreg Clayton 
409340b0309SGreg Clayton             }
410ebc09c36SJim Ingham         }
411ebc09c36SJim Ingham         else
412ebc09c36SJim Ingham         {
413ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
414ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
415ebc09c36SJim Ingham         }
416ebc09c36SJim Ingham         return result.Succeeded();
417ebc09c36SJim Ingham 
418ebc09c36SJim Ingham     }
4195a988416SJim Ingham     CommandOptions m_options;
420ebc09c36SJim Ingham };
421ebc09c36SJim Ingham 
422e0d378b3SGreg Clayton OptionDefinition
423e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
424e16c50a1SJim Ingham {
425d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
426d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
427d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
428d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
429e16c50a1SJim Ingham };
430e16c50a1SJim Ingham 
431ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
432ebc09c36SJim Ingham //-------------------------------------------------------------------------
433ebc09c36SJim Ingham // CommandObjectCommandsAlias
434ebc09c36SJim Ingham //-------------------------------------------------------------------------
435ebc09c36SJim Ingham 
436be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
437be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
43844d93782SGreg Clayton                                                      "def my_command_impl(debugger, args, result, internal_dict):\n";
439be93a35aSEnrico Granata 
440be93a35aSEnrico Granata 
4415a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw
442ebc09c36SJim Ingham {
443be93a35aSEnrico Granata 
444be93a35aSEnrico Granata 
445ebc09c36SJim Ingham public:
446a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
4475a988416SJim Ingham         CommandObjectRaw (interpreter,
4480e5e5a79SGreg Clayton                        "command alias",
449e3d26315SCaroline Tice                        "Allow users to define their own debugger command abbreviations.",
450405fe67fSCaroline Tice                        NULL)
451ebc09c36SJim Ingham     {
452ebc09c36SJim Ingham         SetHelpLong(
453*ea671fbdSKate Stone "'alias' allows the user to create a short-cut or abbreviation for long \
454*ea671fbdSKate Stone commands, multi-word commands, and commands that take particular options.  \
455*ea671fbdSKate Stone Below are some simple examples of how one might use the 'alias' command:" R"(
456*ea671fbdSKate Stone 
457*ea671fbdSKate Stone (lldb) command alias sc script
458*ea671fbdSKate Stone 
459*ea671fbdSKate Stone     Creates the abbreviation 'sc' for the 'script' command.
460*ea671fbdSKate Stone 
461*ea671fbdSKate Stone (lldb) command alias bp breakpoint
462*ea671fbdSKate Stone 
463*ea671fbdSKate Stone )" "    Creates the abbreviation 'bp' for the 'breakpoint' command.  Since \
464*ea671fbdSKate Stone breakpoint commands are two-word commands, the user would still need to \
465*ea671fbdSKate Stone enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"(
466*ea671fbdSKate Stone 
467*ea671fbdSKate Stone (lldb) command alias bpl breakpoint list
468*ea671fbdSKate Stone 
469*ea671fbdSKate Stone     Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
470*ea671fbdSKate Stone 
471*ea671fbdSKate Stone )" "An alias can include some options for the command, with the values either \
472*ea671fbdSKate Stone filled in at the time the alias is created, or specified as positional \
473*ea671fbdSKate Stone arguments, to be filled in when the alias is invoked.  The following example \
474*ea671fbdSKate Stone shows how to create aliases with options:" R"(
475*ea671fbdSKate Stone 
476*ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
477*ea671fbdSKate Stone 
478*ea671fbdSKate Stone )" "    Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
479*ea671fbdSKate Stone options already part of the alias.  So if the user wants to set a breakpoint \
480*ea671fbdSKate Stone by file and line without explicitly having to use the -f and -l options, the \
481*ea671fbdSKate Stone user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \
482*ea671fbdSKate Stone for the actual arguments that will be passed when the alias command is used.  \
483*ea671fbdSKate Stone The number in the placeholder refers to the position/order the actual value \
484*ea671fbdSKate Stone occupies when the alias is used.  All the occurrences of '%1' in the alias \
485*ea671fbdSKate Stone will be replaced with the first argument, all the occurrences of '%2' in the \
486*ea671fbdSKate Stone alias will be replaced with the second argument, and so on.  This also allows \
487*ea671fbdSKate Stone actual arguments to be used multiple times within an alias (see 'process \
488*ea671fbdSKate Stone launch' example below)." R"(
489*ea671fbdSKate Stone 
490*ea671fbdSKate Stone )" "Note: the positional arguments must substitute as whole words in the resultant \
491*ea671fbdSKate Stone command, so you can't at present do something like this to append the file extension \
492*ea671fbdSKate Stone \".cpp\":" R"(
493*ea671fbdSKate Stone 
494*ea671fbdSKate Stone (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
495*ea671fbdSKate Stone 
496*ea671fbdSKate Stone )" "For more complex aliasing, use the \"command regex\" command instead.  In the \
497*ea671fbdSKate Stone 'bfl' case above, the actual file value will be filled in with the first argument \
498*ea671fbdSKate Stone following 'bfl' and the actual line number value will be filled in with the second \
499*ea671fbdSKate Stone argument.  The user would use this alias as follows:" R"(
500*ea671fbdSKate Stone 
501*ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
502*ea671fbdSKate Stone (lldb) bfl my-file.c 137
503*ea671fbdSKate Stone 
504*ea671fbdSKate Stone This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
505*ea671fbdSKate Stone 
506*ea671fbdSKate Stone Another example:
507*ea671fbdSKate Stone 
508*ea671fbdSKate Stone (lldb) command alias pltty process launch -s -o %1 -e %1
509*ea671fbdSKate Stone (lldb) pltty /dev/tty0
510*ea671fbdSKate Stone 
511*ea671fbdSKate Stone     Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
512*ea671fbdSKate Stone 
513*ea671fbdSKate Stone )" "If the user always wanted to pass the same value to a particular option, the \
514*ea671fbdSKate Stone alias could be defined with that value directly in the alias as a constant, \
515*ea671fbdSKate Stone rather than using a positional placeholder:" R"(
516*ea671fbdSKate Stone 
517*ea671fbdSKate Stone (lldb) command alias bl3 breakpoint set -f %1 -l 3
518*ea671fbdSKate Stone 
519*ea671fbdSKate Stone     Always sets a breakpoint on line 3 of whatever file is indicated.)"
520*ea671fbdSKate Stone         );
521ebc09c36SJim Ingham 
522405fe67fSCaroline Tice         CommandArgumentEntry arg1;
523405fe67fSCaroline Tice         CommandArgumentEntry arg2;
524405fe67fSCaroline Tice         CommandArgumentEntry arg3;
525405fe67fSCaroline Tice         CommandArgumentData alias_arg;
526405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
527405fe67fSCaroline Tice         CommandArgumentData options_arg;
528405fe67fSCaroline Tice 
529405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
530405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
531405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
532405fe67fSCaroline Tice 
533405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
534405fe67fSCaroline Tice         arg1.push_back (alias_arg);
535405fe67fSCaroline Tice 
536405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
537405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
538405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
539405fe67fSCaroline Tice 
540405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
541405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
542405fe67fSCaroline Tice 
543405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
544405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
545405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
546405fe67fSCaroline Tice 
547405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
548405fe67fSCaroline Tice         arg3.push_back (options_arg);
549405fe67fSCaroline Tice 
550405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
551405fe67fSCaroline Tice         m_arguments.push_back (arg1);
552405fe67fSCaroline Tice         m_arguments.push_back (arg2);
553405fe67fSCaroline Tice         m_arguments.push_back (arg3);
554ebc09c36SJim Ingham     }
555ebc09c36SJim Ingham 
556ebc09c36SJim Ingham     ~CommandObjectCommandsAlias ()
557ebc09c36SJim Ingham     {
558ebc09c36SJim Ingham     }
559ebc09c36SJim Ingham 
5605a988416SJim Ingham protected:
5615a988416SJim Ingham     virtual bool
5625a988416SJim Ingham     DoExecute (const char *raw_command_line, CommandReturnObject &result)
563844d2303SCaroline Tice     {
564844d2303SCaroline Tice         Args args (raw_command_line);
565844d2303SCaroline Tice         std::string raw_command_string (raw_command_line);
566844d2303SCaroline Tice 
567844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
568844d2303SCaroline Tice 
569844d2303SCaroline Tice         if (argc < 2)
570844d2303SCaroline Tice         {
571844d2303SCaroline Tice             result.AppendError ("'alias' requires at least two arguments");
572844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
573844d2303SCaroline Tice             return false;
574844d2303SCaroline Tice         }
575844d2303SCaroline Tice 
576844d2303SCaroline Tice         // Get the alias command.
577844d2303SCaroline Tice 
578844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
579844d2303SCaroline Tice 
580844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
581844d2303SCaroline Tice         // does the stripping itself.
582844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
583844d2303SCaroline Tice         if (pos == 0)
584844d2303SCaroline Tice         {
585844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
586844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
587844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
588844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
589844d2303SCaroline Tice         }
590844d2303SCaroline Tice         else
591844d2303SCaroline Tice         {
592844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
593844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
594844d2303SCaroline Tice             return false;
595844d2303SCaroline Tice         }
596844d2303SCaroline Tice 
597844d2303SCaroline Tice 
598844d2303SCaroline Tice         // Verify that the command is alias-able.
599844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
600844d2303SCaroline Tice         {
601844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
602844d2303SCaroline Tice                                           alias_command.c_str());
603844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
604844d2303SCaroline Tice             return false;
605844d2303SCaroline Tice         }
606844d2303SCaroline Tice 
607844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
608844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
609844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
610844d2303SCaroline Tice 
611844d2303SCaroline Tice         if (!cmd_obj)
612844d2303SCaroline Tice         {
61386edbf41SGreg Clayton             result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
614844d2303SCaroline Tice                                           "  No alias created.", raw_command_string.c_str());
615844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
616844d2303SCaroline Tice             return false;
617844d2303SCaroline Tice         }
618844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
619844d2303SCaroline Tice         {
620844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
621844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
6225a988416SJim Ingham             return HandleAliasingNormalCommand (args, result);
623844d2303SCaroline Tice         }
624844d2303SCaroline Tice         else
625844d2303SCaroline Tice         {
6265a988416SJim Ingham             return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
6275a988416SJim Ingham         }
6285a988416SJim Ingham         return result.Succeeded();
6295a988416SJim Ingham     }
6305a988416SJim Ingham 
6315a988416SJim Ingham     bool
6325a988416SJim Ingham     HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
6335a988416SJim Ingham     {
634844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
635844d2303SCaroline Tice 
636844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
637844d2303SCaroline Tice             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
638844d2303SCaroline Tice 
6395a988416SJim Ingham             CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
640844d2303SCaroline Tice 
641ca90c47eSCaroline Tice             if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
642844d2303SCaroline Tice             {
643844d2303SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
644ca90c47eSCaroline Tice                 result.SetStatus (eReturnStatusFailed);
645844d2303SCaroline Tice                 return false;
646844d2303SCaroline Tice             }
647844d2303SCaroline Tice 
648844d2303SCaroline Tice             // Create the alias
649844d2303SCaroline Tice             if (m_interpreter.AliasExists (alias_command.c_str())
650844d2303SCaroline Tice                 || m_interpreter.UserCommandExists (alias_command.c_str()))
651844d2303SCaroline Tice             {
652844d2303SCaroline Tice                 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
653844d2303SCaroline Tice                 if (temp_option_arg_sp.get())
654844d2303SCaroline Tice                 {
655844d2303SCaroline Tice                     if (option_arg_vector->size() == 0)
656844d2303SCaroline Tice                         m_interpreter.RemoveAliasOptions (alias_command.c_str());
657844d2303SCaroline Tice                 }
658844d2303SCaroline Tice                 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
659844d2303SCaroline Tice                                                 alias_command.c_str());
660844d2303SCaroline Tice             }
661844d2303SCaroline Tice 
662472362e6SCaroline Tice             if (cmd_obj_sp)
663472362e6SCaroline Tice             {
664844d2303SCaroline Tice                 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
665844d2303SCaroline Tice                 if (option_arg_vector->size() > 0)
666844d2303SCaroline Tice                     m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
667844d2303SCaroline Tice                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
668844d2303SCaroline Tice             }
669472362e6SCaroline Tice             else
670472362e6SCaroline Tice             {
671472362e6SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
672472362e6SCaroline Tice                 result.SetStatus (eReturnStatusFailed);
673472362e6SCaroline Tice             }
674844d2303SCaroline Tice             return result.Succeeded ();
675844d2303SCaroline Tice     }
676ebc09c36SJim Ingham 
677ebc09c36SJim Ingham     bool
6785a988416SJim Ingham     HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
679ebc09c36SJim Ingham     {
680867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
681ebc09c36SJim Ingham 
682ebc09c36SJim Ingham         if (argc < 2)
683ebc09c36SJim Ingham         {
684ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
685ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
686ebc09c36SJim Ingham             return false;
687ebc09c36SJim Ingham         }
688ebc09c36SJim Ingham 
689ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
690ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
691ebc09c36SJim Ingham 
692ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
693ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
694ebc09c36SJim Ingham 
695ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
696ebc09c36SJim Ingham 
697a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
698ebc09c36SJim Ingham         {
699ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
700ebc09c36SJim Ingham                                          alias_command.c_str());
701ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
702ebc09c36SJim Ingham         }
703ebc09c36SJim Ingham         else
704ebc09c36SJim Ingham         {
705a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
706ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
707ebc09c36SJim Ingham              bool use_subcommand = false;
708ebc09c36SJim Ingham              if (command_obj_sp.get())
709ebc09c36SJim Ingham              {
710ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
711c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
712ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
713ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
714ebc09c36SJim Ingham 
715844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
716ebc09c36SJim Ingham                  {
717ebc09c36SJim Ingham                      if (argc >= 3)
718ebc09c36SJim Ingham                      {
719ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
720ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
721998255bfSGreg Clayton                          subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
722ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
723ebc09c36SJim Ingham                          {
724ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
725ebc09c36SJim Ingham                              use_subcommand = true;
726ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
727844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
728ebc09c36SJim Ingham                          }
729ebc09c36SJim Ingham                          else
730ebc09c36SJim Ingham                          {
731f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
732f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
733f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
734ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
735ebc09c36SJim Ingham                              return false;
736ebc09c36SJim Ingham                          }
737ebc09c36SJim Ingham                      }
738ebc09c36SJim Ingham                  }
739ebc09c36SJim Ingham 
740ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
741ebc09c36SJim Ingham 
742ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
743ebc09c36SJim Ingham                  {
744ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
745ebc09c36SJim Ingham                     if (use_subcommand)
746ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
747ca90c47eSCaroline Tice 
748ca90c47eSCaroline Tice                     std::string args_string;
749ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
750ca90c47eSCaroline Tice 
751ca90c47eSCaroline Tice                     if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
752ebc09c36SJim Ingham                     {
753ca90c47eSCaroline Tice                         result.AppendError ("Unable to create requested alias.\n");
754ca90c47eSCaroline Tice                         result.SetStatus (eReturnStatusFailed);
755e7941795SCaroline Tice                         return false;
756867b185dSCaroline Tice                     }
757867b185dSCaroline Tice                  }
758867b185dSCaroline Tice 
759ebc09c36SJim Ingham                  // Create the alias.
760ebc09c36SJim Ingham 
761a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
762a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
763ebc09c36SJim Ingham                  {
764a7015092SGreg Clayton                      OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
765ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
766ebc09c36SJim Ingham                      {
767ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
768a7015092SGreg Clayton                              m_interpreter.RemoveAliasOptions (alias_command.c_str());
769ebc09c36SJim Ingham                      }
770ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
771ebc09c36SJim Ingham                                                      alias_command.c_str());
772ebc09c36SJim Ingham                  }
773ebc09c36SJim Ingham 
774ebc09c36SJim Ingham                  if (use_subcommand)
775a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
776ebc09c36SJim Ingham                  else
777a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
778ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
779a7015092SGreg Clayton                      m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
780ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
781ebc09c36SJim Ingham              }
782ebc09c36SJim Ingham              else
783ebc09c36SJim Ingham              {
784ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
785ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
786e7941795SCaroline Tice                  return false;
787ebc09c36SJim Ingham              }
788ebc09c36SJim Ingham         }
789ebc09c36SJim Ingham 
790ebc09c36SJim Ingham         return result.Succeeded();
791ebc09c36SJim Ingham     }
7925a988416SJim Ingham 
793ebc09c36SJim Ingham };
794ebc09c36SJim Ingham 
795ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
796ebc09c36SJim Ingham //-------------------------------------------------------------------------
797ebc09c36SJim Ingham // CommandObjectCommandsUnalias
798ebc09c36SJim Ingham //-------------------------------------------------------------------------
799ebc09c36SJim Ingham 
8005a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed
801ebc09c36SJim Ingham {
802ebc09c36SJim Ingham public:
803a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
8045a988416SJim Ingham         CommandObjectParsed (interpreter,
8050e5e5a79SGreg Clayton                        "command unalias",
80686ddae50SCaroline Tice                        "Allow the user to remove/delete a user-defined command abbreviation.",
807405fe67fSCaroline Tice                        NULL)
808ebc09c36SJim Ingham     {
809405fe67fSCaroline Tice         CommandArgumentEntry arg;
810405fe67fSCaroline Tice         CommandArgumentData alias_arg;
811405fe67fSCaroline Tice 
812405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
813405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
814405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
815405fe67fSCaroline Tice 
816405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
817405fe67fSCaroline Tice         arg.push_back (alias_arg);
818405fe67fSCaroline Tice 
819405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
820405fe67fSCaroline Tice         m_arguments.push_back (arg);
821ebc09c36SJim Ingham     }
822ebc09c36SJim Ingham 
823ebc09c36SJim Ingham     ~CommandObjectCommandsUnalias()
824ebc09c36SJim Ingham     {
825ebc09c36SJim Ingham     }
826ebc09c36SJim Ingham 
8275a988416SJim Ingham protected:
828ebc09c36SJim Ingham     bool
8295a988416SJim Ingham     DoExecute (Args& args, CommandReturnObject &result)
830ebc09c36SJim Ingham     {
831ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
832ebc09c36SJim Ingham         CommandObject *cmd_obj;
833ebc09c36SJim Ingham 
834ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
835ebc09c36SJim Ingham         {
836ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
837a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
838ebc09c36SJim Ingham             if (cmd_obj)
839ebc09c36SJim Ingham             {
840a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
841ebc09c36SJim Ingham                 {
842b547278cSGreg Clayton                     if (cmd_obj->IsRemovable())
843b547278cSGreg Clayton                     {
844b547278cSGreg Clayton                         result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
845b547278cSGreg Clayton                                                       command_name);
846b547278cSGreg Clayton                     }
847b547278cSGreg Clayton                     else
848b547278cSGreg Clayton                     {
849ebc09c36SJim Ingham                         result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
850ebc09c36SJim Ingham                                                       command_name);
851b547278cSGreg Clayton                     }
852ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
853ebc09c36SJim Ingham                 }
854ebc09c36SJim Ingham                 else
855ebc09c36SJim Ingham                 {
856ebc09c36SJim Ingham 
857a7015092SGreg Clayton                     if (m_interpreter.RemoveAlias (command_name) == false)
858ebc09c36SJim Ingham                     {
859a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
860ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
861ebc09c36SJim Ingham                                                           command_name);
862ebc09c36SJim Ingham                         else
863ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
864ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
865ebc09c36SJim Ingham                     }
866ebc09c36SJim Ingham                     else
867ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
868ebc09c36SJim Ingham                 }
869ebc09c36SJim Ingham             }
870ebc09c36SJim Ingham             else
871ebc09c36SJim Ingham             {
872ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
873ebc09c36SJim Ingham                                               "current list of commands.\n",
874ebc09c36SJim Ingham                                              command_name);
875ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
876ebc09c36SJim Ingham             }
877ebc09c36SJim Ingham         }
878ebc09c36SJim Ingham         else
879ebc09c36SJim Ingham         {
880ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
881ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
882ebc09c36SJim Ingham         }
883ebc09c36SJim Ingham 
884ebc09c36SJim Ingham         return result.Succeeded();
885ebc09c36SJim Ingham     }
886ebc09c36SJim Ingham };
887ebc09c36SJim Ingham 
888b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete
889b547278cSGreg Clayton //-------------------------------------------------------------------------
890b547278cSGreg Clayton // CommandObjectCommandsDelete
891b547278cSGreg Clayton //-------------------------------------------------------------------------
892b547278cSGreg Clayton 
893b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed
894b547278cSGreg Clayton {
895b547278cSGreg Clayton public:
896b547278cSGreg Clayton     CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
897b547278cSGreg Clayton     CommandObjectParsed (interpreter,
898b547278cSGreg Clayton                          "command delete",
899b547278cSGreg Clayton                          "Allow the user to delete user-defined regular expression, python or multi-word commands.",
900b547278cSGreg Clayton                          NULL)
901b547278cSGreg Clayton     {
902b547278cSGreg Clayton         CommandArgumentEntry arg;
903b547278cSGreg Clayton         CommandArgumentData alias_arg;
904b547278cSGreg Clayton 
905b547278cSGreg Clayton         // Define the first (and only) variant of this arg.
906b547278cSGreg Clayton         alias_arg.arg_type = eArgTypeCommandName;
907b547278cSGreg Clayton         alias_arg.arg_repetition = eArgRepeatPlain;
908b547278cSGreg Clayton 
909b547278cSGreg Clayton         // There is only one variant this argument could be; put it into the argument entry.
910b547278cSGreg Clayton         arg.push_back (alias_arg);
911b547278cSGreg Clayton 
912b547278cSGreg Clayton         // Push the data for the first argument into the m_arguments vector.
913b547278cSGreg Clayton         m_arguments.push_back (arg);
914b547278cSGreg Clayton     }
915b547278cSGreg Clayton 
916b547278cSGreg Clayton     ~CommandObjectCommandsDelete()
917b547278cSGreg Clayton     {
918b547278cSGreg Clayton     }
919b547278cSGreg Clayton 
920b547278cSGreg Clayton protected:
921b547278cSGreg Clayton     bool
922b547278cSGreg Clayton     DoExecute (Args& args, CommandReturnObject &result)
923b547278cSGreg Clayton     {
924b547278cSGreg Clayton         CommandObject::CommandMap::iterator pos;
925b547278cSGreg Clayton 
926b547278cSGreg Clayton         if (args.GetArgumentCount() != 0)
927b547278cSGreg Clayton         {
928b547278cSGreg Clayton             const char *command_name = args.GetArgumentAtIndex(0);
929b547278cSGreg Clayton             if (m_interpreter.CommandExists (command_name))
930b547278cSGreg Clayton             {
931b547278cSGreg Clayton                 if (m_interpreter.RemoveCommand (command_name))
932b547278cSGreg Clayton                 {
933b547278cSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
934b547278cSGreg Clayton                 }
935b547278cSGreg Clayton                 else
936b547278cSGreg Clayton                 {
937b547278cSGreg Clayton                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
938b547278cSGreg Clayton                                                   command_name);
939b547278cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
940b547278cSGreg Clayton                 }
941b547278cSGreg Clayton             }
942b547278cSGreg Clayton             else
943b547278cSGreg Clayton             {
944b547278cSGreg Clayton                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
945b547278cSGreg Clayton                                               command_name);
946b547278cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
947b547278cSGreg Clayton             }
948b547278cSGreg Clayton         }
949b547278cSGreg Clayton         else
950b547278cSGreg Clayton         {
951b547278cSGreg Clayton             result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
952b547278cSGreg Clayton             result.SetStatus (eReturnStatusFailed);
953b547278cSGreg Clayton         }
954b547278cSGreg Clayton 
955b547278cSGreg Clayton         return result.Succeeded();
956b547278cSGreg Clayton     }
957b547278cSGreg Clayton };
958b547278cSGreg Clayton 
959de164aaaSGreg Clayton //-------------------------------------------------------------------------
960de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
961de164aaaSGreg Clayton //-------------------------------------------------------------------------
9625a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex
963de164aaaSGreg Clayton 
96444d93782SGreg Clayton class CommandObjectCommandsAddRegex :
96544d93782SGreg Clayton     public CommandObjectParsed,
966ea508635SGreg Clayton     public IOHandlerDelegateMultiline
967de164aaaSGreg Clayton {
968de164aaaSGreg Clayton public:
969de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
9705a988416SJim Ingham         CommandObjectParsed (interpreter,
9710e5e5a79SGreg Clayton                        "command regex",
972de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
9730e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
974ea508635SGreg Clayton         IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
975de164aaaSGreg Clayton         m_options (interpreter)
976de164aaaSGreg Clayton     {
977*ea671fbdSKate Stone         SetHelpLong(R"(
978*ea671fbdSKate Stone )" "This command allows the user to create powerful regular expression commands \
979*ea671fbdSKate Stone with substitutions. The regular expressions and substitutions are specified \
980*ea671fbdSKate Stone using the regular expression substitution format of:" R"(
981*ea671fbdSKate Stone 
982*ea671fbdSKate Stone     s/<regex>/<subst>/
983*ea671fbdSKate Stone 
984*ea671fbdSKate Stone )" "<regex> is a regular expression that can use parenthesis to capture regular \
985*ea671fbdSKate Stone expression input and substitute the captured matches in the output using %1 \
986*ea671fbdSKate Stone for the first match, %2 for the second, and so on." R"(
987*ea671fbdSKate Stone 
988*ea671fbdSKate Stone )" "The regular expressions can all be specified on the command line if more than \
989*ea671fbdSKate Stone one argument is provided. If just the command name is provided on the command \
990*ea671fbdSKate Stone line, then the regular expressions and substitutions can be entered on separate \
991*ea671fbdSKate Stone lines, followed by an empty line to terminate the command definition." R"(
992*ea671fbdSKate Stone 
993*ea671fbdSKate Stone EXAMPLES
994*ea671fbdSKate Stone 
995*ea671fbdSKate Stone )" "The following example will define a regular expression command named 'f' that \
996*ea671fbdSKate Stone will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
997*ea671fbdSKate Stone a number follows 'f':" R"(
998*ea671fbdSKate Stone 
999*ea671fbdSKate Stone     (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
10000e5e5a79SGreg Clayton         );
1001de164aaaSGreg Clayton     }
1002de164aaaSGreg Clayton 
1003de164aaaSGreg Clayton     ~CommandObjectCommandsAddRegex()
1004de164aaaSGreg Clayton     {
1005de164aaaSGreg Clayton     }
1006de164aaaSGreg Clayton 
1007de164aaaSGreg Clayton 
10085a988416SJim Ingham protected:
100944d93782SGreg Clayton 
1010ea508635SGreg Clayton     void
1011ea508635SGreg Clayton     IOHandlerActivated (IOHandler &io_handler) override
101244d93782SGreg Clayton     {
101344d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
101444d93782SGreg Clayton         if (output_sp)
101544d93782SGreg Clayton         {
101644d93782SGreg Clayton             output_sp->PutCString("Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\nTerminate the substitution list with an empty line.\n");
101744d93782SGreg Clayton             output_sp->Flush();
101844d93782SGreg Clayton         }
101944d93782SGreg Clayton     }
102044d93782SGreg Clayton 
1021ea508635SGreg Clayton     void
1022ea508635SGreg Clayton     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
102344d93782SGreg Clayton     {
102444d93782SGreg Clayton         io_handler.SetIsDone(true);
102544d93782SGreg Clayton         if (m_regex_cmd_ap.get())
102644d93782SGreg Clayton         {
102744d93782SGreg Clayton             StringList lines;
102844d93782SGreg Clayton             if (lines.SplitIntoLines (data))
102944d93782SGreg Clayton             {
103044d93782SGreg Clayton                 const size_t num_lines = lines.GetSize();
103144d93782SGreg Clayton                 bool check_only = false;
103244d93782SGreg Clayton                 for (size_t i=0; i<num_lines; ++i)
103344d93782SGreg Clayton                 {
103444d93782SGreg Clayton                     llvm::StringRef bytes_strref (lines[i]);
103544d93782SGreg Clayton                     Error error = AppendRegexSubstitution (bytes_strref, check_only);
103644d93782SGreg Clayton                     if (error.Fail())
103744d93782SGreg Clayton                     {
103844d93782SGreg Clayton                         if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
103944d93782SGreg Clayton                         {
104044d93782SGreg Clayton                             StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
104144d93782SGreg Clayton                             out_stream->Printf("error: %s\n", error.AsCString());
104244d93782SGreg Clayton                         }
104344d93782SGreg Clayton                     }
104444d93782SGreg Clayton                 }
104544d93782SGreg Clayton             }
104644d93782SGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
104744d93782SGreg Clayton             {
104844d93782SGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
104944d93782SGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
105044d93782SGreg Clayton             }
105144d93782SGreg Clayton         }
105244d93782SGreg Clayton     }
105344d93782SGreg Clayton 
1054de164aaaSGreg Clayton     bool
1055b0a1814fSEric Christopher     DoExecute (Args& command, CommandReturnObject &result) override
1056de164aaaSGreg Clayton     {
10575a988416SJim Ingham         const size_t argc = command.GetArgumentCount();
10580e5e5a79SGreg Clayton         if (argc == 0)
1059de164aaaSGreg Clayton         {
106069c12ccbSJason Molenda             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
10610e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
10620e5e5a79SGreg Clayton         }
10630e5e5a79SGreg Clayton         else
10640e5e5a79SGreg Clayton         {
10650e5e5a79SGreg Clayton             Error error;
10665a988416SJim Ingham             const char *name = command.GetArgumentAtIndex(0);
1067de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1068de164aaaSGreg Clayton                                                                  name,
1069de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
1070de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
1071b547278cSGreg Clayton                                                                  10,
1072b547278cSGreg Clayton                                                                  0,
1073b547278cSGreg Clayton                                                                  true));
10740e5e5a79SGreg Clayton 
10750e5e5a79SGreg Clayton             if (argc == 1)
10760e5e5a79SGreg Clayton             {
107744d93782SGreg Clayton                 Debugger &debugger = m_interpreter.GetDebugger();
1078e30f11d9SKate Stone                 bool color_prompt = debugger.GetUseColor();
107944d93782SGreg Clayton                 const bool multiple_lines = true; // Get multiple lines
108044d93782SGreg Clayton                 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
1081e30f11d9SKate Stone                                                                   IOHandler::Type::Other,
108273d80faaSGreg Clayton                                                                   "lldb-regex", // Name of input reader for history
1083ea508635SGreg Clayton                                                                   "> ",         // Prompt
1084e30f11d9SKate Stone                                                                   NULL,         // Continuation prompt
108544d93782SGreg Clayton                                                                   multiple_lines,
1086e30f11d9SKate Stone                                                                   color_prompt,
1087f6913cd7SGreg Clayton                                                                   0,            // Don't show line numbers
108844d93782SGreg Clayton                                                                   *this));
108944d93782SGreg Clayton 
109044d93782SGreg Clayton                 if (io_handler_sp)
1091de164aaaSGreg Clayton                 {
109244d93782SGreg Clayton                     debugger.PushIOHandler(io_handler_sp);
1093de164aaaSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1094de164aaaSGreg Clayton                 }
1095de164aaaSGreg Clayton             }
1096de164aaaSGreg Clayton             else
1097de164aaaSGreg Clayton             {
10980e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
10990e5e5a79SGreg Clayton                 {
11005a988416SJim Ingham                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
110144d93782SGreg Clayton                     bool check_only = false;
110244d93782SGreg Clayton                     error = AppendRegexSubstitution (arg_strref, check_only);
11030e5e5a79SGreg Clayton                     if (error.Fail())
11040e5e5a79SGreg Clayton                         break;
11050e5e5a79SGreg Clayton                 }
11060e5e5a79SGreg Clayton 
11070e5e5a79SGreg Clayton                 if (error.Success())
11080e5e5a79SGreg Clayton                 {
11090e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
11100e5e5a79SGreg Clayton                 }
11110e5e5a79SGreg Clayton             }
11120e5e5a79SGreg Clayton             if (error.Fail())
11130e5e5a79SGreg Clayton             {
11140e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
1115de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1116de164aaaSGreg Clayton             }
11170e5e5a79SGreg Clayton         }
11180e5e5a79SGreg Clayton 
1119de164aaaSGreg Clayton         return result.Succeeded();
1120de164aaaSGreg Clayton     }
1121de164aaaSGreg Clayton 
11220e5e5a79SGreg Clayton     Error
112344d93782SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
1124de164aaaSGreg Clayton     {
11250e5e5a79SGreg Clayton         Error error;
11260e5e5a79SGreg Clayton 
11270e5e5a79SGreg Clayton         if (m_regex_cmd_ap.get() == NULL)
1128de164aaaSGreg Clayton         {
11290e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
11300e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
11310e5e5a79SGreg Clayton                                            regex_sed.data());
11320e5e5a79SGreg Clayton             return error;
1133de164aaaSGreg Clayton         }
11340e5e5a79SGreg Clayton 
11350e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
11360e5e5a79SGreg Clayton 
11370e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
11380e5e5a79SGreg Clayton         {
11390e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
11400e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
11410e5e5a79SGreg Clayton                                            regex_sed.data());
11420e5e5a79SGreg Clayton             return error;
11430e5e5a79SGreg Clayton         }
11440e5e5a79SGreg Clayton 
11450e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
11460e5e5a79SGreg Clayton         {
11470e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
11480e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
11490e5e5a79SGreg Clayton                                            regex_sed.data());
11500e5e5a79SGreg Clayton             return error;
11510e5e5a79SGreg Clayton         }
11520e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
11530e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
11540e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
11550e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
11560e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
11570e5e5a79SGreg Clayton 
11580e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
11590e5e5a79SGreg Clayton         {
1160ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
11610e5e5a79SGreg Clayton                                            separator_char,
11620e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
1163ea508635SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1),
1164ea508635SGreg Clayton                                            (int)regex_sed.size(),
1165ea508635SGreg Clayton                                            regex_sed.data());
11660e5e5a79SGreg Clayton             return error;
11670e5e5a79SGreg Clayton         }
11680e5e5a79SGreg Clayton 
11690e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
11700e5e5a79SGreg Clayton 
11710e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
11720e5e5a79SGreg Clayton         {
1173ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
11740e5e5a79SGreg Clayton                                            separator_char,
11750e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
1176ea508635SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1),
1177ea508635SGreg Clayton                                            (int)regex_sed.size(),
1178ea508635SGreg Clayton                                            regex_sed.data());
11790e5e5a79SGreg Clayton             return error;
11800e5e5a79SGreg Clayton         }
11810e5e5a79SGreg Clayton 
11820e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
11830e5e5a79SGreg Clayton         {
11840e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
11850e5e5a79SGreg Clayton             // separator char
11860e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
11870e5e5a79SGreg Clayton             {
11880e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
11890e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
11900e5e5a79SGreg Clayton                                                regex_sed.data(),
11910e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
11920e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
11930e5e5a79SGreg Clayton                 return error;
11940e5e5a79SGreg Clayton             }
11950e5e5a79SGreg Clayton 
11960e5e5a79SGreg Clayton         }
11970e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
11980e5e5a79SGreg Clayton         {
11990e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
12000e5e5a79SGreg Clayton                                            separator_char,
12010e5e5a79SGreg Clayton                                            separator_char,
12020e5e5a79SGreg Clayton                                            separator_char,
12030e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12040e5e5a79SGreg Clayton                                            regex_sed.data());
12050e5e5a79SGreg Clayton             return error;
12060e5e5a79SGreg Clayton         }
12070e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
12080e5e5a79SGreg Clayton         {
12090e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
12100e5e5a79SGreg Clayton                                            separator_char,
12110e5e5a79SGreg Clayton                                            separator_char,
12120e5e5a79SGreg Clayton                                            separator_char,
12130e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12140e5e5a79SGreg Clayton                                            regex_sed.data());
12150e5e5a79SGreg Clayton             return error;
12160e5e5a79SGreg Clayton         }
121744d93782SGreg Clayton 
121844d93782SGreg Clayton         if (check_only == false)
121944d93782SGreg Clayton         {
12200e5e5a79SGreg Clayton             std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
12210e5e5a79SGreg Clayton             std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
12220e5e5a79SGreg Clayton             m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
12230e5e5a79SGreg Clayton                                              subst.c_str());
122444d93782SGreg Clayton         }
12250e5e5a79SGreg Clayton         return error;
1226de164aaaSGreg Clayton     }
1227de164aaaSGreg Clayton 
1228de164aaaSGreg Clayton     void
12290e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
1230de164aaaSGreg Clayton     {
1231de164aaaSGreg Clayton         if (m_regex_cmd_ap.get())
1232de164aaaSGreg Clayton         {
1233de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
1234de164aaaSGreg Clayton             {
1235de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1236de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1237de164aaaSGreg Clayton             }
1238de164aaaSGreg Clayton         }
1239de164aaaSGreg Clayton     }
1240de164aaaSGreg Clayton 
1241de164aaaSGreg Clayton private:
12427b0992d9SGreg Clayton     std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1243de164aaaSGreg Clayton 
1244de164aaaSGreg Clayton      class CommandOptions : public Options
1245de164aaaSGreg Clayton      {
1246de164aaaSGreg Clayton      public:
1247de164aaaSGreg Clayton 
1248de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
1249de164aaaSGreg Clayton             Options (interpreter)
1250de164aaaSGreg Clayton          {
1251de164aaaSGreg Clayton          }
1252de164aaaSGreg Clayton 
1253de164aaaSGreg Clayton          virtual
1254de164aaaSGreg Clayton          ~CommandOptions (){}
1255de164aaaSGreg Clayton 
1256de164aaaSGreg Clayton          virtual Error
1257de164aaaSGreg Clayton          SetOptionValue (uint32_t option_idx, const char *option_arg)
1258de164aaaSGreg Clayton          {
1259de164aaaSGreg Clayton              Error error;
12603bcdfc0eSGreg Clayton              const int short_option = m_getopt_table[option_idx].val;
1261de164aaaSGreg Clayton 
1262de164aaaSGreg Clayton              switch (short_option)
1263de164aaaSGreg Clayton              {
1264de164aaaSGreg Clayton                  case 'h':
1265de164aaaSGreg Clayton                      m_help.assign (option_arg);
1266de164aaaSGreg Clayton                      break;
1267de164aaaSGreg Clayton                  case 's':
1268de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1269de164aaaSGreg Clayton                      break;
1270de164aaaSGreg Clayton 
1271de164aaaSGreg Clayton                  default:
127286edbf41SGreg Clayton                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1273de164aaaSGreg Clayton                      break;
1274de164aaaSGreg Clayton              }
1275de164aaaSGreg Clayton 
1276de164aaaSGreg Clayton              return error;
1277de164aaaSGreg Clayton          }
1278de164aaaSGreg Clayton 
1279de164aaaSGreg Clayton          void
1280de164aaaSGreg Clayton          OptionParsingStarting ()
1281de164aaaSGreg Clayton          {
1282de164aaaSGreg Clayton              m_help.clear();
1283de164aaaSGreg Clayton              m_syntax.clear();
1284de164aaaSGreg Clayton          }
1285de164aaaSGreg Clayton 
1286de164aaaSGreg Clayton          const OptionDefinition*
1287de164aaaSGreg Clayton          GetDefinitions ()
1288de164aaaSGreg Clayton          {
1289de164aaaSGreg Clayton              return g_option_table;
1290de164aaaSGreg Clayton          }
1291de164aaaSGreg Clayton 
1292de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1293de164aaaSGreg Clayton 
1294de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1295de164aaaSGreg Clayton 
1296de164aaaSGreg Clayton          const char *
1297de164aaaSGreg Clayton          GetHelp ()
1298de164aaaSGreg Clayton          {
1299de164aaaSGreg Clayton              if (m_help.empty())
1300de164aaaSGreg Clayton                  return NULL;
1301de164aaaSGreg Clayton              return m_help.c_str();
1302de164aaaSGreg Clayton          }
1303de164aaaSGreg Clayton          const char *
1304de164aaaSGreg Clayton          GetSyntax ()
1305de164aaaSGreg Clayton          {
1306de164aaaSGreg Clayton              if (m_syntax.empty())
1307de164aaaSGreg Clayton                  return NULL;
1308de164aaaSGreg Clayton              return m_syntax.c_str();
1309de164aaaSGreg Clayton          }
1310de164aaaSGreg Clayton          // Instance variables to hold the values for command options.
1311de164aaaSGreg Clayton      protected:
1312de164aaaSGreg Clayton          std::string m_help;
1313de164aaaSGreg Clayton          std::string m_syntax;
1314de164aaaSGreg Clayton      };
1315de164aaaSGreg Clayton 
1316b0a1814fSEric Christopher      Options *
1317b0a1814fSEric Christopher      GetOptions () override
1318de164aaaSGreg Clayton      {
1319de164aaaSGreg Clayton          return &m_options;
1320de164aaaSGreg Clayton      }
1321de164aaaSGreg Clayton 
13225a988416SJim Ingham      CommandOptions m_options;
1323de164aaaSGreg Clayton };
1324de164aaaSGreg Clayton 
1325de164aaaSGreg Clayton OptionDefinition
1326de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1327de164aaaSGreg Clayton {
1328d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1329d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1330d37221dcSZachary Turner { 0             , false,  NULL   , 0  , 0                , NULL, NULL, 0, eArgTypeNone, NULL }
1331de164aaaSGreg Clayton };
1332de164aaaSGreg Clayton 
1333de164aaaSGreg Clayton 
13345a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw
1335223383edSEnrico Granata {
1336223383edSEnrico Granata private:
1337223383edSEnrico Granata     std::string m_function_name;
13380a305db7SEnrico Granata     ScriptedCommandSynchronicity m_synchro;
1339fac939e9SEnrico Granata     bool m_fetched_help_long;
1340223383edSEnrico Granata 
1341223383edSEnrico Granata public:
1342223383edSEnrico Granata 
1343223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1344223383edSEnrico Granata                                  std::string name,
13450a305db7SEnrico Granata                                  std::string funct,
1346735152e3SEnrico Granata                                  std::string help,
13470a305db7SEnrico Granata                                  ScriptedCommandSynchronicity synch) :
13485a988416SJim Ingham         CommandObjectRaw (interpreter,
1349223383edSEnrico Granata                           name.c_str(),
1350735152e3SEnrico Granata                           NULL,
1351223383edSEnrico Granata                           NULL),
13520a305db7SEnrico Granata         m_function_name(funct),
1353fac939e9SEnrico Granata         m_synchro(synch),
1354fac939e9SEnrico Granata         m_fetched_help_long(false)
1355223383edSEnrico Granata     {
1356735152e3SEnrico Granata         if (!help.empty())
1357735152e3SEnrico Granata             SetHelp(help.c_str());
1358735152e3SEnrico Granata         else
1359735152e3SEnrico Granata         {
1360735152e3SEnrico Granata             StreamString stream;
1361735152e3SEnrico Granata             stream.Printf("For more information run 'help %s'",name.c_str());
1362735152e3SEnrico Granata             SetHelp(stream.GetData());
1363735152e3SEnrico Granata         }
1364223383edSEnrico Granata     }
1365223383edSEnrico Granata 
1366223383edSEnrico Granata     virtual
1367223383edSEnrico Granata     ~CommandObjectPythonFunction ()
1368223383edSEnrico Granata     {
1369223383edSEnrico Granata     }
1370223383edSEnrico Granata 
1371223383edSEnrico Granata     virtual bool
13723a18e319SGreg Clayton     IsRemovable () const
13735a988416SJim Ingham     {
13745a988416SJim Ingham         return true;
13755a988416SJim Ingham     }
13765a988416SJim Ingham 
13775a988416SJim Ingham     const std::string&
13785a988416SJim Ingham     GetFunctionName ()
13795a988416SJim Ingham     {
13805a988416SJim Ingham         return m_function_name;
13815a988416SJim Ingham     }
13825a988416SJim Ingham 
13835a988416SJim Ingham     ScriptedCommandSynchronicity
13845a988416SJim Ingham     GetSynchronicity ()
13855a988416SJim Ingham     {
13865a988416SJim Ingham         return m_synchro;
13875a988416SJim Ingham     }
13885a988416SJim Ingham 
1389fac939e9SEnrico Granata     virtual const char *
1390fac939e9SEnrico Granata     GetHelpLong ()
1391fac939e9SEnrico Granata     {
1392fac939e9SEnrico Granata         if (!m_fetched_help_long)
1393fac939e9SEnrico Granata         {
1394fac939e9SEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1395fac939e9SEnrico Granata             if (scripter)
1396fac939e9SEnrico Granata             {
1397fac939e9SEnrico Granata                 std::string docstring;
1398fac939e9SEnrico Granata                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1399fac939e9SEnrico Granata                 if (!docstring.empty())
1400fac939e9SEnrico Granata                     SetHelpLong(docstring);
1401fac939e9SEnrico Granata             }
1402fac939e9SEnrico Granata         }
1403fac939e9SEnrico Granata         return CommandObjectRaw::GetHelpLong();
1404fac939e9SEnrico Granata     }
1405fac939e9SEnrico Granata 
14065a988416SJim Ingham protected:
14075a988416SJim Ingham     virtual bool
14085a988416SJim Ingham     DoExecute (const char *raw_command_line, CommandReturnObject &result)
1409223383edSEnrico Granata     {
1410223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1411223383edSEnrico Granata 
1412223383edSEnrico Granata         Error error;
1413223383edSEnrico Granata 
141470f11f88SJim Ingham         result.SetStatus(eReturnStatusInvalid);
141570f11f88SJim Ingham 
1416223383edSEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1417223383edSEnrico Granata                                                          raw_command_line,
14180a305db7SEnrico Granata                                                          m_synchro,
1419223383edSEnrico Granata                                                          result,
142006be059aSEnrico Granata                                                          error,
142106be059aSEnrico Granata                                                          m_exe_ctx) == false)
1422223383edSEnrico Granata         {
1423223383edSEnrico Granata             result.AppendError(error.AsCString());
1424223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1425223383edSEnrico Granata         }
1426223383edSEnrico Granata         else
142770f11f88SJim Ingham         {
142870f11f88SJim Ingham             // Don't change the status if the command already set it...
142970f11f88SJim Ingham             if (result.GetStatus() == eReturnStatusInvalid)
143070f11f88SJim Ingham             {
14319a71a7d8SDaniel Malea                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1432223383edSEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
143370f11f88SJim Ingham                 else
143470f11f88SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishResult);
143570f11f88SJim Ingham             }
143670f11f88SJim Ingham         }
1437223383edSEnrico Granata 
1438223383edSEnrico Granata         return result.Succeeded();
1439223383edSEnrico Granata     }
1440223383edSEnrico Granata 
1441223383edSEnrico Granata };
1442223383edSEnrico Granata 
14439fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw
14449fe00e52SEnrico Granata {
14459fe00e52SEnrico Granata private:
14460641ca1aSZachary Turner     StructuredData::GenericSP m_cmd_obj_sp;
14479fe00e52SEnrico Granata     ScriptedCommandSynchronicity m_synchro;
14486f79bb2dSEnrico Granata     bool m_fetched_help_short:1;
14496f79bb2dSEnrico Granata     bool m_fetched_help_long:1;
14509fe00e52SEnrico Granata 
14519fe00e52SEnrico Granata public:
14529fe00e52SEnrico Granata 
14539fe00e52SEnrico Granata     CommandObjectScriptingObject (CommandInterpreter &interpreter,
14549fe00e52SEnrico Granata                                   std::string name,
14550641ca1aSZachary Turner                                   StructuredData::GenericSP cmd_obj_sp,
14569fe00e52SEnrico Granata                                   ScriptedCommandSynchronicity synch) :
14579fe00e52SEnrico Granata     CommandObjectRaw (interpreter,
14589fe00e52SEnrico Granata                       name.c_str(),
14599fe00e52SEnrico Granata                       NULL,
14609fe00e52SEnrico Granata                       NULL),
14619fe00e52SEnrico Granata     m_cmd_obj_sp(cmd_obj_sp),
14626f79bb2dSEnrico Granata     m_synchro(synch),
14636f79bb2dSEnrico Granata     m_fetched_help_short(false),
14646f79bb2dSEnrico Granata     m_fetched_help_long(false)
14659fe00e52SEnrico Granata     {
14669fe00e52SEnrico Granata         StreamString stream;
14679fe00e52SEnrico Granata         stream.Printf("For more information run 'help %s'",name.c_str());
14689fe00e52SEnrico Granata         SetHelp(stream.GetData());
1469e87764f2SEnrico Granata         if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1470e87764f2SEnrico Granata             GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
14719fe00e52SEnrico Granata     }
14729fe00e52SEnrico Granata 
14739fe00e52SEnrico Granata     virtual
14749fe00e52SEnrico Granata     ~CommandObjectScriptingObject ()
14759fe00e52SEnrico Granata     {
14769fe00e52SEnrico Granata     }
14779fe00e52SEnrico Granata 
14789fe00e52SEnrico Granata     virtual bool
14799fe00e52SEnrico Granata     IsRemovable () const
14809fe00e52SEnrico Granata     {
14819fe00e52SEnrico Granata         return true;
14829fe00e52SEnrico Granata     }
14839fe00e52SEnrico Granata 
14840641ca1aSZachary Turner     StructuredData::GenericSP
14859fe00e52SEnrico Granata     GetImplementingObject ()
14869fe00e52SEnrico Granata     {
14879fe00e52SEnrico Granata         return m_cmd_obj_sp;
14889fe00e52SEnrico Granata     }
14899fe00e52SEnrico Granata 
14909fe00e52SEnrico Granata     ScriptedCommandSynchronicity
14919fe00e52SEnrico Granata     GetSynchronicity ()
14929fe00e52SEnrico Granata     {
14939fe00e52SEnrico Granata         return m_synchro;
14949fe00e52SEnrico Granata     }
14959fe00e52SEnrico Granata 
14969fe00e52SEnrico Granata     virtual const char *
14976f79bb2dSEnrico Granata     GetHelp ()
14986f79bb2dSEnrico Granata     {
14996f79bb2dSEnrico Granata         if (!m_fetched_help_short)
15006f79bb2dSEnrico Granata         {
15016f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
15026f79bb2dSEnrico Granata             if (scripter)
15036f79bb2dSEnrico Granata             {
15046f79bb2dSEnrico Granata                 std::string docstring;
15056f79bb2dSEnrico Granata                 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
15066f79bb2dSEnrico Granata                 if (!docstring.empty())
15076f79bb2dSEnrico Granata                     SetHelp(docstring);
15086f79bb2dSEnrico Granata             }
15096f79bb2dSEnrico Granata         }
15106f79bb2dSEnrico Granata         return CommandObjectRaw::GetHelp();
15116f79bb2dSEnrico Granata     }
15126f79bb2dSEnrico Granata 
15136f79bb2dSEnrico Granata     virtual const char *
15149fe00e52SEnrico Granata     GetHelpLong ()
15159fe00e52SEnrico Granata     {
15166f79bb2dSEnrico Granata         if (!m_fetched_help_long)
15176f79bb2dSEnrico Granata         {
15186f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
15196f79bb2dSEnrico Granata             if (scripter)
15206f79bb2dSEnrico Granata             {
15216f79bb2dSEnrico Granata                 std::string docstring;
15226f79bb2dSEnrico Granata                 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
15236f79bb2dSEnrico Granata                 if (!docstring.empty())
15246f79bb2dSEnrico Granata                     SetHelpLong(docstring);
15256f79bb2dSEnrico Granata             }
15266f79bb2dSEnrico Granata         }
15279fe00e52SEnrico Granata         return CommandObjectRaw::GetHelpLong();
15289fe00e52SEnrico Granata     }
15299fe00e52SEnrico Granata 
15309fe00e52SEnrico Granata protected:
15319fe00e52SEnrico Granata     virtual bool
15329fe00e52SEnrico Granata     DoExecute (const char *raw_command_line, CommandReturnObject &result)
15339fe00e52SEnrico Granata     {
15349fe00e52SEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
15359fe00e52SEnrico Granata 
15369fe00e52SEnrico Granata         Error error;
15379fe00e52SEnrico Granata 
15389fe00e52SEnrico Granata         result.SetStatus(eReturnStatusInvalid);
15399fe00e52SEnrico Granata 
15409fe00e52SEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp,
15419fe00e52SEnrico Granata                                                          raw_command_line,
15429fe00e52SEnrico Granata                                                          m_synchro,
15439fe00e52SEnrico Granata                                                          result,
15449fe00e52SEnrico Granata                                                          error,
15459fe00e52SEnrico Granata                                                          m_exe_ctx) == false)
15469fe00e52SEnrico Granata         {
15479fe00e52SEnrico Granata             result.AppendError(error.AsCString());
15489fe00e52SEnrico Granata             result.SetStatus(eReturnStatusFailed);
15499fe00e52SEnrico Granata         }
15509fe00e52SEnrico Granata         else
15519fe00e52SEnrico Granata         {
15529fe00e52SEnrico Granata             // Don't change the status if the command already set it...
15539fe00e52SEnrico Granata             if (result.GetStatus() == eReturnStatusInvalid)
15549fe00e52SEnrico Granata             {
15559fe00e52SEnrico Granata                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
15569fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
15579fe00e52SEnrico Granata                 else
15589fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishResult);
15599fe00e52SEnrico Granata             }
15609fe00e52SEnrico Granata         }
15619fe00e52SEnrico Granata 
15629fe00e52SEnrico Granata         return result.Succeeded();
15639fe00e52SEnrico Granata     }
15649fe00e52SEnrico Granata 
15659fe00e52SEnrico Granata };
15669fe00e52SEnrico Granata 
1567a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1568a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport
1569a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1570a9dbf432SEnrico Granata 
15715a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed
1572a9dbf432SEnrico Granata {
15735a988416SJim Ingham public:
15745a988416SJim Ingham     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
15755a988416SJim Ingham         CommandObjectParsed (interpreter,
15765a988416SJim Ingham                              "command script import",
15775a988416SJim Ingham                              "Import a scripting module in LLDB.",
15785a988416SJim Ingham                              NULL),
15795a988416SJim Ingham         m_options(interpreter)
15805a988416SJim Ingham     {
15815a988416SJim Ingham         CommandArgumentEntry arg1;
15825a988416SJim Ingham         CommandArgumentData cmd_arg;
15835a988416SJim Ingham 
15845a988416SJim Ingham         // Define the first (and only) variant of this arg.
15855a988416SJim Ingham         cmd_arg.arg_type = eArgTypeFilename;
15863b00e35bSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlus;
15875a988416SJim Ingham 
15885a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
15895a988416SJim Ingham         arg1.push_back (cmd_arg);
15905a988416SJim Ingham 
15915a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
15925a988416SJim Ingham         m_arguments.push_back (arg1);
15935a988416SJim Ingham     }
15945a988416SJim Ingham 
15955a988416SJim Ingham     ~CommandObjectCommandsScriptImport ()
15965a988416SJim Ingham     {
15975a988416SJim Ingham     }
15985a988416SJim Ingham 
1599c7bece56SGreg Clayton     virtual int
16005a988416SJim Ingham     HandleArgumentCompletion (Args &input,
16015a988416SJim Ingham                               int &cursor_index,
16025a988416SJim Ingham                               int &cursor_char_position,
16035a988416SJim Ingham                               OptionElementVector &opt_element_vector,
16045a988416SJim Ingham                               int match_start_point,
16055a988416SJim Ingham                               int max_return_elements,
16065a988416SJim Ingham                               bool &word_complete,
16075a988416SJim Ingham                               StringList &matches)
16085a988416SJim Ingham     {
16095a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
16105a988416SJim Ingham         completion_str.erase (cursor_char_position);
16115a988416SJim Ingham 
16125a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
16135a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
16145a988416SJim Ingham                                                              completion_str.c_str(),
16155a988416SJim Ingham                                                              match_start_point,
16165a988416SJim Ingham                                                              max_return_elements,
16175a988416SJim Ingham                                                              NULL,
16185a988416SJim Ingham                                                              word_complete,
16195a988416SJim Ingham                                                              matches);
16205a988416SJim Ingham         return matches.GetSize();
16215a988416SJim Ingham     }
16225a988416SJim Ingham 
16235a988416SJim Ingham     virtual Options *
16245a988416SJim Ingham     GetOptions ()
16255a988416SJim Ingham     {
16265a988416SJim Ingham         return &m_options;
16275a988416SJim Ingham     }
16285a988416SJim Ingham 
16295a988416SJim Ingham protected:
16300a305db7SEnrico Granata 
16310a305db7SEnrico Granata     class CommandOptions : public Options
16320a305db7SEnrico Granata     {
16330a305db7SEnrico Granata     public:
16340a305db7SEnrico Granata 
16350a305db7SEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
16360a305db7SEnrico Granata             Options (interpreter)
16370a305db7SEnrico Granata         {
16380a305db7SEnrico Granata         }
16390a305db7SEnrico Granata 
16400a305db7SEnrico Granata         virtual
16410a305db7SEnrico Granata         ~CommandOptions (){}
16420a305db7SEnrico Granata 
16430a305db7SEnrico Granata         virtual Error
16440a305db7SEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
16450a305db7SEnrico Granata         {
16460a305db7SEnrico Granata             Error error;
16473bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
16480a305db7SEnrico Granata 
16490a305db7SEnrico Granata             switch (short_option)
16500a305db7SEnrico Granata             {
16510a305db7SEnrico Granata                 case 'r':
16520a305db7SEnrico Granata                     m_allow_reload = true;
16530a305db7SEnrico Granata                     break;
16540a305db7SEnrico Granata                 default:
16550a305db7SEnrico Granata                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
16560a305db7SEnrico Granata                     break;
16570a305db7SEnrico Granata             }
16580a305db7SEnrico Granata 
16590a305db7SEnrico Granata             return error;
16600a305db7SEnrico Granata         }
16610a305db7SEnrico Granata 
16620a305db7SEnrico Granata         void
16630a305db7SEnrico Granata         OptionParsingStarting ()
16640a305db7SEnrico Granata         {
1665e0c70f1bSEnrico Granata             m_allow_reload = true;
16660a305db7SEnrico Granata         }
16670a305db7SEnrico Granata 
16680a305db7SEnrico Granata         const OptionDefinition*
16690a305db7SEnrico Granata         GetDefinitions ()
16700a305db7SEnrico Granata         {
16710a305db7SEnrico Granata             return g_option_table;
16720a305db7SEnrico Granata         }
16730a305db7SEnrico Granata 
16740a305db7SEnrico Granata         // Options table: Required for subclasses of Options.
16750a305db7SEnrico Granata 
16760a305db7SEnrico Granata         static OptionDefinition g_option_table[];
16770a305db7SEnrico Granata 
16780a305db7SEnrico Granata         // Instance variables to hold the values for command options.
16790a305db7SEnrico Granata 
16800a305db7SEnrico Granata         bool m_allow_reload;
16810a305db7SEnrico Granata     };
16820a305db7SEnrico Granata 
1683a9dbf432SEnrico Granata     bool
16845a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1685a9dbf432SEnrico Granata     {
1686a9dbf432SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1687a9dbf432SEnrico Granata         {
1688a9dbf432SEnrico Granata             result.AppendError ("only scripting language supported for module importing is currently Python");
1689a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1690a9dbf432SEnrico Granata             return false;
1691a9dbf432SEnrico Granata         }
1692a9dbf432SEnrico Granata 
16935a988416SJim Ingham         size_t argc = command.GetArgumentCount();
16943b00e35bSEnrico Granata         if (0 == argc)
1695a9dbf432SEnrico Granata         {
16963b00e35bSEnrico Granata             result.AppendError("command script import needs one or more arguments");
1697a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1698a9dbf432SEnrico Granata             return false;
1699a9dbf432SEnrico Granata         }
1700a9dbf432SEnrico Granata 
17010e978481SEd Maste         for (size_t i = 0;
17023b00e35bSEnrico Granata              i < argc;
17033b00e35bSEnrico Granata              i++)
17043b00e35bSEnrico Granata         {
17053b00e35bSEnrico Granata             std::string path = command.GetArgumentAtIndex(i);
1706a9dbf432SEnrico Granata             Error error;
1707a9dbf432SEnrico Granata 
1708c9d645d3SGreg Clayton             const bool init_session = true;
1709078551c7SEnrico Granata             // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1710078551c7SEnrico Granata             // commands won't ever be recursively invoked, but it's actually possible to craft
1711078551c7SEnrico Granata             // a Python script that does other "command script imports" in __lldb_init_module
1712078551c7SEnrico Granata             // the real fix is to have recursive commands possible with a CommandInvocation object
1713078551c7SEnrico Granata             // separate from the CommandObject itself, so that recursive command invocations
1714078551c7SEnrico Granata             // won't stomp on each other (wrt to execution contents, options, and more)
1715078551c7SEnrico Granata             m_exe_ctx.Clear();
1716a9dbf432SEnrico Granata             if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
17170a305db7SEnrico Granata                                                                           m_options.m_allow_reload,
1718c9d645d3SGreg Clayton                                                                           init_session,
1719a9dbf432SEnrico Granata                                                                           error))
1720a9dbf432SEnrico Granata             {
1721a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1722a9dbf432SEnrico Granata             }
1723a9dbf432SEnrico Granata             else
1724a9dbf432SEnrico Granata             {
1725a9dbf432SEnrico Granata                 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1726a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1727a9dbf432SEnrico Granata             }
17283b00e35bSEnrico Granata         }
1729a9dbf432SEnrico Granata 
1730a9dbf432SEnrico Granata         return result.Succeeded();
1731a9dbf432SEnrico Granata     }
17320a305db7SEnrico Granata 
17335a988416SJim Ingham     CommandOptions m_options;
1734a9dbf432SEnrico Granata };
1735223383edSEnrico Granata 
17360a305db7SEnrico Granata OptionDefinition
17370a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
17380a305db7SEnrico Granata {
1739d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,        "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."},
1740d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
17410a305db7SEnrico Granata };
17420a305db7SEnrico Granata 
17430a305db7SEnrico Granata 
1744223383edSEnrico Granata //-------------------------------------------------------------------------
1745223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1746223383edSEnrico Granata //-------------------------------------------------------------------------
1747223383edSEnrico Granata 
174844d93782SGreg Clayton class CommandObjectCommandsScriptAdd :
174944d93782SGreg Clayton     public CommandObjectParsed,
175044d93782SGreg Clayton     public IOHandlerDelegateMultiline
1751223383edSEnrico Granata {
17525a988416SJim Ingham public:
17535a988416SJim Ingham     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
17545a988416SJim Ingham         CommandObjectParsed (interpreter,
17555a988416SJim Ingham                              "command script add",
17565a988416SJim Ingham                              "Add a scripted function as an LLDB command.",
17575a988416SJim Ingham                              NULL),
1758c3d874a5SGreg Clayton         IOHandlerDelegateMultiline ("DONE"),
17595a988416SJim Ingham         m_options (interpreter)
17605a988416SJim Ingham     {
17615a988416SJim Ingham         CommandArgumentEntry arg1;
17625a988416SJim Ingham         CommandArgumentData cmd_arg;
17635a988416SJim Ingham 
17645a988416SJim Ingham         // Define the first (and only) variant of this arg.
17655a988416SJim Ingham         cmd_arg.arg_type = eArgTypeCommandName;
17665a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
17675a988416SJim Ingham 
17685a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
17695a988416SJim Ingham         arg1.push_back (cmd_arg);
17705a988416SJim Ingham 
17715a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
17725a988416SJim Ingham         m_arguments.push_back (arg1);
17735a988416SJim Ingham     }
17745a988416SJim Ingham 
17755a988416SJim Ingham     ~CommandObjectCommandsScriptAdd ()
17765a988416SJim Ingham     {
17775a988416SJim Ingham     }
17785a988416SJim Ingham 
17795a988416SJim Ingham     virtual Options *
17805a988416SJim Ingham     GetOptions ()
17815a988416SJim Ingham     {
17825a988416SJim Ingham         return &m_options;
17835a988416SJim Ingham     }
17845a988416SJim Ingham 
17855a988416SJim Ingham protected:
1786223383edSEnrico Granata 
1787223383edSEnrico Granata     class CommandOptions : public Options
1788223383edSEnrico Granata     {
1789223383edSEnrico Granata     public:
1790223383edSEnrico Granata 
1791223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
17929fe00e52SEnrico Granata             Options (interpreter),
17939fe00e52SEnrico Granata             m_class_name(),
17949fe00e52SEnrico Granata             m_funct_name(),
17959fe00e52SEnrico Granata             m_short_help(),
17969fe00e52SEnrico Granata             m_synchronicity(eScriptedCommandSynchronicitySynchronous)
1797223383edSEnrico Granata         {
1798223383edSEnrico Granata         }
1799223383edSEnrico Granata 
1800223383edSEnrico Granata         virtual
1801223383edSEnrico Granata         ~CommandOptions (){}
1802223383edSEnrico Granata 
1803223383edSEnrico Granata         virtual Error
1804223383edSEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
1805223383edSEnrico Granata         {
1806223383edSEnrico Granata             Error error;
18073bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
1808223383edSEnrico Granata 
1809223383edSEnrico Granata             switch (short_option)
1810223383edSEnrico Granata             {
1811223383edSEnrico Granata                 case 'f':
1812735152e3SEnrico Granata                     if (option_arg)
1813735152e3SEnrico Granata                         m_funct_name.assign(option_arg);
1814735152e3SEnrico Granata                     break;
18159fe00e52SEnrico Granata                 case 'c':
18169fe00e52SEnrico Granata                     if (option_arg)
18179fe00e52SEnrico Granata                         m_class_name.assign(option_arg);
18189fe00e52SEnrico Granata                     break;
1819735152e3SEnrico Granata                 case 'h':
1820735152e3SEnrico Granata                     if (option_arg)
1821735152e3SEnrico Granata                         m_short_help.assign(option_arg);
1822223383edSEnrico Granata                     break;
18230a305db7SEnrico Granata                 case 's':
182444d93782SGreg Clayton                     m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
18250a305db7SEnrico Granata                     if (!error.Success())
18260a305db7SEnrico Granata                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
18270a305db7SEnrico Granata                     break;
1828223383edSEnrico Granata                 default:
182986edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1830223383edSEnrico Granata                     break;
1831223383edSEnrico Granata             }
1832223383edSEnrico Granata 
1833223383edSEnrico Granata             return error;
1834223383edSEnrico Granata         }
1835223383edSEnrico Granata 
1836223383edSEnrico Granata         void
1837223383edSEnrico Granata         OptionParsingStarting ()
1838223383edSEnrico Granata         {
18399fe00e52SEnrico Granata             m_class_name.clear();
1840735152e3SEnrico Granata             m_funct_name.clear();
1841735152e3SEnrico Granata             m_short_help.clear();
184244d93782SGreg Clayton             m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1843223383edSEnrico Granata         }
1844223383edSEnrico Granata 
1845223383edSEnrico Granata         const OptionDefinition*
1846223383edSEnrico Granata         GetDefinitions ()
1847223383edSEnrico Granata         {
1848223383edSEnrico Granata             return g_option_table;
1849223383edSEnrico Granata         }
1850223383edSEnrico Granata 
1851223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1852223383edSEnrico Granata 
1853223383edSEnrico Granata         static OptionDefinition g_option_table[];
1854223383edSEnrico Granata 
1855223383edSEnrico Granata         // Instance variables to hold the values for command options.
1856223383edSEnrico Granata 
18579fe00e52SEnrico Granata         std::string m_class_name;
1858223383edSEnrico Granata         std::string m_funct_name;
1859735152e3SEnrico Granata         std::string m_short_help;
186044d93782SGreg Clayton         ScriptedCommandSynchronicity m_synchronicity;
1861223383edSEnrico Granata     };
1862223383edSEnrico Granata 
186344d93782SGreg Clayton     virtual void
186444d93782SGreg Clayton     IOHandlerActivated (IOHandler &io_handler)
1865223383edSEnrico Granata     {
186644d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
186744d93782SGreg Clayton         if (output_sp)
1868223383edSEnrico Granata         {
186944d93782SGreg Clayton             output_sp->PutCString(g_python_command_instructions);
187044d93782SGreg Clayton             output_sp->Flush();
1871223383edSEnrico Granata         }
1872223383edSEnrico Granata     }
1873223383edSEnrico Granata 
1874223383edSEnrico Granata 
187544d93782SGreg Clayton     virtual void
187644d93782SGreg Clayton     IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
1877223383edSEnrico Granata     {
187844d93782SGreg Clayton         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
187944d93782SGreg Clayton 
188044d93782SGreg Clayton         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
188144d93782SGreg Clayton         if (interpreter)
188244d93782SGreg Clayton         {
188344d93782SGreg Clayton 
188444d93782SGreg Clayton             StringList lines;
188544d93782SGreg Clayton             lines.SplitIntoLines(data);
188644d93782SGreg Clayton             if (lines.GetSize() > 0)
188744d93782SGreg Clayton             {
1888a73b7df7SEnrico Granata                 std::string funct_name_str;
188944d93782SGreg Clayton                 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1890223383edSEnrico Granata                 {
1891a73b7df7SEnrico Granata                     if (funct_name_str.empty())
1892223383edSEnrico Granata                     {
189344d93782SGreg Clayton                         error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
189444d93782SGreg Clayton                         error_sp->Flush();
1895223383edSEnrico Granata                     }
189644d93782SGreg Clayton                     else
189744d93782SGreg Clayton                     {
1898223383edSEnrico Granata                         // everything should be fine now, let's add this alias
1899223383edSEnrico Granata 
1900223383edSEnrico Granata                         CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1901223383edSEnrico Granata                                                                                         m_cmd_name,
1902a73b7df7SEnrico Granata                                                                                         funct_name_str.c_str(),
1903735152e3SEnrico Granata                                                                                         m_short_help,
190444d93782SGreg Clayton                                                                                         m_synchronicity));
1905223383edSEnrico Granata 
19060a305db7SEnrico Granata                         if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1907223383edSEnrico Granata                         {
190844d93782SGreg Clayton                             error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
190944d93782SGreg Clayton                             error_sp->Flush();
1910223383edSEnrico Granata                         }
1911223383edSEnrico Granata                     }
191244d93782SGreg Clayton                 }
191344d93782SGreg Clayton                 else
191444d93782SGreg Clayton                 {
191544d93782SGreg Clayton                     error_sp->Printf ("error: unable to create function, didn't add python command.\n");
191644d93782SGreg Clayton                     error_sp->Flush();
191744d93782SGreg Clayton                 }
191844d93782SGreg Clayton             }
191944d93782SGreg Clayton             else
192044d93782SGreg Clayton             {
192144d93782SGreg Clayton                 error_sp->Printf ("error: empty function, didn't add python command.\n");
192244d93782SGreg Clayton                 error_sp->Flush();
192344d93782SGreg Clayton             }
192444d93782SGreg Clayton         }
192544d93782SGreg Clayton         else
192644d93782SGreg Clayton         {
192744d93782SGreg Clayton             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
192844d93782SGreg Clayton             error_sp->Flush();
192944d93782SGreg Clayton         }
193044d93782SGreg Clayton 
193144d93782SGreg Clayton         io_handler.SetIsDone(true);
193244d93782SGreg Clayton 
193344d93782SGreg Clayton 
193444d93782SGreg Clayton     }
1935223383edSEnrico Granata 
19365a988416SJim Ingham protected:
1937223383edSEnrico Granata     bool
19385a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1939223383edSEnrico Granata     {
194099f0b8f9SEnrico Granata 
194199f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
194299f0b8f9SEnrico Granata         {
194399f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
194499f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
194599f0b8f9SEnrico Granata             return false;
194699f0b8f9SEnrico Granata         }
194799f0b8f9SEnrico Granata 
19485a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1949223383edSEnrico Granata 
1950223383edSEnrico Granata         if (argc != 1)
1951223383edSEnrico Granata         {
1952223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
1953223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1954223383edSEnrico Granata             return false;
1955223383edSEnrico Granata         }
1956223383edSEnrico Granata 
1957735152e3SEnrico Granata         // Store the options in case we get multi-line input
195844d93782SGreg Clayton         m_cmd_name = command.GetArgumentAtIndex(0);
1959735152e3SEnrico Granata         m_short_help.assign(m_options.m_short_help);
196044d93782SGreg Clayton         m_synchronicity = m_options.m_synchronicity;
1961223383edSEnrico Granata 
19629fe00e52SEnrico Granata         if (m_options.m_class_name.empty())
19639fe00e52SEnrico Granata         {
1964223383edSEnrico Granata             if (m_options.m_funct_name.empty())
1965223383edSEnrico Granata             {
196644d93782SGreg Clayton                 m_interpreter.GetPythonCommandsFromIOHandler ("     ",  // Prompt
196744d93782SGreg Clayton                                                               *this,    // IOHandlerDelegate
196844d93782SGreg Clayton                                                               true,     // Run IOHandler in async mode
196944d93782SGreg Clayton                                                               NULL);    // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1970223383edSEnrico Granata             }
1971223383edSEnrico Granata             else
1972223383edSEnrico Granata             {
19730a305db7SEnrico Granata                 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
197444d93782SGreg Clayton                                                                         m_cmd_name,
19750a305db7SEnrico Granata                                                                         m_options.m_funct_name,
1976735152e3SEnrico Granata                                                                         m_options.m_short_help,
197744d93782SGreg Clayton                                                                         m_synchronicity));
197844d93782SGreg Clayton                 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
1979223383edSEnrico Granata                 {
1980223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1981223383edSEnrico Granata                 }
1982223383edSEnrico Granata                 else
1983223383edSEnrico Granata                 {
1984223383edSEnrico Granata                     result.AppendError("cannot add command");
1985223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
1986223383edSEnrico Granata                 }
1987223383edSEnrico Granata             }
19889fe00e52SEnrico Granata         }
19899fe00e52SEnrico Granata         else
19909fe00e52SEnrico Granata         {
19919fe00e52SEnrico Granata             ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
19929fe00e52SEnrico Granata             if (!interpreter)
19939fe00e52SEnrico Granata             {
19949fe00e52SEnrico Granata                 result.AppendError("cannot find ScriptInterpreter");
19959fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
19969fe00e52SEnrico Granata                 return false;
19979fe00e52SEnrico Granata             }
19989fe00e52SEnrico Granata 
19999fe00e52SEnrico Granata             auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
20009fe00e52SEnrico Granata             if (!cmd_obj_sp)
20019fe00e52SEnrico Granata             {
20029fe00e52SEnrico Granata                 result.AppendError("cannot create helper object");
20039fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
20049fe00e52SEnrico Granata                 return false;
20059fe00e52SEnrico Granata             }
20069fe00e52SEnrico Granata 
20079fe00e52SEnrico Granata             CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
20089fe00e52SEnrico Granata                                                                      m_cmd_name,
20099fe00e52SEnrico Granata                                                                      cmd_obj_sp,
20109fe00e52SEnrico Granata                                                                      m_synchronicity));
20119fe00e52SEnrico Granata             if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
20129fe00e52SEnrico Granata             {
20139fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
20149fe00e52SEnrico Granata             }
20159fe00e52SEnrico Granata             else
20169fe00e52SEnrico Granata             {
20179fe00e52SEnrico Granata                 result.AppendError("cannot add command");
20189fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
20199fe00e52SEnrico Granata             }
20209fe00e52SEnrico Granata         }
2021223383edSEnrico Granata 
2022223383edSEnrico Granata         return result.Succeeded();
2023223383edSEnrico Granata 
2024223383edSEnrico Granata     }
20255a988416SJim Ingham 
20265a988416SJim Ingham     CommandOptions m_options;
202744d93782SGreg Clayton     std::string m_cmd_name;
2028735152e3SEnrico Granata     std::string m_short_help;
202944d93782SGreg Clayton     ScriptedCommandSynchronicity m_synchronicity;
2030223383edSEnrico Granata };
2031223383edSEnrico Granata 
20320a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] =
20330a305db7SEnrico Granata {
20340a305db7SEnrico Granata     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
20350a305db7SEnrico Granata     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
20360a305db7SEnrico Granata     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
20370a305db7SEnrico Granata     { 0, NULL, NULL }
20380a305db7SEnrico Granata };
20390a305db7SEnrico Granata 
2040223383edSEnrico Granata OptionDefinition
2041223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2042223383edSEnrico Granata {
2043d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."},
20449fe00e52SEnrico Granata     { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass,        "Name of the Python class to bind to this command name."},
20459370d278SEnrico Granata     { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
20469fe00e52SEnrico Granata     { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity,        "Set the synchronicity of this command's executions with regard to LLDB event system."},
2047d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2048223383edSEnrico Granata };
2049223383edSEnrico Granata 
2050223383edSEnrico Granata //-------------------------------------------------------------------------
2051223383edSEnrico Granata // CommandObjectCommandsScriptList
2052223383edSEnrico Granata //-------------------------------------------------------------------------
2053223383edSEnrico Granata 
20545a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed
2055223383edSEnrico Granata {
2056223383edSEnrico Granata private:
2057223383edSEnrico Granata 
2058223383edSEnrico Granata public:
2059223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
20605a988416SJim Ingham     CommandObjectParsed (interpreter,
2061223383edSEnrico Granata                    "command script list",
2062223383edSEnrico Granata                    "List defined scripted commands.",
2063223383edSEnrico Granata                    NULL)
2064223383edSEnrico Granata     {
2065223383edSEnrico Granata     }
2066223383edSEnrico Granata 
2067223383edSEnrico Granata     ~CommandObjectCommandsScriptList ()
2068223383edSEnrico Granata     {
2069223383edSEnrico Granata     }
2070223383edSEnrico Granata 
2071223383edSEnrico Granata     bool
20725a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
2073223383edSEnrico Granata     {
2074223383edSEnrico Granata 
2075223383edSEnrico Granata         m_interpreter.GetHelp(result,
2076223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
2077223383edSEnrico Granata 
2078223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2079223383edSEnrico Granata 
2080223383edSEnrico Granata         return true;
2081223383edSEnrico Granata 
2082223383edSEnrico Granata 
2083223383edSEnrico Granata     }
2084223383edSEnrico Granata };
2085223383edSEnrico Granata 
2086223383edSEnrico Granata //-------------------------------------------------------------------------
2087223383edSEnrico Granata // CommandObjectCommandsScriptClear
2088223383edSEnrico Granata //-------------------------------------------------------------------------
2089223383edSEnrico Granata 
20905a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed
2091223383edSEnrico Granata {
2092223383edSEnrico Granata private:
2093223383edSEnrico Granata 
2094223383edSEnrico Granata public:
2095223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
20965a988416SJim Ingham         CommandObjectParsed (interpreter,
2097223383edSEnrico Granata                              "command script clear",
2098223383edSEnrico Granata                              "Delete all scripted commands.",
2099223383edSEnrico Granata                              NULL)
2100223383edSEnrico Granata     {
2101223383edSEnrico Granata     }
2102223383edSEnrico Granata 
2103223383edSEnrico Granata     ~CommandObjectCommandsScriptClear ()
2104223383edSEnrico Granata     {
2105223383edSEnrico Granata     }
2106223383edSEnrico Granata 
21075a988416SJim Ingham protected:
2108223383edSEnrico Granata     bool
21095a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
2110223383edSEnrico Granata     {
2111223383edSEnrico Granata 
2112223383edSEnrico Granata         m_interpreter.RemoveAllUser();
2113223383edSEnrico Granata 
2114223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2115223383edSEnrico Granata 
2116223383edSEnrico Granata         return true;
2117223383edSEnrico Granata     }
2118223383edSEnrico Granata };
2119223383edSEnrico Granata 
2120223383edSEnrico Granata //-------------------------------------------------------------------------
2121223383edSEnrico Granata // CommandObjectCommandsScriptDelete
2122223383edSEnrico Granata //-------------------------------------------------------------------------
2123223383edSEnrico Granata 
21245a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed
2125223383edSEnrico Granata {
2126223383edSEnrico Granata public:
2127223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
21285a988416SJim Ingham         CommandObjectParsed (interpreter,
2129223383edSEnrico Granata                              "command script delete",
2130223383edSEnrico Granata                              "Delete a scripted command.",
2131223383edSEnrico Granata                              NULL)
2132223383edSEnrico Granata     {
2133223383edSEnrico Granata         CommandArgumentEntry arg1;
2134223383edSEnrico Granata         CommandArgumentData cmd_arg;
2135223383edSEnrico Granata 
2136223383edSEnrico Granata         // Define the first (and only) variant of this arg.
2137223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
2138223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
2139223383edSEnrico Granata 
2140223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
2141223383edSEnrico Granata         arg1.push_back (cmd_arg);
2142223383edSEnrico Granata 
2143223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
2144223383edSEnrico Granata         m_arguments.push_back (arg1);
2145223383edSEnrico Granata     }
2146223383edSEnrico Granata 
2147223383edSEnrico Granata     ~CommandObjectCommandsScriptDelete ()
2148223383edSEnrico Granata     {
2149223383edSEnrico Granata     }
2150223383edSEnrico Granata 
21515a988416SJim Ingham protected:
2152223383edSEnrico Granata     bool
21535a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
2154223383edSEnrico Granata     {
2155223383edSEnrico Granata 
21565a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2157223383edSEnrico Granata 
2158223383edSEnrico Granata         if (argc != 1)
2159223383edSEnrico Granata         {
2160223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
2161223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2162223383edSEnrico Granata             return false;
2163223383edSEnrico Granata         }
2164223383edSEnrico Granata 
21655a988416SJim Ingham         const char* cmd_name = command.GetArgumentAtIndex(0);
2166223383edSEnrico Granata 
2167223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2168223383edSEnrico Granata         {
2169223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
2170223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
2171223383edSEnrico Granata         }
2172223383edSEnrico Granata         else
2173223383edSEnrico Granata         {
2174223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
2175223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2176223383edSEnrico Granata         }
2177223383edSEnrico Granata 
2178223383edSEnrico Granata         return result.Succeeded();
2179223383edSEnrico Granata 
2180223383edSEnrico Granata     }
2181223383edSEnrico Granata };
2182223383edSEnrico Granata 
2183223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
2184223383edSEnrico Granata 
2185223383edSEnrico Granata //-------------------------------------------------------------------------
2186223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
2187223383edSEnrico Granata //-------------------------------------------------------------------------
2188223383edSEnrico Granata 
2189223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2190223383edSEnrico Granata {
2191223383edSEnrico Granata public:
2192223383edSEnrico Granata     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2193223383edSEnrico Granata     CommandObjectMultiword (interpreter,
2194223383edSEnrico Granata                             "command script",
2195223383edSEnrico Granata                             "A set of commands for managing or customizing script commands.",
2196223383edSEnrico Granata                             "command script <subcommand> [<subcommand-options>]")
2197223383edSEnrico Granata     {
2198223383edSEnrico Granata         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2199223383edSEnrico Granata         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2200223383edSEnrico Granata         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
2201223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
2202a9dbf432SEnrico Granata         LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
2203223383edSEnrico Granata     }
2204223383edSEnrico Granata 
2205223383edSEnrico Granata     ~CommandObjectMultiwordCommandsScript ()
2206223383edSEnrico Granata     {
2207223383edSEnrico Granata     }
2208223383edSEnrico Granata 
2209223383edSEnrico Granata };
2210223383edSEnrico Granata 
2211223383edSEnrico Granata 
2212ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
2213ebc09c36SJim Ingham 
2214ebc09c36SJim Ingham //-------------------------------------------------------------------------
2215ebc09c36SJim Ingham // CommandObjectMultiwordCommands
2216ebc09c36SJim Ingham //-------------------------------------------------------------------------
2217ebc09c36SJim Ingham 
2218ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
2219a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
22200e5e5a79SGreg Clayton                             "command",
22213f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
22220e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
2223ebc09c36SJim Ingham {
2224a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2225a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2226a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
2227b547278cSGreg Clayton     LoadSubCommand ("delete",  CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
2228de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
2229a5a97ebeSJim Ingham     LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2230223383edSEnrico Granata     LoadSubCommand ("script",  CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
2231ebc09c36SJim Ingham }
2232ebc09c36SJim Ingham 
2233ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
2234ebc09c36SJim Ingham {
2235ebc09c36SJim Ingham }
2236ebc09c36SJim Ingham 
2237