//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 1997. // // File: mylog.cxx // // Contents: // // Classes: // // Functions: // // Coupling: // // Notes: // // History: 10-15-1996 ericne Created // //---------------------------------------------------------------------------- #include "pch.cxx" #include #include "clog.hxx" #include "mydebug.hxx" // These functions are the same regardless of whether NO_NTLOG is defined or not //+--------------------------------------------------------------------------- // // Member: CLog::Log // // Synopsis: Log a message. This function creates a va_list object and calls // the appropriate method to send the message to the log file // // Arguments: [dwStyle] -- Style of this message // [szFileName] -- Name of source file containing this call // [iLine] -- Line number of this method call // [szFormat] -- Format string of message // [ ... ] -- Variable argument list // // Returns: TRUE if successful, FALSE otherwise // // History: 10-17-1996 ericne Created // // Notes: // //---------------------------------------------------------------------------- BOOL CLog::Log( DWORD dwStyle, // Flags to be applied to this message LPTSTR szFileName, // Name of file containing function call int iLine, // Line number of function call LPCTSTR szFormat, // Format of the message ... ) // other arguments { BOOL fRetVal = FALSE; va_list va; __try { va_start( va, szFormat ); fRetVal = vLog( dwStyle, szFileName, iLine, szFormat, va ); } __finally { va_end( va ); } return( fRetVal ); } //CLog::Log void CLog::Disable() { m_fEnabled = FALSE; } void CLog::Enable() { m_fEnabled = TRUE; } void CLog::SetThreshold( DWORD dwThreshold ) { m_dwThreshold = dwThreshold; } // // If NO_NTLOG is defined ... // #ifdef NO_NTLOG #include "memsnap.hxx" // Don't re-order this list! LPCTSTR szMessageLevel[ cMessageLevels ] = { _T("ABORT"), _T("SEV1"), _T("SEV2"), _T("SEV3"), _T("WARN"), _T("PASS"), _T("CALLTREE"), _T("SYSTEM"), _T("TEST"), _T("VARIATION"), _T("BLOCK"), _T("BREAK"), _T("TESTDEBUG"), _T("INFO"), _T(""), _T("") }; //+--------------------------------------------------------------------------- // // Member: ::CLog // // Synopsis: // // Arguments: (none) // // Returns: // // History: 10-16-1996 ericne Created // // Notes: // //---------------------------------------------------------------------------- CLog::CLog( ) : m_pLogFile( NULL ), m_dwLogStyle( 0 ), m_fEnabled( TRUE ), m_dwThreshold( dwThresholdMask ) { InitializeCriticalSection( &m_CriticalSection ); for( int iLoop = 0; iLoop < cMessageLevels; iLoop++ ) m_ulNbrMessages[ iLoop ] = ( ULONG ) 0; } //::CLog //+--------------------------------------------------------------------------- // // Member: ::~CLog // // Synopsis: // // Arguments: (none) // // Returns: // // History: 10-16-1996 ericne Created // // Notes: // //---------------------------------------------------------------------------- CLog::~CLog( ) { struct tm *newtime; time_t aclock; if( m_fEnabled && NULL != m_pLogFile ) { // Put a blank line between the stats and the memory snapshot _ftprintf( m_pLogFile, _T("\n****\n") ); // Display a snapshot of the memory memsnap( m_pLogFile ); // Get time in seconds time( &aclock ); // Convert time to struct newtime = localtime( &aclock ); // Display the time of completion _ftprintf( m_pLogFile, _T("\n**** LOG TERMINATED %s\n"), _tasctime( newtime ) ); } // Close the file stream if( NULL != m_pLogFile && stdout != m_pLogFile ) fclose( m_pLogFile ); m_pLogFile = NULL; // Delete the critical section DeleteCriticalSection( &m_CriticalSection ); } //::~CLog //+--------------------------------------------------------------------------- // // Member: ::InitLog // // Synopsis: // // Arguments: [szFileName] -- // [dwStyle] -- // // Returns: // // History: 10-16-1996 ericne Created // // Notes: // //---------------------------------------------------------------------------- BOOL CLog::InitLog( LPCTSTR szFileName, DWORD dwStyle ) { LPCTSTR szMode = _T("w"); struct tm *newtime; time_t aclock; // If the log has been initialized already, don't reinitialize it if( NULL != m_pLogFile ) return( FALSE ); m_dwLogStyle = dwStyle; // If the file name is null, send output to stdout if( NULL == szFileName ) m_pLogFile = stdout; else m_pLogFile = _tfopen( szFileName, szMode ); // If the log file failed to open, return FALSE if( NULL == m_pLogFile ) { _RPT1( _CRT_WARN, "CLog::InitLog - Unable to open log file %s\n", ( szFileName ? szFileName : _T(" _ftprintf( m_pLogFile, _T("%d.%d : "), GetCurrentProcessId(), GetCurrentThreadId() ) ) { fSuccessful = FALSE; __leave; } // Display the test types that should be applied to this message // (TEST, VARIATION,...) for( iLoop = 0, dwBitMask = 1L; iLoop < cMessageLevels; iLoop++, dwBitMask <<= 1L ) { // Display the type of test this is if( dwStyle & m_dwLogStyle & dwTestTypesMask & dwBitMask ) { if( 0 > _ftprintf( m_pLogFile, _T("+%s"), szMessageLevel[ iLoop ] ) ) { fSuccessful = FALSE; __leave; } ++m_ulNbrMessages[ iLoop ]; fIsLegalTestType = TRUE; break; } } // If this is an illegal test type, display the Filename and Line number if( ! fIsLegalTestType ) { if( 0 > _ftprintf( m_pLogFile, _T("+FILE : %s +LINE : %d"), szFileName, iLine ) ) { fSuccessful = FALSE; __leave; } } // Display the type of this message (PASS, SEV1, etc..) for( iLoop = 0, dwBitMask = 1L; iLoop < cMessageLevels && fIsLegalTestType; iLoop++, dwBitMask <<= 1L ) { // Display the type of message this is if( dwStyle & m_dwLogStyle & dwMessageTypesMask & dwBitMask ) { if( 0 > _ftprintf( m_pLogFile, _T("+%s"), szMessageLevel[ iLoop ] ) ) { fSuccessful = FALSE; __leave; } ++m_ulNbrMessages[ iLoop ]; break; } } if( 0 > _ftprintf( m_pLogFile, _T(" \t%s\n"), szMessage ) ) { fSuccessful = FALSE; __leave; } } // __try __finally { // Release ownership of critical section LeaveCriticalSection( &m_CriticalSection ); } return( fSuccessful ); } //::Log //+--------------------------------------------------------------------------- // // Member: CLog::ReportStats // // Synopsis: // // Arguments: (none) // // Returns: // // History: 10-18-1996 ericne Created // // Notes: // //---------------------------------------------------------------------------- void CLog::ReportStats( ) { // Total tests is number of tests plus number of variations ULONG ulNbrTests = 0; if( ! m_fEnabled || NULL == m_pLogFile ) return; __try { EnterCriticalSection( &m_CriticalSection ); ulNbrTests = m_ulNbrMessages[ 0 ] + m_ulNbrMessages[ 1 ] + m_ulNbrMessages[ 2 ] + m_ulNbrMessages[ 3 ] + m_ulNbrMessages[ 4 ] + m_ulNbrMessages[ 5 ] + m_ulNbrMessages[ 10 ]; _ftprintf( m_pLogFile, _T("\n") ); _ftprintf( m_pLogFile, _T("LOG REPORT---------------------------\n") ); _ftprintf( m_pLogFile, _T(" Total Tests : %5d\n"), ulNbrTests ); _ftprintf( m_pLogFile, _T("-------------------------------------\n") ); _ftprintf( m_pLogFile, _T(" Tests Passed %5d %3d%%\n"), m_ulNbrMessages[ 5 ], (ulNbrTests ? m_ulNbrMessages[ 5 ] * 100 / ulNbrTests : 0 ) ); _ftprintf( m_pLogFile, _T(" Tests Warned %5d %3d%%\n"), m_ulNbrMessages[ 4 ], (ulNbrTests ? m_ulNbrMessages[ 4 ] * 100 / ulNbrTests : 0 ) ); _ftprintf( m_pLogFile, _T(" Tests Failed SEV3 %5d %3d%%\n"), m_ulNbrMessages[ 3 ], (ulNbrTests ? m_ulNbrMessages[ 3 ] * 100 / ulNbrTests : 0 ) ); _ftprintf( m_pLogFile, _T(" Tests Failed SEV2 %5d %3d%%\n"), m_ulNbrMessages[ 2 ], (ulNbrTests ? m_ulNbrMessages[ 2 ] * 100 / ulNbrTests : 0 ) ); _ftprintf( m_pLogFile, _T(" Tests Failed SEV1 %5d %3d%%\n"), m_ulNbrMessages[ 1 ], (ulNbrTests ? m_ulNbrMessages[ 1 ] * 100 / ulNbrTests : 0 ) ); _ftprintf( m_pLogFile, _T(" Tests Blocked %5d %3d%%\n"), m_ulNbrMessages[ 11 ], (ulNbrTests ? m_ulNbrMessages[ 11 ] * 100 / ulNbrTests : 0 )); _ftprintf( m_pLogFile, _T(" Tests Aborted %5d %3d%%\n"), m_ulNbrMessages[ 0 ], (ulNbrTests ? m_ulNbrMessages[ 0 ] * 100 / ulNbrTests : 0 ) ); _ftprintf( m_pLogFile, _T("-------------------------------------\n") ); } // __try __finally { LeaveCriticalSection( &m_CriticalSection ); } } //CLog::ReportStats // // NO_NTLOG has not been defined. OK to use NTLOG mechanism // #else // NO_NTLOG has not been defined //+--------------------------------------------------------------------------- // // Member: ::CLog // // Synopsis: // // Arguments: (none) // // Returns: // // History: 10-15-1996 ericne Created // // Notes: // //---------------------------------------------------------------------------- CLog::CLog( ) : m_hLog( NULL ), m_fEnabled( TRUE ), m_dwThreshold( dwThresholdMask ) { } //::CLog //+--------------------------------------------------------------------------- // // Member: ::~CLog // // Synopsis: // // Arguments: (none) // // Returns: // // History: 10-15-1996 ericne Created // // Notes: // //---------------------------------------------------------------------------- CLog::~CLog() { if( NULL != m_hLog ) { if( ! tlDestroyLog( m_hLog ) ) { _RPT0( _CRT_WARN, "CLog::~CLog : tlDestroyLog failed.\n" ); } m_hLog = NULL; } } //::~CLog //+--------------------------------------------------------------------------- // // Member: CLog::ReportStats // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-06-1997 ericne Created // // Notes: // //---------------------------------------------------------------------------- void CLog::ReportStats( ) { if( ! m_fEnabled || NULL == m_hLog ) return; tlReportStats( m_hLog ); } //CLog::ReportStats //+--------------------------------------------------------------------------- // // Member: ::InitLog // // Synopsis: used ntlog!tlCreateLog and tlAddParticipant to initialize the // log flie // // Arguments: [szFileName] -- namme of the log file // [dwStyle] -- Style of the log file // // Returns: TRUE if successful, FALSE otherwise // // History: 10-15-1996 ericne Created // // Notes: // //---------------------------------------------------------------------------- BOOL CLog::InitLog( LPCTSTR szFileName, DWORD dwStyle ) { // If the file name is null, log to the monitor DWORD dwMonitor = ( szFileName ? 0L : TLS_MONITOR ); // If the log has been initialized already, return FASLE if( NULL != m_hLog ) return( FALSE ); // Create the log m_hLog = tlCreateLog( szFileName, dwStyle | dwMonitor ); // See if the file was opened correctly if( NULL == m_hLog ) { _RPT1( _CRT_WARN, "CLog::InitLog - Could not open log file %s\n", ( szFileName ? szFileName : _T("") ) ); return( FALSE ); } return( TRUE ); } //::InitLog //+--------------------------------------------------------------------------- // // Member: CLog::AddParticipant // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-05-1997 ericne Created // // Notes: // //---------------------------------------------------------------------------- BOOL CLog::AddParticipant() { // If m_hLog is NULL, the log has not been created if( NULL == m_hLog ) return( FALSE ); // Add a participant return( tlAddParticipant( m_hLog, ( DWORD )0, ( int )0 ) ); } //CLog::AddParticipant //+--------------------------------------------------------------------------- // // Member: CLog::RemoveParticipant // // Synopsis: // // Arguments: (none) // // Returns: // // History: 2-05-1997 ericne Created // // Notes: // //---------------------------------------------------------------------------- BOOL CLog::RemoveParticipant() { // Bad call if m_hLog is NULL if( NULL == m_hLog ) return( FALSE ); return( tlRemoveParticipant( m_hLog ) ); } //CLog::RemoveParticipant //+--------------------------------------------------------------------------- // // Member: CLog::vLog // // Synopsis: Uses ntlog!tlLog to send a message to the log file // // Arguments: [dwStyle] -- style of message // [szFileName] -- name of file containing the function call // [iLine] -- line number of function call // [szFormat] -- format string // [va] -- variable argument list // // Returns: TRUE if successful, false otherwise // // History: 1-15-1997 ericne Created // // Notes: // //---------------------------------------------------------------------------- BOOL CLog::vLog( DWORD dwStyle, // Flags to be applied to this message LPTSTR szFileName, // Name of file containing function call int iLine, // Line number of function call LPCTSTR szFormat, // Format of the message va_list va ) // other arguments { TCHAR szMessage[ MaxLogLineLength ]; BOOL fReturnValue = TRUE; if( ! m_fEnabled ) return( TRUE ); if( NULL == m_hLog ) return( FALSE ); // If the style exceeds the threshold, don't log this message if( m_dwThreshold < ( dwStyle & dwThresholdMask ) ) return( TRUE ); if( -1 == _vsntprintf( szMessage, MaxLogLineLength, szFormat, va ) ) { // Only display the first MaxLogLineLength characters of this message } return( tlLog( m_hLog, dwStyle, szFileName, iLine, szMessage ) ); } //CLog::Log #endif