message.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,030 行 · 第 1/2 页

C
1,030
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "plusplus.h"

#include <setjmp.h>
#include <stdarg.h>

#include "cgfront.h"
#include "stats.h"
#include "memmgr.h"
#include "iosupp.h"
#include "preproc.h"
#include "vbuf.h"
#include "fmtmsg.h"
#include "errdefns.h"
#include "context.h"
#include "ring.h"
#include "srcfile.h"
#include "initdefs.h"
#include "fmtsym.h"
#include "pcheader.h"
#include "cppexit.h"
#include "idedll.h"
#include "macro.h"
#include "intlload.h"
#ifndef NDEBUG
#include "enterdb.h"
#endif

#define RESERVE_MAX                 2048
#define RESERVE_MIN                 256
static unsigned reserveSize;
static void *reserveMem;
static unsigned reserveDepth;

static FILE *err_file;              // ERROR FILE
static TOKEN_LOCN err_locn;         // error location
static TOKEN_LOCN notes_locn;       // notes location
static unsigned char* orig_err_levs;// original error levels
static boolean errLimitExceeded;    // have exceeded error limit
static IntlData *internationalData; // translated messages

static SUICIDE_CALLBACK *suicideCallbacks;

#define MSG_SCOPE static
#define MSG_MEM
#include "errmsgs1.gh"
#include "msgdecod.c"
#define MSG_CONST
#include "errlevel.gh"
#undef MSG_CONST

#if _CPU == 386
#define INTL_NAME   "wpp386"
#elif _CPU == 8086
#define INTL_NAME   "wppi86"
#elif _CPU == _AXP
#define INTL_NAME   "wppaxp"
#else
#error missing _CPU check
#endif

static char *fileName(          // get name of SRCFILE
    SRCFILE src )               // - source file
{
    char *fname;

    if( CompFlags.error_use_full ) {
        fname = SrcFileFullName( src );
    } else {
        fname = SrcFileName( src );
    }
    return( fname );
}


static void build_file_nesting  // DUMP OUT THE INCLUDE NESTING TRACEBACK
    ( void )
{
    SRCFILE src_file;           // - source file descriptor
    char *fname;
    LINE_NO line;

    if( NULL != err_locn.src_file ) {
        if( SrcFileTraceBackReqd( err_locn.src_file ) ) {
            SrcFileTraceBack( err_locn.src_file );
            CompFlags.log_note_msgs = TRUE;
            if( CompFlags.ew_switch_used ) {
                MsgDisplayArgs( IDEMSGSEV_NOTE_MSG
                              , INF_FILE_LOCATION
                              , fileName( err_locn.src_file ) );
            }
            for( src_file = err_locn.src_file; ; ) {
                src_file = SrcFileIncluded( src_file, &line );
                if( src_file == NULL ) break;
                fname = fileName( src_file );
                MsgDisplayArgs( IDEMSGSEV_NOTE, INF_FILE_NEST, fname, line );
            }
            CompFlags.log_note_msgs = FALSE;
        }
    }
}

static void fmt_inf_hdr         // FORMAT THE INFORMATION HDR
    ( char *hdr_str )
{
    CompFlags.log_note_msgs = TRUE;
    MsgDisplayArgs( IDEMSGSEV_NOTE_MSG
                  , INF_ERR_LOCATION
                  , hdr_str );
    CompFlags.log_note_msgs = FALSE;
}


static void fmt_inf_hdr_switch  // FORMAT THE INFORMATION HDR FOR SWITCH
    ( char *hdr_str             // - header name
    , char *sw_val )            // - switch
{
    CompFlags.log_note_msgs = TRUE;
    MsgDisplayArgs( IDEMSGSEV_NOTE_MSG
                  , INF_SWITCH_LOCATION
                  , hdr_str
                  , sw_val );
    CompFlags.log_note_msgs = FALSE;
}

static void fmt_inf_hdr_sym     // FORMAT THE INFORMATION HDR, WITH SYMBOL
    ( char *hdr_str             // - header name
    , SYMBOL sym )              // - symbol in question
{
    CompFlags.log_note_msgs = TRUE;
    MsgDisplayArgs( IDEMSGSEV_NOTE_MSG
                  , INF_CG_LOCATION
                  , hdr_str
                  , sym );
    CompFlags.log_note_msgs = FALSE;
}

char const *IntlUsageText(      // GET INTERNATIONAL USAGE TEXT
    void )
{
    IntlData *data = internationalData;

    if( data != NULL ) {
        return( data->usage_text );
    }
    return( NULL );
}

static void doDecodeMessage(            // extract message from tables
    char *buff,                 // - buffer
    MSG_NUM msg )               // - message
{
    IntlData *data = internationalData;

    if( data != NULL ) {
        if( msg < data->errors_count ) {
            strcpy( buff, data->errors_text[ msg ] );
            return;
        }
    }
    decodeMsg( buff, msg );
}

