1 //===-- MICmnLogMediumFile.cpp ----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 // File: MICmnLogMediumFile.cpp
13 // Overview: CMICmnLogMediumFile implementation.
15 // Environment: Compilers: Visual C++ 12.
16 // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
17 // Libraries: See MIReadmetxt.
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 )
33 //++ ------------------------------------------------------------------------------------
34 // Details: CMICmnLogMediumFile constructor.
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 ) )
50 //++ ------------------------------------------------------------------------------------
51 // Details: CMICmnLogMediumFile destructor.
57 CMICmnLogMediumFile::~CMICmnLogMediumFile( void )
61 //++ ------------------------------------------------------------------------------------
62 // Details: Get the singleton instance of *this class.
65 // Return: CMICmnLogMediumFile - Reference to *this object.
68 CMICmnLogMediumFile & CMICmnLogMediumFile::Instance( void )
70 static CMICmnLogMediumFile instance;
75 //++ ------------------------------------------------------------------------------------
76 // Details: Initialize setup *this medium ready for use.
79 // Return: MIstatus::success - Functional succeeded.
80 // MIstatus::failure - Functional failed.
83 bool CMICmnLogMediumFile::Initialize( void )
85 m_bInitialized = FileFormFileNamePath();
87 return m_bInitialized;
90 //++ ------------------------------------------------------------------------------------
91 // Details: Unbind detach or release resources used by *this medium.
97 bool CMICmnLogMediumFile::Shutdown( void )
101 m_bInitialized = false;
104 return MIstatus::success;
107 //++ ------------------------------------------------------------------------------------
108 // Details: Retrieve the name of *this medium.
111 // Return: CMIUtilString - Text data.
114 const CMIUtilString & CMICmnLogMediumFile::GetName( void ) const
116 return m_constThisMediumName;
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.
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.
132 bool CMICmnLogMediumFile::Write( const CMIUtilString & vData, const CMICmnLog::ELogVerbosity veType )
134 if( m_bInitialized && m_file.IsOk() )
136 const bool bDoWrite = (m_eVerbosityType & veType);
139 bool bNewCreated = false;
140 bool bOk = m_file.CreateWrite( m_fileNamePath, bNewCreated );
144 bOk = FileWriteHeader();
145 bOk = bOk && FileWriteEnglish( MassagedData( vData, veType ) );
151 return MIstatus::failure;
154 //++ ------------------------------------------------------------------------------------
155 // Details: Retrieve *this medium's last error condition.
158 // Return: CString & - Text description.
161 const CMIUtilString & CMICmnLogMediumFile::GetError( void ) const
163 return m_strMILastErrorDescription;
166 //++ ------------------------------------------------------------------------------------
167 // Details: Set the verbosity mode for this medium.
169 // Args: veType - (R) Mask value.
170 // Return: MIstatus::success - Functional succeeded.
171 // MIstatus::failure - Functional failed.
174 bool CMICmnLogMediumFile::SetVerbosity( const MIuint veType )
176 m_eVerbosityType = veType;
177 return MIstatus::success;
180 //++ ------------------------------------------------------------------------------------
181 // Details: Get the verbosity mode for this medium.
183 // Args: veType - (R) Mask value.
184 // Return: CMICmnLog::ELogVerbosity - Mask value.
187 MIuint CMICmnLogMediumFile::GetVerbosity( void ) const
189 return m_eVerbosityType;
192 //++ ------------------------------------------------------------------------------------
193 // Details: Write data to a file English font.
195 // Args: vData - (R) The data to write to the logger.
199 bool CMICmnLogMediumFile::FileWriteEnglish( const CMIUtilString & vData )
201 return m_file.Write( vData );
204 //++ ------------------------------------------------------------------------------------
205 // Details: Determine and form the medium file's directory path and name.
208 // Return: MIstatus::success - Functional succeeded.
209 // MIstatus::failure - Functional failed.
212 bool CMICmnLogMediumFile::FileFormFileNamePath( void )
214 ClrErrorDescription();
216 m_fileNamePath = MIRSRC( IDS_MEDIUMFILE_ERR_INVALID_PATH );
218 CMIUtilString strPathName;
219 if( CMIUtilSystem().GetLogFilesPath( strPathName ) )
221 const CMIUtilString strPath = CMIUtilFileStd().StripOffFileName( strPathName );
223 // ToDo: Review this LINUX log file quick fix so not hidden
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() );
232 m_fileNamePath = CMIUtilString::Format( "%s", m_constMediumFileName.c_str() );
233 #endif // defined ( _MSC_VER )
235 return MIstatus::success;
238 SetErrorDescription( MIRSRC( IDE_MEDIUMFILE_ERR_GET_FILE_PATHNAME_SYS ) );
240 return MIstatus::failure;
243 //++ ------------------------------------------------------------------------------------
244 // Details: Retrieve the medium file's directory path and name.
247 // Return: CMIUtilString & - File path.
250 const CMIUtilString & CMICmnLogMediumFile::GetFileNamePath( void ) const
252 return m_fileNamePath;
255 //++ ------------------------------------------------------------------------------------
256 // Details: Retrieve the medium file's name.
259 // Return: CMIUtilString & - File name.
262 const CMIUtilString & CMICmnLogMediumFile::GetFileName( void ) const
264 return m_constMediumFileName;
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.
272 // Args: vData - (R) Raw data.
273 // veType - (R) Message type.
274 // Return: CMIUtilString - Massaged data.
277 CMIUtilString CMICmnLogMediumFile::MassagedData( const CMIUtilString & vData, const CMICmnLog::ELogVerbosity veType )
279 const CMIUtilString strCr( "\n" );
281 const MIchar verbosityCode( ConvertLogVerbosityTypeToId( veType ) );
282 const CMIUtilString dt( CMIUtilString::Format( "%s %s", m_strDate.c_str(), m_dateTime.GetTime().c_str() ) );
284 data = CMIUtilString::Format( "%c,%s,%s", verbosityCode, dt.c_str(), vData.c_str() );
285 data = ConvertCr( data );
288 const MIint pos = vData.rfind( strCr );
289 if( pos == (MIint) vData.size() )
292 // ... did not have an EOL so add one
293 data += GetLineReturn();
298 //++ ------------------------------------------------------------------------------------
299 // Details: Convert the Log's verbosity type number into a single char character.
301 // Args: veType - (R) Message type.
302 // Return: wchar_t - A letter.
305 MIchar CMICmnLogMediumFile::ConvertLogVerbosityTypeToId( const CMICmnLog::ELogVerbosity veType ) const
311 MIuint number( veType );
314 number = number >> 1;
327 //++ ------------------------------------------------------------------------------------
328 // Details: Retrieve state of whether the file medium is ok.
331 // Return: True - file ok.
332 // False - file has a problem.
335 bool CMICmnLogMediumFile::IsOk( void ) const
337 return m_file.IsOk();
340 //++ ------------------------------------------------------------------------------------
341 // Details: Status on the file log medium existing already.
344 // Return: True - Exists.
345 // False - Not found.
348 bool CMICmnLogMediumFile::IsFileExist( void ) const
350 return m_file.IsFileExist( GetFileNamePath() );
353 //++ ------------------------------------------------------------------------------------
354 // Details: Write the header text the logger file.
356 // Args: vText - (R) Text.
357 // Return: MIstatus::success - Functional succeeded.
358 // MIstatus::failure - Functional failed.
361 bool CMICmnLogMediumFile::FileWriteHeader( void )
363 return FileWriteEnglish( ConvertCr( m_fileHeaderTxt ) );
366 //++ ------------------------------------------------------------------------------------
367 // Details: Convert any carriage line returns to be compatible with the platform the
368 // Log fiel is being written to.
370 // Args: vData - (R) Text data.
371 // Return: CMIUtilString - Converted string data.
374 CMIUtilString CMICmnLogMediumFile::ConvertCr( const CMIUtilString & vData ) const
376 const CMIUtilString strCr( "\n" );
377 const CMIUtilString & rCrCmpat( GetLineReturn() );
379 if( strCr == rCrCmpat )
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 )
388 strConv.replace( pos, nSize, rCrCmpat );
389 pos = strConv.find( strCr, pos + nSizeCmpat );
395 //++ ------------------------------------------------------------------------------------
396 // Details: Set the header text that is written to the logger file at the begining.
398 // Args: vText - (R) Text.
399 // Return: MIstatus::success - Functional succeeded.
400 // MIstatus::failure - Functional failed.
403 bool CMICmnLogMediumFile::SetHeaderTxt( const CMIUtilString & vText )
405 m_fileHeaderTxt = vText;
407 return MIstatus::success;
410 //++ ------------------------------------------------------------------------------------
411 // Details: Retrieve the file current carriage line return characters used.
414 // Return: CMIUtilString & - Text.
417 const CMIUtilString & CMICmnLogMediumFile::GetLineReturn( void ) const
419 return m_file.GetLineReturn();