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