static SYMBOL msgBuild(         // BUILD ERROR MESSAGE
    MSG_NUM msgnum,             // - message number
    va_list args,               // - substitution arguments
    VBUF *pbuf )                // - buffer for message
{
    char msgbuf[MAX_MSG+16];    // - contains expanded message

    CBanner();
    doDecodeMessage( msgbuf, msgnum );
    return FormatMsg( pbuf, msgbuf, args );
}


static IDEBool __stdcall idePrt // PRINT FOR IDE
    ( IDECBHdl hdl              // - handle
    , IDEMsgInfo *info )        // - information
{
    char buffer[512];           // - buffer

    if( err_file == NULL ) {
        ErrFileOpen();
    }
    if( err_file != NULL ) {
        CompFlags.errfile_written = 1;
        IdeMsgFormat( hdl
                    , info
                    , buffer
                    , sizeof( buffer )
                    , &idePrt );
        fputs( buffer, err_file );
        fputc( '\n', err_file );
    }
    return 0;
}


static void ideDisplay          // DISPLAY USING IDE INTERFACE
    ( IDEMsgSeverity severity   // - message severity
    , MSG_NUM msgnum            // - message number
    , char* msg                 // - message
    , TOKEN_LOCN* msg_locn )    // - message location or NULL
{
    IDECallBacks* cbs;          // - pointer to call backs
    IDEMsgInfo inf;             // - message information
    char *fname;                // - file name
    boolean goes_in_err_file;   // - output msg into .err file

    IdeMsgInit( &inf, severity, msg );
    IdeMsgSetMsgNo( &inf, msgnum );
    IdeMsgSetHelp( &inf, "wpperrs.hlp", msgnum + 1 );
    if( CompFlags.ew_switch_used ) {
        IdeMsgSetReadable( &inf );
    }
    if( NULL != msg_locn ) {
        if( msg_locn->src_file != NULL ) {
            fname = fileName( msg_locn->src_file );
            IdeMsgSetSrcFile( &inf, fname );
            IdeMsgSetSrcLine( &inf, msg_locn->line );
            IdeMsgSetSrcColumn( &inf, msg_locn->column );
        }
        notes_locn = *msg_locn;
    }
    goes_in_err_file = FALSE;
    switch( severity ) {
    case IDEMSGSEV_WARNING:
    case IDEMSGSEV_ERROR:
    case IDEMSGSEV_NOTE:
        goes_in_err_file = TRUE;
        break;
    case IDEMSGSEV_BANNER:
    case IDEMSGSEV_DEBUG:
        break;
    case IDEMSGSEV_NOTE_MSG:
        if( CompFlags.log_note_msgs ) {
            goes_in_err_file = TRUE;
        }
        break;
    DbgDefault( "unknown severity" );
    }
    cbs = CompInfo.dll_callbacks;
    if( goes_in_err_file ) {
        if( ! ( CompFlags.eq_switch_used && CompFlags.ide_console_output ) ) {
            (*cbs->PrintWithInfo)( CompInfo.dll_handle, &inf );
        }
        idePrt( CompInfo.dll_handle, &inf );
    } else {
        (*cbs->PrintWithInfo)( CompInfo.dll_handle, &inf );
    }
}


static void setMsgLocation      // SET LOCATION FOR MESSAGE
    ( CTX context )             // - current context
{
    switch( context ) {
      case CTX_FINI :
      case CTX_FUNC_GEN :
      case CTX_CG_FUNC :
      case CTX_CG_OPT :
      case CTX_ENDFILE :
        if( CompFlags.ew_switch_used ) {
      // drops thru
      case CTX_INIT :
      case CTX_CMDLN_ENV :
      case CTX_CMDLN_PGM :
      case CTX_CMDLN_VALID :
            err_locn.src_file = NULL;
            break;
        }
        // drops thru
      case CTX_FORCED_INCS :
      case CTX_SOURCE :
        if( err_locn.src_file == NULL ) {
            if( SrcFilesOpen() ) {
                SrcFileGetTokenLocn( &err_locn );
            } else {
                err_locn.line = SrcLineCount;
                err_locn.column = 0;
                err_locn.src_file = SrcFileCurrent();
            }
        }
        break;
    }
}


