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:
2385a988416SJim Ingham     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
2395a988416SJim Ingham         CommandObjectParsed(interpreter,
2405a988416SJim Ingham                             "command source",
2415a988416SJim Ingham                             "Read in debugger commands from the file <filename> and execute them.",
2426e3d8e7fSEugene Zelenko                             nullptr),
2435a988416SJim Ingham         m_options (interpreter)
2445a988416SJim Ingham     {
2455a988416SJim Ingham         CommandArgumentEntry arg;
2465a988416SJim Ingham         CommandArgumentData file_arg;
2475a988416SJim Ingham 
2485a988416SJim Ingham         // Define the first (and only) variant of this arg.
2495a988416SJim Ingham         file_arg.arg_type = eArgTypeFilename;
2505a988416SJim Ingham         file_arg.arg_repetition = eArgRepeatPlain;
2515a988416SJim Ingham 
2525a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
2535a988416SJim Ingham         arg.push_back (file_arg);
2545a988416SJim Ingham 
2555a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
2565a988416SJim Ingham         m_arguments.push_back (arg);
2575a988416SJim Ingham     }
2585a988416SJim Ingham 
2596e3d8e7fSEugene Zelenko     ~CommandObjectCommandsSource() override = default;
2605a988416SJim Ingham 
26113d21e9aSBruce Mitchener     const char*
26213d21e9aSBruce Mitchener     GetRepeatCommand (Args &current_command_args, uint32_t index) override
2635a988416SJim Ingham     {
2645a988416SJim Ingham         return "";
2655a988416SJim Ingham     }
2665a988416SJim Ingham 
26713d21e9aSBruce Mitchener     int
2685a988416SJim Ingham     HandleArgumentCompletion (Args &input,
2695a988416SJim Ingham                               int &cursor_index,
2705a988416SJim Ingham                               int &cursor_char_position,
2715a988416SJim Ingham                               OptionElementVector &opt_element_vector,
2725a988416SJim Ingham                               int match_start_point,
2735a988416SJim Ingham                               int max_return_elements,
2745a988416SJim Ingham                               bool &word_complete,
27513d21e9aSBruce Mitchener                               StringList &matches) override
2765a988416SJim Ingham     {
2775a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2785a988416SJim Ingham         completion_str.erase (cursor_char_position);
2795a988416SJim Ingham 
2805a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
2815a988416SJim Ingham                                                             CommandCompletions::eDiskFileCompletion,
2825a988416SJim Ingham                                                             completion_str.c_str(),
2835a988416SJim Ingham                                                             match_start_point,
2845a988416SJim Ingham                                                             max_return_elements,
2856e3d8e7fSEugene Zelenko                                                             nullptr,
2865a988416SJim Ingham                                                             word_complete,
2875a988416SJim Ingham                                                             matches);
2885a988416SJim Ingham         return matches.GetSize();
2895a988416SJim Ingham     }
2905a988416SJim Ingham 
29113d21e9aSBruce Mitchener     Options *
29213d21e9aSBruce Mitchener     GetOptions () override
2935a988416SJim Ingham     {
2945a988416SJim Ingham         return &m_options;
2955a988416SJim Ingham     }
2965a988416SJim Ingham 
2975a988416SJim Ingham protected:
298e16c50a1SJim Ingham     class CommandOptions : public Options
299e16c50a1SJim Ingham     {
300e16c50a1SJim Ingham     public:
301eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
302012d4fcaSEnrico Granata             Options (interpreter),
303340b0309SGreg Clayton             m_stop_on_error (true),
304340b0309SGreg Clayton             m_silent_run (false),
305340b0309SGreg Clayton             m_stop_on_continue (true)
306eb0103f2SGreg Clayton         {
307eb0103f2SGreg Clayton         }
308e16c50a1SJim Ingham 
3096e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
310e16c50a1SJim Ingham 
31113d21e9aSBruce Mitchener         Error
31213d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
313e16c50a1SJim Ingham         {
314e16c50a1SJim Ingham             Error error;
3153bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
316e16c50a1SJim Ingham 
317e16c50a1SJim Ingham             switch (short_option)
318e16c50a1SJim Ingham             {
319e16c50a1SJim Ingham                 case 'e':
320c95f7e2aSPavel Labath                     error = m_stop_on_error.SetValueFromString(option_arg);
321e16c50a1SJim Ingham                     break;
322340b0309SGreg Clayton 
323e16c50a1SJim Ingham                 case 'c':
324c95f7e2aSPavel Labath                     error = m_stop_on_continue.SetValueFromString(option_arg);
325e16c50a1SJim Ingham                     break;
326340b0309SGreg Clayton 
32760986174SMichael Sartain                 case 's':
328c95f7e2aSPavel Labath                     error = m_silent_run.SetValueFromString(option_arg);
32960986174SMichael Sartain                     break;
330340b0309SGreg Clayton 
331e16c50a1SJim Ingham                 default:
33286edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
333e16c50a1SJim Ingham                     break;
334e16c50a1SJim Ingham             }
335e16c50a1SJim Ingham 
336e16c50a1SJim Ingham             return error;
337e16c50a1SJim Ingham         }
338e16c50a1SJim Ingham 
339e16c50a1SJim Ingham         void
34013d21e9aSBruce Mitchener         OptionParsingStarting () override
341e16c50a1SJim Ingham         {
342012d4fcaSEnrico Granata             m_stop_on_error.Clear();
343340b0309SGreg Clayton             m_silent_run.Clear();
344340b0309SGreg Clayton             m_stop_on_continue.Clear();
345e16c50a1SJim Ingham         }
346e16c50a1SJim Ingham 
347e0d378b3SGreg Clayton         const OptionDefinition*
34813d21e9aSBruce Mitchener         GetDefinitions () override
349e16c50a1SJim Ingham         {
350e16c50a1SJim Ingham             return g_option_table;
351e16c50a1SJim Ingham         }
352e16c50a1SJim Ingham 
353e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
354e16c50a1SJim Ingham 
355e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
356e16c50a1SJim Ingham 
357e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
358e16c50a1SJim Ingham 
359012d4fcaSEnrico Granata         OptionValueBoolean m_stop_on_error;
360340b0309SGreg Clayton         OptionValueBoolean m_silent_run;
361340b0309SGreg Clayton         OptionValueBoolean m_stop_on_continue;
362e16c50a1SJim Ingham     };
363e16c50a1SJim Ingham 
364ebc09c36SJim Ingham     bool
36513d21e9aSBruce Mitchener     DoExecute(Args& command, CommandReturnObject &result) override
366ebc09c36SJim Ingham     {
367c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
368ebc09c36SJim Ingham         if (argc == 1)
369ebc09c36SJim Ingham         {
3705a988416SJim Ingham             const char *filename = command.GetArgumentAtIndex(0);
371ebc09c36SJim Ingham 
3721ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
3736e3d8e7fSEugene Zelenko             ExecutionContext *exe_ctx = nullptr;  // Just use the default context.
374ebc09c36SJim Ingham 
375340b0309SGreg Clayton             // If any options were set, then use them
376340b0309SGreg Clayton             if (m_options.m_stop_on_error.OptionWasSet()    ||
377340b0309SGreg Clayton                 m_options.m_silent_run.OptionWasSet()       ||
378340b0309SGreg Clayton                 m_options.m_stop_on_continue.OptionWasSet())
379340b0309SGreg Clayton             {
380340b0309SGreg Clayton                 // Use user set settings
38126c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
38226c7bf93SJim Ingham                 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
38326c7bf93SJim Ingham                 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
3847d8555c4SJim Ingham                 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
3857d8555c4SJim Ingham                 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
38626c7bf93SJim Ingham 
387e16c50a1SJim Ingham                 m_interpreter.HandleCommandsFromFile (cmd_file,
388e16c50a1SJim Ingham                                                       exe_ctx,
38926c7bf93SJim Ingham                                                       options,
390e16c50a1SJim Ingham                                                       result);
391340b0309SGreg Clayton             }
392340b0309SGreg Clayton             else
393340b0309SGreg Clayton             {
394340b0309SGreg Clayton                 // No options were set, inherit any settings from nested "command source" commands,
395340b0309SGreg Clayton                 // or set to sane default settings...
39626c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
397340b0309SGreg Clayton                 m_interpreter.HandleCommandsFromFile (cmd_file,
398340b0309SGreg Clayton                                                       exe_ctx,
39926c7bf93SJim Ingham                                                       options,
400340b0309SGreg Clayton                                                       result);
401340b0309SGreg Clayton             }
402ebc09c36SJim Ingham         }
403ebc09c36SJim Ingham         else
404ebc09c36SJim Ingham         {
405ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
406ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
407ebc09c36SJim Ingham         }
408ebc09c36SJim Ingham         return result.Succeeded();
409ebc09c36SJim Ingham     }
4106e3d8e7fSEugene Zelenko 
4115a988416SJim Ingham     CommandOptions m_options;
412ebc09c36SJim Ingham };
413ebc09c36SJim Ingham 
414e0d378b3SGreg Clayton OptionDefinition
415e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
416e16c50a1SJim Ingham {
4176e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
4186e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
4196e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
4206e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
421e16c50a1SJim Ingham };
422e16c50a1SJim Ingham 
423ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
424ebc09c36SJim Ingham //-------------------------------------------------------------------------
425ebc09c36SJim Ingham // CommandObjectCommandsAlias
426ebc09c36SJim Ingham //-------------------------------------------------------------------------
427ebc09c36SJim Ingham 
428be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
429be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
43044d93782SGreg Clayton                                                      "def my_command_impl(debugger, args, result, internal_dict):\n";
431be93a35aSEnrico Granata 
4325a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw
433ebc09c36SJim Ingham {
43445d0e238SEnrico Granata protected:
43545d0e238SEnrico Granata     class CommandOptions : public OptionGroup
43645d0e238SEnrico Granata     {
437ebc09c36SJim Ingham     public:
43845d0e238SEnrico Granata         CommandOptions () :
43945d0e238SEnrico Granata         OptionGroup(),
44045d0e238SEnrico Granata         m_help(),
44145d0e238SEnrico Granata         m_long_help()
44245d0e238SEnrico Granata         {}
44345d0e238SEnrico Granata 
44445d0e238SEnrico Granata         ~CommandOptions() override = default;
44545d0e238SEnrico Granata 
44645d0e238SEnrico Granata         uint32_t
44745d0e238SEnrico Granata         GetNumDefinitions () override
44845d0e238SEnrico Granata         {
44945d0e238SEnrico Granata             return 3;
45045d0e238SEnrico Granata         }
45145d0e238SEnrico Granata 
45245d0e238SEnrico Granata         const OptionDefinition*
45345d0e238SEnrico Granata         GetDefinitions () override
45445d0e238SEnrico Granata         {
45545d0e238SEnrico Granata             return g_option_table;
45645d0e238SEnrico Granata         }
45745d0e238SEnrico Granata 
45845d0e238SEnrico Granata         Error
45945d0e238SEnrico Granata         SetOptionValue (CommandInterpreter &interpreter,
46045d0e238SEnrico Granata                         uint32_t option_idx,
46145d0e238SEnrico Granata                         const char *option_value) override
46245d0e238SEnrico Granata         {
46345d0e238SEnrico Granata             Error error;
46445d0e238SEnrico Granata 
46545d0e238SEnrico Granata             const int short_option = g_option_table[option_idx].short_option;
46645d0e238SEnrico Granata 
46745d0e238SEnrico Granata             switch (short_option)
46845d0e238SEnrico Granata             {
46945d0e238SEnrico Granata                 case 'h':
47045d0e238SEnrico Granata                     m_help.SetCurrentValue(option_value);
47145d0e238SEnrico Granata                     m_help.SetOptionWasSet();
47245d0e238SEnrico Granata                     break;
47345d0e238SEnrico Granata 
47445d0e238SEnrico Granata                 case 'H':
47545d0e238SEnrico Granata                     m_long_help.SetCurrentValue(option_value);
47645d0e238SEnrico Granata                     m_long_help.SetOptionWasSet();
47745d0e238SEnrico Granata                     break;
47845d0e238SEnrico Granata 
47945d0e238SEnrico Granata                 default:
48045d0e238SEnrico Granata                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
48145d0e238SEnrico Granata                     break;
48245d0e238SEnrico Granata             }
48345d0e238SEnrico Granata 
48445d0e238SEnrico Granata             return error;
48545d0e238SEnrico Granata         }
48645d0e238SEnrico Granata 
48745d0e238SEnrico Granata         void
48845d0e238SEnrico Granata         OptionParsingStarting (CommandInterpreter &interpreter) override
48945d0e238SEnrico Granata         {
49045d0e238SEnrico Granata             m_help.Clear();
49145d0e238SEnrico Granata             m_long_help.Clear();
49245d0e238SEnrico Granata         }
49345d0e238SEnrico Granata 
49445d0e238SEnrico Granata         // Options table: Required for subclasses of Options.
49545d0e238SEnrico Granata 
49645d0e238SEnrico Granata         static OptionDefinition g_option_table[];
49745d0e238SEnrico Granata         OptionValueString m_help;
49845d0e238SEnrico Granata         OptionValueString m_long_help;
49945d0e238SEnrico Granata     };
50045d0e238SEnrico Granata 
50145d0e238SEnrico Granata     OptionGroupOptions m_option_group;
50245d0e238SEnrico Granata     CommandOptions m_command_options;
50345d0e238SEnrico Granata 
50445d0e238SEnrico Granata public:
50545d0e238SEnrico Granata     Options *
50645d0e238SEnrico Granata     GetOptions () override
50745d0e238SEnrico Granata     {
50845d0e238SEnrico Granata         return &m_option_group;
50945d0e238SEnrico Granata     }
51045d0e238SEnrico Granata 
511a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
5125a988416SJim Ingham         CommandObjectRaw(interpreter,
5130e5e5a79SGreg Clayton                          "command alias",
514e3d26315SCaroline Tice                          "Allow users to define their own debugger command abbreviations.",
51545d0e238SEnrico Granata                          nullptr),
51645d0e238SEnrico Granata         m_option_group(interpreter),
51745d0e238SEnrico Granata         m_command_options()
518ebc09c36SJim Ingham     {
51945d0e238SEnrico Granata         m_option_group.Append(&m_command_options);
52045d0e238SEnrico Granata         m_option_group.Finalize();
52145d0e238SEnrico Granata 
522ebc09c36SJim Ingham         SetHelpLong(
523ea671fbdSKate Stone "'alias' allows the user to create a short-cut or abbreviation for long \
524ea671fbdSKate Stone commands, multi-word commands, and commands that take particular options.  \
525ea671fbdSKate Stone Below are some simple examples of how one might use the 'alias' command:" R"(
526ea671fbdSKate Stone 
527ea671fbdSKate Stone (lldb) command alias sc script
528ea671fbdSKate Stone 
529ea671fbdSKate Stone     Creates the abbreviation 'sc' for the 'script' command.
530ea671fbdSKate Stone 
531ea671fbdSKate Stone (lldb) command alias bp breakpoint
532ea671fbdSKate Stone 
533ea671fbdSKate Stone )" "    Creates the abbreviation 'bp' for the 'breakpoint' command.  Since \
534ea671fbdSKate Stone breakpoint commands are two-word commands, the user would still need to \
535ea671fbdSKate Stone enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"(
536ea671fbdSKate Stone 
537ea671fbdSKate Stone (lldb) command alias bpl breakpoint list
538ea671fbdSKate Stone 
539ea671fbdSKate Stone     Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
540ea671fbdSKate Stone 
541ea671fbdSKate Stone )" "An alias can include some options for the command, with the values either \
542ea671fbdSKate Stone filled in at the time the alias is created, or specified as positional \
543ea671fbdSKate Stone arguments, to be filled in when the alias is invoked.  The following example \
544ea671fbdSKate Stone shows how to create aliases with options:" R"(
545ea671fbdSKate Stone 
546ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
547ea671fbdSKate Stone 
548ea671fbdSKate Stone )" "    Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
549ea671fbdSKate Stone options already part of the alias.  So if the user wants to set a breakpoint \
550ea671fbdSKate Stone by file and line without explicitly having to use the -f and -l options, the \
551ea671fbdSKate Stone user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \
552ea671fbdSKate Stone for the actual arguments that will be passed when the alias command is used.  \
553ea671fbdSKate Stone The number in the placeholder refers to the position/order the actual value \
554ea671fbdSKate Stone occupies when the alias is used.  All the occurrences of '%1' in the alias \
555ea671fbdSKate Stone will be replaced with the first argument, all the occurrences of '%2' in the \
556ea671fbdSKate Stone alias will be replaced with the second argument, and so on.  This also allows \
557ea671fbdSKate Stone actual arguments to be used multiple times within an alias (see 'process \
558ea671fbdSKate Stone launch' example below)." R"(
559ea671fbdSKate Stone 
560ea671fbdSKate Stone )" "Note: the positional arguments must substitute as whole words in the resultant \
561ea671fbdSKate Stone command, so you can't at present do something like this to append the file extension \
562ea671fbdSKate Stone \".cpp\":" R"(
563ea671fbdSKate Stone 
564ea671fbdSKate Stone (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
565ea671fbdSKate Stone 
566ea671fbdSKate Stone )" "For more complex aliasing, use the \"command regex\" command instead.  In the \
567ea671fbdSKate Stone 'bfl' case above, the actual file value will be filled in with the first argument \
568ea671fbdSKate Stone following 'bfl' and the actual line number value will be filled in with the second \
569ea671fbdSKate Stone argument.  The user would use this alias as follows:" R"(
570ea671fbdSKate Stone 
571ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
572ea671fbdSKate Stone (lldb) bfl my-file.c 137
573ea671fbdSKate Stone 
574ea671fbdSKate Stone This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
575ea671fbdSKate Stone 
576ea671fbdSKate Stone Another example:
577ea671fbdSKate Stone 
578ea671fbdSKate Stone (lldb) command alias pltty process launch -s -o %1 -e %1
579ea671fbdSKate Stone (lldb) pltty /dev/tty0
580ea671fbdSKate Stone 
581ea671fbdSKate Stone     Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
582ea671fbdSKate Stone 
583ea671fbdSKate Stone )" "If the user always wanted to pass the same value to a particular option, the \
584ea671fbdSKate Stone alias could be defined with that value directly in the alias as a constant, \
585ea671fbdSKate Stone rather than using a positional placeholder:" R"(
586ea671fbdSKate Stone 
587ea671fbdSKate Stone (lldb) command alias bl3 breakpoint set -f %1 -l 3
588ea671fbdSKate Stone 
589ea671fbdSKate Stone     Always sets a breakpoint on line 3 of whatever file is indicated.)"
590ea671fbdSKate Stone         );
591ebc09c36SJim Ingham 
592405fe67fSCaroline Tice         CommandArgumentEntry arg1;
593405fe67fSCaroline Tice         CommandArgumentEntry arg2;
594405fe67fSCaroline Tice         CommandArgumentEntry arg3;
595405fe67fSCaroline Tice         CommandArgumentData alias_arg;
596405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
597405fe67fSCaroline Tice         CommandArgumentData options_arg;
598405fe67fSCaroline Tice 
599405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
600405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
601405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
602405fe67fSCaroline Tice 
603405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
604405fe67fSCaroline Tice         arg1.push_back (alias_arg);
605405fe67fSCaroline Tice 
606405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
607405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
608405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
609405fe67fSCaroline Tice 
610405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
611405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
612405fe67fSCaroline Tice 
613405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
614405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
615405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
616405fe67fSCaroline Tice 
617405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
618405fe67fSCaroline Tice         arg3.push_back (options_arg);
619405fe67fSCaroline Tice 
620405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
621405fe67fSCaroline Tice         m_arguments.push_back (arg1);
622405fe67fSCaroline Tice         m_arguments.push_back (arg2);
623405fe67fSCaroline Tice         m_arguments.push_back (arg3);
624ebc09c36SJim Ingham     }
625ebc09c36SJim Ingham 
6266e3d8e7fSEugene Zelenko     ~CommandObjectCommandsAlias() override = default;
627ebc09c36SJim Ingham 
6285a988416SJim Ingham protected:
62913d21e9aSBruce Mitchener     bool
63013d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
631844d2303SCaroline Tice     {
63245d0e238SEnrico Granata         if (!raw_command_line || !raw_command_line[0])
63345d0e238SEnrico Granata         {
634*d72e412fSEnrico Granata             result.AppendError ("'command alias' requires at least two arguments");
63545d0e238SEnrico Granata             return false;
63645d0e238SEnrico Granata         }
63745d0e238SEnrico Granata 
63845d0e238SEnrico Granata         m_option_group.NotifyOptionParsingStarting();
63945d0e238SEnrico Granata 
64045d0e238SEnrico Granata         const char * remainder = nullptr;
64145d0e238SEnrico Granata 
64245d0e238SEnrico Granata         if (raw_command_line[0] == '-')
64345d0e238SEnrico Granata         {
64445d0e238SEnrico Granata             // We have some options and these options MUST end with --.
64545d0e238SEnrico Granata             const char *end_options = nullptr;
64645d0e238SEnrico Granata             const char *s = raw_command_line;
64745d0e238SEnrico Granata             while (s && s[0])
64845d0e238SEnrico Granata             {
64945d0e238SEnrico Granata                 end_options = ::strstr (s, "--");
65045d0e238SEnrico Granata                 if (end_options)
65145d0e238SEnrico Granata                 {
65245d0e238SEnrico Granata                     end_options += 2; // Get past the "--"
65345d0e238SEnrico Granata                     if (::isspace (end_options[0]))
65445d0e238SEnrico Granata                     {
65545d0e238SEnrico Granata                         remainder = end_options;
65645d0e238SEnrico Granata                         while (::isspace (*remainder))
65745d0e238SEnrico Granata                             ++remainder;
65845d0e238SEnrico Granata                         break;
65945d0e238SEnrico Granata                     }
66045d0e238SEnrico Granata                 }
66145d0e238SEnrico Granata                 s = end_options;
66245d0e238SEnrico Granata             }
66345d0e238SEnrico Granata 
66445d0e238SEnrico Granata             if (end_options)
66545d0e238SEnrico Granata             {
66645d0e238SEnrico Granata                 Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
66745d0e238SEnrico Granata                 if (!ParseOptions (args, result))
66845d0e238SEnrico Granata                     return false;
66945d0e238SEnrico Granata 
67045d0e238SEnrico Granata                 Error error (m_option_group.NotifyOptionParsingFinished());
67145d0e238SEnrico Granata                 if (error.Fail())
67245d0e238SEnrico Granata                 {
67345d0e238SEnrico Granata                     result.AppendError (error.AsCString());
67445d0e238SEnrico Granata                     result.SetStatus (eReturnStatusFailed);
67545d0e238SEnrico Granata                     return false;
67645d0e238SEnrico Granata                 }
67745d0e238SEnrico Granata             }
67845d0e238SEnrico Granata         }
67945d0e238SEnrico Granata         if (nullptr == remainder)
68045d0e238SEnrico Granata             remainder = raw_command_line;
68145d0e238SEnrico Granata 
68245d0e238SEnrico Granata         std::string raw_command_string (remainder);
68345d0e238SEnrico Granata         Args args (raw_command_string.c_str());
684844d2303SCaroline Tice 
685844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
686844d2303SCaroline Tice 
687844d2303SCaroline Tice         if (argc < 2)
688844d2303SCaroline Tice         {
689*d72e412fSEnrico Granata             result.AppendError ("'command alias' requires at least two arguments");
690844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
691844d2303SCaroline Tice             return false;
692844d2303SCaroline Tice         }
693844d2303SCaroline Tice 
694844d2303SCaroline Tice         // Get the alias command.
695844d2303SCaroline Tice 
696844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
697*d72e412fSEnrico Granata         if (alias_command.size() > 1 &&
698*d72e412fSEnrico Granata             alias_command[0] == '-')
699*d72e412fSEnrico Granata         {
700*d72e412fSEnrico Granata             result.AppendError("aliases starting with a dash are not supported");
701*d72e412fSEnrico Granata             if (alias_command == "--help" || alias_command == "--long-help")
702*d72e412fSEnrico Granata             {
703*d72e412fSEnrico Granata                 result.AppendWarning("if trying to pass options to 'command alias' add a -- at the end of the options");
704*d72e412fSEnrico Granata             }
705*d72e412fSEnrico Granata             result.SetStatus (eReturnStatusFailed);
706*d72e412fSEnrico Granata             return false;
707*d72e412fSEnrico Granata         }
708844d2303SCaroline Tice 
709844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
710844d2303SCaroline Tice         // does the stripping itself.
711844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
712844d2303SCaroline Tice         if (pos == 0)
713844d2303SCaroline Tice         {
714844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
715844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
716844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
717844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
718844d2303SCaroline Tice         }
719844d2303SCaroline Tice         else
720844d2303SCaroline Tice         {
721844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
722844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
723844d2303SCaroline Tice             return false;
724844d2303SCaroline Tice         }
725844d2303SCaroline Tice 
726844d2303SCaroline Tice 
727844d2303SCaroline Tice         // Verify that the command is alias-able.
728844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
729844d2303SCaroline Tice         {
730844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
731844d2303SCaroline Tice                                           alias_command.c_str());
732844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
733844d2303SCaroline Tice             return false;
734844d2303SCaroline Tice         }
735844d2303SCaroline Tice 
736844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
737844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
738*d72e412fSEnrico Granata         std::string original_raw_command_string(raw_command_string);
739844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
740844d2303SCaroline Tice 
741844d2303SCaroline Tice         if (!cmd_obj)
742844d2303SCaroline Tice         {
743*d72e412fSEnrico Granata             result.AppendErrorWithFormat ("invalid command given to 'command alias'. '%s' does not begin with a valid command."
744*d72e412fSEnrico Granata                                           "  No alias created.", original_raw_command_string.c_str());
745844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
746844d2303SCaroline Tice             return false;
747844d2303SCaroline Tice         }
748844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
749844d2303SCaroline Tice         {
750844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
751844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
7525a988416SJim Ingham             return HandleAliasingNormalCommand (args, result);
753844d2303SCaroline Tice         }
754844d2303SCaroline Tice         else
755844d2303SCaroline Tice         {
7565a988416SJim Ingham             return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
7575a988416SJim Ingham         }
7585a988416SJim Ingham         return result.Succeeded();
7595a988416SJim Ingham     }
7605a988416SJim Ingham 
7615a988416SJim Ingham     bool
7625a988416SJim Ingham     HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
7635a988416SJim Ingham     {
764844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
765844d2303SCaroline Tice 
766844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
767844d2303SCaroline Tice 
768212130acSEnrico Granata             if (CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false))
769844d2303SCaroline Tice             {
770844d2303SCaroline Tice                 if (m_interpreter.AliasExists (alias_command.c_str())
771844d2303SCaroline Tice                     || m_interpreter.UserCommandExists (alias_command.c_str()))
772844d2303SCaroline Tice                 {
773844d2303SCaroline Tice                     result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
774844d2303SCaroline Tice                                                     alias_command.c_str());
775844d2303SCaroline Tice                 }
77645d0e238SEnrico Granata                 if (CommandAlias *alias = m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp, raw_command_string.c_str()))
777472362e6SCaroline Tice                 {
77845d0e238SEnrico Granata                     if (m_command_options.m_help.OptionWasSet())
77945d0e238SEnrico Granata                         alias->SetHelp(m_command_options.m_help.GetCurrentValue());
78045d0e238SEnrico Granata                     if (m_command_options.m_long_help.OptionWasSet())
78145d0e238SEnrico Granata                         alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
782844d2303SCaroline Tice                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
783844d2303SCaroline Tice                 }
784472362e6SCaroline Tice                 else
785472362e6SCaroline Tice                 {
786472362e6SCaroline Tice                     result.AppendError ("Unable to create requested alias.\n");
787472362e6SCaroline Tice                     result.SetStatus (eReturnStatusFailed);
788472362e6SCaroline Tice                 }
789212130acSEnrico Granata 
790212130acSEnrico Granata             }
791212130acSEnrico Granata             else
792212130acSEnrico Granata             {
793212130acSEnrico Granata                 result.AppendError ("Unable to create requested alias.\n");
794212130acSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
795212130acSEnrico Granata             }
796212130acSEnrico Granata 
797844d2303SCaroline Tice             return result.Succeeded ();
798844d2303SCaroline Tice     }
799ebc09c36SJim Ingham 
800ebc09c36SJim Ingham     bool
8015a988416SJim Ingham     HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
802ebc09c36SJim Ingham     {
803867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
804ebc09c36SJim Ingham 
805ebc09c36SJim Ingham         if (argc < 2)
806ebc09c36SJim Ingham         {
807*d72e412fSEnrico Granata             result.AppendError ("'command alias' requires at least two arguments");
808ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
809ebc09c36SJim Ingham             return false;
810ebc09c36SJim Ingham         }
811ebc09c36SJim Ingham 
812ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
813ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
814ebc09c36SJim Ingham 
815ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
816ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
817ebc09c36SJim Ingham 
818ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
819ebc09c36SJim Ingham 
820a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
821ebc09c36SJim Ingham         {
822ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
823ebc09c36SJim Ingham                                          alias_command.c_str());
824ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
825ebc09c36SJim Ingham         }
826ebc09c36SJim Ingham         else
827ebc09c36SJim Ingham         {
828a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
829ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
830ebc09c36SJim Ingham              bool use_subcommand = false;
8316e3d8e7fSEugene Zelenko              if (command_obj_sp)
832ebc09c36SJim Ingham              {
833ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
8346e3d8e7fSEugene Zelenko                  CommandObject *sub_cmd_obj = nullptr;
835ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
836ebc09c36SJim Ingham 
837844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
838ebc09c36SJim Ingham                  {
839ebc09c36SJim Ingham                      if (argc >= 3)
840ebc09c36SJim Ingham                      {
841ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
842ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
843998255bfSGreg Clayton                          subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
8446e3d8e7fSEugene Zelenko                          if (subcommand_obj_sp)
845ebc09c36SJim Ingham                          {
846ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
847ebc09c36SJim Ingham                              use_subcommand = true;
848ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
849844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
850ebc09c36SJim Ingham                          }
851ebc09c36SJim Ingham                          else
852ebc09c36SJim Ingham                          {
853f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
854f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
855f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
856ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
857ebc09c36SJim Ingham                              return false;
858ebc09c36SJim Ingham                          }
859ebc09c36SJim Ingham                      }
860ebc09c36SJim Ingham                  }
861ebc09c36SJim Ingham 
862ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
863ebc09c36SJim Ingham 
864212130acSEnrico Granata                  std::string args_string;
865212130acSEnrico Granata 
866ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
867ebc09c36SJim Ingham                  {
868ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
869ebc09c36SJim Ingham                     if (use_subcommand)
870ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
871ca90c47eSCaroline Tice 
872ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
873867b185dSCaroline Tice                  }
874ebc09c36SJim Ingham 
875a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
876a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
877ebc09c36SJim Ingham                  {
878ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
879ebc09c36SJim Ingham                                                      alias_command.c_str());
880ebc09c36SJim Ingham                  }
881ebc09c36SJim Ingham 
88245d0e238SEnrico Granata                  if (CommandAlias *alias = m_interpreter.AddAlias(alias_command.c_str(),
883212130acSEnrico Granata                                                                   use_subcommand ? subcommand_obj_sp : command_obj_sp,
884212130acSEnrico Granata                                                                   args_string.c_str()))
885212130acSEnrico Granata                  {
88645d0e238SEnrico Granata                      if (m_command_options.m_help.OptionWasSet())
88745d0e238SEnrico Granata                          alias->SetHelp(m_command_options.m_help.GetCurrentValue());
88845d0e238SEnrico Granata                      if (m_command_options.m_long_help.OptionWasSet())
88945d0e238SEnrico Granata                          alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
890ebc09c36SJim Ingham                      result.SetStatus (eReturnStatusSuccessFinishNoResult);
891ebc09c36SJim Ingham                  }
892ebc09c36SJim Ingham                  else
893ebc09c36SJim Ingham                  {
894212130acSEnrico Granata                      result.AppendError ("Unable to create requested alias.\n");
895212130acSEnrico Granata                      result.SetStatus (eReturnStatusFailed);
896212130acSEnrico Granata                      return false;
897212130acSEnrico Granata                  }
898212130acSEnrico Granata              }
899212130acSEnrico Granata              else
900212130acSEnrico Granata              {
901ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
902ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
903e7941795SCaroline Tice                  return false;
904ebc09c36SJim Ingham              }
905ebc09c36SJim Ingham         }
906ebc09c36SJim Ingham 
907ebc09c36SJim Ingham         return result.Succeeded();
908ebc09c36SJim Ingham     }
909ebc09c36SJim Ingham };
910ebc09c36SJim Ingham 
91145d0e238SEnrico Granata OptionDefinition
91245d0e238SEnrico Granata CommandObjectCommandsAlias::CommandOptions::g_option_table[] =
91345d0e238SEnrico Granata {
91445d0e238SEnrico Granata     { LLDB_OPT_SET_ALL, false, "help",      'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText,    "Help text for this command"},
91545d0e238SEnrico Granata     { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText,    "Long help text for this command"},
91645d0e238SEnrico Granata     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
91745d0e238SEnrico Granata };
91845d0e238SEnrico Granata 
919ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
920ebc09c36SJim Ingham //-------------------------------------------------------------------------
921ebc09c36SJim Ingham // CommandObjectCommandsUnalias
922ebc09c36SJim Ingham //-------------------------------------------------------------------------
923ebc09c36SJim Ingham 
9245a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed
925ebc09c36SJim Ingham {
926ebc09c36SJim Ingham public:
927a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
9285a988416SJim Ingham         CommandObjectParsed(interpreter,
9290e5e5a79SGreg Clayton                             "command unalias",
93086ddae50SCaroline Tice                             "Allow the user to remove/delete a user-defined command abbreviation.",
9316e3d8e7fSEugene Zelenko                             nullptr)
932ebc09c36SJim Ingham     {
933405fe67fSCaroline Tice         CommandArgumentEntry arg;
934405fe67fSCaroline Tice         CommandArgumentData alias_arg;
935405fe67fSCaroline Tice 
936405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
937405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
938405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
939405fe67fSCaroline Tice 
940405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
941405fe67fSCaroline Tice         arg.push_back (alias_arg);
942405fe67fSCaroline Tice 
943405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
944405fe67fSCaroline Tice         m_arguments.push_back (arg);
945ebc09c36SJim Ingham     }
946ebc09c36SJim Ingham 
9476e3d8e7fSEugene Zelenko     ~CommandObjectCommandsUnalias() override = default;
948ebc09c36SJim Ingham 
9495a988416SJim Ingham protected:
950ebc09c36SJim Ingham     bool
95113d21e9aSBruce Mitchener     DoExecute (Args& args, CommandReturnObject &result) override
952ebc09c36SJim Ingham     {
953ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
954ebc09c36SJim Ingham         CommandObject *cmd_obj;
955ebc09c36SJim Ingham 
956ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
957ebc09c36SJim Ingham         {
958ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
959a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
960ebc09c36SJim Ingham             if (cmd_obj)
961ebc09c36SJim Ingham             {
962a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
963ebc09c36SJim Ingham                 {
964b547278cSGreg Clayton                     if (cmd_obj->IsRemovable())
965b547278cSGreg Clayton                     {
966b547278cSGreg Clayton                         result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
967b547278cSGreg Clayton                                                       command_name);
968b547278cSGreg Clayton                     }
969b547278cSGreg Clayton                     else
970b547278cSGreg Clayton                     {
971ebc09c36SJim Ingham                         result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
972ebc09c36SJim Ingham                                                       command_name);
973b547278cSGreg Clayton                     }
974ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
975ebc09c36SJim Ingham                 }
976ebc09c36SJim Ingham                 else
977ebc09c36SJim Ingham                 {
9786e3d8e7fSEugene Zelenko                     if (!m_interpreter.RemoveAlias(command_name))
979ebc09c36SJim Ingham                     {
980a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
981ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
982ebc09c36SJim Ingham                                                           command_name);
983ebc09c36SJim Ingham                         else
984ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
985ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
986ebc09c36SJim Ingham                     }
987ebc09c36SJim Ingham                     else
988ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
989ebc09c36SJim Ingham                 }
990ebc09c36SJim Ingham             }
991ebc09c36SJim Ingham             else
992ebc09c36SJim Ingham             {
993ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
994ebc09c36SJim Ingham                                               "current list of commands.\n",
995ebc09c36SJim Ingham                                              command_name);
996ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
997ebc09c36SJim Ingham             }
998ebc09c36SJim Ingham         }
999ebc09c36SJim Ingham         else
1000ebc09c36SJim Ingham         {
1001ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
1002ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
1003ebc09c36SJim Ingham         }
1004ebc09c36SJim Ingham 
1005ebc09c36SJim Ingham         return result.Succeeded();
1006ebc09c36SJim Ingham     }
1007ebc09c36SJim Ingham };
1008ebc09c36SJim Ingham 
1009b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete
1010b547278cSGreg Clayton //-------------------------------------------------------------------------
1011b547278cSGreg Clayton // CommandObjectCommandsDelete
1012b547278cSGreg Clayton //-------------------------------------------------------------------------
1013b547278cSGreg Clayton 
1014b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed
1015b547278cSGreg Clayton {
1016b547278cSGreg Clayton public:
1017b547278cSGreg Clayton     CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
1018b547278cSGreg Clayton         CommandObjectParsed(interpreter,
1019b547278cSGreg Clayton                             "command delete",
1020b547278cSGreg Clayton                             "Allow the user to delete user-defined regular expression, python or multi-word commands.",
10216e3d8e7fSEugene Zelenko                             nullptr)
1022b547278cSGreg Clayton     {
1023b547278cSGreg Clayton         CommandArgumentEntry arg;
1024b547278cSGreg Clayton         CommandArgumentData alias_arg;
1025b547278cSGreg Clayton 
1026b547278cSGreg Clayton         // Define the first (and only) variant of this arg.
1027b547278cSGreg Clayton         alias_arg.arg_type = eArgTypeCommandName;
1028b547278cSGreg Clayton         alias_arg.arg_repetition = eArgRepeatPlain;
1029b547278cSGreg Clayton 
1030b547278cSGreg Clayton         // There is only one variant this argument could be; put it into the argument entry.
1031b547278cSGreg Clayton         arg.push_back (alias_arg);
1032b547278cSGreg Clayton 
1033b547278cSGreg Clayton         // Push the data for the first argument into the m_arguments vector.
1034b547278cSGreg Clayton         m_arguments.push_back (arg);
1035b547278cSGreg Clayton     }
1036b547278cSGreg Clayton 
10376e3d8e7fSEugene Zelenko     ~CommandObjectCommandsDelete() override = default;
1038b547278cSGreg Clayton 
1039b547278cSGreg Clayton protected:
1040b547278cSGreg Clayton     bool
104113d21e9aSBruce Mitchener     DoExecute (Args& args, CommandReturnObject &result) override
1042b547278cSGreg Clayton     {
1043b547278cSGreg Clayton         CommandObject::CommandMap::iterator pos;
1044b547278cSGreg Clayton 
1045b547278cSGreg Clayton         if (args.GetArgumentCount() != 0)
1046b547278cSGreg Clayton         {
1047b547278cSGreg Clayton             const char *command_name = args.GetArgumentAtIndex(0);
1048b547278cSGreg Clayton             if (m_interpreter.CommandExists (command_name))
1049b547278cSGreg Clayton             {
1050b547278cSGreg Clayton                 if (m_interpreter.RemoveCommand (command_name))
1051b547278cSGreg Clayton                 {
1052b547278cSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1053b547278cSGreg Clayton                 }
1054b547278cSGreg Clayton                 else
1055b547278cSGreg Clayton                 {
1056b547278cSGreg Clayton                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
1057b547278cSGreg Clayton                                                   command_name);
1058b547278cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
1059b547278cSGreg Clayton                 }
1060b547278cSGreg Clayton             }
1061b547278cSGreg Clayton             else
1062b547278cSGreg Clayton             {
106346d4aa21SEnrico Granata                 StreamString error_msg_stream;
106446d4aa21SEnrico Granata                 const bool generate_apropos = true;
106546d4aa21SEnrico Granata                 const bool generate_type_lookup = false;
106646d4aa21SEnrico Granata                 CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
106746d4aa21SEnrico Granata                                                                         command_name,
106846d4aa21SEnrico Granata                                                                         nullptr,
106946d4aa21SEnrico Granata                                                                         nullptr,
107046d4aa21SEnrico Granata                                                                         generate_apropos,
107146d4aa21SEnrico Granata                                                                         generate_type_lookup);
107246d4aa21SEnrico Granata                 result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
1073b547278cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1074b547278cSGreg Clayton             }
1075b547278cSGreg Clayton         }
1076b547278cSGreg Clayton         else
1077b547278cSGreg Clayton         {
1078b547278cSGreg Clayton             result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
1079b547278cSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1080b547278cSGreg Clayton         }
1081b547278cSGreg Clayton 
1082b547278cSGreg Clayton         return result.Succeeded();
1083b547278cSGreg Clayton     }
1084b547278cSGreg Clayton };
1085b547278cSGreg Clayton 
1086de164aaaSGreg Clayton //-------------------------------------------------------------------------
1087de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
1088de164aaaSGreg Clayton //-------------------------------------------------------------------------
10895a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex
1090de164aaaSGreg Clayton 
109144d93782SGreg Clayton class CommandObjectCommandsAddRegex :
109244d93782SGreg Clayton     public CommandObjectParsed,
1093ea508635SGreg Clayton     public IOHandlerDelegateMultiline
1094de164aaaSGreg Clayton {
1095de164aaaSGreg Clayton public:
1096de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
10975a988416SJim Ingham         CommandObjectParsed (interpreter,
10980e5e5a79SGreg Clayton                        "command regex",
1099de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
11000e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
1101ea508635SGreg Clayton         IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
1102de164aaaSGreg Clayton         m_options (interpreter)
1103de164aaaSGreg Clayton     {
1104ea671fbdSKate Stone         SetHelpLong(R"(
1105ea671fbdSKate Stone )" "This command allows the user to create powerful regular expression commands \
1106ea671fbdSKate Stone with substitutions. The regular expressions and substitutions are specified \
1107ea671fbdSKate Stone using the regular expression substitution format of:" R"(
1108ea671fbdSKate Stone 
1109ea671fbdSKate Stone     s/<regex>/<subst>/
1110ea671fbdSKate Stone 
1111ea671fbdSKate Stone )" "<regex> is a regular expression that can use parenthesis to capture regular \
1112ea671fbdSKate Stone expression input and substitute the captured matches in the output using %1 \
1113ea671fbdSKate Stone for the first match, %2 for the second, and so on." R"(
1114ea671fbdSKate Stone 
1115ea671fbdSKate Stone )" "The regular expressions can all be specified on the command line if more than \
1116ea671fbdSKate Stone one argument is provided. If just the command name is provided on the command \
1117ea671fbdSKate Stone line, then the regular expressions and substitutions can be entered on separate \
1118ea671fbdSKate Stone lines, followed by an empty line to terminate the command definition." R"(
1119ea671fbdSKate Stone 
1120ea671fbdSKate Stone EXAMPLES
1121ea671fbdSKate Stone 
1122ea671fbdSKate Stone )" "The following example will define a regular expression command named 'f' that \
1123ea671fbdSKate Stone will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
1124ea671fbdSKate Stone a number follows 'f':" R"(
1125ea671fbdSKate Stone 
1126ea671fbdSKate Stone     (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
11270e5e5a79SGreg Clayton         );
1128de164aaaSGreg Clayton     }
1129de164aaaSGreg Clayton 
11306e3d8e7fSEugene Zelenko     ~CommandObjectCommandsAddRegex() override = default;
1131de164aaaSGreg Clayton 
11325a988416SJim Ingham protected:
1133ea508635SGreg Clayton     void
1134ea508635SGreg Clayton     IOHandlerActivated (IOHandler &io_handler) override
113544d93782SGreg Clayton     {
113644d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
113744d93782SGreg Clayton         if (output_sp)
113844d93782SGreg Clayton         {
113944d93782SGreg 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");
114044d93782SGreg Clayton             output_sp->Flush();
114144d93782SGreg Clayton         }
114244d93782SGreg Clayton     }
114344d93782SGreg Clayton 
1144ea508635SGreg Clayton     void
1145ea508635SGreg Clayton     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
114644d93782SGreg Clayton     {
114744d93782SGreg Clayton         io_handler.SetIsDone(true);
11486e3d8e7fSEugene Zelenko         if (m_regex_cmd_ap)
114944d93782SGreg Clayton         {
115044d93782SGreg Clayton             StringList lines;
115144d93782SGreg Clayton             if (lines.SplitIntoLines (data))
115244d93782SGreg Clayton             {
115344d93782SGreg Clayton                 const size_t num_lines = lines.GetSize();
115444d93782SGreg Clayton                 bool check_only = false;
115544d93782SGreg Clayton                 for (size_t i=0; i<num_lines; ++i)
115644d93782SGreg Clayton                 {
115744d93782SGreg Clayton                     llvm::StringRef bytes_strref (lines[i]);
115844d93782SGreg Clayton                     Error error = AppendRegexSubstitution (bytes_strref, check_only);
115944d93782SGreg Clayton                     if (error.Fail())
116044d93782SGreg Clayton                     {
116144d93782SGreg Clayton                         if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
116244d93782SGreg Clayton                         {
116344d93782SGreg Clayton                             StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
116444d93782SGreg Clayton                             out_stream->Printf("error: %s\n", error.AsCString());
116544d93782SGreg Clayton                         }
116644d93782SGreg Clayton                     }
116744d93782SGreg Clayton                 }
116844d93782SGreg Clayton             }
116944d93782SGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
117044d93782SGreg Clayton             {
117144d93782SGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
117244d93782SGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
117344d93782SGreg Clayton             }
117444d93782SGreg Clayton         }
117544d93782SGreg Clayton     }
117644d93782SGreg Clayton 
1177de164aaaSGreg Clayton     bool
1178b0a1814fSEric Christopher     DoExecute (Args& command, CommandReturnObject &result) override
1179de164aaaSGreg Clayton     {
11805a988416SJim Ingham         const size_t argc = command.GetArgumentCount();
11810e5e5a79SGreg Clayton         if (argc == 0)
1182de164aaaSGreg Clayton         {
118369c12ccbSJason Molenda             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
11840e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
11850e5e5a79SGreg Clayton         }
11860e5e5a79SGreg Clayton         else
11870e5e5a79SGreg Clayton         {
11880e5e5a79SGreg Clayton             Error error;
11895a988416SJim Ingham             const char *name = command.GetArgumentAtIndex(0);
1190de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1191de164aaaSGreg Clayton                                                                  name,
1192de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
1193de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
1194b547278cSGreg Clayton                                                                  10,
1195b547278cSGreg Clayton                                                                  0,
1196b547278cSGreg Clayton                                                                  true));
11970e5e5a79SGreg Clayton 
11980e5e5a79SGreg Clayton             if (argc == 1)
11990e5e5a79SGreg Clayton             {
120044d93782SGreg Clayton                 Debugger &debugger = m_interpreter.GetDebugger();
1201e30f11d9SKate Stone                 bool color_prompt = debugger.GetUseColor();
120244d93782SGreg Clayton                 const bool multiple_lines = true; // Get multiple lines
120344d93782SGreg Clayton                 IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
1204e30f11d9SKate Stone                                                                 IOHandler::Type::Other,
120573d80faaSGreg Clayton                                                                 "lldb-regex", // Name of input reader for history
1206ea508635SGreg Clayton                                                                 "> ",         // Prompt
12076e3d8e7fSEugene Zelenko                                                                 nullptr,      // Continuation prompt
120844d93782SGreg Clayton                                                                 multiple_lines,
1209e30f11d9SKate Stone                                                                 color_prompt,
1210f6913cd7SGreg Clayton                                                                 0,            // Don't show line numbers
121144d93782SGreg Clayton                                                                 *this));
121244d93782SGreg Clayton 
121344d93782SGreg Clayton                 if (io_handler_sp)
1214de164aaaSGreg Clayton                 {
121544d93782SGreg Clayton                     debugger.PushIOHandler(io_handler_sp);
1216de164aaaSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1217de164aaaSGreg Clayton                 }
1218de164aaaSGreg Clayton             }
1219de164aaaSGreg Clayton             else
1220de164aaaSGreg Clayton             {
12210e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
12220e5e5a79SGreg Clayton                 {
12235a988416SJim Ingham                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
122444d93782SGreg Clayton                     bool check_only = false;
122544d93782SGreg Clayton                     error = AppendRegexSubstitution (arg_strref, check_only);
12260e5e5a79SGreg Clayton                     if (error.Fail())
12270e5e5a79SGreg Clayton                         break;
12280e5e5a79SGreg Clayton                 }
12290e5e5a79SGreg Clayton 
12300e5e5a79SGreg Clayton                 if (error.Success())
12310e5e5a79SGreg Clayton                 {
12320e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
12330e5e5a79SGreg Clayton                 }
12340e5e5a79SGreg Clayton             }
12350e5e5a79SGreg Clayton             if (error.Fail())
12360e5e5a79SGreg Clayton             {
12370e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
1238de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1239de164aaaSGreg Clayton             }
12400e5e5a79SGreg Clayton         }
12410e5e5a79SGreg Clayton 
1242de164aaaSGreg Clayton         return result.Succeeded();
1243de164aaaSGreg Clayton     }
1244de164aaaSGreg Clayton 
12450e5e5a79SGreg Clayton     Error
124644d93782SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
1247de164aaaSGreg Clayton     {
12480e5e5a79SGreg Clayton         Error error;
12490e5e5a79SGreg Clayton 
12506e3d8e7fSEugene Zelenko         if (!m_regex_cmd_ap)
1251de164aaaSGreg Clayton         {
12520e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
12530e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12540e5e5a79SGreg Clayton                                            regex_sed.data());
12550e5e5a79SGreg Clayton             return error;
1256de164aaaSGreg Clayton         }
12570e5e5a79SGreg Clayton 
12580e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
12590e5e5a79SGreg Clayton 
12600e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
12610e5e5a79SGreg Clayton         {
12620e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
12630e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12640e5e5a79SGreg Clayton                                            regex_sed.data());
12650e5e5a79SGreg Clayton             return error;
12660e5e5a79SGreg Clayton         }
12670e5e5a79SGreg Clayton 
12680e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
12690e5e5a79SGreg Clayton         {
12700e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
12710e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12720e5e5a79SGreg Clayton                                            regex_sed.data());
12730e5e5a79SGreg Clayton             return error;
12740e5e5a79SGreg Clayton         }
12750e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
12760e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
12770e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
12780e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
12790e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
12800e5e5a79SGreg Clayton 
12810e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
12820e5e5a79SGreg Clayton         {
1283ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
12840e5e5a79SGreg Clayton                                            separator_char,
12850e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
1286ea508635SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1),
1287ea508635SGreg Clayton                                            (int)regex_sed.size(),
1288ea508635SGreg Clayton                                            regex_sed.data());
12890e5e5a79SGreg Clayton             return error;
12900e5e5a79SGreg Clayton         }
12910e5e5a79SGreg Clayton 
12920e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
12930e5e5a79SGreg Clayton 
12940e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
12950e5e5a79SGreg Clayton         {
1296ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
12970e5e5a79SGreg Clayton                                            separator_char,
12980e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
1299ea508635SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1),
1300ea508635SGreg Clayton                                            (int)regex_sed.size(),
1301ea508635SGreg Clayton                                            regex_sed.data());
13020e5e5a79SGreg Clayton             return error;
13030e5e5a79SGreg Clayton         }
13040e5e5a79SGreg Clayton 
13050e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
13060e5e5a79SGreg Clayton         {
13070e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
13080e5e5a79SGreg Clayton             // separator char
13090e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
13100e5e5a79SGreg Clayton             {
13110e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
13120e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
13130e5e5a79SGreg Clayton                                                regex_sed.data(),
13140e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
13150e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
13160e5e5a79SGreg Clayton                 return error;
13170e5e5a79SGreg Clayton             }
13180e5e5a79SGreg Clayton         }
13190e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
13200e5e5a79SGreg Clayton         {
13210e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
13220e5e5a79SGreg Clayton                                            separator_char,
13230e5e5a79SGreg Clayton                                            separator_char,
13240e5e5a79SGreg Clayton                                            separator_char,
13250e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
13260e5e5a79SGreg Clayton                                            regex_sed.data());
13270e5e5a79SGreg Clayton             return error;
13280e5e5a79SGreg Clayton         }
13290e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
13300e5e5a79SGreg Clayton         {
13310e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
13320e5e5a79SGreg Clayton                                            separator_char,
13330e5e5a79SGreg Clayton                                            separator_char,
13340e5e5a79SGreg Clayton                                            separator_char,
13350e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
13360e5e5a79SGreg Clayton                                            regex_sed.data());
13370e5e5a79SGreg Clayton             return error;
13380e5e5a79SGreg Clayton         }
133944d93782SGreg Clayton 
13406e3d8e7fSEugene Zelenko         if (!check_only)
134144d93782SGreg Clayton         {
13420e5e5a79SGreg Clayton             std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
13430e5e5a79SGreg Clayton             std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
13440e5e5a79SGreg Clayton             m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
13450e5e5a79SGreg Clayton                                              subst.c_str());
134644d93782SGreg Clayton         }
13470e5e5a79SGreg Clayton         return error;
1348de164aaaSGreg Clayton     }
1349de164aaaSGreg Clayton 
1350de164aaaSGreg Clayton     void
13510e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
1352de164aaaSGreg Clayton     {
13536e3d8e7fSEugene Zelenko         if (m_regex_cmd_ap)
1354de164aaaSGreg Clayton         {
1355de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
1356de164aaaSGreg Clayton             {
1357de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1358de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1359de164aaaSGreg Clayton             }
1360de164aaaSGreg Clayton         }
1361de164aaaSGreg Clayton     }
1362de164aaaSGreg Clayton 
1363de164aaaSGreg Clayton private:
13647b0992d9SGreg Clayton     std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1365de164aaaSGreg Clayton 
1366de164aaaSGreg Clayton      class CommandOptions : public Options
1367de164aaaSGreg Clayton      {
1368de164aaaSGreg Clayton      public:
1369de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
1370de164aaaSGreg Clayton             Options (interpreter)
1371de164aaaSGreg Clayton          {
1372de164aaaSGreg Clayton          }
1373de164aaaSGreg Clayton 
13746e3d8e7fSEugene Zelenko          ~CommandOptions() override = default;
1375de164aaaSGreg Clayton 
137613d21e9aSBruce Mitchener          Error
137713d21e9aSBruce Mitchener          SetOptionValue (uint32_t option_idx, const char *option_arg) override
1378de164aaaSGreg Clayton          {
1379de164aaaSGreg Clayton              Error error;
13803bcdfc0eSGreg Clayton              const int short_option = m_getopt_table[option_idx].val;
1381de164aaaSGreg Clayton 
1382de164aaaSGreg Clayton              switch (short_option)
1383de164aaaSGreg Clayton              {
1384de164aaaSGreg Clayton                  case 'h':
1385de164aaaSGreg Clayton                      m_help.assign (option_arg);
1386de164aaaSGreg Clayton                      break;
1387de164aaaSGreg Clayton                  case 's':
1388de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1389de164aaaSGreg Clayton                      break;
1390de164aaaSGreg Clayton                  default:
139186edbf41SGreg Clayton                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1392de164aaaSGreg Clayton                      break;
1393de164aaaSGreg Clayton              }
1394de164aaaSGreg Clayton 
1395de164aaaSGreg Clayton              return error;
1396de164aaaSGreg Clayton          }
1397de164aaaSGreg Clayton 
1398de164aaaSGreg Clayton          void
139913d21e9aSBruce Mitchener          OptionParsingStarting () override
1400de164aaaSGreg Clayton          {
1401de164aaaSGreg Clayton              m_help.clear();
1402de164aaaSGreg Clayton              m_syntax.clear();
1403de164aaaSGreg Clayton          }
1404de164aaaSGreg Clayton 
1405de164aaaSGreg Clayton          const OptionDefinition*
140613d21e9aSBruce Mitchener          GetDefinitions () override
1407de164aaaSGreg Clayton          {
1408de164aaaSGreg Clayton              return g_option_table;
1409de164aaaSGreg Clayton          }
1410de164aaaSGreg Clayton 
1411de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1412de164aaaSGreg Clayton 
1413de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1414de164aaaSGreg Clayton 
1415de164aaaSGreg Clayton          const char *
1416de164aaaSGreg Clayton          GetHelp()
1417de164aaaSGreg Clayton          {
14186e3d8e7fSEugene Zelenko              return (m_help.empty() ? nullptr : m_help.c_str());
1419de164aaaSGreg Clayton          }
14206e3d8e7fSEugene Zelenko 
1421de164aaaSGreg Clayton          const char *
1422de164aaaSGreg Clayton          GetSyntax ()
1423de164aaaSGreg Clayton          {
14246e3d8e7fSEugene Zelenko              return (m_syntax.empty() ? nullptr : m_syntax.c_str());
1425de164aaaSGreg Clayton          }
14266e3d8e7fSEugene Zelenko 
1427de164aaaSGreg Clayton      protected:
14286e3d8e7fSEugene Zelenko          // Instance variables to hold the values for command options.
14296e3d8e7fSEugene Zelenko 
1430de164aaaSGreg Clayton          std::string m_help;
1431de164aaaSGreg Clayton          std::string m_syntax;
1432de164aaaSGreg Clayton      };
1433de164aaaSGreg Clayton 
1434b0a1814fSEric Christopher      Options *
1435b0a1814fSEric Christopher      GetOptions () override
1436de164aaaSGreg Clayton      {
1437de164aaaSGreg Clayton          return &m_options;
1438de164aaaSGreg Clayton      }
1439de164aaaSGreg Clayton 
14405a988416SJim Ingham      CommandOptions m_options;
1441de164aaaSGreg Clayton };
1442de164aaaSGreg Clayton 
1443de164aaaSGreg Clayton OptionDefinition
1444de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1445de164aaaSGreg Clayton {
14466e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command."},
14476e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
14486e3d8e7fSEugene Zelenko { 0             , false,  nullptr   , 0  , 0                , nullptr, nullptr, 0, eArgTypeNone, nullptr }
1449de164aaaSGreg Clayton };
1450de164aaaSGreg Clayton 
14515a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw
1452223383edSEnrico Granata {
1453223383edSEnrico Granata public:
1454223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1455223383edSEnrico Granata                                  std::string name,
14560a305db7SEnrico Granata                                  std::string funct,
1457735152e3SEnrico Granata                                  std::string help,
14580a305db7SEnrico Granata                                  ScriptedCommandSynchronicity synch) :
14595a988416SJim Ingham         CommandObjectRaw(interpreter,
1460223383edSEnrico Granata                          name.c_str(),
14616e3d8e7fSEugene Zelenko                          nullptr,
14626e3d8e7fSEugene Zelenko                          nullptr),
14630a305db7SEnrico Granata         m_function_name(funct),
1464fac939e9SEnrico Granata         m_synchro(synch),
1465fac939e9SEnrico Granata         m_fetched_help_long(false)
1466223383edSEnrico Granata     {
1467735152e3SEnrico Granata         if (!help.empty())
1468735152e3SEnrico Granata             SetHelp(help.c_str());
1469735152e3SEnrico Granata         else
1470735152e3SEnrico Granata         {
1471735152e3SEnrico Granata             StreamString stream;
1472735152e3SEnrico Granata             stream.Printf("For more information run 'help %s'",name.c_str());
1473735152e3SEnrico Granata             SetHelp(stream.GetData());
1474735152e3SEnrico Granata         }
1475223383edSEnrico Granata     }
1476223383edSEnrico Granata 
14776e3d8e7fSEugene Zelenko     ~CommandObjectPythonFunction() override = default;
1478223383edSEnrico Granata 
147913d21e9aSBruce Mitchener     bool
148013d21e9aSBruce Mitchener     IsRemovable () const override
14815a988416SJim Ingham     {
14825a988416SJim Ingham         return true;
14835a988416SJim Ingham     }
14845a988416SJim Ingham 
14855a988416SJim Ingham     const std::string&
14865a988416SJim Ingham     GetFunctionName ()
14875a988416SJim Ingham     {
14885a988416SJim Ingham         return m_function_name;
14895a988416SJim Ingham     }
14905a988416SJim Ingham 
14915a988416SJim Ingham     ScriptedCommandSynchronicity
14925a988416SJim Ingham     GetSynchronicity ()
14935a988416SJim Ingham     {
14945a988416SJim Ingham         return m_synchro;
14955a988416SJim Ingham     }
14965a988416SJim Ingham 
149713d21e9aSBruce Mitchener     const char *
149813d21e9aSBruce Mitchener     GetHelpLong () override
1499fac939e9SEnrico Granata     {
1500fac939e9SEnrico Granata         if (!m_fetched_help_long)
1501fac939e9SEnrico Granata         {
1502fac939e9SEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1503fac939e9SEnrico Granata             if (scripter)
1504fac939e9SEnrico Granata             {
1505fac939e9SEnrico Granata                 std::string docstring;
1506fac939e9SEnrico Granata                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1507fac939e9SEnrico Granata                 if (!docstring.empty())
1508bfb75e9bSEnrico Granata                     SetHelpLong(docstring.c_str());
1509fac939e9SEnrico Granata             }
1510fac939e9SEnrico Granata         }
1511fac939e9SEnrico Granata         return CommandObjectRaw::GetHelpLong();
1512fac939e9SEnrico Granata     }
1513fac939e9SEnrico Granata 
15145a988416SJim Ingham protected:
151513d21e9aSBruce Mitchener     bool
151613d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
1517223383edSEnrico Granata     {
1518223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1519223383edSEnrico Granata 
1520223383edSEnrico Granata         Error error;
1521223383edSEnrico Granata 
152270f11f88SJim Ingham         result.SetStatus(eReturnStatusInvalid);
152370f11f88SJim Ingham 
15246e3d8e7fSEugene Zelenko         if (!scripter || !scripter->RunScriptBasedCommand(m_function_name.c_str(),
1525223383edSEnrico Granata                                                           raw_command_line,
15260a305db7SEnrico Granata                                                           m_synchro,
1527223383edSEnrico Granata                                                           result,
152806be059aSEnrico Granata                                                           error,
15296e3d8e7fSEugene Zelenko                                                           m_exe_ctx))
1530223383edSEnrico Granata         {
1531223383edSEnrico Granata             result.AppendError(error.AsCString());
1532223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1533223383edSEnrico Granata         }
1534223383edSEnrico Granata         else
153570f11f88SJim Ingham         {
153670f11f88SJim Ingham             // Don't change the status if the command already set it...
153770f11f88SJim Ingham             if (result.GetStatus() == eReturnStatusInvalid)
153870f11f88SJim Ingham             {
15396e3d8e7fSEugene Zelenko                 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
1540223383edSEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
154170f11f88SJim Ingham                 else
154270f11f88SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishResult);
154370f11f88SJim Ingham             }
154470f11f88SJim Ingham         }
1545223383edSEnrico Granata 
1546223383edSEnrico Granata         return result.Succeeded();
1547223383edSEnrico Granata     }
1548223383edSEnrico Granata 
15496e3d8e7fSEugene Zelenko private:
15506e3d8e7fSEugene Zelenko     std::string m_function_name;
15516e3d8e7fSEugene Zelenko     ScriptedCommandSynchronicity m_synchro;
15526e3d8e7fSEugene Zelenko     bool m_fetched_help_long;
1553223383edSEnrico Granata };
1554223383edSEnrico Granata 
15559fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw
15569fe00e52SEnrico Granata {
15579fe00e52SEnrico Granata public:
15589fe00e52SEnrico Granata     CommandObjectScriptingObject (CommandInterpreter &interpreter,
15599fe00e52SEnrico Granata                                   std::string name,
15600641ca1aSZachary Turner                                   StructuredData::GenericSP cmd_obj_sp,
15619fe00e52SEnrico Granata                                   ScriptedCommandSynchronicity synch) :
15629fe00e52SEnrico Granata         CommandObjectRaw(interpreter,
15639fe00e52SEnrico Granata                          name.c_str(),
15646e3d8e7fSEugene Zelenko                          nullptr,
15656e3d8e7fSEugene Zelenko                          nullptr),
15669fe00e52SEnrico Granata         m_cmd_obj_sp(cmd_obj_sp),
15676f79bb2dSEnrico Granata         m_synchro(synch),
15686f79bb2dSEnrico Granata         m_fetched_help_short(false),
15696f79bb2dSEnrico Granata         m_fetched_help_long(false)
15709fe00e52SEnrico Granata     {
15719fe00e52SEnrico Granata         StreamString stream;
15729fe00e52SEnrico Granata         stream.Printf("For more information run 'help %s'",name.c_str());
15739fe00e52SEnrico Granata         SetHelp(stream.GetData());
1574e87764f2SEnrico Granata         if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1575e87764f2SEnrico Granata             GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
15769fe00e52SEnrico Granata     }
15779fe00e52SEnrico Granata 
15786e3d8e7fSEugene Zelenko     ~CommandObjectScriptingObject() override = default;
15799fe00e52SEnrico Granata 
158013d21e9aSBruce Mitchener     bool
158113d21e9aSBruce Mitchener     IsRemovable () const override
15829fe00e52SEnrico Granata     {
15839fe00e52SEnrico Granata         return true;
15849fe00e52SEnrico Granata     }
15859fe00e52SEnrico Granata 
15860641ca1aSZachary Turner     StructuredData::GenericSP
15879fe00e52SEnrico Granata     GetImplementingObject ()
15889fe00e52SEnrico Granata     {
15899fe00e52SEnrico Granata         return m_cmd_obj_sp;
15909fe00e52SEnrico Granata     }
15919fe00e52SEnrico Granata 
15929fe00e52SEnrico Granata     ScriptedCommandSynchronicity
15939fe00e52SEnrico Granata     GetSynchronicity ()
15949fe00e52SEnrico Granata     {
15959fe00e52SEnrico Granata         return m_synchro;
15969fe00e52SEnrico Granata     }
15979fe00e52SEnrico Granata 
159813d21e9aSBruce Mitchener     const char *
159913d21e9aSBruce Mitchener     GetHelp () override
16006f79bb2dSEnrico Granata     {
16016f79bb2dSEnrico Granata         if (!m_fetched_help_short)
16026f79bb2dSEnrico Granata         {
16036f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
16046f79bb2dSEnrico Granata             if (scripter)
16056f79bb2dSEnrico Granata             {
16066f79bb2dSEnrico Granata                 std::string docstring;
16076f79bb2dSEnrico Granata                 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
16086f79bb2dSEnrico Granata                 if (!docstring.empty())
1609bfb75e9bSEnrico Granata                     SetHelp(docstring.c_str());
16106f79bb2dSEnrico Granata             }
16116f79bb2dSEnrico Granata         }
16126f79bb2dSEnrico Granata         return CommandObjectRaw::GetHelp();
16136f79bb2dSEnrico Granata     }
16146f79bb2dSEnrico Granata 
161513d21e9aSBruce Mitchener     const char *
161613d21e9aSBruce Mitchener     GetHelpLong () override
16179fe00e52SEnrico Granata     {
16186f79bb2dSEnrico Granata         if (!m_fetched_help_long)
16196f79bb2dSEnrico Granata         {
16206f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
16216f79bb2dSEnrico Granata             if (scripter)
16226f79bb2dSEnrico Granata             {
16236f79bb2dSEnrico Granata                 std::string docstring;
16246f79bb2dSEnrico Granata                 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
16256f79bb2dSEnrico Granata                 if (!docstring.empty())
1626bfb75e9bSEnrico Granata                     SetHelpLong(docstring.c_str());
16276f79bb2dSEnrico Granata             }
16286f79bb2dSEnrico Granata         }
16299fe00e52SEnrico Granata         return CommandObjectRaw::GetHelpLong();
16309fe00e52SEnrico Granata     }
16319fe00e52SEnrico Granata 
16329fe00e52SEnrico Granata protected:
163313d21e9aSBruce Mitchener     bool
163413d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
16359fe00e52SEnrico Granata     {
16369fe00e52SEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
16379fe00e52SEnrico Granata 
16389fe00e52SEnrico Granata         Error error;
16399fe00e52SEnrico Granata 
16409fe00e52SEnrico Granata         result.SetStatus(eReturnStatusInvalid);
16419fe00e52SEnrico Granata 
16426e3d8e7fSEugene Zelenko         if (!scripter || !scripter->RunScriptBasedCommand(m_cmd_obj_sp,
16439fe00e52SEnrico Granata                                                           raw_command_line,
16449fe00e52SEnrico Granata                                                           m_synchro,
16459fe00e52SEnrico Granata                                                           result,
16469fe00e52SEnrico Granata                                                           error,
16476e3d8e7fSEugene Zelenko                                                           m_exe_ctx))
16489fe00e52SEnrico Granata         {
16499fe00e52SEnrico Granata             result.AppendError(error.AsCString());
16509fe00e52SEnrico Granata             result.SetStatus(eReturnStatusFailed);
16519fe00e52SEnrico Granata         }
16529fe00e52SEnrico Granata         else
16539fe00e52SEnrico Granata         {
16549fe00e52SEnrico Granata             // Don't change the status if the command already set it...
16559fe00e52SEnrico Granata             if (result.GetStatus() == eReturnStatusInvalid)
16569fe00e52SEnrico Granata             {
16576e3d8e7fSEugene Zelenko                 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
16589fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
16599fe00e52SEnrico Granata                 else
16609fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishResult);
16619fe00e52SEnrico Granata             }
16629fe00e52SEnrico Granata         }
16639fe00e52SEnrico Granata 
16649fe00e52SEnrico Granata         return result.Succeeded();
16659fe00e52SEnrico Granata     }
16669fe00e52SEnrico Granata 
16676e3d8e7fSEugene Zelenko private:
16686e3d8e7fSEugene Zelenko     StructuredData::GenericSP m_cmd_obj_sp;
16696e3d8e7fSEugene Zelenko     ScriptedCommandSynchronicity m_synchro;
16706e3d8e7fSEugene Zelenko     bool m_fetched_help_short: 1;
16716e3d8e7fSEugene Zelenko     bool m_fetched_help_long: 1;
16729fe00e52SEnrico Granata };
16739fe00e52SEnrico Granata 
1674a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1675a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport
1676a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1677a9dbf432SEnrico Granata 
16785a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed
1679a9dbf432SEnrico Granata {
16805a988416SJim Ingham public:
16815a988416SJim Ingham     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
16825a988416SJim Ingham         CommandObjectParsed(interpreter,
16835a988416SJim Ingham                             "command script import",
16845a988416SJim Ingham                             "Import a scripting module in LLDB.",
16856e3d8e7fSEugene Zelenko                             nullptr),
16865a988416SJim Ingham         m_options(interpreter)
16875a988416SJim Ingham     {
16885a988416SJim Ingham         CommandArgumentEntry arg1;
16895a988416SJim Ingham         CommandArgumentData cmd_arg;
16905a988416SJim Ingham 
16915a988416SJim Ingham         // Define the first (and only) variant of this arg.
16925a988416SJim Ingham         cmd_arg.arg_type = eArgTypeFilename;
16933b00e35bSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlus;
16945a988416SJim Ingham 
16955a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
16965a988416SJim Ingham         arg1.push_back (cmd_arg);
16975a988416SJim Ingham 
16985a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
16995a988416SJim Ingham         m_arguments.push_back (arg1);
17005a988416SJim Ingham     }
17015a988416SJim Ingham 
17026e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptImport() override = default;
17035a988416SJim Ingham 
170413d21e9aSBruce Mitchener     int
17055a988416SJim Ingham     HandleArgumentCompletion (Args &input,
17065a988416SJim Ingham                               int &cursor_index,
17075a988416SJim Ingham                               int &cursor_char_position,
17085a988416SJim Ingham                               OptionElementVector &opt_element_vector,
17095a988416SJim Ingham                               int match_start_point,
17105a988416SJim Ingham                               int max_return_elements,
17115a988416SJim Ingham                               bool &word_complete,
171213d21e9aSBruce Mitchener                               StringList &matches) override
17135a988416SJim Ingham     {
17145a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
17155a988416SJim Ingham         completion_str.erase (cursor_char_position);
17165a988416SJim Ingham 
17175a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
17185a988416SJim Ingham                                                             CommandCompletions::eDiskFileCompletion,
17195a988416SJim Ingham                                                             completion_str.c_str(),
17205a988416SJim Ingham                                                             match_start_point,
17215a988416SJim Ingham                                                             max_return_elements,
17226e3d8e7fSEugene Zelenko                                                             nullptr,
17235a988416SJim Ingham                                                             word_complete,
17245a988416SJim Ingham                                                             matches);
17255a988416SJim Ingham         return matches.GetSize();
17265a988416SJim Ingham     }
17275a988416SJim Ingham 
172813d21e9aSBruce Mitchener     Options *
172913d21e9aSBruce Mitchener     GetOptions () override
17305a988416SJim Ingham     {
17315a988416SJim Ingham         return &m_options;
17325a988416SJim Ingham     }
17335a988416SJim Ingham 
17345a988416SJim Ingham protected:
17350a305db7SEnrico Granata     class CommandOptions : public Options
17360a305db7SEnrico Granata     {
17370a305db7SEnrico Granata     public:
17380a305db7SEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
17390a305db7SEnrico Granata             Options (interpreter)
17400a305db7SEnrico Granata         {
17410a305db7SEnrico Granata         }
17420a305db7SEnrico Granata 
17436e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
17440a305db7SEnrico Granata 
174513d21e9aSBruce Mitchener         Error
174613d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
17470a305db7SEnrico Granata         {
17480a305db7SEnrico Granata             Error error;
17493bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
17500a305db7SEnrico Granata 
17510a305db7SEnrico Granata             switch (short_option)
17520a305db7SEnrico Granata             {
17530a305db7SEnrico Granata                 case 'r':
17540a305db7SEnrico Granata                     m_allow_reload = true;
17550a305db7SEnrico Granata                     break;
17560a305db7SEnrico Granata                 default:
17570a305db7SEnrico Granata                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
17580a305db7SEnrico Granata                     break;
17590a305db7SEnrico Granata             }
17600a305db7SEnrico Granata 
17610a305db7SEnrico Granata             return error;
17620a305db7SEnrico Granata         }
17630a305db7SEnrico Granata 
17640a305db7SEnrico Granata         void
176513d21e9aSBruce Mitchener         OptionParsingStarting () override
17660a305db7SEnrico Granata         {
1767e0c70f1bSEnrico Granata             m_allow_reload = true;
17680a305db7SEnrico Granata         }
17690a305db7SEnrico Granata 
17700a305db7SEnrico Granata         const OptionDefinition*
177113d21e9aSBruce Mitchener         GetDefinitions () override
17720a305db7SEnrico Granata         {
17730a305db7SEnrico Granata             return g_option_table;
17740a305db7SEnrico Granata         }
17750a305db7SEnrico Granata 
17760a305db7SEnrico Granata         // Options table: Required for subclasses of Options.
17770a305db7SEnrico Granata 
17780a305db7SEnrico Granata         static OptionDefinition g_option_table[];
17790a305db7SEnrico Granata 
17800a305db7SEnrico Granata         // Instance variables to hold the values for command options.
17810a305db7SEnrico Granata 
17820a305db7SEnrico Granata         bool m_allow_reload;
17830a305db7SEnrico Granata     };
17840a305db7SEnrico Granata 
1785a9dbf432SEnrico Granata     bool
178613d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
1787a9dbf432SEnrico Granata     {
1788a9dbf432SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1789a9dbf432SEnrico Granata         {
1790a9dbf432SEnrico Granata             result.AppendError ("only scripting language supported for module importing is currently Python");
1791a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1792a9dbf432SEnrico Granata             return false;
1793a9dbf432SEnrico Granata         }
1794a9dbf432SEnrico Granata 
17955a988416SJim Ingham         size_t argc = command.GetArgumentCount();
17963b00e35bSEnrico Granata         if (0 == argc)
1797a9dbf432SEnrico Granata         {
17983b00e35bSEnrico Granata             result.AppendError("command script import needs one or more arguments");
1799a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1800a9dbf432SEnrico Granata             return false;
1801a9dbf432SEnrico Granata         }
1802a9dbf432SEnrico Granata 
18030e978481SEd Maste         for (size_t i = 0;
18043b00e35bSEnrico Granata              i < argc;
18053b00e35bSEnrico Granata              i++)
18063b00e35bSEnrico Granata         {
18073b00e35bSEnrico Granata             std::string path = command.GetArgumentAtIndex(i);
1808a9dbf432SEnrico Granata             Error error;
1809a9dbf432SEnrico Granata 
1810c9d645d3SGreg Clayton             const bool init_session = true;
1811078551c7SEnrico Granata             // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1812078551c7SEnrico Granata             // commands won't ever be recursively invoked, but it's actually possible to craft
1813078551c7SEnrico Granata             // a Python script that does other "command script imports" in __lldb_init_module
1814078551c7SEnrico Granata             // the real fix is to have recursive commands possible with a CommandInvocation object
1815078551c7SEnrico Granata             // separate from the CommandObject itself, so that recursive command invocations
1816078551c7SEnrico Granata             // won't stomp on each other (wrt to execution contents, options, and more)
1817078551c7SEnrico Granata             m_exe_ctx.Clear();
1818a9dbf432SEnrico Granata             if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
18190a305db7SEnrico Granata                                                                           m_options.m_allow_reload,
1820c9d645d3SGreg Clayton                                                                           init_session,
1821a9dbf432SEnrico Granata                                                                           error))
1822a9dbf432SEnrico Granata             {
1823a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1824a9dbf432SEnrico Granata             }
1825a9dbf432SEnrico Granata             else
1826a9dbf432SEnrico Granata             {
1827a9dbf432SEnrico Granata                 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1828a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1829a9dbf432SEnrico Granata             }
18303b00e35bSEnrico Granata         }
1831a9dbf432SEnrico Granata 
1832a9dbf432SEnrico Granata         return result.Succeeded();
1833a9dbf432SEnrico Granata     }
18340a305db7SEnrico Granata 
18355a988416SJim Ingham     CommandOptions m_options;
1836a9dbf432SEnrico Granata };
1837223383edSEnrico Granata 
18380a305db7SEnrico Granata OptionDefinition
18390a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
18400a305db7SEnrico Granata {
18416e3d8e7fSEugene 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."},
18426e3d8e7fSEugene Zelenko     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
18430a305db7SEnrico Granata };
18440a305db7SEnrico Granata 
1845223383edSEnrico Granata //-------------------------------------------------------------------------
1846223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1847223383edSEnrico Granata //-------------------------------------------------------------------------
1848223383edSEnrico Granata 
184944d93782SGreg Clayton class CommandObjectCommandsScriptAdd :
185044d93782SGreg Clayton     public CommandObjectParsed,
185144d93782SGreg Clayton     public IOHandlerDelegateMultiline
1852223383edSEnrico Granata {
18535a988416SJim Ingham public:
18545a988416SJim Ingham     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
18555a988416SJim Ingham         CommandObjectParsed(interpreter,
18565a988416SJim Ingham                             "command script add",
18575a988416SJim Ingham                             "Add a scripted function as an LLDB command.",
18586e3d8e7fSEugene Zelenko                             nullptr),
1859c3d874a5SGreg Clayton         IOHandlerDelegateMultiline ("DONE"),
18605a988416SJim Ingham         m_options (interpreter)
18615a988416SJim Ingham     {
18625a988416SJim Ingham         CommandArgumentEntry arg1;
18635a988416SJim Ingham         CommandArgumentData cmd_arg;
18645a988416SJim Ingham 
18655a988416SJim Ingham         // Define the first (and only) variant of this arg.
18665a988416SJim Ingham         cmd_arg.arg_type = eArgTypeCommandName;
18675a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
18685a988416SJim Ingham 
18695a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
18705a988416SJim Ingham         arg1.push_back (cmd_arg);
18715a988416SJim Ingham 
18725a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
18735a988416SJim Ingham         m_arguments.push_back (arg1);
18745a988416SJim Ingham     }
18755a988416SJim Ingham 
18766e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptAdd() override = default;
18775a988416SJim Ingham 
187813d21e9aSBruce Mitchener     Options *
187913d21e9aSBruce Mitchener     GetOptions () override
18805a988416SJim Ingham     {
18815a988416SJim Ingham         return &m_options;
18825a988416SJim Ingham     }
18835a988416SJim Ingham 
18845a988416SJim Ingham protected:
1885223383edSEnrico Granata     class CommandOptions : public Options
1886223383edSEnrico Granata     {
1887223383edSEnrico Granata     public:
1888223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
18899fe00e52SEnrico Granata             Options (interpreter),
18909fe00e52SEnrico Granata             m_class_name(),
18919fe00e52SEnrico Granata             m_funct_name(),
18929fe00e52SEnrico Granata             m_short_help(),
18939fe00e52SEnrico Granata             m_synchronicity(eScriptedCommandSynchronicitySynchronous)
1894223383edSEnrico Granata         {
1895223383edSEnrico Granata         }
1896223383edSEnrico Granata 
18976e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
1898223383edSEnrico Granata 
189913d21e9aSBruce Mitchener         Error
190013d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1901223383edSEnrico Granata         {
1902223383edSEnrico Granata             Error error;
19033bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
1904223383edSEnrico Granata 
1905223383edSEnrico Granata             switch (short_option)
1906223383edSEnrico Granata             {
1907223383edSEnrico Granata                 case 'f':
1908735152e3SEnrico Granata                     if (option_arg)
1909735152e3SEnrico Granata                         m_funct_name.assign(option_arg);
1910735152e3SEnrico Granata                     break;
19119fe00e52SEnrico Granata                 case 'c':
19129fe00e52SEnrico Granata                     if (option_arg)
19139fe00e52SEnrico Granata                         m_class_name.assign(option_arg);
19149fe00e52SEnrico Granata                     break;
1915735152e3SEnrico Granata                 case 'h':
1916735152e3SEnrico Granata                     if (option_arg)
1917735152e3SEnrico Granata                         m_short_help.assign(option_arg);
1918223383edSEnrico Granata                     break;
19190a305db7SEnrico Granata                 case 's':
192044d93782SGreg Clayton                     m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
19210a305db7SEnrico Granata                     if (!error.Success())
19220a305db7SEnrico Granata                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
19230a305db7SEnrico Granata                     break;
1924223383edSEnrico Granata                 default:
192586edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1926223383edSEnrico Granata                     break;
1927223383edSEnrico Granata             }
1928223383edSEnrico Granata 
1929223383edSEnrico Granata             return error;
1930223383edSEnrico Granata         }
1931223383edSEnrico Granata 
1932223383edSEnrico Granata         void
193313d21e9aSBruce Mitchener         OptionParsingStarting () override
1934223383edSEnrico Granata         {
19359fe00e52SEnrico Granata             m_class_name.clear();
1936735152e3SEnrico Granata             m_funct_name.clear();
1937735152e3SEnrico Granata             m_short_help.clear();
193844d93782SGreg Clayton             m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1939223383edSEnrico Granata         }
1940223383edSEnrico Granata 
1941223383edSEnrico Granata         const OptionDefinition*
194213d21e9aSBruce Mitchener         GetDefinitions () override
1943223383edSEnrico Granata         {
1944223383edSEnrico Granata             return g_option_table;
1945223383edSEnrico Granata         }
1946223383edSEnrico Granata 
1947223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1948223383edSEnrico Granata 
1949223383edSEnrico Granata         static OptionDefinition g_option_table[];
1950223383edSEnrico Granata 
1951223383edSEnrico Granata         // Instance variables to hold the values for command options.
1952223383edSEnrico Granata 
19539fe00e52SEnrico Granata         std::string m_class_name;
1954223383edSEnrico Granata         std::string m_funct_name;
1955735152e3SEnrico Granata         std::string m_short_help;
195644d93782SGreg Clayton         ScriptedCommandSynchronicity m_synchronicity;
1957223383edSEnrico Granata     };
1958223383edSEnrico Granata 
195913d21e9aSBruce Mitchener     void
196013d21e9aSBruce Mitchener     IOHandlerActivated (IOHandler &io_handler) override
1961223383edSEnrico Granata     {
196244d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
196344d93782SGreg Clayton         if (output_sp)
1964223383edSEnrico Granata         {
196544d93782SGreg Clayton             output_sp->PutCString(g_python_command_instructions);
196644d93782SGreg Clayton             output_sp->Flush();
1967223383edSEnrico Granata         }
1968223383edSEnrico Granata     }
1969223383edSEnrico Granata 
1970223383edSEnrico Granata 
197113d21e9aSBruce Mitchener     void
197213d21e9aSBruce Mitchener     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
1973223383edSEnrico Granata     {
197444d93782SGreg Clayton         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
197544d93782SGreg Clayton 
197644d93782SGreg Clayton         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
197744d93782SGreg Clayton         if (interpreter)
197844d93782SGreg Clayton         {
197944d93782SGreg Clayton 
198044d93782SGreg Clayton             StringList lines;
198144d93782SGreg Clayton             lines.SplitIntoLines(data);
198244d93782SGreg Clayton             if (lines.GetSize() > 0)
198344d93782SGreg Clayton             {
1984a73b7df7SEnrico Granata                 std::string funct_name_str;
198544d93782SGreg Clayton                 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1986223383edSEnrico Granata                 {
1987a73b7df7SEnrico Granata                     if (funct_name_str.empty())
1988223383edSEnrico Granata                     {
198944d93782SGreg Clayton                         error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
199044d93782SGreg Clayton                         error_sp->Flush();
1991223383edSEnrico Granata                     }
199244d93782SGreg Clayton                     else
199344d93782SGreg Clayton                     {
1994223383edSEnrico Granata                         // everything should be fine now, let's add this alias
1995223383edSEnrico Granata 
1996223383edSEnrico Granata                         CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1997223383edSEnrico Granata                                                                                         m_cmd_name,
1998a73b7df7SEnrico Granata                                                                                         funct_name_str.c_str(),
1999735152e3SEnrico Granata                                                                                         m_short_help,
200044d93782SGreg Clayton                                                                                         m_synchronicity));
2001223383edSEnrico Granata 
20020a305db7SEnrico Granata                         if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
2003223383edSEnrico Granata                         {
200444d93782SGreg Clayton                             error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
200544d93782SGreg Clayton                             error_sp->Flush();
2006223383edSEnrico Granata                         }
2007223383edSEnrico Granata                     }
200844d93782SGreg Clayton                 }
200944d93782SGreg Clayton                 else
201044d93782SGreg Clayton                 {
201144d93782SGreg Clayton                     error_sp->Printf ("error: unable to create function, didn't add python command.\n");
201244d93782SGreg Clayton                     error_sp->Flush();
201344d93782SGreg Clayton                 }
201444d93782SGreg Clayton             }
201544d93782SGreg Clayton             else
201644d93782SGreg Clayton             {
201744d93782SGreg Clayton                 error_sp->Printf ("error: empty function, didn't add python command.\n");
201844d93782SGreg Clayton                 error_sp->Flush();
201944d93782SGreg Clayton             }
202044d93782SGreg Clayton         }
202144d93782SGreg Clayton         else
202244d93782SGreg Clayton         {
202344d93782SGreg Clayton             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
202444d93782SGreg Clayton             error_sp->Flush();
202544d93782SGreg Clayton         }
202644d93782SGreg Clayton 
202744d93782SGreg Clayton         io_handler.SetIsDone(true);
202844d93782SGreg Clayton     }
2029223383edSEnrico Granata 
20305a988416SJim Ingham protected:
2031223383edSEnrico Granata     bool
203213d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2033223383edSEnrico Granata     {
203499f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
203599f0b8f9SEnrico Granata         {
203699f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
203799f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
203899f0b8f9SEnrico Granata             return false;
203999f0b8f9SEnrico Granata         }
204099f0b8f9SEnrico Granata 
20415a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2042223383edSEnrico Granata 
2043223383edSEnrico Granata         if (argc != 1)
2044223383edSEnrico Granata         {
2045223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
2046223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2047223383edSEnrico Granata             return false;
2048223383edSEnrico Granata         }
2049223383edSEnrico Granata 
2050735152e3SEnrico Granata         // Store the options in case we get multi-line input
205144d93782SGreg Clayton         m_cmd_name = command.GetArgumentAtIndex(0);
2052735152e3SEnrico Granata         m_short_help.assign(m_options.m_short_help);
205344d93782SGreg Clayton         m_synchronicity = m_options.m_synchronicity;
2054223383edSEnrico Granata 
20559fe00e52SEnrico Granata         if (m_options.m_class_name.empty())
20569fe00e52SEnrico Granata         {
2057223383edSEnrico Granata             if (m_options.m_funct_name.empty())
2058223383edSEnrico Granata             {
205944d93782SGreg Clayton                 m_interpreter.GetPythonCommandsFromIOHandler("     ",  // Prompt
206044d93782SGreg Clayton                                                              *this,    // IOHandlerDelegate
206144d93782SGreg Clayton                                                              true,     // Run IOHandler in async mode
20626e3d8e7fSEugene Zelenko                                                              nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
2063223383edSEnrico Granata             }
2064223383edSEnrico Granata             else
2065223383edSEnrico Granata             {
20660a305db7SEnrico Granata                 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
206744d93782SGreg Clayton                                                                         m_cmd_name,
20680a305db7SEnrico Granata                                                                         m_options.m_funct_name,
2069735152e3SEnrico Granata                                                                         m_options.m_short_help,
207044d93782SGreg Clayton                                                                         m_synchronicity));
207144d93782SGreg Clayton                 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
2072223383edSEnrico Granata                 {
2073223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
2074223383edSEnrico Granata                 }
2075223383edSEnrico Granata                 else
2076223383edSEnrico Granata                 {
2077223383edSEnrico Granata                     result.AppendError("cannot add command");
2078223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
2079223383edSEnrico Granata                 }
2080223383edSEnrico Granata             }
20819fe00e52SEnrico Granata         }
20829fe00e52SEnrico Granata         else
20839fe00e52SEnrico Granata         {
20849fe00e52SEnrico Granata             ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
20859fe00e52SEnrico Granata             if (!interpreter)
20869fe00e52SEnrico Granata             {
20879fe00e52SEnrico Granata                 result.AppendError("cannot find ScriptInterpreter");
20889fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
20899fe00e52SEnrico Granata                 return false;
20909fe00e52SEnrico Granata             }
20919fe00e52SEnrico Granata 
20929fe00e52SEnrico Granata             auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
20939fe00e52SEnrico Granata             if (!cmd_obj_sp)
20949fe00e52SEnrico Granata             {
20959fe00e52SEnrico Granata                 result.AppendError("cannot create helper object");
20969fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
20979fe00e52SEnrico Granata                 return false;
20989fe00e52SEnrico Granata             }
20999fe00e52SEnrico Granata 
21009fe00e52SEnrico Granata             CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
21019fe00e52SEnrico Granata                                                                      m_cmd_name,
21029fe00e52SEnrico Granata                                                                      cmd_obj_sp,
21039fe00e52SEnrico Granata                                                                      m_synchronicity));
21049fe00e52SEnrico Granata             if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
21059fe00e52SEnrico Granata             {
21069fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
21079fe00e52SEnrico Granata             }
21089fe00e52SEnrico Granata             else
21099fe00e52SEnrico Granata             {
21109fe00e52SEnrico Granata                 result.AppendError("cannot add command");
21119fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
21129fe00e52SEnrico Granata             }
21139fe00e52SEnrico Granata         }
2114223383edSEnrico Granata 
2115223383edSEnrico Granata         return result.Succeeded();
2116223383edSEnrico Granata     }
21175a988416SJim Ingham 
21185a988416SJim Ingham     CommandOptions m_options;
211944d93782SGreg Clayton     std::string m_cmd_name;
2120735152e3SEnrico Granata     std::string m_short_help;
212144d93782SGreg Clayton     ScriptedCommandSynchronicity m_synchronicity;
2122223383edSEnrico Granata };
2123223383edSEnrico Granata 
21240a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] =
21250a305db7SEnrico Granata {
21260a305db7SEnrico Granata     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
21270a305db7SEnrico Granata     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
21280a305db7SEnrico Granata     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
21296e3d8e7fSEugene Zelenko     { 0, nullptr, nullptr }
21300a305db7SEnrico Granata };
21310a305db7SEnrico Granata 
2132223383edSEnrico Granata OptionDefinition
2133223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2134223383edSEnrico Granata {
21356e3d8e7fSEugene 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."},
21366e3d8e7fSEugene 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."},
21376e3d8e7fSEugene Zelenko     { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command."},
21386e3d8e7fSEugene 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."},
21396e3d8e7fSEugene Zelenko     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
2140223383edSEnrico Granata };
2141223383edSEnrico Granata 
2142223383edSEnrico Granata //-------------------------------------------------------------------------
2143223383edSEnrico Granata // CommandObjectCommandsScriptList
2144223383edSEnrico Granata //-------------------------------------------------------------------------
2145223383edSEnrico Granata 
21465a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed
2147223383edSEnrico Granata {
2148223383edSEnrico Granata public:
2149223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
21505a988416SJim Ingham         CommandObjectParsed(interpreter,
2151223383edSEnrico Granata                             "command script list",
2152223383edSEnrico Granata                             "List defined scripted commands.",
21536e3d8e7fSEugene Zelenko                             nullptr)
2154223383edSEnrico Granata     {
2155223383edSEnrico Granata     }
2156223383edSEnrico Granata 
21576e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptList() override = default;
2158223383edSEnrico Granata 
2159223383edSEnrico Granata     bool
216013d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2161223383edSEnrico Granata     {
2162223383edSEnrico Granata         m_interpreter.GetHelp(result,
2163223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
2164223383edSEnrico Granata 
2165223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2166223383edSEnrico Granata 
2167223383edSEnrico Granata         return true;
2168223383edSEnrico Granata     }
2169223383edSEnrico Granata };
2170223383edSEnrico Granata 
2171223383edSEnrico Granata //-------------------------------------------------------------------------
2172223383edSEnrico Granata // CommandObjectCommandsScriptClear
2173223383edSEnrico Granata //-------------------------------------------------------------------------
2174223383edSEnrico Granata 
21755a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed
2176223383edSEnrico Granata {
2177223383edSEnrico Granata public:
2178223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
21795a988416SJim Ingham         CommandObjectParsed(interpreter,
2180223383edSEnrico Granata                             "command script clear",
2181223383edSEnrico Granata                             "Delete all scripted commands.",
21826e3d8e7fSEugene Zelenko                             nullptr)
2183223383edSEnrico Granata     {
2184223383edSEnrico Granata     }
2185223383edSEnrico Granata 
21866e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptClear() override = default;
2187223383edSEnrico Granata 
21885a988416SJim Ingham protected:
2189223383edSEnrico Granata     bool
219013d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2191223383edSEnrico Granata     {
2192223383edSEnrico Granata         m_interpreter.RemoveAllUser();
2193223383edSEnrico Granata 
2194223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2195223383edSEnrico Granata 
2196223383edSEnrico Granata         return true;
2197223383edSEnrico Granata     }
2198223383edSEnrico Granata };
2199223383edSEnrico Granata 
2200223383edSEnrico Granata //-------------------------------------------------------------------------
2201223383edSEnrico Granata // CommandObjectCommandsScriptDelete
2202223383edSEnrico Granata //-------------------------------------------------------------------------
2203223383edSEnrico Granata 
22045a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed
2205223383edSEnrico Granata {
2206223383edSEnrico Granata public:
2207223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
22085a988416SJim Ingham         CommandObjectParsed(interpreter,
2209223383edSEnrico Granata                             "command script delete",
2210223383edSEnrico Granata                             "Delete a scripted command.",
22116e3d8e7fSEugene Zelenko                             nullptr)
2212223383edSEnrico Granata     {
2213223383edSEnrico Granata         CommandArgumentEntry arg1;
2214223383edSEnrico Granata         CommandArgumentData cmd_arg;
2215223383edSEnrico Granata 
2216223383edSEnrico Granata         // Define the first (and only) variant of this arg.
2217223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
2218223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
2219223383edSEnrico Granata 
2220223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
2221223383edSEnrico Granata         arg1.push_back (cmd_arg);
2222223383edSEnrico Granata 
2223223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
2224223383edSEnrico Granata         m_arguments.push_back (arg1);
2225223383edSEnrico Granata     }
2226223383edSEnrico Granata 
22276e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptDelete() override = default;
2228223383edSEnrico Granata 
22295a988416SJim Ingham protected:
2230223383edSEnrico Granata     bool
223113d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2232223383edSEnrico Granata     {
2233223383edSEnrico Granata 
22345a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2235223383edSEnrico Granata 
2236223383edSEnrico Granata         if (argc != 1)
2237223383edSEnrico Granata         {
2238223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
2239223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2240223383edSEnrico Granata             return false;
2241223383edSEnrico Granata         }
2242223383edSEnrico Granata 
22435a988416SJim Ingham         const char* cmd_name = command.GetArgumentAtIndex(0);
2244223383edSEnrico Granata 
2245223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2246223383edSEnrico Granata         {
2247223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
2248223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
2249223383edSEnrico Granata         }
2250223383edSEnrico Granata         else
2251223383edSEnrico Granata         {
2252223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
2253223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2254223383edSEnrico Granata         }
2255223383edSEnrico Granata 
2256223383edSEnrico Granata         return result.Succeeded();
2257223383edSEnrico Granata     }
2258223383edSEnrico Granata };
2259223383edSEnrico Granata 
2260223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
2261223383edSEnrico Granata 
2262223383edSEnrico Granata //-------------------------------------------------------------------------
2263223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
2264223383edSEnrico Granata //-------------------------------------------------------------------------
2265223383edSEnrico Granata 
2266223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2267223383edSEnrico Granata {
2268223383edSEnrico Granata public:
2269223383edSEnrico Granata     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2270223383edSEnrico Granata     CommandObjectMultiword (interpreter,
2271223383edSEnrico Granata                             "command script",
2272223383edSEnrico Granata                             "A set of commands for managing or customizing script commands.",
2273223383edSEnrico Granata                             "command script <subcommand> [<subcommand-options>]")
2274223383edSEnrico Granata     {
2275223383edSEnrico Granata         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2276223383edSEnrico Granata         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2277223383edSEnrico Granata         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
2278223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
2279a9dbf432SEnrico Granata         LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
2280223383edSEnrico Granata     }
2281223383edSEnrico Granata 
22826e3d8e7fSEugene Zelenko     ~CommandObjectMultiwordCommandsScript() override = default;
2283223383edSEnrico Granata };
2284223383edSEnrico Granata 
2285ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
2286ebc09c36SJim Ingham 
2287ebc09c36SJim Ingham //-------------------------------------------------------------------------
2288ebc09c36SJim Ingham // CommandObjectMultiwordCommands
2289ebc09c36SJim Ingham //-------------------------------------------------------------------------
2290ebc09c36SJim Ingham 
2291ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
2292a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
22930e5e5a79SGreg Clayton                             "command",
22943f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
22950e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
2296ebc09c36SJim Ingham {
2297a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2298a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2299a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
2300b547278cSGreg Clayton     LoadSubCommand ("delete",  CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
2301de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
2302a5a97ebeSJim Ingham     LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2303223383edSEnrico Granata     LoadSubCommand ("script",  CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
2304ebc09c36SJim Ingham }
2305ebc09c36SJim Ingham 
23066e3d8e7fSEugene Zelenko CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands() = default;
2307