X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device%2Flib%2Fvprintf.c;h=77bd361fab7df3a33580a8701466cb6fe8496f36;hb=2f566bab0a5fe0bf025d6c892d6fc309966618f1;hp=57a775adc7e5b6711e1afd120f8422ad79bbcb71;hpb=1a506e465c83a9316e4624bf92e643d8163c6856;p=fw%2Fsdcc diff --git a/device/lib/vprintf.c b/device/lib/vprintf.c index 57a775ad..77bd361f 100644 --- a/device/lib/vprintf.c +++ b/device/lib/vprintf.c @@ -22,7 +22,15 @@ You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ + +/* this module uses some global variables instead function parameters, so: */ +#ifdef SDCC_STACK_AUTO +#warning "this module cannot yet be use as a reentrant one" +#endif + +#ifdef __ds390 #define USE_FLOATS 1 +#endif #include #include @@ -31,9 +39,17 @@ #define PTR value.p +#ifdef SDCC_ds390 +#define NULL_STRING "" +#define NULL_STRING_LENGTH 6 +#endif + +/* XSPEC is defined in stdio.h and used here to place + auto variables in XSEG */ + /****************************************************************************/ -typedef char _generic *ptr_t; +typedef char * ptr_t; #ifdef toupper #undef toupper @@ -48,7 +64,7 @@ typedef union long l; unsigned long ul; float f; - char _generic *p; + char *p; } value_t; @@ -62,7 +78,10 @@ static bit lsd; /* this one NEEDS to be in data */ static data value_t value; -static xdata unsigned short radix; +static unsigned char radix; + +// jwk: TODO: this makes the whole dammed thing nonreentrent +static int charsOutputted; /****************************************************************************/ @@ -76,13 +95,15 @@ static void output_char( char c ) reentrant { putchar( c ); } + charsOutputted++; } /*--------------------------------------------------------------------------*/ static void output_digit( unsigned char n ) reentrant { - output_char( n <= 9 ? '0'+n : (lower_case ? n+(char)('a'-10) : n+(char)('A'-10)) ); + output_char( n <= 9 ? '0'+n : + (lower_case ? n+(char)('a'-10) : n+(char)('A'-10)) ); } /*--------------------------------------------------------------------------*/ @@ -103,7 +124,7 @@ static void calculate_digit( void ) { _asm clr c - mov a,_value+0 + mov a,_value+0 rlc a mov _value+0,a mov a,_value+1 @@ -237,20 +258,23 @@ static void output_float (float f, unsigned char reqWidth, int vsprintf (const char *buf, const char *format, va_list ap) { - bit left_justify; - bit zero_padding; - bit prefix_sign; - bit prefix_space; - bit signed_argument; - bit char_argument; - bit long_argument; - bit float_argument; + static bit left_justify; + static bit zero_padding; + static bit prefix_sign; + static bit prefix_space; + static bit signed_argument; + static bit char_argument; + static bit long_argument; + static bit float_argument; unsigned char width; signed char decimals; unsigned char length; char c; + // reset output chars + charsOutputted=0; + output_ptr = buf; if ( !buf ) { @@ -261,6 +285,12 @@ int vsprintf (const char *buf, const char *format, va_list ap) output_to_string = 1; } +#ifdef SDCC_ds390 + if (format==0) { + format=NULL_STRING; + } +#endif + while( c=*format++ ) { if ( c=='%' ) @@ -331,13 +361,22 @@ get_conversion_spec: goto get_conversion_spec; case 'C': - output_char( va_arg(ap,unsigned char) ); + output_char( va_arg(ap,int) ); 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; @@ -363,7 +402,7 @@ get_conversion_spec: case 'P': PTR = va_arg(ap,ptr_t); -#ifdef SDCC_MODEL_FLAT24 +#ifdef SDCC_ds390 output_char(memory_id[(value.byte[3] > 3) ? 4 : value.byte[3]] ); output_char(':'); output_char('0'); @@ -376,7 +415,8 @@ get_conversion_spec: output_char(':'); output_char('0'); output_char('x'); - if ((value.byte[2] != 0x00 /* DSEG */) && (value.byte[2] != 0x03 /* SSEG */)) + if ((value.byte[2] != 0x00 /* DSEG */) && + (value.byte[2] != 0x03 /* SSEG */)) output_2digits( value.byte[1] ); output_2digits( value.byte[0] ); #endif @@ -413,11 +453,14 @@ get_conversion_spec: if (float_argument) { value.f=va_arg(ap,float); #if !USE_FLOATS + PTR=""; + while (c=*PTR++) + output_char (c); // treat as long hex - radix=16; - long_argument=1; - zero_padding=1; - width=8; + //radix=16; + //long_argument=1; + //zero_padding=1; + //width=8; #else // ignore b and l conversion spec for now output_float(value.f, width, decimals, left_justify, zero_padding, @@ -568,7 +611,12 @@ _endasm; // Copy \0 to the end of buf // Modified by JB 17/12/99 - if (output_to_string) output_char(0); + if (output_to_string) { + output_char(0); + return charsOutputted-1; + } else { + return charsOutputted; + } } /*--------------------------------------------------------------------------*/