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 = ¬es_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 + -
显示快捷键?