]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdCmdBreak.cpp
mfv (r276698): support for remote control over local sockets.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmdCmdBreak.cpp
1 //===-- MICmdCmdBreak.cpp ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 //++
11 // File:                MICmdCmdBreak.cpp
12 //
13 // Overview:    CMICmdCmdBreakInsert                    implementation.
14 //                              CMICmdCmdBreakDelete                    implementation.
15 //                              CMICmdCmdBreakDisable                   implementation.
16 //                              CMICmdCmdBreakEnable                    implementation.
17 //                              CMICmdCmdBreakAfter                             implementation.
18 //                              CMICmdCmdBreakCondition                 implementation.
19 //
20 // Environment: Compilers:      Visual C++ 12.
21 //                                                      gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
22 //                              Libraries:      See MIReadmetxt. 
23 //
24 // Copyright:   None.
25 //--
26
27 // Third Party Headers:
28 #include <lldb/API/SBBreakpointLocation.h>
29
30 // In-house headers:
31 #include "MICmdCmdBreak.h"
32 #include "MICmnMIResultRecord.h"
33 #include "MICmnMIValueConst.h"
34 #include "MICmnMIOutOfBandRecord.h"
35 #include "MICmnLLDBDebugger.h"
36 #include "MICmnLLDBDebugSessionInfo.h"
37 #include "MICmdArgValFile.h"
38 #include "MICmdArgValNumber.h"
39 #include "MICmdArgValString.h"
40 #include "MICmdArgValThreadGrp.h"
41 #include "MICmdArgValOptionLong.h"
42 #include "MICmdArgValOptionShort.h"
43 #include "MICmdArgValListOfN.h"
44 #include "MICmnStreamStdout.h"
45
46 //++ ------------------------------------------------------------------------------------
47 // Details:     CMICmdCmdBreakInsert constructor.
48 // Type:        Method.
49 // Args:        None.
50 // Return:      None.
51 // Throws:      None.
52 //--
53 CMICmdCmdBreakInsert::CMICmdCmdBreakInsert( void )
54 :       m_bBrkPtIsTemp( false )
55 ,       m_bBrkPtIsPending( false )
56 ,       m_nBrkPtIgnoreCount( 0 )
57 ,       m_bBrkPtEnabled( false )
58 ,       m_bBrkPtCondition( false )
59 ,       m_bBrkPtThreadId( false )
60 ,       m_nBrkPtThreadId( 0 )
61 ,       m_constStrArgNamedTempBrkPt( "t" )
62 ,       m_constStrArgNamedHWBrkPt( "h" )
63 ,       m_constStrArgNamedPendinfBrkPt( "f" )
64 ,       m_constStrArgNamedDisableBrkPt( "d" )
65 ,       m_constStrArgNamedTracePt( "a" )
66 ,       m_constStrArgNamedConditionalBrkPt( "c" )
67 ,       m_constStrArgNamedInoreCnt( "i" )
68 ,       m_constStrArgNamedRestrictBrkPtToThreadId( "p" )
69 ,       m_constStrArgNamedLocation( "location" )
70 ,       m_constStrArgNamedThreadGroup( "thread-group" )
71 {
72         // Command factory matches this name with that received from the stdin stream
73         m_strMiCmd = "break-insert";
74         
75         // Required by the CMICmdFactory when registering *this command
76         m_pSelfCreatorFn = &CMICmdCmdBreakInsert::CreateSelf;
77 }
78
79 //++ ------------------------------------------------------------------------------------
80 // Details:     CMICmdCmdBreakInsert destructor.
81 // Type:        Overrideable.
82 // Args:        None.
83 // Return:      None.
84 // Throws:      None.
85 //--
86 CMICmdCmdBreakInsert::~CMICmdCmdBreakInsert( void )
87 {
88 }
89
90 //++ ------------------------------------------------------------------------------------
91 // Details:     The invoker requires this function. The parses the command line options 
92 //                      arguments to extract values for each of those arguments.
93 // Type:        Overridden.
94 // Args:        None.
95 // Return:      MIstatus::success - Functional succeeded.
96 //                      MIstatus::failure - Functional failed.
97 // Throws:      None.
98 //--
99 bool CMICmdCmdBreakInsert::ParseArgs( void )
100 {
101         bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTempBrkPt, false, true )) );
102         //Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedHWBrkPt, false, false ) ) );
103         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedPendinfBrkPt, false, true, CMICmdArgValListBase::eArgValType_StringQuotedNumberPath, 1 ) ) );
104         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedDisableBrkPt, false, false ) ) );
105         //Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTracePt, false, false ) ) );
106         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedConditionalBrkPt, false, true, CMICmdArgValListBase::eArgValType_StringQuoted, 1 ) ) );
107         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedInoreCnt, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
108         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedRestrictBrkPtToThreadId, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
109         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedLocation, false, true ) ) );
110         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGroup, false, true, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) ); 
111         return (bOk && ParseValidateCmdOptions() );
112 }
113
114 //++ ------------------------------------------------------------------------------------
115 // Details:     The invoker requires this function. The command does work in this function.
116 //                      The command is likely to communicate with the LLDB SBDebugger in here.
117 // Type:        Overridden.
118 // Args:        None.
119 // Return:      MIstatus::success - Functional succeeded.
120 //                      MIstatus::failure - Functional failed.
121 // Throws:      None.
122 //--
123 bool CMICmdCmdBreakInsert::Execute( void )
124 {
125         CMICMDBASE_GETOPTION( pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt );
126         CMICMDBASE_GETOPTION( pArgThreadGroup, OptionLong, m_constStrArgNamedThreadGroup );
127         CMICMDBASE_GETOPTION( pArgLocation, String, m_constStrArgNamedLocation );
128         CMICMDBASE_GETOPTION( pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt );
129         CMICMDBASE_GETOPTION( pArgPendingBrkPt, OptionShort, m_constStrArgNamedPendinfBrkPt );
130         CMICMDBASE_GETOPTION( pArgDisableBrkPt, OptionShort, m_constStrArgNamedDisableBrkPt );
131         CMICMDBASE_GETOPTION( pArgConditionalBrkPt, OptionShort, m_constStrArgNamedConditionalBrkPt );
132         CMICMDBASE_GETOPTION( pArgRestrictBrkPtToThreadId, OptionShort, m_constStrArgNamedRestrictBrkPtToThreadId );
133         
134         m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
135         m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
136         m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
137         if( m_bHaveArgOptionThreadGrp )
138         {
139                 MIuint nThreadGrp = 0;
140                 pArgThreadGroup->GetExpectedOption< CMICmdArgValThreadGrp, MIuint >( nThreadGrp ); 
141                 m_strArgOptionThreadGrp = CMIUtilString::Format( "i%d", nThreadGrp );
142         }
143         m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
144         if( pArgLocation->GetFound() )
145                 m_brkName = pArgLocation->GetValue();
146         else if( m_bBrkPtIsPending )
147         {
148                 pArgPendingBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkName );
149         }
150         if( pArgIgnoreCnt->GetFound() )
151         {
152                 pArgIgnoreCnt->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtIgnoreCount );
153         }
154         m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
155         if( m_bBrkPtCondition )
156         {
157                 pArgConditionalBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkPtCondition );
158         }
159         m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
160         if( m_bBrkPtCondition )
161         {
162                 pArgRestrictBrkPtToThreadId->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtThreadId );
163         }
164         
165         // Determine if break on a file line or at a function
166         BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
167         const CMIUtilString cColon = ":";
168         CMIUtilString fileName;
169         MIuint nFileLine = 0;
170         CMIUtilString strFileFn;
171         const MIint nPosColon = m_brkName.find( cColon );
172         if( nPosColon != (MIint) std::string::npos )
173         {
174                 CMIUtilString::VecString_t vecFileAndLocation;
175                 const MIuint nSplits = m_brkName.Split( cColon, vecFileAndLocation ); MIunused( nSplits );
176                 if( vecFileAndLocation.size() != 2 )
177                 {
178                         SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_LOCATION_FORMAT ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
179                         return MIstatus::failure;
180                 }
181                 fileName = vecFileAndLocation.at( 0 );
182                 const CMIUtilString & rStrLineOrFn( vecFileAndLocation.at( 1 ) );
183                 if( rStrLineOrFn.empty() )
184                         eBrkPtType = eBreakPoint_ByName;
185                 else
186                 {
187                         MIint64 nValue = 0;
188                         if( rStrLineOrFn.ExtractNumber( nValue ) )
189                         {
190                                 nFileLine = static_cast< MIuint >( nValue );
191                                 eBrkPtType = eBreakPoint_ByFileLine;
192                         }
193                         else
194                         {
195                                 strFileFn = rStrLineOrFn;
196                                 eBrkPtType = eBreakPoint_ByFileFn;
197                         }
198                 }
199         }
200
201         // Determine if break defined as an address
202         lldb::addr_t nAddress = 0;
203         if( eBrkPtType == eBreakPoint_NotDefineYet ) 
204         {
205                 MIint64 nValue = 0;
206                 if( m_brkName.ExtractNumber( nValue ) )
207                 {
208                         nAddress = static_cast< lldb::addr_t >( nValue );
209                         eBrkPtType = eBreakPoint_ByAddress;
210                 }
211         }
212         
213         // Break defined as an function
214         if( eBrkPtType == eBreakPoint_NotDefineYet ) 
215         {
216                 eBrkPtType = eBreakPoint_ByName;
217         }
218
219         // Ask LLDB to create a breakpoint
220         bool bOk = MIstatus::success;
221         CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
222         lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
223         switch( eBrkPtType ) 
224         {
225         case eBreakPoint_ByAddress:
226                 m_brkPt = rTarget.BreakpointCreateByAddress( nAddress );
227                 break;
228         case eBreakPoint_ByFileFn:
229                 m_brkPt = rTarget.BreakpointCreateByName( strFileFn.c_str(), fileName.c_str() );
230                 break;
231         case eBreakPoint_ByFileLine:
232                 m_brkPt = rTarget.BreakpointCreateByLocation( fileName.c_str(), nFileLine );
233                 break;
234         case eBreakPoint_ByName:
235                 m_brkPt = rTarget.BreakpointCreateByName( m_brkName.c_str(), rTarget.GetExecutable().GetFilename() );
236                 break;
237         case eBreakPoint_count:
238         case eBreakPoint_NotDefineYet:
239         case eBreakPoint_Invalid:
240                 bOk = MIstatus::failure;
241                 break;
242         }
243         
244         if( bOk )
245         {
246                 m_brkPt.SetEnabled( m_bBrkPtEnabled );
247                 m_brkPt.SetIgnoreCount( m_nBrkPtIgnoreCount );
248                 if( m_bBrkPtCondition )
249                         m_brkPt.SetCondition( m_brkPtCondition.c_str() );
250                 if( m_bBrkPtThreadId )
251                         m_brkPt.SetThreadID( m_nBrkPtThreadId );
252                 if( !m_brkPt.IsValid() )
253                         m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
254         }
255
256         // CODETAG_LLDB_BREAKPOINT_CREATION
257         // This is in the main thread
258         // Record break point information to be by LLDB event handler function
259         CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
260         sBrkPtInfo.m_id = m_brkPt.GetID();
261         sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;            
262         sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
263         sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp; 
264         sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;   
265         sBrkPtInfo.m_strOrigLoc = m_brkName;                                    
266         sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
267         sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
268         sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
269         sBrkPtInfo.m_strCondition = m_brkPtCondition;
270         sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
271         sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
272         bOk = bOk && rSessionInfo.RecordBrkPtInfo( m_brkPt.GetID(), sBrkPtInfo );
273         
274         if( !bOk )
275         {
276                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
277                 return MIstatus::failure;
278         }
279
280         // CODETAG_LLDB_BRKPT_ID_MAX
281         if( m_brkPt.GetID() > (lldb::break_id_t) rSessionInfo.m_nBrkPointCntMax )
282         {
283                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_CNT_EXCEEDED ), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_nBrkPointCntMax, m_brkName.c_str() ) );
284                 return MIstatus::failure;
285         }
286
287         return MIstatus::success;
288 }
289
290 //++ ------------------------------------------------------------------------------------
291 // Details:     The invoker requires this function. The command prepares a MI Record Result
292 //                      for the work carried out in the Execute().
293 // Type:        Overridden.
294 // Args:        None.
295 // Return:      MIstatus::success - Functional succeeded.
296 //                      MIstatus::failure - Functional failed.
297 // Throws:      None.
298 //--
299 bool CMICmdCmdBreakInsert::Acknowledge( void )
300 {
301         // Get breakpoint information
302         CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
303         CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
304         if( !rSessionInfo.GetBrkPtInfo( m_brkPt, sBrkPtInfo ) )
305         {
306                 return MIstatus::failure;
307         }
308
309         // CODETAG_LLDB_BREAKPOINT_CREATION
310         // Add more breakpoint information or overwrite existing information
311         sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;                                    
312         sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;                        
313         sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp; 
314         sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;   
315         sBrkPtInfo.m_nTimes = m_brkPt.GetNumLocations();                
316         sBrkPtInfo.m_strOrigLoc = m_brkName;                                    
317         sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
318         sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
319         sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
320         sBrkPtInfo.m_strCondition = m_brkPtCondition;
321         sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
322         sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
323         
324         // MI print "^done,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",thread-groups=[\"%s\"],times=\"%d\",original-location=\"%s\"}"
325         CMICmnMIValueTuple miValueTuple;
326         if( !rSessionInfo.MIResponseFormBrkPtInfo( sBrkPtInfo, miValueTuple ) )                         
327         {
328                 return MIstatus::failure;
329         }
330
331         const CMICmnMIValueResult miValueResultD( "bkpt", miValueTuple );
332         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultD );
333         m_miResultRecord = miRecordResult;
334
335         return MIstatus::success;
336 }
337
338 //++ ------------------------------------------------------------------------------------
339 // Details:     Required by the CMICmdFactory when registering *this command. The factory
340 //                      calls this function to create an instance of *this command.
341 // Type:        Static method.
342 // Args:        None.
343 // Return:      CMICmdBase * - Pointer to a new command.
344 // Throws:      None.
345 //--
346 CMICmdBase * CMICmdCmdBreakInsert::CreateSelf( void )
347 {
348         return new CMICmdCmdBreakInsert();
349 }
350
351 //---------------------------------------------------------------------------------------
352 //---------------------------------------------------------------------------------------
353 //---------------------------------------------------------------------------------------
354
355 //++ ------------------------------------------------------------------------------------
356 // Details:     CMICmdCmdBreakDelete constructor.
357 // Type:        Method.
358 // Args:        None.
359 // Return:      None.
360 // Throws:      None.
361 //--
362 CMICmdCmdBreakDelete::CMICmdCmdBreakDelete( void )
363 :       m_constStrArgNamedBrkPt( "breakpoint" )
364 ,       m_constStrArgNamedThreadGrp( "thread-group" )
365 {
366         // Command factory matches this name with that received from the stdin stream
367         m_strMiCmd = "break-delete";
368         
369         // Required by the CMICmdFactory when registering *this command
370         m_pSelfCreatorFn = &CMICmdCmdBreakDelete::CreateSelf;
371 }
372
373 //++ ------------------------------------------------------------------------------------
374 // Details:     CMICmdCmdBreakDelete destructor.
375 // Type:        Overrideable.
376 // Args:        None.
377 // Return:      None.
378 // Throws:      None.
379 //--
380 CMICmdCmdBreakDelete::~CMICmdCmdBreakDelete( void )
381 {
382 }
383
384 //++ ------------------------------------------------------------------------------------
385 // Details:     The invoker requires this function. The parses the command line options 
386 //                      arguments to extract values for each of those arguments.
387 // Type:        Overridden.
388 // Args:        None.
389 // Return:      MIstatus::success - Functional succeeded.
390 //                      MIstatus::failure - Functional failed.
391 // Throws:      None.
392 //--
393 bool CMICmdCmdBreakDelete::ParseArgs( void )
394 {
395         bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
396         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
397         return (bOk && ParseValidateCmdOptions() );
398 }
399
400 //++ ------------------------------------------------------------------------------------
401 // Details:     The invoker requires this function. The command does work in this function.
402 //                      The command is likely to communicate with the LLDB SBDebugger in here.
403 // Type:        Overridden.
404 // Args:        None.
405 // Return:      MIstatus::success - Functional succeeded.
406 //                      MIstatus::failure - Functional failed.
407 // Throws:      None.
408 //--
409 bool CMICmdCmdBreakDelete::Execute( void )
410 {
411         CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
412
413         // ATM we only handle one break point ID
414         MIuint64 nBrk = UINT64_MAX;
415         if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
416         {
417                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
418                 return MIstatus::failure;
419         }
420
421         CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
422         const bool bBrkPt = rSessionInfo.m_lldbTarget.BreakpointDelete( static_cast< lldb::break_id_t >( nBrk ) );
423         if( !bBrkPt )
424         {
425                 const CMIUtilString strBrkNum( CMIUtilString::Format( "%d", nBrk ) );
426                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkNum.c_str() ) );
427                 return MIstatus::failure;
428         }
429
430         return MIstatus::success;
431 }
432
433 //++ ------------------------------------------------------------------------------------
434 // Details:     The invoker requires this function. The command prepares a MI Record Result
435 //                      for the work carried out in the Execute().
436 // Type:        Overridden.
437 // Args:        None.
438 // Return:      MIstatus::success - Functional succeeded.
439 //                      MIstatus::failure - Functional failed.
440 // Throws:      None.
441 //--
442 bool CMICmdCmdBreakDelete::Acknowledge( void )
443 {
444         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
445         m_miResultRecord = miRecordResult;
446
447         return MIstatus::success;
448 }
449
450 //++ ------------------------------------------------------------------------------------
451 // Details:     Required by the CMICmdFactory when registering *this command. The factory
452 //                      calls this function to create an instance of *this command.
453 // Type:        Static method.
454 // Args:        None.
455 // Return:      CMICmdBase * - Pointer to a new command.
456 // Throws:      None.
457 //--
458 CMICmdBase * CMICmdCmdBreakDelete::CreateSelf( void )
459 {
460         return new CMICmdCmdBreakDelete();
461 }
462
463 //---------------------------------------------------------------------------------------
464 //---------------------------------------------------------------------------------------
465 //---------------------------------------------------------------------------------------
466
467 //++ ------------------------------------------------------------------------------------
468 // Details:     CMICmdCmdBreakDisable constructor.
469 // Type:        Method.
470 // Args:        None.
471 // Return:      None.
472 // Throws:      None.
473 //--
474 CMICmdCmdBreakDisable::CMICmdCmdBreakDisable( void )
475 :       m_constStrArgNamedThreadGrp( "thread-group" )
476 ,       m_constStrArgNamedBrkPt( "breakpoint" )
477 ,       m_bBrkPtDisabledOk( false )
478 ,       m_nBrkPtId( 0 )
479 {
480         // Command factory matches this name with that received from the stdin stream
481         m_strMiCmd = "break-disable";
482         
483         // Required by the CMICmdFactory when registering *this command
484         m_pSelfCreatorFn = &CMICmdCmdBreakDisable::CreateSelf;
485 }
486
487 //++ ------------------------------------------------------------------------------------
488 // Details:     CMICmdCmdBreakDisable destructor.
489 // Type:        Overrideable.
490 // Args:        None.
491 // Return:      None.
492 // Throws:      None.
493 //--
494 CMICmdCmdBreakDisable::~CMICmdCmdBreakDisable( void )
495 {
496 }
497
498 //++ ------------------------------------------------------------------------------------
499 // Details:     The invoker requires this function. The parses the command line options 
500 //                      arguments to extract values for each of those arguments.
501 // Type:        Overridden.
502 // Args:        None.
503 // Return:      MIstatus::success - Functional succeeded.
504 //                      MIstatus::failure - Functional failed.
505 // Throws:      None.
506 //--
507 bool CMICmdCmdBreakDisable::ParseArgs( void )
508 {
509         bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
510         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
511         return (bOk && ParseValidateCmdOptions() );
512 }
513
514 //++ ------------------------------------------------------------------------------------
515 // Details:     The invoker requires this function. The command does work in this function.
516 //                      The command is likely to communicate with the LLDB SBDebugger in here.
517 // Type:        Overridden.
518 // Args:        None.
519 // Return:      MIstatus::success - Functional succeeded.
520 //                      MIstatus::failure - Functional failed.
521 // Throws:      None.
522 //--
523 bool CMICmdCmdBreakDisable::Execute( void )
524 {
525         CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
526
527         // ATM we only handle one break point ID
528         MIuint64 nBrk = UINT64_MAX;
529         if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
530         {
531                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
532                 return MIstatus::failure;
533         }
534
535         CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
536         lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) );
537         if( brkPt.IsValid() )
538         {
539                 m_bBrkPtDisabledOk = true;
540                 brkPt.SetEnabled( false );
541                 m_nBrkPtId = nBrk;
542         }
543
544         return MIstatus::success;
545 }
546
547 //++ ------------------------------------------------------------------------------------
548 // Details:     The invoker requires this function. The command prepares a MI Record Result
549 //                      for the work carried out in the Execute().
550 // Type:        Overridden.
551 // Args:        None.
552 // Return:      MIstatus::success - Functional succeeded.
553 //                      MIstatus::failure - Functional failed.
554 // Throws:      None.
555 //--
556 bool CMICmdCmdBreakDisable::Acknowledge( void )
557 {
558         if( m_bBrkPtDisabledOk )
559         {
560                 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) );
561                 const CMICmnMIValueResult miValueResult( "number", miValueConst );
562                 CMICmnMIValueTuple miValueTuple( miValueResult );
563                 const CMICmnMIValueConst miValueConst2( "n" );
564                 const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 );
565                 bool bOk = miValueTuple.Add( miValueResult2 );
566                 const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple );
567                 const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 );
568                 bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() );
569                 
570                 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
571                 m_miResultRecord = miRecordResult;
572                 return bOk;
573         }
574
575         const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
576         const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) );
577         const CMICmnMIValueResult miValueResult( "msg", miValueConst );
578         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
579         m_miResultRecord = miRecordResult;
580
581         return MIstatus::success;
582 }
583
584 //++ ------------------------------------------------------------------------------------
585 // Details:     Required by the CMICmdFactory when registering *this command. The factory
586 //                      calls this function to create an instance of *this command.
587 // Type:        Static method.
588 // Args:        None.
589 // Return:      CMICmdBase * - Pointer to a new command.
590 // Throws:      None.
591 //--
592 CMICmdBase * CMICmdCmdBreakDisable::CreateSelf( void )
593 {
594         return new CMICmdCmdBreakDisable();
595 }
596
597 //---------------------------------------------------------------------------------------
598 //---------------------------------------------------------------------------------------
599 //---------------------------------------------------------------------------------------
600
601 //++ ------------------------------------------------------------------------------------
602 // Details:     CMICmdCmdBreakEnable constructor.
603 // Type:        Method.
604 // Args:        None.
605 // Return:      None.
606 // Throws:      None.
607 //--
608 CMICmdCmdBreakEnable::CMICmdCmdBreakEnable( void )
609 :       m_constStrArgNamedThreadGrp( "thread-group" )
610 ,       m_constStrArgNamedBrkPt( "breakpoint" )
611 ,       m_bBrkPtEnabledOk( false )
612 ,       m_nBrkPtId( 0 )
613 {
614         // Command factory matches this name with that received from the stdin stream
615         m_strMiCmd = "break-enable";
616         
617         // Required by the CMICmdFactory when registering *this command
618         m_pSelfCreatorFn = &CMICmdCmdBreakEnable::CreateSelf;
619 }
620
621 //++ ------------------------------------------------------------------------------------
622 // Details:     CMICmdCmdBreakEnable destructor.
623 // Type:        Overrideable.
624 // Args:        None.
625 // Return:      None.
626 // Throws:      None.
627 //--
628 CMICmdCmdBreakEnable::~CMICmdCmdBreakEnable( void )
629 {
630 }
631
632 //++ ------------------------------------------------------------------------------------
633 // Details:     The invoker requires this function. The parses the command line options 
634 //                      arguments to extract values for each of those arguments.
635 // Type:        Overridden.
636 // Args:        None.
637 // Return:      MIstatus::success - Functional succeeded.
638 //                      MIstatus::failure - Functional failed.
639 // Throws:      None.
640 //--
641 bool CMICmdCmdBreakEnable::ParseArgs( void )
642 {
643         bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
644         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
645         return (bOk && ParseValidateCmdOptions() );
646 }
647
648 //++ ------------------------------------------------------------------------------------
649 // Details:     The invoker requires this function. The command does work in this function.
650 //                      The command is likely to communicate with the LLDB SBDebugger in here.
651 // Type:        Overridden.
652 // Args:        None.
653 // Return:      MIstatus::success - Functional succeeded.
654 //                      MIstatus::failure - Functional failed.
655 // Throws:      None.
656 //--
657 bool CMICmdCmdBreakEnable::Execute( void )
658 {
659         CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
660
661         // ATM we only handle one break point ID
662         MIuint64 nBrk = UINT64_MAX;
663         if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
664         {
665                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
666                 return MIstatus::failure;
667         }
668
669         CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
670         lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) );
671         if( brkPt.IsValid() )
672         {
673                 m_bBrkPtEnabledOk = true;
674                 brkPt.SetEnabled( false );
675                 m_nBrkPtId = nBrk;
676         }
677
678         return MIstatus::success;
679 }
680
681 //++ ------------------------------------------------------------------------------------
682 // Details:     The invoker requires this function. The command prepares a MI Record Result
683 //                      for the work carried out in the Execute().
684 // Type:        Overridden.
685 // Args:        None.
686 // Return:      MIstatus::success - Functional succeeded.
687 //                      MIstatus::failure - Functional failed.
688 // Throws:      None.
689 //--
690 bool CMICmdCmdBreakEnable::Acknowledge( void )
691 {
692         if( m_bBrkPtEnabledOk )
693         {
694                 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) );
695                 const CMICmnMIValueResult miValueResult( "number", miValueConst );
696                 CMICmnMIValueTuple miValueTuple( miValueResult );
697                 const CMICmnMIValueConst miValueConst2( "y" );
698                 const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 );
699                 bool bOk = miValueTuple.Add( miValueResult2 );
700                 const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple );
701                 const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 );
702                 bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() );
703                 
704                 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
705                 m_miResultRecord = miRecordResult;
706                 return bOk;
707         }
708
709         const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
710         const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) );
711         const CMICmnMIValueResult miValueResult( "msg", miValueConst );
712         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
713         m_miResultRecord = miRecordResult;
714
715         return MIstatus::success;
716 }
717
718 //++ ------------------------------------------------------------------------------------
719 // Details:     Required by the CMICmdFactory when registering *this command. The factory
720 //                      calls this function to create an instance of *this command.
721 // Type:        Static method.
722 // Args:        None.
723 // Return:      CMICmdBase * - Pointer to a new command.
724 // Throws:      None.
725 //--
726 CMICmdBase * CMICmdCmdBreakEnable::CreateSelf( void )
727 {
728         return new CMICmdCmdBreakEnable();
729 }
730
731 //---------------------------------------------------------------------------------------
732 //---------------------------------------------------------------------------------------
733 //---------------------------------------------------------------------------------------
734
735 //++ ------------------------------------------------------------------------------------
736 // Details:     CMICmdCmdBreakAfter constructor.
737 // Type:        Method.
738 // Args:        None.
739 // Return:      None.
740 // Throws:      None.
741 //--
742 CMICmdCmdBreakAfter::CMICmdCmdBreakAfter( void )
743 :       m_constStrArgNamedThreadGrp( "thread-group" )
744 ,       m_constStrArgNamedNumber( "number" )
745 ,       m_constStrArgNamedCount( "count" )
746 ,       m_nBrkPtId( 0 )
747 ,       m_nBrkPtCount( 0 )
748 {
749         // Command factory matches this name with that received from the stdin stream
750         m_strMiCmd = "break-after";
751         
752         // Required by the CMICmdFactory when registering *this command
753         m_pSelfCreatorFn = &CMICmdCmdBreakAfter::CreateSelf;
754 }
755
756 //++ ------------------------------------------------------------------------------------
757 // Details:     CMICmdCmdBreakAfter destructor.
758 // Type:        Overrideable.
759 // Args:        None.
760 // Return:      None.
761 // Throws:      None.
762 //--
763 CMICmdCmdBreakAfter::~CMICmdCmdBreakAfter( void )
764 {
765 }
766
767 //++ ------------------------------------------------------------------------------------
768 // Details:     The invoker requires this function. The parses the command line options 
769 //                      arguments to extract values for each of those arguments.
770 // Type:        Overridden.
771 // Args:        None.
772 // Return:      MIstatus::success - Functional succeeded.
773 //                      MIstatus::failure - Functional failed.
774 // Throws:      None.
775 //--
776 bool CMICmdCmdBreakAfter::ParseArgs( void )
777 {
778         bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
779         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedNumber, true, true ) ) );
780         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedCount, true, true ) ) );
781         return (bOk && ParseValidateCmdOptions() );
782 }
783
784 //++ ------------------------------------------------------------------------------------
785 // Details:     The invoker requires this function. The command does work in this function.
786 //                      The command is likely to communicate with the LLDB SBDebugger in here.
787 // Type:        Overridden.
788 // Args:        None.
789 // Return:      MIstatus::success - Functional succeeded.
790 //                      MIstatus::failure - Functional failed.
791 // Throws:      None.
792 //--
793 bool CMICmdCmdBreakAfter::Execute( void )
794 {
795         CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber );
796         CMICMDBASE_GETOPTION( pArgCount, Number, m_constStrArgNamedCount );
797
798         m_nBrkPtId = pArgNumber->GetValue();
799         m_nBrkPtCount = pArgCount->GetValue();
800
801         CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
802         lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) );
803         if( brkPt.IsValid() )
804         {
805                 brkPt.SetIgnoreCount( m_nBrkPtCount );
806
807                 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
808                 if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) )
809                 {
810                         SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) );
811                         return MIstatus::failure;
812                 }
813                 sBrkPtInfo.m_nIgnore = m_nBrkPtCount;
814                 rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo );
815         }
816         else
817         {
818                 const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
819                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) );
820                 return MIstatus::failure;
821         }
822
823         return MIstatus::success;
824 }
825
826 //++ ------------------------------------------------------------------------------------
827 // Details:     The invoker requires this function. The command prepares a MI Record Result
828 //                      for the work carried out in the Execute().
829 // Type:        Overridden.
830 // Args:        None.
831 // Return:      MIstatus::success - Functional succeeded.
832 //                      MIstatus::failure - Functional failed.
833 // Throws:      None.
834 //--
835 bool CMICmdCmdBreakAfter::Acknowledge( void )
836 {
837         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
838         m_miResultRecord = miRecordResult;
839
840         return MIstatus::success;
841 }
842
843 //++ ------------------------------------------------------------------------------------
844 // Details:     Required by the CMICmdFactory when registering *this command. The factory
845 //                      calls this function to create an instance of *this command.
846 // Type:        Static method.
847 // Args:        None.
848 // Return:      CMICmdBase * - Pointer to a new command.
849 // Throws:      None.
850 //--
851 CMICmdBase * CMICmdCmdBreakAfter::CreateSelf( void )
852 {
853         return new CMICmdCmdBreakAfter();
854 }
855
856 //---------------------------------------------------------------------------------------
857 //---------------------------------------------------------------------------------------
858 //---------------------------------------------------------------------------------------
859
860 //++ ------------------------------------------------------------------------------------
861 // Details:     CMICmdCmdBreakCondition constructor.
862 // Type:        Method.
863 // Args:        None.
864 // Return:      None.
865 // Throws:      None.
866 //--
867 CMICmdCmdBreakCondition::CMICmdCmdBreakCondition( void )
868 :       m_constStrArgNamedThreadGrp( "thread-group" )
869 ,       m_constStrArgNamedNumber( "number" )
870 ,       m_constStrArgNamedExpr( "expr" )
871 ,       m_constStrArgNamedExprNoQuotes( "expression not surround by quotes" ) // Not specified in MI spec, we need to handle expressions not surrounded by quotes
872 ,       m_nBrkPtId( 0 )
873 {
874         // Command factory matches this name with that received from the stdin stream
875         m_strMiCmd = "break-condition";
876         
877         // Required by the CMICmdFactory when registering *this command
878         m_pSelfCreatorFn = &CMICmdCmdBreakCondition::CreateSelf;
879 }
880
881 //++ ------------------------------------------------------------------------------------
882 // Details:     CMICmdCmdBreakCondition destructor.
883 // Type:        Overrideable.
884 // Args:        None.
885 // Return:      None.
886 // Throws:      None.
887 //--
888 CMICmdCmdBreakCondition::~CMICmdCmdBreakCondition( void )
889 {
890 }
891
892 //++ ------------------------------------------------------------------------------------
893 // Details:     The invoker requires this function. The parses the command line options 
894 //                      arguments to extract values for each of those arguments.
895 // Type:        Overridden.
896 // Args:        None.
897 // Return:      MIstatus::success - Functional succeeded.
898 //                      MIstatus::failure - Functional failed.
899 // Throws:      None.
900 //--
901 bool CMICmdCmdBreakCondition::ParseArgs( void )
902 {
903         bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
904         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedNumber, true, true ) ) );
905         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedExpr, true, true, true, true ) ) );
906         bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedExprNoQuotes, true, false, CMICmdArgValListBase::eArgValType_StringQuotedNumber ) ) );
907         return (bOk && ParseValidateCmdOptions() );
908 }
909
910 //++ ------------------------------------------------------------------------------------
911 // Details:     The invoker requires this function. The command does work in this function.
912 //                      The command is likely to communicate with the LLDB SBDebugger in here.
913 // Type:        Overridden.
914 // Args:        None.
915 // Return:      MIstatus::success - Functional succeeded.
916 //                      MIstatus::failure - Functional failed.
917 // Throws:      None.
918 //--
919 bool CMICmdCmdBreakCondition::Execute( void )
920 {
921         CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber );
922         CMICMDBASE_GETOPTION( pArgExpr, String, m_constStrArgNamedExpr );                                       
923
924         m_nBrkPtId = pArgNumber->GetValue();
925         m_strBrkPtExpr = pArgExpr->GetValue();
926         m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();
927
928         CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
929         lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) );
930         if( brkPt.IsValid() )
931         {
932                 brkPt.SetCondition( m_strBrkPtExpr.c_str() );
933
934                 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
935                 if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) )
936                 {
937                         SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) );
938                         return MIstatus::failure;
939                 }
940                 sBrkPtInfo.m_strCondition = m_strBrkPtExpr;
941                 rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo );
942         }
943         else
944         {
945                 const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
946                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) );
947                 return MIstatus::failure;
948         }
949
950         return MIstatus::success;
951 }
952
953 //++ ------------------------------------------------------------------------------------
954 // Details:     The invoker requires this function. The command prepares a MI Record Result
955 //                      for the work carried out in the Execute().
956 // Type:        Overridden.
957 // Args:        None.
958 // Return:      MIstatus::success - Functional succeeded.
959 //                      MIstatus::failure - Functional failed.
960 // Throws:      None.
961 //--
962 bool CMICmdCmdBreakCondition::Acknowledge( void )
963 {
964         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
965         m_miResultRecord = miRecordResult;
966
967         return MIstatus::success;
968 }
969
970 //++ ------------------------------------------------------------------------------------
971 // Details:     Required by the CMICmdFactory when registering *this command. The factory
972 //                      calls this function to create an instance of *this command.
973 // Type:        Static method.
974 // Args:        None.
975 // Return:      CMICmdBase * - Pointer to a new command.
976 // Throws:      None.
977 //--
978 CMICmdBase * CMICmdCmdBreakCondition::CreateSelf( void )
979 {
980         return new CMICmdCmdBreakCondition();
981 }
982
983 //++ ------------------------------------------------------------------------------------
984 // Details:     A breakpoint expression can be passed to *this command as:
985 //                              a single string i.e. '2' -> ok.
986 //                              a quoted string i.e. "a > 100" -> ok
987 //                              a non quoted string i.e. 'a > 100' -> not ok 
988 //                      CMICmdArgValString only extracts the first space seperated string, the "a".
989 //                      This function using the optional argument type CMICmdArgValListOfN collects 
990 //                      the rest of the expression so that is may be added to the 'a' part to form a
991 //                      complete expression string i.e. "a > 100".
992 //                      If the expression value was guaranteed to be surrounded by quotes them this 
993 //                      function would not be necessary.
994 // Type:        Method.
995 // Args:        None.
996 // Return:      CMIUtilString - Rest of the breakpoint expression.
997 // Throws:      None.
998 //--
999 CMIUtilString CMICmdCmdBreakCondition::GetRestOfExpressionNotSurroundedInQuotes( void )
1000 {
1001         CMIUtilString strExpression;
1002                 
1003         CMICmdArgValListOfN * pArgExprNoQuotes = CMICmdBase::GetOption< CMICmdArgValListOfN >( m_constStrArgNamedExprNoQuotes );
1004         if( pArgExprNoQuotes != nullptr )
1005         {
1006                 CMIUtilString strExpression;
1007                 const CMICmdArgValListBase::VecArgObjPtr_t & rVecExprParts( pArgExprNoQuotes->GetExpectedOptions() );
1008                 if( !rVecExprParts.empty() )
1009                 {
1010                         CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecExprParts.begin();
1011                         while( it != rVecExprParts.end() )
1012                         {
1013                                 const CMICmdArgValString * pPartExpr = static_cast< CMICmdArgValString * >( *it );
1014                                 const CMIUtilString & rPartExpr = pPartExpr->GetValue();
1015                                 strExpression += " ";
1016                                 strExpression += rPartExpr;
1017
1018                                 // Next
1019                                 ++it;
1020                         }
1021                         strExpression = strExpression.Trim();
1022                 }
1023         }
1024
1025         return strExpression;
1026 }