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 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
12ebc09c36SJim Ingham #include "CommandObjectCommands.h"
13ebc09c36SJim Ingham 
14ebc09c36SJim Ingham // C Includes
15ebc09c36SJim Ingham // C++ Includes
16ebc09c36SJim Ingham // Other libraries and framework includes
170e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h"
180e5e5a79SGreg Clayton 
19ebc09c36SJim Ingham // Project includes
20ebc09c36SJim Ingham #include "lldb/Core/Debugger.h"
2144d93782SGreg Clayton #include "lldb/Core/IOHandler.h"
22be93a35aSEnrico Granata #include "lldb/Core/StringList.h"
23de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h"
247594f14fSEnrico Granata #include "lldb/Interpreter/CommandHistory.h"
25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h"
26de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h"
27ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h"
28012d4fcaSEnrico Granata #include "lldb/Interpreter/OptionValueBoolean.h"
297594f14fSEnrico Granata #include "lldb/Interpreter/OptionValueUInt64.h"
30ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
3199f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h"
32ebc09c36SJim Ingham 
33ebc09c36SJim Ingham using namespace lldb;
34ebc09c36SJim Ingham using namespace lldb_private;
35ebc09c36SJim Ingham 
36ebc09c36SJim Ingham //-------------------------------------------------------------------------
37ebc09c36SJim Ingham // CommandObjectCommandsSource
38ebc09c36SJim Ingham //-------------------------------------------------------------------------
39ebc09c36SJim Ingham 
405a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed
41a5a97ebeSJim Ingham {
425a988416SJim Ingham public:
435a988416SJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
445a988416SJim Ingham         CommandObjectParsed (interpreter,
455a988416SJim Ingham                              "command history",
465a988416SJim Ingham                              "Dump the history of commands in this session.",
475a988416SJim Ingham                              NULL),
485a988416SJim Ingham         m_options (interpreter)
495a988416SJim Ingham     {
505a988416SJim Ingham     }
515a988416SJim Ingham 
525a988416SJim Ingham     ~CommandObjectCommandsHistory () {}
535a988416SJim Ingham 
545a988416SJim Ingham     virtual Options *
555a988416SJim Ingham     GetOptions ()
565a988416SJim Ingham     {
575a988416SJim Ingham         return &m_options;
585a988416SJim Ingham     }
595a988416SJim Ingham 
605a988416SJim Ingham protected:
61a5a97ebeSJim Ingham 
62a5a97ebeSJim Ingham     class CommandOptions : public Options
63a5a97ebeSJim Ingham     {
64a5a97ebeSJim Ingham     public:
65a5a97ebeSJim Ingham 
66a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
677594f14fSEnrico Granata             Options (interpreter),
687594f14fSEnrico Granata             m_start_idx(0),
697594f14fSEnrico Granata             m_stop_idx(0),
707594f14fSEnrico Granata             m_count(0),
7163123b64SEnrico Granata             m_clear(false)
72a5a97ebeSJim Ingham         {
73a5a97ebeSJim Ingham         }
74a5a97ebeSJim Ingham 
75a5a97ebeSJim Ingham         virtual
76a5a97ebeSJim Ingham         ~CommandOptions (){}
77a5a97ebeSJim Ingham 
78a5a97ebeSJim Ingham         virtual Error
79a5a97ebeSJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
80a5a97ebeSJim Ingham         {
81a5a97ebeSJim Ingham             Error error;
823bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
83a5a97ebeSJim Ingham 
84a5a97ebeSJim Ingham             switch (short_option)
85a5a97ebeSJim Ingham             {
86a5a97ebeSJim Ingham                 case 'c':
87c95f7e2aSPavel Labath                     error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
88a5a97ebeSJim Ingham                     break;
89a5a97ebeSJim Ingham                 case 's':
907594f14fSEnrico Granata                     if (option_arg && strcmp("end", option_arg) == 0)
917594f14fSEnrico Granata                     {
927594f14fSEnrico Granata                         m_start_idx.SetCurrentValue(UINT64_MAX);
937594f14fSEnrico Granata                         m_start_idx.SetOptionWasSet();
947594f14fSEnrico Granata                     }
957594f14fSEnrico Granata                     else
96c95f7e2aSPavel Labath                         error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
977594f14fSEnrico Granata                     break;
987594f14fSEnrico Granata                 case 'e':
99c95f7e2aSPavel Labath                     error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
1007594f14fSEnrico Granata                     break;
10163123b64SEnrico Granata                 case 'C':
10263123b64SEnrico Granata                     m_clear.SetCurrentValue(true);
10363123b64SEnrico Granata                     m_clear.SetOptionWasSet();
104a5a97ebeSJim Ingham                     break;
105a5a97ebeSJim Ingham                 default:
10686edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
107a5a97ebeSJim Ingham                     break;
108a5a97ebeSJim Ingham             }
109a5a97ebeSJim Ingham 
110a5a97ebeSJim Ingham             return error;
111a5a97ebeSJim Ingham         }
112a5a97ebeSJim Ingham 
113a5a97ebeSJim Ingham         void
114a5a97ebeSJim Ingham         OptionParsingStarting ()
115a5a97ebeSJim Ingham         {
1167594f14fSEnrico Granata             m_start_idx.Clear();
1177594f14fSEnrico Granata             m_stop_idx.Clear();
1187594f14fSEnrico Granata             m_count.Clear();
11963123b64SEnrico Granata             m_clear.Clear();
120a5a97ebeSJim Ingham         }
121a5a97ebeSJim Ingham 
122a5a97ebeSJim Ingham         const OptionDefinition*
123a5a97ebeSJim Ingham         GetDefinitions ()
124a5a97ebeSJim Ingham         {
125a5a97ebeSJim Ingham             return g_option_table;
126a5a97ebeSJim Ingham         }
127a5a97ebeSJim Ingham 
128a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
129a5a97ebeSJim Ingham 
130a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
131a5a97ebeSJim Ingham 
132a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
133a5a97ebeSJim Ingham 
1347594f14fSEnrico Granata         OptionValueUInt64 m_start_idx;
1357594f14fSEnrico Granata         OptionValueUInt64 m_stop_idx;
1367594f14fSEnrico Granata         OptionValueUInt64 m_count;
13763123b64SEnrico Granata         OptionValueBoolean m_clear;
138a5a97ebeSJim Ingham     };
139a5a97ebeSJim Ingham 
140a5a97ebeSJim Ingham     bool
1415a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
142a5a97ebeSJim Ingham     {
14363123b64SEnrico Granata         if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
1447594f14fSEnrico Granata         {
1457594f14fSEnrico Granata             m_interpreter.GetCommandHistory().Clear();
1467594f14fSEnrico Granata             result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
1477594f14fSEnrico Granata         }
1487594f14fSEnrico Granata         else
1497594f14fSEnrico Granata         {
1507594f14fSEnrico Granata             if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
1517594f14fSEnrico Granata             {
1527594f14fSEnrico Granata                 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
1537594f14fSEnrico Granata                 result.SetStatus(lldb::eReturnStatusFailed);
1547594f14fSEnrico Granata             }
1557594f14fSEnrico Granata             else
1567594f14fSEnrico Granata             {
15784400ec7SVirgile Bello                 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
15884400ec7SVirgile Bello                 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
15984400ec7SVirgile Bello                 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
160a5a97ebeSJim Ingham 
1617594f14fSEnrico Granata                 const CommandHistory& history(m_interpreter.GetCommandHistory());
1627594f14fSEnrico Granata 
1637594f14fSEnrico Granata                 if (start_idx.first && start_idx.second == UINT64_MAX)
1647594f14fSEnrico Granata                 {
1657594f14fSEnrico Granata                     if (count.first)
1667594f14fSEnrico Granata                     {
1677594f14fSEnrico Granata                         start_idx.second = history.GetSize() - count.second;
1687594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1697594f14fSEnrico Granata                     }
1707594f14fSEnrico Granata                     else if (stop_idx.first)
1717594f14fSEnrico Granata                     {
1727594f14fSEnrico Granata                         start_idx.second = stop_idx.second;
1737594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1747594f14fSEnrico Granata                     }
1757594f14fSEnrico Granata                     else
1767594f14fSEnrico Granata                     {
1777594f14fSEnrico Granata                         start_idx.second = 0;
1787594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1797594f14fSEnrico Granata                     }
1807594f14fSEnrico Granata                 }
1817594f14fSEnrico Granata                 else
1827594f14fSEnrico Granata                 {
1837594f14fSEnrico Granata                     if (!start_idx.first && !stop_idx.first && !count.first)
1847594f14fSEnrico Granata                     {
1857594f14fSEnrico Granata                         start_idx.second = 0;
1867594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1877594f14fSEnrico Granata                     }
1887594f14fSEnrico Granata                     else if (start_idx.first)
1897594f14fSEnrico Granata                     {
1907594f14fSEnrico Granata                         if (count.first)
1917594f14fSEnrico Granata                         {
1927594f14fSEnrico Granata                             stop_idx.second = start_idx.second + count.second - 1;
1937594f14fSEnrico Granata                         }
1947594f14fSEnrico Granata                         else if (!stop_idx.first)
1957594f14fSEnrico Granata                         {
1967594f14fSEnrico Granata                             stop_idx.second = history.GetSize() - 1;
1977594f14fSEnrico Granata                         }
1987594f14fSEnrico Granata                     }
1997594f14fSEnrico Granata                     else if (stop_idx.first)
2007594f14fSEnrico Granata                     {
2017594f14fSEnrico Granata                         if (count.first)
2027594f14fSEnrico Granata                         {
2037594f14fSEnrico Granata                             if (stop_idx.second >= count.second)
2047594f14fSEnrico Granata                                 start_idx.second = stop_idx.second - count.second + 1;
2057594f14fSEnrico Granata                             else
2067594f14fSEnrico Granata                                 start_idx.second = 0;
2077594f14fSEnrico Granata                         }
2087594f14fSEnrico Granata                     }
2097594f14fSEnrico Granata                     else /* if (count.first) */
2107594f14fSEnrico Granata                     {
2117594f14fSEnrico Granata                         start_idx.second = 0;
2127594f14fSEnrico Granata                         stop_idx.second = count.second - 1;
2137594f14fSEnrico Granata                     }
2147594f14fSEnrico Granata                 }
2157594f14fSEnrico Granata                 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
2167594f14fSEnrico Granata             }
2177594f14fSEnrico Granata         }
218a5a97ebeSJim Ingham         return result.Succeeded();
219a5a97ebeSJim Ingham 
220a5a97ebeSJim Ingham     }
2215a988416SJim Ingham 
2225a988416SJim Ingham     CommandOptions m_options;
223a5a97ebeSJim Ingham };
224a5a97ebeSJim Ingham 
225a5a97ebeSJim Ingham OptionDefinition
226a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
227a5a97ebeSJim Ingham {
228d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
229d37221dcSZachary 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)."},
230d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
231d37221dcSZachary Turner { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean,    "Clears the current command history."},
232d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
233a5a97ebeSJim Ingham };
234a5a97ebeSJim Ingham 
235a5a97ebeSJim Ingham 
236a5a97ebeSJim Ingham //-------------------------------------------------------------------------
237a5a97ebeSJim Ingham // CommandObjectCommandsSource
238a5a97ebeSJim Ingham //-------------------------------------------------------------------------
239a5a97ebeSJim Ingham 
2405a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed
241ebc09c36SJim Ingham {
2425a988416SJim Ingham public:
2435a988416SJim Ingham     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
2445a988416SJim Ingham         CommandObjectParsed (interpreter,
2455a988416SJim Ingham                              "command source",
2465a988416SJim Ingham                              "Read in debugger commands from the file <filename> and execute them.",
2475a988416SJim Ingham                              NULL),
2485a988416SJim Ingham         m_options (interpreter)
2495a988416SJim Ingham     {
2505a988416SJim Ingham         CommandArgumentEntry arg;
2515a988416SJim Ingham         CommandArgumentData file_arg;
2525a988416SJim Ingham 
2535a988416SJim Ingham         // Define the first (and only) variant of this arg.
2545a988416SJim Ingham         file_arg.arg_type = eArgTypeFilename;
2555a988416SJim Ingham         file_arg.arg_repetition = eArgRepeatPlain;
2565a988416SJim Ingham 
2575a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
2585a988416SJim Ingham         arg.push_back (file_arg);
2595a988416SJim Ingham 
2605a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
2615a988416SJim Ingham         m_arguments.push_back (arg);
2625a988416SJim Ingham     }
2635a988416SJim Ingham 
2645a988416SJim Ingham     ~CommandObjectCommandsSource () {}
2655a988416SJim Ingham 
2665a988416SJim Ingham     virtual const char*
2675a988416SJim Ingham     GetRepeatCommand (Args &current_command_args, uint32_t index)
2685a988416SJim Ingham     {
2695a988416SJim Ingham         return "";
2705a988416SJim Ingham     }
2715a988416SJim Ingham 
272c7bece56SGreg Clayton     virtual int
2735a988416SJim Ingham     HandleArgumentCompletion (Args &input,
2745a988416SJim Ingham                               int &cursor_index,
2755a988416SJim Ingham                               int &cursor_char_position,
2765a988416SJim Ingham                               OptionElementVector &opt_element_vector,
2775a988416SJim Ingham                               int match_start_point,
2785a988416SJim Ingham                               int max_return_elements,
2795a988416SJim Ingham                               bool &word_complete,
2805a988416SJim Ingham                               StringList &matches)
2815a988416SJim Ingham     {
2825a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2835a988416SJim Ingham         completion_str.erase (cursor_char_position);
2845a988416SJim Ingham 
2855a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2865a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
2875a988416SJim Ingham                                                              completion_str.c_str(),
2885a988416SJim Ingham                                                              match_start_point,
2895a988416SJim Ingham                                                              max_return_elements,
2905a988416SJim Ingham                                                              NULL,
2915a988416SJim Ingham                                                              word_complete,
2925a988416SJim Ingham                                                              matches);
2935a988416SJim Ingham         return matches.GetSize();
2945a988416SJim Ingham     }
2955a988416SJim Ingham 
2965a988416SJim Ingham     virtual Options *
2975a988416SJim Ingham     GetOptions ()
2985a988416SJim Ingham     {
2995a988416SJim Ingham         return &m_options;
3005a988416SJim Ingham     }
3015a988416SJim Ingham 
3025a988416SJim Ingham protected:
303e16c50a1SJim Ingham 
304e16c50a1SJim Ingham     class CommandOptions : public Options
305e16c50a1SJim Ingham     {
306e16c50a1SJim Ingham     public:
307e16c50a1SJim Ingham 
308eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
309012d4fcaSEnrico Granata             Options (interpreter),
310340b0309SGreg Clayton             m_stop_on_error (true),
311340b0309SGreg Clayton             m_silent_run (false),
312340b0309SGreg Clayton             m_stop_on_continue (true)
313eb0103f2SGreg Clayton         {
314eb0103f2SGreg Clayton         }
315e16c50a1SJim Ingham 
316e16c50a1SJim Ingham         virtual
317e16c50a1SJim Ingham         ~CommandOptions (){}
318e16c50a1SJim Ingham 
319e16c50a1SJim Ingham         virtual Error
320f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
321e16c50a1SJim Ingham         {
322e16c50a1SJim Ingham             Error error;
3233bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
324e16c50a1SJim Ingham 
325e16c50a1SJim Ingham             switch (short_option)
326e16c50a1SJim Ingham             {
327e16c50a1SJim Ingham                 case 'e':
328c95f7e2aSPavel Labath                     error = m_stop_on_error.SetValueFromString(option_arg);
329e16c50a1SJim Ingham                     break;
330340b0309SGreg Clayton 
331e16c50a1SJim Ingham                 case 'c':
332c95f7e2aSPavel Labath                     error = m_stop_on_continue.SetValueFromString(option_arg);
333e16c50a1SJim Ingham                     break;
334340b0309SGreg Clayton 
33560986174SMichael Sartain                 case 's':
336c95f7e2aSPavel Labath                     error = m_silent_run.SetValueFromString(option_arg);
33760986174SMichael Sartain                     break;
338340b0309SGreg Clayton 
339e16c50a1SJim Ingham                 default:
34086edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
341e16c50a1SJim Ingham                     break;
342e16c50a1SJim Ingham             }
343e16c50a1SJim Ingham 
344e16c50a1SJim Ingham             return error;
345e16c50a1SJim Ingham         }
346e16c50a1SJim Ingham 
347e16c50a1SJim Ingham         void
348f6b8b581SGreg Clayton         OptionParsingStarting ()
349e16c50a1SJim Ingham         {
350012d4fcaSEnrico Granata             m_stop_on_error.Clear();
351340b0309SGreg Clayton             m_silent_run.Clear();
352340b0309SGreg Clayton             m_stop_on_continue.Clear();
353e16c50a1SJim Ingham         }
354e16c50a1SJim Ingham 
355e0d378b3SGreg Clayton         const OptionDefinition*
356e16c50a1SJim Ingham         GetDefinitions ()
357e16c50a1SJim Ingham         {
358e16c50a1SJim Ingham             return g_option_table;
359e16c50a1SJim Ingham         }
360e16c50a1SJim Ingham 
361e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
362e16c50a1SJim Ingham 
363e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
364e16c50a1SJim Ingham 
365e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
366e16c50a1SJim Ingham 
367012d4fcaSEnrico Granata         OptionValueBoolean m_stop_on_error;
368340b0309SGreg Clayton         OptionValueBoolean m_silent_run;
369340b0309SGreg Clayton         OptionValueBoolean m_stop_on_continue;
370e16c50a1SJim Ingham     };
371e16c50a1SJim Ingham 
372ebc09c36SJim Ingham     bool
3735a988416SJim Ingham     DoExecute(Args& command, CommandReturnObject &result)
374ebc09c36SJim Ingham     {
375c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
376ebc09c36SJim Ingham         if (argc == 1)
377ebc09c36SJim Ingham         {
3785a988416SJim Ingham             const char *filename = command.GetArgumentAtIndex(0);
379ebc09c36SJim Ingham 
3801ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
381e16c50a1SJim Ingham             ExecutionContext *exe_ctx = NULL;  // Just use the default context.
382ebc09c36SJim Ingham 
383340b0309SGreg Clayton             // If any options were set, then use them
384340b0309SGreg Clayton             if (m_options.m_stop_on_error.OptionWasSet()    ||
385340b0309SGreg Clayton                 m_options.m_silent_run.OptionWasSet()       ||
386340b0309SGreg Clayton                 m_options.m_stop_on_continue.OptionWasSet())
387340b0309SGreg Clayton             {
388340b0309SGreg Clayton                 // Use user set settings
38926c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
39026c7bf93SJim Ingham                 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
39126c7bf93SJim Ingham                 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
3927d8555c4SJim Ingham                 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
3937d8555c4SJim Ingham                 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
39426c7bf93SJim Ingham 
395e16c50a1SJim Ingham                 m_interpreter.HandleCommandsFromFile (cmd_file,
396e16c50a1SJim Ingham                                                       exe_ctx,
39726c7bf93SJim Ingham                                                       options,
398e16c50a1SJim Ingham                                                       result);
399340b0309SGreg Clayton 
400340b0309SGreg Clayton             }
401340b0309SGreg Clayton             else
402340b0309SGreg Clayton             {
403340b0309SGreg Clayton                 // No options were set, inherit any settings from nested "command source" commands,
404340b0309SGreg Clayton                 // or set to sane default settings...
40526c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
406340b0309SGreg Clayton                 m_interpreter.HandleCommandsFromFile (cmd_file,
407340b0309SGreg Clayton                                                       exe_ctx,
40826c7bf93SJim Ingham                                                       options,
409340b0309SGreg Clayton                                                       result);
410340b0309SGreg Clayton 
411340b0309SGreg Clayton             }
412ebc09c36SJim Ingham         }
413ebc09c36SJim Ingham         else
414ebc09c36SJim Ingham         {
415ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
416ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
417ebc09c36SJim Ingham         }
418ebc09c36SJim Ingham         return result.Succeeded();
419ebc09c36SJim Ingham 
420ebc09c36SJim Ingham     }
4215a988416SJim Ingham     CommandOptions m_options;
422ebc09c36SJim Ingham };
423ebc09c36SJim Ingham 
424e0d378b3SGreg Clayton OptionDefinition
425e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
426e16c50a1SJim Ingham {
427d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
428d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
429d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
430d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
431e16c50a1SJim Ingham };
432e16c50a1SJim Ingham 
433ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
434ebc09c36SJim Ingham //-------------------------------------------------------------------------
435ebc09c36SJim Ingham // CommandObjectCommandsAlias
436ebc09c36SJim Ingham //-------------------------------------------------------------------------
437ebc09c36SJim Ingham 
438be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
439be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
44044d93782SGreg Clayton                                                      "def my_command_impl(debugger, args, result, internal_dict):\n";
441be93a35aSEnrico Granata 
442be93a35aSEnrico Granata 
4435a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw
444ebc09c36SJim Ingham {
445be93a35aSEnrico Granata 
446be93a35aSEnrico Granata 
447ebc09c36SJim Ingham public:
448a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
4495a988416SJim Ingham         CommandObjectRaw (interpreter,
4500e5e5a79SGreg Clayton                        "command alias",
451e3d26315SCaroline Tice                        "Allow users to define their own debugger command abbreviations.",
452405fe67fSCaroline Tice                        NULL)
453ebc09c36SJim Ingham     {
454ebc09c36SJim Ingham         SetHelpLong(
455ebc09c36SJim Ingham     "'alias' allows the user to create a short-cut or abbreviation for long \n\
456ebc09c36SJim Ingham     commands, multi-word commands, and commands that take particular options. \n\
457ebc09c36SJim Ingham     Below are some simple examples of how one might use the 'alias' command: \n\
45869c12ccbSJason Molenda     \n    'command alias sc script'            // Creates the abbreviation 'sc' for the 'script' \n\
459ebc09c36SJim Ingham                                          // command. \n\
46069c12ccbSJason Molenda     'command alias bp breakpoint'        // Creates the abbreviation 'bp' for the 'breakpoint' \n\
461ebc09c36SJim Ingham                                          // command.  Since breakpoint commands are two-word \n\
462ebc09c36SJim Ingham                                          // commands, the user will still need to enter the \n\
463ebc09c36SJim Ingham                                          // second word after 'bp', e.g. 'bp enable' or \n\
464ebc09c36SJim Ingham                                          // 'bp delete'. \n\
46569c12ccbSJason Molenda     'command alias bpl breakpoint list'  // Creates the abbreviation 'bpl' for the \n\
466ebc09c36SJim Ingham                                          // two-word command 'breakpoint list'. \n\
467ebc09c36SJim Ingham     \nAn alias can include some options for the command, with the values either \n\
468ebc09c36SJim Ingham     filled in at the time the alias is created, or specified as positional \n\
469ebc09c36SJim Ingham     arguments, to be filled in when the alias is invoked.  The following example \n\
470ebc09c36SJim Ingham     shows how to create aliases with options: \n\
471ebc09c36SJim Ingham     \n\
47269c12ccbSJason Molenda     'command alias bfl breakpoint set -f %1 -l %2' \n\
473ebc09c36SJim Ingham     \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
474ebc09c36SJim Ingham     options already part of the alias.  So if the user wants to set a breakpoint \n\
475ebc09c36SJim Ingham     by file and line without explicitly having to use the -f and -l options, the \n\
476ebc09c36SJim Ingham     user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \n\
477ebc09c36SJim Ingham     for the actual arguments that will be passed when the alias command is used. \n\
478ebc09c36SJim Ingham     The number in the placeholder refers to the position/order the actual value \n\
47981ded935SJim Ingham     occupies when the alias is used.  All the occurrences of '%1' in the alias \n\
480ebc09c36SJim Ingham     will be replaced with the first argument, all the occurrences of '%2' in the \n\
481ebc09c36SJim Ingham     alias will be replaced with the second argument, and so on.  This also allows \n\
482ebc09c36SJim Ingham     actual arguments to be used multiple times within an alias (see 'process \n\
48381ded935SJim Ingham     launch' example below).  \n\
48481ded935SJim Ingham     Note: the positional arguments must substitute as whole words in the resultant\n\
48581ded935SJim Ingham     command, so you can't at present do something like:\n\
48681ded935SJim Ingham     \n\
48769c12ccbSJason Molenda     command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
48881ded935SJim Ingham     \n\
48981ded935SJim Ingham     to get the file extension \".cpp\" automatically appended.  For more complex\n\
49081ded935SJim Ingham     aliasing, use the \"command regex\" command instead.\n\
49181ded935SJim Ingham     \nSo in the 'bfl' case, the actual file value will be \n\
492ebc09c36SJim Ingham     filled in with the first argument following 'bfl' and the actual line number \n\
493ebc09c36SJim Ingham     value will be filled in with the second argument.  The user would use this \n\
494ebc09c36SJim Ingham     alias as follows: \n\
49569c12ccbSJason Molenda     \n    (lldb)  command alias bfl breakpoint set -f %1 -l %2 \n\
496ebc09c36SJim Ingham     <... some time later ...> \n\
49709799af6SCaroline Tice     (lldb)  bfl my-file.c 137 \n\
498ebc09c36SJim Ingham     \nThis would be the same as if the user had entered \n\
499ebc09c36SJim Ingham     'breakpoint set -f my-file.c -l 137'. \n\
500ebc09c36SJim Ingham     \nAnother example: \n\
50169c12ccbSJason Molenda     \n    (lldb)  command alias pltty  process launch -s -o %1 -e %1 \n\
50209799af6SCaroline Tice     (lldb)  pltty /dev/tty0 \n\
503ebc09c36SJim Ingham            // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
504ebc09c36SJim Ingham     \nIf the user always wanted to pass the same value to a particular option, the \n\
505ebc09c36SJim Ingham     alias could be defined with that value directly in the alias as a constant, \n\
506ebc09c36SJim Ingham     rather than using a positional placeholder: \n\
50769c12ccbSJason Molenda     \n    command alias bl3  breakpoint set -f %1 -l 3  // Always sets a breakpoint on line \n\
508ebc09c36SJim Ingham                                                    // 3 of whatever file is indicated. \n");
509ebc09c36SJim Ingham 
510405fe67fSCaroline Tice         CommandArgumentEntry arg1;
511405fe67fSCaroline Tice         CommandArgumentEntry arg2;
512405fe67fSCaroline Tice         CommandArgumentEntry arg3;
513405fe67fSCaroline Tice         CommandArgumentData alias_arg;
514405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
515405fe67fSCaroline Tice         CommandArgumentData options_arg;
516405fe67fSCaroline Tice 
517405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
518405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
519405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
520405fe67fSCaroline Tice 
521405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
522405fe67fSCaroline Tice         arg1.push_back (alias_arg);
523405fe67fSCaroline Tice 
524405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
525405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
526405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
527405fe67fSCaroline Tice 
528405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
529405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
530405fe67fSCaroline Tice 
531405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
532405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
533405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
534405fe67fSCaroline Tice 
535405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
536405fe67fSCaroline Tice         arg3.push_back (options_arg);
537405fe67fSCaroline Tice 
538405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
539405fe67fSCaroline Tice         m_arguments.push_back (arg1);
540405fe67fSCaroline Tice         m_arguments.push_back (arg2);
541405fe67fSCaroline Tice         m_arguments.push_back (arg3);
542ebc09c36SJim Ingham     }
543ebc09c36SJim Ingham 
544ebc09c36SJim Ingham     ~CommandObjectCommandsAlias ()
545ebc09c36SJim Ingham     {
546ebc09c36SJim Ingham     }
547ebc09c36SJim Ingham 
5485a988416SJim Ingham protected:
5495a988416SJim Ingham     virtual bool
5505a988416SJim Ingham     DoExecute (const char *raw_command_line, CommandReturnObject &result)
551844d2303SCaroline Tice     {
552844d2303SCaroline Tice         Args args (raw_command_line);
553844d2303SCaroline Tice         std::string raw_command_string (raw_command_line);
554844d2303SCaroline Tice 
555844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
556844d2303SCaroline Tice 
557844d2303SCaroline Tice         if (argc < 2)
558844d2303SCaroline Tice         {
559844d2303SCaroline Tice             result.AppendError ("'alias' requires at least two arguments");
560844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
561844d2303SCaroline Tice             return false;
562844d2303SCaroline Tice         }
563844d2303SCaroline Tice 
564844d2303SCaroline Tice         // Get the alias command.
565844d2303SCaroline Tice 
566844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
567844d2303SCaroline Tice 
568844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
569844d2303SCaroline Tice         // does the stripping itself.
570844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
571844d2303SCaroline Tice         if (pos == 0)
572844d2303SCaroline Tice         {
573844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
574844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
575844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
576844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
577844d2303SCaroline Tice         }
578844d2303SCaroline Tice         else
579844d2303SCaroline Tice         {
580844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
581844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
582844d2303SCaroline Tice             return false;
583844d2303SCaroline Tice         }
584844d2303SCaroline Tice 
585844d2303SCaroline Tice 
586844d2303SCaroline Tice         // Verify that the command is alias-able.
587844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
588844d2303SCaroline Tice         {
589844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
590844d2303SCaroline Tice                                           alias_command.c_str());
591844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
592844d2303SCaroline Tice             return false;
593844d2303SCaroline Tice         }
594844d2303SCaroline Tice 
595844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
596844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
597844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
598844d2303SCaroline Tice 
599844d2303SCaroline Tice         if (!cmd_obj)
600844d2303SCaroline Tice         {
60186edbf41SGreg Clayton             result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
602844d2303SCaroline Tice                                           "  No alias created.", raw_command_string.c_str());
603844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
604844d2303SCaroline Tice             return false;
605844d2303SCaroline Tice         }
606844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
607844d2303SCaroline Tice         {
608844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
609844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
6105a988416SJim Ingham             return HandleAliasingNormalCommand (args, result);
611844d2303SCaroline Tice         }
612844d2303SCaroline Tice         else
613844d2303SCaroline Tice         {
6145a988416SJim Ingham             return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
6155a988416SJim Ingham         }
6165a988416SJim Ingham         return result.Succeeded();
6175a988416SJim Ingham     }
6185a988416SJim Ingham 
6195a988416SJim Ingham     bool
6205a988416SJim Ingham     HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
6215a988416SJim Ingham     {
622844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
623844d2303SCaroline Tice 
624844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
625844d2303SCaroline Tice             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
626844d2303SCaroline Tice 
6275a988416SJim Ingham             CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
628844d2303SCaroline Tice 
629ca90c47eSCaroline Tice             if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
630844d2303SCaroline Tice             {
631844d2303SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
632ca90c47eSCaroline Tice                 result.SetStatus (eReturnStatusFailed);
633844d2303SCaroline Tice                 return false;
634844d2303SCaroline Tice             }
635844d2303SCaroline Tice 
636844d2303SCaroline Tice             // Create the alias
637844d2303SCaroline Tice             if (m_interpreter.AliasExists (alias_command.c_str())
638844d2303SCaroline Tice                 || m_interpreter.UserCommandExists (alias_command.c_str()))
639844d2303SCaroline Tice             {
640844d2303SCaroline Tice                 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
641844d2303SCaroline Tice                 if (temp_option_arg_sp.get())
642844d2303SCaroline Tice                 {
643844d2303SCaroline Tice                     if (option_arg_vector->size() == 0)
644844d2303SCaroline Tice                         m_interpreter.RemoveAliasOptions (alias_command.c_str());
645844d2303SCaroline Tice                 }
646844d2303SCaroline Tice                 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
647844d2303SCaroline Tice                                                 alias_command.c_str());
648844d2303SCaroline Tice             }
649844d2303SCaroline Tice 
650472362e6SCaroline Tice             if (cmd_obj_sp)
651472362e6SCaroline Tice             {
652844d2303SCaroline Tice                 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
653844d2303SCaroline Tice                 if (option_arg_vector->size() > 0)
654844d2303SCaroline Tice                     m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
655844d2303SCaroline Tice                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
656844d2303SCaroline Tice             }
657472362e6SCaroline Tice             else
658472362e6SCaroline Tice             {
659472362e6SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
660472362e6SCaroline Tice                 result.SetStatus (eReturnStatusFailed);
661472362e6SCaroline Tice             }
662844d2303SCaroline Tice             return result.Succeeded ();
663844d2303SCaroline Tice     }
664ebc09c36SJim Ingham 
665ebc09c36SJim Ingham     bool
6665a988416SJim Ingham     HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
667ebc09c36SJim Ingham     {
668867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
669ebc09c36SJim Ingham 
670ebc09c36SJim Ingham         if (argc < 2)
671ebc09c36SJim Ingham         {
672ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
673ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
674ebc09c36SJim Ingham             return false;
675ebc09c36SJim Ingham         }
676ebc09c36SJim Ingham 
677ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
678ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
679ebc09c36SJim Ingham 
680ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
681ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
682ebc09c36SJim Ingham 
683ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
684ebc09c36SJim Ingham 
685a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
686ebc09c36SJim Ingham         {
687ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
688ebc09c36SJim Ingham                                          alias_command.c_str());
689ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
690ebc09c36SJim Ingham         }
691ebc09c36SJim Ingham         else
692ebc09c36SJim Ingham         {
693a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
694ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
695ebc09c36SJim Ingham              bool use_subcommand = false;
696ebc09c36SJim Ingham              if (command_obj_sp.get())
697ebc09c36SJim Ingham              {
698ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
699c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
700ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
701ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
702ebc09c36SJim Ingham 
703844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
704ebc09c36SJim Ingham                  {
705ebc09c36SJim Ingham                      if (argc >= 3)
706ebc09c36SJim Ingham                      {
707ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
708ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
709998255bfSGreg Clayton                          subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
710ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
711ebc09c36SJim Ingham                          {
712ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
713ebc09c36SJim Ingham                              use_subcommand = true;
714ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
715844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
716ebc09c36SJim Ingham                          }
717ebc09c36SJim Ingham                          else
718ebc09c36SJim Ingham                          {
719f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
720f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
721f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
722ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
723ebc09c36SJim Ingham                              return false;
724ebc09c36SJim Ingham                          }
725ebc09c36SJim Ingham                      }
726ebc09c36SJim Ingham                  }
727ebc09c36SJim Ingham 
728ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
729ebc09c36SJim Ingham 
730ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
731ebc09c36SJim Ingham                  {
732ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
733ebc09c36SJim Ingham                     if (use_subcommand)
734ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
735ca90c47eSCaroline Tice 
736ca90c47eSCaroline Tice                     std::string args_string;
737ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
738ca90c47eSCaroline Tice 
739ca90c47eSCaroline Tice                     if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
740ebc09c36SJim Ingham                     {
741ca90c47eSCaroline Tice                         result.AppendError ("Unable to create requested alias.\n");
742ca90c47eSCaroline Tice                         result.SetStatus (eReturnStatusFailed);
743e7941795SCaroline Tice                         return false;
744867b185dSCaroline Tice                     }
745867b185dSCaroline Tice                  }
746867b185dSCaroline Tice 
747ebc09c36SJim Ingham                  // Create the alias.
748ebc09c36SJim Ingham 
749a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
750a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
751ebc09c36SJim Ingham                  {
752a7015092SGreg Clayton                      OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
753ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
754ebc09c36SJim Ingham                      {
755ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
756a7015092SGreg Clayton                              m_interpreter.RemoveAliasOptions (alias_command.c_str());
757ebc09c36SJim Ingham                      }
758ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
759ebc09c36SJim Ingham                                                      alias_command.c_str());
760ebc09c36SJim Ingham                  }
761ebc09c36SJim Ingham 
762ebc09c36SJim Ingham                  if (use_subcommand)
763a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
764ebc09c36SJim Ingham                  else
765a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
766ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
767a7015092SGreg Clayton                      m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
768ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
769ebc09c36SJim Ingham              }
770ebc09c36SJim Ingham              else
771ebc09c36SJim Ingham              {
772ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
773ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
774e7941795SCaroline Tice                  return false;
775ebc09c36SJim Ingham              }
776ebc09c36SJim Ingham         }
777ebc09c36SJim Ingham 
778ebc09c36SJim Ingham         return result.Succeeded();
779ebc09c36SJim Ingham     }
7805a988416SJim Ingham 
781ebc09c36SJim Ingham };
782ebc09c36SJim Ingham 
783ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
784ebc09c36SJim Ingham //-------------------------------------------------------------------------
785ebc09c36SJim Ingham // CommandObjectCommandsUnalias
786ebc09c36SJim Ingham //-------------------------------------------------------------------------
787ebc09c36SJim Ingham 
7885a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed
789ebc09c36SJim Ingham {
790ebc09c36SJim Ingham public:
791a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
7925a988416SJim Ingham         CommandObjectParsed (interpreter,
7930e5e5a79SGreg Clayton                        "command unalias",
79486ddae50SCaroline Tice                        "Allow the user to remove/delete a user-defined command abbreviation.",
795405fe67fSCaroline Tice                        NULL)
796ebc09c36SJim Ingham     {
797405fe67fSCaroline Tice         CommandArgumentEntry arg;
798405fe67fSCaroline Tice         CommandArgumentData alias_arg;
799405fe67fSCaroline Tice 
800405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
801405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
802405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
803405fe67fSCaroline Tice 
804405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
805405fe67fSCaroline Tice         arg.push_back (alias_arg);
806405fe67fSCaroline Tice 
807405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
808405fe67fSCaroline Tice         m_arguments.push_back (arg);
809ebc09c36SJim Ingham     }
810ebc09c36SJim Ingham 
811ebc09c36SJim Ingham     ~CommandObjectCommandsUnalias()
812ebc09c36SJim Ingham     {
813ebc09c36SJim Ingham     }
814ebc09c36SJim Ingham 
8155a988416SJim Ingham protected:
816ebc09c36SJim Ingham     bool
8175a988416SJim Ingham     DoExecute (Args& args, CommandReturnObject &result)
818ebc09c36SJim Ingham     {
819ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
820ebc09c36SJim Ingham         CommandObject *cmd_obj;
821ebc09c36SJim Ingham 
822ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
823ebc09c36SJim Ingham         {
824ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
825a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
826ebc09c36SJim Ingham             if (cmd_obj)
827ebc09c36SJim Ingham             {
828a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
829ebc09c36SJim Ingham                 {
830b547278cSGreg Clayton                     if (cmd_obj->IsRemovable())
831b547278cSGreg Clayton                     {
832b547278cSGreg Clayton                         result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
833b547278cSGreg Clayton                                                       command_name);
834b547278cSGreg Clayton                     }
835b547278cSGreg Clayton                     else
836b547278cSGreg Clayton                     {
837ebc09c36SJim Ingham                         result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
838ebc09c36SJim Ingham                                                       command_name);
839b547278cSGreg Clayton                     }
840ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
841ebc09c36SJim Ingham                 }
842ebc09c36SJim Ingham                 else
843ebc09c36SJim Ingham                 {
844ebc09c36SJim Ingham 
845a7015092SGreg Clayton                     if (m_interpreter.RemoveAlias (command_name) == false)
846ebc09c36SJim Ingham                     {
847a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
848ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
849ebc09c36SJim Ingham                                                           command_name);
850ebc09c36SJim Ingham                         else
851ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
852ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
853ebc09c36SJim Ingham                     }
854ebc09c36SJim Ingham                     else
855ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
856ebc09c36SJim Ingham                 }
857ebc09c36SJim Ingham             }
858ebc09c36SJim Ingham             else
859ebc09c36SJim Ingham             {
860ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
861ebc09c36SJim Ingham                                               "current list of commands.\n",
862ebc09c36SJim Ingham                                              command_name);
863ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
864ebc09c36SJim Ingham             }
865ebc09c36SJim Ingham         }
866ebc09c36SJim Ingham         else
867ebc09c36SJim Ingham         {
868ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
869ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
870ebc09c36SJim Ingham         }
871ebc09c36SJim Ingham 
872ebc09c36SJim Ingham         return result.Succeeded();
873ebc09c36SJim Ingham     }
874ebc09c36SJim Ingham };
875ebc09c36SJim Ingham 
876b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete
877b547278cSGreg Clayton //-------------------------------------------------------------------------
878b547278cSGreg Clayton // CommandObjectCommandsDelete
879b547278cSGreg Clayton //-------------------------------------------------------------------------
880b547278cSGreg Clayton 
881b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed
882b547278cSGreg Clayton {
883b547278cSGreg Clayton public:
884b547278cSGreg Clayton     CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
885b547278cSGreg Clayton     CommandObjectParsed (interpreter,
886b547278cSGreg Clayton                          "command delete",
887b547278cSGreg Clayton                          "Allow the user to delete user-defined regular expression, python or multi-word commands.",
888b547278cSGreg Clayton                          NULL)
889b547278cSGreg Clayton     {
890b547278cSGreg Clayton         CommandArgumentEntry arg;
891b547278cSGreg Clayton         CommandArgumentData alias_arg;
892b547278cSGreg Clayton 
893b547278cSGreg Clayton         // Define the first (and only) variant of this arg.
894b547278cSGreg Clayton         alias_arg.arg_type = eArgTypeCommandName;
895b547278cSGreg Clayton         alias_arg.arg_repetition = eArgRepeatPlain;
896b547278cSGreg Clayton 
897b547278cSGreg Clayton         // There is only one variant this argument could be; put it into the argument entry.
898b547278cSGreg Clayton         arg.push_back (alias_arg);
899b547278cSGreg Clayton 
900b547278cSGreg Clayton         // Push the data for the first argument into the m_arguments vector.
901b547278cSGreg Clayton         m_arguments.push_back (arg);
902b547278cSGreg Clayton     }
903b547278cSGreg Clayton 
904b547278cSGreg Clayton     ~CommandObjectCommandsDelete()
905b547278cSGreg Clayton     {
906b547278cSGreg Clayton     }
907b547278cSGreg Clayton 
908b547278cSGreg Clayton protected:
909b547278cSGreg Clayton     bool
910b547278cSGreg Clayton     DoExecute (Args& args, CommandReturnObject &result)
911b547278cSGreg Clayton     {
912b547278cSGreg Clayton         CommandObject::CommandMap::iterator pos;
913b547278cSGreg Clayton 
914b547278cSGreg Clayton         if (args.GetArgumentCount() != 0)
915b547278cSGreg Clayton         {
916b547278cSGreg Clayton             const char *command_name = args.GetArgumentAtIndex(0);
917b547278cSGreg Clayton             if (m_interpreter.CommandExists (command_name))
918b547278cSGreg Clayton             {
919b547278cSGreg Clayton                 if (m_interpreter.RemoveCommand (command_name))
920b547278cSGreg Clayton                 {
921b547278cSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
922b547278cSGreg Clayton                 }
923b547278cSGreg Clayton                 else
924b547278cSGreg Clayton                 {
925b547278cSGreg Clayton                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
926b547278cSGreg Clayton                                                   command_name);
927b547278cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
928b547278cSGreg Clayton                 }
929b547278cSGreg Clayton             }
930b547278cSGreg Clayton             else
931b547278cSGreg Clayton             {
932b547278cSGreg Clayton                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
933b547278cSGreg Clayton                                               command_name);
934b547278cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
935b547278cSGreg Clayton             }
936b547278cSGreg Clayton         }
937b547278cSGreg Clayton         else
938b547278cSGreg Clayton         {
939b547278cSGreg Clayton             result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
940b547278cSGreg Clayton             result.SetStatus (eReturnStatusFailed);
941b547278cSGreg Clayton         }
942b547278cSGreg Clayton 
943b547278cSGreg Clayton         return result.Succeeded();
944b547278cSGreg Clayton     }
945b547278cSGreg Clayton };
946b547278cSGreg Clayton 
947de164aaaSGreg Clayton //-------------------------------------------------------------------------
948de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
949de164aaaSGreg Clayton //-------------------------------------------------------------------------
9505a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex
951de164aaaSGreg Clayton 
95244d93782SGreg Clayton class CommandObjectCommandsAddRegex :
95344d93782SGreg Clayton     public CommandObjectParsed,
954ea508635SGreg Clayton     public IOHandlerDelegateMultiline
955de164aaaSGreg Clayton {
956de164aaaSGreg Clayton public:
957de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
9585a988416SJim Ingham         CommandObjectParsed (interpreter,
9590e5e5a79SGreg Clayton                        "command regex",
960de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
9610e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
962ea508635SGreg Clayton         IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
963de164aaaSGreg Clayton         m_options (interpreter)
964de164aaaSGreg Clayton     {
9650e5e5a79SGreg Clayton         SetHelpLong(
9660e5e5a79SGreg Clayton "This command allows the user to create powerful regular expression commands\n"
9670e5e5a79SGreg Clayton "with substitutions. The regular expressions and substitutions are specified\n"
968d93c4a33SBruce Mitchener "using the regular expression substitution format of:\n"
9690e5e5a79SGreg Clayton "\n"
9700e5e5a79SGreg Clayton "    s/<regex>/<subst>/\n"
9710e5e5a79SGreg Clayton "\n"
9720e5e5a79SGreg Clayton "<regex> is a regular expression that can use parenthesis to capture regular\n"
9730e5e5a79SGreg Clayton "expression input and substitute the captured matches in the output using %1\n"
9740e5e5a79SGreg Clayton "for the first match, %2 for the second, and so on.\n"
9750e5e5a79SGreg Clayton "\n"
9760e5e5a79SGreg Clayton "The regular expressions can all be specified on the command line if more than\n"
9770e5e5a79SGreg Clayton "one argument is provided. If just the command name is provided on the command\n"
9780e5e5a79SGreg Clayton "line, then the regular expressions and substitutions can be entered on separate\n"
9790e5e5a79SGreg Clayton " lines, followed by an empty line to terminate the command definition.\n"
9800e5e5a79SGreg Clayton "\n"
9810e5e5a79SGreg Clayton "EXAMPLES\n"
9820e5e5a79SGreg Clayton "\n"
983adc43c99SSean Callanan "The following example will define a regular expression command named 'f' that\n"
9840e5e5a79SGreg Clayton "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
9850e5e5a79SGreg Clayton "a number follows 'f':\n"
986adc43c99SSean Callanan "\n"
9870e5e5a79SGreg Clayton "    (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
988adc43c99SSean Callanan "\n"
9890e5e5a79SGreg Clayton                     );
990de164aaaSGreg Clayton     }
991de164aaaSGreg Clayton 
992de164aaaSGreg Clayton     ~CommandObjectCommandsAddRegex()
993de164aaaSGreg Clayton     {
994de164aaaSGreg Clayton     }
995de164aaaSGreg Clayton 
996de164aaaSGreg Clayton 
9975a988416SJim Ingham protected:
99844d93782SGreg Clayton 
999ea508635SGreg Clayton     void
1000ea508635SGreg Clayton     IOHandlerActivated (IOHandler &io_handler) override
100144d93782SGreg Clayton     {
100244d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
100344d93782SGreg Clayton         if (output_sp)
100444d93782SGreg Clayton         {
100544d93782SGreg 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");
100644d93782SGreg Clayton             output_sp->Flush();
100744d93782SGreg Clayton         }
100844d93782SGreg Clayton     }
100944d93782SGreg Clayton 
1010ea508635SGreg Clayton     void
1011ea508635SGreg Clayton     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
101244d93782SGreg Clayton     {
101344d93782SGreg Clayton         io_handler.SetIsDone(true);
101444d93782SGreg Clayton         if (m_regex_cmd_ap.get())
101544d93782SGreg Clayton         {
101644d93782SGreg Clayton             StringList lines;
101744d93782SGreg Clayton             if (lines.SplitIntoLines (data))
101844d93782SGreg Clayton             {
101944d93782SGreg Clayton                 const size_t num_lines = lines.GetSize();
102044d93782SGreg Clayton                 bool check_only = false;
102144d93782SGreg Clayton                 for (size_t i=0; i<num_lines; ++i)
102244d93782SGreg Clayton                 {
102344d93782SGreg Clayton                     llvm::StringRef bytes_strref (lines[i]);
102444d93782SGreg Clayton                     Error error = AppendRegexSubstitution (bytes_strref, check_only);
102544d93782SGreg Clayton                     if (error.Fail())
102644d93782SGreg Clayton                     {
102744d93782SGreg Clayton                         if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
102844d93782SGreg Clayton                         {
102944d93782SGreg Clayton                             StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
103044d93782SGreg Clayton                             out_stream->Printf("error: %s\n", error.AsCString());
103144d93782SGreg Clayton                         }
103244d93782SGreg Clayton                     }
103344d93782SGreg Clayton                 }
103444d93782SGreg Clayton             }
103544d93782SGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
103644d93782SGreg Clayton             {
103744d93782SGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
103844d93782SGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
103944d93782SGreg Clayton             }
104044d93782SGreg Clayton         }
104144d93782SGreg Clayton     }
104244d93782SGreg Clayton 
1043de164aaaSGreg Clayton     bool
1044b0a1814fSEric Christopher     DoExecute (Args& command, CommandReturnObject &result) override
1045de164aaaSGreg Clayton     {
10465a988416SJim Ingham         const size_t argc = command.GetArgumentCount();
10470e5e5a79SGreg Clayton         if (argc == 0)
1048de164aaaSGreg Clayton         {
104969c12ccbSJason Molenda             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
10500e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
10510e5e5a79SGreg Clayton         }
10520e5e5a79SGreg Clayton         else
10530e5e5a79SGreg Clayton         {
10540e5e5a79SGreg Clayton             Error error;
10555a988416SJim Ingham             const char *name = command.GetArgumentAtIndex(0);
1056de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1057de164aaaSGreg Clayton                                                                  name,
1058de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
1059de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
1060b547278cSGreg Clayton                                                                  10,
1061b547278cSGreg Clayton                                                                  0,
1062b547278cSGreg Clayton                                                                  true));
10630e5e5a79SGreg Clayton 
10640e5e5a79SGreg Clayton             if (argc == 1)
10650e5e5a79SGreg Clayton             {
106644d93782SGreg Clayton                 Debugger &debugger = m_interpreter.GetDebugger();
1067e30f11d9SKate Stone                 bool color_prompt = debugger.GetUseColor();
106844d93782SGreg Clayton                 const bool multiple_lines = true; // Get multiple lines
106944d93782SGreg Clayton                 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
1070e30f11d9SKate Stone                                                                   IOHandler::Type::Other,
107173d80faaSGreg Clayton                                                                   "lldb-regex", // Name of input reader for history
1072ea508635SGreg Clayton                                                                   "> ",         // Prompt
1073e30f11d9SKate Stone                                                                   NULL,         // Continuation prompt
107444d93782SGreg Clayton                                                                   multiple_lines,
1075e30f11d9SKate Stone                                                                   color_prompt,
1076f6913cd7SGreg Clayton                                                                   0,            // Don't show line numbers
107744d93782SGreg Clayton                                                                   *this));
107844d93782SGreg Clayton 
107944d93782SGreg Clayton                 if (io_handler_sp)
1080de164aaaSGreg Clayton                 {
108144d93782SGreg Clayton                     debugger.PushIOHandler(io_handler_sp);
1082de164aaaSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1083de164aaaSGreg Clayton                 }
1084de164aaaSGreg Clayton             }
1085de164aaaSGreg Clayton             else
1086de164aaaSGreg Clayton             {
10870e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
10880e5e5a79SGreg Clayton                 {
10895a988416SJim Ingham                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
109044d93782SGreg Clayton                     bool check_only = false;
109144d93782SGreg Clayton                     error = AppendRegexSubstitution (arg_strref, check_only);
10920e5e5a79SGreg Clayton                     if (error.Fail())
10930e5e5a79SGreg Clayton                         break;
10940e5e5a79SGreg Clayton                 }
10950e5e5a79SGreg Clayton 
10960e5e5a79SGreg Clayton                 if (error.Success())
10970e5e5a79SGreg Clayton                 {
10980e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
10990e5e5a79SGreg Clayton                 }
11000e5e5a79SGreg Clayton             }
11010e5e5a79SGreg Clayton             if (error.Fail())
11020e5e5a79SGreg Clayton             {
11030e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
1104de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1105de164aaaSGreg Clayton             }
11060e5e5a79SGreg Clayton         }
11070e5e5a79SGreg Clayton 
1108de164aaaSGreg Clayton         return result.Succeeded();
1109de164aaaSGreg Clayton     }
1110de164aaaSGreg Clayton 
11110e5e5a79SGreg Clayton     Error
111244d93782SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
1113de164aaaSGreg Clayton     {
11140e5e5a79SGreg Clayton         Error error;
11150e5e5a79SGreg Clayton 
11160e5e5a79SGreg Clayton         if (m_regex_cmd_ap.get() == NULL)
1117de164aaaSGreg Clayton         {
11180e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
11190e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
11200e5e5a79SGreg Clayton                                            regex_sed.data());
11210e5e5a79SGreg Clayton             return error;
1122de164aaaSGreg Clayton         }
11230e5e5a79SGreg Clayton 
11240e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
11250e5e5a79SGreg Clayton 
11260e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
11270e5e5a79SGreg Clayton         {
11280e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
11290e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
11300e5e5a79SGreg Clayton                                            regex_sed.data());
11310e5e5a79SGreg Clayton             return error;
11320e5e5a79SGreg Clayton         }
11330e5e5a79SGreg Clayton 
11340e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
11350e5e5a79SGreg Clayton         {
11360e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
11370e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
11380e5e5a79SGreg Clayton                                            regex_sed.data());
11390e5e5a79SGreg Clayton             return error;
11400e5e5a79SGreg Clayton         }
11410e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
11420e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
11430e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
11440e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
11450e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
11460e5e5a79SGreg Clayton 
11470e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
11480e5e5a79SGreg Clayton         {
1149ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
11500e5e5a79SGreg Clayton                                            separator_char,
11510e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
1152ea508635SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1),
1153ea508635SGreg Clayton                                            (int)regex_sed.size(),
1154ea508635SGreg Clayton                                            regex_sed.data());
11550e5e5a79SGreg Clayton             return error;
11560e5e5a79SGreg Clayton         }
11570e5e5a79SGreg Clayton 
11580e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
11590e5e5a79SGreg Clayton 
11600e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
11610e5e5a79SGreg Clayton         {
1162ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
11630e5e5a79SGreg Clayton                                            separator_char,
11640e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
1165ea508635SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1),
1166ea508635SGreg Clayton                                            (int)regex_sed.size(),
1167ea508635SGreg Clayton                                            regex_sed.data());
11680e5e5a79SGreg Clayton             return error;
11690e5e5a79SGreg Clayton         }
11700e5e5a79SGreg Clayton 
11710e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
11720e5e5a79SGreg Clayton         {
11730e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
11740e5e5a79SGreg Clayton             // separator char
11750e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
11760e5e5a79SGreg Clayton             {
11770e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
11780e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
11790e5e5a79SGreg Clayton                                                regex_sed.data(),
11800e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
11810e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
11820e5e5a79SGreg Clayton                 return error;
11830e5e5a79SGreg Clayton             }
11840e5e5a79SGreg Clayton 
11850e5e5a79SGreg Clayton         }
11860e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
11870e5e5a79SGreg Clayton         {
11880e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
11890e5e5a79SGreg Clayton                                            separator_char,
11900e5e5a79SGreg Clayton                                            separator_char,
11910e5e5a79SGreg Clayton                                            separator_char,
11920e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
11930e5e5a79SGreg Clayton                                            regex_sed.data());
11940e5e5a79SGreg Clayton             return error;
11950e5e5a79SGreg Clayton         }
11960e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
11970e5e5a79SGreg Clayton         {
11980e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
11990e5e5a79SGreg Clayton                                            separator_char,
12000e5e5a79SGreg Clayton                                            separator_char,
12010e5e5a79SGreg Clayton                                            separator_char,
12020e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12030e5e5a79SGreg Clayton                                            regex_sed.data());
12040e5e5a79SGreg Clayton             return error;
12050e5e5a79SGreg Clayton         }
120644d93782SGreg Clayton 
120744d93782SGreg Clayton         if (check_only == false)
120844d93782SGreg Clayton         {
12090e5e5a79SGreg Clayton             std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
12100e5e5a79SGreg Clayton             std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
12110e5e5a79SGreg Clayton             m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
12120e5e5a79SGreg Clayton                                              subst.c_str());
121344d93782SGreg Clayton         }
12140e5e5a79SGreg Clayton         return error;
1215de164aaaSGreg Clayton     }
1216de164aaaSGreg Clayton 
1217de164aaaSGreg Clayton     void
12180e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
1219de164aaaSGreg Clayton     {
1220de164aaaSGreg Clayton         if (m_regex_cmd_ap.get())
1221de164aaaSGreg Clayton         {
1222de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
1223de164aaaSGreg Clayton             {
1224de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1225de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1226de164aaaSGreg Clayton             }
1227de164aaaSGreg Clayton         }
1228de164aaaSGreg Clayton     }
1229de164aaaSGreg Clayton 
1230de164aaaSGreg Clayton private:
12317b0992d9SGreg Clayton     std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1232de164aaaSGreg Clayton 
1233de164aaaSGreg Clayton      class CommandOptions : public Options
1234de164aaaSGreg Clayton      {
1235de164aaaSGreg Clayton      public:
1236de164aaaSGreg Clayton 
1237de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
1238de164aaaSGreg Clayton             Options (interpreter)
1239de164aaaSGreg Clayton          {
1240de164aaaSGreg Clayton          }
1241de164aaaSGreg Clayton 
1242de164aaaSGreg Clayton          virtual
1243de164aaaSGreg Clayton          ~CommandOptions (){}
1244de164aaaSGreg Clayton 
1245de164aaaSGreg Clayton          virtual Error
1246de164aaaSGreg Clayton          SetOptionValue (uint32_t option_idx, const char *option_arg)
1247de164aaaSGreg Clayton          {
1248de164aaaSGreg Clayton              Error error;
12493bcdfc0eSGreg Clayton              const int short_option = m_getopt_table[option_idx].val;
1250de164aaaSGreg Clayton 
1251de164aaaSGreg Clayton              switch (short_option)
1252de164aaaSGreg Clayton              {
1253de164aaaSGreg Clayton                  case 'h':
1254de164aaaSGreg Clayton                      m_help.assign (option_arg);
1255de164aaaSGreg Clayton                      break;
1256de164aaaSGreg Clayton                  case 's':
1257de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1258de164aaaSGreg Clayton                      break;
1259de164aaaSGreg Clayton 
1260de164aaaSGreg Clayton                  default:
126186edbf41SGreg Clayton                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1262de164aaaSGreg Clayton                      break;
1263de164aaaSGreg Clayton              }
1264de164aaaSGreg Clayton 
1265de164aaaSGreg Clayton              return error;
1266de164aaaSGreg Clayton          }
1267de164aaaSGreg Clayton 
1268de164aaaSGreg Clayton          void
1269de164aaaSGreg Clayton          OptionParsingStarting ()
1270de164aaaSGreg Clayton          {
1271de164aaaSGreg Clayton              m_help.clear();
1272de164aaaSGreg Clayton              m_syntax.clear();
1273de164aaaSGreg Clayton          }
1274de164aaaSGreg Clayton 
1275de164aaaSGreg Clayton          const OptionDefinition*
1276de164aaaSGreg Clayton          GetDefinitions ()
1277de164aaaSGreg Clayton          {
1278de164aaaSGreg Clayton              return g_option_table;
1279de164aaaSGreg Clayton          }
1280de164aaaSGreg Clayton 
1281de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1282de164aaaSGreg Clayton 
1283de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1284de164aaaSGreg Clayton 
1285de164aaaSGreg Clayton          const char *
1286de164aaaSGreg Clayton          GetHelp ()
1287de164aaaSGreg Clayton          {
1288de164aaaSGreg Clayton              if (m_help.empty())
1289de164aaaSGreg Clayton                  return NULL;
1290de164aaaSGreg Clayton              return m_help.c_str();
1291de164aaaSGreg Clayton          }
1292de164aaaSGreg Clayton          const char *
1293de164aaaSGreg Clayton          GetSyntax ()
1294de164aaaSGreg Clayton          {
1295de164aaaSGreg Clayton              if (m_syntax.empty())
1296de164aaaSGreg Clayton                  return NULL;
1297de164aaaSGreg Clayton              return m_syntax.c_str();
1298de164aaaSGreg Clayton          }
1299de164aaaSGreg Clayton          // Instance variables to hold the values for command options.
1300de164aaaSGreg Clayton      protected:
1301de164aaaSGreg Clayton          std::string m_help;
1302de164aaaSGreg Clayton          std::string m_syntax;
1303de164aaaSGreg Clayton      };
1304de164aaaSGreg Clayton 
1305b0a1814fSEric Christopher      Options *
1306b0a1814fSEric Christopher      GetOptions () override
1307de164aaaSGreg Clayton      {
1308de164aaaSGreg Clayton          return &m_options;
1309de164aaaSGreg Clayton      }
1310de164aaaSGreg Clayton 
13115a988416SJim Ingham      CommandOptions m_options;
1312de164aaaSGreg Clayton };
1313de164aaaSGreg Clayton 
1314de164aaaSGreg Clayton OptionDefinition
1315de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1316de164aaaSGreg Clayton {
1317d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1318d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1319d37221dcSZachary Turner { 0             , false,  NULL   , 0  , 0                , NULL, NULL, 0, eArgTypeNone, NULL }
1320de164aaaSGreg Clayton };
1321de164aaaSGreg Clayton 
1322de164aaaSGreg Clayton 
13235a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw
1324223383edSEnrico Granata {
1325223383edSEnrico Granata private:
1326223383edSEnrico Granata     std::string m_function_name;
13270a305db7SEnrico Granata     ScriptedCommandSynchronicity m_synchro;
1328fac939e9SEnrico Granata     bool m_fetched_help_long;
1329223383edSEnrico Granata 
1330223383edSEnrico Granata public:
1331223383edSEnrico Granata 
1332223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1333223383edSEnrico Granata                                  std::string name,
13340a305db7SEnrico Granata                                  std::string funct,
1335735152e3SEnrico Granata                                  std::string help,
13360a305db7SEnrico Granata                                  ScriptedCommandSynchronicity synch) :
13375a988416SJim Ingham         CommandObjectRaw (interpreter,
1338223383edSEnrico Granata                           name.c_str(),
1339735152e3SEnrico Granata                           NULL,
1340223383edSEnrico Granata                           NULL),
13410a305db7SEnrico Granata         m_function_name(funct),
1342fac939e9SEnrico Granata         m_synchro(synch),
1343fac939e9SEnrico Granata         m_fetched_help_long(false)
1344223383edSEnrico Granata     {
1345735152e3SEnrico Granata         if (!help.empty())
1346735152e3SEnrico Granata             SetHelp(help.c_str());
1347735152e3SEnrico Granata         else
1348735152e3SEnrico Granata         {
1349735152e3SEnrico Granata             StreamString stream;
1350735152e3SEnrico Granata             stream.Printf("For more information run 'help %s'",name.c_str());
1351735152e3SEnrico Granata             SetHelp(stream.GetData());
1352735152e3SEnrico Granata         }
1353223383edSEnrico Granata     }
1354223383edSEnrico Granata 
1355223383edSEnrico Granata     virtual
1356223383edSEnrico Granata     ~CommandObjectPythonFunction ()
1357223383edSEnrico Granata     {
1358223383edSEnrico Granata     }
1359223383edSEnrico Granata 
1360223383edSEnrico Granata     virtual bool
13613a18e319SGreg Clayton     IsRemovable () const
13625a988416SJim Ingham     {
13635a988416SJim Ingham         return true;
13645a988416SJim Ingham     }
13655a988416SJim Ingham 
13665a988416SJim Ingham     const std::string&
13675a988416SJim Ingham     GetFunctionName ()
13685a988416SJim Ingham     {
13695a988416SJim Ingham         return m_function_name;
13705a988416SJim Ingham     }
13715a988416SJim Ingham 
13725a988416SJim Ingham     ScriptedCommandSynchronicity
13735a988416SJim Ingham     GetSynchronicity ()
13745a988416SJim Ingham     {
13755a988416SJim Ingham         return m_synchro;
13765a988416SJim Ingham     }
13775a988416SJim Ingham 
1378fac939e9SEnrico Granata     virtual const char *
1379fac939e9SEnrico Granata     GetHelpLong ()
1380fac939e9SEnrico Granata     {
1381fac939e9SEnrico Granata         if (!m_fetched_help_long)
1382fac939e9SEnrico Granata         {
1383fac939e9SEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1384fac939e9SEnrico Granata             if (scripter)
1385fac939e9SEnrico Granata             {
1386fac939e9SEnrico Granata                 std::string docstring;
1387fac939e9SEnrico Granata                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1388fac939e9SEnrico Granata                 if (!docstring.empty())
1389fac939e9SEnrico Granata                     SetHelpLong(docstring);
1390fac939e9SEnrico Granata             }
1391fac939e9SEnrico Granata         }
1392fac939e9SEnrico Granata         return CommandObjectRaw::GetHelpLong();
1393fac939e9SEnrico Granata     }
1394fac939e9SEnrico Granata 
13955a988416SJim Ingham protected:
13965a988416SJim Ingham     virtual bool
13975a988416SJim Ingham     DoExecute (const char *raw_command_line, CommandReturnObject &result)
1398223383edSEnrico Granata     {
1399223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1400223383edSEnrico Granata 
1401223383edSEnrico Granata         Error error;
1402223383edSEnrico Granata 
140370f11f88SJim Ingham         result.SetStatus(eReturnStatusInvalid);
140470f11f88SJim Ingham 
1405223383edSEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1406223383edSEnrico Granata                                                          raw_command_line,
14070a305db7SEnrico Granata                                                          m_synchro,
1408223383edSEnrico Granata                                                          result,
140906be059aSEnrico Granata                                                          error,
141006be059aSEnrico Granata                                                          m_exe_ctx) == false)
1411223383edSEnrico Granata         {
1412223383edSEnrico Granata             result.AppendError(error.AsCString());
1413223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1414223383edSEnrico Granata         }
1415223383edSEnrico Granata         else
141670f11f88SJim Ingham         {
141770f11f88SJim Ingham             // Don't change the status if the command already set it...
141870f11f88SJim Ingham             if (result.GetStatus() == eReturnStatusInvalid)
141970f11f88SJim Ingham             {
14209a71a7d8SDaniel Malea                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1421223383edSEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
142270f11f88SJim Ingham                 else
142370f11f88SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishResult);
142470f11f88SJim Ingham             }
142570f11f88SJim Ingham         }
1426223383edSEnrico Granata 
1427223383edSEnrico Granata         return result.Succeeded();
1428223383edSEnrico Granata     }
1429223383edSEnrico Granata 
1430223383edSEnrico Granata };
1431223383edSEnrico Granata 
14329fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw
14339fe00e52SEnrico Granata {
14349fe00e52SEnrico Granata private:
14350641ca1aSZachary Turner     StructuredData::GenericSP m_cmd_obj_sp;
14369fe00e52SEnrico Granata     ScriptedCommandSynchronicity m_synchro;
14376f79bb2dSEnrico Granata     bool m_fetched_help_short:1;
14386f79bb2dSEnrico Granata     bool m_fetched_help_long:1;
14399fe00e52SEnrico Granata 
14409fe00e52SEnrico Granata public:
14419fe00e52SEnrico Granata 
14429fe00e52SEnrico Granata     CommandObjectScriptingObject (CommandInterpreter &interpreter,
14439fe00e52SEnrico Granata                                   std::string name,
14440641ca1aSZachary Turner                                   StructuredData::GenericSP cmd_obj_sp,
14459fe00e52SEnrico Granata                                   ScriptedCommandSynchronicity synch) :
14469fe00e52SEnrico Granata     CommandObjectRaw (interpreter,
14479fe00e52SEnrico Granata                       name.c_str(),
14489fe00e52SEnrico Granata                       NULL,
14499fe00e52SEnrico Granata                       NULL),
14509fe00e52SEnrico Granata     m_cmd_obj_sp(cmd_obj_sp),
14516f79bb2dSEnrico Granata     m_synchro(synch),
14526f79bb2dSEnrico Granata     m_fetched_help_short(false),
14536f79bb2dSEnrico Granata     m_fetched_help_long(false)
14549fe00e52SEnrico Granata     {
14559fe00e52SEnrico Granata         StreamString stream;
14569fe00e52SEnrico Granata         stream.Printf("For more information run 'help %s'",name.c_str());
14579fe00e52SEnrico Granata         SetHelp(stream.GetData());
1458*e87764f2SEnrico Granata         if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1459*e87764f2SEnrico Granata             GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
14609fe00e52SEnrico Granata     }
14619fe00e52SEnrico Granata 
14629fe00e52SEnrico Granata     virtual
14639fe00e52SEnrico Granata     ~CommandObjectScriptingObject ()
14649fe00e52SEnrico Granata     {
14659fe00e52SEnrico Granata     }
14669fe00e52SEnrico Granata 
14679fe00e52SEnrico Granata     virtual bool
14689fe00e52SEnrico Granata     IsRemovable () const
14699fe00e52SEnrico Granata     {
14709fe00e52SEnrico Granata         return true;
14719fe00e52SEnrico Granata     }
14729fe00e52SEnrico Granata 
14730641ca1aSZachary Turner     StructuredData::GenericSP
14749fe00e52SEnrico Granata     GetImplementingObject ()
14759fe00e52SEnrico Granata     {
14769fe00e52SEnrico Granata         return m_cmd_obj_sp;
14779fe00e52SEnrico Granata     }
14789fe00e52SEnrico Granata 
14799fe00e52SEnrico Granata     ScriptedCommandSynchronicity
14809fe00e52SEnrico Granata     GetSynchronicity ()
14819fe00e52SEnrico Granata     {
14829fe00e52SEnrico Granata         return m_synchro;
14839fe00e52SEnrico Granata     }
14849fe00e52SEnrico Granata 
14859fe00e52SEnrico Granata     virtual const char *
14866f79bb2dSEnrico Granata     GetHelp ()
14876f79bb2dSEnrico Granata     {
14886f79bb2dSEnrico Granata         if (!m_fetched_help_short)
14896f79bb2dSEnrico Granata         {
14906f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
14916f79bb2dSEnrico Granata             if (scripter)
14926f79bb2dSEnrico Granata             {
14936f79bb2dSEnrico Granata                 std::string docstring;
14946f79bb2dSEnrico Granata                 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
14956f79bb2dSEnrico Granata                 if (!docstring.empty())
14966f79bb2dSEnrico Granata                     SetHelp(docstring);
14976f79bb2dSEnrico Granata             }
14986f79bb2dSEnrico Granata         }
14996f79bb2dSEnrico Granata         return CommandObjectRaw::GetHelp();
15006f79bb2dSEnrico Granata     }
15016f79bb2dSEnrico Granata 
15026f79bb2dSEnrico Granata     virtual const char *
15039fe00e52SEnrico Granata     GetHelpLong ()
15049fe00e52SEnrico Granata     {
15056f79bb2dSEnrico Granata         if (!m_fetched_help_long)
15066f79bb2dSEnrico Granata         {
15076f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
15086f79bb2dSEnrico Granata             if (scripter)
15096f79bb2dSEnrico Granata             {
15106f79bb2dSEnrico Granata                 std::string docstring;
15116f79bb2dSEnrico Granata                 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
15126f79bb2dSEnrico Granata                 if (!docstring.empty())
15136f79bb2dSEnrico Granata                     SetHelpLong(docstring);
15146f79bb2dSEnrico Granata             }
15156f79bb2dSEnrico Granata         }
15169fe00e52SEnrico Granata         return CommandObjectRaw::GetHelpLong();
15179fe00e52SEnrico Granata     }
15189fe00e52SEnrico Granata 
15199fe00e52SEnrico Granata protected:
15209fe00e52SEnrico Granata     virtual bool
15219fe00e52SEnrico Granata     DoExecute (const char *raw_command_line, CommandReturnObject &result)
15229fe00e52SEnrico Granata     {
15239fe00e52SEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
15249fe00e52SEnrico Granata 
15259fe00e52SEnrico Granata         Error error;
15269fe00e52SEnrico Granata 
15279fe00e52SEnrico Granata         result.SetStatus(eReturnStatusInvalid);
15289fe00e52SEnrico Granata 
15299fe00e52SEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp,
15309fe00e52SEnrico Granata                                                          raw_command_line,
15319fe00e52SEnrico Granata                                                          m_synchro,
15329fe00e52SEnrico Granata                                                          result,
15339fe00e52SEnrico Granata                                                          error,
15349fe00e52SEnrico Granata                                                          m_exe_ctx) == false)
15359fe00e52SEnrico Granata         {
15369fe00e52SEnrico Granata             result.AppendError(error.AsCString());
15379fe00e52SEnrico Granata             result.SetStatus(eReturnStatusFailed);
15389fe00e52SEnrico Granata         }
15399fe00e52SEnrico Granata         else
15409fe00e52SEnrico Granata         {
15419fe00e52SEnrico Granata             // Don't change the status if the command already set it...
15429fe00e52SEnrico Granata             if (result.GetStatus() == eReturnStatusInvalid)
15439fe00e52SEnrico Granata             {
15449fe00e52SEnrico Granata                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
15459fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
15469fe00e52SEnrico Granata                 else
15479fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishResult);
15489fe00e52SEnrico Granata             }
15499fe00e52SEnrico Granata         }
15509fe00e52SEnrico Granata 
15519fe00e52SEnrico Granata         return result.Succeeded();
15529fe00e52SEnrico Granata     }
15539fe00e52SEnrico Granata 
15549fe00e52SEnrico Granata };
15559fe00e52SEnrico Granata 
1556a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1557a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport
1558a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1559a9dbf432SEnrico Granata 
15605a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed
1561a9dbf432SEnrico Granata {
15625a988416SJim Ingham public:
15635a988416SJim Ingham     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
15645a988416SJim Ingham         CommandObjectParsed (interpreter,
15655a988416SJim Ingham                              "command script import",
15665a988416SJim Ingham                              "Import a scripting module in LLDB.",
15675a988416SJim Ingham                              NULL),
15685a988416SJim Ingham         m_options(interpreter)
15695a988416SJim Ingham     {
15705a988416SJim Ingham         CommandArgumentEntry arg1;
15715a988416SJim Ingham         CommandArgumentData cmd_arg;
15725a988416SJim Ingham 
15735a988416SJim Ingham         // Define the first (and only) variant of this arg.
15745a988416SJim Ingham         cmd_arg.arg_type = eArgTypeFilename;
15755a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
15765a988416SJim Ingham 
15775a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
15785a988416SJim Ingham         arg1.push_back (cmd_arg);
15795a988416SJim Ingham 
15805a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
15815a988416SJim Ingham         m_arguments.push_back (arg1);
15825a988416SJim Ingham     }
15835a988416SJim Ingham 
15845a988416SJim Ingham     ~CommandObjectCommandsScriptImport ()
15855a988416SJim Ingham     {
15865a988416SJim Ingham     }
15875a988416SJim Ingham 
1588c7bece56SGreg Clayton     virtual int
15895a988416SJim Ingham     HandleArgumentCompletion (Args &input,
15905a988416SJim Ingham                               int &cursor_index,
15915a988416SJim Ingham                               int &cursor_char_position,
15925a988416SJim Ingham                               OptionElementVector &opt_element_vector,
15935a988416SJim Ingham                               int match_start_point,
15945a988416SJim Ingham                               int max_return_elements,
15955a988416SJim Ingham                               bool &word_complete,
15965a988416SJim Ingham                               StringList &matches)
15975a988416SJim Ingham     {
15985a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
15995a988416SJim Ingham         completion_str.erase (cursor_char_position);
16005a988416SJim Ingham 
16015a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
16025a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
16035a988416SJim Ingham                                                              completion_str.c_str(),
16045a988416SJim Ingham                                                              match_start_point,
16055a988416SJim Ingham                                                              max_return_elements,
16065a988416SJim Ingham                                                              NULL,
16075a988416SJim Ingham                                                              word_complete,
16085a988416SJim Ingham                                                              matches);
16095a988416SJim Ingham         return matches.GetSize();
16105a988416SJim Ingham     }
16115a988416SJim Ingham 
16125a988416SJim Ingham     virtual Options *
16135a988416SJim Ingham     GetOptions ()
16145a988416SJim Ingham     {
16155a988416SJim Ingham         return &m_options;
16165a988416SJim Ingham     }
16175a988416SJim Ingham 
16185a988416SJim Ingham protected:
16190a305db7SEnrico Granata 
16200a305db7SEnrico Granata     class CommandOptions : public Options
16210a305db7SEnrico Granata     {
16220a305db7SEnrico Granata     public:
16230a305db7SEnrico Granata 
16240a305db7SEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
16250a305db7SEnrico Granata             Options (interpreter)
16260a305db7SEnrico Granata         {
16270a305db7SEnrico Granata         }
16280a305db7SEnrico Granata 
16290a305db7SEnrico Granata         virtual
16300a305db7SEnrico Granata         ~CommandOptions (){}
16310a305db7SEnrico Granata 
16320a305db7SEnrico Granata         virtual Error
16330a305db7SEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
16340a305db7SEnrico Granata         {
16350a305db7SEnrico Granata             Error error;
16363bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
16370a305db7SEnrico Granata 
16380a305db7SEnrico Granata             switch (short_option)
16390a305db7SEnrico Granata             {
16400a305db7SEnrico Granata                 case 'r':
16410a305db7SEnrico Granata                     m_allow_reload = true;
16420a305db7SEnrico Granata                     break;
16430a305db7SEnrico Granata                 default:
16440a305db7SEnrico Granata                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
16450a305db7SEnrico Granata                     break;
16460a305db7SEnrico Granata             }
16470a305db7SEnrico Granata 
16480a305db7SEnrico Granata             return error;
16490a305db7SEnrico Granata         }
16500a305db7SEnrico Granata 
16510a305db7SEnrico Granata         void
16520a305db7SEnrico Granata         OptionParsingStarting ()
16530a305db7SEnrico Granata         {
1654e0c70f1bSEnrico Granata             m_allow_reload = true;
16550a305db7SEnrico Granata         }
16560a305db7SEnrico Granata 
16570a305db7SEnrico Granata         const OptionDefinition*
16580a305db7SEnrico Granata         GetDefinitions ()
16590a305db7SEnrico Granata         {
16600a305db7SEnrico Granata             return g_option_table;
16610a305db7SEnrico Granata         }
16620a305db7SEnrico Granata 
16630a305db7SEnrico Granata         // Options table: Required for subclasses of Options.
16640a305db7SEnrico Granata 
16650a305db7SEnrico Granata         static OptionDefinition g_option_table[];
16660a305db7SEnrico Granata 
16670a305db7SEnrico Granata         // Instance variables to hold the values for command options.
16680a305db7SEnrico Granata 
16690a305db7SEnrico Granata         bool m_allow_reload;
16700a305db7SEnrico Granata     };
16710a305db7SEnrico Granata 
1672a9dbf432SEnrico Granata     bool
16735a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1674a9dbf432SEnrico Granata     {
1675a9dbf432SEnrico Granata 
1676a9dbf432SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1677a9dbf432SEnrico Granata         {
1678a9dbf432SEnrico Granata             result.AppendError ("only scripting language supported for module importing is currently Python");
1679a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1680a9dbf432SEnrico Granata             return false;
1681a9dbf432SEnrico Granata         }
1682a9dbf432SEnrico Granata 
16835a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1684a9dbf432SEnrico Granata 
1685a9dbf432SEnrico Granata         if (argc != 1)
1686a9dbf432SEnrico Granata         {
1687a9dbf432SEnrico Granata             result.AppendError ("'command script import' requires one argument");
1688a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1689a9dbf432SEnrico Granata             return false;
1690a9dbf432SEnrico Granata         }
1691a9dbf432SEnrico Granata 
16925a988416SJim Ingham         std::string path = command.GetArgumentAtIndex(0);
1693a9dbf432SEnrico Granata         Error error;
1694a9dbf432SEnrico Granata 
1695c9d645d3SGreg Clayton         const bool init_session = true;
1696078551c7SEnrico Granata         // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1697078551c7SEnrico Granata         // commands won't ever be recursively invoked, but it's actually possible to craft
1698078551c7SEnrico Granata         // a Python script that does other "command script imports" in __lldb_init_module
1699078551c7SEnrico Granata         // the real fix is to have recursive commands possible with a CommandInvocation object
1700078551c7SEnrico Granata         // separate from the CommandObject itself, so that recursive command invocations
1701078551c7SEnrico Granata         // won't stomp on each other (wrt to execution contents, options, and more)
1702078551c7SEnrico Granata         m_exe_ctx.Clear();
1703a9dbf432SEnrico Granata         if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
17040a305db7SEnrico Granata                                                                       m_options.m_allow_reload,
1705c9d645d3SGreg Clayton                                                                       init_session,
1706a9dbf432SEnrico Granata                                                                       error))
1707a9dbf432SEnrico Granata         {
1708a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1709a9dbf432SEnrico Granata         }
1710a9dbf432SEnrico Granata         else
1711a9dbf432SEnrico Granata         {
1712a9dbf432SEnrico Granata             result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1713a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1714a9dbf432SEnrico Granata         }
1715a9dbf432SEnrico Granata 
1716a9dbf432SEnrico Granata         return result.Succeeded();
1717a9dbf432SEnrico Granata     }
17180a305db7SEnrico Granata 
17195a988416SJim Ingham     CommandOptions m_options;
1720a9dbf432SEnrico Granata };
1721223383edSEnrico Granata 
17220a305db7SEnrico Granata OptionDefinition
17230a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
17240a305db7SEnrico Granata {
1725d37221dcSZachary 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."},
1726d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
17270a305db7SEnrico Granata };
17280a305db7SEnrico Granata 
17290a305db7SEnrico Granata 
1730223383edSEnrico Granata //-------------------------------------------------------------------------
1731223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1732223383edSEnrico Granata //-------------------------------------------------------------------------
1733223383edSEnrico Granata 
173444d93782SGreg Clayton class CommandObjectCommandsScriptAdd :
173544d93782SGreg Clayton     public CommandObjectParsed,
173644d93782SGreg Clayton     public IOHandlerDelegateMultiline
1737223383edSEnrico Granata {
17385a988416SJim Ingham public:
17395a988416SJim Ingham     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
17405a988416SJim Ingham         CommandObjectParsed (interpreter,
17415a988416SJim Ingham                              "command script add",
17425a988416SJim Ingham                              "Add a scripted function as an LLDB command.",
17435a988416SJim Ingham                              NULL),
1744c3d874a5SGreg Clayton         IOHandlerDelegateMultiline ("DONE"),
17455a988416SJim Ingham         m_options (interpreter)
17465a988416SJim Ingham     {
17475a988416SJim Ingham         CommandArgumentEntry arg1;
17485a988416SJim Ingham         CommandArgumentData cmd_arg;
17495a988416SJim Ingham 
17505a988416SJim Ingham         // Define the first (and only) variant of this arg.
17515a988416SJim Ingham         cmd_arg.arg_type = eArgTypeCommandName;
17525a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
17535a988416SJim Ingham 
17545a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
17555a988416SJim Ingham         arg1.push_back (cmd_arg);
17565a988416SJim Ingham 
17575a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
17585a988416SJim Ingham         m_arguments.push_back (arg1);
17595a988416SJim Ingham     }
17605a988416SJim Ingham 
17615a988416SJim Ingham     ~CommandObjectCommandsScriptAdd ()
17625a988416SJim Ingham     {
17635a988416SJim Ingham     }
17645a988416SJim Ingham 
17655a988416SJim Ingham     virtual Options *
17665a988416SJim Ingham     GetOptions ()
17675a988416SJim Ingham     {
17685a988416SJim Ingham         return &m_options;
17695a988416SJim Ingham     }
17705a988416SJim Ingham 
17715a988416SJim Ingham protected:
1772223383edSEnrico Granata 
1773223383edSEnrico Granata     class CommandOptions : public Options
1774223383edSEnrico Granata     {
1775223383edSEnrico Granata     public:
1776223383edSEnrico Granata 
1777223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
17789fe00e52SEnrico Granata             Options (interpreter),
17799fe00e52SEnrico Granata             m_class_name(),
17809fe00e52SEnrico Granata             m_funct_name(),
17819fe00e52SEnrico Granata             m_short_help(),
17829fe00e52SEnrico Granata             m_synchronicity(eScriptedCommandSynchronicitySynchronous)
1783223383edSEnrico Granata         {
1784223383edSEnrico Granata         }
1785223383edSEnrico Granata 
1786223383edSEnrico Granata         virtual
1787223383edSEnrico Granata         ~CommandOptions (){}
1788223383edSEnrico Granata 
1789223383edSEnrico Granata         virtual Error
1790223383edSEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
1791223383edSEnrico Granata         {
1792223383edSEnrico Granata             Error error;
17933bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
1794223383edSEnrico Granata 
1795223383edSEnrico Granata             switch (short_option)
1796223383edSEnrico Granata             {
1797223383edSEnrico Granata                 case 'f':
1798735152e3SEnrico Granata                     if (option_arg)
1799735152e3SEnrico Granata                         m_funct_name.assign(option_arg);
1800735152e3SEnrico Granata                     break;
18019fe00e52SEnrico Granata                 case 'c':
18029fe00e52SEnrico Granata                     if (option_arg)
18039fe00e52SEnrico Granata                         m_class_name.assign(option_arg);
18049fe00e52SEnrico Granata                     break;
1805735152e3SEnrico Granata                 case 'h':
1806735152e3SEnrico Granata                     if (option_arg)
1807735152e3SEnrico Granata                         m_short_help.assign(option_arg);
1808223383edSEnrico Granata                     break;
18090a305db7SEnrico Granata                 case 's':
181044d93782SGreg Clayton                     m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
18110a305db7SEnrico Granata                     if (!error.Success())
18120a305db7SEnrico Granata                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
18130a305db7SEnrico Granata                     break;
1814223383edSEnrico Granata                 default:
181586edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1816223383edSEnrico Granata                     break;
1817223383edSEnrico Granata             }
1818223383edSEnrico Granata 
1819223383edSEnrico Granata             return error;
1820223383edSEnrico Granata         }
1821223383edSEnrico Granata 
1822223383edSEnrico Granata         void
1823223383edSEnrico Granata         OptionParsingStarting ()
1824223383edSEnrico Granata         {
18259fe00e52SEnrico Granata             m_class_name.clear();
1826735152e3SEnrico Granata             m_funct_name.clear();
1827735152e3SEnrico Granata             m_short_help.clear();
182844d93782SGreg Clayton             m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1829223383edSEnrico Granata         }
1830223383edSEnrico Granata 
1831223383edSEnrico Granata         const OptionDefinition*
1832223383edSEnrico Granata         GetDefinitions ()
1833223383edSEnrico Granata         {
1834223383edSEnrico Granata             return g_option_table;
1835223383edSEnrico Granata         }
1836223383edSEnrico Granata 
1837223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1838223383edSEnrico Granata 
1839223383edSEnrico Granata         static OptionDefinition g_option_table[];
1840223383edSEnrico Granata 
1841223383edSEnrico Granata         // Instance variables to hold the values for command options.
1842223383edSEnrico Granata 
18439fe00e52SEnrico Granata         std::string m_class_name;
1844223383edSEnrico Granata         std::string m_funct_name;
1845735152e3SEnrico Granata         std::string m_short_help;
184644d93782SGreg Clayton         ScriptedCommandSynchronicity m_synchronicity;
1847223383edSEnrico Granata     };
1848223383edSEnrico Granata 
184944d93782SGreg Clayton     virtual void
185044d93782SGreg Clayton     IOHandlerActivated (IOHandler &io_handler)
1851223383edSEnrico Granata     {
185244d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
185344d93782SGreg Clayton         if (output_sp)
1854223383edSEnrico Granata         {
185544d93782SGreg Clayton             output_sp->PutCString(g_python_command_instructions);
185644d93782SGreg Clayton             output_sp->Flush();
1857223383edSEnrico Granata         }
1858223383edSEnrico Granata     }
1859223383edSEnrico Granata 
1860223383edSEnrico Granata 
186144d93782SGreg Clayton     virtual void
186244d93782SGreg Clayton     IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
1863223383edSEnrico Granata     {
186444d93782SGreg Clayton         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
186544d93782SGreg Clayton 
186644d93782SGreg Clayton         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
186744d93782SGreg Clayton         if (interpreter)
186844d93782SGreg Clayton         {
186944d93782SGreg Clayton 
187044d93782SGreg Clayton             StringList lines;
187144d93782SGreg Clayton             lines.SplitIntoLines(data);
187244d93782SGreg Clayton             if (lines.GetSize() > 0)
187344d93782SGreg Clayton             {
1874a73b7df7SEnrico Granata                 std::string funct_name_str;
187544d93782SGreg Clayton                 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1876223383edSEnrico Granata                 {
1877a73b7df7SEnrico Granata                     if (funct_name_str.empty())
1878223383edSEnrico Granata                     {
187944d93782SGreg Clayton                         error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
188044d93782SGreg Clayton                         error_sp->Flush();
1881223383edSEnrico Granata                     }
188244d93782SGreg Clayton                     else
188344d93782SGreg Clayton                     {
1884223383edSEnrico Granata                         // everything should be fine now, let's add this alias
1885223383edSEnrico Granata 
1886223383edSEnrico Granata                         CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1887223383edSEnrico Granata                                                                                         m_cmd_name,
1888a73b7df7SEnrico Granata                                                                                         funct_name_str.c_str(),
1889735152e3SEnrico Granata                                                                                         m_short_help,
189044d93782SGreg Clayton                                                                                         m_synchronicity));
1891223383edSEnrico Granata 
18920a305db7SEnrico Granata                         if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1893223383edSEnrico Granata                         {
189444d93782SGreg Clayton                             error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
189544d93782SGreg Clayton                             error_sp->Flush();
1896223383edSEnrico Granata                         }
1897223383edSEnrico Granata                     }
189844d93782SGreg Clayton                 }
189944d93782SGreg Clayton                 else
190044d93782SGreg Clayton                 {
190144d93782SGreg Clayton                     error_sp->Printf ("error: unable to create function, didn't add python command.\n");
190244d93782SGreg Clayton                     error_sp->Flush();
190344d93782SGreg Clayton                 }
190444d93782SGreg Clayton             }
190544d93782SGreg Clayton             else
190644d93782SGreg Clayton             {
190744d93782SGreg Clayton                 error_sp->Printf ("error: empty function, didn't add python command.\n");
190844d93782SGreg Clayton                 error_sp->Flush();
190944d93782SGreg Clayton             }
191044d93782SGreg Clayton         }
191144d93782SGreg Clayton         else
191244d93782SGreg Clayton         {
191344d93782SGreg Clayton             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
191444d93782SGreg Clayton             error_sp->Flush();
191544d93782SGreg Clayton         }
191644d93782SGreg Clayton 
191744d93782SGreg Clayton         io_handler.SetIsDone(true);
191844d93782SGreg Clayton 
191944d93782SGreg Clayton 
192044d93782SGreg Clayton     }
1921223383edSEnrico Granata 
19225a988416SJim Ingham protected:
1923223383edSEnrico Granata     bool
19245a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1925223383edSEnrico Granata     {
192699f0b8f9SEnrico Granata 
192799f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
192899f0b8f9SEnrico Granata         {
192999f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
193099f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
193199f0b8f9SEnrico Granata             return false;
193299f0b8f9SEnrico Granata         }
193399f0b8f9SEnrico Granata 
19345a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1935223383edSEnrico Granata 
1936223383edSEnrico Granata         if (argc != 1)
1937223383edSEnrico Granata         {
1938223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
1939223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1940223383edSEnrico Granata             return false;
1941223383edSEnrico Granata         }
1942223383edSEnrico Granata 
1943735152e3SEnrico Granata         // Store the options in case we get multi-line input
194444d93782SGreg Clayton         m_cmd_name = command.GetArgumentAtIndex(0);
1945735152e3SEnrico Granata         m_short_help.assign(m_options.m_short_help);
194644d93782SGreg Clayton         m_synchronicity = m_options.m_synchronicity;
1947223383edSEnrico Granata 
19489fe00e52SEnrico Granata         if (m_options.m_class_name.empty())
19499fe00e52SEnrico Granata         {
1950223383edSEnrico Granata             if (m_options.m_funct_name.empty())
1951223383edSEnrico Granata             {
195244d93782SGreg Clayton                 m_interpreter.GetPythonCommandsFromIOHandler ("     ",  // Prompt
195344d93782SGreg Clayton                                                               *this,    // IOHandlerDelegate
195444d93782SGreg Clayton                                                               true,     // Run IOHandler in async mode
195544d93782SGreg Clayton                                                               NULL);    // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1956223383edSEnrico Granata             }
1957223383edSEnrico Granata             else
1958223383edSEnrico Granata             {
19590a305db7SEnrico Granata                 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
196044d93782SGreg Clayton                                                                         m_cmd_name,
19610a305db7SEnrico Granata                                                                         m_options.m_funct_name,
1962735152e3SEnrico Granata                                                                         m_options.m_short_help,
196344d93782SGreg Clayton                                                                         m_synchronicity));
196444d93782SGreg Clayton                 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
1965223383edSEnrico Granata                 {
1966223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1967223383edSEnrico Granata                 }
1968223383edSEnrico Granata                 else
1969223383edSEnrico Granata                 {
1970223383edSEnrico Granata                     result.AppendError("cannot add command");
1971223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
1972223383edSEnrico Granata                 }
1973223383edSEnrico Granata             }
19749fe00e52SEnrico Granata         }
19759fe00e52SEnrico Granata         else
19769fe00e52SEnrico Granata         {
19779fe00e52SEnrico Granata             ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
19789fe00e52SEnrico Granata             if (!interpreter)
19799fe00e52SEnrico Granata             {
19809fe00e52SEnrico Granata                 result.AppendError("cannot find ScriptInterpreter");
19819fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
19829fe00e52SEnrico Granata                 return false;
19839fe00e52SEnrico Granata             }
19849fe00e52SEnrico Granata 
19859fe00e52SEnrico Granata             auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
19869fe00e52SEnrico Granata             if (!cmd_obj_sp)
19879fe00e52SEnrico Granata             {
19889fe00e52SEnrico Granata                 result.AppendError("cannot create helper object");
19899fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
19909fe00e52SEnrico Granata                 return false;
19919fe00e52SEnrico Granata             }
19929fe00e52SEnrico Granata 
19939fe00e52SEnrico Granata             CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
19949fe00e52SEnrico Granata                                                                      m_cmd_name,
19959fe00e52SEnrico Granata                                                                      cmd_obj_sp,
19969fe00e52SEnrico Granata                                                                      m_synchronicity));
19979fe00e52SEnrico Granata             if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
19989fe00e52SEnrico Granata             {
19999fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
20009fe00e52SEnrico Granata             }
20019fe00e52SEnrico Granata             else
20029fe00e52SEnrico Granata             {
20039fe00e52SEnrico Granata                 result.AppendError("cannot add command");
20049fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
20059fe00e52SEnrico Granata             }
20069fe00e52SEnrico Granata         }
2007223383edSEnrico Granata 
2008223383edSEnrico Granata         return result.Succeeded();
2009223383edSEnrico Granata 
2010223383edSEnrico Granata     }
20115a988416SJim Ingham 
20125a988416SJim Ingham     CommandOptions m_options;
201344d93782SGreg Clayton     std::string m_cmd_name;
2014735152e3SEnrico Granata     std::string m_short_help;
201544d93782SGreg Clayton     ScriptedCommandSynchronicity m_synchronicity;
2016223383edSEnrico Granata };
2017223383edSEnrico Granata 
20180a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] =
20190a305db7SEnrico Granata {
20200a305db7SEnrico Granata     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
20210a305db7SEnrico Granata     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
20220a305db7SEnrico Granata     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
20230a305db7SEnrico Granata     { 0, NULL, NULL }
20240a305db7SEnrico Granata };
20250a305db7SEnrico Granata 
2026223383edSEnrico Granata OptionDefinition
2027223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2028223383edSEnrico Granata {
2029d37221dcSZachary 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."},
20309fe00e52SEnrico 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."},
20319370d278SEnrico Granata     { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
20329fe00e52SEnrico 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."},
2033d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2034223383edSEnrico Granata };
2035223383edSEnrico Granata 
2036223383edSEnrico Granata //-------------------------------------------------------------------------
2037223383edSEnrico Granata // CommandObjectCommandsScriptList
2038223383edSEnrico Granata //-------------------------------------------------------------------------
2039223383edSEnrico Granata 
20405a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed
2041223383edSEnrico Granata {
2042223383edSEnrico Granata private:
2043223383edSEnrico Granata 
2044223383edSEnrico Granata public:
2045223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
20465a988416SJim Ingham     CommandObjectParsed (interpreter,
2047223383edSEnrico Granata                    "command script list",
2048223383edSEnrico Granata                    "List defined scripted commands.",
2049223383edSEnrico Granata                    NULL)
2050223383edSEnrico Granata     {
2051223383edSEnrico Granata     }
2052223383edSEnrico Granata 
2053223383edSEnrico Granata     ~CommandObjectCommandsScriptList ()
2054223383edSEnrico Granata     {
2055223383edSEnrico Granata     }
2056223383edSEnrico Granata 
2057223383edSEnrico Granata     bool
20585a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
2059223383edSEnrico Granata     {
2060223383edSEnrico Granata 
2061223383edSEnrico Granata         m_interpreter.GetHelp(result,
2062223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
2063223383edSEnrico Granata 
2064223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2065223383edSEnrico Granata 
2066223383edSEnrico Granata         return true;
2067223383edSEnrico Granata 
2068223383edSEnrico Granata 
2069223383edSEnrico Granata     }
2070223383edSEnrico Granata };
2071223383edSEnrico Granata 
2072223383edSEnrico Granata //-------------------------------------------------------------------------
2073223383edSEnrico Granata // CommandObjectCommandsScriptClear
2074223383edSEnrico Granata //-------------------------------------------------------------------------
2075223383edSEnrico Granata 
20765a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed
2077223383edSEnrico Granata {
2078223383edSEnrico Granata private:
2079223383edSEnrico Granata 
2080223383edSEnrico Granata public:
2081223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
20825a988416SJim Ingham         CommandObjectParsed (interpreter,
2083223383edSEnrico Granata                              "command script clear",
2084223383edSEnrico Granata                              "Delete all scripted commands.",
2085223383edSEnrico Granata                              NULL)
2086223383edSEnrico Granata     {
2087223383edSEnrico Granata     }
2088223383edSEnrico Granata 
2089223383edSEnrico Granata     ~CommandObjectCommandsScriptClear ()
2090223383edSEnrico Granata     {
2091223383edSEnrico Granata     }
2092223383edSEnrico Granata 
20935a988416SJim Ingham protected:
2094223383edSEnrico Granata     bool
20955a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
2096223383edSEnrico Granata     {
2097223383edSEnrico Granata 
2098223383edSEnrico Granata         m_interpreter.RemoveAllUser();
2099223383edSEnrico Granata 
2100223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2101223383edSEnrico Granata 
2102223383edSEnrico Granata         return true;
2103223383edSEnrico Granata     }
2104223383edSEnrico Granata };
2105223383edSEnrico Granata 
2106223383edSEnrico Granata //-------------------------------------------------------------------------
2107223383edSEnrico Granata // CommandObjectCommandsScriptDelete
2108223383edSEnrico Granata //-------------------------------------------------------------------------
2109223383edSEnrico Granata 
21105a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed
2111223383edSEnrico Granata {
2112223383edSEnrico Granata public:
2113223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
21145a988416SJim Ingham         CommandObjectParsed (interpreter,
2115223383edSEnrico Granata                              "command script delete",
2116223383edSEnrico Granata                              "Delete a scripted command.",
2117223383edSEnrico Granata                              NULL)
2118223383edSEnrico Granata     {
2119223383edSEnrico Granata         CommandArgumentEntry arg1;
2120223383edSEnrico Granata         CommandArgumentData cmd_arg;
2121223383edSEnrico Granata 
2122223383edSEnrico Granata         // Define the first (and only) variant of this arg.
2123223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
2124223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
2125223383edSEnrico Granata 
2126223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
2127223383edSEnrico Granata         arg1.push_back (cmd_arg);
2128223383edSEnrico Granata 
2129223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
2130223383edSEnrico Granata         m_arguments.push_back (arg1);
2131223383edSEnrico Granata     }
2132223383edSEnrico Granata 
2133223383edSEnrico Granata     ~CommandObjectCommandsScriptDelete ()
2134223383edSEnrico Granata     {
2135223383edSEnrico Granata     }
2136223383edSEnrico Granata 
21375a988416SJim Ingham protected:
2138223383edSEnrico Granata     bool
21395a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
2140223383edSEnrico Granata     {
2141223383edSEnrico Granata 
21425a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2143223383edSEnrico Granata 
2144223383edSEnrico Granata         if (argc != 1)
2145223383edSEnrico Granata         {
2146223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
2147223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2148223383edSEnrico Granata             return false;
2149223383edSEnrico Granata         }
2150223383edSEnrico Granata 
21515a988416SJim Ingham         const char* cmd_name = command.GetArgumentAtIndex(0);
2152223383edSEnrico Granata 
2153223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2154223383edSEnrico Granata         {
2155223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
2156223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
2157223383edSEnrico Granata         }
2158223383edSEnrico Granata         else
2159223383edSEnrico Granata         {
2160223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
2161223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2162223383edSEnrico Granata         }
2163223383edSEnrico Granata 
2164223383edSEnrico Granata         return result.Succeeded();
2165223383edSEnrico Granata 
2166223383edSEnrico Granata     }
2167223383edSEnrico Granata };
2168223383edSEnrico Granata 
2169223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
2170223383edSEnrico Granata 
2171223383edSEnrico Granata //-------------------------------------------------------------------------
2172223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
2173223383edSEnrico Granata //-------------------------------------------------------------------------
2174223383edSEnrico Granata 
2175223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2176223383edSEnrico Granata {
2177223383edSEnrico Granata public:
2178223383edSEnrico Granata     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2179223383edSEnrico Granata     CommandObjectMultiword (interpreter,
2180223383edSEnrico Granata                             "command script",
2181223383edSEnrico Granata                             "A set of commands for managing or customizing script commands.",
2182223383edSEnrico Granata                             "command script <subcommand> [<subcommand-options>]")
2183223383edSEnrico Granata     {
2184223383edSEnrico Granata         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2185223383edSEnrico Granata         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2186223383edSEnrico Granata         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
2187223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
2188a9dbf432SEnrico Granata         LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
2189223383edSEnrico Granata     }
2190223383edSEnrico Granata 
2191223383edSEnrico Granata     ~CommandObjectMultiwordCommandsScript ()
2192223383edSEnrico Granata     {
2193223383edSEnrico Granata     }
2194223383edSEnrico Granata 
2195223383edSEnrico Granata };
2196223383edSEnrico Granata 
2197223383edSEnrico Granata 
2198ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
2199ebc09c36SJim Ingham 
2200ebc09c36SJim Ingham //-------------------------------------------------------------------------
2201ebc09c36SJim Ingham // CommandObjectMultiwordCommands
2202ebc09c36SJim Ingham //-------------------------------------------------------------------------
2203ebc09c36SJim Ingham 
2204ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
2205a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
22060e5e5a79SGreg Clayton                             "command",
22073f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
22080e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
2209ebc09c36SJim Ingham {
2210a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2211a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2212a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
2213b547278cSGreg Clayton     LoadSubCommand ("delete",  CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
2214de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
2215a5a97ebeSJim Ingham     LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2216223383edSEnrico Granata     LoadSubCommand ("script",  CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
2217ebc09c36SJim Ingham }
2218ebc09c36SJim Ingham 
2219ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
2220ebc09c36SJim Ingham {
2221ebc09c36SJim Ingham }
2222ebc09c36SJim Ingham 
2223