X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device%2Flib%2Fvprintf.c;h=6c277e84af4f2bfa2e425600def93bf1b1f5996e;hb=4d406d0af5861a351d089724c5f3e6d1ee8f70d4;hp=a0b2d4c14e7b34ce1d6a6fcce67f90b89f1039bd;hpb=ea34442f1a2452c591734d551d76e46718665404;p=fw%2Fsdcc diff --git a/device/lib/vprintf.c b/device/lib/vprintf.c index a0b2d4c1..6c277e84 100644 --- a/device/lib/vprintf.c +++ b/device/lib/vprintf.c @@ -1,6 +1,6 @@ /*------------------------------------------------------------------------- vprintf.c - formatted output conversion - + Written By - Martijn van Balen aed@iae.nl (1999) Added %f By - johan.knol@iduna.nl (2000) @@ -8,21 +8,27 @@ under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! + what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#ifdef __ds390 + +/* 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 + +#if defined(__ds390) #define USE_FLOATS 1 #endif @@ -31,19 +37,17 @@ #include #include -#define PTR value.p +#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; +#define ptr_t char * #ifdef toupper #undef toupper @@ -58,7 +62,7 @@ typedef union long l; unsigned long ul; float f; - char _generic *p; + char *p; } value_t; @@ -72,9 +76,9 @@ static bit lsd; /* this one NEEDS to be in data */ static data value_t value; -static unsigned short radix; +static unsigned char radix; -// jwk: TODO: this makes the whole dammed thing nonreentrent +// this makes the whole dammed thing nonreentrent static int charsOutputted; /****************************************************************************/ @@ -160,7 +164,7 @@ static void output_float (float f, unsigned char reqWidth, bit left, bit zero, bit sign, bit space) { char negative=0; - long integerPart; + unsigned long integerPart; float decimalPart; char fpBuffer[128]; char fpBI=0, fpBD; @@ -172,6 +176,31 @@ static void output_float (float f, unsigned char reqWidth, f=-f; } + 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) { + putchar ('-'); + } else { + if (sign) { + putchar ('+'); + } + } + output_float(f, 0, reqDecimals, 0, 0, 0, 0); + putchar ('e'); + if (exp<0) { + putchar ('-'); + exp = -exp; + } + putchar ('0'+exp/10); + putchar ('0'+exp%10); + return; + } + // split the float integerPart=f; decimalPart=f-integerPart; @@ -252,14 +281,14 @@ 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; @@ -409,7 +438,7 @@ get_conversion_spec: output_char(':'); output_char('0'); output_char('x'); - if ((value.byte[2] != 0x00 /* DSEG */) && + if ((value.byte[2] != 0x00 /* DSEG */) && (value.byte[2] != 0x03 /* SSEG */)) output_2digits( value.byte[1] ); output_2digits( value.byte[0] ); @@ -501,7 +530,6 @@ get_conversion_spec: length=0; lsd = 1; - //jwk20000814: do this at least once, e.g.: printf ("%d", (int)0); do { value.byte[4] = 0; calculate_digit(); @@ -524,7 +552,7 @@ _endasm; lsd = ~lsd; } while( (value.byte[0] != 0) || (value.byte[1] != 0) || (value.byte[2] != 0) || (value.byte[3] != 0) ); - + if (width == 0) { // default width. We set it to 1 to output @@ -534,7 +562,7 @@ _endasm; } /* prepend spaces if needed */ - if (!zero_padding) + if (!zero_padding && !left_justify) { while ( width > length+1 ) { @@ -567,9 +595,18 @@ _endasm; } /* prepend zeroes/spaces if needed */ - while ( width-- > length ) + if (!left_justify) + while ( width-- > length ) + { + output_char( zero_padding ? '0' : ' ' ); + } + else { - output_char( zero_padding ? '0' : ' ' ); + /* spaces are appended after the digits */ + if (width > length) + width -= length; + else + width = 0; } /* output the digits */ @@ -594,6 +631,9 @@ _endasm; output_digit( value.byte[4] ); } + if (left_justify) + while (width-- > 0) + output_char(' '); } } else @@ -602,7 +642,7 @@ _endasm; output_char( c ); } } - + // Copy \0 to the end of buf // Modified by JB 17/12/99 if (output_to_string) {