]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdArgSet.cpp
Merge ^/head r275715 through r275748.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmdArgSet.cpp
1 //===-- MICmdArgSet.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:                MICmdArgSet.cpp
12 //
13 // Overview:    CMICmdArgSet implementation.
14 //
15 // Environment: Compilers:      Visual C++ 12.
16 //                                                      gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
17 //                              Libraries:      See MIReadmetxt. 
18 //
19 // Copyright:   None.
20 //--
21
22 // In-house headers:
23 #include "MICmdArgSet.h"
24 #include "MICmdArgValBase.h"
25 #include "MICmnResources.h"
26 #include "MICmnLog.h"
27
28 //++ ------------------------------------------------------------------------------------
29 // Details:     CMICmdArgSet constructor.
30 // Type:        Method.
31 // Args:        None.
32 // Return:      None.
33 // Throws:      None.
34 //--
35 CMICmdArgSet::CMICmdArgSet( void )
36 :       m_bIsArgsPresentButNotHandledByCmd( false )
37 ,       m_constStrCommaSpc( ", " )
38 {
39 }
40
41 //++ ------------------------------------------------------------------------------------
42 // Details:     CMICmdArgSet destructor.
43 // Type:        Method.
44 // Args:        None.
45 // Return:      None.
46 // Throws:      None.
47 //--
48 CMICmdArgSet::~CMICmdArgSet( void )
49 {
50         // Tidy up
51         Destroy();
52 }
53
54 //++ ------------------------------------------------------------------------------------
55 // Details:     Release resources used by *this container object.
56 // Type:        Method.
57 // Args:        None.
58 // Return:      None.
59 // Throws:      None.
60 //--
61 void CMICmdArgSet::Destroy( void )
62 {
63         // Delete command argument objects
64         if( !m_setCmdArgs.empty() )
65         {
66                 SetCmdArgs_t::iterator it = m_setCmdArgs.begin();
67                 while( it != m_setCmdArgs.end() )
68                 {
69                         CMICmdArgValBase * pArg( *it );
70                         delete pArg;
71                 
72                         // Next
73                         ++it;
74                 }
75                 m_setCmdArgs.clear();
76         }
77
78         m_setCmdArgsThatNotValid.clear();
79         m_setCmdArgsThatAreMissing.clear();
80         m_setCmdArgsNotHandledByCmd.clear();
81         m_setCmdArgsMissingInfo.clear();
82         m_bIsArgsPresentButNotHandledByCmd = false;
83 }
84
85 //++ ------------------------------------------------------------------------------------
86 // Details:     Retrieve the state flag indicating that the command set up ready to parse
87 //                      command arguments or options found that one or more arguments was indeed
88 //                      present but not handled. This is given as a warning in the MI log file.
89 // Type:        Method.
90 // Args:        None.
91 // Return:      bool - True = one or more args not handled, false = all args handled
92 // Throws:      None.
93 //--
94 bool CMICmdArgSet::IsArgsPresentButNotHandledByCmd( void ) const
95 {
96         return m_bIsArgsPresentButNotHandledByCmd;
97 }
98         
99 //++ ------------------------------------------------------------------------------------
100 // Details:     Add the list of command's arguments to parse and validate another one.
101 // Type:        Method.
102 // Args:        vArg    - (R) A command argument object.
103 // Return:      MIstatus::success - Functional succeeded.
104 //                      MIstatus::failure - Functional failed.
105 // Throws:      None.
106 //--
107 bool CMICmdArgSet::Add( const CMICmdArgValBase & vArg )
108 {
109         CMICmdArgValBase * pArg = const_cast< CMICmdArgValBase * >( &vArg );
110         m_setCmdArgs.push_back( pArg );
111
112         return MIstatus::success;
113 }
114
115 //++ ------------------------------------------------------------------------------------
116 // Details:     After validating an options line of text (the context) and there is a failure,
117 //                      it is likely a mandatory command argument that is required is missing. This 
118 //                      function returns the argument that should be present.
119 // Type:        Method.
120 // Args:        None.
121 // Return:      SetCmdArgs_t & - Set of argument objects.
122 // Throws:      None.
123 //--
124 const CMICmdArgSet::SetCmdArgs_t &      CMICmdArgSet::GetArgsThatAreMissing( void ) const
125 {
126         return m_setCmdArgsThatAreMissing;
127 }
128
129 //++ ------------------------------------------------------------------------------------
130 // Details:     After validating an options line of text (the context) and there is a failure,
131 //                      it may be because one or more arguments were unable to extract a value. This 
132 //                      function returns the argument that were found to be invalid.
133 // Type:        Method.
134 // Args:        None.
135 // Return:      SetCmdArgs_t & - Set of argument objects.
136 // Throws:      None.
137 //--
138 const CMICmdArgSet::SetCmdArgs_t &      CMICmdArgSet::GetArgsThatInvalid( void ) const
139 {
140         return m_setCmdArgsThatNotValid;
141 }       
142
143 //++ ------------------------------------------------------------------------------------
144 // Details:     The list of argument or option (objects) that were specified by the command
145 //                      and so recognised when parsed but were not handled. Ideally the command
146 //                      should handle all arguments and options presented to it. The command sends
147 //                      warning to the MI log file to say that these options were not handled.
148 //                      Used as one way to determine option that maybe should really be implemented
149 //                      and not just ignored.
150 // Type:        Method.
151 // Args:        None.
152 // Return:      SetCmdArgs_t & - Set of argument objects.
153 // Throws:      None.
154 //--
155 const CMICmdArgSet::SetCmdArgs_t &      CMICmdArgSet::GetArgsNotHandledByCmd( void ) const
156 {
157         return m_setCmdArgsNotHandledByCmd;
158 }
159
160 //++ ------------------------------------------------------------------------------------
161 // Details:     Given a set of command argument objects parse the context option string to
162 //                      find those argument and retrieve their value. If the function fails call
163 //                      GetArgsThatAreMissing() to see which commands that were mandatory were 
164 //                      missing or failed to parse.
165 // Type:        Method.
166 // Args:        vStrMiCmd               - (R)  Command's name.
167 //                      vCmdArgsText    - (RW) A command's options or argument.
168 // Return:      MIstatus::success - Functional succeeded.
169 //                      MIstatus::failure - Functional failed.
170 // Throws:      None.
171 //--
172 bool CMICmdArgSet::Validate( const CMIUtilString & vStrMiCmd, CMICmdArgContext & vwCmdArgsText )
173 {
174         m_cmdArgContext = vwCmdArgsText;
175
176         // Iterate all the arguments or options required by a command
177         const MIuint nArgs = vwCmdArgsText.GetNumberArgsPresent();
178         MIuint nArgsMandatoryCnt = 0;
179         SetCmdArgs_t::const_iterator it = m_setCmdArgs.begin();
180         while( it != m_setCmdArgs.end() )
181         {
182                 const CMICmdArgValBase * pArg( *it );
183                 const CMIUtilString & rArgName( pArg->GetName() ); MIunused( rArgName );
184                 if( pArg->GetIsMandatory() )
185                         nArgsMandatoryCnt++;
186                 if( !const_cast< CMICmdArgValBase * >( pArg )->Validate( vwCmdArgsText ) )
187                 {
188                         if( pArg->GetIsMandatory() && !pArg->GetFound() )
189                                 m_setCmdArgsThatAreMissing.push_back( const_cast< CMICmdArgValBase * >( pArg ) );
190                         else if( pArg->GetFound() ) 
191                         {
192                                 if( pArg->GetIsMissingOptions() )
193                                         m_setCmdArgsMissingInfo.push_back( const_cast< CMICmdArgValBase * >( pArg ) );
194                                 else if( !pArg->GetValid() )
195                                         m_setCmdArgsThatNotValid.push_back( const_cast< CMICmdArgValBase * >( pArg ) );
196                         }
197                 }
198                 if( pArg->GetFound() && !pArg->GetIsHandledByCmd() )
199                 {
200                         m_bIsArgsPresentButNotHandledByCmd = true;
201                         m_setCmdArgsNotHandledByCmd.push_back( const_cast< CMICmdArgValBase * >( pArg ) );
202                 }
203
204                 // Next
205                 ++it;
206         }
207
208         // Check that one or more argument objects have any issues to report...
209
210         if( nArgs < nArgsMandatoryCnt )
211         {
212                 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_N_OPTIONS_REQUIRED ), nArgsMandatoryCnt ) );
213                 return MIstatus::failure;
214         }
215         
216         if( IsArgsPresentButNotHandledByCmd() )
217                 WarningArgsNotHandledbyCmdLogFile( vStrMiCmd );
218
219         return ValidationFormErrorMessages( vwCmdArgsText );
220 }
221
222 //++ ------------------------------------------------------------------------------------
223 // Details:     Having validated the command's options text and failed for some reason form
224 //                      the error message made up with the faults found.
225 // Type:        Method.
226 //                      vCmdArgsText    - (RW) A command's options or argument.
227 // Return:      MIstatus::success - Functional succeeded.
228 //                      MIstatus::failure - Functional failed.
229 // Throws:      None.
230 //--
231 bool CMICmdArgSet::ValidationFormErrorMessages( const CMICmdArgContext & vwCmdArgsText )
232 {
233         CMIUtilString strListMissing;
234         CMIUtilString strListInvalid;
235         CMIUtilString strListMissingInfo;
236         const bool bArgsMissing = (m_setCmdArgsThatAreMissing.size() > 0);
237         const bool bArgsInvalid = (m_setCmdArgsThatNotValid.size() > 0);
238         const bool bArgsMissingInfo = (m_setCmdArgsMissingInfo.size() > 0);
239         if( !(bArgsMissing || bArgsInvalid || bArgsMissingInfo) )
240                 return MIstatus::success;
241         if( bArgsMissing )
242         {
243                 MIuint i = 0;
244                 SetCmdArgs_t::const_iterator it = m_setCmdArgsThatAreMissing.begin();
245                 while( it != m_setCmdArgsThatAreMissing.end() )
246                 {
247                         if( i++ > 0 )
248                                 strListMissing += m_constStrCommaSpc;
249
250                         const CMICmdArgValBase * pArg( *it );
251                         strListMissing += pArg->GetName();
252
253                         // Next
254                         ++it;
255                 }
256         }
257         if( bArgsInvalid )
258         {
259                 MIuint i = 0;
260                 SetCmdArgs_t::const_iterator it = m_setCmdArgsThatNotValid.begin();
261                 while( it != m_setCmdArgsThatNotValid.end() )
262                 {
263                         if( i++ > 0 )
264                                 strListMissing += m_constStrCommaSpc;
265
266                         const CMICmdArgValBase * pArg( *it );
267                         strListInvalid += pArg->GetName();
268
269                         // Next
270                         ++it;
271                 }
272         }
273         if( bArgsMissingInfo )
274         {
275                 MIuint i = 0;
276                 SetCmdArgs_t::const_iterator it = m_setCmdArgsMissingInfo.begin();
277                 while( it != m_setCmdArgsMissingInfo.end() )
278                 {
279                         if( i++ > 0 )
280                                 strListMissingInfo += m_constStrCommaSpc;
281
282                         const CMICmdArgValBase * pArg( *it );
283                         strListMissingInfo += pArg->GetName();
284
285                         // Next
286                         ++it;
287                 }
288         }
289
290         bool bHaveOneError = false;
291         CMIUtilString strError = MIRSRC( IDS_CMD_ARGS_ERR_PREFIX_MSG );
292         if( bArgsMissing && bArgsInvalid )
293         {
294                 bHaveOneError = true;
295                 strError += CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_MAN_INVALID ), strListMissing.c_str(), strListInvalid.c_str() );
296         }
297         if( bArgsMissing )
298         {
299                 if( bHaveOneError )
300                         strError += ". ";
301                 bHaveOneError = true;
302                 strError += CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_MANDATORY ), strListMissing.c_str() );
303         }
304         if( bArgsMissingInfo )
305         {
306                 if( bHaveOneError )
307                         strError += ". ";
308                 bHaveOneError = true;
309                 strError += CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_MISSING_INF ), strListMissingInfo.c_str() );
310         }
311         if( bArgsInvalid )
312         {
313                 if( bHaveOneError )
314                         strError += ". ";
315                 bHaveOneError = true;
316                 strError += CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_INVALID ), strListInvalid.c_str() );
317         }
318         if( !vwCmdArgsText.IsEmpty() )
319         {
320                 if( bHaveOneError )
321                         strError += ". ";
322                 bHaveOneError = true;
323                 strError += CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_CONTEXT_NOT_ALL_EATTEN ), vwCmdArgsText.GetArgsLeftToParse().c_str() );
324         }
325
326         if( bHaveOneError )
327         {
328                 SetErrorDescription( strError );
329                 return MIstatus::failure;
330         }
331
332         return MIstatus::success;
333 }
334
335 //++ ------------------------------------------------------------------------------------
336 // Details:     Ask if the command's argument options text had any arguments.
337 // Type:        Method.
338 // Args:        None.
339 // Return:      bool    - True = Has one or more arguments present, false = no arguments.
340 // Throws:      None.
341 //--
342 bool CMICmdArgSet::IsArgContextEmpty( void ) const
343 {
344         return m_cmdArgContext.IsEmpty();
345 }
346
347 //++ ------------------------------------------------------------------------------------
348 // Details:     Retrieve the number of arguments that are being used for the command.
349 // Type:        Method.
350 // Args:        None.
351 // Return:      MIuint - Argument count.
352 // Throws:      None.
353 //--
354 MIuint CMICmdArgSet::GetCount( void ) const
355 {
356         return m_setCmdArgs.size();
357 }
358         
359 //++ ------------------------------------------------------------------------------------
360 // Details:     Given a set of command argument objects retrieve the argument with the 
361 //                      specified name.
362 // Type:        Method.
363 // Args:        vpArg   - (W) A pointer to a command's argument object.
364 // Return:      True - Argument found.
365 //                      False - Argument not found.
366 // Throws:      None.
367 //--
368 bool CMICmdArgSet::GetArg( const CMIUtilString & vArgName, CMICmdArgValBase *& vpArg ) const
369 {
370         bool bFound = false;
371         SetCmdArgs_t::const_iterator it = m_setCmdArgs.begin();
372         while( it != m_setCmdArgs.end() )
373         {
374                 CMICmdArgValBase * pArg( *it );
375                 if( pArg->GetName() == vArgName )
376                 {
377                         bFound = true;
378                         vpArg = pArg;
379                         break;
380                 }
381                 
382                 // Next
383                 ++it;
384         }
385
386         return bFound;
387 }
388         
389 //++ ------------------------------------------------------------------------------------
390 // Details:     Write a warning message to the MI Log file about the command's arguments or 
391 //                      options that were found present but not handled.
392 // Type:        Method.
393 // Args:        vrCmdName       - (R) The command's name.
394 // Return:      None.
395 // Throws:      None.
396 //--
397 void CMICmdArgSet::WarningArgsNotHandledbyCmdLogFile( const CMIUtilString & vrCmdName )
398 {
399 #if MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED
400
401         CMIUtilString strArgsNotHandled;
402         const CMICmdArgSet::SetCmdArgs_t & rSetArgs = GetArgsNotHandledByCmd();
403         MIuint nCnt = 0;  
404         CMICmdArgSet::SetCmdArgs_t::const_iterator it = rSetArgs.begin();
405         while( it != rSetArgs.end() )
406         {
407                 if( nCnt++ > 0 )
408                         strArgsNotHandled += m_constStrCommaSpc;
409                 const CMICmdArgValBase * pArg = *it;
410                 strArgsNotHandled += pArg->GetName();
411
412                 // Next
413                 ++it;
414         }
415
416         const CMIUtilString strWarningMsg( CMIUtilString::Format( MIRSRC( IDS_CMD_WRN_ARGS_NOT_HANDLED ), vrCmdName.c_str(), strArgsNotHandled.c_str() ) );
417         m_pLog->WriteLog( strWarningMsg );
418
419 #endif // MICONFIG_GIVE_WARNING_CMD_ARGS_NOT_HANDLED
420 }