C标准库源代码

源代码在线查看: assert.c

软件大小: 1707 K
上传用户: yl810406
关键词: 标准库 源代码
下载地址: 免注册下载 普通下载 VIP

相关代码

				/***
				*assert.c - Display a message and abort
				*
				*       Copyright (c) 1988-1997, Microsoft Corporation. All rights reserved.
				*
				*Purpose:
				*
				*******************************************************************************/
				
				#ifdef _WIN32
				
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				
				#ifdef NDEBUG
				#undef NDEBUG
				#endif  /* NDEBUG */
				#define _ASSERT_OK
				#include 
				
				
				/*
				 * 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: 
				*
				*       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: , file , line 
				             */
				            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, "");
				
				            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 
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				#include 
				
				#undef NDEBUG
				#define _ASSERT_OK
				#include 
				
				#include     // get Mac header
				#include 
				#include 
				#include 
				#include 
				
				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 */
							

相关资源