prtf.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,101 行 · 第 1/3 页
C
1,101 行
ctl++;
break;
case 'h':
if( ctl[1] == 'h' ) {
specs->_flags |= SPF_CHAR;
ctl += 2;
break;
}
specs->_flags |= SPF_SHORT;
ctl++;
break;
#if defined( __LONG_LONG_SUPPORT__ )
case 'I':
if(( ctl[1] == '6' ) && ( ctl[2] == '4' )) {
specs->_flags |= SPF_LONG_LONG;
ctl += 3;
}
break;
JSPEC_CASE_LLONG
/* fall through */
#endif
case 'L':
specs->_flags |= SPF_LONG_DOUBLE | SPF_LONG_LONG;
ctl++;
break;
#if defined( __FAR_SUPPORT__ )
case 'F': /* conflicts with ISO-defined 'F' conversion */
/* fall through */
#endif
case 'W': /* 8086 specific flag for FAR pointer */
specs->_flags |= SPF_FAR;
ctl++;
break;
case 'N': /* 8086 specific flag for NEAR pointer */
specs->_flags |= SPF_NEAR;
ctl++;
break;
#if defined( TSPEC_IS_INT ) || defined( ZSPEC_IS_INT )
TSPEC_CASE_INT /* If either 't' or 'z' spec corresponds to 'int', */
ZSPEC_CASE_INT /* we need to parse and ignore the spec. */
ctl++;
break;
#endif
}
return( ctl );
}
static const CHAR_TYPE *evalflags( const CHAR_TYPE *ctl, SPECS __SLIB *specs )
{
specs->_flags = 0;
for( ; ; ctl++ ) {
if( *ctl == '-' ) {
specs->_flags |= SPF_LEFT_ADJUST;
} else if( *ctl == '#' ) {
specs->_flags |= SPF_ALT;
} else if( *ctl == '+' ) {
specs->_flags |= SPF_FORCE_SIGN;
specs->_flags &= ~SPF_BLANK;
} else if( *ctl == ' ' ) {
if( ( specs->_flags & SPF_FORCE_SIGN ) == 0 ) {
specs->_flags |= SPF_BLANK;
}
} else if( *ctl == '0' ) {
specs->_pad_char = '0';
#ifdef __QNX__
specs->_flags |= SPF_ZERO_PAD;
#endif
} else {
break;
}
}
return( ctl );
}
static int far_strlen( FAR_STRING s, int precision )
{
int len;
len = 0;
while(( len != precision ) && ( *s++ != NULLCHAR ))
++len;
return( len );
}
/*
* far_other_strlen - calculates the length of an ascii string
* for the unicode version
* - calculates the length of a unicode string for
* the standard version
*/
static int far_other_strlen( FAR_STRING s, int precision )
{
int len = 0;
_FAR_OTHER_STRING ptr = (_FAR_OTHER_STRING)s;
#if !defined( __WIDECHAR__ ) && defined( USE_MBCS_TRANSLATION )
char mbBuf[MB_CUR_MAX];
int chBytes;
if( precision == -1 ) {
while( *ptr ) {
chBytes = wctomb( mbBuf, *ptr++ );
if( chBytes != -1 ) {
len += chBytes;
}
}
return( len );
}
while( *ptr && ( len <= precision )) {
chBytes = wctomb( mbBuf, *ptr++ );
if( chBytes != -1 ) {
len += chBytes;
}
}
return(( len <= precision ) ? len : precision );
#else
while( *ptr++ && ( len != precision ))
++len;
return( len );
#endif
}
static void fmt4hex( unsigned value, CHAR_TYPE *buf, int maxlen )
{
int i, len;
__F_NAME(itoa,_itow)( value, buf, 16 );
len = __F_NAME(strlen,wcslen)( buf );
for( i = maxlen - 1; len; --i ) {
--len;
buf[i] = buf[len];
}
while( i >= 0 ) {
buf[i] = '0';
--i;
}
buf[maxlen] = NULLCHAR;
}
static void FixedPoint_Format( CHAR_TYPE *buf, long value, SPECS __SLIB *specs )
{
T32 at;
int i;
CHAR_TYPE *bufp;
at.sWhole = value;
if( at.sWhole < 0 ) {
at.sWhole = - at.sWhole;
*buf++ = '-';
}
if( specs->_prec == -1 )
specs->_prec = 4;
__F_NAME(itoa,_itow)( at.wd.hi, buf, 10 );
bufp = buf; /* remember start address of buffer */
while( *buf )
++buf;
if( specs->_prec != 0 ) {
*buf++ = '.';
for( i = 0; i < specs->_prec; i++ ) {
at.wd.hi = 0;
at.uWhole *= 10;
*buf++ = at.bite.b3 + '0';
}
*buf = NULLCHAR;
}
if( at.wd.lo & 0x8000 ) { /* fraction >= .5, need to round */
for(;;) { /* 22-dec-91 */
if( buf == bufp ) {
*buf++ = '1';
while( *buf == '0' )
++buf;
if( *buf == '.' ) {
*buf++ = '0';
*buf++ = '.';
while( *buf == '0' ) {
++buf;
}
}
*buf++ = '0';
*buf = NULLCHAR;
break;
}
--buf;
if( *buf == '.' )
--buf;
if( *buf != '9' ) {
++ *buf;
break;
}
*buf = '0';
}
}
}
static void float_format( CHAR_TYPE *buffer, my_va_list *pargs, SPECS __SLIB *specs )
{
#ifdef __WIDECHAR__
char mbBuffer[BUF_SIZE*MB_CUR_MAX];
_mbcs_SPECS mbSpecs;
int count;
size_t rc;
char *p;
#endif // __WIDECHAR__
#ifdef __WIDECHAR__
/*
* EFG_PRINTF can only handle MBCS buffers and the MBCS version of the
* SPECS structure. So, make a _mbcs_SPECS structure equivalent to the
* _wide_SPECS one, and use that instead. Note that we can't use
* memcpy() because some field sizes are different.
*/
mbSpecs._dest = NULL; /* this field isn't actually used */
mbSpecs._flags = specs->_flags;
mbSpecs._version = specs->_version;
mbSpecs._fld_width = specs->_fld_width;
mbSpecs._prec = specs->_prec;
mbSpecs._output_count = specs->_output_count;
mbSpecs._n0 = specs->_n0;
mbSpecs._nz0 = specs->_nz0;
mbSpecs._n1 = specs->_n1;
mbSpecs._nz1 = specs->_nz1;
mbSpecs._n2 = specs->_n2;
mbSpecs._nz2 = specs->_nz2;
mbSpecs._character = (char)specs->_character;
mbSpecs._pad_char = (char)specs->_pad_char;
#endif
#ifdef __WIDECHAR__
EFG_PRINTF( mbBuffer, pargs, &mbSpecs );
#else
EFG_PRINTF( buffer, pargs, specs );
#endif
#ifdef __WIDECHAR__
/*
* Now convert the returned information back into our _wide_SPECS
* structure. We can't just use mbstowcs because it's an array of
* characters, not a string.
*/
p = mbBuffer;
for( count = 0; count < BUF_SIZE; count++ ) {
rc = mbtowc( &(buffer[count]), p, MB_CUR_MAX );
if( rc == -1 ) {
buffer[count] = L'?';
}
p = _mbsinc( p );
}
specs->_flags = mbSpecs._flags;
specs->_version = mbSpecs._version;
specs->_fld_width = mbSpecs._fld_width;
specs->_prec = mbSpecs._prec;
specs->_output_count = mbSpecs._output_count;
specs->_n0 = mbSpecs._n0;
specs->_nz0 = mbSpecs._nz0;
specs->_n1 = mbSpecs._n1;
specs->_nz1 = mbSpecs._nz1;
specs->_n2 = mbSpecs._n2;
specs->_nz2 = mbSpecs._nz2;
specs->_character = (wchar_t) mbSpecs._character;
specs->_pad_char = (wchar_t) mbSpecs._pad_char;
#endif
}
static void SetZeroPad( SPECS __SLIB *specs )
{
int n;
if( !(specs->_flags & SPF_LEFT_ADJUST) ) {
if( specs->_pad_char == '0' ) {
n = specs->_fld_width - specs->_n0 - specs->_nz0 -
specs->_n1 - specs->_nz1 - specs->_n2 - specs->_nz2;
if( n > 0 ) {
specs->_nz0 += n;
}
}
}
}
#if !defined( __WIDECHAR__ ) && defined( USE_MBCS_TRANSLATION )
static void write_wide_string( FAR_UNI_STRING str, SPECS *specs,
slib_callback_t *out_putc )
{
int bytes;
char mbBuf[MB_CUR_MAX];
char *mbBufPtr;
while( specs->_n1 > 0 ) {
bytes = wctomb( mbBuf, *str++ );
if( bytes != -1 ) {
if( bytes <= specs->_n1 ) {
mbBufPtr = mbBuf;
while( bytes-- ) {
(out_putc)( specs, *mbBufPtr++ );
--specs->_n1;
}
} else {
specs->_n1 = 0;
}
}
}
}
#endif
#if defined( __WIDECHAR__ ) && defined( USE_MBCS_TRANSLATION )
static void write_skinny_string( FAR_ASCII_STRING str, SPECS *specs,
slib_callback_t *out_putc )
{
int bytes;
wchar_t wc;
FAR_ASCII_STRING mbPtr = str;
char mbBuf[MB_CUR_MAX];
while( specs->_n1 > 0 ) {
mbBuf[0] = *mbPtr++;
if( _ismbblead( mbBuf[0] ) )
mbBuf[1] = *mbPtr++;
bytes = mbtowc( &wc, mbBuf, MB_CUR_MAX );
if( bytes <= specs->_n1 ) {
if( bytes != -1 ) {
(out_putc)( specs, wc );
specs->_n1 -= bytes;
}
} else {
specs->_n1 = 0;
}
}
}
#endif
static FAR_STRING formstring( CHAR_TYPE *buffer, my_va_list *pargs,
SPECS __SLIB *specs, CHAR_TYPE *null_string )
{
FAR_STRING arg;
int length;
int radix;
#if defined( __LONG_LONG_SUPPORT__ )
unsigned long long long_long_value;
#endif
unsigned long long_value;
unsigned int int_value;
#if defined( __FAR_SUPPORT__ )
unsigned int seg_value;
#endif
#if !defined( __WIDECHAR__ ) && defined( USE_MBCS_TRANSLATION )
int bytes;
#endif
arg = buffer;
specs->_n0 = specs->_nz0 =
specs->_n1 = specs->_nz1 =
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?