home *** CD-ROM | disk | FTP | other *** search
- /***
- *assert.c - Display a message and abort
- *
- * Copyright (c) 1988-1997, Microsoft Corporation. All rights reserved.
- *
- *Purpose:
- *
- *******************************************************************************/
-
- #ifdef _WIN32
-
- #include <cruntime.h>
- #include <windows.h>
- #include <file2.h>
- #include <internal.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <signal.h>
- #include <awint.h>
-
- #ifdef NDEBUG
- #undef NDEBUG
- #endif /* NDEBUG */
- #define _ASSERT_OK
- #include <assert.h>
-
-
- /*
- * assertion format string for use with output to stderr
- */
- static char _assertstring[] = "Assertion failed: %s, file %s, line %d\n";
-
- /* Format of MessageBox for assertions:
- *
- * ================= Microsft Visual C++ Debug Library ================
- *
- * Assertion Failed!
- *
- * Program: c:\test\mytest\foo.exe
- * File: c:\test\mytest\bar.c
- * Line: 69
- *
- * Expression: <expression>
- *
- * For information on how your program can cause an assertion
- * failure, see the Visual C++ documentation on asserts
- *
- * (Press Retry to debug the application - JIT must be enabled)
- *
- * ===================================================================
- */
-
- /*
- * assertion string components for message box
- */
- #define BOXINTRO "Assertion failed!"
- #define PROGINTRO "Program: "
- #define FILEINTRO "File: "
- #define LINEINTRO "Line: "
- #define EXPRINTRO "Expression: "
- #define INFOINTRO "For information on how your program can cause an assertion\n" \
- "failure, see the Visual C++ documentation on asserts"
- #define HELPINTRO "(Press Retry to debug the application - JIT must be enabled)"
-
- static char * dotdotdot = "...";
- static char * newline = "\n";
- static char * dblnewline = "\n\n";
-
- #define DOTDOTDOTSZ 3
- #define NEWLINESZ 1
- #define DBLNEWLINESZ 2
-
- #define MAXLINELEN 60 /* max length for line in message box */
- #define ASSERTBUFSZ (MAXLINELEN * 9) /* 9 lines in message box */
-
- #if defined (_M_IX86)
- #define _DbgBreak() __asm { int 3 }
- #elif defined (_M_ALPHA)
- void _BPT();
- #pragma intrinsic(_BPT)
- #define _DbgBreak() _BPT()
- #else /* defined (_M_ALPHA) */
- #define _DbgBreak() DebugBreak()
- #endif /* defined (_M_ALPHA) */
-
- /***
- *_assert() - Display a message and abort
- *
- *Purpose:
- * The assert macro calls this routine if the assert expression is
- * true. By placing the assert code in a subroutine instead of within
- * the body of the macro, programs that call assert multiple times will
- * save space.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- void __cdecl _assert (
- void *expr,
- void *filename,
- unsigned lineno
- )
- {
- /*
- * Build the assertion message, then write it out. The exact form
- * depends on whether it is to be written out via stderr or the
- * MessageBox API.
- */
- if ( (__error_mode == _OUT_TO_STDERR) || ((__error_mode ==
- _OUT_TO_DEFAULT) && (__app_type == _CONSOLE_APP)) )
- {
- /*
- * Build message and write it out to stderr. It will be of the
- * form:
- * Assertion failed: <expr>, file <filename>, line <lineno>
- */
- if ( !anybuf(stderr) )
- /*
- * stderr is unused, hence unbuffered, as yet. set it to
- * single character buffering (to avoid a malloc() of a
- * stream buffer).
- */
- (void) setvbuf(stderr, NULL, _IONBF, 0);
-
- fprintf(stderr, _assertstring, expr, filename, lineno);
- fflush(stderr);
- }
- else {
- int nCode;
- char * pch;
- char assertbuf[ASSERTBUFSZ];
- char progname[MAX_PATH];
-
- /*
- * Line 1: box intro line
- */
- strcpy( assertbuf, BOXINTRO );
- strcat( assertbuf, dblnewline );
-
- /*
- * Line 2: program line
- */
- strcat( assertbuf, PROGINTRO );
-
- if ( !GetModuleFileName( NULL, progname, MAX_PATH ))
- strcpy( progname, "<program name unknown>");
-
- pch = (char *)progname;
-
- /* sizeof(PROGINTRO) includes the NULL terminator */
- if ( sizeof(PROGINTRO) + strlen(progname) + NEWLINESZ > MAXLINELEN )
- {
- pch += (sizeof(PROGINTRO) + strlen(progname) + NEWLINESZ) - MAXLINELEN;
- strncpy( pch, dotdotdot, DOTDOTDOTSZ );
- }
-
- strcat( assertbuf, pch );
- strcat( assertbuf, newline );
-
- /*
- * Line 3: file line
- */
- strcat( assertbuf, FILEINTRO );
-
- /* sizeof(FILEINTRO) includes the NULL terminator */
- if ( sizeof(FILEINTRO) + strlen(filename) + NEWLINESZ >
- MAXLINELEN )
- {
- /* too long. use only the first part of the filename string */
- strncat( assertbuf, filename, MAXLINELEN - sizeof(FILEINTRO)
- - DOTDOTDOTSZ - NEWLINESZ );
- /* append trailing "..." */
- strcat( assertbuf, dotdotdot );
- }
- else
- /* plenty of room on the line, just append the filename */
- strcat( assertbuf, filename );
-
- strcat( assertbuf, newline );
-
- /*
- * Line 4: line line
- */
- strcat( assertbuf, LINEINTRO );
- _itoa( lineno, assertbuf + strlen(assertbuf), 10 );
- strcat( assertbuf, dblnewline );
-
- /*
- * Line 5: message line
- */
- strcat( assertbuf, EXPRINTRO );
-
- /* sizeof(HELPINTRO) includes the NULL terminator */
-
- if ( strlen(assertbuf) +
- strlen(expr) +
- 2*DBLNEWLINESZ +
- sizeof(INFOINTRO)-1 +
- sizeof(HELPINTRO) > ASSERTBUFSZ )
- {
- strncat( assertbuf, expr,
- ASSERTBUFSZ -
- (strlen(assertbuf) +
- DOTDOTDOTSZ +
- 2*DBLNEWLINESZ +
- sizeof(INFOINTRO)-1 +
- sizeof(HELPINTRO)) );
- strcat( assertbuf, dotdotdot );
- }
- else
- strcat( assertbuf, expr );
-
- strcat( assertbuf, dblnewline );
-
- /*
- * Line 6, 7: info line
- */
-
- strcat(assertbuf, INFOINTRO);
- strcat( assertbuf, dblnewline );
-
- /*
- * Line 8: help line
- */
- strcat(assertbuf, HELPINTRO);
-
- /*
- * Write out via MessageBox
- */
-
- nCode = __crtMessageBoxA(assertbuf,
- "Microsoft Visual C++ Runtime Library",
- MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_SETFOREGROUND|MB_TASKMODAL);
-
- /* Abort: abort the program */
- if (nCode == IDABORT)
- {
- /* raise abort signal */
- raise(SIGABRT);
-
- /* We usually won't get here, but it's possible that
- SIGABRT was ignored. So exit the program anyway. */
-
- _exit(3);
- }
-
- /* Retry: call the debugger */
- if (nCode == IDRETRY)
- {
- _DbgBreak();
- /* return to user code */
- return;
- }
-
- /* Ignore: continue execution */
- if (nCode == IDIGNORE)
- return;
- }
-
- abort();
- }
-
- #else /* _WIN32 */
-
- #include <cruntime.h>
- #include <stdlib.h>
- #include <string.h>
- #include <io.h>
- #include <stdio.h>
- #include <msdos.h>
- #include <internal.h>
- #include <file2.h>
- #include <mpw.h>
-
- #undef NDEBUG
- #define _ASSERT_OK
- #include <assert.h>
-
- #include <macos\types.h> // get Mac header
- #include <macos\traps.h>
- #include <macos\osutils.h>
- #include <macos\gestalte.h>
- #include <macos\toolutil.h>
-
- static char _assertstring[] = "Assertion failed: %s, file %s, line %d\n";
- extern MPWBLOCK * _pMPWBlock;
-
-
- /***
- *_assert() - Display a message and abort
- *
- *Purpose:
- * The assert macro calls this routine if the assert expression is
- * true. By placing the assert code in a subroutine instead of within
- * the body of the macro, programs that call assert multiple times will
- * save space.
- *
- *Entry:
- *
- *Exit:
- *
- *Exceptions:
- *
- *******************************************************************************/
-
- #define addrMacJmp24 0x120
- #define addrMacJmp32 0xbff
-
- void _CALLTYPE1 _assert (
- void *expr,
- void *filename,
- unsigned lineno
- )
- {
- char rgch[512];
- long lrespond;
- OSErr osErr;
- long *pl;
- unsigned char ch;
- char *pch;
- int cb;
-
- if (_pMPWBlock != NULL) {
-
- /*
- * This is the original CRT32 code.
- */
-
- if ( !anybuf(stderr) )
- /*
- * stderr is unused, hence unbuffered, as yet. set it to
- * single character buffering (to avoid a malloc() of a
- * stream buffer).
- */
- (void) setvbuf(stderr, NULL, _IONBF, 0);
-
- fprintf(stderr, _assertstring, expr, filename, lineno);
- fflush(stderr);
- }
- else {
-
- /*
- * This assert code will bring up system debugger, most
- * probably MacsBug if there is a debuuger installed.
- * If no debugger installed, write to stderr file.
- * Not sure if this is really working. Need more accurate
- * info on how MacJmp is set up.
- */
-
-
- osErr = Gestalt(gestaltAddressingModeAttr, &lrespond);
- if (!osErr) {
- if (!BitTst(&lrespond, 31-gestalt32BitCapable)) {
- pl = (long *)addrMacJmp24;
- ch = (unsigned char)(*pl);
- }
- else {
- pch = (char *)addrMacJmp32;
- ch = *pch;
- }
- }
-
- if (ch & 0x20) { //test bit 5 for Debugger installed
- sprintf(rgch, _assertstring, expr, filename, lineno);
- _c2pstr(rgch);
- DebugStr(rgch);
- }
- else {
- // freopen("stderr", "wt", stderr);
- // fprintf(stderr, _assertstring, expr, filename, lineno);
- cb = sprintf(rgch, _assertstring, expr, filename, lineno);
- _write(2, rgch, cb);
- // fflush(stderr);
- }
- }
- abort();
- }
-
- #endif /* _WIN32 */
-