message.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,030 行 · 第 1/2 页
C
1,030 行
if( reserveSize > RESERVE_MIN ) {
reserveSize >>= 1;
reserveMem = CMemAlloc( reserveSize );
}
}
}
void ErrFileOpen( // OPEN ERROR FILE
void )
{
char *buf; // - file name
if( CompFlags.errfile_opened ) return;
if( SrcFName != NULL ) {
// we want to keep retrying until we get a source file name
CompFlags.errfile_opened = TRUE;
buf = IoSuppOutFileName( OFT_ERR );
if( buf != NULL ) {
errFileErase( buf );
err_file = SrcFileFOpen( buf, SFO_WRITE_TEXT );
if( err_file != NULL ) {
IoSuppSetBuffering( err_file, 128 );
}
}
}
}
void RegisterSuicideCallback( // REGISTER A FUNCTION TO BE CALLED BEFORE CSuicide
SUICIDE_CALLBACK *ctl ) // - call-back control block
{
RingAppend( &suicideCallbacks, ctl );
}
void CSuicide( // COMMIT SUICIDE
void )
{
void *env;
SUICIDE_CALLBACK *ctl;
DbgStmt( if( DEBUG_PRESENT_NAME ) __trap() );
CompFlags.compile_failed = TRUE;
if( Environment ) {
env = Environment;
Environment = NULL;
RingIterBeg( suicideCallbacks, ctl ) {
ctl->call_back();
} RingIterEnd( ctl )
longjmp( env, 1 );
}
CppExit(1);
}
void SetErrLoc( // SET ERROR LOCATION
TOKEN_LOCN *locn ) // - error location
{
if( locn == NULL ) {
err_locn.src_file = NULL;
} else {
err_locn = *locn;
}
}
static boolean okToPrintMsg // SEE IF OK TO PRINT MESSAGE
( MSG_NUM msgnum // - message number
, int *plevel ) // - addr[ level ]
{
boolean print_err;
int level;
print_err = TRUE;
level = msg_level[ msgnum ] & 0x0F;
switch( msg_level[ msgnum ] >> 4 ) {
case MSG_TYPE_INFO :
level = -1;
break;
case MSG_TYPE_ANSIERR :
case MSG_TYPE_ANSIWARN :
print_err = ! CompFlags.extensions_enabled;
break;
case MSG_TYPE_ANSI :
if( ! CompFlags.extensions_enabled ) {
level = 0;
}
break;
case MSG_TYPE_WARNING :
case MSG_TYPE_ERROR :
break;
}
*plevel = level;
return( print_err );
}
boolean MsgWillPrint( // TEST WHETHER A MESSAGE WILL BE SEEN
MSG_NUM msgnum ) // - message number
{
int level; // - warning level of message
if( ! okToPrintMsg( msgnum, &level ) ) {
return( FALSE );
}
return( level <= WngLevel );
}
static msg_status_t doError( // ISSUE ERROR
MSG_NUM msgnum, // - message number
va_list args, // - varargs
unsigned warn_inc ) // - amount to inc WngCount (if warning)
{
msg_status_t retn; // - message status
int level; // - warning level of message
struct {
unsigned print_err : 1; // - TRUE ==> print the message
unsigned too_many : 1; // - TRUE ==> too many messages
} flag;
#ifndef NDEBUG
fflush(stdout);
fflush(stderr);
#endif
retn = MS_NULL;
if( ! errLimitExceeded ) {
flag.too_many = TRUE;
flag.print_err = okToPrintMsg( msgnum, &level );
if( ErrLimit == -1 ) {
/* unlimited messages */
flag.too_many = FALSE;
} else if( ErrCount < ErrLimit ) {
/* haven't hit the limit */
flag.too_many = FALSE;
} else if( msgnum == ERR_EXCEEDED_LIMIT ) {
/* we hit the limit and we want to diagnose the condition */
flag.too_many = FALSE;
} else if( ErrCount == ErrLimit ) {
/* have hit the limit */
if( !flag.print_err || level != 0 ) {
/* this message isn't an error; it's a warning or info */
flag.too_many = FALSE;
}
}
if( ! flag.too_many ) {
if( flag.print_err && ( level <= WngLevel ) ) {
prtMsg( level, msgnum, args, warn_inc );
retn |= MS_PRINTED;
}
if( level != 0 ) {
/* useful if ANSI requires error but is usually a warning */
retn |= MS_WARNING;
}
} else {
CErr( ERR_EXCEEDED_LIMIT );
errLimitExceeded = TRUE;
CSuicide();
}
}
/* turn off SetErrLoc setting */
err_locn.src_file = NULL;
return retn;
}
msg_status_t CErr( // ISSUE ERROR
MSG_NUM msgnum, // - message number
... ) // - parameters for error
{
va_list args;
msg_status_t s;
va_start( args, msgnum );
s = doError( msgnum, args, 1 );
va_end( args );
return( s );
}
msg_status_t CWarnDontCount( // ISSUE WARNING BUT DON'T COUNT IT
MSG_NUM msgnum, // - message number
... ) // - parameters for warning
{
va_list args;
msg_status_t s;
va_start( args, msgnum );
s = doError( msgnum, args, 0 );
va_end( args );
return( s );
}
msg_status_t CErr1( // ISSUE ERROR (NO PARAMETERS)
MSG_NUM msgnum ) // - message number
{
return CErr( msgnum );
}
msg_status_t CErr2( // ISSUE ERROR (int PARAMETER)
MSG_NUM msgnum, // - message number
int p1 ) // - parameter
{
return CErr( msgnum, p1 );
}
msg_status_t CErr2p( // ISSUE ERROR (char* PARAMETER)
MSG_NUM msgnum, // - message number
void const *p1 ) // - parameter
{
return CErr( msgnum, p1 );
}
void CFatal( // ISSUE ERROR AND COMMIT SUICIDE
char *msg ) // - error message
{
CErr2p( ERR_FATAL_ERROR, msg );
CSuicide();
}
void InfMsgPtr( // INFORMATION MESSAGE, PTR ARG.
MSG_NUM msgnum, // - message number
void const *p1 ) // - extra information
{
CErr( msgnum, p1 );
}
void InfMsgInt( // INFORMATION MESSAGE, INT ARG.
MSG_NUM msgnum, // - message number
int p1 ) // - extra information
{
CErr( msgnum, p1 );
}
void CErrCheckpoint(
error_state_t *save )
{
*save = ErrCount;
}
boolean CErrOccurred(
error_state_t *previous_state )
{
if( *previous_state != ErrCount ) {
return( TRUE );
}
return( FALSE );
}
static boolean warnLevelValidate( // VALIDATE WARNING LEVEL
int level ) // - level to be validated
{
boolean retn; // - return: TRUE ==> good level
if( ( level < 0 )
||( level > 9 ) ) {
CErr1( ERR_PRAG_WARNING_BAD_LEVEL );
retn = FALSE;
} else {
retn = TRUE;
}
return retn;
}
static void changeLevel( // EFFECT A LEVEL CHANGE
int level, // - new level
MSG_NUM msgnum ) // - message number
{
DbgAssert( msgnum < ARRAY_SIZE( msg_level ) );
if( NULL == orig_err_levs ) {
orig_err_levs = CMemAlloc( sizeof( msg_level ) );
memcpy( orig_err_levs, msg_level, sizeof( msg_level ) );
}
msg_level[ msgnum ] = ( msg_level[ msgnum ] & 0xF0 ) + level;
}
void WarnChangeLevel( // CHANGE WARNING LEVEL FOR A MESSAGE
int level, // - new level
MSG_NUM msgnum ) // - message number
{
if( msgnum >= ARRAY_SIZE( msg_level ) ) {
CErr2( ERR_PRAG_WARNING_BAD_MESSAGE, msgnum );
return;
}
switch( msg_level[ msgnum ] >> 4 ) {
case MSG_TYPE_ERROR :
case MSG_TYPE_INFO :
case MSG_TYPE_ANSIERR :
CErr2( ERR_PRAG_WARNING_BAD_MESSAGE, msgnum );
break;
case MSG_TYPE_WARNING :
case MSG_TYPE_ANSI :
case MSG_TYPE_ANSIWARN :
changeLevel( level, msgnum );
break;
}
}
void WarnChangeLevels( // CHANGE WARNING LEVELS FOR ALL MESSAGES
int level ) // - new level
{
MSG_NUM index; // - index for number
if( warnLevelValidate( level ) ) {
for( index = 0
; index < ARRAY_SIZE( msg_level )
; ++ index ) {
switch( msg_level[ index ] >> 4 ) {
case MSG_TYPE_WARNING :
case MSG_TYPE_ANSI :
case MSG_TYPE_ANSIWARN :
changeLevel( level, index );
break;
}
}
}
}
void InfClassDecl( // GENERATE CLASS-DECLARATION NOTE
TYPE cltype ) // - a class type
{
TOKEN_LOCN* locn; // - location for class definition
cltype = ClassTypeForType( cltype );
locn = LocnForClass( cltype );
if( NULL != locn ) {
CErr( INF_CLASS_DECLARATION
, cltype->u.c.info->name
, locn );
}
}
void InfMacroDecl( // GENERATE MACRO-DECLARATION NOTE
void* parm ) // - macro definition
{
MEPTR mdef; // - macro definition
mdef = parm;
if( mdef->macro_flags & MACRO_USER_DEFINED ) {
CErr( INF_MACRO_DECLARATION, mdef->macro_name, &mdef->defn );
}
}
void InfSymbolDeclaration( // GENERATE SYMBOL-DECLARATION NOTE
SYMBOL sym ) // - a symbol
{
CErr( SymIsFunctionTemplateModel( sym )
? INF_TEMPLATE_FN_DECL : INF_SYMBOL_DECLARATION
, sym
, &sym->locn->tl );
}
void InfSymbolAmbiguous( // GENERATE SYMBOL-AMBIGUITY NOTE
SYMBOL sym ) // - a symbol
{
CErr( SymIsFunctionTemplateModel( sym )
? INF_TEMPLATE_FN_AMBIGUOUS : INF_FUNC_AMBIGUOUS
, sym
, &sym->locn->tl );
}
void InfSymbolRejected( // GENERATE SYMBOL-REJECTION NOTE
SYMBOL sym ) // - a symbol
{
CErr( SymIsFunctionTemplateModel( sym )
? INF_TEMPLATE_FN_REJECTED : INF_FUNC_REJECTED
, sym
, &sym->locn->tl );
}
static void openDefFile( void )
{
char *def_fname;
if( SrcFName != NULL ) {
def_fname = IoSuppOutFileName( OFT_DEF );
errFileErase( def_fname );
DefFile = SrcFileFOpen( def_fname, SFO_WRITE_TEXT );
if( DefFile != NULL ) {
IoSuppSetBuffering( DefFile, 128 );
}
}
}
void DefAddPrototype( // ADD PROTOTYPE FOR SYMBOL TO .DEF FILE
SYMBOL fn ) // - function
{
VBUF proto;
if( DefFile == NULL ) {
openDefFile();
}
if( DefFile == NULL ) {
return;
}
if( SymIsFnTemplateMatchable( fn ) ) {
return;
}
if( fn->id == SC_STATIC ) {
return;
}
if( CompFlags.use_base_types ) {
FormatFnDefn( fn, &proto );
} else {
FormatFnDefnWithTypedefs( fn, &proto );
}
fprintf( DefFile
, "//#line \"%s\" %u\n"
, fileName( fn->locn->tl.src_file )
, fn->locn->tl.line );
fprintf( DefFile, "extern %s;\n", proto.buf );
VbufFree( &proto );
}
unsigned ErrPCHVersion( // PROVIDE A VERSION NUMBER FOR THE ERROR MESSAGES
void )
{
return sizeof( msg_level );
}
static void errFileInit( // INITIALIZE FOR NO ERROR FILE
INITFINI* defn ) // - definition
{
defn = defn;
errLimitExceeded = FALSE;
err_file = NULL;
err_locn.src_file = NULL;
suicideCallbacks = NULL;
orig_err_levs = NULL;
reserveSize = RESERVE_MAX;
reserveMem = CMemAlloc( reserveSize );
CMemRegisterCleanup( reserveRelease );
internationalData = LoadInternationalData( INTL_NAME );
}
static void errFileFini( // CLOSE ERROR FILE
INITFINI* defn ) // - definition
{
defn = defn;
if( IoSuppCloseFile( &err_file ) ) {
if( ! CompFlags.errfile_written ) {
errFileErase( IoSuppOutFileName( OFT_ERR ) );
}
}
CMemFree( ErrorFileName );
CMemFreePtr( &reserveMem );
if( NULL != orig_err_levs ) {
memcpy( msg_level, orig_err_levs, sizeof( msg_level ) );
CMemFreePtr( &orig_err_levs );
}
FreeInternationalData( internationalData );
}
INITDEFN( error_file, errFileInit, errFileFini )
pch_status PCHReadErrWarnData( void )
{
char tmp_buff[ sizeof( msg_level ) ];
char *pch_levels;
char *orig_levels;
char *p;
char *o;
char *stop;
PCHReadLocSize( pch_levels, tmp_buff, sizeof( msg_level ) );
if( NULL != orig_err_levs ) {
orig_levels = orig_err_levs;
} else {
orig_levels = msg_level;
}
stop = &pch_levels[ sizeof( msg_level ) ];
for( p = pch_levels, o = orig_levels; p < stop; ++p, ++o ) {
if( *p != *o ) {
// reflect a change from the header file into current levels
changeLevel( *p & 0x0f, p - pch_levels );
}
}
return( PCHCB_OK );
}
pch_status PCHWriteErrWarnData( void )
{
// NYI: save snapshot of msg_level before header file is read
// so that we can write out a msg_level that indicates the
// changes made by the header file
PCHWrite( msg_level, sizeof( msg_level ) );
return( PCHCB_OK );
}
pch_status PCHInitErrWarnData( boolean writing )
{
writing = writing;
return( PCHCB_OK );
}
pch_status PCHFiniErrWarnData( boolean writing )
{
writing = writing;
return( PCHCB_OK );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?