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 // C Includes
11ebc09c36SJim Ingham // C++ Includes
12ebc09c36SJim Ingham // Other libraries and framework includes
130e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h"
140e5e5a79SGreg Clayton 
15ebc09c36SJim Ingham // Project includes
166e3d8e7fSEugene Zelenko #include "CommandObjectCommands.h"
1746d4aa21SEnrico Granata #include "CommandObjectHelp.h"
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"
2745d0e238SEnrico Granata #include "lldb/Interpreter/OptionValueString.h"
287594f14fSEnrico Granata #include "lldb/Interpreter/OptionValueUInt64.h"
29ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
3099f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h"
31ebc09c36SJim Ingham 
32ebc09c36SJim Ingham using namespace lldb;
33ebc09c36SJim Ingham using namespace lldb_private;
34ebc09c36SJim Ingham 
35ebc09c36SJim Ingham //-------------------------------------------------------------------------
36ebc09c36SJim Ingham // CommandObjectCommandsSource
37ebc09c36SJim Ingham //-------------------------------------------------------------------------
38ebc09c36SJim Ingham 
395a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed
40a5a97ebeSJim Ingham {
415a988416SJim Ingham public:
425a988416SJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
435a988416SJim Ingham         CommandObjectParsed(interpreter,
445a988416SJim Ingham                             "command history",
455a988416SJim Ingham                             "Dump the history of commands in this session.",
466e3d8e7fSEugene Zelenko                             nullptr),
475a988416SJim Ingham         m_options (interpreter)
485a988416SJim Ingham     {
495a988416SJim Ingham     }
505a988416SJim Ingham 
516e3d8e7fSEugene Zelenko     ~CommandObjectCommandsHistory() override = default;
525a988416SJim Ingham 
5313d21e9aSBruce Mitchener     Options *
5413d21e9aSBruce Mitchener     GetOptions () override
555a988416SJim Ingham     {
565a988416SJim Ingham         return &m_options;
575a988416SJim Ingham     }
585a988416SJim Ingham 
595a988416SJim Ingham protected:
60a5a97ebeSJim Ingham     class CommandOptions : public Options
61a5a97ebeSJim Ingham     {
62a5a97ebeSJim Ingham     public:
63a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
647594f14fSEnrico Granata             Options (interpreter),
657594f14fSEnrico Granata             m_start_idx(0),
667594f14fSEnrico Granata             m_stop_idx(0),
677594f14fSEnrico Granata             m_count(0),
6863123b64SEnrico Granata             m_clear(false)
69a5a97ebeSJim Ingham         {
70a5a97ebeSJim Ingham         }
71a5a97ebeSJim Ingham 
726e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
73a5a97ebeSJim Ingham 
7413d21e9aSBruce Mitchener         Error
7513d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
76a5a97ebeSJim Ingham         {
77a5a97ebeSJim Ingham             Error error;
783bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
79a5a97ebeSJim Ingham 
80a5a97ebeSJim Ingham             switch (short_option)
81a5a97ebeSJim Ingham             {
82a5a97ebeSJim Ingham                 case 'c':
83c95f7e2aSPavel Labath                     error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
84a5a97ebeSJim Ingham                     break;
85a5a97ebeSJim Ingham                 case 's':
867594f14fSEnrico Granata                     if (option_arg && strcmp("end", option_arg) == 0)
877594f14fSEnrico Granata                     {
887594f14fSEnrico Granata                         m_start_idx.SetCurrentValue(UINT64_MAX);
897594f14fSEnrico Granata                         m_start_idx.SetOptionWasSet();
907594f14fSEnrico Granata                     }
917594f14fSEnrico Granata                     else
92c95f7e2aSPavel Labath                         error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
937594f14fSEnrico Granata                     break;
947594f14fSEnrico Granata                 case 'e':
95c95f7e2aSPavel Labath                     error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
967594f14fSEnrico Granata                     break;
9763123b64SEnrico Granata                 case 'C':
9863123b64SEnrico Granata                     m_clear.SetCurrentValue(true);
9963123b64SEnrico Granata                     m_clear.SetOptionWasSet();
100a5a97ebeSJim Ingham                     break;
101a5a97ebeSJim Ingham                 default:
10286edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
103a5a97ebeSJim Ingham                     break;
104a5a97ebeSJim Ingham             }
105a5a97ebeSJim Ingham 
106a5a97ebeSJim Ingham             return error;
107a5a97ebeSJim Ingham         }
108a5a97ebeSJim Ingham 
109a5a97ebeSJim Ingham         void
11013d21e9aSBruce Mitchener         OptionParsingStarting () override
111a5a97ebeSJim Ingham         {
1127594f14fSEnrico Granata             m_start_idx.Clear();
1137594f14fSEnrico Granata             m_stop_idx.Clear();
1147594f14fSEnrico Granata             m_count.Clear();
11563123b64SEnrico Granata             m_clear.Clear();
116a5a97ebeSJim Ingham         }
117a5a97ebeSJim Ingham 
118a5a97ebeSJim Ingham         const OptionDefinition*
11913d21e9aSBruce Mitchener         GetDefinitions () override
120a5a97ebeSJim Ingham         {
121a5a97ebeSJim Ingham             return g_option_table;
122a5a97ebeSJim Ingham         }
123a5a97ebeSJim Ingham 
124a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
125a5a97ebeSJim Ingham 
126a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
127a5a97ebeSJim Ingham 
128a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
129a5a97ebeSJim Ingham 
1307594f14fSEnrico Granata         OptionValueUInt64 m_start_idx;
1317594f14fSEnrico Granata         OptionValueUInt64 m_stop_idx;
1327594f14fSEnrico Granata         OptionValueUInt64 m_count;
13363123b64SEnrico Granata         OptionValueBoolean m_clear;
134a5a97ebeSJim Ingham     };
135a5a97ebeSJim Ingham 
136a5a97ebeSJim Ingham     bool
13713d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
138a5a97ebeSJim Ingham     {
13963123b64SEnrico Granata         if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
1407594f14fSEnrico Granata         {
1417594f14fSEnrico Granata             m_interpreter.GetCommandHistory().Clear();
1427594f14fSEnrico Granata             result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
1437594f14fSEnrico Granata         }
1447594f14fSEnrico Granata         else
1457594f14fSEnrico Granata         {
1467594f14fSEnrico Granata             if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
1477594f14fSEnrico Granata             {
1487594f14fSEnrico Granata                 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
1497594f14fSEnrico Granata                 result.SetStatus(lldb::eReturnStatusFailed);
1507594f14fSEnrico Granata             }
1517594f14fSEnrico Granata             else
1527594f14fSEnrico Granata             {
15384400ec7SVirgile Bello                 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
15484400ec7SVirgile Bello                 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
15584400ec7SVirgile Bello                 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
156a5a97ebeSJim Ingham 
1577594f14fSEnrico Granata                 const CommandHistory& history(m_interpreter.GetCommandHistory());
1587594f14fSEnrico Granata 
1597594f14fSEnrico Granata                 if (start_idx.first && start_idx.second == UINT64_MAX)
1607594f14fSEnrico Granata                 {
1617594f14fSEnrico Granata                     if (count.first)
1627594f14fSEnrico Granata                     {
1637594f14fSEnrico Granata                         start_idx.second = history.GetSize() - count.second;
1647594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1657594f14fSEnrico Granata                     }
1667594f14fSEnrico Granata                     else if (stop_idx.first)
1677594f14fSEnrico Granata                     {
1687594f14fSEnrico Granata                         start_idx.second = stop_idx.second;
1697594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1707594f14fSEnrico Granata                     }
1717594f14fSEnrico Granata                     else
1727594f14fSEnrico Granata                     {
1737594f14fSEnrico Granata                         start_idx.second = 0;
1747594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1757594f14fSEnrico Granata                     }
1767594f14fSEnrico Granata                 }
1777594f14fSEnrico Granata                 else
1787594f14fSEnrico Granata                 {
1797594f14fSEnrico Granata                     if (!start_idx.first && !stop_idx.first && !count.first)
1807594f14fSEnrico Granata                     {
1817594f14fSEnrico Granata                         start_idx.second = 0;
1827594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1837594f14fSEnrico Granata                     }
1847594f14fSEnrico Granata                     else if (start_idx.first)
1857594f14fSEnrico Granata                     {
1867594f14fSEnrico Granata                         if (count.first)
1877594f14fSEnrico Granata                         {
1887594f14fSEnrico Granata                             stop_idx.second = start_idx.second + count.second - 1;
1897594f14fSEnrico Granata                         }
1907594f14fSEnrico Granata                         else if (!stop_idx.first)
1917594f14fSEnrico Granata                         {
1927594f14fSEnrico Granata                             stop_idx.second = history.GetSize() - 1;
1937594f14fSEnrico Granata                         }
1947594f14fSEnrico Granata                     }
1957594f14fSEnrico Granata                     else if (stop_idx.first)
1967594f14fSEnrico Granata                     {
1977594f14fSEnrico Granata                         if (count.first)
1987594f14fSEnrico Granata                         {
1997594f14fSEnrico Granata                             if (stop_idx.second >= count.second)
2007594f14fSEnrico Granata                                 start_idx.second = stop_idx.second - count.second + 1;
2017594f14fSEnrico Granata                             else
2027594f14fSEnrico Granata                                 start_idx.second = 0;
2037594f14fSEnrico Granata                         }
2047594f14fSEnrico Granata                     }
2057594f14fSEnrico Granata                     else /* if (count.first) */
2067594f14fSEnrico Granata                     {
2077594f14fSEnrico Granata                         start_idx.second = 0;
2087594f14fSEnrico Granata                         stop_idx.second = count.second - 1;
2097594f14fSEnrico Granata                     }
2107594f14fSEnrico Granata                 }
2117594f14fSEnrico Granata                 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
2127594f14fSEnrico Granata             }
2137594f14fSEnrico Granata         }
214a5a97ebeSJim Ingham         return result.Succeeded();
215a5a97ebeSJim Ingham 
216a5a97ebeSJim Ingham     }
2175a988416SJim Ingham 
2185a988416SJim Ingham     CommandOptions m_options;
219a5a97ebeSJim Ingham };
220a5a97ebeSJim Ingham 
221a5a97ebeSJim Ingham OptionDefinition
222a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
223a5a97ebeSJim Ingham {
2246e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
2256e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger,  "Index at which to start printing history commands (or end to mean tail mode)."},
2266e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
2276e3d8e7fSEugene Zelenko { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeBoolean,    "Clears the current command history."},
2286e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
229a5a97ebeSJim Ingham };
230a5a97ebeSJim Ingham 
231a5a97ebeSJim Ingham //-------------------------------------------------------------------------
232a5a97ebeSJim Ingham // CommandObjectCommandsSource
233a5a97ebeSJim Ingham //-------------------------------------------------------------------------
234a5a97ebeSJim Ingham 
2355a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed
236ebc09c36SJim Ingham {
2375a988416SJim Ingham public:
238*7428a18cSKate Stone     CommandObjectCommandsSource(CommandInterpreter &interpreter)
239*7428a18cSKate Stone         : CommandObjectParsed(interpreter, "command source", "Read and execute LLDB commands from the file <filename>.",
2406e3d8e7fSEugene Zelenko                               nullptr),
2415a988416SJim Ingham           m_options(interpreter)
2425a988416SJim Ingham     {
2435a988416SJim Ingham         CommandArgumentEntry arg;
2445a988416SJim Ingham         CommandArgumentData file_arg;
2455a988416SJim Ingham 
2465a988416SJim Ingham         // Define the first (and only) variant of this arg.
2475a988416SJim Ingham         file_arg.arg_type = eArgTypeFilename;
2485a988416SJim Ingham         file_arg.arg_repetition = eArgRepeatPlain;
2495a988416SJim Ingham 
2505a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
2515a988416SJim Ingham         arg.push_back (file_arg);
2525a988416SJim Ingham 
2535a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
2545a988416SJim Ingham         m_arguments.push_back (arg);
2555a988416SJim Ingham     }
2565a988416SJim Ingham 
2576e3d8e7fSEugene Zelenko     ~CommandObjectCommandsSource() override = default;
2585a988416SJim Ingham 
25913d21e9aSBruce Mitchener     const char*
26013d21e9aSBruce Mitchener     GetRepeatCommand (Args &current_command_args, uint32_t index) override
2615a988416SJim Ingham     {
2625a988416SJim Ingham         return "";
2635a988416SJim Ingham     }
2645a988416SJim Ingham 
26513d21e9aSBruce Mitchener     int
2665a988416SJim Ingham     HandleArgumentCompletion (Args &input,
2675a988416SJim Ingham                               int &cursor_index,
2685a988416SJim Ingham                               int &cursor_char_position,
2695a988416SJim Ingham                               OptionElementVector &opt_element_vector,
2705a988416SJim Ingham                               int match_start_point,
2715a988416SJim Ingham                               int max_return_elements,
2725a988416SJim Ingham                               bool &word_complete,
27313d21e9aSBruce Mitchener                               StringList &matches) override
2745a988416SJim Ingham     {
2755a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2765a988416SJim Ingham         completion_str.erase (cursor_char_position);
2775a988416SJim Ingham 
2785a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
2795a988416SJim Ingham                                                             CommandCompletions::eDiskFileCompletion,
2805a988416SJim Ingham                                                             completion_str.c_str(),
2815a988416SJim Ingham                                                             match_start_point,
2825a988416SJim Ingham                                                             max_return_elements,
2836e3d8e7fSEugene Zelenko                                                             nullptr,
2845a988416SJim Ingham                                                             word_complete,
2855a988416SJim Ingham                                                             matches);
2865a988416SJim Ingham         return matches.GetSize();
2875a988416SJim Ingham     }
2885a988416SJim Ingham 
28913d21e9aSBruce Mitchener     Options *
29013d21e9aSBruce Mitchener     GetOptions () override
2915a988416SJim Ingham     {
2925a988416SJim Ingham         return &m_options;
2935a988416SJim Ingham     }
2945a988416SJim Ingham 
2955a988416SJim Ingham protected:
296e16c50a1SJim Ingham     class CommandOptions : public Options
297e16c50a1SJim Ingham     {
298e16c50a1SJim Ingham     public:
299eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
300012d4fcaSEnrico Granata             Options (interpreter),
301340b0309SGreg Clayton             m_stop_on_error (true),
302340b0309SGreg Clayton             m_silent_run (false),
303340b0309SGreg Clayton             m_stop_on_continue (true)
304eb0103f2SGreg Clayton         {
305eb0103f2SGreg Clayton         }
306e16c50a1SJim Ingham 
3076e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
308e16c50a1SJim Ingham 
30913d21e9aSBruce Mitchener         Error
31013d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
311e16c50a1SJim Ingham         {
312e16c50a1SJim Ingham             Error error;
3133bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
314e16c50a1SJim Ingham 
315e16c50a1SJim Ingham             switch (short_option)
316e16c50a1SJim Ingham             {
317e16c50a1SJim Ingham                 case 'e':
318c95f7e2aSPavel Labath                     error = m_stop_on_error.SetValueFromString(option_arg);
319e16c50a1SJim Ingham                     break;
320340b0309SGreg Clayton 
321e16c50a1SJim Ingham                 case 'c':
322c95f7e2aSPavel Labath                     error = m_stop_on_continue.SetValueFromString(option_arg);
323e16c50a1SJim Ingham                     break;
324340b0309SGreg Clayton 
32560986174SMichael Sartain                 case 's':
326c95f7e2aSPavel Labath                     error = m_silent_run.SetValueFromString(option_arg);
32760986174SMichael Sartain                     break;
328340b0309SGreg Clayton 
329e16c50a1SJim Ingham                 default:
33086edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
331e16c50a1SJim Ingham                     break;
332e16c50a1SJim Ingham             }
333e16c50a1SJim Ingham 
334e16c50a1SJim Ingham             return error;
335e16c50a1SJim Ingham         }
336e16c50a1SJim Ingham 
337e16c50a1SJim Ingham         void
33813d21e9aSBruce Mitchener         OptionParsingStarting () override
339e16c50a1SJim Ingham         {
340012d4fcaSEnrico Granata             m_stop_on_error.Clear();
341340b0309SGreg Clayton             m_silent_run.Clear();
342340b0309SGreg Clayton             m_stop_on_continue.Clear();
343e16c50a1SJim Ingham         }
344e16c50a1SJim Ingham 
345e0d378b3SGreg Clayton         const OptionDefinition*
34613d21e9aSBruce Mitchener         GetDefinitions () override
347e16c50a1SJim Ingham         {
348e16c50a1SJim Ingham             return g_option_table;
349e16c50a1SJim Ingham         }
350e16c50a1SJim Ingham 
351e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
352e16c50a1SJim Ingham 
353e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
354e16c50a1SJim Ingham 
355e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
356e16c50a1SJim Ingham 
357012d4fcaSEnrico Granata         OptionValueBoolean m_stop_on_error;
358340b0309SGreg Clayton         OptionValueBoolean m_silent_run;
359340b0309SGreg Clayton         OptionValueBoolean m_stop_on_continue;
360e16c50a1SJim Ingham     };
361e16c50a1SJim Ingham 
362ebc09c36SJim Ingham     bool
36313d21e9aSBruce Mitchener     DoExecute(Args& command, CommandReturnObject &result) override
364ebc09c36SJim Ingham     {
365c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
366ebc09c36SJim Ingham         if (argc == 1)
367ebc09c36SJim Ingham         {
3685a988416SJim Ingham             const char *filename = command.GetArgumentAtIndex(0);
369ebc09c36SJim Ingham 
3701ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
3716e3d8e7fSEugene Zelenko             ExecutionContext *exe_ctx = nullptr;  // Just use the default context.
372ebc09c36SJim Ingham 
373340b0309SGreg Clayton             // If any options were set, then use them
374340b0309SGreg Clayton             if (m_options.m_stop_on_error.OptionWasSet()    ||
375340b0309SGreg Clayton                 m_options.m_silent_run.OptionWasSet()       ||
376340b0309SGreg Clayton                 m_options.m_stop_on_continue.OptionWasSet())
377340b0309SGreg Clayton             {
378340b0309SGreg Clayton                 // Use user set settings
37926c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
38026c7bf93SJim Ingham                 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
38126c7bf93SJim Ingham                 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
3827d8555c4SJim Ingham                 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
3837d8555c4SJim Ingham                 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
38426c7bf93SJim Ingham 
385e16c50a1SJim Ingham                 m_interpreter.HandleCommandsFromFile (cmd_file,
386e16c50a1SJim Ingham                                                       exe_ctx,
38726c7bf93SJim Ingham                                                       options,
388e16c50a1SJim Ingham                                                       result);
389340b0309SGreg Clayton             }
390340b0309SGreg Clayton             else
391340b0309SGreg Clayton             {
392340b0309SGreg Clayton                 // No options were set, inherit any settings from nested "command source" commands,
393340b0309SGreg Clayton                 // or set to sane default settings...
39426c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
395340b0309SGreg Clayton                 m_interpreter.HandleCommandsFromFile (cmd_file,
396340b0309SGreg Clayton                                                       exe_ctx,
39726c7bf93SJim Ingham                                                       options,
398340b0309SGreg Clayton                                                       result);
399340b0309SGreg Clayton             }
400ebc09c36SJim Ingham         }
401ebc09c36SJim Ingham         else
402ebc09c36SJim Ingham         {
403ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
404ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
405ebc09c36SJim Ingham         }
406ebc09c36SJim Ingham         return result.Succeeded();
407ebc09c36SJim Ingham     }
4086e3d8e7fSEugene Zelenko 
4095a988416SJim Ingham     CommandOptions m_options;
410ebc09c36SJim Ingham };
411ebc09c36SJim Ingham 
412e0d378b3SGreg Clayton OptionDefinition
413e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
414e16c50a1SJim Ingham {
4156e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
4166e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
4176e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
4186e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
419e16c50a1SJim Ingham };
420e16c50a1SJim Ingham 
421ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
422ebc09c36SJim Ingham //-------------------------------------------------------------------------
423ebc09c36SJim Ingham // CommandObjectCommandsAlias
424ebc09c36SJim Ingham //-------------------------------------------------------------------------
425ebc09c36SJim Ingham 
426be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
427be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
42844d93782SGreg Clayton                                                      "def my_command_impl(debugger, args, result, internal_dict):\n";
429be93a35aSEnrico Granata 
4305a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw
431ebc09c36SJim Ingham {
43245d0e238SEnrico Granata protected:
43345d0e238SEnrico Granata     class CommandOptions : public OptionGroup
43445d0e238SEnrico Granata     {
435ebc09c36SJim Ingham     public:
43645d0e238SEnrico Granata         CommandOptions () :
43745d0e238SEnrico Granata         OptionGroup(),
43845d0e238SEnrico Granata         m_help(),
43945d0e238SEnrico Granata         m_long_help()
44045d0e238SEnrico Granata         {}
44145d0e238SEnrico Granata 
44245d0e238SEnrico Granata         ~CommandOptions() override = default;
44345d0e238SEnrico Granata 
44445d0e238SEnrico Granata         uint32_t
44545d0e238SEnrico Granata         GetNumDefinitions () override
44645d0e238SEnrico Granata         {
44745d0e238SEnrico Granata             return 3;
44845d0e238SEnrico Granata         }
44945d0e238SEnrico Granata 
45045d0e238SEnrico Granata         const OptionDefinition*
45145d0e238SEnrico Granata         GetDefinitions () override
45245d0e238SEnrico Granata         {
45345d0e238SEnrico Granata             return g_option_table;
45445d0e238SEnrico Granata         }
45545d0e238SEnrico Granata 
45645d0e238SEnrico Granata         Error
45745d0e238SEnrico Granata         SetOptionValue (CommandInterpreter &interpreter,
45845d0e238SEnrico Granata                         uint32_t option_idx,
45945d0e238SEnrico Granata                         const char *option_value) override
46045d0e238SEnrico Granata         {
46145d0e238SEnrico Granata             Error error;
46245d0e238SEnrico Granata 
46345d0e238SEnrico Granata             const int short_option = g_option_table[option_idx].short_option;
46445d0e238SEnrico Granata 
46545d0e238SEnrico Granata             switch (short_option)
46645d0e238SEnrico Granata             {
46745d0e238SEnrico Granata                 case 'h':
46845d0e238SEnrico Granata                     m_help.SetCurrentValue(option_value);
46945d0e238SEnrico Granata                     m_help.SetOptionWasSet();
47045d0e238SEnrico Granata                     break;
47145d0e238SEnrico Granata 
47245d0e238SEnrico Granata                 case 'H':
47345d0e238SEnrico Granata                     m_long_help.SetCurrentValue(option_value);
47445d0e238SEnrico Granata                     m_long_help.SetOptionWasSet();
47545d0e238SEnrico Granata                     break;
47645d0e238SEnrico Granata 
47745d0e238SEnrico Granata                 default:
47845d0e238SEnrico Granata                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
47945d0e238SEnrico Granata                     break;
48045d0e238SEnrico Granata             }
48145d0e238SEnrico Granata 
48245d0e238SEnrico Granata             return error;
48345d0e238SEnrico Granata         }
48445d0e238SEnrico Granata 
48545d0e238SEnrico Granata         void
48645d0e238SEnrico Granata         OptionParsingStarting (CommandInterpreter &interpreter) override
48745d0e238SEnrico Granata         {
48845d0e238SEnrico Granata             m_help.Clear();
48945d0e238SEnrico Granata             m_long_help.Clear();
49045d0e238SEnrico Granata         }
49145d0e238SEnrico Granata 
49245d0e238SEnrico Granata         // Options table: Required for subclasses of Options.
49345d0e238SEnrico Granata 
49445d0e238SEnrico Granata         static OptionDefinition g_option_table[];
49545d0e238SEnrico Granata         OptionValueString m_help;
49645d0e238SEnrico Granata         OptionValueString m_long_help;
49745d0e238SEnrico Granata     };
49845d0e238SEnrico Granata 
49945d0e238SEnrico Granata     OptionGroupOptions m_option_group;
50045d0e238SEnrico Granata     CommandOptions m_command_options;
50145d0e238SEnrico Granata 
50245d0e238SEnrico Granata public:
50345d0e238SEnrico Granata     Options *
50445d0e238SEnrico Granata     GetOptions () override
50545d0e238SEnrico Granata     {
50645d0e238SEnrico Granata         return &m_option_group;
50745d0e238SEnrico Granata     }
50845d0e238SEnrico Granata 
509*7428a18cSKate Stone     CommandObjectCommandsAlias(CommandInterpreter &interpreter)
510*7428a18cSKate Stone         : CommandObjectRaw(interpreter, "command alias", "Define a custom command in terms of an existing command.",
51145d0e238SEnrico Granata                            nullptr),
51245d0e238SEnrico Granata           m_option_group(interpreter),
51345d0e238SEnrico Granata           m_command_options()
514ebc09c36SJim Ingham     {
51545d0e238SEnrico Granata         m_option_group.Append(&m_command_options);
51645d0e238SEnrico Granata         m_option_group.Finalize();
51745d0e238SEnrico Granata 
518ebc09c36SJim Ingham         SetHelpLong(
519ea671fbdSKate Stone "'alias' allows the user to create a short-cut or abbreviation for long \
520ea671fbdSKate Stone commands, multi-word commands, and commands that take particular options.  \
521ea671fbdSKate Stone Below are some simple examples of how one might use the 'alias' command:" R"(
522ea671fbdSKate Stone 
523ea671fbdSKate Stone (lldb) command alias sc script
524ea671fbdSKate Stone 
525ea671fbdSKate Stone     Creates the abbreviation 'sc' for the 'script' command.
526ea671fbdSKate Stone 
527ea671fbdSKate Stone (lldb) command alias bp breakpoint
528ea671fbdSKate Stone 
529ea671fbdSKate Stone )" "    Creates the abbreviation 'bp' for the 'breakpoint' command.  Since \
530ea671fbdSKate Stone breakpoint commands are two-word commands, the user would still need to \
531ea671fbdSKate Stone enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"(
532ea671fbdSKate Stone 
533ea671fbdSKate Stone (lldb) command alias bpl breakpoint list
534ea671fbdSKate Stone 
535ea671fbdSKate Stone     Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
536ea671fbdSKate Stone 
537ea671fbdSKate Stone )" "An alias can include some options for the command, with the values either \
538ea671fbdSKate Stone filled in at the time the alias is created, or specified as positional \
539ea671fbdSKate Stone arguments, to be filled in when the alias is invoked.  The following example \
540ea671fbdSKate Stone shows how to create aliases with options:" R"(
541ea671fbdSKate Stone 
542ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
543ea671fbdSKate Stone 
544ea671fbdSKate Stone )" "    Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
545ea671fbdSKate Stone options already part of the alias.  So if the user wants to set a breakpoint \
546ea671fbdSKate Stone by file and line without explicitly having to use the -f and -l options, the \
547ea671fbdSKate Stone user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \
548ea671fbdSKate Stone for the actual arguments that will be passed when the alias command is used.  \
549ea671fbdSKate Stone The number in the placeholder refers to the position/order the actual value \
550ea671fbdSKate Stone occupies when the alias is used.  All the occurrences of '%1' in the alias \
551ea671fbdSKate Stone will be replaced with the first argument, all the occurrences of '%2' in the \
552ea671fbdSKate Stone alias will be replaced with the second argument, and so on.  This also allows \
553ea671fbdSKate Stone actual arguments to be used multiple times within an alias (see 'process \
554ea671fbdSKate Stone launch' example below)." R"(
555ea671fbdSKate Stone 
556ea671fbdSKate Stone )" "Note: the positional arguments must substitute as whole words in the resultant \
557ea671fbdSKate Stone command, so you can't at present do something like this to append the file extension \
558ea671fbdSKate Stone \".cpp\":" R"(
559ea671fbdSKate Stone 
560ea671fbdSKate Stone (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
561ea671fbdSKate Stone 
562ea671fbdSKate Stone )" "For more complex aliasing, use the \"command regex\" command instead.  In the \
563ea671fbdSKate Stone 'bfl' case above, the actual file value will be filled in with the first argument \
564ea671fbdSKate Stone following 'bfl' and the actual line number value will be filled in with the second \
565ea671fbdSKate Stone argument.  The user would use this alias as follows:" R"(
566ea671fbdSKate Stone 
567ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
568ea671fbdSKate Stone (lldb) bfl my-file.c 137
569ea671fbdSKate Stone 
570ea671fbdSKate Stone This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
571ea671fbdSKate Stone 
572ea671fbdSKate Stone Another example:
573ea671fbdSKate Stone 
574ea671fbdSKate Stone (lldb) command alias pltty process launch -s -o %1 -e %1
575ea671fbdSKate Stone (lldb) pltty /dev/tty0
576ea671fbdSKate Stone 
577ea671fbdSKate Stone     Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
578ea671fbdSKate Stone 
579ea671fbdSKate Stone )" "If the user always wanted to pass the same value to a particular option, the \
580ea671fbdSKate Stone alias could be defined with that value directly in the alias as a constant, \
581ea671fbdSKate Stone rather than using a positional placeholder:" R"(
582ea671fbdSKate Stone 
583ea671fbdSKate Stone (lldb) command alias bl3 breakpoint set -f %1 -l 3
584ea671fbdSKate Stone 
585ea671fbdSKate Stone     Always sets a breakpoint on line 3 of whatever file is indicated.)"
586ea671fbdSKate Stone         );
587ebc09c36SJim Ingham 
588405fe67fSCaroline Tice         CommandArgumentEntry arg1;
589405fe67fSCaroline Tice         CommandArgumentEntry arg2;
590405fe67fSCaroline Tice         CommandArgumentEntry arg3;
591405fe67fSCaroline Tice         CommandArgumentData alias_arg;
592405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
593405fe67fSCaroline Tice         CommandArgumentData options_arg;
594405fe67fSCaroline Tice 
595405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
596405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
597405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
598405fe67fSCaroline Tice 
599405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
600405fe67fSCaroline Tice         arg1.push_back (alias_arg);
601405fe67fSCaroline Tice 
602405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
603405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
604405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
605405fe67fSCaroline Tice 
606405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
607405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
608405fe67fSCaroline Tice 
609405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
610405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
611405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
612405fe67fSCaroline Tice 
613405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
614405fe67fSCaroline Tice         arg3.push_back (options_arg);
615405fe67fSCaroline Tice 
616405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
617405fe67fSCaroline Tice         m_arguments.push_back (arg1);
618405fe67fSCaroline Tice         m_arguments.push_back (arg2);
619405fe67fSCaroline Tice         m_arguments.push_back (arg3);
620ebc09c36SJim Ingham     }
621ebc09c36SJim Ingham 
6226e3d8e7fSEugene Zelenko     ~CommandObjectCommandsAlias() override = default;
623ebc09c36SJim Ingham 
6245a988416SJim Ingham protected:
62513d21e9aSBruce Mitchener     bool
62613d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
627844d2303SCaroline Tice     {
62845d0e238SEnrico Granata         if (!raw_command_line || !raw_command_line[0])
62945d0e238SEnrico Granata         {
630d72e412fSEnrico Granata             result.AppendError ("'command alias' requires at least two arguments");
63145d0e238SEnrico Granata             return false;
63245d0e238SEnrico Granata         }
63345d0e238SEnrico Granata 
63445d0e238SEnrico Granata         m_option_group.NotifyOptionParsingStarting();
63545d0e238SEnrico Granata 
63645d0e238SEnrico Granata         const char * remainder = nullptr;
63745d0e238SEnrico Granata 
63845d0e238SEnrico Granata         if (raw_command_line[0] == '-')
63945d0e238SEnrico Granata         {
64045d0e238SEnrico Granata             // We have some options and these options MUST end with --.
64145d0e238SEnrico Granata             const char *end_options = nullptr;
64245d0e238SEnrico Granata             const char *s = raw_command_line;
64345d0e238SEnrico Granata             while (s && s[0])
64445d0e238SEnrico Granata             {
64545d0e238SEnrico Granata                 end_options = ::strstr (s, "--");
64645d0e238SEnrico Granata                 if (end_options)
64745d0e238SEnrico Granata                 {
64845d0e238SEnrico Granata                     end_options += 2; // Get past the "--"
64945d0e238SEnrico Granata                     if (::isspace (end_options[0]))
65045d0e238SEnrico Granata                     {
65145d0e238SEnrico Granata                         remainder = end_options;
65245d0e238SEnrico Granata                         while (::isspace (*remainder))
65345d0e238SEnrico Granata                             ++remainder;
65445d0e238SEnrico Granata                         break;
65545d0e238SEnrico Granata                     }
65645d0e238SEnrico Granata                 }
65745d0e238SEnrico Granata                 s = end_options;
65845d0e238SEnrico Granata             }
65945d0e238SEnrico Granata 
66045d0e238SEnrico Granata             if (end_options)
66145d0e238SEnrico Granata             {
66245d0e238SEnrico Granata                 Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
66345d0e238SEnrico Granata                 if (!ParseOptions (args, result))
66445d0e238SEnrico Granata                     return false;
66545d0e238SEnrico Granata 
66645d0e238SEnrico Granata                 Error error (m_option_group.NotifyOptionParsingFinished());
66745d0e238SEnrico Granata                 if (error.Fail())
66845d0e238SEnrico Granata                 {
66945d0e238SEnrico Granata                     result.AppendError (error.AsCString());
67045d0e238SEnrico Granata                     result.SetStatus (eReturnStatusFailed);
67145d0e238SEnrico Granata                     return false;
67245d0e238SEnrico Granata                 }
67345d0e238SEnrico Granata             }
67445d0e238SEnrico Granata         }
67545d0e238SEnrico Granata         if (nullptr == remainder)
67645d0e238SEnrico Granata             remainder = raw_command_line;
67745d0e238SEnrico Granata 
67845d0e238SEnrico Granata         std::string raw_command_string (remainder);
67945d0e238SEnrico Granata         Args args (raw_command_string.c_str());
680844d2303SCaroline Tice 
681844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
682844d2303SCaroline Tice 
683844d2303SCaroline Tice         if (argc < 2)
684844d2303SCaroline Tice         {
685d72e412fSEnrico Granata             result.AppendError ("'command alias' requires at least two arguments");
686844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
687844d2303SCaroline Tice             return false;
688844d2303SCaroline Tice         }
689844d2303SCaroline Tice 
690844d2303SCaroline Tice         // Get the alias command.
691844d2303SCaroline Tice 
692844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
693d72e412fSEnrico Granata         if (alias_command.size() > 1 &&
694d72e412fSEnrico Granata             alias_command[0] == '-')
695d72e412fSEnrico Granata         {
696d72e412fSEnrico Granata             result.AppendError("aliases starting with a dash are not supported");
697d72e412fSEnrico Granata             if (alias_command == "--help" || alias_command == "--long-help")
698d72e412fSEnrico Granata             {
699d72e412fSEnrico Granata                 result.AppendWarning("if trying to pass options to 'command alias' add a -- at the end of the options");
700d72e412fSEnrico Granata             }
701d72e412fSEnrico Granata             result.SetStatus (eReturnStatusFailed);
702d72e412fSEnrico Granata             return false;
703d72e412fSEnrico Granata         }
704844d2303SCaroline Tice 
705844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
706844d2303SCaroline Tice         // does the stripping itself.
707844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
708844d2303SCaroline Tice         if (pos == 0)
709844d2303SCaroline Tice         {
710844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
711844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
712844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
713844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
714844d2303SCaroline Tice         }
715844d2303SCaroline Tice         else
716844d2303SCaroline Tice         {
717844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
718844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
719844d2303SCaroline Tice             return false;
720844d2303SCaroline Tice         }
721844d2303SCaroline Tice 
722844d2303SCaroline Tice 
723844d2303SCaroline Tice         // Verify that the command is alias-able.
724844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
725844d2303SCaroline Tice         {
726844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
727844d2303SCaroline Tice                                           alias_command.c_str());
728844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
729844d2303SCaroline Tice             return false;
730844d2303SCaroline Tice         }
731844d2303SCaroline Tice 
732844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
733844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
734d72e412fSEnrico Granata         std::string original_raw_command_string(raw_command_string);
735844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
736844d2303SCaroline Tice 
737844d2303SCaroline Tice         if (!cmd_obj)
738844d2303SCaroline Tice         {
739d72e412fSEnrico Granata             result.AppendErrorWithFormat ("invalid command given to 'command alias'. '%s' does not begin with a valid command."
740d72e412fSEnrico Granata                                           "  No alias created.", original_raw_command_string.c_str());
741844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
742844d2303SCaroline Tice             return false;
743844d2303SCaroline Tice         }
744844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
745844d2303SCaroline Tice         {
746844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
747844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
7485a988416SJim Ingham             return HandleAliasingNormalCommand (args, result);
749844d2303SCaroline Tice         }
750844d2303SCaroline Tice         else
751844d2303SCaroline Tice         {
7525a988416SJim Ingham             return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
7535a988416SJim Ingham         }
7545a988416SJim Ingham         return result.Succeeded();
7555a988416SJim Ingham     }
7565a988416SJim Ingham 
7575a988416SJim Ingham     bool
7585a988416SJim Ingham     HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
7595a988416SJim Ingham     {
760844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
761844d2303SCaroline Tice 
762844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
763844d2303SCaroline Tice 
764212130acSEnrico Granata             if (CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false))
765844d2303SCaroline Tice             {
766844d2303SCaroline Tice                 if (m_interpreter.AliasExists (alias_command.c_str())
767844d2303SCaroline Tice                     || m_interpreter.UserCommandExists (alias_command.c_str()))
768844d2303SCaroline Tice                 {
769844d2303SCaroline Tice                     result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
770844d2303SCaroline Tice                                                     alias_command.c_str());
771844d2303SCaroline Tice                 }
77245d0e238SEnrico Granata                 if (CommandAlias *alias = m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp, raw_command_string.c_str()))
773472362e6SCaroline Tice                 {
77445d0e238SEnrico Granata                     if (m_command_options.m_help.OptionWasSet())
77545d0e238SEnrico Granata                         alias->SetHelp(m_command_options.m_help.GetCurrentValue());
77645d0e238SEnrico Granata                     if (m_command_options.m_long_help.OptionWasSet())
77745d0e238SEnrico Granata                         alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
778844d2303SCaroline Tice                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
779844d2303SCaroline Tice                 }
780472362e6SCaroline Tice                 else
781472362e6SCaroline Tice                 {
782472362e6SCaroline Tice                     result.AppendError ("Unable to create requested alias.\n");
783472362e6SCaroline Tice                     result.SetStatus (eReturnStatusFailed);
784472362e6SCaroline Tice                 }
785212130acSEnrico Granata 
786212130acSEnrico Granata             }
787212130acSEnrico Granata             else
788212130acSEnrico Granata             {
789212130acSEnrico Granata                 result.AppendError ("Unable to create requested alias.\n");
790212130acSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
791212130acSEnrico Granata             }
792212130acSEnrico Granata 
793844d2303SCaroline Tice             return result.Succeeded ();
794844d2303SCaroline Tice     }
795ebc09c36SJim Ingham 
796ebc09c36SJim Ingham     bool
7975a988416SJim Ingham     HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
798ebc09c36SJim Ingham     {
799867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
800ebc09c36SJim Ingham 
801ebc09c36SJim Ingham         if (argc < 2)
802ebc09c36SJim Ingham         {
803d72e412fSEnrico Granata             result.AppendError ("'command alias' requires at least two arguments");
804ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
805ebc09c36SJim Ingham             return false;
806ebc09c36SJim Ingham         }
807ebc09c36SJim Ingham 
808ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
809ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
810ebc09c36SJim Ingham 
811ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
812ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
813ebc09c36SJim Ingham 
814ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
815ebc09c36SJim Ingham 
816a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
817ebc09c36SJim Ingham         {
818ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
819ebc09c36SJim Ingham                                          alias_command.c_str());
820ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
821ebc09c36SJim Ingham         }
822ebc09c36SJim Ingham         else
823ebc09c36SJim Ingham         {
824a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
825ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
826ebc09c36SJim Ingham              bool use_subcommand = false;
8276e3d8e7fSEugene Zelenko              if (command_obj_sp)
828ebc09c36SJim Ingham              {
829ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
8306e3d8e7fSEugene Zelenko                  CommandObject *sub_cmd_obj = nullptr;
831ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
832ebc09c36SJim Ingham 
833844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
834ebc09c36SJim Ingham                  {
835ebc09c36SJim Ingham                      if (argc >= 3)
836ebc09c36SJim Ingham                      {
837ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
838ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
839998255bfSGreg Clayton                          subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
8406e3d8e7fSEugene Zelenko                          if (subcommand_obj_sp)
841ebc09c36SJim Ingham                          {
842ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
843ebc09c36SJim Ingham                              use_subcommand = true;
844ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
845844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
846ebc09c36SJim Ingham                          }
847ebc09c36SJim Ingham                          else
848ebc09c36SJim Ingham                          {
849f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
850f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
851f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
852ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
853ebc09c36SJim Ingham                              return false;
854ebc09c36SJim Ingham                          }
855ebc09c36SJim Ingham                      }
856ebc09c36SJim Ingham                  }
857ebc09c36SJim Ingham 
858ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
859ebc09c36SJim Ingham 
860212130acSEnrico Granata                  std::string args_string;
861212130acSEnrico Granata 
862ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
863ebc09c36SJim Ingham                  {
864ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
865ebc09c36SJim Ingham                     if (use_subcommand)
866ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
867ca90c47eSCaroline Tice 
868ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
869867b185dSCaroline Tice                  }
870ebc09c36SJim Ingham 
871a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
872a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
873ebc09c36SJim Ingham                  {
874ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
875ebc09c36SJim Ingham                                                      alias_command.c_str());
876ebc09c36SJim Ingham                  }
877ebc09c36SJim Ingham 
87845d0e238SEnrico Granata                  if (CommandAlias *alias = m_interpreter.AddAlias(alias_command.c_str(),
879212130acSEnrico Granata                                                                   use_subcommand ? subcommand_obj_sp : command_obj_sp,
880212130acSEnrico Granata                                                                   args_string.c_str()))
881212130acSEnrico Granata                  {
88245d0e238SEnrico Granata                      if (m_command_options.m_help.OptionWasSet())
88345d0e238SEnrico Granata                          alias->SetHelp(m_command_options.m_help.GetCurrentValue());
88445d0e238SEnrico Granata                      if (m_command_options.m_long_help.OptionWasSet())
88545d0e238SEnrico Granata                          alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
886ebc09c36SJim Ingham                      result.SetStatus (eReturnStatusSuccessFinishNoResult);
887ebc09c36SJim Ingham                  }
888ebc09c36SJim Ingham                  else
889ebc09c36SJim Ingham                  {
890212130acSEnrico Granata                      result.AppendError ("Unable to create requested alias.\n");
891212130acSEnrico Granata                      result.SetStatus (eReturnStatusFailed);
892212130acSEnrico Granata                      return false;
893212130acSEnrico Granata                  }
894212130acSEnrico Granata              }
895212130acSEnrico Granata              else
896212130acSEnrico Granata              {
897ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
898ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
899e7941795SCaroline Tice                  return false;
900ebc09c36SJim Ingham              }
901ebc09c36SJim Ingham         }
902ebc09c36SJim Ingham 
903ebc09c36SJim Ingham         return result.Succeeded();
904ebc09c36SJim Ingham     }
905ebc09c36SJim Ingham };
906ebc09c36SJim Ingham 
90745d0e238SEnrico Granata OptionDefinition
90845d0e238SEnrico Granata CommandObjectCommandsAlias::CommandOptions::g_option_table[] =
90945d0e238SEnrico Granata {
91045d0e238SEnrico Granata     { LLDB_OPT_SET_ALL, false, "help",      'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText,    "Help text for this command"},
91145d0e238SEnrico Granata     { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText,    "Long help text for this command"},
91245d0e238SEnrico Granata     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
91345d0e238SEnrico Granata };
91445d0e238SEnrico Granata 
915ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
916ebc09c36SJim Ingham //-------------------------------------------------------------------------
917ebc09c36SJim Ingham // CommandObjectCommandsUnalias
918ebc09c36SJim Ingham //-------------------------------------------------------------------------
919ebc09c36SJim Ingham 
9205a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed
921ebc09c36SJim Ingham {
922ebc09c36SJim Ingham public:
923*7428a18cSKate Stone     CommandObjectCommandsUnalias(CommandInterpreter &interpreter)
924*7428a18cSKate Stone         : CommandObjectParsed(interpreter, "command unalias",
925*7428a18cSKate Stone                               "Delete one or more custom commands defined by 'command alias'.", nullptr)
926ebc09c36SJim Ingham     {
927405fe67fSCaroline Tice         CommandArgumentEntry arg;
928405fe67fSCaroline Tice         CommandArgumentData alias_arg;
929405fe67fSCaroline Tice 
930405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
931405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
932405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
933405fe67fSCaroline Tice 
934405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
935405fe67fSCaroline Tice         arg.push_back (alias_arg);
936405fe67fSCaroline Tice 
937405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
938405fe67fSCaroline Tice         m_arguments.push_back (arg);
939ebc09c36SJim Ingham     }
940ebc09c36SJim Ingham 
9416e3d8e7fSEugene Zelenko     ~CommandObjectCommandsUnalias() override = default;
942ebc09c36SJim Ingham 
9435a988416SJim Ingham protected:
944ebc09c36SJim Ingham     bool
94513d21e9aSBruce Mitchener     DoExecute (Args& args, CommandReturnObject &result) override
946ebc09c36SJim Ingham     {
947ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
948ebc09c36SJim Ingham         CommandObject *cmd_obj;
949ebc09c36SJim Ingham 
950ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
951ebc09c36SJim Ingham         {
952ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
953a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
954ebc09c36SJim Ingham             if (cmd_obj)
955ebc09c36SJim Ingham             {
956a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
957ebc09c36SJim Ingham                 {
958b547278cSGreg Clayton                     if (cmd_obj->IsRemovable())
959b547278cSGreg Clayton                     {
960b547278cSGreg Clayton                         result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
961b547278cSGreg Clayton                                                       command_name);
962b547278cSGreg Clayton                     }
963b547278cSGreg Clayton                     else
964b547278cSGreg Clayton                     {
965ebc09c36SJim Ingham                         result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
966ebc09c36SJim Ingham                                                       command_name);
967b547278cSGreg Clayton                     }
968ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
969ebc09c36SJim Ingham                 }
970ebc09c36SJim Ingham                 else
971ebc09c36SJim Ingham                 {
9726e3d8e7fSEugene Zelenko                     if (!m_interpreter.RemoveAlias(command_name))
973ebc09c36SJim Ingham                     {
974a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
975ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
976ebc09c36SJim Ingham                                                           command_name);
977ebc09c36SJim Ingham                         else
978ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
979ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
980ebc09c36SJim Ingham                     }
981ebc09c36SJim Ingham                     else
982ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
983ebc09c36SJim Ingham                 }
984ebc09c36SJim Ingham             }
985ebc09c36SJim Ingham             else
986ebc09c36SJim Ingham             {
987ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
988ebc09c36SJim Ingham                                               "current list of commands.\n",
989ebc09c36SJim Ingham                                              command_name);
990ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
991ebc09c36SJim Ingham             }
992ebc09c36SJim Ingham         }
993ebc09c36SJim Ingham         else
994ebc09c36SJim Ingham         {
995ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
996ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
997ebc09c36SJim Ingham         }
998ebc09c36SJim Ingham 
999ebc09c36SJim Ingham         return result.Succeeded();
1000ebc09c36SJim Ingham     }
1001ebc09c36SJim Ingham };
1002ebc09c36SJim Ingham 
1003b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete
1004b547278cSGreg Clayton //-------------------------------------------------------------------------
1005b547278cSGreg Clayton // CommandObjectCommandsDelete
1006b547278cSGreg Clayton //-------------------------------------------------------------------------
1007b547278cSGreg Clayton 
1008b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed
1009b547278cSGreg Clayton {
1010b547278cSGreg Clayton public:
1011*7428a18cSKate Stone     CommandObjectCommandsDelete(CommandInterpreter &interpreter)
1012*7428a18cSKate Stone         : CommandObjectParsed(interpreter, "command delete",
1013*7428a18cSKate Stone                               "Delete one or more custom commands defined by 'command regex'.", nullptr)
1014b547278cSGreg Clayton     {
1015b547278cSGreg Clayton         CommandArgumentEntry arg;
1016b547278cSGreg Clayton         CommandArgumentData alias_arg;
1017b547278cSGreg Clayton 
1018b547278cSGreg Clayton         // Define the first (and only) variant of this arg.
1019b547278cSGreg Clayton         alias_arg.arg_type = eArgTypeCommandName;
1020b547278cSGreg Clayton         alias_arg.arg_repetition = eArgRepeatPlain;
1021b547278cSGreg Clayton 
1022b547278cSGreg Clayton         // There is only one variant this argument could be; put it into the argument entry.
1023b547278cSGreg Clayton         arg.push_back (alias_arg);
1024b547278cSGreg Clayton 
1025b547278cSGreg Clayton         // Push the data for the first argument into the m_arguments vector.
1026b547278cSGreg Clayton         m_arguments.push_back (arg);
1027b547278cSGreg Clayton     }
1028b547278cSGreg Clayton 
10296e3d8e7fSEugene Zelenko     ~CommandObjectCommandsDelete() override = default;
1030b547278cSGreg Clayton 
1031b547278cSGreg Clayton protected:
1032b547278cSGreg Clayton     bool
103313d21e9aSBruce Mitchener     DoExecute (Args& args, CommandReturnObject &result) override
1034b547278cSGreg Clayton     {
1035b547278cSGreg Clayton         CommandObject::CommandMap::iterator pos;
1036b547278cSGreg Clayton 
1037b547278cSGreg Clayton         if (args.GetArgumentCount() != 0)
1038b547278cSGreg Clayton         {
1039b547278cSGreg Clayton             const char *command_name = args.GetArgumentAtIndex(0);
1040b547278cSGreg Clayton             if (m_interpreter.CommandExists (command_name))
1041b547278cSGreg Clayton             {
1042b547278cSGreg Clayton                 if (m_interpreter.RemoveCommand (command_name))
1043b547278cSGreg Clayton                 {
1044b547278cSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1045b547278cSGreg Clayton                 }
1046b547278cSGreg Clayton                 else
1047b547278cSGreg Clayton                 {
1048b547278cSGreg Clayton                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
1049b547278cSGreg Clayton                                                   command_name);
1050b547278cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
1051b547278cSGreg Clayton                 }
1052b547278cSGreg Clayton             }
1053b547278cSGreg Clayton             else
1054b547278cSGreg Clayton             {
105546d4aa21SEnrico Granata                 StreamString error_msg_stream;
105646d4aa21SEnrico Granata                 const bool generate_apropos = true;
105746d4aa21SEnrico Granata                 const bool generate_type_lookup = false;
105846d4aa21SEnrico Granata                 CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
105946d4aa21SEnrico Granata                                                                         command_name,
106046d4aa21SEnrico Granata                                                                         nullptr,
106146d4aa21SEnrico Granata                                                                         nullptr,
106246d4aa21SEnrico Granata                                                                         generate_apropos,
106346d4aa21SEnrico Granata                                                                         generate_type_lookup);
106446d4aa21SEnrico Granata                 result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
1065b547278cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1066b547278cSGreg Clayton             }
1067b547278cSGreg Clayton         }
1068b547278cSGreg Clayton         else
1069b547278cSGreg Clayton         {
1070*7428a18cSKate Stone             result.AppendErrorWithFormat(
1071*7428a18cSKate Stone                 "must call '%s' with one or more valid user defined regular expression command names",
1072*7428a18cSKate Stone                 GetCommandName());
1073b547278cSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1074b547278cSGreg Clayton         }
1075b547278cSGreg Clayton 
1076b547278cSGreg Clayton         return result.Succeeded();
1077b547278cSGreg Clayton     }
1078b547278cSGreg Clayton };
1079b547278cSGreg Clayton 
1080de164aaaSGreg Clayton //-------------------------------------------------------------------------
1081de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
1082de164aaaSGreg Clayton //-------------------------------------------------------------------------
10835a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex
1084de164aaaSGreg Clayton 
108544d93782SGreg Clayton class CommandObjectCommandsAddRegex :
108644d93782SGreg Clayton     public CommandObjectParsed,
1087ea508635SGreg Clayton     public IOHandlerDelegateMultiline
1088de164aaaSGreg Clayton {
1089de164aaaSGreg Clayton public:
1090*7428a18cSKate Stone     CommandObjectCommandsAddRegex(CommandInterpreter &interpreter)
1091*7428a18cSKate Stone         : CommandObjectParsed(interpreter, "command regex",
1092*7428a18cSKate Stone                               "Define a custom command in terms of existing commands by matching regular expressions.",
10930e5e5a79SGreg Clayton                               "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
1094ea508635SGreg Clayton           IOHandlerDelegateMultiline("", IOHandlerDelegate::Completion::LLDBCommand),
1095de164aaaSGreg Clayton           m_options(interpreter)
1096de164aaaSGreg Clayton     {
1097ea671fbdSKate Stone         SetHelpLong(R"(
1098ea671fbdSKate Stone )" "This command allows the user to create powerful regular expression commands \
1099ea671fbdSKate Stone with substitutions. The regular expressions and substitutions are specified \
1100ea671fbdSKate Stone using the regular expression substitution format of:" R"(
1101ea671fbdSKate Stone 
1102ea671fbdSKate Stone     s/<regex>/<subst>/
1103ea671fbdSKate Stone 
1104ea671fbdSKate Stone )" "<regex> is a regular expression that can use parenthesis to capture regular \
1105ea671fbdSKate Stone expression input and substitute the captured matches in the output using %1 \
1106ea671fbdSKate Stone for the first match, %2 for the second, and so on." R"(
1107ea671fbdSKate Stone 
1108ea671fbdSKate Stone )" "The regular expressions can all be specified on the command line if more than \
1109ea671fbdSKate Stone one argument is provided. If just the command name is provided on the command \
1110ea671fbdSKate Stone line, then the regular expressions and substitutions can be entered on separate \
1111ea671fbdSKate Stone lines, followed by an empty line to terminate the command definition." R"(
1112ea671fbdSKate Stone 
1113ea671fbdSKate Stone EXAMPLES
1114ea671fbdSKate Stone 
1115ea671fbdSKate Stone )" "The following example will define a regular expression command named 'f' that \
1116ea671fbdSKate Stone will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
1117ea671fbdSKate Stone a number follows 'f':" R"(
1118ea671fbdSKate Stone 
1119ea671fbdSKate Stone     (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
11200e5e5a79SGreg Clayton         );
1121de164aaaSGreg Clayton     }
1122de164aaaSGreg Clayton 
11236e3d8e7fSEugene Zelenko     ~CommandObjectCommandsAddRegex() override = default;
1124de164aaaSGreg Clayton 
11255a988416SJim Ingham protected:
1126ea508635SGreg Clayton     void
1127ea508635SGreg Clayton     IOHandlerActivated (IOHandler &io_handler) override
112844d93782SGreg Clayton     {
112944d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
113044d93782SGreg Clayton         if (output_sp)
113144d93782SGreg Clayton         {
113244d93782SGreg 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");
113344d93782SGreg Clayton             output_sp->Flush();
113444d93782SGreg Clayton         }
113544d93782SGreg Clayton     }
113644d93782SGreg Clayton 
1137ea508635SGreg Clayton     void
1138ea508635SGreg Clayton     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
113944d93782SGreg Clayton     {
114044d93782SGreg Clayton         io_handler.SetIsDone(true);
11416e3d8e7fSEugene Zelenko         if (m_regex_cmd_ap)
114244d93782SGreg Clayton         {
114344d93782SGreg Clayton             StringList lines;
114444d93782SGreg Clayton             if (lines.SplitIntoLines (data))
114544d93782SGreg Clayton             {
114644d93782SGreg Clayton                 const size_t num_lines = lines.GetSize();
114744d93782SGreg Clayton                 bool check_only = false;
114844d93782SGreg Clayton                 for (size_t i=0; i<num_lines; ++i)
114944d93782SGreg Clayton                 {
115044d93782SGreg Clayton                     llvm::StringRef bytes_strref (lines[i]);
115144d93782SGreg Clayton                     Error error = AppendRegexSubstitution (bytes_strref, check_only);
115244d93782SGreg Clayton                     if (error.Fail())
115344d93782SGreg Clayton                     {
115444d93782SGreg Clayton                         if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
115544d93782SGreg Clayton                         {
115644d93782SGreg Clayton                             StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
115744d93782SGreg Clayton                             out_stream->Printf("error: %s\n", error.AsCString());
115844d93782SGreg Clayton                         }
115944d93782SGreg Clayton                     }
116044d93782SGreg Clayton                 }
116144d93782SGreg Clayton             }
116244d93782SGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
116344d93782SGreg Clayton             {
116444d93782SGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
116544d93782SGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
116644d93782SGreg Clayton             }
116744d93782SGreg Clayton         }
116844d93782SGreg Clayton     }
116944d93782SGreg Clayton 
1170de164aaaSGreg Clayton     bool
1171b0a1814fSEric Christopher     DoExecute (Args& command, CommandReturnObject &result) override
1172de164aaaSGreg Clayton     {
11735a988416SJim Ingham         const size_t argc = command.GetArgumentCount();
11740e5e5a79SGreg Clayton         if (argc == 0)
1175de164aaaSGreg Clayton         {
117669c12ccbSJason Molenda             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
11770e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
11780e5e5a79SGreg Clayton         }
11790e5e5a79SGreg Clayton         else
11800e5e5a79SGreg Clayton         {
11810e5e5a79SGreg Clayton             Error error;
11825a988416SJim Ingham             const char *name = command.GetArgumentAtIndex(0);
1183de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1184de164aaaSGreg Clayton                                                                  name,
1185de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
1186de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
1187b547278cSGreg Clayton                                                                  10,
1188b547278cSGreg Clayton                                                                  0,
1189b547278cSGreg Clayton                                                                  true));
11900e5e5a79SGreg Clayton 
11910e5e5a79SGreg Clayton             if (argc == 1)
11920e5e5a79SGreg Clayton             {
119344d93782SGreg Clayton                 Debugger &debugger = m_interpreter.GetDebugger();
1194e30f11d9SKate Stone                 bool color_prompt = debugger.GetUseColor();
119544d93782SGreg Clayton                 const bool multiple_lines = true; // Get multiple lines
119644d93782SGreg Clayton                 IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
1197e30f11d9SKate Stone                                                                 IOHandler::Type::Other,
119873d80faaSGreg Clayton                                                                 "lldb-regex", // Name of input reader for history
1199ea508635SGreg Clayton                                                                 "> ",         // Prompt
12006e3d8e7fSEugene Zelenko                                                                 nullptr,      // Continuation prompt
120144d93782SGreg Clayton                                                                 multiple_lines,
1202e30f11d9SKate Stone                                                                 color_prompt,
1203f6913cd7SGreg Clayton                                                                 0,            // Don't show line numbers
120444d93782SGreg Clayton                                                                 *this));
120544d93782SGreg Clayton 
120644d93782SGreg Clayton                 if (io_handler_sp)
1207de164aaaSGreg Clayton                 {
120844d93782SGreg Clayton                     debugger.PushIOHandler(io_handler_sp);
1209de164aaaSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1210de164aaaSGreg Clayton                 }
1211de164aaaSGreg Clayton             }
1212de164aaaSGreg Clayton             else
1213de164aaaSGreg Clayton             {
12140e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
12150e5e5a79SGreg Clayton                 {
12165a988416SJim Ingham                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
121744d93782SGreg Clayton                     bool check_only = false;
121844d93782SGreg Clayton                     error = AppendRegexSubstitution (arg_strref, check_only);
12190e5e5a79SGreg Clayton                     if (error.Fail())
12200e5e5a79SGreg Clayton                         break;
12210e5e5a79SGreg Clayton                 }
12220e5e5a79SGreg Clayton 
12230e5e5a79SGreg Clayton                 if (error.Success())
12240e5e5a79SGreg Clayton                 {
12250e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
12260e5e5a79SGreg Clayton                 }
12270e5e5a79SGreg Clayton             }
12280e5e5a79SGreg Clayton             if (error.Fail())
12290e5e5a79SGreg Clayton             {
12300e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
1231de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1232de164aaaSGreg Clayton             }
12330e5e5a79SGreg Clayton         }
12340e5e5a79SGreg Clayton 
1235de164aaaSGreg Clayton         return result.Succeeded();
1236de164aaaSGreg Clayton     }
1237de164aaaSGreg Clayton 
12380e5e5a79SGreg Clayton     Error
123944d93782SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
1240de164aaaSGreg Clayton     {
12410e5e5a79SGreg Clayton         Error error;
12420e5e5a79SGreg Clayton 
12436e3d8e7fSEugene Zelenko         if (!m_regex_cmd_ap)
1244de164aaaSGreg Clayton         {
12450e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
12460e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12470e5e5a79SGreg Clayton                                            regex_sed.data());
12480e5e5a79SGreg Clayton             return error;
1249de164aaaSGreg Clayton         }
12500e5e5a79SGreg Clayton 
12510e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
12520e5e5a79SGreg Clayton 
12530e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
12540e5e5a79SGreg Clayton         {
12550e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
12560e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12570e5e5a79SGreg Clayton                                            regex_sed.data());
12580e5e5a79SGreg Clayton             return error;
12590e5e5a79SGreg Clayton         }
12600e5e5a79SGreg Clayton 
12610e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
12620e5e5a79SGreg Clayton         {
12630e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
12640e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12650e5e5a79SGreg Clayton                                            regex_sed.data());
12660e5e5a79SGreg Clayton             return error;
12670e5e5a79SGreg Clayton         }
12680e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
12690e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
12700e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
12710e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
12720e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
12730e5e5a79SGreg Clayton 
12740e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
12750e5e5a79SGreg Clayton         {
1276ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
12770e5e5a79SGreg Clayton                                            separator_char,
12780e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
1279ea508635SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1),
1280ea508635SGreg Clayton                                            (int)regex_sed.size(),
1281ea508635SGreg Clayton                                            regex_sed.data());
12820e5e5a79SGreg Clayton             return error;
12830e5e5a79SGreg Clayton         }
12840e5e5a79SGreg Clayton 
12850e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
12860e5e5a79SGreg Clayton 
12870e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
12880e5e5a79SGreg Clayton         {
1289ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
12900e5e5a79SGreg Clayton                                            separator_char,
12910e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
1292ea508635SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1),
1293ea508635SGreg Clayton                                            (int)regex_sed.size(),
1294ea508635SGreg Clayton                                            regex_sed.data());
12950e5e5a79SGreg Clayton             return error;
12960e5e5a79SGreg Clayton         }
12970e5e5a79SGreg Clayton 
12980e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
12990e5e5a79SGreg Clayton         {
13000e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
13010e5e5a79SGreg Clayton             // separator char
13020e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
13030e5e5a79SGreg Clayton             {
13040e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
13050e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
13060e5e5a79SGreg Clayton                                                regex_sed.data(),
13070e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
13080e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
13090e5e5a79SGreg Clayton                 return error;
13100e5e5a79SGreg Clayton             }
13110e5e5a79SGreg Clayton         }
13120e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
13130e5e5a79SGreg Clayton         {
13140e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
13150e5e5a79SGreg Clayton                                            separator_char,
13160e5e5a79SGreg Clayton                                            separator_char,
13170e5e5a79SGreg Clayton                                            separator_char,
13180e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
13190e5e5a79SGreg Clayton                                            regex_sed.data());
13200e5e5a79SGreg Clayton             return error;
13210e5e5a79SGreg Clayton         }
13220e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
13230e5e5a79SGreg Clayton         {
13240e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
13250e5e5a79SGreg Clayton                                            separator_char,
13260e5e5a79SGreg Clayton                                            separator_char,
13270e5e5a79SGreg Clayton                                            separator_char,
13280e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
13290e5e5a79SGreg Clayton                                            regex_sed.data());
13300e5e5a79SGreg Clayton             return error;
13310e5e5a79SGreg Clayton         }
133244d93782SGreg Clayton 
13336e3d8e7fSEugene Zelenko         if (!check_only)
133444d93782SGreg Clayton         {
13350e5e5a79SGreg Clayton             std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
13360e5e5a79SGreg Clayton             std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
13370e5e5a79SGreg Clayton             m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
13380e5e5a79SGreg Clayton                                              subst.c_str());
133944d93782SGreg Clayton         }
13400e5e5a79SGreg Clayton         return error;
1341de164aaaSGreg Clayton     }
1342de164aaaSGreg Clayton 
1343de164aaaSGreg Clayton     void
13440e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
1345de164aaaSGreg Clayton     {
13466e3d8e7fSEugene Zelenko         if (m_regex_cmd_ap)
1347de164aaaSGreg Clayton         {
1348de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
1349de164aaaSGreg Clayton             {
1350de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1351de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1352de164aaaSGreg Clayton             }
1353de164aaaSGreg Clayton         }
1354de164aaaSGreg Clayton     }
1355de164aaaSGreg Clayton 
1356de164aaaSGreg Clayton private:
13577b0992d9SGreg Clayton     std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1358de164aaaSGreg Clayton 
1359de164aaaSGreg Clayton      class CommandOptions : public Options
1360de164aaaSGreg Clayton      {
1361de164aaaSGreg Clayton      public:
1362de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
1363de164aaaSGreg Clayton             Options (interpreter)
1364de164aaaSGreg Clayton          {
1365de164aaaSGreg Clayton          }
1366de164aaaSGreg Clayton 
13676e3d8e7fSEugene Zelenko          ~CommandOptions() override = default;
1368de164aaaSGreg Clayton 
136913d21e9aSBruce Mitchener          Error
137013d21e9aSBruce Mitchener          SetOptionValue (uint32_t option_idx, const char *option_arg) override
1371de164aaaSGreg Clayton          {
1372de164aaaSGreg Clayton              Error error;
13733bcdfc0eSGreg Clayton              const int short_option = m_getopt_table[option_idx].val;
1374de164aaaSGreg Clayton 
1375de164aaaSGreg Clayton              switch (short_option)
1376de164aaaSGreg Clayton              {
1377de164aaaSGreg Clayton                  case 'h':
1378de164aaaSGreg Clayton                      m_help.assign (option_arg);
1379de164aaaSGreg Clayton                      break;
1380de164aaaSGreg Clayton                  case 's':
1381de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1382de164aaaSGreg Clayton                      break;
1383de164aaaSGreg Clayton                  default:
138486edbf41SGreg Clayton                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1385de164aaaSGreg Clayton                      break;
1386de164aaaSGreg Clayton              }
1387de164aaaSGreg Clayton 
1388de164aaaSGreg Clayton              return error;
1389de164aaaSGreg Clayton          }
1390de164aaaSGreg Clayton 
1391de164aaaSGreg Clayton          void
139213d21e9aSBruce Mitchener          OptionParsingStarting () override
1393de164aaaSGreg Clayton          {
1394de164aaaSGreg Clayton              m_help.clear();
1395de164aaaSGreg Clayton              m_syntax.clear();
1396de164aaaSGreg Clayton          }
1397de164aaaSGreg Clayton 
1398de164aaaSGreg Clayton          const OptionDefinition*
139913d21e9aSBruce Mitchener          GetDefinitions () override
1400de164aaaSGreg Clayton          {
1401de164aaaSGreg Clayton              return g_option_table;
1402de164aaaSGreg Clayton          }
1403de164aaaSGreg Clayton 
1404de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1405de164aaaSGreg Clayton 
1406de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1407de164aaaSGreg Clayton 
1408de164aaaSGreg Clayton          const char *
1409de164aaaSGreg Clayton          GetHelp()
1410de164aaaSGreg Clayton          {
14116e3d8e7fSEugene Zelenko              return (m_help.empty() ? nullptr : m_help.c_str());
1412de164aaaSGreg Clayton          }
14136e3d8e7fSEugene Zelenko 
1414de164aaaSGreg Clayton          const char *
1415de164aaaSGreg Clayton          GetSyntax ()
1416de164aaaSGreg Clayton          {
14176e3d8e7fSEugene Zelenko              return (m_syntax.empty() ? nullptr : m_syntax.c_str());
1418de164aaaSGreg Clayton          }
14196e3d8e7fSEugene Zelenko 
1420de164aaaSGreg Clayton      protected:
14216e3d8e7fSEugene Zelenko          // Instance variables to hold the values for command options.
14226e3d8e7fSEugene Zelenko 
1423de164aaaSGreg Clayton          std::string m_help;
1424de164aaaSGreg Clayton          std::string m_syntax;
1425de164aaaSGreg Clayton      };
1426de164aaaSGreg Clayton 
1427b0a1814fSEric Christopher      Options *
1428b0a1814fSEric Christopher      GetOptions () override
1429de164aaaSGreg Clayton      {
1430de164aaaSGreg Clayton          return &m_options;
1431de164aaaSGreg Clayton      }
1432de164aaaSGreg Clayton 
14335a988416SJim Ingham      CommandOptions m_options;
1434de164aaaSGreg Clayton };
1435de164aaaSGreg Clayton 
1436de164aaaSGreg Clayton OptionDefinition
1437de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1438de164aaaSGreg Clayton {
14396e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command."},
14406e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
14416e3d8e7fSEugene Zelenko { 0             , false,  nullptr   , 0  , 0                , nullptr, nullptr, 0, eArgTypeNone, nullptr }
1442de164aaaSGreg Clayton };
1443de164aaaSGreg Clayton 
14445a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw
1445223383edSEnrico Granata {
1446223383edSEnrico Granata public:
1447223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1448223383edSEnrico Granata                                  std::string name,
14490a305db7SEnrico Granata                                  std::string funct,
1450735152e3SEnrico Granata                                  std::string help,
14510a305db7SEnrico Granata                                  ScriptedCommandSynchronicity synch) :
14525a988416SJim Ingham         CommandObjectRaw(interpreter,
1453223383edSEnrico Granata                          name.c_str(),
14546e3d8e7fSEugene Zelenko                          nullptr,
14556e3d8e7fSEugene Zelenko                          nullptr),
14560a305db7SEnrico Granata         m_function_name(funct),
1457fac939e9SEnrico Granata         m_synchro(synch),
1458fac939e9SEnrico Granata         m_fetched_help_long(false)
1459223383edSEnrico Granata     {
1460735152e3SEnrico Granata         if (!help.empty())
1461735152e3SEnrico Granata             SetHelp(help.c_str());
1462735152e3SEnrico Granata         else
1463735152e3SEnrico Granata         {
1464735152e3SEnrico Granata             StreamString stream;
1465735152e3SEnrico Granata             stream.Printf("For more information run 'help %s'",name.c_str());
1466735152e3SEnrico Granata             SetHelp(stream.GetData());
1467735152e3SEnrico Granata         }
1468223383edSEnrico Granata     }
1469223383edSEnrico Granata 
14706e3d8e7fSEugene Zelenko     ~CommandObjectPythonFunction() override = default;
1471223383edSEnrico Granata 
147213d21e9aSBruce Mitchener     bool
147313d21e9aSBruce Mitchener     IsRemovable () const override
14745a988416SJim Ingham     {
14755a988416SJim Ingham         return true;
14765a988416SJim Ingham     }
14775a988416SJim Ingham 
14785a988416SJim Ingham     const std::string&
14795a988416SJim Ingham     GetFunctionName ()
14805a988416SJim Ingham     {
14815a988416SJim Ingham         return m_function_name;
14825a988416SJim Ingham     }
14835a988416SJim Ingham 
14845a988416SJim Ingham     ScriptedCommandSynchronicity
14855a988416SJim Ingham     GetSynchronicity ()
14865a988416SJim Ingham     {
14875a988416SJim Ingham         return m_synchro;
14885a988416SJim Ingham     }
14895a988416SJim Ingham 
149013d21e9aSBruce Mitchener     const char *
149113d21e9aSBruce Mitchener     GetHelpLong () override
1492fac939e9SEnrico Granata     {
1493fac939e9SEnrico Granata         if (!m_fetched_help_long)
1494fac939e9SEnrico Granata         {
1495fac939e9SEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1496fac939e9SEnrico Granata             if (scripter)
1497fac939e9SEnrico Granata             {
1498fac939e9SEnrico Granata                 std::string docstring;
1499fac939e9SEnrico Granata                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1500fac939e9SEnrico Granata                 if (!docstring.empty())
1501bfb75e9bSEnrico Granata                     SetHelpLong(docstring.c_str());
1502fac939e9SEnrico Granata             }
1503fac939e9SEnrico Granata         }
1504fac939e9SEnrico Granata         return CommandObjectRaw::GetHelpLong();
1505fac939e9SEnrico Granata     }
1506fac939e9SEnrico Granata 
15075a988416SJim Ingham protected:
150813d21e9aSBruce Mitchener     bool
150913d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
1510223383edSEnrico Granata     {
1511223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1512223383edSEnrico Granata 
1513223383edSEnrico Granata         Error error;
1514223383edSEnrico Granata 
151570f11f88SJim Ingham         result.SetStatus(eReturnStatusInvalid);
151670f11f88SJim Ingham 
15176e3d8e7fSEugene Zelenko         if (!scripter || !scripter->RunScriptBasedCommand(m_function_name.c_str(),
1518223383edSEnrico Granata                                                           raw_command_line,
15190a305db7SEnrico Granata                                                           m_synchro,
1520223383edSEnrico Granata                                                           result,
152106be059aSEnrico Granata                                                           error,
15226e3d8e7fSEugene Zelenko                                                           m_exe_ctx))
1523223383edSEnrico Granata         {
1524223383edSEnrico Granata             result.AppendError(error.AsCString());
1525223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1526223383edSEnrico Granata         }
1527223383edSEnrico Granata         else
152870f11f88SJim Ingham         {
152970f11f88SJim Ingham             // Don't change the status if the command already set it...
153070f11f88SJim Ingham             if (result.GetStatus() == eReturnStatusInvalid)
153170f11f88SJim Ingham             {
15326e3d8e7fSEugene Zelenko                 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
1533223383edSEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
153470f11f88SJim Ingham                 else
153570f11f88SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishResult);
153670f11f88SJim Ingham             }
153770f11f88SJim Ingham         }
1538223383edSEnrico Granata 
1539223383edSEnrico Granata         return result.Succeeded();
1540223383edSEnrico Granata     }
1541223383edSEnrico Granata 
15426e3d8e7fSEugene Zelenko private:
15436e3d8e7fSEugene Zelenko     std::string m_function_name;
15446e3d8e7fSEugene Zelenko     ScriptedCommandSynchronicity m_synchro;
15456e3d8e7fSEugene Zelenko     bool m_fetched_help_long;
1546223383edSEnrico Granata };
1547223383edSEnrico Granata 
15489fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw
15499fe00e52SEnrico Granata {
15509fe00e52SEnrico Granata public:
15519fe00e52SEnrico Granata     CommandObjectScriptingObject (CommandInterpreter &interpreter,
15529fe00e52SEnrico Granata                                   std::string name,
15530641ca1aSZachary Turner                                   StructuredData::GenericSP cmd_obj_sp,
15549fe00e52SEnrico Granata                                   ScriptedCommandSynchronicity synch) :
15559fe00e52SEnrico Granata         CommandObjectRaw(interpreter,
15569fe00e52SEnrico Granata                          name.c_str(),
15576e3d8e7fSEugene Zelenko                          nullptr,
15586e3d8e7fSEugene Zelenko                          nullptr),
15599fe00e52SEnrico Granata         m_cmd_obj_sp(cmd_obj_sp),
15606f79bb2dSEnrico Granata         m_synchro(synch),
15616f79bb2dSEnrico Granata         m_fetched_help_short(false),
15626f79bb2dSEnrico Granata         m_fetched_help_long(false)
15639fe00e52SEnrico Granata     {
15649fe00e52SEnrico Granata         StreamString stream;
15659fe00e52SEnrico Granata         stream.Printf("For more information run 'help %s'",name.c_str());
15669fe00e52SEnrico Granata         SetHelp(stream.GetData());
1567e87764f2SEnrico Granata         if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1568e87764f2SEnrico Granata             GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
15699fe00e52SEnrico Granata     }
15709fe00e52SEnrico Granata 
15716e3d8e7fSEugene Zelenko     ~CommandObjectScriptingObject() override = default;
15729fe00e52SEnrico Granata 
157313d21e9aSBruce Mitchener     bool
157413d21e9aSBruce Mitchener     IsRemovable () const override
15759fe00e52SEnrico Granata     {
15769fe00e52SEnrico Granata         return true;
15779fe00e52SEnrico Granata     }
15789fe00e52SEnrico Granata 
15790641ca1aSZachary Turner     StructuredData::GenericSP
15809fe00e52SEnrico Granata     GetImplementingObject ()
15819fe00e52SEnrico Granata     {
15829fe00e52SEnrico Granata         return m_cmd_obj_sp;
15839fe00e52SEnrico Granata     }
15849fe00e52SEnrico Granata 
15859fe00e52SEnrico Granata     ScriptedCommandSynchronicity
15869fe00e52SEnrico Granata     GetSynchronicity ()
15879fe00e52SEnrico Granata     {
15889fe00e52SEnrico Granata         return m_synchro;
15899fe00e52SEnrico Granata     }
15909fe00e52SEnrico Granata 
159113d21e9aSBruce Mitchener     const char *
159213d21e9aSBruce Mitchener     GetHelp () override
15936f79bb2dSEnrico Granata     {
15946f79bb2dSEnrico Granata         if (!m_fetched_help_short)
15956f79bb2dSEnrico Granata         {
15966f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
15976f79bb2dSEnrico Granata             if (scripter)
15986f79bb2dSEnrico Granata             {
15996f79bb2dSEnrico Granata                 std::string docstring;
16006f79bb2dSEnrico Granata                 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
16016f79bb2dSEnrico Granata                 if (!docstring.empty())
1602bfb75e9bSEnrico Granata                     SetHelp(docstring.c_str());
16036f79bb2dSEnrico Granata             }
16046f79bb2dSEnrico Granata         }
16056f79bb2dSEnrico Granata         return CommandObjectRaw::GetHelp();
16066f79bb2dSEnrico Granata     }
16076f79bb2dSEnrico Granata 
160813d21e9aSBruce Mitchener     const char *
160913d21e9aSBruce Mitchener     GetHelpLong () override
16109fe00e52SEnrico Granata     {
16116f79bb2dSEnrico Granata         if (!m_fetched_help_long)
16126f79bb2dSEnrico Granata         {
16136f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
16146f79bb2dSEnrico Granata             if (scripter)
16156f79bb2dSEnrico Granata             {
16166f79bb2dSEnrico Granata                 std::string docstring;
16176f79bb2dSEnrico Granata                 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
16186f79bb2dSEnrico Granata                 if (!docstring.empty())
1619bfb75e9bSEnrico Granata                     SetHelpLong(docstring.c_str());
16206f79bb2dSEnrico Granata             }
16216f79bb2dSEnrico Granata         }
16229fe00e52SEnrico Granata         return CommandObjectRaw::GetHelpLong();
16239fe00e52SEnrico Granata     }
16249fe00e52SEnrico Granata 
16259fe00e52SEnrico Granata protected:
162613d21e9aSBruce Mitchener     bool
162713d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
16289fe00e52SEnrico Granata     {
16299fe00e52SEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
16309fe00e52SEnrico Granata 
16319fe00e52SEnrico Granata         Error error;
16329fe00e52SEnrico Granata 
16339fe00e52SEnrico Granata         result.SetStatus(eReturnStatusInvalid);
16349fe00e52SEnrico Granata 
16356e3d8e7fSEugene Zelenko         if (!scripter || !scripter->RunScriptBasedCommand(m_cmd_obj_sp,
16369fe00e52SEnrico Granata                                                           raw_command_line,
16379fe00e52SEnrico Granata                                                           m_synchro,
16389fe00e52SEnrico Granata                                                           result,
16399fe00e52SEnrico Granata                                                           error,
16406e3d8e7fSEugene Zelenko                                                           m_exe_ctx))
16419fe00e52SEnrico Granata         {
16429fe00e52SEnrico Granata             result.AppendError(error.AsCString());
16439fe00e52SEnrico Granata             result.SetStatus(eReturnStatusFailed);
16449fe00e52SEnrico Granata         }
16459fe00e52SEnrico Granata         else
16469fe00e52SEnrico Granata         {
16479fe00e52SEnrico Granata             // Don't change the status if the command already set it...
16489fe00e52SEnrico Granata             if (result.GetStatus() == eReturnStatusInvalid)
16499fe00e52SEnrico Granata             {
16506e3d8e7fSEugene Zelenko                 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
16519fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
16529fe00e52SEnrico Granata                 else
16539fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishResult);
16549fe00e52SEnrico Granata             }
16559fe00e52SEnrico Granata         }
16569fe00e52SEnrico Granata 
16579fe00e52SEnrico Granata         return result.Succeeded();
16589fe00e52SEnrico Granata     }
16599fe00e52SEnrico Granata 
16606e3d8e7fSEugene Zelenko private:
16616e3d8e7fSEugene Zelenko     StructuredData::GenericSP m_cmd_obj_sp;
16626e3d8e7fSEugene Zelenko     ScriptedCommandSynchronicity m_synchro;
16636e3d8e7fSEugene Zelenko     bool m_fetched_help_short: 1;
16646e3d8e7fSEugene Zelenko     bool m_fetched_help_long: 1;
16659fe00e52SEnrico Granata };
16669fe00e52SEnrico Granata 
1667a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1668a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport
1669a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1670a9dbf432SEnrico Granata 
16715a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed
1672a9dbf432SEnrico Granata {
16735a988416SJim Ingham public:
16745a988416SJim Ingham     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
16755a988416SJim Ingham         CommandObjectParsed(interpreter,
16765a988416SJim Ingham                             "command script import",
16775a988416SJim Ingham                             "Import a scripting module in LLDB.",
16786e3d8e7fSEugene Zelenko                             nullptr),
16795a988416SJim Ingham         m_options(interpreter)
16805a988416SJim Ingham     {
16815a988416SJim Ingham         CommandArgumentEntry arg1;
16825a988416SJim Ingham         CommandArgumentData cmd_arg;
16835a988416SJim Ingham 
16845a988416SJim Ingham         // Define the first (and only) variant of this arg.
16855a988416SJim Ingham         cmd_arg.arg_type = eArgTypeFilename;
16863b00e35bSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlus;
16875a988416SJim Ingham 
16885a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
16895a988416SJim Ingham         arg1.push_back (cmd_arg);
16905a988416SJim Ingham 
16915a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
16925a988416SJim Ingham         m_arguments.push_back (arg1);
16935a988416SJim Ingham     }
16945a988416SJim Ingham 
16956e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptImport() override = default;
16965a988416SJim Ingham 
169713d21e9aSBruce Mitchener     int
16985a988416SJim Ingham     HandleArgumentCompletion (Args &input,
16995a988416SJim Ingham                               int &cursor_index,
17005a988416SJim Ingham                               int &cursor_char_position,
17015a988416SJim Ingham                               OptionElementVector &opt_element_vector,
17025a988416SJim Ingham                               int match_start_point,
17035a988416SJim Ingham                               int max_return_elements,
17045a988416SJim Ingham                               bool &word_complete,
170513d21e9aSBruce Mitchener                               StringList &matches) override
17065a988416SJim Ingham     {
17075a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
17085a988416SJim Ingham         completion_str.erase (cursor_char_position);
17095a988416SJim Ingham 
17105a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
17115a988416SJim Ingham                                                             CommandCompletions::eDiskFileCompletion,
17125a988416SJim Ingham                                                             completion_str.c_str(),
17135a988416SJim Ingham                                                             match_start_point,
17145a988416SJim Ingham                                                             max_return_elements,
17156e3d8e7fSEugene Zelenko                                                             nullptr,
17165a988416SJim Ingham                                                             word_complete,
17175a988416SJim Ingham                                                             matches);
17185a988416SJim Ingham         return matches.GetSize();
17195a988416SJim Ingham     }
17205a988416SJim Ingham 
172113d21e9aSBruce Mitchener     Options *
172213d21e9aSBruce Mitchener     GetOptions () override
17235a988416SJim Ingham     {
17245a988416SJim Ingham         return &m_options;
17255a988416SJim Ingham     }
17265a988416SJim Ingham 
17275a988416SJim Ingham protected:
17280a305db7SEnrico Granata     class CommandOptions : public Options
17290a305db7SEnrico Granata     {
17300a305db7SEnrico Granata     public:
17310a305db7SEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
17320a305db7SEnrico Granata             Options (interpreter)
17330a305db7SEnrico Granata         {
17340a305db7SEnrico Granata         }
17350a305db7SEnrico Granata 
17366e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
17370a305db7SEnrico Granata 
173813d21e9aSBruce Mitchener         Error
173913d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
17400a305db7SEnrico Granata         {
17410a305db7SEnrico Granata             Error error;
17423bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
17430a305db7SEnrico Granata 
17440a305db7SEnrico Granata             switch (short_option)
17450a305db7SEnrico Granata             {
17460a305db7SEnrico Granata                 case 'r':
17470a305db7SEnrico Granata                     m_allow_reload = true;
17480a305db7SEnrico Granata                     break;
17490a305db7SEnrico Granata                 default:
17500a305db7SEnrico Granata                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
17510a305db7SEnrico Granata                     break;
17520a305db7SEnrico Granata             }
17530a305db7SEnrico Granata 
17540a305db7SEnrico Granata             return error;
17550a305db7SEnrico Granata         }
17560a305db7SEnrico Granata 
17570a305db7SEnrico Granata         void
175813d21e9aSBruce Mitchener         OptionParsingStarting () override
17590a305db7SEnrico Granata         {
1760e0c70f1bSEnrico Granata             m_allow_reload = true;
17610a305db7SEnrico Granata         }
17620a305db7SEnrico Granata 
17630a305db7SEnrico Granata         const OptionDefinition*
176413d21e9aSBruce Mitchener         GetDefinitions () override
17650a305db7SEnrico Granata         {
17660a305db7SEnrico Granata             return g_option_table;
17670a305db7SEnrico Granata         }
17680a305db7SEnrico Granata 
17690a305db7SEnrico Granata         // Options table: Required for subclasses of Options.
17700a305db7SEnrico Granata 
17710a305db7SEnrico Granata         static OptionDefinition g_option_table[];
17720a305db7SEnrico Granata 
17730a305db7SEnrico Granata         // Instance variables to hold the values for command options.
17740a305db7SEnrico Granata 
17750a305db7SEnrico Granata         bool m_allow_reload;
17760a305db7SEnrico Granata     };
17770a305db7SEnrico Granata 
1778a9dbf432SEnrico Granata     bool
177913d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
1780a9dbf432SEnrico Granata     {
1781a9dbf432SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1782a9dbf432SEnrico Granata         {
1783a9dbf432SEnrico Granata             result.AppendError ("only scripting language supported for module importing is currently Python");
1784a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1785a9dbf432SEnrico Granata             return false;
1786a9dbf432SEnrico Granata         }
1787a9dbf432SEnrico Granata 
17885a988416SJim Ingham         size_t argc = command.GetArgumentCount();
17893b00e35bSEnrico Granata         if (0 == argc)
1790a9dbf432SEnrico Granata         {
17913b00e35bSEnrico Granata             result.AppendError("command script import needs one or more arguments");
1792a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1793a9dbf432SEnrico Granata             return false;
1794a9dbf432SEnrico Granata         }
1795a9dbf432SEnrico Granata 
17960e978481SEd Maste         for (size_t i = 0;
17973b00e35bSEnrico Granata              i < argc;
17983b00e35bSEnrico Granata              i++)
17993b00e35bSEnrico Granata         {
18003b00e35bSEnrico Granata             std::string path = command.GetArgumentAtIndex(i);
1801a9dbf432SEnrico Granata             Error error;
1802a9dbf432SEnrico Granata 
1803c9d645d3SGreg Clayton             const bool init_session = true;
1804078551c7SEnrico Granata             // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1805078551c7SEnrico Granata             // commands won't ever be recursively invoked, but it's actually possible to craft
1806078551c7SEnrico Granata             // a Python script that does other "command script imports" in __lldb_init_module
1807078551c7SEnrico Granata             // the real fix is to have recursive commands possible with a CommandInvocation object
1808078551c7SEnrico Granata             // separate from the CommandObject itself, so that recursive command invocations
1809078551c7SEnrico Granata             // won't stomp on each other (wrt to execution contents, options, and more)
1810078551c7SEnrico Granata             m_exe_ctx.Clear();
1811a9dbf432SEnrico Granata             if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
18120a305db7SEnrico Granata                                                                           m_options.m_allow_reload,
1813c9d645d3SGreg Clayton                                                                           init_session,
1814a9dbf432SEnrico Granata                                                                           error))
1815a9dbf432SEnrico Granata             {
1816a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1817a9dbf432SEnrico Granata             }
1818a9dbf432SEnrico Granata             else
1819a9dbf432SEnrico Granata             {
1820a9dbf432SEnrico Granata                 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1821a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1822a9dbf432SEnrico Granata             }
18233b00e35bSEnrico Granata         }
1824a9dbf432SEnrico Granata 
1825a9dbf432SEnrico Granata         return result.Succeeded();
1826a9dbf432SEnrico Granata     }
18270a305db7SEnrico Granata 
18285a988416SJim Ingham     CommandOptions m_options;
1829a9dbf432SEnrico Granata };
1830223383edSEnrico Granata 
18310a305db7SEnrico Granata OptionDefinition
18320a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
18330a305db7SEnrico Granata {
18346e3d8e7fSEugene Zelenko     { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, nullptr, 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."},
18356e3d8e7fSEugene Zelenko     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
18360a305db7SEnrico Granata };
18370a305db7SEnrico Granata 
1838223383edSEnrico Granata //-------------------------------------------------------------------------
1839223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1840223383edSEnrico Granata //-------------------------------------------------------------------------
1841223383edSEnrico Granata 
184244d93782SGreg Clayton class CommandObjectCommandsScriptAdd :
184344d93782SGreg Clayton     public CommandObjectParsed,
184444d93782SGreg Clayton     public IOHandlerDelegateMultiline
1845223383edSEnrico Granata {
18465a988416SJim Ingham public:
18475a988416SJim Ingham     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
18485a988416SJim Ingham         CommandObjectParsed(interpreter,
18495a988416SJim Ingham                             "command script add",
18505a988416SJim Ingham                             "Add a scripted function as an LLDB command.",
18516e3d8e7fSEugene Zelenko                             nullptr),
1852c3d874a5SGreg Clayton         IOHandlerDelegateMultiline ("DONE"),
18535a988416SJim Ingham         m_options (interpreter)
18545a988416SJim Ingham     {
18555a988416SJim Ingham         CommandArgumentEntry arg1;
18565a988416SJim Ingham         CommandArgumentData cmd_arg;
18575a988416SJim Ingham 
18585a988416SJim Ingham         // Define the first (and only) variant of this arg.
18595a988416SJim Ingham         cmd_arg.arg_type = eArgTypeCommandName;
18605a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
18615a988416SJim Ingham 
18625a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
18635a988416SJim Ingham         arg1.push_back (cmd_arg);
18645a988416SJim Ingham 
18655a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
18665a988416SJim Ingham         m_arguments.push_back (arg1);
18675a988416SJim Ingham     }
18685a988416SJim Ingham 
18696e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptAdd() override = default;
18705a988416SJim Ingham 
187113d21e9aSBruce Mitchener     Options *
187213d21e9aSBruce Mitchener     GetOptions () override
18735a988416SJim Ingham     {
18745a988416SJim Ingham         return &m_options;
18755a988416SJim Ingham     }
18765a988416SJim Ingham 
18775a988416SJim Ingham protected:
1878223383edSEnrico Granata     class CommandOptions : public Options
1879223383edSEnrico Granata     {
1880223383edSEnrico Granata     public:
1881223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
18829fe00e52SEnrico Granata             Options (interpreter),
18839fe00e52SEnrico Granata             m_class_name(),
18849fe00e52SEnrico Granata             m_funct_name(),
18859fe00e52SEnrico Granata             m_short_help(),
18869fe00e52SEnrico Granata             m_synchronicity(eScriptedCommandSynchronicitySynchronous)
1887223383edSEnrico Granata         {
1888223383edSEnrico Granata         }
1889223383edSEnrico Granata 
18906e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
1891223383edSEnrico Granata 
189213d21e9aSBruce Mitchener         Error
189313d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1894223383edSEnrico Granata         {
1895223383edSEnrico Granata             Error error;
18963bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
1897223383edSEnrico Granata 
1898223383edSEnrico Granata             switch (short_option)
1899223383edSEnrico Granata             {
1900223383edSEnrico Granata                 case 'f':
1901735152e3SEnrico Granata                     if (option_arg)
1902735152e3SEnrico Granata                         m_funct_name.assign(option_arg);
1903735152e3SEnrico Granata                     break;
19049fe00e52SEnrico Granata                 case 'c':
19059fe00e52SEnrico Granata                     if (option_arg)
19069fe00e52SEnrico Granata                         m_class_name.assign(option_arg);
19079fe00e52SEnrico Granata                     break;
1908735152e3SEnrico Granata                 case 'h':
1909735152e3SEnrico Granata                     if (option_arg)
1910735152e3SEnrico Granata                         m_short_help.assign(option_arg);
1911223383edSEnrico Granata                     break;
19120a305db7SEnrico Granata                 case 's':
191344d93782SGreg Clayton                     m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
19140a305db7SEnrico Granata                     if (!error.Success())
19150a305db7SEnrico Granata                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
19160a305db7SEnrico Granata                     break;
1917223383edSEnrico Granata                 default:
191886edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1919223383edSEnrico Granata                     break;
1920223383edSEnrico Granata             }
1921223383edSEnrico Granata 
1922223383edSEnrico Granata             return error;
1923223383edSEnrico Granata         }
1924223383edSEnrico Granata 
1925223383edSEnrico Granata         void
192613d21e9aSBruce Mitchener         OptionParsingStarting () override
1927223383edSEnrico Granata         {
19289fe00e52SEnrico Granata             m_class_name.clear();
1929735152e3SEnrico Granata             m_funct_name.clear();
1930735152e3SEnrico Granata             m_short_help.clear();
193144d93782SGreg Clayton             m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1932223383edSEnrico Granata         }
1933223383edSEnrico Granata 
1934223383edSEnrico Granata         const OptionDefinition*
193513d21e9aSBruce Mitchener         GetDefinitions () override
1936223383edSEnrico Granata         {
1937223383edSEnrico Granata             return g_option_table;
1938223383edSEnrico Granata         }
1939223383edSEnrico Granata 
1940223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1941223383edSEnrico Granata 
1942223383edSEnrico Granata         static OptionDefinition g_option_table[];
1943223383edSEnrico Granata 
1944223383edSEnrico Granata         // Instance variables to hold the values for command options.
1945223383edSEnrico Granata 
19469fe00e52SEnrico Granata         std::string m_class_name;
1947223383edSEnrico Granata         std::string m_funct_name;
1948735152e3SEnrico Granata         std::string m_short_help;
194944d93782SGreg Clayton         ScriptedCommandSynchronicity m_synchronicity;
1950223383edSEnrico Granata     };
1951223383edSEnrico Granata 
195213d21e9aSBruce Mitchener     void
195313d21e9aSBruce Mitchener     IOHandlerActivated (IOHandler &io_handler) override
1954223383edSEnrico Granata     {
195544d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
195644d93782SGreg Clayton         if (output_sp)
1957223383edSEnrico Granata         {
195844d93782SGreg Clayton             output_sp->PutCString(g_python_command_instructions);
195944d93782SGreg Clayton             output_sp->Flush();
1960223383edSEnrico Granata         }
1961223383edSEnrico Granata     }
1962223383edSEnrico Granata 
1963223383edSEnrico Granata 
196413d21e9aSBruce Mitchener     void
196513d21e9aSBruce Mitchener     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
1966223383edSEnrico Granata     {
196744d93782SGreg Clayton         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
196844d93782SGreg Clayton 
196944d93782SGreg Clayton         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
197044d93782SGreg Clayton         if (interpreter)
197144d93782SGreg Clayton         {
197244d93782SGreg Clayton 
197344d93782SGreg Clayton             StringList lines;
197444d93782SGreg Clayton             lines.SplitIntoLines(data);
197544d93782SGreg Clayton             if (lines.GetSize() > 0)
197644d93782SGreg Clayton             {
1977a73b7df7SEnrico Granata                 std::string funct_name_str;
197844d93782SGreg Clayton                 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1979223383edSEnrico Granata                 {
1980a73b7df7SEnrico Granata                     if (funct_name_str.empty())
1981223383edSEnrico Granata                     {
198244d93782SGreg Clayton                         error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
198344d93782SGreg Clayton                         error_sp->Flush();
1984223383edSEnrico Granata                     }
198544d93782SGreg Clayton                     else
198644d93782SGreg Clayton                     {
1987223383edSEnrico Granata                         // everything should be fine now, let's add this alias
1988223383edSEnrico Granata 
1989223383edSEnrico Granata                         CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1990223383edSEnrico Granata                                                                                         m_cmd_name,
1991a73b7df7SEnrico Granata                                                                                         funct_name_str.c_str(),
1992735152e3SEnrico Granata                                                                                         m_short_help,
199344d93782SGreg Clayton                                                                                         m_synchronicity));
1994223383edSEnrico Granata 
19950a305db7SEnrico Granata                         if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1996223383edSEnrico Granata                         {
199744d93782SGreg Clayton                             error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
199844d93782SGreg Clayton                             error_sp->Flush();
1999223383edSEnrico Granata                         }
2000223383edSEnrico Granata                     }
200144d93782SGreg Clayton                 }
200244d93782SGreg Clayton                 else
200344d93782SGreg Clayton                 {
200444d93782SGreg Clayton                     error_sp->Printf ("error: unable to create function, didn't add python command.\n");
200544d93782SGreg Clayton                     error_sp->Flush();
200644d93782SGreg Clayton                 }
200744d93782SGreg Clayton             }
200844d93782SGreg Clayton             else
200944d93782SGreg Clayton             {
201044d93782SGreg Clayton                 error_sp->Printf ("error: empty function, didn't add python command.\n");
201144d93782SGreg Clayton                 error_sp->Flush();
201244d93782SGreg Clayton             }
201344d93782SGreg Clayton         }
201444d93782SGreg Clayton         else
201544d93782SGreg Clayton         {
201644d93782SGreg Clayton             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
201744d93782SGreg Clayton             error_sp->Flush();
201844d93782SGreg Clayton         }
201944d93782SGreg Clayton 
202044d93782SGreg Clayton         io_handler.SetIsDone(true);
202144d93782SGreg Clayton     }
2022223383edSEnrico Granata 
20235a988416SJim Ingham protected:
2024223383edSEnrico Granata     bool
202513d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2026223383edSEnrico Granata     {
202799f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
202899f0b8f9SEnrico Granata         {
202999f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
203099f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
203199f0b8f9SEnrico Granata             return false;
203299f0b8f9SEnrico Granata         }
203399f0b8f9SEnrico Granata 
20345a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2035223383edSEnrico Granata 
2036223383edSEnrico Granata         if (argc != 1)
2037223383edSEnrico Granata         {
2038223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
2039223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2040223383edSEnrico Granata             return false;
2041223383edSEnrico Granata         }
2042223383edSEnrico Granata 
2043735152e3SEnrico Granata         // Store the options in case we get multi-line input
204444d93782SGreg Clayton         m_cmd_name = command.GetArgumentAtIndex(0);
2045735152e3SEnrico Granata         m_short_help.assign(m_options.m_short_help);
204644d93782SGreg Clayton         m_synchronicity = m_options.m_synchronicity;
2047223383edSEnrico Granata 
20489fe00e52SEnrico Granata         if (m_options.m_class_name.empty())
20499fe00e52SEnrico Granata         {
2050223383edSEnrico Granata             if (m_options.m_funct_name.empty())
2051223383edSEnrico Granata             {
205244d93782SGreg Clayton                 m_interpreter.GetPythonCommandsFromIOHandler("     ",  // Prompt
205344d93782SGreg Clayton                                                              *this,    // IOHandlerDelegate
205444d93782SGreg Clayton                                                              true,     // Run IOHandler in async mode
20556e3d8e7fSEugene Zelenko                                                              nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
2056223383edSEnrico Granata             }
2057223383edSEnrico Granata             else
2058223383edSEnrico Granata             {
20590a305db7SEnrico Granata                 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
206044d93782SGreg Clayton                                                                         m_cmd_name,
20610a305db7SEnrico Granata                                                                         m_options.m_funct_name,
2062735152e3SEnrico Granata                                                                         m_options.m_short_help,
206344d93782SGreg Clayton                                                                         m_synchronicity));
206444d93782SGreg Clayton                 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
2065223383edSEnrico Granata                 {
2066223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
2067223383edSEnrico Granata                 }
2068223383edSEnrico Granata                 else
2069223383edSEnrico Granata                 {
2070223383edSEnrico Granata                     result.AppendError("cannot add command");
2071223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
2072223383edSEnrico Granata                 }
2073223383edSEnrico Granata             }
20749fe00e52SEnrico Granata         }
20759fe00e52SEnrico Granata         else
20769fe00e52SEnrico Granata         {
20779fe00e52SEnrico Granata             ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
20789fe00e52SEnrico Granata             if (!interpreter)
20799fe00e52SEnrico Granata             {
20809fe00e52SEnrico Granata                 result.AppendError("cannot find ScriptInterpreter");
20819fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
20829fe00e52SEnrico Granata                 return false;
20839fe00e52SEnrico Granata             }
20849fe00e52SEnrico Granata 
20859fe00e52SEnrico Granata             auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
20869fe00e52SEnrico Granata             if (!cmd_obj_sp)
20879fe00e52SEnrico Granata             {
20889fe00e52SEnrico Granata                 result.AppendError("cannot create helper object");
20899fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
20909fe00e52SEnrico Granata                 return false;
20919fe00e52SEnrico Granata             }
20929fe00e52SEnrico Granata 
20939fe00e52SEnrico Granata             CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
20949fe00e52SEnrico Granata                                                                      m_cmd_name,
20959fe00e52SEnrico Granata                                                                      cmd_obj_sp,
20969fe00e52SEnrico Granata                                                                      m_synchronicity));
20979fe00e52SEnrico Granata             if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
20989fe00e52SEnrico Granata             {
20999fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
21009fe00e52SEnrico Granata             }
21019fe00e52SEnrico Granata             else
21029fe00e52SEnrico Granata             {
21039fe00e52SEnrico Granata                 result.AppendError("cannot add command");
21049fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
21059fe00e52SEnrico Granata             }
21069fe00e52SEnrico Granata         }
2107223383edSEnrico Granata 
2108223383edSEnrico Granata         return result.Succeeded();
2109223383edSEnrico Granata     }
21105a988416SJim Ingham 
21115a988416SJim Ingham     CommandOptions m_options;
211244d93782SGreg Clayton     std::string m_cmd_name;
2113735152e3SEnrico Granata     std::string m_short_help;
211444d93782SGreg Clayton     ScriptedCommandSynchronicity m_synchronicity;
2115223383edSEnrico Granata };
2116223383edSEnrico Granata 
21170a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] =
21180a305db7SEnrico Granata {
21190a305db7SEnrico Granata     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
21200a305db7SEnrico Granata     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
21210a305db7SEnrico Granata     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
21226e3d8e7fSEugene Zelenko     { 0, nullptr, nullptr }
21230a305db7SEnrico Granata };
21240a305db7SEnrico Granata 
2125223383edSEnrico Granata OptionDefinition
2126223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2127223383edSEnrico Granata {
21286e3d8e7fSEugene Zelenko     { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."},
21296e3d8e7fSEugene Zelenko     { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass,        "Name of the Python class to bind to this command name."},
21306e3d8e7fSEugene Zelenko     { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command."},
21316e3d8e7fSEugene Zelenko     { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity,        "Set the synchronicity of this command's executions with regard to LLDB event system."},
21326e3d8e7fSEugene Zelenko     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
2133223383edSEnrico Granata };
2134223383edSEnrico Granata 
2135223383edSEnrico Granata //-------------------------------------------------------------------------
2136223383edSEnrico Granata // CommandObjectCommandsScriptList
2137223383edSEnrico Granata //-------------------------------------------------------------------------
2138223383edSEnrico Granata 
21395a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed
2140223383edSEnrico Granata {
2141223383edSEnrico Granata public:
2142223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
21435a988416SJim Ingham         CommandObjectParsed(interpreter,
2144223383edSEnrico Granata                             "command script list",
2145223383edSEnrico Granata                             "List defined scripted commands.",
21466e3d8e7fSEugene Zelenko                             nullptr)
2147223383edSEnrico Granata     {
2148223383edSEnrico Granata     }
2149223383edSEnrico Granata 
21506e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptList() override = default;
2151223383edSEnrico Granata 
2152223383edSEnrico Granata     bool
215313d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2154223383edSEnrico Granata     {
2155223383edSEnrico Granata         m_interpreter.GetHelp(result,
2156223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
2157223383edSEnrico Granata 
2158223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2159223383edSEnrico Granata 
2160223383edSEnrico Granata         return true;
2161223383edSEnrico Granata     }
2162223383edSEnrico Granata };
2163223383edSEnrico Granata 
2164223383edSEnrico Granata //-------------------------------------------------------------------------
2165223383edSEnrico Granata // CommandObjectCommandsScriptClear
2166223383edSEnrico Granata //-------------------------------------------------------------------------
2167223383edSEnrico Granata 
21685a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed
2169223383edSEnrico Granata {
2170223383edSEnrico Granata public:
2171223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
21725a988416SJim Ingham         CommandObjectParsed(interpreter,
2173223383edSEnrico Granata                             "command script clear",
2174223383edSEnrico Granata                             "Delete all scripted commands.",
21756e3d8e7fSEugene Zelenko                             nullptr)
2176223383edSEnrico Granata     {
2177223383edSEnrico Granata     }
2178223383edSEnrico Granata 
21796e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptClear() override = default;
2180223383edSEnrico Granata 
21815a988416SJim Ingham protected:
2182223383edSEnrico Granata     bool
218313d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2184223383edSEnrico Granata     {
2185223383edSEnrico Granata         m_interpreter.RemoveAllUser();
2186223383edSEnrico Granata 
2187223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2188223383edSEnrico Granata 
2189223383edSEnrico Granata         return true;
2190223383edSEnrico Granata     }
2191223383edSEnrico Granata };
2192223383edSEnrico Granata 
2193223383edSEnrico Granata //-------------------------------------------------------------------------
2194223383edSEnrico Granata // CommandObjectCommandsScriptDelete
2195223383edSEnrico Granata //-------------------------------------------------------------------------
2196223383edSEnrico Granata 
21975a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed
2198223383edSEnrico Granata {
2199223383edSEnrico Granata public:
2200223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
22015a988416SJim Ingham         CommandObjectParsed(interpreter,
2202223383edSEnrico Granata                             "command script delete",
2203223383edSEnrico Granata                             "Delete a scripted command.",
22046e3d8e7fSEugene Zelenko                             nullptr)
2205223383edSEnrico Granata     {
2206223383edSEnrico Granata         CommandArgumentEntry arg1;
2207223383edSEnrico Granata         CommandArgumentData cmd_arg;
2208223383edSEnrico Granata 
2209223383edSEnrico Granata         // Define the first (and only) variant of this arg.
2210223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
2211223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
2212223383edSEnrico Granata 
2213223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
2214223383edSEnrico Granata         arg1.push_back (cmd_arg);
2215223383edSEnrico Granata 
2216223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
2217223383edSEnrico Granata         m_arguments.push_back (arg1);
2218223383edSEnrico Granata     }
2219223383edSEnrico Granata 
22206e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptDelete() override = default;
2221223383edSEnrico Granata 
22225a988416SJim Ingham protected:
2223223383edSEnrico Granata     bool
222413d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2225223383edSEnrico Granata     {
2226223383edSEnrico Granata 
22275a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2228223383edSEnrico Granata 
2229223383edSEnrico Granata         if (argc != 1)
2230223383edSEnrico Granata         {
2231223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
2232223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2233223383edSEnrico Granata             return false;
2234223383edSEnrico Granata         }
2235223383edSEnrico Granata 
22365a988416SJim Ingham         const char* cmd_name = command.GetArgumentAtIndex(0);
2237223383edSEnrico Granata 
2238223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2239223383edSEnrico Granata         {
2240223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
2241223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
2242223383edSEnrico Granata         }
2243223383edSEnrico Granata         else
2244223383edSEnrico Granata         {
2245223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
2246223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2247223383edSEnrico Granata         }
2248223383edSEnrico Granata 
2249223383edSEnrico Granata         return result.Succeeded();
2250223383edSEnrico Granata     }
2251223383edSEnrico Granata };
2252223383edSEnrico Granata 
2253223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
2254223383edSEnrico Granata 
2255223383edSEnrico Granata //-------------------------------------------------------------------------
2256223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
2257223383edSEnrico Granata //-------------------------------------------------------------------------
2258223383edSEnrico Granata 
2259223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2260223383edSEnrico Granata {
2261223383edSEnrico Granata public:
2262*7428a18cSKate Stone     CommandObjectMultiwordCommandsScript(CommandInterpreter &interpreter)
2263*7428a18cSKate Stone         : CommandObjectMultiword(interpreter, "command script",
2264*7428a18cSKate Stone                                  "Commands for managing custom commands implemented by interpreter scripts.",
2265223383edSEnrico Granata                                  "command script <subcommand> [<subcommand-options>]")
2266223383edSEnrico Granata     {
2267223383edSEnrico Granata         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2268223383edSEnrico Granata         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2269223383edSEnrico Granata         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
2270223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
2271a9dbf432SEnrico Granata         LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
2272223383edSEnrico Granata     }
2273223383edSEnrico Granata 
22746e3d8e7fSEugene Zelenko     ~CommandObjectMultiwordCommandsScript() override = default;
2275223383edSEnrico Granata };
2276223383edSEnrico Granata 
2277ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
2278ebc09c36SJim Ingham 
2279ebc09c36SJim Ingham //-------------------------------------------------------------------------
2280ebc09c36SJim Ingham // CommandObjectMultiwordCommands
2281ebc09c36SJim Ingham //-------------------------------------------------------------------------
2282ebc09c36SJim Ingham 
2283*7428a18cSKate Stone CommandObjectMultiwordCommands::CommandObjectMultiwordCommands(CommandInterpreter &interpreter)
2284*7428a18cSKate Stone     : CommandObjectMultiword(interpreter, "command", "Commands for managing custom LLDB commands.",
22850e5e5a79SGreg Clayton                              "command <subcommand> [<subcommand-options>]")
2286ebc09c36SJim Ingham {
2287a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2288a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2289a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
2290b547278cSGreg Clayton     LoadSubCommand ("delete",  CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
2291de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
2292a5a97ebeSJim Ingham     LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2293223383edSEnrico Granata     LoadSubCommand ("script",  CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
2294ebc09c36SJim Ingham }
2295ebc09c36SJim Ingham 
22966e3d8e7fSEugene Zelenko CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands() = default;
2297