Saxum/extern/bullet/Extras/sph/common/mdebug.cpp
Fabian Klemp aeb6218d2d Renaming.
2014-10-24 11:49:46 +02:00

583 lines
15 KiB
C++

/*
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
ZLib license
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//#define MEMORY_DEBUG // Overloads the new and delete operators
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "mdebug.h"
#ifdef _MSC_VER
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <conio.h>
#endif
CDebug debug;
CError error;
//------------------------------------------------- DEBUG CLASS
CDebug::CDebug ()
{
m_OutName = "debug.txt";
m_bStarted = false;
m_bToFile = true;
m_bToSysbox = true;
m_bToCons = false;
m_OutFile = NULL;
m_OutCons = NULL;
Start ();
}
CDebug::~CDebug (void)
{
Stop ();
}
void CDebug::Start ()
{
if ( m_bStarted ) Stop ();
if ( m_bToFile ) {
char fn[200];
#ifdef _MSC_VER
strcpy_s ( fn, 200, m_OutName.c_str () );
fopen_s ( &m_OutFile, fn, "w+t" );
#else
strncpy ( fn, m_OutName.c_str(), 200 );
m_OutFile = fopen( fn, "w+" );
#endif
if ( m_OutFile == 0x0 ) {
exit ( EXIT_FAILURE ); // error: Cannot create debug file
}
m_bStarted = true;
Print ( "debug", "CDebug started to file.\n");
}
m_bStarted = true;
}
void CDebug::Exit ( int code )
{
if ( !m_bToSysbox ) {
#ifdef _MSC_VER
_getch();
#endif
}
exit ( code );
}
void CDebug::Stop ()
{
if ( m_bStarted ) {
if ( m_bToFile ) {
Print ( "debug", "CDebug stopped.");
fclose ( m_OutFile );
}
}
m_bStarted = false;
}
void CDebug::SendToFile ( char* fname )
{
if (m_bStarted) Stop ();
m_bToFile = true;
m_OutName = fname;
}
void CDebug::SendToConsole ( bool tf )
{
m_bToCons = tf;
if ( tf ) {
#ifdef _MSC_VER
AllocConsole ();
long lStdHandle = (long) GetStdHandle( STD_OUTPUT_HANDLE );
int hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
m_OutCons = _fdopen( hConHandle, "w" );
#endif
}
}
void CDebug::SendToSysbox ( bool tf )
{
m_bToSysbox = tf;
}
void CDebug::Print ( std::string subsys, std::string msg )
{
if ( m_bStarted ) {
if ( m_bToFile ) {
fprintf ( m_OutFile, "%s: %s\n", subsys.c_str(), msg.c_str() );
fflush ( m_OutFile);
}
if ( m_bToCons ) {
#ifdef _MSC_VER
fprintf ( m_OutCons, "%s: %s\n", subsys.c_str(), msg.c_str() );
fflush ( m_OutCons );
#else
printf ( "%s: %s\n", subsys.c_str(), msg.c_str() );
#endif
}
}
}
void CDebug::Print (char* msg)
{
if ( m_bStarted ) {
if ( m_bToFile ) {
fprintf ( m_OutFile, "%s", msg );
fflush ( m_OutFile );
}
if ( m_bToCons ) {
#ifdef _MSC_VER
fprintf ( m_OutCons, "%s", msg );
fflush ( m_OutCons );
#else
printf ( "%s", msg );
#endif
}
}
}
void CDebug::Print ( std::string msg )
{
if ( m_bStarted ) {
if ( m_bToFile ) {
fprintf ( m_OutFile, "%s", msg.c_str() );
fflush ( m_OutFile );
}
if ( m_bToCons ) {
#ifdef _MSC_VER
fprintf ( m_OutCons, "%s", msg.c_str() );
fflush ( m_OutCons );
#else
printf ( "%s", msg.c_str() );
#endif
}
}
}
void CDebug::PrintF ( std::string substr, char* format, ... )
{
// Note: This is the >only< way to do this. There is no general way to
// pass on all the arguments from one ellipsis function to another.
// The function vfprintf was specially designed to allow this.
if ( m_bStarted ) {
if ( m_bToFile ) {
va_list argptr;
va_start (argptr, format);
fprintf ( m_OutFile, "%s: ", substr.c_str() );
vfprintf ( m_OutFile, format, argptr);
va_end (argptr);
fflush ( m_OutFile );
}
if ( m_bToCons ) {
#ifdef _MSC_VER
va_list argptr;
va_start (argptr, format);
fprintf ( m_OutCons, "%s: ", substr.c_str() );
vfprintf ( m_OutCons, format, argptr);
va_end (argptr);
fflush ( m_OutCons );
#else
va_list argptr;
va_start (argptr, format);
printf ( "%s: ", substr.c_str() );
vprintf ( format, argptr);
va_end (argptr);
#endif
}
}
}
void CDebug::Printf ( char* format, ... )
{
// Note: This is the >only< way to do this. There is no general way to
// pass on all the arguments from one ellipsis function to another.
// The function vfprintf was specially designed to allow this.
if ( m_bStarted ) {
if ( m_bToFile ) {
va_list argptr;
va_start (argptr, format);
vfprintf ( m_OutFile, format, argptr);
va_end (argptr);
fflush ( m_OutFile );
}
if ( m_bToCons ) {
#ifdef _MSC_VER
va_list argptr;
va_start (argptr, format);
vfprintf ( m_OutCons, format, argptr);
va_end (argptr);
fflush ( m_OutCons );
#else
va_list argptr;
va_start (argptr, format);
vprintf ( format, argptr);
va_end (argptr);
#endif
}
}
}
void CDebug::PrintErr ( std::string errid, std::string subsys, std::string msg, std::string sysbox )
{
if ( m_bStarted ) {
if ( m_bToFile ) {
fprintf ( m_OutFile, "%s: ERROR: %s\n", subsys.c_str(), msg.c_str() );
fflush ( m_OutFile );
}
if ( m_bToCons ) {
#ifdef _MSC_VER
fprintf ( m_OutCons, "%s: ERROR: %s\n", subsys.c_str(), msg.c_str() );
fflush ( m_OutCons );
#else
printf ( "%s: ERROR[%s] %s\n", subsys.c_str(), errid.c_str(), msg.c_str() );
#endif
}
if ( m_bToSysbox ) {
char disp[4000];
char caption[200];
#ifdef _MSC_VER
// Message boxes for Windows
strcpy_s ( caption, 200, "Mint - Error" );
strcpy_s ( disp, 4000, sysbox.c_str());
#include <windows.h>
int hr = MessageBoxA ( 0x0, disp, caption, MB_OK);
#else
strncpy ( caption, m_ErrorSubsys.c_str(), 200 );
strncpy ( disp, msg.c_str(), 4000 );
#endif
}
}
}
//-------------------------------------------------------------------- Error Class Code
//
// This software is released under the LGPL Open Source Liscense.
// See the documentation included with this source code for terms of modification,
// distribution and re-release.
//
// Original Copyright (C) 2002 Rama C. Hoetzlein, GameX R4
//
CError::CError ()
{
m_Errors.clear ();
m_ErrorID = "";
m_ErrorSubsys = "";
m_ErrorMsg = "";
m_ErrorFunc = "";
m_ErrorFix = "";
m_ErrorExtra = "";
}
void CError::Start ()
{
Start ( "" );
}
void CError::Start ( char* fname )
{
if ( fname != 0x0 && strlen(fname) > 0 ) {
// Read error message file. NOT YET IMPLEMENTED
} else {
debug.Print ( "error", "No error file loaded." );
}
debug.Print ( "error", "Error handler started." );
m_bStarted = true;
}
void CError::OutputMessage ()
{
// Create sysbox message
std::string box_msg;
box_msg = "Subsystem: " + m_ErrorSubsys + "\n\n";
box_msg += "Error: " + m_ErrorMsg + "\n";
if ( m_ErrorExtra.length() > 0) box_msg += "Info: " + m_ErrorExtra + "\n";
if ( m_ErrorFix.length() > 0) box_msg += "\nFix: " + m_ErrorFix + "\n";
if ( m_ErrorID.length() > 0 ) box_msg += "Error ID: " + m_ErrorID + "\n";
if ( m_ErrorFunc.length() > 0 ) box_msg += "Function: " + m_ErrorFunc + "\n";
// Error output to debug file
debug.PrintErr ( m_ErrorID, m_ErrorSubsys, m_ErrorMsg, box_msg );
}
void CError::Exit ( int code )
{
debug.Exit ( code );
}
void CError::Print ( char* msg)
{
// User-level error (no additional info)
m_ErrorID = "";
m_ErrorSubsys = "undef";
m_ErrorMsg = msg;
m_ErrorFunc = "";
m_ErrorFix = "";
m_ErrorExtra = "";
OutputMessage ();
}
void CError::Print ( std::string msg )
{
// User-level error (no additional info)
m_ErrorID = "";
m_ErrorSubsys = "undef";
m_ErrorMsg = msg;
m_ErrorFunc = "";
m_ErrorFix = "";
m_ErrorExtra = "";
OutputMessage ();
}
void CError::Print ( std::string subsys, std::string msg ){
// Unregistered error
m_ErrorID = "";
m_ErrorSubsys = subsys;
m_ErrorMsg = msg;
m_ErrorFunc = "";
m_ErrorFix = "";
m_ErrorExtra = "";
OutputMessage ();
}
void CError::PrintF ( std::string subsys, char* msg, ... )
{
char buf[2000];
va_list argptr;
m_ErrorID = "";
m_ErrorSubsys = subsys;
va_start(argptr, msg);
#ifdef _MSC_VER
vsprintf_s (buf, 2000, msg, argptr);
#else
vsnprintf(buf, 2000, msg, argptr);
#endif
va_end (argptr);
m_ErrorMsg = buf;
m_ErrorFunc = "";
m_ErrorFix = "";
m_ErrorExtra = "";
OutputMessage ();
}
void CError::PrintErr ( std::string err )
{
// Registered error - NOT YET IMPLEMENTED
// CErrorMsg* msg = m_
}
void CError::PrintErrDX ( std::string err, int result )
{
//
// #ifdef BUILD_DX
// m_ErrorExtra = DXGetErrorString9 ( result );
// #endif
OutputMessage ();
m_ErrorExtra = "";
}
void CError::PrintErrGL ( std::string err, int result )
{
OutputMessage ();
m_ErrorExtra = "";
}
void CError::PrintErrW ( std::string err, int result )
{
OutputMessage ();
m_ErrorExtra = "";
}
/*
void CError::GetErrorMessage ( ErrorDef::Errors err )
{
switch (err) {
//----------------------------------------------------- MATRIX Errors
case ErrorDef::MatrixIsNull:
m_strDescription = "Matrix data is null\n";
m_strFunction = "Matrix::op()";
m_strFix = "";
break;
case ErrorDef::ColOutOfBounds:
m_strDescription = "Column index out of bounds\n";
m_strFunction = "Matrix::op()";
m_strFix = "";
break;
case ErrorDef::RowOutOfBounds:
m_strDescription = "Row index out of bounds\n";
m_strFunction = "Matrix::op()";
m_strFix = "";
break;
//----------------------------------------------------- WinDX Errors
case ErrorDef::DXInitFail:
m_strDescription = "Initialization of DirectX failed.";
m_strFunction = "GameX::InitDirect3D";
m_strFix = "Reinstall DirectX 9.0. Confirm DirectX hardware support.";
break;
case ErrorDef::DXCannotGetMode:
m_strDescription = "Cannot get current display mode.";
m_strFunction = "GameX::SysGetCurrentMode";
m_strFix = "";
break;
case ErrorDef::DXCannotSetMode:
m_strDescription = "Cannot select display mode.";
m_strFunction = "GameX::SysSelectMode";
m_strFix = "Try requesting a different display mode and options.";
break;
case ErrorDef::WinCannotCreateClass:
m_strDescription = "Cannot create Windows class.";
m_strFunction = "GameX::SysCreateWindowsClass";
m_strFix = "Close other applications. Restart system.";
break;
case ErrorDef::WinCannotCreateWindow:
m_strDescription = "Cannot create Window.";
m_strFunction = "GameX::SysCreateWindow";
m_strFix = "Try requesting a different display mode and options.\nClose other applications. Restart system. Possibly unsupported display hardware.";
break;
case ErrorDef::DXCannotCreateDevice:
m_strDescription = "Cannot create DirectX Device.";
m_strFunction = "GameX::SysCreateDevice3D";
m_strFix = "Try requesting a different display mode and options.";
break;
case ErrorDef::DXCannotCreateDepthStencils:
m_strDescription = "Cannot create DirectX Depth Stencils.";
m_strFunction = "GameX::SysCreateDepthStencils";
m_strFix = "Try requesting a different display mode and options.";
break;
//---------------------------------------------------------------- File Errors
case ErrorDef::CannotAppendAndRead:
m_strDescription = "Cannot open a file in both APPEND and READ mode.";
m_strFunction = "File::Open";
m_strFix = "Use either APPEND, READ or WRITE when opening file.";
break;
case ErrorDef::CannotAppendAndWrite:
m_strDescription = "Cannot open a file in both APPEND and WRITE mode.";
m_strFunction = "File::Open";
m_strFix = "Use either APPEND, READ or WRITE when opening file.";
break;
case ErrorDef::FileNotFound:
m_strDescription = "File not found.";
m_strFunction = "File::Open";
m_strFix = "Use AUTOCREATE if you would like to create a new file.";
break;
case ErrorDef::LeaveEofOnlyOnAppend:
m_strDescription = "Warning:LEAVEEOF flag can only be used in APPEND mode.";
m_strFunction = "File::Open";
m_strFix = "Remove the LEAVEEOF flag or open file in APPEND mode.";
break;
case ErrorDef::NoModeSpecified:
m_strDescription = "No open mode specified.";
m_strFunction = "File::Open";
m_strFix = "You must specify READ, WRITE or APPEND to open a file.";
break;
case ErrorDef::NoNotOpenCmd:
m_strDescription = "NOTOPEN cannot be used as an open file flag.";
m_strFunction = "File::Open";
m_strFix = "Remove the NOTOPEN flag.";
break;
case ErrorDef::NoSeqAndRandom:
m_strDescription = "Cannot open file in both SEQUENTIAL and RANDOM access modes.";
m_strFunction = "File::Open";
m_strFix = "Choose either SEQUENTIAL or RANDOM mode to open file in.";
break;
case ErrorDef::CannotCreateFont:
m_strDescription = "Cannot create default font.";
m_strFunction = "RenderDX::Initialize";
m_strFix = "DirectX fonts are not supported for some reason.";
break;
case ErrorDef::CannotCreateSprite:
m_strDescription = "Cannot create default sprite.";
m_strFunction = "RenderDX::Initialize";
m_strFix = "DirectX sprites are not supported for some reason.";
break;
case ErrorDef::CannotAddImage:
m_strDescription = "Cannot create image on video memory.";
m_strFunction = "RenderDX::AddImage";
m_strFix = "DirectX was unable to create hardware texture for the image.";
break;
case ErrorDef::CannotUpdateImage:
m_strDescription = "Cannot update image data on video memory.";
m_strFunction = "RenderDX::UpdateImage";
m_strFix = "DirectX was unable to modify hardware texture for the image.";
break;
case ErrorDef::CannotOpenFile:
#if defined(BUILD_VSNET)
m_strDescription = strerror( errno );
#else
m_strDescription = ""; // should replace with Mac general error code
#endif
m_strFunction = "File::Open";
m_strFix = "";
break;
case ErrorDef::ImageLoadError:
m_strDescription = "Unable to load image.";
m_strFunction = "ImageX::Load";
m_strFix = "";
break;
default:
char msg[500];
sprintf (msg, "%d", (int) err );
m_strDescription = "Undefined error: ";
m_strDescription += msg;
m_strSubsystem = "Undefined error.";
m_strFix = "Error must be given a description and fix message.";
break;
};
}
*/
#ifdef MEMORY_DEBUG
// User-defined operator new.
void *operator new( size_t stSize )
{
void* pvMem = malloc( stSize );
debug.Printf ( "NEW %p (%d bytes)\n", pvMem, stSize );
return pvMem;
}
// User-defined operator delete.
void operator delete( void *pvMem )
{
debug.Printf ( "DELETE %p\n", pvMem );
free ( pvMem );
}
#endif