msg.c

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

C
599
字号
        }
        if( ch != '%' ) {
            *dest++ = ch;
        } else {
            ch = *src++;
            switch( ch ) {
                /* case statements are sorted in ascii order */
            case 'D' :
                dest = strDec2( dest, (UINT16)va_arg( args, unsigned ) );
                positnArg( args, (UINT16)sizeof( UINT16 ) );
                break;
            case 'C' :
                ch = va_arg( args, int );
                positnArg( args, (UINT16)sizeof( int ) );
                if( isprint( ch ) ) {
                    *dest++ = ch;
                } else {
                    dest = strHex( strApp( dest, "0x" ), (UINT16)ch );
                }
                break;
            case 'E' :
                *dest++ = '(';
                dest = strApp( dest, va_arg( args, char * ) );
                positnArg( args, (UINT16)sizeof( char * ) );
                *dest++ = ')';
                break;
            case 'F' :
                dest = fStrApp( dest, va_arg( args, char FAR * ) );
                positnArg( args, (UINT16)sizeof( char FAR * ) );
                break;
            case 'L' :
                *dest = NULLCHAR;
                return( dest - buff );
                break;
            case 'M' :
                MsgGet( va_arg( args, int ), msgbuff );
                positnArg( args, (UINT16)sizeof( int ) );
                dest = fStrApp( dest, msgbuff );
                break;
            case 'Z' :
#if defined( __DOS__ )
                MsgGet( SYS_ERR_0 + errno, msgbuff );
#else
                strcpy( msgbuff, strerror( errno ) );
#endif
                dest = strApp( dest, msgbuff );
                break;
            case 'c' :
                *dest++ = va_arg( args, int );
                positnArg( args, (UINT16)sizeof( int ) );
                break;
            case 'd' :
                dest = strDec( dest, (UINT16)va_arg( args, unsigned ) );
                positnArg( args, (UINT16)sizeof( UINT16 ) );
                break;
#ifdef CACHE_STATS
            case 'l' :
                dest = strDecL( dest, va_arg( args, UINT32 ) );
                positnArg( args, (UINT16)sizeof( UINT32 ) );
                break;
#endif
            case 's' :
            case '1' :
            case '2' :
                dest = strApp( dest, va_arg( args, char * ) );
                positnArg( args, (UINT16)sizeof( char * ) );
                break;
            case 'u' :
                dest = strDec5( dest, (UINT16)va_arg( args, unsigned ) );
                positnArg( args, (UINT16)sizeof( UINT16 ) );
                break;
            case 'x' :
                dest = strHex( dest, (UINT16)va_arg( args, unsigned ) );
                positnArg( args, (UINT16)sizeof( UINT16 ) );
                break;
            default :
                *dest++ = ch;
                break;
            }
        }
    }
    *dest = NULLCHAR;
    return( dest - buff );
}


extern size_t FmtStr( char *buff, const char *fmt, ... )
/*******************************************************
 * quick sprintf routine... see doFmtStr
 */
{
    va_list args;

    assert( buff != NULL && fmt != NULL );

    va_start( args, fmt );
    return( doFmtStr( buff, fmt, args ) );
}


STATIC void logWrite( const char *buff, size_t len )
/**************************************************/
{
    if( logFH != -1 ) {
        write( logFH, buff, len );
    }
}


