/*-------------------------------------------------------------------------
vprintf.c - formatted output conversion
-
+
Written By - Martijn van Balen aed@iae.nl (1999)
Added %f By - johan.knol@iduna.nl (2000)
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!
-------------------------------------------------------------------------*/
+
+/* 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
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
-#define PTR value.p
+#define PTR value.p
+
+#ifdef SDCC_ds390
+#define NULL_STRING "<NULL>"
+#define NULL_STRING_LENGTH 6
+#endif
/****************************************************************************/
-typedef char _generic *ptr_t;
+//typedef char * ptr_t;
+#define ptr_t char *
#ifdef toupper
#undef toupper
long l;
unsigned long ul;
float f;
- char _generic *p;
+ char *p;
} value_t;
/* this one NEEDS to be in data */
static data value_t value;
-static xdata unsigned short radix;
+static unsigned char radix;
+
+// this makes the whole dammed thing nonreentrent
+static int charsOutputted;
/****************************************************************************/
{
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)) );
}
/*--------------------------------------------------------------------------*/
{
_asm
clr c
- mov a,_value+0
+ mov a,_value+0
rlc a
mov _value+0,a
mov a,_value+1
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;
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;
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 )
{
output_to_string = 1;
}
+#ifdef SDCC_ds390
+ if (format==0) {
+ format=NULL_STRING;
+ }
+#endif
+
while( c=*format++ )
{
if ( c=='%' )
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;
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');
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
if (float_argument) {
value.f=va_arg(ap,float);
#if !USE_FLOATS
+ PTR="<NO FLOAT>";
+ 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,
length=0;
lsd = 1;
- //jwk20000814: do this at least once, e.g.: printf ("%d", (int)0);
do {
value.byte[4] = 0;
calculate_digit();
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
}
/* prepend spaces if needed */
- if (!zero_padding)
+ if (!zero_padding && !left_justify)
{
while ( width > length+1 )
{
}
/* 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 */
output_digit( value.byte[4] );
}
+ if (left_justify)
+ while (width-- > 0)
+ output_char(' ');
}
}
else
output_char( c );
}
}
-
+
// 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;
+ }
}
/*--------------------------------------------------------------------------*/