]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmnLogMediumFile.cpp
Merge llvm 3.6.0rc2 from ^/vendor/llvm/dist, merge clang 3.6.0rc2 from
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / tools / lldb-mi / MICmnLogMediumFile.cpp
1 //===-- MICmnLogMediumFile.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:                MICmnLogMediumFile.cpp
12 //
13 // Overview:    CMICmnLogMediumFile 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 "MICmnLogMediumFile.h"
24 #include "MICmnResources.h"
25 #if defined( _MSC_VER )
26         #include "MIUtilSystemWindows.h"
27 #elif defined( __FreeBSD__ ) || defined( __linux__ )
28         #include "MIUtilSystemLinux.h"
29 #elif defined( __APPLE__ )
30         #include "MIUtilSystemOsx.h"
31 #endif // defined( _MSC_VER )
32
33 //++ ------------------------------------------------------------------------------------
34 // Details:     CMICmnLogMediumFile constructor.
35 // Type:        Method.
36 // Args:        None.
37 // Return:      None.
38 // Throws:      None.
39 //--
40 CMICmnLogMediumFile::CMICmnLogMediumFile( void )
41 :       m_constThisMediumName( MIRSRC( IDS_MEDIUMFILE_NAME ) )
42 ,       m_constMediumFileName( "lldb-mi-log.txt" )
43 ,       m_fileNamePath( MIRSRC( IDS_MEDIUMFILE_ERR_INVALID_PATH ) )
44 ,       m_eVerbosityType( CMICmnLog::eLogVerbosity_Log )
45 ,       m_strDate( CMIUtilDateTimeStd().GetDate() )
46 ,       m_fileHeaderTxt( MIRSRC( IDS_MEDIUMFILE_ERR_FILE_HEADER ) )
47 {
48 }
49
50 //++ ------------------------------------------------------------------------------------
51 // Details:     CMICmnLogMediumFile destructor.
52 // Type:        Overridden.
53 // Args:        None.
54 // Return:      None.
55 // Throws:      None.
56 //--
57 CMICmnLogMediumFile::~CMICmnLogMediumFile( void )
58 {
59 }
60
61 //++ ------------------------------------------------------------------------------------
62 // Details:     Get the singleton instance of *this class.
63 // Type:        Static.
64 // Args:        None.
65 // Return:      CMICmnLogMediumFile - Reference to *this object.
66 // Throws:      None.
67 //--
68 CMICmnLogMediumFile & CMICmnLogMediumFile::Instance( void )
69 {
70         static CMICmnLogMediumFile instance;
71
72         return instance;
73 }
74
75 //++ ------------------------------------------------------------------------------------
76 // Details:     Initialize setup *this medium ready for use.
77 // Type:        Overridden.
78 // Args:        None.
79 // Return:      MIstatus::success - Functional succeeded.
80 //                      MIstatus::failure - Functional failed.
81 // Throws:      None.
82 //--
83 bool CMICmnLogMediumFile::Initialize( void )
84 {
85         m_bInitialized = FileFormFileNamePath();
86         
87         return m_bInitialized;
88 }
89
90 //++ ------------------------------------------------------------------------------------
91 // Details:     Unbind detach or release resources used by *this medium.
92 // Type:        Method.
93 // Args:        None.
94 // Return:      None.
95 // Throws:      None.
96 //--
97 bool CMICmnLogMediumFile::Shutdown( void )
98 {
99         if( m_bInitialized )
100         {
101                 m_bInitialized = false;
102                 m_file.Close();
103         }
104         return MIstatus::success;
105 }
106
107 //++ ------------------------------------------------------------------------------------
108 // Details:     Retrieve the name of *this medium.
109 // Type:        Overridden.
110 // Args:        None.
111 // Return:      CMIUtilString - Text data.
112 // Throws:      None.
113 //--
114 const CMIUtilString & CMICmnLogMediumFile::GetName( void ) const
115 {
116         return m_constThisMediumName;
117 }
118
119 //++ ------------------------------------------------------------------------------------
120 // Details:     The callee client calls the write function on the Logger. The data to be
121 //                      written is given out to all the mediums registered. The verbosity type parameter 
122 //                      indicates to the medium the type of data or message given to it. The medium has
123 //                      modes of verbosity and depending on the verbosity set determines which data is
124 //                      sent to the medium's output.
125 // Type:        Method.
126 // Args:        vData           - (R) The data to write to the logger.
127 //                      veType          - (R) Verbosity type.
128 // Return:      MIstatus::success - Functional succeeded.
129 //                      MIstatus::failure - Functional failed.
130 // Throws:      None.
131 //--
132 bool CMICmnLogMediumFile::Write( const CMIUtilString & vData, const CMICmnLog::ELogVerbosity veType )
133 {
134         if( m_bInitialized && m_file.IsOk() )
135         {
136                 const bool bDoWrite = (m_eVerbosityType & veType);
137                 if( bDoWrite )
138                 {
139                         bool bNewCreated = false;
140                         bool bOk = m_file.CreateWrite( m_fileNamePath, bNewCreated );
141                         if( bOk )
142                         {
143                                 if( bNewCreated )
144                                         bOk = FileWriteHeader();
145                                 bOk = bOk && FileWriteEnglish( MassagedData( vData, veType ) );
146                         }
147                         return bOk;
148                 }
149         }
150         
151         return MIstatus::failure;
152 }
153
154 //++ ------------------------------------------------------------------------------------
155 // Details:     Retrieve *this medium's last error condition.
156 // Type:        Method.
157 // Args:        None.
158 // Return:      CString & -  Text description.
159 // Throws:      None.
160 //--
161 const CMIUtilString & CMICmnLogMediumFile::GetError( void ) const
162 {
163         return m_strMILastErrorDescription;
164 }
165
166 //++ ------------------------------------------------------------------------------------
167 // Details:     Set the verbosity mode for this medium.
168 // Type:        Method.
169 // Args:        veType  - (R) Mask value.
170 // Return:      MIstatus::success - Functional succeeded.
171 //                      MIstatus::failure - Functional failed.
172 // Throws:      None.
173 //--
174 bool CMICmnLogMediumFile::SetVerbosity( const MIuint veType )
175 {
176         m_eVerbosityType = veType;
177         return MIstatus::success;
178 }
179
180 //++ ------------------------------------------------------------------------------------
181 // Details:     Get the verbosity mode for this medium.
182 // Type:        Method.
183 // Args:        veType  - (R) Mask value.
184 // Return:      CMICmnLog::ELogVerbosity - Mask value.
185 // Throws:      None.
186 //--
187 MIuint CMICmnLogMediumFile::GetVerbosity( void ) const
188 {
189         return m_eVerbosityType;
190 }
191
192 //++ ------------------------------------------------------------------------------------
193 // Details:     Write data to a file English font.
194 // Type:        Method.
195 // Args:        vData   - (R) The data to write to the logger.
196 // Return:      None.
197 // Throws:      None.
198 //--
199 bool CMICmnLogMediumFile::FileWriteEnglish( const CMIUtilString & vData )
200 {
201         return m_file.Write( vData );
202 }
203
204 //++ ------------------------------------------------------------------------------------
205 // Details:     Determine and form the medium file's directory path and name.
206 // Type:        Method.
207 // Args:        None.
208 // Return:      MIstatus::success - Functional succeeded.
209 //                      MIstatus::failure - Functional failed.
210 // Throws:      None.
211 //--
212 bool CMICmnLogMediumFile::FileFormFileNamePath( void )
213 {
214         ClrErrorDescription();
215
216         m_fileNamePath = MIRSRC( IDS_MEDIUMFILE_ERR_INVALID_PATH );
217
218         CMIUtilString strPathName;
219         if( CMIUtilSystem().GetLogFilesPath( strPathName ) )
220         {
221                 const CMIUtilString strPath = CMIUtilFileStd().StripOffFileName( strPathName );
222
223                 // ToDo: Review this LINUX log file quick fix so not hidden
224         // AD: 
225         //      Linux was creating a log file here called '.\log.txt'.  The '.' on linux
226         //      signifies that this file is 'hidden' and not normally visible.  A quick fix
227         //      is to remove the path component all together.  Linux also normally uses '/'
228         //      as directory separators, again leading to the problem of the hidden log.
229 #if defined ( _MSC_VER )
230         m_fileNamePath = CMIUtilString::Format( "%s\\%s", strPath.c_str(), m_constMediumFileName.c_str() );
231 #else
232         m_fileNamePath = CMIUtilString::Format( "%s", m_constMediumFileName.c_str() );
233 #endif // defined ( _MSC_VER )
234
235                 return MIstatus::success;
236         }
237
238         SetErrorDescription( MIRSRC( IDE_MEDIUMFILE_ERR_GET_FILE_PATHNAME_SYS ) );
239         
240         return MIstatus::failure;
241 }
242
243 //++ ------------------------------------------------------------------------------------
244 // Details:     Retrieve the medium file's directory path and name.
245 // Type:        Method.
246 // Args:        None.
247 // Return:      CMIUtilString & - File path.
248 // Throws:      None.
249 //--
250 const CMIUtilString & CMICmnLogMediumFile::GetFileNamePath( void ) const
251 {
252         return m_fileNamePath;
253 }
254
255 //++ ------------------------------------------------------------------------------------
256 // Details:     Retrieve the medium file's name.
257 // Type:        Method.
258 // Args:        None.
259 // Return:      CMIUtilString & - File name.
260 // Throws:      None.
261 //--
262 const CMIUtilString & CMICmnLogMediumFile::GetFileName( void ) const
263 {
264         return m_constMediumFileName;
265 }
266
267 //++ ------------------------------------------------------------------------------------
268 // Details:     Massage the data to behave correct when submitted to file. Insert extra log
269 //                      specific text. The veType is there to allow in the future to parse the log and
270 //                      filter in out specific types of message to make viewing the log more manageable.
271 // Type:        Method.
272 // Args:        vData   - (R) Raw data.
273 //                      veType  - (R) Message type.
274 // Return:      CMIUtilString - Massaged data.
275 // Throws:      None.
276 //--
277 CMIUtilString CMICmnLogMediumFile::MassagedData( const CMIUtilString & vData, const CMICmnLog::ELogVerbosity veType )
278 {
279         const CMIUtilString strCr( "\n" );
280         CMIUtilString data;
281         const MIchar verbosityCode( ConvertLogVerbosityTypeToId( veType ) );
282         const CMIUtilString dt( CMIUtilString::Format( "%s %s", m_strDate.c_str(), m_dateTime.GetTime().c_str() ) );
283         
284         data = CMIUtilString::Format( "%c,%s,%s", verbosityCode, dt.c_str(), vData.c_str() );
285         data = ConvertCr( data );
286
287         // Look for EOL...
288         const MIint pos = vData.rfind( strCr );
289         if( pos == (MIint) vData.size() )
290                 return data;
291         
292         // ... did not have an EOL so add one
293         data += GetLineReturn();
294         
295         return data;
296 }
297
298 //++ ------------------------------------------------------------------------------------
299 // Details:     Convert the Log's verbosity type number into a single char character.
300 // Type:        Method.
301 // Args:        veType  - (R) Message type.
302 // Return:      wchar_t - A letter.
303 // Throws:      None.
304 //--
305 MIchar CMICmnLogMediumFile::ConvertLogVerbosityTypeToId( const CMICmnLog::ELogVerbosity veType ) const
306 {
307         MIchar c = 0;
308         if( veType != 0 )
309         {
310                 MIuint cnt = 0;
311                 MIuint number( veType );
312                 while( 1 != number )
313                 {
314                         number = number >> 1;
315                         ++cnt;
316                 }
317                 c = 'A' + cnt;
318         }
319         else
320         {
321                 c = '*';
322         }
323
324         return c;
325 }
326
327 //++ ------------------------------------------------------------------------------------
328 // Details:     Retrieve state of whether the file medium is ok.
329 // Type:        Method.
330 // Args:        None.
331 // Return:      True - file ok.
332 //                      False - file has a problem.
333 // Throws:      None.
334 //--
335 bool CMICmnLogMediumFile::IsOk( void ) const
336 {
337         return m_file.IsOk();
338 }
339
340 //++ ------------------------------------------------------------------------------------
341 // Details:     Status on the file log medium existing already.
342 // Type:        Method.
343 // Args:        None.
344 // Return:      True - Exists.
345 //                      False - Not found.
346 // Throws:      None.
347 //--
348 bool CMICmnLogMediumFile::IsFileExist( void ) const
349 {
350         return m_file.IsFileExist( GetFileNamePath() );
351 }
352
353 //++ ------------------------------------------------------------------------------------
354 // Details:     Write the header text the logger file.
355 // Type:        Method.
356 // Args:        vText   - (R) Text.
357 // Return:      MIstatus::success - Functional succeeded.
358 //                      MIstatus::failure - Functional failed.
359 // Throws:      None.
360 //--
361 bool CMICmnLogMediumFile::FileWriteHeader( void )
362 {
363         return FileWriteEnglish( ConvertCr( m_fileHeaderTxt ) );
364 }
365
366 //++ ------------------------------------------------------------------------------------
367 // Details:     Convert any carriage line returns to be compatible with the platform the
368 //                      Log fiel is being written to.
369 // Type:        Method.
370 // Args:        vData   - (R) Text data.
371 // Return:      CMIUtilString - Converted string data.
372 // Throws:      None.
373 //--
374 CMIUtilString CMICmnLogMediumFile::ConvertCr( const CMIUtilString & vData ) const
375 {
376         const CMIUtilString strCr( "\n" );
377         const CMIUtilString & rCrCmpat( GetLineReturn() );
378
379         if( strCr == rCrCmpat )
380                 return vData;
381
382         const MIuint nSizeCmpat( rCrCmpat.size() );
383         const MIuint nSize( strCr.size() );
384         CMIUtilString strConv( vData );
385         MIint pos = strConv.find( strCr );
386         while( pos != (MIint) CMIUtilString::npos )
387         {
388                 strConv.replace( pos, nSize, rCrCmpat );
389                 pos = strConv.find( strCr, pos + nSizeCmpat );
390         }
391
392         return strConv;
393 }
394
395 //++ ------------------------------------------------------------------------------------
396 // Details:     Set the header text that is written to the logger file at the begining.
397 // Type:        Method.
398 // Args:        vText   - (R) Text.
399 // Return:      MIstatus::success - Functional succeeded.
400 //                      MIstatus::failure - Functional failed.
401 // Throws:      None.
402 //--
403 bool CMICmnLogMediumFile::SetHeaderTxt( const CMIUtilString & vText )
404 {
405         m_fileHeaderTxt = vText;
406
407         return MIstatus::success;
408 }
409
410 //++ ------------------------------------------------------------------------------------
411 // Details:     Retrieve the file current carriage line return characters used.
412 // Type:        Method.
413 // Args:        None.
414 // Return:      CMIUtilString & - Text.
415 // Throws:      None.
416 //--
417 const CMIUtilString & CMICmnLogMediumFile::GetLineReturn( void ) const
418 {
419         return m_file.GetLineReturn();
420 }