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"
20de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h"
21ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h"
22de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h"
23ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h"
24ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h"
25ebc09c36SJim Ingham 
26ebc09c36SJim Ingham using namespace lldb;
27ebc09c36SJim Ingham using namespace lldb_private;
28ebc09c36SJim Ingham 
29ebc09c36SJim Ingham //-------------------------------------------------------------------------
30ebc09c36SJim Ingham // CommandObjectCommandsSource
31ebc09c36SJim Ingham //-------------------------------------------------------------------------
32ebc09c36SJim Ingham 
33*a5a97ebeSJim Ingham class CommandObjectCommandsHistory : public CommandObject
34*a5a97ebeSJim Ingham {
35*a5a97ebeSJim Ingham private:
36*a5a97ebeSJim Ingham 
37*a5a97ebeSJim Ingham     class CommandOptions : public Options
38*a5a97ebeSJim Ingham     {
39*a5a97ebeSJim Ingham     public:
40*a5a97ebeSJim Ingham 
41*a5a97ebeSJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
42*a5a97ebeSJim Ingham             Options (interpreter)
43*a5a97ebeSJim Ingham         {
44*a5a97ebeSJim Ingham         }
45*a5a97ebeSJim Ingham 
46*a5a97ebeSJim Ingham         virtual
47*a5a97ebeSJim Ingham         ~CommandOptions (){}
48*a5a97ebeSJim Ingham 
49*a5a97ebeSJim Ingham         virtual Error
50*a5a97ebeSJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
51*a5a97ebeSJim Ingham         {
52*a5a97ebeSJim Ingham             Error error;
53*a5a97ebeSJim Ingham             char short_option = (char) m_getopt_table[option_idx].val;
54*a5a97ebeSJim Ingham             bool success;
55*a5a97ebeSJim Ingham 
56*a5a97ebeSJim Ingham             switch (short_option)
57*a5a97ebeSJim Ingham             {
58*a5a97ebeSJim Ingham                 case 'c':
59*a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success);
60*a5a97ebeSJim Ingham                     if (!success)
61*a5a97ebeSJim Ingham                         error.SetErrorStringWithFormat("Invalid value for count: %s.\n", option_arg);
62*a5a97ebeSJim Ingham                     if (m_end_idx != 0)
63*a5a97ebeSJim Ingham                         m_end_idx--;
64*a5a97ebeSJim Ingham                     m_start_idx = 0;
65*a5a97ebeSJim Ingham                     break;
66*a5a97ebeSJim Ingham                 case 'e':
67*a5a97ebeSJim Ingham                     m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
68*a5a97ebeSJim Ingham                     if (!success)
69*a5a97ebeSJim Ingham                         error.SetErrorStringWithFormat("Invalid value for end index: %s.\n", option_arg);
70*a5a97ebeSJim Ingham                     break;
71*a5a97ebeSJim Ingham                 case 's':
72*a5a97ebeSJim Ingham                     m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success);
73*a5a97ebeSJim Ingham                     if (!success)
74*a5a97ebeSJim Ingham                         error.SetErrorStringWithFormat("Invalid value for start index: %s.\n", option_arg);
75*a5a97ebeSJim Ingham                     break;
76*a5a97ebeSJim Ingham                 default:
77*a5a97ebeSJim Ingham                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
78*a5a97ebeSJim Ingham                     break;
79*a5a97ebeSJim Ingham             }
80*a5a97ebeSJim Ingham 
81*a5a97ebeSJim Ingham             return error;
82*a5a97ebeSJim Ingham         }
83*a5a97ebeSJim Ingham 
84*a5a97ebeSJim Ingham         void
85*a5a97ebeSJim Ingham         OptionParsingStarting ()
86*a5a97ebeSJim Ingham         {
87*a5a97ebeSJim Ingham             m_start_idx = 0;
88*a5a97ebeSJim Ingham             m_end_idx = UINT_MAX;
89*a5a97ebeSJim Ingham         }
90*a5a97ebeSJim Ingham 
91*a5a97ebeSJim Ingham         const OptionDefinition*
92*a5a97ebeSJim Ingham         GetDefinitions ()
93*a5a97ebeSJim Ingham         {
94*a5a97ebeSJim Ingham             return g_option_table;
95*a5a97ebeSJim Ingham         }
96*a5a97ebeSJim Ingham 
97*a5a97ebeSJim Ingham         // Options table: Required for subclasses of Options.
98*a5a97ebeSJim Ingham 
99*a5a97ebeSJim Ingham         static OptionDefinition g_option_table[];
100*a5a97ebeSJim Ingham 
101*a5a97ebeSJim Ingham         // Instance variables to hold the values for command options.
102*a5a97ebeSJim Ingham 
103*a5a97ebeSJim Ingham         uint32_t m_start_idx;
104*a5a97ebeSJim Ingham         uint32_t m_end_idx;
105*a5a97ebeSJim Ingham     };
106*a5a97ebeSJim Ingham 
107*a5a97ebeSJim Ingham     CommandOptions m_options;
108*a5a97ebeSJim Ingham 
109*a5a97ebeSJim Ingham     virtual Options *
110*a5a97ebeSJim Ingham     GetOptions ()
111*a5a97ebeSJim Ingham     {
112*a5a97ebeSJim Ingham         return &m_options;
113*a5a97ebeSJim Ingham     }
114*a5a97ebeSJim Ingham 
115*a5a97ebeSJim Ingham public:
116*a5a97ebeSJim Ingham     CommandObjectCommandsHistory(CommandInterpreter &interpreter) :
117*a5a97ebeSJim Ingham         CommandObject (interpreter,
118*a5a97ebeSJim Ingham                        "command history",
119*a5a97ebeSJim Ingham                        "Dump the history of commands in this session.",
120*a5a97ebeSJim Ingham                        NULL),
121*a5a97ebeSJim Ingham         m_options (interpreter)
122*a5a97ebeSJim Ingham     {
123*a5a97ebeSJim Ingham     }
124*a5a97ebeSJim Ingham 
125*a5a97ebeSJim Ingham     ~CommandObjectCommandsHistory ()
126*a5a97ebeSJim Ingham     {
127*a5a97ebeSJim Ingham     }
128*a5a97ebeSJim Ingham 
129*a5a97ebeSJim Ingham     bool
130*a5a97ebeSJim Ingham     Execute
131*a5a97ebeSJim Ingham     (
132*a5a97ebeSJim Ingham         Args& args,
133*a5a97ebeSJim Ingham         CommandReturnObject &result
134*a5a97ebeSJim Ingham     )
135*a5a97ebeSJim Ingham     {
136*a5a97ebeSJim Ingham 
137*a5a97ebeSJim Ingham         m_interpreter.DumpHistory (result.GetOutputStream(),
138*a5a97ebeSJim Ingham                                    m_options.m_start_idx,
139*a5a97ebeSJim Ingham                                    m_options.m_end_idx);
140*a5a97ebeSJim Ingham         return result.Succeeded();
141*a5a97ebeSJim Ingham 
142*a5a97ebeSJim Ingham     }
143*a5a97ebeSJim Ingham };
144*a5a97ebeSJim Ingham 
145*a5a97ebeSJim Ingham OptionDefinition
146*a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] =
147*a5a97ebeSJim Ingham {
148*a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger,        "How many history commands to print."},
149*a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger,  "Index at which to start printing history commands."},
150*a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger,    "Index at which to stop printing history commands."},
151*a5a97ebeSJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
152*a5a97ebeSJim Ingham };
153*a5a97ebeSJim Ingham 
154*a5a97ebeSJim Ingham 
155*a5a97ebeSJim Ingham //-------------------------------------------------------------------------
156*a5a97ebeSJim Ingham // CommandObjectCommandsSource
157*a5a97ebeSJim Ingham //-------------------------------------------------------------------------
158*a5a97ebeSJim Ingham 
159ebc09c36SJim Ingham class CommandObjectCommandsSource : public CommandObject
160ebc09c36SJim Ingham {
161e16c50a1SJim Ingham private:
162e16c50a1SJim Ingham 
163e16c50a1SJim Ingham     class CommandOptions : public Options
164e16c50a1SJim Ingham     {
165e16c50a1SJim Ingham     public:
166e16c50a1SJim Ingham 
167eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
168eb0103f2SGreg Clayton             Options (interpreter)
169eb0103f2SGreg Clayton         {
170eb0103f2SGreg Clayton         }
171e16c50a1SJim Ingham 
172e16c50a1SJim Ingham         virtual
173e16c50a1SJim Ingham         ~CommandOptions (){}
174e16c50a1SJim Ingham 
175e16c50a1SJim Ingham         virtual Error
176f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
177e16c50a1SJim Ingham         {
178e16c50a1SJim Ingham             Error error;
179e16c50a1SJim Ingham             char short_option = (char) m_getopt_table[option_idx].val;
180e16c50a1SJim Ingham             bool success;
181e16c50a1SJim Ingham 
182e16c50a1SJim Ingham             switch (short_option)
183e16c50a1SJim Ingham             {
184e16c50a1SJim Ingham                 case 'e':
185e16c50a1SJim Ingham                     m_stop_on_error = Args::StringToBoolean(option_arg, true, &success);
186e16c50a1SJim Ingham                     if (!success)
187e16c50a1SJim Ingham                         error.SetErrorStringWithFormat("Invalid value for stop-on-error: %s.\n", option_arg);
188e16c50a1SJim Ingham                     break;
189e16c50a1SJim Ingham                 case 'c':
190e16c50a1SJim Ingham                     m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success);
191e16c50a1SJim Ingham                     if (!success)
192e16c50a1SJim Ingham                         error.SetErrorStringWithFormat("Invalid value for stop-on-continue: %s.\n", option_arg);
193e16c50a1SJim Ingham                     break;
194e16c50a1SJim Ingham                 default:
195e16c50a1SJim Ingham                     error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
196e16c50a1SJim Ingham                     break;
197e16c50a1SJim Ingham             }
198e16c50a1SJim Ingham 
199e16c50a1SJim Ingham             return error;
200e16c50a1SJim Ingham         }
201e16c50a1SJim Ingham 
202e16c50a1SJim Ingham         void
203f6b8b581SGreg Clayton         OptionParsingStarting ()
204e16c50a1SJim Ingham         {
205e16c50a1SJim Ingham             m_stop_on_error = true;
206e16c50a1SJim Ingham             m_stop_on_continue = true;
207e16c50a1SJim Ingham         }
208e16c50a1SJim Ingham 
209e0d378b3SGreg Clayton         const OptionDefinition*
210e16c50a1SJim Ingham         GetDefinitions ()
211e16c50a1SJim Ingham         {
212e16c50a1SJim Ingham             return g_option_table;
213e16c50a1SJim Ingham         }
214e16c50a1SJim Ingham 
215e16c50a1SJim Ingham         // Options table: Required for subclasses of Options.
216e16c50a1SJim Ingham 
217e0d378b3SGreg Clayton         static OptionDefinition g_option_table[];
218e16c50a1SJim Ingham 
219e16c50a1SJim Ingham         // Instance variables to hold the values for command options.
220e16c50a1SJim Ingham 
221e16c50a1SJim Ingham         bool m_stop_on_error;
222e16c50a1SJim Ingham         bool m_stop_on_continue;
223e16c50a1SJim Ingham     };
224e16c50a1SJim Ingham 
225e16c50a1SJim Ingham     CommandOptions m_options;
226e16c50a1SJim Ingham 
227e16c50a1SJim Ingham     virtual Options *
228e16c50a1SJim Ingham     GetOptions ()
229e16c50a1SJim Ingham     {
230e16c50a1SJim Ingham         return &m_options;
231e16c50a1SJim Ingham     }
232e16c50a1SJim Ingham 
233ebc09c36SJim Ingham public:
234a7015092SGreg Clayton     CommandObjectCommandsSource(CommandInterpreter &interpreter) :
235a7015092SGreg Clayton         CommandObject (interpreter,
2360e5e5a79SGreg Clayton                        "command source",
237e3d26315SCaroline Tice                        "Read in debugger commands from the file <filename> and execute them.",
238eb0103f2SGreg Clayton                        NULL),
239eb0103f2SGreg Clayton         m_options (interpreter)
240ebc09c36SJim Ingham     {
241405fe67fSCaroline Tice         CommandArgumentEntry arg;
242405fe67fSCaroline Tice         CommandArgumentData file_arg;
243405fe67fSCaroline Tice 
244405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
245405fe67fSCaroline Tice         file_arg.arg_type = eArgTypeFilename;
246405fe67fSCaroline Tice         file_arg.arg_repetition = eArgRepeatPlain;
247405fe67fSCaroline Tice 
248405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
249405fe67fSCaroline Tice         arg.push_back (file_arg);
250405fe67fSCaroline Tice 
251405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
252405fe67fSCaroline Tice         m_arguments.push_back (arg);
253ebc09c36SJim Ingham     }
254ebc09c36SJim Ingham 
255ebc09c36SJim Ingham     ~CommandObjectCommandsSource ()
256ebc09c36SJim Ingham     {
257ebc09c36SJim Ingham     }
258ebc09c36SJim Ingham 
259ebc09c36SJim Ingham     bool
260ebc09c36SJim Ingham     Execute
261ebc09c36SJim Ingham     (
262ebc09c36SJim Ingham         Args& args,
263ebc09c36SJim Ingham         CommandReturnObject &result
264ebc09c36SJim Ingham     )
265ebc09c36SJim Ingham     {
266ebc09c36SJim Ingham         const int argc = args.GetArgumentCount();
267ebc09c36SJim Ingham         if (argc == 1)
268ebc09c36SJim Ingham         {
269ebc09c36SJim Ingham             const char *filename = args.GetArgumentAtIndex(0);
270ebc09c36SJim Ingham 
271ebc09c36SJim Ingham             result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename);
272ebc09c36SJim Ingham 
2731ee3853fSJohnny Chen             FileSpec cmd_file (filename, true);
274e16c50a1SJim Ingham             ExecutionContext *exe_ctx = NULL;  // Just use the default context.
275e16c50a1SJim Ingham             bool echo_commands    = true;
276e16c50a1SJim Ingham             bool print_results    = true;
277ebc09c36SJim Ingham 
278e16c50a1SJim Ingham             m_interpreter.HandleCommandsFromFile (cmd_file,
279e16c50a1SJim Ingham                                                   exe_ctx,
280e16c50a1SJim Ingham                                                   m_options.m_stop_on_continue,
281e16c50a1SJim Ingham                                                   m_options.m_stop_on_error,
282e16c50a1SJim Ingham                                                   echo_commands,
283e16c50a1SJim Ingham                                                   print_results,
284e16c50a1SJim Ingham                                                   result);
285ebc09c36SJim Ingham         }
286ebc09c36SJim Ingham         else
287ebc09c36SJim Ingham         {
288ebc09c36SJim Ingham             result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName());
289ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
290ebc09c36SJim Ingham         }
291ebc09c36SJim Ingham         return result.Succeeded();
292ebc09c36SJim Ingham 
293ebc09c36SJim Ingham     }
294ebc09c36SJim Ingham };
295ebc09c36SJim Ingham 
296e0d378b3SGreg Clayton OptionDefinition
297e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] =
298e16c50a1SJim Ingham {
299e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean,    "If true, stop executing commands on error."},
300e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."},
301e16c50a1SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
302e16c50a1SJim Ingham };
303e16c50a1SJim Ingham 
304ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias
305ebc09c36SJim Ingham //-------------------------------------------------------------------------
306ebc09c36SJim Ingham // CommandObjectCommandsAlias
307ebc09c36SJim Ingham //-------------------------------------------------------------------------
308ebc09c36SJim Ingham 
309ebc09c36SJim Ingham class CommandObjectCommandsAlias : public CommandObject
310ebc09c36SJim Ingham {
311ebc09c36SJim Ingham public:
312a7015092SGreg Clayton     CommandObjectCommandsAlias (CommandInterpreter &interpreter) :
313a7015092SGreg Clayton         CommandObject (interpreter,
3140e5e5a79SGreg Clayton                        "command alias",
315e3d26315SCaroline Tice                        "Allow users to define their own debugger command abbreviations.",
316405fe67fSCaroline Tice                        NULL)
317ebc09c36SJim Ingham     {
318ebc09c36SJim Ingham         SetHelpLong(
319ebc09c36SJim Ingham     "'alias' allows the user to create a short-cut or abbreviation for long \n\
320ebc09c36SJim Ingham     commands, multi-word commands, and commands that take particular options. \n\
321ebc09c36SJim Ingham     Below are some simple examples of how one might use the 'alias' command: \n\
32209799af6SCaroline Tice     \n    'commands alias sc script'           // Creates the abbreviation 'sc' for the 'script' \n\
323ebc09c36SJim Ingham                                          // command. \n\
32409799af6SCaroline Tice     'commands alias bp breakpoint'       // Creates the abbreviation 'bp' for the 'breakpoint' \n\
325ebc09c36SJim Ingham                                          // command.  Since breakpoint commands are two-word \n\
326ebc09c36SJim Ingham                                          // commands, the user will still need to enter the \n\
327ebc09c36SJim Ingham                                          // second word after 'bp', e.g. 'bp enable' or \n\
328ebc09c36SJim Ingham                                          // 'bp delete'. \n\
32909799af6SCaroline Tice     'commands alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\
330ebc09c36SJim Ingham                                          // two-word command 'breakpoint list'. \n\
331ebc09c36SJim Ingham     \nAn alias can include some options for the command, with the values either \n\
332ebc09c36SJim Ingham     filled in at the time the alias is created, or specified as positional \n\
333ebc09c36SJim Ingham     arguments, to be filled in when the alias is invoked.  The following example \n\
334ebc09c36SJim Ingham     shows how to create aliases with options: \n\
335ebc09c36SJim Ingham     \n\
33609799af6SCaroline Tice     'commands alias bfl breakpoint set -f %1 -l %2' \n\
337ebc09c36SJim Ingham     \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\
338ebc09c36SJim Ingham     options already part of the alias.  So if the user wants to set a breakpoint \n\
339ebc09c36SJim Ingham     by file and line without explicitly having to use the -f and -l options, the \n\
340ebc09c36SJim Ingham     user can now use 'bfl' instead.  The '%1' and '%2' are positional placeholders \n\
341ebc09c36SJim Ingham     for the actual arguments that will be passed when the alias command is used. \n\
342ebc09c36SJim Ingham     The number in the placeholder refers to the position/order the actual value \n\
343ebc09c36SJim Ingham     occupies when the alias is used.  So all the occurrences of '%1' in the alias \n\
344ebc09c36SJim Ingham     will be replaced with the first argument, all the occurrences of '%2' in the \n\
345ebc09c36SJim Ingham     alias will be replaced with the second argument, and so on.  This also allows \n\
346ebc09c36SJim Ingham     actual arguments to be used multiple times within an alias (see 'process \n\
347ebc09c36SJim Ingham     launch' example below).  So in the 'bfl' case, the actual file value will be \n\
348ebc09c36SJim Ingham     filled in with the first argument following 'bfl' and the actual line number \n\
349ebc09c36SJim Ingham     value will be filled in with the second argument.  The user would use this \n\
350ebc09c36SJim Ingham     alias as follows: \n\
35109799af6SCaroline Tice     \n    (lldb)  commands alias bfl breakpoint set -f %1 -l %2 \n\
352ebc09c36SJim Ingham     <... some time later ...> \n\
35309799af6SCaroline Tice     (lldb)  bfl my-file.c 137 \n\
354ebc09c36SJim Ingham     \nThis would be the same as if the user had entered \n\
355ebc09c36SJim Ingham     'breakpoint set -f my-file.c -l 137'. \n\
356ebc09c36SJim Ingham     \nAnother example: \n\
35709799af6SCaroline Tice     \n    (lldb)  commands alias pltty  process launch -s -o %1 -e %1 \n\
35809799af6SCaroline Tice     (lldb)  pltty /dev/tty0 \n\
359ebc09c36SJim Ingham            // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\
360ebc09c36SJim Ingham     \nIf the user always wanted to pass the same value to a particular option, the \n\
361ebc09c36SJim Ingham     alias could be defined with that value directly in the alias as a constant, \n\
362ebc09c36SJim Ingham     rather than using a positional placeholder: \n\
3630708e2c2SSean Callanan     \n    commands alias bl3  breakpoint set -f %1 -l 3  // Always sets a breakpoint on line \n\
364ebc09c36SJim Ingham                                                    // 3 of whatever file is indicated. \n");
365ebc09c36SJim Ingham 
366405fe67fSCaroline Tice         CommandArgumentEntry arg1;
367405fe67fSCaroline Tice         CommandArgumentEntry arg2;
368405fe67fSCaroline Tice         CommandArgumentEntry arg3;
369405fe67fSCaroline Tice         CommandArgumentData alias_arg;
370405fe67fSCaroline Tice         CommandArgumentData cmd_arg;
371405fe67fSCaroline Tice         CommandArgumentData options_arg;
372405fe67fSCaroline Tice 
373405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
374405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
375405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
376405fe67fSCaroline Tice 
377405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
378405fe67fSCaroline Tice         arg1.push_back (alias_arg);
379405fe67fSCaroline Tice 
380405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
381405fe67fSCaroline Tice         cmd_arg.arg_type = eArgTypeCommandName;
382405fe67fSCaroline Tice         cmd_arg.arg_repetition = eArgRepeatPlain;
383405fe67fSCaroline Tice 
384405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
385405fe67fSCaroline Tice         arg2.push_back (cmd_arg);
386405fe67fSCaroline Tice 
387405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
388405fe67fSCaroline Tice         options_arg.arg_type = eArgTypeAliasOptions;
389405fe67fSCaroline Tice         options_arg.arg_repetition = eArgRepeatOptional;
390405fe67fSCaroline Tice 
391405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
392405fe67fSCaroline Tice         arg3.push_back (options_arg);
393405fe67fSCaroline Tice 
394405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
395405fe67fSCaroline Tice         m_arguments.push_back (arg1);
396405fe67fSCaroline Tice         m_arguments.push_back (arg2);
397405fe67fSCaroline Tice         m_arguments.push_back (arg3);
398ebc09c36SJim Ingham     }
399ebc09c36SJim Ingham 
400ebc09c36SJim Ingham     ~CommandObjectCommandsAlias ()
401ebc09c36SJim Ingham     {
402ebc09c36SJim Ingham     }
403ebc09c36SJim Ingham 
404844d2303SCaroline Tice     bool
405844d2303SCaroline Tice     WantsRawCommandString ()
406844d2303SCaroline Tice     {
407844d2303SCaroline Tice         return true;
408844d2303SCaroline Tice     }
409844d2303SCaroline Tice 
410844d2303SCaroline Tice     bool
411844d2303SCaroline Tice     ExecuteRawCommandString (const char *raw_command_line, CommandReturnObject &result)
412844d2303SCaroline Tice     {
413844d2303SCaroline Tice         Args args (raw_command_line);
414844d2303SCaroline Tice         std::string raw_command_string (raw_command_line);
415844d2303SCaroline Tice 
416844d2303SCaroline Tice         size_t argc = args.GetArgumentCount();
417844d2303SCaroline Tice 
418844d2303SCaroline Tice         if (argc < 2)
419844d2303SCaroline Tice         {
420844d2303SCaroline Tice             result.AppendError ("'alias' requires at least two arguments");
421844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
422844d2303SCaroline Tice             return false;
423844d2303SCaroline Tice         }
424844d2303SCaroline Tice 
425844d2303SCaroline Tice         // Get the alias command.
426844d2303SCaroline Tice 
427844d2303SCaroline Tice         const std::string alias_command = args.GetArgumentAtIndex (0);
428844d2303SCaroline Tice 
429844d2303SCaroline Tice         // Strip the new alias name off 'raw_command_string'  (leave it on args, which gets passed to 'Execute', which
430844d2303SCaroline Tice         // does the stripping itself.
431844d2303SCaroline Tice         size_t pos = raw_command_string.find (alias_command);
432844d2303SCaroline Tice         if (pos == 0)
433844d2303SCaroline Tice         {
434844d2303SCaroline Tice             raw_command_string = raw_command_string.substr (alias_command.size());
435844d2303SCaroline Tice             pos = raw_command_string.find_first_not_of (' ');
436844d2303SCaroline Tice             if ((pos != std::string::npos) && (pos > 0))
437844d2303SCaroline Tice                 raw_command_string = raw_command_string.substr (pos);
438844d2303SCaroline Tice         }
439844d2303SCaroline Tice         else
440844d2303SCaroline Tice         {
441844d2303SCaroline Tice             result.AppendError ("Error parsing command string.  No alias created.");
442844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
443844d2303SCaroline Tice             return false;
444844d2303SCaroline Tice         }
445844d2303SCaroline Tice 
446844d2303SCaroline Tice 
447844d2303SCaroline Tice         // Verify that the command is alias-able.
448844d2303SCaroline Tice         if (m_interpreter.CommandExists (alias_command.c_str()))
449844d2303SCaroline Tice         {
450844d2303SCaroline Tice             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
451844d2303SCaroline Tice                                           alias_command.c_str());
452844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
453844d2303SCaroline Tice             return false;
454844d2303SCaroline Tice         }
455844d2303SCaroline Tice 
456844d2303SCaroline Tice         // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string.
457844d2303SCaroline Tice         // raw_command_string is returned with the name of the command object stripped off the front.
458844d2303SCaroline Tice         CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string);
459844d2303SCaroline Tice 
460844d2303SCaroline Tice         if (!cmd_obj)
461844d2303SCaroline Tice         {
462844d2303SCaroline Tice             result.AppendErrorWithFormat ("Invalid command given to 'alias'. '%s' does not begin with a valid command."
463844d2303SCaroline Tice                                           "  No alias created.", raw_command_string.c_str());
464844d2303SCaroline Tice             result.SetStatus (eReturnStatusFailed);
465844d2303SCaroline Tice             return false;
466844d2303SCaroline Tice         }
467844d2303SCaroline Tice         else if (!cmd_obj->WantsRawCommandString ())
468844d2303SCaroline Tice         {
469844d2303SCaroline Tice             // Note that args was initialized with the original command, and has not been updated to this point.
470844d2303SCaroline Tice             // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias.
471844d2303SCaroline Tice             return Execute (args, result);
472844d2303SCaroline Tice         }
473844d2303SCaroline Tice         else
474844d2303SCaroline Tice         {
475844d2303SCaroline Tice             // Verify & handle any options/arguments passed to the alias command
476844d2303SCaroline Tice 
477844d2303SCaroline Tice             OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
478844d2303SCaroline Tice             OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
479844d2303SCaroline Tice 
480ca90c47eSCaroline Tice             CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
481844d2303SCaroline Tice 
482ca90c47eSCaroline Tice             if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp))
483844d2303SCaroline Tice             {
484844d2303SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
485ca90c47eSCaroline Tice                 result.SetStatus (eReturnStatusFailed);
486844d2303SCaroline Tice                 return false;
487844d2303SCaroline Tice             }
488844d2303SCaroline Tice 
489844d2303SCaroline Tice             // Create the alias
490844d2303SCaroline Tice             if (m_interpreter.AliasExists (alias_command.c_str())
491844d2303SCaroline Tice                 || m_interpreter.UserCommandExists (alias_command.c_str()))
492844d2303SCaroline Tice             {
493844d2303SCaroline Tice                 OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
494844d2303SCaroline Tice                 if (temp_option_arg_sp.get())
495844d2303SCaroline Tice                 {
496844d2303SCaroline Tice                     if (option_arg_vector->size() == 0)
497844d2303SCaroline Tice                         m_interpreter.RemoveAliasOptions (alias_command.c_str());
498844d2303SCaroline Tice                 }
499844d2303SCaroline Tice                 result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
500844d2303SCaroline Tice                                                 alias_command.c_str());
501844d2303SCaroline Tice             }
502844d2303SCaroline Tice 
503472362e6SCaroline Tice             if (cmd_obj_sp)
504472362e6SCaroline Tice             {
505844d2303SCaroline Tice                 m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp);
506844d2303SCaroline Tice                 if (option_arg_vector->size() > 0)
507844d2303SCaroline Tice                     m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
508844d2303SCaroline Tice                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
509844d2303SCaroline Tice             }
510472362e6SCaroline Tice             else
511472362e6SCaroline Tice             {
512472362e6SCaroline Tice                 result.AppendError ("Unable to create requested alias.\n");
513472362e6SCaroline Tice                 result.SetStatus (eReturnStatusFailed);
514472362e6SCaroline Tice             }
515472362e6SCaroline Tice         }
516844d2303SCaroline Tice         return result.Succeeded();
517844d2303SCaroline Tice     }
518ebc09c36SJim Ingham 
519ebc09c36SJim Ingham     bool
520ebc09c36SJim Ingham     Execute
521ebc09c36SJim Ingham     (
522ebc09c36SJim Ingham         Args& args,
523ebc09c36SJim Ingham         CommandReturnObject &result
524ebc09c36SJim Ingham     )
525ebc09c36SJim Ingham     {
526867b185dSCaroline Tice         size_t argc = args.GetArgumentCount();
527ebc09c36SJim Ingham 
528ebc09c36SJim Ingham         if (argc < 2)
529ebc09c36SJim Ingham         {
530ebc09c36SJim Ingham             result.AppendError ("'alias' requires at least two arguments");
531ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
532ebc09c36SJim Ingham             return false;
533ebc09c36SJim Ingham         }
534ebc09c36SJim Ingham 
535ebc09c36SJim Ingham         const std::string alias_command = args.GetArgumentAtIndex(0);
536ebc09c36SJim Ingham         const std::string actual_command = args.GetArgumentAtIndex(1);
537ebc09c36SJim Ingham 
538ebc09c36SJim Ingham         args.Shift();  // Shift the alias command word off the argument vector.
539ebc09c36SJim Ingham         args.Shift();  // Shift the old command word off the argument vector.
540ebc09c36SJim Ingham 
541ebc09c36SJim Ingham         // Verify that the command is alias'able, and get the appropriate command object.
542ebc09c36SJim Ingham 
543a7015092SGreg Clayton         if (m_interpreter.CommandExists (alias_command.c_str()))
544ebc09c36SJim Ingham         {
545ebc09c36SJim Ingham             result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n",
546ebc09c36SJim Ingham                                          alias_command.c_str());
547ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
548ebc09c36SJim Ingham         }
549ebc09c36SJim Ingham         else
550ebc09c36SJim Ingham         {
551a7015092SGreg Clayton              CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true));
552ebc09c36SJim Ingham              CommandObjectSP subcommand_obj_sp;
553ebc09c36SJim Ingham              bool use_subcommand = false;
554ebc09c36SJim Ingham              if (command_obj_sp.get())
555ebc09c36SJim Ingham              {
556ebc09c36SJim Ingham                  CommandObject *cmd_obj = command_obj_sp.get();
557c982c768SGreg Clayton                  CommandObject *sub_cmd_obj = NULL;
558ebc09c36SJim Ingham                  OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector);
559ebc09c36SJim Ingham                  OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
560ebc09c36SJim Ingham 
561844d2303SCaroline Tice                  while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0)
562ebc09c36SJim Ingham                  {
563ebc09c36SJim Ingham                      if (argc >= 3)
564ebc09c36SJim Ingham                      {
565ebc09c36SJim Ingham                          const std::string sub_command = args.GetArgumentAtIndex(0);
566ebc09c36SJim Ingham                          assert (sub_command.length() != 0);
567ebc09c36SJim Ingham                          subcommand_obj_sp =
568ebc09c36SJim Ingham                                            (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str()));
569ebc09c36SJim Ingham                          if (subcommand_obj_sp.get())
570ebc09c36SJim Ingham                          {
571ebc09c36SJim Ingham                              sub_cmd_obj = subcommand_obj_sp.get();
572ebc09c36SJim Ingham                              use_subcommand = true;
573ebc09c36SJim Ingham                              args.Shift();  // Shift the sub_command word off the argument vector.
574844d2303SCaroline Tice                              cmd_obj = sub_cmd_obj;
575ebc09c36SJim Ingham                          }
576ebc09c36SJim Ingham                          else
577ebc09c36SJim Ingham                          {
578f415eeb4SCaroline Tice                              result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'.  "
579f415eeb4SCaroline Tice                                                           "Unable to create alias.\n",
580f415eeb4SCaroline Tice                                                           sub_command.c_str(), actual_command.c_str());
581ebc09c36SJim Ingham                              result.SetStatus (eReturnStatusFailed);
582ebc09c36SJim Ingham                              return false;
583ebc09c36SJim Ingham                          }
584ebc09c36SJim Ingham                      }
585ebc09c36SJim Ingham                  }
586ebc09c36SJim Ingham 
587ebc09c36SJim Ingham                  // Verify & handle any options/arguments passed to the alias command
588ebc09c36SJim Ingham 
589ebc09c36SJim Ingham                  if (args.GetArgumentCount () > 0)
590ebc09c36SJim Ingham                  {
591ca90c47eSCaroline Tice                     CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false);
592ebc09c36SJim Ingham                     if (use_subcommand)
593ca90c47eSCaroline Tice                         tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false);
594ca90c47eSCaroline Tice 
595ca90c47eSCaroline Tice                     std::string args_string;
596ca90c47eSCaroline Tice                     args.GetCommandString (args_string);
597ca90c47eSCaroline Tice 
598ca90c47eSCaroline Tice                     if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp))
599ebc09c36SJim Ingham                     {
600ca90c47eSCaroline Tice                         result.AppendError ("Unable to create requested alias.\n");
601ca90c47eSCaroline Tice                         result.SetStatus (eReturnStatusFailed);
602e7941795SCaroline Tice                         return false;
603867b185dSCaroline Tice                     }
604867b185dSCaroline Tice                  }
605867b185dSCaroline Tice 
606ebc09c36SJim Ingham                  // Create the alias.
607ebc09c36SJim Ingham 
608a7015092SGreg Clayton                  if (m_interpreter.AliasExists (alias_command.c_str())
609a7015092SGreg Clayton                      || m_interpreter.UserCommandExists (alias_command.c_str()))
610ebc09c36SJim Ingham                  {
611a7015092SGreg Clayton                      OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str()));
612ebc09c36SJim Ingham                      if (tmp_option_arg_sp.get())
613ebc09c36SJim Ingham                      {
614ebc09c36SJim Ingham                          if (option_arg_vector->size() == 0)
615a7015092SGreg Clayton                              m_interpreter.RemoveAliasOptions (alias_command.c_str());
616ebc09c36SJim Ingham                      }
617ebc09c36SJim Ingham                      result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n",
618ebc09c36SJim Ingham                                                      alias_command.c_str());
619ebc09c36SJim Ingham                  }
620ebc09c36SJim Ingham 
621ebc09c36SJim Ingham                  if (use_subcommand)
622a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp);
623ebc09c36SJim Ingham                  else
624a7015092SGreg Clayton                      m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp);
625ebc09c36SJim Ingham                  if (option_arg_vector->size() > 0)
626a7015092SGreg Clayton                      m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp);
627ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusSuccessFinishNoResult);
628ebc09c36SJim Ingham              }
629ebc09c36SJim Ingham              else
630ebc09c36SJim Ingham              {
631ebc09c36SJim Ingham                  result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str());
632ebc09c36SJim Ingham                  result.SetStatus (eReturnStatusFailed);
633e7941795SCaroline Tice                  return false;
634ebc09c36SJim Ingham              }
635ebc09c36SJim Ingham         }
636ebc09c36SJim Ingham 
637ebc09c36SJim Ingham         return result.Succeeded();
638ebc09c36SJim Ingham     }
639ebc09c36SJim Ingham };
640ebc09c36SJim Ingham 
641ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias
642ebc09c36SJim Ingham //-------------------------------------------------------------------------
643ebc09c36SJim Ingham // CommandObjectCommandsUnalias
644ebc09c36SJim Ingham //-------------------------------------------------------------------------
645ebc09c36SJim Ingham 
646ebc09c36SJim Ingham class CommandObjectCommandsUnalias : public CommandObject
647ebc09c36SJim Ingham {
648ebc09c36SJim Ingham public:
649a7015092SGreg Clayton     CommandObjectCommandsUnalias (CommandInterpreter &interpreter) :
650a7015092SGreg Clayton         CommandObject (interpreter,
6510e5e5a79SGreg Clayton                        "command unalias",
65286ddae50SCaroline Tice                        "Allow the user to remove/delete a user-defined command abbreviation.",
653405fe67fSCaroline Tice                        NULL)
654ebc09c36SJim Ingham     {
655405fe67fSCaroline Tice         CommandArgumentEntry arg;
656405fe67fSCaroline Tice         CommandArgumentData alias_arg;
657405fe67fSCaroline Tice 
658405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
659405fe67fSCaroline Tice         alias_arg.arg_type = eArgTypeAliasName;
660405fe67fSCaroline Tice         alias_arg.arg_repetition = eArgRepeatPlain;
661405fe67fSCaroline Tice 
662405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
663405fe67fSCaroline Tice         arg.push_back (alias_arg);
664405fe67fSCaroline Tice 
665405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
666405fe67fSCaroline Tice         m_arguments.push_back (arg);
667ebc09c36SJim Ingham     }
668ebc09c36SJim Ingham 
669ebc09c36SJim Ingham     ~CommandObjectCommandsUnalias()
670ebc09c36SJim Ingham     {
671ebc09c36SJim Ingham     }
672ebc09c36SJim Ingham 
673ebc09c36SJim Ingham 
674ebc09c36SJim Ingham     bool
675ebc09c36SJim Ingham     Execute
676ebc09c36SJim Ingham     (
677ebc09c36SJim Ingham         Args& args,
678ebc09c36SJim Ingham         CommandReturnObject &result
679ebc09c36SJim Ingham     )
680ebc09c36SJim Ingham     {
681ebc09c36SJim Ingham         CommandObject::CommandMap::iterator pos;
682ebc09c36SJim Ingham         CommandObject *cmd_obj;
683ebc09c36SJim Ingham 
684ebc09c36SJim Ingham         if (args.GetArgumentCount() != 0)
685ebc09c36SJim Ingham         {
686ebc09c36SJim Ingham             const char *command_name = args.GetArgumentAtIndex(0);
687a7015092SGreg Clayton             cmd_obj = m_interpreter.GetCommandObject(command_name);
688ebc09c36SJim Ingham             if (cmd_obj)
689ebc09c36SJim Ingham             {
690a7015092SGreg Clayton                 if (m_interpreter.CommandExists (command_name))
691ebc09c36SJim Ingham                 {
692ebc09c36SJim Ingham                     result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n",
693ebc09c36SJim Ingham                                                   command_name);
694ebc09c36SJim Ingham                     result.SetStatus (eReturnStatusFailed);
695ebc09c36SJim Ingham                 }
696ebc09c36SJim Ingham                 else
697ebc09c36SJim Ingham                 {
698ebc09c36SJim Ingham 
699a7015092SGreg Clayton                     if (m_interpreter.RemoveAlias (command_name) == false)
700ebc09c36SJim Ingham                     {
701a7015092SGreg Clayton                         if (m_interpreter.AliasExists (command_name))
702ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n",
703ebc09c36SJim Ingham                                                           command_name);
704ebc09c36SJim Ingham                         else
705ebc09c36SJim Ingham                             result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name);
706ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusFailed);
707ebc09c36SJim Ingham                     }
708ebc09c36SJim Ingham                     else
709ebc09c36SJim Ingham                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
710ebc09c36SJim Ingham                 }
711ebc09c36SJim Ingham             }
712ebc09c36SJim Ingham             else
713ebc09c36SJim Ingham             {
714ebc09c36SJim Ingham                 result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a "
715ebc09c36SJim Ingham                                               "current list of commands.\n",
716ebc09c36SJim Ingham                                              command_name);
717ebc09c36SJim Ingham                 result.SetStatus (eReturnStatusFailed);
718ebc09c36SJim Ingham             }
719ebc09c36SJim Ingham         }
720ebc09c36SJim Ingham         else
721ebc09c36SJim Ingham         {
722ebc09c36SJim Ingham             result.AppendError ("must call 'unalias' with a valid alias");
723ebc09c36SJim Ingham             result.SetStatus (eReturnStatusFailed);
724ebc09c36SJim Ingham         }
725ebc09c36SJim Ingham 
726ebc09c36SJim Ingham         return result.Succeeded();
727ebc09c36SJim Ingham     }
728ebc09c36SJim Ingham };
729ebc09c36SJim Ingham 
730de164aaaSGreg Clayton #pragma mark CommandObjectCommandsAddRegex
731de164aaaSGreg Clayton //-------------------------------------------------------------------------
732de164aaaSGreg Clayton // CommandObjectCommandsAddRegex
733de164aaaSGreg Clayton //-------------------------------------------------------------------------
734de164aaaSGreg Clayton 
735de164aaaSGreg Clayton class CommandObjectCommandsAddRegex : public CommandObject
736de164aaaSGreg Clayton {
737de164aaaSGreg Clayton public:
738de164aaaSGreg Clayton     CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) :
739de164aaaSGreg Clayton         CommandObject (interpreter,
7400e5e5a79SGreg Clayton                        "command regex",
741de164aaaSGreg Clayton                        "Allow the user to create a regular expression command.",
7420e5e5a79SGreg Clayton                        "command regex <cmd-name> [s/<regex>/<subst>/ ...]"),
743de164aaaSGreg Clayton         m_options (interpreter)
744de164aaaSGreg Clayton     {
7450e5e5a79SGreg Clayton         SetHelpLong(
7460e5e5a79SGreg Clayton "This command allows the user to create powerful regular expression commands\n"
7470e5e5a79SGreg Clayton "with substitutions. The regular expressions and substitutions are specified\n"
7480e5e5a79SGreg Clayton "using the regular exression substitution format of:\n"
7490e5e5a79SGreg Clayton "\n"
7500e5e5a79SGreg Clayton "    s/<regex>/<subst>/\n"
7510e5e5a79SGreg Clayton "\n"
7520e5e5a79SGreg Clayton "<regex> is a regular expression that can use parenthesis to capture regular\n"
7530e5e5a79SGreg Clayton "expression input and substitute the captured matches in the output using %1\n"
7540e5e5a79SGreg Clayton "for the first match, %2 for the second, and so on.\n"
7550e5e5a79SGreg Clayton "\n"
7560e5e5a79SGreg Clayton "The regular expressions can all be specified on the command line if more than\n"
7570e5e5a79SGreg Clayton "one argument is provided. If just the command name is provided on the command\n"
7580e5e5a79SGreg Clayton "line, then the regular expressions and substitutions can be entered on separate\n"
7590e5e5a79SGreg Clayton " lines, followed by an empty line to terminate the command definition.\n"
7600e5e5a79SGreg Clayton "\n"
7610e5e5a79SGreg Clayton "EXAMPLES\n"
7620e5e5a79SGreg Clayton "\n"
7630e5e5a79SGreg Clayton "The following example with define a regular expression command named 'f' that\n"
7640e5e5a79SGreg Clayton "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n"
7650e5e5a79SGreg Clayton "a number follows 'f':\n"
7660e5e5a79SGreg Clayton "(lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n"
7670e5e5a79SGreg Clayton                     );
768de164aaaSGreg Clayton     }
769de164aaaSGreg Clayton 
770de164aaaSGreg Clayton     ~CommandObjectCommandsAddRegex()
771de164aaaSGreg Clayton     {
772de164aaaSGreg Clayton     }
773de164aaaSGreg Clayton 
774de164aaaSGreg Clayton 
775de164aaaSGreg Clayton     bool
776de164aaaSGreg Clayton     Execute (Args& args, CommandReturnObject &result)
777de164aaaSGreg Clayton     {
7780e5e5a79SGreg Clayton         const size_t argc = args.GetArgumentCount();
7790e5e5a79SGreg Clayton         if (argc == 0)
780de164aaaSGreg Clayton         {
7810e5e5a79SGreg Clayton             result.AppendError ("usage: 'commands regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n");
7820e5e5a79SGreg Clayton             result.SetStatus (eReturnStatusFailed);
7830e5e5a79SGreg Clayton         }
7840e5e5a79SGreg Clayton         else
7850e5e5a79SGreg Clayton         {
7860e5e5a79SGreg Clayton             Error error;
787de164aaaSGreg Clayton             const char *name = args.GetArgumentAtIndex(0);
788de164aaaSGreg Clayton             m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter,
789de164aaaSGreg Clayton                                                                  name,
790de164aaaSGreg Clayton                                                                  m_options.GetHelp (),
791de164aaaSGreg Clayton                                                                  m_options.GetSyntax (),
792de164aaaSGreg Clayton                                                                  10));
7930e5e5a79SGreg Clayton 
7940e5e5a79SGreg Clayton             if (argc == 1)
7950e5e5a79SGreg Clayton             {
7960e5e5a79SGreg Clayton                 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
797de164aaaSGreg Clayton                 if (reader_sp)
798de164aaaSGreg Clayton                 {
7990e5e5a79SGreg Clayton                     error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback,
800de164aaaSGreg Clayton                                                   this,                         // baton
801de164aaaSGreg Clayton                                                   eInputReaderGranularityLine,  // token size, to pass to callback function
8020e5e5a79SGreg Clayton                                                   NULL,                         // end token
803de164aaaSGreg Clayton                                                   "> ",                         // prompt
8040e5e5a79SGreg Clayton                                                   true);                        // echo input
8050e5e5a79SGreg Clayton                     if (error.Success())
806de164aaaSGreg Clayton                     {
807de164aaaSGreg Clayton                         m_interpreter.GetDebugger().PushInputReader (reader_sp);
808de164aaaSGreg Clayton                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
8090e5e5a79SGreg Clayton                         return true;
810de164aaaSGreg Clayton                     }
811de164aaaSGreg Clayton                 }
812de164aaaSGreg Clayton             }
813de164aaaSGreg Clayton             else
814de164aaaSGreg Clayton             {
8150e5e5a79SGreg Clayton                 for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx)
8160e5e5a79SGreg Clayton                 {
8170e5e5a79SGreg Clayton                     llvm::StringRef arg_strref (args.GetArgumentAtIndex(arg_idx));
8180e5e5a79SGreg Clayton                     error = AppendRegexSubstitution (arg_strref);
8190e5e5a79SGreg Clayton                     if (error.Fail())
8200e5e5a79SGreg Clayton                         break;
8210e5e5a79SGreg Clayton                 }
8220e5e5a79SGreg Clayton 
8230e5e5a79SGreg Clayton                 if (error.Success())
8240e5e5a79SGreg Clayton                 {
8250e5e5a79SGreg Clayton                     AddRegexCommandToInterpreter();
8260e5e5a79SGreg Clayton                 }
8270e5e5a79SGreg Clayton             }
8280e5e5a79SGreg Clayton             if (error.Fail())
8290e5e5a79SGreg Clayton             {
8300e5e5a79SGreg Clayton                 result.AppendError (error.AsCString());
831de164aaaSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
832de164aaaSGreg Clayton             }
8330e5e5a79SGreg Clayton         }
8340e5e5a79SGreg Clayton 
835de164aaaSGreg Clayton         return result.Succeeded();
836de164aaaSGreg Clayton     }
837de164aaaSGreg Clayton 
8380e5e5a79SGreg Clayton     Error
8390e5e5a79SGreg Clayton     AppendRegexSubstitution (const llvm::StringRef &regex_sed)
840de164aaaSGreg Clayton     {
8410e5e5a79SGreg Clayton         Error error;
8420e5e5a79SGreg Clayton 
8430e5e5a79SGreg Clayton         if (m_regex_cmd_ap.get() == NULL)
844de164aaaSGreg Clayton         {
8450e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'",
8460e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8470e5e5a79SGreg Clayton                                            regex_sed.data());
8480e5e5a79SGreg Clayton             return error;
849de164aaaSGreg Clayton         }
8500e5e5a79SGreg Clayton 
8510e5e5a79SGreg Clayton         size_t regex_sed_size = regex_sed.size();
8520e5e5a79SGreg Clayton 
8530e5e5a79SGreg Clayton         if (regex_sed_size <= 1)
8540e5e5a79SGreg Clayton         {
8550e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'",
8560e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8570e5e5a79SGreg Clayton                                            regex_sed.data());
8580e5e5a79SGreg Clayton             return error;
8590e5e5a79SGreg Clayton         }
8600e5e5a79SGreg Clayton 
8610e5e5a79SGreg Clayton         if (regex_sed[0] != 's')
8620e5e5a79SGreg Clayton         {
8630e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'",
8640e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
8650e5e5a79SGreg Clayton                                            regex_sed.data());
8660e5e5a79SGreg Clayton             return error;
8670e5e5a79SGreg Clayton         }
8680e5e5a79SGreg Clayton         const size_t first_separator_char_pos = 1;
8690e5e5a79SGreg Clayton         // use the char that follows 's' as the regex separator character
8700e5e5a79SGreg Clayton         // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|"
8710e5e5a79SGreg Clayton         const char separator_char = regex_sed[first_separator_char_pos];
8720e5e5a79SGreg Clayton         const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1);
8730e5e5a79SGreg Clayton 
8740e5e5a79SGreg Clayton         if (second_separator_char_pos == std::string::npos)
8750e5e5a79SGreg Clayton         {
8760e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'",
8770e5e5a79SGreg Clayton                                            separator_char,
8780e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - first_separator_char_pos - 1),
8790e5e5a79SGreg Clayton                                            regex_sed.data() + (first_separator_char_pos + 1));
8800e5e5a79SGreg Clayton             return error;
8810e5e5a79SGreg Clayton         }
8820e5e5a79SGreg Clayton 
8830e5e5a79SGreg Clayton         const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1);
8840e5e5a79SGreg Clayton 
8850e5e5a79SGreg Clayton         if (third_separator_char_pos == std::string::npos)
8860e5e5a79SGreg Clayton         {
8870e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'",
8880e5e5a79SGreg Clayton                                            separator_char,
8890e5e5a79SGreg Clayton                                            (int)(regex_sed.size() - second_separator_char_pos - 1),
8900e5e5a79SGreg Clayton                                            regex_sed.data() + (second_separator_char_pos + 1));
8910e5e5a79SGreg Clayton             return error;
8920e5e5a79SGreg Clayton         }
8930e5e5a79SGreg Clayton 
8940e5e5a79SGreg Clayton         if (third_separator_char_pos != regex_sed_size - 1)
8950e5e5a79SGreg Clayton         {
8960e5e5a79SGreg Clayton             // Make sure that everything that follows the last regex
8970e5e5a79SGreg Clayton             // separator char
8980e5e5a79SGreg Clayton             if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos)
8990e5e5a79SGreg Clayton             {
9000e5e5a79SGreg Clayton                 error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'",
9010e5e5a79SGreg Clayton                                                (int)third_separator_char_pos + 1,
9020e5e5a79SGreg Clayton                                                regex_sed.data(),
9030e5e5a79SGreg Clayton                                                (int)(regex_sed.size() - third_separator_char_pos - 1),
9040e5e5a79SGreg Clayton                                                regex_sed.data() + (third_separator_char_pos + 1));
9050e5e5a79SGreg Clayton                 return error;
9060e5e5a79SGreg Clayton             }
9070e5e5a79SGreg Clayton 
9080e5e5a79SGreg Clayton         }
9090e5e5a79SGreg Clayton         else if (first_separator_char_pos + 1 == second_separator_char_pos)
9100e5e5a79SGreg Clayton         {
9110e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9120e5e5a79SGreg Clayton                                            separator_char,
9130e5e5a79SGreg Clayton                                            separator_char,
9140e5e5a79SGreg Clayton                                            separator_char,
9150e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9160e5e5a79SGreg Clayton                                            regex_sed.data());
9170e5e5a79SGreg Clayton             return error;
9180e5e5a79SGreg Clayton         }
9190e5e5a79SGreg Clayton         else if (second_separator_char_pos + 1 == third_separator_char_pos)
9200e5e5a79SGreg Clayton         {
9210e5e5a79SGreg Clayton             error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'",
9220e5e5a79SGreg Clayton                                            separator_char,
9230e5e5a79SGreg Clayton                                            separator_char,
9240e5e5a79SGreg Clayton                                            separator_char,
9250e5e5a79SGreg Clayton                                            (int)regex_sed.size(),
9260e5e5a79SGreg Clayton                                            regex_sed.data());
9270e5e5a79SGreg Clayton             return error;
9280e5e5a79SGreg Clayton         }
9290e5e5a79SGreg Clayton         std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1));
9300e5e5a79SGreg Clayton         std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1));
9310e5e5a79SGreg Clayton         m_regex_cmd_ap->AddRegexCommand (regex.c_str(),
9320e5e5a79SGreg Clayton                                          subst.c_str());
9330e5e5a79SGreg Clayton         return error;
934de164aaaSGreg Clayton     }
935de164aaaSGreg Clayton 
936de164aaaSGreg Clayton     void
9370e5e5a79SGreg Clayton     AddRegexCommandToInterpreter()
938de164aaaSGreg Clayton     {
939de164aaaSGreg Clayton         if (m_regex_cmd_ap.get())
940de164aaaSGreg Clayton         {
941de164aaaSGreg Clayton             if (m_regex_cmd_ap->HasRegexEntries())
942de164aaaSGreg Clayton             {
943de164aaaSGreg Clayton                 CommandObjectSP cmd_sp (m_regex_cmd_ap.release());
944de164aaaSGreg Clayton                 m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true);
945de164aaaSGreg Clayton             }
946de164aaaSGreg Clayton         }
947de164aaaSGreg Clayton     }
948de164aaaSGreg Clayton 
9490e5e5a79SGreg Clayton     void
9500e5e5a79SGreg Clayton     InputReaderDidCancel()
9510e5e5a79SGreg Clayton     {
9520e5e5a79SGreg Clayton         m_regex_cmd_ap.reset();
9530e5e5a79SGreg Clayton     }
9540e5e5a79SGreg Clayton 
955de164aaaSGreg Clayton     static size_t
956de164aaaSGreg Clayton     InputReaderCallback (void *baton,
957de164aaaSGreg Clayton                          InputReader &reader,
958de164aaaSGreg Clayton                          lldb::InputReaderAction notification,
959de164aaaSGreg Clayton                          const char *bytes,
960de164aaaSGreg Clayton                          size_t bytes_len);
961de164aaaSGreg Clayton private:
962de164aaaSGreg Clayton     std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap;
963de164aaaSGreg Clayton 
964de164aaaSGreg Clayton      class CommandOptions : public Options
965de164aaaSGreg Clayton      {
966de164aaaSGreg Clayton      public:
967de164aaaSGreg Clayton 
968de164aaaSGreg Clayton          CommandOptions (CommandInterpreter &interpreter) :
969de164aaaSGreg Clayton             Options (interpreter)
970de164aaaSGreg Clayton          {
971de164aaaSGreg Clayton          }
972de164aaaSGreg Clayton 
973de164aaaSGreg Clayton          virtual
974de164aaaSGreg Clayton          ~CommandOptions (){}
975de164aaaSGreg Clayton 
976de164aaaSGreg Clayton          virtual Error
977de164aaaSGreg Clayton          SetOptionValue (uint32_t option_idx, const char *option_arg)
978de164aaaSGreg Clayton          {
979de164aaaSGreg Clayton              Error error;
980de164aaaSGreg Clayton              char short_option = (char) m_getopt_table[option_idx].val;
981de164aaaSGreg Clayton 
982de164aaaSGreg Clayton              switch (short_option)
983de164aaaSGreg Clayton              {
984de164aaaSGreg Clayton                  case 'h':
985de164aaaSGreg Clayton                      m_help.assign (option_arg);
986de164aaaSGreg Clayton                      break;
987de164aaaSGreg Clayton                  case 's':
988de164aaaSGreg Clayton                      m_syntax.assign (option_arg);
989de164aaaSGreg Clayton                      break;
990de164aaaSGreg Clayton 
991de164aaaSGreg Clayton                  default:
992de164aaaSGreg Clayton                      error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
993de164aaaSGreg Clayton                      break;
994de164aaaSGreg Clayton              }
995de164aaaSGreg Clayton 
996de164aaaSGreg Clayton              return error;
997de164aaaSGreg Clayton          }
998de164aaaSGreg Clayton 
999de164aaaSGreg Clayton          void
1000de164aaaSGreg Clayton          OptionParsingStarting ()
1001de164aaaSGreg Clayton          {
1002de164aaaSGreg Clayton              m_help.clear();
1003de164aaaSGreg Clayton              m_syntax.clear();
1004de164aaaSGreg Clayton          }
1005de164aaaSGreg Clayton 
1006de164aaaSGreg Clayton          const OptionDefinition*
1007de164aaaSGreg Clayton          GetDefinitions ()
1008de164aaaSGreg Clayton          {
1009de164aaaSGreg Clayton              return g_option_table;
1010de164aaaSGreg Clayton          }
1011de164aaaSGreg Clayton 
1012de164aaaSGreg Clayton          // Options table: Required for subclasses of Options.
1013de164aaaSGreg Clayton 
1014de164aaaSGreg Clayton          static OptionDefinition g_option_table[];
1015de164aaaSGreg Clayton 
1016de164aaaSGreg Clayton          const char *
1017de164aaaSGreg Clayton          GetHelp ()
1018de164aaaSGreg Clayton          {
1019de164aaaSGreg Clayton              if (m_help.empty())
1020de164aaaSGreg Clayton                  return NULL;
1021de164aaaSGreg Clayton              return m_help.c_str();
1022de164aaaSGreg Clayton          }
1023de164aaaSGreg Clayton          const char *
1024de164aaaSGreg Clayton          GetSyntax ()
1025de164aaaSGreg Clayton          {
1026de164aaaSGreg Clayton              if (m_syntax.empty())
1027de164aaaSGreg Clayton                  return NULL;
1028de164aaaSGreg Clayton              return m_syntax.c_str();
1029de164aaaSGreg Clayton          }
1030de164aaaSGreg Clayton          // Instance variables to hold the values for command options.
1031de164aaaSGreg Clayton      protected:
1032de164aaaSGreg Clayton          std::string m_help;
1033de164aaaSGreg Clayton          std::string m_syntax;
1034de164aaaSGreg Clayton      };
1035de164aaaSGreg Clayton 
1036de164aaaSGreg Clayton      CommandOptions m_options;
1037de164aaaSGreg Clayton 
1038de164aaaSGreg Clayton      virtual Options *
1039de164aaaSGreg Clayton      GetOptions ()
1040de164aaaSGreg Clayton      {
1041de164aaaSGreg Clayton          return &m_options;
1042de164aaaSGreg Clayton      }
1043de164aaaSGreg Clayton 
1044de164aaaSGreg Clayton };
1045de164aaaSGreg Clayton 
1046de164aaaSGreg Clayton size_t
1047de164aaaSGreg Clayton CommandObjectCommandsAddRegex::InputReaderCallback (void *baton,
1048de164aaaSGreg Clayton                                                     InputReader &reader,
1049de164aaaSGreg Clayton                                                     lldb::InputReaderAction notification,
1050de164aaaSGreg Clayton                                                     const char *bytes,
1051de164aaaSGreg Clayton                                                     size_t bytes_len)
1052de164aaaSGreg Clayton {
1053de164aaaSGreg Clayton     CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton;
1054d61c10bcSCaroline Tice     bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
1055de164aaaSGreg Clayton 
1056de164aaaSGreg Clayton     switch (notification)
1057de164aaaSGreg Clayton     {
1058de164aaaSGreg Clayton         case eInputReaderActivate:
1059d61c10bcSCaroline Tice             if (!batch_mode)
106015356e7fSCaroline Tice             {
106115356e7fSCaroline Tice                 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream ();
106215356e7fSCaroline Tice                 out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:");
106315356e7fSCaroline Tice                 out_stream->Flush();
106415356e7fSCaroline Tice             }
1065de164aaaSGreg Clayton             break;
1066de164aaaSGreg Clayton         case eInputReaderReactivate:
1067de164aaaSGreg Clayton             break;
1068de164aaaSGreg Clayton 
1069de164aaaSGreg Clayton         case eInputReaderDeactivate:
1070de164aaaSGreg Clayton             break;
1071de164aaaSGreg Clayton 
1072969ed3d1SCaroline Tice         case eInputReaderAsynchronousOutputWritten:
1073969ed3d1SCaroline Tice             break;
1074969ed3d1SCaroline Tice 
1075de164aaaSGreg Clayton         case eInputReaderGotToken:
10760e5e5a79SGreg Clayton             while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n'))
10770e5e5a79SGreg Clayton                 --bytes_len;
1078de164aaaSGreg Clayton             if (bytes_len == 0)
1079de164aaaSGreg Clayton                 reader.SetIsDone(true);
1080de164aaaSGreg Clayton             else if (bytes)
1081de164aaaSGreg Clayton             {
10820e5e5a79SGreg Clayton                 llvm::StringRef bytes_strref (bytes, bytes_len);
10830e5e5a79SGreg Clayton                 Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref));
10840e5e5a79SGreg Clayton                 if (error.Fail())
1085de164aaaSGreg Clayton                 {
1086d61c10bcSCaroline Tice                     if (!batch_mode)
1087d61c10bcSCaroline Tice                     {
108815356e7fSCaroline Tice                         StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
108915356e7fSCaroline Tice                         out_stream->Printf("error: %s\n", error.AsCString());
109015356e7fSCaroline Tice                         out_stream->Flush();
1091d61c10bcSCaroline Tice                     }
10920e5e5a79SGreg Clayton                     add_regex_cmd->InputReaderDidCancel ();
10930e5e5a79SGreg Clayton                     reader.SetIsDone (true);
1094de164aaaSGreg Clayton                 }
1095de164aaaSGreg Clayton             }
1096de164aaaSGreg Clayton             break;
1097de164aaaSGreg Clayton 
1098de164aaaSGreg Clayton         case eInputReaderInterrupt:
109915356e7fSCaroline Tice             {
1100de164aaaSGreg Clayton                 reader.SetIsDone (true);
1101d61c10bcSCaroline Tice                 if (!batch_mode)
1102d61c10bcSCaroline Tice                 {
110315356e7fSCaroline Tice                     StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
110415356e7fSCaroline Tice                     out_stream->PutCString("Regular expression command creations was cancelled.\n");
110515356e7fSCaroline Tice                     out_stream->Flush();
1106d61c10bcSCaroline Tice                 }
11070e5e5a79SGreg Clayton                 add_regex_cmd->InputReaderDidCancel ();
110815356e7fSCaroline Tice             }
1109de164aaaSGreg Clayton             break;
1110de164aaaSGreg Clayton 
1111de164aaaSGreg Clayton         case eInputReaderEndOfFile:
1112de164aaaSGreg Clayton             reader.SetIsDone (true);
1113de164aaaSGreg Clayton             break;
1114de164aaaSGreg Clayton 
1115de164aaaSGreg Clayton         case eInputReaderDone:
11160e5e5a79SGreg Clayton             add_regex_cmd->AddRegexCommandToInterpreter();
1117de164aaaSGreg Clayton             break;
1118de164aaaSGreg Clayton     }
1119de164aaaSGreg Clayton 
1120de164aaaSGreg Clayton     return bytes_len;
1121de164aaaSGreg Clayton }
1122de164aaaSGreg Clayton 
1123de164aaaSGreg Clayton 
1124de164aaaSGreg Clayton OptionDefinition
1125de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] =
1126de164aaaSGreg Clayton {
1127de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "help"  , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."},
1128de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."},
1129de164aaaSGreg Clayton { 0             , false,  NULL   , 0  , 0                , NULL, 0, eArgTypeNone, NULL }
1130de164aaaSGreg Clayton };
1131de164aaaSGreg Clayton 
1132de164aaaSGreg Clayton 
1133ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands
1134ebc09c36SJim Ingham 
1135ebc09c36SJim Ingham //-------------------------------------------------------------------------
1136ebc09c36SJim Ingham // CommandObjectMultiwordCommands
1137ebc09c36SJim Ingham //-------------------------------------------------------------------------
1138ebc09c36SJim Ingham 
1139ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) :
1140a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
11410e5e5a79SGreg Clayton                             "command",
11423f4c09c1SCaroline Tice                             "A set of commands for managing or customizing the debugger commands.",
11430e5e5a79SGreg Clayton                             "command <subcommand> [<subcommand-options>]")
1144ebc09c36SJim Ingham {
1145a7015092SGreg Clayton     LoadSubCommand ("source",  CommandObjectSP (new CommandObjectCommandsSource (interpreter)));
1146a7015092SGreg Clayton     LoadSubCommand ("alias",   CommandObjectSP (new CommandObjectCommandsAlias (interpreter)));
1147a7015092SGreg Clayton     LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter)));
1148de164aaaSGreg Clayton     LoadSubCommand ("regex",   CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter)));
1149*a5a97ebeSJim Ingham     LoadSubCommand ("history",   CommandObjectSP (new CommandObjectCommandsHistory (interpreter)));
1150ebc09c36SJim Ingham }
1151ebc09c36SJim Ingham 
1152ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands ()
1153ebc09c36SJim Ingham {
1154ebc09c36SJim Ingham }
1155ebc09c36SJim Ingham 
1156