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"
24*32abc6edSZachary 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"
3130fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3230fdc8d8SChris Lattner #include "lldb/Interpreter/CommandCompletions.h"
33b57e4a1bSJason Molenda #include "lldb/Target/StackFrame.h"
341b54c88cSJim Ingham #include "lldb/Target/Thread.h"
351b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h"
3630fdc8d8SChris Lattner 
37b7234e40SJohnny Chen #include <vector>
38b7234e40SJohnny Chen 
3930fdc8d8SChris Lattner using namespace lldb;
4030fdc8d8SChris Lattner using namespace lldb_private;
4130fdc8d8SChris Lattner 
4230fdc8d8SChris Lattner static void
4385e8b814SJim Ingham AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel level)
4430fdc8d8SChris Lattner {
4530fdc8d8SChris Lattner     s->IndentMore();
4630fdc8d8SChris Lattner     bp->GetDescription (s, level, true);
4730fdc8d8SChris Lattner     s->IndentLess();
4830fdc8d8SChris Lattner     s->EOL();
4930fdc8d8SChris Lattner }
5030fdc8d8SChris Lattner 
5130fdc8d8SChris Lattner //-------------------------------------------------------------------------
525a988416SJim Ingham // CommandObjectBreakpointSet
5330fdc8d8SChris Lattner //-------------------------------------------------------------------------
5430fdc8d8SChris Lattner 
555a988416SJim Ingham 
565a988416SJim Ingham class CommandObjectBreakpointSet : public CommandObjectParsed
575a988416SJim Ingham {
585a988416SJim Ingham public:
595a988416SJim Ingham 
605a988416SJim Ingham     typedef enum BreakpointSetType
615a988416SJim Ingham     {
625a988416SJim Ingham         eSetTypeInvalid,
635a988416SJim Ingham         eSetTypeFileAndLine,
645a988416SJim Ingham         eSetTypeAddress,
655a988416SJim Ingham         eSetTypeFunctionName,
665a988416SJim Ingham         eSetTypeFunctionRegexp,
675a988416SJim Ingham         eSetTypeSourceRegexp,
685a988416SJim Ingham         eSetTypeException
695a988416SJim Ingham     } BreakpointSetType;
705a988416SJim Ingham 
715a988416SJim Ingham     CommandObjectBreakpointSet (CommandInterpreter &interpreter) :
725a988416SJim Ingham         CommandObjectParsed (interpreter,
735a988416SJim Ingham                              "breakpoint set",
745a988416SJim Ingham                              "Sets a breakpoint or set of breakpoints in the executable.",
755a988416SJim Ingham                              "breakpoint set <cmd-options>"),
765a988416SJim Ingham         m_options (interpreter)
775a988416SJim Ingham     {
785a988416SJim Ingham     }
795a988416SJim Ingham 
805a988416SJim Ingham 
815a988416SJim Ingham     virtual
825a988416SJim Ingham     ~CommandObjectBreakpointSet () {}
835a988416SJim Ingham 
845a988416SJim Ingham     virtual Options *
855a988416SJim Ingham     GetOptions ()
865a988416SJim Ingham     {
875a988416SJim Ingham         return &m_options;
885a988416SJim Ingham     }
895a988416SJim Ingham 
905a988416SJim Ingham     class CommandOptions : public Options
915a988416SJim Ingham     {
925a988416SJim Ingham     public:
935a988416SJim Ingham 
945a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
95eb0103f2SGreg Clayton             Options (interpreter),
967d49c9c8SJohnny Chen             m_condition (),
9787df91b8SJim Ingham             m_filenames (),
9830fdc8d8SChris Lattner             m_line_num (0),
9930fdc8d8SChris Lattner             m_column (0),
100fab10e89SJim Ingham             m_func_names (),
101fab10e89SJim Ingham             m_func_name_type_mask (eFunctionNameTypeNone),
10230fdc8d8SChris Lattner             m_func_regexp (),
103969795f1SJim Ingham             m_source_text_regexp(),
10430fdc8d8SChris Lattner             m_modules (),
1051b54c88cSJim Ingham             m_load_addr(),
106c982c768SGreg Clayton             m_ignore_count (0),
1071b54c88cSJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
108c982c768SGreg Clayton             m_thread_index (UINT32_MAX),
1091b54c88cSJim Ingham             m_thread_name(),
110fab10e89SJim Ingham             m_queue_name(),
111fab10e89SJim Ingham             m_catch_bp (false),
1121f746071SGreg Clayton             m_throw_bp (true),
113eb023e75SGreg Clayton             m_hardware (false),
114a8558b62SJim Ingham             m_language (eLanguageTypeUnknown),
115ca36cd16SJim Ingham             m_skip_prologue (eLazyBoolCalculate),
116e732052fSJim Ingham             m_one_shot (false),
117e732052fSJim Ingham             m_all_files (false)
11830fdc8d8SChris Lattner         {
11930fdc8d8SChris Lattner         }
12030fdc8d8SChris Lattner 
12130fdc8d8SChris Lattner 
1225a988416SJim Ingham         virtual
1235a988416SJim Ingham         ~CommandOptions () {}
12487df91b8SJim Ingham 
1255a988416SJim Ingham         virtual Error
1265a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
12730fdc8d8SChris Lattner         {
12830fdc8d8SChris Lattner             Error error;
1293bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13030fdc8d8SChris Lattner 
13130fdc8d8SChris Lattner             switch (short_option)
13230fdc8d8SChris Lattner             {
13330fdc8d8SChris Lattner                 case 'a':
134b9d5df58SGreg Clayton                     {
135b9d5df58SGreg Clayton                         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
136b9d5df58SGreg Clayton                         m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
137b9d5df58SGreg Clayton                     }
13830fdc8d8SChris Lattner                     break;
13930fdc8d8SChris Lattner 
140e732052fSJim Ingham                 case 'A':
141e732052fSJim Ingham                     m_all_files = true;
142e732052fSJim Ingham                     break;
143e732052fSJim Ingham 
144ca36cd16SJim Ingham                 case 'b':
145ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
146ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeBase;
147ca36cd16SJim Ingham                     break;
148ca36cd16SJim Ingham 
1497d49c9c8SJohnny Chen                 case 'C':
1505275aaa0SVince Harron                     m_column = StringConvert::ToUInt32 (option_arg, 0);
15130fdc8d8SChris Lattner                     break;
1520c5cd90dSGreg Clayton 
1537d49c9c8SJohnny Chen                 case 'c':
1547d49c9c8SJohnny Chen                     m_condition.assign(option_arg);
1557d49c9c8SJohnny Chen                     break;
1567d49c9c8SJohnny Chen 
15733df7cd3SJim Ingham                 case 'D':
15833df7cd3SJim Ingham                     m_use_dummy = true;
15933df7cd3SJim Ingham                     break;
16033df7cd3SJim Ingham 
161fab10e89SJim Ingham                 case 'E':
162fab10e89SJim Ingham                 {
163fab10e89SJim Ingham                     LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
164fab10e89SJim Ingham 
165fab10e89SJim Ingham                     switch (language)
166fab10e89SJim Ingham                     {
167fab10e89SJim Ingham                         case eLanguageTypeC89:
168fab10e89SJim Ingham                         case eLanguageTypeC:
169fab10e89SJim Ingham                         case eLanguageTypeC99:
1701d0089faSBruce Mitchener                         case eLanguageTypeC11:
171fab10e89SJim Ingham                             m_language = eLanguageTypeC;
172fab10e89SJim Ingham                             break;
173fab10e89SJim Ingham                         case eLanguageTypeC_plus_plus:
1741d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_03:
1751d0089faSBruce Mitchener                         case eLanguageTypeC_plus_plus_11:
1762ba84a6aSBruce Mitchener                         case eLanguageTypeC_plus_plus_14:
177fab10e89SJim Ingham                             m_language = eLanguageTypeC_plus_plus;
178fab10e89SJim Ingham                             break;
179fab10e89SJim Ingham                         case eLanguageTypeObjC:
180fab10e89SJim Ingham                             m_language = eLanguageTypeObjC;
181fab10e89SJim Ingham                             break;
182fab10e89SJim Ingham                         case eLanguageTypeObjC_plus_plus:
183fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
184fab10e89SJim Ingham                             break;
185fab10e89SJim Ingham                         case eLanguageTypeUnknown:
186fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
187fab10e89SJim Ingham                             break;
188fab10e89SJim Ingham                         default:
189fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
190fab10e89SJim Ingham                     }
191fab10e89SJim Ingham                 }
192fab10e89SJim Ingham                 break;
193ca36cd16SJim Ingham 
194ca36cd16SJim Ingham                 case 'f':
195ca36cd16SJim Ingham                     m_filenames.AppendIfUnique (FileSpec(option_arg, false));
196fab10e89SJim Ingham                     break;
197ca36cd16SJim Ingham 
198ca36cd16SJim Ingham                 case 'F':
199ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
200ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeFull;
201ca36cd16SJim Ingham                     break;
202ca36cd16SJim Ingham 
203fab10e89SJim Ingham                 case 'h':
204fab10e89SJim Ingham                     {
205fab10e89SJim Ingham                         bool success;
206fab10e89SJim Ingham                         m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
207fab10e89SJim Ingham                         if (!success)
208fab10e89SJim Ingham                             error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
209fab10e89SJim Ingham                     }
210168d469aSJim Ingham                     break;
211eb023e75SGreg Clayton 
212eb023e75SGreg Clayton                 case 'H':
213eb023e75SGreg Clayton                     m_hardware = true;
214eb023e75SGreg Clayton                     break;
215eb023e75SGreg Clayton 
216ca36cd16SJim Ingham                 case 'i':
217ca36cd16SJim Ingham                 {
2185275aaa0SVince Harron                     m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
219ca36cd16SJim Ingham                     if (m_ignore_count == UINT32_MAX)
220ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
221ca36cd16SJim Ingham                     break;
222ca36cd16SJim Ingham                 }
223ca36cd16SJim Ingham 
224a8558b62SJim Ingham                 case 'K':
225a8558b62SJim Ingham                 {
226a8558b62SJim Ingham                     bool success;
227a8558b62SJim Ingham                     bool value;
228a8558b62SJim Ingham                     value = Args::StringToBoolean (option_arg, true, &success);
229a8558b62SJim Ingham                     if (value)
230a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolYes;
231a8558b62SJim Ingham                     else
232a8558b62SJim Ingham                         m_skip_prologue = eLazyBoolNo;
233a8558b62SJim Ingham 
234a8558b62SJim Ingham                     if (!success)
235a8558b62SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for skip prologue option: '%s'", option_arg);
236a8558b62SJim Ingham                 }
237fab10e89SJim Ingham                 break;
238ca36cd16SJim Ingham 
239ca36cd16SJim Ingham                 case 'l':
2405275aaa0SVince Harron                     m_line_num = StringConvert::ToUInt32 (option_arg, 0);
241ca36cd16SJim Ingham                     break;
242ca36cd16SJim Ingham 
243ca36cd16SJim Ingham                 case 'M':
244ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
245ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeMethod;
246ca36cd16SJim Ingham                     break;
247ca36cd16SJim Ingham 
248ca36cd16SJim Ingham                 case 'n':
249ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
250ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeAuto;
251ca36cd16SJim Ingham                     break;
252ca36cd16SJim Ingham 
2535e09c8c3SJim Ingham                 case 'N':
2545e09c8c3SJim Ingham                     if (BreakpointID::StringIsBreakpointName(option_arg, error))
2555e09c8c3SJim Ingham                         m_breakpoint_names.push_back (option_arg);
2565e09c8c3SJim Ingham                     break;
2575e09c8c3SJim Ingham 
258ca36cd16SJim Ingham                 case 'o':
259ca36cd16SJim Ingham                     m_one_shot = true;
260ca36cd16SJim Ingham                     break;
261ca36cd16SJim Ingham 
262ca36cd16SJim Ingham                 case 'p':
263ca36cd16SJim Ingham                     m_source_text_regexp.assign (option_arg);
264ca36cd16SJim Ingham                     break;
265ca36cd16SJim Ingham 
266ca36cd16SJim Ingham                 case 'q':
267ca36cd16SJim Ingham                     m_queue_name.assign (option_arg);
268ca36cd16SJim Ingham                     break;
269ca36cd16SJim Ingham 
270ca36cd16SJim Ingham                 case 'r':
271ca36cd16SJim Ingham                     m_func_regexp.assign (option_arg);
272ca36cd16SJim Ingham                     break;
273ca36cd16SJim Ingham 
274ca36cd16SJim Ingham                 case 's':
275ca36cd16SJim Ingham                 {
276ca36cd16SJim Ingham                     m_modules.AppendIfUnique (FileSpec (option_arg, false));
277ca36cd16SJim Ingham                     break;
278ca36cd16SJim Ingham                 }
279ca36cd16SJim Ingham 
280ca36cd16SJim Ingham                 case 'S':
281ca36cd16SJim Ingham                     m_func_names.push_back (option_arg);
282ca36cd16SJim Ingham                     m_func_name_type_mask |= eFunctionNameTypeSelector;
283ca36cd16SJim Ingham                     break;
284ca36cd16SJim Ingham 
285ca36cd16SJim Ingham                 case 't' :
286ca36cd16SJim Ingham                 {
2875275aaa0SVince Harron                     m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
288ca36cd16SJim Ingham                     if (m_thread_id == LLDB_INVALID_THREAD_ID)
289ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
290ca36cd16SJim Ingham                 }
291ca36cd16SJim Ingham                 break;
292ca36cd16SJim Ingham 
293ca36cd16SJim Ingham                 case 'T':
294ca36cd16SJim Ingham                     m_thread_name.assign (option_arg);
295ca36cd16SJim Ingham                     break;
296ca36cd16SJim Ingham 
297ca36cd16SJim Ingham                 case 'w':
298ca36cd16SJim Ingham                 {
299ca36cd16SJim Ingham                     bool success;
300ca36cd16SJim Ingham                     m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
301ca36cd16SJim Ingham                     if (!success)
302ca36cd16SJim Ingham                         error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
303ca36cd16SJim Ingham                 }
304ca36cd16SJim Ingham                 break;
305ca36cd16SJim Ingham 
306ca36cd16SJim Ingham                 case 'x':
307ca36cd16SJim Ingham                 {
3085275aaa0SVince Harron                     m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
309ca36cd16SJim Ingham                     if (m_thread_id == UINT32_MAX)
310ca36cd16SJim Ingham                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
311ca36cd16SJim Ingham 
312ca36cd16SJim Ingham                 }
313ca36cd16SJim Ingham                 break;
314ca36cd16SJim Ingham 
31530fdc8d8SChris Lattner                 default:
31686edbf41SGreg Clayton                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
31730fdc8d8SChris Lattner                     break;
31830fdc8d8SChris Lattner             }
31930fdc8d8SChris Lattner 
32030fdc8d8SChris Lattner             return error;
32130fdc8d8SChris Lattner         }
32230fdc8d8SChris Lattner         void
3235a988416SJim Ingham         OptionParsingStarting ()
32430fdc8d8SChris Lattner         {
3257d49c9c8SJohnny Chen             m_condition.clear();
32687df91b8SJim Ingham             m_filenames.Clear();
32730fdc8d8SChris Lattner             m_line_num = 0;
32830fdc8d8SChris Lattner             m_column = 0;
329fab10e89SJim Ingham             m_func_names.clear();
3301f746071SGreg Clayton             m_func_name_type_mask = eFunctionNameTypeNone;
33130fdc8d8SChris Lattner             m_func_regexp.clear();
3321f746071SGreg Clayton             m_source_text_regexp.clear();
33387df91b8SJim Ingham             m_modules.Clear();
3341f746071SGreg Clayton             m_load_addr = LLDB_INVALID_ADDRESS;
335c982c768SGreg Clayton             m_ignore_count = 0;
3361b54c88cSJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
337c982c768SGreg Clayton             m_thread_index = UINT32_MAX;
3381b54c88cSJim Ingham             m_thread_name.clear();
3391b54c88cSJim Ingham             m_queue_name.clear();
340fab10e89SJim Ingham             m_catch_bp = false;
341fab10e89SJim Ingham             m_throw_bp = true;
342eb023e75SGreg Clayton             m_hardware = false;
3431f746071SGreg Clayton             m_language = eLanguageTypeUnknown;
344a8558b62SJim Ingham             m_skip_prologue = eLazyBoolCalculate;
345ca36cd16SJim Ingham             m_one_shot = false;
34633df7cd3SJim Ingham             m_use_dummy = false;
3475e09c8c3SJim Ingham             m_breakpoint_names.clear();
348e732052fSJim Ingham             m_all_files = false;
34930fdc8d8SChris Lattner         }
35030fdc8d8SChris Lattner 
3515a988416SJim Ingham         const OptionDefinition*
3525a988416SJim Ingham         GetDefinitions ()
35330fdc8d8SChris Lattner         {
3545a988416SJim Ingham             return g_option_table;
35530fdc8d8SChris Lattner         }
35630fdc8d8SChris Lattner 
3575a988416SJim Ingham         // Options table: Required for subclasses of Options.
35830fdc8d8SChris Lattner 
3595a988416SJim Ingham         static OptionDefinition g_option_table[];
36030fdc8d8SChris Lattner 
3615a988416SJim Ingham         // Instance variables to hold the values for command options.
362969795f1SJim Ingham 
3635a988416SJim Ingham         std::string m_condition;
3645a988416SJim Ingham         FileSpecList m_filenames;
3655a988416SJim Ingham         uint32_t m_line_num;
3665a988416SJim Ingham         uint32_t m_column;
3675a988416SJim Ingham         std::vector<std::string> m_func_names;
3685e09c8c3SJim Ingham         std::vector<std::string> m_breakpoint_names;
3695a988416SJim Ingham         uint32_t m_func_name_type_mask;
3705a988416SJim Ingham         std::string m_func_regexp;
3715a988416SJim Ingham         std::string m_source_text_regexp;
3725a988416SJim Ingham         FileSpecList m_modules;
3735a988416SJim Ingham         lldb::addr_t m_load_addr;
3745a988416SJim Ingham         uint32_t m_ignore_count;
3755a988416SJim Ingham         lldb::tid_t m_thread_id;
3765a988416SJim Ingham         uint32_t m_thread_index;
3775a988416SJim Ingham         std::string m_thread_name;
3785a988416SJim Ingham         std::string m_queue_name;
3795a988416SJim Ingham         bool m_catch_bp;
3805a988416SJim Ingham         bool m_throw_bp;
381eb023e75SGreg Clayton         bool m_hardware; // Request to use hardware breakpoints
3825a988416SJim Ingham         lldb::LanguageType m_language;
3835a988416SJim Ingham         LazyBool m_skip_prologue;
384ca36cd16SJim Ingham         bool m_one_shot;
38533df7cd3SJim Ingham         bool m_use_dummy;
386e732052fSJim Ingham         bool m_all_files;
3875a988416SJim Ingham 
3885a988416SJim Ingham     };
3895a988416SJim Ingham 
3905a988416SJim Ingham protected:
3915a988416SJim Ingham     virtual bool
3925a988416SJim Ingham     DoExecute (Args& command,
3935a988416SJim Ingham               CommandReturnObject &result)
39430fdc8d8SChris Lattner     {
39533df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
39633df7cd3SJim Ingham 
397893c932aSJim Ingham         if (target == nullptr)
39830fdc8d8SChris Lattner         {
399effe5c95SGreg Clayton             result.AppendError ("Invalid target.  Must set target before setting breakpoints (see 'target create' command).");
40030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
40130fdc8d8SChris Lattner             return false;
40230fdc8d8SChris Lattner         }
40330fdc8d8SChris Lattner 
40430fdc8d8SChris Lattner         // The following are the various types of breakpoints that could be set:
40530fdc8d8SChris Lattner         //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
40630fdc8d8SChris Lattner         //   2).  -a  [-s -g]         (setting breakpoint by address)
40730fdc8d8SChris Lattner         //   3).  -n  [-s -g]         (setting breakpoint by function name)
40830fdc8d8SChris Lattner         //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)
409969795f1SJim Ingham         //   5).  -p -f               (setting a breakpoint by comparing a reg-exp to source text)
410fab10e89SJim Ingham         //   6).  -E [-w -h]          (setting a breakpoint for exceptions for a given language.)
41130fdc8d8SChris Lattner 
41230fdc8d8SChris Lattner         BreakpointSetType break_type = eSetTypeInvalid;
41330fdc8d8SChris Lattner 
41430fdc8d8SChris Lattner         if (m_options.m_line_num != 0)
41530fdc8d8SChris Lattner             break_type = eSetTypeFileAndLine;
41630fdc8d8SChris Lattner         else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
41730fdc8d8SChris Lattner             break_type = eSetTypeAddress;
418fab10e89SJim Ingham         else if (!m_options.m_func_names.empty())
41930fdc8d8SChris Lattner             break_type = eSetTypeFunctionName;
42030fdc8d8SChris Lattner         else if  (!m_options.m_func_regexp.empty())
42130fdc8d8SChris Lattner             break_type = eSetTypeFunctionRegexp;
422969795f1SJim Ingham         else if (!m_options.m_source_text_regexp.empty())
423969795f1SJim Ingham             break_type = eSetTypeSourceRegexp;
424fab10e89SJim Ingham         else if (m_options.m_language != eLanguageTypeUnknown)
425fab10e89SJim Ingham             break_type = eSetTypeException;
42630fdc8d8SChris Lattner 
42730fdc8d8SChris Lattner         Breakpoint *bp = NULL;
428274060b6SGreg Clayton         FileSpec module_spec;
429a8558b62SJim Ingham         const bool internal = false;
430a8558b62SJim Ingham 
43130fdc8d8SChris Lattner         switch (break_type)
43230fdc8d8SChris Lattner         {
43330fdc8d8SChris Lattner             case eSetTypeFileAndLine: // Breakpoint by source position
43430fdc8d8SChris Lattner                 {
43530fdc8d8SChris Lattner                     FileSpec file;
436c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
43787df91b8SJim Ingham                     if (num_files == 0)
43887df91b8SJim Ingham                     {
43987df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
44087df91b8SJim Ingham                         {
44187df91b8SJim Ingham                             result.AppendError("No file supplied and no default file available.");
44287df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
44387df91b8SJim Ingham                             return false;
44487df91b8SJim Ingham                         }
44587df91b8SJim Ingham                     }
44687df91b8SJim Ingham                     else if (num_files > 1)
44787df91b8SJim Ingham                     {
44887df91b8SJim Ingham                         result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
44987df91b8SJim Ingham                         result.SetStatus (eReturnStatusFailed);
45087df91b8SJim Ingham                         return false;
45187df91b8SJim Ingham                     }
45287df91b8SJim Ingham                     else
45387df91b8SJim Ingham                         file = m_options.m_filenames.GetFileSpecAtIndex(0);
45430fdc8d8SChris Lattner 
4551f746071SGreg Clayton                     // Only check for inline functions if
4561f746071SGreg Clayton                     LazyBool check_inlines = eLazyBoolCalculate;
4571f746071SGreg Clayton 
45887df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
45930fdc8d8SChris Lattner                                                    file,
46030fdc8d8SChris Lattner                                                    m_options.m_line_num,
4611f746071SGreg Clayton                                                    check_inlines,
462a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
463eb023e75SGreg Clayton                                                    internal,
464eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
46530fdc8d8SChris Lattner                 }
46630fdc8d8SChris Lattner                 break;
4676eee5aa0SGreg Clayton 
46830fdc8d8SChris Lattner             case eSetTypeAddress: // Breakpoint by address
469eb023e75SGreg Clayton                 bp = target->CreateBreakpoint (m_options.m_load_addr,
470eb023e75SGreg Clayton                                                internal,
471eb023e75SGreg Clayton                                                m_options.m_hardware).get();
47230fdc8d8SChris Lattner                 break;
4730c5cd90dSGreg Clayton 
47430fdc8d8SChris Lattner             case eSetTypeFunctionName: // Breakpoint by function name
4750c5cd90dSGreg Clayton                 {
4760c5cd90dSGreg Clayton                     uint32_t name_type_mask = m_options.m_func_name_type_mask;
4770c5cd90dSGreg Clayton 
4780c5cd90dSGreg Clayton                     if (name_type_mask == 0)
479e02b8504SGreg Clayton                         name_type_mask = eFunctionNameTypeAuto;
4800c5cd90dSGreg Clayton 
48187df91b8SJim Ingham                     bp = target->CreateBreakpoint (&(m_options.m_modules),
48287df91b8SJim Ingham                                                    &(m_options.m_filenames),
483fab10e89SJim Ingham                                                    m_options.m_func_names,
484274060b6SGreg Clayton                                                    name_type_mask,
485a8558b62SJim Ingham                                                    m_options.m_skip_prologue,
486eb023e75SGreg Clayton                                                    internal,
487eb023e75SGreg Clayton                                                    m_options.m_hardware).get();
4880c5cd90dSGreg Clayton                 }
48930fdc8d8SChris Lattner                 break;
4900c5cd90dSGreg Clayton 
49130fdc8d8SChris Lattner             case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
49230fdc8d8SChris Lattner                 {
49330fdc8d8SChris Lattner                     RegularExpression regexp(m_options.m_func_regexp.c_str());
494969795f1SJim Ingham                     if (!regexp.IsValid())
49530fdc8d8SChris Lattner                     {
496969795f1SJim Ingham                         char err_str[1024];
497969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
498969795f1SJim Ingham                         result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
499969795f1SJim Ingham                                                      err_str);
50030fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
501969795f1SJim Ingham                         return false;
50230fdc8d8SChris Lattner                     }
50387df91b8SJim Ingham 
504a8558b62SJim Ingham                     bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules),
505a8558b62SJim Ingham                                                             &(m_options.m_filenames),
506a8558b62SJim Ingham                                                             regexp,
507a8558b62SJim Ingham                                                             m_options.m_skip_prologue,
508eb023e75SGreg Clayton                                                             internal,
509eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
51030fdc8d8SChris Lattner                 }
51130fdc8d8SChris Lattner                 break;
512969795f1SJim Ingham             case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
513969795f1SJim Ingham                 {
514c7bece56SGreg Clayton                     const size_t num_files = m_options.m_filenames.GetSize();
51587df91b8SJim Ingham 
516e732052fSJim Ingham                     if (num_files == 0 && !m_options.m_all_files)
51787df91b8SJim Ingham                     {
518969795f1SJim Ingham                         FileSpec file;
51987df91b8SJim Ingham                         if (!GetDefaultFile (target, file, result))
52087df91b8SJim Ingham                         {
52187df91b8SJim Ingham                             result.AppendError ("No files provided and could not find default file.");
52287df91b8SJim Ingham                             result.SetStatus (eReturnStatusFailed);
52387df91b8SJim Ingham                             return false;
52487df91b8SJim Ingham                         }
52587df91b8SJim Ingham                         else
52687df91b8SJim Ingham                         {
52787df91b8SJim Ingham                             m_options.m_filenames.Append (file);
52887df91b8SJim Ingham                         }
52987df91b8SJim Ingham                     }
5300c5cd90dSGreg Clayton 
531969795f1SJim Ingham                     RegularExpression regexp(m_options.m_source_text_regexp.c_str());
532969795f1SJim Ingham                     if (!regexp.IsValid())
533969795f1SJim Ingham                     {
534969795f1SJim Ingham                         char err_str[1024];
535969795f1SJim Ingham                         regexp.GetErrorAsCString(err_str, sizeof(err_str));
536969795f1SJim Ingham                         result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
537969795f1SJim Ingham                                                      err_str);
538969795f1SJim Ingham                         result.SetStatus (eReturnStatusFailed);
539969795f1SJim Ingham                         return false;
540969795f1SJim Ingham                     }
541eb023e75SGreg Clayton                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
542eb023e75SGreg Clayton                                                               &(m_options.m_filenames),
543eb023e75SGreg Clayton                                                               regexp,
544eb023e75SGreg Clayton                                                               internal,
545eb023e75SGreg Clayton                                                               m_options.m_hardware).get();
546969795f1SJim Ingham                 }
547969795f1SJim Ingham                 break;
548fab10e89SJim Ingham             case eSetTypeException:
549fab10e89SJim Ingham                 {
550eb023e75SGreg Clayton                     bp = target->CreateExceptionBreakpoint (m_options.m_language,
551eb023e75SGreg Clayton                                                             m_options.m_catch_bp,
552eb023e75SGreg Clayton                                                             m_options.m_throw_bp,
553eb023e75SGreg Clayton                                                             m_options.m_hardware).get();
554fab10e89SJim Ingham                 }
555fab10e89SJim Ingham                 break;
55630fdc8d8SChris Lattner             default:
55730fdc8d8SChris Lattner                 break;
55830fdc8d8SChris Lattner         }
55930fdc8d8SChris Lattner 
5601b54c88cSJim Ingham         // Now set the various options that were passed in:
5611b54c88cSJim Ingham         if (bp)
5621b54c88cSJim Ingham         {
5631b54c88cSJim Ingham             if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5641b54c88cSJim Ingham                 bp->SetThreadID (m_options.m_thread_id);
5651b54c88cSJim Ingham 
566c982c768SGreg Clayton             if (m_options.m_thread_index != UINT32_MAX)
5671b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
5681b54c88cSJim Ingham 
5691b54c88cSJim Ingham             if (!m_options.m_thread_name.empty())
5701b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
5711b54c88cSJim Ingham 
5721b54c88cSJim Ingham             if (!m_options.m_queue_name.empty())
5731b54c88cSJim Ingham                 bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
5741b54c88cSJim Ingham 
575c982c768SGreg Clayton             if (m_options.m_ignore_count != 0)
5761b54c88cSJim Ingham                 bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
5777d49c9c8SJohnny Chen 
5787d49c9c8SJohnny Chen             if (!m_options.m_condition.empty())
5797d49c9c8SJohnny Chen                 bp->GetOptions()->SetCondition(m_options.m_condition.c_str());
580ca36cd16SJim Ingham 
5815e09c8c3SJim Ingham             if (!m_options.m_breakpoint_names.empty())
5825e09c8c3SJim Ingham             {
5835e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
5845e09c8c3SJim Ingham                 for (auto name : m_options.m_breakpoint_names)
5855e09c8c3SJim Ingham                     bp->AddName(name.c_str(), error);
5865e09c8c3SJim Ingham             }
5875e09c8c3SJim Ingham 
588ca36cd16SJim Ingham             bp->SetOneShot (m_options.m_one_shot);
5891b54c88cSJim Ingham         }
5901b54c88cSJim Ingham 
591969795f1SJim Ingham         if (bp)
59230fdc8d8SChris Lattner         {
59385e8b814SJim Ingham             Stream &output_stream = result.GetOutputStream();
5941391cc7dSJim Ingham             const bool show_locations = false;
5951391cc7dSJim Ingham             bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial, show_locations);
5964aeb1989SJim Ingham             if (target == m_interpreter.GetDebugger().GetDummyTarget())
5974aeb1989SJim Ingham                     output_stream.Printf ("Breakpoint set in dummy target, will get copied into future targets.\n");
5984aeb1989SJim Ingham             else
5994aeb1989SJim Ingham             {
600fab10e89SJim Ingham                 // Don't print out this warning for exception breakpoints.  They can get set before the target
601fab10e89SJim Ingham                 // is set, but we won't know how to actually set the breakpoint till we run.
602fab10e89SJim Ingham                 if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
6034aeb1989SJim Ingham                 {
604be484f41SCaroline Tice                     output_stream.Printf ("WARNING:  Unable to resolve breakpoint to any actual locations.\n");
6054aeb1989SJim Ingham                 }
6064aeb1989SJim Ingham             }
60730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishResult);
60830fdc8d8SChris Lattner         }
60930fdc8d8SChris Lattner         else if (!bp)
61030fdc8d8SChris Lattner         {
61130fdc8d8SChris Lattner             result.AppendError ("Breakpoint creation failed: No breakpoint created.");
61230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
61330fdc8d8SChris Lattner         }
61430fdc8d8SChris Lattner 
61530fdc8d8SChris Lattner         return result.Succeeded();
61630fdc8d8SChris Lattner     }
61730fdc8d8SChris Lattner 
6185a988416SJim Ingham private:
6195a988416SJim Ingham     bool
6205a988416SJim Ingham     GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
6215a988416SJim Ingham     {
6225a988416SJim Ingham         uint32_t default_line;
6235a988416SJim Ingham         // First use the Source Manager's default file.
6245a988416SJim Ingham         // Then use the current stack frame's file.
6255a988416SJim Ingham         if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
6265a988416SJim Ingham         {
627b57e4a1bSJason Molenda             StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
6285a988416SJim Ingham             if (cur_frame == NULL)
6295a988416SJim Ingham             {
6305a988416SJim Ingham                 result.AppendError ("No selected frame to use to find the default file.");
6315a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6325a988416SJim Ingham                 return false;
6335a988416SJim Ingham             }
6345a988416SJim Ingham             else if (!cur_frame->HasDebugInformation())
6355a988416SJim Ingham             {
6365a988416SJim Ingham                 result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
6375a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
6385a988416SJim Ingham                 return false;
6395a988416SJim Ingham             }
6405a988416SJim Ingham             else
6415a988416SJim Ingham             {
6425a988416SJim Ingham                 const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
6435a988416SJim Ingham                 if (sc.line_entry.file)
6445a988416SJim Ingham                 {
6455a988416SJim Ingham                     file = sc.line_entry.file;
6465a988416SJim Ingham                 }
6475a988416SJim Ingham                 else
6485a988416SJim Ingham                 {
6495a988416SJim Ingham                     result.AppendError ("Can't find the file for the selected frame to use as the default file.");
6505a988416SJim Ingham                     result.SetStatus (eReturnStatusFailed);
6515a988416SJim Ingham                     return false;
6525a988416SJim Ingham                 }
6535a988416SJim Ingham             }
6545a988416SJim Ingham         }
6555a988416SJim Ingham         return true;
6565a988416SJim Ingham     }
6575a988416SJim Ingham 
6585a988416SJim Ingham     CommandOptions m_options;
6595a988416SJim Ingham };
6605a988416SJim Ingham // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to
6615a988416SJim Ingham // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately.
6625a988416SJim Ingham #define LLDB_OPT_FILE ( LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2 )
6635a988416SJim Ingham #define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10 )
6645a988416SJim Ingham #define LLDB_OPT_SKIP_PROLOGUE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3,8) )
6655a988416SJim Ingham 
6665a988416SJim Ingham OptionDefinition
6675a988416SJim Ingham CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
6685a988416SJim Ingham {
669d37221dcSZachary Turner     { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
6705a988416SJim Ingham         "Set the breakpoint only in this shared library.  "
6715a988416SJim Ingham         "Can repeat this option multiple times to specify multiple shared libraries."},
6725a988416SJim Ingham 
673d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "ignore-count", 'i', OptionParser::eRequiredArgument,   NULL, NULL, 0, eArgTypeCount,
6745a988416SJim Ingham         "Set the number of times this breakpoint is skipped before stopping." },
6755a988416SJim Ingham 
676d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "one-shot", 'o', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
677b2b256afSJim Ingham         "The breakpoint is deleted the first time it causes a stop." },
678ca36cd16SJim Ingham 
679d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "condition",    'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpression,
6805a988416SJim Ingham         "The breakpoint stops only if this condition expression evaluates to true."},
6815a988416SJim Ingham 
682d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex,
683a89be91fSJim Ingham         "The breakpoint stops only for the thread whose indeX matches this argument."},
6845a988416SJim Ingham 
685d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID,
6865a988416SJim Ingham         "The breakpoint stops only for the thread whose TID matches this argument."},
6875a988416SJim Ingham 
688d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName,
6895a988416SJim Ingham         "The breakpoint stops only for the thread whose thread name matches this argument."},
6905a988416SJim Ingham 
691d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
692eb023e75SGreg Clayton         "Require the breakpoint to use hardware breakpoints."},
693eb023e75SGreg Clayton 
694d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName,
6955a988416SJim Ingham         "The breakpoint stops only for threads in the queue whose name is given by this argument."},
6965a988416SJim Ingham 
697d37221dcSZachary Turner     { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
698289aca64SJim Ingham         "Specifies the source file in which to set this breakpoint.  "
699289aca64SJim Ingham         "Note, by default lldb only looks for files that are #included if they use the standard include file extensions.  "
7006394479eSJim Ingham         "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
701289aca64SJim Ingham         " to \"always\"."},
7025a988416SJim Ingham 
703d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
7045a988416SJim Ingham         "Specifies the line number on which to set this breakpoint."},
7055a988416SJim Ingham 
7065a988416SJim Ingham     // Comment out this option for the moment, as we don't actually use it, but will in the future.
7075a988416SJim Ingham     // This way users won't see it, but the infrastructure is left in place.
708e2607b50SVirgile Bello     //    { 0, false, "column",     'C', OptionParser::eRequiredArgument, NULL, "<column>",
7095a988416SJim Ingham     //    "Set the breakpoint by source location at this particular column."},
7105a988416SJim Ingham 
711d37221dcSZachary Turner     { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression,
7125a988416SJim Ingham         "Set the breakpoint by address, at the specified address."},
7135a988416SJim Ingham 
714d37221dcSZachary Turner     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
715551262d7SJim Ingham         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
7165a988416SJim Ingham 
717d37221dcSZachary Turner     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
7185a988416SJim Ingham         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
7195a988416SJim Ingham         "for Objective C this means a full function prototype with class and selector.   "
7205a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple names." },
7215a988416SJim Ingham 
722d37221dcSZachary Turner     { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSelector,
7235a988416SJim Ingham         "Set the breakpoint by ObjC selector name. Can be repeated multiple times to make one breakpoint for multiple Selectors." },
7245a988416SJim Ingham 
725d37221dcSZachary Turner     { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeMethod,
7265a988416SJim Ingham         "Set the breakpoint by C++ method names.  Can be repeated multiple times to make one breakpoint for multiple methods." },
7275a988416SJim Ingham 
728d37221dcSZachary Turner     { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
7295a988416SJim Ingham         "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },
7305a988416SJim Ingham 
731d37221dcSZachary Turner     { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
7325a988416SJim Ingham         "Set the breakpoint by function basename (C++ namespaces and arguments will be ignored). "
7335a988416SJim Ingham         "Can be repeated multiple times to make one breakpoint for multiple symbols." },
7345a988416SJim Ingham 
735d37221dcSZachary Turner     { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeRegularExpression,
736e96ade8bSJim Ingham         "Set the breakpoint by specifying a regular expression which is matched against the source text in a source file or files "
737e96ade8bSJim Ingham         "specified with the -f option.  The -f option can be specified more than once.  "
738e96ade8bSJim Ingham         "If no source files are specified, uses the current \"default source file\"" },
7395a988416SJim Ingham 
740e732052fSJim Ingham     { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument,   NULL, NULL, 0, eArgTypeNone,
741e732052fSJim Ingham         "All files are searched for source pattern matches." },
742e732052fSJim Ingham 
743d37221dcSZachary Turner     { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,
7445a988416SJim Ingham         "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
7455a988416SJim Ingham 
746d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7475a988416SJim Ingham         "Set the breakpoint on exception throW." },
7485a988416SJim Ingham 
749d37221dcSZachary Turner     { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7505a988416SJim Ingham         "Set the breakpoint on exception catcH." },
7515a988416SJim Ingham 
752d37221dcSZachary Turner     { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
7535a988416SJim Ingham         "sKip the prologue if the breakpoint is at the beginning of a function.  If not set the target.skip-prologue setting is used." },
7545a988416SJim Ingham 
75533df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
75633df7cd3SJim Ingham         "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
75733df7cd3SJim Ingham 
7585e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName,
7595e09c8c3SJim Ingham         "Adds this to the list of names for this breakopint."},
7605e09c8c3SJim Ingham 
761d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
7625a988416SJim Ingham };
7635a988416SJim Ingham 
7645a988416SJim Ingham //-------------------------------------------------------------------------
7655a988416SJim Ingham // CommandObjectBreakpointModify
7665a988416SJim Ingham //-------------------------------------------------------------------------
7675a988416SJim Ingham #pragma mark Modify
7685a988416SJim Ingham 
7695a988416SJim Ingham class CommandObjectBreakpointModify : public CommandObjectParsed
7705a988416SJim Ingham {
7715a988416SJim Ingham public:
7725a988416SJim Ingham 
7735a988416SJim Ingham     CommandObjectBreakpointModify (CommandInterpreter &interpreter) :
7745a988416SJim Ingham         CommandObjectParsed (interpreter,
7755a988416SJim Ingham                              "breakpoint modify",
7765a988416SJim Ingham                              "Modify the options on a breakpoint or set of breakpoints in the executable.  "
7775a988416SJim Ingham                              "If no breakpoint is specified, acts on the last created breakpoint.  "
7785a988416SJim Ingham                              "With the exception of -e, -d and -i, passing an empty argument clears the modification.",
7795a988416SJim Ingham                              NULL),
7805a988416SJim Ingham         m_options (interpreter)
7815a988416SJim Ingham     {
7825a988416SJim Ingham         CommandArgumentEntry arg;
7835a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
7845a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
7855a988416SJim Ingham         m_arguments.push_back (arg);
7865a988416SJim Ingham     }
7875a988416SJim Ingham 
7885a988416SJim Ingham 
7895a988416SJim Ingham     virtual
7905a988416SJim Ingham     ~CommandObjectBreakpointModify () {}
7915a988416SJim Ingham 
7925a988416SJim Ingham     virtual Options *
7935a988416SJim Ingham     GetOptions ()
7945a988416SJim Ingham     {
7955a988416SJim Ingham         return &m_options;
7965a988416SJim Ingham     }
7975a988416SJim Ingham 
7985a988416SJim Ingham     class CommandOptions : public Options
7995a988416SJim Ingham     {
8005a988416SJim Ingham     public:
8015a988416SJim Ingham 
8025a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
8035a988416SJim Ingham             Options (interpreter),
8045a988416SJim Ingham             m_ignore_count (0),
8055a988416SJim Ingham             m_thread_id(LLDB_INVALID_THREAD_ID),
8065a988416SJim Ingham             m_thread_id_passed(false),
8075a988416SJim Ingham             m_thread_index (UINT32_MAX),
8085a988416SJim Ingham             m_thread_index_passed(false),
8095a988416SJim Ingham             m_thread_name(),
8105a988416SJim Ingham             m_queue_name(),
8115a988416SJim Ingham             m_condition (),
812ca36cd16SJim Ingham             m_one_shot (false),
8135a988416SJim Ingham             m_enable_passed (false),
8145a988416SJim Ingham             m_enable_value (false),
8155a988416SJim Ingham             m_name_passed (false),
8165a988416SJim Ingham             m_queue_passed (false),
817ca36cd16SJim Ingham             m_condition_passed (false),
81833df7cd3SJim Ingham             m_one_shot_passed (false),
81933df7cd3SJim Ingham             m_use_dummy (false)
8205a988416SJim Ingham         {
8215a988416SJim Ingham         }
8225a988416SJim Ingham 
8235a988416SJim Ingham         virtual
8245a988416SJim Ingham         ~CommandOptions () {}
8255a988416SJim Ingham 
8265a988416SJim Ingham         virtual Error
8275a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
8285a988416SJim Ingham         {
8295a988416SJim Ingham             Error error;
8303bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
8315a988416SJim Ingham 
8325a988416SJim Ingham             switch (short_option)
8335a988416SJim Ingham             {
8345a988416SJim Ingham                 case 'c':
8355a988416SJim Ingham                     if (option_arg != NULL)
8365a988416SJim Ingham                         m_condition.assign (option_arg);
8375a988416SJim Ingham                     else
8385a988416SJim Ingham                         m_condition.clear();
8395a988416SJim Ingham                     m_condition_passed = true;
8405a988416SJim Ingham                     break;
8415a988416SJim Ingham                 case 'd':
8425a988416SJim Ingham                     m_enable_passed = true;
8435a988416SJim Ingham                     m_enable_value = false;
8445a988416SJim Ingham                     break;
84533df7cd3SJim Ingham                 case 'D':
84633df7cd3SJim Ingham                     m_use_dummy = true;
84733df7cd3SJim Ingham                     break;
8485a988416SJim Ingham                 case 'e':
8495a988416SJim Ingham                     m_enable_passed = true;
8505a988416SJim Ingham                     m_enable_value = true;
8515a988416SJim Ingham                     break;
8525a988416SJim Ingham                 case 'i':
8535a988416SJim Ingham                 {
8545275aaa0SVince Harron                     m_ignore_count = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
8555a988416SJim Ingham                     if (m_ignore_count == UINT32_MAX)
8565a988416SJim Ingham                        error.SetErrorStringWithFormat ("invalid ignore count '%s'", option_arg);
8575a988416SJim Ingham                 }
8585a988416SJim Ingham                 break;
859ca36cd16SJim Ingham                 case 'o':
860ca36cd16SJim Ingham                 {
861ca36cd16SJim Ingham                     bool value, success;
862ca36cd16SJim Ingham                     value = Args::StringToBoolean(option_arg, false, &success);
863ca36cd16SJim Ingham                     if (success)
864ca36cd16SJim Ingham                     {
865ca36cd16SJim Ingham                         m_one_shot_passed = true;
866ca36cd16SJim Ingham                         m_one_shot = value;
867ca36cd16SJim Ingham                     }
868ca36cd16SJim Ingham                     else
869ca36cd16SJim Ingham                         error.SetErrorStringWithFormat("invalid boolean value '%s' passed for -o option", option_arg);
870ca36cd16SJim Ingham                 }
871ca36cd16SJim Ingham                 break;
8725a988416SJim Ingham                 case 't' :
8735a988416SJim Ingham                 {
8745a988416SJim Ingham                     if (option_arg[0] == '\0')
8755a988416SJim Ingham                     {
8765a988416SJim Ingham                         m_thread_id = LLDB_INVALID_THREAD_ID;
8775a988416SJim Ingham                         m_thread_id_passed = true;
8785a988416SJim Ingham                     }
8795a988416SJim Ingham                     else
8805a988416SJim Ingham                     {
8815275aaa0SVince Harron                         m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
8825a988416SJim Ingham                         if (m_thread_id == LLDB_INVALID_THREAD_ID)
8835a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
8845a988416SJim Ingham                         else
8855a988416SJim Ingham                             m_thread_id_passed = true;
8865a988416SJim Ingham                     }
8875a988416SJim Ingham                 }
8885a988416SJim Ingham                 break;
8895a988416SJim Ingham                 case 'T':
8905a988416SJim Ingham                     if (option_arg != NULL)
8915a988416SJim Ingham                         m_thread_name.assign (option_arg);
8925a988416SJim Ingham                     else
8935a988416SJim Ingham                         m_thread_name.clear();
8945a988416SJim Ingham                     m_name_passed = true;
8955a988416SJim Ingham                     break;
8965a988416SJim Ingham                 case 'q':
8975a988416SJim Ingham                     if (option_arg != NULL)
8985a988416SJim Ingham                         m_queue_name.assign (option_arg);
8995a988416SJim Ingham                     else
9005a988416SJim Ingham                         m_queue_name.clear();
9015a988416SJim Ingham                     m_queue_passed = true;
9025a988416SJim Ingham                     break;
9035a988416SJim Ingham                 case 'x':
9045a988416SJim Ingham                 {
9055a988416SJim Ingham                     if (option_arg[0] == '\n')
9065a988416SJim Ingham                     {
9075a988416SJim Ingham                         m_thread_index = UINT32_MAX;
9085a988416SJim Ingham                         m_thread_index_passed = true;
9095a988416SJim Ingham                     }
9105a988416SJim Ingham                     else
9115a988416SJim Ingham                     {
9125275aaa0SVince Harron                         m_thread_index = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0);
9135a988416SJim Ingham                         if (m_thread_id == UINT32_MAX)
9145a988416SJim Ingham                            error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
9155a988416SJim Ingham                         else
9165a988416SJim Ingham                             m_thread_index_passed = true;
9175a988416SJim Ingham                     }
9185a988416SJim Ingham                 }
9195a988416SJim Ingham                 break;
9205a988416SJim Ingham                 default:
9215a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
9225a988416SJim Ingham                     break;
9235a988416SJim Ingham             }
9245a988416SJim Ingham 
9255a988416SJim Ingham             return error;
9265a988416SJim Ingham         }
9275a988416SJim Ingham         void
9285a988416SJim Ingham         OptionParsingStarting ()
9295a988416SJim Ingham         {
9305a988416SJim Ingham             m_ignore_count = 0;
9315a988416SJim Ingham             m_thread_id = LLDB_INVALID_THREAD_ID;
9325a988416SJim Ingham             m_thread_id_passed = false;
9335a988416SJim Ingham             m_thread_index = UINT32_MAX;
9345a988416SJim Ingham             m_thread_index_passed = false;
9355a988416SJim Ingham             m_thread_name.clear();
9365a988416SJim Ingham             m_queue_name.clear();
9375a988416SJim Ingham             m_condition.clear();
938ca36cd16SJim Ingham             m_one_shot = false;
9395a988416SJim Ingham             m_enable_passed = false;
9405a988416SJim Ingham             m_queue_passed = false;
9415a988416SJim Ingham             m_name_passed = false;
9425a988416SJim Ingham             m_condition_passed = false;
943ca36cd16SJim Ingham             m_one_shot_passed = false;
94433df7cd3SJim Ingham             m_use_dummy = false;
9455a988416SJim Ingham         }
9465a988416SJim Ingham 
9475a988416SJim Ingham         const OptionDefinition*
9485a988416SJim Ingham         GetDefinitions ()
9495a988416SJim Ingham         {
9505a988416SJim Ingham             return g_option_table;
9515a988416SJim Ingham         }
9525a988416SJim Ingham 
9535a988416SJim Ingham 
9545a988416SJim Ingham         // Options table: Required for subclasses of Options.
9555a988416SJim Ingham 
9565a988416SJim Ingham         static OptionDefinition g_option_table[];
9575a988416SJim Ingham 
9585a988416SJim Ingham         // Instance variables to hold the values for command options.
9595a988416SJim Ingham 
9605a988416SJim Ingham         uint32_t m_ignore_count;
9615a988416SJim Ingham         lldb::tid_t m_thread_id;
9625a988416SJim Ingham         bool m_thread_id_passed;
9635a988416SJim Ingham         uint32_t m_thread_index;
9645a988416SJim Ingham         bool m_thread_index_passed;
9655a988416SJim Ingham         std::string m_thread_name;
9665a988416SJim Ingham         std::string m_queue_name;
9675a988416SJim Ingham         std::string m_condition;
968ca36cd16SJim Ingham         bool m_one_shot;
9695a988416SJim Ingham         bool m_enable_passed;
9705a988416SJim Ingham         bool m_enable_value;
9715a988416SJim Ingham         bool m_name_passed;
9725a988416SJim Ingham         bool m_queue_passed;
9735a988416SJim Ingham         bool m_condition_passed;
974ca36cd16SJim Ingham         bool m_one_shot_passed;
97533df7cd3SJim Ingham         bool m_use_dummy;
9765a988416SJim Ingham 
9775a988416SJim Ingham     };
9785a988416SJim Ingham 
9795a988416SJim Ingham protected:
9805a988416SJim Ingham     virtual bool
9815a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
9825a988416SJim Ingham     {
98333df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
9845a988416SJim Ingham         if (target == NULL)
9855a988416SJim Ingham         {
9865a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
9875a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
9885a988416SJim Ingham             return false;
9895a988416SJim Ingham         }
9905a988416SJim Ingham 
9915a988416SJim Ingham         Mutex::Locker locker;
9925a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
9935a988416SJim Ingham 
9945a988416SJim Ingham         BreakpointIDList valid_bp_ids;
9955a988416SJim Ingham 
9965e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
9975a988416SJim Ingham 
9985a988416SJim Ingham         if (result.Succeeded())
9995a988416SJim Ingham         {
10005a988416SJim Ingham             const size_t count = valid_bp_ids.GetSize();
10015a988416SJim Ingham             for (size_t i = 0; i < count; ++i)
10025a988416SJim Ingham             {
10035a988416SJim Ingham                 BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
10045a988416SJim Ingham 
10055a988416SJim Ingham                 if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
10065a988416SJim Ingham                 {
10075a988416SJim Ingham                     Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
10085a988416SJim Ingham                     if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
10095a988416SJim Ingham                     {
10105a988416SJim Ingham                         BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
10115a988416SJim Ingham                         if (location)
10125a988416SJim Ingham                         {
10135a988416SJim Ingham                             if (m_options.m_thread_id_passed)
10145a988416SJim Ingham                                 location->SetThreadID (m_options.m_thread_id);
10155a988416SJim Ingham 
10165a988416SJim Ingham                             if (m_options.m_thread_index_passed)
10175a988416SJim Ingham                                 location->SetThreadIndex(m_options.m_thread_index);
10185a988416SJim Ingham 
10195a988416SJim Ingham                             if (m_options.m_name_passed)
10205a988416SJim Ingham                                 location->SetThreadName(m_options.m_thread_name.c_str());
10215a988416SJim Ingham 
10225a988416SJim Ingham                             if (m_options.m_queue_passed)
10235a988416SJim Ingham                                 location->SetQueueName(m_options.m_queue_name.c_str());
10245a988416SJim Ingham 
10255a988416SJim Ingham                             if (m_options.m_ignore_count != 0)
10265a988416SJim Ingham                                 location->SetIgnoreCount(m_options.m_ignore_count);
10275a988416SJim Ingham 
10285a988416SJim Ingham                             if (m_options.m_enable_passed)
10295a988416SJim Ingham                                 location->SetEnabled (m_options.m_enable_value);
10305a988416SJim Ingham 
10315a988416SJim Ingham                             if (m_options.m_condition_passed)
10325a988416SJim Ingham                                 location->SetCondition (m_options.m_condition.c_str());
10335a988416SJim Ingham                         }
10345a988416SJim Ingham                     }
10355a988416SJim Ingham                     else
10365a988416SJim Ingham                     {
10375a988416SJim Ingham                         if (m_options.m_thread_id_passed)
10385a988416SJim Ingham                             bp->SetThreadID (m_options.m_thread_id);
10395a988416SJim Ingham 
10405a988416SJim Ingham                         if (m_options.m_thread_index_passed)
10415a988416SJim Ingham                             bp->SetThreadIndex(m_options.m_thread_index);
10425a988416SJim Ingham 
10435a988416SJim Ingham                         if (m_options.m_name_passed)
10445a988416SJim Ingham                             bp->SetThreadName(m_options.m_thread_name.c_str());
10455a988416SJim Ingham 
10465a988416SJim Ingham                         if (m_options.m_queue_passed)
10475a988416SJim Ingham                             bp->SetQueueName(m_options.m_queue_name.c_str());
10485a988416SJim Ingham 
10495a988416SJim Ingham                         if (m_options.m_ignore_count != 0)
10505a988416SJim Ingham                             bp->SetIgnoreCount(m_options.m_ignore_count);
10515a988416SJim Ingham 
10525a988416SJim Ingham                         if (m_options.m_enable_passed)
10535a988416SJim Ingham                             bp->SetEnabled (m_options.m_enable_value);
10545a988416SJim Ingham 
10555a988416SJim Ingham                         if (m_options.m_condition_passed)
10565a988416SJim Ingham                             bp->SetCondition (m_options.m_condition.c_str());
10575a988416SJim Ingham                     }
10585a988416SJim Ingham                 }
10595a988416SJim Ingham             }
10605a988416SJim Ingham         }
10615a988416SJim Ingham 
10625a988416SJim Ingham         return result.Succeeded();
10635a988416SJim Ingham     }
10645a988416SJim Ingham 
10655a988416SJim Ingham private:
10665a988416SJim Ingham     CommandOptions m_options;
10675a988416SJim Ingham };
10685a988416SJim Ingham 
10695a988416SJim Ingham #pragma mark Modify::CommandOptions
10705a988416SJim Ingham OptionDefinition
10715a988416SJim Ingham CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
10725a988416SJim Ingham {
1073d37221dcSZachary 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." },
1074d37221dcSZachary 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." },
1075d37221dcSZachary 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."},
1076d37221dcSZachary 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."},
1077d37221dcSZachary 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."},
1078d37221dcSZachary 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."},
1079d37221dcSZachary 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."},
1080d37221dcSZachary Turner { LLDB_OPT_SET_1,   false, "enable",       'e', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Enable the breakpoint."},
1081d37221dcSZachary Turner { LLDB_OPT_SET_2,   false, "disable",      'd', OptionParser::eNoArgument,       NULL, NULL, 0, eArgTypeNone, "Disable the breakpoint."},
108233df7cd3SJim 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."},
108333df7cd3SJim Ingham 
1084d37221dcSZachary Turner { 0,                false, NULL,            0 , 0,                 NULL, NULL, 0, eArgTypeNone, NULL }
10855a988416SJim Ingham };
10865a988416SJim Ingham 
10875a988416SJim Ingham //-------------------------------------------------------------------------
10885a988416SJim Ingham // CommandObjectBreakpointEnable
10895a988416SJim Ingham //-------------------------------------------------------------------------
10905a988416SJim Ingham #pragma mark Enable
10915a988416SJim Ingham 
10925a988416SJim Ingham class CommandObjectBreakpointEnable : public CommandObjectParsed
10935a988416SJim Ingham {
10945a988416SJim Ingham public:
10955a988416SJim Ingham     CommandObjectBreakpointEnable (CommandInterpreter &interpreter) :
10965a988416SJim Ingham         CommandObjectParsed (interpreter,
10975a988416SJim Ingham                              "enable",
10985a988416SJim Ingham                              "Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them.",
10995a988416SJim Ingham                              NULL)
11005a988416SJim Ingham     {
11015a988416SJim Ingham         CommandArgumentEntry arg;
11025a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
11035a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
11045a988416SJim Ingham         m_arguments.push_back (arg);
11055a988416SJim Ingham     }
11065a988416SJim Ingham 
11075a988416SJim Ingham 
11085a988416SJim Ingham     virtual
11095a988416SJim Ingham     ~CommandObjectBreakpointEnable () {}
11105a988416SJim Ingham 
11115a988416SJim Ingham protected:
11125a988416SJim Ingham     virtual bool
11135a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
11145a988416SJim Ingham     {
1115893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
11165a988416SJim Ingham         if (target == NULL)
11175a988416SJim Ingham         {
11185a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
11195a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11205a988416SJim Ingham             return false;
11215a988416SJim Ingham         }
11225a988416SJim Ingham 
11235a988416SJim Ingham         Mutex::Locker locker;
11245a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
11255a988416SJim Ingham 
11265a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
11275a988416SJim Ingham 
11285a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
11295a988416SJim Ingham 
11305a988416SJim Ingham         if (num_breakpoints == 0)
11315a988416SJim Ingham         {
11325a988416SJim Ingham             result.AppendError ("No breakpoints exist to be enabled.");
11335a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
11345a988416SJim Ingham             return false;
11355a988416SJim Ingham         }
11365a988416SJim Ingham 
11375a988416SJim Ingham         if (command.GetArgumentCount() == 0)
11385a988416SJim Ingham         {
11395a988416SJim Ingham             // No breakpoint selected; enable all currently set breakpoints.
11405a988416SJim Ingham             target->EnableAllBreakpoints ();
11416fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints enabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
11425a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
11435a988416SJim Ingham         }
11445a988416SJim Ingham         else
11455a988416SJim Ingham         {
11465a988416SJim Ingham             // Particular breakpoint selected; enable that breakpoint.
11475a988416SJim Ingham             BreakpointIDList valid_bp_ids;
11485e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
11495a988416SJim Ingham 
11505a988416SJim Ingham             if (result.Succeeded())
11515a988416SJim Ingham             {
11525a988416SJim Ingham                 int enable_count = 0;
11535a988416SJim Ingham                 int loc_count = 0;
11545a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
11555a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
11565a988416SJim Ingham                 {
11575a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
11585a988416SJim Ingham 
11595a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
11605a988416SJim Ingham                     {
11615a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
11625a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
11635a988416SJim Ingham                         {
11645a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
11655a988416SJim Ingham                             if (location)
11665a988416SJim Ingham                             {
11675a988416SJim Ingham                                 location->SetEnabled (true);
11685a988416SJim Ingham                                 ++loc_count;
11695a988416SJim Ingham                             }
11705a988416SJim Ingham                         }
11715a988416SJim Ingham                         else
11725a988416SJim Ingham                         {
11735a988416SJim Ingham                             breakpoint->SetEnabled (true);
11745a988416SJim Ingham                             ++enable_count;
11755a988416SJim Ingham                         }
11765a988416SJim Ingham                     }
11775a988416SJim Ingham                 }
11785a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
11795a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
11805a988416SJim Ingham             }
11815a988416SJim Ingham         }
11825a988416SJim Ingham 
11835a988416SJim Ingham         return result.Succeeded();
11845a988416SJim Ingham     }
11855a988416SJim Ingham };
11865a988416SJim Ingham 
11875a988416SJim Ingham //-------------------------------------------------------------------------
11885a988416SJim Ingham // CommandObjectBreakpointDisable
11895a988416SJim Ingham //-------------------------------------------------------------------------
11905a988416SJim Ingham #pragma mark Disable
11915a988416SJim Ingham 
11925a988416SJim Ingham class CommandObjectBreakpointDisable : public CommandObjectParsed
11935a988416SJim Ingham {
11945a988416SJim Ingham public:
11955a988416SJim Ingham     CommandObjectBreakpointDisable (CommandInterpreter &interpreter) :
11965a988416SJim Ingham         CommandObjectParsed (interpreter,
11975a988416SJim Ingham                              "breakpoint disable",
11985a988416SJim Ingham                              "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
11995a988416SJim Ingham                              NULL)
12005a988416SJim Ingham     {
1201b0fac509SJim Ingham         SetHelpLong(
1202b0fac509SJim Ingham "Disable the specified breakpoint(s) without removing it/them.  \n\
1203b0fac509SJim Ingham If no breakpoints are specified, disable them all.\n\
1204b0fac509SJim Ingham \n\
1205b0fac509SJim Ingham Note: disabling a breakpoint will cause none of its locations to be hit\n\
1206b0fac509SJim Ingham regardless of whether they are enabled or disabled.  So the sequence: \n\
1207b0fac509SJim Ingham \n\
1208b0fac509SJim Ingham     (lldb) break disable 1\n\
1209b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1210b0fac509SJim Ingham \n\
1211b0fac509SJim Ingham will NOT cause location 1.1 to get hit.  To achieve that, do:\n\
1212b0fac509SJim Ingham \n\
1213b0fac509SJim Ingham     (lldb) break disable 1.*\n\
1214b0fac509SJim Ingham     (lldb) break enable 1.1\n\
1215b0fac509SJim Ingham \n\
1216b0fac509SJim Ingham The first command disables all the locations of breakpoint 1, \n\
1217b0fac509SJim Ingham the second re-enables the first location."
1218b0fac509SJim Ingham                     );
1219b0fac509SJim Ingham 
12205a988416SJim Ingham         CommandArgumentEntry arg;
12215a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
12225a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
12235a988416SJim Ingham         m_arguments.push_back (arg);
1224b0fac509SJim Ingham 
12255a988416SJim Ingham     }
12265a988416SJim Ingham 
12275a988416SJim Ingham 
12285a988416SJim Ingham     virtual
12295a988416SJim Ingham     ~CommandObjectBreakpointDisable () {}
12305a988416SJim Ingham 
12315a988416SJim Ingham protected:
12325a988416SJim Ingham     virtual bool
12335a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
12345a988416SJim Ingham     {
1235893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
12365a988416SJim Ingham         if (target == NULL)
12375a988416SJim Ingham         {
12385a988416SJim Ingham             result.AppendError ("Invalid target.  No existing target or breakpoints.");
12395a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12405a988416SJim Ingham             return false;
12415a988416SJim Ingham         }
12425a988416SJim Ingham 
12435a988416SJim Ingham         Mutex::Locker locker;
12445a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
12455a988416SJim Ingham 
12465a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
12475a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
12485a988416SJim Ingham 
12495a988416SJim Ingham         if (num_breakpoints == 0)
12505a988416SJim Ingham         {
12515a988416SJim Ingham             result.AppendError ("No breakpoints exist to be disabled.");
12525a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
12535a988416SJim Ingham             return false;
12545a988416SJim Ingham         }
12555a988416SJim Ingham 
12565a988416SJim Ingham         if (command.GetArgumentCount() == 0)
12575a988416SJim Ingham         {
12585a988416SJim Ingham             // No breakpoint selected; disable all currently set breakpoints.
12595a988416SJim Ingham             target->DisableAllBreakpoints ();
12606fea17e8SGreg Clayton             result.AppendMessageWithFormat ("All breakpoints disabled. (%" PRIu64 " breakpoints)\n", (uint64_t)num_breakpoints);
12615a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
12625a988416SJim Ingham         }
12635a988416SJim Ingham         else
12645a988416SJim Ingham         {
12655a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
12665a988416SJim Ingham             BreakpointIDList valid_bp_ids;
12675a988416SJim Ingham 
12685e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
12695a988416SJim Ingham 
12705a988416SJim Ingham             if (result.Succeeded())
12715a988416SJim Ingham             {
12725a988416SJim Ingham                 int disable_count = 0;
12735a988416SJim Ingham                 int loc_count = 0;
12745a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
12755a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
12765a988416SJim Ingham                 {
12775a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
12785a988416SJim Ingham 
12795a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
12805a988416SJim Ingham                     {
12815a988416SJim Ingham                         Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
12825a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
12835a988416SJim Ingham                         {
12845a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
12855a988416SJim Ingham                             if (location)
12865a988416SJim Ingham                             {
12875a988416SJim Ingham                                 location->SetEnabled (false);
12885a988416SJim Ingham                                 ++loc_count;
12895a988416SJim Ingham                             }
12905a988416SJim Ingham                         }
12915a988416SJim Ingham                         else
12925a988416SJim Ingham                         {
12935a988416SJim Ingham                             breakpoint->SetEnabled (false);
12945a988416SJim Ingham                             ++disable_count;
12955a988416SJim Ingham                         }
12965a988416SJim Ingham                     }
12975a988416SJim Ingham                 }
12985a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
12995a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
13005a988416SJim Ingham             }
13015a988416SJim Ingham         }
13025a988416SJim Ingham 
13035a988416SJim Ingham         return result.Succeeded();
13045a988416SJim Ingham     }
13055a988416SJim Ingham 
13065a988416SJim Ingham };
13075a988416SJim Ingham 
13085a988416SJim Ingham //-------------------------------------------------------------------------
13095a988416SJim Ingham // CommandObjectBreakpointList
13105a988416SJim Ingham //-------------------------------------------------------------------------
13115a988416SJim Ingham #pragma mark List
13125a988416SJim Ingham 
13135a988416SJim Ingham class CommandObjectBreakpointList : public CommandObjectParsed
13145a988416SJim Ingham {
13155a988416SJim Ingham public:
13165a988416SJim Ingham     CommandObjectBreakpointList (CommandInterpreter &interpreter) :
13175a988416SJim Ingham         CommandObjectParsed (interpreter,
13185a988416SJim Ingham                              "breakpoint list",
13195a988416SJim Ingham                              "List some or all breakpoints at configurable levels of detail.",
13205a988416SJim Ingham                              NULL),
13215a988416SJim Ingham         m_options (interpreter)
13225a988416SJim Ingham     {
13235a988416SJim Ingham         CommandArgumentEntry arg;
13245a988416SJim Ingham         CommandArgumentData bp_id_arg;
13255a988416SJim Ingham 
13265a988416SJim Ingham         // Define the first (and only) variant of this arg.
13275a988416SJim Ingham         bp_id_arg.arg_type = eArgTypeBreakpointID;
13285a988416SJim Ingham         bp_id_arg.arg_repetition = eArgRepeatOptional;
13295a988416SJim Ingham 
13305a988416SJim Ingham         // There is only one variant this argument could be; put it into the argument entry.
13315a988416SJim Ingham         arg.push_back (bp_id_arg);
13325a988416SJim Ingham 
13335a988416SJim Ingham         // Push the data for the first argument into the m_arguments vector.
13345a988416SJim Ingham         m_arguments.push_back (arg);
13355a988416SJim Ingham     }
13365a988416SJim Ingham 
13375a988416SJim Ingham 
13385a988416SJim Ingham     virtual
13395a988416SJim Ingham     ~CommandObjectBreakpointList () {}
13405a988416SJim Ingham 
13415a988416SJim Ingham     virtual Options *
13425a988416SJim Ingham     GetOptions ()
13435a988416SJim Ingham     {
13445a988416SJim Ingham         return &m_options;
13455a988416SJim Ingham     }
13465a988416SJim Ingham 
13475a988416SJim Ingham     class CommandOptions : public Options
13485a988416SJim Ingham     {
13495a988416SJim Ingham     public:
13505a988416SJim Ingham 
13515a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
13525a988416SJim Ingham             Options (interpreter),
135333df7cd3SJim Ingham             m_level (lldb::eDescriptionLevelBrief),
135433df7cd3SJim Ingham             m_use_dummy(false)
13555a988416SJim Ingham         {
13565a988416SJim Ingham         }
13575a988416SJim Ingham 
13585a988416SJim Ingham         virtual
13595a988416SJim Ingham         ~CommandOptions () {}
13605a988416SJim Ingham 
13615a988416SJim Ingham         virtual Error
13625a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
13635a988416SJim Ingham         {
13645a988416SJim Ingham             Error error;
13653bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
13665a988416SJim Ingham 
13675a988416SJim Ingham             switch (short_option)
13685a988416SJim Ingham             {
13695a988416SJim Ingham                 case 'b':
13705a988416SJim Ingham                     m_level = lldb::eDescriptionLevelBrief;
13715a988416SJim Ingham                     break;
137233df7cd3SJim Ingham                 case 'D':
137333df7cd3SJim Ingham                     m_use_dummy = true;
137433df7cd3SJim Ingham                     break;
13755a988416SJim Ingham                 case 'f':
13765a988416SJim Ingham                     m_level = lldb::eDescriptionLevelFull;
13775a988416SJim Ingham                     break;
13785a988416SJim Ingham                 case 'v':
13795a988416SJim Ingham                     m_level = lldb::eDescriptionLevelVerbose;
13805a988416SJim Ingham                     break;
13815a988416SJim Ingham                 case 'i':
13825a988416SJim Ingham                     m_internal = true;
13835a988416SJim Ingham                     break;
13845a988416SJim Ingham                 default:
13855a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
13865a988416SJim Ingham                     break;
13875a988416SJim Ingham             }
13885a988416SJim Ingham 
13895a988416SJim Ingham             return error;
13905a988416SJim Ingham         }
13915a988416SJim Ingham 
13925a988416SJim Ingham         void
13935a988416SJim Ingham         OptionParsingStarting ()
13945a988416SJim Ingham         {
13955a988416SJim Ingham             m_level = lldb::eDescriptionLevelFull;
13965a988416SJim Ingham             m_internal = false;
139733df7cd3SJim Ingham             m_use_dummy = false;
13985a988416SJim Ingham         }
13995a988416SJim Ingham 
14005a988416SJim Ingham         const OptionDefinition *
14015a988416SJim Ingham         GetDefinitions ()
14025a988416SJim Ingham         {
14035a988416SJim Ingham             return g_option_table;
14045a988416SJim Ingham         }
14055a988416SJim Ingham 
14065a988416SJim Ingham         // Options table: Required for subclasses of Options.
14075a988416SJim Ingham 
14085a988416SJim Ingham         static OptionDefinition g_option_table[];
14095a988416SJim Ingham 
14105a988416SJim Ingham         // Instance variables to hold the values for command options.
14115a988416SJim Ingham 
14125a988416SJim Ingham         lldb::DescriptionLevel m_level;
14135a988416SJim Ingham 
14145a988416SJim Ingham         bool m_internal;
141533df7cd3SJim Ingham         bool m_use_dummy;
14165a988416SJim Ingham     };
14175a988416SJim Ingham 
14185a988416SJim Ingham protected:
14195a988416SJim Ingham     virtual bool
14205a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
14215a988416SJim Ingham     {
142233df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
142333df7cd3SJim Ingham 
14245a988416SJim Ingham         if (target == NULL)
14255a988416SJim Ingham         {
14265a988416SJim Ingham             result.AppendError ("Invalid target. No current target or breakpoints.");
14275a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14285a988416SJim Ingham             return true;
14295a988416SJim Ingham         }
14305a988416SJim Ingham 
14315a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
14325a988416SJim Ingham         Mutex::Locker locker;
14335a988416SJim Ingham         target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
14345a988416SJim Ingham 
14355a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
14365a988416SJim Ingham 
14375a988416SJim Ingham         if (num_breakpoints == 0)
14385a988416SJim Ingham         {
14395a988416SJim Ingham             result.AppendMessage ("No breakpoints currently set.");
14405a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14415a988416SJim Ingham             return true;
14425a988416SJim Ingham         }
14435a988416SJim Ingham 
14445a988416SJim Ingham         Stream &output_stream = result.GetOutputStream();
14455a988416SJim Ingham 
14465a988416SJim Ingham         if (command.GetArgumentCount() == 0)
14475a988416SJim Ingham         {
14485a988416SJim Ingham             // No breakpoint selected; show info about all currently set breakpoints.
14495a988416SJim Ingham             result.AppendMessage ("Current breakpoints:");
14505a988416SJim Ingham             for (size_t i = 0; i < num_breakpoints; ++i)
14515a988416SJim Ingham             {
14525a988416SJim Ingham                 Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
14535a988416SJim Ingham                 AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14545a988416SJim Ingham             }
14555a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
14565a988416SJim Ingham         }
14575a988416SJim Ingham         else
14585a988416SJim Ingham         {
14595a988416SJim Ingham             // Particular breakpoints selected; show info about that breakpoint.
14605a988416SJim Ingham             BreakpointIDList valid_bp_ids;
14615e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
14625a988416SJim Ingham 
14635a988416SJim Ingham             if (result.Succeeded())
14645a988416SJim Ingham             {
14655a988416SJim Ingham                 for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
14665a988416SJim Ingham                 {
14675a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
14685a988416SJim Ingham                     Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
14695a988416SJim Ingham                     AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
14705a988416SJim Ingham                 }
14715a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
14725a988416SJim Ingham             }
14735a988416SJim Ingham             else
14745a988416SJim Ingham             {
14755a988416SJim Ingham                 result.AppendError ("Invalid breakpoint id.");
14765a988416SJim Ingham                 result.SetStatus (eReturnStatusFailed);
14775a988416SJim Ingham             }
14785a988416SJim Ingham         }
14795a988416SJim Ingham 
14805a988416SJim Ingham         return result.Succeeded();
14815a988416SJim Ingham     }
14825a988416SJim Ingham 
14835a988416SJim Ingham private:
14845a988416SJim Ingham     CommandOptions m_options;
14855a988416SJim Ingham };
14865a988416SJim Ingham 
14875a988416SJim Ingham #pragma mark List::CommandOptions
14885a988416SJim Ingham OptionDefinition
14895a988416SJim Ingham CommandObjectBreakpointList::CommandOptions::g_option_table[] =
14905a988416SJim Ingham {
1491d37221dcSZachary Turner     { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14925a988416SJim Ingham         "Show debugger internal breakpoints" },
14935a988416SJim Ingham 
1494d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "brief",    'b', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
14955a988416SJim Ingham         "Give a brief description of the breakpoint (no location info)."},
14965a988416SJim Ingham 
14975a988416SJim Ingham     // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
14985a988416SJim Ingham     // But I need to see it for now, and don't want to wait.
1499d37221dcSZachary Turner     { LLDB_OPT_SET_2, false, "full",    'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15005a988416SJim Ingham         "Give a full description of the breakpoint and its locations."},
15015a988416SJim Ingham 
1502d37221dcSZachary Turner     { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
15035a988416SJim Ingham         "Explain everything we know about the breakpoint (for debugging debugger bugs)." },
15045a988416SJim Ingham 
150533df7cd3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
150633df7cd3SJim Ingham         "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
150733df7cd3SJim Ingham 
1508d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
15095a988416SJim Ingham };
15105a988416SJim Ingham 
15115a988416SJim Ingham //-------------------------------------------------------------------------
15125a988416SJim Ingham // CommandObjectBreakpointClear
15135a988416SJim Ingham //-------------------------------------------------------------------------
15145a988416SJim Ingham #pragma mark Clear
15155a988416SJim Ingham 
15165a988416SJim Ingham class CommandObjectBreakpointClear : public CommandObjectParsed
15175a988416SJim Ingham {
15185a988416SJim Ingham public:
15195a988416SJim Ingham 
15205a988416SJim Ingham     typedef enum BreakpointClearType
15215a988416SJim Ingham     {
15225a988416SJim Ingham         eClearTypeInvalid,
15235a988416SJim Ingham         eClearTypeFileAndLine
15245a988416SJim Ingham     } BreakpointClearType;
15255a988416SJim Ingham 
15265a988416SJim Ingham     CommandObjectBreakpointClear (CommandInterpreter &interpreter) :
15275a988416SJim Ingham         CommandObjectParsed (interpreter,
15285a988416SJim Ingham                              "breakpoint clear",
15295a988416SJim Ingham                              "Clears a breakpoint or set of breakpoints in the executable.",
15305a988416SJim Ingham                              "breakpoint clear <cmd-options>"),
15315a988416SJim Ingham         m_options (interpreter)
15325a988416SJim Ingham     {
15335a988416SJim Ingham     }
15345a988416SJim Ingham 
15355a988416SJim Ingham     virtual
15365a988416SJim Ingham     ~CommandObjectBreakpointClear () {}
15375a988416SJim Ingham 
15385a988416SJim Ingham     virtual Options *
15395a988416SJim Ingham     GetOptions ()
15405a988416SJim Ingham     {
15415a988416SJim Ingham         return &m_options;
15425a988416SJim Ingham     }
15435a988416SJim Ingham 
15445a988416SJim Ingham     class CommandOptions : public Options
15455a988416SJim Ingham     {
15465a988416SJim Ingham     public:
15475a988416SJim Ingham 
15485a988416SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
15495a988416SJim Ingham             Options (interpreter),
15505a988416SJim Ingham             m_filename (),
15515a988416SJim Ingham             m_line_num (0)
15525a988416SJim Ingham         {
15535a988416SJim Ingham         }
15545a988416SJim Ingham 
15555a988416SJim Ingham         virtual
15565a988416SJim Ingham         ~CommandOptions () {}
15575a988416SJim Ingham 
15585a988416SJim Ingham         virtual Error
15595a988416SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
15605a988416SJim Ingham         {
15615a988416SJim Ingham             Error error;
15623bcdfc0eSGreg Clayton             const int short_option = m_getopt_table[option_idx].val;
15635a988416SJim Ingham 
15645a988416SJim Ingham             switch (short_option)
15655a988416SJim Ingham             {
15665a988416SJim Ingham                 case 'f':
15675a988416SJim Ingham                     m_filename.assign (option_arg);
15685a988416SJim Ingham                     break;
15695a988416SJim Ingham 
15705a988416SJim Ingham                 case 'l':
15715275aaa0SVince Harron                     m_line_num = StringConvert::ToUInt32 (option_arg, 0);
15725a988416SJim Ingham                     break;
15735a988416SJim Ingham 
15745a988416SJim Ingham                 default:
15755a988416SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
15765a988416SJim Ingham                     break;
15775a988416SJim Ingham             }
15785a988416SJim Ingham 
15795a988416SJim Ingham             return error;
15805a988416SJim Ingham         }
15815a988416SJim Ingham 
15825a988416SJim Ingham         void
15835a988416SJim Ingham         OptionParsingStarting ()
15845a988416SJim Ingham         {
15855a988416SJim Ingham             m_filename.clear();
15865a988416SJim Ingham             m_line_num = 0;
15875a988416SJim Ingham         }
15885a988416SJim Ingham 
15895a988416SJim Ingham         const OptionDefinition*
15905a988416SJim Ingham         GetDefinitions ()
15915a988416SJim Ingham         {
15925a988416SJim Ingham             return g_option_table;
15935a988416SJim Ingham         }
15945a988416SJim Ingham 
15955a988416SJim Ingham         // Options table: Required for subclasses of Options.
15965a988416SJim Ingham 
15975a988416SJim Ingham         static OptionDefinition g_option_table[];
15985a988416SJim Ingham 
15995a988416SJim Ingham         // Instance variables to hold the values for command options.
16005a988416SJim Ingham 
16015a988416SJim Ingham         std::string m_filename;
16025a988416SJim Ingham         uint32_t m_line_num;
16035a988416SJim Ingham 
16045a988416SJim Ingham     };
16055a988416SJim Ingham 
16065a988416SJim Ingham protected:
16075a988416SJim Ingham     virtual bool
16085a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
16095a988416SJim Ingham     {
1610893c932aSJim Ingham         Target *target = GetSelectedOrDummyTarget();
16115a988416SJim Ingham         if (target == NULL)
16125a988416SJim Ingham         {
16135a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
16145a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16155a988416SJim Ingham             return false;
16165a988416SJim Ingham         }
16175a988416SJim Ingham 
16185a988416SJim Ingham         // The following are the various types of breakpoints that could be cleared:
16195a988416SJim Ingham         //   1). -f -l (clearing breakpoint by source location)
16205a988416SJim Ingham 
16215a988416SJim Ingham         BreakpointClearType break_type = eClearTypeInvalid;
16225a988416SJim Ingham 
16235a988416SJim Ingham         if (m_options.m_line_num != 0)
16245a988416SJim Ingham             break_type = eClearTypeFileAndLine;
16255a988416SJim Ingham 
16265a988416SJim Ingham         Mutex::Locker locker;
16275a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
16285a988416SJim Ingham 
16295a988416SJim Ingham         BreakpointList &breakpoints = target->GetBreakpointList();
16305a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
16315a988416SJim Ingham 
16325a988416SJim Ingham         // Early return if there's no breakpoint at all.
16335a988416SJim Ingham         if (num_breakpoints == 0)
16345a988416SJim Ingham         {
16355a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16365a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16375a988416SJim Ingham             return result.Succeeded();
16385a988416SJim Ingham         }
16395a988416SJim Ingham 
16405a988416SJim Ingham         // Find matching breakpoints and delete them.
16415a988416SJim Ingham 
16425a988416SJim Ingham         // First create a copy of all the IDs.
16435a988416SJim Ingham         std::vector<break_id_t> BreakIDs;
16445a988416SJim Ingham         for (size_t i = 0; i < num_breakpoints; ++i)
16455a988416SJim Ingham             BreakIDs.push_back(breakpoints.GetBreakpointAtIndex(i).get()->GetID());
16465a988416SJim Ingham 
16475a988416SJim Ingham         int num_cleared = 0;
16485a988416SJim Ingham         StreamString ss;
16495a988416SJim Ingham         switch (break_type)
16505a988416SJim Ingham         {
16515a988416SJim Ingham             case eClearTypeFileAndLine: // Breakpoint by source position
16525a988416SJim Ingham                 {
16535a988416SJim Ingham                     const ConstString filename(m_options.m_filename.c_str());
16545a988416SJim Ingham                     BreakpointLocationCollection loc_coll;
16555a988416SJim Ingham 
16565a988416SJim Ingham                     for (size_t i = 0; i < num_breakpoints; ++i)
16575a988416SJim Ingham                     {
16585a988416SJim Ingham                         Breakpoint *bp = breakpoints.FindBreakpointByID(BreakIDs[i]).get();
16595a988416SJim Ingham 
16605a988416SJim Ingham                         if (bp->GetMatchingFileLine(filename, m_options.m_line_num, loc_coll))
16615a988416SJim Ingham                         {
16625a988416SJim Ingham                             // If the collection size is 0, it's a full match and we can just remove the breakpoint.
16635a988416SJim Ingham                             if (loc_coll.GetSize() == 0)
16645a988416SJim Ingham                             {
16655a988416SJim Ingham                                 bp->GetDescription(&ss, lldb::eDescriptionLevelBrief);
16665a988416SJim Ingham                                 ss.EOL();
16675a988416SJim Ingham                                 target->RemoveBreakpointByID (bp->GetID());
16685a988416SJim Ingham                                 ++num_cleared;
16695a988416SJim Ingham                             }
16705a988416SJim Ingham                         }
16715a988416SJim Ingham                     }
16725a988416SJim Ingham                 }
16735a988416SJim Ingham                 break;
16745a988416SJim Ingham 
16755a988416SJim Ingham             default:
16765a988416SJim Ingham                 break;
16775a988416SJim Ingham         }
16785a988416SJim Ingham 
16795a988416SJim Ingham         if (num_cleared > 0)
16805a988416SJim Ingham         {
16815a988416SJim Ingham             Stream &output_stream = result.GetOutputStream();
16825a988416SJim Ingham             output_stream.Printf ("%d breakpoints cleared:\n", num_cleared);
16835a988416SJim Ingham             output_stream << ss.GetData();
16845a988416SJim Ingham             output_stream.EOL();
16855a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
16865a988416SJim Ingham         }
16875a988416SJim Ingham         else
16885a988416SJim Ingham         {
16895a988416SJim Ingham             result.AppendError ("Breakpoint clear: No breakpoint cleared.");
16905a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
16915a988416SJim Ingham         }
16925a988416SJim Ingham 
16935a988416SJim Ingham         return result.Succeeded();
16945a988416SJim Ingham     }
16955a988416SJim Ingham 
16965a988416SJim Ingham private:
16975a988416SJim Ingham     CommandOptions m_options;
16985a988416SJim Ingham };
16995a988416SJim Ingham 
17005a988416SJim Ingham #pragma mark Clear::CommandOptions
17015a988416SJim Ingham 
17025a988416SJim Ingham OptionDefinition
17035a988416SJim Ingham CommandObjectBreakpointClear::CommandOptions::g_option_table[] =
17045a988416SJim Ingham {
1705d37221dcSZachary Turner     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
17065a988416SJim Ingham         "Specify the breakpoint by source location in this particular file."},
17075a988416SJim Ingham 
1708d37221dcSZachary Turner     { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum,
17095a988416SJim Ingham         "Specify the breakpoint by source location at this particular line."},
17105a988416SJim Ingham 
1711d37221dcSZachary Turner     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
17125a988416SJim Ingham };
17135a988416SJim Ingham 
17145a988416SJim Ingham //-------------------------------------------------------------------------
17155a988416SJim Ingham // CommandObjectBreakpointDelete
17165a988416SJim Ingham //-------------------------------------------------------------------------
17175a988416SJim Ingham #pragma mark Delete
17185a988416SJim Ingham 
17195a988416SJim Ingham class CommandObjectBreakpointDelete : public CommandObjectParsed
17205a988416SJim Ingham {
17215a988416SJim Ingham public:
17225a988416SJim Ingham     CommandObjectBreakpointDelete (CommandInterpreter &interpreter) :
17235a988416SJim Ingham         CommandObjectParsed (interpreter,
17245a988416SJim Ingham                              "breakpoint delete",
17255a988416SJim Ingham                              "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
172633df7cd3SJim Ingham                              NULL),
172733df7cd3SJim Ingham         m_options (interpreter)
17285a988416SJim Ingham     {
17295a988416SJim Ingham         CommandArgumentEntry arg;
17305a988416SJim Ingham         CommandObject::AddIDsArgumentData(arg, eArgTypeBreakpointID, eArgTypeBreakpointIDRange);
17315a988416SJim Ingham         // Add the entry for the first argument for this command to the object's arguments vector.
17325a988416SJim Ingham         m_arguments.push_back (arg);
17335a988416SJim Ingham     }
17345a988416SJim Ingham 
17355a988416SJim Ingham     virtual
17365a988416SJim Ingham     ~CommandObjectBreakpointDelete () {}
17375a988416SJim Ingham 
173833df7cd3SJim Ingham     virtual Options *
173933df7cd3SJim Ingham     GetOptions ()
174033df7cd3SJim Ingham     {
174133df7cd3SJim Ingham         return &m_options;
174233df7cd3SJim Ingham     }
174333df7cd3SJim Ingham 
174433df7cd3SJim Ingham     class CommandOptions : public Options
174533df7cd3SJim Ingham     {
174633df7cd3SJim Ingham     public:
174733df7cd3SJim Ingham 
174833df7cd3SJim Ingham         CommandOptions (CommandInterpreter &interpreter) :
174933df7cd3SJim Ingham             Options (interpreter),
175033df7cd3SJim Ingham             m_use_dummy (false),
175133df7cd3SJim Ingham             m_force (false)
175233df7cd3SJim Ingham         {
175333df7cd3SJim Ingham         }
175433df7cd3SJim Ingham 
175533df7cd3SJim Ingham         virtual
175633df7cd3SJim Ingham         ~CommandOptions () {}
175733df7cd3SJim Ingham 
175833df7cd3SJim Ingham         virtual Error
175933df7cd3SJim Ingham         SetOptionValue (uint32_t option_idx, const char *option_arg)
176033df7cd3SJim Ingham         {
176133df7cd3SJim Ingham             Error error;
176233df7cd3SJim Ingham             const int short_option = m_getopt_table[option_idx].val;
176333df7cd3SJim Ingham 
176433df7cd3SJim Ingham             switch (short_option)
176533df7cd3SJim Ingham             {
176633df7cd3SJim Ingham                 case 'f':
176733df7cd3SJim Ingham                     m_force = true;
176833df7cd3SJim Ingham                     break;
176933df7cd3SJim Ingham 
177033df7cd3SJim Ingham                 case 'D':
177133df7cd3SJim Ingham                     m_use_dummy = true;
177233df7cd3SJim Ingham                     break;
177333df7cd3SJim Ingham 
177433df7cd3SJim Ingham                 default:
177533df7cd3SJim Ingham                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
177633df7cd3SJim Ingham                     break;
177733df7cd3SJim Ingham             }
177833df7cd3SJim Ingham 
177933df7cd3SJim Ingham             return error;
178033df7cd3SJim Ingham         }
178133df7cd3SJim Ingham 
178233df7cd3SJim Ingham         void
178333df7cd3SJim Ingham         OptionParsingStarting ()
178433df7cd3SJim Ingham         {
178533df7cd3SJim Ingham             m_use_dummy = false;
178633df7cd3SJim Ingham             m_force = false;
178733df7cd3SJim Ingham         }
178833df7cd3SJim Ingham 
178933df7cd3SJim Ingham         const OptionDefinition*
179033df7cd3SJim Ingham         GetDefinitions ()
179133df7cd3SJim Ingham         {
179233df7cd3SJim Ingham             return g_option_table;
179333df7cd3SJim Ingham         }
179433df7cd3SJim Ingham 
179533df7cd3SJim Ingham         // Options table: Required for subclasses of Options.
179633df7cd3SJim Ingham 
179733df7cd3SJim Ingham         static OptionDefinition g_option_table[];
179833df7cd3SJim Ingham 
179933df7cd3SJim Ingham         // Instance variables to hold the values for command options.
180033df7cd3SJim Ingham         bool m_use_dummy;
180133df7cd3SJim Ingham         bool m_force;
180233df7cd3SJim Ingham     };
180333df7cd3SJim Ingham 
18045a988416SJim Ingham protected:
18055a988416SJim Ingham     virtual bool
18065a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
18075a988416SJim Ingham     {
180833df7cd3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_options.m_use_dummy);
180933df7cd3SJim Ingham 
18105a988416SJim Ingham         if (target == NULL)
18115a988416SJim Ingham         {
18125a988416SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
18135a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18145a988416SJim Ingham             return false;
18155a988416SJim Ingham         }
18165a988416SJim Ingham 
18175a988416SJim Ingham         Mutex::Locker locker;
18185a988416SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
18195a988416SJim Ingham 
18205a988416SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
18215a988416SJim Ingham 
18225a988416SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
18235a988416SJim Ingham 
18245a988416SJim Ingham         if (num_breakpoints == 0)
18255a988416SJim Ingham         {
18265a988416SJim Ingham             result.AppendError ("No breakpoints exist to be deleted.");
18275a988416SJim Ingham             result.SetStatus (eReturnStatusFailed);
18285a988416SJim Ingham             return false;
18295a988416SJim Ingham         }
18305a988416SJim Ingham 
18315a988416SJim Ingham         if (command.GetArgumentCount() == 0)
18325a988416SJim Ingham         {
183333df7cd3SJim Ingham             if (!m_options.m_force && !m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
18345a988416SJim Ingham             {
18355a988416SJim Ingham                 result.AppendMessage("Operation cancelled...");
18365a988416SJim Ingham             }
18375a988416SJim Ingham             else
18385a988416SJim Ingham             {
18395a988416SJim Ingham                 target->RemoveAllBreakpoints ();
18406fea17e8SGreg Clayton                 result.AppendMessageWithFormat ("All breakpoints removed. (%" PRIu64 " breakpoint%s)\n", (uint64_t)num_breakpoints, num_breakpoints > 1 ? "s" : "");
18415a988416SJim Ingham             }
18425a988416SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
18435a988416SJim Ingham         }
18445a988416SJim Ingham         else
18455a988416SJim Ingham         {
18465a988416SJim Ingham             // Particular breakpoint selected; disable that breakpoint.
18475a988416SJim Ingham             BreakpointIDList valid_bp_ids;
18485e09c8c3SJim Ingham             CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs (command, target, result, &valid_bp_ids);
18495a988416SJim Ingham 
18505a988416SJim Ingham             if (result.Succeeded())
18515a988416SJim Ingham             {
18525a988416SJim Ingham                 int delete_count = 0;
18535a988416SJim Ingham                 int disable_count = 0;
18545a988416SJim Ingham                 const size_t count = valid_bp_ids.GetSize();
18555a988416SJim Ingham                 for (size_t i = 0; i < count; ++i)
18565a988416SJim Ingham                 {
18575a988416SJim Ingham                     BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
18585a988416SJim Ingham 
18595a988416SJim Ingham                     if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
18605a988416SJim Ingham                     {
18615a988416SJim Ingham                         if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
18625a988416SJim Ingham                         {
18635a988416SJim Ingham                             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
18645a988416SJim Ingham                             BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
18655a988416SJim Ingham                             // It makes no sense to try to delete individual locations, so we disable them instead.
18665a988416SJim Ingham                             if (location)
18675a988416SJim Ingham                             {
18685a988416SJim Ingham                                 location->SetEnabled (false);
18695a988416SJim Ingham                                 ++disable_count;
18705a988416SJim Ingham                             }
18715a988416SJim Ingham                         }
18725a988416SJim Ingham                         else
18735a988416SJim Ingham                         {
18745a988416SJim Ingham                             target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
18755a988416SJim Ingham                             ++delete_count;
18765a988416SJim Ingham                         }
18775a988416SJim Ingham                     }
18785a988416SJim Ingham                 }
18795a988416SJim Ingham                 result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
18805a988416SJim Ingham                                                delete_count, disable_count);
18815a988416SJim Ingham                 result.SetStatus (eReturnStatusSuccessFinishNoResult);
18825a988416SJim Ingham             }
18835a988416SJim Ingham         }
18845a988416SJim Ingham         return result.Succeeded();
18855a988416SJim Ingham     }
188633df7cd3SJim Ingham private:
188733df7cd3SJim Ingham     CommandOptions m_options;
188833df7cd3SJim Ingham };
188933df7cd3SJim Ingham 
189033df7cd3SJim Ingham OptionDefinition
189133df7cd3SJim Ingham CommandObjectBreakpointDelete::CommandOptions::g_option_table[] =
189233df7cd3SJim Ingham {
189333df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
189433df7cd3SJim Ingham         "Delete all breakpoints without querying for confirmation."},
189533df7cd3SJim Ingham 
189633df7cd3SJim Ingham     { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
189733df7cd3SJim Ingham         "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
189833df7cd3SJim Ingham 
189933df7cd3SJim Ingham     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
19005a988416SJim Ingham };
19015a988416SJim Ingham 
190230fdc8d8SChris Lattner //-------------------------------------------------------------------------
19035e09c8c3SJim Ingham // CommandObjectBreakpointName
19045e09c8c3SJim Ingham //-------------------------------------------------------------------------
19055e09c8c3SJim Ingham 
19065e09c8c3SJim Ingham static OptionDefinition
19075e09c8c3SJim Ingham g_breakpoint_name_options[] =
19085e09c8c3SJim Ingham {
19095e09c8c3SJim Ingham     { LLDB_OPT_SET_1,   false, "name", 'N', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."},
19105e09c8c3SJim Ingham     { LLDB_OPT_SET_2,   false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBreakpointID,   "Specify a breakpoint id to use."},
19115e09c8c3SJim Ingham     { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
19125e09c8c3SJim Ingham         "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
19135e09c8c3SJim Ingham };
19145e09c8c3SJim Ingham class BreakpointNameOptionGroup : public OptionGroup
19155e09c8c3SJim Ingham {
19165e09c8c3SJim Ingham public:
19175e09c8c3SJim Ingham     BreakpointNameOptionGroup() :
19185e09c8c3SJim Ingham         OptionGroup(),
19195e09c8c3SJim Ingham         m_breakpoint(LLDB_INVALID_BREAK_ID),
19205e09c8c3SJim Ingham         m_use_dummy (false)
19215e09c8c3SJim Ingham     {
19225e09c8c3SJim Ingham 
19235e09c8c3SJim Ingham     }
19245e09c8c3SJim Ingham 
19255e09c8c3SJim Ingham     virtual
19265e09c8c3SJim Ingham     ~BreakpointNameOptionGroup ()
19275e09c8c3SJim Ingham     {
19285e09c8c3SJim Ingham     }
19295e09c8c3SJim Ingham 
19305e09c8c3SJim Ingham     virtual uint32_t
19315e09c8c3SJim Ingham     GetNumDefinitions ()
19325e09c8c3SJim Ingham     {
19335e09c8c3SJim Ingham       return sizeof (g_breakpoint_name_options) / sizeof (OptionDefinition);
19345e09c8c3SJim Ingham     }
19355e09c8c3SJim Ingham 
19365e09c8c3SJim Ingham     virtual const OptionDefinition*
19375e09c8c3SJim Ingham     GetDefinitions ()
19385e09c8c3SJim Ingham     {
19395e09c8c3SJim Ingham         return g_breakpoint_name_options;
19405e09c8c3SJim Ingham     }
19415e09c8c3SJim Ingham 
19425e09c8c3SJim Ingham     virtual Error
19435e09c8c3SJim Ingham     SetOptionValue (CommandInterpreter &interpreter,
19445e09c8c3SJim Ingham                     uint32_t option_idx,
19455e09c8c3SJim Ingham                     const char *option_value)
19465e09c8c3SJim Ingham     {
19475e09c8c3SJim Ingham         Error error;
19485e09c8c3SJim Ingham         const int short_option = g_breakpoint_name_options[option_idx].short_option;
19495e09c8c3SJim Ingham 
19505e09c8c3SJim Ingham         switch (short_option)
19515e09c8c3SJim Ingham         {
19525e09c8c3SJim Ingham         case 'N':
19535e09c8c3SJim Ingham             if (BreakpointID::StringIsBreakpointName(option_value, error) && error.Success())
1954c95f7e2aSPavel Labath                 m_name.SetValueFromString(option_value);
19555e09c8c3SJim Ingham             break;
19565e09c8c3SJim Ingham 
19575e09c8c3SJim Ingham         case 'B':
1958c95f7e2aSPavel Labath             if (m_breakpoint.SetValueFromString(option_value).Fail())
19595e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for breakpoint", option_value);
19605e09c8c3SJim Ingham             break;
19615e09c8c3SJim Ingham         case 'D':
1962c95f7e2aSPavel Labath             if (m_use_dummy.SetValueFromString(option_value).Fail())
19635e09c8c3SJim Ingham                 error.SetErrorStringWithFormat ("unrecognized value \"%s\" for use-dummy", option_value);
19645e09c8c3SJim Ingham             break;
19655e09c8c3SJim Ingham 
19665e09c8c3SJim Ingham         default:
19675e09c8c3SJim Ingham               error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
19685e09c8c3SJim Ingham               break;
19695e09c8c3SJim Ingham         }
19705e09c8c3SJim Ingham         return error;
19715e09c8c3SJim Ingham     }
19725e09c8c3SJim Ingham 
19735e09c8c3SJim Ingham     virtual void
19745e09c8c3SJim Ingham     OptionParsingStarting (CommandInterpreter &interpreter)
19755e09c8c3SJim Ingham     {
19765e09c8c3SJim Ingham         m_name.Clear();
19775e09c8c3SJim Ingham         m_breakpoint.Clear();
19785e09c8c3SJim Ingham         m_use_dummy.Clear();
19795e09c8c3SJim Ingham         m_use_dummy.SetDefaultValue(false);
19805e09c8c3SJim Ingham     }
19815e09c8c3SJim Ingham 
19825e09c8c3SJim Ingham     OptionValueString m_name;
19835e09c8c3SJim Ingham     OptionValueUInt64 m_breakpoint;
19845e09c8c3SJim Ingham     OptionValueBoolean m_use_dummy;
19855e09c8c3SJim Ingham };
19865e09c8c3SJim Ingham 
19875e09c8c3SJim Ingham 
19885e09c8c3SJim Ingham class CommandObjectBreakpointNameAdd : public CommandObjectParsed
19895e09c8c3SJim Ingham {
19905e09c8c3SJim Ingham public:
19915e09c8c3SJim Ingham     CommandObjectBreakpointNameAdd (CommandInterpreter &interpreter) :
19925e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
19935e09c8c3SJim Ingham                              "add",
19945e09c8c3SJim Ingham                              "Add a name to the breakpoints provided.",
19955e09c8c3SJim Ingham                              "breakpoint name add <command-options> <breakpoint-id-list>"),
19965e09c8c3SJim Ingham         m_name_options(),
19975e09c8c3SJim Ingham         m_option_group(interpreter)
19985e09c8c3SJim Ingham         {
19995e09c8c3SJim Ingham             // Create the first variant for the first (and only) argument for this command.
20005e09c8c3SJim Ingham             CommandArgumentEntry arg1;
20015e09c8c3SJim Ingham             CommandArgumentData id_arg;
20025e09c8c3SJim Ingham             id_arg.arg_type = eArgTypeBreakpointID;
20035e09c8c3SJim Ingham             id_arg.arg_repetition = eArgRepeatOptional;
20045e09c8c3SJim Ingham             arg1.push_back(id_arg);
20055e09c8c3SJim Ingham             m_arguments.push_back (arg1);
20065e09c8c3SJim Ingham 
20075e09c8c3SJim Ingham             m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
20085e09c8c3SJim Ingham             m_option_group.Finalize();
20095e09c8c3SJim Ingham         }
20105e09c8c3SJim Ingham 
20115e09c8c3SJim Ingham     virtual
20125e09c8c3SJim Ingham     ~CommandObjectBreakpointNameAdd () {}
20135e09c8c3SJim Ingham 
20145e09c8c3SJim Ingham   Options *
20155e09c8c3SJim Ingham   GetOptions ()
20165e09c8c3SJim Ingham   {
20175e09c8c3SJim Ingham     return &m_option_group;
20185e09c8c3SJim Ingham   }
20195e09c8c3SJim Ingham 
20205e09c8c3SJim Ingham protected:
20215e09c8c3SJim Ingham     virtual bool
20225e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
20235e09c8c3SJim Ingham     {
20245e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
20255e09c8c3SJim Ingham         {
20265e09c8c3SJim Ingham             result.SetError("No name option provided.");
20275e09c8c3SJim Ingham             return false;
20285e09c8c3SJim Ingham         }
20295e09c8c3SJim Ingham 
20305e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
20315e09c8c3SJim Ingham 
20325e09c8c3SJim Ingham         if (target == NULL)
20335e09c8c3SJim Ingham         {
20345e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
20355e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
20365e09c8c3SJim Ingham             return false;
20375e09c8c3SJim Ingham         }
20385e09c8c3SJim Ingham 
20395e09c8c3SJim Ingham         Mutex::Locker locker;
20405e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
20415e09c8c3SJim Ingham 
20425e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
20435e09c8c3SJim Ingham 
20445e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
20455e09c8c3SJim Ingham         if (num_breakpoints == 0)
20465e09c8c3SJim Ingham         {
20475e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot add names.");
20485e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
20495e09c8c3SJim Ingham             return false;
20505e09c8c3SJim Ingham         }
20515e09c8c3SJim Ingham 
20525e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
20535e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
20545e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
20555e09c8c3SJim Ingham 
20565e09c8c3SJim Ingham         if (result.Succeeded())
20575e09c8c3SJim Ingham         {
20585e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
20595e09c8c3SJim Ingham             {
20605e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot add names.");
20615e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
20625e09c8c3SJim Ingham                 return false;
20635e09c8c3SJim Ingham             }
20645e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
20655e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
20665e09c8c3SJim Ingham             {
20675e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
20685e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
20695e09c8c3SJim Ingham                 Error error;  // We don't need to check the error here, since the option parser checked it...
20705e09c8c3SJim Ingham                 bp_sp->AddName(m_name_options.m_name.GetCurrentValue(), error);
20715e09c8c3SJim Ingham             }
20725e09c8c3SJim Ingham         }
20735e09c8c3SJim Ingham 
20745e09c8c3SJim Ingham         return true;
20755e09c8c3SJim Ingham     }
20765e09c8c3SJim Ingham 
20775e09c8c3SJim Ingham private:
20785e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
20795e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
20805e09c8c3SJim Ingham };
20815e09c8c3SJim Ingham 
20825e09c8c3SJim Ingham 
20835e09c8c3SJim Ingham 
20845e09c8c3SJim Ingham class CommandObjectBreakpointNameDelete : public CommandObjectParsed
20855e09c8c3SJim Ingham {
20865e09c8c3SJim Ingham public:
20875e09c8c3SJim Ingham     CommandObjectBreakpointNameDelete (CommandInterpreter &interpreter) :
20885e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
20895e09c8c3SJim Ingham                              "delete",
20905e09c8c3SJim Ingham                              "Delete a name from the breakpoints provided.",
20915e09c8c3SJim Ingham                              "breakpoint name delete <command-options> <breakpoint-id-list>"),
20925e09c8c3SJim Ingham         m_name_options(),
20935e09c8c3SJim Ingham         m_option_group(interpreter)
20945e09c8c3SJim Ingham     {
20955e09c8c3SJim Ingham         // Create the first variant for the first (and only) argument for this command.
20965e09c8c3SJim Ingham         CommandArgumentEntry arg1;
20975e09c8c3SJim Ingham         CommandArgumentData id_arg;
20985e09c8c3SJim Ingham         id_arg.arg_type = eArgTypeBreakpointID;
20995e09c8c3SJim Ingham         id_arg.arg_repetition = eArgRepeatOptional;
21005e09c8c3SJim Ingham         arg1.push_back(id_arg);
21015e09c8c3SJim Ingham         m_arguments.push_back (arg1);
21025e09c8c3SJim Ingham 
21035e09c8c3SJim Ingham         m_option_group.Append (&m_name_options, LLDB_OPT_SET_1, LLDB_OPT_SET_ALL);
21045e09c8c3SJim Ingham         m_option_group.Finalize();
21055e09c8c3SJim Ingham     }
21065e09c8c3SJim Ingham 
21075e09c8c3SJim Ingham     virtual
21085e09c8c3SJim Ingham     ~CommandObjectBreakpointNameDelete () {}
21095e09c8c3SJim Ingham 
21105e09c8c3SJim Ingham   Options *
21115e09c8c3SJim Ingham   GetOptions ()
21125e09c8c3SJim Ingham   {
21135e09c8c3SJim Ingham     return &m_option_group;
21145e09c8c3SJim Ingham   }
21155e09c8c3SJim Ingham 
21165e09c8c3SJim Ingham protected:
21175e09c8c3SJim Ingham     virtual bool
21185e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
21195e09c8c3SJim Ingham     {
21205e09c8c3SJim Ingham         if (!m_name_options.m_name.OptionWasSet())
21215e09c8c3SJim Ingham         {
21225e09c8c3SJim Ingham             result.SetError("No name option provided.");
21235e09c8c3SJim Ingham             return false;
21245e09c8c3SJim Ingham         }
21255e09c8c3SJim Ingham 
21265e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
21275e09c8c3SJim Ingham 
21285e09c8c3SJim Ingham         if (target == NULL)
21295e09c8c3SJim Ingham         {
21305e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
21315e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21325e09c8c3SJim Ingham             return false;
21335e09c8c3SJim Ingham         }
21345e09c8c3SJim Ingham 
21355e09c8c3SJim Ingham         Mutex::Locker locker;
21365e09c8c3SJim Ingham         target->GetBreakpointList().GetListMutex(locker);
21375e09c8c3SJim Ingham 
21385e09c8c3SJim Ingham         const BreakpointList &breakpoints = target->GetBreakpointList();
21395e09c8c3SJim Ingham 
21405e09c8c3SJim Ingham         size_t num_breakpoints = breakpoints.GetSize();
21415e09c8c3SJim Ingham         if (num_breakpoints == 0)
21425e09c8c3SJim Ingham         {
21435e09c8c3SJim Ingham             result.SetError("No breakpoints, cannot delete names.");
21445e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
21455e09c8c3SJim Ingham             return false;
21465e09c8c3SJim Ingham         }
21475e09c8c3SJim Ingham 
21485e09c8c3SJim Ingham         // Particular breakpoint selected; disable that breakpoint.
21495e09c8c3SJim Ingham         BreakpointIDList valid_bp_ids;
21505e09c8c3SJim Ingham         CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
21515e09c8c3SJim Ingham 
21525e09c8c3SJim Ingham         if (result.Succeeded())
21535e09c8c3SJim Ingham         {
21545e09c8c3SJim Ingham             if (valid_bp_ids.GetSize() == 0)
21555e09c8c3SJim Ingham             {
21565e09c8c3SJim Ingham                 result.SetError("No breakpoints specified, cannot delete names.");
21575e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
21585e09c8c3SJim Ingham                 return false;
21595e09c8c3SJim Ingham             }
21605e09c8c3SJim Ingham             size_t num_valid_ids = valid_bp_ids.GetSize();
21615e09c8c3SJim Ingham             for (size_t index = 0; index < num_valid_ids; index++)
21625e09c8c3SJim Ingham             {
21635e09c8c3SJim Ingham                 lldb::break_id_t bp_id = valid_bp_ids.GetBreakpointIDAtIndex(index).GetBreakpointID();
21645e09c8c3SJim Ingham                 BreakpointSP bp_sp = breakpoints.FindBreakpointByID(bp_id);
21655e09c8c3SJim Ingham                 bp_sp->RemoveName(m_name_options.m_name.GetCurrentValue());
21665e09c8c3SJim Ingham             }
21675e09c8c3SJim Ingham         }
21685e09c8c3SJim Ingham 
21695e09c8c3SJim Ingham         return true;
21705e09c8c3SJim Ingham     }
21715e09c8c3SJim Ingham 
21725e09c8c3SJim Ingham private:
21735e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
21745e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
21755e09c8c3SJim Ingham };
21765e09c8c3SJim Ingham 
21775e09c8c3SJim Ingham class CommandObjectBreakpointNameList : public CommandObjectParsed
21785e09c8c3SJim Ingham {
21795e09c8c3SJim Ingham public:
21805e09c8c3SJim Ingham     CommandObjectBreakpointNameList (CommandInterpreter &interpreter) :
21815e09c8c3SJim Ingham         CommandObjectParsed (interpreter,
21825e09c8c3SJim Ingham                              "list",
21835e09c8c3SJim Ingham                              "List either the names for a breakpoint or the breakpoints for a given name.",
21845e09c8c3SJim Ingham                              "breakpoint name list <command-options>"),
21855e09c8c3SJim Ingham         m_name_options(),
21865e09c8c3SJim Ingham         m_option_group(interpreter)
21875e09c8c3SJim Ingham     {
21885e09c8c3SJim Ingham         m_option_group.Append (&m_name_options);
21895e09c8c3SJim Ingham         m_option_group.Finalize();
21905e09c8c3SJim Ingham     }
21915e09c8c3SJim Ingham 
21925e09c8c3SJim Ingham     virtual
21935e09c8c3SJim Ingham     ~CommandObjectBreakpointNameList () {}
21945e09c8c3SJim Ingham 
21955e09c8c3SJim Ingham   Options *
21965e09c8c3SJim Ingham   GetOptions ()
21975e09c8c3SJim Ingham   {
21985e09c8c3SJim Ingham     return &m_option_group;
21995e09c8c3SJim Ingham   }
22005e09c8c3SJim Ingham 
22015e09c8c3SJim Ingham protected:
22025e09c8c3SJim Ingham protected:
22035e09c8c3SJim Ingham     virtual bool
22045e09c8c3SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
22055e09c8c3SJim Ingham     {
22065e09c8c3SJim Ingham         Target *target = GetSelectedOrDummyTarget(m_name_options.m_use_dummy.GetCurrentValue());
22075e09c8c3SJim Ingham 
22085e09c8c3SJim Ingham         if (target == NULL)
22095e09c8c3SJim Ingham         {
22105e09c8c3SJim Ingham             result.AppendError ("Invalid target. No existing target or breakpoints.");
22115e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
22125e09c8c3SJim Ingham             return false;
22135e09c8c3SJim Ingham         }
22145e09c8c3SJim Ingham 
22155e09c8c3SJim Ingham         if (m_name_options.m_name.OptionWasSet())
22165e09c8c3SJim Ingham         {
22175e09c8c3SJim Ingham             const char *name = m_name_options.m_name.GetCurrentValue();
22185e09c8c3SJim Ingham             Mutex::Locker locker;
22195e09c8c3SJim Ingham             target->GetBreakpointList().GetListMutex(locker);
22205e09c8c3SJim Ingham 
22215e09c8c3SJim Ingham             BreakpointList &breakpoints = target->GetBreakpointList();
22225e09c8c3SJim Ingham             for (BreakpointSP bp_sp : breakpoints.Breakpoints())
22235e09c8c3SJim Ingham             {
22245e09c8c3SJim Ingham                 if (bp_sp->MatchesName(name))
22255e09c8c3SJim Ingham                 {
22265e09c8c3SJim Ingham                     StreamString s;
22275e09c8c3SJim Ingham                     bp_sp->GetDescription(&s, eDescriptionLevelBrief);
22285e09c8c3SJim Ingham                     s.EOL();
22295e09c8c3SJim Ingham                     result.AppendMessage(s.GetData());
22305e09c8c3SJim Ingham                 }
22315e09c8c3SJim Ingham             }
22325e09c8c3SJim Ingham 
22335e09c8c3SJim Ingham         }
22345e09c8c3SJim Ingham         else if (m_name_options.m_breakpoint.OptionWasSet())
22355e09c8c3SJim Ingham         {
22365e09c8c3SJim Ingham             BreakpointSP bp_sp = target->GetBreakpointList().FindBreakpointByID(m_name_options.m_breakpoint.GetCurrentValue());
22375e09c8c3SJim Ingham             if (bp_sp)
22385e09c8c3SJim Ingham             {
22395e09c8c3SJim Ingham                 std::vector<std::string> names;
22405e09c8c3SJim Ingham                 bp_sp->GetNames (names);
22415e09c8c3SJim Ingham                 result.AppendMessage ("Names:");
22425e09c8c3SJim Ingham                 for (auto name : names)
22435e09c8c3SJim Ingham                     result.AppendMessageWithFormat ("    %s\n", name.c_str());
22445e09c8c3SJim Ingham             }
22455e09c8c3SJim Ingham             else
22465e09c8c3SJim Ingham             {
22475e09c8c3SJim Ingham                 result.AppendErrorWithFormat ("Could not find breakpoint %" PRId64 ".\n",
22485e09c8c3SJim Ingham                                            m_name_options.m_breakpoint.GetCurrentValue());
22495e09c8c3SJim Ingham                 result.SetStatus (eReturnStatusFailed);
22505e09c8c3SJim Ingham                 return false;
22515e09c8c3SJim Ingham             }
22525e09c8c3SJim Ingham         }
22535e09c8c3SJim Ingham         else
22545e09c8c3SJim Ingham         {
22555e09c8c3SJim Ingham             result.SetError ("Must specify -N or -B option to list.");
22565e09c8c3SJim Ingham             result.SetStatus (eReturnStatusFailed);
22575e09c8c3SJim Ingham             return false;
22585e09c8c3SJim Ingham         }
22595e09c8c3SJim Ingham         return true;
22605e09c8c3SJim Ingham     }
22615e09c8c3SJim Ingham 
22625e09c8c3SJim Ingham private:
22635e09c8c3SJim Ingham     BreakpointNameOptionGroup m_name_options;
22645e09c8c3SJim Ingham     OptionGroupOptions m_option_group;
22655e09c8c3SJim Ingham };
22665e09c8c3SJim Ingham 
22675e09c8c3SJim Ingham //-------------------------------------------------------------------------
22685e09c8c3SJim Ingham // CommandObjectMultiwordBreakpoint
22695e09c8c3SJim Ingham //-------------------------------------------------------------------------
22705e09c8c3SJim Ingham class CommandObjectBreakpointName : public CommandObjectMultiword
22715e09c8c3SJim Ingham {
22725e09c8c3SJim Ingham public:
22735e09c8c3SJim Ingham     CommandObjectBreakpointName (CommandInterpreter &interpreter) :
22745e09c8c3SJim Ingham         CommandObjectMultiword(interpreter,
22755e09c8c3SJim Ingham                                 "name",
22765e09c8c3SJim Ingham                                 "A set of commands to manage name tags for breakpoints",
22775e09c8c3SJim Ingham                                 "breakpoint name <command> [<command-options>]")
22785e09c8c3SJim Ingham     {
22795e09c8c3SJim Ingham         CommandObjectSP add_command_object (new CommandObjectBreakpointNameAdd (interpreter));
22805e09c8c3SJim Ingham         CommandObjectSP delete_command_object (new CommandObjectBreakpointNameDelete (interpreter));
22815e09c8c3SJim Ingham         CommandObjectSP list_command_object (new CommandObjectBreakpointNameList (interpreter));
22825e09c8c3SJim Ingham 
22835e09c8c3SJim Ingham         LoadSubCommand ("add", add_command_object);
22845e09c8c3SJim Ingham         LoadSubCommand ("delete", delete_command_object);
22855e09c8c3SJim Ingham         LoadSubCommand ("list", list_command_object);
22865e09c8c3SJim Ingham 
22875e09c8c3SJim Ingham     }
22885e09c8c3SJim Ingham 
22895e09c8c3SJim Ingham     virtual
22905e09c8c3SJim Ingham     ~CommandObjectBreakpointName ()
22915e09c8c3SJim Ingham     {
22925e09c8c3SJim Ingham     }
22935e09c8c3SJim Ingham 
22945e09c8c3SJim Ingham };
22955e09c8c3SJim Ingham 
22965e09c8c3SJim Ingham 
22975e09c8c3SJim Ingham //-------------------------------------------------------------------------
229830fdc8d8SChris Lattner // CommandObjectMultiwordBreakpoint
229930fdc8d8SChris Lattner //-------------------------------------------------------------------------
2300ae1c4cf5SJim Ingham #pragma mark MultiwordBreakpoint
230130fdc8d8SChris Lattner 
23026611103cSGreg Clayton CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
2303a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
2304a7015092SGreg Clayton                             "breakpoint",
230546fbc60fSJim Ingham                             "A set of commands for operating on breakpoints. Also see _regexp-break.",
230630fdc8d8SChris Lattner                             "breakpoint <command> [<command-options>]")
230730fdc8d8SChris Lattner {
2308a7015092SGreg Clayton     CommandObjectSP list_command_object (new CommandObjectBreakpointList (interpreter));
2309a7015092SGreg Clayton     CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable (interpreter));
2310a7015092SGreg Clayton     CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable (interpreter));
2311b7234e40SJohnny Chen     CommandObjectSP clear_command_object (new CommandObjectBreakpointClear (interpreter));
2312b7234e40SJohnny Chen     CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete (interpreter));
2313a7015092SGreg Clayton     CommandObjectSP set_command_object (new CommandObjectBreakpointSet (interpreter));
231430fdc8d8SChris Lattner     CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
2315a7015092SGreg Clayton     CommandObjectSP modify_command_object (new CommandObjectBreakpointModify(interpreter));
23165e09c8c3SJim Ingham     CommandObjectSP name_command_object (new CommandObjectBreakpointName(interpreter));
231730fdc8d8SChris Lattner 
2318b7234e40SJohnny Chen     list_command_object->SetCommandName ("breakpoint list");
231930fdc8d8SChris Lattner     enable_command_object->SetCommandName("breakpoint enable");
232030fdc8d8SChris Lattner     disable_command_object->SetCommandName("breakpoint disable");
2321b7234e40SJohnny Chen     clear_command_object->SetCommandName("breakpoint clear");
2322b7234e40SJohnny Chen     delete_command_object->SetCommandName("breakpoint delete");
2323ae1c4cf5SJim Ingham     set_command_object->SetCommandName("breakpoint set");
2324b7234e40SJohnny Chen     command_command_object->SetCommandName ("breakpoint command");
2325b7234e40SJohnny Chen     modify_command_object->SetCommandName ("breakpoint modify");
23265e09c8c3SJim Ingham     name_command_object->SetCommandName ("breakpoint name");
232730fdc8d8SChris Lattner 
232823f59509SGreg Clayton     LoadSubCommand ("list",       list_command_object);
232923f59509SGreg Clayton     LoadSubCommand ("enable",     enable_command_object);
233023f59509SGreg Clayton     LoadSubCommand ("disable",    disable_command_object);
233123f59509SGreg Clayton     LoadSubCommand ("clear",      clear_command_object);
233223f59509SGreg Clayton     LoadSubCommand ("delete",     delete_command_object);
233323f59509SGreg Clayton     LoadSubCommand ("set",        set_command_object);
233423f59509SGreg Clayton     LoadSubCommand ("command",    command_command_object);
233523f59509SGreg Clayton     LoadSubCommand ("modify",     modify_command_object);
23365e09c8c3SJim Ingham     LoadSubCommand ("name",       name_command_object);
233730fdc8d8SChris Lattner }
233830fdc8d8SChris Lattner 
233930fdc8d8SChris Lattner CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
234030fdc8d8SChris Lattner {
234130fdc8d8SChris Lattner }
234230fdc8d8SChris Lattner 
234330fdc8d8SChris Lattner void
23445e09c8c3SJim Ingham CommandObjectMultiwordBreakpoint::VerifyIDs (Args &args,
23455e09c8c3SJim Ingham                                              Target *target,
23465e09c8c3SJim Ingham                                              bool allow_locations,
23475e09c8c3SJim Ingham                                              CommandReturnObject &result,
234830fdc8d8SChris Lattner                                              BreakpointIDList *valid_ids)
234930fdc8d8SChris Lattner {
235030fdc8d8SChris Lattner     // args can be strings representing 1). integers (for breakpoint ids)
235130fdc8d8SChris Lattner     //                                  2). the full breakpoint & location canonical representation
235230fdc8d8SChris Lattner     //                                  3). the word "to" or a hyphen, representing a range (in which case there
235330fdc8d8SChris Lattner     //                                      had *better* be an entry both before & after of one of the first two types.
23545e09c8c3SJim Ingham     //                                  4). A breakpoint name
235536f3b369SJim Ingham     // If args is empty, we will use the last created breakpoint (if there is one.)
235630fdc8d8SChris Lattner 
235730fdc8d8SChris Lattner     Args temp_args;
235830fdc8d8SChris Lattner 
235936f3b369SJim Ingham     if (args.GetArgumentCount() == 0)
236036f3b369SJim Ingham     {
23614d122c40SGreg Clayton         if (target->GetLastCreatedBreakpoint())
236236f3b369SJim Ingham         {
236336f3b369SJim Ingham             valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
236436f3b369SJim Ingham             result.SetStatus (eReturnStatusSuccessFinishNoResult);
236536f3b369SJim Ingham         }
236636f3b369SJim Ingham         else
236736f3b369SJim Ingham         {
236836f3b369SJim Ingham             result.AppendError("No breakpoint specified and no last created breakpoint.");
236936f3b369SJim Ingham             result.SetStatus (eReturnStatusFailed);
237036f3b369SJim Ingham         }
237136f3b369SJim Ingham         return;
237236f3b369SJim Ingham     }
237336f3b369SJim Ingham 
237430fdc8d8SChris Lattner     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
237530fdc8d8SChris Lattner     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
237630fdc8d8SChris Lattner     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
237730fdc8d8SChris Lattner 
23785e09c8c3SJim Ingham     BreakpointIDList::FindAndReplaceIDRanges (args, target, allow_locations, result, temp_args);
237930fdc8d8SChris Lattner 
238030fdc8d8SChris Lattner     // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:
238130fdc8d8SChris Lattner 
2382c982c768SGreg Clayton     valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);
238330fdc8d8SChris Lattner 
238430fdc8d8SChris Lattner     // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
238530fdc8d8SChris Lattner     // and put into valid_ids.
238630fdc8d8SChris Lattner 
238730fdc8d8SChris Lattner     if (result.Succeeded())
238830fdc8d8SChris Lattner     {
238930fdc8d8SChris Lattner         // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
239030fdc8d8SChris Lattner         // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.
239130fdc8d8SChris Lattner 
2392c982c768SGreg Clayton         const size_t count = valid_ids->GetSize();
2393c982c768SGreg Clayton         for (size_t i = 0; i < count; ++i)
239430fdc8d8SChris Lattner         {
239530fdc8d8SChris Lattner             BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
239630fdc8d8SChris Lattner             Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
239730fdc8d8SChris Lattner             if (breakpoint != NULL)
239830fdc8d8SChris Lattner             {
2399c7bece56SGreg Clayton                 const size_t num_locations = breakpoint->GetNumLocations();
24003985c8c6SSaleem Abdulrasool                 if (static_cast<size_t>(cur_bp_id.GetLocationID()) > num_locations)
240130fdc8d8SChris Lattner                 {
240230fdc8d8SChris Lattner                     StreamString id_str;
2403c982c768SGreg Clayton                     BreakpointID::GetCanonicalReference (&id_str,
2404c982c768SGreg Clayton                                                          cur_bp_id.GetBreakpointID(),
240530fdc8d8SChris Lattner                                                          cur_bp_id.GetLocationID());
2406c982c768SGreg Clayton                     i = valid_ids->GetSize() + 1;
240730fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
240830fdc8d8SChris Lattner                                                  id_str.GetData());
240930fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
241030fdc8d8SChris Lattner                 }
241130fdc8d8SChris Lattner             }
241230fdc8d8SChris Lattner             else
241330fdc8d8SChris Lattner             {
2414c982c768SGreg Clayton                 i = valid_ids->GetSize() + 1;
241530fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
241630fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
241730fdc8d8SChris Lattner             }
241830fdc8d8SChris Lattner         }
241930fdc8d8SChris Lattner     }
242030fdc8d8SChris Lattner }
2421