1ebc09c36SJim Ingham //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
2ebc09c36SJim Ingham //
3ebc09c36SJim Ingham //                     The LLVM Compiler Infrastructure
4ebc09c36SJim Ingham //
5ebc09c36SJim Ingham // This file is distributed under the University of Illinois Open Source
6ebc09c36SJim Ingham // License. See LICENSE.TXT for details.
7ebc09c36SJim Ingham //
8ebc09c36SJim Ingham //===----------------------------------------------------------------------===//
9ebc09c36SJim Ingham 
10ebc09c36SJim Ingham #include "CommandObjectCommands.h"
11ebc09c36SJim Ingham 
12ebc09c36SJim Ingham // C Includes
13ebc09c36SJim Ingham // C++ Includes
14ebc09c36SJim Ingham // Other libraries and framework includes
150e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h"
160e5e5a79SGreg Clayton 
17ebc09c36SJim Ingham // Project includes
18ebc09c36SJim Ingham #include "lldb/Core/Debugger.h"
19de164aaaSGreg Clayton #include "lldb/Core/InputReader.h"
20be93a35aSEnrico Granata #include "lldb/Core/InputReaderEZ.h"
21be93a35aSEnrico Granata #include "lldb/Core/StringList.h"
22de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h"
23ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h"
24de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h"
25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h"
26ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
2799f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h"
2899f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreterPython.h"
29ebc09c36SJim Ingham 
30ebc09c36SJim Ingham using namespace lldb;
31ebc09c36SJim Ingham using namespace lldb_private;
32ebc09c36SJim Ingham 
33ebc09c36SJim Ingham //-------------------------------------------------------------------------
34ebc09c36SJim Ingham // CommandObjectCommandsSource
35ebc09c36SJim Ingham //-------------------------------------------------------------------------
36ebc09c36SJim Ingham 
375a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed
38a5a97ebeSJim Ingham {
395a988416SJim Ingham public:
405a988416SJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
415a988416SJim Ingham         CommandObjectParsed (interpreter,
425a988416SJim Ingham                              "command history",
435a988416SJim Ingham                              "Dump the history of commands in this session.",
445a988416SJim Ingham                              NULL),
455a988416SJim Ingham         m_options (interpreter)
465a988416SJim Ingham     {
475a988416SJim Ingham     }
485a988416SJim Ingham 
495a988416SJim Ingham     ~CommandObjectCommandsHistory () {}
505a988416SJim Ingham 
515a988416SJim Ingham     virtual Options *
525a988416SJim Ingham     GetOptions ()
535a988416SJim Ingham     {
545a988416SJim Ingham         return &m_options;
555a988416SJim Ingham     }
565a988416SJim Ingham 
575a988416SJim Ingham protected:
58a5a97ebeSJim Ingham 
59a5a97ebeSJim Ingham     class CommandOptions : public Options
60a5a97ebeSJim Ingham     {
61a5a97ebeSJim Ingham     public:
62a5a97ebeSJim Ingham 
63a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
64a5a97ebeSJim Ingham             Options (interpreter)
65a5a97ebeSJim Ingham         {
66a5a97ebeSJim Ingham         }
67a5a97ebeSJim Ingham 
68a5a97ebeSJim Ingham         virtual
69a5a97ebeSJim Ingham         ~CommandOptions (){}
70a5a97ebeSJim Ingham 
71a5a97ebeSJim Ingham         virtual Error
72a5a97ebeSJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
73a5a97ebeSJim Ingham         {
74a5a97ebeSJim Ingham             Error error;
75*3bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
76a5a97ebeSJim Ingham             bool success;
77a5a97ebeSJim Ingham 
78a5a97ebeSJim Ingham             switch (short_option)
79a5a97ebeSJim Ingham             {
80a5a97ebeSJim Ingham                 case 'c':
81a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
82a5a97ebeSJim Ingham                     if (!success)
8386edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for count: %s", option_arg);
84a5a97ebeSJim Ingham                     if (m_end_idx != 0)
85a5a97ebeSJim Ingham                         m_end_idx--;
86a5a97ebeSJim Ingham                     m_start_idx = 0;
87a5a97ebeSJim Ingham                     break;
88a5a97ebeSJim Ingham                 case 'e':
89a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
90a5a97ebeSJim Ingham                     if (!success)
9186edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for end index: %s", option_arg);
92a5a97ebeSJim Ingham                     break;
93a5a97ebeSJim Ingham                 case 's':
94a5a97ebeSJim Ingham                     m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
95a5a97ebeSJim Ingham                     if (!success)
9686edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for start index: %s", option_arg);
97a5a97ebeSJim Ingham                     break;
98a5a97ebeSJim Ingham                 default:
9986edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
100a5a97ebeSJim Ingham                     break;
101a5a97ebeSJim Ingham             }
102a5a97ebeSJim Ingham 
103a5a97ebeSJim Ingham             return error;
104a5a97ebeSJim Ingham         }
105a5a97ebeSJim Ingham 
106a5a97ebeSJim Ingham         void
107a5a97ebeSJim Ingham         OptionParsingStarting ()
108a5a97ebeSJim Ingham         {
109a5a97ebeSJim Ingham             m_start_idx = 0;
110a5a97ebeSJim Ingham             m_end_idx = UINT_MAX;
111a5a97ebeSJim Ingham         }
112a5a97ebeSJim Ingham 
113a5a97ebeSJim Ingham         const OptionDefinition*
114a5a97ebeSJim Ingham         GetDefinitions ()
115a5a97ebeSJim Ingham         {
116a5a97ebeSJim Ingham             return g_option_table;
117a5a97ebeSJim Ingham         }
118a5a97ebeSJim Ingham 
119a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
120a5a97ebeSJim Ingham 
121a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
122a5a97ebeSJim Ingham 
123a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
124a5a97ebeSJim Ingham 
125a5a97ebeSJim Ingham         uint32_t m_start_idx;
126a5a97ebeSJim Ingham         uint32_t m_end_idx;
127a5a97ebeSJim Ingham     };
128a5a97ebeSJim Ingham 
129a5a97ebeSJim Ingham     bool
1305a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
131a5a97ebeSJim Ingham     {
132a5a97ebeSJim Ingham 
133a5a97ebeSJim Ingham         m_interpreter.DumpHistory (result.GetOutputStream(),
134a5a97ebeSJim Ingham                                    m_options.m_start_idx,
135a5a97ebeSJim Ingham                                    m_options.m_end_idx);
136a5a97ebeSJim Ingham         return result.Succeeded();
137a5a97ebeSJim Ingham 
138a5a97ebeSJim Ingham     }
1395a988416SJim Ingham 
1405a988416SJim Ingham     CommandOptions m_options;
141a5a97ebeSJim Ingham };
142a5a97ebeSJim Ingham 
143a5a97ebeSJim Ingham OptionDefinition
144a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
145a5a97ebeSJim Ingham {
146a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
147a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger,  "Index at which to start printing history commands."},
148a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
149a5a97ebeSJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
150a5a97ebeSJim Ingham };
151a5a97ebeSJim Ingham 
152a5a97ebeSJim Ingham 
153a5a97ebeSJim Ingham //-------------------------------------------------------------------------
154a5a97ebeSJim Ingham // CommandObjectCommandsSource
155a5a97ebeSJim Ingham //-------------------------------------------------------------------------
156a5a97ebeSJim Ingham 
1575a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed
158ebc09c36SJim Ingham {
1595a988416SJim Ingham public:
1605a988416SJim Ingham     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
1615a988416SJim Ingham         CommandObjectParsed (interpreter,
1625a988416SJim Ingham                              "command source",
1635a988416SJim Ingham                              "Read in debugger commands from the file <filename> and execute them.",
1645a988416SJim Ingham                              NULL),
1655a988416SJim Ingham         m_options (interpreter)
1665a988416SJim Ingham     {
1675a988416SJim Ingham         CommandArgumentEntry arg;
1685a988416SJim Ingham         CommandArgumentData file_arg;
1695a988416SJim Ingham 
1705a988416SJim Ingham         // Define the first (and only) variant of this arg.
1715a988416SJim Ingham         file_arg.arg_type = eArgTypeFilename;
1725a988416SJim Ingham         file_arg.arg_repetition = eArgRepeatPlain;
1735a988416SJim Ingham 
1745a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
1755a988416SJim Ingham         arg.push_back (file_arg);
1765a988416SJim Ingham 
1775a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
1785a988416SJim Ingham         m_arguments.push_back (arg);
1795a988416SJim Ingham     }
1805a988416SJim Ingham 
1815a988416SJim Ingham     ~CommandObjectCommandsSource () {}
1825a988416SJim Ingham 
1835a988416SJim Ingham     virtual const char*
1845a988416SJim Ingham     GetRepeatCommand (Args &current_command_args, uint32_t index)
1855a988416SJim Ingham     {
1865a988416SJim Ingham         return "";
1875a988416SJim Ingham     }
1885a988416SJim Ingham 
1895a988416SJim Ingham     int
1905a988416SJim Ingham     HandleArgumentCompletion (Args &input,
1915a988416SJim Ingham                               int &cursor_index,
1925a988416SJim Ingham                               int &cursor_char_position,
1935a988416SJim Ingham                               OptionElementVector &opt_element_vector,
1945a988416SJim Ingham                               int match_start_point,
1955a988416SJim Ingham                               int max_return_elements,
1965a988416SJim Ingham                               bool &word_complete,
1975a988416SJim Ingham                               StringList &matches)
1985a988416SJim Ingham     {
1995a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2005a988416SJim Ingham         completion_str.erase (cursor_char_position);
2015a988416SJim Ingham 
2025a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2035a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
2045a988416SJim Ingham                                                              completion_str.c_str(),
2055a988416SJim Ingham                                                              match_start_point,
2065a988416SJim Ingham                                                              max_return_elements,
2075a988416SJim Ingham                                                              NULL,
2085a988416SJim Ingham                                                              word_complete,
2095a988416SJim Ingham                                                              matches);
2105a988416SJim Ingham         return matches.GetSize();
2115a988416SJim Ingham     }
2125a988416SJim Ingham 
2135a988416SJim Ingham     virtual Options *
2145a988416SJim Ingham     GetOptions ()
2155a988416SJim Ingham     {
2165a988416SJim Ingham         return &m_options;
2175a988416SJim Ingham     }
2185a988416SJim Ingham 
2195a988416SJim Ingham protected:
220e16c50a1SJim Ingham 
221e16c50a1SJim Ingham     class CommandOptions : public Options
222e16c50a1SJim Ingham     {
223e16c50a1SJim Ingham     public:
224e16c50a1SJim Ingham 
225eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
226eb0103f2SGreg Clayton             Options (interpreter)
227eb0103f2SGreg Clayton         {
228eb0103f2SGreg Clayton         }
229e16c50a1SJim Ingham 
230e16c50a1SJim Ingham         virtual
231e16c50a1SJim Ingham         ~CommandOptions (){}
232e16c50a1SJim Ingham 
233e16c50a1SJim Ingham         virtual Error
234f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
235e16c50a1SJim Ingham         {
236e16c50a1SJim Ingham             Error error;
237*3bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
238e16c50a1SJim Ingham             bool success;
239e16c50a1SJim Ingham 
240e16c50a1SJim Ingham             switch (short_option)
241e16c50a1SJim Ingham             {
242e16c50a1SJim Ingham                 case 'e':
243e16c50a1SJim Ingham                     m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
244e16c50a1SJim Ingham                     if (!success)
24586edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for stop-on-error: %s", option_arg);
246e16c50a1SJim Ingham                     break;
247e16c50a1SJim Ingham                 case 'c':
248e16c50a1SJim Ingham                     m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
249e16c50a1SJim Ingham                     if (!success)
25086edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg);
251e16c50a1SJim Ingham                     break;
252e16c50a1SJim Ingham                 default:
25386edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
254e16c50a1SJim Ingham                     break;
255e16c50a1SJim Ingham             }
256e16c50a1SJim Ingham 
257e16c50a1SJim Ingham             return error;
258e16c50a1SJim Ingham         }
259e16c50a1SJim Ingham 
260e16c50a1SJim Ingham         void
261f6b8b581SGreg Clayton         OptionParsingStarting ()
262e16c50a1SJim Ingham         {
263e16c50a1SJim Ingham             m_stop_on_error = true;
264e16c50a1SJim Ingham             m_stop_on_continue = true;
265e16c50a1SJim Ingham         }
266e16c50a1SJim Ingham 
267e0d378b3SGreg Clayton         const OptionDefinition*
268e16c50a1SJim Ingham         GetDefinitions ()
269e16c50a1SJim Ingham         {
270e16c50a1SJim Ingham             return g_option_table;
271e16c50a1SJim Ingham         }
272e16c50a1SJim Ingham 
273e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
274e16c50a1SJim Ingham 
275e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
276e16c50a1SJim Ingham 
277e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
278e16c50a1SJim Ingham 
279e16c50a1SJim Ingham         bool m_stop_on_error;
280e16c50a1SJim Ingham         bool m_stop_on_continue;
281e16c50a1SJim Ingham     };
282e16c50a1SJim Ingham 
283ebc09c36SJim Ingham     bool
2845a988416SJim Ingham     DoExecute(Args& command, CommandReturnObject &result)
285ebc09c36SJim Ingham     {
2865a988416SJim Ingham         const int argc = command.GetArgumentCount();
287ebc09c36SJim Ingham         if (argc == 1)
288ebc09c36SJim Ingham         {
2895a988416SJim Ingham             const char *filename = command.GetArgumentAtIndex(0);
290ebc09c36SJim Ingham 
291ebc09c36SJim Ingham             result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
292ebc09c36SJim Ingham 
2931ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
294e16c50a1SJim Ingham             ExecutionContext *exe_ctx = NULL;  // Just use the default context.
295e16c50a1SJim Ingham             bool echo_commands    = true;
296e16c50a1SJim Ingham             bool print_results    = true;
297ebc09c36SJim Ingham 
298e16c50a1SJim Ingham             m_interpreter.HandleCommandsFromFile (cmd_file,
299e16c50a1SJim Ingham                                                   exe_ctx,
300e16c50a1SJim Ingham                                                   m_options.m_stop_on_continue,
301e16c50a1SJim Ingham                                                   m_options.m_stop_on_error,
302e16c50a1SJim Ingham                                                   echo_commands,
303e16c50a1SJim Ingham                                                   print_results,
3045f5ab602SEnrico Granata                                                   eLazyBoolCalculate,
305e16c50a1SJim Ingham                                                   result);
306ebc09c36SJim Ingham         }
307ebc09c36SJim Ingham         else
308ebc09c36SJim Ingham         {
309ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
310ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
311ebc09c36SJim Ingham         }
312ebc09c36SJim Ingham         return result.Succeeded();
313ebc09c36SJim Ingham 
314ebc09c36SJim Ingham     }
3155a988416SJim Ingham     CommandOptions m_options;
316ebc09c36SJim Ingham };
317ebc09c36SJim Ingham 
318e0d378b3SGreg Clayton OptionDefinition
319e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
320e16c50a1SJim Ingham {
321e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
322e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
323e16c50a1SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
324e16c50a1SJim Ingham };
325e16c50a1SJim Ingham 
326ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
327ebc09c36SJim Ingham //-------------------------------------------------------------------------
328ebc09c36SJim Ingham // CommandObjectCommandsAlias
329ebc09c36SJim Ingham //-------------------------------------------------------------------------
330ebc09c36SJim Ingham 
331be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
332be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
33340d55710SEnrico Granata                                                      "def my_command_impl(debugger, args, result, internal_dict):";
334be93a35aSEnrico Granata 
335be93a35aSEnrico Granata 
3365a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw
337ebc09c36SJim Ingham {
338be93a35aSEnrico Granata 
339be93a35aSEnrico Granata 
340ebc09c36SJim Ingham public:
341a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
3425a988416SJim Ingham         CommandObjectRaw (interpreter,
3430e5e5a79SGreg Clayton                        "command alias",
344e3d26315SCaroline Tice                        "Allow users to define their own debugger command abbreviations.",
345405fe67fSCaroline Tice                        NULL)
346ebc09c36SJim Ingham     {
347ebc09c36SJim Ingham         SetHelpLong(
348ebc09c36SJim Ingham     "'alias' allows the user to create a short-cut or abbreviation for long \n\
349ebc09c36SJim Ingham     commands, multi-word commands, and commands that take particular options. \n\
350ebc09c36SJim Ingham     Below are some simple examples of how one might use the 'alias' command: \n\
35169c12ccbSJason Molenda     \n    'command alias sc script'            // Creates the abbreviation 'sc' for the 'script' \n\
352ebc09c36SJim Ingham                                          // command. \n\
35369c12ccbSJason Molenda     'command alias bp breakpoint'        // Creates the abbreviation 'bp' for the 'breakpoint' \n\
354ebc09c36SJim Ingham                                          // command.  Since breakpoint commands are two-word \n\
355ebc09c36SJim Ingham                                          // commands, the user will still need to enter the \n\
356ebc09c36SJim Ingham                                          // second word after 'bp', e.g. 'bp enable' or \n\
357ebc09c36SJim Ingham                                          // 'bp delete'. \n\
35869c12ccbSJason Molenda     'command alias bpl breakpoint list'  // Creates the abbreviation 'bpl' for the \n\
359ebc09c36SJim Ingham                                          // two-word command 'breakpoint list'. \n\
360ebc09c36SJim Ingham     \nAn alias can include some options for the command, with the values either \n\
361ebc09c36SJim Ingham     filled in at the time the alias is created, or specified as positional \n\
362ebc09c36SJim Ingham     arguments, to be filled in when the alias is invoked.  The following example \n\
363ebc09c36SJim Ingham     shows how to create aliases with options: \n\
364ebc09c36SJim Ingham     \n\
36569c12ccbSJason Molenda     'command alias bfl breakpoint set -f %1 -l %2' \n\
366ebc09c36SJim Ingham     \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
367ebc09c36SJim Ingham     options already part of the alias.  So if the user wants to set a breakpoint \n\
368ebc09c36SJim Ingham     by file and line without explicitly having to use the -f and -l options, the \n\
369ebc09c36SJim Ingham     user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \n\
370ebc09c36SJim Ingham     for the actual arguments that will be passed when the alias command is used. \n\
371ebc09c36SJim Ingham     The number in the placeholder refers to the position/order the actual value \n\
37281ded935SJim Ingham     occupies when the alias is used.  All the occurrences of '%1' in the alias \n\
373ebc09c36SJim Ingham     will be replaced with the first argument, all the occurrences of '%2' in the \n\
374ebc09c36SJim Ingham     alias will be replaced with the second argument, and so on.  This also allows \n\
375ebc09c36SJim Ingham     actual arguments to be used multiple times within an alias (see 'process \n\
37681ded935SJim Ingham     launch' example below).  \n\
37781ded935SJim Ingham     Note: the positional arguments must substitute as whole words in the resultant\n\
37881ded935SJim Ingham     command, so you can't at present do something like:\n\
37981ded935SJim Ingham     \n\
38069c12ccbSJason Molenda     command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
38181ded935SJim Ingham     \n\
38281ded935SJim Ingham     to get the file extension \".cpp\" automatically appended.  For more complex\n\
38381ded935SJim Ingham     aliasing, use the \"command regex\" command instead.\n\
38481ded935SJim Ingham     \nSo in the 'bfl' case, the actual file value will be \n\
385ebc09c36SJim Ingham     filled in with the first argument following 'bfl' and the actual line number \n\
386ebc09c36SJim Ingham     value will be filled in with the second argument.  The user would use this \n\
387ebc09c36SJim Ingham     alias as follows: \n\
38869c12ccbSJason Molenda     \n    (lldb)  command alias bfl breakpoint set -f %1 -l %2 \n\
389ebc09c36SJim Ingham     <... some time later ...> \n\
39009799af6SCaroline Tice     (lldb)  bfl my-file.c 137 \n\
391ebc09c36SJim Ingham     \nThis would be the same as if the user had entered \n\
392ebc09c36SJim Ingham     'breakpoint set -f my-file.c -l 137'. \n\
393ebc09c36SJim Ingham     \nAnother example: \n\
39469c12ccbSJason Molenda     \n    (lldb)  command alias pltty  process launch -s -o %1 -e %1 \n\
39509799af6SCaroline Tice     (lldb)  pltty /dev/tty0 \n\
396ebc09c36SJim Ingham            // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
397ebc09c36SJim Ingham     \nIf the user always wanted to pass the same value to a particular option, the \n\
398ebc09c36SJim Ingham     alias could be defined with that value directly in the alias as a constant, \n\
399ebc09c36SJim Ingham     rather than using a positional placeholder: \n\
40069c12ccbSJason Molenda     \n    command alias bl3  breakpoint set -f %1 -l 3  // Always sets a breakpoint on line \n\
401ebc09c36SJim Ingham                                                    // 3 of whatever file is indicated. \n");
402ebc09c36SJim Ingham 
403405fe67fSCaroline Tice         CommandArgumentEntry arg1;
404405fe67fSCaroline Tice         CommandArgumentEntry arg2;
405405fe67fSCaroline Tice         CommandArgumentEntry arg3;
406405fe67fSCaroline Tice         CommandArgumentData alias_arg;
407405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
408405fe67fSCaroline Tice         CommandArgumentData options_arg;
409405fe67fSCaroline Tice 
410405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
411405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
412405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
413405fe67fSCaroline Tice 
414405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
415405fe67fSCaroline Tice         arg1.push_back (alias_arg);
416405fe67fSCaroline Tice 
417405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
418405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
419405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
420405fe67fSCaroline Tice 
421405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
422405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
423405fe67fSCaroline Tice 
424405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
425405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
426405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
427405fe67fSCaroline Tice 
428405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
429405fe67fSCaroline Tice         arg3.push_back (options_arg);
430405fe67fSCaroline Tice 
431405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
432405fe67fSCaroline Tice         m_arguments.push_back (arg1);
433405fe67fSCaroline Tice         m_arguments.push_back (arg2);
434405fe67fSCaroline Tice         m_arguments.push_back (arg3);
435ebc09c36SJim Ingham     }
436ebc09c36SJim Ingham 
437ebc09c36SJim Ingham     ~CommandObjectCommandsAlias ()
438ebc09c36SJim Ingham     {
439ebc09c36SJim Ingham     }
440ebc09c36SJim Ingham 
4415a988416SJim Ingham protected:
4425a988416SJim Ingham     virtual bool
4435a988416SJim Ingham     DoExecute (const char *raw_command_line, CommandReturnObject &result)
444844d2303SCaroline Tice     {
445844d2303SCaroline Tice         Args args (raw_command_line);
446844d2303SCaroline Tice         std::string raw_command_string (raw_command_line);
447844d2303SCaroline Tice 
448844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
449844d2303SCaroline Tice 
450844d2303SCaroline Tice         if (argc < 2)
451844d2303SCaroline Tice         {
452844d2303SCaroline Tice             result.AppendError ("'alias' requires at least two arguments");
453844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
454844d2303SCaroline Tice             return false;
455844d2303SCaroline Tice         }
456844d2303SCaroline Tice 
457844d2303SCaroline Tice         // Get the alias command.
458844d2303SCaroline Tice 
459844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
460844d2303SCaroline Tice 
461844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
462844d2303SCaroline Tice         // does the stripping itself.
463844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
464844d2303SCaroline Tice         if (pos == 0)
465844d2303SCaroline Tice         {
466844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
467844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
468844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
469844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
470844d2303SCaroline Tice         }
471844d2303SCaroline Tice         else
472844d2303SCaroline Tice         {
473844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
474844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
475844d2303SCaroline Tice             return false;
476844d2303SCaroline Tice         }
477844d2303SCaroline Tice 
478844d2303SCaroline Tice 
479844d2303SCaroline Tice         // Verify that the command is alias-able.
480844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
481844d2303SCaroline Tice         {
482844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
483844d2303SCaroline Tice                                           alias_command.c_str());
484844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
485844d2303SCaroline Tice             return false;
486844d2303SCaroline Tice         }
487844d2303SCaroline Tice 
488844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
489844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
490844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
491844d2303SCaroline Tice 
492844d2303SCaroline Tice         if (!cmd_obj)
493844d2303SCaroline Tice         {
49486edbf41SGreg Clayton             result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
495844d2303SCaroline Tice                                           "  No alias created.", raw_command_string.c_str());
496844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
497844d2303SCaroline Tice             return false;
498844d2303SCaroline Tice         }
499844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
500844d2303SCaroline Tice         {
501844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
502844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
5035a988416SJim Ingham             return HandleAliasingNormalCommand (args, result);
504844d2303SCaroline Tice         }
505844d2303SCaroline Tice         else
506844d2303SCaroline Tice         {
5075a988416SJim Ingham             return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
5085a988416SJim Ingham         }
5095a988416SJim Ingham         return result.Succeeded();
5105a988416SJim Ingham     }
5115a988416SJim Ingham 
5125a988416SJim Ingham     bool
5135a988416SJim Ingham     HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
5145a988416SJim Ingham     {
515844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
516844d2303SCaroline Tice 
517844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
518844d2303SCaroline Tice             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
519844d2303SCaroline Tice 
5205a988416SJim Ingham             CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
521844d2303SCaroline Tice 
522ca90c47eSCaroline Tice             if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
523844d2303SCaroline Tice             {
524844d2303SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
525ca90c47eSCaroline Tice                 result.SetStatus (eReturnStatusFailed);
526844d2303SCaroline Tice                 return false;
527844d2303SCaroline Tice             }
528844d2303SCaroline Tice 
529844d2303SCaroline Tice             // Create the alias
530844d2303SCaroline Tice             if (m_interpreter.AliasExists (alias_command.c_str())
531844d2303SCaroline Tice                 || m_interpreter.UserCommandExists (alias_command.c_str()))
532844d2303SCaroline Tice             {
533844d2303SCaroline Tice                 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
534844d2303SCaroline Tice                 if (temp_option_arg_sp.get())
535844d2303SCaroline Tice                 {
536844d2303SCaroline Tice                     if (option_arg_vector->size() == 0)
537844d2303SCaroline Tice                         m_interpreter.RemoveAliasOptions (alias_command.c_str());
538844d2303SCaroline Tice                 }
539844d2303SCaroline Tice                 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
540844d2303SCaroline Tice                                                 alias_command.c_str());
541844d2303SCaroline Tice             }
542844d2303SCaroline Tice 
543472362e6SCaroline Tice             if (cmd_obj_sp)
544472362e6SCaroline Tice             {
545844d2303SCaroline Tice                 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
546844d2303SCaroline Tice                 if (option_arg_vector->size() > 0)
547844d2303SCaroline Tice                     m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
548844d2303SCaroline Tice                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
549844d2303SCaroline Tice             }
550472362e6SCaroline Tice             else
551472362e6SCaroline Tice             {
552472362e6SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
553472362e6SCaroline Tice                 result.SetStatus (eReturnStatusFailed);
554472362e6SCaroline Tice             }
555844d2303SCaroline Tice             return result.Succeeded ();
556844d2303SCaroline Tice     }
557ebc09c36SJim Ingham 
558ebc09c36SJim Ingham     bool
5595a988416SJim Ingham     HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
560ebc09c36SJim Ingham     {
561867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
562ebc09c36SJim Ingham 
563ebc09c36SJim Ingham         if (argc < 2)
564ebc09c36SJim Ingham         {
565ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
566ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
567ebc09c36SJim Ingham             return false;
568ebc09c36SJim Ingham         }
569ebc09c36SJim Ingham 
570ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
571ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
572ebc09c36SJim Ingham 
573ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
574ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
575ebc09c36SJim Ingham 
576ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
577ebc09c36SJim Ingham 
578a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
579ebc09c36SJim Ingham         {
580ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
581ebc09c36SJim Ingham                                          alias_command.c_str());
582ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
583ebc09c36SJim Ingham         }
584ebc09c36SJim Ingham         else
585ebc09c36SJim Ingham         {
586a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
587ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
588ebc09c36SJim Ingham              bool use_subcommand = false;
589ebc09c36SJim Ingham              if (command_obj_sp.get())
590ebc09c36SJim Ingham              {
591ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
592c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
593ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
594ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
595ebc09c36SJim Ingham 
596844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
597ebc09c36SJim Ingham                  {
598ebc09c36SJim Ingham                      if (argc >= 3)
599ebc09c36SJim Ingham                      {
600ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
601ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
602998255bfSGreg Clayton                          subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
603ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
604ebc09c36SJim Ingham                          {
605ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
606ebc09c36SJim Ingham                              use_subcommand = true;
607ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
608844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
609ebc09c36SJim Ingham                          }
610ebc09c36SJim Ingham                          else
611ebc09c36SJim Ingham                          {
612f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
613f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
614f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
615ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
616ebc09c36SJim Ingham                              return false;
617ebc09c36SJim Ingham                          }
618ebc09c36SJim Ingham                      }
619ebc09c36SJim Ingham                  }
620ebc09c36SJim Ingham 
621ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
622ebc09c36SJim Ingham 
623ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
624ebc09c36SJim Ingham                  {
625ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
626ebc09c36SJim Ingham                     if (use_subcommand)
627ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
628ca90c47eSCaroline Tice 
629ca90c47eSCaroline Tice                     std::string args_string;
630ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
631ca90c47eSCaroline Tice 
632ca90c47eSCaroline Tice                     if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
633ebc09c36SJim Ingham                     {
634ca90c47eSCaroline Tice                         result.AppendError ("Unable to create requested alias.\n");
635ca90c47eSCaroline Tice                         result.SetStatus (eReturnStatusFailed);
636e7941795SCaroline Tice                         return false;
637867b185dSCaroline Tice                     }
638867b185dSCaroline Tice                  }
639867b185dSCaroline Tice 
640ebc09c36SJim Ingham                  // Create the alias.
641ebc09c36SJim Ingham 
642a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
643a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
644ebc09c36SJim Ingham                  {
645a7015092SGreg Clayton                      OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
646ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
647ebc09c36SJim Ingham                      {
648ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
649a7015092SGreg Clayton                              m_interpreter.RemoveAliasOptions (alias_command.c_str());
650ebc09c36SJim Ingham                      }
651ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
652ebc09c36SJim Ingham                                                      alias_command.c_str());
653ebc09c36SJim Ingham                  }
654ebc09c36SJim Ingham 
655ebc09c36SJim Ingham                  if (use_subcommand)
656a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
657ebc09c36SJim Ingham                  else
658a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
659ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
660a7015092SGreg Clayton                      m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
661ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
662ebc09c36SJim Ingham              }
663ebc09c36SJim Ingham              else
664ebc09c36SJim Ingham              {
665ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
666ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
667e7941795SCaroline Tice                  return false;
668ebc09c36SJim Ingham              }
669ebc09c36SJim Ingham         }
670ebc09c36SJim Ingham 
671ebc09c36SJim Ingham         return result.Succeeded();
672ebc09c36SJim Ingham     }
6735a988416SJim Ingham 
674ebc09c36SJim Ingham };
675ebc09c36SJim Ingham 
676ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
677ebc09c36SJim Ingham //-------------------------------------------------------------------------
678ebc09c36SJim Ingham // CommandObjectCommandsUnalias
679ebc09c36SJim Ingham //-------------------------------------------------------------------------
680ebc09c36SJim Ingham 
6815a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed
682ebc09c36SJim Ingham {
683ebc09c36SJim Ingham public:
684a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
6855a988416SJim Ingham         CommandObjectParsed (interpreter,
6860e5e5a79SGreg Clayton                        "command unalias",
68786ddae50SCaroline Tice                        "Allow the user to remove/delete a user-defined command abbreviation.",
688405fe67fSCaroline Tice                        NULL)
689ebc09c36SJim Ingham     {
690405fe67fSCaroline Tice         CommandArgumentEntry arg;
691405fe67fSCaroline Tice         CommandArgumentData alias_arg;
692405fe67fSCaroline Tice 
693405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
694405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
695405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
696405fe67fSCaroline Tice 
697405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
698405fe67fSCaroline Tice         arg.push_back (alias_arg);
699405fe67fSCaroline Tice 
700405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
701405fe67fSCaroline Tice         m_arguments.push_back (arg);
702ebc09c36SJim Ingham     }
703ebc09c36SJim Ingham 
704ebc09c36SJim Ingham     ~CommandObjectCommandsUnalias()
705ebc09c36SJim Ingham     {
706ebc09c36SJim Ingham     }
707ebc09c36SJim Ingham 
7085a988416SJim Ingham protected:
709ebc09c36SJim Ingham     bool
7105a988416SJim Ingham     DoExecute (Args& args, CommandReturnObject &result)
711ebc09c36SJim Ingham     {
712ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
713ebc09c36SJim Ingham         CommandObject *cmd_obj;
714ebc09c36SJim Ingham 
715ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
716ebc09c36SJim Ingham         {
717ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
718a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
719ebc09c36SJim Ingham             if (cmd_obj)
720ebc09c36SJim Ingham             {
721a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
722ebc09c36SJim Ingham                 {
723ebc09c36SJim Ingham                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
724ebc09c36SJim Ingham                                                   command_name);
725ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
726ebc09c36SJim Ingham                 }
727ebc09c36SJim Ingham                 else
728ebc09c36SJim Ingham                 {
729ebc09c36SJim Ingham 
730a7015092SGreg Clayton                     if (m_interpreter.RemoveAlias (command_name) == false)
731ebc09c36SJim Ingham                     {
732a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
733ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
734ebc09c36SJim Ingham                                                           command_name);
735ebc09c36SJim Ingham                         else
736ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
737ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
738ebc09c36SJim Ingham                     }
739ebc09c36SJim Ingham                     else
740ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
741ebc09c36SJim Ingham                 }
742ebc09c36SJim Ingham             }
743ebc09c36SJim Ingham             else
744ebc09c36SJim Ingham             {
745ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
746ebc09c36SJim Ingham                                               "current list of commands.\n",
747ebc09c36SJim Ingham                                              command_name);
748ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
749ebc09c36SJim Ingham             }
750ebc09c36SJim Ingham         }
751ebc09c36SJim Ingham         else
752ebc09c36SJim Ingham         {
753ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
754ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
755ebc09c36SJim Ingham         }
756ebc09c36SJim Ingham 
757ebc09c36SJim Ingham         return result.Succeeded();
758ebc09c36SJim Ingham     }
759ebc09c36SJim Ingham };
760ebc09c36SJim Ingham 
761de164aaaSGreg Clayton //-------------------------------------------------------------------------
762de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
763de164aaaSGreg Clayton //-------------------------------------------------------------------------
7645a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex
765de164aaaSGreg Clayton 
7665a988416SJim Ingham class CommandObjectCommandsAddRegex : public CommandObjectParsed
767de164aaaSGreg Clayton {
768de164aaaSGreg Clayton public:
769de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
7705a988416SJim Ingham         CommandObjectParsed (interpreter,
7710e5e5a79SGreg Clayton                        "command regex",
772de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
7730e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
774de164aaaSGreg Clayton         m_options (interpreter)
775de164aaaSGreg Clayton     {
7760e5e5a79SGreg Clayton         SetHelpLong(
7770e5e5a79SGreg Clayton "This command allows the user to create powerful regular expression commands\n"
7780e5e5a79SGreg Clayton "with substitutions. The regular expressions and substitutions are specified\n"
7790e5e5a79SGreg Clayton "using the regular exression substitution format of:\n"
7800e5e5a79SGreg Clayton "\n"
7810e5e5a79SGreg Clayton "    s/<regex>/<subst>/\n"
7820e5e5a79SGreg Clayton "\n"
7830e5e5a79SGreg Clayton "<regex> is a regular expression that can use parenthesis to capture regular\n"
7840e5e5a79SGreg Clayton "expression input and substitute the captured matches in the output using %1\n"
7850e5e5a79SGreg Clayton "for the first match, %2 for the second, and so on.\n"
7860e5e5a79SGreg Clayton "\n"
7870e5e5a79SGreg Clayton "The regular expressions can all be specified on the command line if more than\n"
7880e5e5a79SGreg Clayton "one argument is provided. If just the command name is provided on the command\n"
7890e5e5a79SGreg Clayton "line, then the regular expressions and substitutions can be entered on separate\n"
7900e5e5a79SGreg Clayton " lines, followed by an empty line to terminate the command definition.\n"
7910e5e5a79SGreg Clayton "\n"
7920e5e5a79SGreg Clayton "EXAMPLES\n"
7930e5e5a79SGreg Clayton "\n"
794adc43c99SSean Callanan "The following example will define a regular expression command named 'f' that\n"
7950e5e5a79SGreg Clayton "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
7960e5e5a79SGreg Clayton "a number follows 'f':\n"
797adc43c99SSean Callanan "\n"
7980e5e5a79SGreg Clayton "    (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
799adc43c99SSean Callanan "\n"
8000e5e5a79SGreg Clayton                     );
801de164aaaSGreg Clayton     }
802de164aaaSGreg Clayton 
803de164aaaSGreg Clayton     ~CommandObjectCommandsAddRegex()
804de164aaaSGreg Clayton     {
805de164aaaSGreg Clayton     }
806de164aaaSGreg Clayton 
807de164aaaSGreg Clayton 
8085a988416SJim Ingham protected:
809de164aaaSGreg Clayton     bool
8105a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
811de164aaaSGreg Clayton     {
8125a988416SJim Ingham         const size_t argc = command.GetArgumentCount();
8130e5e5a79SGreg Clayton         if (argc == 0)
814de164aaaSGreg Clayton         {
81569c12ccbSJason Molenda             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
8160e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
8170e5e5a79SGreg Clayton         }
8180e5e5a79SGreg Clayton         else
8190e5e5a79SGreg Clayton         {
8200e5e5a79SGreg Clayton             Error error;
8215a988416SJim Ingham             const char *name = command.GetArgumentAtIndex(0);
822de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
823de164aaaSGreg Clayton                                                                  name,
824de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
825de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
826de164aaaSGreg Clayton                                                                  10));
8270e5e5a79SGreg Clayton 
8280e5e5a79SGreg Clayton             if (argc == 1)
8290e5e5a79SGreg Clayton             {
8300e5e5a79SGreg Clayton                 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
831de164aaaSGreg Clayton                 if (reader_sp)
832de164aaaSGreg Clayton                 {
8330e5e5a79SGreg Clayton                     error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
834de164aaaSGreg Clayton                                                   this,                         // baton
835de164aaaSGreg Clayton                                                   eInputReaderGranularityLine,  // token size, to pass to callback function
8360e5e5a79SGreg Clayton                                                   NULL,                         // end token
837de164aaaSGreg Clayton                                                   "> ",                         // prompt
8380e5e5a79SGreg Clayton                                                   true);                        // echo input
8390e5e5a79SGreg Clayton                     if (error.Success())
840de164aaaSGreg Clayton                     {
841de164aaaSGreg Clayton                         m_interpreter.GetDebugger().PushInputReader (reader_sp);
842de164aaaSGreg Clayton                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
8430e5e5a79SGreg Clayton                         return true;
844de164aaaSGreg Clayton                     }
845de164aaaSGreg Clayton                 }
846de164aaaSGreg Clayton             }
847de164aaaSGreg Clayton             else
848de164aaaSGreg Clayton             {
8490e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
8500e5e5a79SGreg Clayton                 {
8515a988416SJim Ingham                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
8520e5e5a79SGreg Clayton                     error = AppendRegexSubstitution (arg_strref);
8530e5e5a79SGreg Clayton                     if (error.Fail())
8540e5e5a79SGreg Clayton                         break;
8550e5e5a79SGreg Clayton                 }
8560e5e5a79SGreg Clayton 
8570e5e5a79SGreg Clayton                 if (error.Success())
8580e5e5a79SGreg Clayton                 {
8590e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
8600e5e5a79SGreg Clayton                 }
8610e5e5a79SGreg Clayton             }
8620e5e5a79SGreg Clayton             if (error.Fail())
8630e5e5a79SGreg Clayton             {
8640e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
865de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
866de164aaaSGreg Clayton             }
8670e5e5a79SGreg Clayton         }
8680e5e5a79SGreg Clayton 
869de164aaaSGreg Clayton         return result.Succeeded();
870de164aaaSGreg Clayton     }
871de164aaaSGreg Clayton 
8720e5e5a79SGreg Clayton     Error
8730e5e5a79SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed)
874de164aaaSGreg Clayton     {
8750e5e5a79SGreg Clayton         Error error;
8760e5e5a79SGreg Clayton 
8770e5e5a79SGreg Clayton         if (m_regex_cmd_ap.get() == NULL)
878de164aaaSGreg Clayton         {
8790e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
8800e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8810e5e5a79SGreg Clayton                                            regex_sed.data());
8820e5e5a79SGreg Clayton             return error;
883de164aaaSGreg Clayton         }
8840e5e5a79SGreg Clayton 
8850e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
8860e5e5a79SGreg Clayton 
8870e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
8880e5e5a79SGreg Clayton         {
8890e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
8900e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8910e5e5a79SGreg Clayton                                            regex_sed.data());
8920e5e5a79SGreg Clayton             return error;
8930e5e5a79SGreg Clayton         }
8940e5e5a79SGreg Clayton 
8950e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
8960e5e5a79SGreg Clayton         {
8970e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
8980e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8990e5e5a79SGreg Clayton                                            regex_sed.data());
9000e5e5a79SGreg Clayton             return error;
9010e5e5a79SGreg Clayton         }
9020e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
9030e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
9040e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
9050e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
9060e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
9070e5e5a79SGreg Clayton 
9080e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
9090e5e5a79SGreg Clayton         {
9100e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
9110e5e5a79SGreg Clayton                                            separator_char,
9120e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
9130e5e5a79SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1));
9140e5e5a79SGreg Clayton             return error;
9150e5e5a79SGreg Clayton         }
9160e5e5a79SGreg Clayton 
9170e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
9180e5e5a79SGreg Clayton 
9190e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
9200e5e5a79SGreg Clayton         {
9210e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
9220e5e5a79SGreg Clayton                                            separator_char,
9230e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
9240e5e5a79SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1));
9250e5e5a79SGreg Clayton             return error;
9260e5e5a79SGreg Clayton         }
9270e5e5a79SGreg Clayton 
9280e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
9290e5e5a79SGreg Clayton         {
9300e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
9310e5e5a79SGreg Clayton             // separator char
9320e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
9330e5e5a79SGreg Clayton             {
9340e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
9350e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
9360e5e5a79SGreg Clayton                                                regex_sed.data(),
9370e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
9380e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
9390e5e5a79SGreg Clayton                 return error;
9400e5e5a79SGreg Clayton             }
9410e5e5a79SGreg Clayton 
9420e5e5a79SGreg Clayton         }
9430e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
9440e5e5a79SGreg Clayton         {
9450e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9460e5e5a79SGreg Clayton                                            separator_char,
9470e5e5a79SGreg Clayton                                            separator_char,
9480e5e5a79SGreg Clayton                                            separator_char,
9490e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9500e5e5a79SGreg Clayton                                            regex_sed.data());
9510e5e5a79SGreg Clayton             return error;
9520e5e5a79SGreg Clayton         }
9530e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
9540e5e5a79SGreg Clayton         {
9550e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9560e5e5a79SGreg Clayton                                            separator_char,
9570e5e5a79SGreg Clayton                                            separator_char,
9580e5e5a79SGreg Clayton                                            separator_char,
9590e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9600e5e5a79SGreg Clayton                                            regex_sed.data());
9610e5e5a79SGreg Clayton             return error;
9620e5e5a79SGreg Clayton         }
9630e5e5a79SGreg Clayton         std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
9640e5e5a79SGreg Clayton         std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
9650e5e5a79SGreg Clayton         m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
9660e5e5a79SGreg Clayton                                          subst.c_str());
9670e5e5a79SGreg Clayton         return error;
968de164aaaSGreg Clayton     }
969de164aaaSGreg Clayton 
970de164aaaSGreg Clayton     void
9710e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
972de164aaaSGreg Clayton     {
973de164aaaSGreg Clayton         if (m_regex_cmd_ap.get())
974de164aaaSGreg Clayton         {
975de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
976de164aaaSGreg Clayton             {
977de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
978de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
979de164aaaSGreg Clayton             }
980de164aaaSGreg Clayton         }
981de164aaaSGreg Clayton     }
982de164aaaSGreg Clayton 
9830e5e5a79SGreg Clayton     void
9840e5e5a79SGreg Clayton     InputReaderDidCancel()
9850e5e5a79SGreg Clayton     {
9860e5e5a79SGreg Clayton         m_regex_cmd_ap.reset();
9870e5e5a79SGreg Clayton     }
9880e5e5a79SGreg Clayton 
989de164aaaSGreg Clayton     static size_t
990de164aaaSGreg Clayton     InputReaderCallback (void *baton,
991de164aaaSGreg Clayton                          InputReader &reader,
992de164aaaSGreg Clayton                          lldb::InputReaderAction notification,
993de164aaaSGreg Clayton                          const char *bytes,
9945a988416SJim Ingham                          size_t bytes_len)
9955a988416SJim Ingham     {
9965a988416SJim Ingham         CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
9975a988416SJim Ingham         bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
9985a988416SJim Ingham 
9995a988416SJim Ingham         switch (notification)
10005a988416SJim Ingham         {
10015a988416SJim Ingham             case eInputReaderActivate:
10025a988416SJim Ingham                 if (!batch_mode)
10035a988416SJim Ingham                 {
10045a988416SJim Ingham                     StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
10055a988416SJim Ingham                     out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
10065a988416SJim Ingham                     out_stream->Flush();
10075a988416SJim Ingham                 }
10085a988416SJim Ingham                 break;
10095a988416SJim Ingham             case eInputReaderReactivate:
10105a988416SJim Ingham                 break;
10115a988416SJim Ingham 
10125a988416SJim Ingham             case eInputReaderDeactivate:
10135a988416SJim Ingham                 break;
10145a988416SJim Ingham 
10155a988416SJim Ingham             case eInputReaderAsynchronousOutputWritten:
10165a988416SJim Ingham                 break;
10175a988416SJim Ingham 
10185a988416SJim Ingham             case eInputReaderGotToken:
10195a988416SJim Ingham                 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
10205a988416SJim Ingham                     --bytes_len;
10215a988416SJim Ingham                 if (bytes_len == 0)
10225a988416SJim Ingham                     reader.SetIsDone(true);
10235a988416SJim Ingham                 else if (bytes)
10245a988416SJim Ingham                 {
10255a988416SJim Ingham                     llvm::StringRef bytes_strref (bytes, bytes_len);
10265a988416SJim Ingham                     Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
10275a988416SJim Ingham                     if (error.Fail())
10285a988416SJim Ingham                     {
10295a988416SJim Ingham                         if (!batch_mode)
10305a988416SJim Ingham                         {
10315a988416SJim Ingham                             StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
10325a988416SJim Ingham                             out_stream->Printf("error: %s\n", error.AsCString());
10335a988416SJim Ingham                             out_stream->Flush();
10345a988416SJim Ingham                         }
10355a988416SJim Ingham                         add_regex_cmd->InputReaderDidCancel ();
10365a988416SJim Ingham                         reader.SetIsDone (true);
10375a988416SJim Ingham                     }
10385a988416SJim Ingham                 }
10395a988416SJim Ingham                 break;
10405a988416SJim Ingham 
10415a988416SJim Ingham             case eInputReaderInterrupt:
10425a988416SJim Ingham                 {
10435a988416SJim Ingham                     reader.SetIsDone (true);
10445a988416SJim Ingham                     if (!batch_mode)
10455a988416SJim Ingham                     {
10465a988416SJim Ingham                         StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
10475a988416SJim Ingham                         out_stream->PutCString("Regular expression command creations was cancelled.\n");
10485a988416SJim Ingham                         out_stream->Flush();
10495a988416SJim Ingham                     }
10505a988416SJim Ingham                     add_regex_cmd->InputReaderDidCancel ();
10515a988416SJim Ingham                 }
10525a988416SJim Ingham                 break;
10535a988416SJim Ingham 
10545a988416SJim Ingham             case eInputReaderEndOfFile:
10555a988416SJim Ingham                 reader.SetIsDone (true);
10565a988416SJim Ingham                 break;
10575a988416SJim Ingham 
10585a988416SJim Ingham             case eInputReaderDone:
10595a988416SJim Ingham                 add_regex_cmd->AddRegexCommandToInterpreter();
10605a988416SJim Ingham                 break;
10615a988416SJim Ingham         }
10625a988416SJim Ingham 
10635a988416SJim Ingham         return bytes_len;
10645a988416SJim Ingham     }
10655a988416SJim Ingham 
1066de164aaaSGreg Clayton private:
1067de164aaaSGreg Clayton     std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1068de164aaaSGreg Clayton 
1069de164aaaSGreg Clayton      class CommandOptions : public Options
1070de164aaaSGreg Clayton      {
1071de164aaaSGreg Clayton      public:
1072de164aaaSGreg Clayton 
1073de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
1074de164aaaSGreg Clayton             Options (interpreter)
1075de164aaaSGreg Clayton          {
1076de164aaaSGreg Clayton          }
1077de164aaaSGreg Clayton 
1078de164aaaSGreg Clayton          virtual
1079de164aaaSGreg Clayton          ~CommandOptions (){}
1080de164aaaSGreg Clayton 
1081de164aaaSGreg Clayton          virtual Error
1082de164aaaSGreg Clayton          SetOptionValue (uint32_t option_idx, const char *option_arg)
1083de164aaaSGreg Clayton          {
1084de164aaaSGreg Clayton              Error error;
1085*3bcdfc0eSGreg Clayton              const int short_option = m_getopt_table[option_idx].val;
1086de164aaaSGreg Clayton 
1087de164aaaSGreg Clayton              switch (short_option)
1088de164aaaSGreg Clayton              {
1089de164aaaSGreg Clayton                  case 'h':
1090de164aaaSGreg Clayton                      m_help.assign (option_arg);
1091de164aaaSGreg Clayton                      break;
1092de164aaaSGreg Clayton                  case 's':
1093de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1094de164aaaSGreg Clayton                      break;
1095de164aaaSGreg Clayton 
1096de164aaaSGreg Clayton                  default:
109786edbf41SGreg Clayton                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1098de164aaaSGreg Clayton                      break;
1099de164aaaSGreg Clayton              }
1100de164aaaSGreg Clayton 
1101de164aaaSGreg Clayton              return error;
1102de164aaaSGreg Clayton          }
1103de164aaaSGreg Clayton 
1104de164aaaSGreg Clayton          void
1105de164aaaSGreg Clayton          OptionParsingStarting ()
1106de164aaaSGreg Clayton          {
1107de164aaaSGreg Clayton              m_help.clear();
1108de164aaaSGreg Clayton              m_syntax.clear();
1109de164aaaSGreg Clayton          }
1110de164aaaSGreg Clayton 
1111de164aaaSGreg Clayton          const OptionDefinition*
1112de164aaaSGreg Clayton          GetDefinitions ()
1113de164aaaSGreg Clayton          {
1114de164aaaSGreg Clayton              return g_option_table;
1115de164aaaSGreg Clayton          }
1116de164aaaSGreg Clayton 
1117de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1118de164aaaSGreg Clayton 
1119de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1120de164aaaSGreg Clayton 
1121de164aaaSGreg Clayton          const char *
1122de164aaaSGreg Clayton          GetHelp ()
1123de164aaaSGreg Clayton          {
1124de164aaaSGreg Clayton              if (m_help.empty())
1125de164aaaSGreg Clayton                  return NULL;
1126de164aaaSGreg Clayton              return m_help.c_str();
1127de164aaaSGreg Clayton          }
1128de164aaaSGreg Clayton          const char *
1129de164aaaSGreg Clayton          GetSyntax ()
1130de164aaaSGreg Clayton          {
1131de164aaaSGreg Clayton              if (m_syntax.empty())
1132de164aaaSGreg Clayton                  return NULL;
1133de164aaaSGreg Clayton              return m_syntax.c_str();
1134de164aaaSGreg Clayton          }
1135de164aaaSGreg Clayton          // Instance variables to hold the values for command options.
1136de164aaaSGreg Clayton      protected:
1137de164aaaSGreg Clayton          std::string m_help;
1138de164aaaSGreg Clayton          std::string m_syntax;
1139de164aaaSGreg Clayton      };
1140de164aaaSGreg Clayton 
1141de164aaaSGreg Clayton      virtual Options *
1142de164aaaSGreg Clayton      GetOptions ()
1143de164aaaSGreg Clayton      {
1144de164aaaSGreg Clayton          return &m_options;
1145de164aaaSGreg Clayton      }
1146de164aaaSGreg Clayton 
11475a988416SJim Ingham      CommandOptions m_options;
1148de164aaaSGreg Clayton };
1149de164aaaSGreg Clayton 
1150de164aaaSGreg Clayton OptionDefinition
1151de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1152de164aaaSGreg Clayton {
1153de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "help"  , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1154de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1155de164aaaSGreg Clayton { 0             , false,  NULL   , 0  , 0                , NULL, 0, eArgTypeNone, NULL }
1156de164aaaSGreg Clayton };
1157de164aaaSGreg Clayton 
1158de164aaaSGreg Clayton 
11595a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw
1160223383edSEnrico Granata {
1161223383edSEnrico Granata private:
1162223383edSEnrico Granata     std::string m_function_name;
11630a305db7SEnrico Granata     ScriptedCommandSynchronicity m_synchro;
1164fac939e9SEnrico Granata     bool m_fetched_help_long;
1165223383edSEnrico Granata 
1166223383edSEnrico Granata public:
1167223383edSEnrico Granata 
1168223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1169223383edSEnrico Granata                                  std::string name,
11700a305db7SEnrico Granata                                  std::string funct,
11710a305db7SEnrico Granata                                  ScriptedCommandSynchronicity synch) :
11725a988416SJim Ingham         CommandObjectRaw (interpreter,
1173223383edSEnrico Granata                           name.c_str(),
1174223383edSEnrico Granata                           (std::string("Run Python function ") + funct).c_str(),
1175223383edSEnrico Granata                           NULL),
11760a305db7SEnrico Granata         m_function_name(funct),
1177fac939e9SEnrico Granata         m_synchro(synch),
1178fac939e9SEnrico Granata         m_fetched_help_long(false)
1179223383edSEnrico Granata     {
1180223383edSEnrico Granata     }
1181223383edSEnrico Granata 
1182223383edSEnrico Granata     virtual
1183223383edSEnrico Granata     ~CommandObjectPythonFunction ()
1184223383edSEnrico Granata     {
1185223383edSEnrico Granata     }
1186223383edSEnrico Granata 
1187223383edSEnrico Granata     virtual bool
11883a18e319SGreg Clayton     IsRemovable () const
11895a988416SJim Ingham     {
11905a988416SJim Ingham         return true;
11915a988416SJim Ingham     }
11925a988416SJim Ingham 
11935a988416SJim Ingham     const std::string&
11945a988416SJim Ingham     GetFunctionName ()
11955a988416SJim Ingham     {
11965a988416SJim Ingham         return m_function_name;
11975a988416SJim Ingham     }
11985a988416SJim Ingham 
11995a988416SJim Ingham     ScriptedCommandSynchronicity
12005a988416SJim Ingham     GetSynchronicity ()
12015a988416SJim Ingham     {
12025a988416SJim Ingham         return m_synchro;
12035a988416SJim Ingham     }
12045a988416SJim Ingham 
1205fac939e9SEnrico Granata     virtual const char *
1206fac939e9SEnrico Granata     GetHelpLong ()
1207fac939e9SEnrico Granata     {
1208fac939e9SEnrico Granata         if (!m_fetched_help_long)
1209fac939e9SEnrico Granata         {
1210fac939e9SEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1211fac939e9SEnrico Granata             if (scripter)
1212fac939e9SEnrico Granata             {
1213fac939e9SEnrico Granata                 std::string docstring;
1214fac939e9SEnrico Granata                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1215fac939e9SEnrico Granata                 if (!docstring.empty())
1216fac939e9SEnrico Granata                     SetHelpLong(docstring);
1217fac939e9SEnrico Granata             }
1218fac939e9SEnrico Granata         }
1219fac939e9SEnrico Granata         return CommandObjectRaw::GetHelpLong();
1220fac939e9SEnrico Granata     }
1221fac939e9SEnrico Granata 
12225a988416SJim Ingham protected:
12235a988416SJim Ingham     virtual bool
12245a988416SJim Ingham     DoExecute (const char *raw_command_line, CommandReturnObject &result)
1225223383edSEnrico Granata     {
1226223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1227223383edSEnrico Granata 
1228223383edSEnrico Granata         Error error;
1229223383edSEnrico Granata 
123070f11f88SJim Ingham         result.SetStatus(eReturnStatusInvalid);
123170f11f88SJim Ingham 
1232223383edSEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1233223383edSEnrico Granata                                                          raw_command_line,
12340a305db7SEnrico Granata                                                          m_synchro,
1235223383edSEnrico Granata                                                          result,
1236223383edSEnrico Granata                                                          error) == false)
1237223383edSEnrico Granata         {
1238223383edSEnrico Granata             result.AppendError(error.AsCString());
1239223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1240223383edSEnrico Granata         }
1241223383edSEnrico Granata         else
124270f11f88SJim Ingham         {
124370f11f88SJim Ingham             // Don't change the status if the command already set it...
124470f11f88SJim Ingham             if (result.GetStatus() == eReturnStatusInvalid)
124570f11f88SJim Ingham             {
124670f11f88SJim Ingham                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1247223383edSEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
124870f11f88SJim Ingham                 else
124970f11f88SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishResult);
125070f11f88SJim Ingham             }
125170f11f88SJim Ingham         }
1252223383edSEnrico Granata 
1253223383edSEnrico Granata         return result.Succeeded();
1254223383edSEnrico Granata     }
1255223383edSEnrico Granata 
1256223383edSEnrico Granata };
1257223383edSEnrico Granata 
1258a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1259a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport
1260a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1261a9dbf432SEnrico Granata 
12625a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed
1263a9dbf432SEnrico Granata {
12645a988416SJim Ingham public:
12655a988416SJim Ingham     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
12665a988416SJim Ingham         CommandObjectParsed (interpreter,
12675a988416SJim Ingham                              "command script import",
12685a988416SJim Ingham                              "Import a scripting module in LLDB.",
12695a988416SJim Ingham                              NULL),
12705a988416SJim Ingham         m_options(interpreter)
12715a988416SJim Ingham     {
12725a988416SJim Ingham         CommandArgumentEntry arg1;
12735a988416SJim Ingham         CommandArgumentData cmd_arg;
12745a988416SJim Ingham 
12755a988416SJim Ingham         // Define the first (and only) variant of this arg.
12765a988416SJim Ingham         cmd_arg.arg_type = eArgTypeFilename;
12775a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
12785a988416SJim Ingham 
12795a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
12805a988416SJim Ingham         arg1.push_back (cmd_arg);
12815a988416SJim Ingham 
12825a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
12835a988416SJim Ingham         m_arguments.push_back (arg1);
12845a988416SJim Ingham     }
12855a988416SJim Ingham 
12865a988416SJim Ingham     ~CommandObjectCommandsScriptImport ()
12875a988416SJim Ingham     {
12885a988416SJim Ingham     }
12895a988416SJim Ingham 
12905a988416SJim Ingham     int
12915a988416SJim Ingham     HandleArgumentCompletion (Args &input,
12925a988416SJim Ingham                               int &cursor_index,
12935a988416SJim Ingham                               int &cursor_char_position,
12945a988416SJim Ingham                               OptionElementVector &opt_element_vector,
12955a988416SJim Ingham                               int match_start_point,
12965a988416SJim Ingham                               int max_return_elements,
12975a988416SJim Ingham                               bool &word_complete,
12985a988416SJim Ingham                               StringList &matches)
12995a988416SJim Ingham     {
13005a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
13015a988416SJim Ingham         completion_str.erase (cursor_char_position);
13025a988416SJim Ingham 
13035a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
13045a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
13055a988416SJim Ingham                                                              completion_str.c_str(),
13065a988416SJim Ingham                                                              match_start_point,
13075a988416SJim Ingham                                                              max_return_elements,
13085a988416SJim Ingham                                                              NULL,
13095a988416SJim Ingham                                                              word_complete,
13105a988416SJim Ingham                                                              matches);
13115a988416SJim Ingham         return matches.GetSize();
13125a988416SJim Ingham     }
13135a988416SJim Ingham 
13145a988416SJim Ingham     virtual Options *
13155a988416SJim Ingham     GetOptions ()
13165a988416SJim Ingham     {
13175a988416SJim Ingham         return &m_options;
13185a988416SJim Ingham     }
13195a988416SJim Ingham 
13205a988416SJim Ingham protected:
13210a305db7SEnrico Granata 
13220a305db7SEnrico Granata     class CommandOptions : public Options
13230a305db7SEnrico Granata     {
13240a305db7SEnrico Granata     public:
13250a305db7SEnrico Granata 
13260a305db7SEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
13270a305db7SEnrico Granata             Options (interpreter)
13280a305db7SEnrico Granata         {
13290a305db7SEnrico Granata         }
13300a305db7SEnrico Granata 
13310a305db7SEnrico Granata         virtual
13320a305db7SEnrico Granata         ~CommandOptions (){}
13330a305db7SEnrico Granata 
13340a305db7SEnrico Granata         virtual Error
13350a305db7SEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
13360a305db7SEnrico Granata         {
13370a305db7SEnrico Granata             Error error;
1338*3bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13390a305db7SEnrico Granata 
13400a305db7SEnrico Granata             switch (short_option)
13410a305db7SEnrico Granata             {
13420a305db7SEnrico Granata                 case 'r':
13430a305db7SEnrico Granata                     m_allow_reload = true;
13440a305db7SEnrico Granata                     break;
13450a305db7SEnrico Granata                 default:
13460a305db7SEnrico Granata                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
13470a305db7SEnrico Granata                     break;
13480a305db7SEnrico Granata             }
13490a305db7SEnrico Granata 
13500a305db7SEnrico Granata             return error;
13510a305db7SEnrico Granata         }
13520a305db7SEnrico Granata 
13530a305db7SEnrico Granata         void
13540a305db7SEnrico Granata         OptionParsingStarting ()
13550a305db7SEnrico Granata         {
13560a305db7SEnrico Granata             m_allow_reload = false;
13570a305db7SEnrico Granata         }
13580a305db7SEnrico Granata 
13590a305db7SEnrico Granata         const OptionDefinition*
13600a305db7SEnrico Granata         GetDefinitions ()
13610a305db7SEnrico Granata         {
13620a305db7SEnrico Granata             return g_option_table;
13630a305db7SEnrico Granata         }
13640a305db7SEnrico Granata 
13650a305db7SEnrico Granata         // Options table: Required for subclasses of Options.
13660a305db7SEnrico Granata 
13670a305db7SEnrico Granata         static OptionDefinition g_option_table[];
13680a305db7SEnrico Granata 
13690a305db7SEnrico Granata         // Instance variables to hold the values for command options.
13700a305db7SEnrico Granata 
13710a305db7SEnrico Granata         bool m_allow_reload;
13720a305db7SEnrico Granata     };
13730a305db7SEnrico Granata 
1374a9dbf432SEnrico Granata     bool
13755a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1376a9dbf432SEnrico Granata     {
1377a9dbf432SEnrico Granata 
1378a9dbf432SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1379a9dbf432SEnrico Granata         {
1380a9dbf432SEnrico Granata             result.AppendError ("only scripting language supported for module importing is currently Python");
1381a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1382a9dbf432SEnrico Granata             return false;
1383a9dbf432SEnrico Granata         }
1384a9dbf432SEnrico Granata 
13855a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1386a9dbf432SEnrico Granata 
1387a9dbf432SEnrico Granata         if (argc != 1)
1388a9dbf432SEnrico Granata         {
1389a9dbf432SEnrico Granata             result.AppendError ("'command script import' requires one argument");
1390a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1391a9dbf432SEnrico Granata             return false;
1392a9dbf432SEnrico Granata         }
1393a9dbf432SEnrico Granata 
13945a988416SJim Ingham         std::string path = command.GetArgumentAtIndex(0);
1395a9dbf432SEnrico Granata         Error error;
1396a9dbf432SEnrico Granata 
1397c9d645d3SGreg Clayton         const bool init_session = true;
1398a9dbf432SEnrico Granata         if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
13990a305db7SEnrico Granata                                                                       m_options.m_allow_reload,
1400c9d645d3SGreg Clayton                                                                       init_session,
1401a9dbf432SEnrico Granata                                                                       error))
1402a9dbf432SEnrico Granata         {
1403a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1404a9dbf432SEnrico Granata         }
1405a9dbf432SEnrico Granata         else
1406a9dbf432SEnrico Granata         {
1407a9dbf432SEnrico Granata             result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1408a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1409a9dbf432SEnrico Granata         }
1410a9dbf432SEnrico Granata 
1411a9dbf432SEnrico Granata         return result.Succeeded();
1412a9dbf432SEnrico Granata     }
14130a305db7SEnrico Granata 
14145a988416SJim Ingham     CommandOptions m_options;
1415a9dbf432SEnrico Granata };
1416223383edSEnrico Granata 
14170a305db7SEnrico Granata OptionDefinition
14180a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
14190a305db7SEnrico Granata {
14200a305db7SEnrico 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 (for Python, the __lldb_init_module function will be called again, but the module will not be reloaded from disk)."},
14210a305db7SEnrico Granata     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
14220a305db7SEnrico Granata };
14230a305db7SEnrico Granata 
14240a305db7SEnrico Granata 
1425223383edSEnrico Granata //-------------------------------------------------------------------------
1426223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1427223383edSEnrico Granata //-------------------------------------------------------------------------
1428223383edSEnrico Granata 
14295a988416SJim Ingham class CommandObjectCommandsScriptAdd : public CommandObjectParsed
1430223383edSEnrico Granata {
14315a988416SJim Ingham public:
14325a988416SJim Ingham     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
14335a988416SJim Ingham         CommandObjectParsed (interpreter,
14345a988416SJim Ingham                              "command script add",
14355a988416SJim Ingham                              "Add a scripted function as an LLDB command.",
14365a988416SJim Ingham                              NULL),
14375a988416SJim Ingham         m_options (interpreter)
14385a988416SJim Ingham     {
14395a988416SJim Ingham         CommandArgumentEntry arg1;
14405a988416SJim Ingham         CommandArgumentData cmd_arg;
14415a988416SJim Ingham 
14425a988416SJim Ingham         // Define the first (and only) variant of this arg.
14435a988416SJim Ingham         cmd_arg.arg_type = eArgTypeCommandName;
14445a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
14455a988416SJim Ingham 
14465a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
14475a988416SJim Ingham         arg1.push_back (cmd_arg);
14485a988416SJim Ingham 
14495a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
14505a988416SJim Ingham         m_arguments.push_back (arg1);
14515a988416SJim Ingham     }
14525a988416SJim Ingham 
14535a988416SJim Ingham     ~CommandObjectCommandsScriptAdd ()
14545a988416SJim Ingham     {
14555a988416SJim Ingham     }
14565a988416SJim Ingham 
14575a988416SJim Ingham     virtual Options *
14585a988416SJim Ingham     GetOptions ()
14595a988416SJim Ingham     {
14605a988416SJim Ingham         return &m_options;
14615a988416SJim Ingham     }
14625a988416SJim Ingham 
14635a988416SJim Ingham protected:
1464223383edSEnrico Granata 
1465223383edSEnrico Granata     class CommandOptions : public Options
1466223383edSEnrico Granata     {
1467223383edSEnrico Granata     public:
1468223383edSEnrico Granata 
1469223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
1470223383edSEnrico Granata         Options (interpreter)
1471223383edSEnrico Granata         {
1472223383edSEnrico Granata         }
1473223383edSEnrico Granata 
1474223383edSEnrico Granata         virtual
1475223383edSEnrico Granata         ~CommandOptions (){}
1476223383edSEnrico Granata 
1477223383edSEnrico Granata         virtual Error
1478223383edSEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
1479223383edSEnrico Granata         {
1480223383edSEnrico Granata             Error error;
1481*3bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
1482223383edSEnrico Granata 
1483223383edSEnrico Granata             switch (short_option)
1484223383edSEnrico Granata             {
1485223383edSEnrico Granata                 case 'f':
1486223383edSEnrico Granata                     m_funct_name = std::string(option_arg);
1487223383edSEnrico Granata                     break;
14880a305db7SEnrico Granata                 case 's':
14890a305db7SEnrico Granata                     m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
14900a305db7SEnrico Granata                     if (!error.Success())
14910a305db7SEnrico Granata                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
14920a305db7SEnrico Granata                     break;
1493223383edSEnrico Granata                 default:
149486edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1495223383edSEnrico Granata                     break;
1496223383edSEnrico Granata             }
1497223383edSEnrico Granata 
1498223383edSEnrico Granata             return error;
1499223383edSEnrico Granata         }
1500223383edSEnrico Granata 
1501223383edSEnrico Granata         void
1502223383edSEnrico Granata         OptionParsingStarting ()
1503223383edSEnrico Granata         {
1504223383edSEnrico Granata             m_funct_name = "";
15050a305db7SEnrico Granata             m_synchronous = eScriptedCommandSynchronicitySynchronous;
1506223383edSEnrico Granata         }
1507223383edSEnrico Granata 
1508223383edSEnrico Granata         const OptionDefinition*
1509223383edSEnrico Granata         GetDefinitions ()
1510223383edSEnrico Granata         {
1511223383edSEnrico Granata             return g_option_table;
1512223383edSEnrico Granata         }
1513223383edSEnrico Granata 
1514223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1515223383edSEnrico Granata 
1516223383edSEnrico Granata         static OptionDefinition g_option_table[];
1517223383edSEnrico Granata 
1518223383edSEnrico Granata         // Instance variables to hold the values for command options.
1519223383edSEnrico Granata 
1520223383edSEnrico Granata         std::string m_funct_name;
15210a305db7SEnrico Granata         ScriptedCommandSynchronicity m_synchronous;
1522223383edSEnrico Granata     };
1523223383edSEnrico Granata 
15245a988416SJim Ingham private:
1525223383edSEnrico Granata     class PythonAliasReader : public InputReaderEZ
1526223383edSEnrico Granata     {
1527223383edSEnrico Granata     private:
1528223383edSEnrico Granata         CommandInterpreter& m_interpreter;
1529223383edSEnrico Granata         std::string m_cmd_name;
15300a305db7SEnrico Granata         ScriptedCommandSynchronicity m_synchronous;
1531223383edSEnrico Granata         StringList m_user_input;
1532223383edSEnrico Granata         DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1533223383edSEnrico Granata     public:
1534223383edSEnrico Granata         PythonAliasReader(Debugger& debugger,
1535223383edSEnrico Granata                           CommandInterpreter& interpreter,
15360a305db7SEnrico Granata                           std::string cmd_name,
15370a305db7SEnrico Granata                           ScriptedCommandSynchronicity synch) :
1538223383edSEnrico Granata         InputReaderEZ(debugger),
1539223383edSEnrico Granata         m_interpreter(interpreter),
1540223383edSEnrico Granata         m_cmd_name(cmd_name),
15410a305db7SEnrico Granata         m_synchronous(synch),
1542223383edSEnrico Granata         m_user_input()
1543223383edSEnrico Granata         {}
1544223383edSEnrico Granata 
1545223383edSEnrico Granata         virtual
1546223383edSEnrico Granata         ~PythonAliasReader()
1547223383edSEnrico Granata         {
1548223383edSEnrico Granata         }
1549223383edSEnrico Granata 
1550223383edSEnrico Granata         virtual void ActivateHandler(HandlerData& data)
1551223383edSEnrico Granata         {
1552223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1553223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1554223383edSEnrico Granata             if (!batch_mode)
1555223383edSEnrico Granata             {
1556223383edSEnrico Granata                 out_stream->Printf ("%s\n", g_python_command_instructions);
1557223383edSEnrico Granata                 if (data.reader.GetPrompt())
1558223383edSEnrico Granata                     out_stream->Printf ("%s", data.reader.GetPrompt());
1559223383edSEnrico Granata                 out_stream->Flush();
1560223383edSEnrico Granata             }
1561223383edSEnrico Granata         }
1562223383edSEnrico Granata 
1563223383edSEnrico Granata         virtual void ReactivateHandler(HandlerData& data)
1564223383edSEnrico Granata         {
1565223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1566223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1567223383edSEnrico Granata             if (data.reader.GetPrompt() && !batch_mode)
1568223383edSEnrico Granata             {
1569223383edSEnrico Granata                 out_stream->Printf ("%s", data.reader.GetPrompt());
1570223383edSEnrico Granata                 out_stream->Flush();
1571223383edSEnrico Granata             }
1572223383edSEnrico Granata         }
1573223383edSEnrico Granata         virtual void GotTokenHandler(HandlerData& data)
1574223383edSEnrico Granata         {
1575223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1576223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1577223383edSEnrico Granata             if (data.bytes && data.bytes_len)
1578223383edSEnrico Granata             {
1579223383edSEnrico Granata                 m_user_input.AppendString(data.bytes, data.bytes_len);
1580223383edSEnrico Granata             }
1581223383edSEnrico Granata             if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1582223383edSEnrico Granata             {
1583223383edSEnrico Granata                 out_stream->Printf ("%s", data.reader.GetPrompt());
1584223383edSEnrico Granata                 out_stream->Flush();
1585223383edSEnrico Granata             }
1586223383edSEnrico Granata         }
1587223383edSEnrico Granata         virtual void InterruptHandler(HandlerData& data)
1588223383edSEnrico Granata         {
1589223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1590223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1591223383edSEnrico Granata             data.reader.SetIsDone (true);
1592223383edSEnrico Granata             if (!batch_mode)
1593223383edSEnrico Granata             {
15940a305db7SEnrico Granata                 out_stream->Printf ("Warning: No script attached.\n");
1595223383edSEnrico Granata                 out_stream->Flush();
1596223383edSEnrico Granata             }
1597223383edSEnrico Granata         }
1598223383edSEnrico Granata         virtual void EOFHandler(HandlerData& data)
1599223383edSEnrico Granata         {
1600223383edSEnrico Granata             data.reader.SetIsDone (true);
1601223383edSEnrico Granata         }
1602223383edSEnrico Granata         virtual void DoneHandler(HandlerData& data)
1603223383edSEnrico Granata         {
1604223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1605223383edSEnrico Granata 
1606223383edSEnrico Granata             ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1607223383edSEnrico Granata             if (!interpreter)
1608223383edSEnrico Granata             {
16090a305db7SEnrico Granata                 out_stream->Printf ("Script interpreter missing: no script attached.\n");
1610223383edSEnrico Granata                 out_stream->Flush();
1611223383edSEnrico Granata                 return;
1612223383edSEnrico Granata             }
1613a73b7df7SEnrico Granata             std::string funct_name_str;
1614223383edSEnrico Granata             if (!interpreter->GenerateScriptAliasFunction (m_user_input,
1615a73b7df7SEnrico Granata                                                            funct_name_str))
1616223383edSEnrico Granata             {
16170a305db7SEnrico Granata                 out_stream->Printf ("Unable to create function: no script attached.\n");
1618223383edSEnrico Granata                 out_stream->Flush();
1619223383edSEnrico Granata                 return;
1620223383edSEnrico Granata             }
1621a73b7df7SEnrico Granata             if (funct_name_str.empty())
1622223383edSEnrico Granata             {
16230a305db7SEnrico Granata                 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
1624223383edSEnrico Granata                 out_stream->Flush();
1625223383edSEnrico Granata                 return;
1626223383edSEnrico Granata             }
1627223383edSEnrico Granata             // everything should be fine now, let's add this alias
1628223383edSEnrico Granata 
1629223383edSEnrico Granata             CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1630223383edSEnrico Granata                                                                            m_cmd_name,
1631a73b7df7SEnrico Granata                                                                            funct_name_str.c_str(),
16320a305db7SEnrico Granata                                                                            m_synchronous));
1633223383edSEnrico Granata 
16340a305db7SEnrico Granata             if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1635223383edSEnrico Granata             {
16360a305db7SEnrico Granata                 out_stream->Printf ("Unable to add selected command: no script attached.\n");
1637223383edSEnrico Granata                 out_stream->Flush();
1638223383edSEnrico Granata                 return;
1639223383edSEnrico Granata             }
1640223383edSEnrico Granata         }
1641223383edSEnrico Granata     };
1642223383edSEnrico Granata 
16435a988416SJim Ingham protected:
1644223383edSEnrico Granata     bool
16455a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1646223383edSEnrico Granata     {
164799f0b8f9SEnrico Granata 
164899f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
164999f0b8f9SEnrico Granata         {
165099f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
165199f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
165299f0b8f9SEnrico Granata             return false;
165399f0b8f9SEnrico Granata         }
165499f0b8f9SEnrico Granata 
16555a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1656223383edSEnrico Granata 
1657223383edSEnrico Granata         if (argc != 1)
1658223383edSEnrico Granata         {
1659223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
1660223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1661223383edSEnrico Granata             return false;
1662223383edSEnrico Granata         }
1663223383edSEnrico Granata 
16645a988416SJim Ingham         std::string cmd_name = command.GetArgumentAtIndex(0);
1665223383edSEnrico Granata 
1666223383edSEnrico Granata         if (m_options.m_funct_name.empty())
1667223383edSEnrico Granata         {
1668223383edSEnrico Granata             InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1669223383edSEnrico Granata                                                             m_interpreter,
16700a305db7SEnrico Granata                                                             cmd_name,
16710a305db7SEnrico Granata                                                             m_options.m_synchronous));
1672223383edSEnrico Granata 
1673223383edSEnrico Granata             if (reader_sp)
1674223383edSEnrico Granata             {
1675223383edSEnrico Granata 
1676223383edSEnrico Granata                 InputReaderEZ::InitializationParameters ipr;
1677223383edSEnrico Granata 
1678223383edSEnrico Granata                 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt("     ")));
1679223383edSEnrico Granata                 if (err.Success())
1680223383edSEnrico Granata                 {
1681223383edSEnrico Granata                     m_interpreter.GetDebugger().PushInputReader (reader_sp);
1682223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1683223383edSEnrico Granata                 }
1684223383edSEnrico Granata                 else
1685223383edSEnrico Granata                 {
1686223383edSEnrico Granata                     result.AppendError (err.AsCString());
1687223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
1688223383edSEnrico Granata                 }
1689223383edSEnrico Granata             }
1690223383edSEnrico Granata             else
1691223383edSEnrico Granata             {
1692223383edSEnrico Granata                 result.AppendError("out of memory");
1693223383edSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1694223383edSEnrico Granata             }
1695223383edSEnrico Granata         }
1696223383edSEnrico Granata         else
1697223383edSEnrico Granata         {
16980a305db7SEnrico Granata             CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
16990a305db7SEnrico Granata                                                                     cmd_name,
17000a305db7SEnrico Granata                                                                     m_options.m_funct_name,
17010a305db7SEnrico Granata                                                                     m_options.m_synchronous));
17020a305db7SEnrico Granata             if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
1703223383edSEnrico Granata             {
1704223383edSEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1705223383edSEnrico Granata             }
1706223383edSEnrico Granata             else
1707223383edSEnrico Granata             {
1708223383edSEnrico Granata                 result.AppendError("cannot add command");
1709223383edSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1710223383edSEnrico Granata             }
1711223383edSEnrico Granata         }
1712223383edSEnrico Granata 
1713223383edSEnrico Granata         return result.Succeeded();
1714223383edSEnrico Granata 
1715223383edSEnrico Granata     }
17165a988416SJim Ingham 
17175a988416SJim Ingham     CommandOptions m_options;
1718223383edSEnrico Granata };
1719223383edSEnrico Granata 
17200a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] =
17210a305db7SEnrico Granata {
17220a305db7SEnrico Granata     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
17230a305db7SEnrico Granata     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
17240a305db7SEnrico Granata     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
17250a305db7SEnrico Granata     { 0, NULL, NULL }
17260a305db7SEnrico Granata };
17270a305db7SEnrico Granata 
1728223383edSEnrico Granata OptionDefinition
1729223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1730223383edSEnrico Granata {
17319128ee2fSEnrico Granata     { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."},
17320a305db7SEnrico 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."},
1733223383edSEnrico Granata     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1734223383edSEnrico Granata };
1735223383edSEnrico Granata 
1736223383edSEnrico Granata //-------------------------------------------------------------------------
1737223383edSEnrico Granata // CommandObjectCommandsScriptList
1738223383edSEnrico Granata //-------------------------------------------------------------------------
1739223383edSEnrico Granata 
17405a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed
1741223383edSEnrico Granata {
1742223383edSEnrico Granata private:
1743223383edSEnrico Granata 
1744223383edSEnrico Granata public:
1745223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
17465a988416SJim Ingham     CommandObjectParsed (interpreter,
1747223383edSEnrico Granata                    "command script list",
1748223383edSEnrico Granata                    "List defined scripted commands.",
1749223383edSEnrico Granata                    NULL)
1750223383edSEnrico Granata     {
1751223383edSEnrico Granata     }
1752223383edSEnrico Granata 
1753223383edSEnrico Granata     ~CommandObjectCommandsScriptList ()
1754223383edSEnrico Granata     {
1755223383edSEnrico Granata     }
1756223383edSEnrico Granata 
1757223383edSEnrico Granata     bool
17585a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1759223383edSEnrico Granata     {
1760223383edSEnrico Granata 
1761223383edSEnrico Granata         m_interpreter.GetHelp(result,
1762223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
1763223383edSEnrico Granata 
1764223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
1765223383edSEnrico Granata 
1766223383edSEnrico Granata         return true;
1767223383edSEnrico Granata 
1768223383edSEnrico Granata 
1769223383edSEnrico Granata     }
1770223383edSEnrico Granata };
1771223383edSEnrico Granata 
1772223383edSEnrico Granata //-------------------------------------------------------------------------
1773223383edSEnrico Granata // CommandObjectCommandsScriptClear
1774223383edSEnrico Granata //-------------------------------------------------------------------------
1775223383edSEnrico Granata 
17765a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed
1777223383edSEnrico Granata {
1778223383edSEnrico Granata private:
1779223383edSEnrico Granata 
1780223383edSEnrico Granata public:
1781223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
17825a988416SJim Ingham         CommandObjectParsed (interpreter,
1783223383edSEnrico Granata                              "command script clear",
1784223383edSEnrico Granata                              "Delete all scripted commands.",
1785223383edSEnrico Granata                              NULL)
1786223383edSEnrico Granata     {
1787223383edSEnrico Granata     }
1788223383edSEnrico Granata 
1789223383edSEnrico Granata     ~CommandObjectCommandsScriptClear ()
1790223383edSEnrico Granata     {
1791223383edSEnrico Granata     }
1792223383edSEnrico Granata 
17935a988416SJim Ingham protected:
1794223383edSEnrico Granata     bool
17955a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1796223383edSEnrico Granata     {
1797223383edSEnrico Granata 
1798223383edSEnrico Granata         m_interpreter.RemoveAllUser();
1799223383edSEnrico Granata 
1800223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
1801223383edSEnrico Granata 
1802223383edSEnrico Granata         return true;
1803223383edSEnrico Granata     }
1804223383edSEnrico Granata };
1805223383edSEnrico Granata 
1806223383edSEnrico Granata //-------------------------------------------------------------------------
1807223383edSEnrico Granata // CommandObjectCommandsScriptDelete
1808223383edSEnrico Granata //-------------------------------------------------------------------------
1809223383edSEnrico Granata 
18105a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed
1811223383edSEnrico Granata {
1812223383edSEnrico Granata public:
1813223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
18145a988416SJim Ingham         CommandObjectParsed (interpreter,
1815223383edSEnrico Granata                              "command script delete",
1816223383edSEnrico Granata                              "Delete a scripted command.",
1817223383edSEnrico Granata                              NULL)
1818223383edSEnrico Granata     {
1819223383edSEnrico Granata         CommandArgumentEntry arg1;
1820223383edSEnrico Granata         CommandArgumentData cmd_arg;
1821223383edSEnrico Granata 
1822223383edSEnrico Granata         // Define the first (and only) variant of this arg.
1823223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
1824223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
1825223383edSEnrico Granata 
1826223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
1827223383edSEnrico Granata         arg1.push_back (cmd_arg);
1828223383edSEnrico Granata 
1829223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
1830223383edSEnrico Granata         m_arguments.push_back (arg1);
1831223383edSEnrico Granata     }
1832223383edSEnrico Granata 
1833223383edSEnrico Granata     ~CommandObjectCommandsScriptDelete ()
1834223383edSEnrico Granata     {
1835223383edSEnrico Granata     }
1836223383edSEnrico Granata 
18375a988416SJim Ingham protected:
1838223383edSEnrico Granata     bool
18395a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1840223383edSEnrico Granata     {
1841223383edSEnrico Granata 
18425a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1843223383edSEnrico Granata 
1844223383edSEnrico Granata         if (argc != 1)
1845223383edSEnrico Granata         {
1846223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
1847223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1848223383edSEnrico Granata             return false;
1849223383edSEnrico Granata         }
1850223383edSEnrico Granata 
18515a988416SJim Ingham         const char* cmd_name = command.GetArgumentAtIndex(0);
1852223383edSEnrico Granata 
1853223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1854223383edSEnrico Granata         {
1855223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
1856223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
1857223383edSEnrico Granata         }
1858223383edSEnrico Granata         else
1859223383edSEnrico Granata         {
1860223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
1861223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1862223383edSEnrico Granata         }
1863223383edSEnrico Granata 
1864223383edSEnrico Granata         return result.Succeeded();
1865223383edSEnrico Granata 
1866223383edSEnrico Granata     }
1867223383edSEnrico Granata };
1868223383edSEnrico Granata 
1869223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
1870223383edSEnrico Granata 
1871223383edSEnrico Granata //-------------------------------------------------------------------------
1872223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
1873223383edSEnrico Granata //-------------------------------------------------------------------------
1874223383edSEnrico Granata 
1875223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1876223383edSEnrico Granata {
1877223383edSEnrico Granata public:
1878223383edSEnrico Granata     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1879223383edSEnrico Granata     CommandObjectMultiword (interpreter,
1880223383edSEnrico Granata                             "command script",
1881223383edSEnrico Granata                             "A set of commands for managing or customizing script commands.",
1882223383edSEnrico Granata                             "command script <subcommand> [<subcommand-options>]")
1883223383edSEnrico Granata     {
1884223383edSEnrico Granata         LoadSubCommand ("add",  CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1885223383edSEnrico Granata         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1886223383edSEnrico Granata         LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1887223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
1888a9dbf432SEnrico Granata         LoadSubCommand ("import",   CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
1889223383edSEnrico Granata     }
1890223383edSEnrico Granata 
1891223383edSEnrico Granata     ~CommandObjectMultiwordCommandsScript ()
1892223383edSEnrico Granata     {
1893223383edSEnrico Granata     }
1894223383edSEnrico Granata 
1895223383edSEnrico Granata };
1896223383edSEnrico Granata 
1897223383edSEnrico Granata 
1898ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
1899ebc09c36SJim Ingham 
1900ebc09c36SJim Ingham //-------------------------------------------------------------------------
1901ebc09c36SJim Ingham // CommandObjectMultiwordCommands
1902ebc09c36SJim Ingham //-------------------------------------------------------------------------
1903ebc09c36SJim Ingham 
1904ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
1905a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
19060e5e5a79SGreg Clayton                             "command",
19073f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
19080e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
1909ebc09c36SJim Ingham {
1910a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1911a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1912a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
1913de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
1914a5a97ebeSJim Ingham     LoadSubCommand ("history",   CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
1915223383edSEnrico Granata     LoadSubCommand ("script",   CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
1916ebc09c36SJim Ingham }
1917ebc09c36SJim Ingham 
1918ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1919ebc09c36SJim Ingham {
1920ebc09c36SJim Ingham }
1921ebc09c36SJim Ingham 
1922