rfmtutil.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 993 行 · 第 1/2 页
C
993 行
top = P1d100;
if( IOCB->scale != 0 ) { // we must shift the range of our check;
bot = pow( 10, IOCB->scale );
top *= bot;
bot *= P1d_99;
} else {
bot = P1d_99;
}
if( ( ( absvalue <= bot ) || ( absvalue >= top ) ) &&
( absvalue != 0.0 ) ) {
ch = NULLCHAR; // no exponent letter
exp = 3;
} else {
#endif
exp = 2;
#if defined( _M_IX86 ) || defined( __AXP__ ) || defined( __PPC__ )
}
#endif
}
R_F2E( value, buf, wid, fmt->fld2, (IOCB->flags & IOF_PLUS) != 0,
IOCB->scale, exp, ch );
}
fcb->col += wid;
}
bool FmtH2B( char *src, uint width, char PGM *dst, int len, PTYPE typ ) {
//==========================================================================
char ch1;
byte ch2;
bool valid;
char *stop;
#if defined( _M_IX86 ) || defined( __AXP__ ) || defined( __PPC__ )
#else
typ = typ;
#endif
pgm_memset( dst, 0, len );
if( width >= 2 * len ) {
len *= 2;
src += width - len;
} else {
len = width;
}
stop = src + len;
ch1 = '0';
if( ( len & 1 ) == 0 ) {
ch1 = *src;
src++;
}
ch2 = *src;
src++;
#if defined( _M_IX86 ) || defined( __AXP__ ) || defined( __PPC__ )
if( typ != PT_CHAR ) {
++len;
len &= ~1;
len /= 2;
dst += len - 1;
}
#endif
for(;;) {
valid = FALSE;
if( !isxdigit( ch1 ) ) {
if( ch1 != ' ' ) break;
ch1 = '0';
}
if( !isxdigit( ch2 ) ) {
if( ch2 != ' ' ) break;
ch2 = '0';
}
valid = TRUE;
*dst = ( Hex( ch1 ) << 4 ) + Hex( ch2 );
#if defined( _M_IX86 ) || defined( __AXP__ ) || defined( __PPC__ )
if( typ == PT_CHAR ) {
++dst;
} else {
--dst;
}
#else
dst++;
#endif
if( src == stop ) break;
ch1 = *src;
src++;
ch2 = *src;
src++;
}
return( valid );
}
void R_FIHex( void ) {
//=================
uint width;
int len;
ftnfile *fcb;
PTYPE typ;
void PGM *ptr;
fcb = IOCB->fileinfo;
width = IOCB->fmtptr->fmt1.fld1;
len = GetLen();
typ = IOCB->typ;
ChkBuffLen( width );
if( typ == PT_CHAR ) {
ptr = IORslt.string.strptr;
} else {
ptr = IORslt.pgm_ptr;
if( typ == PT_CPLX_8 ) {
if( IOCB->flags & IOF_FMTREALPART ) {
ptr = &((complex *)ptr)->realpart;
} else {
ptr = &((complex *)ptr)->imagpart;
}
} else if( typ == PT_CPLX_16 ) {
if( IOCB->flags & IOF_FMTREALPART ) {
ptr = &((dcomplex *)ptr)->imagpart;
} else {
ptr = &((dcomplex *)ptr)->imagpart;
}
}
}
if( !FmtH2B( &fcb->buffer[ fcb->col ], width, ptr, len, typ ) ) {
IOErr( IO_BAD_CHAR );
}
fcb->col += width;
}
void R_FOHex( void ) {
//=================
FOHex( IOCB->fmtptr->fmt1.fld1 );
}
void FOHex( uint width ) {
//===========================
uint len;
int trunc;
ftnfile *fcb;
PTYPE typ;
char *buff;
fcb = IOCB->fileinfo;
typ = IOCB->typ;
len = GetLen();
trunc = 0;
// Use this method when real and imaginary parts are formatted using
// one edit descriptor:
/*
if( ( IOCB->typ == PT_CPLX_8 ) || ( IOCB->typ == PT_CPLX_16 ) ) {
len *= 2;
IOCB->flags &= ~IOF_FMTREALPART; // we'll print both parts at once
}
*/
// Use this method when real and imaginary parts each require an
// edit descriptor:
if( IOCB->typ == PT_CPLX_8 ) {
if( !(IOCB->flags & IOF_FMTREALPART) ) {
IORslt.complex.realpart = IORslt.complex.imagpart;
}
} else if( IOCB->typ == PT_CPLX_16 ) {
if( !(IOCB->flags & IOF_FMTREALPART) ) {
IORslt.dcomplex.realpart = IORslt.dcomplex.imagpart;
}
} else if( IOCB->typ == PT_CPLX_32 ) {
if( !(IOCB->flags & IOF_FMTREALPART) ) {
IORslt.xcomplex.realpart = IORslt.xcomplex.imagpart;
}
}
if( width == 0 ) {
width = 2*len;
}
trunc = ( len * 2 ) - width;
if( trunc < 0 ) {
SendChar( ' ', -trunc );
}
if( trunc <= 0 ) {
trunc = 0;
}
if( typ != PT_CHAR ) {
len *= 2;
HexFlip( (char *)&IORslt, len );
BToHS( (char *)&IORslt , len, IOCB->buffer );
strupr( IOCB->buffer );
SendStr( IOCB->buffer + trunc, len - trunc );
} else {
buff = IOCB->buffer;
len *= 2;
if( len > IO_FIELD_BUFF ) {
buff = RChkAlloc( len + 1 );
}
pgm_BToHS( IORslt.string.strptr, len, buff );
strupr( buff );
SendStr( buff + trunc, len - trunc );
if( len > IO_FIELD_BUFF ) {
RMemFree( buff );
}
}
}
static void HexFlip( char *src, int len ) {
//=============================================
// Convert number to hex string.
char *ptr;
char *last;
int num_len;
char tmp;
ptr = src;
num_len = len / 2;
last = src + num_len - 1;
while( num_len > 0 ) {
tmp = *ptr;
*ptr = *last;
*last = tmp;
ptr++;
last--;
num_len -= 2;
}
}
void R_FIInt( void ) {
//=================
intstar4 value;
uint width;
int new_width;
int status;
ftnfile *fcb;
bool comma;
fcb = IOCB->fileinfo;
width = IOCB->fmtptr->fmt2.fld1;
ChkBuffLen( width );
comma = __AllowCommaSep();
status = FmtS2I( &fcb->buffer[ fcb->col ], width,
( fcb->blanks == BLANK_ZERO ), &value, comma, &new_width );
if( status == INT_INVALID ) {
IOErr( IO_BAD_CHAR );
} else if( status == INT_OVERFLOW ) {
IOErr( IO_IOVERFLOW );
} else {
if( comma && ( width != new_width ) ) { // use comma as field separator
fcb->col += new_width;
if( fcb->buffer[ fcb->col ] == ',' ) {
fcb->col++;
} else {
IOErr( IO_BAD_CHAR );
}
} else {
fcb->col += width;
}
if( IOCB->typ == PT_INT_1 ) {
*(intstar1 PGM *)(IORslt.pgm_ptr) = value;
} else if( IOCB->typ == PT_INT_2 ) {
*(intstar2 PGM *)(IORslt.pgm_ptr) = value;
} else {
*(intstar4 PGM *)(IORslt.pgm_ptr) = value;
}
}
}
void R_FOInt( void ) {
//=================
OutInt( IOCB->fmtptr->fmt2.fld1, IOCB->fmtptr->fmt2.fld2 );
}
static void OutInt( uint width, uint min ) {
//==============================================
char *number;
uint length;
uint space;
bool minus;
intstar4 iorslt;
if( UndefIntRtn( width ) ) return;
iorslt = IORslt.intstar4;
if( ( iorslt == 0 ) && ( min == 0 ) ) {
SendChar( ' ', width );
} else {
minus = ( iorslt < 0 );
number = IOCB->buffer;
if( minus ) {
number++; // skip the minus sign
}
ltoa( iorslt, IOCB->buffer, 10 );
length = strlen( number );
if( length > min ) {
min = length;
}
if( min <= width ) {
space = width - min;
if( minus || ( IOCB->flags & IOF_PLUS ) ) {
if( space != 0 ) {
SendChar( ' ', space - 1 );
if( minus ) {
Drop( '-' );
} else {
Drop( '+' );
}
SendChar( '0', min - length );
SendStr( number, length );
} else {
SendChar( '*', width );
}
} else {
SendChar( ' ', space );
SendChar( '0', min - length );
SendStr( number, length );
}
} else {
SendChar( '*', width );
}
}
}
static int Div10S( real val ) {
//==================================
int retn;
if( val < SInfinity.value ) {
retn = -1;
while( val >= 1 ) {
retn++;
val /= 10;
}
return( retn );
} else {
return( INT_MAX );
}
}
// this function is called to determine if a number printed in G
// format is printed with the E format or the F format
static int Div10L( double val ) {
//====================================
int retn;
unsigned short int * ui = (unsigned short int *) & val;
if ( (ui [3] & 0x7FF0) == 0x7FF0 ) { /* NaN or Inf */
return( INT_MAX );
}
if ( val < DInfinity.value ) {
retn = -1;
while( val >= 1 ) {
retn++;
// check for runaway due to a NaN
// if ( retn == 1000 )
// return ( INT_MAX );
val /= 10;
}
return( retn );
} else {
return( INT_MAX );
}
}
static int Div10X( extended val ) {
//======================================
int retn;
if( val < XInfinity.value ) {
retn = -1;
while( val >= 1 ) {
retn++;
val /= 10;
}
return( retn );
} else {
return( INT_MAX );
}
}
void R_FOG( void ) {
//===============
int width;
int dec;
int exp;
int logval;
char *buf;
ftnfile *fcb;
char ch;
extended value;
extended absvalue;
width = IOCB->fmtptr->fmt3.fld1;
dec = IOCB->fmtptr->fmt3.fld2;
exp = IOCB->fmtptr->fmt3.fld3;
fcb = IOCB->fileinfo;
buf = &fcb->buffer[ fcb->col ];
if( IOCB->typ <= PT_LOG_4 ) {
R_FOLog();
} else if( IOCB->typ <= PT_INT_4 ) {
OutInt( width, 1 );
} else {
if( GetRealRtn( &value, width ) ) {
absvalue = value;
if( value < 0.0 ) {
absvalue = -value;
}
/* round to "dec" digits */
absvalue = absvalue + .5 * pow( 10, -dec );
if( ( IOCB->typ == PT_REAL_4 ) || ( IOCB->typ == PT_CPLX_8 ) ) {
logval = Div10S( absvalue );
} else if((IOCB->typ == PT_REAL_8) || (IOCB->typ == PT_CPLX_16)) {
logval = Div10L( absvalue );
} else {
logval = Div10X( absvalue );
}
if( ( absvalue < 0.1 ) || ( logval >= dec ) ) {
ch = 'E';
if( exp == 0 ) { // if Gw.d
#if defined( _M_IX86 ) || defined( __AXP__ ) || defined( __PPC__ )
if( ( ( absvalue <= P1d_99 ) || ( absvalue >= P1d100 ) ) &&
( absvalue != 0.0 ) ) {
ch = NULLCHAR; // no exponent letter
exp = 3;
} else {
#endif
exp = 2;
#if defined( _M_IX86 ) || defined( __AXP__ ) || defined( __PPC__ )
}
#endif
}
R_F2E( value, buf, width, dec, (IOCB->flags & IOF_PLUS) != 0,
IOCB->scale, exp, ch );
fcb->col += width;
} else {
if( exp == 0 ) { // if Gw.d
exp = 4;
} else {
exp += 2;
}
width -= exp;
if( width > 0 ) {
dec -= ( logval + 1 );
if( ( dec <= width ) && ( dec >= 0 ) ) {
R_F2F( value, buf, width, dec,
( IOCB->flags & IOF_PLUS ) != 0, 0 );
fcb->col += width;
if( *buf == '*' ) {
// fill remaining field
SendChar( '*', exp );
} else {
SendChar( ' ', exp );
}
} else {
SendChar( '*', width + exp );
}
} else {
SendChar( '*', width + exp );
}
}
} else { // undefined chars will be filled in for value
fcb->col += width;
}
}
}
void ChkBuffLen( uint width ) {
//================================
if( IOCB->fileinfo->col + width > IOCB->fileinfo->len ) {
IOErr( IO_BUFF_LEN );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?