1ebc09c36SJim Ingham //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
2ebc09c36SJim Ingham //
3ebc09c36SJim Ingham //                     The LLVM Compiler Infrastructure
4ebc09c36SJim Ingham //
5ebc09c36SJim Ingham // This file is distributed under the University of Illinois Open Source
6ebc09c36SJim Ingham // License. See LICENSE.TXT for details.
7ebc09c36SJim Ingham //
8ebc09c36SJim Ingham //===----------------------------------------------------------------------===//
9ebc09c36SJim Ingham 
10ebc09c36SJim Ingham #include "CommandObjectCommands.h"
11ebc09c36SJim Ingham 
12ebc09c36SJim Ingham // C Includes
13ebc09c36SJim Ingham // C++ Includes
14ebc09c36SJim Ingham // Other libraries and framework includes
150e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h"
160e5e5a79SGreg Clayton 
17ebc09c36SJim Ingham // Project includes
18ebc09c36SJim Ingham #include "lldb/Core/Debugger.h"
1944d93782SGreg Clayton #include "lldb/Core/IOHandler.h"
20be93a35aSEnrico Granata #include "lldb/Core/StringList.h"
21de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h"
227594f14fSEnrico Granata #include "lldb/Interpreter/CommandHistory.h"
23ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h"
24de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h"
25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h"
26012d4fcaSEnrico Granata #include "lldb/Interpreter/OptionValueBoolean.h"
277594f14fSEnrico Granata #include "lldb/Interpreter/OptionValueUInt64.h"
28ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
2999f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h"
30ebc09c36SJim Ingham 
31ebc09c36SJim Ingham using namespace lldb;
32ebc09c36SJim Ingham using namespace lldb_private;
33ebc09c36SJim Ingham 
34ebc09c36SJim Ingham //-------------------------------------------------------------------------
35ebc09c36SJim Ingham // CommandObjectCommandsSource
36ebc09c36SJim Ingham //-------------------------------------------------------------------------
37ebc09c36SJim Ingham 
385a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed
39a5a97ebeSJim Ingham {
405a988416SJim Ingham public:
415a988416SJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
425a988416SJim Ingham         CommandObjectParsed (interpreter,
435a988416SJim Ingham                              "command history",
445a988416SJim Ingham                              "Dump the history of commands in this session.",
455a988416SJim Ingham                              NULL),
465a988416SJim Ingham         m_options (interpreter)
475a988416SJim Ingham     {
485a988416SJim Ingham     }
495a988416SJim Ingham 
50*13d21e9aSBruce Mitchener     ~CommandObjectCommandsHistory () override {}
515a988416SJim Ingham 
52*13d21e9aSBruce Mitchener     Options *
53*13d21e9aSBruce Mitchener     GetOptions () override
545a988416SJim Ingham     {
555a988416SJim Ingham         return &m_options;
565a988416SJim Ingham     }
575a988416SJim Ingham 
585a988416SJim Ingham protected:
59a5a97ebeSJim Ingham 
60a5a97ebeSJim Ingham     class CommandOptions : public Options
61a5a97ebeSJim Ingham     {
62a5a97ebeSJim Ingham     public:
63a5a97ebeSJim Ingham 
64a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
657594f14fSEnrico Granata             Options (interpreter),
667594f14fSEnrico Granata             m_start_idx(0),
677594f14fSEnrico Granata             m_stop_idx(0),
687594f14fSEnrico Granata             m_count(0),
6963123b64SEnrico Granata             m_clear(false)
70a5a97ebeSJim Ingham         {
71a5a97ebeSJim Ingham         }
72a5a97ebeSJim Ingham 
73*13d21e9aSBruce Mitchener         ~CommandOptions () override {}
74a5a97ebeSJim Ingham 
75*13d21e9aSBruce Mitchener         Error
76*13d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
77a5a97ebeSJim Ingham         {
78a5a97ebeSJim Ingham             Error error;
793bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
80a5a97ebeSJim Ingham 
81a5a97ebeSJim Ingham             switch (short_option)
82a5a97ebeSJim Ingham             {
83a5a97ebeSJim Ingham                 case 'c':
84c95f7e2aSPavel Labath                     error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
85a5a97ebeSJim Ingham                     break;
86a5a97ebeSJim Ingham                 case 's':
877594f14fSEnrico Granata                     if (option_arg && strcmp("end", option_arg) == 0)
887594f14fSEnrico Granata                     {
897594f14fSEnrico Granata                         m_start_idx.SetCurrentValue(UINT64_MAX);
907594f14fSEnrico Granata                         m_start_idx.SetOptionWasSet();
917594f14fSEnrico Granata                     }
927594f14fSEnrico Granata                     else
93c95f7e2aSPavel Labath                         error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
947594f14fSEnrico Granata                     break;
957594f14fSEnrico Granata                 case 'e':
96c95f7e2aSPavel Labath                     error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
977594f14fSEnrico Granata                     break;
9863123b64SEnrico Granata                 case 'C':
9963123b64SEnrico Granata                     m_clear.SetCurrentValue(true);
10063123b64SEnrico Granata                     m_clear.SetOptionWasSet();
101a5a97ebeSJim Ingham                     break;
102a5a97ebeSJim Ingham                 default:
10386edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
104a5a97ebeSJim Ingham                     break;
105a5a97ebeSJim Ingham             }
106a5a97ebeSJim Ingham 
107a5a97ebeSJim Ingham             return error;
108a5a97ebeSJim Ingham         }
109a5a97ebeSJim Ingham 
110a5a97ebeSJim Ingham         void
111*13d21e9aSBruce Mitchener         OptionParsingStarting () override
112a5a97ebeSJim Ingham         {
1137594f14fSEnrico Granata             m_start_idx.Clear();
1147594f14fSEnrico Granata             m_stop_idx.Clear();
1157594f14fSEnrico Granata             m_count.Clear();
11663123b64SEnrico Granata             m_clear.Clear();
117a5a97ebeSJim Ingham         }
118a5a97ebeSJim Ingham 
119a5a97ebeSJim Ingham         const OptionDefinition*
120*13d21e9aSBruce Mitchener         GetDefinitions () override
121a5a97ebeSJim Ingham         {
122a5a97ebeSJim Ingham             return g_option_table;
123a5a97ebeSJim Ingham         }
124a5a97ebeSJim Ingham 
125a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
126a5a97ebeSJim Ingham 
127a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
128a5a97ebeSJim Ingham 
129a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
130a5a97ebeSJim Ingham 
1317594f14fSEnrico Granata         OptionValueUInt64 m_start_idx;
1327594f14fSEnrico Granata         OptionValueUInt64 m_stop_idx;
1337594f14fSEnrico Granata         OptionValueUInt64 m_count;
13463123b64SEnrico Granata         OptionValueBoolean m_clear;
135a5a97ebeSJim Ingham     };
136a5a97ebeSJim Ingham 
137a5a97ebeSJim Ingham     bool
138*13d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
139a5a97ebeSJim Ingham     {
14063123b64SEnrico Granata         if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
1417594f14fSEnrico Granata         {
1427594f14fSEnrico Granata             m_interpreter.GetCommandHistory().Clear();
1437594f14fSEnrico Granata             result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
1447594f14fSEnrico Granata         }
1457594f14fSEnrico Granata         else
1467594f14fSEnrico Granata         {
1477594f14fSEnrico Granata             if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
1487594f14fSEnrico Granata             {
1497594f14fSEnrico Granata                 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
1507594f14fSEnrico Granata                 result.SetStatus(lldb::eReturnStatusFailed);
1517594f14fSEnrico Granata             }
1527594f14fSEnrico Granata             else
1537594f14fSEnrico Granata             {
15484400ec7SVirgile Bello                 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
15584400ec7SVirgile Bello                 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
15684400ec7SVirgile Bello                 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
157a5a97ebeSJim Ingham 
1587594f14fSEnrico Granata                 const CommandHistory& history(m_interpreter.GetCommandHistory());
1597594f14fSEnrico Granata 
1607594f14fSEnrico Granata                 if (start_idx.first && start_idx.second == UINT64_MAX)
1617594f14fSEnrico Granata                 {
1627594f14fSEnrico Granata                     if (count.first)
1637594f14fSEnrico Granata                     {
1647594f14fSEnrico Granata                         start_idx.second = history.GetSize() - count.second;
1657594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1667594f14fSEnrico Granata                     }
1677594f14fSEnrico Granata                     else if (stop_idx.first)
1687594f14fSEnrico Granata                     {
1697594f14fSEnrico Granata                         start_idx.second = stop_idx.second;
1707594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1717594f14fSEnrico Granata                     }
1727594f14fSEnrico Granata                     else
1737594f14fSEnrico Granata                     {
1747594f14fSEnrico Granata                         start_idx.second = 0;
1757594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1767594f14fSEnrico Granata                     }
1777594f14fSEnrico Granata                 }
1787594f14fSEnrico Granata                 else
1797594f14fSEnrico Granata                 {
1807594f14fSEnrico Granata                     if (!start_idx.first && !stop_idx.first && !count.first)
1817594f14fSEnrico Granata                     {
1827594f14fSEnrico Granata                         start_idx.second = 0;
1837594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1847594f14fSEnrico Granata                     }
1857594f14fSEnrico Granata                     else if (start_idx.first)
1867594f14fSEnrico Granata                     {
1877594f14fSEnrico Granata                         if (count.first)
1887594f14fSEnrico Granata                         {
1897594f14fSEnrico Granata                             stop_idx.second = start_idx.second + count.second - 1;
1907594f14fSEnrico Granata                         }
1917594f14fSEnrico Granata                         else if (!stop_idx.first)
1927594f14fSEnrico Granata                         {
1937594f14fSEnrico Granata                             stop_idx.second = history.GetSize() - 1;
1947594f14fSEnrico Granata                         }
1957594f14fSEnrico Granata                     }
1967594f14fSEnrico Granata                     else if (stop_idx.first)
1977594f14fSEnrico Granata                     {
1987594f14fSEnrico Granata                         if (count.first)
1997594f14fSEnrico Granata                         {
2007594f14fSEnrico Granata                             if (stop_idx.second >= count.second)
2017594f14fSEnrico Granata                                 start_idx.second = stop_idx.second - count.second + 1;
2027594f14fSEnrico Granata                             else
2037594f14fSEnrico Granata                                 start_idx.second = 0;
2047594f14fSEnrico Granata                         }
2057594f14fSEnrico Granata                     }
2067594f14fSEnrico Granata                     else /* if (count.first) */
2077594f14fSEnrico Granata                     {
2087594f14fSEnrico Granata                         start_idx.second = 0;
2097594f14fSEnrico Granata                         stop_idx.second = count.second - 1;
2107594f14fSEnrico Granata                     }
2117594f14fSEnrico Granata                 }
2127594f14fSEnrico Granata                 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
2137594f14fSEnrico Granata             }
2147594f14fSEnrico Granata         }
215a5a97ebeSJim Ingham         return result.Succeeded();
216a5a97ebeSJim Ingham 
217a5a97ebeSJim Ingham     }
2185a988416SJim Ingham 
2195a988416SJim Ingham     CommandOptions m_options;
220a5a97ebeSJim Ingham };
221a5a97ebeSJim Ingham 
222a5a97ebeSJim Ingham OptionDefinition
223a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
224a5a97ebeSJim Ingham {
225d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
226d37221dcSZachary 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)."},
227d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
228d37221dcSZachary Turner { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean,    "Clears the current command history."},
229d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
230a5a97ebeSJim Ingham };
231a5a97ebeSJim Ingham 
232a5a97ebeSJim Ingham 
233a5a97ebeSJim Ingham //-------------------------------------------------------------------------
234a5a97ebeSJim Ingham // CommandObjectCommandsSource
235a5a97ebeSJim Ingham //-------------------------------------------------------------------------
236a5a97ebeSJim Ingham 
2375a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed
238ebc09c36SJim Ingham {
2395a988416SJim Ingham public:
2405a988416SJim Ingham     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
2415a988416SJim Ingham         CommandObjectParsed (interpreter,
2425a988416SJim Ingham                              "command source",
2435a988416SJim Ingham                              "Read in debugger commands from the file <filename> and execute them.",
2445a988416SJim Ingham                              NULL),
2455a988416SJim Ingham         m_options (interpreter)
2465a988416SJim Ingham     {
2475a988416SJim Ingham         CommandArgumentEntry arg;
2485a988416SJim Ingham         CommandArgumentData file_arg;
2495a988416SJim Ingham 
2505a988416SJim Ingham         // Define the first (and only) variant of this arg.
2515a988416SJim Ingham         file_arg.arg_type = eArgTypeFilename;
2525a988416SJim Ingham         file_arg.arg_repetition = eArgRepeatPlain;
2535a988416SJim Ingham 
2545a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
2555a988416SJim Ingham         arg.push_back (file_arg);
2565a988416SJim Ingham 
2575a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
2585a988416SJim Ingham         m_arguments.push_back (arg);
2595a988416SJim Ingham     }
2605a988416SJim Ingham 
261*13d21e9aSBruce Mitchener     ~CommandObjectCommandsSource () override {}
2625a988416SJim Ingham 
263*13d21e9aSBruce Mitchener     const char*
264*13d21e9aSBruce Mitchener     GetRepeatCommand (Args &current_command_args, uint32_t index) override
2655a988416SJim Ingham     {
2665a988416SJim Ingham         return "";
2675a988416SJim Ingham     }
2685a988416SJim Ingham 
269*13d21e9aSBruce Mitchener     int
2705a988416SJim Ingham     HandleArgumentCompletion (Args &input,
2715a988416SJim Ingham                               int &cursor_index,
2725a988416SJim Ingham                               int &cursor_char_position,
2735a988416SJim Ingham                               OptionElementVector &opt_element_vector,
2745a988416SJim Ingham                               int match_start_point,
2755a988416SJim Ingham                               int max_return_elements,
2765a988416SJim Ingham                               bool &word_complete,
277*13d21e9aSBruce Mitchener                               StringList &matches) override
2785a988416SJim Ingham     {
2795a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2805a988416SJim Ingham         completion_str.erase (cursor_char_position);
2815a988416SJim Ingham 
2825a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2835a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
2845a988416SJim Ingham                                                              completion_str.c_str(),
2855a988416SJim Ingham                                                              match_start_point,
2865a988416SJim Ingham                                                              max_return_elements,
2875a988416SJim Ingham                                                              NULL,
2885a988416SJim Ingham                                                              word_complete,
2895a988416SJim Ingham                                                              matches);
2905a988416SJim Ingham         return matches.GetSize();
2915a988416SJim Ingham     }
2925a988416SJim Ingham 
293*13d21e9aSBruce Mitchener     Options *
294*13d21e9aSBruce Mitchener     GetOptions () override
2955a988416SJim Ingham     {
2965a988416SJim Ingham         return &m_options;
2975a988416SJim Ingham     }
2985a988416SJim Ingham 
2995a988416SJim Ingham protected:
300e16c50a1SJim Ingham 
301e16c50a1SJim Ingham     class CommandOptions : public Options
302e16c50a1SJim Ingham     {
303e16c50a1SJim Ingham     public:
304e16c50a1SJim Ingham 
305eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
306012d4fcaSEnrico Granata             Options (interpreter),
307340b0309SGreg Clayton             m_stop_on_error (true),
308340b0309SGreg Clayton             m_silent_run (false),
309340b0309SGreg Clayton             m_stop_on_continue (true)
310eb0103f2SGreg Clayton         {
311eb0103f2SGreg Clayton         }
312e16c50a1SJim Ingham 
313*13d21e9aSBruce Mitchener         ~CommandOptions () override {}
314e16c50a1SJim Ingham 
315*13d21e9aSBruce Mitchener         Error
316*13d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
317e16c50a1SJim Ingham         {
318e16c50a1SJim Ingham             Error error;
3193bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
320e16c50a1SJim Ingham 
321e16c50a1SJim Ingham             switch (short_option)
322e16c50a1SJim Ingham             {
323e16c50a1SJim Ingham                 case 'e':
324c95f7e2aSPavel Labath                     error = m_stop_on_error.SetValueFromString(option_arg);
325e16c50a1SJim Ingham                     break;
326340b0309SGreg Clayton 
327e16c50a1SJim Ingham                 case 'c':
328c95f7e2aSPavel Labath                     error = m_stop_on_continue.SetValueFromString(option_arg);
329e16c50a1SJim Ingham                     break;
330340b0309SGreg Clayton 
33160986174SMichael Sartain                 case 's':
332c95f7e2aSPavel Labath                     error = m_silent_run.SetValueFromString(option_arg);
33360986174SMichael Sartain                     break;
334340b0309SGreg Clayton 
335e16c50a1SJim Ingham                 default:
33686edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
337e16c50a1SJim Ingham                     break;
338e16c50a1SJim Ingham             }
339e16c50a1SJim Ingham 
340e16c50a1SJim Ingham             return error;
341e16c50a1SJim Ingham         }
342e16c50a1SJim Ingham 
343e16c50a1SJim Ingham         void
344*13d21e9aSBruce Mitchener         OptionParsingStarting () override
345e16c50a1SJim Ingham         {
346012d4fcaSEnrico Granata             m_stop_on_error.Clear();
347340b0309SGreg Clayton             m_silent_run.Clear();
348340b0309SGreg Clayton             m_stop_on_continue.Clear();
349e16c50a1SJim Ingham         }
350e16c50a1SJim Ingham 
351e0d378b3SGreg Clayton         const OptionDefinition*
352*13d21e9aSBruce Mitchener         GetDefinitions () override
353e16c50a1SJim Ingham         {
354e16c50a1SJim Ingham             return g_option_table;
355e16c50a1SJim Ingham         }
356e16c50a1SJim Ingham 
357e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
358e16c50a1SJim Ingham 
359e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
360e16c50a1SJim Ingham 
361e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
362e16c50a1SJim Ingham 
363012d4fcaSEnrico Granata         OptionValueBoolean m_stop_on_error;
364340b0309SGreg Clayton         OptionValueBoolean m_silent_run;
365340b0309SGreg Clayton         OptionValueBoolean m_stop_on_continue;
366e16c50a1SJim Ingham     };
367e16c50a1SJim Ingham 
368ebc09c36SJim Ingham     bool
369*13d21e9aSBruce Mitchener     DoExecute(Args& command, CommandReturnObject &result) override
370ebc09c36SJim Ingham     {
371c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
372ebc09c36SJim Ingham         if (argc == 1)
373ebc09c36SJim Ingham         {
3745a988416SJim Ingham             const char *filename = command.GetArgumentAtIndex(0);
375ebc09c36SJim Ingham 
3761ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
377e16c50a1SJim Ingham             ExecutionContext *exe_ctx = NULL;  // Just use the default context.
378ebc09c36SJim Ingham 
379340b0309SGreg Clayton             // If any options were set, then use them
380340b0309SGreg Clayton             if (m_options.m_stop_on_error.OptionWasSet()    ||
381340b0309SGreg Clayton                 m_options.m_silent_run.OptionWasSet()       ||
382340b0309SGreg Clayton                 m_options.m_stop_on_continue.OptionWasSet())
383340b0309SGreg Clayton             {
384340b0309SGreg Clayton                 // Use user set settings
38526c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
38626c7bf93SJim Ingham                 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
38726c7bf93SJim Ingham                 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
3887d8555c4SJim Ingham                 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
3897d8555c4SJim Ingham                 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
39026c7bf93SJim Ingham 
391e16c50a1SJim Ingham                 m_interpreter.HandleCommandsFromFile (cmd_file,
392e16c50a1SJim Ingham                                                       exe_ctx,
39326c7bf93SJim Ingham                                                       options,
394e16c50a1SJim Ingham                                                       result);
395340b0309SGreg Clayton 
396340b0309SGreg Clayton             }
397340b0309SGreg Clayton             else
398340b0309SGreg Clayton             {
399340b0309SGreg Clayton                 // No options were set, inherit any settings from nested "command source" commands,
400340b0309SGreg Clayton                 // or set to sane default settings...
40126c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
402340b0309SGreg Clayton                 m_interpreter.HandleCommandsFromFile (cmd_file,
403340b0309SGreg Clayton                                                       exe_ctx,
40426c7bf93SJim Ingham                                                       options,
405340b0309SGreg Clayton                                                       result);
406340b0309SGreg Clayton 
407340b0309SGreg Clayton             }
408ebc09c36SJim Ingham         }
409ebc09c36SJim Ingham         else
410ebc09c36SJim Ingham         {
411ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
412ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
413ebc09c36SJim Ingham         }
414ebc09c36SJim Ingham         return result.Succeeded();
415ebc09c36SJim Ingham 
416ebc09c36SJim Ingham     }
4175a988416SJim Ingham     CommandOptions m_options;
418ebc09c36SJim Ingham };
419ebc09c36SJim Ingham 
420e0d378b3SGreg Clayton OptionDefinition
421e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
422e16c50a1SJim Ingham {
423d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
424d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
425d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
426d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
427e16c50a1SJim Ingham };
428e16c50a1SJim Ingham 
429ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
430ebc09c36SJim Ingham //-------------------------------------------------------------------------
431ebc09c36SJim Ingham // CommandObjectCommandsAlias
432ebc09c36SJim Ingham //-------------------------------------------------------------------------
433ebc09c36SJim Ingham 
434be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
435be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
43644d93782SGreg Clayton                                                      "def my_command_impl(debugger, args, result, internal_dict):\n";
437be93a35aSEnrico Granata 
438be93a35aSEnrico Granata 
4395a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw
440ebc09c36SJim Ingham {
441be93a35aSEnrico Granata 
442be93a35aSEnrico Granata 
443ebc09c36SJim Ingham public:
444a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
4455a988416SJim Ingham         CommandObjectRaw (interpreter,
4460e5e5a79SGreg Clayton                        "command alias",
447e3d26315SCaroline Tice                        "Allow users to define their own debugger command abbreviations.",
448405fe67fSCaroline Tice                        NULL)
449ebc09c36SJim Ingham     {
450ebc09c36SJim Ingham         SetHelpLong(
451ea671fbdSKate Stone "'alias' allows the user to create a short-cut or abbreviation for long \
452ea671fbdSKate Stone commands, multi-word commands, and commands that take particular options.  \
453ea671fbdSKate Stone Below are some simple examples of how one might use the 'alias' command:" R"(
454ea671fbdSKate Stone 
455ea671fbdSKate Stone (lldb) command alias sc script
456ea671fbdSKate Stone 
457ea671fbdSKate Stone     Creates the abbreviation 'sc' for the 'script' command.
458ea671fbdSKate Stone 
459ea671fbdSKate Stone (lldb) command alias bp breakpoint
460ea671fbdSKate Stone 
461ea671fbdSKate Stone )" "    Creates the abbreviation 'bp' for the 'breakpoint' command.  Since \
462ea671fbdSKate Stone breakpoint commands are two-word commands, the user would still need to \
463ea671fbdSKate Stone enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"(
464ea671fbdSKate Stone 
465ea671fbdSKate Stone (lldb) command alias bpl breakpoint list
466ea671fbdSKate Stone 
467ea671fbdSKate Stone     Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
468ea671fbdSKate Stone 
469ea671fbdSKate Stone )" "An alias can include some options for the command, with the values either \
470ea671fbdSKate Stone filled in at the time the alias is created, or specified as positional \
471ea671fbdSKate Stone arguments, to be filled in when the alias is invoked.  The following example \
472ea671fbdSKate Stone shows how to create aliases with options:" R"(
473ea671fbdSKate Stone 
474ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
475ea671fbdSKate Stone 
476ea671fbdSKate Stone )" "    Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
477ea671fbdSKate Stone options already part of the alias.  So if the user wants to set a breakpoint \
478ea671fbdSKate Stone by file and line without explicitly having to use the -f and -l options, the \
479ea671fbdSKate Stone user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \
480ea671fbdSKate Stone for the actual arguments that will be passed when the alias command is used.  \
481ea671fbdSKate Stone The number in the placeholder refers to the position/order the actual value \
482ea671fbdSKate Stone occupies when the alias is used.  All the occurrences of '%1' in the alias \
483ea671fbdSKate Stone will be replaced with the first argument, all the occurrences of '%2' in the \
484ea671fbdSKate Stone alias will be replaced with the second argument, and so on.  This also allows \
485ea671fbdSKate Stone actual arguments to be used multiple times within an alias (see 'process \
486ea671fbdSKate Stone launch' example below)." R"(
487ea671fbdSKate Stone 
488ea671fbdSKate Stone )" "Note: the positional arguments must substitute as whole words in the resultant \
489ea671fbdSKate Stone command, so you can't at present do something like this to append the file extension \
490ea671fbdSKate Stone \".cpp\":" R"(
491ea671fbdSKate Stone 
492ea671fbdSKate Stone (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
493ea671fbdSKate Stone 
494ea671fbdSKate Stone )" "For more complex aliasing, use the \"command regex\" command instead.  In the \
495ea671fbdSKate Stone 'bfl' case above, the actual file value will be filled in with the first argument \
496ea671fbdSKate Stone following 'bfl' and the actual line number value will be filled in with the second \
497ea671fbdSKate Stone argument.  The user would use this alias as follows:" R"(
498ea671fbdSKate Stone 
499ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
500ea671fbdSKate Stone (lldb) bfl my-file.c 137
501ea671fbdSKate Stone 
502ea671fbdSKate Stone This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
503ea671fbdSKate Stone 
504ea671fbdSKate Stone Another example:
505ea671fbdSKate Stone 
506ea671fbdSKate Stone (lldb) command alias pltty process launch -s -o %1 -e %1
507ea671fbdSKate Stone (lldb) pltty /dev/tty0
508ea671fbdSKate Stone 
509ea671fbdSKate Stone     Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
510ea671fbdSKate Stone 
511ea671fbdSKate Stone )" "If the user always wanted to pass the same value to a particular option, the \
512ea671fbdSKate Stone alias could be defined with that value directly in the alias as a constant, \
513ea671fbdSKate Stone rather than using a positional placeholder:" R"(
514ea671fbdSKate Stone 
515ea671fbdSKate Stone (lldb) command alias bl3 breakpoint set -f %1 -l 3
516ea671fbdSKate Stone 
517ea671fbdSKate Stone     Always sets a breakpoint on line 3 of whatever file is indicated.)"
518ea671fbdSKate Stone         );
519ebc09c36SJim Ingham 
520405fe67fSCaroline Tice         CommandArgumentEntry arg1;
521405fe67fSCaroline Tice         CommandArgumentEntry arg2;
522405fe67fSCaroline Tice         CommandArgumentEntry arg3;
523405fe67fSCaroline Tice         CommandArgumentData alias_arg;
524405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
525405fe67fSCaroline Tice         CommandArgumentData options_arg;
526405fe67fSCaroline Tice 
527405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
528405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
529405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
530405fe67fSCaroline Tice 
531405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
532405fe67fSCaroline Tice         arg1.push_back (alias_arg);
533405fe67fSCaroline Tice 
534405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
535405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
536405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
537405fe67fSCaroline Tice 
538405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
539405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
540405fe67fSCaroline Tice 
541405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
542405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
543405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
544405fe67fSCaroline Tice 
545405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
546405fe67fSCaroline Tice         arg3.push_back (options_arg);
547405fe67fSCaroline Tice 
548405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
549405fe67fSCaroline Tice         m_arguments.push_back (arg1);
550405fe67fSCaroline Tice         m_arguments.push_back (arg2);
551405fe67fSCaroline Tice         m_arguments.push_back (arg3);
552ebc09c36SJim Ingham     }
553ebc09c36SJim Ingham 
554*13d21e9aSBruce Mitchener     ~CommandObjectCommandsAlias () override
555ebc09c36SJim Ingham     {
556ebc09c36SJim Ingham     }
557ebc09c36SJim Ingham 
5585a988416SJim Ingham protected:
559*13d21e9aSBruce Mitchener     bool
560*13d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
561844d2303SCaroline Tice     {
562844d2303SCaroline Tice         Args args (raw_command_line);
563844d2303SCaroline Tice         std::string raw_command_string (raw_command_line);
564844d2303SCaroline Tice 
565844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
566844d2303SCaroline Tice 
567844d2303SCaroline Tice         if (argc < 2)
568844d2303SCaroline Tice         {
569844d2303SCaroline Tice             result.AppendError ("'alias' requires at least two arguments");
570844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
571844d2303SCaroline Tice             return false;
572844d2303SCaroline Tice         }
573844d2303SCaroline Tice 
574844d2303SCaroline Tice         // Get the alias command.
575844d2303SCaroline Tice 
576844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
577844d2303SCaroline Tice 
578844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
579844d2303SCaroline Tice         // does the stripping itself.
580844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
581844d2303SCaroline Tice         if (pos == 0)
582844d2303SCaroline Tice         {
583844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
584844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
585844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
586844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
587844d2303SCaroline Tice         }
588844d2303SCaroline Tice         else
589844d2303SCaroline Tice         {
590844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
591844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
592844d2303SCaroline Tice             return false;
593844d2303SCaroline Tice         }
594844d2303SCaroline Tice 
595844d2303SCaroline Tice 
596844d2303SCaroline Tice         // Verify that the command is alias-able.
597844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
598844d2303SCaroline Tice         {
599844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
600844d2303SCaroline Tice                                           alias_command.c_str());
601844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
602844d2303SCaroline Tice             return false;
603844d2303SCaroline Tice         }
604844d2303SCaroline Tice 
605844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
606844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
607844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
608844d2303SCaroline Tice 
609844d2303SCaroline Tice         if (!cmd_obj)
610844d2303SCaroline Tice         {
61186edbf41SGreg Clayton             result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
612844d2303SCaroline Tice                                           "  No alias created.", raw_command_string.c_str());
613844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
614844d2303SCaroline Tice             return false;
615844d2303SCaroline Tice         }
616844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
617844d2303SCaroline Tice         {
618844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
619844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
6205a988416SJim Ingham             return HandleAliasingNormalCommand (args, result);
621844d2303SCaroline Tice         }
622844d2303SCaroline Tice         else
623844d2303SCaroline Tice         {
6245a988416SJim Ingham             return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
6255a988416SJim Ingham         }
6265a988416SJim Ingham         return result.Succeeded();
6275a988416SJim Ingham     }
6285a988416SJim Ingham 
6295a988416SJim Ingham     bool
6305a988416SJim Ingham     HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
6315a988416SJim Ingham     {
632844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
633844d2303SCaroline Tice 
634844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
635844d2303SCaroline Tice             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
636844d2303SCaroline Tice 
6375a988416SJim Ingham             CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
638844d2303SCaroline Tice 
639ca90c47eSCaroline Tice             if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
640844d2303SCaroline Tice             {
641844d2303SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
642ca90c47eSCaroline Tice                 result.SetStatus (eReturnStatusFailed);
643844d2303SCaroline Tice                 return false;
644844d2303SCaroline Tice             }
645844d2303SCaroline Tice 
646844d2303SCaroline Tice             // Create the alias
647844d2303SCaroline Tice             if (m_interpreter.AliasExists (alias_command.c_str())
648844d2303SCaroline Tice                 || m_interpreter.UserCommandExists (alias_command.c_str()))
649844d2303SCaroline Tice             {
650844d2303SCaroline Tice                 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
651844d2303SCaroline Tice                 if (temp_option_arg_sp.get())
652844d2303SCaroline Tice                 {
653844d2303SCaroline Tice                     if (option_arg_vector->size() == 0)
654844d2303SCaroline Tice                         m_interpreter.RemoveAliasOptions (alias_command.c_str());
655844d2303SCaroline Tice                 }
656844d2303SCaroline Tice                 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
657844d2303SCaroline Tice                                                 alias_command.c_str());
658844d2303SCaroline Tice             }
659844d2303SCaroline Tice 
660472362e6SCaroline Tice             if (cmd_obj_sp)
661472362e6SCaroline Tice             {
662844d2303SCaroline Tice                 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
663844d2303SCaroline Tice                 if (option_arg_vector->size() > 0)
664844d2303SCaroline Tice                     m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
665844d2303SCaroline Tice                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
666844d2303SCaroline Tice             }
667472362e6SCaroline Tice             else
668472362e6SCaroline Tice             {
669472362e6SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
670472362e6SCaroline Tice                 result.SetStatus (eReturnStatusFailed);
671472362e6SCaroline Tice             }
672844d2303SCaroline Tice             return result.Succeeded ();
673844d2303SCaroline Tice     }
674ebc09c36SJim Ingham 
675ebc09c36SJim Ingham     bool
6765a988416SJim Ingham     HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
677ebc09c36SJim Ingham     {
678867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
679ebc09c36SJim Ingham 
680ebc09c36SJim Ingham         if (argc < 2)
681ebc09c36SJim Ingham         {
682ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
683ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
684ebc09c36SJim Ingham             return false;
685ebc09c36SJim Ingham         }
686ebc09c36SJim Ingham 
687ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
688ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
689ebc09c36SJim Ingham 
690ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
691ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
692ebc09c36SJim Ingham 
693ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
694ebc09c36SJim Ingham 
695a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
696ebc09c36SJim Ingham         {
697ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
698ebc09c36SJim Ingham                                          alias_command.c_str());
699ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
700ebc09c36SJim Ingham         }
701ebc09c36SJim Ingham         else
702ebc09c36SJim Ingham         {
703a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
704ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
705ebc09c36SJim Ingham              bool use_subcommand = false;
706ebc09c36SJim Ingham              if (command_obj_sp.get())
707ebc09c36SJim Ingham              {
708ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
709c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
710ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
711ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
712ebc09c36SJim Ingham 
713844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
714ebc09c36SJim Ingham                  {
715ebc09c36SJim Ingham                      if (argc >= 3)
716ebc09c36SJim Ingham                      {
717ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
718ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
719998255bfSGreg Clayton                          subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
720ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
721ebc09c36SJim Ingham                          {
722ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
723ebc09c36SJim Ingham                              use_subcommand = true;
724ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
725844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
726ebc09c36SJim Ingham                          }
727ebc09c36SJim Ingham                          else
728ebc09c36SJim Ingham                          {
729f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
730f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
731f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
732ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
733ebc09c36SJim Ingham                              return false;
734ebc09c36SJim Ingham                          }
735ebc09c36SJim Ingham                      }
736ebc09c36SJim Ingham                  }
737ebc09c36SJim Ingham 
738ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
739ebc09c36SJim Ingham 
740ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
741ebc09c36SJim Ingham                  {
742ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
743ebc09c36SJim Ingham                     if (use_subcommand)
744ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
745ca90c47eSCaroline Tice 
746ca90c47eSCaroline Tice                     std::string args_string;
747ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
748ca90c47eSCaroline Tice 
749ca90c47eSCaroline Tice                     if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
750ebc09c36SJim Ingham                     {
751ca90c47eSCaroline Tice                         result.AppendError ("Unable to create requested alias.\n");
752ca90c47eSCaroline Tice                         result.SetStatus (eReturnStatusFailed);
753e7941795SCaroline Tice                         return false;
754867b185dSCaroline Tice                     }
755867b185dSCaroline Tice                  }
756867b185dSCaroline Tice 
757ebc09c36SJim Ingham                  // Create the alias.
758ebc09c36SJim Ingham 
759a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
760a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
761ebc09c36SJim Ingham                  {
762a7015092SGreg Clayton                      OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
763ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
764ebc09c36SJim Ingham                      {
765ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
766a7015092SGreg Clayton                              m_interpreter.RemoveAliasOptions (alias_command.c_str());
767ebc09c36SJim Ingham                      }
768ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
769ebc09c36SJim Ingham                                                      alias_command.c_str());
770ebc09c36SJim Ingham                  }
771ebc09c36SJim Ingham 
772ebc09c36SJim Ingham                  if (use_subcommand)
773a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
774ebc09c36SJim Ingham                  else
775a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
776ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
777a7015092SGreg Clayton                      m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
778ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
779ebc09c36SJim Ingham              }
780ebc09c36SJim Ingham              else
781ebc09c36SJim Ingham              {
782ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
783ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
784e7941795SCaroline Tice                  return false;
785ebc09c36SJim Ingham              }
786ebc09c36SJim Ingham         }
787ebc09c36SJim Ingham 
788ebc09c36SJim Ingham         return result.Succeeded();
789ebc09c36SJim Ingham     }
7905a988416SJim Ingham 
791ebc09c36SJim Ingham };
792ebc09c36SJim Ingham 
793ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
794ebc09c36SJim Ingham //-------------------------------------------------------------------------
795ebc09c36SJim Ingham // CommandObjectCommandsUnalias
796ebc09c36SJim Ingham //-------------------------------------------------------------------------
797ebc09c36SJim Ingham 
7985a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed
799ebc09c36SJim Ingham {
800ebc09c36SJim Ingham public:
801a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
8025a988416SJim Ingham         CommandObjectParsed (interpreter,
8030e5e5a79SGreg Clayton                        "command unalias",
80486ddae50SCaroline Tice                        "Allow the user to remove/delete a user-defined command abbreviation.",
805405fe67fSCaroline Tice                        NULL)
806ebc09c36SJim Ingham     {
807405fe67fSCaroline Tice         CommandArgumentEntry arg;
808405fe67fSCaroline Tice         CommandArgumentData alias_arg;
809405fe67fSCaroline Tice 
810405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
811405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
812405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
813405fe67fSCaroline Tice 
814405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
815405fe67fSCaroline Tice         arg.push_back (alias_arg);
816405fe67fSCaroline Tice 
817405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
818405fe67fSCaroline Tice         m_arguments.push_back (arg);
819ebc09c36SJim Ingham     }
820ebc09c36SJim Ingham 
821*13d21e9aSBruce Mitchener     ~CommandObjectCommandsUnalias() override
822ebc09c36SJim Ingham     {
823ebc09c36SJim Ingham     }
824ebc09c36SJim Ingham 
8255a988416SJim Ingham protected:
826ebc09c36SJim Ingham     bool
827*13d21e9aSBruce Mitchener     DoExecute (Args& args, CommandReturnObject &result) override
828ebc09c36SJim Ingham     {
829ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
830ebc09c36SJim Ingham         CommandObject *cmd_obj;
831ebc09c36SJim Ingham 
832ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
833ebc09c36SJim Ingham         {
834ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
835a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
836ebc09c36SJim Ingham             if (cmd_obj)
837ebc09c36SJim Ingham             {
838a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
839ebc09c36SJim Ingham                 {
840b547278cSGreg Clayton                     if (cmd_obj->IsRemovable())
841b547278cSGreg Clayton                     {
842b547278cSGreg Clayton                         result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
843b547278cSGreg Clayton                                                       command_name);
844b547278cSGreg Clayton                     }
845b547278cSGreg Clayton                     else
846b547278cSGreg Clayton                     {
847ebc09c36SJim Ingham                         result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
848ebc09c36SJim Ingham                                                       command_name);
849b547278cSGreg Clayton                     }
850ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
851ebc09c36SJim Ingham                 }
852ebc09c36SJim Ingham                 else
853ebc09c36SJim Ingham                 {
854ebc09c36SJim Ingham 
855a7015092SGreg Clayton                     if (m_interpreter.RemoveAlias (command_name) == false)
856ebc09c36SJim Ingham                     {
857a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
858ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
859ebc09c36SJim Ingham                                                           command_name);
860ebc09c36SJim Ingham                         else
861ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
862ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
863ebc09c36SJim Ingham                     }
864ebc09c36SJim Ingham                     else
865ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
866ebc09c36SJim Ingham                 }
867ebc09c36SJim Ingham             }
868ebc09c36SJim Ingham             else
869ebc09c36SJim Ingham             {
870ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
871ebc09c36SJim Ingham                                               "current list of commands.\n",
872ebc09c36SJim Ingham                                              command_name);
873ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
874ebc09c36SJim Ingham             }
875ebc09c36SJim Ingham         }
876ebc09c36SJim Ingham         else
877ebc09c36SJim Ingham         {
878ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
879ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
880ebc09c36SJim Ingham         }
881ebc09c36SJim Ingham 
882ebc09c36SJim Ingham         return result.Succeeded();
883ebc09c36SJim Ingham     }
884ebc09c36SJim Ingham };
885ebc09c36SJim Ingham 
886b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete
887b547278cSGreg Clayton //-------------------------------------------------------------------------
888b547278cSGreg Clayton // CommandObjectCommandsDelete
889b547278cSGreg Clayton //-------------------------------------------------------------------------
890b547278cSGreg Clayton 
891b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed
892b547278cSGreg Clayton {
893b547278cSGreg Clayton public:
894b547278cSGreg Clayton     CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
895b547278cSGreg Clayton     CommandObjectParsed (interpreter,
896b547278cSGreg Clayton                          "command delete",
897b547278cSGreg Clayton                          "Allow the user to delete user-defined regular expression, python or multi-word commands.",
898b547278cSGreg Clayton                          NULL)
899b547278cSGreg Clayton     {
900b547278cSGreg Clayton         CommandArgumentEntry arg;
901b547278cSGreg Clayton         CommandArgumentData alias_arg;
902b547278cSGreg Clayton 
903b547278cSGreg Clayton         // Define the first (and only) variant of this arg.
904b547278cSGreg Clayton         alias_arg.arg_type = eArgTypeCommandName;
905b547278cSGreg Clayton         alias_arg.arg_repetition = eArgRepeatPlain;
906b547278cSGreg Clayton 
907b547278cSGreg Clayton         // There is only one variant this argument could be; put it into the argument entry.
908b547278cSGreg Clayton         arg.push_back (alias_arg);
909b547278cSGreg Clayton 
910b547278cSGreg Clayton         // Push the data for the first argument into the m_arguments vector.
911b547278cSGreg Clayton         m_arguments.push_back (arg);
912b547278cSGreg Clayton     }
913b547278cSGreg Clayton 
914*13d21e9aSBruce Mitchener     ~CommandObjectCommandsDelete() override
915b547278cSGreg Clayton     {
916b547278cSGreg Clayton     }
917b547278cSGreg Clayton 
918b547278cSGreg Clayton protected:
919b547278cSGreg Clayton     bool
920*13d21e9aSBruce Mitchener     DoExecute (Args& args, CommandReturnObject &result) override
921b547278cSGreg Clayton     {
922b547278cSGreg Clayton         CommandObject::CommandMap::iterator pos;
923b547278cSGreg Clayton 
924b547278cSGreg Clayton         if (args.GetArgumentCount() != 0)
925b547278cSGreg Clayton         {
926b547278cSGreg Clayton             const char *command_name = args.GetArgumentAtIndex(0);
927b547278cSGreg Clayton             if (m_interpreter.CommandExists (command_name))
928b547278cSGreg Clayton             {
929b547278cSGreg Clayton                 if (m_interpreter.RemoveCommand (command_name))
930b547278cSGreg Clayton                 {
931b547278cSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
932b547278cSGreg Clayton                 }
933b547278cSGreg Clayton                 else
934b547278cSGreg Clayton                 {
935b547278cSGreg Clayton                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
936b547278cSGreg Clayton                                                   command_name);
937b547278cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
938b547278cSGreg Clayton                 }
939b547278cSGreg Clayton             }
940b547278cSGreg Clayton             else
941b547278cSGreg Clayton             {
942b547278cSGreg Clayton                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
943b547278cSGreg Clayton                                               command_name);
944b547278cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
945b547278cSGreg Clayton             }
946b547278cSGreg Clayton         }
947b547278cSGreg Clayton         else
948b547278cSGreg Clayton         {
949b547278cSGreg Clayton             result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
950b547278cSGreg Clayton             result.SetStatus (eReturnStatusFailed);
951b547278cSGreg Clayton         }
952b547278cSGreg Clayton 
953b547278cSGreg Clayton         return result.Succeeded();
954b547278cSGreg Clayton     }
955b547278cSGreg Clayton };
956b547278cSGreg Clayton 
957de164aaaSGreg Clayton //-------------------------------------------------------------------------
958de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
959de164aaaSGreg Clayton //-------------------------------------------------------------------------
9605a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex
961de164aaaSGreg Clayton 
96244d93782SGreg Clayton class CommandObjectCommandsAddRegex :
96344d93782SGreg Clayton     public CommandObjectParsed,
964ea508635SGreg Clayton     public IOHandlerDelegateMultiline
965de164aaaSGreg Clayton {
966de164aaaSGreg Clayton public:
967de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
9685a988416SJim Ingham         CommandObjectParsed (interpreter,
9690e5e5a79SGreg Clayton                        "command regex",
970de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
9710e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
972ea508635SGreg Clayton         IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
973de164aaaSGreg Clayton         m_options (interpreter)
974de164aaaSGreg Clayton     {
975ea671fbdSKate Stone         SetHelpLong(R"(
976ea671fbdSKate Stone )" "This command allows the user to create powerful regular expression commands \
977ea671fbdSKate Stone with substitutions. The regular expressions and substitutions are specified \
978ea671fbdSKate Stone using the regular expression substitution format of:" R"(
979ea671fbdSKate Stone 
980ea671fbdSKate Stone     s/<regex>/<subst>/
981ea671fbdSKate Stone 
982ea671fbdSKate Stone )" "<regex> is a regular expression that can use parenthesis to capture regular \
983ea671fbdSKate Stone expression input and substitute the captured matches in the output using %1 \
984ea671fbdSKate Stone for the first match, %2 for the second, and so on." R"(
985ea671fbdSKate Stone 
986ea671fbdSKate Stone )" "The regular expressions can all be specified on the command line if more than \
987ea671fbdSKate Stone one argument is provided. If just the command name is provided on the command \
988ea671fbdSKate Stone line, then the regular expressions and substitutions can be entered on separate \
989ea671fbdSKate Stone lines, followed by an empty line to terminate the command definition." R"(
990ea671fbdSKate Stone 
991ea671fbdSKate Stone EXAMPLES
992ea671fbdSKate Stone 
993ea671fbdSKate Stone )" "The following example will define a regular expression command named 'f' that \
994ea671fbdSKate Stone will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
995ea671fbdSKate Stone a number follows 'f':" R"(
996ea671fbdSKate Stone 
997ea671fbdSKate Stone     (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
9980e5e5a79SGreg Clayton         );
999de164aaaSGreg Clayton     }
1000de164aaaSGreg Clayton 
1001*13d21e9aSBruce Mitchener     ~CommandObjectCommandsAddRegex() override
1002de164aaaSGreg Clayton     {
1003de164aaaSGreg Clayton     }
1004de164aaaSGreg Clayton 
1005de164aaaSGreg Clayton 
10065a988416SJim Ingham protected:
100744d93782SGreg Clayton 
1008ea508635SGreg Clayton     void
1009ea508635SGreg Clayton     IOHandlerActivated (IOHandler &io_handler) override
101044d93782SGreg Clayton     {
101144d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
101244d93782SGreg Clayton         if (output_sp)
101344d93782SGreg Clayton         {
101444d93782SGreg 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");
101544d93782SGreg Clayton             output_sp->Flush();
101644d93782SGreg Clayton         }
101744d93782SGreg Clayton     }
101844d93782SGreg Clayton 
1019ea508635SGreg Clayton     void
1020ea508635SGreg Clayton     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
102144d93782SGreg Clayton     {
102244d93782SGreg Clayton         io_handler.SetIsDone(true);
102344d93782SGreg Clayton         if (m_regex_cmd_ap.get())
102444d93782SGreg Clayton         {
102544d93782SGreg Clayton             StringList lines;
102644d93782SGreg Clayton             if (lines.SplitIntoLines (data))
102744d93782SGreg Clayton             {
102844d93782SGreg Clayton                 const size_t num_lines = lines.GetSize();
102944d93782SGreg Clayton                 bool check_only = false;
103044d93782SGreg Clayton                 for (size_t i=0; i<num_lines; ++i)
103144d93782SGreg Clayton                 {
103244d93782SGreg Clayton                     llvm::StringRef bytes_strref (lines[i]);
103344d93782SGreg Clayton                     Error error = AppendRegexSubstitution (bytes_strref, check_only);
103444d93782SGreg Clayton                     if (error.Fail())
103544d93782SGreg Clayton                     {
103644d93782SGreg Clayton                         if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
103744d93782SGreg Clayton                         {
103844d93782SGreg Clayton                             StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
103944d93782SGreg Clayton                             out_stream->Printf("error: %s\n", error.AsCString());
104044d93782SGreg Clayton                         }
104144d93782SGreg Clayton                     }
104244d93782SGreg Clayton                 }
104344d93782SGreg Clayton             }
104444d93782SGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
104544d93782SGreg Clayton             {
104644d93782SGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
104744d93782SGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
104844d93782SGreg Clayton             }
104944d93782SGreg Clayton         }
105044d93782SGreg Clayton     }
105144d93782SGreg Clayton 
1052de164aaaSGreg Clayton     bool
1053b0a1814fSEric Christopher     DoExecute (Args& command, CommandReturnObject &result) override
1054de164aaaSGreg Clayton     {
10555a988416SJim Ingham         const size_t argc = command.GetArgumentCount();
10560e5e5a79SGreg Clayton         if (argc == 0)
1057de164aaaSGreg Clayton         {
105869c12ccbSJason Molenda             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
10590e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
10600e5e5a79SGreg Clayton         }
10610e5e5a79SGreg Clayton         else
10620e5e5a79SGreg Clayton         {
10630e5e5a79SGreg Clayton             Error error;
10645a988416SJim Ingham             const char *name = command.GetArgumentAtIndex(0);
1065de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1066de164aaaSGreg Clayton                                                                  name,
1067de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
1068de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
1069b547278cSGreg Clayton                                                                  10,
1070b547278cSGreg Clayton                                                                  0,
1071b547278cSGreg Clayton                                                                  true));
10720e5e5a79SGreg Clayton 
10730e5e5a79SGreg Clayton             if (argc == 1)
10740e5e5a79SGreg Clayton             {
107544d93782SGreg Clayton                 Debugger &debugger = m_interpreter.GetDebugger();
1076e30f11d9SKate Stone                 bool color_prompt = debugger.GetUseColor();
107744d93782SGreg Clayton                 const bool multiple_lines = true; // Get multiple lines
107844d93782SGreg Clayton                 IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
1079e30f11d9SKate Stone                                                                   IOHandler::Type::Other,
108073d80faaSGreg Clayton                                                                   "lldb-regex", // Name of input reader for history
1081ea508635SGreg Clayton                                                                   "> ",         // Prompt
1082e30f11d9SKate Stone                                                                   NULL,         // Continuation prompt
108344d93782SGreg Clayton                                                                   multiple_lines,
1084e30f11d9SKate Stone                                                                   color_prompt,
1085f6913cd7SGreg Clayton                                                                   0,            // Don't show line numbers
108644d93782SGreg Clayton                                                                   *this));
108744d93782SGreg Clayton 
108844d93782SGreg Clayton                 if (io_handler_sp)
1089de164aaaSGreg Clayton                 {
109044d93782SGreg Clayton                     debugger.PushIOHandler(io_handler_sp);
1091de164aaaSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1092de164aaaSGreg Clayton                 }
1093de164aaaSGreg Clayton             }
1094de164aaaSGreg Clayton             else
1095de164aaaSGreg Clayton             {
10960e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
10970e5e5a79SGreg Clayton                 {
10985a988416SJim Ingham                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
109944d93782SGreg Clayton                     bool check_only = false;
110044d93782SGreg Clayton                     error = AppendRegexSubstitution (arg_strref, check_only);
11010e5e5a79SGreg Clayton                     if (error.Fail())
11020e5e5a79SGreg Clayton                         break;
11030e5e5a79SGreg Clayton                 }
11040e5e5a79SGreg Clayton 
11050e5e5a79SGreg Clayton                 if (error.Success())
11060e5e5a79SGreg Clayton                 {
11070e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
11080e5e5a79SGreg Clayton                 }
11090e5e5a79SGreg Clayton             }
11100e5e5a79SGreg Clayton             if (error.Fail())
11110e5e5a79SGreg Clayton             {
11120e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
1113de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1114de164aaaSGreg Clayton             }
11150e5e5a79SGreg Clayton         }
11160e5e5a79SGreg Clayton 
1117de164aaaSGreg Clayton         return result.Succeeded();
1118de164aaaSGreg Clayton     }
1119de164aaaSGreg Clayton 
11200e5e5a79SGreg Clayton     Error
112144d93782SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
1122de164aaaSGreg Clayton     {
11230e5e5a79SGreg Clayton         Error error;
11240e5e5a79SGreg Clayton 
11250e5e5a79SGreg Clayton         if (m_regex_cmd_ap.get() == NULL)
1126de164aaaSGreg Clayton         {
11270e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
11280e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
11290e5e5a79SGreg Clayton                                            regex_sed.data());
11300e5e5a79SGreg Clayton             return error;
1131de164aaaSGreg Clayton         }
11320e5e5a79SGreg Clayton 
11330e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
11340e5e5a79SGreg Clayton 
11350e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
11360e5e5a79SGreg Clayton         {
11370e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
11380e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
11390e5e5a79SGreg Clayton                                            regex_sed.data());
11400e5e5a79SGreg Clayton             return error;
11410e5e5a79SGreg Clayton         }
11420e5e5a79SGreg Clayton 
11430e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
11440e5e5a79SGreg Clayton         {
11450e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
11460e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
11470e5e5a79SGreg Clayton                                            regex_sed.data());
11480e5e5a79SGreg Clayton             return error;
11490e5e5a79SGreg Clayton         }
11500e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
11510e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
11520e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
11530e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
11540e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
11550e5e5a79SGreg Clayton 
11560e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
11570e5e5a79SGreg Clayton         {
1158ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
11590e5e5a79SGreg Clayton                                            separator_char,
11600e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
1161ea508635SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1),
1162ea508635SGreg Clayton                                            (int)regex_sed.size(),
1163ea508635SGreg Clayton                                            regex_sed.data());
11640e5e5a79SGreg Clayton             return error;
11650e5e5a79SGreg Clayton         }
11660e5e5a79SGreg Clayton 
11670e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
11680e5e5a79SGreg Clayton 
11690e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
11700e5e5a79SGreg Clayton         {
1171ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
11720e5e5a79SGreg Clayton                                            separator_char,
11730e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
1174ea508635SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1),
1175ea508635SGreg Clayton                                            (int)regex_sed.size(),
1176ea508635SGreg Clayton                                            regex_sed.data());
11770e5e5a79SGreg Clayton             return error;
11780e5e5a79SGreg Clayton         }
11790e5e5a79SGreg Clayton 
11800e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
11810e5e5a79SGreg Clayton         {
11820e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
11830e5e5a79SGreg Clayton             // separator char
11840e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
11850e5e5a79SGreg Clayton             {
11860e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
11870e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
11880e5e5a79SGreg Clayton                                                regex_sed.data(),
11890e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
11900e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
11910e5e5a79SGreg Clayton                 return error;
11920e5e5a79SGreg Clayton             }
11930e5e5a79SGreg Clayton 
11940e5e5a79SGreg Clayton         }
11950e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
11960e5e5a79SGreg Clayton         {
11970e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
11980e5e5a79SGreg Clayton                                            separator_char,
11990e5e5a79SGreg Clayton                                            separator_char,
12000e5e5a79SGreg Clayton                                            separator_char,
12010e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12020e5e5a79SGreg Clayton                                            regex_sed.data());
12030e5e5a79SGreg Clayton             return error;
12040e5e5a79SGreg Clayton         }
12050e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
12060e5e5a79SGreg Clayton         {
12070e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
12080e5e5a79SGreg Clayton                                            separator_char,
12090e5e5a79SGreg Clayton                                            separator_char,
12100e5e5a79SGreg Clayton                                            separator_char,
12110e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12120e5e5a79SGreg Clayton                                            regex_sed.data());
12130e5e5a79SGreg Clayton             return error;
12140e5e5a79SGreg Clayton         }
121544d93782SGreg Clayton 
121644d93782SGreg Clayton         if (check_only == false)
121744d93782SGreg Clayton         {
12180e5e5a79SGreg Clayton             std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
12190e5e5a79SGreg Clayton             std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
12200e5e5a79SGreg Clayton             m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
12210e5e5a79SGreg Clayton                                              subst.c_str());
122244d93782SGreg Clayton         }
12230e5e5a79SGreg Clayton         return error;
1224de164aaaSGreg Clayton     }
1225de164aaaSGreg Clayton 
1226de164aaaSGreg Clayton     void
12270e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
1228de164aaaSGreg Clayton     {
1229de164aaaSGreg Clayton         if (m_regex_cmd_ap.get())
1230de164aaaSGreg Clayton         {
1231de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
1232de164aaaSGreg Clayton             {
1233de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1234de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1235de164aaaSGreg Clayton             }
1236de164aaaSGreg Clayton         }
1237de164aaaSGreg Clayton     }
1238de164aaaSGreg Clayton 
1239de164aaaSGreg Clayton private:
12407b0992d9SGreg Clayton     std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1241de164aaaSGreg Clayton 
1242de164aaaSGreg Clayton      class CommandOptions : public Options
1243de164aaaSGreg Clayton      {
1244de164aaaSGreg Clayton      public:
1245de164aaaSGreg Clayton 
1246de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
1247de164aaaSGreg Clayton             Options (interpreter)
1248de164aaaSGreg Clayton          {
1249de164aaaSGreg Clayton          }
1250de164aaaSGreg Clayton 
1251*13d21e9aSBruce Mitchener          ~CommandOptions () override {}
1252de164aaaSGreg Clayton 
1253*13d21e9aSBruce Mitchener          Error
1254*13d21e9aSBruce Mitchener          SetOptionValue (uint32_t option_idx, const char *option_arg) override
1255de164aaaSGreg Clayton          {
1256de164aaaSGreg Clayton              Error error;
12573bcdfc0eSGreg Clayton              const int short_option = m_getopt_table[option_idx].val;
1258de164aaaSGreg Clayton 
1259de164aaaSGreg Clayton              switch (short_option)
1260de164aaaSGreg Clayton              {
1261de164aaaSGreg Clayton                  case 'h':
1262de164aaaSGreg Clayton                      m_help.assign (option_arg);
1263de164aaaSGreg Clayton                      break;
1264de164aaaSGreg Clayton                  case 's':
1265de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1266de164aaaSGreg Clayton                      break;
1267de164aaaSGreg Clayton 
1268de164aaaSGreg Clayton                  default:
126986edbf41SGreg Clayton                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1270de164aaaSGreg Clayton                      break;
1271de164aaaSGreg Clayton              }
1272de164aaaSGreg Clayton 
1273de164aaaSGreg Clayton              return error;
1274de164aaaSGreg Clayton          }
1275de164aaaSGreg Clayton 
1276de164aaaSGreg Clayton          void
1277*13d21e9aSBruce Mitchener          OptionParsingStarting () override
1278de164aaaSGreg Clayton          {
1279de164aaaSGreg Clayton              m_help.clear();
1280de164aaaSGreg Clayton              m_syntax.clear();
1281de164aaaSGreg Clayton          }
1282de164aaaSGreg Clayton 
1283de164aaaSGreg Clayton          const OptionDefinition*
1284*13d21e9aSBruce Mitchener          GetDefinitions () override
1285de164aaaSGreg Clayton          {
1286de164aaaSGreg Clayton              return g_option_table;
1287de164aaaSGreg Clayton          }
1288de164aaaSGreg Clayton 
1289de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1290de164aaaSGreg Clayton 
1291de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1292de164aaaSGreg Clayton 
1293de164aaaSGreg Clayton          const char *
1294de164aaaSGreg Clayton          GetHelp ()
1295de164aaaSGreg Clayton          {
1296de164aaaSGreg Clayton              if (m_help.empty())
1297de164aaaSGreg Clayton                  return NULL;
1298de164aaaSGreg Clayton              return m_help.c_str();
1299de164aaaSGreg Clayton          }
1300de164aaaSGreg Clayton          const char *
1301de164aaaSGreg Clayton          GetSyntax ()
1302de164aaaSGreg Clayton          {
1303de164aaaSGreg Clayton              if (m_syntax.empty())
1304de164aaaSGreg Clayton                  return NULL;
1305de164aaaSGreg Clayton              return m_syntax.c_str();
1306de164aaaSGreg Clayton          }
1307de164aaaSGreg Clayton          // Instance variables to hold the values for command options.
1308de164aaaSGreg Clayton      protected:
1309de164aaaSGreg Clayton          std::string m_help;
1310de164aaaSGreg Clayton          std::string m_syntax;
1311de164aaaSGreg Clayton      };
1312de164aaaSGreg Clayton 
1313b0a1814fSEric Christopher      Options *
1314b0a1814fSEric Christopher      GetOptions () override
1315de164aaaSGreg Clayton      {
1316de164aaaSGreg Clayton          return &m_options;
1317de164aaaSGreg Clayton      }
1318de164aaaSGreg Clayton 
13195a988416SJim Ingham      CommandOptions m_options;
1320de164aaaSGreg Clayton };
1321de164aaaSGreg Clayton 
1322de164aaaSGreg Clayton OptionDefinition
1323de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1324de164aaaSGreg Clayton {
1325d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1326d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1327d37221dcSZachary Turner { 0             , false,  NULL   , 0  , 0                , NULL, NULL, 0, eArgTypeNone, NULL }
1328de164aaaSGreg Clayton };
1329de164aaaSGreg Clayton 
1330de164aaaSGreg Clayton 
13315a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw
1332223383edSEnrico Granata {
1333223383edSEnrico Granata private:
1334223383edSEnrico Granata     std::string m_function_name;
13350a305db7SEnrico Granata     ScriptedCommandSynchronicity m_synchro;
1336fac939e9SEnrico Granata     bool m_fetched_help_long;
1337223383edSEnrico Granata 
1338223383edSEnrico Granata public:
1339223383edSEnrico Granata 
1340223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1341223383edSEnrico Granata                                  std::string name,
13420a305db7SEnrico Granata                                  std::string funct,
1343735152e3SEnrico Granata                                  std::string help,
13440a305db7SEnrico Granata                                  ScriptedCommandSynchronicity synch) :
13455a988416SJim Ingham         CommandObjectRaw (interpreter,
1346223383edSEnrico Granata                           name.c_str(),
1347735152e3SEnrico Granata                           NULL,
1348223383edSEnrico Granata                           NULL),
13490a305db7SEnrico Granata         m_function_name(funct),
1350fac939e9SEnrico Granata         m_synchro(synch),
1351fac939e9SEnrico Granata         m_fetched_help_long(false)
1352223383edSEnrico Granata     {
1353735152e3SEnrico Granata         if (!help.empty())
1354735152e3SEnrico Granata             SetHelp(help.c_str());
1355735152e3SEnrico Granata         else
1356735152e3SEnrico Granata         {
1357735152e3SEnrico Granata             StreamString stream;
1358735152e3SEnrico Granata             stream.Printf("For more information run 'help %s'",name.c_str());
1359735152e3SEnrico Granata             SetHelp(stream.GetData());
1360735152e3SEnrico Granata         }
1361223383edSEnrico Granata     }
1362223383edSEnrico Granata 
1363*13d21e9aSBruce Mitchener     ~CommandObjectPythonFunction () override
1364223383edSEnrico Granata     {
1365223383edSEnrico Granata     }
1366223383edSEnrico Granata 
1367*13d21e9aSBruce Mitchener     bool
1368*13d21e9aSBruce Mitchener     IsRemovable () const override
13695a988416SJim Ingham     {
13705a988416SJim Ingham         return true;
13715a988416SJim Ingham     }
13725a988416SJim Ingham 
13735a988416SJim Ingham     const std::string&
13745a988416SJim Ingham     GetFunctionName ()
13755a988416SJim Ingham     {
13765a988416SJim Ingham         return m_function_name;
13775a988416SJim Ingham     }
13785a988416SJim Ingham 
13795a988416SJim Ingham     ScriptedCommandSynchronicity
13805a988416SJim Ingham     GetSynchronicity ()
13815a988416SJim Ingham     {
13825a988416SJim Ingham         return m_synchro;
13835a988416SJim Ingham     }
13845a988416SJim Ingham 
1385*13d21e9aSBruce Mitchener     const char *
1386*13d21e9aSBruce Mitchener     GetHelpLong () override
1387fac939e9SEnrico Granata     {
1388fac939e9SEnrico Granata         if (!m_fetched_help_long)
1389fac939e9SEnrico Granata         {
1390fac939e9SEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1391fac939e9SEnrico Granata             if (scripter)
1392fac939e9SEnrico Granata             {
1393fac939e9SEnrico Granata                 std::string docstring;
1394fac939e9SEnrico Granata                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1395fac939e9SEnrico Granata                 if (!docstring.empty())
1396fac939e9SEnrico Granata                     SetHelpLong(docstring);
1397fac939e9SEnrico Granata             }
1398fac939e9SEnrico Granata         }
1399fac939e9SEnrico Granata         return CommandObjectRaw::GetHelpLong();
1400fac939e9SEnrico Granata     }
1401fac939e9SEnrico Granata 
14025a988416SJim Ingham protected:
1403*13d21e9aSBruce Mitchener     bool
1404*13d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
1405223383edSEnrico Granata     {
1406223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1407223383edSEnrico Granata 
1408223383edSEnrico Granata         Error error;
1409223383edSEnrico Granata 
141070f11f88SJim Ingham         result.SetStatus(eReturnStatusInvalid);
141170f11f88SJim Ingham 
1412223383edSEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1413223383edSEnrico Granata                                                          raw_command_line,
14140a305db7SEnrico Granata                                                          m_synchro,
1415223383edSEnrico Granata                                                          result,
141606be059aSEnrico Granata                                                          error,
141706be059aSEnrico Granata                                                          m_exe_ctx) == false)
1418223383edSEnrico Granata         {
1419223383edSEnrico Granata             result.AppendError(error.AsCString());
1420223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1421223383edSEnrico Granata         }
1422223383edSEnrico Granata         else
142370f11f88SJim Ingham         {
142470f11f88SJim Ingham             // Don't change the status if the command already set it...
142570f11f88SJim Ingham             if (result.GetStatus() == eReturnStatusInvalid)
142670f11f88SJim Ingham             {
14279a71a7d8SDaniel Malea                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1428223383edSEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
142970f11f88SJim Ingham                 else
143070f11f88SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishResult);
143170f11f88SJim Ingham             }
143270f11f88SJim Ingham         }
1433223383edSEnrico Granata 
1434223383edSEnrico Granata         return result.Succeeded();
1435223383edSEnrico Granata     }
1436223383edSEnrico Granata 
1437223383edSEnrico Granata };
1438223383edSEnrico Granata 
14399fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw
14409fe00e52SEnrico Granata {
14419fe00e52SEnrico Granata private:
14420641ca1aSZachary Turner     StructuredData::GenericSP m_cmd_obj_sp;
14439fe00e52SEnrico Granata     ScriptedCommandSynchronicity m_synchro;
14446f79bb2dSEnrico Granata     bool m_fetched_help_short:1;
14456f79bb2dSEnrico Granata     bool m_fetched_help_long:1;
14469fe00e52SEnrico Granata 
14479fe00e52SEnrico Granata public:
14489fe00e52SEnrico Granata 
14499fe00e52SEnrico Granata     CommandObjectScriptingObject (CommandInterpreter &interpreter,
14509fe00e52SEnrico Granata                                   std::string name,
14510641ca1aSZachary Turner                                   StructuredData::GenericSP cmd_obj_sp,
14529fe00e52SEnrico Granata                                   ScriptedCommandSynchronicity synch) :
14539fe00e52SEnrico Granata     CommandObjectRaw (interpreter,
14549fe00e52SEnrico Granata                       name.c_str(),
14559fe00e52SEnrico Granata                       NULL,
14569fe00e52SEnrico Granata                       NULL),
14579fe00e52SEnrico Granata     m_cmd_obj_sp(cmd_obj_sp),
14586f79bb2dSEnrico Granata     m_synchro(synch),
14596f79bb2dSEnrico Granata     m_fetched_help_short(false),
14606f79bb2dSEnrico Granata     m_fetched_help_long(false)
14619fe00e52SEnrico Granata     {
14629fe00e52SEnrico Granata         StreamString stream;
14639fe00e52SEnrico Granata         stream.Printf("For more information run 'help %s'",name.c_str());
14649fe00e52SEnrico Granata         SetHelp(stream.GetData());
1465e87764f2SEnrico Granata         if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1466e87764f2SEnrico Granata             GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
14679fe00e52SEnrico Granata     }
14689fe00e52SEnrico Granata 
1469*13d21e9aSBruce Mitchener     ~CommandObjectScriptingObject () override
14709fe00e52SEnrico Granata     {
14719fe00e52SEnrico Granata     }
14729fe00e52SEnrico Granata 
1473*13d21e9aSBruce Mitchener     bool
1474*13d21e9aSBruce Mitchener     IsRemovable () const override
14759fe00e52SEnrico Granata     {
14769fe00e52SEnrico Granata         return true;
14779fe00e52SEnrico Granata     }
14789fe00e52SEnrico Granata 
14790641ca1aSZachary Turner     StructuredData::GenericSP
14809fe00e52SEnrico Granata     GetImplementingObject ()
14819fe00e52SEnrico Granata     {
14829fe00e52SEnrico Granata         return m_cmd_obj_sp;
14839fe00e52SEnrico Granata     }
14849fe00e52SEnrico Granata 
14859fe00e52SEnrico Granata     ScriptedCommandSynchronicity
14869fe00e52SEnrico Granata     GetSynchronicity ()
14879fe00e52SEnrico Granata     {
14889fe00e52SEnrico Granata         return m_synchro;
14899fe00e52SEnrico Granata     }
14909fe00e52SEnrico Granata 
1491*13d21e9aSBruce Mitchener     const char *
1492*13d21e9aSBruce Mitchener     GetHelp () override
14936f79bb2dSEnrico Granata     {
14946f79bb2dSEnrico Granata         if (!m_fetched_help_short)
14956f79bb2dSEnrico Granata         {
14966f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
14976f79bb2dSEnrico Granata             if (scripter)
14986f79bb2dSEnrico Granata             {
14996f79bb2dSEnrico Granata                 std::string docstring;
15006f79bb2dSEnrico Granata                 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
15016f79bb2dSEnrico Granata                 if (!docstring.empty())
15026f79bb2dSEnrico Granata                     SetHelp(docstring);
15036f79bb2dSEnrico Granata             }
15046f79bb2dSEnrico Granata         }
15056f79bb2dSEnrico Granata         return CommandObjectRaw::GetHelp();
15066f79bb2dSEnrico Granata     }
15076f79bb2dSEnrico Granata 
1508*13d21e9aSBruce Mitchener     const char *
1509*13d21e9aSBruce Mitchener     GetHelpLong () override
15109fe00e52SEnrico Granata     {
15116f79bb2dSEnrico Granata         if (!m_fetched_help_long)
15126f79bb2dSEnrico Granata         {
15136f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
15146f79bb2dSEnrico Granata             if (scripter)
15156f79bb2dSEnrico Granata             {
15166f79bb2dSEnrico Granata                 std::string docstring;
15176f79bb2dSEnrico Granata                 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
15186f79bb2dSEnrico Granata                 if (!docstring.empty())
15196f79bb2dSEnrico Granata                     SetHelpLong(docstring);
15206f79bb2dSEnrico Granata             }
15216f79bb2dSEnrico Granata         }
15229fe00e52SEnrico Granata         return CommandObjectRaw::GetHelpLong();
15239fe00e52SEnrico Granata     }
15249fe00e52SEnrico Granata 
15259fe00e52SEnrico Granata protected:
1526*13d21e9aSBruce Mitchener     bool
1527*13d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
15289fe00e52SEnrico Granata     {
15299fe00e52SEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
15309fe00e52SEnrico Granata 
15319fe00e52SEnrico Granata         Error error;
15329fe00e52SEnrico Granata 
15339fe00e52SEnrico Granata         result.SetStatus(eReturnStatusInvalid);
15349fe00e52SEnrico Granata 
15359fe00e52SEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp,
15369fe00e52SEnrico Granata                                                          raw_command_line,
15379fe00e52SEnrico Granata                                                          m_synchro,
15389fe00e52SEnrico Granata                                                          result,
15399fe00e52SEnrico Granata                                                          error,
15409fe00e52SEnrico Granata                                                          m_exe_ctx) == false)
15419fe00e52SEnrico Granata         {
15429fe00e52SEnrico Granata             result.AppendError(error.AsCString());
15439fe00e52SEnrico Granata             result.SetStatus(eReturnStatusFailed);
15449fe00e52SEnrico Granata         }
15459fe00e52SEnrico Granata         else
15469fe00e52SEnrico Granata         {
15479fe00e52SEnrico Granata             // Don't change the status if the command already set it...
15489fe00e52SEnrico Granata             if (result.GetStatus() == eReturnStatusInvalid)
15499fe00e52SEnrico Granata             {
15509fe00e52SEnrico Granata                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
15519fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
15529fe00e52SEnrico Granata                 else
15539fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishResult);
15549fe00e52SEnrico Granata             }
15559fe00e52SEnrico Granata         }
15569fe00e52SEnrico Granata 
15579fe00e52SEnrico Granata         return result.Succeeded();
15589fe00e52SEnrico Granata     }
15599fe00e52SEnrico Granata 
15609fe00e52SEnrico Granata };
15619fe00e52SEnrico Granata 
1562a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1563a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport
1564a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1565a9dbf432SEnrico Granata 
15665a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed
1567a9dbf432SEnrico Granata {
15685a988416SJim Ingham public:
15695a988416SJim Ingham     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
15705a988416SJim Ingham         CommandObjectParsed (interpreter,
15715a988416SJim Ingham                              "command script import",
15725a988416SJim Ingham                              "Import a scripting module in LLDB.",
15735a988416SJim Ingham                              NULL),
15745a988416SJim Ingham         m_options(interpreter)
15755a988416SJim Ingham     {
15765a988416SJim Ingham         CommandArgumentEntry arg1;
15775a988416SJim Ingham         CommandArgumentData cmd_arg;
15785a988416SJim Ingham 
15795a988416SJim Ingham         // Define the first (and only) variant of this arg.
15805a988416SJim Ingham         cmd_arg.arg_type = eArgTypeFilename;
15813b00e35bSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlus;
15825a988416SJim Ingham 
15835a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
15845a988416SJim Ingham         arg1.push_back (cmd_arg);
15855a988416SJim Ingham 
15865a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
15875a988416SJim Ingham         m_arguments.push_back (arg1);
15885a988416SJim Ingham     }
15895a988416SJim Ingham 
1590*13d21e9aSBruce Mitchener     ~CommandObjectCommandsScriptImport () override
15915a988416SJim Ingham     {
15925a988416SJim Ingham     }
15935a988416SJim Ingham 
1594*13d21e9aSBruce Mitchener     int
15955a988416SJim Ingham     HandleArgumentCompletion (Args &input,
15965a988416SJim Ingham                               int &cursor_index,
15975a988416SJim Ingham                               int &cursor_char_position,
15985a988416SJim Ingham                               OptionElementVector &opt_element_vector,
15995a988416SJim Ingham                               int match_start_point,
16005a988416SJim Ingham                               int max_return_elements,
16015a988416SJim Ingham                               bool &word_complete,
1602*13d21e9aSBruce Mitchener                               StringList &matches) override
16035a988416SJim Ingham     {
16045a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
16055a988416SJim Ingham         completion_str.erase (cursor_char_position);
16065a988416SJim Ingham 
16075a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
16085a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
16095a988416SJim Ingham                                                              completion_str.c_str(),
16105a988416SJim Ingham                                                              match_start_point,
16115a988416SJim Ingham                                                              max_return_elements,
16125a988416SJim Ingham                                                              NULL,
16135a988416SJim Ingham                                                              word_complete,
16145a988416SJim Ingham                                                              matches);
16155a988416SJim Ingham         return matches.GetSize();
16165a988416SJim Ingham     }
16175a988416SJim Ingham 
1618*13d21e9aSBruce Mitchener     Options *
1619*13d21e9aSBruce Mitchener     GetOptions () override
16205a988416SJim Ingham     {
16215a988416SJim Ingham         return &m_options;
16225a988416SJim Ingham     }
16235a988416SJim Ingham 
16245a988416SJim Ingham protected:
16250a305db7SEnrico Granata 
16260a305db7SEnrico Granata     class CommandOptions : public Options
16270a305db7SEnrico Granata     {
16280a305db7SEnrico Granata     public:
16290a305db7SEnrico Granata 
16300a305db7SEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
16310a305db7SEnrico Granata             Options (interpreter)
16320a305db7SEnrico Granata         {
16330a305db7SEnrico Granata         }
16340a305db7SEnrico Granata 
1635*13d21e9aSBruce Mitchener         ~CommandOptions () override {}
16360a305db7SEnrico Granata 
1637*13d21e9aSBruce Mitchener         Error
1638*13d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
16390a305db7SEnrico Granata         {
16400a305db7SEnrico Granata             Error error;
16413bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
16420a305db7SEnrico Granata 
16430a305db7SEnrico Granata             switch (short_option)
16440a305db7SEnrico Granata             {
16450a305db7SEnrico Granata                 case 'r':
16460a305db7SEnrico Granata                     m_allow_reload = true;
16470a305db7SEnrico Granata                     break;
16480a305db7SEnrico Granata                 default:
16490a305db7SEnrico Granata                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
16500a305db7SEnrico Granata                     break;
16510a305db7SEnrico Granata             }
16520a305db7SEnrico Granata 
16530a305db7SEnrico Granata             return error;
16540a305db7SEnrico Granata         }
16550a305db7SEnrico Granata 
16560a305db7SEnrico Granata         void
1657*13d21e9aSBruce Mitchener         OptionParsingStarting () override
16580a305db7SEnrico Granata         {
1659e0c70f1bSEnrico Granata             m_allow_reload = true;
16600a305db7SEnrico Granata         }
16610a305db7SEnrico Granata 
16620a305db7SEnrico Granata         const OptionDefinition*
1663*13d21e9aSBruce Mitchener         GetDefinitions () override
16640a305db7SEnrico Granata         {
16650a305db7SEnrico Granata             return g_option_table;
16660a305db7SEnrico Granata         }
16670a305db7SEnrico Granata 
16680a305db7SEnrico Granata         // Options table: Required for subclasses of Options.
16690a305db7SEnrico Granata 
16700a305db7SEnrico Granata         static OptionDefinition g_option_table[];
16710a305db7SEnrico Granata 
16720a305db7SEnrico Granata         // Instance variables to hold the values for command options.
16730a305db7SEnrico Granata 
16740a305db7SEnrico Granata         bool m_allow_reload;
16750a305db7SEnrico Granata     };
16760a305db7SEnrico Granata 
1677a9dbf432SEnrico Granata     bool
1678*13d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
1679a9dbf432SEnrico Granata     {
1680a9dbf432SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1681a9dbf432SEnrico Granata         {
1682a9dbf432SEnrico Granata             result.AppendError ("only scripting language supported for module importing is currently Python");
1683a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1684a9dbf432SEnrico Granata             return false;
1685a9dbf432SEnrico Granata         }
1686a9dbf432SEnrico Granata 
16875a988416SJim Ingham         size_t argc = command.GetArgumentCount();
16883b00e35bSEnrico Granata         if (0 == argc)
1689a9dbf432SEnrico Granata         {
16903b00e35bSEnrico Granata             result.AppendError("command script import needs one or more arguments");
1691a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1692a9dbf432SEnrico Granata             return false;
1693a9dbf432SEnrico Granata         }
1694a9dbf432SEnrico Granata 
16950e978481SEd Maste         for (size_t i = 0;
16963b00e35bSEnrico Granata              i < argc;
16973b00e35bSEnrico Granata              i++)
16983b00e35bSEnrico Granata         {
16993b00e35bSEnrico Granata             std::string path = command.GetArgumentAtIndex(i);
1700a9dbf432SEnrico Granata             Error error;
1701a9dbf432SEnrico Granata 
1702c9d645d3SGreg Clayton             const bool init_session = true;
1703078551c7SEnrico Granata             // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1704078551c7SEnrico Granata             // commands won't ever be recursively invoked, but it's actually possible to craft
1705078551c7SEnrico Granata             // a Python script that does other "command script imports" in __lldb_init_module
1706078551c7SEnrico Granata             // the real fix is to have recursive commands possible with a CommandInvocation object
1707078551c7SEnrico Granata             // separate from the CommandObject itself, so that recursive command invocations
1708078551c7SEnrico Granata             // won't stomp on each other (wrt to execution contents, options, and more)
1709078551c7SEnrico Granata             m_exe_ctx.Clear();
1710a9dbf432SEnrico Granata             if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
17110a305db7SEnrico Granata                                                                           m_options.m_allow_reload,
1712c9d645d3SGreg Clayton                                                                           init_session,
1713a9dbf432SEnrico Granata                                                                           error))
1714a9dbf432SEnrico Granata             {
1715a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1716a9dbf432SEnrico Granata             }
1717a9dbf432SEnrico Granata             else
1718a9dbf432SEnrico Granata             {
1719a9dbf432SEnrico Granata                 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1720a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1721a9dbf432SEnrico Granata             }
17223b00e35bSEnrico Granata         }
1723a9dbf432SEnrico Granata 
1724a9dbf432SEnrico Granata         return result.Succeeded();
1725a9dbf432SEnrico Granata     }
17260a305db7SEnrico Granata 
17275a988416SJim Ingham     CommandOptions m_options;
1728a9dbf432SEnrico Granata };
1729223383edSEnrico Granata 
17300a305db7SEnrico Granata OptionDefinition
17310a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
17320a305db7SEnrico Granata {
1733d37221dcSZachary 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."},
1734d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
17350a305db7SEnrico Granata };
17360a305db7SEnrico Granata 
17370a305db7SEnrico Granata 
1738223383edSEnrico Granata //-------------------------------------------------------------------------
1739223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1740223383edSEnrico Granata //-------------------------------------------------------------------------
1741223383edSEnrico Granata 
174244d93782SGreg Clayton class CommandObjectCommandsScriptAdd :
174344d93782SGreg Clayton     public CommandObjectParsed,
174444d93782SGreg Clayton     public IOHandlerDelegateMultiline
1745223383edSEnrico Granata {
17465a988416SJim Ingham public:
17475a988416SJim Ingham     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
17485a988416SJim Ingham         CommandObjectParsed (interpreter,
17495a988416SJim Ingham                              "command script add",
17505a988416SJim Ingham                              "Add a scripted function as an LLDB command.",
17515a988416SJim Ingham                              NULL),
1752c3d874a5SGreg Clayton         IOHandlerDelegateMultiline ("DONE"),
17535a988416SJim Ingham         m_options (interpreter)
17545a988416SJim Ingham     {
17555a988416SJim Ingham         CommandArgumentEntry arg1;
17565a988416SJim Ingham         CommandArgumentData cmd_arg;
17575a988416SJim Ingham 
17585a988416SJim Ingham         // Define the first (and only) variant of this arg.
17595a988416SJim Ingham         cmd_arg.arg_type = eArgTypeCommandName;
17605a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
17615a988416SJim Ingham 
17625a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
17635a988416SJim Ingham         arg1.push_back (cmd_arg);
17645a988416SJim Ingham 
17655a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
17665a988416SJim Ingham         m_arguments.push_back (arg1);
17675a988416SJim Ingham     }
17685a988416SJim Ingham 
1769*13d21e9aSBruce Mitchener     ~CommandObjectCommandsScriptAdd () override
17705a988416SJim Ingham     {
17715a988416SJim Ingham     }
17725a988416SJim Ingham 
1773*13d21e9aSBruce Mitchener     Options *
1774*13d21e9aSBruce Mitchener     GetOptions () override
17755a988416SJim Ingham     {
17765a988416SJim Ingham         return &m_options;
17775a988416SJim Ingham     }
17785a988416SJim Ingham 
17795a988416SJim Ingham protected:
1780223383edSEnrico Granata 
1781223383edSEnrico Granata     class CommandOptions : public Options
1782223383edSEnrico Granata     {
1783223383edSEnrico Granata     public:
1784223383edSEnrico Granata 
1785223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
17869fe00e52SEnrico Granata             Options (interpreter),
17879fe00e52SEnrico Granata             m_class_name(),
17889fe00e52SEnrico Granata             m_funct_name(),
17899fe00e52SEnrico Granata             m_short_help(),
17909fe00e52SEnrico Granata             m_synchronicity(eScriptedCommandSynchronicitySynchronous)
1791223383edSEnrico Granata         {
1792223383edSEnrico Granata         }
1793223383edSEnrico Granata 
1794*13d21e9aSBruce Mitchener         ~CommandOptions () override {}
1795223383edSEnrico Granata 
1796*13d21e9aSBruce Mitchener         Error
1797*13d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1798223383edSEnrico Granata         {
1799223383edSEnrico Granata             Error error;
18003bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
1801223383edSEnrico Granata 
1802223383edSEnrico Granata             switch (short_option)
1803223383edSEnrico Granata             {
1804223383edSEnrico Granata                 case 'f':
1805735152e3SEnrico Granata                     if (option_arg)
1806735152e3SEnrico Granata                         m_funct_name.assign(option_arg);
1807735152e3SEnrico Granata                     break;
18089fe00e52SEnrico Granata                 case 'c':
18099fe00e52SEnrico Granata                     if (option_arg)
18109fe00e52SEnrico Granata                         m_class_name.assign(option_arg);
18119fe00e52SEnrico Granata                     break;
1812735152e3SEnrico Granata                 case 'h':
1813735152e3SEnrico Granata                     if (option_arg)
1814735152e3SEnrico Granata                         m_short_help.assign(option_arg);
1815223383edSEnrico Granata                     break;
18160a305db7SEnrico Granata                 case 's':
181744d93782SGreg Clayton                     m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
18180a305db7SEnrico Granata                     if (!error.Success())
18190a305db7SEnrico Granata                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
18200a305db7SEnrico Granata                     break;
1821223383edSEnrico Granata                 default:
182286edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1823223383edSEnrico Granata                     break;
1824223383edSEnrico Granata             }
1825223383edSEnrico Granata 
1826223383edSEnrico Granata             return error;
1827223383edSEnrico Granata         }
1828223383edSEnrico Granata 
1829223383edSEnrico Granata         void
1830*13d21e9aSBruce Mitchener         OptionParsingStarting () override
1831223383edSEnrico Granata         {
18329fe00e52SEnrico Granata             m_class_name.clear();
1833735152e3SEnrico Granata             m_funct_name.clear();
1834735152e3SEnrico Granata             m_short_help.clear();
183544d93782SGreg Clayton             m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1836223383edSEnrico Granata         }
1837223383edSEnrico Granata 
1838223383edSEnrico Granata         const OptionDefinition*
1839*13d21e9aSBruce Mitchener         GetDefinitions () override
1840223383edSEnrico Granata         {
1841223383edSEnrico Granata             return g_option_table;
1842223383edSEnrico Granata         }
1843223383edSEnrico Granata 
1844223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1845223383edSEnrico Granata 
1846223383edSEnrico Granata         static OptionDefinition g_option_table[];
1847223383edSEnrico Granata 
1848223383edSEnrico Granata         // Instance variables to hold the values for command options.
1849223383edSEnrico Granata 
18509fe00e52SEnrico Granata         std::string m_class_name;
1851223383edSEnrico Granata         std::string m_funct_name;
1852735152e3SEnrico Granata         std::string m_short_help;
185344d93782SGreg Clayton         ScriptedCommandSynchronicity m_synchronicity;
1854223383edSEnrico Granata     };
1855223383edSEnrico Granata 
1856*13d21e9aSBruce Mitchener     void
1857*13d21e9aSBruce Mitchener     IOHandlerActivated (IOHandler &io_handler) override
1858223383edSEnrico Granata     {
185944d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
186044d93782SGreg Clayton         if (output_sp)
1861223383edSEnrico Granata         {
186244d93782SGreg Clayton             output_sp->PutCString(g_python_command_instructions);
186344d93782SGreg Clayton             output_sp->Flush();
1864223383edSEnrico Granata         }
1865223383edSEnrico Granata     }
1866223383edSEnrico Granata 
1867223383edSEnrico Granata 
1868*13d21e9aSBruce Mitchener     void
1869*13d21e9aSBruce Mitchener     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
1870223383edSEnrico Granata     {
187144d93782SGreg Clayton         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
187244d93782SGreg Clayton 
187344d93782SGreg Clayton         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
187444d93782SGreg Clayton         if (interpreter)
187544d93782SGreg Clayton         {
187644d93782SGreg Clayton 
187744d93782SGreg Clayton             StringList lines;
187844d93782SGreg Clayton             lines.SplitIntoLines(data);
187944d93782SGreg Clayton             if (lines.GetSize() > 0)
188044d93782SGreg Clayton             {
1881a73b7df7SEnrico Granata                 std::string funct_name_str;
188244d93782SGreg Clayton                 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1883223383edSEnrico Granata                 {
1884a73b7df7SEnrico Granata                     if (funct_name_str.empty())
1885223383edSEnrico Granata                     {
188644d93782SGreg Clayton                         error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
188744d93782SGreg Clayton                         error_sp->Flush();
1888223383edSEnrico Granata                     }
188944d93782SGreg Clayton                     else
189044d93782SGreg Clayton                     {
1891223383edSEnrico Granata                         // everything should be fine now, let's add this alias
1892223383edSEnrico Granata 
1893223383edSEnrico Granata                         CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1894223383edSEnrico Granata                                                                                         m_cmd_name,
1895a73b7df7SEnrico Granata                                                                                         funct_name_str.c_str(),
1896735152e3SEnrico Granata                                                                                         m_short_help,
189744d93782SGreg Clayton                                                                                         m_synchronicity));
1898223383edSEnrico Granata 
18990a305db7SEnrico Granata                         if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1900223383edSEnrico Granata                         {
190144d93782SGreg Clayton                             error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
190244d93782SGreg Clayton                             error_sp->Flush();
1903223383edSEnrico Granata                         }
1904223383edSEnrico Granata                     }
190544d93782SGreg Clayton                 }
190644d93782SGreg Clayton                 else
190744d93782SGreg Clayton                 {
190844d93782SGreg Clayton                     error_sp->Printf ("error: unable to create function, didn't add python command.\n");
190944d93782SGreg Clayton                     error_sp->Flush();
191044d93782SGreg Clayton                 }
191144d93782SGreg Clayton             }
191244d93782SGreg Clayton             else
191344d93782SGreg Clayton             {
191444d93782SGreg Clayton                 error_sp->Printf ("error: empty function, didn't add python command.\n");
191544d93782SGreg Clayton                 error_sp->Flush();
191644d93782SGreg Clayton             }
191744d93782SGreg Clayton         }
191844d93782SGreg Clayton         else
191944d93782SGreg Clayton         {
192044d93782SGreg Clayton             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
192144d93782SGreg Clayton             error_sp->Flush();
192244d93782SGreg Clayton         }
192344d93782SGreg Clayton 
192444d93782SGreg Clayton         io_handler.SetIsDone(true);
192544d93782SGreg Clayton 
192644d93782SGreg Clayton 
192744d93782SGreg Clayton     }
1928223383edSEnrico Granata 
19295a988416SJim Ingham protected:
1930223383edSEnrico Granata     bool
1931*13d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
1932223383edSEnrico Granata     {
193399f0b8f9SEnrico Granata 
193499f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
193599f0b8f9SEnrico Granata         {
193699f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
193799f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
193899f0b8f9SEnrico Granata             return false;
193999f0b8f9SEnrico Granata         }
194099f0b8f9SEnrico Granata 
19415a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1942223383edSEnrico Granata 
1943223383edSEnrico Granata         if (argc != 1)
1944223383edSEnrico Granata         {
1945223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
1946223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1947223383edSEnrico Granata             return false;
1948223383edSEnrico Granata         }
1949223383edSEnrico Granata 
1950735152e3SEnrico Granata         // Store the options in case we get multi-line input
195144d93782SGreg Clayton         m_cmd_name = command.GetArgumentAtIndex(0);
1952735152e3SEnrico Granata         m_short_help.assign(m_options.m_short_help);
195344d93782SGreg Clayton         m_synchronicity = m_options.m_synchronicity;
1954223383edSEnrico Granata 
19559fe00e52SEnrico Granata         if (m_options.m_class_name.empty())
19569fe00e52SEnrico Granata         {
1957223383edSEnrico Granata             if (m_options.m_funct_name.empty())
1958223383edSEnrico Granata             {
195944d93782SGreg Clayton                 m_interpreter.GetPythonCommandsFromIOHandler ("     ",  // Prompt
196044d93782SGreg Clayton                                                               *this,    // IOHandlerDelegate
196144d93782SGreg Clayton                                                               true,     // Run IOHandler in async mode
196244d93782SGreg Clayton                                                               NULL);    // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1963223383edSEnrico Granata             }
1964223383edSEnrico Granata             else
1965223383edSEnrico Granata             {
19660a305db7SEnrico Granata                 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
196744d93782SGreg Clayton                                                                         m_cmd_name,
19680a305db7SEnrico Granata                                                                         m_options.m_funct_name,
1969735152e3SEnrico Granata                                                                         m_options.m_short_help,
197044d93782SGreg Clayton                                                                         m_synchronicity));
197144d93782SGreg Clayton                 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
1972223383edSEnrico Granata                 {
1973223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1974223383edSEnrico Granata                 }
1975223383edSEnrico Granata                 else
1976223383edSEnrico Granata                 {
1977223383edSEnrico Granata                     result.AppendError("cannot add command");
1978223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
1979223383edSEnrico Granata                 }
1980223383edSEnrico Granata             }
19819fe00e52SEnrico Granata         }
19829fe00e52SEnrico Granata         else
19839fe00e52SEnrico Granata         {
19849fe00e52SEnrico Granata             ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
19859fe00e52SEnrico Granata             if (!interpreter)
19869fe00e52SEnrico Granata             {
19879fe00e52SEnrico Granata                 result.AppendError("cannot find ScriptInterpreter");
19889fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
19899fe00e52SEnrico Granata                 return false;
19909fe00e52SEnrico Granata             }
19919fe00e52SEnrico Granata 
19929fe00e52SEnrico Granata             auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
19939fe00e52SEnrico Granata             if (!cmd_obj_sp)
19949fe00e52SEnrico Granata             {
19959fe00e52SEnrico Granata                 result.AppendError("cannot create helper object");
19969fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
19979fe00e52SEnrico Granata                 return false;
19989fe00e52SEnrico Granata             }
19999fe00e52SEnrico Granata 
20009fe00e52SEnrico Granata             CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
20019fe00e52SEnrico Granata                                                                      m_cmd_name,
20029fe00e52SEnrico Granata                                                                      cmd_obj_sp,
20039fe00e52SEnrico Granata                                                                      m_synchronicity));
20049fe00e52SEnrico Granata             if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
20059fe00e52SEnrico Granata             {
20069fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
20079fe00e52SEnrico Granata             }
20089fe00e52SEnrico Granata             else
20099fe00e52SEnrico Granata             {
20109fe00e52SEnrico Granata                 result.AppendError("cannot add command");
20119fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
20129fe00e52SEnrico Granata             }
20139fe00e52SEnrico Granata         }
2014223383edSEnrico Granata 
2015223383edSEnrico Granata         return result.Succeeded();
2016223383edSEnrico Granata 
2017223383edSEnrico Granata     }
20185a988416SJim Ingham 
20195a988416SJim Ingham     CommandOptions m_options;
202044d93782SGreg Clayton     std::string m_cmd_name;
2021735152e3SEnrico Granata     std::string m_short_help;
202244d93782SGreg Clayton     ScriptedCommandSynchronicity m_synchronicity;
2023223383edSEnrico Granata };
2024223383edSEnrico Granata 
20250a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] =
20260a305db7SEnrico Granata {
20270a305db7SEnrico Granata     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
20280a305db7SEnrico Granata     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
20290a305db7SEnrico Granata     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
20300a305db7SEnrico Granata     { 0, NULL, NULL }
20310a305db7SEnrico Granata };
20320a305db7SEnrico Granata 
2033223383edSEnrico Granata OptionDefinition
2034223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2035223383edSEnrico Granata {
2036d37221dcSZachary 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."},
20379fe00e52SEnrico 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."},
20389370d278SEnrico Granata     { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."},
20399fe00e52SEnrico 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."},
2040d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2041223383edSEnrico Granata };
2042223383edSEnrico Granata 
2043223383edSEnrico Granata //-------------------------------------------------------------------------
2044223383edSEnrico Granata // CommandObjectCommandsScriptList
2045223383edSEnrico Granata //-------------------------------------------------------------------------
2046223383edSEnrico Granata 
20475a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed
2048223383edSEnrico Granata {
2049223383edSEnrico Granata private:
2050223383edSEnrico Granata 
2051223383edSEnrico Granata public:
2052223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
20535a988416SJim Ingham     CommandObjectParsed (interpreter,
2054223383edSEnrico Granata                    "command script list",
2055223383edSEnrico Granata                    "List defined scripted commands.",
2056223383edSEnrico Granata                    NULL)
2057223383edSEnrico Granata     {
2058223383edSEnrico Granata     }
2059223383edSEnrico Granata 
2060*13d21e9aSBruce Mitchener     ~CommandObjectCommandsScriptList () override
2061223383edSEnrico Granata     {
2062223383edSEnrico Granata     }
2063223383edSEnrico Granata 
2064223383edSEnrico Granata     bool
2065*13d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2066223383edSEnrico Granata     {
2067223383edSEnrico Granata 
2068223383edSEnrico Granata         m_interpreter.GetHelp(result,
2069223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
2070223383edSEnrico Granata 
2071223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2072223383edSEnrico Granata 
2073223383edSEnrico Granata         return true;
2074223383edSEnrico Granata 
2075223383edSEnrico Granata 
2076223383edSEnrico Granata     }
2077223383edSEnrico Granata };
2078223383edSEnrico Granata 
2079223383edSEnrico Granata //-------------------------------------------------------------------------
2080223383edSEnrico Granata // CommandObjectCommandsScriptClear
2081223383edSEnrico Granata //-------------------------------------------------------------------------
2082223383edSEnrico Granata 
20835a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed
2084223383edSEnrico Granata {
2085223383edSEnrico Granata private:
2086223383edSEnrico Granata 
2087223383edSEnrico Granata public:
2088223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
20895a988416SJim Ingham         CommandObjectParsed (interpreter,
2090223383edSEnrico Granata                              "command script clear",
2091223383edSEnrico Granata                              "Delete all scripted commands.",
2092223383edSEnrico Granata                              NULL)
2093223383edSEnrico Granata     {
2094223383edSEnrico Granata     }
2095223383edSEnrico Granata 
2096*13d21e9aSBruce Mitchener     ~CommandObjectCommandsScriptClear () override
2097223383edSEnrico Granata     {
2098223383edSEnrico Granata     }
2099223383edSEnrico Granata 
21005a988416SJim Ingham protected:
2101223383edSEnrico Granata     bool
2102*13d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2103223383edSEnrico Granata     {
2104223383edSEnrico Granata 
2105223383edSEnrico Granata         m_interpreter.RemoveAllUser();
2106223383edSEnrico Granata 
2107223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2108223383edSEnrico Granata 
2109223383edSEnrico Granata         return true;
2110223383edSEnrico Granata     }
2111223383edSEnrico Granata };
2112223383edSEnrico Granata 
2113223383edSEnrico Granata //-------------------------------------------------------------------------
2114223383edSEnrico Granata // CommandObjectCommandsScriptDelete
2115223383edSEnrico Granata //-------------------------------------------------------------------------
2116223383edSEnrico Granata 
21175a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed
2118223383edSEnrico Granata {
2119223383edSEnrico Granata public:
2120223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
21215a988416SJim Ingham         CommandObjectParsed (interpreter,
2122223383edSEnrico Granata                              "command script delete",
2123223383edSEnrico Granata                              "Delete a scripted command.",
2124223383edSEnrico Granata                              NULL)
2125223383edSEnrico Granata     {
2126223383edSEnrico Granata         CommandArgumentEntry arg1;
2127223383edSEnrico Granata         CommandArgumentData cmd_arg;
2128223383edSEnrico Granata 
2129223383edSEnrico Granata         // Define the first (and only) variant of this arg.
2130223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
2131223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
2132223383edSEnrico Granata 
2133223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
2134223383edSEnrico Granata         arg1.push_back (cmd_arg);
2135223383edSEnrico Granata 
2136223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
2137223383edSEnrico Granata         m_arguments.push_back (arg1);
2138223383edSEnrico Granata     }
2139223383edSEnrico Granata 
2140*13d21e9aSBruce Mitchener     ~CommandObjectCommandsScriptDelete () override
2141223383edSEnrico Granata     {
2142223383edSEnrico Granata     }
2143223383edSEnrico Granata 
21445a988416SJim Ingham protected:
2145223383edSEnrico Granata     bool
2146*13d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2147223383edSEnrico Granata     {
2148223383edSEnrico Granata 
21495a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2150223383edSEnrico Granata 
2151223383edSEnrico Granata         if (argc != 1)
2152223383edSEnrico Granata         {
2153223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
2154223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2155223383edSEnrico Granata             return false;
2156223383edSEnrico Granata         }
2157223383edSEnrico Granata 
21585a988416SJim Ingham         const char* cmd_name = command.GetArgumentAtIndex(0);
2159223383edSEnrico Granata 
2160223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2161223383edSEnrico Granata         {
2162223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
2163223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
2164223383edSEnrico Granata         }
2165223383edSEnrico Granata         else
2166223383edSEnrico Granata         {
2167223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
2168223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2169223383edSEnrico Granata         }
2170223383edSEnrico Granata 
2171223383edSEnrico Granata         return result.Succeeded();
2172223383edSEnrico Granata 
2173223383edSEnrico Granata     }
2174223383edSEnrico Granata };
2175223383edSEnrico Granata 
2176223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
2177223383edSEnrico Granata 
2178223383edSEnrico Granata //-------------------------------------------------------------------------
2179223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
2180223383edSEnrico Granata //-------------------------------------------------------------------------
2181223383edSEnrico Granata 
2182223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2183223383edSEnrico Granata {
2184223383edSEnrico Granata public:
2185223383edSEnrico Granata     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2186223383edSEnrico Granata     CommandObjectMultiword (interpreter,
2187223383edSEnrico Granata                             "command script",
2188223383edSEnrico Granata                             "A set of commands for managing or customizing script commands.",
2189223383edSEnrico Granata                             "command script <subcommand> [<subcommand-options>]")
2190223383edSEnrico Granata     {
2191223383edSEnrico Granata         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2192223383edSEnrico Granata         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2193223383edSEnrico Granata         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
2194223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
2195a9dbf432SEnrico Granata         LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
2196223383edSEnrico Granata     }
2197223383edSEnrico Granata 
2198*13d21e9aSBruce Mitchener     ~CommandObjectMultiwordCommandsScript () override
2199223383edSEnrico Granata     {
2200223383edSEnrico Granata     }
2201223383edSEnrico Granata 
2202223383edSEnrico Granata };
2203223383edSEnrico Granata 
2204223383edSEnrico Granata 
2205ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
2206ebc09c36SJim Ingham 
2207ebc09c36SJim Ingham //-------------------------------------------------------------------------
2208ebc09c36SJim Ingham // CommandObjectMultiwordCommands
2209ebc09c36SJim Ingham //-------------------------------------------------------------------------
2210ebc09c36SJim Ingham 
2211ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
2212a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
22130e5e5a79SGreg Clayton                             "command",
22143f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
22150e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
2216ebc09c36SJim Ingham {
2217a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2218a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2219a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
2220b547278cSGreg Clayton     LoadSubCommand ("delete",  CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
2221de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
2222a5a97ebeSJim Ingham     LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2223223383edSEnrico Granata     LoadSubCommand ("script",  CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
2224ebc09c36SJim Ingham }
2225ebc09c36SJim Ingham 
2226ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
2227ebc09c36SJim Ingham {
2228ebc09c36SJim Ingham }
2229ebc09c36SJim Ingham 
2230