1ebc09c36SJim Ingham //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
2ebc09c36SJim Ingham //
3ebc09c36SJim Ingham //                     The LLVM Compiler Infrastructure
4ebc09c36SJim Ingham //
5ebc09c36SJim Ingham // This file is distributed under the University of Illinois Open Source
6ebc09c36SJim Ingham // License. See LICENSE.TXT for details.
7ebc09c36SJim Ingham //
8ebc09c36SJim Ingham //===----------------------------------------------------------------------===//
9ebc09c36SJim Ingham 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
12ebc09c36SJim Ingham #include "CommandObjectCommands.h"
13ebc09c36SJim Ingham 
14ebc09c36SJim Ingham // C Includes
15ebc09c36SJim Ingham // C++ Includes
16ebc09c36SJim Ingham // Other libraries and framework includes
170e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h"
180e5e5a79SGreg Clayton 
19ebc09c36SJim Ingham // Project includes
20ebc09c36SJim Ingham #include "lldb/Core/Debugger.h"
21de164aaaSGreg Clayton #include "lldb/Core/InputReader.h"
22be93a35aSEnrico Granata #include "lldb/Core/InputReaderEZ.h"
23be93a35aSEnrico Granata #include "lldb/Core/StringList.h"
24de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h"
25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h"
26de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h"
27ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h"
28ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
2999f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h"
3099f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreterPython.h"
31ebc09c36SJim Ingham 
32ebc09c36SJim Ingham using namespace lldb;
33ebc09c36SJim Ingham using namespace lldb_private;
34ebc09c36SJim Ingham 
35ebc09c36SJim Ingham //-------------------------------------------------------------------------
36ebc09c36SJim Ingham // CommandObjectCommandsSource
37ebc09c36SJim Ingham //-------------------------------------------------------------------------
38ebc09c36SJim Ingham 
395a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed
40a5a97ebeSJim Ingham {
415a988416SJim Ingham public:
425a988416SJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
435a988416SJim Ingham         CommandObjectParsed (interpreter,
445a988416SJim Ingham                              "command history",
455a988416SJim Ingham                              "Dump the history of commands in this session.",
465a988416SJim Ingham                              NULL),
475a988416SJim Ingham         m_options (interpreter)
485a988416SJim Ingham     {
495a988416SJim Ingham     }
505a988416SJim Ingham 
515a988416SJim Ingham     ~CommandObjectCommandsHistory () {}
525a988416SJim Ingham 
535a988416SJim Ingham     virtual Options *
545a988416SJim Ingham     GetOptions ()
555a988416SJim Ingham     {
565a988416SJim Ingham         return &m_options;
575a988416SJim Ingham     }
585a988416SJim Ingham 
595a988416SJim Ingham protected:
60a5a97ebeSJim Ingham 
61a5a97ebeSJim Ingham     class CommandOptions : public Options
62a5a97ebeSJim Ingham     {
63a5a97ebeSJim Ingham     public:
64a5a97ebeSJim Ingham 
65a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
66a5a97ebeSJim Ingham             Options (interpreter)
67a5a97ebeSJim Ingham         {
68a5a97ebeSJim Ingham         }
69a5a97ebeSJim Ingham 
70a5a97ebeSJim Ingham         virtual
71a5a97ebeSJim Ingham         ~CommandOptions (){}
72a5a97ebeSJim Ingham 
73a5a97ebeSJim Ingham         virtual Error
74a5a97ebeSJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
75a5a97ebeSJim Ingham         {
76a5a97ebeSJim Ingham             Error error;
773bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
78a5a97ebeSJim Ingham             bool success;
79a5a97ebeSJim Ingham 
80a5a97ebeSJim Ingham             switch (short_option)
81a5a97ebeSJim Ingham             {
82a5a97ebeSJim Ingham                 case 'c':
83a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
84a5a97ebeSJim Ingham                     if (!success)
8586edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for count: %s", option_arg);
86a5a97ebeSJim Ingham                     if (m_end_idx != 0)
87a5a97ebeSJim Ingham                         m_end_idx--;
88a5a97ebeSJim Ingham                     m_start_idx = 0;
89a5a97ebeSJim Ingham                     break;
90a5a97ebeSJim Ingham                 case 'e':
91a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
92a5a97ebeSJim Ingham                     if (!success)
9386edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for end index: %s", option_arg);
94a5a97ebeSJim Ingham                     break;
95a5a97ebeSJim Ingham                 case 's':
96a5a97ebeSJim Ingham                     m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
97a5a97ebeSJim Ingham                     if (!success)
9886edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for start index: %s", option_arg);
99a5a97ebeSJim Ingham                     break;
100a5a97ebeSJim Ingham                 default:
10186edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
102a5a97ebeSJim Ingham                     break;
103a5a97ebeSJim Ingham             }
104a5a97ebeSJim Ingham 
105a5a97ebeSJim Ingham             return error;
106a5a97ebeSJim Ingham         }
107a5a97ebeSJim Ingham 
108a5a97ebeSJim Ingham         void
109a5a97ebeSJim Ingham         OptionParsingStarting ()
110a5a97ebeSJim Ingham         {
111a5a97ebeSJim Ingham             m_start_idx = 0;
112a5a97ebeSJim Ingham             m_end_idx = UINT_MAX;
113a5a97ebeSJim Ingham         }
114a5a97ebeSJim Ingham 
115a5a97ebeSJim Ingham         const OptionDefinition*
116a5a97ebeSJim Ingham         GetDefinitions ()
117a5a97ebeSJim Ingham         {
118a5a97ebeSJim Ingham             return g_option_table;
119a5a97ebeSJim Ingham         }
120a5a97ebeSJim Ingham 
121a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
122a5a97ebeSJim Ingham 
123a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
124a5a97ebeSJim Ingham 
125a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
126a5a97ebeSJim Ingham 
127a5a97ebeSJim Ingham         uint32_t m_start_idx;
128a5a97ebeSJim Ingham         uint32_t m_end_idx;
129a5a97ebeSJim Ingham     };
130a5a97ebeSJim Ingham 
131a5a97ebeSJim Ingham     bool
1325a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
133a5a97ebeSJim Ingham     {
134a5a97ebeSJim Ingham 
135a5a97ebeSJim Ingham         m_interpreter.DumpHistory (result.GetOutputStream(),
136a5a97ebeSJim Ingham                                    m_options.m_start_idx,
137a5a97ebeSJim Ingham                                    m_options.m_end_idx);
138a5a97ebeSJim Ingham         return result.Succeeded();
139a5a97ebeSJim Ingham 
140a5a97ebeSJim Ingham     }
1415a988416SJim Ingham 
1425a988416SJim Ingham     CommandOptions m_options;
143a5a97ebeSJim Ingham };
144a5a97ebeSJim Ingham 
145a5a97ebeSJim Ingham OptionDefinition
146a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
147a5a97ebeSJim Ingham {
148a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
149a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger,  "Index at which to start printing history commands."},
150a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
151a5a97ebeSJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
152a5a97ebeSJim Ingham };
153a5a97ebeSJim Ingham 
154a5a97ebeSJim Ingham 
155a5a97ebeSJim Ingham //-------------------------------------------------------------------------
156a5a97ebeSJim Ingham // CommandObjectCommandsSource
157a5a97ebeSJim Ingham //-------------------------------------------------------------------------
158a5a97ebeSJim Ingham 
1595a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed
160ebc09c36SJim Ingham {
1615a988416SJim Ingham public:
1625a988416SJim Ingham     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
1635a988416SJim Ingham         CommandObjectParsed (interpreter,
1645a988416SJim Ingham                              "command source",
1655a988416SJim Ingham                              "Read in debugger commands from the file <filename> and execute them.",
1665a988416SJim Ingham                              NULL),
1675a988416SJim Ingham         m_options (interpreter)
1685a988416SJim Ingham     {
1695a988416SJim Ingham         CommandArgumentEntry arg;
1705a988416SJim Ingham         CommandArgumentData file_arg;
1715a988416SJim Ingham 
1725a988416SJim Ingham         // Define the first (and only) variant of this arg.
1735a988416SJim Ingham         file_arg.arg_type = eArgTypeFilename;
1745a988416SJim Ingham         file_arg.arg_repetition = eArgRepeatPlain;
1755a988416SJim Ingham 
1765a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
1775a988416SJim Ingham         arg.push_back (file_arg);
1785a988416SJim Ingham 
1795a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
1805a988416SJim Ingham         m_arguments.push_back (arg);
1815a988416SJim Ingham     }
1825a988416SJim Ingham 
1835a988416SJim Ingham     ~CommandObjectCommandsSource () {}
1845a988416SJim Ingham 
1855a988416SJim Ingham     virtual const char*
1865a988416SJim Ingham     GetRepeatCommand (Args &current_command_args, uint32_t index)
1875a988416SJim Ingham     {
1885a988416SJim Ingham         return "";
1895a988416SJim Ingham     }
1905a988416SJim Ingham 
191*c7bece56SGreg Clayton     virtual int
1925a988416SJim Ingham     HandleArgumentCompletion (Args &input,
1935a988416SJim Ingham                               int &cursor_index,
1945a988416SJim Ingham                               int &cursor_char_position,
1955a988416SJim Ingham                               OptionElementVector &opt_element_vector,
1965a988416SJim Ingham                               int match_start_point,
1975a988416SJim Ingham                               int max_return_elements,
1985a988416SJim Ingham                               bool &word_complete,
1995a988416SJim Ingham                               StringList &matches)
2005a988416SJim Ingham     {
2015a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2025a988416SJim Ingham         completion_str.erase (cursor_char_position);
2035a988416SJim Ingham 
2045a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2055a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
2065a988416SJim Ingham                                                              completion_str.c_str(),
2075a988416SJim Ingham                                                              match_start_point,
2085a988416SJim Ingham                                                              max_return_elements,
2095a988416SJim Ingham                                                              NULL,
2105a988416SJim Ingham                                                              word_complete,
2115a988416SJim Ingham                                                              matches);
2125a988416SJim Ingham         return matches.GetSize();
2135a988416SJim Ingham     }
2145a988416SJim Ingham 
2155a988416SJim Ingham     virtual Options *
2165a988416SJim Ingham     GetOptions ()
2175a988416SJim Ingham     {
2185a988416SJim Ingham         return &m_options;
2195a988416SJim Ingham     }
2205a988416SJim Ingham 
2215a988416SJim Ingham protected:
222e16c50a1SJim Ingham 
223e16c50a1SJim Ingham     class CommandOptions : public Options
224e16c50a1SJim Ingham     {
225e16c50a1SJim Ingham     public:
226e16c50a1SJim Ingham 
227eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
228eb0103f2SGreg Clayton             Options (interpreter)
229eb0103f2SGreg Clayton         {
230eb0103f2SGreg Clayton         }
231e16c50a1SJim Ingham 
232e16c50a1SJim Ingham         virtual
233e16c50a1SJim Ingham         ~CommandOptions (){}
234e16c50a1SJim Ingham 
235e16c50a1SJim Ingham         virtual Error
236f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
237e16c50a1SJim Ingham         {
238e16c50a1SJim Ingham             Error error;
2393bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
240e16c50a1SJim Ingham             bool success;
241e16c50a1SJim Ingham 
242e16c50a1SJim Ingham             switch (short_option)
243e16c50a1SJim Ingham             {
244e16c50a1SJim Ingham                 case 'e':
245e16c50a1SJim Ingham                     m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
246e16c50a1SJim Ingham                     if (!success)
24786edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for stop-on-error: %s", option_arg);
248e16c50a1SJim Ingham                     break;
249e16c50a1SJim Ingham                 case 'c':
250e16c50a1SJim Ingham                     m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
251e16c50a1SJim Ingham                     if (!success)
25286edbf41SGreg Clayton                         error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg);
253e16c50a1SJim Ingham                     break;
254e16c50a1SJim Ingham                 default:
25586edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
256e16c50a1SJim Ingham                     break;
257e16c50a1SJim Ingham             }
258e16c50a1SJim Ingham 
259e16c50a1SJim Ingham             return error;
260e16c50a1SJim Ingham         }
261e16c50a1SJim Ingham 
262e16c50a1SJim Ingham         void
263f6b8b581SGreg Clayton         OptionParsingStarting ()
264e16c50a1SJim Ingham         {
265e16c50a1SJim Ingham             m_stop_on_error = true;
266e16c50a1SJim Ingham             m_stop_on_continue = true;
267e16c50a1SJim Ingham         }
268e16c50a1SJim Ingham 
269e0d378b3SGreg Clayton         const OptionDefinition*
270e16c50a1SJim Ingham         GetDefinitions ()
271e16c50a1SJim Ingham         {
272e16c50a1SJim Ingham             return g_option_table;
273e16c50a1SJim Ingham         }
274e16c50a1SJim Ingham 
275e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
276e16c50a1SJim Ingham 
277e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
278e16c50a1SJim Ingham 
279e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
280e16c50a1SJim Ingham 
281e16c50a1SJim Ingham         bool m_stop_on_error;
282e16c50a1SJim Ingham         bool m_stop_on_continue;
283e16c50a1SJim Ingham     };
284e16c50a1SJim Ingham 
285ebc09c36SJim Ingham     bool
2865a988416SJim Ingham     DoExecute(Args& command, CommandReturnObject &result)
287ebc09c36SJim Ingham     {
288*c7bece56SGreg Clayton         const size_t argc = command.GetArgumentCount();
289ebc09c36SJim Ingham         if (argc == 1)
290ebc09c36SJim Ingham         {
2915a988416SJim Ingham             const char *filename = command.GetArgumentAtIndex(0);
292ebc09c36SJim Ingham 
293ebc09c36SJim Ingham             result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
294ebc09c36SJim Ingham 
2951ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
296e16c50a1SJim Ingham             ExecutionContext *exe_ctx = NULL;  // Just use the default context.
297e16c50a1SJim Ingham             bool echo_commands    = true;
298e16c50a1SJim Ingham             bool print_results    = true;
299ebc09c36SJim Ingham 
300e16c50a1SJim Ingham             m_interpreter.HandleCommandsFromFile (cmd_file,
301e16c50a1SJim Ingham                                                   exe_ctx,
302e16c50a1SJim Ingham                                                   m_options.m_stop_on_continue,
303e16c50a1SJim Ingham                                                   m_options.m_stop_on_error,
304e16c50a1SJim Ingham                                                   echo_commands,
305e16c50a1SJim Ingham                                                   print_results,
3065f5ab602SEnrico Granata                                                   eLazyBoolCalculate,
307e16c50a1SJim Ingham                                                   result);
308ebc09c36SJim Ingham         }
309ebc09c36SJim Ingham         else
310ebc09c36SJim Ingham         {
311ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
312ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
313ebc09c36SJim Ingham         }
314ebc09c36SJim Ingham         return result.Succeeded();
315ebc09c36SJim Ingham 
316ebc09c36SJim Ingham     }
3175a988416SJim Ingham     CommandOptions m_options;
318ebc09c36SJim Ingham };
319ebc09c36SJim Ingham 
320e0d378b3SGreg Clayton OptionDefinition
321e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
322e16c50a1SJim Ingham {
323e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
324e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
325e16c50a1SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
326e16c50a1SJim Ingham };
327e16c50a1SJim Ingham 
328ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
329ebc09c36SJim Ingham //-------------------------------------------------------------------------
330ebc09c36SJim Ingham // CommandObjectCommandsAlias
331ebc09c36SJim Ingham //-------------------------------------------------------------------------
332ebc09c36SJim Ingham 
333be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
334be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
33540d55710SEnrico Granata                                                      "def my_command_impl(debugger, args, result, internal_dict):";
336be93a35aSEnrico Granata 
337be93a35aSEnrico Granata 
3385a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw
339ebc09c36SJim Ingham {
340be93a35aSEnrico Granata 
341be93a35aSEnrico Granata 
342ebc09c36SJim Ingham public:
343a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
3445a988416SJim Ingham         CommandObjectRaw (interpreter,
3450e5e5a79SGreg Clayton                        "command alias",
346e3d26315SCaroline Tice                        "Allow users to define their own debugger command abbreviations.",
347405fe67fSCaroline Tice                        NULL)
348ebc09c36SJim Ingham     {
349ebc09c36SJim Ingham         SetHelpLong(
350ebc09c36SJim Ingham     "'alias' allows the user to create a short-cut or abbreviation for long \n\
351ebc09c36SJim Ingham     commands, multi-word commands, and commands that take particular options. \n\
352ebc09c36SJim Ingham     Below are some simple examples of how one might use the 'alias' command: \n\
35369c12ccbSJason Molenda     \n    'command alias sc script'            // Creates the abbreviation 'sc' for the 'script' \n\
354ebc09c36SJim Ingham                                          // command. \n\
35569c12ccbSJason Molenda     'command alias bp breakpoint'        // Creates the abbreviation 'bp' for the 'breakpoint' \n\
356ebc09c36SJim Ingham                                          // command.  Since breakpoint commands are two-word \n\
357ebc09c36SJim Ingham                                          // commands, the user will still need to enter the \n\
358ebc09c36SJim Ingham                                          // second word after 'bp', e.g. 'bp enable' or \n\
359ebc09c36SJim Ingham                                          // 'bp delete'. \n\
36069c12ccbSJason Molenda     'command alias bpl breakpoint list'  // Creates the abbreviation 'bpl' for the \n\
361ebc09c36SJim Ingham                                          // two-word command 'breakpoint list'. \n\
362ebc09c36SJim Ingham     \nAn alias can include some options for the command, with the values either \n\
363ebc09c36SJim Ingham     filled in at the time the alias is created, or specified as positional \n\
364ebc09c36SJim Ingham     arguments, to be filled in when the alias is invoked.  The following example \n\
365ebc09c36SJim Ingham     shows how to create aliases with options: \n\
366ebc09c36SJim Ingham     \n\
36769c12ccbSJason Molenda     'command alias bfl breakpoint set -f %1 -l %2' \n\
368ebc09c36SJim Ingham     \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
369ebc09c36SJim Ingham     options already part of the alias.  So if the user wants to set a breakpoint \n\
370ebc09c36SJim Ingham     by file and line without explicitly having to use the -f and -l options, the \n\
371ebc09c36SJim Ingham     user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \n\
372ebc09c36SJim Ingham     for the actual arguments that will be passed when the alias command is used. \n\
373ebc09c36SJim Ingham     The number in the placeholder refers to the position/order the actual value \n\
37481ded935SJim Ingham     occupies when the alias is used.  All the occurrences of '%1' in the alias \n\
375ebc09c36SJim Ingham     will be replaced with the first argument, all the occurrences of '%2' in the \n\
376ebc09c36SJim Ingham     alias will be replaced with the second argument, and so on.  This also allows \n\
377ebc09c36SJim Ingham     actual arguments to be used multiple times within an alias (see 'process \n\
37881ded935SJim Ingham     launch' example below).  \n\
37981ded935SJim Ingham     Note: the positional arguments must substitute as whole words in the resultant\n\
38081ded935SJim Ingham     command, so you can't at present do something like:\n\
38181ded935SJim Ingham     \n\
38269c12ccbSJason Molenda     command alias bcppfl breakpoint set -f %1.cpp -l %2\n\
38381ded935SJim Ingham     \n\
38481ded935SJim Ingham     to get the file extension \".cpp\" automatically appended.  For more complex\n\
38581ded935SJim Ingham     aliasing, use the \"command regex\" command instead.\n\
38681ded935SJim Ingham     \nSo in the 'bfl' case, the actual file value will be \n\
387ebc09c36SJim Ingham     filled in with the first argument following 'bfl' and the actual line number \n\
388ebc09c36SJim Ingham     value will be filled in with the second argument.  The user would use this \n\
389ebc09c36SJim Ingham     alias as follows: \n\
39069c12ccbSJason Molenda     \n    (lldb)  command alias bfl breakpoint set -f %1 -l %2 \n\
391ebc09c36SJim Ingham     <... some time later ...> \n\
39209799af6SCaroline Tice     (lldb)  bfl my-file.c 137 \n\
393ebc09c36SJim Ingham     \nThis would be the same as if the user had entered \n\
394ebc09c36SJim Ingham     'breakpoint set -f my-file.c -l 137'. \n\
395ebc09c36SJim Ingham     \nAnother example: \n\
39669c12ccbSJason Molenda     \n    (lldb)  command alias pltty  process launch -s -o %1 -e %1 \n\
39709799af6SCaroline Tice     (lldb)  pltty /dev/tty0 \n\
398ebc09c36SJim Ingham            // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
399ebc09c36SJim Ingham     \nIf the user always wanted to pass the same value to a particular option, the \n\
400ebc09c36SJim Ingham     alias could be defined with that value directly in the alias as a constant, \n\
401ebc09c36SJim Ingham     rather than using a positional placeholder: \n\
40269c12ccbSJason Molenda     \n    command alias bl3  breakpoint set -f %1 -l 3  // Always sets a breakpoint on line \n\
403ebc09c36SJim Ingham                                                    // 3 of whatever file is indicated. \n");
404ebc09c36SJim Ingham 
405405fe67fSCaroline Tice         CommandArgumentEntry arg1;
406405fe67fSCaroline Tice         CommandArgumentEntry arg2;
407405fe67fSCaroline Tice         CommandArgumentEntry arg3;
408405fe67fSCaroline Tice         CommandArgumentData alias_arg;
409405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
410405fe67fSCaroline Tice         CommandArgumentData options_arg;
411405fe67fSCaroline Tice 
412405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
413405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
414405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
415405fe67fSCaroline Tice 
416405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
417405fe67fSCaroline Tice         arg1.push_back (alias_arg);
418405fe67fSCaroline Tice 
419405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
420405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
421405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
422405fe67fSCaroline Tice 
423405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
424405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
425405fe67fSCaroline Tice 
426405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
427405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
428405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
429405fe67fSCaroline Tice 
430405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
431405fe67fSCaroline Tice         arg3.push_back (options_arg);
432405fe67fSCaroline Tice 
433405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
434405fe67fSCaroline Tice         m_arguments.push_back (arg1);
435405fe67fSCaroline Tice         m_arguments.push_back (arg2);
436405fe67fSCaroline Tice         m_arguments.push_back (arg3);
437ebc09c36SJim Ingham     }
438ebc09c36SJim Ingham 
439ebc09c36SJim Ingham     ~CommandObjectCommandsAlias ()
440ebc09c36SJim Ingham     {
441ebc09c36SJim Ingham     }
442ebc09c36SJim Ingham 
4435a988416SJim Ingham protected:
4445a988416SJim Ingham     virtual bool
4455a988416SJim Ingham     DoExecute (const char *raw_command_line, CommandReturnObject &result)
446844d2303SCaroline Tice     {
447844d2303SCaroline Tice         Args args (raw_command_line);
448844d2303SCaroline Tice         std::string raw_command_string (raw_command_line);
449844d2303SCaroline Tice 
450844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
451844d2303SCaroline Tice 
452844d2303SCaroline Tice         if (argc < 2)
453844d2303SCaroline Tice         {
454844d2303SCaroline Tice             result.AppendError ("'alias' requires at least two arguments");
455844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
456844d2303SCaroline Tice             return false;
457844d2303SCaroline Tice         }
458844d2303SCaroline Tice 
459844d2303SCaroline Tice         // Get the alias command.
460844d2303SCaroline Tice 
461844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
462844d2303SCaroline Tice 
463844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
464844d2303SCaroline Tice         // does the stripping itself.
465844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
466844d2303SCaroline Tice         if (pos == 0)
467844d2303SCaroline Tice         {
468844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
469844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
470844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
471844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
472844d2303SCaroline Tice         }
473844d2303SCaroline Tice         else
474844d2303SCaroline Tice         {
475844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
476844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
477844d2303SCaroline Tice             return false;
478844d2303SCaroline Tice         }
479844d2303SCaroline Tice 
480844d2303SCaroline Tice 
481844d2303SCaroline Tice         // Verify that the command is alias-able.
482844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
483844d2303SCaroline Tice         {
484844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
485844d2303SCaroline Tice                                           alias_command.c_str());
486844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
487844d2303SCaroline Tice             return false;
488844d2303SCaroline Tice         }
489844d2303SCaroline Tice 
490844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
491844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
492844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
493844d2303SCaroline Tice 
494844d2303SCaroline Tice         if (!cmd_obj)
495844d2303SCaroline Tice         {
49686edbf41SGreg Clayton             result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command."
497844d2303SCaroline Tice                                           "  No alias created.", raw_command_string.c_str());
498844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
499844d2303SCaroline Tice             return false;
500844d2303SCaroline Tice         }
501844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
502844d2303SCaroline Tice         {
503844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
504844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
5055a988416SJim Ingham             return HandleAliasingNormalCommand (args, result);
506844d2303SCaroline Tice         }
507844d2303SCaroline Tice         else
508844d2303SCaroline Tice         {
5095a988416SJim Ingham             return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result);
5105a988416SJim Ingham         }
5115a988416SJim Ingham         return result.Succeeded();
5125a988416SJim Ingham     }
5135a988416SJim Ingham 
5145a988416SJim Ingham     bool
5155a988416SJim Ingham     HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result)
5165a988416SJim Ingham     {
517844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
518844d2303SCaroline Tice 
519844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
520844d2303SCaroline Tice             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
521844d2303SCaroline Tice 
5225a988416SJim Ingham             CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false);
523844d2303SCaroline Tice 
524ca90c47eSCaroline Tice             if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
525844d2303SCaroline Tice             {
526844d2303SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
527ca90c47eSCaroline Tice                 result.SetStatus (eReturnStatusFailed);
528844d2303SCaroline Tice                 return false;
529844d2303SCaroline Tice             }
530844d2303SCaroline Tice 
531844d2303SCaroline Tice             // Create the alias
532844d2303SCaroline Tice             if (m_interpreter.AliasExists (alias_command.c_str())
533844d2303SCaroline Tice                 || m_interpreter.UserCommandExists (alias_command.c_str()))
534844d2303SCaroline Tice             {
535844d2303SCaroline Tice                 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
536844d2303SCaroline Tice                 if (temp_option_arg_sp.get())
537844d2303SCaroline Tice                 {
538844d2303SCaroline Tice                     if (option_arg_vector->size() == 0)
539844d2303SCaroline Tice                         m_interpreter.RemoveAliasOptions (alias_command.c_str());
540844d2303SCaroline Tice                 }
541844d2303SCaroline Tice                 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
542844d2303SCaroline Tice                                                 alias_command.c_str());
543844d2303SCaroline Tice             }
544844d2303SCaroline Tice 
545472362e6SCaroline Tice             if (cmd_obj_sp)
546472362e6SCaroline Tice             {
547844d2303SCaroline Tice                 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
548844d2303SCaroline Tice                 if (option_arg_vector->size() > 0)
549844d2303SCaroline Tice                     m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
550844d2303SCaroline Tice                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
551844d2303SCaroline Tice             }
552472362e6SCaroline Tice             else
553472362e6SCaroline Tice             {
554472362e6SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
555472362e6SCaroline Tice                 result.SetStatus (eReturnStatusFailed);
556472362e6SCaroline Tice             }
557844d2303SCaroline Tice             return result.Succeeded ();
558844d2303SCaroline Tice     }
559ebc09c36SJim Ingham 
560ebc09c36SJim Ingham     bool
5615a988416SJim Ingham     HandleAliasingNormalCommand (Args& args, CommandReturnObject &result)
562ebc09c36SJim Ingham     {
563867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
564ebc09c36SJim Ingham 
565ebc09c36SJim Ingham         if (argc < 2)
566ebc09c36SJim Ingham         {
567ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
568ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
569ebc09c36SJim Ingham             return false;
570ebc09c36SJim Ingham         }
571ebc09c36SJim Ingham 
572ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
573ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
574ebc09c36SJim Ingham 
575ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
576ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
577ebc09c36SJim Ingham 
578ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
579ebc09c36SJim Ingham 
580a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
581ebc09c36SJim Ingham         {
582ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
583ebc09c36SJim Ingham                                          alias_command.c_str());
584ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
585ebc09c36SJim Ingham         }
586ebc09c36SJim Ingham         else
587ebc09c36SJim Ingham         {
588a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
589ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
590ebc09c36SJim Ingham              bool use_subcommand = false;
591ebc09c36SJim Ingham              if (command_obj_sp.get())
592ebc09c36SJim Ingham              {
593ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
594c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
595ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
596ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
597ebc09c36SJim Ingham 
598844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
599ebc09c36SJim Ingham                  {
600ebc09c36SJim Ingham                      if (argc >= 3)
601ebc09c36SJim Ingham                      {
602ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
603ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
604998255bfSGreg Clayton                          subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str());
605ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
606ebc09c36SJim Ingham                          {
607ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
608ebc09c36SJim Ingham                              use_subcommand = true;
609ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
610844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
611ebc09c36SJim Ingham                          }
612ebc09c36SJim Ingham                          else
613ebc09c36SJim Ingham                          {
614f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
615f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
616f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
617ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
618ebc09c36SJim Ingham                              return false;
619ebc09c36SJim Ingham                          }
620ebc09c36SJim Ingham                      }
621ebc09c36SJim Ingham                  }
622ebc09c36SJim Ingham 
623ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
624ebc09c36SJim Ingham 
625ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
626ebc09c36SJim Ingham                  {
627ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
628ebc09c36SJim Ingham                     if (use_subcommand)
629ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
630ca90c47eSCaroline Tice 
631ca90c47eSCaroline Tice                     std::string args_string;
632ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
633ca90c47eSCaroline Tice 
634ca90c47eSCaroline Tice                     if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
635ebc09c36SJim Ingham                     {
636ca90c47eSCaroline Tice                         result.AppendError ("Unable to create requested alias.\n");
637ca90c47eSCaroline Tice                         result.SetStatus (eReturnStatusFailed);
638e7941795SCaroline Tice                         return false;
639867b185dSCaroline Tice                     }
640867b185dSCaroline Tice                  }
641867b185dSCaroline Tice 
642ebc09c36SJim Ingham                  // Create the alias.
643ebc09c36SJim Ingham 
644a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
645a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
646ebc09c36SJim Ingham                  {
647a7015092SGreg Clayton                      OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
648ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
649ebc09c36SJim Ingham                      {
650ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
651a7015092SGreg Clayton                              m_interpreter.RemoveAliasOptions (alias_command.c_str());
652ebc09c36SJim Ingham                      }
653ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
654ebc09c36SJim Ingham                                                      alias_command.c_str());
655ebc09c36SJim Ingham                  }
656ebc09c36SJim Ingham 
657ebc09c36SJim Ingham                  if (use_subcommand)
658a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
659ebc09c36SJim Ingham                  else
660a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
661ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
662a7015092SGreg Clayton                      m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
663ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
664ebc09c36SJim Ingham              }
665ebc09c36SJim Ingham              else
666ebc09c36SJim Ingham              {
667ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
668ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
669e7941795SCaroline Tice                  return false;
670ebc09c36SJim Ingham              }
671ebc09c36SJim Ingham         }
672ebc09c36SJim Ingham 
673ebc09c36SJim Ingham         return result.Succeeded();
674ebc09c36SJim Ingham     }
6755a988416SJim Ingham 
676ebc09c36SJim Ingham };
677ebc09c36SJim Ingham 
678ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
679ebc09c36SJim Ingham //-------------------------------------------------------------------------
680ebc09c36SJim Ingham // CommandObjectCommandsUnalias
681ebc09c36SJim Ingham //-------------------------------------------------------------------------
682ebc09c36SJim Ingham 
6835a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed
684ebc09c36SJim Ingham {
685ebc09c36SJim Ingham public:
686a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
6875a988416SJim Ingham         CommandObjectParsed (interpreter,
6880e5e5a79SGreg Clayton                        "command unalias",
68986ddae50SCaroline Tice                        "Allow the user to remove/delete a user-defined command abbreviation.",
690405fe67fSCaroline Tice                        NULL)
691ebc09c36SJim Ingham     {
692405fe67fSCaroline Tice         CommandArgumentEntry arg;
693405fe67fSCaroline Tice         CommandArgumentData alias_arg;
694405fe67fSCaroline Tice 
695405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
696405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
697405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
698405fe67fSCaroline Tice 
699405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
700405fe67fSCaroline Tice         arg.push_back (alias_arg);
701405fe67fSCaroline Tice 
702405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
703405fe67fSCaroline Tice         m_arguments.push_back (arg);
704ebc09c36SJim Ingham     }
705ebc09c36SJim Ingham 
706ebc09c36SJim Ingham     ~CommandObjectCommandsUnalias()
707ebc09c36SJim Ingham     {
708ebc09c36SJim Ingham     }
709ebc09c36SJim Ingham 
7105a988416SJim Ingham protected:
711ebc09c36SJim Ingham     bool
7125a988416SJim Ingham     DoExecute (Args& args, CommandReturnObject &result)
713ebc09c36SJim Ingham     {
714ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
715ebc09c36SJim Ingham         CommandObject *cmd_obj;
716ebc09c36SJim Ingham 
717ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
718ebc09c36SJim Ingham         {
719ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
720a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
721ebc09c36SJim Ingham             if (cmd_obj)
722ebc09c36SJim Ingham             {
723a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
724ebc09c36SJim Ingham                 {
725ebc09c36SJim Ingham                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
726ebc09c36SJim Ingham                                                   command_name);
727ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
728ebc09c36SJim Ingham                 }
729ebc09c36SJim Ingham                 else
730ebc09c36SJim Ingham                 {
731ebc09c36SJim Ingham 
732a7015092SGreg Clayton                     if (m_interpreter.RemoveAlias (command_name) == false)
733ebc09c36SJim Ingham                     {
734a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
735ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
736ebc09c36SJim Ingham                                                           command_name);
737ebc09c36SJim Ingham                         else
738ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
739ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
740ebc09c36SJim Ingham                     }
741ebc09c36SJim Ingham                     else
742ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
743ebc09c36SJim Ingham                 }
744ebc09c36SJim Ingham             }
745ebc09c36SJim Ingham             else
746ebc09c36SJim Ingham             {
747ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
748ebc09c36SJim Ingham                                               "current list of commands.\n",
749ebc09c36SJim Ingham                                              command_name);
750ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
751ebc09c36SJim Ingham             }
752ebc09c36SJim Ingham         }
753ebc09c36SJim Ingham         else
754ebc09c36SJim Ingham         {
755ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
756ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
757ebc09c36SJim Ingham         }
758ebc09c36SJim Ingham 
759ebc09c36SJim Ingham         return result.Succeeded();
760ebc09c36SJim Ingham     }
761ebc09c36SJim Ingham };
762ebc09c36SJim Ingham 
763de164aaaSGreg Clayton //-------------------------------------------------------------------------
764de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
765de164aaaSGreg Clayton //-------------------------------------------------------------------------
7665a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex
767de164aaaSGreg Clayton 
7685a988416SJim Ingham class CommandObjectCommandsAddRegex : public CommandObjectParsed
769de164aaaSGreg Clayton {
770de164aaaSGreg Clayton public:
771de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
7725a988416SJim Ingham         CommandObjectParsed (interpreter,
7730e5e5a79SGreg Clayton                        "command regex",
774de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
7750e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
776de164aaaSGreg Clayton         m_options (interpreter)
777de164aaaSGreg Clayton     {
7780e5e5a79SGreg Clayton         SetHelpLong(
7790e5e5a79SGreg Clayton "This command allows the user to create powerful regular expression commands\n"
7800e5e5a79SGreg Clayton "with substitutions. The regular expressions and substitutions are specified\n"
7810e5e5a79SGreg Clayton "using the regular exression substitution format of:\n"
7820e5e5a79SGreg Clayton "\n"
7830e5e5a79SGreg Clayton "    s/<regex>/<subst>/\n"
7840e5e5a79SGreg Clayton "\n"
7850e5e5a79SGreg Clayton "<regex> is a regular expression that can use parenthesis to capture regular\n"
7860e5e5a79SGreg Clayton "expression input and substitute the captured matches in the output using %1\n"
7870e5e5a79SGreg Clayton "for the first match, %2 for the second, and so on.\n"
7880e5e5a79SGreg Clayton "\n"
7890e5e5a79SGreg Clayton "The regular expressions can all be specified on the command line if more than\n"
7900e5e5a79SGreg Clayton "one argument is provided. If just the command name is provided on the command\n"
7910e5e5a79SGreg Clayton "line, then the regular expressions and substitutions can be entered on separate\n"
7920e5e5a79SGreg Clayton " lines, followed by an empty line to terminate the command definition.\n"
7930e5e5a79SGreg Clayton "\n"
7940e5e5a79SGreg Clayton "EXAMPLES\n"
7950e5e5a79SGreg Clayton "\n"
796adc43c99SSean Callanan "The following example will define a regular expression command named 'f' that\n"
7970e5e5a79SGreg Clayton "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
7980e5e5a79SGreg Clayton "a number follows 'f':\n"
799adc43c99SSean Callanan "\n"
8000e5e5a79SGreg Clayton "    (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
801adc43c99SSean Callanan "\n"
8020e5e5a79SGreg Clayton                     );
803de164aaaSGreg Clayton     }
804de164aaaSGreg Clayton 
805de164aaaSGreg Clayton     ~CommandObjectCommandsAddRegex()
806de164aaaSGreg Clayton     {
807de164aaaSGreg Clayton     }
808de164aaaSGreg Clayton 
809de164aaaSGreg Clayton 
8105a988416SJim Ingham protected:
811de164aaaSGreg Clayton     bool
8125a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
813de164aaaSGreg Clayton     {
8145a988416SJim Ingham         const size_t argc = command.GetArgumentCount();
8150e5e5a79SGreg Clayton         if (argc == 0)
816de164aaaSGreg Clayton         {
81769c12ccbSJason Molenda             result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
8180e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
8190e5e5a79SGreg Clayton         }
8200e5e5a79SGreg Clayton         else
8210e5e5a79SGreg Clayton         {
8220e5e5a79SGreg Clayton             Error error;
8235a988416SJim Ingham             const char *name = command.GetArgumentAtIndex(0);
824de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
825de164aaaSGreg Clayton                                                                  name,
826de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
827de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
828de164aaaSGreg Clayton                                                                  10));
8290e5e5a79SGreg Clayton 
8300e5e5a79SGreg Clayton             if (argc == 1)
8310e5e5a79SGreg Clayton             {
8320e5e5a79SGreg Clayton                 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
833de164aaaSGreg Clayton                 if (reader_sp)
834de164aaaSGreg Clayton                 {
8350e5e5a79SGreg Clayton                     error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
836de164aaaSGreg Clayton                                                   this,                         // baton
837de164aaaSGreg Clayton                                                   eInputReaderGranularityLine,  // token size, to pass to callback function
8380e5e5a79SGreg Clayton                                                   NULL,                         // end token
839de164aaaSGreg Clayton                                                   "> ",                         // prompt
8400e5e5a79SGreg Clayton                                                   true);                        // echo input
8410e5e5a79SGreg Clayton                     if (error.Success())
842de164aaaSGreg Clayton                     {
843de164aaaSGreg Clayton                         m_interpreter.GetDebugger().PushInputReader (reader_sp);
844de164aaaSGreg Clayton                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
8450e5e5a79SGreg Clayton                         return true;
846de164aaaSGreg Clayton                     }
847de164aaaSGreg Clayton                 }
848de164aaaSGreg Clayton             }
849de164aaaSGreg Clayton             else
850de164aaaSGreg Clayton             {
8510e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
8520e5e5a79SGreg Clayton                 {
8535a988416SJim Ingham                     llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx));
8540e5e5a79SGreg Clayton                     error = AppendRegexSubstitution (arg_strref);
8550e5e5a79SGreg Clayton                     if (error.Fail())
8560e5e5a79SGreg Clayton                         break;
8570e5e5a79SGreg Clayton                 }
8580e5e5a79SGreg Clayton 
8590e5e5a79SGreg Clayton                 if (error.Success())
8600e5e5a79SGreg Clayton                 {
8610e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
8620e5e5a79SGreg Clayton                 }
8630e5e5a79SGreg Clayton             }
8640e5e5a79SGreg Clayton             if (error.Fail())
8650e5e5a79SGreg Clayton             {
8660e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
867de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
868de164aaaSGreg Clayton             }
8690e5e5a79SGreg Clayton         }
8700e5e5a79SGreg Clayton 
871de164aaaSGreg Clayton         return result.Succeeded();
872de164aaaSGreg Clayton     }
873de164aaaSGreg Clayton 
8740e5e5a79SGreg Clayton     Error
8750e5e5a79SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed)
876de164aaaSGreg Clayton     {
8770e5e5a79SGreg Clayton         Error error;
8780e5e5a79SGreg Clayton 
8790e5e5a79SGreg Clayton         if (m_regex_cmd_ap.get() == NULL)
880de164aaaSGreg Clayton         {
8810e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
8820e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8830e5e5a79SGreg Clayton                                            regex_sed.data());
8840e5e5a79SGreg Clayton             return error;
885de164aaaSGreg Clayton         }
8860e5e5a79SGreg Clayton 
8870e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
8880e5e5a79SGreg Clayton 
8890e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
8900e5e5a79SGreg Clayton         {
8910e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
8920e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8930e5e5a79SGreg Clayton                                            regex_sed.data());
8940e5e5a79SGreg Clayton             return error;
8950e5e5a79SGreg Clayton         }
8960e5e5a79SGreg Clayton 
8970e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
8980e5e5a79SGreg Clayton         {
8990e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
9000e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9010e5e5a79SGreg Clayton                                            regex_sed.data());
9020e5e5a79SGreg Clayton             return error;
9030e5e5a79SGreg Clayton         }
9040e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
9050e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
9060e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
9070e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
9080e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
9090e5e5a79SGreg Clayton 
9100e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
9110e5e5a79SGreg Clayton         {
9120e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
9130e5e5a79SGreg Clayton                                            separator_char,
9140e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
9150e5e5a79SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1));
9160e5e5a79SGreg Clayton             return error;
9170e5e5a79SGreg Clayton         }
9180e5e5a79SGreg Clayton 
9190e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
9200e5e5a79SGreg Clayton 
9210e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
9220e5e5a79SGreg Clayton         {
9230e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
9240e5e5a79SGreg Clayton                                            separator_char,
9250e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
9260e5e5a79SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1));
9270e5e5a79SGreg Clayton             return error;
9280e5e5a79SGreg Clayton         }
9290e5e5a79SGreg Clayton 
9300e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
9310e5e5a79SGreg Clayton         {
9320e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
9330e5e5a79SGreg Clayton             // separator char
9340e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
9350e5e5a79SGreg Clayton             {
9360e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
9370e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
9380e5e5a79SGreg Clayton                                                regex_sed.data(),
9390e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
9400e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
9410e5e5a79SGreg Clayton                 return error;
9420e5e5a79SGreg Clayton             }
9430e5e5a79SGreg Clayton 
9440e5e5a79SGreg Clayton         }
9450e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
9460e5e5a79SGreg Clayton         {
9470e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9480e5e5a79SGreg Clayton                                            separator_char,
9490e5e5a79SGreg Clayton                                            separator_char,
9500e5e5a79SGreg Clayton                                            separator_char,
9510e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9520e5e5a79SGreg Clayton                                            regex_sed.data());
9530e5e5a79SGreg Clayton             return error;
9540e5e5a79SGreg Clayton         }
9550e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
9560e5e5a79SGreg Clayton         {
9570e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9580e5e5a79SGreg Clayton                                            separator_char,
9590e5e5a79SGreg Clayton                                            separator_char,
9600e5e5a79SGreg Clayton                                            separator_char,
9610e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9620e5e5a79SGreg Clayton                                            regex_sed.data());
9630e5e5a79SGreg Clayton             return error;
9640e5e5a79SGreg Clayton         }
9650e5e5a79SGreg Clayton         std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
9660e5e5a79SGreg Clayton         std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
9670e5e5a79SGreg Clayton         m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
9680e5e5a79SGreg Clayton                                          subst.c_str());
9690e5e5a79SGreg Clayton         return error;
970de164aaaSGreg Clayton     }
971de164aaaSGreg Clayton 
972de164aaaSGreg Clayton     void
9730e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
974de164aaaSGreg Clayton     {
975de164aaaSGreg Clayton         if (m_regex_cmd_ap.get())
976de164aaaSGreg Clayton         {
977de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
978de164aaaSGreg Clayton             {
979de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
980de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
981de164aaaSGreg Clayton             }
982de164aaaSGreg Clayton         }
983de164aaaSGreg Clayton     }
984de164aaaSGreg Clayton 
9850e5e5a79SGreg Clayton     void
9860e5e5a79SGreg Clayton     InputReaderDidCancel()
9870e5e5a79SGreg Clayton     {
9880e5e5a79SGreg Clayton         m_regex_cmd_ap.reset();
9890e5e5a79SGreg Clayton     }
9900e5e5a79SGreg Clayton 
991de164aaaSGreg Clayton     static size_t
992de164aaaSGreg Clayton     InputReaderCallback (void *baton,
993de164aaaSGreg Clayton                          InputReader &reader,
994de164aaaSGreg Clayton                          lldb::InputReaderAction notification,
995de164aaaSGreg Clayton                          const char *bytes,
9965a988416SJim Ingham                          size_t bytes_len)
9975a988416SJim Ingham     {
9985a988416SJim Ingham         CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
9995a988416SJim Ingham         bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
10005a988416SJim Ingham 
10015a988416SJim Ingham         switch (notification)
10025a988416SJim Ingham         {
10035a988416SJim Ingham             case eInputReaderActivate:
10045a988416SJim Ingham                 if (!batch_mode)
10055a988416SJim Ingham                 {
10065a988416SJim Ingham                     StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
10075a988416SJim Ingham                     out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
10085a988416SJim Ingham                     out_stream->Flush();
10095a988416SJim Ingham                 }
10105a988416SJim Ingham                 break;
10115a988416SJim Ingham             case eInputReaderReactivate:
10125a988416SJim Ingham                 break;
10135a988416SJim Ingham 
10145a988416SJim Ingham             case eInputReaderDeactivate:
10155a988416SJim Ingham                 break;
10165a988416SJim Ingham 
10175a988416SJim Ingham             case eInputReaderAsynchronousOutputWritten:
10185a988416SJim Ingham                 break;
10195a988416SJim Ingham 
10205a988416SJim Ingham             case eInputReaderGotToken:
10215a988416SJim Ingham                 while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
10225a988416SJim Ingham                     --bytes_len;
10235a988416SJim Ingham                 if (bytes_len == 0)
10245a988416SJim Ingham                     reader.SetIsDone(true);
10255a988416SJim Ingham                 else if (bytes)
10265a988416SJim Ingham                 {
10275a988416SJim Ingham                     llvm::StringRef bytes_strref (bytes, bytes_len);
10285a988416SJim Ingham                     Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
10295a988416SJim Ingham                     if (error.Fail())
10305a988416SJim Ingham                     {
10315a988416SJim Ingham                         if (!batch_mode)
10325a988416SJim Ingham                         {
10335a988416SJim Ingham                             StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
10345a988416SJim Ingham                             out_stream->Printf("error: %s\n", error.AsCString());
10355a988416SJim Ingham                             out_stream->Flush();
10365a988416SJim Ingham                         }
10375a988416SJim Ingham                         add_regex_cmd->InputReaderDidCancel ();
10385a988416SJim Ingham                         reader.SetIsDone (true);
10395a988416SJim Ingham                     }
10405a988416SJim Ingham                 }
10415a988416SJim Ingham                 break;
10425a988416SJim Ingham 
10435a988416SJim Ingham             case eInputReaderInterrupt:
10445a988416SJim Ingham                 {
10455a988416SJim Ingham                     reader.SetIsDone (true);
10465a988416SJim Ingham                     if (!batch_mode)
10475a988416SJim Ingham                     {
10485a988416SJim Ingham                         StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
10495a988416SJim Ingham                         out_stream->PutCString("Regular expression command creations was cancelled.\n");
10505a988416SJim Ingham                         out_stream->Flush();
10515a988416SJim Ingham                     }
10525a988416SJim Ingham                     add_regex_cmd->InputReaderDidCancel ();
10535a988416SJim Ingham                 }
10545a988416SJim Ingham                 break;
10555a988416SJim Ingham 
10565a988416SJim Ingham             case eInputReaderEndOfFile:
10575a988416SJim Ingham                 reader.SetIsDone (true);
10585a988416SJim Ingham                 break;
10595a988416SJim Ingham 
10605a988416SJim Ingham             case eInputReaderDone:
10615a988416SJim Ingham                 add_regex_cmd->AddRegexCommandToInterpreter();
10625a988416SJim Ingham                 break;
10635a988416SJim Ingham         }
10645a988416SJim Ingham 
10655a988416SJim Ingham         return bytes_len;
10665a988416SJim Ingham     }
10675a988416SJim Ingham 
1068de164aaaSGreg Clayton private:
1069de164aaaSGreg Clayton     std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
1070de164aaaSGreg Clayton 
1071de164aaaSGreg Clayton      class CommandOptions : public Options
1072de164aaaSGreg Clayton      {
1073de164aaaSGreg Clayton      public:
1074de164aaaSGreg Clayton 
1075de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
1076de164aaaSGreg Clayton             Options (interpreter)
1077de164aaaSGreg Clayton          {
1078de164aaaSGreg Clayton          }
1079de164aaaSGreg Clayton 
1080de164aaaSGreg Clayton          virtual
1081de164aaaSGreg Clayton          ~CommandOptions (){}
1082de164aaaSGreg Clayton 
1083de164aaaSGreg Clayton          virtual Error
1084de164aaaSGreg Clayton          SetOptionValue (uint32_t option_idx, const char *option_arg)
1085de164aaaSGreg Clayton          {
1086de164aaaSGreg Clayton              Error error;
10873bcdfc0eSGreg Clayton              const int short_option = m_getopt_table[option_idx].val;
1088de164aaaSGreg Clayton 
1089de164aaaSGreg Clayton              switch (short_option)
1090de164aaaSGreg Clayton              {
1091de164aaaSGreg Clayton                  case 'h':
1092de164aaaSGreg Clayton                      m_help.assign (option_arg);
1093de164aaaSGreg Clayton                      break;
1094de164aaaSGreg Clayton                  case 's':
1095de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1096de164aaaSGreg Clayton                      break;
1097de164aaaSGreg Clayton 
1098de164aaaSGreg Clayton                  default:
109986edbf41SGreg Clayton                      error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1100de164aaaSGreg Clayton                      break;
1101de164aaaSGreg Clayton              }
1102de164aaaSGreg Clayton 
1103de164aaaSGreg Clayton              return error;
1104de164aaaSGreg Clayton          }
1105de164aaaSGreg Clayton 
1106de164aaaSGreg Clayton          void
1107de164aaaSGreg Clayton          OptionParsingStarting ()
1108de164aaaSGreg Clayton          {
1109de164aaaSGreg Clayton              m_help.clear();
1110de164aaaSGreg Clayton              m_syntax.clear();
1111de164aaaSGreg Clayton          }
1112de164aaaSGreg Clayton 
1113de164aaaSGreg Clayton          const OptionDefinition*
1114de164aaaSGreg Clayton          GetDefinitions ()
1115de164aaaSGreg Clayton          {
1116de164aaaSGreg Clayton              return g_option_table;
1117de164aaaSGreg Clayton          }
1118de164aaaSGreg Clayton 
1119de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1120de164aaaSGreg Clayton 
1121de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1122de164aaaSGreg Clayton 
1123de164aaaSGreg Clayton          const char *
1124de164aaaSGreg Clayton          GetHelp ()
1125de164aaaSGreg Clayton          {
1126de164aaaSGreg Clayton              if (m_help.empty())
1127de164aaaSGreg Clayton                  return NULL;
1128de164aaaSGreg Clayton              return m_help.c_str();
1129de164aaaSGreg Clayton          }
1130de164aaaSGreg Clayton          const char *
1131de164aaaSGreg Clayton          GetSyntax ()
1132de164aaaSGreg Clayton          {
1133de164aaaSGreg Clayton              if (m_syntax.empty())
1134de164aaaSGreg Clayton                  return NULL;
1135de164aaaSGreg Clayton              return m_syntax.c_str();
1136de164aaaSGreg Clayton          }
1137de164aaaSGreg Clayton          // Instance variables to hold the values for command options.
1138de164aaaSGreg Clayton      protected:
1139de164aaaSGreg Clayton          std::string m_help;
1140de164aaaSGreg Clayton          std::string m_syntax;
1141de164aaaSGreg Clayton      };
1142de164aaaSGreg Clayton 
1143de164aaaSGreg Clayton      virtual Options *
1144de164aaaSGreg Clayton      GetOptions ()
1145de164aaaSGreg Clayton      {
1146de164aaaSGreg Clayton          return &m_options;
1147de164aaaSGreg Clayton      }
1148de164aaaSGreg Clayton 
11495a988416SJim Ingham      CommandOptions m_options;
1150de164aaaSGreg Clayton };
1151de164aaaSGreg Clayton 
1152de164aaaSGreg Clayton OptionDefinition
1153de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1154de164aaaSGreg Clayton {
1155de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "help"  , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1156de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1157de164aaaSGreg Clayton { 0             , false,  NULL   , 0  , 0                , NULL, 0, eArgTypeNone, NULL }
1158de164aaaSGreg Clayton };
1159de164aaaSGreg Clayton 
1160de164aaaSGreg Clayton 
11615a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw
1162223383edSEnrico Granata {
1163223383edSEnrico Granata private:
1164223383edSEnrico Granata     std::string m_function_name;
11650a305db7SEnrico Granata     ScriptedCommandSynchronicity m_synchro;
1166fac939e9SEnrico Granata     bool m_fetched_help_long;
1167223383edSEnrico Granata 
1168223383edSEnrico Granata public:
1169223383edSEnrico Granata 
1170223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1171223383edSEnrico Granata                                  std::string name,
11720a305db7SEnrico Granata                                  std::string funct,
11730a305db7SEnrico Granata                                  ScriptedCommandSynchronicity synch) :
11745a988416SJim Ingham         CommandObjectRaw (interpreter,
1175223383edSEnrico Granata                           name.c_str(),
1176223383edSEnrico Granata                           (std::string("Run Python function ") + funct).c_str(),
1177223383edSEnrico Granata                           NULL),
11780a305db7SEnrico Granata         m_function_name(funct),
1179fac939e9SEnrico Granata         m_synchro(synch),
1180fac939e9SEnrico Granata         m_fetched_help_long(false)
1181223383edSEnrico Granata     {
1182223383edSEnrico Granata     }
1183223383edSEnrico Granata 
1184223383edSEnrico Granata     virtual
1185223383edSEnrico Granata     ~CommandObjectPythonFunction ()
1186223383edSEnrico Granata     {
1187223383edSEnrico Granata     }
1188223383edSEnrico Granata 
1189223383edSEnrico Granata     virtual bool
11903a18e319SGreg Clayton     IsRemovable () const
11915a988416SJim Ingham     {
11925a988416SJim Ingham         return true;
11935a988416SJim Ingham     }
11945a988416SJim Ingham 
11955a988416SJim Ingham     const std::string&
11965a988416SJim Ingham     GetFunctionName ()
11975a988416SJim Ingham     {
11985a988416SJim Ingham         return m_function_name;
11995a988416SJim Ingham     }
12005a988416SJim Ingham 
12015a988416SJim Ingham     ScriptedCommandSynchronicity
12025a988416SJim Ingham     GetSynchronicity ()
12035a988416SJim Ingham     {
12045a988416SJim Ingham         return m_synchro;
12055a988416SJim Ingham     }
12065a988416SJim Ingham 
1207fac939e9SEnrico Granata     virtual const char *
1208fac939e9SEnrico Granata     GetHelpLong ()
1209fac939e9SEnrico Granata     {
1210fac939e9SEnrico Granata         if (!m_fetched_help_long)
1211fac939e9SEnrico Granata         {
1212fac939e9SEnrico Granata             ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1213fac939e9SEnrico Granata             if (scripter)
1214fac939e9SEnrico Granata             {
1215fac939e9SEnrico Granata                 std::string docstring;
1216fac939e9SEnrico Granata                 m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring);
1217fac939e9SEnrico Granata                 if (!docstring.empty())
1218fac939e9SEnrico Granata                     SetHelpLong(docstring);
1219fac939e9SEnrico Granata             }
1220fac939e9SEnrico Granata         }
1221fac939e9SEnrico Granata         return CommandObjectRaw::GetHelpLong();
1222fac939e9SEnrico Granata     }
1223fac939e9SEnrico Granata 
12245a988416SJim Ingham protected:
12255a988416SJim Ingham     virtual bool
12265a988416SJim Ingham     DoExecute (const char *raw_command_line, CommandReturnObject &result)
1227223383edSEnrico Granata     {
1228223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1229223383edSEnrico Granata 
1230223383edSEnrico Granata         Error error;
1231223383edSEnrico Granata 
123270f11f88SJim Ingham         result.SetStatus(eReturnStatusInvalid);
123370f11f88SJim Ingham 
1234223383edSEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1235223383edSEnrico Granata                                                          raw_command_line,
12360a305db7SEnrico Granata                                                          m_synchro,
1237223383edSEnrico Granata                                                          result,
1238223383edSEnrico Granata                                                          error) == false)
1239223383edSEnrico Granata         {
1240223383edSEnrico Granata             result.AppendError(error.AsCString());
1241223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1242223383edSEnrico Granata         }
1243223383edSEnrico Granata         else
124470f11f88SJim Ingham         {
124570f11f88SJim Ingham             // Don't change the status if the command already set it...
124670f11f88SJim Ingham             if (result.GetStatus() == eReturnStatusInvalid)
124770f11f88SJim Ingham             {
124870f11f88SJim Ingham                 if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0')
1249223383edSEnrico Granata                     result.SetStatus(eReturnStatusSuccessFinishNoResult);
125070f11f88SJim Ingham                 else
125170f11f88SJim Ingham                     result.SetStatus(eReturnStatusSuccessFinishResult);
125270f11f88SJim Ingham             }
125370f11f88SJim Ingham         }
1254223383edSEnrico Granata 
1255223383edSEnrico Granata         return result.Succeeded();
1256223383edSEnrico Granata     }
1257223383edSEnrico Granata 
1258223383edSEnrico Granata };
1259223383edSEnrico Granata 
1260a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1261a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport
1262a9dbf432SEnrico Granata //-------------------------------------------------------------------------
1263a9dbf432SEnrico Granata 
12645a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed
1265a9dbf432SEnrico Granata {
12665a988416SJim Ingham public:
12675a988416SJim Ingham     CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) :
12685a988416SJim Ingham         CommandObjectParsed (interpreter,
12695a988416SJim Ingham                              "command script import",
12705a988416SJim Ingham                              "Import a scripting module in LLDB.",
12715a988416SJim Ingham                              NULL),
12725a988416SJim Ingham         m_options(interpreter)
12735a988416SJim Ingham     {
12745a988416SJim Ingham         CommandArgumentEntry arg1;
12755a988416SJim Ingham         CommandArgumentData cmd_arg;
12765a988416SJim Ingham 
12775a988416SJim Ingham         // Define the first (and only) variant of this arg.
12785a988416SJim Ingham         cmd_arg.arg_type = eArgTypeFilename;
12795a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
12805a988416SJim Ingham 
12815a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
12825a988416SJim Ingham         arg1.push_back (cmd_arg);
12835a988416SJim Ingham 
12845a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
12855a988416SJim Ingham         m_arguments.push_back (arg1);
12865a988416SJim Ingham     }
12875a988416SJim Ingham 
12885a988416SJim Ingham     ~CommandObjectCommandsScriptImport ()
12895a988416SJim Ingham     {
12905a988416SJim Ingham     }
12915a988416SJim Ingham 
1292*c7bece56SGreg Clayton     virtual int
12935a988416SJim Ingham     HandleArgumentCompletion (Args &input,
12945a988416SJim Ingham                               int &cursor_index,
12955a988416SJim Ingham                               int &cursor_char_position,
12965a988416SJim Ingham                               OptionElementVector &opt_element_vector,
12975a988416SJim Ingham                               int match_start_point,
12985a988416SJim Ingham                               int max_return_elements,
12995a988416SJim Ingham                               bool &word_complete,
13005a988416SJim Ingham                               StringList &matches)
13015a988416SJim Ingham     {
13025a988416SJim Ingham         std::string completion_str (input.GetArgumentAtIndex(cursor_index));
13035a988416SJim Ingham         completion_str.erase (cursor_char_position);
13045a988416SJim Ingham 
13055a988416SJim Ingham         CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
13065a988416SJim Ingham                                                              CommandCompletions::eDiskFileCompletion,
13075a988416SJim Ingham                                                              completion_str.c_str(),
13085a988416SJim Ingham                                                              match_start_point,
13095a988416SJim Ingham                                                              max_return_elements,
13105a988416SJim Ingham                                                              NULL,
13115a988416SJim Ingham                                                              word_complete,
13125a988416SJim Ingham                                                              matches);
13135a988416SJim Ingham         return matches.GetSize();
13145a988416SJim Ingham     }
13155a988416SJim Ingham 
13165a988416SJim Ingham     virtual Options *
13175a988416SJim Ingham     GetOptions ()
13185a988416SJim Ingham     {
13195a988416SJim Ingham         return &m_options;
13205a988416SJim Ingham     }
13215a988416SJim Ingham 
13225a988416SJim Ingham protected:
13230a305db7SEnrico Granata 
13240a305db7SEnrico Granata     class CommandOptions : public Options
13250a305db7SEnrico Granata     {
13260a305db7SEnrico Granata     public:
13270a305db7SEnrico Granata 
13280a305db7SEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
13290a305db7SEnrico Granata             Options (interpreter)
13300a305db7SEnrico Granata         {
13310a305db7SEnrico Granata         }
13320a305db7SEnrico Granata 
13330a305db7SEnrico Granata         virtual
13340a305db7SEnrico Granata         ~CommandOptions (){}
13350a305db7SEnrico Granata 
13360a305db7SEnrico Granata         virtual Error
13370a305db7SEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
13380a305db7SEnrico Granata         {
13390a305db7SEnrico Granata             Error error;
13403bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13410a305db7SEnrico Granata 
13420a305db7SEnrico Granata             switch (short_option)
13430a305db7SEnrico Granata             {
13440a305db7SEnrico Granata                 case 'r':
13450a305db7SEnrico Granata                     m_allow_reload = true;
13460a305db7SEnrico Granata                     break;
13470a305db7SEnrico Granata                 default:
13480a305db7SEnrico Granata                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
13490a305db7SEnrico Granata                     break;
13500a305db7SEnrico Granata             }
13510a305db7SEnrico Granata 
13520a305db7SEnrico Granata             return error;
13530a305db7SEnrico Granata         }
13540a305db7SEnrico Granata 
13550a305db7SEnrico Granata         void
13560a305db7SEnrico Granata         OptionParsingStarting ()
13570a305db7SEnrico Granata         {
13580a305db7SEnrico Granata             m_allow_reload = false;
13590a305db7SEnrico Granata         }
13600a305db7SEnrico Granata 
13610a305db7SEnrico Granata         const OptionDefinition*
13620a305db7SEnrico Granata         GetDefinitions ()
13630a305db7SEnrico Granata         {
13640a305db7SEnrico Granata             return g_option_table;
13650a305db7SEnrico Granata         }
13660a305db7SEnrico Granata 
13670a305db7SEnrico Granata         // Options table: Required for subclasses of Options.
13680a305db7SEnrico Granata 
13690a305db7SEnrico Granata         static OptionDefinition g_option_table[];
13700a305db7SEnrico Granata 
13710a305db7SEnrico Granata         // Instance variables to hold the values for command options.
13720a305db7SEnrico Granata 
13730a305db7SEnrico Granata         bool m_allow_reload;
13740a305db7SEnrico Granata     };
13750a305db7SEnrico Granata 
1376a9dbf432SEnrico Granata     bool
13775a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1378a9dbf432SEnrico Granata     {
1379a9dbf432SEnrico Granata 
1380a9dbf432SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1381a9dbf432SEnrico Granata         {
1382a9dbf432SEnrico Granata             result.AppendError ("only scripting language supported for module importing is currently Python");
1383a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1384a9dbf432SEnrico Granata             return false;
1385a9dbf432SEnrico Granata         }
1386a9dbf432SEnrico Granata 
13875a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1388a9dbf432SEnrico Granata 
1389a9dbf432SEnrico Granata         if (argc != 1)
1390a9dbf432SEnrico Granata         {
1391a9dbf432SEnrico Granata             result.AppendError ("'command script import' requires one argument");
1392a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1393a9dbf432SEnrico Granata             return false;
1394a9dbf432SEnrico Granata         }
1395a9dbf432SEnrico Granata 
13965a988416SJim Ingham         std::string path = command.GetArgumentAtIndex(0);
1397a9dbf432SEnrico Granata         Error error;
1398a9dbf432SEnrico Granata 
1399c9d645d3SGreg Clayton         const bool init_session = true;
1400a9dbf432SEnrico Granata         if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(),
14010a305db7SEnrico Granata                                                                       m_options.m_allow_reload,
1402c9d645d3SGreg Clayton                                                                       init_session,
1403a9dbf432SEnrico Granata                                                                       error))
1404a9dbf432SEnrico Granata         {
1405a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishNoResult);
1406a9dbf432SEnrico Granata         }
1407a9dbf432SEnrico Granata         else
1408a9dbf432SEnrico Granata         {
1409a9dbf432SEnrico Granata             result.AppendErrorWithFormat("module importing failed: %s", error.AsCString());
1410a9dbf432SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1411a9dbf432SEnrico Granata         }
1412a9dbf432SEnrico Granata 
1413a9dbf432SEnrico Granata         return result.Succeeded();
1414a9dbf432SEnrico Granata     }
14150a305db7SEnrico Granata 
14165a988416SJim Ingham     CommandOptions m_options;
1417a9dbf432SEnrico Granata };
1418223383edSEnrico Granata 
14190a305db7SEnrico Granata OptionDefinition
14200a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] =
14210a305db7SEnrico Granata {
14220a305db7SEnrico 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)."},
14230a305db7SEnrico Granata     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
14240a305db7SEnrico Granata };
14250a305db7SEnrico Granata 
14260a305db7SEnrico Granata 
1427223383edSEnrico Granata //-------------------------------------------------------------------------
1428223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1429223383edSEnrico Granata //-------------------------------------------------------------------------
1430223383edSEnrico Granata 
14315a988416SJim Ingham class CommandObjectCommandsScriptAdd : public CommandObjectParsed
1432223383edSEnrico Granata {
14335a988416SJim Ingham public:
14345a988416SJim Ingham     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
14355a988416SJim Ingham         CommandObjectParsed (interpreter,
14365a988416SJim Ingham                              "command script add",
14375a988416SJim Ingham                              "Add a scripted function as an LLDB command.",
14385a988416SJim Ingham                              NULL),
14395a988416SJim Ingham         m_options (interpreter)
14405a988416SJim Ingham     {
14415a988416SJim Ingham         CommandArgumentEntry arg1;
14425a988416SJim Ingham         CommandArgumentData cmd_arg;
14435a988416SJim Ingham 
14445a988416SJim Ingham         // Define the first (and only) variant of this arg.
14455a988416SJim Ingham         cmd_arg.arg_type = eArgTypeCommandName;
14465a988416SJim Ingham         cmd_arg.arg_repetition = eArgRepeatPlain;
14475a988416SJim Ingham 
14485a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
14495a988416SJim Ingham         arg1.push_back (cmd_arg);
14505a988416SJim Ingham 
14515a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
14525a988416SJim Ingham         m_arguments.push_back (arg1);
14535a988416SJim Ingham     }
14545a988416SJim Ingham 
14555a988416SJim Ingham     ~CommandObjectCommandsScriptAdd ()
14565a988416SJim Ingham     {
14575a988416SJim Ingham     }
14585a988416SJim Ingham 
14595a988416SJim Ingham     virtual Options *
14605a988416SJim Ingham     GetOptions ()
14615a988416SJim Ingham     {
14625a988416SJim Ingham         return &m_options;
14635a988416SJim Ingham     }
14645a988416SJim Ingham 
14655a988416SJim Ingham protected:
1466223383edSEnrico Granata 
1467223383edSEnrico Granata     class CommandOptions : public Options
1468223383edSEnrico Granata     {
1469223383edSEnrico Granata     public:
1470223383edSEnrico Granata 
1471223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
1472223383edSEnrico Granata         Options (interpreter)
1473223383edSEnrico Granata         {
1474223383edSEnrico Granata         }
1475223383edSEnrico Granata 
1476223383edSEnrico Granata         virtual
1477223383edSEnrico Granata         ~CommandOptions (){}
1478223383edSEnrico Granata 
1479223383edSEnrico Granata         virtual Error
1480223383edSEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
1481223383edSEnrico Granata         {
1482223383edSEnrico Granata             Error error;
14833bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
1484223383edSEnrico Granata 
1485223383edSEnrico Granata             switch (short_option)
1486223383edSEnrico Granata             {
1487223383edSEnrico Granata                 case 'f':
1488223383edSEnrico Granata                     m_funct_name = std::string(option_arg);
1489223383edSEnrico Granata                     break;
14900a305db7SEnrico Granata                 case 's':
14910a305db7SEnrico Granata                     m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error);
14920a305db7SEnrico Granata                     if (!error.Success())
14930a305db7SEnrico Granata                         error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg);
14940a305db7SEnrico Granata                     break;
1495223383edSEnrico Granata                 default:
149686edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1497223383edSEnrico Granata                     break;
1498223383edSEnrico Granata             }
1499223383edSEnrico Granata 
1500223383edSEnrico Granata             return error;
1501223383edSEnrico Granata         }
1502223383edSEnrico Granata 
1503223383edSEnrico Granata         void
1504223383edSEnrico Granata         OptionParsingStarting ()
1505223383edSEnrico Granata         {
1506223383edSEnrico Granata             m_funct_name = "";
15070a305db7SEnrico Granata             m_synchronous = eScriptedCommandSynchronicitySynchronous;
1508223383edSEnrico Granata         }
1509223383edSEnrico Granata 
1510223383edSEnrico Granata         const OptionDefinition*
1511223383edSEnrico Granata         GetDefinitions ()
1512223383edSEnrico Granata         {
1513223383edSEnrico Granata             return g_option_table;
1514223383edSEnrico Granata         }
1515223383edSEnrico Granata 
1516223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1517223383edSEnrico Granata 
1518223383edSEnrico Granata         static OptionDefinition g_option_table[];
1519223383edSEnrico Granata 
1520223383edSEnrico Granata         // Instance variables to hold the values for command options.
1521223383edSEnrico Granata 
1522223383edSEnrico Granata         std::string m_funct_name;
15230a305db7SEnrico Granata         ScriptedCommandSynchronicity m_synchronous;
1524223383edSEnrico Granata     };
1525223383edSEnrico Granata 
15265a988416SJim Ingham private:
1527223383edSEnrico Granata     class PythonAliasReader : public InputReaderEZ
1528223383edSEnrico Granata     {
1529223383edSEnrico Granata     private:
1530223383edSEnrico Granata         CommandInterpreter& m_interpreter;
1531223383edSEnrico Granata         std::string m_cmd_name;
15320a305db7SEnrico Granata         ScriptedCommandSynchronicity m_synchronous;
1533223383edSEnrico Granata         StringList m_user_input;
1534223383edSEnrico Granata         DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1535223383edSEnrico Granata     public:
1536223383edSEnrico Granata         PythonAliasReader(Debugger& debugger,
1537223383edSEnrico Granata                           CommandInterpreter& interpreter,
15380a305db7SEnrico Granata                           std::string cmd_name,
15390a305db7SEnrico Granata                           ScriptedCommandSynchronicity synch) :
1540223383edSEnrico Granata         InputReaderEZ(debugger),
1541223383edSEnrico Granata         m_interpreter(interpreter),
1542223383edSEnrico Granata         m_cmd_name(cmd_name),
15430a305db7SEnrico Granata         m_synchronous(synch),
1544223383edSEnrico Granata         m_user_input()
1545223383edSEnrico Granata         {}
1546223383edSEnrico Granata 
1547223383edSEnrico Granata         virtual
1548223383edSEnrico Granata         ~PythonAliasReader()
1549223383edSEnrico Granata         {
1550223383edSEnrico Granata         }
1551223383edSEnrico Granata 
1552223383edSEnrico Granata         virtual void ActivateHandler(HandlerData& data)
1553223383edSEnrico Granata         {
1554223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1555223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1556223383edSEnrico Granata             if (!batch_mode)
1557223383edSEnrico Granata             {
1558223383edSEnrico Granata                 out_stream->Printf ("%s\n", g_python_command_instructions);
1559223383edSEnrico Granata                 if (data.reader.GetPrompt())
1560223383edSEnrico Granata                     out_stream->Printf ("%s", data.reader.GetPrompt());
1561223383edSEnrico Granata                 out_stream->Flush();
1562223383edSEnrico Granata             }
1563223383edSEnrico Granata         }
1564223383edSEnrico Granata 
1565223383edSEnrico Granata         virtual void ReactivateHandler(HandlerData& data)
1566223383edSEnrico Granata         {
1567223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1568223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1569223383edSEnrico Granata             if (data.reader.GetPrompt() && !batch_mode)
1570223383edSEnrico Granata             {
1571223383edSEnrico Granata                 out_stream->Printf ("%s", data.reader.GetPrompt());
1572223383edSEnrico Granata                 out_stream->Flush();
1573223383edSEnrico Granata             }
1574223383edSEnrico Granata         }
1575223383edSEnrico Granata         virtual void GotTokenHandler(HandlerData& data)
1576223383edSEnrico Granata         {
1577223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1578223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1579223383edSEnrico Granata             if (data.bytes && data.bytes_len)
1580223383edSEnrico Granata             {
1581223383edSEnrico Granata                 m_user_input.AppendString(data.bytes, data.bytes_len);
1582223383edSEnrico Granata             }
1583223383edSEnrico Granata             if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1584223383edSEnrico Granata             {
1585223383edSEnrico Granata                 out_stream->Printf ("%s", data.reader.GetPrompt());
1586223383edSEnrico Granata                 out_stream->Flush();
1587223383edSEnrico Granata             }
1588223383edSEnrico Granata         }
1589223383edSEnrico Granata         virtual void InterruptHandler(HandlerData& data)
1590223383edSEnrico Granata         {
1591223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1592223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1593223383edSEnrico Granata             data.reader.SetIsDone (true);
1594223383edSEnrico Granata             if (!batch_mode)
1595223383edSEnrico Granata             {
15960a305db7SEnrico Granata                 out_stream->Printf ("Warning: No script attached.\n");
1597223383edSEnrico Granata                 out_stream->Flush();
1598223383edSEnrico Granata             }
1599223383edSEnrico Granata         }
1600223383edSEnrico Granata         virtual void EOFHandler(HandlerData& data)
1601223383edSEnrico Granata         {
1602223383edSEnrico Granata             data.reader.SetIsDone (true);
1603223383edSEnrico Granata         }
1604223383edSEnrico Granata         virtual void DoneHandler(HandlerData& data)
1605223383edSEnrico Granata         {
1606223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1607223383edSEnrico Granata 
1608223383edSEnrico Granata             ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1609223383edSEnrico Granata             if (!interpreter)
1610223383edSEnrico Granata             {
16110a305db7SEnrico Granata                 out_stream->Printf ("Script interpreter missing: no script attached.\n");
1612223383edSEnrico Granata                 out_stream->Flush();
1613223383edSEnrico Granata                 return;
1614223383edSEnrico Granata             }
1615a73b7df7SEnrico Granata             std::string funct_name_str;
1616223383edSEnrico Granata             if (!interpreter->GenerateScriptAliasFunction (m_user_input,
1617a73b7df7SEnrico Granata                                                            funct_name_str))
1618223383edSEnrico Granata             {
16190a305db7SEnrico Granata                 out_stream->Printf ("Unable to create function: no script attached.\n");
1620223383edSEnrico Granata                 out_stream->Flush();
1621223383edSEnrico Granata                 return;
1622223383edSEnrico Granata             }
1623a73b7df7SEnrico Granata             if (funct_name_str.empty())
1624223383edSEnrico Granata             {
16250a305db7SEnrico Granata                 out_stream->Printf ("Unable to obtain a function name: no script attached.\n");
1626223383edSEnrico Granata                 out_stream->Flush();
1627223383edSEnrico Granata                 return;
1628223383edSEnrico Granata             }
1629223383edSEnrico Granata             // everything should be fine now, let's add this alias
1630223383edSEnrico Granata 
1631223383edSEnrico Granata             CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1632223383edSEnrico Granata                                                                            m_cmd_name,
1633a73b7df7SEnrico Granata                                                                            funct_name_str.c_str(),
16340a305db7SEnrico Granata                                                                            m_synchronous));
1635223383edSEnrico Granata 
16360a305db7SEnrico Granata             if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true))
1637223383edSEnrico Granata             {
16380a305db7SEnrico Granata                 out_stream->Printf ("Unable to add selected command: no script attached.\n");
1639223383edSEnrico Granata                 out_stream->Flush();
1640223383edSEnrico Granata                 return;
1641223383edSEnrico Granata             }
1642223383edSEnrico Granata         }
1643223383edSEnrico Granata     };
1644223383edSEnrico Granata 
16455a988416SJim Ingham protected:
1646223383edSEnrico Granata     bool
16475a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1648223383edSEnrico Granata     {
164999f0b8f9SEnrico Granata 
165099f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
165199f0b8f9SEnrico Granata         {
165299f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
165399f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
165499f0b8f9SEnrico Granata             return false;
165599f0b8f9SEnrico Granata         }
165699f0b8f9SEnrico Granata 
16575a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1658223383edSEnrico Granata 
1659223383edSEnrico Granata         if (argc != 1)
1660223383edSEnrico Granata         {
1661223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
1662223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1663223383edSEnrico Granata             return false;
1664223383edSEnrico Granata         }
1665223383edSEnrico Granata 
16665a988416SJim Ingham         std::string cmd_name = command.GetArgumentAtIndex(0);
1667223383edSEnrico Granata 
1668223383edSEnrico Granata         if (m_options.m_funct_name.empty())
1669223383edSEnrico Granata         {
1670223383edSEnrico Granata             InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1671223383edSEnrico Granata                                                             m_interpreter,
16720a305db7SEnrico Granata                                                             cmd_name,
16730a305db7SEnrico Granata                                                             m_options.m_synchronous));
1674223383edSEnrico Granata 
1675223383edSEnrico Granata             if (reader_sp)
1676223383edSEnrico Granata             {
1677223383edSEnrico Granata 
1678223383edSEnrico Granata                 InputReaderEZ::InitializationParameters ipr;
1679223383edSEnrico Granata 
1680223383edSEnrico Granata                 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt("     ")));
1681223383edSEnrico Granata                 if (err.Success())
1682223383edSEnrico Granata                 {
1683223383edSEnrico Granata                     m_interpreter.GetDebugger().PushInputReader (reader_sp);
1684223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1685223383edSEnrico Granata                 }
1686223383edSEnrico Granata                 else
1687223383edSEnrico Granata                 {
1688223383edSEnrico Granata                     result.AppendError (err.AsCString());
1689223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
1690223383edSEnrico Granata                 }
1691223383edSEnrico Granata             }
1692223383edSEnrico Granata             else
1693223383edSEnrico Granata             {
1694223383edSEnrico Granata                 result.AppendError("out of memory");
1695223383edSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1696223383edSEnrico Granata             }
1697223383edSEnrico Granata         }
1698223383edSEnrico Granata         else
1699223383edSEnrico Granata         {
17000a305db7SEnrico Granata             CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter,
17010a305db7SEnrico Granata                                                                     cmd_name,
17020a305db7SEnrico Granata                                                                     m_options.m_funct_name,
17030a305db7SEnrico Granata                                                                     m_options.m_synchronous));
17040a305db7SEnrico Granata             if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true))
1705223383edSEnrico Granata             {
1706223383edSEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1707223383edSEnrico Granata             }
1708223383edSEnrico Granata             else
1709223383edSEnrico Granata             {
1710223383edSEnrico Granata                 result.AppendError("cannot add command");
1711223383edSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1712223383edSEnrico Granata             }
1713223383edSEnrico Granata         }
1714223383edSEnrico Granata 
1715223383edSEnrico Granata         return result.Succeeded();
1716223383edSEnrico Granata 
1717223383edSEnrico Granata     }
17185a988416SJim Ingham 
17195a988416SJim Ingham     CommandOptions m_options;
1720223383edSEnrico Granata };
1721223383edSEnrico Granata 
17220a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] =
17230a305db7SEnrico Granata {
17240a305db7SEnrico Granata     { eScriptedCommandSynchronicitySynchronous,      "synchronous",       "Run synchronous"},
17250a305db7SEnrico Granata     { eScriptedCommandSynchronicityAsynchronous,     "asynchronous",      "Run asynchronous"},
17260a305db7SEnrico Granata     { eScriptedCommandSynchronicityCurrentValue,     "current",           "Do not alter current setting"},
17270a305db7SEnrico Granata     { 0, NULL, NULL }
17280a305db7SEnrico Granata };
17290a305db7SEnrico Granata 
1730223383edSEnrico Granata OptionDefinition
1731223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1732223383edSEnrico Granata {
17339128ee2fSEnrico Granata     { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction,        "Name of the Python function to bind to this command name."},
17340a305db7SEnrico 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."},
1735223383edSEnrico Granata     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1736223383edSEnrico Granata };
1737223383edSEnrico Granata 
1738223383edSEnrico Granata //-------------------------------------------------------------------------
1739223383edSEnrico Granata // CommandObjectCommandsScriptList
1740223383edSEnrico Granata //-------------------------------------------------------------------------
1741223383edSEnrico Granata 
17425a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed
1743223383edSEnrico Granata {
1744223383edSEnrico Granata private:
1745223383edSEnrico Granata 
1746223383edSEnrico Granata public:
1747223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
17485a988416SJim Ingham     CommandObjectParsed (interpreter,
1749223383edSEnrico Granata                    "command script list",
1750223383edSEnrico Granata                    "List defined scripted commands.",
1751223383edSEnrico Granata                    NULL)
1752223383edSEnrico Granata     {
1753223383edSEnrico Granata     }
1754223383edSEnrico Granata 
1755223383edSEnrico Granata     ~CommandObjectCommandsScriptList ()
1756223383edSEnrico Granata     {
1757223383edSEnrico Granata     }
1758223383edSEnrico Granata 
1759223383edSEnrico Granata     bool
17605a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1761223383edSEnrico Granata     {
1762223383edSEnrico Granata 
1763223383edSEnrico Granata         m_interpreter.GetHelp(result,
1764223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
1765223383edSEnrico Granata 
1766223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
1767223383edSEnrico Granata 
1768223383edSEnrico Granata         return true;
1769223383edSEnrico Granata 
1770223383edSEnrico Granata 
1771223383edSEnrico Granata     }
1772223383edSEnrico Granata };
1773223383edSEnrico Granata 
1774223383edSEnrico Granata //-------------------------------------------------------------------------
1775223383edSEnrico Granata // CommandObjectCommandsScriptClear
1776223383edSEnrico Granata //-------------------------------------------------------------------------
1777223383edSEnrico Granata 
17785a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed
1779223383edSEnrico Granata {
1780223383edSEnrico Granata private:
1781223383edSEnrico Granata 
1782223383edSEnrico Granata public:
1783223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
17845a988416SJim Ingham         CommandObjectParsed (interpreter,
1785223383edSEnrico Granata                              "command script clear",
1786223383edSEnrico Granata                              "Delete all scripted commands.",
1787223383edSEnrico Granata                              NULL)
1788223383edSEnrico Granata     {
1789223383edSEnrico Granata     }
1790223383edSEnrico Granata 
1791223383edSEnrico Granata     ~CommandObjectCommandsScriptClear ()
1792223383edSEnrico Granata     {
1793223383edSEnrico Granata     }
1794223383edSEnrico Granata 
17955a988416SJim Ingham protected:
1796223383edSEnrico Granata     bool
17975a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1798223383edSEnrico Granata     {
1799223383edSEnrico Granata 
1800223383edSEnrico Granata         m_interpreter.RemoveAllUser();
1801223383edSEnrico Granata 
1802223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
1803223383edSEnrico Granata 
1804223383edSEnrico Granata         return true;
1805223383edSEnrico Granata     }
1806223383edSEnrico Granata };
1807223383edSEnrico Granata 
1808223383edSEnrico Granata //-------------------------------------------------------------------------
1809223383edSEnrico Granata // CommandObjectCommandsScriptDelete
1810223383edSEnrico Granata //-------------------------------------------------------------------------
1811223383edSEnrico Granata 
18125a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed
1813223383edSEnrico Granata {
1814223383edSEnrico Granata public:
1815223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
18165a988416SJim Ingham         CommandObjectParsed (interpreter,
1817223383edSEnrico Granata                              "command script delete",
1818223383edSEnrico Granata                              "Delete a scripted command.",
1819223383edSEnrico Granata                              NULL)
1820223383edSEnrico Granata     {
1821223383edSEnrico Granata         CommandArgumentEntry arg1;
1822223383edSEnrico Granata         CommandArgumentData cmd_arg;
1823223383edSEnrico Granata 
1824223383edSEnrico Granata         // Define the first (and only) variant of this arg.
1825223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
1826223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
1827223383edSEnrico Granata 
1828223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
1829223383edSEnrico Granata         arg1.push_back (cmd_arg);
1830223383edSEnrico Granata 
1831223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
1832223383edSEnrico Granata         m_arguments.push_back (arg1);
1833223383edSEnrico Granata     }
1834223383edSEnrico Granata 
1835223383edSEnrico Granata     ~CommandObjectCommandsScriptDelete ()
1836223383edSEnrico Granata     {
1837223383edSEnrico Granata     }
1838223383edSEnrico Granata 
18395a988416SJim Ingham protected:
1840223383edSEnrico Granata     bool
18415a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
1842223383edSEnrico Granata     {
1843223383edSEnrico Granata 
18445a988416SJim Ingham         size_t argc = command.GetArgumentCount();
1845223383edSEnrico Granata 
1846223383edSEnrico Granata         if (argc != 1)
1847223383edSEnrico Granata         {
1848223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
1849223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1850223383edSEnrico Granata             return false;
1851223383edSEnrico Granata         }
1852223383edSEnrico Granata 
18535a988416SJim Ingham         const char* cmd_name = command.GetArgumentAtIndex(0);
1854223383edSEnrico Granata 
1855223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1856223383edSEnrico Granata         {
1857223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
1858223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
1859223383edSEnrico Granata         }
1860223383edSEnrico Granata         else
1861223383edSEnrico Granata         {
1862223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
1863223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1864223383edSEnrico Granata         }
1865223383edSEnrico Granata 
1866223383edSEnrico Granata         return result.Succeeded();
1867223383edSEnrico Granata 
1868223383edSEnrico Granata     }
1869223383edSEnrico Granata };
1870223383edSEnrico Granata 
1871223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
1872223383edSEnrico Granata 
1873223383edSEnrico Granata //-------------------------------------------------------------------------
1874223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
1875223383edSEnrico Granata //-------------------------------------------------------------------------
1876223383edSEnrico Granata 
1877223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1878223383edSEnrico Granata {
1879223383edSEnrico Granata public:
1880223383edSEnrico Granata     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1881223383edSEnrico Granata     CommandObjectMultiword (interpreter,
1882223383edSEnrico Granata                             "command script",
1883223383edSEnrico Granata                             "A set of commands for managing or customizing script commands.",
1884223383edSEnrico Granata                             "command script <subcommand> [<subcommand-options>]")
1885223383edSEnrico Granata     {
1886223383edSEnrico Granata         LoadSubCommand ("add",  CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1887223383edSEnrico Granata         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1888223383edSEnrico Granata         LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1889223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
1890a9dbf432SEnrico Granata         LoadSubCommand ("import",   CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter)));
1891223383edSEnrico Granata     }
1892223383edSEnrico Granata 
1893223383edSEnrico Granata     ~CommandObjectMultiwordCommandsScript ()
1894223383edSEnrico Granata     {
1895223383edSEnrico Granata     }
1896223383edSEnrico Granata 
1897223383edSEnrico Granata };
1898223383edSEnrico Granata 
1899223383edSEnrico Granata 
1900ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
1901ebc09c36SJim Ingham 
1902ebc09c36SJim Ingham //-------------------------------------------------------------------------
1903ebc09c36SJim Ingham // CommandObjectMultiwordCommands
1904ebc09c36SJim Ingham //-------------------------------------------------------------------------
1905ebc09c36SJim Ingham 
1906ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
1907a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
19080e5e5a79SGreg Clayton                             "command",
19093f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
19100e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
1911ebc09c36SJim Ingham {
1912a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1913a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1914a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
1915de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
1916a5a97ebeSJim Ingham     LoadSubCommand ("history",   CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
1917223383edSEnrico Granata     LoadSubCommand ("script",   CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
1918ebc09c36SJim Ingham }
1919ebc09c36SJim Ingham 
1920ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1921ebc09c36SJim Ingham {
1922ebc09c36SJim Ingham }
1923ebc09c36SJim Ingham 
1924