X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device%2Flib%2Fprintf_large.c;h=fba74ff0298f76c5d2d3f2d2f073f1b9be7bf034;hb=e56ff7ea8ea1bffdcf4fee43ec8a125453a6ad8d;hp=d93288026fa8d81056be2f8df23f3a6b15e9987c;hpb=a1028493f3e38ab0704267390c50f09d63fdc3aa;p=fw%2Fsdcc diff --git a/device/lib/printf_large.c b/device/lib/printf_large.c index d9328802..fba74ff0 100644 --- a/device/lib/printf_large.c +++ b/device/lib/printf_large.c @@ -42,6 +42,14 @@ #define NULL_STRING_LENGTH 6 #endif +#if defined (SDCC_mcs51) && defined (SDCC_MODEL_SMALL) && !defined (SDCC_STACK_AUTO) +# define MEM_SPACE_BUF __idata +# define MEM_SPACE_BUF_PP __idata +#else +# define MEM_SPACE_BUF +# define MEM_SPACE_BUF_PP _AUTOMEM +#endif + /****************************************************************************/ //typedef char * ptr_t; @@ -50,9 +58,21 @@ #ifdef toupper #undef toupper #endif +#ifdef tolower +#undef tolower +#endif +#ifdef islower +#undef islower +#endif +#ifdef isdigit +#undef isdigit +#endif //#define toupper(c) ((c)&=~0x20) #define toupper(c) ((c)&=0xDF) +#define tolower(c) ((c)|=0x20) +#define islower(c) ((unsigned char)c >= (unsigned char)'a' && (unsigned char)c <= (unsigned char)'z') +#define isdigit(c) ((unsigned char)c >= (unsigned char)'0' && (unsigned char)c <= (unsigned char)'9') typedef union { @@ -63,44 +83,68 @@ typedef union char *ptr; } value_t; -static const char memory_id[] = "IXCP-"; - #ifndef SDCC_STACK_AUTO static BOOL lower_case; static pfn_outputchar output_char; static void* p; static value_t value; + static int charsOutputted; #endif /****************************************************************************/ #ifdef SDCC_STACK_AUTO - static void output_digit( unsigned char n, BOOL lower_case, pfn_outputchar output_char, void* p ) + #define OUTPUT_CHAR(c, p) { output_char (c, p); charsOutputted++; } #else - static void output_digit( unsigned char n ) + #define OUTPUT_CHAR(c, p) _output_char (c) + static void _output_char( unsigned char c ) + { + output_char( c, p ); + charsOutputted++; + } #endif + +/*--------------------------------------------------------------------------*/ + +#ifdef SDCC_STACK_AUTO + static void output_digit( unsigned char n, BOOL lower_case, pfn_outputchar output_char, void* p ) { - register unsigned char c; - if (n <= 9) - c = n + '0'; - else if (lower_case) - c = n + (unsigned char)('a' - 10); - else - c = n + (unsigned char)('A' - 10); + register unsigned char c = n + (unsigned char)'0'; + + if (c > (unsigned char)'9') + { + c += (unsigned char)('A' - '0' - 10); + if (lower_case) + c += (unsigned char)('a' - 'A'); + } output_char( c, p ); } +#else + static void output_digit( unsigned char n ) + { + register unsigned char c = n + (unsigned char)'0'; + + if (c > (unsigned char)'9') + { + c += (unsigned char)('A' - '0' - 10); + if (lower_case) + c = tolower(c); + } + _output_char( c ); + } +#endif /*--------------------------------------------------------------------------*/ #ifdef SDCC_STACK_AUTO - #define OUTPUT_2DIGITS( B ) output_2digits( B, lower_case, output_char, p ) + #define OUTPUT_2DIGITS( B ) { output_2digits( B, lower_case, output_char, p ); charsOutputted += 2; } static void output_2digits( unsigned char b, BOOL lower_case, pfn_outputchar output_char, void* p ) { output_digit( b>>4, lower_case, output_char, p ); output_digit( b&0x0F, lower_case, output_char, p ); } #else - #define OUTPUT_2DIGITS( B ) output_2digits( B ) + #define OUTPUT_2DIGITS( B ) output_2digits( B ) static void output_2digits( unsigned char b ) { output_digit( b>>4 ); @@ -126,7 +170,7 @@ static void calculate_digit( value_t _AUTOMEM * value, unsigned char radix ) { *pb4 -= radix; ul |= 1; - } + } } while (--i); value->ul = ul; } @@ -147,7 +191,7 @@ static void calculate_digit( unsigned char radix ) { b4 -= radix; ul |= 1; - } + } } while (--i); value.ul = ul; value.byte[4] = b4; @@ -167,25 +211,35 @@ static void calculate_digit( unsigned char radix ) #define DEFAULT_FLOAT_PRECISION 6 #ifdef SDCC_STACK_AUTO -#define OUTPUT_FLOAT(F, W, D, L, Z, S, P) output_float(F, W, D, L, Z, S, P, output_char, p) -static int output_float (float f, unsigned char reqWidth, - signed char reqDecimals, - BOOL left, BOOL zero, BOOL sign, BOOL space, - pfn_outputchar output_char, void* p) +#define OUTPUT_FLOAT(F, W, D, L, Z, S, P) output_float(F, W, D, L, Z, S, P, output_char, p) +static unsigned char +output_float (float f, unsigned char reqWidth, + signed char reqDecimals, + BOOL left, BOOL zero, BOOL sign, BOOL space, + pfn_outputchar output_char, void* p) +{ + unsigned char charsOutputted = 0; + #if defined (SDCC_mcs51) + char fpBuffer[16]; //mcs51 has only a small stack + #else + char fpBuffer[128]; + #endif #else -#define OUTPUT_FLOAT(F, W, D, L, Z, S, P) output_float(F, W, D, L, Z, S, P) -static int output_float (float f, unsigned char reqWidth, - signed char reqDecimals, - BOOL left, BOOL zero, BOOL sign, BOOL space) -#endif +#define OUTPUT_FLOAT(F, W, D, L, Z, S, P) output_float(F, W, D, L, Z, S, P) +static void +output_float (float f, unsigned char reqWidth, + signed char reqDecimals, + BOOL left, BOOL zero, BOOL sign, BOOL space) { - BOOL negative=0; + __xdata char fpBuffer[128]; +#endif //SDCC_STACK_AUTO + BOOL negative = 0; unsigned long integerPart; + float rounding; float decimalPart; - char fpBuffer[128]; char fpBI=0, fpBD; unsigned char minWidth, i; - int charsOutputted=0; + signed char exp = -128; // save the sign if (f<0) { @@ -195,37 +249,38 @@ static int output_float (float f, unsigned char reqWidth, if (f>0x00ffffff) { // this part is from Frank van der Hulst - signed char exp; for (exp = 0; f >= 10.0; exp++) f /=10.0; for ( ; f < 1.0; exp--) f *=10.0; if (negative) { - output_char ('-', p); - charsOutputted++; + OUTPUT_CHAR ('-', p); } else { if (sign) { - output_char ('+', p); - charsOutputted++; + OUTPUT_CHAR ('+', p); } } - charsOutputted += OUTPUT_FLOAT(f, 0, reqDecimals, 0, 0, 0, 0); - output_char ('e', p); - charsOutputted++; - if (exp<0) { - output_char ('-', p); - charsOutputted++; - exp = -exp; - } - output_char ('0'+exp/10, p); - output_char ('0'+exp%10, p); - charsOutputted += 2; - return charsOutputted; + reqWidth = 0; + left = 0; + zero = 0; + sign = 0; + space = 0; } + // display some decimals as default + if (reqDecimals==-1) + reqDecimals=DEFAULT_FLOAT_PRECISION; + + // round the float + rounding = 0.5; + for (i=reqDecimals; i>0; i--) { + rounding /= 10.0; + } + f += rounding; + // split the float - integerPart=f; - decimalPart=f-integerPart; + integerPart = f; + decimalPart = f - integerPart; // fill the buffer with the integerPart (in reversed order!) while (integerPart) { @@ -237,25 +292,15 @@ static int output_float (float f, unsigned char reqWidth, fpBuffer[fpBI++]='0'; } - // display some decimals as default - if (reqDecimals==-1) - reqDecimals=DEFAULT_FLOAT_PRECISION; - // fill buffer with the decimalPart (in normal order) fpBD=fpBI; - for (i=reqDecimals; i>1; i--) { + for (i=reqDecimals; i>0; i--) { decimalPart *= 10.0; // truncate the float - integerPart=decimalPart; - fpBuffer[fpBD++]='0' + integerPart; - decimalPart-=integerPart; - } - if (i) { - decimalPart *= 10.0; - // truncate the float - integerPart = decimalPart + 0.5; - fpBuffer[fpBD++] = '0' + integerPart; + integerPart = decimalPart; + fpBuffer[fpBD++] = '0' + integerPart; + decimalPart -= integerPart; } minWidth=fpBI; // we need at least these @@ -267,93 +312,92 @@ static int output_float (float f, unsigned char reqWidth, if (zero) { if (negative) { - output_char('-', p); - charsOutputted++; + OUTPUT_CHAR('-', p); } else if (sign) { - output_char('+', p); - charsOutputted++; + OUTPUT_CHAR('+', p); } else if (space) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } while (reqWidth-->minWidth) { - output_char('0', p); - charsOutputted++; + OUTPUT_CHAR('0', p); } } else { while (reqWidth-->minWidth) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } if (negative) { - output_char('-', p); - charsOutputted++; + OUTPUT_CHAR('-', p); } else if (sign) { - output_char('+', p); - charsOutputted++; + OUTPUT_CHAR('+', p); } else if (space) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } } } else { if (negative) { - output_char('-', p); - charsOutputted++; + OUTPUT_CHAR('-', p); } else if (sign) { - output_char('+', p); - charsOutputted++; + OUTPUT_CHAR('+', p); } else if (space) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } } // output the integer part i=fpBI-1; do { - output_char (fpBuffer[i], p); - charsOutputted++; + OUTPUT_CHAR (fpBuffer[i], p); } while (i--); // ouput the decimal part if (reqDecimals) { - output_char ('.', p); - charsOutputted++; + OUTPUT_CHAR ('.', p); i=fpBI; while (reqDecimals--) { - output_char (fpBuffer[i++], p); - charsOutputted++; + OUTPUT_CHAR (fpBuffer[i++], p); } } if (left && reqWidth>minWidth) { while (reqWidth-->minWidth) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); + } + } + + if (exp != -128) { + OUTPUT_CHAR ('e', p); + if (exp<0) { + OUTPUT_CHAR ('-', p); + exp = -exp; } + OUTPUT_CHAR ('0'+exp/10, p); + OUTPUT_CHAR ('0'+exp%10, p); } +#ifdef SDCC_STACK_AUTO return charsOutputted; +#else + return; +#endif //SDCC_STACK_AUTO } -#endif +#endif //USE_FLOATS int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list ap) { @@ -368,11 +412,11 @@ int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list #ifdef SDCC_STACK_AUTO BOOL lower_case; value_t value; + int charsOutputted; #endif BOOL lsd; unsigned char radix; - int charsOutputted; unsigned char width; signed char decimals; unsigned char length; @@ -387,7 +431,7 @@ int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list #endif // reset output chars - charsOutputted=0; + charsOutputted = 0; #ifdef SDCC_ds390 if (format==0) { @@ -416,8 +460,7 @@ get_conversion_spec: c = *format++; if (c=='%') { - output_char(c, p); - charsOutputted++; + OUTPUT_CHAR(c, p); continue; } @@ -435,17 +478,19 @@ get_conversion_spec: } if (c=='.') { - if (decimals=-1) decimals=0; + if (decimals==-1) decimals=0; else ; // duplicate, ignore goto get_conversion_spec; } - lower_case = islower(c); - if (lower_case) + if (islower(c)) { c = toupper(c); + lower_case = 1; } + else + lower_case = 0; switch( c ) { @@ -466,8 +511,11 @@ get_conversion_spec: goto get_conversion_spec; case 'C': - output_char( va_arg(ap,int), p ); - charsOutputted++; + if( char_argument ) + c = va_arg(ap,char); + else + c = va_arg(ap,int); + OUTPUT_CHAR( c, p ); break; case 'S': @@ -492,15 +540,14 @@ get_conversion_spec: width -= length; while( width-- != 0 ) { - output_char( ' ', p ); - charsOutputted++; + OUTPUT_CHAR( ' ', p ); } } - while ( *PTR && (decimals-- > 0)) + while ( (c = *PTR) && (decimals-- > 0)) { - output_char( *PTR++, p ); - charsOutputted++; + OUTPUT_CHAR( c, p ); + PTR++; } if ( left_justify && (length < width)) @@ -508,8 +555,7 @@ get_conversion_spec: width -= length; while( width-- != 0 ) { - output_char( ' ', p ); - charsOutputted++; + OUTPUT_CHAR( ' ', p ); } } break; @@ -520,53 +566,49 @@ get_conversion_spec: #if defined (SDCC_ds390) { unsigned char memtype = value.byte[3]; - if (memtype > 0x80) + if (memtype >= 0x80) c = 'C'; - else if (memtype > 0x60) + else if (memtype >= 0x60) c = 'P'; - else if (memtype > 0x40) + else if (memtype >= 0x40) c = 'I'; else c = 'X'; } - output_char(c, p); - output_char(':', p); - output_char('0', p); - output_char('x', p); + OUTPUT_CHAR(c, 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; #elif defined (SDCC_mcs51) { unsigned char memtype = value.byte[2]; - if (memtype > 0x80) + if (memtype >= 0x80) c = 'C'; - else if (memtype > 0x60) + else if (memtype >= 0x60) c = 'P'; - else if (memtype > 0x40) + else if (memtype >= 0x40) c = 'I'; else c = 'X'; } - output_char(c, p); - output_char(':', p); - output_char('0', p); - output_char('x', p); + OUTPUT_CHAR(c, p); + OUTPUT_CHAR(':', p); + OUTPUT_CHAR('0', p); + OUTPUT_CHAR('x', p); if ((c != 'I' /* idata */) && (c != 'P' /* pdata */)) { OUTPUT_2DIGITS( value.byte[1] ); - charsOutputted += 2; } OUTPUT_2DIGITS( value.byte[0] ); - charsOutputted += 6; #else - output_char('0', p); - output_char('x', p); + OUTPUT_CHAR('0', p); + OUTPUT_CHAR('x', p); OUTPUT_2DIGITS( value.byte[1] ); OUTPUT_2DIGITS( value.byte[0] ); - charsOutputted += 6; #endif break; @@ -594,8 +636,7 @@ get_conversion_spec: default: // nothing special, just output the character - output_char( c, p ); - charsOutputted++; + OUTPUT_CHAR( c, p ); break; } @@ -605,8 +646,7 @@ get_conversion_spec: PTR=""; while (c=*PTR++) { - output_char (c, p); - charsOutputted++; + OUTPUT_CHAR (c, p); } // treat as long hex //radix=16; @@ -615,15 +655,20 @@ get_conversion_spec: //width=8; #else // ignore b and l conversion spec for now +#ifdef SDCC_STACK_AUTO charsOutputted += OUTPUT_FLOAT(value.f, width, decimals, left_justify, zero_padding, prefix_sign, prefix_space); -#endif +#else + OUTPUT_FLOAT(value.f, width, decimals, left_justify, + zero_padding, prefix_sign, prefix_space); +#endif //SDCC_STACK_AUTO +#endif //USE_FLOATS } else if (radix != 0) { - // Apperently we have to output an integral type + // Apparently we have to output an integral type // with radix "radix" - unsigned char store[6]; - unsigned char _AUTOMEM *pstore = &store[5]; + unsigned char MEM_SPACE_BUF store[6]; + unsigned char MEM_SPACE_BUF_PP *pstore = &store[5]; // store value in byte[0] (LSB) ... byte[3] (MSB) if (char_argument) @@ -691,16 +736,14 @@ get_conversion_spec: { while ( width > (unsigned char) (length+1) ) { - output_char( ' ', p ); - charsOutputted++; + OUTPUT_CHAR( ' ', p ); width--; } } if (signed_argument) // this now means the original value was negative { - output_char( '-', p ); - charsOutputted++; + OUTPUT_CHAR( '-', p ); // adjust width to compensate for this character width--; } @@ -709,15 +752,13 @@ get_conversion_spec: // value > 0 if (prefix_sign) { - output_char( '+', p ); - charsOutputted++; + OUTPUT_CHAR( '+', p ); // adjust width to compensate for this character width--; } else if (prefix_space) { - output_char( ' ', p ); - charsOutputted++; + OUTPUT_CHAR( ' ', p ); // adjust width to compensate for this character width--; } @@ -727,8 +768,7 @@ get_conversion_spec: if (!left_justify) while ( width-- > length ) { - output_char( zero_padding ? '0' : ' ', p ); - charsOutputted++; + OUTPUT_CHAR( zero_padding ? '0' : ' ', p ); } else { @@ -754,24 +794,22 @@ get_conversion_spec: } #ifdef SDCC_STACK_AUTO output_digit( value.byte[4], lower_case, output_char, p ); + charsOutputted++; #else output_digit( value.byte[4] ); #endif - charsOutputted++; } if (left_justify) while (width-- > 0) { - output_char(' ', p); - charsOutputted++; + OUTPUT_CHAR(' ', p); } } } else { // nothing special, just output the character - output_char( c, p ); - charsOutputted++; + OUTPUT_CHAR( c, p ); } }