void MsgDisplay                 // DISPLAY A MESSAGE
    ( IDEMsgSeverity severity   // - message severity
    , MSG_NUM msgnum            // - message number
    , va_list args )            // - substitution arguments
{

    VBUF buffer;                // - formatting buffer
    SYMBOL sym;                 // - sym requiring location
    TOKEN_LOCN prt_locn;        // - print location
    TOKEN_LOCN *msg_locn;       // - message location
    CTX context;                // - current context
    void *inf;                  // - information about context
    char *inf_prefix;           // - prefix for information
    boolean context_changed;    // - TRUE ==> new context from last time

    context_changed = CtxCurrent( &context, &inf, &inf_prefix );
    setMsgLocation( context );
    prt_locn = err_locn;
    ++reserveDepth;
    VbufInit( &buffer );
    VStrNull( &buffer );
    sym = msgBuild( msgnum, args, &buffer );
    switch( severity ) {
      case IDEMSGSEV_ERROR :
      case IDEMSGSEV_WARNING :
        if( CompFlags.ew_switch_used ) {
            switch( context ) {
              case CTX_INIT :
              case CTX_FINI :
              case CTX_CMDLN_VALID :
              case CTX_CG_OPT :
              case CTX_ENDFILE :
                if( context_changed ) {
                    fmt_inf_hdr( inf_prefix );
                }
                break;
              case CTX_CMDLN_ENV :
              case CTX_CMDLN_PGM :
                if( context_changed ) {
                    fmt_inf_hdr_switch( inf_prefix, inf );
                }
                break;
              case CTX_CG_FUNC :
              case CTX_FUNC_GEN :
                if( context_changed ) {
                    fmt_inf_hdr_sym( inf_prefix, inf );
                }
                break;
              case CTX_FORCED_INCS :
              case CTX_SOURCE :
                build_file_nesting();
                break;
              DbgDefault( "Unexpected message context" );
            }
        }
        msg_locn = &prt_locn;
        break;
      case IDEMSGSEV_NOTE :
      case IDEMSGSEV_NOTE_MSG :
        msg_locn = &notes_locn;
        break;
      default :
        msg_locn = NULL;
        break;
    }
    ideDisplay( severity
              , msgnum
              , buffer.buf
              , msg_locn );
    if( context_changed
     && ! CompFlags.ew_switch_used
     && ( severity == IDEMSGSEV_ERROR
       || severity == IDEMSGSEV_WARNING )
     && ( context == CTX_SOURCE
       || context == CTX_FORCED_INCS )
      ) {
        build_file_nesting();
    }
    VbufFree( &buffer );
    --reserveDepth;
    if( NULL != sym ) {
        notes_locn = sym->locn->tl;
        MsgDisplayArgs( IDEMSGSEV_NOTE
                      , SymIsFunctionTemplateModel( sym )
                            ? INF_TEMPLATE_FN_DECL : INF_SYMBOL_DECLARATION
                      , sym
                      , &sym->locn->tl );
    }
}


void MsgDisplayArgs             // DISPLAY A MESSAGE WITH ARGS
    ( IDEMsgSeverity severity   // - message severity
    , MSG_NUM msgnum            // - message number
    , ... )                     // - arguments
{
    va_list args;

    va_start( args, msgnum );
    MsgDisplay( severity, msgnum, args );
    va_end( args );
}


void MsgDisplayLine             // DISPLAY A BARE LINE
    ( char* line )              // - the line
{
    ideDisplay( IDEMSGSEV_NOTE_MSG, 0, line, NULL );
}


void MsgDisplayLineArgs         // DISPLAY A BARE LINE, FROM ARGUMENTS
    ( char* seg                 // - the line segments
    , ... )
{
    va_list args;               // - arg list
    char* str;                  // - current segment
    VBUF buffer;                // - buffer

    VbufInit( &buffer );
    VStrNull( &buffer );
    va_start( args, seg );
    for( str = seg; str != NULL; str = va_arg( args, char* ) ) {
        VStrConcStr( &buffer, str );
    }
    ideDisplay( IDEMSGSEV_NOTE_MSG, 0, buffer.buf, NULL );
    va_end( args );
    VbufFree( &buffer );
}


void MsgDisplayBanner           // DISPLAY A BANNER LINE
    ( char* line )              // - the line
{
    ideDisplay( IDEMSGSEV_BANNER, 0, line, NULL );
}


void AddNoteMessage(            // ADD A NOTE TO A MESSAGE
    MSG_NUM msg_num,            // - message number
    ... )                       // - error message arguments
{
    va_list args;

    va_start( args, msg_num );
    MsgDisplay( IDEMSGSEV_NOTE, msg_num, args );
    va_end( args );
}


static void prtMsg(             // PRINT A MESSAGE
    int warn_level,             // - warning level
    MSG_NUM msgnum,             // - message number
    va_list args,               // - substitution arguments
    unsigned warn_inc )         // - amount to inc WngCount
{
    IDEMsgSeverity severity;    // - message severity

    if( CompFlags.cpp_output )  return;
    if( warn_level == -1 ) {
        err_locn = notes_locn;
        severity = IDEMSGSEV_NOTE;
    } else if( warn_level == 0 ) {
        ++ErrCount;
        severity = IDEMSGSEV_ERROR;
    } else {
        WngCount += warn_inc;
        severity = IDEMSGSEV_WARNING;
    }
    MsgDisplay( severity, msgnum, args );
    if( warn_level != -1 && msgnum != ERR_EXCEEDED_LIMIT ) {
        CtxPostContext();
    }
}


static void errFileErase(       // ERASE ERROR FILE
    const char *name )          // - file name
{
    if( name != NULL ) {
        remove( name );
    }
}

static void reserveRelease( void )
{
    void *p;

    if( reserveDepth == 0 ) {
        return;
    }
    p = reserveMem;
    if( p != NULL ) {
        reserveMem = NULL;
        CMemFree( p );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?