130fdc8d8SChris Lattner //===-- CommandObjectBreakpoint.cpp -----------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
1230fdc8d8SChris Lattner #include "CommandObjectBreakpoint.h"
1330fdc8d8SChris Lattner #include "CommandObjectBreakpointCommand.h"
1430fdc8d8SChris Lattner 
1530fdc8d8SChris Lattner // C Includes
1630fdc8d8SChris Lattner // C++ Includes
1730fdc8d8SChris Lattner // Other libraries and framework includes
1830fdc8d8SChris Lattner // Project includes
1930fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h"
2030fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointIDList.h"
2130fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h"
225275aaa0SVince Harron #include "lldb/Host/StringConvert.h"
2340af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
2432abc6edSZachary Turner #include "lldb/Interpreter/OptionValueBoolean.h"
255e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueString.h"
265e09c8c3SJim Ingham #include "lldb/Interpreter/OptionValueUInt64.h"
2730fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
2830fdc8d8SChris Lattner #include "lldb/Core/StreamString.h"
2930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
3030fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
31*a78bd7ffSZachary Turner #include "lldb/Target/LanguageRuntime.h"
3230fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3330fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
34b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h"
351b54c88cSJim Ingham #include "lldb/Target/Thread.h"
361b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h"
3730fdc8d8SChris Lattner 
38b7234e40SJohnny Chen #include <vector>
39b7234e40SJohnny Chen 
4030fdc8d8SChris Lattner using namespace lldb;
4130fdc8d8SChris Lattner using namespace lldb_private;
4230fdc8d8SChris Lattner 
4330fdc8d8SChris Lattner static void
4485e8b814SJim Ingham AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
4530fdc8d8SChris Lattner {
4630fdc8d8SChris Lattner     s->IndentMore();
4730fdc8d8SChris Lattner     bp->GetDescription (s, level, true);
4830fdc8d8SChris Lattner     s->IndentLess();
4930fdc8d8SChris Lattner     s->EOL();
5030fdc8d8SChris Lattner }
5130fdc8d8SChris Lattner 
5230fdc8d8SChris Lattner //-------------------------------------------------------------------------
535a988416SJim Ingham // CommandObjectBreakpointSet
5430fdc8d8SChris Lattner //-------------------------------------------------------------------------
5530fdc8d8SChris Lattner 
565a988416SJim Ingham 
575a988416SJim Ingham class CommandObjectBreakpointSet : public CommandObjectParsed
585a988416SJim Ingham {
595a988416SJim Ingham public:
605a988416SJim Ingham 
615a988416SJim Ingham     typedef enum BreakpointSetType
625a988416SJim Ingham     {
635a988416SJim Ingham         eSetTypeInvalid,
645a988416SJim Ingham         eSetTypeFileAndLine,
655a988416SJim Ingham         eSetTypeAddress,
665a988416SJim Ingham         eSetTypeFunctionName,
675a988416SJim Ingham         eSetTypeFunctionRegexp,
685a988416SJim Ingham         eSetTypeSourceRegexp,
695a988416SJim Ingham         eSetTypeException
705a988416SJim Ingham     } BreakpointSetType;
715a988416SJim Ingham 
725a988416SJim Ingham     CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
735a988416SJim Ingham         CommandObjectParsed (interpreter,
745a988416SJim Ingham                              "breakpoint set",
755a988416SJim Ingham                              "Sets a breakpoint or set of breakpoints in the executable.",
765a988416SJim Ingham                              "breakpoint set <cmd-options>"),
775a988416SJim Ingham         m_options (interpreter)
785a988416SJim Ingham     {
795a988416SJim Ingham     }
805a988416SJim Ingham 
815a988416SJim Ingham 
825a988416SJim Ingham     virtual
835a988416SJim Ingham     ~CommandObjectBreakpointSet () {}
845a988416SJim Ingham 
855a988416SJim Ingham     virtual Options *
865a988416SJim Ingham     GetOptions ()
875a988416SJim Ingham     {
885a988416SJim Ingham         return &m_options;
895a988416SJim Ingham     }
905a988416SJim Ingham 
915a988416SJim Ingham     class CommandOptions : public Options
925a988416SJim Ingham     {
935a988416SJim Ingham     public:
945a988416SJim Ingham 
955a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
96eb0103f2SGreg Clayton             Options (interpreter),
977d49c9c8SJohnny Chen             m_condition (),
9887df91b8SJim Ingham             m_filenames (),
9930fdc8d8SChris Lattner             m_line_num (0),
10030fdc8d8SChris Lattner             m_column (0),
101fab10e89SJim Ingham             m_func_names (),
102fab10e89SJim Ingham             m_func_name_type_mask (eFunctionNameTypeNone),
10330fdc8d8SChris Lattner             m_func_regexp (),
104969795f1SJim Ingham             m_source_text_regexp(),
10530fdc8d8SChris Lattner             m_modules (),
1061b54c88cSJim Ingham             m_load_addr(),
107c982c768SGreg Clayton             m_ignore_count (0),
1081b54c88cSJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
109c982c768SGreg Clayton             m_thread_index (UINT32_MAX),
1101b54c88cSJim Ingham             m_thread_name(),
111fab10e89SJim Ingham             m_queue_name(),
112fab10e89SJim Ingham             m_catch_bp (false),
1131f746071SGreg Clayton             m_throw_bp (true),
114eb023e75SGreg Clayton             m_hardware (false),
115a8558b62SJim Ingham             m_language (eLanguageTypeUnknown),
116ca36cd16SJim Ingham             m_skip_prologue (eLazyBoolCalculate),
117e732052fSJim Ingham             m_one_shot (false),
118e732052fSJim Ingham             m_all_files (false)
11930fdc8d8SChris Lattner         {
12030fdc8d8SChris Lattner         }
12130fdc8d8SChris Lattner 
12230fdc8d8SChris Lattner 
1235a988416SJim Ingham         virtual
1245a988416SJim Ingham         ~CommandOptions () {}
12587df91b8SJim Ingham 
1265a988416SJim Ingham         virtual Error
1275a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
12830fdc8d8SChris Lattner         {
12930fdc8d8SChris Lattner             Error error;
1303bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13130fdc8d8SChris Lattner 
13230fdc8d8SChris Lattner             switch (short_option)
13330fdc8d8SChris Lattner             {
13430fdc8d8SChris Lattner                 case 'a':
135b9d5df58SGreg Clayton                     {
136b9d5df58SGreg Clayton                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
137b9d5df58SGreg Clayton                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
138b9d5df58SGreg Clayton                     }
13930fdc8d8SChris Lattner                     break;
14030fdc8d8SChris Lattner 
141e732052fSJim Ingham                 case 'A':
142e732052fSJim Ingham                     m_all_files = true;
143e732052fSJim Ingham                     break;
144e732052fSJim Ingham 
145ca36cd16SJim Ingham                 case 'b':
146ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
147ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeBase;
148ca36cd16SJim Ingham                     break;
149ca36cd16SJim Ingham 
1507d49c9c8SJohnny Chen                 case 'C':
1515275aaa0SVince Harron                     m_column = StringConvert::ToUInt32 (option_arg, 0);
15230fdc8d8SChris Lattner                     break;
1530c5cd90dSGreg Clayton 
1547d49c9c8SJohnny Chen                 case 'c':
1557d49c9c8SJohnny Chen                     m_condition.assign(option_arg);
1567d49c9c8SJohnny Chen                     break;
1577d49c9c8SJohnny Chen 
15833df7cd3SJim Ingham                 case 'D':
15933df7cd3SJim Ingham                     m_use_dummy = true;
16033df7cd3SJim Ingham                     break;
16133df7cd3SJim Ingham 
162fab10e89SJim Ingham                 case 'E':
163fab10e89SJim Ingham                 {
164fab10e89SJim Ingham                     LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
165fab10e89SJim Ingham 
166fab10e89SJim Ingham                     switch (language)
167fab10e89SJim Ingham                     {
168fab10e89SJim Ingham                         case eLanguageTypeC89:
169fab10e89SJim Ingham                         case eLanguageTypeC:
170fab10e89SJim Ingham                         case eLanguageTypeC99:
1711d0089faSBruce Mitchener                         case eLanguageTypeC11:
172fab10e89SJim Ingham                             m_language = eLanguageTypeC;
173fab10e89SJim Ingham                             break;
174fab10e89SJim Ingham                         case eLanguageTypeC_plus_plus:
1751d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_03:
1761d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_11:
1772ba84a6aSBruce Mitchener                         case eLanguageTypeC_plus_plus_14:
178fab10e89SJim Ingham                             m_language = eLanguageTypeC_plus_plus;
179fab10e89SJim Ingham                             break;
180fab10e89SJim Ingham                         case eLanguageTypeObjC:
181fab10e89SJim Ingham                             m_language = eLanguageTypeObjC;
182fab10e89SJim Ingham                             break;
183fab10e89SJim Ingham                         case eLanguageTypeObjC_plus_plus:
184fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
185fab10e89SJim Ingham                             break;
186fab10e89SJim Ingham                         case eLanguageTypeUnknown:
187fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
188fab10e89SJim Ingham                             break;
189fab10e89SJim Ingham                         default:
190fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
191fab10e89SJim Ingham                     }
192fab10e89SJim Ingham                 }
193fab10e89SJim Ingham                 break;
194ca36cd16SJim Ingham 
195ca36cd16SJim Ingham                 case 'f':
196ca36cd16SJim Ingham                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
197fab10e89SJim Ingham                     break;
198ca36cd16SJim Ingham 
199ca36cd16SJim Ingham                 case 'F':
200ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
201ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeFull;
202ca36cd16SJim Ingham                     break;
203ca36cd16SJim Ingham 
204fab10e89SJim Ingham                 case 'h':
205fab10e89SJim Ingham                     {
206fab10e89SJim Ingham                         bool success;
207fab10e89SJim Ingham                         m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
208fab10e89SJim Ingham                         if (!success)
209fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
210fab10e89SJim Ingham                     }
211168d469aSJim Ingham                     break;
212eb023e75SGreg Clayton 
213eb023e75SGreg Clayton                 case 'H':
214eb023e75SGreg Clayton                     m_hardware = true;
215eb023e75SGreg Clayton                     break;
216eb023e75SGreg Clayton 
217ca36cd16SJim Ingham                 case 'i':
218ca36cd16SJim Ingham                 {
2195275aaa0SVince Harron                     m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
220ca36cd16SJim Ingham                     if (m_ignore_count == UINT32_MAX)
221ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
222ca36cd16SJim Ingham                     break;
223ca36cd16SJim Ingham                 }
224ca36cd16SJim Ingham 
225a8558b62SJim Ingham                 case 'K':
226a8558b62SJim Ingham                 {
227a8558b62SJim Ingham                     bool success;
228a8558b62SJim Ingham                     bool value;
229a8558b62SJim Ingham                     value = Args::StringToBoolean (option_arg, true, &success);
230a8558b62SJim Ingham                     if (value)
231a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolYes;
232a8558b62SJim Ingham                     else
233a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolNo;
234a8558b62SJim Ingham 
235a8558b62SJim Ingham                     if (!success)
236a8558b62SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
237a8558b62SJim Ingham                 }
238fab10e89SJim Ingham                 break;
239ca36cd16SJim Ingham 
240ca36cd16SJim Ingham                 case 'l':
2415275aaa0SVince Harron                     m_line_num = StringConvert::ToUInt32 (option_arg, 0);
242ca36cd16SJim Ingham                     break;
243ca36cd16SJim Ingham 
244ca36cd16SJim Ingham                 case 'M':
245ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
246ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeMethod;
247ca36cd16SJim Ingham                     break;
248ca36cd16SJim Ingham 
249ca36cd16SJim Ingham                 case 'n':
250ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
251ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeAuto;
252ca36cd16SJim Ingham                     break;
253ca36cd16SJim Ingham 
2545e09c8c3SJim Ingham                 case 'N':
2555e09c8c3SJim Ingham                     if (BreakpointID::StringIsBreakpointName(option_arg, error))
2565e09c8c3SJim Ingham                         m_breakpoint_names.push_back (option_arg);
2575e09c8c3SJim Ingham                     break;
2585e09c8c3SJim Ingham 
259ca36cd16SJim Ingham                 case 'o':
260ca36cd16SJim Ingham                     m_one_shot = true;
261ca36cd16SJim Ingham                     break;
262ca36cd16SJim Ingham 
263ca36cd16SJim Ingham                 case 'p':
264ca36cd16SJim Ingham                     m_source_text_regexp.assign (option_arg);
265ca36cd16SJim Ingham                     break;
266ca36cd16SJim Ingham 
267ca36cd16SJim Ingham                 case 'q':
268ca36cd16SJim Ingham                     m_queue_name.assign (option_arg);
269ca36cd16SJim Ingham                     break;
270ca36cd16SJim Ingham 
271ca36cd16SJim Ingham                 case 'r':
272ca36cd16SJim Ingham                     m_func_regexp.assign (option_arg);
273ca36cd16SJim Ingham                     break;
274ca36cd16SJim Ingham 
275ca36cd16SJim Ingham                 case 's':
276ca36cd16SJim Ingham                 {
277ca36cd16SJim Ingham                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
278ca36cd16SJim Ingham                     break;
279ca36cd16SJim Ingham                 }
280ca36cd16SJim Ingham 
281ca36cd16SJim Ingham                 case 'S':
282ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
283ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeSelector;
284ca36cd16SJim Ingham                     break;
285ca36cd16SJim Ingham 
286ca36cd16SJim Ingham                 case 't' :
287ca36cd16SJim Ingham                 {
2885275aaa0SVince Harron                     m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
289ca36cd16SJim Ingham                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
290ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
291ca36cd16SJim Ingham                 }
292ca36cd16SJim Ingham                 break;
293ca36cd16SJim Ingham 
294ca36cd16SJim Ingham                 case 'T':
295ca36cd16SJim Ingham                     m_thread_name.assign (option_arg);
296ca36cd16SJim Ingham                     break;
297ca36cd16SJim Ingham 
298ca36cd16SJim Ingham                 case 'w':
299ca36cd16SJim Ingham                 {
300ca36cd16SJim Ingham                     bool success;
301ca36cd16SJim Ingham                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
302ca36cd16SJim Ingham                     if (!success)
303ca36cd16SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
304ca36cd16SJim Ingham                 }
305ca36cd16SJim Ingham                 break;
306ca36cd16SJim Ingham 
307ca36cd16SJim Ingham                 case 'x':
308ca36cd16SJim Ingham                 {
3095275aaa0SVince Harron                     m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
310ca36cd16SJim Ingham                     if (m_thread_id == UINT32_MAX)
311ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
312ca36cd16SJim Ingham 
313ca36cd16SJim Ingham                 }
314ca36cd16SJim Ingham                 break;
315ca36cd16SJim Ingham 
31630fdc8d8SChris Lattner                 default:
31786edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
31830fdc8d8SChris Lattner                     break;
31930fdc8d8SChris Lattner             }
32030fdc8d8SChris Lattner 
32130fdc8d8SChris Lattner             return error;
32230fdc8d8SChris Lattner         }
32330fdc8d8SChris Lattner         void
3245a988416SJim Ingham         OptionParsingStarting ()
32530fdc8d8SChris Lattner         {
3267d49c9c8SJohnny Chen             m_condition.clear();
32787df91b8SJim Ingham             m_filenames.Clear();
32830fdc8d8SChris Lattner             m_line_num = 0;
32930fdc8d8SChris Lattner             m_column = 0;
330fab10e89SJim Ingham             m_func_names.clear();
3311f746071SGreg Clayton             m_func_name_type_mask = eFunctionNameTypeNone;
33230fdc8d8SChris Lattner             m_func_regexp.clear();
3331f746071SGreg Clayton             m_source_text_regexp.clear();
33487df91b8SJim Ingham             m_modules.Clear();
3351f746071SGreg Clayton             m_load_addr = LLDB_INVALID_ADDRESS;
336c982c768SGreg Clayton             m_ignore_count = 0;
3371b54c88cSJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
338c982c768SGreg Clayton             m_thread_index = UINT32_MAX;
3391b54c88cSJim Ingham             m_thread_name.clear();
3401b54c88cSJim Ingham             m_queue_name.clear();
341fab10e89SJim Ingham             m_catch_bp = false;
342fab10e89SJim Ingham             m_throw_bp = true;
343eb023e75SGreg Clayton             m_hardware = false;
3441f746071SGreg Clayton             m_language = eLanguageTypeUnknown;
345a8558b62SJim Ingham             m_skip_prologue = eLazyBoolCalculate;
346ca36cd16SJim Ingham             m_one_shot = false;
34733df7cd3SJim Ingham             m_use_dummy = false;
3485e09c8c3SJim Ingham             m_breakpoint_names.clear();
349e732052fSJim Ingham             m_all_files = false;
35030fdc8d8SChris Lattner         }
35130fdc8d8SChris Lattner 
3525a988416SJim Ingham         const OptionDefinition*
3535a988416SJim Ingham         GetDefinitions ()
35430fdc8d8SChris Lattner         {
3555a988416SJim Ingham             return g_option_table;
35630fdc8d8SChris Lattner         }
35730fdc8d8SChris Lattner 
3585a988416SJim Ingham         // Options table: Required for subclasses of Options.
35930fdc8d8SChris Lattner 
3605a988416SJim Ingham         static OptionDefinition g_option_table[];
36130fdc8d8SChris Lattner 
3625a988416SJim Ingham         // Instance variables to hold the values for command options.
363969795f1SJim Ingham 
3645a988416SJim Ingham         std::string m_condition;
3655a988416SJim Ingham         FileSpecList m_filenames;
3665a988416SJim Ingham         uint32_t m_line_num;
3675a988416SJim Ingham         uint32_t m_column;
3685a988416SJim Ingham         std::vector<std::string> m_func_names;
3695e09c8c3SJim Ingham         std::vector<std::string> m_breakpoint_names;
3705a988416SJim Ingham         uint32_t m_func_name_type_mask;
3715a988416SJim Ingham         std::string m_func_regexp;
3725a988416SJim Ingham         std::string m_source_text_regexp;
3735a988416SJim Ingham         FileSpecList m_modules;
3745a988416SJim Ingham         lldb::addr_t m_load_addr;
3755a988416SJim Ingham         uint32_t m_ignore_count;
3765a988416SJim Ingham         lldb::tid_t m_thread_id;
3775a988416SJim Ingham         uint32_t m_thread_index;
3785a988416SJim Ingham         std::string m_thread_name;
3795a988416SJim Ingham         std::string m_queue_name;
3805a988416SJim Ingham         bool m_catch_bp;
3815a988416SJim Ingham         bool m_throw_bp;
382eb023e75SGreg Clayton         bool m_hardware; // Request to use hardware breakpoints
3835a988416SJim Ingham         lldb::LanguageType m_language;
3845a988416SJim Ingham         LazyBool m_skip_prologue;
385ca36cd16SJim Ingham         bool m_one_shot;
38633df7cd3SJim Ingham         bool m_use_dummy;
387e732052fSJim Ingham         bool m_all_files;
3885a988416SJim Ingham 
3895a988416SJim Ingham     };
3905a988416SJim Ingham 
3915a988416SJim Ingham protected:
3925a988416SJim Ingham     virtual bool
3935a988416SJim Ingham     DoExecute (Args& command,
3945a988416SJim Ingham               CommandReturnObject &result)
39530fdc8d8SChris Lattner     {
39633df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
39733df7cd3SJim Ingham 
398893c932aSJim Ingham         if (target == nullptr)
39930fdc8d8SChris Lattner         {
400effe5c95SGreg Clayton             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
40130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
40230fdc8d8SChris Lattner             return false;
40330fdc8d8SChris Lattner         }
40430fdc8d8SChris Lattner 
40530fdc8d8SChris Lattner         // The following are the various types of breakpoints that could be set:
40630fdc8d8SChris Lattner         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
40730fdc8d8SChris Lattner         //   2).  -a  [-s -g]         (setting breakpoint by address)
40830fdc8d8SChris Lattner         //   3).  -n  [-s -g]         (setting breakpoint by function name)
40930fdc8d8SChris Lattner         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
410969795f1SJim Ingham         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
411fab10e89SJim Ingham         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
41230fdc8d8SChris Lattner 
41330fdc8d8SChris Lattner         BreakpointSetType break_type = eSetTypeInvalid;
41430fdc8d8SChris Lattner 
41530fdc8d8SChris Lattner         if (m_options.m_line_num != 0)
41630fdc8d8SChris Lattner             break_type = eSetTypeFileAndLine;
41730fdc8d8SChris Lattner         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
41830fdc8d8SChris Lattner             break_type = eSetTypeAddress;
419fab10e89SJim Ingham         else if (!m_options.m_func_names.empty())
42030fdc8d8SChris Lattner             break_type = eSetTypeFunctionName;
42130fdc8d8SChris Lattner         else if  (!m_options.m_func_regexp.empty())
42230fdc8d8SChris Lattner             break_type = eSetTypeFunctionRegexp;
423969795f1SJim Ingham         else if (!m_options.m_source_text_regexp.empty())
424969795f1SJim Ingham             break_type = eSetTypeSourceRegexp;
425fab10e89SJim Ingham         else if (m_options.m_language != eLanguageTypeUnknown)
426fab10e89SJim Ingham             break_type = eSetTypeException;
42730fdc8d8SChris Lattner 
42830fdc8d8SChris Lattner         Breakpoint *bp = NULL;
429274060b6SGreg Clayton         FileSpec module_spec;
430a8558b62SJim Ingham         const bool internal = false;
431a8558b62SJim Ingham 
43230fdc8d8SChris Lattner         switch (break_type)
43330fdc8d8SChris Lattner         {
43430fdc8d8SChris Lattner             case eSetTypeFileAndLine: // Breakpoint by source position
43530fdc8d8SChris Lattner                 {
43630fdc8d8SChris Lattner                     FileSpec file;
437c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
43887df91b8SJim Ingham                     if (num_files == 0)
43987df91b8SJim Ingham                     {
44087df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
44187df91b8SJim Ingham                         {
44287df91b8SJim Ingham                             result.AppendError("No file supplied and no default file available.");
44387df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
44487df91b8SJim Ingham                             return false;
44587df91b8SJim Ingham                         }
44687df91b8SJim Ingham                     }
44787df91b8SJim Ingham                     else if (num_files > 1)
44887df91b8SJim Ingham                     {
44987df91b8SJim Ingham                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
45087df91b8SJim Ingham                         result.SetStatus (eReturnStatusFailed);
45187df91b8SJim Ingham                         return false;
45287df91b8SJim Ingham                     }
45387df91b8SJim Ingham                     else
45487df91b8SJim Ingham                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
45530fdc8d8SChris Lattner 
4561f746071SGreg Clayton                     // Only check for inline functions if
4571f746071SGreg Clayton                     LazyBool check_inlines = eLazyBoolCalculate;
4581f746071SGreg Clayton 
45987df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
46030fdc8d8SChris Lattner                                                    file,
46130fdc8d8SChris Lattner                                                    m_options.m_line_num,
4621f746071SGreg Clayton                                                    check_inlines,
463a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
464eb023e75SGreg Clayton                                                    internal,
465eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
46630fdc8d8SChris Lattner                 }
46730fdc8d8SChris Lattner                 break;
4686eee5aa0SGreg Clayton 
46930fdc8d8SChris Lattner             case eSetTypeAddress: // Breakpoint by address
470eb023e75SGreg Clayton                 bp = target->CreateBreakpoint (m_options.m_load_addr,
471eb023e75SGreg Clayton                                                internal,
472eb023e75SGreg Clayton                                                m_options.m_hardware).get();
47330fdc8d8SChris Lattner                 break;
4740c5cd90dSGreg Clayton 
47530fdc8d8SChris Lattner             case eSetTypeFunctionName: // Breakpoint by function name
4760c5cd90dSGreg Clayton                 {
4770c5cd90dSGreg Clayton                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
4780c5cd90dSGreg Clayton 
4790c5cd90dSGreg Clayton                     if (name_type_mask == 0)
480e02b8504SGreg Clayton                         name_type_mask = eFunctionNameTypeAuto;
4810c5cd90dSGreg Clayton 
48287df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
48387df91b8SJim Ingham                                                    &(m_options.m_filenames),
484fab10e89SJim Ingham                                                    m_options.m_func_names,
485274060b6SGreg Clayton                                                    name_type_mask,
486a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
487eb023e75SGreg Clayton                                                    internal,
488eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
4890c5cd90dSGreg Clayton                 }
49030fdc8d8SChris Lattner                 break;
4910c5cd90dSGreg Clayton 
49230fdc8d8SChris Lattner             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
49330fdc8d8SChris Lattner                 {
49430fdc8d8SChris Lattner                     RegularExpression regexp(m_options.m_func_regexp.c_str());
495969795f1SJim Ingham                     if (!regexp.IsValid())
49630fdc8d8SChris Lattner                     {
497969795f1SJim Ingham                         char err_str[1024];
498969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
499969795f1SJim Ingham                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
500969795f1SJim Ingham                                                      err_str);
50130fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
502969795f1SJim Ingham                         return false;
50330fdc8d8SChris Lattner                     }
50487df91b8SJim Ingham 
505a8558b62SJim Ingham                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
506a8558b62SJim Ingham                                                             &(m_options.m_filenames),
507a8558b62SJim Ingham                                                             regexp,
508a8558b62SJim Ingham                                                             m_options.m_skip_prologue,
509eb023e75SGreg Clayton                                                             internal,
510eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
51130fdc8d8SChris Lattner                 }
51230fdc8d8SChris Lattner                 break;
513969795f1SJim Ingham             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
514969795f1SJim Ingham                 {
515c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
51687df91b8SJim Ingham 
517e732052fSJim Ingham                     if (num_files == 0 && !m_options.m_all_files)
51887df91b8SJim Ingham                     {
519969795f1SJim Ingham                         FileSpec file;
52087df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
52187df91b8SJim Ingham                         {
52287df91b8SJim Ingham                             result.AppendError ("No files provided and could not find default file.");
52387df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
52487df91b8SJim Ingham                             return false;
52587df91b8SJim Ingham                         }
52687df91b8SJim Ingham                         else
52787df91b8SJim Ingham                         {
52887df91b8SJim Ingham                             m_options.m_filenames.Append (file);
52987df91b8SJim Ingham                         }
53087df91b8SJim Ingham                     }
5310c5cd90dSGreg Clayton 
532969795f1SJim Ingham                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
533969795f1SJim Ingham                     if (!regexp.IsValid())
534969795f1SJim Ingham                     {
535969795f1SJim Ingham                         char err_str[1024];
536969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
537969795f1SJim Ingham                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
538969795f1SJim Ingham                                                      err_str);
539969795f1SJim Ingham                         result.SetStatus (eReturnStatusFailed);
540969795f1SJim Ingham                         return false;
541969795f1SJim Ingham                     }
542eb023e75SGreg Clayton                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
543eb023e75SGreg Clayton                                                               &(m_options.m_filenames),
544eb023e75SGreg Clayton                                                               regexp,
545eb023e75SGreg Clayton                                                               internal,
546eb023e75SGreg Clayton                                                               m_options.m_hardware).get();
547969795f1SJim Ingham                 }
548969795f1SJim Ingham                 break;
549fab10e89SJim Ingham             case eSetTypeException:
550fab10e89SJim Ingham                 {
551eb023e75SGreg Clayton                     bp = target->CreateExceptionBreakpoint (m_options.m_language,
552eb023e75SGreg Clayton                                                             m_options.m_catch_bp,
553eb023e75SGreg Clayton                                                             m_options.m_throw_bp,
554eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
555fab10e89SJim Ingham                 }
556fab10e89SJim Ingham                 break;
55730fdc8d8SChris Lattner             default:
55830fdc8d8SChris Lattner                 break;
55930fdc8d8SChris Lattner         }
56030fdc8d8SChris Lattner 
5611b54c88cSJim Ingham         // Now set the various options that were passed in:
5621b54c88cSJim Ingham         if (bp)
5631b54c88cSJim Ingham         {
5641b54c88cSJim Ingham             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5651b54c88cSJim Ingham                 bp->SetThreadID (m_options.m_thread_id);
5661b54c88cSJim Ingham 
567c982c768SGreg Clayton             if (m_options.m_thread_index != UINT32_MAX)
5681b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
5691b54c88cSJim Ingham 
5701b54c88cSJim Ingham             if (!m_options.m_thread_name.empty())
5711b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
5721b54c88cSJim Ingham 
5731b54c88cSJim Ingham             if (!m_options.m_queue_name.empty())
5741b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
5751b54c88cSJim Ingham 
576c982c768SGreg Clayton             if (m_options.m_ignore_count != 0)
5771b54c88cSJim Ingham                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
5787d49c9c8SJohnny Chen 
5797d49c9c8SJohnny Chen             if (!m_options.m_condition.empty())
5807d49c9c8SJohnny Chen                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
581ca36cd16SJim Ingham 
5825e09c8c3SJim Ingham             if (!m_options.m_breakpoint_names.empty())
5835e09c8c3SJim Ingham             {
5845e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
5855e09c8c3SJim Ingham                 for (auto name : m_options.m_breakpoint_names)
5865e09c8c3SJim Ingham                     bp->AddName(name.c_str(), error);
5875e09c8c3SJim Ingham             }
5885e09c8c3SJim Ingham 
589ca36cd16SJim Ingham             bp->SetOneShot (m_options.m_one_shot);
5901b54c88cSJim Ingham         }
5911b54c88cSJim Ingham 
592969795f1SJim Ingham         if (bp)
59330fdc8d8SChris Lattner         {
59485e8b814SJim Ingham             Stream &output_stream = result.GetOutputStream();
5951391cc7dSJim Ingham             const bool show_locations = false;
5961391cc7dSJim Ingham             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
5974aeb1989SJim Ingham             if (target == m_interpreter.GetDebugger().GetDummyTarget())
5984aeb1989SJim Ingham                     output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
5994aeb1989SJim Ingham             else
6004aeb1989SJim Ingham             {
601fab10e89SJim Ingham                 // Don't print out this warning for exception breakpoints.  They can get set before the target
602fab10e89SJim Ingham                 // is set, but we won't know how to actually set the breakpoint till we run.
603fab10e89SJim Ingham                 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
6044aeb1989SJim Ingham                 {
605be484f41SCaroline Tice                     output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
6064aeb1989SJim Ingham                 }
6074aeb1989SJim Ingham             }
60830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
60930fdc8d8SChris Lattner         }
61030fdc8d8SChris Lattner         else if (!bp)
61130fdc8d8SChris Lattner         {
61230fdc8d8SChris Lattner             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
61330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
61430fdc8d8SChris Lattner         }
61530fdc8d8SChris Lattner 
61630fdc8d8SChris Lattner         return result.Succeeded();
61730fdc8d8SChris Lattner     }
61830fdc8d8SChris Lattner 
6195a988416SJim Ingham private:
6205a988416SJim Ingham     bool
6215a988416SJim Ingham     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
6225a988416SJim Ingham     {
6235a988416SJim Ingham         uint32_t default_line;
6245a988416SJim Ingham         // First use the Source Manager's default file.
6255a988416SJim Ingham         // Then use the current stack frame's file.
6265a988416SJim Ingham         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
6275a988416SJim Ingham         {
628b57e4a1bSJason Molenda             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
6295a988416SJim Ingham             if (cur_frame == NULL)
6305a988416SJim Ingham             {
6315a988416SJim Ingham                 result.AppendError ("No selected frame to use to find the default file.");
6325a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6335a988416SJim Ingham                 return false;
6345a988416SJim Ingham             }
6355a988416SJim Ingham             else if (!cur_frame->HasDebugInformation())
6365a988416SJim Ingham             {
6375a988416SJim Ingham                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
6385a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6395a988416SJim Ingham                 return false;
6405a988416SJim Ingham             }
6415a988416SJim Ingham             else
6425a988416SJim Ingham             {
6435a988416SJim Ingham                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
6445a988416SJim Ingham                 if (sc.line_entry.file)
6455a988416SJim Ingham                 {
6465a988416SJim Ingham                     file = sc.line_entry.file;
6475a988416SJim Ingham                 }
6485a988416SJim Ingham                 else
6495a988416SJim Ingham                 {
6505a988416SJim Ingham                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
6515a988416SJim Ingham                     result.SetStatus (eReturnStatusFailed);
6525a988416SJim Ingham                     return false;
6535a988416SJim Ingham                 }
6545a988416SJim Ingham             }
6555a988416SJim Ingham         }
6565a988416SJim Ingham         return true;
6575a988416SJim Ingham     }
6585a988416SJim Ingham 
6595a988416SJim Ingham     CommandOptions m_options;
6605a988416SJim Ingham };
6615a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
6625a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
6635a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
6645a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
6655a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
6665a988416SJim Ingham 
6675a988416SJim Ingham OptionDefinition
6685a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
6695a988416SJim Ingham {
670d37221dcSZachary Turner     { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
6715a988416SJim Ingham         "Set the breakpoint only in this shared library.  "
6725a988416SJim Ingham         "Can repeat this option multiple times to specify multiple shared libraries."},
6735a988416SJim Ingham 
674d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeCount,
6755a988416SJim Ingham         "Set the number of times this breakpoint is skipped before stopping." },
6765a988416SJim Ingham 
677d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
678b2b256afSJim Ingham         "The breakpoint is deleted the first time it causes a stop." },
679ca36cd16SJim Ingham 
680d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
6815a988416SJim Ingham         "The breakpoint stops only if this condition expression evaluates to true."},
6825a988416SJim Ingham 
683d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
684a89be91fSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
6855a988416SJim Ingham 
686d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
6875a988416SJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
6885a988416SJim Ingham 
689d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
6905a988416SJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
6915a988416SJim Ingham 
692d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
693eb023e75SGreg Clayton         "Require the breakpoint to use hardware breakpoints."},
694eb023e75SGreg Clayton 
695d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
6965a988416SJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
6975a988416SJim Ingham 
698d37221dcSZachary Turner     { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
699289aca64SJim Ingham         "Specifies the source file in which to set this breakpoint.  "
700289aca64SJim Ingham         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
7016394479eSJim Ingham         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
702289aca64SJim Ingham         " to \"always\"."},
7035a988416SJim Ingham 
704d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
7055a988416SJim Ingham         "Specifies the line number on which to set this breakpoint."},
7065a988416SJim Ingham 
7075a988416SJim Ingham     // Comment out this option for the moment, as we don't actually use it, but will in the future.
7085a988416SJim Ingham     // This way users won't see it, but the infrastructure is left in place.
709e2607b50SVirgile Bello     //    { 0, false, "column",     'C', OptionParser::eRequiredArgument, NULL, "<column>",
7105a988416SJim Ingham     //    "Set the breakpoint by source location at this particular column."},
7115a988416SJim Ingham 
712d37221dcSZachary Turner     { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
7135a988416SJim Ingham         "Set the breakpoint by address, at the specified address."},
7145a988416SJim Ingham 
715d37221dcSZachary Turner     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
716551262d7SJim Ingham         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
7175a988416SJim Ingham 
718d37221dcSZachary Turner     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
7195a988416SJim Ingham         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
7205a988416SJim Ingham         "for Objective C this means a full function prototype with class and selector.   "
7215a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple names." },
7225a988416SJim Ingham 
723d37221dcSZachary Turner     { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
7245a988416SJim Ingham         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
7255a988416SJim Ingham 
726d37221dcSZachary Turner     { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
7275a988416SJim Ingham         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
7285a988416SJim Ingham 
729d37221dcSZachary Turner     { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
7305a988416SJim Ingham         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
7315a988416SJim Ingham 
732d37221dcSZachary Turner     { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
7335a988416SJim Ingham         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
7345a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
7355a988416SJim Ingham 
736d37221dcSZachary Turner     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
737e96ade8bSJim Ingham         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
738e96ade8bSJim Ingham         "specified with the -f option.  The -f option can be specified more than once.  "
739e96ade8bSJim Ingham         "If no source files are specified, uses the current \"default source file\"" },
7405a988416SJim Ingham 
741e732052fSJim Ingham     { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
742e732052fSJim Ingham         "All files are searched for source pattern matches." },
743e732052fSJim Ingham 
744d37221dcSZachary Turner     { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
7455a988416SJim Ingham         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
7465a988416SJim Ingham 
747d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7485a988416SJim Ingham         "Set the breakpoint on exception throW." },
7495a988416SJim Ingham 
750d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7515a988416SJim Ingham         "Set the breakpoint on exception catcH." },
7525a988416SJim Ingham 
753d37221dcSZachary Turner     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7545a988416SJim Ingham         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
7555a988416SJim Ingham 
75633df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
75733df7cd3SJim Ingham         "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
75833df7cd3SJim Ingham 
7595e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
7605e09c8c3SJim Ingham         "Adds this to the list of names for this breakopint."},
7615e09c8c3SJim Ingham 
762d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
7635a988416SJim Ingham };
7645a988416SJim Ingham 
7655a988416SJim Ingham //-------------------------------------------------------------------------
7665a988416SJim Ingham // CommandObjectBreakpointModify
7675a988416SJim Ingham //-------------------------------------------------------------------------
7685a988416SJim Ingham #pragma mark Modify
7695a988416SJim Ingham 
7705a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed
7715a988416SJim Ingham {
7725a988416SJim Ingham public:
7735a988416SJim Ingham 
7745a988416SJim Ingham     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
7755a988416SJim Ingham         CommandObjectParsed (interpreter,
7765a988416SJim Ingham                              "breakpoint modify",
7775a988416SJim Ingham                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
7785a988416SJim Ingham                              "If no breakpoint is specified, acts on the last created breakpoint.  "
7795a988416SJim Ingham                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
7805a988416SJim Ingham                              NULL),
7815a988416SJim Ingham         m_options (interpreter)
7825a988416SJim Ingham     {
7835a988416SJim Ingham         CommandArgumentEntry arg;
7845a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
7855a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
7865a988416SJim Ingham         m_arguments.push_back (arg);
7875a988416SJim Ingham     }
7885a988416SJim Ingham 
7895a988416SJim Ingham 
7905a988416SJim Ingham     virtual
7915a988416SJim Ingham     ~CommandObjectBreakpointModify () {}
7925a988416SJim Ingham 
7935a988416SJim Ingham     virtual Options *
7945a988416SJim Ingham     GetOptions ()
7955a988416SJim Ingham     {
7965a988416SJim Ingham         return &m_options;
7975a988416SJim Ingham     }
7985a988416SJim Ingham 
7995a988416SJim Ingham     class CommandOptions : public Options
8005a988416SJim Ingham     {
8015a988416SJim Ingham     public:
8025a988416SJim Ingham 
8035a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
8045a988416SJim Ingham             Options (interpreter),
8055a988416SJim Ingham             m_ignore_count (0),
8065a988416SJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
8075a988416SJim Ingham             m_thread_id_passed(false),
8085a988416SJim Ingham             m_thread_index (UINT32_MAX),
8095a988416SJim Ingham             m_thread_index_passed(false),
8105a988416SJim Ingham             m_thread_name(),
8115a988416SJim Ingham             m_queue_name(),
8125a988416SJim Ingham             m_condition (),
813ca36cd16SJim Ingham             m_one_shot (false),
8145a988416SJim Ingham             m_enable_passed (false),
8155a988416SJim Ingham             m_enable_value (false),
8165a988416SJim Ingham             m_name_passed (false),
8175a988416SJim Ingham             m_queue_passed (false),
818ca36cd16SJim Ingham             m_condition_passed (false),
81933df7cd3SJim Ingham             m_one_shot_passed (false),
82033df7cd3SJim Ingham             m_use_dummy (false)
8215a988416SJim Ingham         {
8225a988416SJim Ingham         }
8235a988416SJim Ingham 
8245a988416SJim Ingham         virtual
8255a988416SJim Ingham         ~CommandOptions () {}
8265a988416SJim Ingham 
8275a988416SJim Ingham         virtual Error
8285a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
8295a988416SJim Ingham         {
8305a988416SJim Ingham             Error error;
8313bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
8325a988416SJim Ingham 
8335a988416SJim Ingham             switch (short_option)
8345a988416SJim Ingham             {
8355a988416SJim Ingham                 case 'c':
8365a988416SJim Ingham                     if (option_arg != NULL)
8375a988416SJim Ingham                         m_condition.assign (option_arg);
8385a988416SJim Ingham                     else
8395a988416SJim Ingham                         m_condition.clear();
8405a988416SJim Ingham                     m_condition_passed = true;
8415a988416SJim Ingham                     break;
8425a988416SJim Ingham                 case 'd':
8435a988416SJim Ingham                     m_enable_passed = true;
8445a988416SJim Ingham                     m_enable_value = false;
8455a988416SJim Ingham                     break;
84633df7cd3SJim Ingham                 case 'D':
84733df7cd3SJim Ingham                     m_use_dummy = true;
84833df7cd3SJim Ingham                     break;
8495a988416SJim Ingham                 case 'e':
8505a988416SJim Ingham                     m_enable_passed = true;
8515a988416SJim Ingham                     m_enable_value = true;
8525a988416SJim Ingham                     break;
8535a988416SJim Ingham                 case 'i':
8545a988416SJim Ingham                 {
8555275aaa0SVince Harron                     m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
8565a988416SJim Ingham                     if (m_ignore_count == UINT32_MAX)
8575a988416SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
8585a988416SJim Ingham                 }
8595a988416SJim Ingham                 break;
860ca36cd16SJim Ingham                 case 'o':
861ca36cd16SJim Ingham                 {
862ca36cd16SJim Ingham                     bool value, success;
863ca36cd16SJim Ingham                     value = Args::StringToBoolean(option_arg, false, &success);
864ca36cd16SJim Ingham                     if (success)
865ca36cd16SJim Ingham                     {
866ca36cd16SJim Ingham                         m_one_shot_passed = true;
867ca36cd16SJim Ingham                         m_one_shot = value;
868ca36cd16SJim Ingham                     }
869ca36cd16SJim Ingham                     else
870ca36cd16SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
871ca36cd16SJim Ingham                 }
872ca36cd16SJim Ingham                 break;
8735a988416SJim Ingham                 case 't' :
8745a988416SJim Ingham                 {
8755a988416SJim Ingham                     if (option_arg[0] == '\0')
8765a988416SJim Ingham                     {
8775a988416SJim Ingham                         m_thread_id = LLDB_INVALID_THREAD_ID;
8785a988416SJim Ingham                         m_thread_id_passed = true;
8795a988416SJim Ingham                     }
8805a988416SJim Ingham                     else
8815a988416SJim Ingham                     {
8825275aaa0SVince Harron                         m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
8835a988416SJim Ingham                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
8845a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
8855a988416SJim Ingham                         else
8865a988416SJim Ingham                             m_thread_id_passed = true;
8875a988416SJim Ingham                     }
8885a988416SJim Ingham                 }
8895a988416SJim Ingham                 break;
8905a988416SJim Ingham                 case 'T':
8915a988416SJim Ingham                     if (option_arg != NULL)
8925a988416SJim Ingham                         m_thread_name.assign (option_arg);
8935a988416SJim Ingham                     else
8945a988416SJim Ingham                         m_thread_name.clear();
8955a988416SJim Ingham                     m_name_passed = true;
8965a988416SJim Ingham                     break;
8975a988416SJim Ingham                 case 'q':
8985a988416SJim Ingham                     if (option_arg != NULL)
8995a988416SJim Ingham                         m_queue_name.assign (option_arg);
9005a988416SJim Ingham                     else
9015a988416SJim Ingham                         m_queue_name.clear();
9025a988416SJim Ingham                     m_queue_passed = true;
9035a988416SJim Ingham                     break;
9045a988416SJim Ingham                 case 'x':
9055a988416SJim Ingham                 {
9065a988416SJim Ingham                     if (option_arg[0] == '\n')
9075a988416SJim Ingham                     {
9085a988416SJim Ingham                         m_thread_index = UINT32_MAX;
9095a988416SJim Ingham                         m_thread_index_passed = true;
9105a988416SJim Ingham                     }
9115a988416SJim Ingham                     else
9125a988416SJim Ingham                     {
9135275aaa0SVince Harron                         m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
9145a988416SJim Ingham                         if (m_thread_id == UINT32_MAX)
9155a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
9165a988416SJim Ingham                         else
9175a988416SJim Ingham                             m_thread_index_passed = true;
9185a988416SJim Ingham                     }
9195a988416SJim Ingham                 }
9205a988416SJim Ingham                 break;
9215a988416SJim Ingham                 default:
9225a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
9235a988416SJim Ingham                     break;
9245a988416SJim Ingham             }
9255a988416SJim Ingham 
9265a988416SJim Ingham             return error;
9275a988416SJim Ingham         }
9285a988416SJim Ingham         void
9295a988416SJim Ingham         OptionParsingStarting ()
9305a988416SJim Ingham         {
9315a988416SJim Ingham             m_ignore_count = 0;
9325a988416SJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
9335a988416SJim Ingham             m_thread_id_passed = false;
9345a988416SJim Ingham             m_thread_index = UINT32_MAX;
9355a988416SJim Ingham             m_thread_index_passed = false;
9365a988416SJim Ingham             m_thread_name.clear();
9375a988416SJim Ingham             m_queue_name.clear();
9385a988416SJim Ingham             m_condition.clear();
939ca36cd16SJim Ingham             m_one_shot = false;
9405a988416SJim Ingham             m_enable_passed = false;
9415a988416SJim Ingham             m_queue_passed = false;
9425a988416SJim Ingham             m_name_passed = false;
9435a988416SJim Ingham             m_condition_passed = false;
944ca36cd16SJim Ingham             m_one_shot_passed = false;
94533df7cd3SJim Ingham             m_use_dummy = false;
9465a988416SJim Ingham         }
9475a988416SJim Ingham 
9485a988416SJim Ingham         const OptionDefinition*
9495a988416SJim Ingham         GetDefinitions ()
9505a988416SJim Ingham         {
9515a988416SJim Ingham             return g_option_table;
9525a988416SJim Ingham         }
9535a988416SJim Ingham 
9545a988416SJim Ingham 
9555a988416SJim Ingham         // Options table: Required for subclasses of Options.
9565a988416SJim Ingham 
9575a988416SJim Ingham         static OptionDefinition g_option_table[];
9585a988416SJim Ingham 
9595a988416SJim Ingham         // Instance variables to hold the values for command options.
9605a988416SJim Ingham 
9615a988416SJim Ingham         uint32_t m_ignore_count;
9625a988416SJim Ingham         lldb::tid_t m_thread_id;
9635a988416SJim Ingham         bool m_thread_id_passed;
9645a988416SJim Ingham         uint32_t m_thread_index;
9655a988416SJim Ingham         bool m_thread_index_passed;
9665a988416SJim Ingham         std::string m_thread_name;
9675a988416SJim Ingham         std::string m_queue_name;
9685a988416SJim Ingham         std::string m_condition;
969ca36cd16SJim Ingham         bool m_one_shot;
9705a988416SJim Ingham         bool m_enable_passed;
9715a988416SJim Ingham         bool m_enable_value;
9725a988416SJim Ingham         bool m_name_passed;
9735a988416SJim Ingham         bool m_queue_passed;
9745a988416SJim Ingham         bool m_condition_passed;
975ca36cd16SJim Ingham         bool m_one_shot_passed;
97633df7cd3SJim Ingham         bool m_use_dummy;
9775a988416SJim Ingham 
9785a988416SJim Ingham     };
9795a988416SJim Ingham 
9805a988416SJim Ingham protected:
9815a988416SJim Ingham     virtual bool
9825a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
9835a988416SJim Ingham     {
98433df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
9855a988416SJim Ingham         if (target == NULL)
9865a988416SJim Ingham         {
9875a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
9885a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
9895a988416SJim Ingham             return false;
9905a988416SJim Ingham         }
9915a988416SJim Ingham 
9925a988416SJim Ingham         Mutex::Locker locker;
9935a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
9945a988416SJim Ingham 
9955a988416SJim Ingham         BreakpointIDList valid_bp_ids;
9965a988416SJim Ingham 
9975e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
9985a988416SJim Ingham 
9995a988416SJim Ingham         if (result.Succeeded())
10005a988416SJim Ingham         {
10015a988416SJim Ingham             const size_t count = valid_bp_ids.GetSize();
10025a988416SJim Ingham             for (size_t i = 0; i < count; ++i)
10035a988416SJim Ingham             {
10045a988416SJim Ingham                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
10055a988416SJim Ingham 
10065a988416SJim Ingham                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
10075a988416SJim Ingham                 {
10085a988416SJim Ingham                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
10095a988416SJim Ingham                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
10105a988416SJim Ingham                     {
10115a988416SJim Ingham                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
10125a988416SJim Ingham                         if (location)
10135a988416SJim Ingham                         {
10145a988416SJim Ingham                             if (m_options.m_thread_id_passed)
10155a988416SJim Ingham                                 location->SetThreadID (m_options.m_thread_id);
10165a988416SJim Ingham 
10175a988416SJim Ingham                             if (m_options.m_thread_index_passed)
10185a988416SJim Ingham                                 location->SetThreadIndex(m_options.m_thread_index);
10195a988416SJim Ingham 
10205a988416SJim Ingham                             if (m_options.m_name_passed)
10215a988416SJim Ingham                                 location->SetThreadName(m_options.m_thread_name.c_str());
10225a988416SJim Ingham 
10235a988416SJim Ingham                             if (m_options.m_queue_passed)
10245a988416SJim Ingham                                 location->SetQueueName(m_options.m_queue_name.c_str());
10255a988416SJim Ingham 
10265a988416SJim Ingham                             if (m_options.m_ignore_count != 0)
10275a988416SJim Ingham                                 location->SetIgnoreCount(m_options.m_ignore_count);
10285a988416SJim Ingham 
10295a988416SJim Ingham                             if (m_options.m_enable_passed)
10305a988416SJim Ingham                                 location->SetEnabled (m_options.m_enable_value);
10315a988416SJim Ingham 
10325a988416SJim Ingham                             if (m_options.m_condition_passed)
10335a988416SJim Ingham                                 location->SetCondition (m_options.m_condition.c_str());
10345a988416SJim Ingham                         }
10355a988416SJim Ingham                     }
10365a988416SJim Ingham                     else
10375a988416SJim Ingham                     {
10385a988416SJim Ingham                         if (m_options.m_thread_id_passed)
10395a988416SJim Ingham                             bp->SetThreadID (m_options.m_thread_id);
10405a988416SJim Ingham 
10415a988416SJim Ingham                         if (m_options.m_thread_index_passed)
10425a988416SJim Ingham                             bp->SetThreadIndex(m_options.m_thread_index);
10435a988416SJim Ingham 
10445a988416SJim Ingham                         if (m_options.m_name_passed)
10455a988416SJim Ingham                             bp->SetThreadName(m_options.m_thread_name.c_str());
10465a988416SJim Ingham 
10475a988416SJim Ingham                         if (m_options.m_queue_passed)
10485a988416SJim Ingham                             bp->SetQueueName(m_options.m_queue_name.c_str());
10495a988416SJim Ingham 
10505a988416SJim Ingham                         if (m_options.m_ignore_count != 0)
10515a988416SJim Ingham                             bp->SetIgnoreCount(m_options.m_ignore_count);
10525a988416SJim Ingham 
10535a988416SJim Ingham                         if (m_options.m_enable_passed)
10545a988416SJim Ingham                             bp->SetEnabled (m_options.m_enable_value);
10555a988416SJim Ingham 
10565a988416SJim Ingham                         if (m_options.m_condition_passed)
10575a988416SJim Ingham                             bp->SetCondition (m_options.m_condition.c_str());
10585a988416SJim Ingham                     }
10595a988416SJim Ingham                 }
10605a988416SJim Ingham             }
10615a988416SJim Ingham         }
10625a988416SJim Ingham 
10635a988416SJim Ingham         return result.Succeeded();
10645a988416SJim Ingham     }
10655a988416SJim Ingham 
10665a988416SJim Ingham private:
10675a988416SJim Ingham     CommandOptions m_options;
10685a988416SJim Ingham };
10695a988416SJim Ingham 
10705a988416SJim Ingham #pragma mark Modify::CommandOptions
10715a988416SJim Ingham OptionDefinition
10725a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
10735a988416SJim Ingham {
1074d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." },
1075d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "one-shot",     'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." },
1076d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument."},
1077d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-id",    't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
1078d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "thread-name",  'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
1079d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "queue-name",   'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
1080d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
1081d37221dcSZachary Turner { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1082d37221dcSZachary Turner { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
108333df7cd3SJim Ingham { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
108433df7cd3SJim Ingham 
1085d37221dcSZachary Turner { 0,                false, NULL,            0 , 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
10865a988416SJim Ingham };
10875a988416SJim Ingham 
10885a988416SJim Ingham //-------------------------------------------------------------------------
10895a988416SJim Ingham // CommandObjectBreakpointEnable
10905a988416SJim Ingham //-------------------------------------------------------------------------
10915a988416SJim Ingham #pragma mark Enable
10925a988416SJim Ingham 
10935a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed
10945a988416SJim Ingham {
10955a988416SJim Ingham public:
10965a988416SJim Ingham     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
10975a988416SJim Ingham         CommandObjectParsed (interpreter,
10985a988416SJim Ingham                              "enable",
10995a988416SJim Ingham                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
11005a988416SJim Ingham                              NULL)
11015a988416SJim Ingham     {
11025a988416SJim Ingham         CommandArgumentEntry arg;
11035a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
11045a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
11055a988416SJim Ingham         m_arguments.push_back (arg);
11065a988416SJim Ingham     }
11075a988416SJim Ingham 
11085a988416SJim Ingham 
11095a988416SJim Ingham     virtual
11105a988416SJim Ingham     ~CommandObjectBreakpointEnable () {}
11115a988416SJim Ingham 
11125a988416SJim Ingham protected:
11135a988416SJim Ingham     virtual bool
11145a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
11155a988416SJim Ingham     {
1116893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
11175a988416SJim Ingham         if (target == NULL)
11185a988416SJim Ingham         {
11195a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
11205a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11215a988416SJim Ingham             return false;
11225a988416SJim Ingham         }
11235a988416SJim Ingham 
11245a988416SJim Ingham         Mutex::Locker locker;
11255a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
11265a988416SJim Ingham 
11275a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
11285a988416SJim Ingham 
11295a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
11305a988416SJim Ingham 
11315a988416SJim Ingham         if (num_breakpoints == 0)
11325a988416SJim Ingham         {
11335a988416SJim Ingham             result.AppendError ("No breakpoints exist to be enabled.");
11345a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11355a988416SJim Ingham             return false;
11365a988416SJim Ingham         }
11375a988416SJim Ingham 
11385a988416SJim Ingham         if (command.GetArgumentCount() == 0)
11395a988416SJim Ingham         {
11405a988416SJim Ingham             // No breakpoint selected; enable all currently set breakpoints.
11415a988416SJim Ingham             target->EnableAllBreakpoints ();
11426fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
11435a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
11445a988416SJim Ingham         }
11455a988416SJim Ingham         else
11465a988416SJim Ingham         {
11475a988416SJim Ingham             // Particular breakpoint selected; enable that breakpoint.
11485a988416SJim Ingham             BreakpointIDList valid_bp_ids;
11495e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
11505a988416SJim Ingham 
11515a988416SJim Ingham             if (result.Succeeded())
11525a988416SJim Ingham             {
11535a988416SJim Ingham                 int enable_count = 0;
11545a988416SJim Ingham                 int loc_count = 0;
11555a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
11565a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
11575a988416SJim Ingham                 {
11585a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
11595a988416SJim Ingham 
11605a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
11615a988416SJim Ingham                     {
11625a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
11635a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
11645a988416SJim Ingham                         {
11655a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
11665a988416SJim Ingham                             if (location)
11675a988416SJim Ingham                             {
11685a988416SJim Ingham                                 location->SetEnabled (true);
11695a988416SJim Ingham                                 ++loc_count;
11705a988416SJim Ingham                             }
11715a988416SJim Ingham                         }
11725a988416SJim Ingham                         else
11735a988416SJim Ingham                         {
11745a988416SJim Ingham                             breakpoint->SetEnabled (true);
11755a988416SJim Ingham                             ++enable_count;
11765a988416SJim Ingham                         }
11775a988416SJim Ingham                     }
11785a988416SJim Ingham                 }
11795a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
11805a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
11815a988416SJim Ingham             }
11825a988416SJim Ingham         }
11835a988416SJim Ingham 
11845a988416SJim Ingham         return result.Succeeded();
11855a988416SJim Ingham     }
11865a988416SJim Ingham };
11875a988416SJim Ingham 
11885a988416SJim Ingham //-------------------------------------------------------------------------
11895a988416SJim Ingham // CommandObjectBreakpointDisable
11905a988416SJim Ingham //-------------------------------------------------------------------------
11915a988416SJim Ingham #pragma mark Disable
11925a988416SJim Ingham 
11935a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed
11945a988416SJim Ingham {
11955a988416SJim Ingham public:
11965a988416SJim Ingham     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
11975a988416SJim Ingham         CommandObjectParsed (interpreter,
11985a988416SJim Ingham                              "breakpoint disable",
11995a988416SJim Ingham                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
12005a988416SJim Ingham                              NULL)
12015a988416SJim Ingham     {
1202b0fac509SJim Ingham         SetHelpLong(
1203b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them.  \n\
1204b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\
1205b0fac509SJim Ingham \n\
1206b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\
1207b0fac509SJim Ingham regardless of whether they are enabled or disabled.  So the sequence: \n\
1208b0fac509SJim Ingham \n\
1209b0fac509SJim Ingham     (lldb) break disable 1\n\
1210b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1211b0fac509SJim Ingham \n\
1212b0fac509SJim Ingham will NOT cause location 1.1 to get hit.  To achieve that, do:\n\
1213b0fac509SJim Ingham \n\
1214b0fac509SJim Ingham     (lldb) break disable 1.*\n\
1215b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1216b0fac509SJim Ingham \n\
1217b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\
1218b0fac509SJim Ingham the second re-enables the first location."
1219b0fac509SJim Ingham                     );
1220b0fac509SJim Ingham 
12215a988416SJim Ingham         CommandArgumentEntry arg;
12225a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
12235a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
12245a988416SJim Ingham         m_arguments.push_back (arg);
1225b0fac509SJim Ingham 
12265a988416SJim Ingham     }
12275a988416SJim Ingham 
12285a988416SJim Ingham 
12295a988416SJim Ingham     virtual
12305a988416SJim Ingham     ~CommandObjectBreakpointDisable () {}
12315a988416SJim Ingham 
12325a988416SJim Ingham protected:
12335a988416SJim Ingham     virtual bool
12345a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
12355a988416SJim Ingham     {
1236893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
12375a988416SJim Ingham         if (target == NULL)
12385a988416SJim Ingham         {
12395a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
12405a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12415a988416SJim Ingham             return false;
12425a988416SJim Ingham         }
12435a988416SJim Ingham 
12445a988416SJim Ingham         Mutex::Locker locker;
12455a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
12465a988416SJim Ingham 
12475a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
12485a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
12495a988416SJim Ingham 
12505a988416SJim Ingham         if (num_breakpoints == 0)
12515a988416SJim Ingham         {
12525a988416SJim Ingham             result.AppendError ("No breakpoints exist to be disabled.");
12535a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12545a988416SJim Ingham             return false;
12555a988416SJim Ingham         }
12565a988416SJim Ingham 
12575a988416SJim Ingham         if (command.GetArgumentCount() == 0)
12585a988416SJim Ingham         {
12595a988416SJim Ingham             // No breakpoint selected; disable all currently set breakpoints.
12605a988416SJim Ingham             target->DisableAllBreakpoints ();
12616fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
12625a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
12635a988416SJim Ingham         }
12645a988416SJim Ingham         else
12655a988416SJim Ingham         {
12665a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
12675a988416SJim Ingham             BreakpointIDList valid_bp_ids;
12685a988416SJim Ingham 
12695e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
12705a988416SJim Ingham 
12715a988416SJim Ingham             if (result.Succeeded())
12725a988416SJim Ingham             {
12735a988416SJim Ingham                 int disable_count = 0;
12745a988416SJim Ingham                 int loc_count = 0;
12755a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
12765a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
12775a988416SJim Ingham                 {
12785a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
12795a988416SJim Ingham 
12805a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
12815a988416SJim Ingham                     {
12825a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
12835a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
12845a988416SJim Ingham                         {
12855a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
12865a988416SJim Ingham                             if (location)
12875a988416SJim Ingham                             {
12885a988416SJim Ingham                                 location->SetEnabled (false);
12895a988416SJim Ingham                                 ++loc_count;
12905a988416SJim Ingham                             }
12915a988416SJim Ingham                         }
12925a988416SJim Ingham                         else
12935a988416SJim Ingham                         {
12945a988416SJim Ingham                             breakpoint->SetEnabled (false);
12955a988416SJim Ingham                             ++disable_count;
12965a988416SJim Ingham                         }
12975a988416SJim Ingham                     }
12985a988416SJim Ingham                 }
12995a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
13005a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
13015a988416SJim Ingham             }
13025a988416SJim Ingham         }
13035a988416SJim Ingham 
13045a988416SJim Ingham         return result.Succeeded();
13055a988416SJim Ingham     }
13065a988416SJim Ingham 
13075a988416SJim Ingham };
13085a988416SJim Ingham 
13095a988416SJim Ingham //-------------------------------------------------------------------------
13105a988416SJim Ingham // CommandObjectBreakpointList
13115a988416SJim Ingham //-------------------------------------------------------------------------
13125a988416SJim Ingham #pragma mark List
13135a988416SJim Ingham 
13145a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed
13155a988416SJim Ingham {
13165a988416SJim Ingham public:
13175a988416SJim Ingham     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
13185a988416SJim Ingham         CommandObjectParsed (interpreter,
13195a988416SJim Ingham                              "breakpoint list",
13205a988416SJim Ingham                              "List some or all breakpoints at configurable levels of detail.",
13215a988416SJim Ingham                              NULL),
13225a988416SJim Ingham         m_options (interpreter)
13235a988416SJim Ingham     {
13245a988416SJim Ingham         CommandArgumentEntry arg;
13255a988416SJim Ingham         CommandArgumentData bp_id_arg;
13265a988416SJim Ingham 
13275a988416SJim Ingham         // Define the first (and only) variant of this arg.
13285a988416SJim Ingham         bp_id_arg.arg_type = eArgTypeBreakpointID;
13295a988416SJim Ingham         bp_id_arg.arg_repetition = eArgRepeatOptional;
13305a988416SJim Ingham 
13315a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
13325a988416SJim Ingham         arg.push_back (bp_id_arg);
13335a988416SJim Ingham 
13345a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
13355a988416SJim Ingham         m_arguments.push_back (arg);
13365a988416SJim Ingham     }
13375a988416SJim Ingham 
13385a988416SJim Ingham 
13395a988416SJim Ingham     virtual
13405a988416SJim Ingham     ~CommandObjectBreakpointList () {}
13415a988416SJim Ingham 
13425a988416SJim Ingham     virtual Options *
13435a988416SJim Ingham     GetOptions ()
13445a988416SJim Ingham     {
13455a988416SJim Ingham         return &m_options;
13465a988416SJim Ingham     }
13475a988416SJim Ingham 
13485a988416SJim Ingham     class CommandOptions : public Options
13495a988416SJim Ingham     {
13505a988416SJim Ingham     public:
13515a988416SJim Ingham 
13525a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
13535a988416SJim Ingham             Options (interpreter),
135433df7cd3SJim Ingham             m_level (lldb::eDescriptionLevelBrief),
135533df7cd3SJim Ingham             m_use_dummy(false)
13565a988416SJim Ingham         {
13575a988416SJim Ingham         }
13585a988416SJim Ingham 
13595a988416SJim Ingham         virtual
13605a988416SJim Ingham         ~CommandOptions () {}
13615a988416SJim Ingham 
13625a988416SJim Ingham         virtual Error
13635a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
13645a988416SJim Ingham         {
13655a988416SJim Ingham             Error error;
13663bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13675a988416SJim Ingham 
13685a988416SJim Ingham             switch (short_option)
13695a988416SJim Ingham             {
13705a988416SJim Ingham                 case 'b':
13715a988416SJim Ingham                     m_level = lldb::eDescriptionLevelBrief;
13725a988416SJim Ingham                     break;
137333df7cd3SJim Ingham                 case 'D':
137433df7cd3SJim Ingham                     m_use_dummy = true;
137533df7cd3SJim Ingham                     break;
13765a988416SJim Ingham                 case 'f':
13775a988416SJim Ingham                     m_level = lldb::eDescriptionLevelFull;
13785a988416SJim Ingham                     break;
13795a988416SJim Ingham                 case 'v':
13805a988416SJim Ingham                     m_level = lldb::eDescriptionLevelVerbose;
13815a988416SJim Ingham                     break;
13825a988416SJim Ingham                 case 'i':
13835a988416SJim Ingham                     m_internal = true;
13845a988416SJim Ingham                     break;
13855a988416SJim Ingham                 default:
13865a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
13875a988416SJim Ingham                     break;
13885a988416SJim Ingham             }
13895a988416SJim Ingham 
13905a988416SJim Ingham             return error;
13915a988416SJim Ingham         }
13925a988416SJim Ingham 
13935a988416SJim Ingham         void
13945a988416SJim Ingham         OptionParsingStarting ()
13955a988416SJim Ingham         {
13965a988416SJim Ingham             m_level = lldb::eDescriptionLevelFull;
13975a988416SJim Ingham             m_internal = false;
139833df7cd3SJim Ingham             m_use_dummy = false;
13995a988416SJim Ingham         }
14005a988416SJim Ingham 
14015a988416SJim Ingham         const OptionDefinition *
14025a988416SJim Ingham         GetDefinitions ()
14035a988416SJim Ingham         {
14045a988416SJim Ingham             return g_option_table;
14055a988416SJim Ingham         }
14065a988416SJim Ingham 
14075a988416SJim Ingham         // Options table: Required for subclasses of Options.
14085a988416SJim Ingham 
14095a988416SJim Ingham         static OptionDefinition g_option_table[];
14105a988416SJim Ingham 
14115a988416SJim Ingham         // Instance variables to hold the values for command options.
14125a988416SJim Ingham 
14135a988416SJim Ingham         lldb::DescriptionLevel m_level;
14145a988416SJim Ingham 
14155a988416SJim Ingham         bool m_internal;
141633df7cd3SJim Ingham         bool m_use_dummy;
14175a988416SJim Ingham     };
14185a988416SJim Ingham 
14195a988416SJim Ingham protected:
14205a988416SJim Ingham     virtual bool
14215a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
14225a988416SJim Ingham     {
142333df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
142433df7cd3SJim Ingham 
14255a988416SJim Ingham         if (target == NULL)
14265a988416SJim Ingham         {
14275a988416SJim Ingham             result.AppendError ("Invalid target. No current target or breakpoints.");
14285a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14295a988416SJim Ingham             return true;
14305a988416SJim Ingham         }
14315a988416SJim Ingham 
14325a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
14335a988416SJim Ingham         Mutex::Locker locker;
14345a988416SJim Ingham         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
14355a988416SJim Ingham 
14365a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
14375a988416SJim Ingham 
14385a988416SJim Ingham         if (num_breakpoints == 0)
14395a988416SJim Ingham         {
14405a988416SJim Ingham             result.AppendMessage ("No breakpoints currently set.");
14415a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14425a988416SJim Ingham             return true;
14435a988416SJim Ingham         }
14445a988416SJim Ingham 
14455a988416SJim Ingham         Stream &output_stream = result.GetOutputStream();
14465a988416SJim Ingham 
14475a988416SJim Ingham         if (command.GetArgumentCount() == 0)
14485a988416SJim Ingham         {
14495a988416SJim Ingham             // No breakpoint selected; show info about all currently set breakpoints.
14505a988416SJim Ingham             result.AppendMessage ("Current breakpoints:");
14515a988416SJim Ingham             for (size_t i = 0; i < num_breakpoints; ++i)
14525a988416SJim Ingham             {
14535a988416SJim Ingham                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
14545a988416SJim Ingham                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14555a988416SJim Ingham             }
14565a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14575a988416SJim Ingham         }
14585a988416SJim Ingham         else
14595a988416SJim Ingham         {
14605a988416SJim Ingham             // Particular breakpoints selected; show info about that breakpoint.
14615a988416SJim Ingham             BreakpointIDList valid_bp_ids;
14625e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
14635a988416SJim Ingham 
14645a988416SJim Ingham             if (result.Succeeded())
14655a988416SJim Ingham             {
14665a988416SJim Ingham                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
14675a988416SJim Ingham                 {
14685a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
14695a988416SJim Ingham                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
14705a988416SJim Ingham                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14715a988416SJim Ingham                 }
14725a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
14735a988416SJim Ingham             }
14745a988416SJim Ingham             else
14755a988416SJim Ingham             {
14765a988416SJim Ingham                 result.AppendError ("Invalid breakpoint id.");
14775a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
14785a988416SJim Ingham             }
14795a988416SJim Ingham         }
14805a988416SJim Ingham 
14815a988416SJim Ingham         return result.Succeeded();
14825a988416SJim Ingham     }
14835a988416SJim Ingham 
14845a988416SJim Ingham private:
14855a988416SJim Ingham     CommandOptions m_options;
14865a988416SJim Ingham };
14875a988416SJim Ingham 
14885a988416SJim Ingham #pragma mark List::CommandOptions
14895a988416SJim Ingham OptionDefinition
14905a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] =
14915a988416SJim Ingham {
1492d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14935a988416SJim Ingham         "Show debugger internal breakpoints" },
14945a988416SJim Ingham 
1495d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "brief",    'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14965a988416SJim Ingham         "Give a brief description of the breakpoint (no location info)."},
14975a988416SJim Ingham 
14985a988416SJim Ingham     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
14995a988416SJim Ingham     // But I need to see it for now, and don't want to wait.
1500d37221dcSZachary Turner     { LLDB_OPT_SET_2, false, "full",    'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15015a988416SJim Ingham         "Give a full description of the breakpoint and its locations."},
15025a988416SJim Ingham 
1503d37221dcSZachary Turner     { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15045a988416SJim Ingham         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
15055a988416SJim Ingham 
150633df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
150733df7cd3SJim Ingham         "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
150833df7cd3SJim Ingham 
1509d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
15105a988416SJim Ingham };
15115a988416SJim Ingham 
15125a988416SJim Ingham //-------------------------------------------------------------------------
15135a988416SJim Ingham // CommandObjectBreakpointClear
15145a988416SJim Ingham //-------------------------------------------------------------------------
15155a988416SJim Ingham #pragma mark Clear
15165a988416SJim Ingham 
15175a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed
15185a988416SJim Ingham {
15195a988416SJim Ingham public:
15205a988416SJim Ingham 
15215a988416SJim Ingham     typedef enum BreakpointClearType
15225a988416SJim Ingham     {
15235a988416SJim Ingham         eClearTypeInvalid,
15245a988416SJim Ingham         eClearTypeFileAndLine
15255a988416SJim Ingham     } BreakpointClearType;
15265a988416SJim Ingham 
15275a988416SJim Ingham     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
15285a988416SJim Ingham         CommandObjectParsed (interpreter,
15295a988416SJim Ingham                              "breakpoint clear",
15305a988416SJim Ingham                              "Clears a breakpoint or set of breakpoints in the executable.",
15315a988416SJim Ingham                              "breakpoint clear <cmd-options>"),
15325a988416SJim Ingham         m_options (interpreter)
15335a988416SJim Ingham     {
15345a988416SJim Ingham     }
15355a988416SJim Ingham 
15365a988416SJim Ingham     virtual
15375a988416SJim Ingham     ~CommandObjectBreakpointClear () {}
15385a988416SJim Ingham 
15395a988416SJim Ingham     virtual Options *
15405a988416SJim Ingham     GetOptions ()
15415a988416SJim Ingham     {
15425a988416SJim Ingham         return &m_options;
15435a988416SJim Ingham     }
15445a988416SJim Ingham 
15455a988416SJim Ingham     class CommandOptions : public Options
15465a988416SJim Ingham     {
15475a988416SJim Ingham     public:
15485a988416SJim Ingham 
15495a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
15505a988416SJim Ingham             Options (interpreter),
15515a988416SJim Ingham             m_filename (),
15525a988416SJim Ingham             m_line_num (0)
15535a988416SJim Ingham         {
15545a988416SJim Ingham         }
15555a988416SJim Ingham 
15565a988416SJim Ingham         virtual
15575a988416SJim Ingham         ~CommandOptions () {}
15585a988416SJim Ingham 
15595a988416SJim Ingham         virtual Error
15605a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
15615a988416SJim Ingham         {
15625a988416SJim Ingham             Error error;
15633bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
15645a988416SJim Ingham 
15655a988416SJim Ingham             switch (short_option)
15665a988416SJim Ingham             {
15675a988416SJim Ingham                 case 'f':
15685a988416SJim Ingham                     m_filename.assign (option_arg);
15695a988416SJim Ingham                     break;
15705a988416SJim Ingham 
15715a988416SJim Ingham                 case 'l':
15725275aaa0SVince Harron                     m_line_num = StringConvert::ToUInt32 (option_arg, 0);
15735a988416SJim Ingham                     break;
15745a988416SJim Ingham 
15755a988416SJim Ingham                 default:
15765a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
15775a988416SJim Ingham                     break;
15785a988416SJim Ingham             }
15795a988416SJim Ingham 
15805a988416SJim Ingham             return error;
15815a988416SJim Ingham         }
15825a988416SJim Ingham 
15835a988416SJim Ingham         void
15845a988416SJim Ingham         OptionParsingStarting ()
15855a988416SJim Ingham         {
15865a988416SJim Ingham             m_filename.clear();
15875a988416SJim Ingham             m_line_num = 0;
15885a988416SJim Ingham         }
15895a988416SJim Ingham 
15905a988416SJim Ingham         const OptionDefinition*
15915a988416SJim Ingham         GetDefinitions ()
15925a988416SJim Ingham         {
15935a988416SJim Ingham             return g_option_table;
15945a988416SJim Ingham         }
15955a988416SJim Ingham 
15965a988416SJim Ingham         // Options table: Required for subclasses of Options.
15975a988416SJim Ingham 
15985a988416SJim Ingham         static OptionDefinition g_option_table[];
15995a988416SJim Ingham 
16005a988416SJim Ingham         // Instance variables to hold the values for command options.
16015a988416SJim Ingham 
16025a988416SJim Ingham         std::string m_filename;
16035a988416SJim Ingham         uint32_t m_line_num;
16045a988416SJim Ingham 
16055a988416SJim Ingham     };
16065a988416SJim Ingham 
16075a988416SJim Ingham protected:
16085a988416SJim Ingham     virtual bool
16095a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
16105a988416SJim Ingham     {
1611893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
16125a988416SJim Ingham         if (target == NULL)
16135a988416SJim Ingham         {
16145a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
16155a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16165a988416SJim Ingham             return false;
16175a988416SJim Ingham         }
16185a988416SJim Ingham 
16195a988416SJim Ingham         // The following are the various types of breakpoints that could be cleared:
16205a988416SJim Ingham         //   1). -f -l (clearing breakpoint by source location)
16215a988416SJim Ingham 
16225a988416SJim Ingham         BreakpointClearType break_type = eClearTypeInvalid;
16235a988416SJim Ingham 
16245a988416SJim Ingham         if (m_options.m_line_num != 0)
16255a988416SJim Ingham             break_type = eClearTypeFileAndLine;
16265a988416SJim Ingham 
16275a988416SJim Ingham         Mutex::Locker locker;
16285a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
16295a988416SJim Ingham 
16305a988416SJim Ingham         BreakpointList &breakpoints = target->GetBreakpointList();
16315a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
16325a988416SJim Ingham 
16335a988416SJim Ingham         // Early return if there's no breakpoint at all.
16345a988416SJim Ingham         if (num_breakpoints == 0)
16355a988416SJim Ingham         {
16365a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16375a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16385a988416SJim Ingham             return result.Succeeded();
16395a988416SJim Ingham         }
16405a988416SJim Ingham 
16415a988416SJim Ingham         // Find matching breakpoints and delete them.
16425a988416SJim Ingham 
16435a988416SJim Ingham         // First create a copy of all the IDs.
16445a988416SJim Ingham         std::vector<break_id_t> BreakIDs;
16455a988416SJim Ingham         for (size_t i = 0; i < num_breakpoints; ++i)
16465a988416SJim Ingham             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
16475a988416SJim Ingham 
16485a988416SJim Ingham         int num_cleared = 0;
16495a988416SJim Ingham         StreamString ss;
16505a988416SJim Ingham         switch (break_type)
16515a988416SJim Ingham         {
16525a988416SJim Ingham             case eClearTypeFileAndLine: // Breakpoint by source position
16535a988416SJim Ingham                 {
16545a988416SJim Ingham                     const ConstString filename(m_options.m_filename.c_str());
16555a988416SJim Ingham                     BreakpointLocationCollection loc_coll;
16565a988416SJim Ingham 
16575a988416SJim Ingham                     for (size_t i = 0; i < num_breakpoints; ++i)
16585a988416SJim Ingham                     {
16595a988416SJim Ingham                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
16605a988416SJim Ingham 
16615a988416SJim Ingham                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
16625a988416SJim Ingham                         {
16635a988416SJim Ingham                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
16645a988416SJim Ingham                             if (loc_coll.GetSize() == 0)
16655a988416SJim Ingham                             {
16665a988416SJim Ingham                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
16675a988416SJim Ingham                                 ss.EOL();
16685a988416SJim Ingham                                 target->RemoveBreakpointByID (bp->GetID());
16695a988416SJim Ingham                                 ++num_cleared;
16705a988416SJim Ingham                             }
16715a988416SJim Ingham                         }
16725a988416SJim Ingham                     }
16735a988416SJim Ingham                 }
16745a988416SJim Ingham                 break;
16755a988416SJim Ingham 
16765a988416SJim Ingham             default:
16775a988416SJim Ingham                 break;
16785a988416SJim Ingham         }
16795a988416SJim Ingham 
16805a988416SJim Ingham         if (num_cleared > 0)
16815a988416SJim Ingham         {
16825a988416SJim Ingham             Stream &output_stream = result.GetOutputStream();
16835a988416SJim Ingham             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
16845a988416SJim Ingham             output_stream << ss.GetData();
16855a988416SJim Ingham             output_stream.EOL();
16865a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
16875a988416SJim Ingham         }
16885a988416SJim Ingham         else
16895a988416SJim Ingham         {
16905a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16915a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16925a988416SJim Ingham         }
16935a988416SJim Ingham 
16945a988416SJim Ingham         return result.Succeeded();
16955a988416SJim Ingham     }
16965a988416SJim Ingham 
16975a988416SJim Ingham private:
16985a988416SJim Ingham     CommandOptions m_options;
16995a988416SJim Ingham };
17005a988416SJim Ingham 
17015a988416SJim Ingham #pragma mark Clear::CommandOptions
17025a988416SJim Ingham 
17035a988416SJim Ingham OptionDefinition
17045a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
17055a988416SJim Ingham {
1706d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
17075a988416SJim Ingham         "Specify the breakpoint by source location in this particular file."},
17085a988416SJim Ingham 
1709d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
17105a988416SJim Ingham         "Specify the breakpoint by source location at this particular line."},
17115a988416SJim Ingham 
1712d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
17135a988416SJim Ingham };
17145a988416SJim Ingham 
17155a988416SJim Ingham //-------------------------------------------------------------------------
17165a988416SJim Ingham // CommandObjectBreakpointDelete
17175a988416SJim Ingham //-------------------------------------------------------------------------
17185a988416SJim Ingham #pragma mark Delete
17195a988416SJim Ingham 
17205a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed
17215a988416SJim Ingham {
17225a988416SJim Ingham public:
17235a988416SJim Ingham     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
17245a988416SJim Ingham         CommandObjectParsed (interpreter,
17255a988416SJim Ingham                              "breakpoint delete",
17265a988416SJim Ingham                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
172733df7cd3SJim Ingham                              NULL),
172833df7cd3SJim Ingham         m_options (interpreter)
17295a988416SJim Ingham     {
17305a988416SJim Ingham         CommandArgumentEntry arg;
17315a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
17325a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
17335a988416SJim Ingham         m_arguments.push_back (arg);
17345a988416SJim Ingham     }
17355a988416SJim Ingham 
17365a988416SJim Ingham     virtual
17375a988416SJim Ingham     ~CommandObjectBreakpointDelete () {}
17385a988416SJim Ingham 
173933df7cd3SJim Ingham     virtual Options *
174033df7cd3SJim Ingham     GetOptions ()
174133df7cd3SJim Ingham     {
174233df7cd3SJim Ingham         return &m_options;
174333df7cd3SJim Ingham     }
174433df7cd3SJim Ingham 
174533df7cd3SJim Ingham     class CommandOptions : public Options
174633df7cd3SJim Ingham     {
174733df7cd3SJim Ingham     public:
174833df7cd3SJim Ingham 
174933df7cd3SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
175033df7cd3SJim Ingham             Options (interpreter),
175133df7cd3SJim Ingham             m_use_dummy (false),
175233df7cd3SJim Ingham             m_force (false)
175333df7cd3SJim Ingham         {
175433df7cd3SJim Ingham         }
175533df7cd3SJim Ingham 
175633df7cd3SJim Ingham         virtual
175733df7cd3SJim Ingham         ~CommandOptions () {}
175833df7cd3SJim Ingham 
175933df7cd3SJim Ingham         virtual Error
176033df7cd3SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
176133df7cd3SJim Ingham         {
176233df7cd3SJim Ingham             Error error;
176333df7cd3SJim Ingham             const int short_option = m_getopt_table[option_idx].val;
176433df7cd3SJim Ingham 
176533df7cd3SJim Ingham             switch (short_option)
176633df7cd3SJim Ingham             {
176733df7cd3SJim Ingham                 case 'f':
176833df7cd3SJim Ingham                     m_force = true;
176933df7cd3SJim Ingham                     break;
177033df7cd3SJim Ingham 
177133df7cd3SJim Ingham                 case 'D':
177233df7cd3SJim Ingham                     m_use_dummy = true;
177333df7cd3SJim Ingham                     break;
177433df7cd3SJim Ingham 
177533df7cd3SJim Ingham                 default:
177633df7cd3SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
177733df7cd3SJim Ingham                     break;
177833df7cd3SJim Ingham             }
177933df7cd3SJim Ingham 
178033df7cd3SJim Ingham             return error;
178133df7cd3SJim Ingham         }
178233df7cd3SJim Ingham 
178333df7cd3SJim Ingham         void
178433df7cd3SJim Ingham         OptionParsingStarting ()
178533df7cd3SJim Ingham         {
178633df7cd3SJim Ingham             m_use_dummy = false;
178733df7cd3SJim Ingham             m_force = false;
178833df7cd3SJim Ingham         }
178933df7cd3SJim Ingham 
179033df7cd3SJim Ingham         const OptionDefinition*
179133df7cd3SJim Ingham         GetDefinitions ()
179233df7cd3SJim Ingham         {
179333df7cd3SJim Ingham             return g_option_table;
179433df7cd3SJim Ingham         }
179533df7cd3SJim Ingham 
179633df7cd3SJim Ingham         // Options table: Required for subclasses of Options.
179733df7cd3SJim Ingham 
179833df7cd3SJim Ingham         static OptionDefinition g_option_table[];
179933df7cd3SJim Ingham 
180033df7cd3SJim Ingham         // Instance variables to hold the values for command options.
180133df7cd3SJim Ingham         bool m_use_dummy;
180233df7cd3SJim Ingham         bool m_force;
180333df7cd3SJim Ingham     };
180433df7cd3SJim Ingham 
18055a988416SJim Ingham protected:
18065a988416SJim Ingham     virtual bool
18075a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
18085a988416SJim Ingham     {
180933df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
181033df7cd3SJim Ingham 
18115a988416SJim Ingham         if (target == NULL)
18125a988416SJim Ingham         {
18135a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
18145a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18155a988416SJim Ingham             return false;
18165a988416SJim Ingham         }
18175a988416SJim Ingham 
18185a988416SJim Ingham         Mutex::Locker locker;
18195a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
18205a988416SJim Ingham 
18215a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
18225a988416SJim Ingham 
18235a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
18245a988416SJim Ingham 
18255a988416SJim Ingham         if (num_breakpoints == 0)
18265a988416SJim Ingham         {
18275a988416SJim Ingham             result.AppendError ("No breakpoints exist to be deleted.");
18285a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18295a988416SJim Ingham             return false;
18305a988416SJim Ingham         }
18315a988416SJim Ingham 
18325a988416SJim Ingham         if (command.GetArgumentCount() == 0)
18335a988416SJim Ingham         {
183433df7cd3SJim Ingham             if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
18355a988416SJim Ingham             {
18365a988416SJim Ingham                 result.AppendMessage("Operation cancelled...");
18375a988416SJim Ingham             }
18385a988416SJim Ingham             else
18395a988416SJim Ingham             {
18405a988416SJim Ingham                 target->RemoveAllBreakpoints ();
18416fea17e8SGreg Clayton                 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
18425a988416SJim Ingham             }
18435a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
18445a988416SJim Ingham         }
18455a988416SJim Ingham         else
18465a988416SJim Ingham         {
18475a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
18485a988416SJim Ingham             BreakpointIDList valid_bp_ids;
18495e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
18505a988416SJim Ingham 
18515a988416SJim Ingham             if (result.Succeeded())
18525a988416SJim Ingham             {
18535a988416SJim Ingham                 int delete_count = 0;
18545a988416SJim Ingham                 int disable_count = 0;
18555a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
18565a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
18575a988416SJim Ingham                 {
18585a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
18595a988416SJim Ingham 
18605a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
18615a988416SJim Ingham                     {
18625a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
18635a988416SJim Ingham                         {
18645a988416SJim Ingham                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
18655a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
18665a988416SJim Ingham                             // It makes no sense to try to delete individual locations, so we disable them instead.
18675a988416SJim Ingham                             if (location)
18685a988416SJim Ingham                             {
18695a988416SJim Ingham                                 location->SetEnabled (false);
18705a988416SJim Ingham                                 ++disable_count;
18715a988416SJim Ingham                             }
18725a988416SJim Ingham                         }
18735a988416SJim Ingham                         else
18745a988416SJim Ingham                         {
18755a988416SJim Ingham                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
18765a988416SJim Ingham                             ++delete_count;
18775a988416SJim Ingham                         }
18785a988416SJim Ingham                     }
18795a988416SJim Ingham                 }
18805a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
18815a988416SJim Ingham                                                delete_count, disable_count);
18825a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
18835a988416SJim Ingham             }
18845a988416SJim Ingham         }
18855a988416SJim Ingham         return result.Succeeded();
18865a988416SJim Ingham     }
188733df7cd3SJim Ingham private:
188833df7cd3SJim Ingham     CommandOptions m_options;
188933df7cd3SJim Ingham };
189033df7cd3SJim Ingham 
189133df7cd3SJim Ingham OptionDefinition
189233df7cd3SJim Ingham CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
189333df7cd3SJim Ingham {
189433df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
189533df7cd3SJim Ingham         "Delete all breakpoints without querying for confirmation."},
189633df7cd3SJim Ingham 
189733df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
189833df7cd3SJim Ingham         "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
189933df7cd3SJim Ingham 
190033df7cd3SJim Ingham     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
19015a988416SJim Ingham };
19025a988416SJim Ingham 
190330fdc8d8SChris Lattner //-------------------------------------------------------------------------
19045e09c8c3SJim Ingham // CommandObjectBreakpointName
19055e09c8c3SJim Ingham //-------------------------------------------------------------------------
19065e09c8c3SJim Ingham 
19075e09c8c3SJim Ingham static OptionDefinition
19085e09c8c3SJim Ingham g_breakpoint_name_options[] =
19095e09c8c3SJim Ingham {
19105e09c8c3SJim Ingham     { LLDB_OPT_SET_1,   false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
19115e09c8c3SJim Ingham     { LLDB_OPT_SET_2,   false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID,   "Specify a breakpoint id to use."},
19125e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
19135e09c8c3SJim Ingham         "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
19145e09c8c3SJim Ingham };
19155e09c8c3SJim Ingham class BreakpointNameOptionGroup : public OptionGroup
19165e09c8c3SJim Ingham {
19175e09c8c3SJim Ingham public:
19185e09c8c3SJim Ingham     BreakpointNameOptionGroup() :
19195e09c8c3SJim Ingham         OptionGroup(),
19205e09c8c3SJim Ingham         m_breakpoint(LLDB_INVALID_BREAK_ID),
19215e09c8c3SJim Ingham         m_use_dummy (false)
19225e09c8c3SJim Ingham     {
19235e09c8c3SJim Ingham 
19245e09c8c3SJim Ingham     }
19255e09c8c3SJim Ingham 
19265e09c8c3SJim Ingham     virtual
19275e09c8c3SJim Ingham     ~BreakpointNameOptionGroup ()
19285e09c8c3SJim Ingham     {
19295e09c8c3SJim Ingham     }
19305e09c8c3SJim Ingham 
19315e09c8c3SJim Ingham     virtual uint32_t
19325e09c8c3SJim Ingham     GetNumDefinitions ()
19335e09c8c3SJim Ingham     {
19345e09c8c3SJim Ingham       return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
19355e09c8c3SJim Ingham     }
19365e09c8c3SJim Ingham 
19375e09c8c3SJim Ingham     virtual const OptionDefinition*
19385e09c8c3SJim Ingham     GetDefinitions ()
19395e09c8c3SJim Ingham     {
19405e09c8c3SJim Ingham         return g_breakpoint_name_options;
19415e09c8c3SJim Ingham     }
19425e09c8c3SJim Ingham 
19435e09c8c3SJim Ingham     virtual Error
19445e09c8c3SJim Ingham     SetOptionValue (CommandInterpreter &interpreter,
19455e09c8c3SJim Ingham                     uint32_t option_idx,
19465e09c8c3SJim Ingham                     const char *option_value)
19475e09c8c3SJim Ingham     {
19485e09c8c3SJim Ingham         Error error;
19495e09c8c3SJim Ingham         const int short_option = g_breakpoint_name_options[option_idx].short_option;
19505e09c8c3SJim Ingham 
19515e09c8c3SJim Ingham         switch (short_option)
19525e09c8c3SJim Ingham         {
19535e09c8c3SJim Ingham         case 'N':
19545e09c8c3SJim Ingham             if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
1955c95f7e2aSPavel Labath                 m_name.SetValueFromString(option_value);
19565e09c8c3SJim Ingham             break;
19575e09c8c3SJim Ingham 
19585e09c8c3SJim Ingham         case 'B':
1959c95f7e2aSPavel Labath             if (m_breakpoint.SetValueFromString(option_value).Fail())
19605e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
19615e09c8c3SJim Ingham             break;
19625e09c8c3SJim Ingham         case 'D':
1963c95f7e2aSPavel Labath             if (m_use_dummy.SetValueFromString(option_value).Fail())
19645e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
19655e09c8c3SJim Ingham             break;
19665e09c8c3SJim Ingham 
19675e09c8c3SJim Ingham         default:
19685e09c8c3SJim Ingham               error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
19695e09c8c3SJim Ingham               break;
19705e09c8c3SJim Ingham         }
19715e09c8c3SJim Ingham         return error;
19725e09c8c3SJim Ingham     }
19735e09c8c3SJim Ingham 
19745e09c8c3SJim Ingham     virtual void
19755e09c8c3SJim Ingham     OptionParsingStarting (CommandInterpreter &interpreter)
19765e09c8c3SJim Ingham     {
19775e09c8c3SJim Ingham         m_name.Clear();
19785e09c8c3SJim Ingham         m_breakpoint.Clear();
19795e09c8c3SJim Ingham         m_use_dummy.Clear();
19805e09c8c3SJim Ingham         m_use_dummy.SetDefaultValue(false);
19815e09c8c3SJim Ingham     }
19825e09c8c3SJim Ingham 
19835e09c8c3SJim Ingham     OptionValueString m_name;
19845e09c8c3SJim Ingham     OptionValueUInt64 m_breakpoint;
19855e09c8c3SJim Ingham     OptionValueBoolean m_use_dummy;
19865e09c8c3SJim Ingham };
19875e09c8c3SJim Ingham 
19885e09c8c3SJim Ingham 
19895e09c8c3SJim Ingham class CommandObjectBreakpointNameAdd : public CommandObjectParsed
19905e09c8c3SJim Ingham {
19915e09c8c3SJim Ingham public:
19925e09c8c3SJim Ingham     CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
19935e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
19945e09c8c3SJim Ingham                              "add",
19955e09c8c3SJim Ingham                              "Add a name to the breakpoints provided.",
19965e09c8c3SJim Ingham                              "breakpoint name add <command-options> <breakpoint-id-list>"),
19975e09c8c3SJim Ingham         m_name_options(),
19985e09c8c3SJim Ingham         m_option_group(interpreter)
19995e09c8c3SJim Ingham         {
20005e09c8c3SJim Ingham             // Create the first variant for the first (and only) argument for this command.
20015e09c8c3SJim Ingham             CommandArgumentEntry arg1;
20025e09c8c3SJim Ingham             CommandArgumentData id_arg;
20035e09c8c3SJim Ingham             id_arg.arg_type = eArgTypeBreakpointID;
20045e09c8c3SJim Ingham             id_arg.arg_repetition = eArgRepeatOptional;
20055e09c8c3SJim Ingham             arg1.push_back(id_arg);
20065e09c8c3SJim Ingham             m_arguments.push_back (arg1);
20075e09c8c3SJim Ingham 
20085e09c8c3SJim Ingham             m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
20095e09c8c3SJim Ingham             m_option_group.Finalize();
20105e09c8c3SJim Ingham         }
20115e09c8c3SJim Ingham 
20125e09c8c3SJim Ingham     virtual
20135e09c8c3SJim Ingham     ~CommandObjectBreakpointNameAdd () {}
20145e09c8c3SJim Ingham 
20155e09c8c3SJim Ingham   Options *
20165e09c8c3SJim Ingham   GetOptions ()
20175e09c8c3SJim Ingham   {
20185e09c8c3SJim Ingham     return &m_option_group;
20195e09c8c3SJim Ingham   }
20205e09c8c3SJim Ingham 
20215e09c8c3SJim Ingham protected:
20225e09c8c3SJim Ingham     virtual bool
20235e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
20245e09c8c3SJim Ingham     {
20255e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
20265e09c8c3SJim Ingham         {
20275e09c8c3SJim Ingham             result.SetError("No name option provided.");
20285e09c8c3SJim Ingham             return false;
20295e09c8c3SJim Ingham         }
20305e09c8c3SJim Ingham 
20315e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
20325e09c8c3SJim Ingham 
20335e09c8c3SJim Ingham         if (target == NULL)
20345e09c8c3SJim Ingham         {
20355e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
20365e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
20375e09c8c3SJim Ingham             return false;
20385e09c8c3SJim Ingham         }
20395e09c8c3SJim Ingham 
20405e09c8c3SJim Ingham         Mutex::Locker locker;
20415e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
20425e09c8c3SJim Ingham 
20435e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
20445e09c8c3SJim Ingham 
20455e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
20465e09c8c3SJim Ingham         if (num_breakpoints == 0)
20475e09c8c3SJim Ingham         {
20485e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot add names.");
20495e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
20505e09c8c3SJim Ingham             return false;
20515e09c8c3SJim Ingham         }
20525e09c8c3SJim Ingham 
20535e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
20545e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
20555e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
20565e09c8c3SJim Ingham 
20575e09c8c3SJim Ingham         if (result.Succeeded())
20585e09c8c3SJim Ingham         {
20595e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
20605e09c8c3SJim Ingham             {
20615e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot add names.");
20625e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
20635e09c8c3SJim Ingham                 return false;
20645e09c8c3SJim Ingham             }
20655e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
20665e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
20675e09c8c3SJim Ingham             {
20685e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
20695e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
20705e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
20715e09c8c3SJim Ingham                 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
20725e09c8c3SJim Ingham             }
20735e09c8c3SJim Ingham         }
20745e09c8c3SJim Ingham 
20755e09c8c3SJim Ingham         return true;
20765e09c8c3SJim Ingham     }
20775e09c8c3SJim Ingham 
20785e09c8c3SJim Ingham private:
20795e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
20805e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
20815e09c8c3SJim Ingham };
20825e09c8c3SJim Ingham 
20835e09c8c3SJim Ingham 
20845e09c8c3SJim Ingham 
20855e09c8c3SJim Ingham class CommandObjectBreakpointNameDelete : public CommandObjectParsed
20865e09c8c3SJim Ingham {
20875e09c8c3SJim Ingham public:
20885e09c8c3SJim Ingham     CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
20895e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
20905e09c8c3SJim Ingham                              "delete",
20915e09c8c3SJim Ingham                              "Delete a name from the breakpoints provided.",
20925e09c8c3SJim Ingham                              "breakpoint name delete <command-options> <breakpoint-id-list>"),
20935e09c8c3SJim Ingham         m_name_options(),
20945e09c8c3SJim Ingham         m_option_group(interpreter)
20955e09c8c3SJim Ingham     {
20965e09c8c3SJim Ingham         // Create the first variant for the first (and only) argument for this command.
20975e09c8c3SJim Ingham         CommandArgumentEntry arg1;
20985e09c8c3SJim Ingham         CommandArgumentData id_arg;
20995e09c8c3SJim Ingham         id_arg.arg_type = eArgTypeBreakpointID;
21005e09c8c3SJim Ingham         id_arg.arg_repetition = eArgRepeatOptional;
21015e09c8c3SJim Ingham         arg1.push_back(id_arg);
21025e09c8c3SJim Ingham         m_arguments.push_back (arg1);
21035e09c8c3SJim Ingham 
21045e09c8c3SJim Ingham         m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
21055e09c8c3SJim Ingham         m_option_group.Finalize();
21065e09c8c3SJim Ingham     }
21075e09c8c3SJim Ingham 
21085e09c8c3SJim Ingham     virtual
21095e09c8c3SJim Ingham     ~CommandObjectBreakpointNameDelete () {}
21105e09c8c3SJim Ingham 
21115e09c8c3SJim Ingham   Options *
21125e09c8c3SJim Ingham   GetOptions ()
21135e09c8c3SJim Ingham   {
21145e09c8c3SJim Ingham     return &m_option_group;
21155e09c8c3SJim Ingham   }
21165e09c8c3SJim Ingham 
21175e09c8c3SJim Ingham protected:
21185e09c8c3SJim Ingham     virtual bool
21195e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
21205e09c8c3SJim Ingham     {
21215e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
21225e09c8c3SJim Ingham         {
21235e09c8c3SJim Ingham             result.SetError("No name option provided.");
21245e09c8c3SJim Ingham             return false;
21255e09c8c3SJim Ingham         }
21265e09c8c3SJim Ingham 
21275e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
21285e09c8c3SJim Ingham 
21295e09c8c3SJim Ingham         if (target == NULL)
21305e09c8c3SJim Ingham         {
21315e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
21325e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21335e09c8c3SJim Ingham             return false;
21345e09c8c3SJim Ingham         }
21355e09c8c3SJim Ingham 
21365e09c8c3SJim Ingham         Mutex::Locker locker;
21375e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
21385e09c8c3SJim Ingham 
21395e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
21405e09c8c3SJim Ingham 
21415e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
21425e09c8c3SJim Ingham         if (num_breakpoints == 0)
21435e09c8c3SJim Ingham         {
21445e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot delete names.");
21455e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21465e09c8c3SJim Ingham             return false;
21475e09c8c3SJim Ingham         }
21485e09c8c3SJim Ingham 
21495e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
21505e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
21515e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
21525e09c8c3SJim Ingham 
21535e09c8c3SJim Ingham         if (result.Succeeded())
21545e09c8c3SJim Ingham         {
21555e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
21565e09c8c3SJim Ingham             {
21575e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot delete names.");
21585e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
21595e09c8c3SJim Ingham                 return false;
21605e09c8c3SJim Ingham             }
21615e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
21625e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
21635e09c8c3SJim Ingham             {
21645e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
21655e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
21665e09c8c3SJim Ingham                 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
21675e09c8c3SJim Ingham             }
21685e09c8c3SJim Ingham         }
21695e09c8c3SJim Ingham 
21705e09c8c3SJim Ingham         return true;
21715e09c8c3SJim Ingham     }
21725e09c8c3SJim Ingham 
21735e09c8c3SJim Ingham private:
21745e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
21755e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
21765e09c8c3SJim Ingham };
21775e09c8c3SJim Ingham 
21785e09c8c3SJim Ingham class CommandObjectBreakpointNameList : public CommandObjectParsed
21795e09c8c3SJim Ingham {
21805e09c8c3SJim Ingham public:
21815e09c8c3SJim Ingham     CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
21825e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
21835e09c8c3SJim Ingham                              "list",
21845e09c8c3SJim Ingham                              "List either the names for a breakpoint or the breakpoints for a given name.",
21855e09c8c3SJim Ingham                              "breakpoint name list <command-options>"),
21865e09c8c3SJim Ingham         m_name_options(),
21875e09c8c3SJim Ingham         m_option_group(interpreter)
21885e09c8c3SJim Ingham     {
21895e09c8c3SJim Ingham         m_option_group.Append (&m_name_options);
21905e09c8c3SJim Ingham         m_option_group.Finalize();
21915e09c8c3SJim Ingham     }
21925e09c8c3SJim Ingham 
21935e09c8c3SJim Ingham     virtual
21945e09c8c3SJim Ingham     ~CommandObjectBreakpointNameList () {}
21955e09c8c3SJim Ingham 
21965e09c8c3SJim Ingham   Options *
21975e09c8c3SJim Ingham   GetOptions ()
21985e09c8c3SJim Ingham   {
21995e09c8c3SJim Ingham     return &m_option_group;
22005e09c8c3SJim Ingham   }
22015e09c8c3SJim Ingham 
22025e09c8c3SJim Ingham protected:
22035e09c8c3SJim Ingham protected:
22045e09c8c3SJim Ingham     virtual bool
22055e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
22065e09c8c3SJim Ingham     {
22075e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
22085e09c8c3SJim Ingham 
22095e09c8c3SJim Ingham         if (target == NULL)
22105e09c8c3SJim Ingham         {
22115e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
22125e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
22135e09c8c3SJim Ingham             return false;
22145e09c8c3SJim Ingham         }
22155e09c8c3SJim Ingham 
22165e09c8c3SJim Ingham         if (m_name_options.m_name.OptionWasSet())
22175e09c8c3SJim Ingham         {
22185e09c8c3SJim Ingham             const char *name = m_name_options.m_name.GetCurrentValue();
22195e09c8c3SJim Ingham             Mutex::Locker locker;
22205e09c8c3SJim Ingham             target->GetBreakpointList().GetListMutex(locker);
22215e09c8c3SJim Ingham 
22225e09c8c3SJim Ingham             BreakpointList &breakpoints = target->GetBreakpointList();
22235e09c8c3SJim Ingham             for (BreakpointSP bp_sp : breakpoints.Breakpoints())
22245e09c8c3SJim Ingham             {
22255e09c8c3SJim Ingham                 if (bp_sp->MatchesName(name))
22265e09c8c3SJim Ingham                 {
22275e09c8c3SJim Ingham                     StreamString s;
22285e09c8c3SJim Ingham                     bp_sp->GetDescription(&s, eDescriptionLevelBrief);
22295e09c8c3SJim Ingham                     s.EOL();
22305e09c8c3SJim Ingham                     result.AppendMessage(s.GetData());
22315e09c8c3SJim Ingham                 }
22325e09c8c3SJim Ingham             }
22335e09c8c3SJim Ingham 
22345e09c8c3SJim Ingham         }
22355e09c8c3SJim Ingham         else if (m_name_options.m_breakpoint.OptionWasSet())
22365e09c8c3SJim Ingham         {
22375e09c8c3SJim Ingham             BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
22385e09c8c3SJim Ingham             if (bp_sp)
22395e09c8c3SJim Ingham             {
22405e09c8c3SJim Ingham                 std::vector<std::string> names;
22415e09c8c3SJim Ingham                 bp_sp->GetNames (names);
22425e09c8c3SJim Ingham                 result.AppendMessage ("Names:");
22435e09c8c3SJim Ingham                 for (auto name : names)
22445e09c8c3SJim Ingham                     result.AppendMessageWithFormat ("    %s\n", name.c_str());
22455e09c8c3SJim Ingham             }
22465e09c8c3SJim Ingham             else
22475e09c8c3SJim Ingham             {
22485e09c8c3SJim Ingham                 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
22495e09c8c3SJim Ingham                                            m_name_options.m_breakpoint.GetCurrentValue());
22505e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
22515e09c8c3SJim Ingham                 return false;
22525e09c8c3SJim Ingham             }
22535e09c8c3SJim Ingham         }
22545e09c8c3SJim Ingham         else
22555e09c8c3SJim Ingham         {
22565e09c8c3SJim Ingham             result.SetError ("Must specify -N or -B option to list.");
22575e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
22585e09c8c3SJim Ingham             return false;
22595e09c8c3SJim Ingham         }
22605e09c8c3SJim Ingham         return true;
22615e09c8c3SJim Ingham     }
22625e09c8c3SJim Ingham 
22635e09c8c3SJim Ingham private:
22645e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
22655e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
22665e09c8c3SJim Ingham };
22675e09c8c3SJim Ingham 
22685e09c8c3SJim Ingham //-------------------------------------------------------------------------
22695e09c8c3SJim Ingham // CommandObjectMultiwordBreakpoint
22705e09c8c3SJim Ingham //-------------------------------------------------------------------------
22715e09c8c3SJim Ingham class CommandObjectBreakpointName : public CommandObjectMultiword
22725e09c8c3SJim Ingham {
22735e09c8c3SJim Ingham public:
22745e09c8c3SJim Ingham     CommandObjectBreakpointName (CommandInterpreter &interpreter) :
22755e09c8c3SJim Ingham         CommandObjectMultiword(interpreter,
22765e09c8c3SJim Ingham                                 "name",
22775e09c8c3SJim Ingham                                 "A set of commands to manage name tags for breakpoints",
22785e09c8c3SJim Ingham                                 "breakpoint name <command> [<command-options>]")
22795e09c8c3SJim Ingham     {
22805e09c8c3SJim Ingham         CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
22815e09c8c3SJim Ingham         CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
22825e09c8c3SJim Ingham         CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
22835e09c8c3SJim Ingham 
22845e09c8c3SJim Ingham         LoadSubCommand ("add", add_command_object);
22855e09c8c3SJim Ingham         LoadSubCommand ("delete", delete_command_object);
22865e09c8c3SJim Ingham         LoadSubCommand ("list", list_command_object);
22875e09c8c3SJim Ingham 
22885e09c8c3SJim Ingham     }
22895e09c8c3SJim Ingham 
22905e09c8c3SJim Ingham     virtual
22915e09c8c3SJim Ingham     ~CommandObjectBreakpointName ()
22925e09c8c3SJim Ingham     {
22935e09c8c3SJim Ingham     }
22945e09c8c3SJim Ingham 
22955e09c8c3SJim Ingham };
22965e09c8c3SJim Ingham 
22975e09c8c3SJim Ingham 
22985e09c8c3SJim Ingham //-------------------------------------------------------------------------
229930fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
230030fdc8d8SChris Lattner //-------------------------------------------------------------------------
2301ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
230230fdc8d8SChris Lattner 
23036611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
2304a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
2305a7015092SGreg Clayton                             "breakpoint",
230646fbc60fSJim Ingham                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
230730fdc8d8SChris Lattner                             "breakpoint <command> [<command-options>]")
230830fdc8d8SChris Lattner {
2309a7015092SGreg Clayton     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
2310a7015092SGreg Clayton     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2311a7015092SGreg Clayton     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
2312b7234e40SJohnny Chen     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2313b7234e40SJohnny Chen     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
2314a7015092SGreg Clayton     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
231530fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
2316a7015092SGreg Clayton     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
23175e09c8c3SJim Ingham     CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
231830fdc8d8SChris Lattner 
2319b7234e40SJohnny Chen     list_command_object->SetCommandName ("breakpoint list");
232030fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
232130fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
2322b7234e40SJohnny Chen     clear_command_object->SetCommandName("breakpoint clear");
2323b7234e40SJohnny Chen     delete_command_object->SetCommandName("breakpoint delete");
2324ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
2325b7234e40SJohnny Chen     command_command_object->SetCommandName ("breakpoint command");
2326b7234e40SJohnny Chen     modify_command_object->SetCommandName ("breakpoint modify");
23275e09c8c3SJim Ingham     name_command_object->SetCommandName ("breakpoint name");
232830fdc8d8SChris Lattner 
232923f59509SGreg Clayton     LoadSubCommand ("list",       list_command_object);
233023f59509SGreg Clayton     LoadSubCommand ("enable",     enable_command_object);
233123f59509SGreg Clayton     LoadSubCommand ("disable",    disable_command_object);
233223f59509SGreg Clayton     LoadSubCommand ("clear",      clear_command_object);
233323f59509SGreg Clayton     LoadSubCommand ("delete",     delete_command_object);
233423f59509SGreg Clayton     LoadSubCommand ("set",        set_command_object);
233523f59509SGreg Clayton     LoadSubCommand ("command",    command_command_object);
233623f59509SGreg Clayton     LoadSubCommand ("modify",     modify_command_object);
23375e09c8c3SJim Ingham     LoadSubCommand ("name",       name_command_object);
233830fdc8d8SChris Lattner }
233930fdc8d8SChris Lattner 
234030fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
234130fdc8d8SChris Lattner {
234230fdc8d8SChris Lattner }
234330fdc8d8SChris Lattner 
234430fdc8d8SChris Lattner void
23455e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
23465e09c8c3SJim Ingham                                              Target *target,
23475e09c8c3SJim Ingham                                              bool allow_locations,
23485e09c8c3SJim Ingham                                              CommandReturnObject &result,
234930fdc8d8SChris Lattner                                              BreakpointIDList *valid_ids)
235030fdc8d8SChris Lattner {
235130fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
235230fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
235330fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
235430fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
23555e09c8c3SJim Ingham     //                                  4). A breakpoint name
235636f3b369SJim Ingham     // If args is empty, we will use the last created breakpoint (if there is one.)
235730fdc8d8SChris Lattner 
235830fdc8d8SChris Lattner     Args temp_args;
235930fdc8d8SChris Lattner 
236036f3b369SJim Ingham     if (args.GetArgumentCount() == 0)
236136f3b369SJim Ingham     {
23624d122c40SGreg Clayton         if (target->GetLastCreatedBreakpoint())
236336f3b369SJim Ingham         {
236436f3b369SJim Ingham             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
236536f3b369SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
236636f3b369SJim Ingham         }
236736f3b369SJim Ingham         else
236836f3b369SJim Ingham         {
236936f3b369SJim Ingham             result.AppendError("No breakpoint specified and no last created breakpoint.");
237036f3b369SJim Ingham             result.SetStatus (eReturnStatusFailed);
237136f3b369SJim Ingham         }
237236f3b369SJim Ingham         return;
237336f3b369SJim Ingham     }
237436f3b369SJim Ingham 
237530fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
237630fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
237730fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
237830fdc8d8SChris Lattner 
23795e09c8c3SJim Ingham     BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
238030fdc8d8SChris Lattner 
238130fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
238230fdc8d8SChris Lattner 
2383c982c768SGreg Clayton     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
238430fdc8d8SChris Lattner 
238530fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
238630fdc8d8SChris Lattner     // and put into valid_ids.
238730fdc8d8SChris Lattner 
238830fdc8d8SChris Lattner     if (result.Succeeded())
238930fdc8d8SChris Lattner     {
239030fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
239130fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
239230fdc8d8SChris Lattner 
2393c982c768SGreg Clayton         const size_t count = valid_ids->GetSize();
2394c982c768SGreg Clayton         for (size_t i = 0; i < count; ++i)
239530fdc8d8SChris Lattner         {
239630fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
239730fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
239830fdc8d8SChris Lattner             if (breakpoint != NULL)
239930fdc8d8SChris Lattner             {
2400c7bece56SGreg Clayton                 const size_t num_locations = breakpoint->GetNumLocations();
24013985c8c6SSaleem Abdulrasool                 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
240230fdc8d8SChris Lattner                 {
240330fdc8d8SChris Lattner                     StreamString id_str;
2404c982c768SGreg Clayton                     BreakpointID::GetCanonicalReference (&id_str,
2405c982c768SGreg Clayton                                                          cur_bp_id.GetBreakpointID(),
240630fdc8d8SChris Lattner                                                          cur_bp_id.GetLocationID());
2407c982c768SGreg Clayton                     i = valid_ids->GetSize() + 1;
240830fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
240930fdc8d8SChris Lattner                                                  id_str.GetData());
241030fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
241130fdc8d8SChris Lattner                 }
241230fdc8d8SChris Lattner             }
241330fdc8d8SChris Lattner             else
241430fdc8d8SChris Lattner             {
2415c982c768SGreg Clayton                 i = valid_ids->GetSize() + 1;
241630fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
241730fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
241830fdc8d8SChris Lattner             }
241930fdc8d8SChris Lattner         }
242030fdc8d8SChris Lattner     }
242130fdc8d8SChris Lattner }
2422