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"
27*45d0e238SEnrico Granata #include "lldb/Interpreter/OptionValueString.h"
287594f14fSEnrico Granata #include "lldb/Interpreter/OptionValueUInt64.h"
29ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
3099f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h"
31ebc09c36SJim Ingham 
32ebc09c36SJim Ingham using namespace lldb;
33ebc09c36SJim Ingham using namespace lldb_private;
34ebc09c36SJim Ingham 
35ebc09c36SJim Ingham //-------------------------------------------------------------------------
36ebc09c36SJim Ingham // CommandObjectCommandsSource
37ebc09c36SJim Ingham //-------------------------------------------------------------------------
38ebc09c36SJim Ingham 
395a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed
40a5a97ebeSJim Ingham {
415a988416SJim Ingham public:
425a988416SJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
435a988416SJim Ingham         CommandObjectParsed(interpreter,
445a988416SJim Ingham                             "command history",
455a988416SJim Ingham                             "Dump the history of commands in this session.",
466e3d8e7fSEugene Zelenko                             nullptr),
475a988416SJim Ingham         m_options (interpreter)
485a988416SJim Ingham     {
495a988416SJim Ingham     }
505a988416SJim Ingham 
516e3d8e7fSEugene Zelenko     ~CommandObjectCommandsHistory() override = default;
525a988416SJim Ingham 
5313d21e9aSBruce Mitchener     Options *
5413d21e9aSBruce Mitchener     GetOptions () override
555a988416SJim Ingham     {
565a988416SJim Ingham         return &m_options;
575a988416SJim Ingham     }
585a988416SJim Ingham 
595a988416SJim Ingham protected:
60a5a97ebeSJim Ingham     class CommandOptions : public Options
61a5a97ebeSJim Ingham     {
62a5a97ebeSJim Ingham     public:
63a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
647594f14fSEnrico Granata             Options (interpreter),
657594f14fSEnrico Granata             m_start_idx(0),
667594f14fSEnrico Granata             m_stop_idx(0),
677594f14fSEnrico Granata             m_count(0),
6863123b64SEnrico Granata             m_clear(false)
69a5a97ebeSJim Ingham         {
70a5a97ebeSJim Ingham         }
71a5a97ebeSJim Ingham 
726e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
73a5a97ebeSJim Ingham 
7413d21e9aSBruce Mitchener         Error
7513d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
76a5a97ebeSJim Ingham         {
77a5a97ebeSJim Ingham             Error error;
783bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
79a5a97ebeSJim Ingham 
80a5a97ebeSJim Ingham             switch (short_option)
81a5a97ebeSJim Ingham             {
82a5a97ebeSJim Ingham                 case 'c':
83c95f7e2aSPavel Labath                     error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign);
84a5a97ebeSJim Ingham                     break;
85a5a97ebeSJim Ingham                 case 's':
867594f14fSEnrico Granata                     if (option_arg && strcmp("end", option_arg) == 0)
877594f14fSEnrico Granata                     {
887594f14fSEnrico Granata                         m_start_idx.SetCurrentValue(UINT64_MAX);
897594f14fSEnrico Granata                         m_start_idx.SetOptionWasSet();
907594f14fSEnrico Granata                     }
917594f14fSEnrico Granata                     else
92c95f7e2aSPavel Labath                         error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
937594f14fSEnrico Granata                     break;
947594f14fSEnrico Granata                 case 'e':
95c95f7e2aSPavel Labath                     error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign);
967594f14fSEnrico Granata                     break;
9763123b64SEnrico Granata                 case 'C':
9863123b64SEnrico Granata                     m_clear.SetCurrentValue(true);
9963123b64SEnrico Granata                     m_clear.SetOptionWasSet();
100a5a97ebeSJim Ingham                     break;
101a5a97ebeSJim Ingham                 default:
10286edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
103a5a97ebeSJim Ingham                     break;
104a5a97ebeSJim Ingham             }
105a5a97ebeSJim Ingham 
106a5a97ebeSJim Ingham             return error;
107a5a97ebeSJim Ingham         }
108a5a97ebeSJim Ingham 
109a5a97ebeSJim Ingham         void
11013d21e9aSBruce Mitchener         OptionParsingStarting () override
111a5a97ebeSJim Ingham         {
1127594f14fSEnrico Granata             m_start_idx.Clear();
1137594f14fSEnrico Granata             m_stop_idx.Clear();
1147594f14fSEnrico Granata             m_count.Clear();
11563123b64SEnrico Granata             m_clear.Clear();
116a5a97ebeSJim Ingham         }
117a5a97ebeSJim Ingham 
118a5a97ebeSJim Ingham         const OptionDefinition*
11913d21e9aSBruce Mitchener         GetDefinitions () override
120a5a97ebeSJim Ingham         {
121a5a97ebeSJim Ingham             return g_option_table;
122a5a97ebeSJim Ingham         }
123a5a97ebeSJim Ingham 
124a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
125a5a97ebeSJim Ingham 
126a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
127a5a97ebeSJim Ingham 
128a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
129a5a97ebeSJim Ingham 
1307594f14fSEnrico Granata         OptionValueUInt64 m_start_idx;
1317594f14fSEnrico Granata         OptionValueUInt64 m_stop_idx;
1327594f14fSEnrico Granata         OptionValueUInt64 m_count;
13363123b64SEnrico Granata         OptionValueBoolean m_clear;
134a5a97ebeSJim Ingham     };
135a5a97ebeSJim Ingham 
136a5a97ebeSJim Ingham     bool
13713d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
138a5a97ebeSJim Ingham     {
13963123b64SEnrico Granata         if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet())
1407594f14fSEnrico Granata         {
1417594f14fSEnrico Granata             m_interpreter.GetCommandHistory().Clear();
1427594f14fSEnrico Granata             result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
1437594f14fSEnrico Granata         }
1447594f14fSEnrico Granata         else
1457594f14fSEnrico Granata         {
1467594f14fSEnrico Granata             if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet())
1477594f14fSEnrico Granata             {
1487594f14fSEnrico Granata                 result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation");
1497594f14fSEnrico Granata                 result.SetStatus(lldb::eReturnStatusFailed);
1507594f14fSEnrico Granata             }
1517594f14fSEnrico Granata             else
1527594f14fSEnrico Granata             {
15384400ec7SVirgile Bello                 std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue());
15484400ec7SVirgile Bello                 std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue());
15584400ec7SVirgile Bello                 std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue());
156a5a97ebeSJim Ingham 
1577594f14fSEnrico Granata                 const CommandHistory& history(m_interpreter.GetCommandHistory());
1587594f14fSEnrico Granata 
1597594f14fSEnrico Granata                 if (start_idx.first && start_idx.second == UINT64_MAX)
1607594f14fSEnrico Granata                 {
1617594f14fSEnrico Granata                     if (count.first)
1627594f14fSEnrico Granata                     {
1637594f14fSEnrico Granata                         start_idx.second = history.GetSize() - count.second;
1647594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1657594f14fSEnrico Granata                     }
1667594f14fSEnrico Granata                     else if (stop_idx.first)
1677594f14fSEnrico Granata                     {
1687594f14fSEnrico Granata                         start_idx.second = stop_idx.second;
1697594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1707594f14fSEnrico Granata                     }
1717594f14fSEnrico Granata                     else
1727594f14fSEnrico Granata                     {
1737594f14fSEnrico Granata                         start_idx.second = 0;
1747594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1757594f14fSEnrico Granata                     }
1767594f14fSEnrico Granata                 }
1777594f14fSEnrico Granata                 else
1787594f14fSEnrico Granata                 {
1797594f14fSEnrico Granata                     if (!start_idx.first && !stop_idx.first && !count.first)
1807594f14fSEnrico Granata                     {
1817594f14fSEnrico Granata                         start_idx.second = 0;
1827594f14fSEnrico Granata                         stop_idx.second = history.GetSize() - 1;
1837594f14fSEnrico Granata                     }
1847594f14fSEnrico Granata                     else if (start_idx.first)
1857594f14fSEnrico Granata                     {
1867594f14fSEnrico Granata                         if (count.first)
1877594f14fSEnrico Granata                         {
1887594f14fSEnrico Granata                             stop_idx.second = start_idx.second + count.second - 1;
1897594f14fSEnrico Granata                         }
1907594f14fSEnrico Granata                         else if (!stop_idx.first)
1917594f14fSEnrico Granata                         {
1927594f14fSEnrico Granata                             stop_idx.second = history.GetSize() - 1;
1937594f14fSEnrico Granata                         }
1947594f14fSEnrico Granata                     }
1957594f14fSEnrico Granata                     else if (stop_idx.first)
1967594f14fSEnrico Granata                     {
1977594f14fSEnrico Granata                         if (count.first)
1987594f14fSEnrico Granata                         {
1997594f14fSEnrico Granata                             if (stop_idx.second >= count.second)
2007594f14fSEnrico Granata                                 start_idx.second = stop_idx.second - count.second + 1;
2017594f14fSEnrico Granata                             else
2027594f14fSEnrico Granata                                 start_idx.second = 0;
2037594f14fSEnrico Granata                         }
2047594f14fSEnrico Granata                     }
2057594f14fSEnrico Granata                     else /* if (count.first) */
2067594f14fSEnrico Granata                     {
2077594f14fSEnrico Granata                         start_idx.second = 0;
2087594f14fSEnrico Granata                         stop_idx.second = count.second - 1;
2097594f14fSEnrico Granata                     }
2107594f14fSEnrico Granata                 }
2117594f14fSEnrico Granata                 history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second);
2127594f14fSEnrico Granata             }
2137594f14fSEnrico Granata         }
214a5a97ebeSJim Ingham         return result.Succeeded();
215a5a97ebeSJim Ingham 
216a5a97ebeSJim Ingham     }
2175a988416SJim Ingham 
2185a988416SJim Ingham     CommandOptions m_options;
219a5a97ebeSJim Ingham };
220a5a97ebeSJim Ingham 
221a5a97ebeSJim Ingham OptionDefinition
222a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
223a5a97ebeSJim Ingham {
2246e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
2256e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger,  "Index at which to start printing history commands (or end to mean tail mode)."},
2266e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
2276e3d8e7fSEugene Zelenko { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeBoolean,    "Clears the current command history."},
2286e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
229a5a97ebeSJim Ingham };
230a5a97ebeSJim Ingham 
231a5a97ebeSJim Ingham //-------------------------------------------------------------------------
232a5a97ebeSJim Ingham // CommandObjectCommandsSource
233a5a97ebeSJim Ingham //-------------------------------------------------------------------------
234a5a97ebeSJim Ingham 
2355a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed
236ebc09c36SJim Ingham {
2375a988416SJim Ingham public:
2385a988416SJim Ingham     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
2395a988416SJim Ingham         CommandObjectParsed(interpreter,
2405a988416SJim Ingham                             "command source",
2415a988416SJim Ingham                             "Read in debugger commands from the file <filename> and execute them.",
2426e3d8e7fSEugene Zelenko                             nullptr),
2435a988416SJim Ingham         m_options (interpreter)
2445a988416SJim Ingham     {
2455a988416SJim Ingham         CommandArgumentEntry arg;
2465a988416SJim Ingham         CommandArgumentData file_arg;
2475a988416SJim Ingham 
2485a988416SJim Ingham         // Define the first (and only) variant of this arg.
2495a988416SJim Ingham         file_arg.arg_type = eArgTypeFilename;
2505a988416SJim Ingham         file_arg.arg_repetition = eArgRepeatPlain;
2515a988416SJim Ingham 
2525a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
2535a988416SJim Ingham         arg.push_back (file_arg);
2545a988416SJim Ingham 
2555a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
2565a988416SJim Ingham         m_arguments.push_back (arg);
2575a988416SJim Ingham     }
2585a988416SJim Ingham 
2596e3d8e7fSEugene Zelenko     ~CommandObjectCommandsSource() override = default;
2605a988416SJim Ingham 
26113d21e9aSBruce Mitchener     const char*
26213d21e9aSBruce Mitchener     GetRepeatCommand (Args &current_command_args, uint32_t index) override
2635a988416SJim Ingham     {
2645a988416SJim Ingham         return "";
2655a988416SJim Ingham     }
2665a988416SJim Ingham 
26713d21e9aSBruce Mitchener     int
2685a988416SJim Ingham     HandleArgumentCompletion (Args &input,
2695a988416SJim Ingham                               int &cursor_index,
2705a988416SJim Ingham                               int &cursor_char_position,
2715a988416SJim Ingham                               OptionElementVector &opt_element_vector,
2725a988416SJim Ingham                               int match_start_point,
2735a988416SJim Ingham                               int max_return_elements,
2745a988416SJim Ingham                               bool &word_complete,
27513d21e9aSBruce Mitchener                               StringList &matches) override
2765a988416SJim Ingham     {
2775a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2785a988416SJim Ingham         completion_str.erase (cursor_char_position);
2795a988416SJim Ingham 
2805a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
2815a988416SJim Ingham                                                             CommandCompletions::eDiskFileCompletion,
2825a988416SJim Ingham                                                             completion_str.c_str(),
2835a988416SJim Ingham                                                             match_start_point,
2845a988416SJim Ingham                                                             max_return_elements,
2856e3d8e7fSEugene Zelenko                                                             nullptr,
2865a988416SJim Ingham                                                             word_complete,
2875a988416SJim Ingham                                                             matches);
2885a988416SJim Ingham         return matches.GetSize();
2895a988416SJim Ingham     }
2905a988416SJim Ingham 
29113d21e9aSBruce Mitchener     Options *
29213d21e9aSBruce Mitchener     GetOptions () override
2935a988416SJim Ingham     {
2945a988416SJim Ingham         return &m_options;
2955a988416SJim Ingham     }
2965a988416SJim Ingham 
2975a988416SJim Ingham protected:
298e16c50a1SJim Ingham     class CommandOptions : public Options
299e16c50a1SJim Ingham     {
300e16c50a1SJim Ingham     public:
301eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
302012d4fcaSEnrico Granata             Options (interpreter),
303340b0309SGreg Clayton             m_stop_on_error (true),
304340b0309SGreg Clayton             m_silent_run (false),
305340b0309SGreg Clayton             m_stop_on_continue (true)
306eb0103f2SGreg Clayton         {
307eb0103f2SGreg Clayton         }
308e16c50a1SJim Ingham 
3096e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
310e16c50a1SJim Ingham 
31113d21e9aSBruce Mitchener         Error
31213d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
313e16c50a1SJim Ingham         {
314e16c50a1SJim Ingham             Error error;
3153bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
316e16c50a1SJim Ingham 
317e16c50a1SJim Ingham             switch (short_option)
318e16c50a1SJim Ingham             {
319e16c50a1SJim Ingham                 case 'e':
320c95f7e2aSPavel Labath                     error = m_stop_on_error.SetValueFromString(option_arg);
321e16c50a1SJim Ingham                     break;
322340b0309SGreg Clayton 
323e16c50a1SJim Ingham                 case 'c':
324c95f7e2aSPavel Labath                     error = m_stop_on_continue.SetValueFromString(option_arg);
325e16c50a1SJim Ingham                     break;
326340b0309SGreg Clayton 
32760986174SMichael Sartain                 case 's':
328c95f7e2aSPavel Labath                     error = m_silent_run.SetValueFromString(option_arg);
32960986174SMichael Sartain                     break;
330340b0309SGreg Clayton 
331e16c50a1SJim Ingham                 default:
33286edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
333e16c50a1SJim Ingham                     break;
334e16c50a1SJim Ingham             }
335e16c50a1SJim Ingham 
336e16c50a1SJim Ingham             return error;
337e16c50a1SJim Ingham         }
338e16c50a1SJim Ingham 
339e16c50a1SJim Ingham         void
34013d21e9aSBruce Mitchener         OptionParsingStarting () override
341e16c50a1SJim Ingham         {
342012d4fcaSEnrico Granata             m_stop_on_error.Clear();
343340b0309SGreg Clayton             m_silent_run.Clear();
344340b0309SGreg Clayton             m_stop_on_continue.Clear();
345e16c50a1SJim Ingham         }
346e16c50a1SJim Ingham 
347e0d378b3SGreg Clayton         const OptionDefinition*
34813d21e9aSBruce Mitchener         GetDefinitions () override
349e16c50a1SJim Ingham         {
350e16c50a1SJim Ingham             return g_option_table;
351e16c50a1SJim Ingham         }
352e16c50a1SJim Ingham 
353e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
354e16c50a1SJim Ingham 
355e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
356e16c50a1SJim Ingham 
357e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
358e16c50a1SJim Ingham 
359012d4fcaSEnrico Granata         OptionValueBoolean m_stop_on_error;
360340b0309SGreg Clayton         OptionValueBoolean m_silent_run;
361340b0309SGreg Clayton         OptionValueBoolean m_stop_on_continue;
362e16c50a1SJim Ingham     };
363e16c50a1SJim Ingham 
364ebc09c36SJim Ingham     bool
36513d21e9aSBruce Mitchener     DoExecute(Args& command, CommandReturnObject &result) override
366ebc09c36SJim Ingham     {
367c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
368ebc09c36SJim Ingham         if (argc == 1)
369ebc09c36SJim Ingham         {
3705a988416SJim Ingham             const char *filename = command.GetArgumentAtIndex(0);
371ebc09c36SJim Ingham 
3721ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
3736e3d8e7fSEugene Zelenko             ExecutionContext *exe_ctx = nullptr;  // Just use the default context.
374ebc09c36SJim Ingham 
375340b0309SGreg Clayton             // If any options were set, then use them
376340b0309SGreg Clayton             if (m_options.m_stop_on_error.OptionWasSet()    ||
377340b0309SGreg Clayton                 m_options.m_silent_run.OptionWasSet()       ||
378340b0309SGreg Clayton                 m_options.m_stop_on_continue.OptionWasSet())
379340b0309SGreg Clayton             {
380340b0309SGreg Clayton                 // Use user set settings
38126c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
38226c7bf93SJim Ingham                 options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue());
38326c7bf93SJim Ingham                 options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue());
3847d8555c4SJim Ingham                 options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue());
3857d8555c4SJim Ingham                 options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue());
38626c7bf93SJim Ingham 
387e16c50a1SJim Ingham                 m_interpreter.HandleCommandsFromFile (cmd_file,
388e16c50a1SJim Ingham                                                       exe_ctx,
38926c7bf93SJim Ingham                                                       options,
390e16c50a1SJim Ingham                                                       result);
391340b0309SGreg Clayton             }
392340b0309SGreg Clayton             else
393340b0309SGreg Clayton             {
394340b0309SGreg Clayton                 // No options were set, inherit any settings from nested "command source" commands,
395340b0309SGreg Clayton                 // or set to sane default settings...
39626c7bf93SJim Ingham                 CommandInterpreterRunOptions options;
397340b0309SGreg Clayton                 m_interpreter.HandleCommandsFromFile (cmd_file,
398340b0309SGreg Clayton                                                       exe_ctx,
39926c7bf93SJim Ingham                                                       options,
400340b0309SGreg Clayton                                                       result);
401340b0309SGreg Clayton             }
402ebc09c36SJim Ingham         }
403ebc09c36SJim Ingham         else
404ebc09c36SJim Ingham         {
405ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
406ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
407ebc09c36SJim Ingham         }
408ebc09c36SJim Ingham         return result.Succeeded();
409ebc09c36SJim Ingham     }
4106e3d8e7fSEugene Zelenko 
4115a988416SJim Ingham     CommandOptions m_options;
412ebc09c36SJim Ingham };
413ebc09c36SJim Ingham 
414e0d378b3SGreg Clayton OptionDefinition
415e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
416e16c50a1SJim Ingham {
4176e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
4186e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
4196e3d8e7fSEugene Zelenko { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true don't echo commands while executing."},
4206e3d8e7fSEugene Zelenko { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
421e16c50a1SJim Ingham };
422e16c50a1SJim Ingham 
423ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
424ebc09c36SJim Ingham //-------------------------------------------------------------------------
425ebc09c36SJim Ingham // CommandObjectCommandsAlias
426ebc09c36SJim Ingham //-------------------------------------------------------------------------
427ebc09c36SJim Ingham 
428be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
429be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
43044d93782SGreg Clayton                                                      "def my_command_impl(debugger, args, result, internal_dict):\n";
431be93a35aSEnrico Granata 
4325a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw
433ebc09c36SJim Ingham {
434*45d0e238SEnrico Granata protected:
435*45d0e238SEnrico Granata     class CommandOptions : public OptionGroup
436*45d0e238SEnrico Granata     {
437ebc09c36SJim Ingham     public:
438*45d0e238SEnrico Granata         CommandOptions () :
439*45d0e238SEnrico Granata         OptionGroup(),
440*45d0e238SEnrico Granata         m_help(),
441*45d0e238SEnrico Granata         m_long_help()
442*45d0e238SEnrico Granata         {}
443*45d0e238SEnrico Granata 
444*45d0e238SEnrico Granata         ~CommandOptions() override = default;
445*45d0e238SEnrico Granata 
446*45d0e238SEnrico Granata         uint32_t
447*45d0e238SEnrico Granata         GetNumDefinitions () override
448*45d0e238SEnrico Granata         {
449*45d0e238SEnrico Granata             return 3;
450*45d0e238SEnrico Granata         }
451*45d0e238SEnrico Granata 
452*45d0e238SEnrico Granata         const OptionDefinition*
453*45d0e238SEnrico Granata         GetDefinitions () override
454*45d0e238SEnrico Granata         {
455*45d0e238SEnrico Granata             return g_option_table;
456*45d0e238SEnrico Granata         }
457*45d0e238SEnrico Granata 
458*45d0e238SEnrico Granata         Error
459*45d0e238SEnrico Granata         SetOptionValue (CommandInterpreter &interpreter,
460*45d0e238SEnrico Granata                         uint32_t option_idx,
461*45d0e238SEnrico Granata                         const char *option_value) override
462*45d0e238SEnrico Granata         {
463*45d0e238SEnrico Granata             Error error;
464*45d0e238SEnrico Granata 
465*45d0e238SEnrico Granata             const int short_option = g_option_table[option_idx].short_option;
466*45d0e238SEnrico Granata 
467*45d0e238SEnrico Granata             switch (short_option)
468*45d0e238SEnrico Granata             {
469*45d0e238SEnrico Granata                 case 'h':
470*45d0e238SEnrico Granata                     m_help.SetCurrentValue(option_value);
471*45d0e238SEnrico Granata                     m_help.SetOptionWasSet();
472*45d0e238SEnrico Granata                     break;
473*45d0e238SEnrico Granata 
474*45d0e238SEnrico Granata                 case 'H':
475*45d0e238SEnrico Granata                     m_long_help.SetCurrentValue(option_value);
476*45d0e238SEnrico Granata                     m_long_help.SetOptionWasSet();
477*45d0e238SEnrico Granata                     break;
478*45d0e238SEnrico Granata 
479*45d0e238SEnrico Granata                 default:
480*45d0e238SEnrico Granata                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
481*45d0e238SEnrico Granata                     break;
482*45d0e238SEnrico Granata             }
483*45d0e238SEnrico Granata 
484*45d0e238SEnrico Granata             return error;
485*45d0e238SEnrico Granata         }
486*45d0e238SEnrico Granata 
487*45d0e238SEnrico Granata         void
488*45d0e238SEnrico Granata         OptionParsingStarting (CommandInterpreter &interpreter) override
489*45d0e238SEnrico Granata         {
490*45d0e238SEnrico Granata             m_help.Clear();
491*45d0e238SEnrico Granata             m_long_help.Clear();
492*45d0e238SEnrico Granata         }
493*45d0e238SEnrico Granata 
494*45d0e238SEnrico Granata         // Options table: Required for subclasses of Options.
495*45d0e238SEnrico Granata 
496*45d0e238SEnrico Granata         static OptionDefinition g_option_table[];
497*45d0e238SEnrico Granata         OptionValueString m_help;
498*45d0e238SEnrico Granata         OptionValueString m_long_help;
499*45d0e238SEnrico Granata     };
500*45d0e238SEnrico Granata 
501*45d0e238SEnrico Granata     OptionGroupOptions m_option_group;
502*45d0e238SEnrico Granata     CommandOptions m_command_options;
503*45d0e238SEnrico Granata 
504*45d0e238SEnrico Granata public:
505*45d0e238SEnrico Granata     Options *
506*45d0e238SEnrico Granata     GetOptions () override
507*45d0e238SEnrico Granata     {
508*45d0e238SEnrico Granata         return &m_option_group;
509*45d0e238SEnrico Granata     }
510*45d0e238SEnrico Granata 
511a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
5125a988416SJim Ingham         CommandObjectRaw(interpreter,
5130e5e5a79SGreg Clayton                          "command alias",
514e3d26315SCaroline Tice                          "Allow users to define their own debugger command abbreviations.",
515*45d0e238SEnrico Granata                          nullptr),
516*45d0e238SEnrico Granata         m_option_group(interpreter),
517*45d0e238SEnrico Granata         m_command_options()
518ebc09c36SJim Ingham     {
519*45d0e238SEnrico Granata         m_option_group.Append(&m_command_options);
520*45d0e238SEnrico Granata         m_option_group.Finalize();
521*45d0e238SEnrico Granata 
522ebc09c36SJim Ingham         SetHelpLong(
523ea671fbdSKate Stone "'alias' allows the user to create a short-cut or abbreviation for long \
524ea671fbdSKate Stone commands, multi-word commands, and commands that take particular options.  \
525ea671fbdSKate Stone Below are some simple examples of how one might use the 'alias' command:" R"(
526ea671fbdSKate Stone 
527ea671fbdSKate Stone (lldb) command alias sc script
528ea671fbdSKate Stone 
529ea671fbdSKate Stone     Creates the abbreviation 'sc' for the 'script' command.
530ea671fbdSKate Stone 
531ea671fbdSKate Stone (lldb) command alias bp breakpoint
532ea671fbdSKate Stone 
533ea671fbdSKate Stone )" "    Creates the abbreviation 'bp' for the 'breakpoint' command.  Since \
534ea671fbdSKate Stone breakpoint commands are two-word commands, the user would still need to \
535ea671fbdSKate Stone enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"(
536ea671fbdSKate Stone 
537ea671fbdSKate Stone (lldb) command alias bpl breakpoint list
538ea671fbdSKate Stone 
539ea671fbdSKate Stone     Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'.
540ea671fbdSKate Stone 
541ea671fbdSKate Stone )" "An alias can include some options for the command, with the values either \
542ea671fbdSKate Stone filled in at the time the alias is created, or specified as positional \
543ea671fbdSKate Stone arguments, to be filled in when the alias is invoked.  The following example \
544ea671fbdSKate Stone shows how to create aliases with options:" R"(
545ea671fbdSKate Stone 
546ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
547ea671fbdSKate Stone 
548ea671fbdSKate Stone )" "    Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \
549ea671fbdSKate Stone options already part of the alias.  So if the user wants to set a breakpoint \
550ea671fbdSKate Stone by file and line without explicitly having to use the -f and -l options, the \
551ea671fbdSKate Stone user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \
552ea671fbdSKate Stone for the actual arguments that will be passed when the alias command is used.  \
553ea671fbdSKate Stone The number in the placeholder refers to the position/order the actual value \
554ea671fbdSKate Stone occupies when the alias is used.  All the occurrences of '%1' in the alias \
555ea671fbdSKate Stone will be replaced with the first argument, all the occurrences of '%2' in the \
556ea671fbdSKate Stone alias will be replaced with the second argument, and so on.  This also allows \
557ea671fbdSKate Stone actual arguments to be used multiple times within an alias (see 'process \
558ea671fbdSKate Stone launch' example below)." R"(
559ea671fbdSKate Stone 
560ea671fbdSKate Stone )" "Note: the positional arguments must substitute as whole words in the resultant \
561ea671fbdSKate Stone command, so you can't at present do something like this to append the file extension \
562ea671fbdSKate Stone \".cpp\":" R"(
563ea671fbdSKate Stone 
564ea671fbdSKate Stone (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2
565ea671fbdSKate Stone 
566ea671fbdSKate Stone )" "For more complex aliasing, use the \"command regex\" command instead.  In the \
567ea671fbdSKate Stone 'bfl' case above, the actual file value will be filled in with the first argument \
568ea671fbdSKate Stone following 'bfl' and the actual line number value will be filled in with the second \
569ea671fbdSKate Stone argument.  The user would use this alias as follows:" R"(
570ea671fbdSKate Stone 
571ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2
572ea671fbdSKate Stone (lldb) bfl my-file.c 137
573ea671fbdSKate Stone 
574ea671fbdSKate Stone This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'.
575ea671fbdSKate Stone 
576ea671fbdSKate Stone Another example:
577ea671fbdSKate Stone 
578ea671fbdSKate Stone (lldb) command alias pltty process launch -s -o %1 -e %1
579ea671fbdSKate Stone (lldb) pltty /dev/tty0
580ea671fbdSKate Stone 
581ea671fbdSKate Stone     Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0'
582ea671fbdSKate Stone 
583ea671fbdSKate Stone )" "If the user always wanted to pass the same value to a particular option, the \
584ea671fbdSKate Stone alias could be defined with that value directly in the alias as a constant, \
585ea671fbdSKate Stone rather than using a positional placeholder:" R"(
586ea671fbdSKate Stone 
587ea671fbdSKate Stone (lldb) command alias bl3 breakpoint set -f %1 -l 3
588ea671fbdSKate Stone 
589ea671fbdSKate Stone     Always sets a breakpoint on line 3 of whatever file is indicated.)"
590ea671fbdSKate Stone         );
591ebc09c36SJim Ingham 
592405fe67fSCaroline Tice         CommandArgumentEntry arg1;
593405fe67fSCaroline Tice         CommandArgumentEntry arg2;
594405fe67fSCaroline Tice         CommandArgumentEntry arg3;
595405fe67fSCaroline Tice         CommandArgumentData alias_arg;
596405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
597405fe67fSCaroline Tice         CommandArgumentData options_arg;
598405fe67fSCaroline Tice 
599405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
600405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
601405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
602405fe67fSCaroline Tice 
603405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
604405fe67fSCaroline Tice         arg1.push_back (alias_arg);
605405fe67fSCaroline Tice 
606405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
607405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
608405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
609405fe67fSCaroline Tice 
610405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
611405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
612405fe67fSCaroline Tice 
613405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
614405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
615405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
616405fe67fSCaroline Tice 
617405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
618405fe67fSCaroline Tice         arg3.push_back (options_arg);
619405fe67fSCaroline Tice 
620405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
621405fe67fSCaroline Tice         m_arguments.push_back (arg1);
622405fe67fSCaroline Tice         m_arguments.push_back (arg2);
623405fe67fSCaroline Tice         m_arguments.push_back (arg3);
624ebc09c36SJim Ingham     }
625ebc09c36SJim Ingham 
6266e3d8e7fSEugene Zelenko     ~CommandObjectCommandsAlias() override = default;
627ebc09c36SJim Ingham 
6285a988416SJim Ingham protected:
62913d21e9aSBruce Mitchener     bool
63013d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
631844d2303SCaroline Tice     {
632*45d0e238SEnrico Granata         if (!raw_command_line || !raw_command_line[0])
633*45d0e238SEnrico Granata         {
634*45d0e238SEnrico Granata             result.AppendError ("'alias' requires at least two arguments");
635*45d0e238SEnrico Granata             return false;
636*45d0e238SEnrico Granata         }
637*45d0e238SEnrico Granata 
638*45d0e238SEnrico Granata         m_option_group.NotifyOptionParsingStarting();
639*45d0e238SEnrico Granata 
640*45d0e238SEnrico Granata         const char * remainder = nullptr;
641*45d0e238SEnrico Granata 
642*45d0e238SEnrico Granata         if (raw_command_line[0] == '-')
643*45d0e238SEnrico Granata         {
644*45d0e238SEnrico Granata             // We have some options and these options MUST end with --.
645*45d0e238SEnrico Granata             const char *end_options = nullptr;
646*45d0e238SEnrico Granata             const char *s = raw_command_line;
647*45d0e238SEnrico Granata             while (s && s[0])
648*45d0e238SEnrico Granata             {
649*45d0e238SEnrico Granata                 end_options = ::strstr (s, "--");
650*45d0e238SEnrico Granata                 if (end_options)
651*45d0e238SEnrico Granata                 {
652*45d0e238SEnrico Granata                     end_options += 2; // Get past the "--"
653*45d0e238SEnrico Granata                     if (::isspace (end_options[0]))
654*45d0e238SEnrico Granata                     {
655*45d0e238SEnrico Granata                         remainder = end_options;
656*45d0e238SEnrico Granata                         while (::isspace (*remainder))
657*45d0e238SEnrico Granata                             ++remainder;
658*45d0e238SEnrico Granata                         break;
659*45d0e238SEnrico Granata                     }
660*45d0e238SEnrico Granata                 }
661*45d0e238SEnrico Granata                 s = end_options;
662*45d0e238SEnrico Granata             }
663*45d0e238SEnrico Granata 
664*45d0e238SEnrico Granata             if (end_options)
665*45d0e238SEnrico Granata             {
666*45d0e238SEnrico Granata                 Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
667*45d0e238SEnrico Granata                 if (!ParseOptions (args, result))
668*45d0e238SEnrico Granata                     return false;
669*45d0e238SEnrico Granata 
670*45d0e238SEnrico Granata                 Error error (m_option_group.NotifyOptionParsingFinished());
671*45d0e238SEnrico Granata                 if (error.Fail())
672*45d0e238SEnrico Granata                 {
673*45d0e238SEnrico Granata                     result.AppendError (error.AsCString());
674*45d0e238SEnrico Granata                     result.SetStatus (eReturnStatusFailed);
675*45d0e238SEnrico Granata                     return false;
676*45d0e238SEnrico Granata                 }
677*45d0e238SEnrico Granata             }
678*45d0e238SEnrico Granata         }
679*45d0e238SEnrico Granata         if (nullptr == remainder)
680*45d0e238SEnrico Granata             remainder = raw_command_line;
681*45d0e238SEnrico Granata 
682*45d0e238SEnrico Granata         std::string raw_command_string (remainder);
683*45d0e238SEnrico Granata         Args args (raw_command_string.c_str());
684844d2303SCaroline Tice 
685844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
686844d2303SCaroline Tice 
687844d2303SCaroline Tice         if (argc < 2)
688844d2303SCaroline Tice         {
689844d2303SCaroline Tice             result.AppendError ("'alias' requires at least two arguments");
690844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
691844d2303SCaroline Tice             return false;
692844d2303SCaroline Tice         }
693844d2303SCaroline Tice 
694844d2303SCaroline Tice         // Get the alias command.
695844d2303SCaroline Tice 
696844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
697844d2303SCaroline Tice 
698844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
699844d2303SCaroline Tice         // does the stripping itself.
700844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
701844d2303SCaroline Tice         if (pos == 0)
702844d2303SCaroline Tice         {
703844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
704844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
705844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
706844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
707844d2303SCaroline Tice         }
708844d2303SCaroline Tice         else
709844d2303SCaroline Tice         {
710844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
711844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
712844d2303SCaroline Tice             return false;
713844d2303SCaroline Tice         }
714844d2303SCaroline Tice 
715844d2303SCaroline Tice 
716844d2303SCaroline Tice         // Verify that the command is alias-able.
717844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
718844d2303SCaroline Tice         {
719844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
720844d2303SCaroline Tice                                           alias_command.c_str());
721844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
722844d2303SCaroline Tice             return false;
723844d2303SCaroline Tice         }
724844d2303SCaroline Tice 
725844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
726844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
727844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
728844d2303SCaroline Tice 
729844d2303SCaroline Tice         if (!cmd_obj)
730844d2303SCaroline Tice         {
73186edbf41SGreg Clayton             result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
732844d2303SCaroline Tice                                           "  No alias created.", raw_command_string.c_str());
733844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
734844d2303SCaroline Tice             return false;
735844d2303SCaroline Tice         }
736844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
737844d2303SCaroline Tice         {
738844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
739844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
7405a988416SJim Ingham             return HandleAliasingNormalCommand (args, result);
741844d2303SCaroline Tice         }
742844d2303SCaroline Tice         else
743844d2303SCaroline Tice         {
7445a988416SJim Ingham             return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
7455a988416SJim Ingham         }
7465a988416SJim Ingham         return result.Succeeded();
7475a988416SJim Ingham     }
7485a988416SJim Ingham 
7495a988416SJim Ingham     bool
7505a988416SJim Ingham     HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
7515a988416SJim Ingham     {
752844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
753844d2303SCaroline Tice 
754844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
755844d2303SCaroline Tice 
756212130acSEnrico Granata             if (CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false))
757844d2303SCaroline Tice             {
758844d2303SCaroline Tice                 if (m_interpreter.AliasExists (alias_command.c_str())
759844d2303SCaroline Tice                     || m_interpreter.UserCommandExists (alias_command.c_str()))
760844d2303SCaroline Tice                 {
761844d2303SCaroline Tice                     result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
762844d2303SCaroline Tice                                                     alias_command.c_str());
763844d2303SCaroline Tice                 }
764*45d0e238SEnrico Granata                 if (CommandAlias *alias = m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp, raw_command_string.c_str()))
765472362e6SCaroline Tice                 {
766*45d0e238SEnrico Granata                     if (m_command_options.m_help.OptionWasSet())
767*45d0e238SEnrico Granata                         alias->SetHelp(m_command_options.m_help.GetCurrentValue());
768*45d0e238SEnrico Granata                     if (m_command_options.m_long_help.OptionWasSet())
769*45d0e238SEnrico Granata                         alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
770844d2303SCaroline Tice                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
771844d2303SCaroline Tice                 }
772472362e6SCaroline Tice                 else
773472362e6SCaroline Tice                 {
774472362e6SCaroline Tice                     result.AppendError ("Unable to create requested alias.\n");
775472362e6SCaroline Tice                     result.SetStatus (eReturnStatusFailed);
776472362e6SCaroline Tice                 }
777212130acSEnrico Granata 
778212130acSEnrico Granata             }
779212130acSEnrico Granata             else
780212130acSEnrico Granata             {
781212130acSEnrico Granata                 result.AppendError ("Unable to create requested alias.\n");
782212130acSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
783212130acSEnrico Granata             }
784212130acSEnrico Granata 
785844d2303SCaroline Tice             return result.Succeeded ();
786844d2303SCaroline Tice     }
787ebc09c36SJim Ingham 
788ebc09c36SJim Ingham     bool
7895a988416SJim Ingham     HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
790ebc09c36SJim Ingham     {
791867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
792ebc09c36SJim Ingham 
793ebc09c36SJim Ingham         if (argc < 2)
794ebc09c36SJim Ingham         {
795ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
796ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
797ebc09c36SJim Ingham             return false;
798ebc09c36SJim Ingham         }
799ebc09c36SJim Ingham 
800ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
801ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
802ebc09c36SJim Ingham 
803ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
804ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
805ebc09c36SJim Ingham 
806ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
807ebc09c36SJim Ingham 
808a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
809ebc09c36SJim Ingham         {
810ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
811ebc09c36SJim Ingham                                          alias_command.c_str());
812ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
813ebc09c36SJim Ingham         }
814ebc09c36SJim Ingham         else
815ebc09c36SJim Ingham         {
816a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
817ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
818ebc09c36SJim Ingham              bool use_subcommand = false;
8196e3d8e7fSEugene Zelenko              if (command_obj_sp)
820ebc09c36SJim Ingham              {
821ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
8226e3d8e7fSEugene Zelenko                  CommandObject *sub_cmd_obj = nullptr;
823ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
824ebc09c36SJim Ingham 
825844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
826ebc09c36SJim Ingham                  {
827ebc09c36SJim Ingham                      if (argc >= 3)
828ebc09c36SJim Ingham                      {
829ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
830ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
831998255bfSGreg Clayton                          subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
8326e3d8e7fSEugene Zelenko                          if (subcommand_obj_sp)
833ebc09c36SJim Ingham                          {
834ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
835ebc09c36SJim Ingham                              use_subcommand = true;
836ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
837844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
838ebc09c36SJim Ingham                          }
839ebc09c36SJim Ingham                          else
840ebc09c36SJim Ingham                          {
841f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
842f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
843f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
844ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
845ebc09c36SJim Ingham                              return false;
846ebc09c36SJim Ingham                          }
847ebc09c36SJim Ingham                      }
848ebc09c36SJim Ingham                  }
849ebc09c36SJim Ingham 
850ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
851ebc09c36SJim Ingham 
852212130acSEnrico Granata                  std::string args_string;
853212130acSEnrico Granata 
854ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
855ebc09c36SJim Ingham                  {
856ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
857ebc09c36SJim Ingham                     if (use_subcommand)
858ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
859ca90c47eSCaroline Tice 
860ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
861867b185dSCaroline Tice                  }
862ebc09c36SJim Ingham 
863a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
864a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
865ebc09c36SJim Ingham                  {
866ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
867ebc09c36SJim Ingham                                                      alias_command.c_str());
868ebc09c36SJim Ingham                  }
869ebc09c36SJim Ingham 
870*45d0e238SEnrico Granata                  if (CommandAlias *alias = m_interpreter.AddAlias(alias_command.c_str(),
871212130acSEnrico Granata                                                                   use_subcommand ? subcommand_obj_sp : command_obj_sp,
872212130acSEnrico Granata                                                                   args_string.c_str()))
873212130acSEnrico Granata                  {
874*45d0e238SEnrico Granata                      if (m_command_options.m_help.OptionWasSet())
875*45d0e238SEnrico Granata                          alias->SetHelp(m_command_options.m_help.GetCurrentValue());
876*45d0e238SEnrico Granata                      if (m_command_options.m_long_help.OptionWasSet())
877*45d0e238SEnrico Granata                          alias->SetHelpLong(m_command_options.m_long_help.GetCurrentValue());
878ebc09c36SJim Ingham                      result.SetStatus (eReturnStatusSuccessFinishNoResult);
879ebc09c36SJim Ingham                  }
880ebc09c36SJim Ingham                  else
881ebc09c36SJim Ingham                  {
882212130acSEnrico Granata                      result.AppendError ("Unable to create requested alias.\n");
883212130acSEnrico Granata                      result.SetStatus (eReturnStatusFailed);
884212130acSEnrico Granata                      return false;
885212130acSEnrico Granata                  }
886212130acSEnrico Granata              }
887212130acSEnrico Granata              else
888212130acSEnrico Granata              {
889ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
890ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
891e7941795SCaroline Tice                  return false;
892ebc09c36SJim Ingham              }
893ebc09c36SJim Ingham         }
894ebc09c36SJim Ingham 
895ebc09c36SJim Ingham         return result.Succeeded();
896ebc09c36SJim Ingham     }
897ebc09c36SJim Ingham };
898ebc09c36SJim Ingham 
899*45d0e238SEnrico Granata OptionDefinition
900*45d0e238SEnrico Granata CommandObjectCommandsAlias::CommandOptions::g_option_table[] =
901*45d0e238SEnrico Granata {
902*45d0e238SEnrico Granata     { LLDB_OPT_SET_ALL, false, "help",      'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText,    "Help text for this command"},
903*45d0e238SEnrico Granata     { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText,    "Long help text for this command"},
904*45d0e238SEnrico Granata     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
905*45d0e238SEnrico Granata };
906*45d0e238SEnrico Granata 
907ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
908ebc09c36SJim Ingham //-------------------------------------------------------------------------
909ebc09c36SJim Ingham // CommandObjectCommandsUnalias
910ebc09c36SJim Ingham //-------------------------------------------------------------------------
911ebc09c36SJim Ingham 
9125a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed
913ebc09c36SJim Ingham {
914ebc09c36SJim Ingham public:
915a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
9165a988416SJim Ingham         CommandObjectParsed(interpreter,
9170e5e5a79SGreg Clayton                             "command unalias",
91886ddae50SCaroline Tice                             "Allow the user to remove/delete a user-defined command abbreviation.",
9196e3d8e7fSEugene Zelenko                             nullptr)
920ebc09c36SJim Ingham     {
921405fe67fSCaroline Tice         CommandArgumentEntry arg;
922405fe67fSCaroline Tice         CommandArgumentData alias_arg;
923405fe67fSCaroline Tice 
924405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
925405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
926405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
927405fe67fSCaroline Tice 
928405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
929405fe67fSCaroline Tice         arg.push_back (alias_arg);
930405fe67fSCaroline Tice 
931405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
932405fe67fSCaroline Tice         m_arguments.push_back (arg);
933ebc09c36SJim Ingham     }
934ebc09c36SJim Ingham 
9356e3d8e7fSEugene Zelenko     ~CommandObjectCommandsUnalias() override = default;
936ebc09c36SJim Ingham 
9375a988416SJim Ingham protected:
938ebc09c36SJim Ingham     bool
93913d21e9aSBruce Mitchener     DoExecute (Args& args, CommandReturnObject &result) override
940ebc09c36SJim Ingham     {
941ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
942ebc09c36SJim Ingham         CommandObject *cmd_obj;
943ebc09c36SJim Ingham 
944ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
945ebc09c36SJim Ingham         {
946ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
947a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
948ebc09c36SJim Ingham             if (cmd_obj)
949ebc09c36SJim Ingham             {
950a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
951ebc09c36SJim Ingham                 {
952b547278cSGreg Clayton                     if (cmd_obj->IsRemovable())
953b547278cSGreg Clayton                     {
954b547278cSGreg Clayton                         result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n",
955b547278cSGreg Clayton                                                       command_name);
956b547278cSGreg Clayton                     }
957b547278cSGreg Clayton                     else
958b547278cSGreg Clayton                     {
959ebc09c36SJim Ingham                         result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
960ebc09c36SJim Ingham                                                       command_name);
961b547278cSGreg Clayton                     }
962ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
963ebc09c36SJim Ingham                 }
964ebc09c36SJim Ingham                 else
965ebc09c36SJim Ingham                 {
9666e3d8e7fSEugene Zelenko                     if (!m_interpreter.RemoveAlias(command_name))
967ebc09c36SJim Ingham                     {
968a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
969ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
970ebc09c36SJim Ingham                                                           command_name);
971ebc09c36SJim Ingham                         else
972ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
973ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
974ebc09c36SJim Ingham                     }
975ebc09c36SJim Ingham                     else
976ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
977ebc09c36SJim Ingham                 }
978ebc09c36SJim Ingham             }
979ebc09c36SJim Ingham             else
980ebc09c36SJim Ingham             {
981ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
982ebc09c36SJim Ingham                                               "current list of commands.\n",
983ebc09c36SJim Ingham                                              command_name);
984ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
985ebc09c36SJim Ingham             }
986ebc09c36SJim Ingham         }
987ebc09c36SJim Ingham         else
988ebc09c36SJim Ingham         {
989ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
990ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
991ebc09c36SJim Ingham         }
992ebc09c36SJim Ingham 
993ebc09c36SJim Ingham         return result.Succeeded();
994ebc09c36SJim Ingham     }
995ebc09c36SJim Ingham };
996ebc09c36SJim Ingham 
997b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete
998b547278cSGreg Clayton //-------------------------------------------------------------------------
999b547278cSGreg Clayton // CommandObjectCommandsDelete
1000b547278cSGreg Clayton //-------------------------------------------------------------------------
1001b547278cSGreg Clayton 
1002b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed
1003b547278cSGreg Clayton {
1004b547278cSGreg Clayton public:
1005b547278cSGreg Clayton     CommandObjectCommandsDelete (CommandInterpreter &interpreter) :
1006b547278cSGreg Clayton         CommandObjectParsed(interpreter,
1007b547278cSGreg Clayton                             "command delete",
1008b547278cSGreg Clayton                             "Allow the user to delete user-defined regular expression, python or multi-word commands.",
10096e3d8e7fSEugene Zelenko                             nullptr)
1010b547278cSGreg Clayton     {
1011b547278cSGreg Clayton         CommandArgumentEntry arg;
1012b547278cSGreg Clayton         CommandArgumentData alias_arg;
1013b547278cSGreg Clayton 
1014b547278cSGreg Clayton         // Define the first (and only) variant of this arg.
1015b547278cSGreg Clayton         alias_arg.arg_type = eArgTypeCommandName;
1016b547278cSGreg Clayton         alias_arg.arg_repetition = eArgRepeatPlain;
1017b547278cSGreg Clayton 
1018b547278cSGreg Clayton         // There is only one variant this argument could be; put it into the argument entry.
1019b547278cSGreg Clayton         arg.push_back (alias_arg);
1020b547278cSGreg Clayton 
1021b547278cSGreg Clayton         // Push the data for the first argument into the m_arguments vector.
1022b547278cSGreg Clayton         m_arguments.push_back (arg);
1023b547278cSGreg Clayton     }
1024b547278cSGreg Clayton 
10256e3d8e7fSEugene Zelenko     ~CommandObjectCommandsDelete() override = default;
1026b547278cSGreg Clayton 
1027b547278cSGreg Clayton protected:
1028b547278cSGreg Clayton     bool
102913d21e9aSBruce Mitchener     DoExecute (Args& args, CommandReturnObject &result) override
1030b547278cSGreg Clayton     {
1031b547278cSGreg Clayton         CommandObject::CommandMap::iterator pos;
1032b547278cSGreg Clayton 
1033b547278cSGreg Clayton         if (args.GetArgumentCount() != 0)
1034b547278cSGreg Clayton         {
1035b547278cSGreg Clayton             const char *command_name = args.GetArgumentAtIndex(0);
1036b547278cSGreg Clayton             if (m_interpreter.CommandExists (command_name))
1037b547278cSGreg Clayton             {
1038b547278cSGreg Clayton                 if (m_interpreter.RemoveCommand (command_name))
1039b547278cSGreg Clayton                 {
1040b547278cSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1041b547278cSGreg Clayton                 }
1042b547278cSGreg Clayton                 else
1043b547278cSGreg Clayton                 {
1044b547278cSGreg Clayton                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
1045b547278cSGreg Clayton                                                   command_name);
1046b547278cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
1047b547278cSGreg Clayton                 }
1048b547278cSGreg Clayton             }
1049b547278cSGreg Clayton             else
1050b547278cSGreg Clayton             {
105146d4aa21SEnrico Granata                 StreamString error_msg_stream;
105246d4aa21SEnrico Granata                 const bool generate_apropos = true;
105346d4aa21SEnrico Granata                 const bool generate_type_lookup = false;
105446d4aa21SEnrico Granata                 CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
105546d4aa21SEnrico Granata                                                                         command_name,
105646d4aa21SEnrico Granata                                                                         nullptr,
105746d4aa21SEnrico Granata                                                                         nullptr,
105846d4aa21SEnrico Granata                                                                         generate_apropos,
105946d4aa21SEnrico Granata                                                                         generate_type_lookup);
106046d4aa21SEnrico Granata                 result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
1061b547278cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1062b547278cSGreg Clayton             }
1063b547278cSGreg Clayton         }
1064b547278cSGreg Clayton         else
1065b547278cSGreg Clayton         {
1066b547278cSGreg Clayton             result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ());
1067b547278cSGreg Clayton             result.SetStatus (eReturnStatusFailed);
1068b547278cSGreg Clayton         }
1069b547278cSGreg Clayton 
1070b547278cSGreg Clayton         return result.Succeeded();
1071b547278cSGreg Clayton     }
1072b547278cSGreg Clayton };
1073b547278cSGreg Clayton 
1074de164aaaSGreg Clayton //-------------------------------------------------------------------------
1075de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
1076de164aaaSGreg Clayton //-------------------------------------------------------------------------
10775a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex
1078de164aaaSGreg Clayton 
107944d93782SGreg Clayton class CommandObjectCommandsAddRegex :
108044d93782SGreg Clayton     public CommandObjectParsed,
1081ea508635SGreg Clayton     public IOHandlerDelegateMultiline
1082de164aaaSGreg Clayton {
1083de164aaaSGreg Clayton public:
1084de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
10855a988416SJim Ingham         CommandObjectParsed (interpreter,
10860e5e5a79SGreg Clayton                        "command regex",
1087de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
10880e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
1089ea508635SGreg Clayton         IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand),
1090de164aaaSGreg Clayton         m_options (interpreter)
1091de164aaaSGreg Clayton     {
1092ea671fbdSKate Stone         SetHelpLong(R"(
1093ea671fbdSKate Stone )" "This command allows the user to create powerful regular expression commands \
1094ea671fbdSKate Stone with substitutions. The regular expressions and substitutions are specified \
1095ea671fbdSKate Stone using the regular expression substitution format of:" R"(
1096ea671fbdSKate Stone 
1097ea671fbdSKate Stone     s/<regex>/<subst>/
1098ea671fbdSKate Stone 
1099ea671fbdSKate Stone )" "<regex> is a regular expression that can use parenthesis to capture regular \
1100ea671fbdSKate Stone expression input and substitute the captured matches in the output using %1 \
1101ea671fbdSKate Stone for the first match, %2 for the second, and so on." R"(
1102ea671fbdSKate Stone 
1103ea671fbdSKate Stone )" "The regular expressions can all be specified on the command line if more than \
1104ea671fbdSKate Stone one argument is provided. If just the command name is provided on the command \
1105ea671fbdSKate Stone line, then the regular expressions and substitutions can be entered on separate \
1106ea671fbdSKate Stone lines, followed by an empty line to terminate the command definition." R"(
1107ea671fbdSKate Stone 
1108ea671fbdSKate Stone EXAMPLES
1109ea671fbdSKate Stone 
1110ea671fbdSKate Stone )" "The following example will define a regular expression command named 'f' that \
1111ea671fbdSKate Stone will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \
1112ea671fbdSKate Stone a number follows 'f':" R"(
1113ea671fbdSKate Stone 
1114ea671fbdSKate Stone     (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')"
11150e5e5a79SGreg Clayton         );
1116de164aaaSGreg Clayton     }
1117de164aaaSGreg Clayton 
11186e3d8e7fSEugene Zelenko     ~CommandObjectCommandsAddRegex() override = default;
1119de164aaaSGreg Clayton 
11205a988416SJim Ingham protected:
1121ea508635SGreg Clayton     void
1122ea508635SGreg Clayton     IOHandlerActivated (IOHandler &io_handler) override
112344d93782SGreg Clayton     {
112444d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
112544d93782SGreg Clayton         if (output_sp)
112644d93782SGreg Clayton         {
112744d93782SGreg 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");
112844d93782SGreg Clayton             output_sp->Flush();
112944d93782SGreg Clayton         }
113044d93782SGreg Clayton     }
113144d93782SGreg Clayton 
1132ea508635SGreg Clayton     void
1133ea508635SGreg Clayton     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
113444d93782SGreg Clayton     {
113544d93782SGreg Clayton         io_handler.SetIsDone(true);
11366e3d8e7fSEugene Zelenko         if (m_regex_cmd_ap)
113744d93782SGreg Clayton         {
113844d93782SGreg Clayton             StringList lines;
113944d93782SGreg Clayton             if (lines.SplitIntoLines (data))
114044d93782SGreg Clayton             {
114144d93782SGreg Clayton                 const size_t num_lines = lines.GetSize();
114244d93782SGreg Clayton                 bool check_only = false;
114344d93782SGreg Clayton                 for (size_t i=0; i<num_lines; ++i)
114444d93782SGreg Clayton                 {
114544d93782SGreg Clayton                     llvm::StringRef bytes_strref (lines[i]);
114644d93782SGreg Clayton                     Error error = AppendRegexSubstitution (bytes_strref, check_only);
114744d93782SGreg Clayton                     if (error.Fail())
114844d93782SGreg Clayton                     {
114944d93782SGreg Clayton                         if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode())
115044d93782SGreg Clayton                         {
115144d93782SGreg Clayton                             StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream();
115244d93782SGreg Clayton                             out_stream->Printf("error: %s\n", error.AsCString());
115344d93782SGreg Clayton                         }
115444d93782SGreg Clayton                     }
115544d93782SGreg Clayton                 }
115644d93782SGreg Clayton             }
115744d93782SGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
115844d93782SGreg Clayton             {
115944d93782SGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
116044d93782SGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
116144d93782SGreg Clayton             }
116244d93782SGreg Clayton         }
116344d93782SGreg Clayton     }
116444d93782SGreg Clayton 
1165de164aaaSGreg Clayton     bool
1166b0a1814fSEric Christopher     DoExecute (Args& command, CommandReturnObject &result) override
1167de164aaaSGreg Clayton     {
11685a988416SJim Ingham         const size_t argc = command.GetArgumentCount();
11690e5e5a79SGreg Clayton         if (argc == 0)
1170de164aaaSGreg Clayton         {
117169c12ccbSJason Molenda             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
11720e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
11730e5e5a79SGreg Clayton         }
11740e5e5a79SGreg Clayton         else
11750e5e5a79SGreg Clayton         {
11760e5e5a79SGreg Clayton             Error error;
11775a988416SJim Ingham             const char *name = command.GetArgumentAtIndex(0);
1178de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
1179de164aaaSGreg Clayton                                                                  name,
1180de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
1181de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
1182b547278cSGreg Clayton                                                                  10,
1183b547278cSGreg Clayton                                                                  0,
1184b547278cSGreg Clayton                                                                  true));
11850e5e5a79SGreg Clayton 
11860e5e5a79SGreg Clayton             if (argc == 1)
11870e5e5a79SGreg Clayton             {
118844d93782SGreg Clayton                 Debugger &debugger = m_interpreter.GetDebugger();
1189e30f11d9SKate Stone                 bool color_prompt = debugger.GetUseColor();
119044d93782SGreg Clayton                 const bool multiple_lines = true; // Get multiple lines
119144d93782SGreg Clayton                 IOHandlerSP io_handler_sp(new IOHandlerEditline(debugger,
1192e30f11d9SKate Stone                                                                 IOHandler::Type::Other,
119373d80faaSGreg Clayton                                                                 "lldb-regex", // Name of input reader for history
1194ea508635SGreg Clayton                                                                 "> ",         // Prompt
11956e3d8e7fSEugene Zelenko                                                                 nullptr,      // Continuation prompt
119644d93782SGreg Clayton                                                                 multiple_lines,
1197e30f11d9SKate Stone                                                                 color_prompt,
1198f6913cd7SGreg Clayton                                                                 0,            // Don't show line numbers
119944d93782SGreg Clayton                                                                 *this));
120044d93782SGreg Clayton 
120144d93782SGreg Clayton                 if (io_handler_sp)
1202de164aaaSGreg Clayton                 {
120344d93782SGreg Clayton                     debugger.PushIOHandler(io_handler_sp);
1204de164aaaSGreg Clayton                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1205de164aaaSGreg Clayton                 }
1206de164aaaSGreg Clayton             }
1207de164aaaSGreg Clayton             else
1208de164aaaSGreg Clayton             {
12090e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
12100e5e5a79SGreg Clayton                 {
12115a988416SJim Ingham                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
121244d93782SGreg Clayton                     bool check_only = false;
121344d93782SGreg Clayton                     error = AppendRegexSubstitution (arg_strref, check_only);
12140e5e5a79SGreg Clayton                     if (error.Fail())
12150e5e5a79SGreg Clayton                         break;
12160e5e5a79SGreg Clayton                 }
12170e5e5a79SGreg Clayton 
12180e5e5a79SGreg Clayton                 if (error.Success())
12190e5e5a79SGreg Clayton                 {
12200e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
12210e5e5a79SGreg Clayton                 }
12220e5e5a79SGreg Clayton             }
12230e5e5a79SGreg Clayton             if (error.Fail())
12240e5e5a79SGreg Clayton             {
12250e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
1226de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
1227de164aaaSGreg Clayton             }
12280e5e5a79SGreg Clayton         }
12290e5e5a79SGreg Clayton 
1230de164aaaSGreg Clayton         return result.Succeeded();
1231de164aaaSGreg Clayton     }
1232de164aaaSGreg Clayton 
12330e5e5a79SGreg Clayton     Error
123444d93782SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed, bool check_only)
1235de164aaaSGreg Clayton     {
12360e5e5a79SGreg Clayton         Error error;
12370e5e5a79SGreg Clayton 
12386e3d8e7fSEugene Zelenko         if (!m_regex_cmd_ap)
1239de164aaaSGreg Clayton         {
12400e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
12410e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12420e5e5a79SGreg Clayton                                            regex_sed.data());
12430e5e5a79SGreg Clayton             return error;
1244de164aaaSGreg Clayton         }
12450e5e5a79SGreg Clayton 
12460e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
12470e5e5a79SGreg Clayton 
12480e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
12490e5e5a79SGreg Clayton         {
12500e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
12510e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12520e5e5a79SGreg Clayton                                            regex_sed.data());
12530e5e5a79SGreg Clayton             return error;
12540e5e5a79SGreg Clayton         }
12550e5e5a79SGreg Clayton 
12560e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
12570e5e5a79SGreg Clayton         {
12580e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
12590e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
12600e5e5a79SGreg Clayton                                            regex_sed.data());
12610e5e5a79SGreg Clayton             return error;
12620e5e5a79SGreg Clayton         }
12630e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
12640e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
12650e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
12660e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
12670e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
12680e5e5a79SGreg Clayton 
12690e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
12700e5e5a79SGreg Clayton         {
1271ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'",
12720e5e5a79SGreg Clayton                                            separator_char,
12730e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
1274ea508635SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1),
1275ea508635SGreg Clayton                                            (int)regex_sed.size(),
1276ea508635SGreg Clayton                                            regex_sed.data());
12770e5e5a79SGreg Clayton             return error;
12780e5e5a79SGreg Clayton         }
12790e5e5a79SGreg Clayton 
12800e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
12810e5e5a79SGreg Clayton 
12820e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
12830e5e5a79SGreg Clayton         {
1284ea508635SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'",
12850e5e5a79SGreg Clayton                                            separator_char,
12860e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
1287ea508635SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1),
1288ea508635SGreg Clayton                                            (int)regex_sed.size(),
1289ea508635SGreg Clayton                                            regex_sed.data());
12900e5e5a79SGreg Clayton             return error;
12910e5e5a79SGreg Clayton         }
12920e5e5a79SGreg Clayton 
12930e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
12940e5e5a79SGreg Clayton         {
12950e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
12960e5e5a79SGreg Clayton             // separator char
12970e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
12980e5e5a79SGreg Clayton             {
12990e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
13000e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
13010e5e5a79SGreg Clayton                                                regex_sed.data(),
13020e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
13030e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
13040e5e5a79SGreg Clayton                 return error;
13050e5e5a79SGreg Clayton             }
13060e5e5a79SGreg Clayton         }
13070e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
13080e5e5a79SGreg Clayton         {
13090e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
13100e5e5a79SGreg Clayton                                            separator_char,
13110e5e5a79SGreg Clayton                                            separator_char,
13120e5e5a79SGreg Clayton                                            separator_char,
13130e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
13140e5e5a79SGreg Clayton                                            regex_sed.data());
13150e5e5a79SGreg Clayton             return error;
13160e5e5a79SGreg Clayton         }
13170e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
13180e5e5a79SGreg Clayton         {
13190e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
13200e5e5a79SGreg Clayton                                            separator_char,
13210e5e5a79SGreg Clayton                                            separator_char,
13220e5e5a79SGreg Clayton                                            separator_char,
13230e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
13240e5e5a79SGreg Clayton                                            regex_sed.data());
13250e5e5a79SGreg Clayton             return error;
13260e5e5a79SGreg Clayton         }
132744d93782SGreg Clayton 
13286e3d8e7fSEugene Zelenko         if (!check_only)
132944d93782SGreg Clayton         {
13300e5e5a79SGreg Clayton             std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
13310e5e5a79SGreg Clayton             std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
13320e5e5a79SGreg Clayton             m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
13330e5e5a79SGreg Clayton                                              subst.c_str());
133444d93782SGreg Clayton         }
13350e5e5a79SGreg Clayton         return error;
1336de164aaaSGreg Clayton     }
1337de164aaaSGreg Clayton 
1338de164aaaSGreg Clayton     void
13390e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
1340de164aaaSGreg Clayton     {
13416e3d8e7fSEugene Zelenko         if (m_regex_cmd_ap)
1342de164aaaSGreg Clayton         {
1343de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
1344de164aaaSGreg Clayton             {
1345de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
1346de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
1347de164aaaSGreg Clayton             }
1348de164aaaSGreg Clayton         }
1349de164aaaSGreg Clayton     }
1350de164aaaSGreg Clayton 
1351de164aaaSGreg Clayton private:
13527b0992d9SGreg Clayton     std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1353de164aaaSGreg Clayton 
1354de164aaaSGreg Clayton      class CommandOptions : public Options
1355de164aaaSGreg Clayton      {
1356de164aaaSGreg Clayton      public:
1357de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
1358de164aaaSGreg Clayton             Options (interpreter)
1359de164aaaSGreg Clayton          {
1360de164aaaSGreg Clayton          }
1361de164aaaSGreg Clayton 
13626e3d8e7fSEugene Zelenko          ~CommandOptions() override = default;
1363de164aaaSGreg Clayton 
136413d21e9aSBruce Mitchener          Error
136513d21e9aSBruce Mitchener          SetOptionValue (uint32_t option_idx, const char *option_arg) override
1366de164aaaSGreg Clayton          {
1367de164aaaSGreg Clayton              Error error;
13683bcdfc0eSGreg Clayton              const int short_option = m_getopt_table[option_idx].val;
1369de164aaaSGreg Clayton 
1370de164aaaSGreg Clayton              switch (short_option)
1371de164aaaSGreg Clayton              {
1372de164aaaSGreg Clayton                  case 'h':
1373de164aaaSGreg Clayton                      m_help.assign (option_arg);
1374de164aaaSGreg Clayton                      break;
1375de164aaaSGreg Clayton                  case 's':
1376de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1377de164aaaSGreg Clayton                      break;
1378de164aaaSGreg Clayton                  default:
137986edbf41SGreg Clayton                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1380de164aaaSGreg Clayton                      break;
1381de164aaaSGreg Clayton              }
1382de164aaaSGreg Clayton 
1383de164aaaSGreg Clayton              return error;
1384de164aaaSGreg Clayton          }
1385de164aaaSGreg Clayton 
1386de164aaaSGreg Clayton          void
138713d21e9aSBruce Mitchener          OptionParsingStarting () override
1388de164aaaSGreg Clayton          {
1389de164aaaSGreg Clayton              m_help.clear();
1390de164aaaSGreg Clayton              m_syntax.clear();
1391de164aaaSGreg Clayton          }
1392de164aaaSGreg Clayton 
1393de164aaaSGreg Clayton          const OptionDefinition*
139413d21e9aSBruce Mitchener          GetDefinitions () override
1395de164aaaSGreg Clayton          {
1396de164aaaSGreg Clayton              return g_option_table;
1397de164aaaSGreg Clayton          }
1398de164aaaSGreg Clayton 
1399de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1400de164aaaSGreg Clayton 
1401de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1402de164aaaSGreg Clayton 
1403de164aaaSGreg Clayton          const char *
1404de164aaaSGreg Clayton          GetHelp()
1405de164aaaSGreg Clayton          {
14066e3d8e7fSEugene Zelenko              return (m_help.empty() ? nullptr : m_help.c_str());
1407de164aaaSGreg Clayton          }
14086e3d8e7fSEugene Zelenko 
1409de164aaaSGreg Clayton          const char *
1410de164aaaSGreg Clayton          GetSyntax ()
1411de164aaaSGreg Clayton          {
14126e3d8e7fSEugene Zelenko              return (m_syntax.empty() ? nullptr : m_syntax.c_str());
1413de164aaaSGreg Clayton          }
14146e3d8e7fSEugene Zelenko 
1415de164aaaSGreg Clayton      protected:
14166e3d8e7fSEugene Zelenko          // Instance variables to hold the values for command options.
14176e3d8e7fSEugene Zelenko 
1418de164aaaSGreg Clayton          std::string m_help;
1419de164aaaSGreg Clayton          std::string m_syntax;
1420de164aaaSGreg Clayton      };
1421de164aaaSGreg Clayton 
1422b0a1814fSEric Christopher      Options *
1423b0a1814fSEric Christopher      GetOptions () override
1424de164aaaSGreg Clayton      {
1425de164aaaSGreg Clayton          return &m_options;
1426de164aaaSGreg Clayton      }
1427de164aaaSGreg Clayton 
14285a988416SJim Ingham      CommandOptions m_options;
1429de164aaaSGreg Clayton };
1430de164aaaSGreg Clayton 
1431de164aaaSGreg Clayton OptionDefinition
1432de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1433de164aaaSGreg Clayton {
14346e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command."},
14356e3d8e7fSEugene Zelenko { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
14366e3d8e7fSEugene Zelenko { 0             , false,  nullptr   , 0  , 0                , nullptr, nullptr, 0, eArgTypeNone, nullptr }
1437de164aaaSGreg Clayton };
1438de164aaaSGreg Clayton 
14395a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw
1440223383edSEnrico Granata {
1441223383edSEnrico Granata public:
1442223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1443223383edSEnrico Granata                                  std::string name,
14440a305db7SEnrico Granata                                  std::string funct,
1445735152e3SEnrico Granata                                  std::string help,
14460a305db7SEnrico Granata                                  ScriptedCommandSynchronicity synch) :
14475a988416SJim Ingham         CommandObjectRaw(interpreter,
1448223383edSEnrico Granata                          name.c_str(),
14496e3d8e7fSEugene Zelenko                          nullptr,
14506e3d8e7fSEugene Zelenko                          nullptr),
14510a305db7SEnrico Granata         m_function_name(funct),
1452fac939e9SEnrico Granata         m_synchro(synch),
1453fac939e9SEnrico Granata         m_fetched_help_long(false)
1454223383edSEnrico Granata     {
1455735152e3SEnrico Granata         if (!help.empty())
1456735152e3SEnrico Granata             SetHelp(help.c_str());
1457735152e3SEnrico Granata         else
1458735152e3SEnrico Granata         {
1459735152e3SEnrico Granata             StreamString stream;
1460735152e3SEnrico Granata             stream.Printf("For more information run 'help %s'",name.c_str());
1461735152e3SEnrico Granata             SetHelp(stream.GetData());
1462735152e3SEnrico Granata         }
1463223383edSEnrico Granata     }
1464223383edSEnrico Granata 
14656e3d8e7fSEugene Zelenko     ~CommandObjectPythonFunction() override = default;
1466223383edSEnrico Granata 
146713d21e9aSBruce Mitchener     bool
146813d21e9aSBruce Mitchener     IsRemovable () const override
14695a988416SJim Ingham     {
14705a988416SJim Ingham         return true;
14715a988416SJim Ingham     }
14725a988416SJim Ingham 
14735a988416SJim Ingham     const std::string&
14745a988416SJim Ingham     GetFunctionName ()
14755a988416SJim Ingham     {
14765a988416SJim Ingham         return m_function_name;
14775a988416SJim Ingham     }
14785a988416SJim Ingham 
14795a988416SJim Ingham     ScriptedCommandSynchronicity
14805a988416SJim Ingham     GetSynchronicity ()
14815a988416SJim Ingham     {
14825a988416SJim Ingham         return m_synchro;
14835a988416SJim Ingham     }
14845a988416SJim Ingham 
148513d21e9aSBruce Mitchener     const char *
148613d21e9aSBruce Mitchener     GetHelpLong () override
1487fac939e9SEnrico Granata     {
1488fac939e9SEnrico Granata         if (!m_fetched_help_long)
1489fac939e9SEnrico Granata         {
1490fac939e9SEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1491fac939e9SEnrico Granata             if (scripter)
1492fac939e9SEnrico Granata             {
1493fac939e9SEnrico Granata                 std::string docstring;
1494fac939e9SEnrico Granata                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1495fac939e9SEnrico Granata                 if (!docstring.empty())
1496bfb75e9bSEnrico Granata                     SetHelpLong(docstring.c_str());
1497fac939e9SEnrico Granata             }
1498fac939e9SEnrico Granata         }
1499fac939e9SEnrico Granata         return CommandObjectRaw::GetHelpLong();
1500fac939e9SEnrico Granata     }
1501fac939e9SEnrico Granata 
15025a988416SJim Ingham protected:
150313d21e9aSBruce Mitchener     bool
150413d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
1505223383edSEnrico Granata     {
1506223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1507223383edSEnrico Granata 
1508223383edSEnrico Granata         Error error;
1509223383edSEnrico Granata 
151070f11f88SJim Ingham         result.SetStatus(eReturnStatusInvalid);
151170f11f88SJim Ingham 
15126e3d8e7fSEugene Zelenko         if (!scripter || !scripter->RunScriptBasedCommand(m_function_name.c_str(),
1513223383edSEnrico Granata                                                           raw_command_line,
15140a305db7SEnrico Granata                                                           m_synchro,
1515223383edSEnrico Granata                                                           result,
151606be059aSEnrico Granata                                                           error,
15176e3d8e7fSEugene Zelenko                                                           m_exe_ctx))
1518223383edSEnrico Granata         {
1519223383edSEnrico Granata             result.AppendError(error.AsCString());
1520223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1521223383edSEnrico Granata         }
1522223383edSEnrico Granata         else
152370f11f88SJim Ingham         {
152470f11f88SJim Ingham             // Don't change the status if the command already set it...
152570f11f88SJim Ingham             if (result.GetStatus() == eReturnStatusInvalid)
152670f11f88SJim Ingham             {
15276e3d8e7fSEugene Zelenko                 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
1528223383edSEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
152970f11f88SJim Ingham                 else
153070f11f88SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishResult);
153170f11f88SJim Ingham             }
153270f11f88SJim Ingham         }
1533223383edSEnrico Granata 
1534223383edSEnrico Granata         return result.Succeeded();
1535223383edSEnrico Granata     }
1536223383edSEnrico Granata 
15376e3d8e7fSEugene Zelenko private:
15386e3d8e7fSEugene Zelenko     std::string m_function_name;
15396e3d8e7fSEugene Zelenko     ScriptedCommandSynchronicity m_synchro;
15406e3d8e7fSEugene Zelenko     bool m_fetched_help_long;
1541223383edSEnrico Granata };
1542223383edSEnrico Granata 
15439fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw
15449fe00e52SEnrico Granata {
15459fe00e52SEnrico Granata public:
15469fe00e52SEnrico Granata     CommandObjectScriptingObject (CommandInterpreter &interpreter,
15479fe00e52SEnrico Granata                                   std::string name,
15480641ca1aSZachary Turner                                   StructuredData::GenericSP cmd_obj_sp,
15499fe00e52SEnrico Granata                                   ScriptedCommandSynchronicity synch) :
15509fe00e52SEnrico Granata         CommandObjectRaw(interpreter,
15519fe00e52SEnrico Granata                          name.c_str(),
15526e3d8e7fSEugene Zelenko                          nullptr,
15536e3d8e7fSEugene Zelenko                          nullptr),
15549fe00e52SEnrico Granata         m_cmd_obj_sp(cmd_obj_sp),
15556f79bb2dSEnrico Granata         m_synchro(synch),
15566f79bb2dSEnrico Granata         m_fetched_help_short(false),
15576f79bb2dSEnrico Granata         m_fetched_help_long(false)
15589fe00e52SEnrico Granata     {
15599fe00e52SEnrico Granata         StreamString stream;
15609fe00e52SEnrico Granata         stream.Printf("For more information run 'help %s'",name.c_str());
15619fe00e52SEnrico Granata         SetHelp(stream.GetData());
1562e87764f2SEnrico Granata         if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter())
1563e87764f2SEnrico Granata             GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp));
15649fe00e52SEnrico Granata     }
15659fe00e52SEnrico Granata 
15666e3d8e7fSEugene Zelenko     ~CommandObjectScriptingObject() override = default;
15679fe00e52SEnrico Granata 
156813d21e9aSBruce Mitchener     bool
156913d21e9aSBruce Mitchener     IsRemovable () const override
15709fe00e52SEnrico Granata     {
15719fe00e52SEnrico Granata         return true;
15729fe00e52SEnrico Granata     }
15739fe00e52SEnrico Granata 
15740641ca1aSZachary Turner     StructuredData::GenericSP
15759fe00e52SEnrico Granata     GetImplementingObject ()
15769fe00e52SEnrico Granata     {
15779fe00e52SEnrico Granata         return m_cmd_obj_sp;
15789fe00e52SEnrico Granata     }
15799fe00e52SEnrico Granata 
15809fe00e52SEnrico Granata     ScriptedCommandSynchronicity
15819fe00e52SEnrico Granata     GetSynchronicity ()
15829fe00e52SEnrico Granata     {
15839fe00e52SEnrico Granata         return m_synchro;
15849fe00e52SEnrico Granata     }
15859fe00e52SEnrico Granata 
158613d21e9aSBruce Mitchener     const char *
158713d21e9aSBruce Mitchener     GetHelp () override
15886f79bb2dSEnrico Granata     {
15896f79bb2dSEnrico Granata         if (!m_fetched_help_short)
15906f79bb2dSEnrico Granata         {
15916f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
15926f79bb2dSEnrico Granata             if (scripter)
15936f79bb2dSEnrico Granata             {
15946f79bb2dSEnrico Granata                 std::string docstring;
15956f79bb2dSEnrico Granata                 m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring);
15966f79bb2dSEnrico Granata                 if (!docstring.empty())
1597bfb75e9bSEnrico Granata                     SetHelp(docstring.c_str());
15986f79bb2dSEnrico Granata             }
15996f79bb2dSEnrico Granata         }
16006f79bb2dSEnrico Granata         return CommandObjectRaw::GetHelp();
16016f79bb2dSEnrico Granata     }
16026f79bb2dSEnrico Granata 
160313d21e9aSBruce Mitchener     const char *
160413d21e9aSBruce Mitchener     GetHelpLong () override
16059fe00e52SEnrico Granata     {
16066f79bb2dSEnrico Granata         if (!m_fetched_help_long)
16076f79bb2dSEnrico Granata         {
16086f79bb2dSEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
16096f79bb2dSEnrico Granata             if (scripter)
16106f79bb2dSEnrico Granata             {
16116f79bb2dSEnrico Granata                 std::string docstring;
16126f79bb2dSEnrico Granata                 m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring);
16136f79bb2dSEnrico Granata                 if (!docstring.empty())
1614bfb75e9bSEnrico Granata                     SetHelpLong(docstring.c_str());
16156f79bb2dSEnrico Granata             }
16166f79bb2dSEnrico Granata         }
16179fe00e52SEnrico Granata         return CommandObjectRaw::GetHelpLong();
16189fe00e52SEnrico Granata     }
16199fe00e52SEnrico Granata 
16209fe00e52SEnrico Granata protected:
162113d21e9aSBruce Mitchener     bool
162213d21e9aSBruce Mitchener     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
16239fe00e52SEnrico Granata     {
16249fe00e52SEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
16259fe00e52SEnrico Granata 
16269fe00e52SEnrico Granata         Error error;
16279fe00e52SEnrico Granata 
16289fe00e52SEnrico Granata         result.SetStatus(eReturnStatusInvalid);
16299fe00e52SEnrico Granata 
16306e3d8e7fSEugene Zelenko         if (!scripter || !scripter->RunScriptBasedCommand(m_cmd_obj_sp,
16319fe00e52SEnrico Granata                                                           raw_command_line,
16329fe00e52SEnrico Granata                                                           m_synchro,
16339fe00e52SEnrico Granata                                                           result,
16349fe00e52SEnrico Granata                                                           error,
16356e3d8e7fSEugene Zelenko                                                           m_exe_ctx))
16369fe00e52SEnrico Granata         {
16379fe00e52SEnrico Granata             result.AppendError(error.AsCString());
16389fe00e52SEnrico Granata             result.SetStatus(eReturnStatusFailed);
16399fe00e52SEnrico Granata         }
16409fe00e52SEnrico Granata         else
16419fe00e52SEnrico Granata         {
16429fe00e52SEnrico Granata             // Don't change the status if the command already set it...
16439fe00e52SEnrico Granata             if (result.GetStatus() == eReturnStatusInvalid)
16449fe00e52SEnrico Granata             {
16456e3d8e7fSEugene Zelenko                 if (result.GetOutputData() == nullptr || result.GetOutputData()[0] == '\0')
16469fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
16479fe00e52SEnrico Granata                 else
16489fe00e52SEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishResult);
16499fe00e52SEnrico Granata             }
16509fe00e52SEnrico Granata         }
16519fe00e52SEnrico Granata 
16529fe00e52SEnrico Granata         return result.Succeeded();
16539fe00e52SEnrico Granata     }
16549fe00e52SEnrico Granata 
16556e3d8e7fSEugene Zelenko private:
16566e3d8e7fSEugene Zelenko     StructuredData::GenericSP m_cmd_obj_sp;
16576e3d8e7fSEugene Zelenko     ScriptedCommandSynchronicity m_synchro;
16586e3d8e7fSEugene Zelenko     bool m_fetched_help_short: 1;
16596e3d8e7fSEugene Zelenko     bool m_fetched_help_long: 1;
16609fe00e52SEnrico Granata };
16619fe00e52SEnrico Granata 
1662a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1663a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport
1664a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1665a9dbf432SEnrico Granata 
16665a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed
1667a9dbf432SEnrico Granata {
16685a988416SJim Ingham public:
16695a988416SJim Ingham     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
16705a988416SJim Ingham         CommandObjectParsed(interpreter,
16715a988416SJim Ingham                             "command script import",
16725a988416SJim Ingham                             "Import a scripting module in LLDB.",
16736e3d8e7fSEugene Zelenko                             nullptr),
16745a988416SJim Ingham         m_options(interpreter)
16755a988416SJim Ingham     {
16765a988416SJim Ingham         CommandArgumentEntry arg1;
16775a988416SJim Ingham         CommandArgumentData cmd_arg;
16785a988416SJim Ingham 
16795a988416SJim Ingham         // Define the first (and only) variant of this arg.
16805a988416SJim Ingham         cmd_arg.arg_type = eArgTypeFilename;
16813b00e35bSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlus;
16825a988416SJim Ingham 
16835a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
16845a988416SJim Ingham         arg1.push_back (cmd_arg);
16855a988416SJim Ingham 
16865a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
16875a988416SJim Ingham         m_arguments.push_back (arg1);
16885a988416SJim Ingham     }
16895a988416SJim Ingham 
16906e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptImport() override = default;
16915a988416SJim Ingham 
169213d21e9aSBruce Mitchener     int
16935a988416SJim Ingham     HandleArgumentCompletion (Args &input,
16945a988416SJim Ingham                               int &cursor_index,
16955a988416SJim Ingham                               int &cursor_char_position,
16965a988416SJim Ingham                               OptionElementVector &opt_element_vector,
16975a988416SJim Ingham                               int match_start_point,
16985a988416SJim Ingham                               int max_return_elements,
16995a988416SJim Ingham                               bool &word_complete,
170013d21e9aSBruce Mitchener                               StringList &matches) override
17015a988416SJim Ingham     {
17025a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
17035a988416SJim Ingham         completion_str.erase (cursor_char_position);
17045a988416SJim Ingham 
17055a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks(m_interpreter,
17065a988416SJim Ingham                                                             CommandCompletions::eDiskFileCompletion,
17075a988416SJim Ingham                                                             completion_str.c_str(),
17085a988416SJim Ingham                                                             match_start_point,
17095a988416SJim Ingham                                                             max_return_elements,
17106e3d8e7fSEugene Zelenko                                                             nullptr,
17115a988416SJim Ingham                                                             word_complete,
17125a988416SJim Ingham                                                             matches);
17135a988416SJim Ingham         return matches.GetSize();
17145a988416SJim Ingham     }
17155a988416SJim Ingham 
171613d21e9aSBruce Mitchener     Options *
171713d21e9aSBruce Mitchener     GetOptions () override
17185a988416SJim Ingham     {
17195a988416SJim Ingham         return &m_options;
17205a988416SJim Ingham     }
17215a988416SJim Ingham 
17225a988416SJim Ingham protected:
17230a305db7SEnrico Granata     class CommandOptions : public Options
17240a305db7SEnrico Granata     {
17250a305db7SEnrico Granata     public:
17260a305db7SEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
17270a305db7SEnrico Granata             Options (interpreter)
17280a305db7SEnrico Granata         {
17290a305db7SEnrico Granata         }
17300a305db7SEnrico Granata 
17316e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
17320a305db7SEnrico Granata 
173313d21e9aSBruce Mitchener         Error
173413d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
17350a305db7SEnrico Granata         {
17360a305db7SEnrico Granata             Error error;
17373bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
17380a305db7SEnrico Granata 
17390a305db7SEnrico Granata             switch (short_option)
17400a305db7SEnrico Granata             {
17410a305db7SEnrico Granata                 case 'r':
17420a305db7SEnrico Granata                     m_allow_reload = true;
17430a305db7SEnrico Granata                     break;
17440a305db7SEnrico Granata                 default:
17450a305db7SEnrico Granata                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
17460a305db7SEnrico Granata                     break;
17470a305db7SEnrico Granata             }
17480a305db7SEnrico Granata 
17490a305db7SEnrico Granata             return error;
17500a305db7SEnrico Granata         }
17510a305db7SEnrico Granata 
17520a305db7SEnrico Granata         void
175313d21e9aSBruce Mitchener         OptionParsingStarting () override
17540a305db7SEnrico Granata         {
1755e0c70f1bSEnrico Granata             m_allow_reload = true;
17560a305db7SEnrico Granata         }
17570a305db7SEnrico Granata 
17580a305db7SEnrico Granata         const OptionDefinition*
175913d21e9aSBruce Mitchener         GetDefinitions () override
17600a305db7SEnrico Granata         {
17610a305db7SEnrico Granata             return g_option_table;
17620a305db7SEnrico Granata         }
17630a305db7SEnrico Granata 
17640a305db7SEnrico Granata         // Options table: Required for subclasses of Options.
17650a305db7SEnrico Granata 
17660a305db7SEnrico Granata         static OptionDefinition g_option_table[];
17670a305db7SEnrico Granata 
17680a305db7SEnrico Granata         // Instance variables to hold the values for command options.
17690a305db7SEnrico Granata 
17700a305db7SEnrico Granata         bool m_allow_reload;
17710a305db7SEnrico Granata     };
17720a305db7SEnrico Granata 
1773a9dbf432SEnrico Granata     bool
177413d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
1775a9dbf432SEnrico Granata     {
1776a9dbf432SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1777a9dbf432SEnrico Granata         {
1778a9dbf432SEnrico Granata             result.AppendError ("only scripting language supported for module importing is currently Python");
1779a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1780a9dbf432SEnrico Granata             return false;
1781a9dbf432SEnrico Granata         }
1782a9dbf432SEnrico Granata 
17835a988416SJim Ingham         size_t argc = command.GetArgumentCount();
17843b00e35bSEnrico Granata         if (0 == argc)
1785a9dbf432SEnrico Granata         {
17863b00e35bSEnrico Granata             result.AppendError("command script import needs one or more arguments");
1787a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1788a9dbf432SEnrico Granata             return false;
1789a9dbf432SEnrico Granata         }
1790a9dbf432SEnrico Granata 
17910e978481SEd Maste         for (size_t i = 0;
17923b00e35bSEnrico Granata              i < argc;
17933b00e35bSEnrico Granata              i++)
17943b00e35bSEnrico Granata         {
17953b00e35bSEnrico Granata             std::string path = command.GetArgumentAtIndex(i);
1796a9dbf432SEnrico Granata             Error error;
1797a9dbf432SEnrico Granata 
1798c9d645d3SGreg Clayton             const bool init_session = true;
1799078551c7SEnrico Granata             // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1800078551c7SEnrico Granata             // commands won't ever be recursively invoked, but it's actually possible to craft
1801078551c7SEnrico Granata             // a Python script that does other "command script imports" in __lldb_init_module
1802078551c7SEnrico Granata             // the real fix is to have recursive commands possible with a CommandInvocation object
1803078551c7SEnrico Granata             // separate from the CommandObject itself, so that recursive command invocations
1804078551c7SEnrico Granata             // won't stomp on each other (wrt to execution contents, options, and more)
1805078551c7SEnrico Granata             m_exe_ctx.Clear();
1806a9dbf432SEnrico Granata             if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
18070a305db7SEnrico Granata                                                                           m_options.m_allow_reload,
1808c9d645d3SGreg Clayton                                                                           init_session,
1809a9dbf432SEnrico Granata                                                                           error))
1810a9dbf432SEnrico Granata             {
1811a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1812a9dbf432SEnrico Granata             }
1813a9dbf432SEnrico Granata             else
1814a9dbf432SEnrico Granata             {
1815a9dbf432SEnrico Granata                 result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1816a9dbf432SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1817a9dbf432SEnrico Granata             }
18183b00e35bSEnrico Granata         }
1819a9dbf432SEnrico Granata 
1820a9dbf432SEnrico Granata         return result.Succeeded();
1821a9dbf432SEnrico Granata     }
18220a305db7SEnrico Granata 
18235a988416SJim Ingham     CommandOptions m_options;
1824a9dbf432SEnrico Granata };
1825223383edSEnrico Granata 
18260a305db7SEnrico Granata OptionDefinition
18270a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
18280a305db7SEnrico Granata {
18296e3d8e7fSEugene 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."},
18306e3d8e7fSEugene Zelenko     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
18310a305db7SEnrico Granata };
18320a305db7SEnrico Granata 
1833223383edSEnrico Granata //-------------------------------------------------------------------------
1834223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1835223383edSEnrico Granata //-------------------------------------------------------------------------
1836223383edSEnrico Granata 
183744d93782SGreg Clayton class CommandObjectCommandsScriptAdd :
183844d93782SGreg Clayton     public CommandObjectParsed,
183944d93782SGreg Clayton     public IOHandlerDelegateMultiline
1840223383edSEnrico Granata {
18415a988416SJim Ingham public:
18425a988416SJim Ingham     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
18435a988416SJim Ingham         CommandObjectParsed(interpreter,
18445a988416SJim Ingham                             "command script add",
18455a988416SJim Ingham                             "Add a scripted function as an LLDB command.",
18466e3d8e7fSEugene Zelenko                             nullptr),
1847c3d874a5SGreg Clayton         IOHandlerDelegateMultiline ("DONE"),
18485a988416SJim Ingham         m_options (interpreter)
18495a988416SJim Ingham     {
18505a988416SJim Ingham         CommandArgumentEntry arg1;
18515a988416SJim Ingham         CommandArgumentData cmd_arg;
18525a988416SJim Ingham 
18535a988416SJim Ingham         // Define the first (and only) variant of this arg.
18545a988416SJim Ingham         cmd_arg.arg_type = eArgTypeCommandName;
18555a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
18565a988416SJim Ingham 
18575a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
18585a988416SJim Ingham         arg1.push_back (cmd_arg);
18595a988416SJim Ingham 
18605a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
18615a988416SJim Ingham         m_arguments.push_back (arg1);
18625a988416SJim Ingham     }
18635a988416SJim Ingham 
18646e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptAdd() override = default;
18655a988416SJim Ingham 
186613d21e9aSBruce Mitchener     Options *
186713d21e9aSBruce Mitchener     GetOptions () override
18685a988416SJim Ingham     {
18695a988416SJim Ingham         return &m_options;
18705a988416SJim Ingham     }
18715a988416SJim Ingham 
18725a988416SJim Ingham protected:
1873223383edSEnrico Granata     class CommandOptions : public Options
1874223383edSEnrico Granata     {
1875223383edSEnrico Granata     public:
1876223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
18779fe00e52SEnrico Granata             Options (interpreter),
18789fe00e52SEnrico Granata             m_class_name(),
18799fe00e52SEnrico Granata             m_funct_name(),
18809fe00e52SEnrico Granata             m_short_help(),
18819fe00e52SEnrico Granata             m_synchronicity(eScriptedCommandSynchronicitySynchronous)
1882223383edSEnrico Granata         {
1883223383edSEnrico Granata         }
1884223383edSEnrico Granata 
18856e3d8e7fSEugene Zelenko         ~CommandOptions() override = default;
1886223383edSEnrico Granata 
188713d21e9aSBruce Mitchener         Error
188813d21e9aSBruce Mitchener         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1889223383edSEnrico Granata         {
1890223383edSEnrico Granata             Error error;
18913bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
1892223383edSEnrico Granata 
1893223383edSEnrico Granata             switch (short_option)
1894223383edSEnrico Granata             {
1895223383edSEnrico Granata                 case 'f':
1896735152e3SEnrico Granata                     if (option_arg)
1897735152e3SEnrico Granata                         m_funct_name.assign(option_arg);
1898735152e3SEnrico Granata                     break;
18999fe00e52SEnrico Granata                 case 'c':
19009fe00e52SEnrico Granata                     if (option_arg)
19019fe00e52SEnrico Granata                         m_class_name.assign(option_arg);
19029fe00e52SEnrico Granata                     break;
1903735152e3SEnrico Granata                 case 'h':
1904735152e3SEnrico Granata                     if (option_arg)
1905735152e3SEnrico Granata                         m_short_help.assign(option_arg);
1906223383edSEnrico Granata                     break;
19070a305db7SEnrico Granata                 case 's':
190844d93782SGreg Clayton                     m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
19090a305db7SEnrico Granata                     if (!error.Success())
19100a305db7SEnrico Granata                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
19110a305db7SEnrico Granata                     break;
1912223383edSEnrico Granata                 default:
191386edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1914223383edSEnrico Granata                     break;
1915223383edSEnrico Granata             }
1916223383edSEnrico Granata 
1917223383edSEnrico Granata             return error;
1918223383edSEnrico Granata         }
1919223383edSEnrico Granata 
1920223383edSEnrico Granata         void
192113d21e9aSBruce Mitchener         OptionParsingStarting () override
1922223383edSEnrico Granata         {
19239fe00e52SEnrico Granata             m_class_name.clear();
1924735152e3SEnrico Granata             m_funct_name.clear();
1925735152e3SEnrico Granata             m_short_help.clear();
192644d93782SGreg Clayton             m_synchronicity = eScriptedCommandSynchronicitySynchronous;
1927223383edSEnrico Granata         }
1928223383edSEnrico Granata 
1929223383edSEnrico Granata         const OptionDefinition*
193013d21e9aSBruce Mitchener         GetDefinitions () override
1931223383edSEnrico Granata         {
1932223383edSEnrico Granata             return g_option_table;
1933223383edSEnrico Granata         }
1934223383edSEnrico Granata 
1935223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1936223383edSEnrico Granata 
1937223383edSEnrico Granata         static OptionDefinition g_option_table[];
1938223383edSEnrico Granata 
1939223383edSEnrico Granata         // Instance variables to hold the values for command options.
1940223383edSEnrico Granata 
19419fe00e52SEnrico Granata         std::string m_class_name;
1942223383edSEnrico Granata         std::string m_funct_name;
1943735152e3SEnrico Granata         std::string m_short_help;
194444d93782SGreg Clayton         ScriptedCommandSynchronicity m_synchronicity;
1945223383edSEnrico Granata     };
1946223383edSEnrico Granata 
194713d21e9aSBruce Mitchener     void
194813d21e9aSBruce Mitchener     IOHandlerActivated (IOHandler &io_handler) override
1949223383edSEnrico Granata     {
195044d93782SGreg Clayton         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
195144d93782SGreg Clayton         if (output_sp)
1952223383edSEnrico Granata         {
195344d93782SGreg Clayton             output_sp->PutCString(g_python_command_instructions);
195444d93782SGreg Clayton             output_sp->Flush();
1955223383edSEnrico Granata         }
1956223383edSEnrico Granata     }
1957223383edSEnrico Granata 
1958223383edSEnrico Granata 
195913d21e9aSBruce Mitchener     void
196013d21e9aSBruce Mitchener     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
1961223383edSEnrico Granata     {
196244d93782SGreg Clayton         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
196344d93782SGreg Clayton 
196444d93782SGreg Clayton         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
196544d93782SGreg Clayton         if (interpreter)
196644d93782SGreg Clayton         {
196744d93782SGreg Clayton 
196844d93782SGreg Clayton             StringList lines;
196944d93782SGreg Clayton             lines.SplitIntoLines(data);
197044d93782SGreg Clayton             if (lines.GetSize() > 0)
197144d93782SGreg Clayton             {
1972a73b7df7SEnrico Granata                 std::string funct_name_str;
197344d93782SGreg Clayton                 if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str))
1974223383edSEnrico Granata                 {
1975a73b7df7SEnrico Granata                     if (funct_name_str.empty())
1976223383edSEnrico Granata                     {
197744d93782SGreg Clayton                         error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n");
197844d93782SGreg Clayton                         error_sp->Flush();
1979223383edSEnrico Granata                     }
198044d93782SGreg Clayton                     else
198144d93782SGreg Clayton                     {
1982223383edSEnrico Granata                         // everything should be fine now, let's add this alias
1983223383edSEnrico Granata 
1984223383edSEnrico Granata                         CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter,
1985223383edSEnrico Granata                                                                                         m_cmd_name,
1986a73b7df7SEnrico Granata                                                                                         funct_name_str.c_str(),
1987735152e3SEnrico Granata                                                                                         m_short_help,
198844d93782SGreg Clayton                                                                                         m_synchronicity));
1989223383edSEnrico Granata 
19900a305db7SEnrico Granata                         if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1991223383edSEnrico Granata                         {
199244d93782SGreg Clayton                             error_sp->Printf ("error: unable to add selected command, didn't add python command.\n");
199344d93782SGreg Clayton                             error_sp->Flush();
1994223383edSEnrico Granata                         }
1995223383edSEnrico Granata                     }
199644d93782SGreg Clayton                 }
199744d93782SGreg Clayton                 else
199844d93782SGreg Clayton                 {
199944d93782SGreg Clayton                     error_sp->Printf ("error: unable to create function, didn't add python command.\n");
200044d93782SGreg Clayton                     error_sp->Flush();
200144d93782SGreg Clayton                 }
200244d93782SGreg Clayton             }
200344d93782SGreg Clayton             else
200444d93782SGreg Clayton             {
200544d93782SGreg Clayton                 error_sp->Printf ("error: empty function, didn't add python command.\n");
200644d93782SGreg Clayton                 error_sp->Flush();
200744d93782SGreg Clayton             }
200844d93782SGreg Clayton         }
200944d93782SGreg Clayton         else
201044d93782SGreg Clayton         {
201144d93782SGreg Clayton             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
201244d93782SGreg Clayton             error_sp->Flush();
201344d93782SGreg Clayton         }
201444d93782SGreg Clayton 
201544d93782SGreg Clayton         io_handler.SetIsDone(true);
201644d93782SGreg Clayton     }
2017223383edSEnrico Granata 
20185a988416SJim Ingham protected:
2019223383edSEnrico Granata     bool
202013d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2021223383edSEnrico Granata     {
202299f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
202399f0b8f9SEnrico Granata         {
202499f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
202599f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
202699f0b8f9SEnrico Granata             return false;
202799f0b8f9SEnrico Granata         }
202899f0b8f9SEnrico Granata 
20295a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2030223383edSEnrico Granata 
2031223383edSEnrico Granata         if (argc != 1)
2032223383edSEnrico Granata         {
2033223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
2034223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2035223383edSEnrico Granata             return false;
2036223383edSEnrico Granata         }
2037223383edSEnrico Granata 
2038735152e3SEnrico Granata         // Store the options in case we get multi-line input
203944d93782SGreg Clayton         m_cmd_name = command.GetArgumentAtIndex(0);
2040735152e3SEnrico Granata         m_short_help.assign(m_options.m_short_help);
204144d93782SGreg Clayton         m_synchronicity = m_options.m_synchronicity;
2042223383edSEnrico Granata 
20439fe00e52SEnrico Granata         if (m_options.m_class_name.empty())
20449fe00e52SEnrico Granata         {
2045223383edSEnrico Granata             if (m_options.m_funct_name.empty())
2046223383edSEnrico Granata             {
204744d93782SGreg Clayton                 m_interpreter.GetPythonCommandsFromIOHandler("     ",  // Prompt
204844d93782SGreg Clayton                                                              *this,    // IOHandlerDelegate
204944d93782SGreg Clayton                                                              true,     // Run IOHandler in async mode
20506e3d8e7fSEugene Zelenko                                                              nullptr); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
2051223383edSEnrico Granata             }
2052223383edSEnrico Granata             else
2053223383edSEnrico Granata             {
20540a305db7SEnrico Granata                 CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
205544d93782SGreg Clayton                                                                         m_cmd_name,
20560a305db7SEnrico Granata                                                                         m_options.m_funct_name,
2057735152e3SEnrico Granata                                                                         m_options.m_short_help,
205844d93782SGreg Clayton                                                                         m_synchronicity));
205944d93782SGreg Clayton                 if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
2060223383edSEnrico Granata                 {
2061223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
2062223383edSEnrico Granata                 }
2063223383edSEnrico Granata                 else
2064223383edSEnrico Granata                 {
2065223383edSEnrico Granata                     result.AppendError("cannot add command");
2066223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
2067223383edSEnrico Granata                 }
2068223383edSEnrico Granata             }
20699fe00e52SEnrico Granata         }
20709fe00e52SEnrico Granata         else
20719fe00e52SEnrico Granata         {
20729fe00e52SEnrico Granata             ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter();
20739fe00e52SEnrico Granata             if (!interpreter)
20749fe00e52SEnrico Granata             {
20759fe00e52SEnrico Granata                 result.AppendError("cannot find ScriptInterpreter");
20769fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
20779fe00e52SEnrico Granata                 return false;
20789fe00e52SEnrico Granata             }
20799fe00e52SEnrico Granata 
20809fe00e52SEnrico Granata             auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str());
20819fe00e52SEnrico Granata             if (!cmd_obj_sp)
20829fe00e52SEnrico Granata             {
20839fe00e52SEnrico Granata                 result.AppendError("cannot create helper object");
20849fe00e52SEnrico Granata                 result.SetStatus(eReturnStatusFailed);
20859fe00e52SEnrico Granata                 return false;
20869fe00e52SEnrico Granata             }
20879fe00e52SEnrico Granata 
20889fe00e52SEnrico Granata             CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter,
20899fe00e52SEnrico Granata                                                                      m_cmd_name,
20909fe00e52SEnrico Granata                                                                      cmd_obj_sp,
20919fe00e52SEnrico Granata                                                                      m_synchronicity));
20929fe00e52SEnrico Granata             if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true))
20939fe00e52SEnrico Granata             {
20949fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
20959fe00e52SEnrico Granata             }
20969fe00e52SEnrico Granata             else
20979fe00e52SEnrico Granata             {
20989fe00e52SEnrico Granata                 result.AppendError("cannot add command");
20999fe00e52SEnrico Granata                 result.SetStatus (eReturnStatusFailed);
21009fe00e52SEnrico Granata             }
21019fe00e52SEnrico Granata         }
2102223383edSEnrico Granata 
2103223383edSEnrico Granata         return result.Succeeded();
2104223383edSEnrico Granata     }
21055a988416SJim Ingham 
21065a988416SJim Ingham     CommandOptions m_options;
210744d93782SGreg Clayton     std::string m_cmd_name;
2108735152e3SEnrico Granata     std::string m_short_help;
210944d93782SGreg Clayton     ScriptedCommandSynchronicity m_synchronicity;
2110223383edSEnrico Granata };
2111223383edSEnrico Granata 
21120a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] =
21130a305db7SEnrico Granata {
21140a305db7SEnrico Granata     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
21150a305db7SEnrico Granata     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
21160a305db7SEnrico Granata     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
21176e3d8e7fSEugene Zelenko     { 0, nullptr, nullptr }
21180a305db7SEnrico Granata };
21190a305db7SEnrico Granata 
2120223383edSEnrico Granata OptionDefinition
2121223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
2122223383edSEnrico Granata {
21236e3d8e7fSEugene 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."},
21246e3d8e7fSEugene 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."},
21256e3d8e7fSEugene Zelenko     { LLDB_OPT_SET_1, false, "help"  , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command."},
21266e3d8e7fSEugene 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."},
21276e3d8e7fSEugene Zelenko     { 0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
2128223383edSEnrico Granata };
2129223383edSEnrico Granata 
2130223383edSEnrico Granata //-------------------------------------------------------------------------
2131223383edSEnrico Granata // CommandObjectCommandsScriptList
2132223383edSEnrico Granata //-------------------------------------------------------------------------
2133223383edSEnrico Granata 
21345a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed
2135223383edSEnrico Granata {
2136223383edSEnrico Granata public:
2137223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
21385a988416SJim Ingham         CommandObjectParsed(interpreter,
2139223383edSEnrico Granata                             "command script list",
2140223383edSEnrico Granata                             "List defined scripted commands.",
21416e3d8e7fSEugene Zelenko                             nullptr)
2142223383edSEnrico Granata     {
2143223383edSEnrico Granata     }
2144223383edSEnrico Granata 
21456e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptList() override = default;
2146223383edSEnrico Granata 
2147223383edSEnrico Granata     bool
214813d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2149223383edSEnrico Granata     {
2150223383edSEnrico Granata         m_interpreter.GetHelp(result,
2151223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
2152223383edSEnrico Granata 
2153223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2154223383edSEnrico Granata 
2155223383edSEnrico Granata         return true;
2156223383edSEnrico Granata     }
2157223383edSEnrico Granata };
2158223383edSEnrico Granata 
2159223383edSEnrico Granata //-------------------------------------------------------------------------
2160223383edSEnrico Granata // CommandObjectCommandsScriptClear
2161223383edSEnrico Granata //-------------------------------------------------------------------------
2162223383edSEnrico Granata 
21635a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed
2164223383edSEnrico Granata {
2165223383edSEnrico Granata public:
2166223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
21675a988416SJim Ingham         CommandObjectParsed(interpreter,
2168223383edSEnrico Granata                             "command script clear",
2169223383edSEnrico Granata                             "Delete all scripted commands.",
21706e3d8e7fSEugene Zelenko                             nullptr)
2171223383edSEnrico Granata     {
2172223383edSEnrico Granata     }
2173223383edSEnrico Granata 
21746e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptClear() override = default;
2175223383edSEnrico Granata 
21765a988416SJim Ingham protected:
2177223383edSEnrico Granata     bool
217813d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2179223383edSEnrico Granata     {
2180223383edSEnrico Granata         m_interpreter.RemoveAllUser();
2181223383edSEnrico Granata 
2182223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
2183223383edSEnrico Granata 
2184223383edSEnrico Granata         return true;
2185223383edSEnrico Granata     }
2186223383edSEnrico Granata };
2187223383edSEnrico Granata 
2188223383edSEnrico Granata //-------------------------------------------------------------------------
2189223383edSEnrico Granata // CommandObjectCommandsScriptDelete
2190223383edSEnrico Granata //-------------------------------------------------------------------------
2191223383edSEnrico Granata 
21925a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed
2193223383edSEnrico Granata {
2194223383edSEnrico Granata public:
2195223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
21965a988416SJim Ingham         CommandObjectParsed(interpreter,
2197223383edSEnrico Granata                             "command script delete",
2198223383edSEnrico Granata                             "Delete a scripted command.",
21996e3d8e7fSEugene Zelenko                             nullptr)
2200223383edSEnrico Granata     {
2201223383edSEnrico Granata         CommandArgumentEntry arg1;
2202223383edSEnrico Granata         CommandArgumentData cmd_arg;
2203223383edSEnrico Granata 
2204223383edSEnrico Granata         // Define the first (and only) variant of this arg.
2205223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
2206223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
2207223383edSEnrico Granata 
2208223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
2209223383edSEnrico Granata         arg1.push_back (cmd_arg);
2210223383edSEnrico Granata 
2211223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
2212223383edSEnrico Granata         m_arguments.push_back (arg1);
2213223383edSEnrico Granata     }
2214223383edSEnrico Granata 
22156e3d8e7fSEugene Zelenko     ~CommandObjectCommandsScriptDelete() override = default;
2216223383edSEnrico Granata 
22175a988416SJim Ingham protected:
2218223383edSEnrico Granata     bool
221913d21e9aSBruce Mitchener     DoExecute (Args& command, CommandReturnObject &result) override
2220223383edSEnrico Granata     {
2221223383edSEnrico Granata 
22225a988416SJim Ingham         size_t argc = command.GetArgumentCount();
2223223383edSEnrico Granata 
2224223383edSEnrico Granata         if (argc != 1)
2225223383edSEnrico Granata         {
2226223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
2227223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2228223383edSEnrico Granata             return false;
2229223383edSEnrico Granata         }
2230223383edSEnrico Granata 
22315a988416SJim Ingham         const char* cmd_name = command.GetArgumentAtIndex(0);
2232223383edSEnrico Granata 
2233223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
2234223383edSEnrico Granata         {
2235223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
2236223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
2237223383edSEnrico Granata         }
2238223383edSEnrico Granata         else
2239223383edSEnrico Granata         {
2240223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
2241223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
2242223383edSEnrico Granata         }
2243223383edSEnrico Granata 
2244223383edSEnrico Granata         return result.Succeeded();
2245223383edSEnrico Granata     }
2246223383edSEnrico Granata };
2247223383edSEnrico Granata 
2248223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
2249223383edSEnrico Granata 
2250223383edSEnrico Granata //-------------------------------------------------------------------------
2251223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
2252223383edSEnrico Granata //-------------------------------------------------------------------------
2253223383edSEnrico Granata 
2254223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
2255223383edSEnrico Granata {
2256223383edSEnrico Granata public:
2257223383edSEnrico Granata     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
2258223383edSEnrico Granata     CommandObjectMultiword (interpreter,
2259223383edSEnrico Granata                             "command script",
2260223383edSEnrico Granata                             "A set of commands for managing or customizing script commands.",
2261223383edSEnrico Granata                             "command script <subcommand> [<subcommand-options>]")
2262223383edSEnrico Granata     {
2263223383edSEnrico Granata         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
2264223383edSEnrico Granata         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
2265223383edSEnrico Granata         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
2266223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
2267a9dbf432SEnrico Granata         LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
2268223383edSEnrico Granata     }
2269223383edSEnrico Granata 
22706e3d8e7fSEugene Zelenko     ~CommandObjectMultiwordCommandsScript() override = default;
2271223383edSEnrico Granata };
2272223383edSEnrico Granata 
2273ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
2274ebc09c36SJim Ingham 
2275ebc09c36SJim Ingham //-------------------------------------------------------------------------
2276ebc09c36SJim Ingham // CommandObjectMultiwordCommands
2277ebc09c36SJim Ingham //-------------------------------------------------------------------------
2278ebc09c36SJim Ingham 
2279ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
2280a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
22810e5e5a79SGreg Clayton                             "command",
22823f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
22830e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
2284ebc09c36SJim Ingham {
2285a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
2286a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
2287a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
2288b547278cSGreg Clayton     LoadSubCommand ("delete",  CommandObjectSP (new CommandObjectCommandsDelete (interpreter)));
2289de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
2290a5a97ebeSJim Ingham     LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
2291223383edSEnrico Granata     LoadSubCommand ("script",  CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
2292ebc09c36SJim Ingham }
2293ebc09c36SJim Ingham 
22946e3d8e7fSEugene Zelenko CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands() = default;
2295