home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
tlx501.zip
/
SRC
/
ASSERTS.CPP
next >
Wrap
C/C++ Source or Header
|
1996-07-08
|
14KB
|
412 lines
/****************************************************************************
$Id: asserts.cpp 501.0 1995/03/07 12:26:06 RON Exp $
Copyright (c) 1991-95 Tarma Software Research. All rights reserved.
Project: Tarma Library for C++ V5.0
Author: Ron van der Wal
Implementation of class TLAssert. The implementation of its functions
depends on the platform:
- MS-DOS prints to stderr
- Macintosh pops up a message box
- OS/2 command line version prints to stderr
- OS/2 Presentation Manager version pops up message box
- Windows pops up a message box
$Log: asserts.cpp $
Revision 501.0 1995/03/07 12:26:06 RON
Updated for TLX 5.01
Revision 1.12 1995/01/31 16:30:02 RON
Update for release 012
Added partial support for SunPro C++ compiler
Revision 1.11 1995/01/18 19:00:08 ron
Added support for _GUI preprocessor name
Revision 1.10 1995/01/10 16:31:14 ron
Small formatting changes
Revision 1.9 1995/01/06 15:57:21 ron
Corrected Revision keyword
Revision 1.8 1995/01/05 15:19:36 ron
Added Ensure() functions
Revision 1.7 1994/11/16 15:35:35 ron
Made global functions into static members of TLAssert
Added module info; rearranged #include directives
Revision 1.6 1994/10/05 18:33:17 ron
Renamed TLx...() functions to tl...()
Revision 1.5 1994/09/28 14:12:06 ron
Removed Macintosh-style #include references
Revision 1.4 1994/09/27 20:21:54 ron
Changed path separator from / to \
Revision 1.3 1994/09/26 15:38:24 ron
Moved code around
Revision 1.2 1994/09/06 14:09:32 ron
Replaced exit() in ABORT action by throw TLXAssert
Revision 1.1 1994/08/16 18:12:51 ron
Initial revision
****************************************************************************/
#include <tlx\501\_build.h>
TLX_MODULE_INFO("$Revision: 501.0 $");
#include <stdarg.h>
#include <stdlib.h>
#include <tlx\501\except.h>
#ifndef _GUI
#include <ctype.h>
#include <stdio.h>
#elif OS_MAC
#include <stdio.h>
#include <string.h>
#include <pascal.h>
#define ALRT_ASSERT 30000 // ALRT resource ID
#elif OS_WINXXX
#include <string.h>
#include <windows.h>
#endif
/*-------------------------------------------------------------------------*/
void TLAssert::AssertFailed(const char *aFile, int aLine)
/* Called when a general assertion has failed. It displays an appropriate
diagnostic message and lets the user choose how to continue.
---------------------------------------------------------------------------*/
{
Diagnostic(dfError, aFile, aLine, "Assertion failed");
}
/*-------------------------------------------------------------------------*/
void TLAssert::CheckFailed(const char *aFile, int aLine)
/* Called when a general check has failed. It displays an appropriate
diagnostic message and lets the user choose how to continue.
---------------------------------------------------------------------------*/
{
Diagnostic(dfWarning, aFile, aLine, "Check failed");
}
/*-------------------------------------------------------------------------*/
void TLAssert::Diagnostic(
int aSeverity, // Severity of the diagnostic
const char * aFile, // File name of the diagnostic
int aLine, // Line number
const char * aFmt, // printf-style format string
... // Format arguments
)
/* Performs the actual diagnostic output. It accepts various parameters from
which to paste together the entire diagnostic message. After the message
is displayed, the function gives the user the choice whether to abort or
to continue the program.
----------------------------------------------------------------------------*/
{
//lint -e606 (Do not complain about '\p')
// Continuation choices after a diagnostic message
#define DO_ABORT 1
#define DO_BREAK 2
#define DO_CONTINUE 3
const char *title = "Tarma Library for C++ diagnostic";
int result = DO_ABORT;
va_list args;
va_start(args, aFmt);
#ifndef _GUI
const BUFSIZE = 256;
char buf[BUFSIZE];
const char *sev;
switch (aSeverity)
{
case dfInfo:
sev = "[Info] ";
result = DO_CONTINUE;
break;
case dfWarning:
sev = "[Warn] ";
result = DO_CONTINUE;
break;
case dfError:
sev = "[Error] ";
result = DO_ABORT;
break;
case dfFatal:
sev = "[Fatal] ";
result = DO_ABORT;
break;
default:
sev = "[-----] ";
result = DO_CONTINUE;
break;
}
fprintf(stderr, "\n***** %s *****\n\n%s", title, sev);
vfprintf(stderr, aFmt, args);
fprintf(stderr, "\n\nFile: %s\nLine: %d\n", aFile, aLine);
fprintf(stderr, "\nAbort, Break, or Continue (A/B/C)? ");
fflush(stderr);
gets(buf);
// Default case has been set up above
switch (toupper(buf[0]))
{
default:
case 'A':
result = DO_ABORT;
break;
case 'B':
result = DO_BREAK;
break;
case 'C':
result = DO_CONTINUE;
break;
}
#elif OS_MAC
const BUFSIZE = 256;
char msgBuf[BUFSIZE];
char fileBuf[BUFSIZE];
unsigned char lineBuf[12];
// ALRT resource layout:
//
// ^0 = Assertion text
// ^1 = Source file name
// ^2 = Source line number
//
// Note: the following vsprintf() might have difficulty interpreting
// integers (%d and %u) in the format string under THINK C, because
// the THINK C implementation of the printf() family assumes 2-byte
// integer arguments for these formats. However, TLX is compiled with
// 4-byte integers under THINK C for compatibility with Symantec C++,
// and all 'int' and 'unsigned int' are therefore 4 bytes. The safest
// way is NOT to use %d and %u specifiers for integers, but %ld and %lu.
// For short integers, there should not be a problem.. (Or are they
// converted implicitly to integer, and therefore to 4 bytes as well??)
vsprintf(msgBuf, aFmt, args);
strncpy(fileBuf, aFile, 128);
NumToString(aLine, lineBuf);
ParamText(CtoPstr(msgBuf), CtoPstr(fileBuf), lineBuf, "\p");
StopAlert(ALRT_ASSERT, NULL);
#elif OS_WINXXX
const BUFSIZE = 512;
char vBuffer[BUFSIZE];
int mbFlags;
wvsprintf(vBuffer, aFmt, args);
wsprintf(&vBuffer[strlen(vBuffer)], "\n\nFile: %s\nLine: %d", aFile, aLine);
switch (aSeverity)
{
case dfInfo:
mbFlags = MB_OK | MB_ICONINFORMATION;
break;
case dfWarning:
mbFlags = MB_ABORTRETRYIGNORE | MB_ICONEXCLAMATION | MB_DEFBUTTON3;
break;
case dfError:
case dfFatal:
default:
mbFlags = MB_ABORTRETRYIGNORE | MB_ICONSTOP | MB_DEFBUTTON3;
break;
}
switch (MessageBox(0, vBuffer, title, MB_TASKMODAL | mbFlags))
{
case IDABORT: // Abort - stays abort
result = DO_ABORT;
break;
case IDRETRY: // Retry - converted to Break
result = DO_BREAK;
break;
case IDIGNORE: // Ignore - converted to Continue
case IDOK: // OK - converted to continue
result = DO_CONTINUE;
break;
default:
TLX_ASSERT_UNREACHABLE;
result = DO_ABORT;
break;
}
#else
#error Unsupported platform; contact Tarma Software Research
#endif
va_end(args);
// Deal with user's response.
switch (result)
{
case DO_BREAK:
TLX_DEBUG_BREAK; // Invokes debugger
break;
case DO_CONTINUE: // Just pretend nothing happened
break;
case DO_ABORT:
THROW(TLXAssert(TLXLocus(aFile, aLine)));
// FALL THROUGH - if 'throw' isn't supported
default:
TLX_ASSERT_UNREACHABLE;
break;
}
}
/*-------------------------------------------------------------------------*/
void TLAssert::EnsureFailed(const char *aFile, int aLine)
/* Called when a postcondition has failed. It displays an appropriate
diagnostic message and lets the user choose how to continue.
---------------------------------------------------------------------------*/
{
Diagnostic(dfError, aFile, aLine, "Postcondition failed");
}
/*-------------------------------------------------------------------------*/
void TLAssert::EnsureNullPtrFailed(const char *aFile, int aLine)
/* Called when a non-NULL pointer has been detected during an assertion. It
displays an error diagnostic to that effect.
---------------------------------------------------------------------------*/
{
Diagnostic(dfError, aFile, aLine,
"Postcondition failed: NULL pointer expected");
}
/*-------------------------------------------------------------------------*/
void TLAssert::EnsurePtrFailed(const char *aFile, int aLine)
/* Called when a NULL pointer has been detected during an assertion. It
displays an error diagnostic to that effect.
---------------------------------------------------------------------------*/
{
Diagnostic(dfError, aFile, aLine,
"Precondition failed: valid pointer expected");
}
/*-------------------------------------------------------------------------*/
void TLAssert::NotImplemented(
const char * aMsg, // Describes not implemented feature
const char * aFile, // Filename
int aLine // Line number
)
/* Called when a piece of code is executed that is not fully implemented.
It displays an informational diagnostic describing the missing feature.
---------------------------------------------------------------------------*/
{
Diagnostic(dfInfo, aFile, aLine, "\"%s\" not implemented", aMsg);
}
/*-------------------------------------------------------------------------*/
void TLAssert::NullPtrCheck(const char *aFile, int aLine)
/* Called when a non-NULL pointer has been detected during a check. It
displays a warning diagnostic to that effect.
---------------------------------------------------------------------------*/
{
Diagnostic(dfWarning, aFile, aLine, "Pointer should be NULL");
}
/*-------------------------------------------------------------------------*/
void TLAssert::NullPtrFailed(const char *aFile, int aLine)
/* Called when a non-NULL pointer has been detected during an assertion. It
displays an error diagnostic to that effect.
---------------------------------------------------------------------------*/
{
Diagnostic(dfError, aFile, aLine, "Pointer should be NULL");
}
/*-------------------------------------------------------------------------*/
void TLAssert::PtrCheck(const char *aFile, int aLine)
/* Called when a NULL pointer has been detected during a check. It displays
a warning diagnostic to that effect.
---------------------------------------------------------------------------*/
{
Diagnostic(dfWarning, aFile, aLine, "Unexpected NULL pointer");
}
/*-------------------------------------------------------------------------*/
void TLAssert::PtrFailed(const char *aFile, int aLine)
/* Called when a NULL pointer has been detected during an assertion. It
displays an error diagnostic to that effect.
---------------------------------------------------------------------------*/
{
Diagnostic(dfError, aFile, aLine, "Unexpected NULL pointer");
}
/*-------------------------------------------------------------------------*/
void TLAssert::Reached(const char *aFile, int aLine)
/* Called when an unreachable statement has been executed. It displays an
error diagnostic to that effect.
---------------------------------------------------------------------------*/
{
Diagnostic(dfError, aFile, aLine, "Unreachable code reached");
}
/*-------------------------------------------------------------------------*/
void TLAssert::RequireFailed(const char *aFile, int aLine)
/* Called when a precondition has failed. It displays an appropriate
diagnostic message and lets the user choose how to continue.
---------------------------------------------------------------------------*/
{
Diagnostic(dfError, aFile, aLine, "Precondition failed");
}
/*-------------------------------------------------------------------------*/
void TLAssert::RequireNullPtrFailed(const char *aFile, int aLine)
/* Called when a non-NULL pointer has been detected during an assertion. It
displays an error diagnostic to that effect.
---------------------------------------------------------------------------*/
{
Diagnostic(dfError, aFile, aLine,
"Precondition failed: NULL pointer expected");
}
/*-------------------------------------------------------------------------*/
void TLAssert::RequirePtrFailed(const char *aFile, int aLine)
/* Called when a NULL pointer has been detected during an assertion. It
displays an error diagnostic to that effect.
---------------------------------------------------------------------------*/
{
Diagnostic(dfError, aFile, aLine,
"Precondition failed: valid pointer expected");
}
/*-------------------------------------------------------------------------*/
void TLAssert::ToDo(const char *aMsg, const char *aFile, int aLine)
/* Called when a piece of code is executed that is incomplete. It displays
an informational message describing the missing piece.
---------------------------------------------------------------------------*/
{
Diagnostic(dfInfo, aFile, aLine, "To do: %s", aMsg);
}