msg.c

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

C
599
字号
/****************************************************************************
*
*                            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:  Message formatting and output for wmake.
*
****************************************************************************/


#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

#include "make.h"
#include "massert.h"
#include "mrcmsg.h"
#include "msg.h"
#include "mstream.h"
#include "mtypes.h"

STATIC const char   *logName;
STATIC int          logFH;

typedef union msg_arg {
    UINT16      ui16;
    UINT32      ui32;
    int         i;
    char        *cp;
    char FAR    *cfp;
} MSG_ARG;

STATIC MSG_ARG  ArgValue[2];
STATIC int      USEARGVALUE = 0;    /* set to non_zero if ArgValue is used */

/*
 * now we do some pre-processor magic, and build msgText[]
 */
#undef pick
#define pick( num, string ) string

STATIC const char FAR * const FAR msgText[] = {
#include "msg.h"


STATIC void reOrder( va_list args, char *paratype )
/*************************************************/
{
    int         i;

    for( i = 1; i >= 0 && *paratype != '\0'; --i ) {
        switch( *paratype++ ) {
        case 'D':
        case 'd':
        case 'x':
            ArgValue[i].ui16 = (UINT16)va_arg( args, unsigned );
            break;
        case 'C':
        case 'c':
        case 'M':
            ArgValue[i].i = (UINT16)va_arg( args, unsigned );
            break;
        case 'E':
        case 's':
        case '1':
        case '2':
            ArgValue[i].cp = va_arg( args, char * );
            break;
        case 'F':
            ArgValue[i].cfp = va_arg( args, char FAR * );
            break;
        case 'l':
            ArgValue[i].ui32 = va_arg( args, UINT32 );
            break;
        }
    }
}


STATIC void positnArg( va_list args, UINT16 size )
/*************************************************
 * the reordered parameter are passed to FmtStr as a union of 4 bytes.
 * so we have to take two more bytes out for int, char *, etc, when we use
 * va_arg().
 */
{
    UINT16      i; /* to avoid a compiler warning */

    if( USEARGVALUE && ( size < (UINT16)sizeof(MSG_ARG) ) ) {
        i = (UINT16)va_arg( args, unsigned );
    }
}


/*
 *  These str routines are support routines for doFmtStr.  They return a
 *  pointer to where the null-terminator for dest should be.  (Not all of
 *  them null terminate their result).
 */

STATIC char *strApp( char *dest, const char *src )
/************************************************/
{
    assert( dest != NULL && src != NULL );

    while( (*dest = *src) ) {
        ++dest;
        ++src;
    }
    return( dest );
}


STATIC char *strDec( char *dest, UINT16 num )
/*******************************************/
{
    char    *orig;
    char    *str;
    div_t   res;

    assert( dest != NULL );

    orig = dest;
    str = dest + 5;
    res.quot = num;
    do {
        ++dest;
        res = div( res.quot, 10 );
        *--str = '0' + res.rem;
    } while( res.quot != 0 );

    while( dest >= orig ) {
        *orig++ = *str++;
    }

    return( dest );
}


#ifdef CACHE_STATS
STATIC char *strDecL( char *dest, UINT32 num )
/********************************************/
{
    char    *orig;
    char    *str;
    ldiv_t  res;

    assert( dest != NULL );

    orig = dest;
    str = dest + 10;
    res.quot = num;
    do {
        ++dest;
        res = ldiv( res.quot, 10 );
        *--str = '0' + res.rem;
    } while( res.quot != 0 );

    while( dest >= orig ) {
        *orig++ = *str++;
    }

    return( dest );
}
#endif


STATIC char *strHex( char *dest, UINT16 num )
/*******************************************/
{
    int     digits;
    char    *str;

    assert( dest != NULL );

    digits = (num > 0xff) ? 4 : 2;

    dest += digits;
    str = dest;
    while( digits > 0 ) {
        *--str = "0123456789abcdef"[num & 0x0f];
        num >>= 4;
        --digits;
    }

    return( dest );
}


#ifdef USE_FAR
STATIC char *fStrApp( char *dest, const char FAR *fstr )
/******************************************************/
{
    assert( dest != NULL && fstr != NULL );

    while( *dest = *fstr ) {
        ++dest;
        ++fstr;
    }
    return( dest );
}
#else
#   define fStrApp( n, f )  strApp( n, f )
#endif


STATIC char *strDec2( char *dest, UINT16 num )
/********************************************/
{
    div_t   res;

    assert( dest != NULL );

    res = div( num % 100, 10 );
    *dest++ = res.quot + '0';
    *dest++ = res.rem + '0';
    return( dest );
}

STATIC char *strDec5( char *dest, UINT16 num )
/********************************************/
{
    div_t   res;
    char    *temp;

    assert( dest != NULL );


    temp = dest + 4;
    res.quot = num;
    while( temp >= dest ) {
        res = div( res.quot, 10 );
        *temp = res.rem + '0';
        --temp;
    }
    return( dest + 5 );
}


STATIC size_t doFmtStr( char *buff, const char FAR *src, va_list args )
/**********************************************************************
 * quick vsprintf routine
 * assumptions - format string does not end in '%'
 *             - only use of '%' is as follows:
 *  %D  : decimal with leading 0 modulo 100 ie: %02d
 *  %C  : 'safe' character ie: if(!isprint) then do %x
 *  %E  : envoloped string ie: "(%s)"
 *  %F  : far string
 *  %L  : long string ( the process exits here to let another function to
          print the long string. Trailing part must be printed
          using other calls. see printMac()@macros. )
 *  %M  : a message number from msgText
 *  %Z  : strerror( errno ) - print a system error
 *  %c  : character
 *  %d  : decimal
 *  %l  : long decimal  ( only if -dCACHE_STATS )
 *  %s  : string
 *  %1  : string
 *  %2  : string
 *  %x  : hex number (2 or 4 digits)
 *  %anything else : %anything else
 */
{
    char        ch;
    char        *dest;
    char        msgbuff[MAX_RESOURCE_SIZE];

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

    dest = buff;
    for( ;; ) {
        ch = *src++;
        if( ch == NULLCHAR ) {
            break;

⌨️ 快捷键说明

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