/////////////////////////////////////////////////////////////////////////////// // TraceEx.cpp // // Contains functions and macro's for tracing program execution in debug and // // non-debug versions of a program. // // // // Copyright (c) JAK++ Software Development B.V. 1995-1999 All Rights // // Reserved. // // Copyright (c) Smartsoft, LLC 1999-2001. All Rights Reserved. // // Written by Jan Knepper // // Thank the Lord for giving me everything to make this possible! // // // // Redistribution and use in source and binary forms, with or without // // modification, are permitted provided that the following conditions // // are met: // // 1. Redistributions of source code must retain the above copyright // // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // // notice, this list of conditions and the following disclaimer in the // // documentation and/or other materials provided with the distribution. // // 3. The name of the author may not be used to endorse or promote products // // derived from this software without specific prior written permission. // // // // THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND // // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE // // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF // // THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////////// #include #include #include "Const.h" #if defined(I_WIN_32) # ifndef _CONSOLE # else # ifdef TXT2 # include "Screen.hpp" # include "Message.hpp" # endif # endif #elif defined(I_WIN_16) #elif defined(I_OS2_32) # include "Message.hpp" #elif defined(I_DOS_32) # include "Message.hpp" #elif defined(I_DOS_16) # include "Message.hpp" #else #endif #include "TraceEx.h" #ifdef __cplusplus extern "C" { #endif const size_t _LOCATION = 4096; const size_t _MESSAGE = 4096; const size_t _TRACEBUFFER = 8192; static int _tracelog = 1; static int _tracetitle = 1; static int _tracemessage = 1; static TCHAR _traceformat [ 64 ] = _T ( "%s [%d]" ); static TCHAR _traceseparator [ 64 ] = _T ( " => " ); #ifndef I_UNIX_32 static TCHAR _tracelogfile [ FILENAMESIZE ] = _T ( "C:\\TMP\\TRACE.JAK" ); #else static TCHAR _tracelogfile [ FILENAMESIZE ] = _T ( "/tmp/trace.jak" ); #endif static TCHAR _location [ _LOCATION ]; static TCHAR _message [ _MESSAGE ]; static TCHAR _tracebuffer [ _TRACEBUFFER ]; int _GetTraceLog () { return ( _tracelog ); } void _SetTraceLog ( int _flag ) { _tracelog = _flag; } int _GetTraceTitle () { return ( _tracetitle ); } void _SetTraceTitle ( int _flag ) { _tracetitle = _flag; } int _GetTraceMessage () { return ( _tracemessage ); } void _SetTraceMessage ( int _flag ) { _tracemessage = _flag; } const TCHAR *_GetTraceFormat () { return ( _traceformat ); } void _SetTraceFormat ( const TCHAR *_format ) { _tcscpy ( _traceformat, _format ); } const TCHAR *_GetTraceSeparator () { return ( _traceseparator ); } void _SetTraceSeparator ( const TCHAR *_separator ) { _tcscpy ( _traceseparator, _separator ); } const TCHAR *_GetTraceLogFile () { return ( _tracelogfile ); } void _SetTraceLogFile ( const TCHAR *_name ) { _tcscpy ( _tracelogfile, _name ); } #if defined(I_WIN_32) static int __TraceLog ( HWND, const TCHAR *, const TCHAR * ); static int __TraceTitle ( HWND, const TCHAR *, const TCHAR * ); static int __TraceMessage ( HWND, const TCHAR *, const TCHAR * ); int _TraceLog ( HWND hwnd, const TCHAR *_file, int _line, const TCHAR *_format, ... ) { va_list arg; _stprintf ( _location, _traceformat, _file, _line ); va_start ( arg, _format ); _vstprintf ( _message , _format, arg ); va_end ( arg ); return ( __TraceLog ( hwnd, _location, _message ) ); } static int __TraceLog ( HWND hwnd, const TCHAR *_location, const TCHAR *_message ) { if ( ! _tracelog ) return ( 0 ); HANDLE handle; DWORD written; LONG moved = 0; _tcscpy ( _tracebuffer, _location ); _tcscat ( _tracebuffer, _traceseparator ); _tcscat ( _tracebuffer, _message ); // Take care of carriage return and line feed. _tcscat ( _tracebuffer, _T ( "\r\n" ) ); // Write the file. if ( ( handle = CreateFile ( _tracelogfile, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 ) ) != INVALID_HANDLE_VALUE ) { if ( SetFilePointer ( handle, 0, &moved, FILE_END ) == 0 ) { // Handle Unicode output. #ifdef _UNICODE if ( moved == 0 ) WriteFile ( handle, "\xFF\xFE", 2, &written, 0 ); #endif } WriteFile ( handle, _tracebuffer, _tcslen ( _tracebuffer ) * sizeof ( TCHAR ), &written, 0 ); CloseHandle ( handle ); } return ( 1 ); } int _TraceTitle ( HWND hwnd, const TCHAR *_file, int _line, const TCHAR *_format, ... ) { va_list arg; _stprintf ( _location, _traceformat, _file, _line ); va_start ( arg, _format ); _vstprintf ( _message , _format, arg ); va_end ( arg ); return ( __TraceTitle ( hwnd, _location, _message ) ); } static int __TraceTitle ( HWND hwnd, const TCHAR *_location, const TCHAR *_message ) { __TraceLog ( hwnd, _location, _message ); if ( ! _tracetitle ) return ( 0 ); _tcscpy ( _tracebuffer, _location ); _tcscat ( _tracebuffer, _traceseparator ); _tcscat ( _tracebuffer, _message ); #ifndef _CONSOLE if ( ( hwnd != 0 ) && ( IsWindow ( hwnd ) ) ) SetWindowText ( hwnd, _tracebuffer ); #else #ifdef TXT2 if ( screen != 0 ) { screen -> MvPutS ( 0, 0, _tracebuffer ); screen -> Flush (); } else puts ( _tracebuffer ); #else puts ( _tracebuffer ); #endif #endif return ( 1 ); } int _TraceMessage ( HWND hwnd, const TCHAR *_file, int _line, const TCHAR *_format, ... ) { va_list arg; _stprintf ( _location, _traceformat, _file, _line ); va_start ( arg, _format ); _vstprintf ( _message , _format, arg ); va_end ( arg ); return ( __TraceMessage ( hwnd, _location, _message ) ); } static int __TraceMessage ( HWND hwnd, const TCHAR *_location, const TCHAR *_message ) { __TraceTitle ( hwnd, _location, _message ); if ( ! _tracemessage ) return ( 0 ); #ifndef _CONSOLE if ( ( hwnd != 0 ) && ( ! IsWindow ( hwnd ) ) ) hwnd = 0; MessageBox ( hwnd, _message, _location, MB_OK ); #else #ifdef TXT2 iMessage :: Action ( iMessage :: ButtonOk, _location, 0, _message ); #else printf ( "%s : %s\n", _location, _message ); #endif #endif return ( 1 ); } #elif defined(I_WIN_16) #elif defined(I_OS2_32) #elif defined(I_DOS_32) #elif defined(I_DOS_16) static int __TraceLog ( int, const TCHAR *, const TCHAR * ); int _TraceLog ( int hwnd, const TCHAR *_file, int _line, const TCHAR *_format, ... ) { va_list arg; _stprintf ( _location, _traceformat, _file, _line ); va_start ( arg, _format ); _vstprintf ( _message , _format, arg ); va_end ( arg ); return ( __TraceLog ( hwnd, _location, _message ) ); } static int __TraceLog ( int hwnd, const TCHAR *_location, const TCHAR *_message ) { if ( ! _tracelog ) return ( 0 ); int fd; _tcscpy ( _tracebuffer, _location ); _tcscat ( _tracebuffer, _traceseparator ); _tcscat ( _tracebuffer, _message ); // Take care of carriage return and line feed. _tcscat ( _tracebuffer, _T ( "\r\n" ) ); // Write the file. if ( ( fd = open ( _tracelogfile, O_WRONLY | O_APPEND | O_CREAT, S_IREAD | S_IWRITE ) ) != -1 ) { write ( fd, _tracebuffer, _tcslen ( _tracebuffer ) * sizeof ( TCHAR ) ); close ( fd ); } return ( 1 ); } #elif defined(I_UNIX_32) static int __TraceLog ( int, const TCHAR *, const TCHAR * ); static int __TraceTitle ( int, const TCHAR *, const TCHAR * ); static int __TraceMessage ( int, const TCHAR *, const TCHAR * ); int _TraceLog ( int hwnd, const TCHAR *_file, int _line, const TCHAR *_format, ... ) { va_list arg; _stprintf ( _location, _traceformat, _file, _line ); va_start ( arg, _format ); _vstprintf ( _message , _format, arg ); va_end ( arg ); return ( __TraceLog ( hwnd, _location, _message ) ); } static int __TraceLog ( int hwnd, const TCHAR *_location, const TCHAR *_message ) { if ( ! _tracelog ) return ( 0 ); int fd; _tcscpy ( _tracebuffer, _location ); _tcscat ( _tracebuffer, _traceseparator ); _tcscat ( _tracebuffer, _message ); // Take care of carriage return and line feed. _tcscat ( _tracebuffer, _T ( "\r\n" ) ); // Write the file. if ( ( fd = open ( _tracelogfile, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR ) ) != -1 ) { write ( fd, _tracebuffer, _tcslen ( _tracebuffer ) * sizeof ( TCHAR ) ); close ( fd ); } return ( 1 ); } int _TraceTitle ( int hwnd, const TCHAR *_file, int _line, const TCHAR *_format, ... ) { va_list arg; _stprintf ( _location, _traceformat, _file, _line ); va_start ( arg, _format ); _vstprintf ( _message , _format, arg ); va_end ( arg ); return ( __TraceTitle ( hwnd, _location, _message ) ); } static int __TraceTitle ( int hwnd, const TCHAR *_location, const TCHAR *_message ) { __TraceLog ( hwnd, _location, _message ); if ( ! _tracetitle ) return ( 0 ); _tcscpy ( _tracebuffer, _location ); _tcscat ( _tracebuffer, _traceseparator ); _tcscat ( _tracebuffer, _message ); #ifdef TXT2 if ( screen != 0 ) { screen -> MvPutS ( 0, 0, _tracebuffer ); screen -> Flush (); } else puts ( _tracebuffer ); #else fputs ( _tracebuffer, stderr ); fflush ( stderr ); #endif return ( 1 ); } int _TraceMessage ( int hwnd, const TCHAR *_file, int _line, const TCHAR *_format, ... ) { va_list arg; _stprintf ( _location, _traceformat, _file, _line ); va_start ( arg, _format ); _vstprintf ( _message , _format, arg ); va_end ( arg ); return ( __TraceMessage ( hwnd, _location, _message ) ); } static int __TraceMessage ( int hwnd, const TCHAR *_location, const TCHAR *_message ) { __TraceTitle ( hwnd, _location, _message ); if ( ! _tracemessage ) return ( 0 ); #ifdef TXT2 iMessage :: Action ( iMessage :: ButtonOk, _location, 0, _message ); #else fprintf ( stderr, "%s : %s\n", _location, _message ); fflush ( stderr ); #endif return ( 1 ); } #else #pragma message "Can't trace on this target platform yet!" #error "Can't trace on this target platform yet!" #endif #ifdef __cplusplus } #endif