#ifdef __WATCOMC__
#pragma on (check_stack);
#endif
extern void PrtMsg( enum MsgClass num, ... )
/*******************************************
 * report a message with various format options
 */
{
    va_list         args;
    char            buff[1024];
    enum MsgClass   pref = M_ERROR;
    unsigned        len;
    unsigned        class;
    const char      *fname;
    UINT16          fline;
    int             fh;
    char            wefchar = 'F';    /* W, E, or F */
    char            *str;
    char            msgbuff[MAX_RESOURCE_SIZE];
    char            *paratype;

    if( !Glob.debug && (num & DBG) ) {
        return;
    }

    len = 0;

    if( (num & LOC) && GetFileLine( &fname, &fline ) == RET_SUCCESS ) {
        if( fname != NULL ) {
            len += FmtStr( &buff[len], "%s", fname );
        }
        if( fline != 0 ) {
            len += FmtStr( &buff[len], "(%d)", fline );
        }
        if( len > 0 ) {
            len += FmtStr( &buff[len], ": " );
        }
    }

    class = num & CLASS_MSK;
    switch( class ) {
    case INF & CLASS_MSK:
        fh = STDOUT;
        break;
    default:
        fh = STDERR;
        switch( class ) {
        case WRN & CLASS_MSK:
            wefchar = 'W';
            pref = M_WARNING;
            break;
        case ERR & CLASS_MSK:
            Glob.erroryet = TRUE;
            wefchar = 'E';
            pref = M_ERROR;
            break;
        case FTL & CLASS_MSK:
            Glob.erroryet = TRUE;
            wefchar = 'F';
            pref = M_ERROR;
            break;
        }
        if( !( num & PRNTSTR ) ) {
            len += FmtStr( &buff[len], "%M(%c%D): ", pref, wefchar,
                num & NUM_MSK );
        }
        break;
    }

    Header();

    /*
     * print the leader to our message, if any... do this now because it
     * may contain a long filename, and we don't want to overwrite the stack
     * with the doFmtStr() substitution.
     */
    if( len > 0 ) {
        if( fh == STDERR ) {
            logWrite( buff, len );
        }
        write( fh, buff, len );
    }

    va_start( args, num );
    if( num & PRNTSTR ) {       /* print a big string */
        str = va_arg( args, char * );

        if( fh == STDERR ) {
            logWrite( str, strlen( str ) );
        }
        write( fh, str, strlen( str ) );
        len = 0;
    } else {                    /* print a formatted string */
        if( ( num & NUM_MSK ) >= END_OF_RESOURCE_MSG ) {
            len = doFmtStr( buff, msgText[(num&NUM_MSK)-END_OF_RESOURCE_MSG],
                                                                args );
        } else if( MsgReOrder( num & NUM_MSK, msgbuff, &paratype ) ) {
            USEARGVALUE = 1;
            reOrder( args, paratype ); /* reposition the parameters */
            len = FmtStr( buff, msgbuff, ArgValue[0], ArgValue[1] );
            USEARGVALUE = 0;
        } else {
            len = doFmtStr( buff, msgbuff, args );
        }
    }
    if( !(num & NEOL) ) {
        buff[len++] = EOL;
    }
    if( fh == STDERR ) {
        logWrite( buff, len );
    }
    write( fh, buff, len );
    if( !Glob.microsoft && ( num == ( CANNOT_NEST_FURTHER | FTL | LOC ) ||
                             num == ( IGNORE_OUT_OF_PLACE_M | ERR | LOC ))) {
        PrtMsg( WRN | LOC | MICROSOFT_MAKEFILE );
    }
    if( class == ( FTL & CLASS_MSK ) ) {
        exit( ExitSafe( EXIT_FATAL ) );
    }
}
#ifdef __WATCOMC__
#pragma off(check_stack);
#endif


extern void Usage( void )
/***********************/
{
    char        msgbuff[MAX_RESOURCE_SIZE];
    int         i;

    for( i = USAGE_BASE;; i++ ) {
        MsgGet( i, msgbuff );
        if( ( msgbuff[0] == '.' ) && ( msgbuff[1] == 0 ) ) {
            break;
        }
        PrtMsg( INF | PRNTSTR, msgbuff );
    }
    exit( ExitSafe( EXIT_OK ) );
}


#ifdef __WATCOMC__
#pragma on (check_stack);
#endif
extern BOOLEAN GetYes( enum MsgClass querymsg )
/**********************************************
 * ask question, and return true if user responds 'y', else false
 * You should phrase the question such that the default action is the least
 * damaging (ie: the 'no' action is least damaging).
 */
{
    char    buf[LINE_BUFF];

    PrtMsg( INF | NEOL | STRING_YES_NO, querymsg );

    if( read( STDIN, buf, LINE_BUFF ) == 0 ) {
        return( FALSE );
    }

    return( toupper( buf[0] ) == YES_CHAR );
}
#ifdef __WATCOMC__
#pragma off(check_stack);
#endif


extern void LogInit( const char *name )
/**************************************
 * assumes name points to static memory
 */
{
    logName = name;
    logFH = -1;
    if( name != NULL ) {
        logFH = open( logName, O_WRONLY | O_APPEND | O_CREAT | O_TEXT,
                  S_IWRITE | S_IREAD );
    }
    return;
}


extern void LogFini( void )
/*************************/
{
    if( logFH != -1 ) {
        close( logFH );
    }
}

⌨️ 快捷键说明

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