1ebc09c36SJim Ingham //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===//
2ebc09c36SJim Ingham //
3ebc09c36SJim Ingham //                     The LLVM Compiler Infrastructure
4ebc09c36SJim Ingham //
5ebc09c36SJim Ingham // This file is distributed under the University of Illinois Open Source
6ebc09c36SJim Ingham // License. See LICENSE.TXT for details.
7ebc09c36SJim Ingham //
8ebc09c36SJim Ingham //===----------------------------------------------------------------------===//
9ebc09c36SJim Ingham 
10ebc09c36SJim Ingham #include "CommandObjectCommands.h"
11ebc09c36SJim Ingham 
12ebc09c36SJim Ingham // C Includes
13ebc09c36SJim Ingham // C++ Includes
14ebc09c36SJim Ingham // Other libraries and framework includes
150e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h"
160e5e5a79SGreg Clayton 
17ebc09c36SJim Ingham // Project includes
18ebc09c36SJim Ingham #include "lldb/Core/Debugger.h"
19de164aaaSGreg Clayton #include "lldb/Core/InputReader.h"
20be93a35aSEnrico Granata #include "lldb/Core/InputReaderEZ.h"
21be93a35aSEnrico Granata #include "lldb/Core/StringList.h"
22de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h"
23ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h"
24de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h"
25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h"
26ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
27*99f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h"
28*99f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreterPython.h"
29ebc09c36SJim Ingham 
30ebc09c36SJim Ingham using namespace lldb;
31ebc09c36SJim Ingham using namespace lldb_private;
32ebc09c36SJim Ingham 
33ebc09c36SJim Ingham //-------------------------------------------------------------------------
34ebc09c36SJim Ingham // CommandObjectCommandsSource
35ebc09c36SJim Ingham //-------------------------------------------------------------------------
36ebc09c36SJim Ingham 
37a5a97ebeSJim Ingham class CommandObjectCommandsHistory : public CommandObject
38a5a97ebeSJim Ingham {
39a5a97ebeSJim Ingham private:
40a5a97ebeSJim Ingham 
41a5a97ebeSJim Ingham     class CommandOptions : public Options
42a5a97ebeSJim Ingham     {
43a5a97ebeSJim Ingham     public:
44a5a97ebeSJim Ingham 
45a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
46a5a97ebeSJim Ingham             Options (interpreter)
47a5a97ebeSJim Ingham         {
48a5a97ebeSJim Ingham         }
49a5a97ebeSJim Ingham 
50a5a97ebeSJim Ingham         virtual
51a5a97ebeSJim Ingham         ~CommandOptions (){}
52a5a97ebeSJim Ingham 
53a5a97ebeSJim Ingham         virtual Error
54a5a97ebeSJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
55a5a97ebeSJim Ingham         {
56a5a97ebeSJim Ingham             Error error;
57a5a97ebeSJim Ingham             char short_option = (char) m_getopt_table[option_idx].val;
58a5a97ebeSJim Ingham             bool success;
59a5a97ebeSJim Ingham 
60a5a97ebeSJim Ingham             switch (short_option)
61a5a97ebeSJim Ingham             {
62a5a97ebeSJim Ingham                 case 'c':
63a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
64a5a97ebeSJim Ingham                     if (!success)
65a5a97ebeSJim Ingham                         error.SetErrorStringWithFormat("Invalid value for count: %s.\n", option_arg);
66a5a97ebeSJim Ingham                     if (m_end_idx != 0)
67a5a97ebeSJim Ingham                         m_end_idx--;
68a5a97ebeSJim Ingham                     m_start_idx = 0;
69a5a97ebeSJim Ingham                     break;
70a5a97ebeSJim Ingham                 case 'e':
71a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
72a5a97ebeSJim Ingham                     if (!success)
73a5a97ebeSJim Ingham                         error.SetErrorStringWithFormat("Invalid value for end index: %s.\n", option_arg);
74a5a97ebeSJim Ingham                     break;
75a5a97ebeSJim Ingham                 case 's':
76a5a97ebeSJim Ingham                     m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
77a5a97ebeSJim Ingham                     if (!success)
78a5a97ebeSJim Ingham                         error.SetErrorStringWithFormat("Invalid value for start index: %s.\n", option_arg);
79a5a97ebeSJim Ingham                     break;
80a5a97ebeSJim Ingham                 default:
81a5a97ebeSJim Ingham                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
82a5a97ebeSJim Ingham                     break;
83a5a97ebeSJim Ingham             }
84a5a97ebeSJim Ingham 
85a5a97ebeSJim Ingham             return error;
86a5a97ebeSJim Ingham         }
87a5a97ebeSJim Ingham 
88a5a97ebeSJim Ingham         void
89a5a97ebeSJim Ingham         OptionParsingStarting ()
90a5a97ebeSJim Ingham         {
91a5a97ebeSJim Ingham             m_start_idx = 0;
92a5a97ebeSJim Ingham             m_end_idx = UINT_MAX;
93a5a97ebeSJim Ingham         }
94a5a97ebeSJim Ingham 
95a5a97ebeSJim Ingham         const OptionDefinition*
96a5a97ebeSJim Ingham         GetDefinitions ()
97a5a97ebeSJim Ingham         {
98a5a97ebeSJim Ingham             return g_option_table;
99a5a97ebeSJim Ingham         }
100a5a97ebeSJim Ingham 
101a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
102a5a97ebeSJim Ingham 
103a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
104a5a97ebeSJim Ingham 
105a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
106a5a97ebeSJim Ingham 
107a5a97ebeSJim Ingham         uint32_t m_start_idx;
108a5a97ebeSJim Ingham         uint32_t m_end_idx;
109a5a97ebeSJim Ingham     };
110a5a97ebeSJim Ingham 
111a5a97ebeSJim Ingham     CommandOptions m_options;
112a5a97ebeSJim Ingham 
113a5a97ebeSJim Ingham     virtual Options *
114a5a97ebeSJim Ingham     GetOptions ()
115a5a97ebeSJim Ingham     {
116a5a97ebeSJim Ingham         return &m_options;
117a5a97ebeSJim Ingham     }
118a5a97ebeSJim Ingham 
119a5a97ebeSJim Ingham public:
120a5a97ebeSJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
121a5a97ebeSJim Ingham         CommandObject (interpreter,
122a5a97ebeSJim Ingham                        "command history",
123a5a97ebeSJim Ingham                        "Dump the history of commands in this session.",
124a5a97ebeSJim Ingham                        NULL),
125a5a97ebeSJim Ingham         m_options (interpreter)
126a5a97ebeSJim Ingham     {
127a5a97ebeSJim Ingham     }
128a5a97ebeSJim Ingham 
129a5a97ebeSJim Ingham     ~CommandObjectCommandsHistory ()
130a5a97ebeSJim Ingham     {
131a5a97ebeSJim Ingham     }
132a5a97ebeSJim Ingham 
133a5a97ebeSJim Ingham     bool
134a5a97ebeSJim Ingham     Execute
135a5a97ebeSJim Ingham     (
136a5a97ebeSJim Ingham         Args& args,
137a5a97ebeSJim Ingham         CommandReturnObject &result
138a5a97ebeSJim Ingham     )
139a5a97ebeSJim Ingham     {
140a5a97ebeSJim Ingham 
141a5a97ebeSJim Ingham         m_interpreter.DumpHistory (result.GetOutputStream(),
142a5a97ebeSJim Ingham                                    m_options.m_start_idx,
143a5a97ebeSJim Ingham                                    m_options.m_end_idx);
144a5a97ebeSJim Ingham         return result.Succeeded();
145a5a97ebeSJim Ingham 
146a5a97ebeSJim Ingham     }
147a5a97ebeSJim Ingham };
148a5a97ebeSJim Ingham 
149a5a97ebeSJim Ingham OptionDefinition
150a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
151a5a97ebeSJim Ingham {
152a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
153a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger,  "Index at which to start printing history commands."},
154a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
155a5a97ebeSJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
156a5a97ebeSJim Ingham };
157a5a97ebeSJim Ingham 
158a5a97ebeSJim Ingham 
159a5a97ebeSJim Ingham //-------------------------------------------------------------------------
160a5a97ebeSJim Ingham // CommandObjectCommandsSource
161a5a97ebeSJim Ingham //-------------------------------------------------------------------------
162a5a97ebeSJim Ingham 
163ebc09c36SJim Ingham class CommandObjectCommandsSource : public CommandObject
164ebc09c36SJim Ingham {
165e16c50a1SJim Ingham private:
166e16c50a1SJim Ingham 
167e16c50a1SJim Ingham     class CommandOptions : public Options
168e16c50a1SJim Ingham     {
169e16c50a1SJim Ingham     public:
170e16c50a1SJim Ingham 
171eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
172eb0103f2SGreg Clayton             Options (interpreter)
173eb0103f2SGreg Clayton         {
174eb0103f2SGreg Clayton         }
175e16c50a1SJim Ingham 
176e16c50a1SJim Ingham         virtual
177e16c50a1SJim Ingham         ~CommandOptions (){}
178e16c50a1SJim Ingham 
179e16c50a1SJim Ingham         virtual Error
180f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
181e16c50a1SJim Ingham         {
182e16c50a1SJim Ingham             Error error;
183e16c50a1SJim Ingham             char short_option = (char) m_getopt_table[option_idx].val;
184e16c50a1SJim Ingham             bool success;
185e16c50a1SJim Ingham 
186e16c50a1SJim Ingham             switch (short_option)
187e16c50a1SJim Ingham             {
188e16c50a1SJim Ingham                 case 'e':
189e16c50a1SJim Ingham                     m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
190e16c50a1SJim Ingham                     if (!success)
191e16c50a1SJim Ingham                         error.SetErrorStringWithFormat("Invalid value for stop-on-error: %s.\n", option_arg);
192e16c50a1SJim Ingham                     break;
193e16c50a1SJim Ingham                 case 'c':
194e16c50a1SJim Ingham                     m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
195e16c50a1SJim Ingham                     if (!success)
196e16c50a1SJim Ingham                         error.SetErrorStringWithFormat("Invalid value for stop-on-continue: %s.\n", option_arg);
197e16c50a1SJim Ingham                     break;
198e16c50a1SJim Ingham                 default:
199e16c50a1SJim Ingham                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
200e16c50a1SJim Ingham                     break;
201e16c50a1SJim Ingham             }
202e16c50a1SJim Ingham 
203e16c50a1SJim Ingham             return error;
204e16c50a1SJim Ingham         }
205e16c50a1SJim Ingham 
206e16c50a1SJim Ingham         void
207f6b8b581SGreg Clayton         OptionParsingStarting ()
208e16c50a1SJim Ingham         {
209e16c50a1SJim Ingham             m_stop_on_error = true;
210e16c50a1SJim Ingham             m_stop_on_continue = true;
211e16c50a1SJim Ingham         }
212e16c50a1SJim Ingham 
213e0d378b3SGreg Clayton         const OptionDefinition*
214e16c50a1SJim Ingham         GetDefinitions ()
215e16c50a1SJim Ingham         {
216e16c50a1SJim Ingham             return g_option_table;
217e16c50a1SJim Ingham         }
218e16c50a1SJim Ingham 
219e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
220e16c50a1SJim Ingham 
221e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
222e16c50a1SJim Ingham 
223e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
224e16c50a1SJim Ingham 
225e16c50a1SJim Ingham         bool m_stop_on_error;
226e16c50a1SJim Ingham         bool m_stop_on_continue;
227e16c50a1SJim Ingham     };
228e16c50a1SJim Ingham 
229e16c50a1SJim Ingham     CommandOptions m_options;
230e16c50a1SJim Ingham 
231e16c50a1SJim Ingham     virtual Options *
232e16c50a1SJim Ingham     GetOptions ()
233e16c50a1SJim Ingham     {
234e16c50a1SJim Ingham         return &m_options;
235e16c50a1SJim Ingham     }
236e16c50a1SJim Ingham 
237ebc09c36SJim Ingham public:
238a7015092SGreg Clayton     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
239a7015092SGreg Clayton         CommandObject (interpreter,
2400e5e5a79SGreg Clayton                        "command source",
241e3d26315SCaroline Tice                        "Read in debugger commands from the file <filename> and execute them.",
242eb0103f2SGreg Clayton                        NULL),
243eb0103f2SGreg Clayton         m_options (interpreter)
244ebc09c36SJim Ingham     {
245405fe67fSCaroline Tice         CommandArgumentEntry arg;
246405fe67fSCaroline Tice         CommandArgumentData file_arg;
247405fe67fSCaroline Tice 
248405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
249405fe67fSCaroline Tice         file_arg.arg_type = eArgTypeFilename;
250405fe67fSCaroline Tice         file_arg.arg_repetition = eArgRepeatPlain;
251405fe67fSCaroline Tice 
252405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
253405fe67fSCaroline Tice         arg.push_back (file_arg);
254405fe67fSCaroline Tice 
255405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
256405fe67fSCaroline Tice         m_arguments.push_back (arg);
257ebc09c36SJim Ingham     }
258ebc09c36SJim Ingham 
259ebc09c36SJim Ingham     ~CommandObjectCommandsSource ()
260ebc09c36SJim Ingham     {
261ebc09c36SJim Ingham     }
262ebc09c36SJim Ingham 
263ebc09c36SJim Ingham     bool
264ebc09c36SJim Ingham     Execute
265ebc09c36SJim Ingham     (
266ebc09c36SJim Ingham         Args& args,
267ebc09c36SJim Ingham         CommandReturnObject &result
268ebc09c36SJim Ingham     )
269ebc09c36SJim Ingham     {
270ebc09c36SJim Ingham         const int argc = args.GetArgumentCount();
271ebc09c36SJim Ingham         if (argc == 1)
272ebc09c36SJim Ingham         {
273ebc09c36SJim Ingham             const char *filename = args.GetArgumentAtIndex(0);
274ebc09c36SJim Ingham 
275ebc09c36SJim Ingham             result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
276ebc09c36SJim Ingham 
2771ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
278e16c50a1SJim Ingham             ExecutionContext *exe_ctx = NULL;  // Just use the default context.
279e16c50a1SJim Ingham             bool echo_commands    = true;
280e16c50a1SJim Ingham             bool print_results    = true;
281ebc09c36SJim Ingham 
282e16c50a1SJim Ingham             m_interpreter.HandleCommandsFromFile (cmd_file,
283e16c50a1SJim Ingham                                                   exe_ctx,
284e16c50a1SJim Ingham                                                   m_options.m_stop_on_continue,
285e16c50a1SJim Ingham                                                   m_options.m_stop_on_error,
286e16c50a1SJim Ingham                                                   echo_commands,
287e16c50a1SJim Ingham                                                   print_results,
288e16c50a1SJim Ingham                                                   result);
289ebc09c36SJim Ingham         }
290ebc09c36SJim Ingham         else
291ebc09c36SJim Ingham         {
292ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
293ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
294ebc09c36SJim Ingham         }
295ebc09c36SJim Ingham         return result.Succeeded();
296ebc09c36SJim Ingham 
297ebc09c36SJim Ingham     }
298ebc09c36SJim Ingham };
299ebc09c36SJim Ingham 
300e0d378b3SGreg Clayton OptionDefinition
301e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
302e16c50a1SJim Ingham {
303e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
304e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
305e16c50a1SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
306e16c50a1SJim Ingham };
307e16c50a1SJim Ingham 
308ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
309ebc09c36SJim Ingham //-------------------------------------------------------------------------
310ebc09c36SJim Ingham // CommandObjectCommandsAlias
311ebc09c36SJim Ingham //-------------------------------------------------------------------------
312ebc09c36SJim Ingham 
313be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
314be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
315223383edSEnrico Granata                                                      "def my_command_impl(debugger, args, result, dict):";
316be93a35aSEnrico Granata 
317be93a35aSEnrico Granata 
318ebc09c36SJim Ingham class CommandObjectCommandsAlias : public CommandObject
319ebc09c36SJim Ingham {
320be93a35aSEnrico Granata 
321be93a35aSEnrico Granata 
322ebc09c36SJim Ingham public:
323a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
324a7015092SGreg Clayton         CommandObject (interpreter,
3250e5e5a79SGreg Clayton                        "command alias",
326e3d26315SCaroline Tice                        "Allow users to define their own debugger command abbreviations.",
327405fe67fSCaroline Tice                        NULL)
328ebc09c36SJim Ingham     {
329ebc09c36SJim Ingham         SetHelpLong(
330ebc09c36SJim Ingham     "'alias' allows the user to create a short-cut or abbreviation for long \n\
331ebc09c36SJim Ingham     commands, multi-word commands, and commands that take particular options. \n\
332ebc09c36SJim Ingham     Below are some simple examples of how one might use the 'alias' command: \n\
33309799af6SCaroline Tice     \n    'commands alias sc script'           // Creates the abbreviation 'sc' for the 'script' \n\
334ebc09c36SJim Ingham                                          // command. \n\
33509799af6SCaroline Tice     'commands alias bp breakpoint'       // Creates the abbreviation 'bp' for the 'breakpoint' \n\
336ebc09c36SJim Ingham                                          // command.  Since breakpoint commands are two-word \n\
337ebc09c36SJim Ingham                                          // commands, the user will still need to enter the \n\
338ebc09c36SJim Ingham                                          // second word after 'bp', e.g. 'bp enable' or \n\
339ebc09c36SJim Ingham                                          // 'bp delete'. \n\
34009799af6SCaroline Tice     'commands alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
341ebc09c36SJim Ingham                                          // two-word command 'breakpoint list'. \n\
342ebc09c36SJim Ingham     \nAn alias can include some options for the command, with the values either \n\
343ebc09c36SJim Ingham     filled in at the time the alias is created, or specified as positional \n\
344ebc09c36SJim Ingham     arguments, to be filled in when the alias is invoked.  The following example \n\
345ebc09c36SJim Ingham     shows how to create aliases with options: \n\
346ebc09c36SJim Ingham     \n\
34709799af6SCaroline Tice     'commands alias bfl breakpoint set -f %1 -l %2' \n\
348ebc09c36SJim Ingham     \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
349ebc09c36SJim Ingham     options already part of the alias.  So if the user wants to set a breakpoint \n\
350ebc09c36SJim Ingham     by file and line without explicitly having to use the -f and -l options, the \n\
351ebc09c36SJim Ingham     user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \n\
352ebc09c36SJim Ingham     for the actual arguments that will be passed when the alias command is used. \n\
353ebc09c36SJim Ingham     The number in the placeholder refers to the position/order the actual value \n\
354ebc09c36SJim Ingham     occupies when the alias is used.  So all the occurrences of '%1' in the alias \n\
355ebc09c36SJim Ingham     will be replaced with the first argument, all the occurrences of '%2' in the \n\
356ebc09c36SJim Ingham     alias will be replaced with the second argument, and so on.  This also allows \n\
357ebc09c36SJim Ingham     actual arguments to be used multiple times within an alias (see 'process \n\
358ebc09c36SJim Ingham     launch' example below).  So in the 'bfl' case, the actual file value will be \n\
359ebc09c36SJim Ingham     filled in with the first argument following 'bfl' and the actual line number \n\
360ebc09c36SJim Ingham     value will be filled in with the second argument.  The user would use this \n\
361ebc09c36SJim Ingham     alias as follows: \n\
36209799af6SCaroline Tice     \n    (lldb)  commands alias bfl breakpoint set -f %1 -l %2 \n\
363ebc09c36SJim Ingham     <... some time later ...> \n\
36409799af6SCaroline Tice     (lldb)  bfl my-file.c 137 \n\
365ebc09c36SJim Ingham     \nThis would be the same as if the user had entered \n\
366ebc09c36SJim Ingham     'breakpoint set -f my-file.c -l 137'. \n\
367ebc09c36SJim Ingham     \nAnother example: \n\
36809799af6SCaroline Tice     \n    (lldb)  commands alias pltty  process launch -s -o %1 -e %1 \n\
36909799af6SCaroline Tice     (lldb)  pltty /dev/tty0 \n\
370ebc09c36SJim Ingham            // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
371ebc09c36SJim Ingham     \nIf the user always wanted to pass the same value to a particular option, the \n\
372ebc09c36SJim Ingham     alias could be defined with that value directly in the alias as a constant, \n\
373ebc09c36SJim Ingham     rather than using a positional placeholder: \n\
3740708e2c2SSean Callanan     \n    commands alias bl3  breakpoint set -f %1 -l 3  // Always sets a breakpoint on line \n\
375ebc09c36SJim Ingham                                                    // 3 of whatever file is indicated. \n");
376ebc09c36SJim Ingham 
377405fe67fSCaroline Tice         CommandArgumentEntry arg1;
378405fe67fSCaroline Tice         CommandArgumentEntry arg2;
379405fe67fSCaroline Tice         CommandArgumentEntry arg3;
380405fe67fSCaroline Tice         CommandArgumentData alias_arg;
381405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
382405fe67fSCaroline Tice         CommandArgumentData options_arg;
383405fe67fSCaroline Tice 
384405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
385405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
386405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
387405fe67fSCaroline Tice 
388405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
389405fe67fSCaroline Tice         arg1.push_back (alias_arg);
390405fe67fSCaroline Tice 
391405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
392405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
393405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
394405fe67fSCaroline Tice 
395405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
396405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
397405fe67fSCaroline Tice 
398405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
399405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
400405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
401405fe67fSCaroline Tice 
402405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
403405fe67fSCaroline Tice         arg3.push_back (options_arg);
404405fe67fSCaroline Tice 
405405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
406405fe67fSCaroline Tice         m_arguments.push_back (arg1);
407405fe67fSCaroline Tice         m_arguments.push_back (arg2);
408405fe67fSCaroline Tice         m_arguments.push_back (arg3);
409ebc09c36SJim Ingham     }
410ebc09c36SJim Ingham 
411ebc09c36SJim Ingham     ~CommandObjectCommandsAlias ()
412ebc09c36SJim Ingham     {
413ebc09c36SJim Ingham     }
414ebc09c36SJim Ingham 
415844d2303SCaroline Tice     bool
416844d2303SCaroline Tice     WantsRawCommandString ()
417844d2303SCaroline Tice     {
418844d2303SCaroline Tice         return true;
419844d2303SCaroline Tice     }
420844d2303SCaroline Tice 
421844d2303SCaroline Tice     bool
422844d2303SCaroline Tice     ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
423844d2303SCaroline Tice     {
424844d2303SCaroline Tice         Args args (raw_command_line);
425844d2303SCaroline Tice         std::string raw_command_string (raw_command_line);
426844d2303SCaroline Tice 
427844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
428844d2303SCaroline Tice 
429844d2303SCaroline Tice         if (argc < 2)
430844d2303SCaroline Tice         {
431844d2303SCaroline Tice             result.AppendError ("'alias' requires at least two arguments");
432844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
433844d2303SCaroline Tice             return false;
434844d2303SCaroline Tice         }
435844d2303SCaroline Tice 
436844d2303SCaroline Tice         // Get the alias command.
437844d2303SCaroline Tice 
438844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
439844d2303SCaroline Tice 
440844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
441844d2303SCaroline Tice         // does the stripping itself.
442844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
443844d2303SCaroline Tice         if (pos == 0)
444844d2303SCaroline Tice         {
445844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
446844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
447844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
448844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
449844d2303SCaroline Tice         }
450844d2303SCaroline Tice         else
451844d2303SCaroline Tice         {
452844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
453844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
454844d2303SCaroline Tice             return false;
455844d2303SCaroline Tice         }
456844d2303SCaroline Tice 
457844d2303SCaroline Tice 
458844d2303SCaroline Tice         // Verify that the command is alias-able.
459844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
460844d2303SCaroline Tice         {
461844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
462844d2303SCaroline Tice                                           alias_command.c_str());
463844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
464844d2303SCaroline Tice             return false;
465844d2303SCaroline Tice         }
466844d2303SCaroline Tice 
467844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
468844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
469844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
470844d2303SCaroline Tice 
471844d2303SCaroline Tice         if (!cmd_obj)
472844d2303SCaroline Tice         {
473844d2303SCaroline Tice             result.AppendErrorWithFormat ("Invalid command given to 'alias'. '%s' does not begin with a valid command."
474844d2303SCaroline Tice                                           "  No alias created.", raw_command_string.c_str());
475844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
476844d2303SCaroline Tice             return false;
477844d2303SCaroline Tice         }
478844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
479844d2303SCaroline Tice         {
480844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
481844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
482844d2303SCaroline Tice             return Execute (args, result);
483844d2303SCaroline Tice         }
484844d2303SCaroline Tice         else
485844d2303SCaroline Tice         {
486844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
487844d2303SCaroline Tice 
488844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
489844d2303SCaroline Tice             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
490844d2303SCaroline Tice 
491ca90c47eSCaroline Tice             CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
492844d2303SCaroline Tice 
493ca90c47eSCaroline Tice             if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
494844d2303SCaroline Tice             {
495844d2303SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
496ca90c47eSCaroline Tice                 result.SetStatus (eReturnStatusFailed);
497844d2303SCaroline Tice                 return false;
498844d2303SCaroline Tice             }
499844d2303SCaroline Tice 
500844d2303SCaroline Tice             // Create the alias
501844d2303SCaroline Tice             if (m_interpreter.AliasExists (alias_command.c_str())
502844d2303SCaroline Tice                 || m_interpreter.UserCommandExists (alias_command.c_str()))
503844d2303SCaroline Tice             {
504844d2303SCaroline Tice                 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
505844d2303SCaroline Tice                 if (temp_option_arg_sp.get())
506844d2303SCaroline Tice                 {
507844d2303SCaroline Tice                     if (option_arg_vector->size() == 0)
508844d2303SCaroline Tice                         m_interpreter.RemoveAliasOptions (alias_command.c_str());
509844d2303SCaroline Tice                 }
510844d2303SCaroline Tice                 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
511844d2303SCaroline Tice                                                 alias_command.c_str());
512844d2303SCaroline Tice             }
513844d2303SCaroline Tice 
514472362e6SCaroline Tice             if (cmd_obj_sp)
515472362e6SCaroline Tice             {
516844d2303SCaroline Tice                 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
517844d2303SCaroline Tice                 if (option_arg_vector->size() > 0)
518844d2303SCaroline Tice                     m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
519844d2303SCaroline Tice                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
520844d2303SCaroline Tice             }
521472362e6SCaroline Tice             else
522472362e6SCaroline Tice             {
523472362e6SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
524472362e6SCaroline Tice                 result.SetStatus (eReturnStatusFailed);
525472362e6SCaroline Tice             }
526472362e6SCaroline Tice         }
527844d2303SCaroline Tice         return result.Succeeded();
528844d2303SCaroline Tice     }
529ebc09c36SJim Ingham 
530ebc09c36SJim Ingham     bool
531ebc09c36SJim Ingham     Execute
532ebc09c36SJim Ingham     (
533ebc09c36SJim Ingham         Args& args,
534ebc09c36SJim Ingham         CommandReturnObject &result
535ebc09c36SJim Ingham     )
536ebc09c36SJim Ingham     {
537867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
538ebc09c36SJim Ingham 
539ebc09c36SJim Ingham         if (argc < 2)
540ebc09c36SJim Ingham         {
541ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
542ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
543ebc09c36SJim Ingham             return false;
544ebc09c36SJim Ingham         }
545ebc09c36SJim Ingham 
546ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
547ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
548ebc09c36SJim Ingham 
549ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
550ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
551ebc09c36SJim Ingham 
552ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
553ebc09c36SJim Ingham 
554a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
555ebc09c36SJim Ingham         {
556ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
557ebc09c36SJim Ingham                                          alias_command.c_str());
558ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
559ebc09c36SJim Ingham         }
560ebc09c36SJim Ingham         else
561ebc09c36SJim Ingham         {
562a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
563ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
564ebc09c36SJim Ingham              bool use_subcommand = false;
565ebc09c36SJim Ingham              if (command_obj_sp.get())
566ebc09c36SJim Ingham              {
567ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
568c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
569ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
570ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
571ebc09c36SJim Ingham 
572844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
573ebc09c36SJim Ingham                  {
574ebc09c36SJim Ingham                      if (argc >= 3)
575ebc09c36SJim Ingham                      {
576ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
577ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
578ebc09c36SJim Ingham                          subcommand_obj_sp =
579ebc09c36SJim Ingham                                            (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
580ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
581ebc09c36SJim Ingham                          {
582ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
583ebc09c36SJim Ingham                              use_subcommand = true;
584ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
585844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
586ebc09c36SJim Ingham                          }
587ebc09c36SJim Ingham                          else
588ebc09c36SJim Ingham                          {
589f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
590f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
591f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
592ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
593ebc09c36SJim Ingham                              return false;
594ebc09c36SJim Ingham                          }
595ebc09c36SJim Ingham                      }
596ebc09c36SJim Ingham                  }
597ebc09c36SJim Ingham 
598ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
599ebc09c36SJim Ingham 
600ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
601ebc09c36SJim Ingham                  {
602ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
603ebc09c36SJim Ingham                     if (use_subcommand)
604ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
605ca90c47eSCaroline Tice 
606ca90c47eSCaroline Tice                     std::string args_string;
607ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
608ca90c47eSCaroline Tice 
609ca90c47eSCaroline Tice                     if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
610ebc09c36SJim Ingham                     {
611ca90c47eSCaroline Tice                         result.AppendError ("Unable to create requested alias.\n");
612ca90c47eSCaroline Tice                         result.SetStatus (eReturnStatusFailed);
613e7941795SCaroline Tice                         return false;
614867b185dSCaroline Tice                     }
615867b185dSCaroline Tice                  }
616867b185dSCaroline Tice 
617ebc09c36SJim Ingham                  // Create the alias.
618ebc09c36SJim Ingham 
619a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
620a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
621ebc09c36SJim Ingham                  {
622a7015092SGreg Clayton                      OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
623ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
624ebc09c36SJim Ingham                      {
625ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
626a7015092SGreg Clayton                              m_interpreter.RemoveAliasOptions (alias_command.c_str());
627ebc09c36SJim Ingham                      }
628ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
629ebc09c36SJim Ingham                                                      alias_command.c_str());
630ebc09c36SJim Ingham                  }
631ebc09c36SJim Ingham 
632ebc09c36SJim Ingham                  if (use_subcommand)
633a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
634ebc09c36SJim Ingham                  else
635a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
636ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
637a7015092SGreg Clayton                      m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
638ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
639ebc09c36SJim Ingham              }
640ebc09c36SJim Ingham              else
641ebc09c36SJim Ingham              {
642ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
643ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
644e7941795SCaroline Tice                  return false;
645ebc09c36SJim Ingham              }
646ebc09c36SJim Ingham         }
647ebc09c36SJim Ingham 
648ebc09c36SJim Ingham         return result.Succeeded();
649ebc09c36SJim Ingham     }
650ebc09c36SJim Ingham };
651ebc09c36SJim Ingham 
652ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
653ebc09c36SJim Ingham //-------------------------------------------------------------------------
654ebc09c36SJim Ingham // CommandObjectCommandsUnalias
655ebc09c36SJim Ingham //-------------------------------------------------------------------------
656ebc09c36SJim Ingham 
657ebc09c36SJim Ingham class CommandObjectCommandsUnalias : public CommandObject
658ebc09c36SJim Ingham {
659ebc09c36SJim Ingham public:
660a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
661a7015092SGreg Clayton         CommandObject (interpreter,
6620e5e5a79SGreg Clayton                        "command unalias",
66386ddae50SCaroline Tice                        "Allow the user to remove/delete a user-defined command abbreviation.",
664405fe67fSCaroline Tice                        NULL)
665ebc09c36SJim Ingham     {
666405fe67fSCaroline Tice         CommandArgumentEntry arg;
667405fe67fSCaroline Tice         CommandArgumentData alias_arg;
668405fe67fSCaroline Tice 
669405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
670405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
671405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
672405fe67fSCaroline Tice 
673405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
674405fe67fSCaroline Tice         arg.push_back (alias_arg);
675405fe67fSCaroline Tice 
676405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
677405fe67fSCaroline Tice         m_arguments.push_back (arg);
678ebc09c36SJim Ingham     }
679ebc09c36SJim Ingham 
680ebc09c36SJim Ingham     ~CommandObjectCommandsUnalias()
681ebc09c36SJim Ingham     {
682ebc09c36SJim Ingham     }
683ebc09c36SJim Ingham 
684ebc09c36SJim Ingham 
685ebc09c36SJim Ingham     bool
686ebc09c36SJim Ingham     Execute
687ebc09c36SJim Ingham     (
688ebc09c36SJim Ingham         Args& args,
689ebc09c36SJim Ingham         CommandReturnObject &result
690ebc09c36SJim Ingham     )
691ebc09c36SJim Ingham     {
692ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
693ebc09c36SJim Ingham         CommandObject *cmd_obj;
694ebc09c36SJim Ingham 
695ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
696ebc09c36SJim Ingham         {
697ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
698a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
699ebc09c36SJim Ingham             if (cmd_obj)
700ebc09c36SJim Ingham             {
701a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
702ebc09c36SJim Ingham                 {
703ebc09c36SJim Ingham                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
704ebc09c36SJim Ingham                                                   command_name);
705ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
706ebc09c36SJim Ingham                 }
707ebc09c36SJim Ingham                 else
708ebc09c36SJim Ingham                 {
709ebc09c36SJim Ingham 
710a7015092SGreg Clayton                     if (m_interpreter.RemoveAlias (command_name) == false)
711ebc09c36SJim Ingham                     {
712a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
713ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
714ebc09c36SJim Ingham                                                           command_name);
715ebc09c36SJim Ingham                         else
716ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
717ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
718ebc09c36SJim Ingham                     }
719ebc09c36SJim Ingham                     else
720ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
721ebc09c36SJim Ingham                 }
722ebc09c36SJim Ingham             }
723ebc09c36SJim Ingham             else
724ebc09c36SJim Ingham             {
725ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
726ebc09c36SJim Ingham                                               "current list of commands.\n",
727ebc09c36SJim Ingham                                              command_name);
728ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
729ebc09c36SJim Ingham             }
730ebc09c36SJim Ingham         }
731ebc09c36SJim Ingham         else
732ebc09c36SJim Ingham         {
733ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
734ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
735ebc09c36SJim Ingham         }
736ebc09c36SJim Ingham 
737ebc09c36SJim Ingham         return result.Succeeded();
738ebc09c36SJim Ingham     }
739ebc09c36SJim Ingham };
740ebc09c36SJim Ingham 
741de164aaaSGreg Clayton #pragma mark CommandObjectCommandsAddRegex
742de164aaaSGreg Clayton //-------------------------------------------------------------------------
743de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
744de164aaaSGreg Clayton //-------------------------------------------------------------------------
745de164aaaSGreg Clayton 
746de164aaaSGreg Clayton class CommandObjectCommandsAddRegex : public CommandObject
747de164aaaSGreg Clayton {
748de164aaaSGreg Clayton public:
749de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
750de164aaaSGreg Clayton         CommandObject (interpreter,
7510e5e5a79SGreg Clayton                        "command regex",
752de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
7530e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
754de164aaaSGreg Clayton         m_options (interpreter)
755de164aaaSGreg Clayton     {
7560e5e5a79SGreg Clayton         SetHelpLong(
7570e5e5a79SGreg Clayton "This command allows the user to create powerful regular expression commands\n"
7580e5e5a79SGreg Clayton "with substitutions. The regular expressions and substitutions are specified\n"
7590e5e5a79SGreg Clayton "using the regular exression substitution format of:\n"
7600e5e5a79SGreg Clayton "\n"
7610e5e5a79SGreg Clayton "    s/<regex>/<subst>/\n"
7620e5e5a79SGreg Clayton "\n"
7630e5e5a79SGreg Clayton "<regex> is a regular expression that can use parenthesis to capture regular\n"
7640e5e5a79SGreg Clayton "expression input and substitute the captured matches in the output using %1\n"
7650e5e5a79SGreg Clayton "for the first match, %2 for the second, and so on.\n"
7660e5e5a79SGreg Clayton "\n"
7670e5e5a79SGreg Clayton "The regular expressions can all be specified on the command line if more than\n"
7680e5e5a79SGreg Clayton "one argument is provided. If just the command name is provided on the command\n"
7690e5e5a79SGreg Clayton "line, then the regular expressions and substitutions can be entered on separate\n"
7700e5e5a79SGreg Clayton " lines, followed by an empty line to terminate the command definition.\n"
7710e5e5a79SGreg Clayton "\n"
7720e5e5a79SGreg Clayton "EXAMPLES\n"
7730e5e5a79SGreg Clayton "\n"
7740e5e5a79SGreg Clayton "The following example with define a regular expression command named 'f' that\n"
7750e5e5a79SGreg Clayton "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
7760e5e5a79SGreg Clayton "a number follows 'f':\n"
7770e5e5a79SGreg Clayton "(lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
7780e5e5a79SGreg Clayton                     );
779de164aaaSGreg Clayton     }
780de164aaaSGreg Clayton 
781de164aaaSGreg Clayton     ~CommandObjectCommandsAddRegex()
782de164aaaSGreg Clayton     {
783de164aaaSGreg Clayton     }
784de164aaaSGreg Clayton 
785de164aaaSGreg Clayton 
786de164aaaSGreg Clayton     bool
787de164aaaSGreg Clayton     Execute (Args& args, CommandReturnObject &result)
788de164aaaSGreg Clayton     {
7890e5e5a79SGreg Clayton         const size_t argc = args.GetArgumentCount();
7900e5e5a79SGreg Clayton         if (argc == 0)
791de164aaaSGreg Clayton         {
7920e5e5a79SGreg Clayton             result.AppendError ("usage: 'commands regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
7930e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
7940e5e5a79SGreg Clayton         }
7950e5e5a79SGreg Clayton         else
7960e5e5a79SGreg Clayton         {
7970e5e5a79SGreg Clayton             Error error;
798de164aaaSGreg Clayton             const char *name = args.GetArgumentAtIndex(0);
799de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
800de164aaaSGreg Clayton                                                                  name,
801de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
802de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
803de164aaaSGreg Clayton                                                                  10));
8040e5e5a79SGreg Clayton 
8050e5e5a79SGreg Clayton             if (argc == 1)
8060e5e5a79SGreg Clayton             {
8070e5e5a79SGreg Clayton                 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
808de164aaaSGreg Clayton                 if (reader_sp)
809de164aaaSGreg Clayton                 {
8100e5e5a79SGreg Clayton                     error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
811de164aaaSGreg Clayton                                                   this,                         // baton
812de164aaaSGreg Clayton                                                   eInputReaderGranularityLine,  // token size, to pass to callback function
8130e5e5a79SGreg Clayton                                                   NULL,                         // end token
814de164aaaSGreg Clayton                                                   "> ",                         // prompt
8150e5e5a79SGreg Clayton                                                   true);                        // echo input
8160e5e5a79SGreg Clayton                     if (error.Success())
817de164aaaSGreg Clayton                     {
818de164aaaSGreg Clayton                         m_interpreter.GetDebugger().PushInputReader (reader_sp);
819de164aaaSGreg Clayton                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
8200e5e5a79SGreg Clayton                         return true;
821de164aaaSGreg Clayton                     }
822de164aaaSGreg Clayton                 }
823de164aaaSGreg Clayton             }
824de164aaaSGreg Clayton             else
825de164aaaSGreg Clayton             {
8260e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
8270e5e5a79SGreg Clayton                 {
8280e5e5a79SGreg Clayton                     llvm::StringRef arg_strref (args.GetArgumentAtIndex(arg_idx));
8290e5e5a79SGreg Clayton                     error = AppendRegexSubstitution (arg_strref);
8300e5e5a79SGreg Clayton                     if (error.Fail())
8310e5e5a79SGreg Clayton                         break;
8320e5e5a79SGreg Clayton                 }
8330e5e5a79SGreg Clayton 
8340e5e5a79SGreg Clayton                 if (error.Success())
8350e5e5a79SGreg Clayton                 {
8360e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
8370e5e5a79SGreg Clayton                 }
8380e5e5a79SGreg Clayton             }
8390e5e5a79SGreg Clayton             if (error.Fail())
8400e5e5a79SGreg Clayton             {
8410e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
842de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
843de164aaaSGreg Clayton             }
8440e5e5a79SGreg Clayton         }
8450e5e5a79SGreg Clayton 
846de164aaaSGreg Clayton         return result.Succeeded();
847de164aaaSGreg Clayton     }
848de164aaaSGreg Clayton 
8490e5e5a79SGreg Clayton     Error
8500e5e5a79SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed)
851de164aaaSGreg Clayton     {
8520e5e5a79SGreg Clayton         Error error;
8530e5e5a79SGreg Clayton 
8540e5e5a79SGreg Clayton         if (m_regex_cmd_ap.get() == NULL)
855de164aaaSGreg Clayton         {
8560e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
8570e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8580e5e5a79SGreg Clayton                                            regex_sed.data());
8590e5e5a79SGreg Clayton             return error;
860de164aaaSGreg Clayton         }
8610e5e5a79SGreg Clayton 
8620e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
8630e5e5a79SGreg Clayton 
8640e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
8650e5e5a79SGreg Clayton         {
8660e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
8670e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8680e5e5a79SGreg Clayton                                            regex_sed.data());
8690e5e5a79SGreg Clayton             return error;
8700e5e5a79SGreg Clayton         }
8710e5e5a79SGreg Clayton 
8720e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
8730e5e5a79SGreg Clayton         {
8740e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
8750e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8760e5e5a79SGreg Clayton                                            regex_sed.data());
8770e5e5a79SGreg Clayton             return error;
8780e5e5a79SGreg Clayton         }
8790e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
8800e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
8810e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
8820e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
8830e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
8840e5e5a79SGreg Clayton 
8850e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
8860e5e5a79SGreg Clayton         {
8870e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
8880e5e5a79SGreg Clayton                                            separator_char,
8890e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
8900e5e5a79SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1));
8910e5e5a79SGreg Clayton             return error;
8920e5e5a79SGreg Clayton         }
8930e5e5a79SGreg Clayton 
8940e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
8950e5e5a79SGreg Clayton 
8960e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
8970e5e5a79SGreg Clayton         {
8980e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
8990e5e5a79SGreg Clayton                                            separator_char,
9000e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
9010e5e5a79SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1));
9020e5e5a79SGreg Clayton             return error;
9030e5e5a79SGreg Clayton         }
9040e5e5a79SGreg Clayton 
9050e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
9060e5e5a79SGreg Clayton         {
9070e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
9080e5e5a79SGreg Clayton             // separator char
9090e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
9100e5e5a79SGreg Clayton             {
9110e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
9120e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
9130e5e5a79SGreg Clayton                                                regex_sed.data(),
9140e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
9150e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
9160e5e5a79SGreg Clayton                 return error;
9170e5e5a79SGreg Clayton             }
9180e5e5a79SGreg Clayton 
9190e5e5a79SGreg Clayton         }
9200e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
9210e5e5a79SGreg Clayton         {
9220e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9230e5e5a79SGreg Clayton                                            separator_char,
9240e5e5a79SGreg Clayton                                            separator_char,
9250e5e5a79SGreg Clayton                                            separator_char,
9260e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9270e5e5a79SGreg Clayton                                            regex_sed.data());
9280e5e5a79SGreg Clayton             return error;
9290e5e5a79SGreg Clayton         }
9300e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
9310e5e5a79SGreg Clayton         {
9320e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9330e5e5a79SGreg Clayton                                            separator_char,
9340e5e5a79SGreg Clayton                                            separator_char,
9350e5e5a79SGreg Clayton                                            separator_char,
9360e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9370e5e5a79SGreg Clayton                                            regex_sed.data());
9380e5e5a79SGreg Clayton             return error;
9390e5e5a79SGreg Clayton         }
9400e5e5a79SGreg Clayton         std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
9410e5e5a79SGreg Clayton         std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
9420e5e5a79SGreg Clayton         m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
9430e5e5a79SGreg Clayton                                          subst.c_str());
9440e5e5a79SGreg Clayton         return error;
945de164aaaSGreg Clayton     }
946de164aaaSGreg Clayton 
947de164aaaSGreg Clayton     void
9480e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
949de164aaaSGreg Clayton     {
950de164aaaSGreg Clayton         if (m_regex_cmd_ap.get())
951de164aaaSGreg Clayton         {
952de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
953de164aaaSGreg Clayton             {
954de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
955de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
956de164aaaSGreg Clayton             }
957de164aaaSGreg Clayton         }
958de164aaaSGreg Clayton     }
959de164aaaSGreg Clayton 
9600e5e5a79SGreg Clayton     void
9610e5e5a79SGreg Clayton     InputReaderDidCancel()
9620e5e5a79SGreg Clayton     {
9630e5e5a79SGreg Clayton         m_regex_cmd_ap.reset();
9640e5e5a79SGreg Clayton     }
9650e5e5a79SGreg Clayton 
966de164aaaSGreg Clayton     static size_t
967de164aaaSGreg Clayton     InputReaderCallback (void *baton,
968de164aaaSGreg Clayton                          InputReader &reader,
969de164aaaSGreg Clayton                          lldb::InputReaderAction notification,
970de164aaaSGreg Clayton                          const char *bytes,
971de164aaaSGreg Clayton                          size_t bytes_len);
972de164aaaSGreg Clayton private:
973de164aaaSGreg Clayton     std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
974de164aaaSGreg Clayton 
975de164aaaSGreg Clayton      class CommandOptions : public Options
976de164aaaSGreg Clayton      {
977de164aaaSGreg Clayton      public:
978de164aaaSGreg Clayton 
979de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
980de164aaaSGreg Clayton             Options (interpreter)
981de164aaaSGreg Clayton          {
982de164aaaSGreg Clayton          }
983de164aaaSGreg Clayton 
984de164aaaSGreg Clayton          virtual
985de164aaaSGreg Clayton          ~CommandOptions (){}
986de164aaaSGreg Clayton 
987de164aaaSGreg Clayton          virtual Error
988de164aaaSGreg Clayton          SetOptionValue (uint32_t option_idx, const char *option_arg)
989de164aaaSGreg Clayton          {
990de164aaaSGreg Clayton              Error error;
991de164aaaSGreg Clayton              char short_option = (char) m_getopt_table[option_idx].val;
992de164aaaSGreg Clayton 
993de164aaaSGreg Clayton              switch (short_option)
994de164aaaSGreg Clayton              {
995de164aaaSGreg Clayton                  case 'h':
996de164aaaSGreg Clayton                      m_help.assign (option_arg);
997de164aaaSGreg Clayton                      break;
998de164aaaSGreg Clayton                  case 's':
999de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
1000de164aaaSGreg Clayton                      break;
1001de164aaaSGreg Clayton 
1002de164aaaSGreg Clayton                  default:
1003de164aaaSGreg Clayton                      error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1004de164aaaSGreg Clayton                      break;
1005de164aaaSGreg Clayton              }
1006de164aaaSGreg Clayton 
1007de164aaaSGreg Clayton              return error;
1008de164aaaSGreg Clayton          }
1009de164aaaSGreg Clayton 
1010de164aaaSGreg Clayton          void
1011de164aaaSGreg Clayton          OptionParsingStarting ()
1012de164aaaSGreg Clayton          {
1013de164aaaSGreg Clayton              m_help.clear();
1014de164aaaSGreg Clayton              m_syntax.clear();
1015de164aaaSGreg Clayton          }
1016de164aaaSGreg Clayton 
1017de164aaaSGreg Clayton          const OptionDefinition*
1018de164aaaSGreg Clayton          GetDefinitions ()
1019de164aaaSGreg Clayton          {
1020de164aaaSGreg Clayton              return g_option_table;
1021de164aaaSGreg Clayton          }
1022de164aaaSGreg Clayton 
1023de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1024de164aaaSGreg Clayton 
1025de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1026de164aaaSGreg Clayton 
1027de164aaaSGreg Clayton          const char *
1028de164aaaSGreg Clayton          GetHelp ()
1029de164aaaSGreg Clayton          {
1030de164aaaSGreg Clayton              if (m_help.empty())
1031de164aaaSGreg Clayton                  return NULL;
1032de164aaaSGreg Clayton              return m_help.c_str();
1033de164aaaSGreg Clayton          }
1034de164aaaSGreg Clayton          const char *
1035de164aaaSGreg Clayton          GetSyntax ()
1036de164aaaSGreg Clayton          {
1037de164aaaSGreg Clayton              if (m_syntax.empty())
1038de164aaaSGreg Clayton                  return NULL;
1039de164aaaSGreg Clayton              return m_syntax.c_str();
1040de164aaaSGreg Clayton          }
1041de164aaaSGreg Clayton          // Instance variables to hold the values for command options.
1042de164aaaSGreg Clayton      protected:
1043de164aaaSGreg Clayton          std::string m_help;
1044de164aaaSGreg Clayton          std::string m_syntax;
1045de164aaaSGreg Clayton      };
1046de164aaaSGreg Clayton 
1047de164aaaSGreg Clayton      CommandOptions m_options;
1048de164aaaSGreg Clayton 
1049de164aaaSGreg Clayton      virtual Options *
1050de164aaaSGreg Clayton      GetOptions ()
1051de164aaaSGreg Clayton      {
1052de164aaaSGreg Clayton          return &m_options;
1053de164aaaSGreg Clayton      }
1054de164aaaSGreg Clayton 
1055de164aaaSGreg Clayton };
1056de164aaaSGreg Clayton 
1057de164aaaSGreg Clayton size_t
1058de164aaaSGreg Clayton CommandObjectCommandsAddRegex::InputReaderCallback (void *baton,
1059de164aaaSGreg Clayton                                                     InputReader &reader,
1060de164aaaSGreg Clayton                                                     lldb::InputReaderAction notification,
1061de164aaaSGreg Clayton                                                     const char *bytes,
1062de164aaaSGreg Clayton                                                     size_t bytes_len)
1063de164aaaSGreg Clayton {
1064de164aaaSGreg Clayton     CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
1065d61c10bcSCaroline Tice     bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
1066de164aaaSGreg Clayton 
1067de164aaaSGreg Clayton     switch (notification)
1068de164aaaSGreg Clayton     {
1069de164aaaSGreg Clayton         case eInputReaderActivate:
1070d61c10bcSCaroline Tice             if (!batch_mode)
107115356e7fSCaroline Tice             {
107215356e7fSCaroline Tice                 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
107315356e7fSCaroline Tice                 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
107415356e7fSCaroline Tice                 out_stream->Flush();
107515356e7fSCaroline Tice             }
1076de164aaaSGreg Clayton             break;
1077de164aaaSGreg Clayton         case eInputReaderReactivate:
1078de164aaaSGreg Clayton             break;
1079de164aaaSGreg Clayton 
1080de164aaaSGreg Clayton         case eInputReaderDeactivate:
1081de164aaaSGreg Clayton             break;
1082de164aaaSGreg Clayton 
1083969ed3d1SCaroline Tice         case eInputReaderAsynchronousOutputWritten:
1084969ed3d1SCaroline Tice             break;
1085969ed3d1SCaroline Tice 
1086de164aaaSGreg Clayton         case eInputReaderGotToken:
10870e5e5a79SGreg Clayton             while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
10880e5e5a79SGreg Clayton                 --bytes_len;
1089de164aaaSGreg Clayton             if (bytes_len == 0)
1090de164aaaSGreg Clayton                 reader.SetIsDone(true);
1091de164aaaSGreg Clayton             else if (bytes)
1092de164aaaSGreg Clayton             {
10930e5e5a79SGreg Clayton                 llvm::StringRef bytes_strref (bytes, bytes_len);
10940e5e5a79SGreg Clayton                 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
10950e5e5a79SGreg Clayton                 if (error.Fail())
1096de164aaaSGreg Clayton                 {
1097d61c10bcSCaroline Tice                     if (!batch_mode)
1098d61c10bcSCaroline Tice                     {
109915356e7fSCaroline Tice                         StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
110015356e7fSCaroline Tice                         out_stream->Printf("error: %s\n", error.AsCString());
110115356e7fSCaroline Tice                         out_stream->Flush();
1102d61c10bcSCaroline Tice                     }
11030e5e5a79SGreg Clayton                     add_regex_cmd->InputReaderDidCancel ();
11040e5e5a79SGreg Clayton                     reader.SetIsDone (true);
1105de164aaaSGreg Clayton                 }
1106de164aaaSGreg Clayton             }
1107de164aaaSGreg Clayton             break;
1108de164aaaSGreg Clayton 
1109de164aaaSGreg Clayton         case eInputReaderInterrupt:
111015356e7fSCaroline Tice             {
1111de164aaaSGreg Clayton                 reader.SetIsDone (true);
1112d61c10bcSCaroline Tice                 if (!batch_mode)
1113d61c10bcSCaroline Tice                 {
111415356e7fSCaroline Tice                     StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
111515356e7fSCaroline Tice                     out_stream->PutCString("Regular expression command creations was cancelled.\n");
111615356e7fSCaroline Tice                     out_stream->Flush();
1117d61c10bcSCaroline Tice                 }
11180e5e5a79SGreg Clayton                 add_regex_cmd->InputReaderDidCancel ();
111915356e7fSCaroline Tice             }
1120de164aaaSGreg Clayton             break;
1121de164aaaSGreg Clayton 
1122de164aaaSGreg Clayton         case eInputReaderEndOfFile:
1123de164aaaSGreg Clayton             reader.SetIsDone (true);
1124de164aaaSGreg Clayton             break;
1125de164aaaSGreg Clayton 
1126de164aaaSGreg Clayton         case eInputReaderDone:
11270e5e5a79SGreg Clayton             add_regex_cmd->AddRegexCommandToInterpreter();
1128de164aaaSGreg Clayton             break;
1129de164aaaSGreg Clayton     }
1130de164aaaSGreg Clayton 
1131de164aaaSGreg Clayton     return bytes_len;
1132de164aaaSGreg Clayton }
1133de164aaaSGreg Clayton 
1134de164aaaSGreg Clayton 
1135de164aaaSGreg Clayton OptionDefinition
1136de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1137de164aaaSGreg Clayton {
1138de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "help"  , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1139de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1140de164aaaSGreg Clayton { 0             , false,  NULL   , 0  , 0                , NULL, 0, eArgTypeNone, NULL }
1141de164aaaSGreg Clayton };
1142de164aaaSGreg Clayton 
1143de164aaaSGreg Clayton 
1144223383edSEnrico Granata class CommandObjectPythonFunction : public CommandObject
1145223383edSEnrico Granata {
1146223383edSEnrico Granata private:
1147223383edSEnrico Granata     std::string m_function_name;
1148223383edSEnrico Granata 
1149223383edSEnrico Granata public:
1150223383edSEnrico Granata 
1151223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1152223383edSEnrico Granata                                  std::string name,
1153223383edSEnrico Granata                                  std::string funct) :
1154223383edSEnrico Granata     CommandObject (interpreter,
1155223383edSEnrico Granata                    name.c_str(),
1156223383edSEnrico Granata                    (std::string("Run Python function ") + funct).c_str(),
1157223383edSEnrico Granata                    NULL),
1158223383edSEnrico Granata     m_function_name(funct)
1159223383edSEnrico Granata     {
1160*99f0b8f9SEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1161*99f0b8f9SEnrico Granata         if (scripter)
1162*99f0b8f9SEnrico Granata         {
1163*99f0b8f9SEnrico Granata             std::string docstring = scripter->GetDocumentationForItem(funct.c_str());
1164*99f0b8f9SEnrico Granata             if (!docstring.empty())
1165*99f0b8f9SEnrico Granata                 SetHelpLong(docstring);
1166*99f0b8f9SEnrico Granata         }
1167223383edSEnrico Granata     }
1168223383edSEnrico Granata 
1169223383edSEnrico Granata     virtual
1170223383edSEnrico Granata     ~CommandObjectPythonFunction ()
1171223383edSEnrico Granata     {
1172223383edSEnrico Granata     }
1173223383edSEnrico Granata 
1174223383edSEnrico Granata     virtual bool
1175223383edSEnrico Granata     ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
1176223383edSEnrico Granata     {
1177223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1178223383edSEnrico Granata 
1179223383edSEnrico Granata         Error error;
1180223383edSEnrico Granata 
1181223383edSEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1182223383edSEnrico Granata                                                          raw_command_line,
1183223383edSEnrico Granata                                                          result,
1184223383edSEnrico Granata                                                          error) == false)
1185223383edSEnrico Granata         {
1186223383edSEnrico Granata             result.AppendError(error.AsCString());
1187223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1188223383edSEnrico Granata         }
1189223383edSEnrico Granata         else
1190223383edSEnrico Granata             result.SetStatus(eReturnStatusSuccessFinishNoResult);
1191223383edSEnrico Granata 
1192223383edSEnrico Granata         return result.Succeeded();
1193223383edSEnrico Granata     }
1194223383edSEnrico Granata 
1195223383edSEnrico Granata     virtual bool
1196223383edSEnrico Granata     WantsRawCommandString ()
1197223383edSEnrico Granata     {
1198223383edSEnrico Granata         return true;
1199223383edSEnrico Granata     }
1200223383edSEnrico Granata 
1201223383edSEnrico Granata     bool
1202223383edSEnrico Granata     Execute (Args& command,
1203223383edSEnrico Granata              CommandReturnObject &result)
1204223383edSEnrico Granata     {
1205223383edSEnrico Granata         std::string cmd_string;
1206223383edSEnrico Granata         command.GetCommandString(cmd_string);
1207223383edSEnrico Granata         return ExecuteRawCommandString(cmd_string.c_str(), result);
1208223383edSEnrico Granata     }
1209223383edSEnrico Granata 
1210223383edSEnrico Granata     virtual bool
1211223383edSEnrico Granata     IsRemovable() { return true; }
1212223383edSEnrico Granata 
1213223383edSEnrico Granata };
1214223383edSEnrico Granata 
1215223383edSEnrico Granata 
1216223383edSEnrico Granata //-------------------------------------------------------------------------
1217223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1218223383edSEnrico Granata //-------------------------------------------------------------------------
1219223383edSEnrico Granata 
1220223383edSEnrico Granata class CommandObjectCommandsScriptAdd : public CommandObject
1221223383edSEnrico Granata {
1222223383edSEnrico Granata private:
1223223383edSEnrico Granata 
1224223383edSEnrico Granata     class CommandOptions : public Options
1225223383edSEnrico Granata     {
1226223383edSEnrico Granata     public:
1227223383edSEnrico Granata 
1228223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
1229223383edSEnrico Granata         Options (interpreter)
1230223383edSEnrico Granata         {
1231223383edSEnrico Granata         }
1232223383edSEnrico Granata 
1233223383edSEnrico Granata         virtual
1234223383edSEnrico Granata         ~CommandOptions (){}
1235223383edSEnrico Granata 
1236223383edSEnrico Granata         virtual Error
1237223383edSEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
1238223383edSEnrico Granata         {
1239223383edSEnrico Granata             Error error;
1240223383edSEnrico Granata             char short_option = (char) m_getopt_table[option_idx].val;
1241223383edSEnrico Granata 
1242223383edSEnrico Granata             switch (short_option)
1243223383edSEnrico Granata             {
1244223383edSEnrico Granata                 case 'f':
1245223383edSEnrico Granata                     m_funct_name = std::string(option_arg);
1246223383edSEnrico Granata                     break;
1247223383edSEnrico Granata                 default:
1248223383edSEnrico Granata                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1249223383edSEnrico Granata                     break;
1250223383edSEnrico Granata             }
1251223383edSEnrico Granata 
1252223383edSEnrico Granata             return error;
1253223383edSEnrico Granata         }
1254223383edSEnrico Granata 
1255223383edSEnrico Granata         void
1256223383edSEnrico Granata         OptionParsingStarting ()
1257223383edSEnrico Granata         {
1258223383edSEnrico Granata             m_funct_name = "";
1259223383edSEnrico Granata         }
1260223383edSEnrico Granata 
1261223383edSEnrico Granata         const OptionDefinition*
1262223383edSEnrico Granata         GetDefinitions ()
1263223383edSEnrico Granata         {
1264223383edSEnrico Granata             return g_option_table;
1265223383edSEnrico Granata         }
1266223383edSEnrico Granata 
1267223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1268223383edSEnrico Granata 
1269223383edSEnrico Granata         static OptionDefinition g_option_table[];
1270223383edSEnrico Granata 
1271223383edSEnrico Granata         // Instance variables to hold the values for command options.
1272223383edSEnrico Granata 
1273223383edSEnrico Granata         std::string m_funct_name;
1274223383edSEnrico Granata     };
1275223383edSEnrico Granata 
1276223383edSEnrico Granata     CommandOptions m_options;
1277223383edSEnrico Granata 
1278223383edSEnrico Granata     virtual Options *
1279223383edSEnrico Granata     GetOptions ()
1280223383edSEnrico Granata     {
1281223383edSEnrico Granata         return &m_options;
1282223383edSEnrico Granata     }
1283223383edSEnrico Granata 
1284223383edSEnrico Granata     class PythonAliasReader : public InputReaderEZ
1285223383edSEnrico Granata     {
1286223383edSEnrico Granata     private:
1287223383edSEnrico Granata         CommandInterpreter& m_interpreter;
1288223383edSEnrico Granata         std::string m_cmd_name;
1289223383edSEnrico Granata         StringList m_user_input;
1290223383edSEnrico Granata         DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1291223383edSEnrico Granata     public:
1292223383edSEnrico Granata         PythonAliasReader(Debugger& debugger,
1293223383edSEnrico Granata                           CommandInterpreter& interpreter,
1294223383edSEnrico Granata                           std::string cmd_name) :
1295223383edSEnrico Granata         InputReaderEZ(debugger),
1296223383edSEnrico Granata         m_interpreter(interpreter),
1297223383edSEnrico Granata         m_cmd_name(cmd_name),
1298223383edSEnrico Granata         m_user_input()
1299223383edSEnrico Granata         {}
1300223383edSEnrico Granata 
1301223383edSEnrico Granata         virtual
1302223383edSEnrico Granata         ~PythonAliasReader()
1303223383edSEnrico Granata         {
1304223383edSEnrico Granata         }
1305223383edSEnrico Granata 
1306223383edSEnrico Granata         virtual void ActivateHandler(HandlerData& data)
1307223383edSEnrico Granata         {
1308223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1309223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1310223383edSEnrico Granata             if (!batch_mode)
1311223383edSEnrico Granata             {
1312223383edSEnrico Granata                 out_stream->Printf ("%s\n", g_python_command_instructions);
1313223383edSEnrico Granata                 if (data.reader.GetPrompt())
1314223383edSEnrico Granata                     out_stream->Printf ("%s", data.reader.GetPrompt());
1315223383edSEnrico Granata                 out_stream->Flush();
1316223383edSEnrico Granata             }
1317223383edSEnrico Granata         }
1318223383edSEnrico Granata 
1319223383edSEnrico Granata         virtual void ReactivateHandler(HandlerData& data)
1320223383edSEnrico Granata         {
1321223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1322223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1323223383edSEnrico Granata             if (data.reader.GetPrompt() && !batch_mode)
1324223383edSEnrico Granata             {
1325223383edSEnrico Granata                 out_stream->Printf ("%s", data.reader.GetPrompt());
1326223383edSEnrico Granata                 out_stream->Flush();
1327223383edSEnrico Granata             }
1328223383edSEnrico Granata         }
1329223383edSEnrico Granata         virtual void GotTokenHandler(HandlerData& data)
1330223383edSEnrico Granata         {
1331223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1332223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1333223383edSEnrico Granata             if (data.bytes && data.bytes_len)
1334223383edSEnrico Granata             {
1335223383edSEnrico Granata                 m_user_input.AppendString(data.bytes, data.bytes_len);
1336223383edSEnrico Granata             }
1337223383edSEnrico Granata             if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1338223383edSEnrico Granata             {
1339223383edSEnrico Granata                 out_stream->Printf ("%s", data.reader.GetPrompt());
1340223383edSEnrico Granata                 out_stream->Flush();
1341223383edSEnrico Granata             }
1342223383edSEnrico Granata         }
1343223383edSEnrico Granata         virtual void InterruptHandler(HandlerData& data)
1344223383edSEnrico Granata         {
1345223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1346223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1347223383edSEnrico Granata             data.reader.SetIsDone (true);
1348223383edSEnrico Granata             if (!batch_mode)
1349223383edSEnrico Granata             {
1350223383edSEnrico Granata                 out_stream->Printf ("Warning: No command attached to breakpoint.\n");
1351223383edSEnrico Granata                 out_stream->Flush();
1352223383edSEnrico Granata             }
1353223383edSEnrico Granata         }
1354223383edSEnrico Granata         virtual void EOFHandler(HandlerData& data)
1355223383edSEnrico Granata         {
1356223383edSEnrico Granata             data.reader.SetIsDone (true);
1357223383edSEnrico Granata         }
1358223383edSEnrico Granata         virtual void DoneHandler(HandlerData& data)
1359223383edSEnrico Granata         {
1360223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1361223383edSEnrico Granata 
1362223383edSEnrico Granata             ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1363223383edSEnrico Granata             if (!interpreter)
1364223383edSEnrico Granata             {
1365223383edSEnrico Granata                 out_stream->Printf ("Internal error #1: no script attached.\n");
1366223383edSEnrico Granata                 out_stream->Flush();
1367223383edSEnrico Granata                 return;
1368223383edSEnrico Granata             }
1369223383edSEnrico Granata             StringList funct_name_sl;
1370223383edSEnrico Granata             if (!interpreter->GenerateScriptAliasFunction (m_user_input,
1371223383edSEnrico Granata                                                            funct_name_sl))
1372223383edSEnrico Granata             {
1373223383edSEnrico Granata                 out_stream->Printf ("Internal error #2: no script attached.\n");
1374223383edSEnrico Granata                 out_stream->Flush();
1375223383edSEnrico Granata                 return;
1376223383edSEnrico Granata             }
1377223383edSEnrico Granata             if (funct_name_sl.GetSize() == 0)
1378223383edSEnrico Granata             {
1379223383edSEnrico Granata                 out_stream->Printf ("Internal error #3: no script attached.\n");
1380223383edSEnrico Granata                 out_stream->Flush();
1381223383edSEnrico Granata                 return;
1382223383edSEnrico Granata             }
1383223383edSEnrico Granata             const char *funct_name = funct_name_sl.GetStringAtIndex(0);
1384223383edSEnrico Granata             if (!funct_name || !funct_name[0])
1385223383edSEnrico Granata             {
1386223383edSEnrico Granata                 out_stream->Printf ("Internal error #4: no script attached.\n");
1387223383edSEnrico Granata                 out_stream->Flush();
1388223383edSEnrico Granata                 return;
1389223383edSEnrico Granata             }
1390223383edSEnrico Granata 
1391223383edSEnrico Granata             // everything should be fine now, let's add this alias
1392223383edSEnrico Granata 
1393223383edSEnrico Granata             CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1394223383edSEnrico Granata                                                                            m_cmd_name,
1395223383edSEnrico Granata                                                                            funct_name));
1396223383edSEnrico Granata 
1397223383edSEnrico Granata             if (!m_interpreter.AddUserCommand(m_cmd_name.c_str(), command_obj_sp, true))
1398223383edSEnrico Granata             {
1399223383edSEnrico Granata                 out_stream->Printf ("Internal error #5: no script attached.\n");
1400223383edSEnrico Granata                 out_stream->Flush();
1401223383edSEnrico Granata                 return;
1402223383edSEnrico Granata             }
1403223383edSEnrico Granata         }
1404223383edSEnrico Granata     };
1405223383edSEnrico Granata 
1406223383edSEnrico Granata public:
1407223383edSEnrico Granata     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1408223383edSEnrico Granata     CommandObject (interpreter,
1409223383edSEnrico Granata                    "command script add",
1410223383edSEnrico Granata                    "Add a scripted function as an LLDB command.",
1411223383edSEnrico Granata                    NULL),
1412223383edSEnrico Granata     m_options (interpreter)
1413223383edSEnrico Granata     {
1414223383edSEnrico Granata         CommandArgumentEntry arg1;
1415223383edSEnrico Granata         CommandArgumentData cmd_arg;
1416223383edSEnrico Granata 
1417223383edSEnrico Granata         // Define the first (and only) variant of this arg.
1418223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
1419223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
1420223383edSEnrico Granata 
1421223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
1422223383edSEnrico Granata         arg1.push_back (cmd_arg);
1423223383edSEnrico Granata 
1424223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
1425223383edSEnrico Granata         m_arguments.push_back (arg1);
1426223383edSEnrico Granata     }
1427223383edSEnrico Granata 
1428223383edSEnrico Granata     ~CommandObjectCommandsScriptAdd ()
1429223383edSEnrico Granata     {
1430223383edSEnrico Granata     }
1431223383edSEnrico Granata 
1432223383edSEnrico Granata     bool
1433223383edSEnrico Granata     Execute
1434223383edSEnrico Granata     (
1435223383edSEnrico Granata      Args& args,
1436223383edSEnrico Granata      CommandReturnObject &result
1437223383edSEnrico Granata      )
1438223383edSEnrico Granata     {
1439*99f0b8f9SEnrico Granata 
1440*99f0b8f9SEnrico Granata         if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython)
1441*99f0b8f9SEnrico Granata         {
1442*99f0b8f9SEnrico Granata             result.AppendError ("only scripting language supported for scripted commands is currently Python");
1443*99f0b8f9SEnrico Granata             result.SetStatus (eReturnStatusFailed);
1444*99f0b8f9SEnrico Granata             return false;
1445*99f0b8f9SEnrico Granata         }
1446*99f0b8f9SEnrico Granata 
1447223383edSEnrico Granata         size_t argc = args.GetArgumentCount();
1448223383edSEnrico Granata 
1449223383edSEnrico Granata         if (argc != 1)
1450223383edSEnrico Granata         {
1451223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
1452223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1453223383edSEnrico Granata             return false;
1454223383edSEnrico Granata         }
1455223383edSEnrico Granata 
1456223383edSEnrico Granata         std::string cmd_name = args.GetArgumentAtIndex(0);
1457223383edSEnrico Granata 
1458223383edSEnrico Granata         if (m_options.m_funct_name.empty())
1459223383edSEnrico Granata         {
1460223383edSEnrico Granata             InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1461223383edSEnrico Granata                                                             m_interpreter,
1462223383edSEnrico Granata                                                             cmd_name));
1463223383edSEnrico Granata 
1464223383edSEnrico Granata             if (reader_sp)
1465223383edSEnrico Granata             {
1466223383edSEnrico Granata 
1467223383edSEnrico Granata                 InputReaderEZ::InitializationParameters ipr;
1468223383edSEnrico Granata 
1469223383edSEnrico Granata                 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt("     ")));
1470223383edSEnrico Granata                 if (err.Success())
1471223383edSEnrico Granata                 {
1472223383edSEnrico Granata                     m_interpreter.GetDebugger().PushInputReader (reader_sp);
1473223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1474223383edSEnrico Granata                 }
1475223383edSEnrico Granata                 else
1476223383edSEnrico Granata                 {
1477223383edSEnrico Granata                     result.AppendError (err.AsCString());
1478223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
1479223383edSEnrico Granata                 }
1480223383edSEnrico Granata             }
1481223383edSEnrico Granata             else
1482223383edSEnrico Granata             {
1483223383edSEnrico Granata                 result.AppendError("out of memory");
1484223383edSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1485223383edSEnrico Granata             }
1486223383edSEnrico Granata         }
1487223383edSEnrico Granata         else
1488223383edSEnrico Granata         {
1489223383edSEnrico Granata             CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, cmd_name, m_options.m_funct_name));
1490223383edSEnrico Granata             if (m_interpreter.AddUserCommand(cmd_name.c_str(), new_cmd, true))
1491223383edSEnrico Granata             {
1492223383edSEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1493223383edSEnrico Granata             }
1494223383edSEnrico Granata             else
1495223383edSEnrico Granata             {
1496223383edSEnrico Granata                 result.AppendError("cannot add command");
1497223383edSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1498223383edSEnrico Granata             }
1499223383edSEnrico Granata         }
1500223383edSEnrico Granata 
1501223383edSEnrico Granata         return result.Succeeded();
1502223383edSEnrico Granata 
1503223383edSEnrico Granata     }
1504223383edSEnrico Granata };
1505223383edSEnrico Granata 
1506223383edSEnrico Granata OptionDefinition
1507223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1508223383edSEnrico Granata {
1509223383edSEnrico Granata     { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypeName,        "Name of a Python function to use."},
1510223383edSEnrico Granata     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1511223383edSEnrico Granata };
1512223383edSEnrico Granata 
1513223383edSEnrico Granata //-------------------------------------------------------------------------
1514223383edSEnrico Granata // CommandObjectCommandsScriptList
1515223383edSEnrico Granata //-------------------------------------------------------------------------
1516223383edSEnrico Granata 
1517223383edSEnrico Granata class CommandObjectCommandsScriptList : public CommandObject
1518223383edSEnrico Granata {
1519223383edSEnrico Granata private:
1520223383edSEnrico Granata 
1521223383edSEnrico Granata public:
1522223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
1523223383edSEnrico Granata     CommandObject (interpreter,
1524223383edSEnrico Granata                    "command script list",
1525223383edSEnrico Granata                    "List defined scripted commands.",
1526223383edSEnrico Granata                    NULL)
1527223383edSEnrico Granata     {
1528223383edSEnrico Granata     }
1529223383edSEnrico Granata 
1530223383edSEnrico Granata     ~CommandObjectCommandsScriptList ()
1531223383edSEnrico Granata     {
1532223383edSEnrico Granata     }
1533223383edSEnrico Granata 
1534223383edSEnrico Granata     bool
1535223383edSEnrico Granata     Execute
1536223383edSEnrico Granata     (
1537223383edSEnrico Granata      Args& args,
1538223383edSEnrico Granata      CommandReturnObject &result
1539223383edSEnrico Granata      )
1540223383edSEnrico Granata     {
1541223383edSEnrico Granata 
1542223383edSEnrico Granata         m_interpreter.GetHelp(result,
1543223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
1544223383edSEnrico Granata 
1545223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
1546223383edSEnrico Granata 
1547223383edSEnrico Granata         return true;
1548223383edSEnrico Granata 
1549223383edSEnrico Granata 
1550223383edSEnrico Granata     }
1551223383edSEnrico Granata };
1552223383edSEnrico Granata 
1553223383edSEnrico Granata //-------------------------------------------------------------------------
1554223383edSEnrico Granata // CommandObjectCommandsScriptClear
1555223383edSEnrico Granata //-------------------------------------------------------------------------
1556223383edSEnrico Granata 
1557223383edSEnrico Granata class CommandObjectCommandsScriptClear : public CommandObject
1558223383edSEnrico Granata {
1559223383edSEnrico Granata private:
1560223383edSEnrico Granata 
1561223383edSEnrico Granata public:
1562223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
1563223383edSEnrico Granata     CommandObject (interpreter,
1564223383edSEnrico Granata                    "command script clear",
1565223383edSEnrico Granata                    "Delete all scripted commands.",
1566223383edSEnrico Granata                    NULL)
1567223383edSEnrico Granata     {
1568223383edSEnrico Granata     }
1569223383edSEnrico Granata 
1570223383edSEnrico Granata     ~CommandObjectCommandsScriptClear ()
1571223383edSEnrico Granata     {
1572223383edSEnrico Granata     }
1573223383edSEnrico Granata 
1574223383edSEnrico Granata     bool
1575223383edSEnrico Granata     Execute
1576223383edSEnrico Granata     (
1577223383edSEnrico Granata      Args& args,
1578223383edSEnrico Granata      CommandReturnObject &result
1579223383edSEnrico Granata      )
1580223383edSEnrico Granata     {
1581223383edSEnrico Granata 
1582223383edSEnrico Granata         m_interpreter.RemoveAllUser();
1583223383edSEnrico Granata 
1584223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
1585223383edSEnrico Granata 
1586223383edSEnrico Granata         return true;
1587223383edSEnrico Granata 
1588223383edSEnrico Granata 
1589223383edSEnrico Granata     }
1590223383edSEnrico Granata };
1591223383edSEnrico Granata 
1592223383edSEnrico Granata //-------------------------------------------------------------------------
1593223383edSEnrico Granata // CommandObjectCommandsScriptDelete
1594223383edSEnrico Granata //-------------------------------------------------------------------------
1595223383edSEnrico Granata 
1596223383edSEnrico Granata class CommandObjectCommandsScriptDelete : public CommandObject
1597223383edSEnrico Granata {
1598223383edSEnrico Granata private:
1599223383edSEnrico Granata 
1600223383edSEnrico Granata public:
1601223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
1602223383edSEnrico Granata     CommandObject (interpreter,
1603223383edSEnrico Granata                    "command script delete",
1604223383edSEnrico Granata                    "Delete a scripted command.",
1605223383edSEnrico Granata                    NULL)
1606223383edSEnrico Granata     {
1607223383edSEnrico Granata         CommandArgumentEntry arg1;
1608223383edSEnrico Granata         CommandArgumentData cmd_arg;
1609223383edSEnrico Granata 
1610223383edSEnrico Granata         // Define the first (and only) variant of this arg.
1611223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
1612223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
1613223383edSEnrico Granata 
1614223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
1615223383edSEnrico Granata         arg1.push_back (cmd_arg);
1616223383edSEnrico Granata 
1617223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
1618223383edSEnrico Granata         m_arguments.push_back (arg1);
1619223383edSEnrico Granata     }
1620223383edSEnrico Granata 
1621223383edSEnrico Granata     ~CommandObjectCommandsScriptDelete ()
1622223383edSEnrico Granata     {
1623223383edSEnrico Granata     }
1624223383edSEnrico Granata 
1625223383edSEnrico Granata     bool
1626223383edSEnrico Granata     Execute
1627223383edSEnrico Granata     (
1628223383edSEnrico Granata      Args& args,
1629223383edSEnrico Granata      CommandReturnObject &result
1630223383edSEnrico Granata      )
1631223383edSEnrico Granata     {
1632223383edSEnrico Granata 
1633223383edSEnrico Granata         size_t argc = args.GetArgumentCount();
1634223383edSEnrico Granata 
1635223383edSEnrico Granata         if (argc != 1)
1636223383edSEnrico Granata         {
1637223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
1638223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1639223383edSEnrico Granata             return false;
1640223383edSEnrico Granata         }
1641223383edSEnrico Granata 
1642223383edSEnrico Granata         const char* cmd_name = args.GetArgumentAtIndex(0);
1643223383edSEnrico Granata 
1644223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1645223383edSEnrico Granata         {
1646223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
1647223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
1648223383edSEnrico Granata         }
1649223383edSEnrico Granata         else
1650223383edSEnrico Granata         {
1651223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
1652223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1653223383edSEnrico Granata         }
1654223383edSEnrico Granata 
1655223383edSEnrico Granata         return result.Succeeded();
1656223383edSEnrico Granata 
1657223383edSEnrico Granata     }
1658223383edSEnrico Granata };
1659223383edSEnrico Granata 
1660223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
1661223383edSEnrico Granata 
1662223383edSEnrico Granata //-------------------------------------------------------------------------
1663223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
1664223383edSEnrico Granata //-------------------------------------------------------------------------
1665223383edSEnrico Granata 
1666223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1667223383edSEnrico Granata {
1668223383edSEnrico Granata public:
1669223383edSEnrico Granata     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1670223383edSEnrico Granata     CommandObjectMultiword (interpreter,
1671223383edSEnrico Granata                             "command script",
1672223383edSEnrico Granata                             "A set of commands for managing or customizing script commands.",
1673223383edSEnrico Granata                             "command script <subcommand> [<subcommand-options>]")
1674223383edSEnrico Granata     {
1675223383edSEnrico Granata         LoadSubCommand ("add",  CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1676223383edSEnrico Granata         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1677223383edSEnrico Granata         LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1678223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
1679223383edSEnrico Granata     }
1680223383edSEnrico Granata 
1681223383edSEnrico Granata     ~CommandObjectMultiwordCommandsScript ()
1682223383edSEnrico Granata     {
1683223383edSEnrico Granata     }
1684223383edSEnrico Granata 
1685223383edSEnrico Granata };
1686223383edSEnrico Granata 
1687223383edSEnrico Granata 
1688ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
1689ebc09c36SJim Ingham 
1690ebc09c36SJim Ingham //-------------------------------------------------------------------------
1691ebc09c36SJim Ingham // CommandObjectMultiwordCommands
1692ebc09c36SJim Ingham //-------------------------------------------------------------------------
1693ebc09c36SJim Ingham 
1694ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
1695a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
16960e5e5a79SGreg Clayton                             "command",
16973f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
16980e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
1699ebc09c36SJim Ingham {
1700a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1701a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1702a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
1703de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
1704a5a97ebeSJim Ingham     LoadSubCommand ("history",   CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
1705223383edSEnrico Granata     LoadSubCommand ("script",   CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
1706ebc09c36SJim Ingham }
1707ebc09c36SJim Ingham 
1708ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1709ebc09c36SJim Ingham {
1710ebc09c36SJim Ingham }
1711ebc09c36SJim Ingham 
1712