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),
47*e1cfbc79STodd Fiala         m_options()
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:
63*e1cfbc79STodd Fiala         CommandOptions() :
64*e1cfbc79STodd Fiala             Options(),
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
75*e1cfbc79STodd Fiala         SetOptionValue (uint32_t option_idx, const char *option_arg,
76*e1cfbc79STodd Fiala                         ExecutionContext *execution_context) override
77a5a97ebeSJim Ingham         {
78a5a97ebeSJim Ingham             Error error;
793bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
80a5a97ebeSJim Ingham 
81a5a97ebeSJim Ingham             switch (short_option)
82a5a97ebeSJim Ingham             {
83a5a97ebeSJim Ingham                 case 'c':
84c95f7e2aSPavel Labath                     error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
85a5a97ebeSJim Ingham                     break;
86a5a97ebeSJim Ingham                 case 's':
877594f14fSEnrico Granata                     if (option_arg && strcmp("end", option_arg) == 0)
887594f14fSEnrico Granata                     {
897594f14fSEnrico Granata                         m_start_idx.SetCurrentValue(UINT64_MAX);
907594f14fSEnrico Granata                         m_start_idx.SetOptionWasSet();
917594f14fSEnrico Granata                     }
927594f14fSEnrico Granata                     else
93c95f7e2aSPavel Labath                         error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
947594f14fSEnrico Granata                     break;
957594f14fSEnrico Granata                 case 'e':
96c95f7e2aSPavel Labath                     error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
977594f14fSEnrico Granata                     break;
9863123b64SEnrico Granata                 case 'C':
9963123b64SEnrico Granata                     m_clear.SetCurrentValue(true);
10063123b64SEnrico Granata                     m_clear.SetOptionWasSet();
101a5a97ebeSJim Ingham                     break;
102a5a97ebeSJim Ingham                 default:
10386edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
104a5a97ebeSJim Ingham                     break;
105a5a97ebeSJim Ingham             }
106a5a97ebeSJim Ingham 
107a5a97ebeSJim Ingham             return error;
108a5a97ebeSJim Ingham         }
109a5a97ebeSJim Ingham 
110a5a97ebeSJim Ingham         void
111*e1cfbc79STodd Fiala         OptionParsingStarting (ExecutionContext *execution_context) override
112a5a97ebeSJim Ingham         {
1137594f14fSEnrico Granata             m_start_idx.Clear();
1147594f14fSEnrico Granata             m_stop_idx.Clear();
1157594f14fSEnrico Granata             m_count.Clear();
11663123b64SEnrico Granata             m_clear.Clear();
117a5a97ebeSJim Ingham         }
118a5a97ebeSJim Ingham 
119a5a97ebeSJim Ingham         const OptionDefinition*
12013d21e9aSBruce Mitchener         GetDefinitions () override
121a5a97ebeSJim Ingham         {
122a5a97ebeSJim Ingham             return g_option_table;
123a5a97ebeSJim Ingham         }
124a5a97ebeSJim Ingham 
125a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
126a5a97ebeSJim Ingham 
127a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
128a5a97ebeSJim Ingham 
129a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
130a5a97ebeSJim Ingham 
1317594f14fSEnrico Granata         OptionValueUInt64 m_start_idx;
1327594f14fSEnrico Granata         OptionValueUInt64 m_stop_idx;
1337594f14fSEnrico Granata         OptionValueUInt64 m_count;
13463123b64SEnrico Granata         OptionValueBoolean m_clear;
135a5a97ebeSJim Ingham     };
136a5a97ebeSJim Ingham 
137a5a97ebeSJim Ingham     bool
13813d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
139a5a97ebeSJim Ingham     {
14063123b64SEnrico Granata         if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
1417594f14fSEnrico Granata         {
1427594f14fSEnrico Granata             m_interpreter.GetCommandHistory().Clear();
1437594f14fSEnrico Granata             result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
1447594f14fSEnrico Granata         }
1457594f14fSEnrico Granata         else
1467594f14fSEnrico Granata         {
1477594f14fSEnrico Granata             if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
1487594f14fSEnrico Granata             {
1497594f14fSEnrico Granata                 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
1507594f14fSEnrico Granata                 result.SetStatus(lldb::eReturnStatusFailed);
1517594f14fSEnrico Granata             }
1527594f14fSEnrico Granata             else
1537594f14fSEnrico Granata             {
15484400ec7SVirgile Bello                 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
15584400ec7SVirgile Bello                 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
15684400ec7SVirgile Bello                 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
157a5a97ebeSJim Ingham 
1587594f14fSEnrico Granata                 const CommandHistory& history(m_interpreter.GetCommandHistory());
1597594f14fSEnrico Granata 
1607594f14fSEnrico Granata                 if (start_idx.first && start_idx.second == UINT64_MAX)
1617594f14fSEnrico Granata                 {
1627594f14fSEnrico Granata                     if (count.first)
1637594f14fSEnrico Granata                     {
1647594f14fSEnrico Granata                         start_idx.second = history.GetSize() - count.second;
1657594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1667594f14fSEnrico Granata                     }
1677594f14fSEnrico Granata                     else if (stop_idx.first)
1687594f14fSEnrico Granata                     {
1697594f14fSEnrico Granata                         start_idx.second = stop_idx.second;
1707594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1717594f14fSEnrico Granata                     }
1727594f14fSEnrico Granata                     else
1737594f14fSEnrico Granata                     {
1747594f14fSEnrico Granata                         start_idx.second = 0;
1757594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1767594f14fSEnrico Granata                     }
1777594f14fSEnrico Granata                 }
1787594f14fSEnrico Granata                 else
1797594f14fSEnrico Granata                 {
1807594f14fSEnrico Granata                     if (!start_idx.first && !stop_idx.first && !count.first)
1817594f14fSEnrico Granata                     {
1827594f14fSEnrico Granata                         start_idx.second = 0;
1837594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1847594f14fSEnrico Granata                     }
1857594f14fSEnrico Granata                     else if (start_idx.first)
1867594f14fSEnrico Granata                     {
1877594f14fSEnrico Granata                         if (count.first)
1887594f14fSEnrico Granata                         {
1897594f14fSEnrico Granata                             stop_idx.second = start_idx.second + count.second - 1;
1907594f14fSEnrico Granata                         }
1917594f14fSEnrico Granata                         else if (!stop_idx.first)
1927594f14fSEnrico Granata                         {
1937594f14fSEnrico Granata                             stop_idx.second = history.GetSize() - 1;
1947594f14fSEnrico Granata                         }
1957594f14fSEnrico Granata                     }
1967594f14fSEnrico Granata                     else if (stop_idx.first)
1977594f14fSEnrico Granata                     {
1987594f14fSEnrico Granata                         if (count.first)
1997594f14fSEnrico Granata                         {
2007594f14fSEnrico Granata                             if (stop_idx.second >= count.second)
2017594f14fSEnrico Granata                                 start_idx.second = stop_idx.second - count.second + 1;
2027594f14fSEnrico Granata                             else
2037594f14fSEnrico Granata                                 start_idx.second = 0;
2047594f14fSEnrico Granata                         }
2057594f14fSEnrico Granata                     }
2067594f14fSEnrico Granata                     else /* if (count.first) */
2077594f14fSEnrico Granata                     {
2087594f14fSEnrico Granata                         start_idx.second = 0;
2097594f14fSEnrico Granata                         stop_idx.second = count.second - 1;
2107594f14fSEnrico Granata                     }
2117594f14fSEnrico Granata                 }
2127594f14fSEnrico Granata                 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
2137594f14fSEnrico Granata             }
2147594f14fSEnrico Granata         }
215a5a97ebeSJim Ingham         return result.Succeeded();
216a5a97ebeSJim Ingham 
217a5a97ebeSJim Ingham     }
2185a988416SJim Ingham 
2195a988416SJim Ingham     CommandOptions m_options;
220a5a97ebeSJim Ingham };
221a5a97ebeSJim Ingham 
222a5a97ebeSJim Ingham OptionDefinition
223a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
224a5a97ebeSJim Ingham {
2256e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
2266e3d8e7fSEugene 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)."},
2276e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
2286e3d8e7fSEugene Zelenko { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeBoolean,    "Clears the current command history."},
2296e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
230a5a97ebeSJim Ingham };
231a5a97ebeSJim Ingham 
232a5a97ebeSJim Ingham //-------------------------------------------------------------------------
233a5a97ebeSJim Ingham // CommandObjectCommandsSource
234a5a97ebeSJim Ingham //-------------------------------------------------------------------------
235a5a97ebeSJim Ingham 
2365a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed
237ebc09c36SJim Ingham {
2385a988416SJim Ingham public:
2397428a18cSKate Stone     CommandObjectCommandsSource(CommandInterpreter &interpreter)
2407428a18cSKate Stone         : CommandObjectParsed(interpreter, "command source", "Read and execute LLDB commands from the file <filename>.",
2416e3d8e7fSEugene Zelenko                               nullptr),
242*e1cfbc79STodd Fiala           m_options()
2435a988416SJim Ingham     {
2445a988416SJim Ingham         CommandArgumentEntry arg;
2455a988416SJim Ingham         CommandArgumentData file_arg;
2465a988416SJim Ingham 
2475a988416SJim Ingham         // Define the first (and only) variant of this arg.
2485a988416SJim Ingham         file_arg.arg_type = eArgTypeFilename;
2495a988416SJim Ingham         file_arg.arg_repetition = eArgRepeatPlain;
2505a988416SJim Ingham 
2515a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
2525a988416SJim Ingham         arg.push_back (file_arg);
2535a988416SJim Ingham 
2545a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
2555a988416SJim Ingham         m_arguments.push_back (arg);
2565a988416SJim Ingham     }
2575a988416SJim Ingham 
2586e3d8e7fSEugene Zelenko     ~CommandObjectCommandsSource() override = default;
2595a988416SJim Ingham 
26013d21e9aSBruce Mitchener     const char*
26113d21e9aSBruce Mitchener     GetRepeatCommand (Args &current_command_args, uint32_t index) override
2625a988416SJim Ingham     {
2635a988416SJim Ingham         return "";
2645a988416SJim Ingham     }
2655a988416SJim Ingham 
26613d21e9aSBruce Mitchener     int
2675a988416SJim Ingham     HandleArgumentCompletion (Args &input,
2685a988416SJim Ingham                               int &cursor_index,
2695a988416SJim Ingham                               int &cursor_char_position,
2705a988416SJim Ingham                               OptionElementVector &opt_element_vector,
2715a988416SJim Ingham                               int match_start_point,
2725a988416SJim Ingham                               int max_return_elements,
2735a988416SJim Ingham                               bool &word_complete,
27413d21e9aSBruce Mitchener                               StringList &matches) override
2755a988416SJim Ingham     {
2765a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2775a988416SJim Ingham         completion_str.erase (cursor_char_position);
2785a988416SJim Ingham 
279*e1cfbc79STodd Fiala         CommandCompletions::InvokeCommonCompletionCallbacks(GetCommandInterpreter(),
2805a988416SJim Ingham                                                             CommandCompletions::eDiskFileCompletion,
2815a988416SJim Ingham                                                             completion_str.c_str(),
2825a988416SJim Ingham                                                             match_start_point,
2835a988416SJim Ingham                                                             max_return_elements,
2846e3d8e7fSEugene Zelenko                                                             nullptr,
2855a988416SJim Ingham                                                             word_complete,
2865a988416SJim Ingham                                                             matches);
2875a988416SJim Ingham         return matches.GetSize();
2885a988416SJim Ingham     }
2895a988416SJim Ingham 
29013d21e9aSBruce Mitchener     Options *
29113d21e9aSBruce Mitchener     GetOptions () override
2925a988416SJim Ingham     {
2935a988416SJim Ingham         return &m_options;
2945a988416SJim Ingham     }
2955a988416SJim Ingham 
2965a988416SJim Ingham protected:
297e16c50a1SJim Ingham     class CommandOptions : public Options
298e16c50a1SJim Ingham     {
299e16c50a1SJim Ingham     public:
300*e1cfbc79STodd Fiala         CommandOptions() :
301*e1cfbc79STodd Fiala             Options(),
302340b0309SGreg Clayton             m_stop_on_error (true),
303340b0309SGreg Clayton             m_silent_run (false),
304340b0309SGreg Clayton             m_stop_on_continue (true)
305eb0103f2SGreg Clayton         {
306eb0103f2SGreg Clayton         }
307e16c50a1SJim Ingham 
3086e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
309e16c50a1SJim Ingham 
31013d21e9aSBruce Mitchener         Error
311*e1cfbc79STodd Fiala         SetOptionValue (uint32_t option_idx, const char *option_arg,
312*e1cfbc79STodd Fiala                         ExecutionContext *execution_context) 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
340*e1cfbc79STodd Fiala         OptionParsingStarting (ExecutionContext *execution_context) 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
459*e1cfbc79STodd Fiala         SetOptionValue (uint32_t option_idx,
460*e1cfbc79STodd Fiala                         const char *option_value,
461*e1cfbc79STodd Fiala                         ExecutionContext *execution_context) 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
488*e1cfbc79STodd Fiala         OptionParsingStarting (ExecutionContext *execution_context) 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 
5117428a18cSKate Stone     CommandObjectCommandsAlias(CommandInterpreter &interpreter)
5127428a18cSKate Stone         : CommandObjectRaw(interpreter, "command alias", "Define a custom command in terms of an existing command.",
51345d0e238SEnrico Granata                            nullptr),
514*e1cfbc79STodd Fiala           m_option_group(),
51545d0e238SEnrico Granata           m_command_options()
516ebc09c36SJim Ingham     {
51745d0e238SEnrico Granata         m_option_group.Append(&m_command_options);
51845d0e238SEnrico Granata         m_option_group.Finalize();
51945d0e238SEnrico Granata 
520ebc09c36SJim Ingham         SetHelpLong(
521ea671fbdSKate Stone "'alias' allows the user to create a short-cut or abbreviation for long \
522ea671fbdSKate Stone commands, multi-word commands, and commands that take particular options.  \
523ea671fbdSKate Stone Below are some simple examples of how one might use the 'alias' command:" R"(
524ea671fbdSKate Stone 
525ea671fbdSKate Stone (lldb) command alias sc script
526ea671fbdSKate Stone 
527ea671fbdSKate Stone     Creates the abbreviation 'sc' for the 'script' command.
528ea671fbdSKate Stone 
529ea671fbdSKate Stone (lldb) command alias bp breakpoint
530ea671fbdSKate Stone 
531ea671fbdSKate Stone )" "    Creates the abbreviation 'bp' for the 'breakpoint' command.  Since \
532ea671fbdSKate Stone breakpoint commands are two-word commands, the user would still need to \
533ea671fbdSKate Stone enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"(
534ea671fbdSKate Stone 
535ea671fbdSKate Stone (lldb) command alias bpl breakpoint list
536ea671fbdSKate Stone 
537ea671fbdSKate Stone     Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
538ea671fbdSKate Stone 
539ea671fbdSKate Stone )" "An alias can include some options for the command, with the values either \
540ea671fbdSKate Stone filled in at the time the alias is created, or specified as positional \
541ea671fbdSKate Stone arguments, to be filled in when the alias is invoked.  The following example \
542ea671fbdSKate Stone shows how to create aliases with options:" R"(
543ea671fbdSKate Stone 
544ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
545ea671fbdSKate Stone 
546ea671fbdSKate Stone )" "    Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
547ea671fbdSKate Stone options already part of the alias.  So if the user wants to set a breakpoint \
548ea671fbdSKate Stone by file and line without explicitly having to use the -f and -l options, the \
549ea671fbdSKate Stone user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \
550ea671fbdSKate Stone for the actual arguments that will be passed when the alias command is used.  \
551ea671fbdSKate Stone The number in the placeholder refers to the position/order the actual value \
552ea671fbdSKate Stone occupies when the alias is used.  All the occurrences of '%1' in the alias \
553ea671fbdSKate Stone will be replaced with the first argument, all the occurrences of '%2' in the \
554ea671fbdSKate Stone alias will be replaced with the second argument, and so on.  This also allows \
555ea671fbdSKate Stone actual arguments to be used multiple times within an alias (see 'process \
556ea671fbdSKate Stone launch' example below)." R"(
557ea671fbdSKate Stone 
558ea671fbdSKate Stone )" "Note: the positional arguments must substitute as whole words in the resultant \
559ea671fbdSKate Stone command, so you can't at present do something like this to append the file extension \
560ea671fbdSKate Stone \".cpp\":" R"(
561ea671fbdSKate Stone 
562ea671fbdSKate Stone (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
563ea671fbdSKate Stone 
564ea671fbdSKate Stone )" "For more complex aliasing, use the \"command regex\" command instead.  In the \
565ea671fbdSKate Stone 'bfl' case above, the actual file value will be filled in with the first argument \
566ea671fbdSKate Stone following 'bfl' and the actual line number value will be filled in with the second \
567ea671fbdSKate Stone argument.  The user would use this alias as follows:" R"(
568ea671fbdSKate Stone 
569ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
570ea671fbdSKate Stone (lldb) bfl my-file.c 137
571ea671fbdSKate Stone 
572ea671fbdSKate Stone This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
573ea671fbdSKate Stone 
574ea671fbdSKate Stone Another example:
575ea671fbdSKate Stone 
576ea671fbdSKate Stone (lldb) command alias pltty process launch -s -o %1 -e %1
577ea671fbdSKate Stone (lldb) pltty /dev/tty0
578ea671fbdSKate Stone 
579ea671fbdSKate Stone     Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
580ea671fbdSKate Stone 
581ea671fbdSKate Stone )" "If the user always wanted to pass the same value to a particular option, the \
582ea671fbdSKate Stone alias could be defined with that value directly in the alias as a constant, \
583ea671fbdSKate Stone rather than using a positional placeholder:" R"(
584ea671fbdSKate Stone 
585ea671fbdSKate Stone (lldb) command alias bl3 breakpoint set -f %1 -l 3
586ea671fbdSKate Stone 
587ea671fbdSKate Stone     Always sets a breakpoint on line 3 of whatever file is indicated.)"
588ea671fbdSKate Stone         );
589ebc09c36SJim Ingham 
590405fe67fSCaroline Tice         CommandArgumentEntry arg1;
591405fe67fSCaroline Tice         CommandArgumentEntry arg2;
592405fe67fSCaroline Tice         CommandArgumentEntry arg3;
593405fe67fSCaroline Tice         CommandArgumentData alias_arg;
594405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
595405fe67fSCaroline Tice         CommandArgumentData options_arg;
596405fe67fSCaroline Tice 
597405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
598405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
599405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
600405fe67fSCaroline Tice 
601405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
602405fe67fSCaroline Tice         arg1.push_back (alias_arg);
603405fe67fSCaroline Tice 
604405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
605405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
606405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
607405fe67fSCaroline Tice 
608405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
609405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
610405fe67fSCaroline Tice 
611405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
612405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
613405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
614405fe67fSCaroline Tice 
615405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
616405fe67fSCaroline Tice         arg3.push_back (options_arg);
617405fe67fSCaroline Tice 
618405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
619405fe67fSCaroline Tice         m_arguments.push_back (arg1);
620405fe67fSCaroline Tice         m_arguments.push_back (arg2);
621405fe67fSCaroline Tice         m_arguments.push_back (arg3);
622ebc09c36SJim Ingham     }
623ebc09c36SJim Ingham 
6246e3d8e7fSEugene Zelenko     ~CommandObjectCommandsAlias() override = default;
625ebc09c36SJim Ingham 
6265a988416SJim Ingham protected:
62713d21e9aSBruce Mitchener     bool
62813d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
629844d2303SCaroline Tice     {
63045d0e238SEnrico Granata         if (!raw_command_line || !raw_command_line[0])
63145d0e238SEnrico Granata         {
632d72e412fSEnrico Granata             result.AppendError ("'command alias' requires at least two arguments");
63345d0e238SEnrico Granata             return false;
63445d0e238SEnrico Granata         }
63545d0e238SEnrico Granata 
636*e1cfbc79STodd Fiala         ExecutionContext exe_ctx = GetCommandInterpreter().GetExecutionContext();
637*e1cfbc79STodd Fiala         m_option_group.NotifyOptionParsingStarting(&exe_ctx);
63845d0e238SEnrico Granata 
63945d0e238SEnrico Granata         const char * remainder = nullptr;
64045d0e238SEnrico Granata 
64145d0e238SEnrico Granata         if (raw_command_line[0] == '-')
64245d0e238SEnrico Granata         {
64345d0e238SEnrico Granata             // We have some options and these options MUST end with --.
64445d0e238SEnrico Granata             const char *end_options = nullptr;
64545d0e238SEnrico Granata             const char *s = raw_command_line;
64645d0e238SEnrico Granata             while (s && s[0])
64745d0e238SEnrico Granata             {
64845d0e238SEnrico Granata                 end_options = ::strstr (s, "--");
64945d0e238SEnrico Granata                 if (end_options)
65045d0e238SEnrico Granata                 {
65145d0e238SEnrico Granata                     end_options += 2; // Get past the "--"
65245d0e238SEnrico Granata                     if (::isspace (end_options[0]))
65345d0e238SEnrico Granata                     {
65445d0e238SEnrico Granata                         remainder = end_options;
65545d0e238SEnrico Granata                         while (::isspace (*remainder))
65645d0e238SEnrico Granata                             ++remainder;
65745d0e238SEnrico Granata                         break;
65845d0e238SEnrico Granata                     }
65945d0e238SEnrico Granata                 }
66045d0e238SEnrico Granata                 s = end_options;
66145d0e238SEnrico Granata             }
66245d0e238SEnrico Granata 
66345d0e238SEnrico Granata             if (end_options)
66445d0e238SEnrico Granata             {
66545d0e238SEnrico Granata                 Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
66645d0e238SEnrico Granata                 if (!ParseOptions (args, result))
66745d0e238SEnrico Granata                     return false;
66845d0e238SEnrico Granata 
669*e1cfbc79STodd Fiala                 Error error (m_option_group.NotifyOptionParsingFinished(&exe_ctx));
67045d0e238SEnrico Granata                 if (error.Fail())
67145d0e238SEnrico Granata                 {
67245d0e238SEnrico Granata                     result.AppendError (error.AsCString());
67345d0e238SEnrico Granata                     result.SetStatus (eReturnStatusFailed);
67445d0e238SEnrico Granata                     return false;
67545d0e238SEnrico Granata                 }
67645d0e238SEnrico Granata             }
67745d0e238SEnrico Granata         }
67845d0e238SEnrico Granata         if (nullptr == remainder)
67945d0e238SEnrico Granata             remainder = raw_command_line;
68045d0e238SEnrico Granata 
68145d0e238SEnrico Granata         std::string raw_command_string (remainder);
68245d0e238SEnrico Granata         Args args (raw_command_string.c_str());
683844d2303SCaroline Tice 
684844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
685844d2303SCaroline Tice 
686844d2303SCaroline Tice         if (argc < 2)
687844d2303SCaroline Tice         {
688d72e412fSEnrico Granata             result.AppendError ("'command alias' requires at least two arguments");
689844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
690844d2303SCaroline Tice             return false;
691844d2303SCaroline Tice         }
692844d2303SCaroline Tice 
693844d2303SCaroline Tice         // Get the alias command.
694844d2303SCaroline Tice 
695844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
696d72e412fSEnrico Granata         if (alias_command.size() > 1 &&
697d72e412fSEnrico Granata             alias_command[0] == '-')
698d72e412fSEnrico Granata         {
699d72e412fSEnrico Granata             result.AppendError("aliases starting with a dash are not supported");
700d72e412fSEnrico Granata             if (alias_command == "--help" || alias_command == "--long-help")
701d72e412fSEnrico Granata             {
702d72e412fSEnrico Granata                 result.AppendWarning("if trying to pass options to 'command alias' add a -- at the end of the options");
703d72e412fSEnrico Granata             }
704d72e412fSEnrico Granata             result.SetStatus (eReturnStatusFailed);
705d72e412fSEnrico Granata             return false;
706d72e412fSEnrico Granata         }
707844d2303SCaroline Tice 
708844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
709844d2303SCaroline Tice         // does the stripping itself.
710844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
711844d2303SCaroline Tice         if (pos == 0)
712844d2303SCaroline Tice         {
713844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
714844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
715844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
716844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
717844d2303SCaroline Tice         }
718844d2303SCaroline Tice         else
719844d2303SCaroline Tice         {
720844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
721844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
722844d2303SCaroline Tice             return false;
723844d2303SCaroline Tice         }
724844d2303SCaroline Tice 
725844d2303SCaroline Tice 
726844d2303SCaroline Tice         // Verify that the command is alias-able.
727844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
728844d2303SCaroline Tice         {
729844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
730844d2303SCaroline Tice                                           alias_command.c_str());
731844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
732844d2303SCaroline Tice             return false;
733844d2303SCaroline Tice         }
734844d2303SCaroline Tice 
735844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
736844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
737d72e412fSEnrico Granata         std::string original_raw_command_string(raw_command_string);
738844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
739844d2303SCaroline Tice 
740844d2303SCaroline Tice         if (!cmd_obj)
741844d2303SCaroline Tice         {
742d72e412fSEnrico Granata             result.AppendErrorWithFormat ("invalid command given to 'command alias'. '%s' does not begin with a valid command."
743d72e412fSEnrico Granata                                           "  No alias created.", original_raw_command_string.c_str());
744844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
745844d2303SCaroline Tice             return false;
746844d2303SCaroline Tice         }
747844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
748844d2303SCaroline Tice         {
749844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
750844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
7515a988416SJim Ingham             return HandleAliasingNormalCommand (args, result);
752844d2303SCaroline Tice         }
753844d2303SCaroline Tice         else
754844d2303SCaroline Tice         {
7555a988416SJim Ingham             return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
7565a988416SJim Ingham         }
7575a988416SJim Ingham         return result.Succeeded();
7585a988416SJim Ingham     }
7595a988416SJim Ingham 
7605a988416SJim Ingham     bool
7615a988416SJim Ingham     HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
7625a988416SJim Ingham     {
763844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
764844d2303SCaroline Tice 
765844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
766844d2303SCaroline Tice 
767212130acSEnrico Granata             if (CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false))
768844d2303SCaroline Tice             {
769844d2303SCaroline Tice                 if (m_interpreter.AliasExists (alias_command.c_str())
770844d2303SCaroline Tice                     || m_interpreter.UserCommandExists (alias_command.c_str()))
771844d2303SCaroline Tice                 {
772844d2303SCaroline Tice                     result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
773844d2303SCaroline Tice                                                     alias_command.c_str());
774844d2303SCaroline Tice                 }
77545d0e238SEnrico Granata                 if (CommandAlias *alias = m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp, raw_command_string.c_str()))
776472362e6SCaroline Tice                 {
77745d0e238SEnrico Granata                     if (m_command_options.m_help.OptionWasSet())
77845d0e238SEnrico Granata                         alias->SetHelp(m_command_options.m_help.GetCurrentValue());
77945d0e238SEnrico Granata                     if (m_command_options.m_long_help.OptionWasSet())
78045d0e238SEnrico Granata                         alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
781844d2303SCaroline Tice                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
782844d2303SCaroline Tice                 }
783472362e6SCaroline Tice                 else
784472362e6SCaroline Tice                 {
785472362e6SCaroline Tice                     result.AppendError ("Unable to create requested alias.\n");
786472362e6SCaroline Tice                     result.SetStatus (eReturnStatusFailed);
787472362e6SCaroline Tice                 }
788212130acSEnrico Granata 
789212130acSEnrico Granata             }
790212130acSEnrico Granata             else
791212130acSEnrico Granata             {
792212130acSEnrico Granata                 result.AppendError ("Unable to create requested alias.\n");
793212130acSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
794212130acSEnrico Granata             }
795212130acSEnrico Granata 
796844d2303SCaroline Tice             return result.Succeeded ();
797844d2303SCaroline Tice     }
798ebc09c36SJim Ingham 
799ebc09c36SJim Ingham     bool
8005a988416SJim Ingham     HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
801ebc09c36SJim Ingham     {
802867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
803ebc09c36SJim Ingham 
804ebc09c36SJim Ingham         if (argc < 2)
805ebc09c36SJim Ingham         {
806d72e412fSEnrico Granata             result.AppendError ("'command alias' requires at least two arguments");
807ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
808ebc09c36SJim Ingham             return false;
809ebc09c36SJim Ingham         }
810ebc09c36SJim Ingham 
811ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
812ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
813ebc09c36SJim Ingham 
814ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
815ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
816ebc09c36SJim Ingham 
817ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
818ebc09c36SJim Ingham 
819a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
820ebc09c36SJim Ingham         {
821ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
822ebc09c36SJim Ingham                                          alias_command.c_str());
823ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
824ebc09c36SJim Ingham         }
825ebc09c36SJim Ingham         else
826ebc09c36SJim Ingham         {
827a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
828ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
829ebc09c36SJim Ingham              bool use_subcommand = false;
8306e3d8e7fSEugene Zelenko              if (command_obj_sp)
831ebc09c36SJim Ingham              {
832ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
8336e3d8e7fSEugene Zelenko                  CommandObject *sub_cmd_obj = nullptr;
834ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
835ebc09c36SJim Ingham 
836844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
837ebc09c36SJim Ingham                  {
838ebc09c36SJim Ingham                      if (argc >= 3)
839ebc09c36SJim Ingham                      {
840ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
841ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
842998255bfSGreg Clayton                          subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
8436e3d8e7fSEugene Zelenko                          if (subcommand_obj_sp)
844ebc09c36SJim Ingham                          {
845ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
846ebc09c36SJim Ingham                              use_subcommand = true;
847ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
848844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
849ebc09c36SJim Ingham                          }
850ebc09c36SJim Ingham                          else
851ebc09c36SJim Ingham                          {
852f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
853f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
854f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
855ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
856ebc09c36SJim Ingham                              return false;
857ebc09c36SJim Ingham                          }
858ebc09c36SJim Ingham                      }
859ebc09c36SJim Ingham                  }
860ebc09c36SJim Ingham 
861ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
862ebc09c36SJim Ingham 
863212130acSEnrico Granata                  std::string args_string;
864212130acSEnrico Granata 
865ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
866ebc09c36SJim Ingham                  {
867ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
868ebc09c36SJim Ingham                     if (use_subcommand)
869ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
870ca90c47eSCaroline Tice 
871ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
872867b185dSCaroline Tice                  }
873ebc09c36SJim Ingham 
874a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
875a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
876ebc09c36SJim Ingham                  {
877ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
878ebc09c36SJim Ingham                                                      alias_command.c_str());
879ebc09c36SJim Ingham                  }
880ebc09c36SJim Ingham 
88145d0e238SEnrico Granata                  if (CommandAlias *alias = m_interpreter.AddAlias(alias_command.c_str(),
882212130acSEnrico Granata                                                                   use_subcommand ? subcommand_obj_sp : command_obj_sp,
883212130acSEnrico Granata                                                                   args_string.c_str()))
884212130acSEnrico Granata                  {
88545d0e238SEnrico Granata                      if (m_command_options.m_help.OptionWasSet())
88645d0e238SEnrico Granata                          alias->SetHelp(m_command_options.m_help.GetCurrentValue());
88745d0e238SEnrico Granata                      if (m_command_options.m_long_help.OptionWasSet())
88845d0e238SEnrico Granata                          alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
889ebc09c36SJim Ingham                      result.SetStatus (eReturnStatusSuccessFinishNoResult);
890ebc09c36SJim Ingham                  }
891ebc09c36SJim Ingham                  else
892ebc09c36SJim Ingham                  {
893212130acSEnrico Granata                      result.AppendError ("Unable to create requested alias.\n");
894212130acSEnrico Granata                      result.SetStatus (eReturnStatusFailed);
895212130acSEnrico Granata                      return false;
896212130acSEnrico Granata                  }
897212130acSEnrico Granata              }
898212130acSEnrico Granata              else
899212130acSEnrico Granata              {
900ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
901ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
902e7941795SCaroline Tice                  return false;
903ebc09c36SJim Ingham              }
904ebc09c36SJim Ingham         }
905ebc09c36SJim Ingham 
906ebc09c36SJim Ingham         return result.Succeeded();
907ebc09c36SJim Ingham     }
908ebc09c36SJim Ingham };
909ebc09c36SJim Ingham 
91045d0e238SEnrico Granata OptionDefinition
91145d0e238SEnrico Granata CommandObjectCommandsAlias::CommandOptions::g_option_table[] =
91245d0e238SEnrico Granata {
91345d0e238SEnrico Granata     { LLDB_OPT_SET_ALL, false, "help",      'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText,    "Help text for this command"},
91445d0e238SEnrico Granata     { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText,    "Long help text for this command"},
91545d0e238SEnrico Granata     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
91645d0e238SEnrico Granata };
91745d0e238SEnrico Granata 
918ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
919ebc09c36SJim Ingham //-------------------------------------------------------------------------
920ebc09c36SJim Ingham // CommandObjectCommandsUnalias
921ebc09c36SJim Ingham //-------------------------------------------------------------------------
922ebc09c36SJim Ingham 
9235a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed
924ebc09c36SJim Ingham {
925ebc09c36SJim Ingham public:
9267428a18cSKate Stone     CommandObjectCommandsUnalias(CommandInterpreter &interpreter)
9277428a18cSKate Stone         : CommandObjectParsed(interpreter, "command unalias",
9287428a18cSKate Stone                               "Delete one or more custom commands defined by 'command alias'.", nullptr)
929ebc09c36SJim Ingham     {
930405fe67fSCaroline Tice         CommandArgumentEntry arg;
931405fe67fSCaroline Tice         CommandArgumentData alias_arg;
932405fe67fSCaroline Tice 
933405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
934405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
935405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
936405fe67fSCaroline Tice 
937405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
938405fe67fSCaroline Tice         arg.push_back (alias_arg);
939405fe67fSCaroline Tice 
940405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
941405fe67fSCaroline Tice         m_arguments.push_back (arg);
942ebc09c36SJim Ingham     }
943ebc09c36SJim Ingham 
9446e3d8e7fSEugene Zelenko     ~CommandObjectCommandsUnalias() override = default;
945ebc09c36SJim Ingham 
9465a988416SJim Ingham protected:
947ebc09c36SJim Ingham     bool
94813d21e9aSBruce Mitchener     DoExecute (Args& args, CommandReturnObject &result) override
949ebc09c36SJim Ingham     {
950ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
951ebc09c36SJim Ingham         CommandObject *cmd_obj;
952ebc09c36SJim Ingham 
953ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
954ebc09c36SJim Ingham         {
955ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
956a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
957ebc09c36SJim Ingham             if (cmd_obj)
958ebc09c36SJim Ingham             {
959a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
960ebc09c36SJim Ingham                 {
961b547278cSGreg Clayton                     if (cmd_obj->IsRemovable())
962b547278cSGreg Clayton                     {
963b547278cSGreg Clayton                         result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
964b547278cSGreg Clayton                                                       command_name);
965b547278cSGreg Clayton                     }
966b547278cSGreg Clayton                     else
967b547278cSGreg Clayton                     {
968ebc09c36SJim Ingham                         result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
969ebc09c36SJim Ingham                                                       command_name);
970b547278cSGreg Clayton                     }
971ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
972ebc09c36SJim Ingham                 }
973ebc09c36SJim Ingham                 else
974ebc09c36SJim Ingham                 {
9756e3d8e7fSEugene Zelenko                     if (!m_interpreter.RemoveAlias(command_name))
976ebc09c36SJim Ingham                     {
977a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
978ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
979ebc09c36SJim Ingham                                                           command_name);
980ebc09c36SJim Ingham                         else
981ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
982ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
983ebc09c36SJim Ingham                     }
984ebc09c36SJim Ingham                     else
985ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
986ebc09c36SJim Ingham                 }
987ebc09c36SJim Ingham             }
988ebc09c36SJim Ingham             else
989ebc09c36SJim Ingham             {
990ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
991ebc09c36SJim Ingham                                               "current list of commands.\n",
992ebc09c36SJim Ingham                                              command_name);
993ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
994ebc09c36SJim Ingham             }
995ebc09c36SJim Ingham         }
996ebc09c36SJim Ingham         else
997ebc09c36SJim Ingham         {
998ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
999ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
1000ebc09c36SJim Ingham         }
1001ebc09c36SJim Ingham 
1002ebc09c36SJim Ingham         return result.Succeeded();
1003ebc09c36SJim Ingham     }
1004ebc09c36SJim Ingham };
1005ebc09c36SJim Ingham 
1006b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete
1007b547278cSGreg Clayton //-------------------------------------------------------------------------
1008b547278cSGreg Clayton // CommandObjectCommandsDelete
1009b547278cSGreg Clayton //-------------------------------------------------------------------------
1010b547278cSGreg Clayton 
1011b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed
1012b547278cSGreg Clayton {
1013b547278cSGreg Clayton public:
10147428a18cSKate Stone     CommandObjectCommandsDelete(CommandInterpreter &interpreter)
10157428a18cSKate Stone         : CommandObjectParsed(interpreter, "command delete",
10167428a18cSKate Stone                               "Delete one or more custom commands defined by 'command regex'.", nullptr)
1017b547278cSGreg Clayton     {
1018b547278cSGreg Clayton         CommandArgumentEntry arg;
1019b547278cSGreg Clayton         CommandArgumentData alias_arg;
1020b547278cSGreg Clayton 
1021b547278cSGreg Clayton         // Define the first (and only) variant of this arg.
1022b547278cSGreg Clayton         alias_arg.arg_type = eArgTypeCommandName;
1023b547278cSGreg Clayton         alias_arg.arg_repetition = eArgRepeatPlain;
1024b547278cSGreg Clayton 
1025b547278cSGreg Clayton         // There is only one variant this argument could be; put it into the argument entry.
1026b547278cSGreg Clayton         arg.push_back (alias_arg);
1027b547278cSGreg Clayton 
1028b547278cSGreg Clayton         // Push the data for the first argument into the m_arguments vector.
1029b547278cSGreg Clayton         m_arguments.push_back (arg);
1030b547278cSGreg Clayton     }
1031b547278cSGreg Clayton 
10326e3d8e7fSEugene Zelenko     ~CommandObjectCommandsDelete() override = default;
1033b547278cSGreg Clayton 
1034b547278cSGreg Clayton protected:
1035b547278cSGreg Clayton     bool
103613d21e9aSBruce Mitchener     DoExecute (Args& args, CommandReturnObject &result) override
1037b547278cSGreg Clayton     {
1038b547278cSGreg Clayton         CommandObject::CommandMap::iterator pos;
1039b547278cSGreg Clayton 
1040b547278cSGreg Clayton         if (args.GetArgumentCount() != 0)
1041b547278cSGreg Clayton         {
1042b547278cSGreg Clayton             const char *command_name = args.GetArgumentAtIndex(0);
1043b547278cSGreg Clayton             if (m_interpreter.CommandExists (command_name))
1044b547278cSGreg Clayton             {
1045b547278cSGreg Clayton                 if (m_interpreter.RemoveCommand (command_name))
1046b547278cSGreg Clayton                 {
1047b547278cSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1048b547278cSGreg Clayton                 }
1049b547278cSGreg Clayton                 else
1050b547278cSGreg Clayton                 {
1051b547278cSGreg Clayton                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
1052b547278cSGreg Clayton                                                   command_name);
1053b547278cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
1054b547278cSGreg Clayton                 }
1055b547278cSGreg Clayton             }
1056b547278cSGreg Clayton             else
1057b547278cSGreg Clayton             {
105846d4aa21SEnrico Granata                 StreamString error_msg_stream;
105946d4aa21SEnrico Granata                 const bool generate_apropos = true;
106046d4aa21SEnrico Granata                 const bool generate_type_lookup = false;
106146d4aa21SEnrico Granata                 CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
106246d4aa21SEnrico Granata                                                                         command_name,
106346d4aa21SEnrico Granata                                                                         nullptr,
106446d4aa21SEnrico Granata                                                                         nullptr,
106546d4aa21SEnrico Granata                                                                         generate_apropos,
106646d4aa21SEnrico Granata                                                                         generate_type_lookup);
106746d4aa21SEnrico Granata                 result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
1068b547278cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1069b547278cSGreg Clayton             }
1070b547278cSGreg Clayton         }
1071b547278cSGreg Clayton         else
1072b547278cSGreg Clayton         {
10737428a18cSKate Stone             result.AppendErrorWithFormat(
10747428a18cSKate Stone                 "must call '%s' with one or more valid user defined regular expression command names",
10757428a18cSKate Stone                 GetCommandName());
1076b547278cSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1077b547278cSGreg Clayton         }
1078b547278cSGreg Clayton 
1079b547278cSGreg Clayton         return result.Succeeded();
1080b547278cSGreg Clayton     }
1081b547278cSGreg Clayton };
1082b547278cSGreg Clayton 
1083de164aaaSGreg Clayton //-------------------------------------------------------------------------
1084de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
1085de164aaaSGreg Clayton //-------------------------------------------------------------------------
10865a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex
1087de164aaaSGreg Clayton 
108844d93782SGreg Clayton class CommandObjectCommandsAddRegex :
108944d93782SGreg Clayton     public CommandObjectParsed,
1090ea508635SGreg Clayton     public IOHandlerDelegateMultiline
1091de164aaaSGreg Clayton {
1092de164aaaSGreg Clayton public:
10937428a18cSKate Stone     CommandObjectCommandsAddRegex(CommandInterpreter &interpreter)
10947428a18cSKate Stone         : CommandObjectParsed(interpreter, "command regex",
10957428a18cSKate Stone                               "Define a custom command in terms of existing commands by matching regular expressions.",
10960e5e5a79SGreg Clayton                               "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
1097ea508635SGreg Clayton           IOHandlerDelegateMultiline("", IOHandlerDelegate::Completion::LLDBCommand),
1098*e1cfbc79STodd Fiala           m_options()
1099de164aaaSGreg Clayton     {
1100ea671fbdSKate Stone         SetHelpLong(R"(
1101ea671fbdSKate Stone )" "This command allows the user to create powerful regular expression commands \
1102ea671fbdSKate Stone with substitutions. The regular expressions and substitutions are specified \
1103ea671fbdSKate Stone using the regular expression substitution format of:" R"(
1104ea671fbdSKate Stone 
1105ea671fbdSKate Stone     s/<regex>/<subst>/
1106ea671fbdSKate Stone 
1107ea671fbdSKate Stone )" "<regex> is a regular expression that can use parenthesis to capture regular \
1108ea671fbdSKate Stone expression input and substitute the captured matches in the output using %1 \
1109ea671fbdSKate Stone for the first match, %2 for the second, and so on." R"(
1110ea671fbdSKate Stone 
1111ea671fbdSKate Stone )" "The regular expressions can all be specified on the command line if more than \
1112ea671fbdSKate Stone one argument is provided. If just the command name is provided on the command \
1113ea671fbdSKate Stone line, then the regular expressions and substitutions can be entered on separate \
1114ea671fbdSKate Stone lines, followed by an empty line to terminate the command definition." R"(
1115ea671fbdSKate Stone 
1116ea671fbdSKate Stone EXAMPLES
1117ea671fbdSKate Stone 
1118ea671fbdSKate Stone )" "The following example will define a regular expression command named 'f' that \
1119ea671fbdSKate Stone will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
1120ea671fbdSKate Stone a number follows 'f':" R"(
1121ea671fbdSKate Stone 
1122ea671fbdSKate Stone     (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
11230e5e5a79SGreg Clayton         );
1124de164aaaSGreg Clayton     }
1125de164aaaSGreg Clayton 
11266e3d8e7fSEugene Zelenko     ~CommandObjectCommandsAddRegex() override = default;
1127de164aaaSGreg Clayton 
11285a988416SJim Ingham protected:
1129ea508635SGreg Clayton     void
1130ea508635SGreg Clayton     IOHandlerActivated (IOHandler &io_handler) override
113144d93782SGreg Clayton     {
113244d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
113344d93782SGreg Clayton         if (output_sp)
113444d93782SGreg Clayton         {
113544d93782SGreg 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");
113644d93782SGreg Clayton             output_sp->Flush();
113744d93782SGreg Clayton         }
113844d93782SGreg Clayton     }
113944d93782SGreg Clayton 
1140ea508635SGreg Clayton     void
1141ea508635SGreg Clayton     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
114244d93782SGreg Clayton     {
114344d93782SGreg Clayton         io_handler.SetIsDone(true);
11446e3d8e7fSEugene Zelenko         if (m_regex_cmd_ap)
114544d93782SGreg Clayton         {
114644d93782SGreg Clayton             StringList lines;
114744d93782SGreg Clayton             if (lines.SplitIntoLines (data))
114844d93782SGreg Clayton             {
114944d93782SGreg Clayton                 const size_t num_lines = lines.GetSize();
115044d93782SGreg Clayton                 bool check_only = false;
115144d93782SGreg Clayton                 for (size_t i=0; i<num_lines; ++i)
115244d93782SGreg Clayton                 {
115344d93782SGreg Clayton                     llvm::StringRef bytes_strref (lines[i]);
115444d93782SGreg Clayton                     Error error = AppendRegexSubstitution (bytes_strref, check_only);
115544d93782SGreg Clayton                     if (error.Fail())
115644d93782SGreg Clayton                     {
115744d93782SGreg Clayton                         if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
115844d93782SGreg Clayton                         {
115944d93782SGreg Clayton                             StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
116044d93782SGreg Clayton                             out_stream->Printf("error: %s\n", error.AsCString());
116144d93782SGreg Clayton                         }
116244d93782SGreg Clayton                     }
116344d93782SGreg Clayton                 }
116444d93782SGreg Clayton             }
116544d93782SGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
116644d93782SGreg Clayton             {
116744d93782SGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
116844d93782SGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
116944d93782SGreg Clayton             }
117044d93782SGreg Clayton         }
117144d93782SGreg Clayton     }
117244d93782SGreg Clayton 
1173de164aaaSGreg Clayton     bool
1174b0a1814fSEric Christopher     DoExecute (Args& command, CommandReturnObject &result) override
1175de164aaaSGreg Clayton     {
11765a988416SJim Ingham         const size_t argc = command.GetArgumentCount();
11770e5e5a79SGreg Clayton         if (argc == 0)
1178de164aaaSGreg Clayton         {
117969c12ccbSJason Molenda             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
11800e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
11810e5e5a79SGreg Clayton         }
11820e5e5a79SGreg Clayton         else
11830e5e5a79SGreg Clayton         {
11840e5e5a79SGreg Clayton             Error error;
11855a988416SJim Ingham             const char *name = command.GetArgumentAtIndex(0);
1186de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1187de164aaaSGreg Clayton                                                                  name,
1188de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
1189de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
1190b547278cSGreg Clayton                                                                  10,
1191b547278cSGreg Clayton                                                                  0,
1192b547278cSGreg Clayton                                                                  true));
11930e5e5a79SGreg Clayton 
11940e5e5a79SGreg Clayton             if (argc == 1)
11950e5e5a79SGreg Clayton             {
119644d93782SGreg Clayton                 Debugger &debugger = m_interpreter.GetDebugger();
1197e30f11d9SKate Stone                 bool color_prompt = debugger.GetUseColor();
119844d93782SGreg Clayton                 const bool multiple_lines = true; // Get multiple lines
119944d93782SGreg Clayton                 IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
1200e30f11d9SKate Stone                                                                 IOHandler::Type::Other,
120173d80faaSGreg Clayton                                                                 "lldb-regex", // Name of input reader for history
1202ea508635SGreg Clayton                                                                 "> ",         // Prompt
12036e3d8e7fSEugene Zelenko                                                                 nullptr,      // Continuation prompt
120444d93782SGreg Clayton                                                                 multiple_lines,
1205e30f11d9SKate Stone                                                                 color_prompt,
1206f6913cd7SGreg Clayton                                                                 0,            // Don't show line numbers
120744d93782SGreg Clayton                                                                 *this));
120844d93782SGreg Clayton 
120944d93782SGreg Clayton                 if (io_handler_sp)
1210de164aaaSGreg Clayton                 {
121144d93782SGreg Clayton                     debugger.PushIOHandler(io_handler_sp);
1212de164aaaSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1213de164aaaSGreg Clayton                 }
1214de164aaaSGreg Clayton             }
1215de164aaaSGreg Clayton             else
1216de164aaaSGreg Clayton             {
12170e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
12180e5e5a79SGreg Clayton                 {
12195a988416SJim Ingham                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
122044d93782SGreg Clayton                     bool check_only = false;
122144d93782SGreg Clayton                     error = AppendRegexSubstitution (arg_strref, check_only);
12220e5e5a79SGreg Clayton                     if (error.Fail())
12230e5e5a79SGreg Clayton                         break;
12240e5e5a79SGreg Clayton                 }
12250e5e5a79SGreg Clayton 
12260e5e5a79SGreg Clayton                 if (error.Success())
12270e5e5a79SGreg Clayton                 {
12280e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
12290e5e5a79SGreg Clayton                 }
12300e5e5a79SGreg Clayton             }
12310e5e5a79SGreg Clayton             if (error.Fail())
12320e5e5a79SGreg Clayton             {
12330e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
1234de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1235de164aaaSGreg Clayton             }
12360e5e5a79SGreg Clayton         }
12370e5e5a79SGreg Clayton 
1238de164aaaSGreg Clayton         return result.Succeeded();
1239de164aaaSGreg Clayton     }
1240de164aaaSGreg Clayton 
12410e5e5a79SGreg Clayton     Error
124244d93782SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
1243de164aaaSGreg Clayton     {
12440e5e5a79SGreg Clayton         Error error;
12450e5e5a79SGreg Clayton 
12466e3d8e7fSEugene Zelenko         if (!m_regex_cmd_ap)
1247de164aaaSGreg Clayton         {
12480e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
12490e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12500e5e5a79SGreg Clayton                                            regex_sed.data());
12510e5e5a79SGreg Clayton             return error;
1252de164aaaSGreg Clayton         }
12530e5e5a79SGreg Clayton 
12540e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
12550e5e5a79SGreg Clayton 
12560e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
12570e5e5a79SGreg Clayton         {
12580e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
12590e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12600e5e5a79SGreg Clayton                                            regex_sed.data());
12610e5e5a79SGreg Clayton             return error;
12620e5e5a79SGreg Clayton         }
12630e5e5a79SGreg Clayton 
12640e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
12650e5e5a79SGreg Clayton         {
12660e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
12670e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12680e5e5a79SGreg Clayton                                            regex_sed.data());
12690e5e5a79SGreg Clayton             return error;
12700e5e5a79SGreg Clayton         }
12710e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
12720e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
12730e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
12740e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
12750e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
12760e5e5a79SGreg Clayton 
12770e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
12780e5e5a79SGreg Clayton         {
1279ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
12800e5e5a79SGreg Clayton                                            separator_char,
12810e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
1282ea508635SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1),
1283ea508635SGreg Clayton                                            (int)regex_sed.size(),
1284ea508635SGreg Clayton                                            regex_sed.data());
12850e5e5a79SGreg Clayton             return error;
12860e5e5a79SGreg Clayton         }
12870e5e5a79SGreg Clayton 
12880e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
12890e5e5a79SGreg Clayton 
12900e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
12910e5e5a79SGreg Clayton         {
1292ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
12930e5e5a79SGreg Clayton                                            separator_char,
12940e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
1295ea508635SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1),
1296ea508635SGreg Clayton                                            (int)regex_sed.size(),
1297ea508635SGreg Clayton                                            regex_sed.data());
12980e5e5a79SGreg Clayton             return error;
12990e5e5a79SGreg Clayton         }
13000e5e5a79SGreg Clayton 
13010e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
13020e5e5a79SGreg Clayton         {
13030e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
13040e5e5a79SGreg Clayton             // separator char
13050e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
13060e5e5a79SGreg Clayton             {
13070e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
13080e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
13090e5e5a79SGreg Clayton                                                regex_sed.data(),
13100e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
13110e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
13120e5e5a79SGreg Clayton                 return error;
13130e5e5a79SGreg Clayton             }
13140e5e5a79SGreg Clayton         }
13150e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
13160e5e5a79SGreg Clayton         {
13170e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
13180e5e5a79SGreg Clayton                                            separator_char,
13190e5e5a79SGreg Clayton                                            separator_char,
13200e5e5a79SGreg Clayton                                            separator_char,
13210e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
13220e5e5a79SGreg Clayton                                            regex_sed.data());
13230e5e5a79SGreg Clayton             return error;
13240e5e5a79SGreg Clayton         }
13250e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
13260e5e5a79SGreg Clayton         {
13270e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
13280e5e5a79SGreg Clayton                                            separator_char,
13290e5e5a79SGreg Clayton                                            separator_char,
13300e5e5a79SGreg Clayton                                            separator_char,
13310e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
13320e5e5a79SGreg Clayton                                            regex_sed.data());
13330e5e5a79SGreg Clayton             return error;
13340e5e5a79SGreg Clayton         }
133544d93782SGreg Clayton 
13366e3d8e7fSEugene Zelenko         if (!check_only)
133744d93782SGreg Clayton         {
13380e5e5a79SGreg Clayton             std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
13390e5e5a79SGreg Clayton             std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
13400e5e5a79SGreg Clayton             m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
13410e5e5a79SGreg Clayton                                              subst.c_str());
134244d93782SGreg Clayton         }
13430e5e5a79SGreg Clayton         return error;
1344de164aaaSGreg Clayton     }
1345de164aaaSGreg Clayton 
1346de164aaaSGreg Clayton     void
13470e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
1348de164aaaSGreg Clayton     {
13496e3d8e7fSEugene Zelenko         if (m_regex_cmd_ap)
1350de164aaaSGreg Clayton         {
1351de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
1352de164aaaSGreg Clayton             {
1353de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1354de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1355de164aaaSGreg Clayton             }
1356de164aaaSGreg Clayton         }
1357de164aaaSGreg Clayton     }
1358de164aaaSGreg Clayton 
1359de164aaaSGreg Clayton private:
13607b0992d9SGreg Clayton     std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1361de164aaaSGreg Clayton 
1362de164aaaSGreg Clayton      class CommandOptions : public Options
1363de164aaaSGreg Clayton      {
1364de164aaaSGreg Clayton      public:
1365*e1cfbc79STodd Fiala          CommandOptions() :
1366*e1cfbc79STodd Fiala             Options()
1367de164aaaSGreg Clayton          {
1368de164aaaSGreg Clayton          }
1369de164aaaSGreg Clayton 
13706e3d8e7fSEugene Zelenko          ~CommandOptions() override = default;
1371de164aaaSGreg Clayton 
137213d21e9aSBruce Mitchener          Error
1373*e1cfbc79STodd Fiala          SetOptionValue (uint32_t option_idx, const char *option_arg,
1374*e1cfbc79STodd Fiala                          ExecutionContext *execution_context) override
1375de164aaaSGreg Clayton          {
1376de164aaaSGreg Clayton              Error error;
13773bcdfc0eSGreg Clayton              const int short_option = m_getopt_table[option_idx].val;
1378de164aaaSGreg Clayton 
1379de164aaaSGreg Clayton              switch (short_option)
1380de164aaaSGreg Clayton              {
1381de164aaaSGreg Clayton                  case 'h':
1382de164aaaSGreg Clayton                      m_help.assign (option_arg);
1383de164aaaSGreg Clayton                      break;
1384de164aaaSGreg Clayton                  case 's':
1385de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1386de164aaaSGreg Clayton                      break;
1387de164aaaSGreg Clayton                  default:
138886edbf41SGreg Clayton                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1389de164aaaSGreg Clayton                      break;
1390de164aaaSGreg Clayton              }
1391de164aaaSGreg Clayton 
1392de164aaaSGreg Clayton              return error;
1393de164aaaSGreg Clayton          }
1394de164aaaSGreg Clayton 
1395de164aaaSGreg Clayton          void
1396*e1cfbc79STodd Fiala          OptionParsingStarting (ExecutionContext *execution_context) override
1397de164aaaSGreg Clayton          {
1398de164aaaSGreg Clayton              m_help.clear();
1399de164aaaSGreg Clayton              m_syntax.clear();
1400de164aaaSGreg Clayton          }
1401de164aaaSGreg Clayton 
1402de164aaaSGreg Clayton          const OptionDefinition*
140313d21e9aSBruce Mitchener          GetDefinitions () override
1404de164aaaSGreg Clayton          {
1405de164aaaSGreg Clayton              return g_option_table;
1406de164aaaSGreg Clayton          }
1407de164aaaSGreg Clayton 
1408de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1409de164aaaSGreg Clayton 
1410de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1411de164aaaSGreg Clayton 
1412de164aaaSGreg Clayton          const char *
1413de164aaaSGreg Clayton          GetHelp()
1414de164aaaSGreg Clayton          {
14156e3d8e7fSEugene Zelenko              return (m_help.empty() ? nullptr : m_help.c_str());
1416de164aaaSGreg Clayton          }
14176e3d8e7fSEugene Zelenko 
1418de164aaaSGreg Clayton          const char *
1419de164aaaSGreg Clayton          GetSyntax ()
1420de164aaaSGreg Clayton          {
14216e3d8e7fSEugene Zelenko              return (m_syntax.empty() ? nullptr : m_syntax.c_str());
1422de164aaaSGreg Clayton          }
14236e3d8e7fSEugene Zelenko 
1424de164aaaSGreg Clayton      protected:
14256e3d8e7fSEugene Zelenko          // Instance variables to hold the values for command options.
14266e3d8e7fSEugene Zelenko 
1427de164aaaSGreg Clayton          std::string m_help;
1428de164aaaSGreg Clayton          std::string m_syntax;
1429de164aaaSGreg Clayton      };
1430de164aaaSGreg Clayton 
1431b0a1814fSEric Christopher      Options *
1432b0a1814fSEric Christopher      GetOptions () override
1433de164aaaSGreg Clayton      {
1434de164aaaSGreg Clayton          return &m_options;
1435de164aaaSGreg Clayton      }
1436de164aaaSGreg Clayton 
14375a988416SJim Ingham      CommandOptions m_options;
1438de164aaaSGreg Clayton };
1439de164aaaSGreg Clayton 
1440de164aaaSGreg Clayton OptionDefinition
1441de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1442de164aaaSGreg Clayton {
14436e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command."},
14446e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
14456e3d8e7fSEugene Zelenko { 0             , false,  nullptr   , 0  , 0                , nullptr, nullptr, 0, eArgTypeNone, nullptr }
1446de164aaaSGreg Clayton };
1447de164aaaSGreg Clayton 
14485a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw
1449223383edSEnrico Granata {
1450223383edSEnrico Granata public:
1451223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1452223383edSEnrico Granata                                  std::string name,
14530a305db7SEnrico Granata                                  std::string funct,
1454735152e3SEnrico Granata                                  std::string help,
14550a305db7SEnrico Granata                                  ScriptedCommandSynchronicity synch) :
14565a988416SJim Ingham         CommandObjectRaw(interpreter,
1457223383edSEnrico Granata                          name.c_str(),
14586e3d8e7fSEugene Zelenko                          nullptr,
14596e3d8e7fSEugene Zelenko                          nullptr),
14600a305db7SEnrico Granata         m_function_name(funct),
1461fac939e9SEnrico Granata         m_synchro(synch),
1462fac939e9SEnrico Granata         m_fetched_help_long(false)
1463223383edSEnrico Granata     {
1464735152e3SEnrico Granata         if (!help.empty())
1465735152e3SEnrico Granata             SetHelp(help.c_str());
1466735152e3SEnrico Granata         else
1467735152e3SEnrico Granata         {
1468735152e3SEnrico Granata             StreamString stream;
1469735152e3SEnrico Granata             stream.Printf("For more information run 'help %s'",name.c_str());
1470735152e3SEnrico Granata             SetHelp(stream.GetData());
1471735152e3SEnrico Granata         }
1472223383edSEnrico Granata     }
1473223383edSEnrico Granata 
14746e3d8e7fSEugene Zelenko     ~CommandObjectPythonFunction() override = default;
1475223383edSEnrico Granata 
147613d21e9aSBruce Mitchener     bool
147713d21e9aSBruce Mitchener     IsRemovable () const override
14785a988416SJim Ingham     {
14795a988416SJim Ingham         return true;
14805a988416SJim Ingham     }
14815a988416SJim Ingham 
14825a988416SJim Ingham     const std::string&
14835a988416SJim Ingham     GetFunctionName ()
14845a988416SJim Ingham     {
14855a988416SJim Ingham         return m_function_name;
14865a988416SJim Ingham     }
14875a988416SJim Ingham 
14885a988416SJim Ingham     ScriptedCommandSynchronicity
14895a988416SJim Ingham     GetSynchronicity ()
14905a988416SJim Ingham     {
14915a988416SJim Ingham         return m_synchro;
14925a988416SJim Ingham     }
14935a988416SJim Ingham 
149413d21e9aSBruce Mitchener     const char *
149513d21e9aSBruce Mitchener     GetHelpLong () override
1496fac939e9SEnrico Granata     {
1497fac939e9SEnrico Granata         if (!m_fetched_help_long)
1498fac939e9SEnrico Granata         {
1499fac939e9SEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1500fac939e9SEnrico Granata             if (scripter)
1501fac939e9SEnrico Granata             {
1502fac939e9SEnrico Granata                 std::string docstring;
1503fac939e9SEnrico Granata                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1504fac939e9SEnrico Granata                 if (!docstring.empty())
1505bfb75e9bSEnrico Granata                     SetHelpLong(docstring.c_str());
1506fac939e9SEnrico Granata             }
1507fac939e9SEnrico Granata         }
1508fac939e9SEnrico Granata         return CommandObjectRaw::GetHelpLong();
1509fac939e9SEnrico Granata     }
1510fac939e9SEnrico Granata 
15115a988416SJim Ingham protected:
151213d21e9aSBruce Mitchener     bool
151313d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
1514223383edSEnrico Granata     {
1515223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1516223383edSEnrico Granata 
1517223383edSEnrico Granata         Error error;
1518223383edSEnrico Granata 
151970f11f88SJim Ingham         result.SetStatus(eReturnStatusInvalid);
152070f11f88SJim Ingham 
15216e3d8e7fSEugene Zelenko         if (!scripter || !scripter->RunScriptBasedCommand(m_function_name.c_str(),
1522223383edSEnrico Granata                                                           raw_command_line,
15230a305db7SEnrico Granata                                                           m_synchro,
1524223383edSEnrico Granata                                                           result,
152506be059aSEnrico Granata                                                           error,
15266e3d8e7fSEugene Zelenko                                                           m_exe_ctx))
1527223383edSEnrico Granata         {
1528223383edSEnrico Granata             result.AppendError(error.AsCString());
1529223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1530223383edSEnrico Granata         }
1531223383edSEnrico Granata         else
153270f11f88SJim Ingham         {
153370f11f88SJim Ingham             // Don't change the status if the command already set it...
153470f11f88SJim Ingham             if (result.GetStatus() == eReturnStatusInvalid)
153570f11f88SJim Ingham             {
15366e3d8e7fSEugene Zelenko                 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
1537223383edSEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
153870f11f88SJim Ingham                 else
153970f11f88SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishResult);
154070f11f88SJim Ingham             }
154170f11f88SJim Ingham         }
1542223383edSEnrico Granata 
1543223383edSEnrico Granata         return result.Succeeded();
1544223383edSEnrico Granata     }
1545223383edSEnrico Granata 
15466e3d8e7fSEugene Zelenko private:
15476e3d8e7fSEugene Zelenko     std::string m_function_name;
15486e3d8e7fSEugene Zelenko     ScriptedCommandSynchronicity m_synchro;
15496e3d8e7fSEugene Zelenko     bool m_fetched_help_long;
1550223383edSEnrico Granata };
1551223383edSEnrico Granata 
15529fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw
15539fe00e52SEnrico Granata {
15549fe00e52SEnrico Granata public:
15559fe00e52SEnrico Granata     CommandObjectScriptingObject (CommandInterpreter &interpreter,
15569fe00e52SEnrico Granata                                   std::string name,
15570641ca1aSZachary Turner                                   StructuredData::GenericSP cmd_obj_sp,
15589fe00e52SEnrico Granata                                   ScriptedCommandSynchronicity synch) :
15599fe00e52SEnrico Granata         CommandObjectRaw(interpreter,
15609fe00e52SEnrico Granata                          name.c_str(),
15616e3d8e7fSEugene Zelenko                          nullptr,
15626e3d8e7fSEugene Zelenko                          nullptr),
15639fe00e52SEnrico Granata         m_cmd_obj_sp(cmd_obj_sp),
15646f79bb2dSEnrico Granata         m_synchro(synch),
15656f79bb2dSEnrico Granata         m_fetched_help_short(false),
15666f79bb2dSEnrico Granata         m_fetched_help_long(false)
15679fe00e52SEnrico Granata     {
15689fe00e52SEnrico Granata         StreamString stream;
15699fe00e52SEnrico Granata         stream.Printf("For more information run 'help %s'",name.c_str());
15709fe00e52SEnrico Granata         SetHelp(stream.GetData());
1571e87764f2SEnrico Granata         if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1572e87764f2SEnrico Granata             GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
15739fe00e52SEnrico Granata     }
15749fe00e52SEnrico Granata 
15756e3d8e7fSEugene Zelenko     ~CommandObjectScriptingObject() override = default;
15769fe00e52SEnrico Granata 
157713d21e9aSBruce Mitchener     bool
157813d21e9aSBruce Mitchener     IsRemovable () const override
15799fe00e52SEnrico Granata     {
15809fe00e52SEnrico Granata         return true;
15819fe00e52SEnrico Granata     }
15829fe00e52SEnrico Granata 
15830641ca1aSZachary Turner     StructuredData::GenericSP
15849fe00e52SEnrico Granata     GetImplementingObject ()
15859fe00e52SEnrico Granata     {
15869fe00e52SEnrico Granata         return m_cmd_obj_sp;
15879fe00e52SEnrico Granata     }
15889fe00e52SEnrico Granata 
15899fe00e52SEnrico Granata     ScriptedCommandSynchronicity
15909fe00e52SEnrico Granata     GetSynchronicity ()
15919fe00e52SEnrico Granata     {
15929fe00e52SEnrico Granata         return m_synchro;
15939fe00e52SEnrico Granata     }
15949fe00e52SEnrico Granata 
159513d21e9aSBruce Mitchener     const char *
159613d21e9aSBruce Mitchener     GetHelp () override
15976f79bb2dSEnrico Granata     {
15986f79bb2dSEnrico Granata         if (!m_fetched_help_short)
15996f79bb2dSEnrico Granata         {
16006f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
16016f79bb2dSEnrico Granata             if (scripter)
16026f79bb2dSEnrico Granata             {
16036f79bb2dSEnrico Granata                 std::string docstring;
16046f79bb2dSEnrico Granata                 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
16056f79bb2dSEnrico Granata                 if (!docstring.empty())
1606bfb75e9bSEnrico Granata                     SetHelp(docstring.c_str());
16076f79bb2dSEnrico Granata             }
16086f79bb2dSEnrico Granata         }
16096f79bb2dSEnrico Granata         return CommandObjectRaw::GetHelp();
16106f79bb2dSEnrico Granata     }
16116f79bb2dSEnrico Granata 
161213d21e9aSBruce Mitchener     const char *
161313d21e9aSBruce Mitchener     GetHelpLong () override
16149fe00e52SEnrico Granata     {
16156f79bb2dSEnrico Granata         if (!m_fetched_help_long)
16166f79bb2dSEnrico Granata         {
16176f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
16186f79bb2dSEnrico Granata             if (scripter)
16196f79bb2dSEnrico Granata             {
16206f79bb2dSEnrico Granata                 std::string docstring;
16216f79bb2dSEnrico Granata                 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
16226f79bb2dSEnrico Granata                 if (!docstring.empty())
1623bfb75e9bSEnrico Granata                     SetHelpLong(docstring.c_str());
16246f79bb2dSEnrico Granata             }
16256f79bb2dSEnrico Granata         }
16269fe00e52SEnrico Granata         return CommandObjectRaw::GetHelpLong();
16279fe00e52SEnrico Granata     }
16289fe00e52SEnrico Granata 
16299fe00e52SEnrico Granata protected:
163013d21e9aSBruce Mitchener     bool
163113d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
16329fe00e52SEnrico Granata     {
16339fe00e52SEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
16349fe00e52SEnrico Granata 
16359fe00e52SEnrico Granata         Error error;
16369fe00e52SEnrico Granata 
16379fe00e52SEnrico Granata         result.SetStatus(eReturnStatusInvalid);
16389fe00e52SEnrico Granata 
16396e3d8e7fSEugene Zelenko         if (!scripter || !scripter->RunScriptBasedCommand(m_cmd_obj_sp,
16409fe00e52SEnrico Granata                                                           raw_command_line,
16419fe00e52SEnrico Granata                                                           m_synchro,
16429fe00e52SEnrico Granata                                                           result,
16439fe00e52SEnrico Granata                                                           error,
16446e3d8e7fSEugene Zelenko                                                           m_exe_ctx))
16459fe00e52SEnrico Granata         {
16469fe00e52SEnrico Granata             result.AppendError(error.AsCString());
16479fe00e52SEnrico Granata             result.SetStatus(eReturnStatusFailed);
16489fe00e52SEnrico Granata         }
16499fe00e52SEnrico Granata         else
16509fe00e52SEnrico Granata         {
16519fe00e52SEnrico Granata             // Don't change the status if the command already set it...
16529fe00e52SEnrico Granata             if (result.GetStatus() == eReturnStatusInvalid)
16539fe00e52SEnrico Granata             {
16546e3d8e7fSEugene Zelenko                 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
16559fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
16569fe00e52SEnrico Granata                 else
16579fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishResult);
16589fe00e52SEnrico Granata             }
16599fe00e52SEnrico Granata         }
16609fe00e52SEnrico Granata 
16619fe00e52SEnrico Granata         return result.Succeeded();
16629fe00e52SEnrico Granata     }
16639fe00e52SEnrico Granata 
16646e3d8e7fSEugene Zelenko private:
16656e3d8e7fSEugene Zelenko     StructuredData::GenericSP m_cmd_obj_sp;
16666e3d8e7fSEugene Zelenko     ScriptedCommandSynchronicity m_synchro;
16676e3d8e7fSEugene Zelenko     bool m_fetched_help_short: 1;
16686e3d8e7fSEugene Zelenko     bool m_fetched_help_long: 1;
16699fe00e52SEnrico Granata };
16709fe00e52SEnrico Granata 
1671a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1672a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport
1673a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1674a9dbf432SEnrico Granata 
16755a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed
1676a9dbf432SEnrico Granata {
16775a988416SJim Ingham public:
16785a988416SJim Ingham     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
16795a988416SJim Ingham         CommandObjectParsed(interpreter,
16805a988416SJim Ingham                             "command script import",
16815a988416SJim Ingham                             "Import a scripting module in LLDB.",
16826e3d8e7fSEugene Zelenko                             nullptr),
1683*e1cfbc79STodd Fiala         m_options()
16845a988416SJim Ingham     {
16855a988416SJim Ingham         CommandArgumentEntry arg1;
16865a988416SJim Ingham         CommandArgumentData cmd_arg;
16875a988416SJim Ingham 
16885a988416SJim Ingham         // Define the first (and only) variant of this arg.
16895a988416SJim Ingham         cmd_arg.arg_type = eArgTypeFilename;
16903b00e35bSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlus;
16915a988416SJim Ingham 
16925a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
16935a988416SJim Ingham         arg1.push_back (cmd_arg);
16945a988416SJim Ingham 
16955a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
16965a988416SJim Ingham         m_arguments.push_back (arg1);
16975a988416SJim Ingham     }
16985a988416SJim Ingham 
16996e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptImport() override = default;
17005a988416SJim Ingham 
170113d21e9aSBruce Mitchener     int
17025a988416SJim Ingham     HandleArgumentCompletion (Args &input,
17035a988416SJim Ingham                               int &cursor_index,
17045a988416SJim Ingham                               int &cursor_char_position,
17055a988416SJim Ingham                               OptionElementVector &opt_element_vector,
17065a988416SJim Ingham                               int match_start_point,
17075a988416SJim Ingham                               int max_return_elements,
17085a988416SJim Ingham                               bool &word_complete,
170913d21e9aSBruce Mitchener                               StringList &matches) override
17105a988416SJim Ingham     {
17115a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
17125a988416SJim Ingham         completion_str.erase (cursor_char_position);
17135a988416SJim Ingham 
1714*e1cfbc79STodd Fiala         CommandCompletions::InvokeCommonCompletionCallbacks(GetCommandInterpreter(),
17155a988416SJim Ingham                                                             CommandCompletions::eDiskFileCompletion,
17165a988416SJim Ingham                                                             completion_str.c_str(),
17175a988416SJim Ingham                                                             match_start_point,
17185a988416SJim Ingham                                                             max_return_elements,
17196e3d8e7fSEugene Zelenko                                                             nullptr,
17205a988416SJim Ingham                                                             word_complete,
17215a988416SJim Ingham                                                             matches);
17225a988416SJim Ingham         return matches.GetSize();
17235a988416SJim Ingham     }
17245a988416SJim Ingham 
172513d21e9aSBruce Mitchener     Options *
172613d21e9aSBruce Mitchener     GetOptions () override
17275a988416SJim Ingham     {
17285a988416SJim Ingham         return &m_options;
17295a988416SJim Ingham     }
17305a988416SJim Ingham 
17315a988416SJim Ingham protected:
17320a305db7SEnrico Granata     class CommandOptions : public Options
17330a305db7SEnrico Granata     {
17340a305db7SEnrico Granata     public:
1735*e1cfbc79STodd Fiala         CommandOptions() :
1736*e1cfbc79STodd Fiala             Options()
17370a305db7SEnrico Granata         {
17380a305db7SEnrico Granata         }
17390a305db7SEnrico Granata 
17406e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
17410a305db7SEnrico Granata 
174213d21e9aSBruce Mitchener         Error
1743*e1cfbc79STodd Fiala         SetOptionValue (uint32_t option_idx, const char *option_arg,
1744*e1cfbc79STodd Fiala                         ExecutionContext *execution_context) override
17450a305db7SEnrico Granata         {
17460a305db7SEnrico Granata             Error error;
17473bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
17480a305db7SEnrico Granata 
17490a305db7SEnrico Granata             switch (short_option)
17500a305db7SEnrico Granata             {
17510a305db7SEnrico Granata                 case 'r':
17520a305db7SEnrico Granata                     m_allow_reload = true;
17530a305db7SEnrico Granata                     break;
17540a305db7SEnrico Granata                 default:
17550a305db7SEnrico Granata                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
17560a305db7SEnrico Granata                     break;
17570a305db7SEnrico Granata             }
17580a305db7SEnrico Granata 
17590a305db7SEnrico Granata             return error;
17600a305db7SEnrico Granata         }
17610a305db7SEnrico Granata 
17620a305db7SEnrico Granata         void
1763*e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
17640a305db7SEnrico Granata         {
1765e0c70f1bSEnrico Granata             m_allow_reload = true;
17660a305db7SEnrico Granata         }
17670a305db7SEnrico Granata 
17680a305db7SEnrico Granata         const OptionDefinition*
176913d21e9aSBruce Mitchener         GetDefinitions () override
17700a305db7SEnrico Granata         {
17710a305db7SEnrico Granata             return g_option_table;
17720a305db7SEnrico Granata         }
17730a305db7SEnrico Granata 
17740a305db7SEnrico Granata         // Options table: Required for subclasses of Options.
17750a305db7SEnrico Granata 
17760a305db7SEnrico Granata         static OptionDefinition g_option_table[];
17770a305db7SEnrico Granata 
17780a305db7SEnrico Granata         // Instance variables to hold the values for command options.
17790a305db7SEnrico Granata 
17800a305db7SEnrico Granata         bool m_allow_reload;
17810a305db7SEnrico Granata     };
17820a305db7SEnrico Granata 
1783a9dbf432SEnrico Granata     bool
178413d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
1785a9dbf432SEnrico Granata     {
1786a9dbf432SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1787a9dbf432SEnrico Granata         {
1788a9dbf432SEnrico Granata             result.AppendError ("only scripting language supported for module importing is currently Python");
1789a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1790a9dbf432SEnrico Granata             return false;
1791a9dbf432SEnrico Granata         }
1792a9dbf432SEnrico Granata 
17935a988416SJim Ingham         size_t argc = command.GetArgumentCount();
17943b00e35bSEnrico Granata         if (0 == argc)
1795a9dbf432SEnrico Granata         {
17963b00e35bSEnrico Granata             result.AppendError("command script import needs one or more arguments");
1797a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1798a9dbf432SEnrico Granata             return false;
1799a9dbf432SEnrico Granata         }
1800a9dbf432SEnrico Granata 
18010e978481SEd Maste         for (size_t i = 0;
18023b00e35bSEnrico Granata              i < argc;
18033b00e35bSEnrico Granata              i++)
18043b00e35bSEnrico Granata         {
18053b00e35bSEnrico Granata             std::string path = command.GetArgumentAtIndex(i);
1806a9dbf432SEnrico Granata             Error error;
1807a9dbf432SEnrico Granata 
1808c9d645d3SGreg Clayton             const bool init_session = true;
1809078551c7SEnrico Granata             // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1810078551c7SEnrico Granata             // commands won't ever be recursively invoked, but it's actually possible to craft
1811078551c7SEnrico Granata             // a Python script that does other "command script imports" in __lldb_init_module
1812078551c7SEnrico Granata             // the real fix is to have recursive commands possible with a CommandInvocation object
1813078551c7SEnrico Granata             // separate from the CommandObject itself, so that recursive command invocations
1814078551c7SEnrico Granata             // won't stomp on each other (wrt to execution contents, options, and more)
1815078551c7SEnrico Granata             m_exe_ctx.Clear();
1816a9dbf432SEnrico Granata             if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
18170a305db7SEnrico Granata                                                                           m_options.m_allow_reload,
1818c9d645d3SGreg Clayton                                                                           init_session,
1819a9dbf432SEnrico Granata                                                                           error))
1820a9dbf432SEnrico Granata             {
1821a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1822a9dbf432SEnrico Granata             }
1823a9dbf432SEnrico Granata             else
1824a9dbf432SEnrico Granata             {
1825a9dbf432SEnrico Granata                 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1826a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1827a9dbf432SEnrico Granata             }
18283b00e35bSEnrico Granata         }
1829a9dbf432SEnrico Granata 
1830a9dbf432SEnrico Granata         return result.Succeeded();
1831a9dbf432SEnrico Granata     }
18320a305db7SEnrico Granata 
18335a988416SJim Ingham     CommandOptions m_options;
1834a9dbf432SEnrico Granata };
1835223383edSEnrico Granata 
18360a305db7SEnrico Granata OptionDefinition
18370a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
18380a305db7SEnrico Granata {
18396e3d8e7fSEugene 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."},
18406e3d8e7fSEugene Zelenko     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
18410a305db7SEnrico Granata };
18420a305db7SEnrico Granata 
1843223383edSEnrico Granata //-------------------------------------------------------------------------
1844223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1845223383edSEnrico Granata //-------------------------------------------------------------------------
1846223383edSEnrico Granata 
184744d93782SGreg Clayton class CommandObjectCommandsScriptAdd :
184844d93782SGreg Clayton     public CommandObjectParsed,
184944d93782SGreg Clayton     public IOHandlerDelegateMultiline
1850223383edSEnrico Granata {
18515a988416SJim Ingham public:
18525a988416SJim Ingham     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
18535a988416SJim Ingham         CommandObjectParsed(interpreter,
18545a988416SJim Ingham                             "command script add",
18555a988416SJim Ingham                             "Add a scripted function as an LLDB command.",
18566e3d8e7fSEugene Zelenko                             nullptr),
1857c3d874a5SGreg Clayton         IOHandlerDelegateMultiline ("DONE"),
1858*e1cfbc79STodd Fiala         m_options()
18595a988416SJim Ingham     {
18605a988416SJim Ingham         CommandArgumentEntry arg1;
18615a988416SJim Ingham         CommandArgumentData cmd_arg;
18625a988416SJim Ingham 
18635a988416SJim Ingham         // Define the first (and only) variant of this arg.
18645a988416SJim Ingham         cmd_arg.arg_type = eArgTypeCommandName;
18655a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
18665a988416SJim Ingham 
18675a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
18685a988416SJim Ingham         arg1.push_back (cmd_arg);
18695a988416SJim Ingham 
18705a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
18715a988416SJim Ingham         m_arguments.push_back (arg1);
18725a988416SJim Ingham     }
18735a988416SJim Ingham 
18746e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptAdd() override = default;
18755a988416SJim Ingham 
187613d21e9aSBruce Mitchener     Options *
187713d21e9aSBruce Mitchener     GetOptions () override
18785a988416SJim Ingham     {
18795a988416SJim Ingham         return &m_options;
18805a988416SJim Ingham     }
18815a988416SJim Ingham 
18825a988416SJim Ingham protected:
1883223383edSEnrico Granata     class CommandOptions : public Options
1884223383edSEnrico Granata     {
1885223383edSEnrico Granata     public:
1886*e1cfbc79STodd Fiala         CommandOptions() :
1887*e1cfbc79STodd Fiala             Options(),
18889fe00e52SEnrico Granata             m_class_name(),
18899fe00e52SEnrico Granata             m_funct_name(),
18909fe00e52SEnrico Granata             m_short_help(),
18919fe00e52SEnrico Granata             m_synchronicity(eScriptedCommandSynchronicitySynchronous)
1892223383edSEnrico Granata         {
1893223383edSEnrico Granata         }
1894223383edSEnrico Granata 
18956e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
1896223383edSEnrico Granata 
189713d21e9aSBruce Mitchener         Error
1898*e1cfbc79STodd Fiala         SetOptionValue (uint32_t option_idx, const char *option_arg,
1899*e1cfbc79STodd Fiala                         ExecutionContext *execution_context) override
1900223383edSEnrico Granata         {
1901223383edSEnrico Granata             Error error;
19023bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
1903223383edSEnrico Granata 
1904223383edSEnrico Granata             switch (short_option)
1905223383edSEnrico Granata             {
1906223383edSEnrico Granata                 case 'f':
1907735152e3SEnrico Granata                     if (option_arg)
1908735152e3SEnrico Granata                         m_funct_name.assign(option_arg);
1909735152e3SEnrico Granata                     break;
19109fe00e52SEnrico Granata                 case 'c':
19119fe00e52SEnrico Granata                     if (option_arg)
19129fe00e52SEnrico Granata                         m_class_name.assign(option_arg);
19139fe00e52SEnrico Granata                     break;
1914735152e3SEnrico Granata                 case 'h':
1915735152e3SEnrico Granata                     if (option_arg)
1916735152e3SEnrico Granata                         m_short_help.assign(option_arg);
1917223383edSEnrico Granata                     break;
19180a305db7SEnrico Granata                 case 's':
191944d93782SGreg Clayton                     m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
19200a305db7SEnrico Granata                     if (!error.Success())
19210a305db7SEnrico Granata                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
19220a305db7SEnrico Granata                     break;
1923223383edSEnrico Granata                 default:
192486edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1925223383edSEnrico Granata                     break;
1926223383edSEnrico Granata             }
1927223383edSEnrico Granata 
1928223383edSEnrico Granata             return error;
1929223383edSEnrico Granata         }
1930223383edSEnrico Granata 
1931223383edSEnrico Granata         void
1932*e1cfbc79STodd Fiala         OptionParsingStarting(ExecutionContext *execution_context) override
1933223383edSEnrico Granata         {
19349fe00e52SEnrico Granata             m_class_name.clear();
1935735152e3SEnrico Granata             m_funct_name.clear();
1936735152e3SEnrico Granata             m_short_help.clear();
193744d93782SGreg Clayton             m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1938223383edSEnrico Granata         }
1939223383edSEnrico Granata 
1940223383edSEnrico Granata         const OptionDefinition*
194113d21e9aSBruce Mitchener         GetDefinitions () override
1942223383edSEnrico Granata         {
1943223383edSEnrico Granata             return g_option_table;
1944223383edSEnrico Granata         }
1945223383edSEnrico Granata 
1946223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1947223383edSEnrico Granata 
1948223383edSEnrico Granata         static OptionDefinition g_option_table[];
1949223383edSEnrico Granata 
1950223383edSEnrico Granata         // Instance variables to hold the values for command options.
1951223383edSEnrico Granata 
19529fe00e52SEnrico Granata         std::string m_class_name;
1953223383edSEnrico Granata         std::string m_funct_name;
1954735152e3SEnrico Granata         std::string m_short_help;
195544d93782SGreg Clayton         ScriptedCommandSynchronicity m_synchronicity;
1956223383edSEnrico Granata     };
1957223383edSEnrico Granata 
195813d21e9aSBruce Mitchener     void
195913d21e9aSBruce Mitchener     IOHandlerActivated (IOHandler &io_handler) override
1960223383edSEnrico Granata     {
196144d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
196244d93782SGreg Clayton         if (output_sp)
1963223383edSEnrico Granata         {
196444d93782SGreg Clayton             output_sp->PutCString(g_python_command_instructions);
196544d93782SGreg Clayton             output_sp->Flush();
1966223383edSEnrico Granata         }
1967223383edSEnrico Granata     }
1968223383edSEnrico Granata 
1969223383edSEnrico Granata 
197013d21e9aSBruce Mitchener     void
197113d21e9aSBruce Mitchener     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
1972223383edSEnrico Granata     {
197344d93782SGreg Clayton         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
197444d93782SGreg Clayton 
197544d93782SGreg Clayton         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
197644d93782SGreg Clayton         if (interpreter)
197744d93782SGreg Clayton         {
197844d93782SGreg Clayton 
197944d93782SGreg Clayton             StringList lines;
198044d93782SGreg Clayton             lines.SplitIntoLines(data);
198144d93782SGreg Clayton             if (lines.GetSize() > 0)
198244d93782SGreg Clayton             {
1983a73b7df7SEnrico Granata                 std::string funct_name_str;
198444d93782SGreg Clayton                 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1985223383edSEnrico Granata                 {
1986a73b7df7SEnrico Granata                     if (funct_name_str.empty())
1987223383edSEnrico Granata                     {
198844d93782SGreg Clayton                         error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
198944d93782SGreg Clayton                         error_sp->Flush();
1990223383edSEnrico Granata                     }
199144d93782SGreg Clayton                     else
199244d93782SGreg Clayton                     {
1993223383edSEnrico Granata                         // everything should be fine now, let's add this alias
1994223383edSEnrico Granata 
1995223383edSEnrico Granata                         CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1996223383edSEnrico Granata                                                                                         m_cmd_name,
1997a73b7df7SEnrico Granata                                                                                         funct_name_str.c_str(),
1998735152e3SEnrico Granata                                                                                         m_short_help,
199944d93782SGreg Clayton                                                                                         m_synchronicity));
2000223383edSEnrico Granata 
20010a305db7SEnrico Granata                         if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
2002223383edSEnrico Granata                         {
200344d93782SGreg Clayton                             error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
200444d93782SGreg Clayton                             error_sp->Flush();
2005223383edSEnrico Granata                         }
2006223383edSEnrico Granata                     }
200744d93782SGreg Clayton                 }
200844d93782SGreg Clayton                 else
200944d93782SGreg Clayton                 {
201044d93782SGreg Clayton                     error_sp->Printf ("error: unable to create function, didn't add python command.\n");
201144d93782SGreg Clayton                     error_sp->Flush();
201244d93782SGreg Clayton                 }
201344d93782SGreg Clayton             }
201444d93782SGreg Clayton             else
201544d93782SGreg Clayton             {
201644d93782SGreg Clayton                 error_sp->Printf ("error: empty function, didn't add python command.\n");
201744d93782SGreg Clayton                 error_sp->Flush();
201844d93782SGreg Clayton             }
201944d93782SGreg Clayton         }
202044d93782SGreg Clayton         else
202144d93782SGreg Clayton         {
202244d93782SGreg Clayton             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
202344d93782SGreg Clayton             error_sp->Flush();
202444d93782SGreg Clayton         }
202544d93782SGreg Clayton 
202644d93782SGreg Clayton         io_handler.SetIsDone(true);
202744d93782SGreg Clayton     }
2028223383edSEnrico Granata 
20295a988416SJim Ingham protected:
2030223383edSEnrico Granata     bool
203113d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2032223383edSEnrico Granata     {
203399f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
203499f0b8f9SEnrico Granata         {
203599f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
203699f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
203799f0b8f9SEnrico Granata             return false;
203899f0b8f9SEnrico Granata         }
203999f0b8f9SEnrico Granata 
20405a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2041223383edSEnrico Granata 
2042223383edSEnrico Granata         if (argc != 1)
2043223383edSEnrico Granata         {
2044223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
2045223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2046223383edSEnrico Granata             return false;
2047223383edSEnrico Granata         }
2048223383edSEnrico Granata 
2049735152e3SEnrico Granata         // Store the options in case we get multi-line input
205044d93782SGreg Clayton         m_cmd_name = command.GetArgumentAtIndex(0);
2051735152e3SEnrico Granata         m_short_help.assign(m_options.m_short_help);
205244d93782SGreg Clayton         m_synchronicity = m_options.m_synchronicity;
2053223383edSEnrico Granata 
20549fe00e52SEnrico Granata         if (m_options.m_class_name.empty())
20559fe00e52SEnrico Granata         {
2056223383edSEnrico Granata             if (m_options.m_funct_name.empty())
2057223383edSEnrico Granata             {
205844d93782SGreg Clayton                 m_interpreter.GetPythonCommandsFromIOHandler("     ",  // Prompt
205944d93782SGreg Clayton                                                              *this,    // IOHandlerDelegate
206044d93782SGreg Clayton                                                              true,     // Run IOHandler in async mode
20616e3d8e7fSEugene Zelenko                                                              nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
2062223383edSEnrico Granata             }
2063223383edSEnrico Granata             else
2064223383edSEnrico Granata             {
20650a305db7SEnrico Granata                 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
206644d93782SGreg Clayton                                                                         m_cmd_name,
20670a305db7SEnrico Granata                                                                         m_options.m_funct_name,
2068735152e3SEnrico Granata                                                                         m_options.m_short_help,
206944d93782SGreg Clayton                                                                         m_synchronicity));
207044d93782SGreg Clayton                 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
2071223383edSEnrico Granata                 {
2072223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
2073223383edSEnrico Granata                 }
2074223383edSEnrico Granata                 else
2075223383edSEnrico Granata                 {
2076223383edSEnrico Granata                     result.AppendError("cannot add command");
2077223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
2078223383edSEnrico Granata                 }
2079223383edSEnrico Granata             }
20809fe00e52SEnrico Granata         }
20819fe00e52SEnrico Granata         else
20829fe00e52SEnrico Granata         {
20839fe00e52SEnrico Granata             ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
20849fe00e52SEnrico Granata             if (!interpreter)
20859fe00e52SEnrico Granata             {
20869fe00e52SEnrico Granata                 result.AppendError("cannot find ScriptInterpreter");
20879fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
20889fe00e52SEnrico Granata                 return false;
20899fe00e52SEnrico Granata             }
20909fe00e52SEnrico Granata 
20919fe00e52SEnrico Granata             auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
20929fe00e52SEnrico Granata             if (!cmd_obj_sp)
20939fe00e52SEnrico Granata             {
20949fe00e52SEnrico Granata                 result.AppendError("cannot create helper object");
20959fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
20969fe00e52SEnrico Granata                 return false;
20979fe00e52SEnrico Granata             }
20989fe00e52SEnrico Granata 
20999fe00e52SEnrico Granata             CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
21009fe00e52SEnrico Granata                                                                      m_cmd_name,
21019fe00e52SEnrico Granata                                                                      cmd_obj_sp,
21029fe00e52SEnrico Granata                                                                      m_synchronicity));
21039fe00e52SEnrico Granata             if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
21049fe00e52SEnrico Granata             {
21059fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
21069fe00e52SEnrico Granata             }
21079fe00e52SEnrico Granata             else
21089fe00e52SEnrico Granata             {
21099fe00e52SEnrico Granata                 result.AppendError("cannot add command");
21109fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
21119fe00e52SEnrico Granata             }
21129fe00e52SEnrico Granata         }
2113223383edSEnrico Granata 
2114223383edSEnrico Granata         return result.Succeeded();
2115223383edSEnrico Granata     }
21165a988416SJim Ingham 
21175a988416SJim Ingham     CommandOptions m_options;
211844d93782SGreg Clayton     std::string m_cmd_name;
2119735152e3SEnrico Granata     std::string m_short_help;
212044d93782SGreg Clayton     ScriptedCommandSynchronicity m_synchronicity;
2121223383edSEnrico Granata };
2122223383edSEnrico Granata 
21230a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] =
21240a305db7SEnrico Granata {
21250a305db7SEnrico Granata     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
21260a305db7SEnrico Granata     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
21270a305db7SEnrico Granata     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
21286e3d8e7fSEugene Zelenko     { 0, nullptr, nullptr }
21290a305db7SEnrico Granata };
21300a305db7SEnrico Granata 
2131223383edSEnrico Granata OptionDefinition
2132223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2133223383edSEnrico Granata {
21346e3d8e7fSEugene 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."},
21356e3d8e7fSEugene 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."},
21366e3d8e7fSEugene Zelenko     { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command."},
21376e3d8e7fSEugene 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."},
21386e3d8e7fSEugene Zelenko     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
2139223383edSEnrico Granata };
2140223383edSEnrico Granata 
2141223383edSEnrico Granata //-------------------------------------------------------------------------
2142223383edSEnrico Granata // CommandObjectCommandsScriptList
2143223383edSEnrico Granata //-------------------------------------------------------------------------
2144223383edSEnrico Granata 
21455a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed
2146223383edSEnrico Granata {
2147223383edSEnrico Granata public:
2148223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
21495a988416SJim Ingham         CommandObjectParsed(interpreter,
2150223383edSEnrico Granata                             "command script list",
2151223383edSEnrico Granata                             "List defined scripted commands.",
21526e3d8e7fSEugene Zelenko                             nullptr)
2153223383edSEnrico Granata     {
2154223383edSEnrico Granata     }
2155223383edSEnrico Granata 
21566e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptList() override = default;
2157223383edSEnrico Granata 
2158223383edSEnrico Granata     bool
215913d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2160223383edSEnrico Granata     {
2161223383edSEnrico Granata         m_interpreter.GetHelp(result,
2162223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
2163223383edSEnrico Granata 
2164223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2165223383edSEnrico Granata 
2166223383edSEnrico Granata         return true;
2167223383edSEnrico Granata     }
2168223383edSEnrico Granata };
2169223383edSEnrico Granata 
2170223383edSEnrico Granata //-------------------------------------------------------------------------
2171223383edSEnrico Granata // CommandObjectCommandsScriptClear
2172223383edSEnrico Granata //-------------------------------------------------------------------------
2173223383edSEnrico Granata 
21745a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed
2175223383edSEnrico Granata {
2176223383edSEnrico Granata public:
2177223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
21785a988416SJim Ingham         CommandObjectParsed(interpreter,
2179223383edSEnrico Granata                             "command script clear",
2180223383edSEnrico Granata                             "Delete all scripted commands.",
21816e3d8e7fSEugene Zelenko                             nullptr)
2182223383edSEnrico Granata     {
2183223383edSEnrico Granata     }
2184223383edSEnrico Granata 
21856e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptClear() override = default;
2186223383edSEnrico Granata 
21875a988416SJim Ingham protected:
2188223383edSEnrico Granata     bool
218913d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2190223383edSEnrico Granata     {
2191223383edSEnrico Granata         m_interpreter.RemoveAllUser();
2192223383edSEnrico Granata 
2193223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2194223383edSEnrico Granata 
2195223383edSEnrico Granata         return true;
2196223383edSEnrico Granata     }
2197223383edSEnrico Granata };
2198223383edSEnrico Granata 
2199223383edSEnrico Granata //-------------------------------------------------------------------------
2200223383edSEnrico Granata // CommandObjectCommandsScriptDelete
2201223383edSEnrico Granata //-------------------------------------------------------------------------
2202223383edSEnrico Granata 
22035a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed
2204223383edSEnrico Granata {
2205223383edSEnrico Granata public:
2206223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
22075a988416SJim Ingham         CommandObjectParsed(interpreter,
2208223383edSEnrico Granata                             "command script delete",
2209223383edSEnrico Granata                             "Delete a scripted command.",
22106e3d8e7fSEugene Zelenko                             nullptr)
2211223383edSEnrico Granata     {
2212223383edSEnrico Granata         CommandArgumentEntry arg1;
2213223383edSEnrico Granata         CommandArgumentData cmd_arg;
2214223383edSEnrico Granata 
2215223383edSEnrico Granata         // Define the first (and only) variant of this arg.
2216223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
2217223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
2218223383edSEnrico Granata 
2219223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
2220223383edSEnrico Granata         arg1.push_back (cmd_arg);
2221223383edSEnrico Granata 
2222223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
2223223383edSEnrico Granata         m_arguments.push_back (arg1);
2224223383edSEnrico Granata     }
2225223383edSEnrico Granata 
22266e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptDelete() override = default;
2227223383edSEnrico Granata 
22285a988416SJim Ingham protected:
2229223383edSEnrico Granata     bool
223013d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2231223383edSEnrico Granata     {
2232223383edSEnrico Granata 
22335a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2234223383edSEnrico Granata 
2235223383edSEnrico Granata         if (argc != 1)
2236223383edSEnrico Granata         {
2237223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
2238223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2239223383edSEnrico Granata             return false;
2240223383edSEnrico Granata         }
2241223383edSEnrico Granata 
22425a988416SJim Ingham         const char* cmd_name = command.GetArgumentAtIndex(0);
2243223383edSEnrico Granata 
2244223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2245223383edSEnrico Granata         {
2246223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
2247223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
2248223383edSEnrico Granata         }
2249223383edSEnrico Granata         else
2250223383edSEnrico Granata         {
2251223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
2252223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2253223383edSEnrico Granata         }
2254223383edSEnrico Granata 
2255223383edSEnrico Granata         return result.Succeeded();
2256223383edSEnrico Granata     }
2257223383edSEnrico Granata };
2258223383edSEnrico Granata 
2259223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
2260223383edSEnrico Granata 
2261223383edSEnrico Granata //-------------------------------------------------------------------------
2262223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
2263223383edSEnrico Granata //-------------------------------------------------------------------------
2264223383edSEnrico Granata 
2265223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2266223383edSEnrico Granata {
2267223383edSEnrico Granata public:
22687428a18cSKate Stone     CommandObjectMultiwordCommandsScript(CommandInterpreter &interpreter)
22697428a18cSKate Stone         : CommandObjectMultiword(interpreter, "command script",
22707428a18cSKate Stone                                  "Commands for managing custom commands implemented by interpreter scripts.",
2271223383edSEnrico Granata                                  "command script <subcommand> [<subcommand-options>]")
2272223383edSEnrico Granata     {
2273223383edSEnrico Granata         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2274223383edSEnrico Granata         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2275223383edSEnrico Granata         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
2276223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
2277a9dbf432SEnrico Granata         LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
2278223383edSEnrico Granata     }
2279223383edSEnrico Granata 
22806e3d8e7fSEugene Zelenko     ~CommandObjectMultiwordCommandsScript() override = default;
2281223383edSEnrico Granata };
2282223383edSEnrico Granata 
2283ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
2284ebc09c36SJim Ingham 
2285ebc09c36SJim Ingham //-------------------------------------------------------------------------
2286ebc09c36SJim Ingham // CommandObjectMultiwordCommands
2287ebc09c36SJim Ingham //-------------------------------------------------------------------------
2288ebc09c36SJim Ingham 
22897428a18cSKate Stone CommandObjectMultiwordCommands::CommandObjectMultiwordCommands(CommandInterpreter &interpreter)
22907428a18cSKate Stone     : CommandObjectMultiword(interpreter, "command", "Commands for managing custom LLDB commands.",
22910e5e5a79SGreg Clayton                              "command <subcommand> [<subcommand-options>]")
2292ebc09c36SJim Ingham {
2293a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2294a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2295a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
2296b547278cSGreg Clayton     LoadSubCommand ("delete",  CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
2297de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
2298a5a97ebeSJim Ingham     LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2299223383edSEnrico Granata     LoadSubCommand ("script",  CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
2300ebc09c36SJim Ingham }
2301ebc09c36SJim Ingham 
23026e3d8e7fSEugene Zelenko CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands() = default;
2303