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 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
12ebc09c36SJim Ingham #include "CommandObjectCommands.h"
13ebc09c36SJim Ingham 
14ebc09c36SJim Ingham // C Includes
15ebc09c36SJim Ingham // C++ Includes
16ebc09c36SJim Ingham // Other libraries and framework includes
170e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h"
180e5e5a79SGreg Clayton 
19ebc09c36SJim Ingham // Project includes
20ebc09c36SJim Ingham #include "lldb/Core/Debugger.h"
21de164aaaSGreg Clayton #include "lldb/Core/InputReader.h"
22be93a35aSEnrico Granata #include "lldb/Core/InputReaderEZ.h"
23be93a35aSEnrico Granata #include "lldb/Core/StringList.h"
24de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h"
25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h"
26de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h"
27ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h"
28*012d4fcaSEnrico Granata #include "lldb/Interpreter/OptionValueBoolean.h"
29ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
3099f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h"
3199f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreterPython.h"
32ebc09c36SJim Ingham 
33ebc09c36SJim Ingham using namespace lldb;
34ebc09c36SJim Ingham using namespace lldb_private;
35ebc09c36SJim Ingham 
36ebc09c36SJim Ingham //-------------------------------------------------------------------------
37ebc09c36SJim Ingham // CommandObjectCommandsSource
38ebc09c36SJim Ingham //-------------------------------------------------------------------------
39ebc09c36SJim Ingham 
405a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed
41a5a97ebeSJim Ingham {
425a988416SJim Ingham public:
435a988416SJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
445a988416SJim Ingham         CommandObjectParsed (interpreter,
455a988416SJim Ingham                              "command history",
465a988416SJim Ingham                              "Dump the history of commands in this session.",
475a988416SJim Ingham                              NULL),
485a988416SJim Ingham         m_options (interpreter)
495a988416SJim Ingham     {
505a988416SJim Ingham     }
515a988416SJim Ingham 
525a988416SJim Ingham     ~CommandObjectCommandsHistory () {}
535a988416SJim Ingham 
545a988416SJim Ingham     virtual Options *
555a988416SJim Ingham     GetOptions ()
565a988416SJim Ingham     {
575a988416SJim Ingham         return &m_options;
585a988416SJim Ingham     }
595a988416SJim Ingham 
605a988416SJim Ingham protected:
61a5a97ebeSJim Ingham 
62a5a97ebeSJim Ingham     class CommandOptions : public Options
63a5a97ebeSJim Ingham     {
64a5a97ebeSJim Ingham     public:
65a5a97ebeSJim Ingham 
66a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
67a5a97ebeSJim Ingham             Options (interpreter)
68a5a97ebeSJim Ingham         {
69a5a97ebeSJim Ingham         }
70a5a97ebeSJim Ingham 
71a5a97ebeSJim Ingham         virtual
72a5a97ebeSJim Ingham         ~CommandOptions (){}
73a5a97ebeSJim Ingham 
74a5a97ebeSJim Ingham         virtual Error
75a5a97ebeSJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
76a5a97ebeSJim Ingham         {
77a5a97ebeSJim Ingham             Error error;
783bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
79a5a97ebeSJim Ingham             bool success;
80a5a97ebeSJim Ingham 
81a5a97ebeSJim Ingham             switch (short_option)
82a5a97ebeSJim Ingham             {
83a5a97ebeSJim Ingham                 case 'c':
84a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
85a5a97ebeSJim Ingham                     if (!success)
8686edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for count: %s", option_arg);
87a5a97ebeSJim Ingham                     if (m_end_idx != 0)
88a5a97ebeSJim Ingham                         m_end_idx--;
89a5a97ebeSJim Ingham                     m_start_idx = 0;
90a5a97ebeSJim Ingham                     break;
91a5a97ebeSJim Ingham                 case 'e':
92a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
93a5a97ebeSJim Ingham                     if (!success)
9486edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for end index: %s", option_arg);
95a5a97ebeSJim Ingham                     break;
96a5a97ebeSJim Ingham                 case 's':
97a5a97ebeSJim Ingham                     m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
98a5a97ebeSJim Ingham                     if (!success)
9986edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for start index: %s", option_arg);
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
110a5a97ebeSJim Ingham         OptionParsingStarting ()
111a5a97ebeSJim Ingham         {
112a5a97ebeSJim Ingham             m_start_idx = 0;
113a5a97ebeSJim Ingham             m_end_idx = UINT_MAX;
114a5a97ebeSJim Ingham         }
115a5a97ebeSJim Ingham 
116a5a97ebeSJim Ingham         const OptionDefinition*
117a5a97ebeSJim Ingham         GetDefinitions ()
118a5a97ebeSJim Ingham         {
119a5a97ebeSJim Ingham             return g_option_table;
120a5a97ebeSJim Ingham         }
121a5a97ebeSJim Ingham 
122a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
123a5a97ebeSJim Ingham 
124a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
125a5a97ebeSJim Ingham 
126a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
127a5a97ebeSJim Ingham 
128a5a97ebeSJim Ingham         uint32_t m_start_idx;
129a5a97ebeSJim Ingham         uint32_t m_end_idx;
130a5a97ebeSJim Ingham     };
131a5a97ebeSJim Ingham 
132a5a97ebeSJim Ingham     bool
1335a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
134a5a97ebeSJim Ingham     {
135a5a97ebeSJim Ingham 
136a5a97ebeSJim Ingham         m_interpreter.DumpHistory (result.GetOutputStream(),
137a5a97ebeSJim Ingham                                    m_options.m_start_idx,
138a5a97ebeSJim Ingham                                    m_options.m_end_idx);
139a5a97ebeSJim Ingham         return result.Succeeded();
140a5a97ebeSJim Ingham 
141a5a97ebeSJim Ingham     }
1425a988416SJim Ingham 
1435a988416SJim Ingham     CommandOptions m_options;
144a5a97ebeSJim Ingham };
145a5a97ebeSJim Ingham 
146a5a97ebeSJim Ingham OptionDefinition
147a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
148a5a97ebeSJim Ingham {
149a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
150a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger,  "Index at which to start printing history commands."},
151a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
152a5a97ebeSJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
153a5a97ebeSJim Ingham };
154a5a97ebeSJim Ingham 
155a5a97ebeSJim Ingham 
156a5a97ebeSJim Ingham //-------------------------------------------------------------------------
157a5a97ebeSJim Ingham // CommandObjectCommandsSource
158a5a97ebeSJim Ingham //-------------------------------------------------------------------------
159a5a97ebeSJim Ingham 
1605a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed
161ebc09c36SJim Ingham {
1625a988416SJim Ingham public:
1635a988416SJim Ingham     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
1645a988416SJim Ingham         CommandObjectParsed (interpreter,
1655a988416SJim Ingham                              "command source",
1665a988416SJim Ingham                              "Read in debugger commands from the file <filename> and execute them.",
1675a988416SJim Ingham                              NULL),
1685a988416SJim Ingham         m_options (interpreter)
1695a988416SJim Ingham     {
1705a988416SJim Ingham         CommandArgumentEntry arg;
1715a988416SJim Ingham         CommandArgumentData file_arg;
1725a988416SJim Ingham 
1735a988416SJim Ingham         // Define the first (and only) variant of this arg.
1745a988416SJim Ingham         file_arg.arg_type = eArgTypeFilename;
1755a988416SJim Ingham         file_arg.arg_repetition = eArgRepeatPlain;
1765a988416SJim Ingham 
1775a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
1785a988416SJim Ingham         arg.push_back (file_arg);
1795a988416SJim Ingham 
1805a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
1815a988416SJim Ingham         m_arguments.push_back (arg);
1825a988416SJim Ingham     }
1835a988416SJim Ingham 
1845a988416SJim Ingham     ~CommandObjectCommandsSource () {}
1855a988416SJim Ingham 
1865a988416SJim Ingham     virtual const char*
1875a988416SJim Ingham     GetRepeatCommand (Args &current_command_args, uint32_t index)
1885a988416SJim Ingham     {
1895a988416SJim Ingham         return "";
1905a988416SJim Ingham     }
1915a988416SJim Ingham 
192c7bece56SGreg Clayton     virtual int
1935a988416SJim Ingham     HandleArgumentCompletion (Args &input,
1945a988416SJim Ingham                               int &cursor_index,
1955a988416SJim Ingham                               int &cursor_char_position,
1965a988416SJim Ingham                               OptionElementVector &opt_element_vector,
1975a988416SJim Ingham                               int match_start_point,
1985a988416SJim Ingham                               int max_return_elements,
1995a988416SJim Ingham                               bool &word_complete,
2005a988416SJim Ingham                               StringList &matches)
2015a988416SJim Ingham     {
2025a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2035a988416SJim Ingham         completion_str.erase (cursor_char_position);
2045a988416SJim Ingham 
2055a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2065a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
2075a988416SJim Ingham                                                              completion_str.c_str(),
2085a988416SJim Ingham                                                              match_start_point,
2095a988416SJim Ingham                                                              max_return_elements,
2105a988416SJim Ingham                                                              NULL,
2115a988416SJim Ingham                                                              word_complete,
2125a988416SJim Ingham                                                              matches);
2135a988416SJim Ingham         return matches.GetSize();
2145a988416SJim Ingham     }
2155a988416SJim Ingham 
2165a988416SJim Ingham     virtual Options *
2175a988416SJim Ingham     GetOptions ()
2185a988416SJim Ingham     {
2195a988416SJim Ingham         return &m_options;
2205a988416SJim Ingham     }
2215a988416SJim Ingham 
2225a988416SJim Ingham protected:
223e16c50a1SJim Ingham 
224e16c50a1SJim Ingham     class CommandOptions : public Options
225e16c50a1SJim Ingham     {
226e16c50a1SJim Ingham     public:
227e16c50a1SJim Ingham 
228eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
229*012d4fcaSEnrico Granata             Options (interpreter),
230*012d4fcaSEnrico Granata             m_stop_on_error (true)
231eb0103f2SGreg Clayton         {
232eb0103f2SGreg Clayton         }
233e16c50a1SJim Ingham 
234e16c50a1SJim Ingham         virtual
235e16c50a1SJim Ingham         ~CommandOptions (){}
236e16c50a1SJim Ingham 
237e16c50a1SJim Ingham         virtual Error
238f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
239e16c50a1SJim Ingham         {
240e16c50a1SJim Ingham             Error error;
2413bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
242e16c50a1SJim Ingham             bool success;
243e16c50a1SJim Ingham 
244e16c50a1SJim Ingham             switch (short_option)
245e16c50a1SJim Ingham             {
246e16c50a1SJim Ingham                 case 'e':
247*012d4fcaSEnrico Granata                     m_stop_on_error.SetCurrentValue(Args::StringToBoolean(option_arg, true, &success));
248e16c50a1SJim Ingham                     if (!success)
24986edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for stop-on-error: %s", option_arg);
250e16c50a1SJim Ingham                     break;
251e16c50a1SJim Ingham                 case 'c':
252e16c50a1SJim Ingham                     m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
253e16c50a1SJim Ingham                     if (!success)
25486edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg);
255e16c50a1SJim Ingham                     break;
256e16c50a1SJim Ingham                 default:
25786edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
258e16c50a1SJim Ingham                     break;
259e16c50a1SJim Ingham             }
260e16c50a1SJim Ingham 
261e16c50a1SJim Ingham             return error;
262e16c50a1SJim Ingham         }
263e16c50a1SJim Ingham 
264e16c50a1SJim Ingham         void
265f6b8b581SGreg Clayton         OptionParsingStarting ()
266e16c50a1SJim Ingham         {
267*012d4fcaSEnrico Granata             m_stop_on_error.Clear();
268e16c50a1SJim Ingham             m_stop_on_continue = true;
269e16c50a1SJim Ingham         }
270e16c50a1SJim Ingham 
271e0d378b3SGreg Clayton         const OptionDefinition*
272e16c50a1SJim Ingham         GetDefinitions ()
273e16c50a1SJim Ingham         {
274e16c50a1SJim Ingham             return g_option_table;
275e16c50a1SJim Ingham         }
276e16c50a1SJim Ingham 
277e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
278e16c50a1SJim Ingham 
279e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
280e16c50a1SJim Ingham 
281e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
282e16c50a1SJim Ingham 
283*012d4fcaSEnrico Granata         OptionValueBoolean m_stop_on_error;
284e16c50a1SJim Ingham         bool m_stop_on_continue;
285e16c50a1SJim Ingham     };
286e16c50a1SJim Ingham 
287ebc09c36SJim Ingham     bool
2885a988416SJim Ingham     DoExecute(Args& command, CommandReturnObject &result)
289ebc09c36SJim Ingham     {
290c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
291ebc09c36SJim Ingham         if (argc == 1)
292ebc09c36SJim Ingham         {
2935a988416SJim Ingham             const char *filename = command.GetArgumentAtIndex(0);
294ebc09c36SJim Ingham 
295ebc09c36SJim Ingham             result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
296ebc09c36SJim Ingham 
2971ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
298e16c50a1SJim Ingham             ExecutionContext *exe_ctx = NULL;  // Just use the default context.
299e16c50a1SJim Ingham             bool echo_commands    = true;
300e16c50a1SJim Ingham             bool print_results    = true;
301*012d4fcaSEnrico Granata             bool stop_on_error = m_options.m_stop_on_error.OptionWasSet() ? (bool)m_options.m_stop_on_error : m_interpreter.GetStopCmdSourceOnError();
302ebc09c36SJim Ingham 
303e16c50a1SJim Ingham             m_interpreter.HandleCommandsFromFile (cmd_file,
304e16c50a1SJim Ingham                                                   exe_ctx,
305e16c50a1SJim Ingham                                                   m_options.m_stop_on_continue,
306*012d4fcaSEnrico Granata                                                   stop_on_error,
307e16c50a1SJim Ingham                                                   echo_commands,
308e16c50a1SJim Ingham                                                   print_results,
3095f5ab602SEnrico Granata                                                   eLazyBoolCalculate,
310e16c50a1SJim Ingham                                                   result);
311ebc09c36SJim Ingham         }
312ebc09c36SJim Ingham         else
313ebc09c36SJim Ingham         {
314ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
315ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
316ebc09c36SJim Ingham         }
317ebc09c36SJim Ingham         return result.Succeeded();
318ebc09c36SJim Ingham 
319ebc09c36SJim Ingham     }
3205a988416SJim Ingham     CommandOptions m_options;
321ebc09c36SJim Ingham };
322ebc09c36SJim Ingham 
323e0d378b3SGreg Clayton OptionDefinition
324e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
325e16c50a1SJim Ingham {
326e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
327e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
328e16c50a1SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
329e16c50a1SJim Ingham };
330e16c50a1SJim Ingham 
331ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
332ebc09c36SJim Ingham //-------------------------------------------------------------------------
333ebc09c36SJim Ingham // CommandObjectCommandsAlias
334ebc09c36SJim Ingham //-------------------------------------------------------------------------
335ebc09c36SJim Ingham 
336be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
337be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
33840d55710SEnrico Granata                                                      "def my_command_impl(debugger, args, result, internal_dict):";
339be93a35aSEnrico Granata 
340be93a35aSEnrico Granata 
3415a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw
342ebc09c36SJim Ingham {
343be93a35aSEnrico Granata 
344be93a35aSEnrico Granata 
345ebc09c36SJim Ingham public:
346a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
3475a988416SJim Ingham         CommandObjectRaw (interpreter,
3480e5e5a79SGreg Clayton                        "command alias",
349e3d26315SCaroline Tice                        "Allow users to define their own debugger command abbreviations.",
350405fe67fSCaroline Tice                        NULL)
351ebc09c36SJim Ingham     {
352ebc09c36SJim Ingham         SetHelpLong(
353ebc09c36SJim Ingham     "'alias' allows the user to create a short-cut or abbreviation for long \n\
354ebc09c36SJim Ingham     commands, multi-word commands, and commands that take particular options. \n\
355ebc09c36SJim Ingham     Below are some simple examples of how one might use the 'alias' command: \n\
35669c12ccbSJason Molenda     \n    'command alias sc script'            // Creates the abbreviation 'sc' for the 'script' \n\
357ebc09c36SJim Ingham                                          // command. \n\
35869c12ccbSJason Molenda     'command alias bp breakpoint'        // Creates the abbreviation 'bp' for the 'breakpoint' \n\
359ebc09c36SJim Ingham                                          // command.  Since breakpoint commands are two-word \n\
360ebc09c36SJim Ingham                                          // commands, the user will still need to enter the \n\
361ebc09c36SJim Ingham                                          // second word after 'bp', e.g. 'bp enable' or \n\
362ebc09c36SJim Ingham                                          // 'bp delete'. \n\
36369c12ccbSJason Molenda     'command alias bpl breakpoint list'  // Creates the abbreviation 'bpl' for the \n\
364ebc09c36SJim Ingham                                          // two-word command 'breakpoint list'. \n\
365ebc09c36SJim Ingham     \nAn alias can include some options for the command, with the values either \n\
366ebc09c36SJim Ingham     filled in at the time the alias is created, or specified as positional \n\
367ebc09c36SJim Ingham     arguments, to be filled in when the alias is invoked.  The following example \n\
368ebc09c36SJim Ingham     shows how to create aliases with options: \n\
369ebc09c36SJim Ingham     \n\
37069c12ccbSJason Molenda     'command alias bfl breakpoint set -f %1 -l %2' \n\
371ebc09c36SJim Ingham     \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
372ebc09c36SJim Ingham     options already part of the alias.  So if the user wants to set a breakpoint \n\
373ebc09c36SJim Ingham     by file and line without explicitly having to use the -f and -l options, the \n\
374ebc09c36SJim Ingham     user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \n\
375ebc09c36SJim Ingham     for the actual arguments that will be passed when the alias command is used. \n\
376ebc09c36SJim Ingham     The number in the placeholder refers to the position/order the actual value \n\
37781ded935SJim Ingham     occupies when the alias is used.  All the occurrences of '%1' in the alias \n\
378ebc09c36SJim Ingham     will be replaced with the first argument, all the occurrences of '%2' in the \n\
379ebc09c36SJim Ingham     alias will be replaced with the second argument, and so on.  This also allows \n\
380ebc09c36SJim Ingham     actual arguments to be used multiple times within an alias (see 'process \n\
38181ded935SJim Ingham     launch' example below).  \n\
38281ded935SJim Ingham     Note: the positional arguments must substitute as whole words in the resultant\n\
38381ded935SJim Ingham     command, so you can't at present do something like:\n\
38481ded935SJim Ingham     \n\
38569c12ccbSJason Molenda     command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
38681ded935SJim Ingham     \n\
38781ded935SJim Ingham     to get the file extension \".cpp\" automatically appended.  For more complex\n\
38881ded935SJim Ingham     aliasing, use the \"command regex\" command instead.\n\
38981ded935SJim Ingham     \nSo in the 'bfl' case, the actual file value will be \n\
390ebc09c36SJim Ingham     filled in with the first argument following 'bfl' and the actual line number \n\
391ebc09c36SJim Ingham     value will be filled in with the second argument.  The user would use this \n\
392ebc09c36SJim Ingham     alias as follows: \n\
39369c12ccbSJason Molenda     \n    (lldb)  command alias bfl breakpoint set -f %1 -l %2 \n\
394ebc09c36SJim Ingham     <... some time later ...> \n\
39509799af6SCaroline Tice     (lldb)  bfl my-file.c 137 \n\
396ebc09c36SJim Ingham     \nThis would be the same as if the user had entered \n\
397ebc09c36SJim Ingham     'breakpoint set -f my-file.c -l 137'. \n\
398ebc09c36SJim Ingham     \nAnother example: \n\
39969c12ccbSJason Molenda     \n    (lldb)  command alias pltty  process launch -s -o %1 -e %1 \n\
40009799af6SCaroline Tice     (lldb)  pltty /dev/tty0 \n\
401ebc09c36SJim Ingham            // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
402ebc09c36SJim Ingham     \nIf the user always wanted to pass the same value to a particular option, the \n\
403ebc09c36SJim Ingham     alias could be defined with that value directly in the alias as a constant, \n\
404ebc09c36SJim Ingham     rather than using a positional placeholder: \n\
40569c12ccbSJason Molenda     \n    command alias bl3  breakpoint set -f %1 -l 3  // Always sets a breakpoint on line \n\
406ebc09c36SJim Ingham                                                    // 3 of whatever file is indicated. \n");
407ebc09c36SJim Ingham 
408405fe67fSCaroline Tice         CommandArgumentEntry arg1;
409405fe67fSCaroline Tice         CommandArgumentEntry arg2;
410405fe67fSCaroline Tice         CommandArgumentEntry arg3;
411405fe67fSCaroline Tice         CommandArgumentData alias_arg;
412405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
413405fe67fSCaroline Tice         CommandArgumentData options_arg;
414405fe67fSCaroline Tice 
415405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
416405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
417405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
418405fe67fSCaroline Tice 
419405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
420405fe67fSCaroline Tice         arg1.push_back (alias_arg);
421405fe67fSCaroline Tice 
422405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
423405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
424405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
425405fe67fSCaroline Tice 
426405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
427405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
428405fe67fSCaroline Tice 
429405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
430405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
431405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
432405fe67fSCaroline Tice 
433405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
434405fe67fSCaroline Tice         arg3.push_back (options_arg);
435405fe67fSCaroline Tice 
436405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
437405fe67fSCaroline Tice         m_arguments.push_back (arg1);
438405fe67fSCaroline Tice         m_arguments.push_back (arg2);
439405fe67fSCaroline Tice         m_arguments.push_back (arg3);
440ebc09c36SJim Ingham     }
441ebc09c36SJim Ingham 
442ebc09c36SJim Ingham     ~CommandObjectCommandsAlias ()
443ebc09c36SJim Ingham     {
444ebc09c36SJim Ingham     }
445ebc09c36SJim Ingham 
4465a988416SJim Ingham protected:
4475a988416SJim Ingham     virtual bool
4485a988416SJim Ingham     DoExecute (const char *raw_command_line, CommandReturnObject &result)
449844d2303SCaroline Tice     {
450844d2303SCaroline Tice         Args args (raw_command_line);
451844d2303SCaroline Tice         std::string raw_command_string (raw_command_line);
452844d2303SCaroline Tice 
453844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
454844d2303SCaroline Tice 
455844d2303SCaroline Tice         if (argc < 2)
456844d2303SCaroline Tice         {
457844d2303SCaroline Tice             result.AppendError ("'alias' requires at least two arguments");
458844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
459844d2303SCaroline Tice             return false;
460844d2303SCaroline Tice         }
461844d2303SCaroline Tice 
462844d2303SCaroline Tice         // Get the alias command.
463844d2303SCaroline Tice 
464844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
465844d2303SCaroline Tice 
466844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
467844d2303SCaroline Tice         // does the stripping itself.
468844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
469844d2303SCaroline Tice         if (pos == 0)
470844d2303SCaroline Tice         {
471844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
472844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
473844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
474844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
475844d2303SCaroline Tice         }
476844d2303SCaroline Tice         else
477844d2303SCaroline Tice         {
478844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
479844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
480844d2303SCaroline Tice             return false;
481844d2303SCaroline Tice         }
482844d2303SCaroline Tice 
483844d2303SCaroline Tice 
484844d2303SCaroline Tice         // Verify that the command is alias-able.
485844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
486844d2303SCaroline Tice         {
487844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
488844d2303SCaroline Tice                                           alias_command.c_str());
489844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
490844d2303SCaroline Tice             return false;
491844d2303SCaroline Tice         }
492844d2303SCaroline Tice 
493844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
494844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
495844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
496844d2303SCaroline Tice 
497844d2303SCaroline Tice         if (!cmd_obj)
498844d2303SCaroline Tice         {
49986edbf41SGreg Clayton             result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
500844d2303SCaroline Tice                                           "  No alias created.", raw_command_string.c_str());
501844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
502844d2303SCaroline Tice             return false;
503844d2303SCaroline Tice         }
504844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
505844d2303SCaroline Tice         {
506844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
507844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
5085a988416SJim Ingham             return HandleAliasingNormalCommand (args, result);
509844d2303SCaroline Tice         }
510844d2303SCaroline Tice         else
511844d2303SCaroline Tice         {
5125a988416SJim Ingham             return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
5135a988416SJim Ingham         }
5145a988416SJim Ingham         return result.Succeeded();
5155a988416SJim Ingham     }
5165a988416SJim Ingham 
5175a988416SJim Ingham     bool
5185a988416SJim Ingham     HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
5195a988416SJim Ingham     {
520844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
521844d2303SCaroline Tice 
522844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
523844d2303SCaroline Tice             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
524844d2303SCaroline Tice 
5255a988416SJim Ingham             CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
526844d2303SCaroline Tice 
527ca90c47eSCaroline Tice             if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
528844d2303SCaroline Tice             {
529844d2303SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
530ca90c47eSCaroline Tice                 result.SetStatus (eReturnStatusFailed);
531844d2303SCaroline Tice                 return false;
532844d2303SCaroline Tice             }
533844d2303SCaroline Tice 
534844d2303SCaroline Tice             // Create the alias
535844d2303SCaroline Tice             if (m_interpreter.AliasExists (alias_command.c_str())
536844d2303SCaroline Tice                 || m_interpreter.UserCommandExists (alias_command.c_str()))
537844d2303SCaroline Tice             {
538844d2303SCaroline Tice                 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
539844d2303SCaroline Tice                 if (temp_option_arg_sp.get())
540844d2303SCaroline Tice                 {
541844d2303SCaroline Tice                     if (option_arg_vector->size() == 0)
542844d2303SCaroline Tice                         m_interpreter.RemoveAliasOptions (alias_command.c_str());
543844d2303SCaroline Tice                 }
544844d2303SCaroline Tice                 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
545844d2303SCaroline Tice                                                 alias_command.c_str());
546844d2303SCaroline Tice             }
547844d2303SCaroline Tice 
548472362e6SCaroline Tice             if (cmd_obj_sp)
549472362e6SCaroline Tice             {
550844d2303SCaroline Tice                 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
551844d2303SCaroline Tice                 if (option_arg_vector->size() > 0)
552844d2303SCaroline Tice                     m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
553844d2303SCaroline Tice                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
554844d2303SCaroline Tice             }
555472362e6SCaroline Tice             else
556472362e6SCaroline Tice             {
557472362e6SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
558472362e6SCaroline Tice                 result.SetStatus (eReturnStatusFailed);
559472362e6SCaroline Tice             }
560844d2303SCaroline Tice             return result.Succeeded ();
561844d2303SCaroline Tice     }
562ebc09c36SJim Ingham 
563ebc09c36SJim Ingham     bool
5645a988416SJim Ingham     HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
565ebc09c36SJim Ingham     {
566867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
567ebc09c36SJim Ingham 
568ebc09c36SJim Ingham         if (argc < 2)
569ebc09c36SJim Ingham         {
570ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
571ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
572ebc09c36SJim Ingham             return false;
573ebc09c36SJim Ingham         }
574ebc09c36SJim Ingham 
575ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
576ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
577ebc09c36SJim Ingham 
578ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
579ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
580ebc09c36SJim Ingham 
581ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
582ebc09c36SJim Ingham 
583a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
584ebc09c36SJim Ingham         {
585ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
586ebc09c36SJim Ingham                                          alias_command.c_str());
587ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
588ebc09c36SJim Ingham         }
589ebc09c36SJim Ingham         else
590ebc09c36SJim Ingham         {
591a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
592ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
593ebc09c36SJim Ingham              bool use_subcommand = false;
594ebc09c36SJim Ingham              if (command_obj_sp.get())
595ebc09c36SJim Ingham              {
596ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
597c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
598ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
599ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
600ebc09c36SJim Ingham 
601844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
602ebc09c36SJim Ingham                  {
603ebc09c36SJim Ingham                      if (argc >= 3)
604ebc09c36SJim Ingham                      {
605ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
606ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
607998255bfSGreg Clayton                          subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
608ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
609ebc09c36SJim Ingham                          {
610ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
611ebc09c36SJim Ingham                              use_subcommand = true;
612ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
613844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
614ebc09c36SJim Ingham                          }
615ebc09c36SJim Ingham                          else
616ebc09c36SJim Ingham                          {
617f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
618f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
619f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
620ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
621ebc09c36SJim Ingham                              return false;
622ebc09c36SJim Ingham                          }
623ebc09c36SJim Ingham                      }
624ebc09c36SJim Ingham                  }
625ebc09c36SJim Ingham 
626ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
627ebc09c36SJim Ingham 
628ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
629ebc09c36SJim Ingham                  {
630ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
631ebc09c36SJim Ingham                     if (use_subcommand)
632ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
633ca90c47eSCaroline Tice 
634ca90c47eSCaroline Tice                     std::string args_string;
635ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
636ca90c47eSCaroline Tice 
637ca90c47eSCaroline Tice                     if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
638ebc09c36SJim Ingham                     {
639ca90c47eSCaroline Tice                         result.AppendError ("Unable to create requested alias.\n");
640ca90c47eSCaroline Tice                         result.SetStatus (eReturnStatusFailed);
641e7941795SCaroline Tice                         return false;
642867b185dSCaroline Tice                     }
643867b185dSCaroline Tice                  }
644867b185dSCaroline Tice 
645ebc09c36SJim Ingham                  // Create the alias.
646ebc09c36SJim Ingham 
647a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
648a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
649ebc09c36SJim Ingham                  {
650a7015092SGreg Clayton                      OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
651ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
652ebc09c36SJim Ingham                      {
653ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
654a7015092SGreg Clayton                              m_interpreter.RemoveAliasOptions (alias_command.c_str());
655ebc09c36SJim Ingham                      }
656ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
657ebc09c36SJim Ingham                                                      alias_command.c_str());
658ebc09c36SJim Ingham                  }
659ebc09c36SJim Ingham 
660ebc09c36SJim Ingham                  if (use_subcommand)
661a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
662ebc09c36SJim Ingham                  else
663a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
664ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
665a7015092SGreg Clayton                      m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
666ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
667ebc09c36SJim Ingham              }
668ebc09c36SJim Ingham              else
669ebc09c36SJim Ingham              {
670ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
671ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
672e7941795SCaroline Tice                  return false;
673ebc09c36SJim Ingham              }
674ebc09c36SJim Ingham         }
675ebc09c36SJim Ingham 
676ebc09c36SJim Ingham         return result.Succeeded();
677ebc09c36SJim Ingham     }
6785a988416SJim Ingham 
679ebc09c36SJim Ingham };
680ebc09c36SJim Ingham 
681ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
682ebc09c36SJim Ingham //-------------------------------------------------------------------------
683ebc09c36SJim Ingham // CommandObjectCommandsUnalias
684ebc09c36SJim Ingham //-------------------------------------------------------------------------
685ebc09c36SJim Ingham 
6865a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed
687ebc09c36SJim Ingham {
688ebc09c36SJim Ingham public:
689a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
6905a988416SJim Ingham         CommandObjectParsed (interpreter,
6910e5e5a79SGreg Clayton                        "command unalias",
69286ddae50SCaroline Tice                        "Allow the user to remove/delete a user-defined command abbreviation.",
693405fe67fSCaroline Tice                        NULL)
694ebc09c36SJim Ingham     {
695405fe67fSCaroline Tice         CommandArgumentEntry arg;
696405fe67fSCaroline Tice         CommandArgumentData alias_arg;
697405fe67fSCaroline Tice 
698405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
699405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
700405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
701405fe67fSCaroline Tice 
702405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
703405fe67fSCaroline Tice         arg.push_back (alias_arg);
704405fe67fSCaroline Tice 
705405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
706405fe67fSCaroline Tice         m_arguments.push_back (arg);
707ebc09c36SJim Ingham     }
708ebc09c36SJim Ingham 
709ebc09c36SJim Ingham     ~CommandObjectCommandsUnalias()
710ebc09c36SJim Ingham     {
711ebc09c36SJim Ingham     }
712ebc09c36SJim Ingham 
7135a988416SJim Ingham protected:
714ebc09c36SJim Ingham     bool
7155a988416SJim Ingham     DoExecute (Args& args, CommandReturnObject &result)
716ebc09c36SJim Ingham     {
717ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
718ebc09c36SJim Ingham         CommandObject *cmd_obj;
719ebc09c36SJim Ingham 
720ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
721ebc09c36SJim Ingham         {
722ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
723a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
724ebc09c36SJim Ingham             if (cmd_obj)
725ebc09c36SJim Ingham             {
726a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
727ebc09c36SJim Ingham                 {
728ebc09c36SJim Ingham                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
729ebc09c36SJim Ingham                                                   command_name);
730ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
731ebc09c36SJim Ingham                 }
732ebc09c36SJim Ingham                 else
733ebc09c36SJim Ingham                 {
734ebc09c36SJim Ingham 
735a7015092SGreg Clayton                     if (m_interpreter.RemoveAlias (command_name) == false)
736ebc09c36SJim Ingham                     {
737a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
738ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
739ebc09c36SJim Ingham                                                           command_name);
740ebc09c36SJim Ingham                         else
741ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
742ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
743ebc09c36SJim Ingham                     }
744ebc09c36SJim Ingham                     else
745ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
746ebc09c36SJim Ingham                 }
747ebc09c36SJim Ingham             }
748ebc09c36SJim Ingham             else
749ebc09c36SJim Ingham             {
750ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
751ebc09c36SJim Ingham                                               "current list of commands.\n",
752ebc09c36SJim Ingham                                              command_name);
753ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
754ebc09c36SJim Ingham             }
755ebc09c36SJim Ingham         }
756ebc09c36SJim Ingham         else
757ebc09c36SJim Ingham         {
758ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
759ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
760ebc09c36SJim Ingham         }
761ebc09c36SJim Ingham 
762ebc09c36SJim Ingham         return result.Succeeded();
763ebc09c36SJim Ingham     }
764ebc09c36SJim Ingham };
765ebc09c36SJim Ingham 
766de164aaaSGreg Clayton //-------------------------------------------------------------------------
767de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
768de164aaaSGreg Clayton //-------------------------------------------------------------------------
7695a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex
770de164aaaSGreg Clayton 
7715a988416SJim Ingham class CommandObjectCommandsAddRegex : public CommandObjectParsed
772de164aaaSGreg Clayton {
773de164aaaSGreg Clayton public:
774de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
7755a988416SJim Ingham         CommandObjectParsed (interpreter,
7760e5e5a79SGreg Clayton                        "command regex",
777de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
7780e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
779de164aaaSGreg Clayton         m_options (interpreter)
780de164aaaSGreg Clayton     {
7810e5e5a79SGreg Clayton         SetHelpLong(
7820e5e5a79SGreg Clayton "This command allows the user to create powerful regular expression commands\n"
7830e5e5a79SGreg Clayton "with substitutions. The regular expressions and substitutions are specified\n"
7840e5e5a79SGreg Clayton "using the regular exression substitution format of:\n"
7850e5e5a79SGreg Clayton "\n"
7860e5e5a79SGreg Clayton "    s/<regex>/<subst>/\n"
7870e5e5a79SGreg Clayton "\n"
7880e5e5a79SGreg Clayton "<regex> is a regular expression that can use parenthesis to capture regular\n"
7890e5e5a79SGreg Clayton "expression input and substitute the captured matches in the output using %1\n"
7900e5e5a79SGreg Clayton "for the first match, %2 for the second, and so on.\n"
7910e5e5a79SGreg Clayton "\n"
7920e5e5a79SGreg Clayton "The regular expressions can all be specified on the command line if more than\n"
7930e5e5a79SGreg Clayton "one argument is provided. If just the command name is provided on the command\n"
7940e5e5a79SGreg Clayton "line, then the regular expressions and substitutions can be entered on separate\n"
7950e5e5a79SGreg Clayton " lines, followed by an empty line to terminate the command definition.\n"
7960e5e5a79SGreg Clayton "\n"
7970e5e5a79SGreg Clayton "EXAMPLES\n"
7980e5e5a79SGreg Clayton "\n"
799adc43c99SSean Callanan "The following example will define a regular expression command named 'f' that\n"
8000e5e5a79SGreg Clayton "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
8010e5e5a79SGreg Clayton "a number follows 'f':\n"
802adc43c99SSean Callanan "\n"
8030e5e5a79SGreg Clayton "    (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
804adc43c99SSean Callanan "\n"
8050e5e5a79SGreg Clayton                     );
806de164aaaSGreg Clayton     }
807de164aaaSGreg Clayton 
808de164aaaSGreg Clayton     ~CommandObjectCommandsAddRegex()
809de164aaaSGreg Clayton     {
810de164aaaSGreg Clayton     }
811de164aaaSGreg Clayton 
812de164aaaSGreg Clayton 
8135a988416SJim Ingham protected:
814de164aaaSGreg Clayton     bool
8155a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
816de164aaaSGreg Clayton     {
8175a988416SJim Ingham         const size_t argc = command.GetArgumentCount();
8180e5e5a79SGreg Clayton         if (argc == 0)
819de164aaaSGreg Clayton         {
82069c12ccbSJason Molenda             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
8210e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
8220e5e5a79SGreg Clayton         }
8230e5e5a79SGreg Clayton         else
8240e5e5a79SGreg Clayton         {
8250e5e5a79SGreg Clayton             Error error;
8265a988416SJim Ingham             const char *name = command.GetArgumentAtIndex(0);
827de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
828de164aaaSGreg Clayton                                                                  name,
829de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
830de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
831de164aaaSGreg Clayton                                                                  10));
8320e5e5a79SGreg Clayton 
8330e5e5a79SGreg Clayton             if (argc == 1)
8340e5e5a79SGreg Clayton             {
8350e5e5a79SGreg Clayton                 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
836de164aaaSGreg Clayton                 if (reader_sp)
837de164aaaSGreg Clayton                 {
8380e5e5a79SGreg Clayton                     error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
839de164aaaSGreg Clayton                                                   this,                         // baton
840de164aaaSGreg Clayton                                                   eInputReaderGranularityLine,  // token size, to pass to callback function
8410e5e5a79SGreg Clayton                                                   NULL,                         // end token
842de164aaaSGreg Clayton                                                   "> ",                         // prompt
8430e5e5a79SGreg Clayton                                                   true);                        // echo input
8440e5e5a79SGreg Clayton                     if (error.Success())
845de164aaaSGreg Clayton                     {
846de164aaaSGreg Clayton                         m_interpreter.GetDebugger().PushInputReader (reader_sp);
847de164aaaSGreg Clayton                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
8480e5e5a79SGreg Clayton                         return true;
849de164aaaSGreg Clayton                     }
850de164aaaSGreg Clayton                 }
851de164aaaSGreg Clayton             }
852de164aaaSGreg Clayton             else
853de164aaaSGreg Clayton             {
8540e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
8550e5e5a79SGreg Clayton                 {
8565a988416SJim Ingham                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
8570e5e5a79SGreg Clayton                     error = AppendRegexSubstitution (arg_strref);
8580e5e5a79SGreg Clayton                     if (error.Fail())
8590e5e5a79SGreg Clayton                         break;
8600e5e5a79SGreg Clayton                 }
8610e5e5a79SGreg Clayton 
8620e5e5a79SGreg Clayton                 if (error.Success())
8630e5e5a79SGreg Clayton                 {
8640e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
8650e5e5a79SGreg Clayton                 }
8660e5e5a79SGreg Clayton             }
8670e5e5a79SGreg Clayton             if (error.Fail())
8680e5e5a79SGreg Clayton             {
8690e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
870de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
871de164aaaSGreg Clayton             }
8720e5e5a79SGreg Clayton         }
8730e5e5a79SGreg Clayton 
874de164aaaSGreg Clayton         return result.Succeeded();
875de164aaaSGreg Clayton     }
876de164aaaSGreg Clayton 
8770e5e5a79SGreg Clayton     Error
8780e5e5a79SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed)
879de164aaaSGreg Clayton     {
8800e5e5a79SGreg Clayton         Error error;
8810e5e5a79SGreg Clayton 
8820e5e5a79SGreg Clayton         if (m_regex_cmd_ap.get() == NULL)
883de164aaaSGreg Clayton         {
8840e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
8850e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8860e5e5a79SGreg Clayton                                            regex_sed.data());
8870e5e5a79SGreg Clayton             return error;
888de164aaaSGreg Clayton         }
8890e5e5a79SGreg Clayton 
8900e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
8910e5e5a79SGreg Clayton 
8920e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
8930e5e5a79SGreg Clayton         {
8940e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
8950e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8960e5e5a79SGreg Clayton                                            regex_sed.data());
8970e5e5a79SGreg Clayton             return error;
8980e5e5a79SGreg Clayton         }
8990e5e5a79SGreg Clayton 
9000e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
9010e5e5a79SGreg Clayton         {
9020e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
9030e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9040e5e5a79SGreg Clayton                                            regex_sed.data());
9050e5e5a79SGreg Clayton             return error;
9060e5e5a79SGreg Clayton         }
9070e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
9080e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
9090e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
9100e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
9110e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
9120e5e5a79SGreg Clayton 
9130e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
9140e5e5a79SGreg Clayton         {
9150e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
9160e5e5a79SGreg Clayton                                            separator_char,
9170e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
9180e5e5a79SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1));
9190e5e5a79SGreg Clayton             return error;
9200e5e5a79SGreg Clayton         }
9210e5e5a79SGreg Clayton 
9220e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
9230e5e5a79SGreg Clayton 
9240e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
9250e5e5a79SGreg Clayton         {
9260e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
9270e5e5a79SGreg Clayton                                            separator_char,
9280e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
9290e5e5a79SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1));
9300e5e5a79SGreg Clayton             return error;
9310e5e5a79SGreg Clayton         }
9320e5e5a79SGreg Clayton 
9330e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
9340e5e5a79SGreg Clayton         {
9350e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
9360e5e5a79SGreg Clayton             // separator char
9370e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
9380e5e5a79SGreg Clayton             {
9390e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
9400e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
9410e5e5a79SGreg Clayton                                                regex_sed.data(),
9420e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
9430e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
9440e5e5a79SGreg Clayton                 return error;
9450e5e5a79SGreg Clayton             }
9460e5e5a79SGreg Clayton 
9470e5e5a79SGreg Clayton         }
9480e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
9490e5e5a79SGreg Clayton         {
9500e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9510e5e5a79SGreg Clayton                                            separator_char,
9520e5e5a79SGreg Clayton                                            separator_char,
9530e5e5a79SGreg Clayton                                            separator_char,
9540e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9550e5e5a79SGreg Clayton                                            regex_sed.data());
9560e5e5a79SGreg Clayton             return error;
9570e5e5a79SGreg Clayton         }
9580e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
9590e5e5a79SGreg Clayton         {
9600e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9610e5e5a79SGreg Clayton                                            separator_char,
9620e5e5a79SGreg Clayton                                            separator_char,
9630e5e5a79SGreg Clayton                                            separator_char,
9640e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9650e5e5a79SGreg Clayton                                            regex_sed.data());
9660e5e5a79SGreg Clayton             return error;
9670e5e5a79SGreg Clayton         }
9680e5e5a79SGreg Clayton         std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
9690e5e5a79SGreg Clayton         std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
9700e5e5a79SGreg Clayton         m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
9710e5e5a79SGreg Clayton                                          subst.c_str());
9720e5e5a79SGreg Clayton         return error;
973de164aaaSGreg Clayton     }
974de164aaaSGreg Clayton 
975de164aaaSGreg Clayton     void
9760e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
977de164aaaSGreg Clayton     {
978de164aaaSGreg Clayton         if (m_regex_cmd_ap.get())
979de164aaaSGreg Clayton         {
980de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
981de164aaaSGreg Clayton             {
982de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
983de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
984de164aaaSGreg Clayton             }
985de164aaaSGreg Clayton         }
986de164aaaSGreg Clayton     }
987de164aaaSGreg Clayton 
9880e5e5a79SGreg Clayton     void
9890e5e5a79SGreg Clayton     InputReaderDidCancel()
9900e5e5a79SGreg Clayton     {
9910e5e5a79SGreg Clayton         m_regex_cmd_ap.reset();
9920e5e5a79SGreg Clayton     }
9930e5e5a79SGreg Clayton 
994de164aaaSGreg Clayton     static size_t
995de164aaaSGreg Clayton     InputReaderCallback (void *baton,
996de164aaaSGreg Clayton                          InputReader &reader,
997de164aaaSGreg Clayton                          lldb::InputReaderAction notification,
998de164aaaSGreg Clayton                          const char *bytes,
9995a988416SJim Ingham                          size_t bytes_len)
10005a988416SJim Ingham     {
10015a988416SJim Ingham         CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
10025a988416SJim Ingham         bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
10035a988416SJim Ingham 
10045a988416SJim Ingham         switch (notification)
10055a988416SJim Ingham         {
10065a988416SJim Ingham             case eInputReaderActivate:
10075a988416SJim Ingham                 if (!batch_mode)
10085a988416SJim Ingham                 {
10095a988416SJim Ingham                     StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
10105a988416SJim Ingham                     out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
10115a988416SJim Ingham                     out_stream->Flush();
10125a988416SJim Ingham                 }
10135a988416SJim Ingham                 break;
10145a988416SJim Ingham             case eInputReaderReactivate:
10155a988416SJim Ingham                 break;
10165a988416SJim Ingham 
10175a988416SJim Ingham             case eInputReaderDeactivate:
10185a988416SJim Ingham                 break;
10195a988416SJim Ingham 
10205a988416SJim Ingham             case eInputReaderAsynchronousOutputWritten:
10215a988416SJim Ingham                 break;
10225a988416SJim Ingham 
10235a988416SJim Ingham             case eInputReaderGotToken:
10245a988416SJim Ingham                 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
10255a988416SJim Ingham                     --bytes_len;
10265a988416SJim Ingham                 if (bytes_len == 0)
10275a988416SJim Ingham                     reader.SetIsDone(true);
10285a988416SJim Ingham                 else if (bytes)
10295a988416SJim Ingham                 {
10305a988416SJim Ingham                     llvm::StringRef bytes_strref (bytes, bytes_len);
10315a988416SJim Ingham                     Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
10325a988416SJim Ingham                     if (error.Fail())
10335a988416SJim Ingham                     {
10345a988416SJim Ingham                         if (!batch_mode)
10355a988416SJim Ingham                         {
10365a988416SJim Ingham                             StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
10375a988416SJim Ingham                             out_stream->Printf("error: %s\n", error.AsCString());
10385a988416SJim Ingham                             out_stream->Flush();
10395a988416SJim Ingham                         }
10405a988416SJim Ingham                         add_regex_cmd->InputReaderDidCancel ();
10415a988416SJim Ingham                         reader.SetIsDone (true);
10425a988416SJim Ingham                     }
10435a988416SJim Ingham                 }
10445a988416SJim Ingham                 break;
10455a988416SJim Ingham 
10465a988416SJim Ingham             case eInputReaderInterrupt:
10475a988416SJim Ingham                 {
10485a988416SJim Ingham                     reader.SetIsDone (true);
10495a988416SJim Ingham                     if (!batch_mode)
10505a988416SJim Ingham                     {
10515a988416SJim Ingham                         StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
10525a988416SJim Ingham                         out_stream->PutCString("Regular expression command creations was cancelled.\n");
10535a988416SJim Ingham                         out_stream->Flush();
10545a988416SJim Ingham                     }
10555a988416SJim Ingham                     add_regex_cmd->InputReaderDidCancel ();
10565a988416SJim Ingham                 }
10575a988416SJim Ingham                 break;
10585a988416SJim Ingham 
10595a988416SJim Ingham             case eInputReaderEndOfFile:
10605a988416SJim Ingham                 reader.SetIsDone (true);
10615a988416SJim Ingham                 break;
10625a988416SJim Ingham 
10635a988416SJim Ingham             case eInputReaderDone:
10645a988416SJim Ingham                 add_regex_cmd->AddRegexCommandToInterpreter();
10655a988416SJim Ingham                 break;
10665a988416SJim Ingham         }
10675a988416SJim Ingham 
10685a988416SJim Ingham         return bytes_len;
10695a988416SJim Ingham     }
10705a988416SJim Ingham 
1071de164aaaSGreg Clayton private:
10727b0992d9SGreg Clayton     std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1073de164aaaSGreg Clayton 
1074de164aaaSGreg Clayton      class CommandOptions : public Options
1075de164aaaSGreg Clayton      {
1076de164aaaSGreg Clayton      public:
1077de164aaaSGreg Clayton 
1078de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
1079de164aaaSGreg Clayton             Options (interpreter)
1080de164aaaSGreg Clayton          {
1081de164aaaSGreg Clayton          }
1082de164aaaSGreg Clayton 
1083de164aaaSGreg Clayton          virtual
1084de164aaaSGreg Clayton          ~CommandOptions (){}
1085de164aaaSGreg Clayton 
1086de164aaaSGreg Clayton          virtual Error
1087de164aaaSGreg Clayton          SetOptionValue (uint32_t option_idx, const char *option_arg)
1088de164aaaSGreg Clayton          {
1089de164aaaSGreg Clayton              Error error;
10903bcdfc0eSGreg Clayton              const int short_option = m_getopt_table[option_idx].val;
1091de164aaaSGreg Clayton 
1092de164aaaSGreg Clayton              switch (short_option)
1093de164aaaSGreg Clayton              {
1094de164aaaSGreg Clayton                  case 'h':
1095de164aaaSGreg Clayton                      m_help.assign (option_arg);
1096de164aaaSGreg Clayton                      break;
1097de164aaaSGreg Clayton                  case 's':
1098de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1099de164aaaSGreg Clayton                      break;
1100de164aaaSGreg Clayton 
1101de164aaaSGreg Clayton                  default:
110286edbf41SGreg Clayton                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1103de164aaaSGreg Clayton                      break;
1104de164aaaSGreg Clayton              }
1105de164aaaSGreg Clayton 
1106de164aaaSGreg Clayton              return error;
1107de164aaaSGreg Clayton          }
1108de164aaaSGreg Clayton 
1109de164aaaSGreg Clayton          void
1110de164aaaSGreg Clayton          OptionParsingStarting ()
1111de164aaaSGreg Clayton          {
1112de164aaaSGreg Clayton              m_help.clear();
1113de164aaaSGreg Clayton              m_syntax.clear();
1114de164aaaSGreg Clayton          }
1115de164aaaSGreg Clayton 
1116de164aaaSGreg Clayton          const OptionDefinition*
1117de164aaaSGreg Clayton          GetDefinitions ()
1118de164aaaSGreg Clayton          {
1119de164aaaSGreg Clayton              return g_option_table;
1120de164aaaSGreg Clayton          }
1121de164aaaSGreg Clayton 
1122de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1123de164aaaSGreg Clayton 
1124de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1125de164aaaSGreg Clayton 
1126de164aaaSGreg Clayton          const char *
1127de164aaaSGreg Clayton          GetHelp ()
1128de164aaaSGreg Clayton          {
1129de164aaaSGreg Clayton              if (m_help.empty())
1130de164aaaSGreg Clayton                  return NULL;
1131de164aaaSGreg Clayton              return m_help.c_str();
1132de164aaaSGreg Clayton          }
1133de164aaaSGreg Clayton          const char *
1134de164aaaSGreg Clayton          GetSyntax ()
1135de164aaaSGreg Clayton          {
1136de164aaaSGreg Clayton              if (m_syntax.empty())
1137de164aaaSGreg Clayton                  return NULL;
1138de164aaaSGreg Clayton              return m_syntax.c_str();
1139de164aaaSGreg Clayton          }
1140de164aaaSGreg Clayton          // Instance variables to hold the values for command options.
1141de164aaaSGreg Clayton      protected:
1142de164aaaSGreg Clayton          std::string m_help;
1143de164aaaSGreg Clayton          std::string m_syntax;
1144de164aaaSGreg Clayton      };
1145de164aaaSGreg Clayton 
1146de164aaaSGreg Clayton      virtual Options *
1147de164aaaSGreg Clayton      GetOptions ()
1148de164aaaSGreg Clayton      {
1149de164aaaSGreg Clayton          return &m_options;
1150de164aaaSGreg Clayton      }
1151de164aaaSGreg Clayton 
11525a988416SJim Ingham      CommandOptions m_options;
1153de164aaaSGreg Clayton };
1154de164aaaSGreg Clayton 
1155de164aaaSGreg Clayton OptionDefinition
1156de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1157de164aaaSGreg Clayton {
1158de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "help"  , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1159de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1160de164aaaSGreg Clayton { 0             , false,  NULL   , 0  , 0                , NULL, 0, eArgTypeNone, NULL }
1161de164aaaSGreg Clayton };
1162de164aaaSGreg Clayton 
1163de164aaaSGreg Clayton 
11645a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw
1165223383edSEnrico Granata {
1166223383edSEnrico Granata private:
1167223383edSEnrico Granata     std::string m_function_name;
11680a305db7SEnrico Granata     ScriptedCommandSynchronicity m_synchro;
1169fac939e9SEnrico Granata     bool m_fetched_help_long;
1170223383edSEnrico Granata 
1171223383edSEnrico Granata public:
1172223383edSEnrico Granata 
1173223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1174223383edSEnrico Granata                                  std::string name,
11750a305db7SEnrico Granata                                  std::string funct,
11760a305db7SEnrico Granata                                  ScriptedCommandSynchronicity synch) :
11775a988416SJim Ingham         CommandObjectRaw (interpreter,
1178223383edSEnrico Granata                           name.c_str(),
1179223383edSEnrico Granata                           (std::string("Run Python function ") + funct).c_str(),
1180223383edSEnrico Granata                           NULL),
11810a305db7SEnrico Granata         m_function_name(funct),
1182fac939e9SEnrico Granata         m_synchro(synch),
1183fac939e9SEnrico Granata         m_fetched_help_long(false)
1184223383edSEnrico Granata     {
1185223383edSEnrico Granata     }
1186223383edSEnrico Granata 
1187223383edSEnrico Granata     virtual
1188223383edSEnrico Granata     ~CommandObjectPythonFunction ()
1189223383edSEnrico Granata     {
1190223383edSEnrico Granata     }
1191223383edSEnrico Granata 
1192223383edSEnrico Granata     virtual bool
11933a18e319SGreg Clayton     IsRemovable () const
11945a988416SJim Ingham     {
11955a988416SJim Ingham         return true;
11965a988416SJim Ingham     }
11975a988416SJim Ingham 
11985a988416SJim Ingham     const std::string&
11995a988416SJim Ingham     GetFunctionName ()
12005a988416SJim Ingham     {
12015a988416SJim Ingham         return m_function_name;
12025a988416SJim Ingham     }
12035a988416SJim Ingham 
12045a988416SJim Ingham     ScriptedCommandSynchronicity
12055a988416SJim Ingham     GetSynchronicity ()
12065a988416SJim Ingham     {
12075a988416SJim Ingham         return m_synchro;
12085a988416SJim Ingham     }
12095a988416SJim Ingham 
1210fac939e9SEnrico Granata     virtual const char *
1211fac939e9SEnrico Granata     GetHelpLong ()
1212fac939e9SEnrico Granata     {
1213fac939e9SEnrico Granata         if (!m_fetched_help_long)
1214fac939e9SEnrico Granata         {
1215fac939e9SEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1216fac939e9SEnrico Granata             if (scripter)
1217fac939e9SEnrico Granata             {
1218fac939e9SEnrico Granata                 std::string docstring;
1219fac939e9SEnrico Granata                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1220fac939e9SEnrico Granata                 if (!docstring.empty())
1221fac939e9SEnrico Granata                     SetHelpLong(docstring);
1222fac939e9SEnrico Granata             }
1223fac939e9SEnrico Granata         }
1224fac939e9SEnrico Granata         return CommandObjectRaw::GetHelpLong();
1225fac939e9SEnrico Granata     }
1226fac939e9SEnrico Granata 
12275a988416SJim Ingham protected:
12285a988416SJim Ingham     virtual bool
12295a988416SJim Ingham     DoExecute (const char *raw_command_line, CommandReturnObject &result)
1230223383edSEnrico Granata     {
1231223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1232223383edSEnrico Granata 
1233223383edSEnrico Granata         Error error;
1234223383edSEnrico Granata 
123570f11f88SJim Ingham         result.SetStatus(eReturnStatusInvalid);
123670f11f88SJim Ingham 
1237223383edSEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1238223383edSEnrico Granata                                                          raw_command_line,
12390a305db7SEnrico Granata                                                          m_synchro,
1240223383edSEnrico Granata                                                          result,
1241223383edSEnrico Granata                                                          error) == false)
1242223383edSEnrico Granata         {
1243223383edSEnrico Granata             result.AppendError(error.AsCString());
1244223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1245223383edSEnrico Granata         }
1246223383edSEnrico Granata         else
124770f11f88SJim Ingham         {
124870f11f88SJim Ingham             // Don't change the status if the command already set it...
124970f11f88SJim Ingham             if (result.GetStatus() == eReturnStatusInvalid)
125070f11f88SJim Ingham             {
125170f11f88SJim Ingham                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1252223383edSEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
125370f11f88SJim Ingham                 else
125470f11f88SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishResult);
125570f11f88SJim Ingham             }
125670f11f88SJim Ingham         }
1257223383edSEnrico Granata 
1258223383edSEnrico Granata         return result.Succeeded();
1259223383edSEnrico Granata     }
1260223383edSEnrico Granata 
1261223383edSEnrico Granata };
1262223383edSEnrico Granata 
1263a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1264a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport
1265a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1266a9dbf432SEnrico Granata 
12675a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed
1268a9dbf432SEnrico Granata {
12695a988416SJim Ingham public:
12705a988416SJim Ingham     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
12715a988416SJim Ingham         CommandObjectParsed (interpreter,
12725a988416SJim Ingham                              "command script import",
12735a988416SJim Ingham                              "Import a scripting module in LLDB.",
12745a988416SJim Ingham                              NULL),
12755a988416SJim Ingham         m_options(interpreter)
12765a988416SJim Ingham     {
12775a988416SJim Ingham         CommandArgumentEntry arg1;
12785a988416SJim Ingham         CommandArgumentData cmd_arg;
12795a988416SJim Ingham 
12805a988416SJim Ingham         // Define the first (and only) variant of this arg.
12815a988416SJim Ingham         cmd_arg.arg_type = eArgTypeFilename;
12825a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
12835a988416SJim Ingham 
12845a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
12855a988416SJim Ingham         arg1.push_back (cmd_arg);
12865a988416SJim Ingham 
12875a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
12885a988416SJim Ingham         m_arguments.push_back (arg1);
12895a988416SJim Ingham     }
12905a988416SJim Ingham 
12915a988416SJim Ingham     ~CommandObjectCommandsScriptImport ()
12925a988416SJim Ingham     {
12935a988416SJim Ingham     }
12945a988416SJim Ingham 
1295c7bece56SGreg Clayton     virtual int
12965a988416SJim Ingham     HandleArgumentCompletion (Args &input,
12975a988416SJim Ingham                               int &cursor_index,
12985a988416SJim Ingham                               int &cursor_char_position,
12995a988416SJim Ingham                               OptionElementVector &opt_element_vector,
13005a988416SJim Ingham                               int match_start_point,
13015a988416SJim Ingham                               int max_return_elements,
13025a988416SJim Ingham                               bool &word_complete,
13035a988416SJim Ingham                               StringList &matches)
13045a988416SJim Ingham     {
13055a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
13065a988416SJim Ingham         completion_str.erase (cursor_char_position);
13075a988416SJim Ingham 
13085a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
13095a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
13105a988416SJim Ingham                                                              completion_str.c_str(),
13115a988416SJim Ingham                                                              match_start_point,
13125a988416SJim Ingham                                                              max_return_elements,
13135a988416SJim Ingham                                                              NULL,
13145a988416SJim Ingham                                                              word_complete,
13155a988416SJim Ingham                                                              matches);
13165a988416SJim Ingham         return matches.GetSize();
13175a988416SJim Ingham     }
13185a988416SJim Ingham 
13195a988416SJim Ingham     virtual Options *
13205a988416SJim Ingham     GetOptions ()
13215a988416SJim Ingham     {
13225a988416SJim Ingham         return &m_options;
13235a988416SJim Ingham     }
13245a988416SJim Ingham 
13255a988416SJim Ingham protected:
13260a305db7SEnrico Granata 
13270a305db7SEnrico Granata     class CommandOptions : public Options
13280a305db7SEnrico Granata     {
13290a305db7SEnrico Granata     public:
13300a305db7SEnrico Granata 
13310a305db7SEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
13320a305db7SEnrico Granata             Options (interpreter)
13330a305db7SEnrico Granata         {
13340a305db7SEnrico Granata         }
13350a305db7SEnrico Granata 
13360a305db7SEnrico Granata         virtual
13370a305db7SEnrico Granata         ~CommandOptions (){}
13380a305db7SEnrico Granata 
13390a305db7SEnrico Granata         virtual Error
13400a305db7SEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
13410a305db7SEnrico Granata         {
13420a305db7SEnrico Granata             Error error;
13433bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13440a305db7SEnrico Granata 
13450a305db7SEnrico Granata             switch (short_option)
13460a305db7SEnrico Granata             {
13470a305db7SEnrico Granata                 case 'r':
13480a305db7SEnrico Granata                     m_allow_reload = true;
13490a305db7SEnrico Granata                     break;
13500a305db7SEnrico Granata                 default:
13510a305db7SEnrico Granata                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
13520a305db7SEnrico Granata                     break;
13530a305db7SEnrico Granata             }
13540a305db7SEnrico Granata 
13550a305db7SEnrico Granata             return error;
13560a305db7SEnrico Granata         }
13570a305db7SEnrico Granata 
13580a305db7SEnrico Granata         void
13590a305db7SEnrico Granata         OptionParsingStarting ()
13600a305db7SEnrico Granata         {
1361e0c70f1bSEnrico Granata             m_allow_reload = true;
13620a305db7SEnrico Granata         }
13630a305db7SEnrico Granata 
13640a305db7SEnrico Granata         const OptionDefinition*
13650a305db7SEnrico Granata         GetDefinitions ()
13660a305db7SEnrico Granata         {
13670a305db7SEnrico Granata             return g_option_table;
13680a305db7SEnrico Granata         }
13690a305db7SEnrico Granata 
13700a305db7SEnrico Granata         // Options table: Required for subclasses of Options.
13710a305db7SEnrico Granata 
13720a305db7SEnrico Granata         static OptionDefinition g_option_table[];
13730a305db7SEnrico Granata 
13740a305db7SEnrico Granata         // Instance variables to hold the values for command options.
13750a305db7SEnrico Granata 
13760a305db7SEnrico Granata         bool m_allow_reload;
13770a305db7SEnrico Granata     };
13780a305db7SEnrico Granata 
1379a9dbf432SEnrico Granata     bool
13805a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1381a9dbf432SEnrico Granata     {
1382a9dbf432SEnrico Granata 
1383a9dbf432SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1384a9dbf432SEnrico Granata         {
1385a9dbf432SEnrico Granata             result.AppendError ("only scripting language supported for module importing is currently Python");
1386a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1387a9dbf432SEnrico Granata             return false;
1388a9dbf432SEnrico Granata         }
1389a9dbf432SEnrico Granata 
13905a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1391a9dbf432SEnrico Granata 
1392a9dbf432SEnrico Granata         if (argc != 1)
1393a9dbf432SEnrico Granata         {
1394a9dbf432SEnrico Granata             result.AppendError ("'command script import' requires one argument");
1395a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1396a9dbf432SEnrico Granata             return false;
1397a9dbf432SEnrico Granata         }
1398a9dbf432SEnrico Granata 
13995a988416SJim Ingham         std::string path = command.GetArgumentAtIndex(0);
1400a9dbf432SEnrico Granata         Error error;
1401a9dbf432SEnrico Granata 
1402c9d645d3SGreg Clayton         const bool init_session = true;
1403078551c7SEnrico Granata         // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that
1404078551c7SEnrico Granata         // commands won't ever be recursively invoked, but it's actually possible to craft
1405078551c7SEnrico Granata         // a Python script that does other "command script imports" in __lldb_init_module
1406078551c7SEnrico Granata         // the real fix is to have recursive commands possible with a CommandInvocation object
1407078551c7SEnrico Granata         // separate from the CommandObject itself, so that recursive command invocations
1408078551c7SEnrico Granata         // won't stomp on each other (wrt to execution contents, options, and more)
1409078551c7SEnrico Granata         m_exe_ctx.Clear();
1410a9dbf432SEnrico Granata         if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
14110a305db7SEnrico Granata                                                                       m_options.m_allow_reload,
1412c9d645d3SGreg Clayton                                                                       init_session,
1413a9dbf432SEnrico Granata                                                                       error))
1414a9dbf432SEnrico Granata         {
1415a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1416a9dbf432SEnrico Granata         }
1417a9dbf432SEnrico Granata         else
1418a9dbf432SEnrico Granata         {
1419a9dbf432SEnrico Granata             result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1420a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1421a9dbf432SEnrico Granata         }
1422a9dbf432SEnrico Granata 
1423a9dbf432SEnrico Granata         return result.Succeeded();
1424a9dbf432SEnrico Granata     }
14250a305db7SEnrico Granata 
14265a988416SJim Ingham     CommandOptions m_options;
1427a9dbf432SEnrico Granata };
1428223383edSEnrico Granata 
14290a305db7SEnrico Granata OptionDefinition
14300a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
14310a305db7SEnrico Granata {
1432e0c70f1bSEnrico Granata     { LLDB_OPT_SET_1, false, "allow-reload", 'r', no_argument, NULL, 0, eArgTypeNone,        "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."},
14330a305db7SEnrico Granata     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
14340a305db7SEnrico Granata };
14350a305db7SEnrico Granata 
14360a305db7SEnrico Granata 
1437223383edSEnrico Granata //-------------------------------------------------------------------------
1438223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1439223383edSEnrico Granata //-------------------------------------------------------------------------
1440223383edSEnrico Granata 
14415a988416SJim Ingham class CommandObjectCommandsScriptAdd : public CommandObjectParsed
1442223383edSEnrico Granata {
14435a988416SJim Ingham public:
14445a988416SJim Ingham     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
14455a988416SJim Ingham         CommandObjectParsed (interpreter,
14465a988416SJim Ingham                              "command script add",
14475a988416SJim Ingham                              "Add a scripted function as an LLDB command.",
14485a988416SJim Ingham                              NULL),
14495a988416SJim Ingham         m_options (interpreter)
14505a988416SJim Ingham     {
14515a988416SJim Ingham         CommandArgumentEntry arg1;
14525a988416SJim Ingham         CommandArgumentData cmd_arg;
14535a988416SJim Ingham 
14545a988416SJim Ingham         // Define the first (and only) variant of this arg.
14555a988416SJim Ingham         cmd_arg.arg_type = eArgTypeCommandName;
14565a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
14575a988416SJim Ingham 
14585a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
14595a988416SJim Ingham         arg1.push_back (cmd_arg);
14605a988416SJim Ingham 
14615a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
14625a988416SJim Ingham         m_arguments.push_back (arg1);
14635a988416SJim Ingham     }
14645a988416SJim Ingham 
14655a988416SJim Ingham     ~CommandObjectCommandsScriptAdd ()
14665a988416SJim Ingham     {
14675a988416SJim Ingham     }
14685a988416SJim Ingham 
14695a988416SJim Ingham     virtual Options *
14705a988416SJim Ingham     GetOptions ()
14715a988416SJim Ingham     {
14725a988416SJim Ingham         return &m_options;
14735a988416SJim Ingham     }
14745a988416SJim Ingham 
14755a988416SJim Ingham protected:
1476223383edSEnrico Granata 
1477223383edSEnrico Granata     class CommandOptions : public Options
1478223383edSEnrico Granata     {
1479223383edSEnrico Granata     public:
1480223383edSEnrico Granata 
1481223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
1482223383edSEnrico Granata         Options (interpreter)
1483223383edSEnrico Granata         {
1484223383edSEnrico Granata         }
1485223383edSEnrico Granata 
1486223383edSEnrico Granata         virtual
1487223383edSEnrico Granata         ~CommandOptions (){}
1488223383edSEnrico Granata 
1489223383edSEnrico Granata         virtual Error
1490223383edSEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
1491223383edSEnrico Granata         {
1492223383edSEnrico Granata             Error error;
14933bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
1494223383edSEnrico Granata 
1495223383edSEnrico Granata             switch (short_option)
1496223383edSEnrico Granata             {
1497223383edSEnrico Granata                 case 'f':
1498223383edSEnrico Granata                     m_funct_name = std::string(option_arg);
1499223383edSEnrico Granata                     break;
15000a305db7SEnrico Granata                 case 's':
15010a305db7SEnrico Granata                     m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
15020a305db7SEnrico Granata                     if (!error.Success())
15030a305db7SEnrico Granata                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
15040a305db7SEnrico Granata                     break;
1505223383edSEnrico Granata                 default:
150686edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1507223383edSEnrico Granata                     break;
1508223383edSEnrico Granata             }
1509223383edSEnrico Granata 
1510223383edSEnrico Granata             return error;
1511223383edSEnrico Granata         }
1512223383edSEnrico Granata 
1513223383edSEnrico Granata         void
1514223383edSEnrico Granata         OptionParsingStarting ()
1515223383edSEnrico Granata         {
1516223383edSEnrico Granata             m_funct_name = "";
15170a305db7SEnrico Granata             m_synchronous = eScriptedCommandSynchronicitySynchronous;
1518223383edSEnrico Granata         }
1519223383edSEnrico Granata 
1520223383edSEnrico Granata         const OptionDefinition*
1521223383edSEnrico Granata         GetDefinitions ()
1522223383edSEnrico Granata         {
1523223383edSEnrico Granata             return g_option_table;
1524223383edSEnrico Granata         }
1525223383edSEnrico Granata 
1526223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1527223383edSEnrico Granata 
1528223383edSEnrico Granata         static OptionDefinition g_option_table[];
1529223383edSEnrico Granata 
1530223383edSEnrico Granata         // Instance variables to hold the values for command options.
1531223383edSEnrico Granata 
1532223383edSEnrico Granata         std::string m_funct_name;
15330a305db7SEnrico Granata         ScriptedCommandSynchronicity m_synchronous;
1534223383edSEnrico Granata     };
1535223383edSEnrico Granata 
15365a988416SJim Ingham private:
1537223383edSEnrico Granata     class PythonAliasReader : public InputReaderEZ
1538223383edSEnrico Granata     {
1539223383edSEnrico Granata     private:
1540223383edSEnrico Granata         CommandInterpreter& m_interpreter;
1541223383edSEnrico Granata         std::string m_cmd_name;
15420a305db7SEnrico Granata         ScriptedCommandSynchronicity m_synchronous;
1543223383edSEnrico Granata         StringList m_user_input;
1544223383edSEnrico Granata         DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1545223383edSEnrico Granata     public:
1546223383edSEnrico Granata         PythonAliasReader(Debugger& debugger,
1547223383edSEnrico Granata                           CommandInterpreter& interpreter,
15480a305db7SEnrico Granata                           std::string cmd_name,
15490a305db7SEnrico Granata                           ScriptedCommandSynchronicity synch) :
1550223383edSEnrico Granata         InputReaderEZ(debugger),
1551223383edSEnrico Granata         m_interpreter(interpreter),
1552223383edSEnrico Granata         m_cmd_name(cmd_name),
15530a305db7SEnrico Granata         m_synchronous(synch),
1554223383edSEnrico Granata         m_user_input()
1555223383edSEnrico Granata         {}
1556223383edSEnrico Granata 
1557223383edSEnrico Granata         virtual
1558223383edSEnrico Granata         ~PythonAliasReader()
1559223383edSEnrico Granata         {
1560223383edSEnrico Granata         }
1561223383edSEnrico Granata 
1562223383edSEnrico Granata         virtual void ActivateHandler(HandlerData& data)
1563223383edSEnrico Granata         {
1564223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1565223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1566223383edSEnrico Granata             if (!batch_mode)
1567223383edSEnrico Granata             {
1568223383edSEnrico Granata                 out_stream->Printf ("%s\n", g_python_command_instructions);
1569223383edSEnrico Granata                 if (data.reader.GetPrompt())
1570223383edSEnrico Granata                     out_stream->Printf ("%s", data.reader.GetPrompt());
1571223383edSEnrico Granata                 out_stream->Flush();
1572223383edSEnrico Granata             }
1573223383edSEnrico Granata         }
1574223383edSEnrico Granata 
1575223383edSEnrico Granata         virtual void ReactivateHandler(HandlerData& data)
1576223383edSEnrico Granata         {
1577223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1578223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1579223383edSEnrico Granata             if (data.reader.GetPrompt() && !batch_mode)
1580223383edSEnrico Granata             {
1581223383edSEnrico Granata                 out_stream->Printf ("%s", data.reader.GetPrompt());
1582223383edSEnrico Granata                 out_stream->Flush();
1583223383edSEnrico Granata             }
1584223383edSEnrico Granata         }
1585223383edSEnrico Granata         virtual void GotTokenHandler(HandlerData& data)
1586223383edSEnrico Granata         {
1587223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1588223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1589223383edSEnrico Granata             if (data.bytes && data.bytes_len)
1590223383edSEnrico Granata             {
1591223383edSEnrico Granata                 m_user_input.AppendString(data.bytes, data.bytes_len);
1592223383edSEnrico Granata             }
1593223383edSEnrico Granata             if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1594223383edSEnrico Granata             {
1595223383edSEnrico Granata                 out_stream->Printf ("%s", data.reader.GetPrompt());
1596223383edSEnrico Granata                 out_stream->Flush();
1597223383edSEnrico Granata             }
1598223383edSEnrico Granata         }
1599223383edSEnrico Granata         virtual void InterruptHandler(HandlerData& data)
1600223383edSEnrico Granata         {
1601223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1602223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1603223383edSEnrico Granata             data.reader.SetIsDone (true);
1604223383edSEnrico Granata             if (!batch_mode)
1605223383edSEnrico Granata             {
16060a305db7SEnrico Granata                 out_stream->Printf ("Warning: No script attached.\n");
1607223383edSEnrico Granata                 out_stream->Flush();
1608223383edSEnrico Granata             }
1609223383edSEnrico Granata         }
1610223383edSEnrico Granata         virtual void EOFHandler(HandlerData& data)
1611223383edSEnrico Granata         {
1612223383edSEnrico Granata             data.reader.SetIsDone (true);
1613223383edSEnrico Granata         }
1614223383edSEnrico Granata         virtual void DoneHandler(HandlerData& data)
1615223383edSEnrico Granata         {
1616223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1617223383edSEnrico Granata 
1618223383edSEnrico Granata             ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1619223383edSEnrico Granata             if (!interpreter)
1620223383edSEnrico Granata             {
16210a305db7SEnrico Granata                 out_stream->Printf ("Script interpreter missing: no script attached.\n");
1622223383edSEnrico Granata                 out_stream->Flush();
1623223383edSEnrico Granata                 return;
1624223383edSEnrico Granata             }
1625a73b7df7SEnrico Granata             std::string funct_name_str;
1626223383edSEnrico Granata             if (!interpreter->GenerateScriptAliasFunction (m_user_input,
1627a73b7df7SEnrico Granata                                                            funct_name_str))
1628223383edSEnrico Granata             {
16290a305db7SEnrico Granata                 out_stream->Printf ("Unable to create function: no script attached.\n");
1630223383edSEnrico Granata                 out_stream->Flush();
1631223383edSEnrico Granata                 return;
1632223383edSEnrico Granata             }
1633a73b7df7SEnrico Granata             if (funct_name_str.empty())
1634223383edSEnrico Granata             {
16350a305db7SEnrico Granata                 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
1636223383edSEnrico Granata                 out_stream->Flush();
1637223383edSEnrico Granata                 return;
1638223383edSEnrico Granata             }
1639223383edSEnrico Granata             // everything should be fine now, let's add this alias
1640223383edSEnrico Granata 
1641223383edSEnrico Granata             CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1642223383edSEnrico Granata                                                                            m_cmd_name,
1643a73b7df7SEnrico Granata                                                                            funct_name_str.c_str(),
16440a305db7SEnrico Granata                                                                            m_synchronous));
1645223383edSEnrico Granata 
16460a305db7SEnrico Granata             if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1647223383edSEnrico Granata             {
16480a305db7SEnrico Granata                 out_stream->Printf ("Unable to add selected command: no script attached.\n");
1649223383edSEnrico Granata                 out_stream->Flush();
1650223383edSEnrico Granata                 return;
1651223383edSEnrico Granata             }
1652223383edSEnrico Granata         }
1653223383edSEnrico Granata     };
1654223383edSEnrico Granata 
16555a988416SJim Ingham protected:
1656223383edSEnrico Granata     bool
16575a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1658223383edSEnrico Granata     {
165999f0b8f9SEnrico Granata 
166099f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
166199f0b8f9SEnrico Granata         {
166299f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
166399f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
166499f0b8f9SEnrico Granata             return false;
166599f0b8f9SEnrico Granata         }
166699f0b8f9SEnrico Granata 
16675a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1668223383edSEnrico Granata 
1669223383edSEnrico Granata         if (argc != 1)
1670223383edSEnrico Granata         {
1671223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
1672223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1673223383edSEnrico Granata             return false;
1674223383edSEnrico Granata         }
1675223383edSEnrico Granata 
16765a988416SJim Ingham         std::string cmd_name = command.GetArgumentAtIndex(0);
1677223383edSEnrico Granata 
1678223383edSEnrico Granata         if (m_options.m_funct_name.empty())
1679223383edSEnrico Granata         {
1680223383edSEnrico Granata             InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1681223383edSEnrico Granata                                                             m_interpreter,
16820a305db7SEnrico Granata                                                             cmd_name,
16830a305db7SEnrico Granata                                                             m_options.m_synchronous));
1684223383edSEnrico Granata 
1685223383edSEnrico Granata             if (reader_sp)
1686223383edSEnrico Granata             {
1687223383edSEnrico Granata 
1688223383edSEnrico Granata                 InputReaderEZ::InitializationParameters ipr;
1689223383edSEnrico Granata 
1690223383edSEnrico Granata                 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt("     ")));
1691223383edSEnrico Granata                 if (err.Success())
1692223383edSEnrico Granata                 {
1693223383edSEnrico Granata                     m_interpreter.GetDebugger().PushInputReader (reader_sp);
1694223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1695223383edSEnrico Granata                 }
1696223383edSEnrico Granata                 else
1697223383edSEnrico Granata                 {
1698223383edSEnrico Granata                     result.AppendError (err.AsCString());
1699223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
1700223383edSEnrico Granata                 }
1701223383edSEnrico Granata             }
1702223383edSEnrico Granata             else
1703223383edSEnrico Granata             {
1704223383edSEnrico Granata                 result.AppendError("out of memory");
1705223383edSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1706223383edSEnrico Granata             }
1707223383edSEnrico Granata         }
1708223383edSEnrico Granata         else
1709223383edSEnrico Granata         {
17100a305db7SEnrico Granata             CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
17110a305db7SEnrico Granata                                                                     cmd_name,
17120a305db7SEnrico Granata                                                                     m_options.m_funct_name,
17130a305db7SEnrico Granata                                                                     m_options.m_synchronous));
17140a305db7SEnrico Granata             if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
1715223383edSEnrico Granata             {
1716223383edSEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1717223383edSEnrico Granata             }
1718223383edSEnrico Granata             else
1719223383edSEnrico Granata             {
1720223383edSEnrico Granata                 result.AppendError("cannot add command");
1721223383edSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1722223383edSEnrico Granata             }
1723223383edSEnrico Granata         }
1724223383edSEnrico Granata 
1725223383edSEnrico Granata         return result.Succeeded();
1726223383edSEnrico Granata 
1727223383edSEnrico Granata     }
17285a988416SJim Ingham 
17295a988416SJim Ingham     CommandOptions m_options;
1730223383edSEnrico Granata };
1731223383edSEnrico Granata 
17320a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] =
17330a305db7SEnrico Granata {
17340a305db7SEnrico Granata     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
17350a305db7SEnrico Granata     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
17360a305db7SEnrico Granata     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
17370a305db7SEnrico Granata     { 0, NULL, NULL }
17380a305db7SEnrico Granata };
17390a305db7SEnrico Granata 
1740223383edSEnrico Granata OptionDefinition
1741223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1742223383edSEnrico Granata {
17439128ee2fSEnrico Granata     { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."},
17440a305db7SEnrico Granata     { LLDB_OPT_SET_1, false, "synchronicity", 's', required_argument, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity,        "Set the synchronicity of this command's executions with regard to LLDB event system."},
1745223383edSEnrico Granata     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1746223383edSEnrico Granata };
1747223383edSEnrico Granata 
1748223383edSEnrico Granata //-------------------------------------------------------------------------
1749223383edSEnrico Granata // CommandObjectCommandsScriptList
1750223383edSEnrico Granata //-------------------------------------------------------------------------
1751223383edSEnrico Granata 
17525a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed
1753223383edSEnrico Granata {
1754223383edSEnrico Granata private:
1755223383edSEnrico Granata 
1756223383edSEnrico Granata public:
1757223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
17585a988416SJim Ingham     CommandObjectParsed (interpreter,
1759223383edSEnrico Granata                    "command script list",
1760223383edSEnrico Granata                    "List defined scripted commands.",
1761223383edSEnrico Granata                    NULL)
1762223383edSEnrico Granata     {
1763223383edSEnrico Granata     }
1764223383edSEnrico Granata 
1765223383edSEnrico Granata     ~CommandObjectCommandsScriptList ()
1766223383edSEnrico Granata     {
1767223383edSEnrico Granata     }
1768223383edSEnrico Granata 
1769223383edSEnrico Granata     bool
17705a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1771223383edSEnrico Granata     {
1772223383edSEnrico Granata 
1773223383edSEnrico Granata         m_interpreter.GetHelp(result,
1774223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
1775223383edSEnrico Granata 
1776223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
1777223383edSEnrico Granata 
1778223383edSEnrico Granata         return true;
1779223383edSEnrico Granata 
1780223383edSEnrico Granata 
1781223383edSEnrico Granata     }
1782223383edSEnrico Granata };
1783223383edSEnrico Granata 
1784223383edSEnrico Granata //-------------------------------------------------------------------------
1785223383edSEnrico Granata // CommandObjectCommandsScriptClear
1786223383edSEnrico Granata //-------------------------------------------------------------------------
1787223383edSEnrico Granata 
17885a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed
1789223383edSEnrico Granata {
1790223383edSEnrico Granata private:
1791223383edSEnrico Granata 
1792223383edSEnrico Granata public:
1793223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
17945a988416SJim Ingham         CommandObjectParsed (interpreter,
1795223383edSEnrico Granata                              "command script clear",
1796223383edSEnrico Granata                              "Delete all scripted commands.",
1797223383edSEnrico Granata                              NULL)
1798223383edSEnrico Granata     {
1799223383edSEnrico Granata     }
1800223383edSEnrico Granata 
1801223383edSEnrico Granata     ~CommandObjectCommandsScriptClear ()
1802223383edSEnrico Granata     {
1803223383edSEnrico Granata     }
1804223383edSEnrico Granata 
18055a988416SJim Ingham protected:
1806223383edSEnrico Granata     bool
18075a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1808223383edSEnrico Granata     {
1809223383edSEnrico Granata 
1810223383edSEnrico Granata         m_interpreter.RemoveAllUser();
1811223383edSEnrico Granata 
1812223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
1813223383edSEnrico Granata 
1814223383edSEnrico Granata         return true;
1815223383edSEnrico Granata     }
1816223383edSEnrico Granata };
1817223383edSEnrico Granata 
1818223383edSEnrico Granata //-------------------------------------------------------------------------
1819223383edSEnrico Granata // CommandObjectCommandsScriptDelete
1820223383edSEnrico Granata //-------------------------------------------------------------------------
1821223383edSEnrico Granata 
18225a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed
1823223383edSEnrico Granata {
1824223383edSEnrico Granata public:
1825223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
18265a988416SJim Ingham         CommandObjectParsed (interpreter,
1827223383edSEnrico Granata                              "command script delete",
1828223383edSEnrico Granata                              "Delete a scripted command.",
1829223383edSEnrico Granata                              NULL)
1830223383edSEnrico Granata     {
1831223383edSEnrico Granata         CommandArgumentEntry arg1;
1832223383edSEnrico Granata         CommandArgumentData cmd_arg;
1833223383edSEnrico Granata 
1834223383edSEnrico Granata         // Define the first (and only) variant of this arg.
1835223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
1836223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
1837223383edSEnrico Granata 
1838223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
1839223383edSEnrico Granata         arg1.push_back (cmd_arg);
1840223383edSEnrico Granata 
1841223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
1842223383edSEnrico Granata         m_arguments.push_back (arg1);
1843223383edSEnrico Granata     }
1844223383edSEnrico Granata 
1845223383edSEnrico Granata     ~CommandObjectCommandsScriptDelete ()
1846223383edSEnrico Granata     {
1847223383edSEnrico Granata     }
1848223383edSEnrico Granata 
18495a988416SJim Ingham protected:
1850223383edSEnrico Granata     bool
18515a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1852223383edSEnrico Granata     {
1853223383edSEnrico Granata 
18545a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1855223383edSEnrico Granata 
1856223383edSEnrico Granata         if (argc != 1)
1857223383edSEnrico Granata         {
1858223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
1859223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1860223383edSEnrico Granata             return false;
1861223383edSEnrico Granata         }
1862223383edSEnrico Granata 
18635a988416SJim Ingham         const char* cmd_name = command.GetArgumentAtIndex(0);
1864223383edSEnrico Granata 
1865223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1866223383edSEnrico Granata         {
1867223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
1868223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
1869223383edSEnrico Granata         }
1870223383edSEnrico Granata         else
1871223383edSEnrico Granata         {
1872223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
1873223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1874223383edSEnrico Granata         }
1875223383edSEnrico Granata 
1876223383edSEnrico Granata         return result.Succeeded();
1877223383edSEnrico Granata 
1878223383edSEnrico Granata     }
1879223383edSEnrico Granata };
1880223383edSEnrico Granata 
1881223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
1882223383edSEnrico Granata 
1883223383edSEnrico Granata //-------------------------------------------------------------------------
1884223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
1885223383edSEnrico Granata //-------------------------------------------------------------------------
1886223383edSEnrico Granata 
1887223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1888223383edSEnrico Granata {
1889223383edSEnrico Granata public:
1890223383edSEnrico Granata     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1891223383edSEnrico Granata     CommandObjectMultiword (interpreter,
1892223383edSEnrico Granata                             "command script",
1893223383edSEnrico Granata                             "A set of commands for managing or customizing script commands.",
1894223383edSEnrico Granata                             "command script <subcommand> [<subcommand-options>]")
1895223383edSEnrico Granata     {
1896223383edSEnrico Granata         LoadSubCommand ("add",  CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1897223383edSEnrico Granata         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1898223383edSEnrico Granata         LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1899223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
1900a9dbf432SEnrico Granata         LoadSubCommand ("import",   CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
1901223383edSEnrico Granata     }
1902223383edSEnrico Granata 
1903223383edSEnrico Granata     ~CommandObjectMultiwordCommandsScript ()
1904223383edSEnrico Granata     {
1905223383edSEnrico Granata     }
1906223383edSEnrico Granata 
1907223383edSEnrico Granata };
1908223383edSEnrico Granata 
1909223383edSEnrico Granata 
1910ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
1911ebc09c36SJim Ingham 
1912ebc09c36SJim Ingham //-------------------------------------------------------------------------
1913ebc09c36SJim Ingham // CommandObjectMultiwordCommands
1914ebc09c36SJim Ingham //-------------------------------------------------------------------------
1915ebc09c36SJim Ingham 
1916ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
1917a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
19180e5e5a79SGreg Clayton                             "command",
19193f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
19200e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
1921ebc09c36SJim Ingham {
1922a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1923a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1924a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
1925de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
1926a5a97ebeSJim Ingham     LoadSubCommand ("history",   CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
1927223383edSEnrico Granata     LoadSubCommand ("script",   CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
1928ebc09c36SJim Ingham }
1929ebc09c36SJim Ingham 
1930ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1931ebc09c36SJim Ingham {
1932ebc09c36SJim Ingham }
1933ebc09c36SJim Ingham 
1934