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"
27ebc09c36SJim Ingham 
28ebc09c36SJim Ingham using namespace lldb;
29ebc09c36SJim Ingham using namespace lldb_private;
30ebc09c36SJim Ingham 
31ebc09c36SJim Ingham //-------------------------------------------------------------------------
32ebc09c36SJim Ingham // CommandObjectCommandsSource
33ebc09c36SJim Ingham //-------------------------------------------------------------------------
34ebc09c36SJim Ingham 
35a5a97ebeSJim Ingham class CommandObjectCommandsHistory : public CommandObject
36a5a97ebeSJim Ingham {
37a5a97ebeSJim Ingham private:
38a5a97ebeSJim Ingham 
39a5a97ebeSJim Ingham     class CommandOptions : public Options
40a5a97ebeSJim Ingham     {
41a5a97ebeSJim Ingham     public:
42a5a97ebeSJim Ingham 
43a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
44a5a97ebeSJim Ingham             Options (interpreter)
45a5a97ebeSJim Ingham         {
46a5a97ebeSJim Ingham         }
47a5a97ebeSJim Ingham 
48a5a97ebeSJim Ingham         virtual
49a5a97ebeSJim Ingham         ~CommandOptions (){}
50a5a97ebeSJim Ingham 
51a5a97ebeSJim Ingham         virtual Error
52a5a97ebeSJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
53a5a97ebeSJim Ingham         {
54a5a97ebeSJim Ingham             Error error;
55a5a97ebeSJim Ingham             char short_option = (char) m_getopt_table[option_idx].val;
56a5a97ebeSJim Ingham             bool success;
57a5a97ebeSJim Ingham 
58a5a97ebeSJim Ingham             switch (short_option)
59a5a97ebeSJim Ingham             {
60a5a97ebeSJim Ingham                 case 'c':
61a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
62a5a97ebeSJim Ingham                     if (!success)
63a5a97ebeSJim Ingham                         error.SetErrorStringWithFormat("Invalid value for count: %s.\n", option_arg);
64a5a97ebeSJim Ingham                     if (m_end_idx != 0)
65a5a97ebeSJim Ingham                         m_end_idx--;
66a5a97ebeSJim Ingham                     m_start_idx = 0;
67a5a97ebeSJim Ingham                     break;
68a5a97ebeSJim Ingham                 case 'e':
69a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
70a5a97ebeSJim Ingham                     if (!success)
71a5a97ebeSJim Ingham                         error.SetErrorStringWithFormat("Invalid value for end index: %s.\n", option_arg);
72a5a97ebeSJim Ingham                     break;
73a5a97ebeSJim Ingham                 case 's':
74a5a97ebeSJim Ingham                     m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
75a5a97ebeSJim Ingham                     if (!success)
76a5a97ebeSJim Ingham                         error.SetErrorStringWithFormat("Invalid value for start index: %s.\n", option_arg);
77a5a97ebeSJim Ingham                     break;
78a5a97ebeSJim Ingham                 default:
79a5a97ebeSJim Ingham                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
80a5a97ebeSJim Ingham                     break;
81a5a97ebeSJim Ingham             }
82a5a97ebeSJim Ingham 
83a5a97ebeSJim Ingham             return error;
84a5a97ebeSJim Ingham         }
85a5a97ebeSJim Ingham 
86a5a97ebeSJim Ingham         void
87a5a97ebeSJim Ingham         OptionParsingStarting ()
88a5a97ebeSJim Ingham         {
89a5a97ebeSJim Ingham             m_start_idx = 0;
90a5a97ebeSJim Ingham             m_end_idx = UINT_MAX;
91a5a97ebeSJim Ingham         }
92a5a97ebeSJim Ingham 
93a5a97ebeSJim Ingham         const OptionDefinition*
94a5a97ebeSJim Ingham         GetDefinitions ()
95a5a97ebeSJim Ingham         {
96a5a97ebeSJim Ingham             return g_option_table;
97a5a97ebeSJim Ingham         }
98a5a97ebeSJim Ingham 
99a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
100a5a97ebeSJim Ingham 
101a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
102a5a97ebeSJim Ingham 
103a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
104a5a97ebeSJim Ingham 
105a5a97ebeSJim Ingham         uint32_t m_start_idx;
106a5a97ebeSJim Ingham         uint32_t m_end_idx;
107a5a97ebeSJim Ingham     };
108a5a97ebeSJim Ingham 
109a5a97ebeSJim Ingham     CommandOptions m_options;
110a5a97ebeSJim Ingham 
111a5a97ebeSJim Ingham     virtual Options *
112a5a97ebeSJim Ingham     GetOptions ()
113a5a97ebeSJim Ingham     {
114a5a97ebeSJim Ingham         return &m_options;
115a5a97ebeSJim Ingham     }
116a5a97ebeSJim Ingham 
117a5a97ebeSJim Ingham public:
118a5a97ebeSJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
119a5a97ebeSJim Ingham         CommandObject (interpreter,
120a5a97ebeSJim Ingham                        "command history",
121a5a97ebeSJim Ingham                        "Dump the history of commands in this session.",
122a5a97ebeSJim Ingham                        NULL),
123a5a97ebeSJim Ingham         m_options (interpreter)
124a5a97ebeSJim Ingham     {
125a5a97ebeSJim Ingham     }
126a5a97ebeSJim Ingham 
127a5a97ebeSJim Ingham     ~CommandObjectCommandsHistory ()
128a5a97ebeSJim Ingham     {
129a5a97ebeSJim Ingham     }
130a5a97ebeSJim Ingham 
131a5a97ebeSJim Ingham     bool
132a5a97ebeSJim Ingham     Execute
133a5a97ebeSJim Ingham     (
134a5a97ebeSJim Ingham         Args& args,
135a5a97ebeSJim Ingham         CommandReturnObject &result
136a5a97ebeSJim Ingham     )
137a5a97ebeSJim Ingham     {
138a5a97ebeSJim Ingham 
139a5a97ebeSJim Ingham         m_interpreter.DumpHistory (result.GetOutputStream(),
140a5a97ebeSJim Ingham                                    m_options.m_start_idx,
141a5a97ebeSJim Ingham                                    m_options.m_end_idx);
142a5a97ebeSJim Ingham         return result.Succeeded();
143a5a97ebeSJim Ingham 
144a5a97ebeSJim Ingham     }
145a5a97ebeSJim Ingham };
146a5a97ebeSJim Ingham 
147a5a97ebeSJim Ingham OptionDefinition
148a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
149a5a97ebeSJim Ingham {
150a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
151a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger,  "Index at which to start printing history commands."},
152a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
153a5a97ebeSJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
154a5a97ebeSJim Ingham };
155a5a97ebeSJim Ingham 
156a5a97ebeSJim Ingham 
157a5a97ebeSJim Ingham //-------------------------------------------------------------------------
158a5a97ebeSJim Ingham // CommandObjectCommandsSource
159a5a97ebeSJim Ingham //-------------------------------------------------------------------------
160a5a97ebeSJim Ingham 
161ebc09c36SJim Ingham class CommandObjectCommandsSource : public CommandObject
162ebc09c36SJim Ingham {
163e16c50a1SJim Ingham private:
164e16c50a1SJim Ingham 
165e16c50a1SJim Ingham     class CommandOptions : public Options
166e16c50a1SJim Ingham     {
167e16c50a1SJim Ingham     public:
168e16c50a1SJim Ingham 
169eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
170eb0103f2SGreg Clayton             Options (interpreter)
171eb0103f2SGreg Clayton         {
172eb0103f2SGreg Clayton         }
173e16c50a1SJim Ingham 
174e16c50a1SJim Ingham         virtual
175e16c50a1SJim Ingham         ~CommandOptions (){}
176e16c50a1SJim Ingham 
177e16c50a1SJim Ingham         virtual Error
178f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
179e16c50a1SJim Ingham         {
180e16c50a1SJim Ingham             Error error;
181e16c50a1SJim Ingham             char short_option = (char) m_getopt_table[option_idx].val;
182e16c50a1SJim Ingham             bool success;
183e16c50a1SJim Ingham 
184e16c50a1SJim Ingham             switch (short_option)
185e16c50a1SJim Ingham             {
186e16c50a1SJim Ingham                 case 'e':
187e16c50a1SJim Ingham                     m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
188e16c50a1SJim Ingham                     if (!success)
189e16c50a1SJim Ingham                         error.SetErrorStringWithFormat("Invalid value for stop-on-error: %s.\n", option_arg);
190e16c50a1SJim Ingham                     break;
191e16c50a1SJim Ingham                 case 'c':
192e16c50a1SJim Ingham                     m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
193e16c50a1SJim Ingham                     if (!success)
194e16c50a1SJim Ingham                         error.SetErrorStringWithFormat("Invalid value for stop-on-continue: %s.\n", option_arg);
195e16c50a1SJim Ingham                     break;
196e16c50a1SJim Ingham                 default:
197e16c50a1SJim Ingham                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
198e16c50a1SJim Ingham                     break;
199e16c50a1SJim Ingham             }
200e16c50a1SJim Ingham 
201e16c50a1SJim Ingham             return error;
202e16c50a1SJim Ingham         }
203e16c50a1SJim Ingham 
204e16c50a1SJim Ingham         void
205f6b8b581SGreg Clayton         OptionParsingStarting ()
206e16c50a1SJim Ingham         {
207e16c50a1SJim Ingham             m_stop_on_error = true;
208e16c50a1SJim Ingham             m_stop_on_continue = true;
209e16c50a1SJim Ingham         }
210e16c50a1SJim Ingham 
211e0d378b3SGreg Clayton         const OptionDefinition*
212e16c50a1SJim Ingham         GetDefinitions ()
213e16c50a1SJim Ingham         {
214e16c50a1SJim Ingham             return g_option_table;
215e16c50a1SJim Ingham         }
216e16c50a1SJim Ingham 
217e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
218e16c50a1SJim Ingham 
219e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
220e16c50a1SJim Ingham 
221e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
222e16c50a1SJim Ingham 
223e16c50a1SJim Ingham         bool m_stop_on_error;
224e16c50a1SJim Ingham         bool m_stop_on_continue;
225e16c50a1SJim Ingham     };
226e16c50a1SJim Ingham 
227e16c50a1SJim Ingham     CommandOptions m_options;
228e16c50a1SJim Ingham 
229e16c50a1SJim Ingham     virtual Options *
230e16c50a1SJim Ingham     GetOptions ()
231e16c50a1SJim Ingham     {
232e16c50a1SJim Ingham         return &m_options;
233e16c50a1SJim Ingham     }
234e16c50a1SJim Ingham 
235ebc09c36SJim Ingham public:
236a7015092SGreg Clayton     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
237a7015092SGreg Clayton         CommandObject (interpreter,
2380e5e5a79SGreg Clayton                        "command source",
239e3d26315SCaroline Tice                        "Read in debugger commands from the file <filename> and execute them.",
240eb0103f2SGreg Clayton                        NULL),
241eb0103f2SGreg Clayton         m_options (interpreter)
242ebc09c36SJim Ingham     {
243405fe67fSCaroline Tice         CommandArgumentEntry arg;
244405fe67fSCaroline Tice         CommandArgumentData file_arg;
245405fe67fSCaroline Tice 
246405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
247405fe67fSCaroline Tice         file_arg.arg_type = eArgTypeFilename;
248405fe67fSCaroline Tice         file_arg.arg_repetition = eArgRepeatPlain;
249405fe67fSCaroline Tice 
250405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
251405fe67fSCaroline Tice         arg.push_back (file_arg);
252405fe67fSCaroline Tice 
253405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
254405fe67fSCaroline Tice         m_arguments.push_back (arg);
255ebc09c36SJim Ingham     }
256ebc09c36SJim Ingham 
257ebc09c36SJim Ingham     ~CommandObjectCommandsSource ()
258ebc09c36SJim Ingham     {
259ebc09c36SJim Ingham     }
260ebc09c36SJim Ingham 
261ebc09c36SJim Ingham     bool
262ebc09c36SJim Ingham     Execute
263ebc09c36SJim Ingham     (
264ebc09c36SJim Ingham         Args& args,
265ebc09c36SJim Ingham         CommandReturnObject &result
266ebc09c36SJim Ingham     )
267ebc09c36SJim Ingham     {
268ebc09c36SJim Ingham         const int argc = args.GetArgumentCount();
269ebc09c36SJim Ingham         if (argc == 1)
270ebc09c36SJim Ingham         {
271ebc09c36SJim Ingham             const char *filename = args.GetArgumentAtIndex(0);
272ebc09c36SJim Ingham 
273ebc09c36SJim Ingham             result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
274ebc09c36SJim Ingham 
2751ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
276e16c50a1SJim Ingham             ExecutionContext *exe_ctx = NULL;  // Just use the default context.
277e16c50a1SJim Ingham             bool echo_commands    = true;
278e16c50a1SJim Ingham             bool print_results    = true;
279ebc09c36SJim Ingham 
280e16c50a1SJim Ingham             m_interpreter.HandleCommandsFromFile (cmd_file,
281e16c50a1SJim Ingham                                                   exe_ctx,
282e16c50a1SJim Ingham                                                   m_options.m_stop_on_continue,
283e16c50a1SJim Ingham                                                   m_options.m_stop_on_error,
284e16c50a1SJim Ingham                                                   echo_commands,
285e16c50a1SJim Ingham                                                   print_results,
286e16c50a1SJim Ingham                                                   result);
287ebc09c36SJim Ingham         }
288ebc09c36SJim Ingham         else
289ebc09c36SJim Ingham         {
290ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
291ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
292ebc09c36SJim Ingham         }
293ebc09c36SJim Ingham         return result.Succeeded();
294ebc09c36SJim Ingham 
295ebc09c36SJim Ingham     }
296ebc09c36SJim Ingham };
297ebc09c36SJim Ingham 
298e0d378b3SGreg Clayton OptionDefinition
299e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
300e16c50a1SJim Ingham {
301e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
302e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
303e16c50a1SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
304e16c50a1SJim Ingham };
305e16c50a1SJim Ingham 
306ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
307ebc09c36SJim Ingham //-------------------------------------------------------------------------
308ebc09c36SJim Ingham // CommandObjectCommandsAlias
309ebc09c36SJim Ingham //-------------------------------------------------------------------------
310ebc09c36SJim Ingham 
311be93a35aSEnrico Granata static const char *g_python_command_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
312be93a35aSEnrico Granata                                                      "You must define a Python function with this signature:\n"
313*223383edSEnrico Granata                                                      "def my_command_impl(debugger, args, result, dict):";
314be93a35aSEnrico Granata 
315be93a35aSEnrico Granata 
316ebc09c36SJim Ingham class CommandObjectCommandsAlias : public CommandObject
317ebc09c36SJim Ingham {
318be93a35aSEnrico Granata 
319be93a35aSEnrico Granata 
320ebc09c36SJim Ingham public:
321a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
322a7015092SGreg Clayton         CommandObject (interpreter,
3230e5e5a79SGreg Clayton                        "command alias",
324e3d26315SCaroline Tice                        "Allow users to define their own debugger command abbreviations.",
325405fe67fSCaroline Tice                        NULL)
326ebc09c36SJim Ingham     {
327ebc09c36SJim Ingham         SetHelpLong(
328ebc09c36SJim Ingham     "'alias' allows the user to create a short-cut or abbreviation for long \n\
329ebc09c36SJim Ingham     commands, multi-word commands, and commands that take particular options. \n\
330ebc09c36SJim Ingham     Below are some simple examples of how one might use the 'alias' command: \n\
33109799af6SCaroline Tice     \n    'commands alias sc script'           // Creates the abbreviation 'sc' for the 'script' \n\
332ebc09c36SJim Ingham                                          // command. \n\
33309799af6SCaroline Tice     'commands alias bp breakpoint'       // Creates the abbreviation 'bp' for the 'breakpoint' \n\
334ebc09c36SJim Ingham                                          // command.  Since breakpoint commands are two-word \n\
335ebc09c36SJim Ingham                                          // commands, the user will still need to enter the \n\
336ebc09c36SJim Ingham                                          // second word after 'bp', e.g. 'bp enable' or \n\
337ebc09c36SJim Ingham                                          // 'bp delete'. \n\
33809799af6SCaroline Tice     'commands alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
339ebc09c36SJim Ingham                                          // two-word command 'breakpoint list'. \n\
340ebc09c36SJim Ingham     \nAn alias can include some options for the command, with the values either \n\
341ebc09c36SJim Ingham     filled in at the time the alias is created, or specified as positional \n\
342ebc09c36SJim Ingham     arguments, to be filled in when the alias is invoked.  The following example \n\
343ebc09c36SJim Ingham     shows how to create aliases with options: \n\
344ebc09c36SJim Ingham     \n\
34509799af6SCaroline Tice     'commands alias bfl breakpoint set -f %1 -l %2' \n\
346ebc09c36SJim Ingham     \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
347ebc09c36SJim Ingham     options already part of the alias.  So if the user wants to set a breakpoint \n\
348ebc09c36SJim Ingham     by file and line without explicitly having to use the -f and -l options, the \n\
349ebc09c36SJim Ingham     user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \n\
350ebc09c36SJim Ingham     for the actual arguments that will be passed when the alias command is used. \n\
351ebc09c36SJim Ingham     The number in the placeholder refers to the position/order the actual value \n\
352ebc09c36SJim Ingham     occupies when the alias is used.  So all the occurrences of '%1' in the alias \n\
353ebc09c36SJim Ingham     will be replaced with the first argument, all the occurrences of '%2' in the \n\
354ebc09c36SJim Ingham     alias will be replaced with the second argument, and so on.  This also allows \n\
355ebc09c36SJim Ingham     actual arguments to be used multiple times within an alias (see 'process \n\
356ebc09c36SJim Ingham     launch' example below).  So in the 'bfl' case, the actual file value will be \n\
357ebc09c36SJim Ingham     filled in with the first argument following 'bfl' and the actual line number \n\
358ebc09c36SJim Ingham     value will be filled in with the second argument.  The user would use this \n\
359ebc09c36SJim Ingham     alias as follows: \n\
36009799af6SCaroline Tice     \n    (lldb)  commands alias bfl breakpoint set -f %1 -l %2 \n\
361ebc09c36SJim Ingham     <... some time later ...> \n\
36209799af6SCaroline Tice     (lldb)  bfl my-file.c 137 \n\
363ebc09c36SJim Ingham     \nThis would be the same as if the user had entered \n\
364ebc09c36SJim Ingham     'breakpoint set -f my-file.c -l 137'. \n\
365ebc09c36SJim Ingham     \nAnother example: \n\
36609799af6SCaroline Tice     \n    (lldb)  commands alias pltty  process launch -s -o %1 -e %1 \n\
36709799af6SCaroline Tice     (lldb)  pltty /dev/tty0 \n\
368ebc09c36SJim Ingham            // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
369ebc09c36SJim Ingham     \nIf the user always wanted to pass the same value to a particular option, the \n\
370ebc09c36SJim Ingham     alias could be defined with that value directly in the alias as a constant, \n\
371ebc09c36SJim Ingham     rather than using a positional placeholder: \n\
3720708e2c2SSean Callanan     \n    commands alias bl3  breakpoint set -f %1 -l 3  // Always sets a breakpoint on line \n\
373ebc09c36SJim Ingham                                                    // 3 of whatever file is indicated. \n");
374ebc09c36SJim Ingham 
375405fe67fSCaroline Tice         CommandArgumentEntry arg1;
376405fe67fSCaroline Tice         CommandArgumentEntry arg2;
377405fe67fSCaroline Tice         CommandArgumentEntry arg3;
378405fe67fSCaroline Tice         CommandArgumentData alias_arg;
379405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
380405fe67fSCaroline Tice         CommandArgumentData options_arg;
381405fe67fSCaroline Tice 
382405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
383405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
384405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
385405fe67fSCaroline Tice 
386405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
387405fe67fSCaroline Tice         arg1.push_back (alias_arg);
388405fe67fSCaroline Tice 
389405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
390405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
391405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
392405fe67fSCaroline Tice 
393405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
394405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
395405fe67fSCaroline Tice 
396405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
397405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
398405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
399405fe67fSCaroline Tice 
400405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
401405fe67fSCaroline Tice         arg3.push_back (options_arg);
402405fe67fSCaroline Tice 
403405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
404405fe67fSCaroline Tice         m_arguments.push_back (arg1);
405405fe67fSCaroline Tice         m_arguments.push_back (arg2);
406405fe67fSCaroline Tice         m_arguments.push_back (arg3);
407ebc09c36SJim Ingham     }
408ebc09c36SJim Ingham 
409ebc09c36SJim Ingham     ~CommandObjectCommandsAlias ()
410ebc09c36SJim Ingham     {
411ebc09c36SJim Ingham     }
412ebc09c36SJim Ingham 
413844d2303SCaroline Tice     bool
414844d2303SCaroline Tice     WantsRawCommandString ()
415844d2303SCaroline Tice     {
416844d2303SCaroline Tice         return true;
417844d2303SCaroline Tice     }
418844d2303SCaroline Tice 
419844d2303SCaroline Tice     bool
420844d2303SCaroline Tice     ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
421844d2303SCaroline Tice     {
422844d2303SCaroline Tice         Args args (raw_command_line);
423844d2303SCaroline Tice         std::string raw_command_string (raw_command_line);
424844d2303SCaroline Tice 
425844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
426844d2303SCaroline Tice 
427844d2303SCaroline Tice         if (argc < 2)
428844d2303SCaroline Tice         {
429844d2303SCaroline Tice             result.AppendError ("'alias' requires at least two arguments");
430844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
431844d2303SCaroline Tice             return false;
432844d2303SCaroline Tice         }
433844d2303SCaroline Tice 
434844d2303SCaroline Tice         // Get the alias command.
435844d2303SCaroline Tice 
436844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
437844d2303SCaroline Tice 
438844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
439844d2303SCaroline Tice         // does the stripping itself.
440844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
441844d2303SCaroline Tice         if (pos == 0)
442844d2303SCaroline Tice         {
443844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
444844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
445844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
446844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
447844d2303SCaroline Tice         }
448844d2303SCaroline Tice         else
449844d2303SCaroline Tice         {
450844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
451844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
452844d2303SCaroline Tice             return false;
453844d2303SCaroline Tice         }
454844d2303SCaroline Tice 
455844d2303SCaroline Tice 
456844d2303SCaroline Tice         // Verify that the command is alias-able.
457844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
458844d2303SCaroline Tice         {
459844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
460844d2303SCaroline Tice                                           alias_command.c_str());
461844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
462844d2303SCaroline Tice             return false;
463844d2303SCaroline Tice         }
464844d2303SCaroline Tice 
465844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
466844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
467844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
468844d2303SCaroline Tice 
469844d2303SCaroline Tice         if (!cmd_obj)
470844d2303SCaroline Tice         {
471844d2303SCaroline Tice             result.AppendErrorWithFormat ("Invalid command given to 'alias'. '%s' does not begin with a valid command."
472844d2303SCaroline Tice                                           "  No alias created.", raw_command_string.c_str());
473844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
474844d2303SCaroline Tice             return false;
475844d2303SCaroline Tice         }
476844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
477844d2303SCaroline Tice         {
478844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
479844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
480844d2303SCaroline Tice             return Execute (args, result);
481844d2303SCaroline Tice         }
482844d2303SCaroline Tice         else
483844d2303SCaroline Tice         {
484844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
485844d2303SCaroline Tice 
486844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
487844d2303SCaroline Tice             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
488844d2303SCaroline Tice 
489ca90c47eSCaroline Tice             CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
490844d2303SCaroline Tice 
491ca90c47eSCaroline Tice             if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
492844d2303SCaroline Tice             {
493844d2303SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
494ca90c47eSCaroline Tice                 result.SetStatus (eReturnStatusFailed);
495844d2303SCaroline Tice                 return false;
496844d2303SCaroline Tice             }
497844d2303SCaroline Tice 
498844d2303SCaroline Tice             // Create the alias
499844d2303SCaroline Tice             if (m_interpreter.AliasExists (alias_command.c_str())
500844d2303SCaroline Tice                 || m_interpreter.UserCommandExists (alias_command.c_str()))
501844d2303SCaroline Tice             {
502844d2303SCaroline Tice                 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
503844d2303SCaroline Tice                 if (temp_option_arg_sp.get())
504844d2303SCaroline Tice                 {
505844d2303SCaroline Tice                     if (option_arg_vector->size() == 0)
506844d2303SCaroline Tice                         m_interpreter.RemoveAliasOptions (alias_command.c_str());
507844d2303SCaroline Tice                 }
508844d2303SCaroline Tice                 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
509844d2303SCaroline Tice                                                 alias_command.c_str());
510844d2303SCaroline Tice             }
511844d2303SCaroline Tice 
512472362e6SCaroline Tice             if (cmd_obj_sp)
513472362e6SCaroline Tice             {
514844d2303SCaroline Tice                 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
515844d2303SCaroline Tice                 if (option_arg_vector->size() > 0)
516844d2303SCaroline Tice                     m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
517844d2303SCaroline Tice                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
518844d2303SCaroline Tice             }
519472362e6SCaroline Tice             else
520472362e6SCaroline Tice             {
521472362e6SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
522472362e6SCaroline Tice                 result.SetStatus (eReturnStatusFailed);
523472362e6SCaroline Tice             }
524472362e6SCaroline Tice         }
525844d2303SCaroline Tice         return result.Succeeded();
526844d2303SCaroline Tice     }
527ebc09c36SJim Ingham 
528ebc09c36SJim Ingham     bool
529ebc09c36SJim Ingham     Execute
530ebc09c36SJim Ingham     (
531ebc09c36SJim Ingham         Args& args,
532ebc09c36SJim Ingham         CommandReturnObject &result
533ebc09c36SJim Ingham     )
534ebc09c36SJim Ingham     {
535867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
536ebc09c36SJim Ingham 
537ebc09c36SJim Ingham         if (argc < 2)
538ebc09c36SJim Ingham         {
539ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
540ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
541ebc09c36SJim Ingham             return false;
542ebc09c36SJim Ingham         }
543ebc09c36SJim Ingham 
544ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
545ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
546ebc09c36SJim Ingham 
547ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
548ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
549ebc09c36SJim Ingham 
550ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
551ebc09c36SJim Ingham 
552a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
553ebc09c36SJim Ingham         {
554ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
555ebc09c36SJim Ingham                                          alias_command.c_str());
556ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
557ebc09c36SJim Ingham         }
558ebc09c36SJim Ingham         else
559ebc09c36SJim Ingham         {
560a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
561ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
562ebc09c36SJim Ingham              bool use_subcommand = false;
563ebc09c36SJim Ingham              if (command_obj_sp.get())
564ebc09c36SJim Ingham              {
565ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
566c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
567ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
568ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
569ebc09c36SJim Ingham 
570844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
571ebc09c36SJim Ingham                  {
572ebc09c36SJim Ingham                      if (argc >= 3)
573ebc09c36SJim Ingham                      {
574ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
575ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
576ebc09c36SJim Ingham                          subcommand_obj_sp =
577ebc09c36SJim Ingham                                            (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
578ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
579ebc09c36SJim Ingham                          {
580ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
581ebc09c36SJim Ingham                              use_subcommand = true;
582ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
583844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
584ebc09c36SJim Ingham                          }
585ebc09c36SJim Ingham                          else
586ebc09c36SJim Ingham                          {
587f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
588f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
589f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
590ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
591ebc09c36SJim Ingham                              return false;
592ebc09c36SJim Ingham                          }
593ebc09c36SJim Ingham                      }
594ebc09c36SJim Ingham                  }
595ebc09c36SJim Ingham 
596ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
597ebc09c36SJim Ingham 
598ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
599ebc09c36SJim Ingham                  {
600ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
601ebc09c36SJim Ingham                     if (use_subcommand)
602ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
603ca90c47eSCaroline Tice 
604ca90c47eSCaroline Tice                     std::string args_string;
605ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
606ca90c47eSCaroline Tice 
607ca90c47eSCaroline Tice                     if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
608ebc09c36SJim Ingham                     {
609ca90c47eSCaroline Tice                         result.AppendError ("Unable to create requested alias.\n");
610ca90c47eSCaroline Tice                         result.SetStatus (eReturnStatusFailed);
611e7941795SCaroline Tice                         return false;
612867b185dSCaroline Tice                     }
613867b185dSCaroline Tice                  }
614867b185dSCaroline Tice 
615ebc09c36SJim Ingham                  // Create the alias.
616ebc09c36SJim Ingham 
617a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
618a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
619ebc09c36SJim Ingham                  {
620a7015092SGreg Clayton                      OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
621ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
622ebc09c36SJim Ingham                      {
623ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
624a7015092SGreg Clayton                              m_interpreter.RemoveAliasOptions (alias_command.c_str());
625ebc09c36SJim Ingham                      }
626ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
627ebc09c36SJim Ingham                                                      alias_command.c_str());
628ebc09c36SJim Ingham                  }
629ebc09c36SJim Ingham 
630ebc09c36SJim Ingham                  if (use_subcommand)
631a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
632ebc09c36SJim Ingham                  else
633a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
634ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
635a7015092SGreg Clayton                      m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
636ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
637ebc09c36SJim Ingham              }
638ebc09c36SJim Ingham              else
639ebc09c36SJim Ingham              {
640ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
641ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
642e7941795SCaroline Tice                  return false;
643ebc09c36SJim Ingham              }
644ebc09c36SJim Ingham         }
645ebc09c36SJim Ingham 
646ebc09c36SJim Ingham         return result.Succeeded();
647ebc09c36SJim Ingham     }
648ebc09c36SJim Ingham };
649ebc09c36SJim Ingham 
650ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
651ebc09c36SJim Ingham //-------------------------------------------------------------------------
652ebc09c36SJim Ingham // CommandObjectCommandsUnalias
653ebc09c36SJim Ingham //-------------------------------------------------------------------------
654ebc09c36SJim Ingham 
655ebc09c36SJim Ingham class CommandObjectCommandsUnalias : public CommandObject
656ebc09c36SJim Ingham {
657ebc09c36SJim Ingham public:
658a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
659a7015092SGreg Clayton         CommandObject (interpreter,
6600e5e5a79SGreg Clayton                        "command unalias",
66186ddae50SCaroline Tice                        "Allow the user to remove/delete a user-defined command abbreviation.",
662405fe67fSCaroline Tice                        NULL)
663ebc09c36SJim Ingham     {
664405fe67fSCaroline Tice         CommandArgumentEntry arg;
665405fe67fSCaroline Tice         CommandArgumentData alias_arg;
666405fe67fSCaroline Tice 
667405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
668405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
669405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
670405fe67fSCaroline Tice 
671405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
672405fe67fSCaroline Tice         arg.push_back (alias_arg);
673405fe67fSCaroline Tice 
674405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
675405fe67fSCaroline Tice         m_arguments.push_back (arg);
676ebc09c36SJim Ingham     }
677ebc09c36SJim Ingham 
678ebc09c36SJim Ingham     ~CommandObjectCommandsUnalias()
679ebc09c36SJim Ingham     {
680ebc09c36SJim Ingham     }
681ebc09c36SJim Ingham 
682ebc09c36SJim Ingham 
683ebc09c36SJim Ingham     bool
684ebc09c36SJim Ingham     Execute
685ebc09c36SJim Ingham     (
686ebc09c36SJim Ingham         Args& args,
687ebc09c36SJim Ingham         CommandReturnObject &result
688ebc09c36SJim Ingham     )
689ebc09c36SJim Ingham     {
690ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
691ebc09c36SJim Ingham         CommandObject *cmd_obj;
692ebc09c36SJim Ingham 
693ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
694ebc09c36SJim Ingham         {
695ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
696a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
697ebc09c36SJim Ingham             if (cmd_obj)
698ebc09c36SJim Ingham             {
699a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
700ebc09c36SJim Ingham                 {
701ebc09c36SJim Ingham                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
702ebc09c36SJim Ingham                                                   command_name);
703ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
704ebc09c36SJim Ingham                 }
705ebc09c36SJim Ingham                 else
706ebc09c36SJim Ingham                 {
707ebc09c36SJim Ingham 
708a7015092SGreg Clayton                     if (m_interpreter.RemoveAlias (command_name) == false)
709ebc09c36SJim Ingham                     {
710a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
711ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
712ebc09c36SJim Ingham                                                           command_name);
713ebc09c36SJim Ingham                         else
714ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
715ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
716ebc09c36SJim Ingham                     }
717ebc09c36SJim Ingham                     else
718ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
719ebc09c36SJim Ingham                 }
720ebc09c36SJim Ingham             }
721ebc09c36SJim Ingham             else
722ebc09c36SJim Ingham             {
723ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
724ebc09c36SJim Ingham                                               "current list of commands.\n",
725ebc09c36SJim Ingham                                              command_name);
726ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
727ebc09c36SJim Ingham             }
728ebc09c36SJim Ingham         }
729ebc09c36SJim Ingham         else
730ebc09c36SJim Ingham         {
731ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
732ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
733ebc09c36SJim Ingham         }
734ebc09c36SJim Ingham 
735ebc09c36SJim Ingham         return result.Succeeded();
736ebc09c36SJim Ingham     }
737ebc09c36SJim Ingham };
738ebc09c36SJim Ingham 
739de164aaaSGreg Clayton #pragma mark CommandObjectCommandsAddRegex
740de164aaaSGreg Clayton //-------------------------------------------------------------------------
741de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
742de164aaaSGreg Clayton //-------------------------------------------------------------------------
743de164aaaSGreg Clayton 
744de164aaaSGreg Clayton class CommandObjectCommandsAddRegex : public CommandObject
745de164aaaSGreg Clayton {
746de164aaaSGreg Clayton public:
747de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
748de164aaaSGreg Clayton         CommandObject (interpreter,
7490e5e5a79SGreg Clayton                        "command regex",
750de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
7510e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
752de164aaaSGreg Clayton         m_options (interpreter)
753de164aaaSGreg Clayton     {
7540e5e5a79SGreg Clayton         SetHelpLong(
7550e5e5a79SGreg Clayton "This command allows the user to create powerful regular expression commands\n"
7560e5e5a79SGreg Clayton "with substitutions. The regular expressions and substitutions are specified\n"
7570e5e5a79SGreg Clayton "using the regular exression substitution format of:\n"
7580e5e5a79SGreg Clayton "\n"
7590e5e5a79SGreg Clayton "    s/<regex>/<subst>/\n"
7600e5e5a79SGreg Clayton "\n"
7610e5e5a79SGreg Clayton "<regex> is a regular expression that can use parenthesis to capture regular\n"
7620e5e5a79SGreg Clayton "expression input and substitute the captured matches in the output using %1\n"
7630e5e5a79SGreg Clayton "for the first match, %2 for the second, and so on.\n"
7640e5e5a79SGreg Clayton "\n"
7650e5e5a79SGreg Clayton "The regular expressions can all be specified on the command line if more than\n"
7660e5e5a79SGreg Clayton "one argument is provided. If just the command name is provided on the command\n"
7670e5e5a79SGreg Clayton "line, then the regular expressions and substitutions can be entered on separate\n"
7680e5e5a79SGreg Clayton " lines, followed by an empty line to terminate the command definition.\n"
7690e5e5a79SGreg Clayton "\n"
7700e5e5a79SGreg Clayton "EXAMPLES\n"
7710e5e5a79SGreg Clayton "\n"
7720e5e5a79SGreg Clayton "The following example with define a regular expression command named 'f' that\n"
7730e5e5a79SGreg Clayton "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
7740e5e5a79SGreg Clayton "a number follows 'f':\n"
7750e5e5a79SGreg Clayton "(lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
7760e5e5a79SGreg Clayton                     );
777de164aaaSGreg Clayton     }
778de164aaaSGreg Clayton 
779de164aaaSGreg Clayton     ~CommandObjectCommandsAddRegex()
780de164aaaSGreg Clayton     {
781de164aaaSGreg Clayton     }
782de164aaaSGreg Clayton 
783de164aaaSGreg Clayton 
784de164aaaSGreg Clayton     bool
785de164aaaSGreg Clayton     Execute (Args& args, CommandReturnObject &result)
786de164aaaSGreg Clayton     {
7870e5e5a79SGreg Clayton         const size_t argc = args.GetArgumentCount();
7880e5e5a79SGreg Clayton         if (argc == 0)
789de164aaaSGreg Clayton         {
7900e5e5a79SGreg Clayton             result.AppendError ("usage: 'commands regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
7910e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
7920e5e5a79SGreg Clayton         }
7930e5e5a79SGreg Clayton         else
7940e5e5a79SGreg Clayton         {
7950e5e5a79SGreg Clayton             Error error;
796de164aaaSGreg Clayton             const char *name = args.GetArgumentAtIndex(0);
797de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
798de164aaaSGreg Clayton                                                                  name,
799de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
800de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
801de164aaaSGreg Clayton                                                                  10));
8020e5e5a79SGreg Clayton 
8030e5e5a79SGreg Clayton             if (argc == 1)
8040e5e5a79SGreg Clayton             {
8050e5e5a79SGreg Clayton                 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
806de164aaaSGreg Clayton                 if (reader_sp)
807de164aaaSGreg Clayton                 {
8080e5e5a79SGreg Clayton                     error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
809de164aaaSGreg Clayton                                                   this,                         // baton
810de164aaaSGreg Clayton                                                   eInputReaderGranularityLine,  // token size, to pass to callback function
8110e5e5a79SGreg Clayton                                                   NULL,                         // end token
812de164aaaSGreg Clayton                                                   "> ",                         // prompt
8130e5e5a79SGreg Clayton                                                   true);                        // echo input
8140e5e5a79SGreg Clayton                     if (error.Success())
815de164aaaSGreg Clayton                     {
816de164aaaSGreg Clayton                         m_interpreter.GetDebugger().PushInputReader (reader_sp);
817de164aaaSGreg Clayton                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
8180e5e5a79SGreg Clayton                         return true;
819de164aaaSGreg Clayton                     }
820de164aaaSGreg Clayton                 }
821de164aaaSGreg Clayton             }
822de164aaaSGreg Clayton             else
823de164aaaSGreg Clayton             {
8240e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
8250e5e5a79SGreg Clayton                 {
8260e5e5a79SGreg Clayton                     llvm::StringRef arg_strref (args.GetArgumentAtIndex(arg_idx));
8270e5e5a79SGreg Clayton                     error = AppendRegexSubstitution (arg_strref);
8280e5e5a79SGreg Clayton                     if (error.Fail())
8290e5e5a79SGreg Clayton                         break;
8300e5e5a79SGreg Clayton                 }
8310e5e5a79SGreg Clayton 
8320e5e5a79SGreg Clayton                 if (error.Success())
8330e5e5a79SGreg Clayton                 {
8340e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
8350e5e5a79SGreg Clayton                 }
8360e5e5a79SGreg Clayton             }
8370e5e5a79SGreg Clayton             if (error.Fail())
8380e5e5a79SGreg Clayton             {
8390e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
840de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
841de164aaaSGreg Clayton             }
8420e5e5a79SGreg Clayton         }
8430e5e5a79SGreg Clayton 
844de164aaaSGreg Clayton         return result.Succeeded();
845de164aaaSGreg Clayton     }
846de164aaaSGreg Clayton 
8470e5e5a79SGreg Clayton     Error
8480e5e5a79SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed)
849de164aaaSGreg Clayton     {
8500e5e5a79SGreg Clayton         Error error;
8510e5e5a79SGreg Clayton 
8520e5e5a79SGreg Clayton         if (m_regex_cmd_ap.get() == NULL)
853de164aaaSGreg Clayton         {
8540e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
8550e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8560e5e5a79SGreg Clayton                                            regex_sed.data());
8570e5e5a79SGreg Clayton             return error;
858de164aaaSGreg Clayton         }
8590e5e5a79SGreg Clayton 
8600e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
8610e5e5a79SGreg Clayton 
8620e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
8630e5e5a79SGreg Clayton         {
8640e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
8650e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8660e5e5a79SGreg Clayton                                            regex_sed.data());
8670e5e5a79SGreg Clayton             return error;
8680e5e5a79SGreg Clayton         }
8690e5e5a79SGreg Clayton 
8700e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
8710e5e5a79SGreg Clayton         {
8720e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
8730e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8740e5e5a79SGreg Clayton                                            regex_sed.data());
8750e5e5a79SGreg Clayton             return error;
8760e5e5a79SGreg Clayton         }
8770e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
8780e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
8790e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
8800e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
8810e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
8820e5e5a79SGreg Clayton 
8830e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
8840e5e5a79SGreg Clayton         {
8850e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
8860e5e5a79SGreg Clayton                                            separator_char,
8870e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
8880e5e5a79SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1));
8890e5e5a79SGreg Clayton             return error;
8900e5e5a79SGreg Clayton         }
8910e5e5a79SGreg Clayton 
8920e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
8930e5e5a79SGreg Clayton 
8940e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
8950e5e5a79SGreg Clayton         {
8960e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
8970e5e5a79SGreg Clayton                                            separator_char,
8980e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
8990e5e5a79SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1));
9000e5e5a79SGreg Clayton             return error;
9010e5e5a79SGreg Clayton         }
9020e5e5a79SGreg Clayton 
9030e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
9040e5e5a79SGreg Clayton         {
9050e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
9060e5e5a79SGreg Clayton             // separator char
9070e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
9080e5e5a79SGreg Clayton             {
9090e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
9100e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
9110e5e5a79SGreg Clayton                                                regex_sed.data(),
9120e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
9130e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
9140e5e5a79SGreg Clayton                 return error;
9150e5e5a79SGreg Clayton             }
9160e5e5a79SGreg Clayton 
9170e5e5a79SGreg Clayton         }
9180e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
9190e5e5a79SGreg Clayton         {
9200e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9210e5e5a79SGreg Clayton                                            separator_char,
9220e5e5a79SGreg Clayton                                            separator_char,
9230e5e5a79SGreg Clayton                                            separator_char,
9240e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9250e5e5a79SGreg Clayton                                            regex_sed.data());
9260e5e5a79SGreg Clayton             return error;
9270e5e5a79SGreg Clayton         }
9280e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
9290e5e5a79SGreg Clayton         {
9300e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9310e5e5a79SGreg Clayton                                            separator_char,
9320e5e5a79SGreg Clayton                                            separator_char,
9330e5e5a79SGreg Clayton                                            separator_char,
9340e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9350e5e5a79SGreg Clayton                                            regex_sed.data());
9360e5e5a79SGreg Clayton             return error;
9370e5e5a79SGreg Clayton         }
9380e5e5a79SGreg Clayton         std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
9390e5e5a79SGreg Clayton         std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
9400e5e5a79SGreg Clayton         m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
9410e5e5a79SGreg Clayton                                          subst.c_str());
9420e5e5a79SGreg Clayton         return error;
943de164aaaSGreg Clayton     }
944de164aaaSGreg Clayton 
945de164aaaSGreg Clayton     void
9460e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
947de164aaaSGreg Clayton     {
948de164aaaSGreg Clayton         if (m_regex_cmd_ap.get())
949de164aaaSGreg Clayton         {
950de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
951de164aaaSGreg Clayton             {
952de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
953de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
954de164aaaSGreg Clayton             }
955de164aaaSGreg Clayton         }
956de164aaaSGreg Clayton     }
957de164aaaSGreg Clayton 
9580e5e5a79SGreg Clayton     void
9590e5e5a79SGreg Clayton     InputReaderDidCancel()
9600e5e5a79SGreg Clayton     {
9610e5e5a79SGreg Clayton         m_regex_cmd_ap.reset();
9620e5e5a79SGreg Clayton     }
9630e5e5a79SGreg Clayton 
964de164aaaSGreg Clayton     static size_t
965de164aaaSGreg Clayton     InputReaderCallback (void *baton,
966de164aaaSGreg Clayton                          InputReader &reader,
967de164aaaSGreg Clayton                          lldb::InputReaderAction notification,
968de164aaaSGreg Clayton                          const char *bytes,
969de164aaaSGreg Clayton                          size_t bytes_len);
970de164aaaSGreg Clayton private:
971de164aaaSGreg Clayton     std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
972de164aaaSGreg Clayton 
973de164aaaSGreg Clayton      class CommandOptions : public Options
974de164aaaSGreg Clayton      {
975de164aaaSGreg Clayton      public:
976de164aaaSGreg Clayton 
977de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
978de164aaaSGreg Clayton             Options (interpreter)
979de164aaaSGreg Clayton          {
980de164aaaSGreg Clayton          }
981de164aaaSGreg Clayton 
982de164aaaSGreg Clayton          virtual
983de164aaaSGreg Clayton          ~CommandOptions (){}
984de164aaaSGreg Clayton 
985de164aaaSGreg Clayton          virtual Error
986de164aaaSGreg Clayton          SetOptionValue (uint32_t option_idx, const char *option_arg)
987de164aaaSGreg Clayton          {
988de164aaaSGreg Clayton              Error error;
989de164aaaSGreg Clayton              char short_option = (char) m_getopt_table[option_idx].val;
990de164aaaSGreg Clayton 
991de164aaaSGreg Clayton              switch (short_option)
992de164aaaSGreg Clayton              {
993de164aaaSGreg Clayton                  case 'h':
994de164aaaSGreg Clayton                      m_help.assign (option_arg);
995de164aaaSGreg Clayton                      break;
996de164aaaSGreg Clayton                  case 's':
997de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
998de164aaaSGreg Clayton                      break;
999de164aaaSGreg Clayton 
1000de164aaaSGreg Clayton                  default:
1001de164aaaSGreg Clayton                      error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1002de164aaaSGreg Clayton                      break;
1003de164aaaSGreg Clayton              }
1004de164aaaSGreg Clayton 
1005de164aaaSGreg Clayton              return error;
1006de164aaaSGreg Clayton          }
1007de164aaaSGreg Clayton 
1008de164aaaSGreg Clayton          void
1009de164aaaSGreg Clayton          OptionParsingStarting ()
1010de164aaaSGreg Clayton          {
1011de164aaaSGreg Clayton              m_help.clear();
1012de164aaaSGreg Clayton              m_syntax.clear();
1013de164aaaSGreg Clayton          }
1014de164aaaSGreg Clayton 
1015de164aaaSGreg Clayton          const OptionDefinition*
1016de164aaaSGreg Clayton          GetDefinitions ()
1017de164aaaSGreg Clayton          {
1018de164aaaSGreg Clayton              return g_option_table;
1019de164aaaSGreg Clayton          }
1020de164aaaSGreg Clayton 
1021de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1022de164aaaSGreg Clayton 
1023de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1024de164aaaSGreg Clayton 
1025de164aaaSGreg Clayton          const char *
1026de164aaaSGreg Clayton          GetHelp ()
1027de164aaaSGreg Clayton          {
1028de164aaaSGreg Clayton              if (m_help.empty())
1029de164aaaSGreg Clayton                  return NULL;
1030de164aaaSGreg Clayton              return m_help.c_str();
1031de164aaaSGreg Clayton          }
1032de164aaaSGreg Clayton          const char *
1033de164aaaSGreg Clayton          GetSyntax ()
1034de164aaaSGreg Clayton          {
1035de164aaaSGreg Clayton              if (m_syntax.empty())
1036de164aaaSGreg Clayton                  return NULL;
1037de164aaaSGreg Clayton              return m_syntax.c_str();
1038de164aaaSGreg Clayton          }
1039de164aaaSGreg Clayton          // Instance variables to hold the values for command options.
1040de164aaaSGreg Clayton      protected:
1041de164aaaSGreg Clayton          std::string m_help;
1042de164aaaSGreg Clayton          std::string m_syntax;
1043de164aaaSGreg Clayton      };
1044de164aaaSGreg Clayton 
1045de164aaaSGreg Clayton      CommandOptions m_options;
1046de164aaaSGreg Clayton 
1047de164aaaSGreg Clayton      virtual Options *
1048de164aaaSGreg Clayton      GetOptions ()
1049de164aaaSGreg Clayton      {
1050de164aaaSGreg Clayton          return &m_options;
1051de164aaaSGreg Clayton      }
1052de164aaaSGreg Clayton 
1053de164aaaSGreg Clayton };
1054de164aaaSGreg Clayton 
1055de164aaaSGreg Clayton size_t
1056de164aaaSGreg Clayton CommandObjectCommandsAddRegex::InputReaderCallback (void *baton,
1057de164aaaSGreg Clayton                                                     InputReader &reader,
1058de164aaaSGreg Clayton                                                     lldb::InputReaderAction notification,
1059de164aaaSGreg Clayton                                                     const char *bytes,
1060de164aaaSGreg Clayton                                                     size_t bytes_len)
1061de164aaaSGreg Clayton {
1062de164aaaSGreg Clayton     CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
1063d61c10bcSCaroline Tice     bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
1064de164aaaSGreg Clayton 
1065de164aaaSGreg Clayton     switch (notification)
1066de164aaaSGreg Clayton     {
1067de164aaaSGreg Clayton         case eInputReaderActivate:
1068d61c10bcSCaroline Tice             if (!batch_mode)
106915356e7fSCaroline Tice             {
107015356e7fSCaroline Tice                 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
107115356e7fSCaroline Tice                 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
107215356e7fSCaroline Tice                 out_stream->Flush();
107315356e7fSCaroline Tice             }
1074de164aaaSGreg Clayton             break;
1075de164aaaSGreg Clayton         case eInputReaderReactivate:
1076de164aaaSGreg Clayton             break;
1077de164aaaSGreg Clayton 
1078de164aaaSGreg Clayton         case eInputReaderDeactivate:
1079de164aaaSGreg Clayton             break;
1080de164aaaSGreg Clayton 
1081969ed3d1SCaroline Tice         case eInputReaderAsynchronousOutputWritten:
1082969ed3d1SCaroline Tice             break;
1083969ed3d1SCaroline Tice 
1084de164aaaSGreg Clayton         case eInputReaderGotToken:
10850e5e5a79SGreg Clayton             while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
10860e5e5a79SGreg Clayton                 --bytes_len;
1087de164aaaSGreg Clayton             if (bytes_len == 0)
1088de164aaaSGreg Clayton                 reader.SetIsDone(true);
1089de164aaaSGreg Clayton             else if (bytes)
1090de164aaaSGreg Clayton             {
10910e5e5a79SGreg Clayton                 llvm::StringRef bytes_strref (bytes, bytes_len);
10920e5e5a79SGreg Clayton                 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
10930e5e5a79SGreg Clayton                 if (error.Fail())
1094de164aaaSGreg Clayton                 {
1095d61c10bcSCaroline Tice                     if (!batch_mode)
1096d61c10bcSCaroline Tice                     {
109715356e7fSCaroline Tice                         StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
109815356e7fSCaroline Tice                         out_stream->Printf("error: %s\n", error.AsCString());
109915356e7fSCaroline Tice                         out_stream->Flush();
1100d61c10bcSCaroline Tice                     }
11010e5e5a79SGreg Clayton                     add_regex_cmd->InputReaderDidCancel ();
11020e5e5a79SGreg Clayton                     reader.SetIsDone (true);
1103de164aaaSGreg Clayton                 }
1104de164aaaSGreg Clayton             }
1105de164aaaSGreg Clayton             break;
1106de164aaaSGreg Clayton 
1107de164aaaSGreg Clayton         case eInputReaderInterrupt:
110815356e7fSCaroline Tice             {
1109de164aaaSGreg Clayton                 reader.SetIsDone (true);
1110d61c10bcSCaroline Tice                 if (!batch_mode)
1111d61c10bcSCaroline Tice                 {
111215356e7fSCaroline Tice                     StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
111315356e7fSCaroline Tice                     out_stream->PutCString("Regular expression command creations was cancelled.\n");
111415356e7fSCaroline Tice                     out_stream->Flush();
1115d61c10bcSCaroline Tice                 }
11160e5e5a79SGreg Clayton                 add_regex_cmd->InputReaderDidCancel ();
111715356e7fSCaroline Tice             }
1118de164aaaSGreg Clayton             break;
1119de164aaaSGreg Clayton 
1120de164aaaSGreg Clayton         case eInputReaderEndOfFile:
1121de164aaaSGreg Clayton             reader.SetIsDone (true);
1122de164aaaSGreg Clayton             break;
1123de164aaaSGreg Clayton 
1124de164aaaSGreg Clayton         case eInputReaderDone:
11250e5e5a79SGreg Clayton             add_regex_cmd->AddRegexCommandToInterpreter();
1126de164aaaSGreg Clayton             break;
1127de164aaaSGreg Clayton     }
1128de164aaaSGreg Clayton 
1129de164aaaSGreg Clayton     return bytes_len;
1130de164aaaSGreg Clayton }
1131de164aaaSGreg Clayton 
1132de164aaaSGreg Clayton 
1133de164aaaSGreg Clayton OptionDefinition
1134de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1135de164aaaSGreg Clayton {
1136de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "help"  , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1137de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1138de164aaaSGreg Clayton { 0             , false,  NULL   , 0  , 0                , NULL, 0, eArgTypeNone, NULL }
1139de164aaaSGreg Clayton };
1140de164aaaSGreg Clayton 
1141de164aaaSGreg Clayton 
1142*223383edSEnrico Granata class CommandObjectPythonFunction : public CommandObject
1143*223383edSEnrico Granata {
1144*223383edSEnrico Granata private:
1145*223383edSEnrico Granata     std::string m_function_name;
1146*223383edSEnrico Granata 
1147*223383edSEnrico Granata public:
1148*223383edSEnrico Granata 
1149*223383edSEnrico Granata     CommandObjectPythonFunction (CommandInterpreter &interpreter,
1150*223383edSEnrico Granata                                  std::string name,
1151*223383edSEnrico Granata                                  std::string funct) :
1152*223383edSEnrico Granata     CommandObject (interpreter,
1153*223383edSEnrico Granata                    name.c_str(),
1154*223383edSEnrico Granata                    (std::string("Run Python function ") + funct).c_str(),
1155*223383edSEnrico Granata                    NULL),
1156*223383edSEnrico Granata     m_function_name(funct)
1157*223383edSEnrico Granata     {
1158*223383edSEnrico Granata     }
1159*223383edSEnrico Granata 
1160*223383edSEnrico Granata     virtual
1161*223383edSEnrico Granata     ~CommandObjectPythonFunction ()
1162*223383edSEnrico Granata     {
1163*223383edSEnrico Granata     }
1164*223383edSEnrico Granata 
1165*223383edSEnrico Granata     virtual bool
1166*223383edSEnrico Granata     ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
1167*223383edSEnrico Granata     {
1168*223383edSEnrico Granata         ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter();
1169*223383edSEnrico Granata 
1170*223383edSEnrico Granata         Error error;
1171*223383edSEnrico Granata 
1172*223383edSEnrico Granata         if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(),
1173*223383edSEnrico Granata                                                          raw_command_line,
1174*223383edSEnrico Granata                                                          result,
1175*223383edSEnrico Granata                                                          error) == false)
1176*223383edSEnrico Granata         {
1177*223383edSEnrico Granata             result.AppendError(error.AsCString());
1178*223383edSEnrico Granata             result.SetStatus(eReturnStatusFailed);
1179*223383edSEnrico Granata         }
1180*223383edSEnrico Granata         else
1181*223383edSEnrico Granata             result.SetStatus(eReturnStatusSuccessFinishNoResult);
1182*223383edSEnrico Granata 
1183*223383edSEnrico Granata         return result.Succeeded();
1184*223383edSEnrico Granata     }
1185*223383edSEnrico Granata 
1186*223383edSEnrico Granata     virtual bool
1187*223383edSEnrico Granata     WantsRawCommandString ()
1188*223383edSEnrico Granata     {
1189*223383edSEnrico Granata         return true;
1190*223383edSEnrico Granata     }
1191*223383edSEnrico Granata 
1192*223383edSEnrico Granata     bool
1193*223383edSEnrico Granata     Execute (Args& command,
1194*223383edSEnrico Granata              CommandReturnObject &result)
1195*223383edSEnrico Granata     {
1196*223383edSEnrico Granata         std::string cmd_string;
1197*223383edSEnrico Granata         command.GetCommandString(cmd_string);
1198*223383edSEnrico Granata         return ExecuteRawCommandString(cmd_string.c_str(), result);
1199*223383edSEnrico Granata     }
1200*223383edSEnrico Granata 
1201*223383edSEnrico Granata     virtual bool
1202*223383edSEnrico Granata     IsRemovable() { return true; }
1203*223383edSEnrico Granata 
1204*223383edSEnrico Granata };
1205*223383edSEnrico Granata 
1206*223383edSEnrico Granata 
1207*223383edSEnrico Granata //-------------------------------------------------------------------------
1208*223383edSEnrico Granata // CommandObjectCommandsScriptAdd
1209*223383edSEnrico Granata //-------------------------------------------------------------------------
1210*223383edSEnrico Granata 
1211*223383edSEnrico Granata class CommandObjectCommandsScriptAdd : public CommandObject
1212*223383edSEnrico Granata {
1213*223383edSEnrico Granata private:
1214*223383edSEnrico Granata 
1215*223383edSEnrico Granata     class CommandOptions : public Options
1216*223383edSEnrico Granata     {
1217*223383edSEnrico Granata     public:
1218*223383edSEnrico Granata 
1219*223383edSEnrico Granata         CommandOptions (CommandInterpreter &interpreter) :
1220*223383edSEnrico Granata         Options (interpreter)
1221*223383edSEnrico Granata         {
1222*223383edSEnrico Granata         }
1223*223383edSEnrico Granata 
1224*223383edSEnrico Granata         virtual
1225*223383edSEnrico Granata         ~CommandOptions (){}
1226*223383edSEnrico Granata 
1227*223383edSEnrico Granata         virtual Error
1228*223383edSEnrico Granata         SetOptionValue (uint32_t option_idx, const char *option_arg)
1229*223383edSEnrico Granata         {
1230*223383edSEnrico Granata             Error error;
1231*223383edSEnrico Granata             char short_option = (char) m_getopt_table[option_idx].val;
1232*223383edSEnrico Granata 
1233*223383edSEnrico Granata             switch (short_option)
1234*223383edSEnrico Granata             {
1235*223383edSEnrico Granata                 case 'f':
1236*223383edSEnrico Granata                     m_funct_name = std::string(option_arg);
1237*223383edSEnrico Granata                     break;
1238*223383edSEnrico Granata                 default:
1239*223383edSEnrico Granata                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
1240*223383edSEnrico Granata                     break;
1241*223383edSEnrico Granata             }
1242*223383edSEnrico Granata 
1243*223383edSEnrico Granata             return error;
1244*223383edSEnrico Granata         }
1245*223383edSEnrico Granata 
1246*223383edSEnrico Granata         void
1247*223383edSEnrico Granata         OptionParsingStarting ()
1248*223383edSEnrico Granata         {
1249*223383edSEnrico Granata             m_funct_name = "";
1250*223383edSEnrico Granata         }
1251*223383edSEnrico Granata 
1252*223383edSEnrico Granata         const OptionDefinition*
1253*223383edSEnrico Granata         GetDefinitions ()
1254*223383edSEnrico Granata         {
1255*223383edSEnrico Granata             return g_option_table;
1256*223383edSEnrico Granata         }
1257*223383edSEnrico Granata 
1258*223383edSEnrico Granata         // Options table: Required for subclasses of Options.
1259*223383edSEnrico Granata 
1260*223383edSEnrico Granata         static OptionDefinition g_option_table[];
1261*223383edSEnrico Granata 
1262*223383edSEnrico Granata         // Instance variables to hold the values for command options.
1263*223383edSEnrico Granata 
1264*223383edSEnrico Granata         std::string m_funct_name;
1265*223383edSEnrico Granata     };
1266*223383edSEnrico Granata 
1267*223383edSEnrico Granata     CommandOptions m_options;
1268*223383edSEnrico Granata 
1269*223383edSEnrico Granata     virtual Options *
1270*223383edSEnrico Granata     GetOptions ()
1271*223383edSEnrico Granata     {
1272*223383edSEnrico Granata         return &m_options;
1273*223383edSEnrico Granata     }
1274*223383edSEnrico Granata 
1275*223383edSEnrico Granata     class PythonAliasReader : public InputReaderEZ
1276*223383edSEnrico Granata     {
1277*223383edSEnrico Granata     private:
1278*223383edSEnrico Granata         CommandInterpreter& m_interpreter;
1279*223383edSEnrico Granata         std::string m_cmd_name;
1280*223383edSEnrico Granata         StringList m_user_input;
1281*223383edSEnrico Granata         DISALLOW_COPY_AND_ASSIGN (PythonAliasReader);
1282*223383edSEnrico Granata     public:
1283*223383edSEnrico Granata         PythonAliasReader(Debugger& debugger,
1284*223383edSEnrico Granata                           CommandInterpreter& interpreter,
1285*223383edSEnrico Granata                           std::string cmd_name) :
1286*223383edSEnrico Granata         InputReaderEZ(debugger),
1287*223383edSEnrico Granata         m_interpreter(interpreter),
1288*223383edSEnrico Granata         m_cmd_name(cmd_name),
1289*223383edSEnrico Granata         m_user_input()
1290*223383edSEnrico Granata         {}
1291*223383edSEnrico Granata 
1292*223383edSEnrico Granata         virtual
1293*223383edSEnrico Granata         ~PythonAliasReader()
1294*223383edSEnrico Granata         {
1295*223383edSEnrico Granata         }
1296*223383edSEnrico Granata 
1297*223383edSEnrico Granata         virtual void ActivateHandler(HandlerData& data)
1298*223383edSEnrico Granata         {
1299*223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1300*223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1301*223383edSEnrico Granata             if (!batch_mode)
1302*223383edSEnrico Granata             {
1303*223383edSEnrico Granata                 out_stream->Printf ("%s\n", g_python_command_instructions);
1304*223383edSEnrico Granata                 if (data.reader.GetPrompt())
1305*223383edSEnrico Granata                     out_stream->Printf ("%s", data.reader.GetPrompt());
1306*223383edSEnrico Granata                 out_stream->Flush();
1307*223383edSEnrico Granata             }
1308*223383edSEnrico Granata         }
1309*223383edSEnrico Granata 
1310*223383edSEnrico Granata         virtual void ReactivateHandler(HandlerData& data)
1311*223383edSEnrico Granata         {
1312*223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1313*223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1314*223383edSEnrico Granata             if (data.reader.GetPrompt() && !batch_mode)
1315*223383edSEnrico Granata             {
1316*223383edSEnrico Granata                 out_stream->Printf ("%s", data.reader.GetPrompt());
1317*223383edSEnrico Granata                 out_stream->Flush();
1318*223383edSEnrico Granata             }
1319*223383edSEnrico Granata         }
1320*223383edSEnrico Granata         virtual void GotTokenHandler(HandlerData& data)
1321*223383edSEnrico Granata         {
1322*223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1323*223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1324*223383edSEnrico Granata             if (data.bytes && data.bytes_len)
1325*223383edSEnrico Granata             {
1326*223383edSEnrico Granata                 m_user_input.AppendString(data.bytes, data.bytes_len);
1327*223383edSEnrico Granata             }
1328*223383edSEnrico Granata             if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
1329*223383edSEnrico Granata             {
1330*223383edSEnrico Granata                 out_stream->Printf ("%s", data.reader.GetPrompt());
1331*223383edSEnrico Granata                 out_stream->Flush();
1332*223383edSEnrico Granata             }
1333*223383edSEnrico Granata         }
1334*223383edSEnrico Granata         virtual void InterruptHandler(HandlerData& data)
1335*223383edSEnrico Granata         {
1336*223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1337*223383edSEnrico Granata             bool batch_mode = data.GetBatchMode();
1338*223383edSEnrico Granata             data.reader.SetIsDone (true);
1339*223383edSEnrico Granata             if (!batch_mode)
1340*223383edSEnrico Granata             {
1341*223383edSEnrico Granata                 out_stream->Printf ("Warning: No command attached to breakpoint.\n");
1342*223383edSEnrico Granata                 out_stream->Flush();
1343*223383edSEnrico Granata             }
1344*223383edSEnrico Granata         }
1345*223383edSEnrico Granata         virtual void EOFHandler(HandlerData& data)
1346*223383edSEnrico Granata         {
1347*223383edSEnrico Granata             data.reader.SetIsDone (true);
1348*223383edSEnrico Granata         }
1349*223383edSEnrico Granata         virtual void DoneHandler(HandlerData& data)
1350*223383edSEnrico Granata         {
1351*223383edSEnrico Granata             StreamSP out_stream = data.GetOutStream();
1352*223383edSEnrico Granata 
1353*223383edSEnrico Granata             ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
1354*223383edSEnrico Granata             if (!interpreter)
1355*223383edSEnrico Granata             {
1356*223383edSEnrico Granata                 out_stream->Printf ("Internal error #1: no script attached.\n");
1357*223383edSEnrico Granata                 out_stream->Flush();
1358*223383edSEnrico Granata                 return;
1359*223383edSEnrico Granata             }
1360*223383edSEnrico Granata             StringList funct_name_sl;
1361*223383edSEnrico Granata             if (!interpreter->GenerateScriptAliasFunction (m_user_input,
1362*223383edSEnrico Granata                                                            funct_name_sl))
1363*223383edSEnrico Granata             {
1364*223383edSEnrico Granata                 out_stream->Printf ("Internal error #2: no script attached.\n");
1365*223383edSEnrico Granata                 out_stream->Flush();
1366*223383edSEnrico Granata                 return;
1367*223383edSEnrico Granata             }
1368*223383edSEnrico Granata             if (funct_name_sl.GetSize() == 0)
1369*223383edSEnrico Granata             {
1370*223383edSEnrico Granata                 out_stream->Printf ("Internal error #3: no script attached.\n");
1371*223383edSEnrico Granata                 out_stream->Flush();
1372*223383edSEnrico Granata                 return;
1373*223383edSEnrico Granata             }
1374*223383edSEnrico Granata             const char *funct_name = funct_name_sl.GetStringAtIndex(0);
1375*223383edSEnrico Granata             if (!funct_name || !funct_name[0])
1376*223383edSEnrico Granata             {
1377*223383edSEnrico Granata                 out_stream->Printf ("Internal error #4: no script attached.\n");
1378*223383edSEnrico Granata                 out_stream->Flush();
1379*223383edSEnrico Granata                 return;
1380*223383edSEnrico Granata             }
1381*223383edSEnrico Granata 
1382*223383edSEnrico Granata             // everything should be fine now, let's add this alias
1383*223383edSEnrico Granata 
1384*223383edSEnrico Granata             CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter,
1385*223383edSEnrico Granata                                                                            m_cmd_name,
1386*223383edSEnrico Granata                                                                            funct_name));
1387*223383edSEnrico Granata 
1388*223383edSEnrico Granata             if (!m_interpreter.AddUserCommand(m_cmd_name.c_str(), command_obj_sp, true))
1389*223383edSEnrico Granata             {
1390*223383edSEnrico Granata                 out_stream->Printf ("Internal error #5: no script attached.\n");
1391*223383edSEnrico Granata                 out_stream->Flush();
1392*223383edSEnrico Granata                 return;
1393*223383edSEnrico Granata             }
1394*223383edSEnrico Granata         }
1395*223383edSEnrico Granata     };
1396*223383edSEnrico Granata 
1397*223383edSEnrico Granata public:
1398*223383edSEnrico Granata     CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) :
1399*223383edSEnrico Granata     CommandObject (interpreter,
1400*223383edSEnrico Granata                    "command script add",
1401*223383edSEnrico Granata                    "Add a scripted function as an LLDB command.",
1402*223383edSEnrico Granata                    NULL),
1403*223383edSEnrico Granata     m_options (interpreter)
1404*223383edSEnrico Granata     {
1405*223383edSEnrico Granata         CommandArgumentEntry arg1;
1406*223383edSEnrico Granata         CommandArgumentData cmd_arg;
1407*223383edSEnrico Granata 
1408*223383edSEnrico Granata         // Define the first (and only) variant of this arg.
1409*223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
1410*223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
1411*223383edSEnrico Granata 
1412*223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
1413*223383edSEnrico Granata         arg1.push_back (cmd_arg);
1414*223383edSEnrico Granata 
1415*223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
1416*223383edSEnrico Granata         m_arguments.push_back (arg1);
1417*223383edSEnrico Granata     }
1418*223383edSEnrico Granata 
1419*223383edSEnrico Granata     ~CommandObjectCommandsScriptAdd ()
1420*223383edSEnrico Granata     {
1421*223383edSEnrico Granata     }
1422*223383edSEnrico Granata 
1423*223383edSEnrico Granata     bool
1424*223383edSEnrico Granata     Execute
1425*223383edSEnrico Granata     (
1426*223383edSEnrico Granata      Args& args,
1427*223383edSEnrico Granata      CommandReturnObject &result
1428*223383edSEnrico Granata      )
1429*223383edSEnrico Granata     {
1430*223383edSEnrico Granata         size_t argc = args.GetArgumentCount();
1431*223383edSEnrico Granata 
1432*223383edSEnrico Granata         if (argc != 1)
1433*223383edSEnrico Granata         {
1434*223383edSEnrico Granata             result.AppendError ("'command script add' requires one argument");
1435*223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1436*223383edSEnrico Granata             return false;
1437*223383edSEnrico Granata         }
1438*223383edSEnrico Granata 
1439*223383edSEnrico Granata         std::string cmd_name = args.GetArgumentAtIndex(0);
1440*223383edSEnrico Granata 
1441*223383edSEnrico Granata         if (m_options.m_funct_name.empty())
1442*223383edSEnrico Granata         {
1443*223383edSEnrico Granata             InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(),
1444*223383edSEnrico Granata                                                             m_interpreter,
1445*223383edSEnrico Granata                                                             cmd_name));
1446*223383edSEnrico Granata 
1447*223383edSEnrico Granata             if (reader_sp)
1448*223383edSEnrico Granata             {
1449*223383edSEnrico Granata 
1450*223383edSEnrico Granata                 InputReaderEZ::InitializationParameters ipr;
1451*223383edSEnrico Granata 
1452*223383edSEnrico Granata                 Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt("     ")));
1453*223383edSEnrico Granata                 if (err.Success())
1454*223383edSEnrico Granata                 {
1455*223383edSEnrico Granata                     m_interpreter.GetDebugger().PushInputReader (reader_sp);
1456*223383edSEnrico Granata                     result.SetStatus (eReturnStatusSuccessFinishNoResult);
1457*223383edSEnrico Granata                 }
1458*223383edSEnrico Granata                 else
1459*223383edSEnrico Granata                 {
1460*223383edSEnrico Granata                     result.AppendError (err.AsCString());
1461*223383edSEnrico Granata                     result.SetStatus (eReturnStatusFailed);
1462*223383edSEnrico Granata                 }
1463*223383edSEnrico Granata             }
1464*223383edSEnrico Granata             else
1465*223383edSEnrico Granata             {
1466*223383edSEnrico Granata                 result.AppendError("out of memory");
1467*223383edSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1468*223383edSEnrico Granata             }
1469*223383edSEnrico Granata         }
1470*223383edSEnrico Granata         else
1471*223383edSEnrico Granata         {
1472*223383edSEnrico Granata             CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, cmd_name, m_options.m_funct_name));
1473*223383edSEnrico Granata             if (m_interpreter.AddUserCommand(cmd_name.c_str(), new_cmd, true))
1474*223383edSEnrico Granata             {
1475*223383edSEnrico Granata                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1476*223383edSEnrico Granata             }
1477*223383edSEnrico Granata             else
1478*223383edSEnrico Granata             {
1479*223383edSEnrico Granata                 result.AppendError("cannot add command");
1480*223383edSEnrico Granata                 result.SetStatus (eReturnStatusFailed);
1481*223383edSEnrico Granata             }
1482*223383edSEnrico Granata         }
1483*223383edSEnrico Granata 
1484*223383edSEnrico Granata         return result.Succeeded();
1485*223383edSEnrico Granata 
1486*223383edSEnrico Granata     }
1487*223383edSEnrico Granata };
1488*223383edSEnrico Granata 
1489*223383edSEnrico Granata OptionDefinition
1490*223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] =
1491*223383edSEnrico Granata {
1492*223383edSEnrico Granata     { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypeName,        "Name of a Python function to use."},
1493*223383edSEnrico Granata     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1494*223383edSEnrico Granata };
1495*223383edSEnrico Granata 
1496*223383edSEnrico Granata //-------------------------------------------------------------------------
1497*223383edSEnrico Granata // CommandObjectCommandsScriptList
1498*223383edSEnrico Granata //-------------------------------------------------------------------------
1499*223383edSEnrico Granata 
1500*223383edSEnrico Granata class CommandObjectCommandsScriptList : public CommandObject
1501*223383edSEnrico Granata {
1502*223383edSEnrico Granata private:
1503*223383edSEnrico Granata 
1504*223383edSEnrico Granata public:
1505*223383edSEnrico Granata     CommandObjectCommandsScriptList(CommandInterpreter &interpreter) :
1506*223383edSEnrico Granata     CommandObject (interpreter,
1507*223383edSEnrico Granata                    "command script list",
1508*223383edSEnrico Granata                    "List defined scripted commands.",
1509*223383edSEnrico Granata                    NULL)
1510*223383edSEnrico Granata     {
1511*223383edSEnrico Granata     }
1512*223383edSEnrico Granata 
1513*223383edSEnrico Granata     ~CommandObjectCommandsScriptList ()
1514*223383edSEnrico Granata     {
1515*223383edSEnrico Granata     }
1516*223383edSEnrico Granata 
1517*223383edSEnrico Granata     bool
1518*223383edSEnrico Granata     Execute
1519*223383edSEnrico Granata     (
1520*223383edSEnrico Granata      Args& args,
1521*223383edSEnrico Granata      CommandReturnObject &result
1522*223383edSEnrico Granata      )
1523*223383edSEnrico Granata     {
1524*223383edSEnrico Granata 
1525*223383edSEnrico Granata         m_interpreter.GetHelp(result,
1526*223383edSEnrico Granata                               CommandInterpreter::eCommandTypesUserDef);
1527*223383edSEnrico Granata 
1528*223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
1529*223383edSEnrico Granata 
1530*223383edSEnrico Granata         return true;
1531*223383edSEnrico Granata 
1532*223383edSEnrico Granata 
1533*223383edSEnrico Granata     }
1534*223383edSEnrico Granata };
1535*223383edSEnrico Granata 
1536*223383edSEnrico Granata //-------------------------------------------------------------------------
1537*223383edSEnrico Granata // CommandObjectCommandsScriptClear
1538*223383edSEnrico Granata //-------------------------------------------------------------------------
1539*223383edSEnrico Granata 
1540*223383edSEnrico Granata class CommandObjectCommandsScriptClear : public CommandObject
1541*223383edSEnrico Granata {
1542*223383edSEnrico Granata private:
1543*223383edSEnrico Granata 
1544*223383edSEnrico Granata public:
1545*223383edSEnrico Granata     CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) :
1546*223383edSEnrico Granata     CommandObject (interpreter,
1547*223383edSEnrico Granata                    "command script clear",
1548*223383edSEnrico Granata                    "Delete all scripted commands.",
1549*223383edSEnrico Granata                    NULL)
1550*223383edSEnrico Granata     {
1551*223383edSEnrico Granata     }
1552*223383edSEnrico Granata 
1553*223383edSEnrico Granata     ~CommandObjectCommandsScriptClear ()
1554*223383edSEnrico Granata     {
1555*223383edSEnrico Granata     }
1556*223383edSEnrico Granata 
1557*223383edSEnrico Granata     bool
1558*223383edSEnrico Granata     Execute
1559*223383edSEnrico Granata     (
1560*223383edSEnrico Granata      Args& args,
1561*223383edSEnrico Granata      CommandReturnObject &result
1562*223383edSEnrico Granata      )
1563*223383edSEnrico Granata     {
1564*223383edSEnrico Granata 
1565*223383edSEnrico Granata         m_interpreter.RemoveAllUser();
1566*223383edSEnrico Granata 
1567*223383edSEnrico Granata         result.SetStatus (eReturnStatusSuccessFinishResult);
1568*223383edSEnrico Granata 
1569*223383edSEnrico Granata         return true;
1570*223383edSEnrico Granata 
1571*223383edSEnrico Granata 
1572*223383edSEnrico Granata     }
1573*223383edSEnrico Granata };
1574*223383edSEnrico Granata 
1575*223383edSEnrico Granata //-------------------------------------------------------------------------
1576*223383edSEnrico Granata // CommandObjectCommandsScriptDelete
1577*223383edSEnrico Granata //-------------------------------------------------------------------------
1578*223383edSEnrico Granata 
1579*223383edSEnrico Granata class CommandObjectCommandsScriptDelete : public CommandObject
1580*223383edSEnrico Granata {
1581*223383edSEnrico Granata private:
1582*223383edSEnrico Granata 
1583*223383edSEnrico Granata public:
1584*223383edSEnrico Granata     CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) :
1585*223383edSEnrico Granata     CommandObject (interpreter,
1586*223383edSEnrico Granata                    "command script delete",
1587*223383edSEnrico Granata                    "Delete a scripted command.",
1588*223383edSEnrico Granata                    NULL)
1589*223383edSEnrico Granata     {
1590*223383edSEnrico Granata         CommandArgumentEntry arg1;
1591*223383edSEnrico Granata         CommandArgumentData cmd_arg;
1592*223383edSEnrico Granata 
1593*223383edSEnrico Granata         // Define the first (and only) variant of this arg.
1594*223383edSEnrico Granata         cmd_arg.arg_type = eArgTypeCommandName;
1595*223383edSEnrico Granata         cmd_arg.arg_repetition = eArgRepeatPlain;
1596*223383edSEnrico Granata 
1597*223383edSEnrico Granata         // There is only one variant this argument could be; put it into the argument entry.
1598*223383edSEnrico Granata         arg1.push_back (cmd_arg);
1599*223383edSEnrico Granata 
1600*223383edSEnrico Granata         // Push the data for the first argument into the m_arguments vector.
1601*223383edSEnrico Granata         m_arguments.push_back (arg1);
1602*223383edSEnrico Granata     }
1603*223383edSEnrico Granata 
1604*223383edSEnrico Granata     ~CommandObjectCommandsScriptDelete ()
1605*223383edSEnrico Granata     {
1606*223383edSEnrico Granata     }
1607*223383edSEnrico Granata 
1608*223383edSEnrico Granata     bool
1609*223383edSEnrico Granata     Execute
1610*223383edSEnrico Granata     (
1611*223383edSEnrico Granata      Args& args,
1612*223383edSEnrico Granata      CommandReturnObject &result
1613*223383edSEnrico Granata      )
1614*223383edSEnrico Granata     {
1615*223383edSEnrico Granata 
1616*223383edSEnrico Granata         size_t argc = args.GetArgumentCount();
1617*223383edSEnrico Granata 
1618*223383edSEnrico Granata         if (argc != 1)
1619*223383edSEnrico Granata         {
1620*223383edSEnrico Granata             result.AppendError ("'command script delete' requires one argument");
1621*223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1622*223383edSEnrico Granata             return false;
1623*223383edSEnrico Granata         }
1624*223383edSEnrico Granata 
1625*223383edSEnrico Granata         const char* cmd_name = args.GetArgumentAtIndex(0);
1626*223383edSEnrico Granata 
1627*223383edSEnrico Granata         if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name))
1628*223383edSEnrico Granata         {
1629*223383edSEnrico Granata             m_interpreter.RemoveUser(cmd_name);
1630*223383edSEnrico Granata             result.SetStatus (eReturnStatusSuccessFinishResult);
1631*223383edSEnrico Granata         }
1632*223383edSEnrico Granata         else
1633*223383edSEnrico Granata         {
1634*223383edSEnrico Granata             result.AppendErrorWithFormat ("command %s not found", cmd_name);
1635*223383edSEnrico Granata             result.SetStatus (eReturnStatusFailed);
1636*223383edSEnrico Granata         }
1637*223383edSEnrico Granata 
1638*223383edSEnrico Granata         return result.Succeeded();
1639*223383edSEnrico Granata 
1640*223383edSEnrico Granata     }
1641*223383edSEnrico Granata };
1642*223383edSEnrico Granata 
1643*223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript
1644*223383edSEnrico Granata 
1645*223383edSEnrico Granata //-------------------------------------------------------------------------
1646*223383edSEnrico Granata // CommandObjectMultiwordCommandsScript
1647*223383edSEnrico Granata //-------------------------------------------------------------------------
1648*223383edSEnrico Granata 
1649*223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword
1650*223383edSEnrico Granata {
1651*223383edSEnrico Granata public:
1652*223383edSEnrico Granata     CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) :
1653*223383edSEnrico Granata     CommandObjectMultiword (interpreter,
1654*223383edSEnrico Granata                             "command script",
1655*223383edSEnrico Granata                             "A set of commands for managing or customizing script commands.",
1656*223383edSEnrico Granata                             "command script <subcommand> [<subcommand-options>]")
1657*223383edSEnrico Granata     {
1658*223383edSEnrico Granata         LoadSubCommand ("add",  CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter)));
1659*223383edSEnrico Granata         LoadSubCommand ("delete",   CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter)));
1660*223383edSEnrico Granata         LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter)));
1661*223383edSEnrico Granata         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectCommandsScriptList (interpreter)));
1662*223383edSEnrico Granata     }
1663*223383edSEnrico Granata 
1664*223383edSEnrico Granata     ~CommandObjectMultiwordCommandsScript ()
1665*223383edSEnrico Granata     {
1666*223383edSEnrico Granata     }
1667*223383edSEnrico Granata 
1668*223383edSEnrico Granata };
1669*223383edSEnrico Granata 
1670*223383edSEnrico Granata 
1671ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
1672ebc09c36SJim Ingham 
1673ebc09c36SJim Ingham //-------------------------------------------------------------------------
1674ebc09c36SJim Ingham // CommandObjectMultiwordCommands
1675ebc09c36SJim Ingham //-------------------------------------------------------------------------
1676ebc09c36SJim Ingham 
1677ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
1678a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
16790e5e5a79SGreg Clayton                             "command",
16803f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
16810e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
1682ebc09c36SJim Ingham {
1683a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1684a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1685a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
1686de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
1687a5a97ebeSJim Ingham     LoadSubCommand ("history",   CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
1688*223383edSEnrico Granata     LoadSubCommand ("script",   CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter)));
1689ebc09c36SJim Ingham }
1690ebc09c36SJim Ingham 
1691ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1692ebc09c36SJim Ingham {
1693ebc09c36SJim Ingham }
1694ebc09c36SJim Ingham 
1695