📄 printf_large.c
字号:
unsigned char length;
char c;
#ifdef SDCC_STACK_AUTO
#define output_char pfn
#define p pvoid
#else
output_char = pfn;
p = pvoid;
#endif
// reset output chars
charsOutputted=0;
#ifdef SDCC_ds390
if (format==0) {
format=NULL_STRING;
}
#endif
while( c=*format++ )
{
if ( c=='%' )
{
left_justify = 0;
zero_padding = 0;
prefix_sign = 0;
prefix_space = 0;
signed_argument = 0;
radix = 0;
char_argument = 0;
long_argument = 0;
float_argument = 0;
width = 0;
decimals = -1;
get_conversion_spec:
c = *format++;
if (c=='%') {
output_char(c, p);
charsOutputted++;
continue;
}
if (isdigit(c)) {
if (decimals==-1) {
width = 10*width + (c - '0');
if (width == 0) {
/* first character of width is a zero */
zero_padding = 1;
}
} else {
decimals = 10*decimals + (c-'0');
}
goto get_conversion_spec;
}
if (c=='.') {
if (decimals=-1) decimals=0;
else
; // duplicate, ignore
goto get_conversion_spec;
}
lower_case = islower(c);
if (lower_case)
{
c = toupper(c);
}
switch( c )
{
case '-':
left_justify = 1;
goto get_conversion_spec;
case '+':
prefix_sign = 1;
goto get_conversion_spec;
case ' ':
prefix_space = 1;
goto get_conversion_spec;
case 'B':
char_argument = 1;
goto get_conversion_spec;
case 'L':
long_argument = 1;
goto get_conversion_spec;
case 'C':
output_char( va_arg(ap,int), p );
charsOutputted++;
break;
case 'S':
PTR = va_arg(ap,ptr_t);
#ifdef SDCC_ds390
if (PTR==0) {
PTR=NULL_STRING;
length=NULL_STRING_LENGTH;
} else {
length = strlen(PTR);
}
#else
length = strlen(PTR);
#endif
if ( ( !left_justify ) && (length < width) )
{
width -= length;
while( width-- != 0 )
{
output_char( ' ', p );
charsOutputted++;
}
}
while ( *PTR && (decimals != 0))
{
output_char( *PTR++, p );
charsOutputted++;
if (decimals != -1) --decimals;
}
if ( left_justify && (length < width))
{
width -= length;
while( width-- != 0 )
{
output_char( ' ', p );
charsOutputted++;
}
}
break;
case 'P':
PTR = va_arg(ap,ptr_t);
#ifdef SDCC_ds390
output_char(memory_id[(value.byte[3] > 3) ? 4 : value.byte[3]], p );
output_char(':', p);
output_char('0', p);
output_char('x', p);
OUTPUT_2DIGITS( value.byte[2] );
OUTPUT_2DIGITS( value.byte[1] );
OUTPUT_2DIGITS( value.byte[0] );
charsOutputted += 10;
#else
output_char( memory_id[(value.byte[2] > 3) ? 4 : value.byte[2]], p );
output_char(':', p);
output_char('0', p);
output_char('x', p);
if ((value.byte[2] != 0x00 /* DSEG */) &&
(value.byte[2] != 0x03 /* SSEG */))
{
OUTPUT_2DIGITS( value.byte[1] );
charsOutputted += 2;
}
OUTPUT_2DIGITS( value.byte[0] );
charsOutputted += 6;
#endif
break;
case 'D':
case 'I':
signed_argument = 1;
radix = 10;
break;
case 'O':
radix = 8;
break;
case 'U':
radix = 10;
break;
case 'X':
radix = 16;
break;
case 'F':
float_argument=1;
break;
default:
// nothing special, just output the character
output_char( c, p );
charsOutputted++;
break;
}
if (float_argument) {
value.f=va_arg(ap,float);
#if !USE_FLOATS
PTR="<NO FLOAT>";
while (c=*PTR++)
{
output_char (c, p);
charsOutputted++;
}
// treat as long hex
//radix=16;
//long_argument=1;
//zero_padding=1;
//width=8;
#else
// ignore b and l conversion spec for now
charsOutputted += OUTPUT_FLOAT(value.f, width, decimals, left_justify,
zero_padding, prefix_sign, prefix_space);
#endif
} else if (radix != 0)
{
// Apperently we have to output an integral type
// with radix "radix"
unsigned char store[6];
unsigned char _AUTOMEM *pstore = &store[5];
// store value in byte[0] (LSB) ... byte[3] (MSB)
if (char_argument)
{
value.l = va_arg(ap,char);
if (!signed_argument)
{
value.l &= 0xFF;
}
}
else if (long_argument)
{
value.l = va_arg(ap,long);
}
else // must be int
{
value.l = va_arg(ap,int);
if (!signed_argument)
{
value.l &= 0xFFFF;
}
}
if ( signed_argument )
{
if (value.l < 0)
value.l = -value.l;
else
signed_argument = 0;
}
length=0;
lsd = 1;
do {
value.byte[4] = 0;
#if defined SDCC_STACK_AUTO
calculate_digit(&value, radix);
#else
calculate_digit(radix);
#endif
if (!lsd)
{
*pstore = (value.byte[4] << 4) | (value.byte[4] >> 4) | *pstore;
pstore--;
}
else
{
*pstore = value.byte[4];
}
length++;
lsd = !lsd;
} while( value.ul );
if (width == 0)
{
// default width. We set it to 1 to output
// at least one character in case the value itself
// is zero (i.e. length==0)
width=1;
}
/* prepend spaces if needed */
if (!zero_padding && !left_justify)
{
while ( width > (unsigned char) (length+1) )
{
output_char( ' ', p );
charsOutputted++;
width--;
}
}
if (signed_argument) // this now means the original value was negative
{
output_char( '-', p );
charsOutputted++;
// adjust width to compensate for this character
width--;
}
else if (length != 0)
{
// value > 0
if (prefix_sign)
{
output_char( '+', p );
charsOutputted++;
// adjust width to compensate for this character
width--;
}
else if (prefix_space)
{
output_char( ' ', p );
charsOutputted++;
// adjust width to compensate for this character
width--;
}
}
/* prepend zeroes/spaces if needed */
if (!left_justify)
while ( width-- > length )
{
output_char( zero_padding ? '0' : ' ', p );
charsOutputted++;
}
else
{
/* spaces are appended after the digits */
if (width > length)
width -= length;
else
width = 0;
}
/* output the digits */
while( length-- )
{
lsd = !lsd;
if (!lsd)
{
pstore++;
value.byte[4] = *pstore >> 4;
}
else
{
value.byte[4] = *pstore & 0x0F;
}
#ifdef SDCC_STACK_AUTO
output_digit( value.byte[4], lower_case, output_char, p );
#else
output_digit( value.byte[4] );
#endif
charsOutputted++;
}
if (left_justify)
while (width-- > 0)
{
output_char(' ', p);
charsOutputted++;
}
}
}
else
{
// nothing special, just output the character
output_char( c, p );
charsOutputted++;
}
}
return charsOutputted;
}
/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -