* device/include/stdio.h: added NULL, size_t, typedef pfn_outputchar,
authormaartenbrock <maartenbrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 31 Aug 2004 17:06:35 +0000 (17:06 +0000)
committermaartenbrock <maartenbrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 31 Aug 2004 17:06:35 +0000 (17:06 +0000)
  _print_format; updated printf, sprintf, vsprintf
* device/include/asm/default/features.h: corrected comment/define
* device/lib/Makefile.in: added sprintf.c
* device/lib/libsdcc.lib: added sprintf module
* device/lib/printf_large.c,
* device/lib/vprintf.c,
* device/lib/sprintf.c: totally refactored printf_large and vprintf
  into these 3 files
* support/regression/Makefile: changed ALL_PORTS into a usefull default
* support/regression/ports/mcs51-stack-auto/spec.mk: added sprintf
* support/regression/tests/bug-927659.c: removed dummy putchar, enabled
  hc08 test
* support/regression/tests/zeropad.c: define idata as data for hc08

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3467 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
device/include/asm/default/features.h
device/include/stdio.h
device/lib/Makefile.in
device/lib/libsdcc.lib
device/lib/printf_large.c
device/lib/vprintf.c
support/regression/Makefile
support/regression/ports/mcs51-stack-auto/spec.mk
support/regression/tests/bug-927659.c
support/regression/tests/zeropad.c

index 4788d7f586a2f7b014e290afaed0d4d688cda7c5..8aa4ffe0a4a4a09c13166cfb58ecaab2bca23954 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,21 @@
-2004-08-30 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+2004-08-31 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       * device/include/stdio.h: added NULL, size_t, typedef pfn_outputchar,
+         _print_format; updated printf, sprintf, vsprintf
+       * device/include/asm/default/features.h: corrected comment/define
+       * device/lib/Makefile.in: added sprintf.c
+       * device/lib/libsdcc.lib: added sprintf module
+       * device/lib/printf_large.c,
+       * device/lib/vprintf.c,
+       * device/lib/sprintf.c: totally refactored printf_large and vprintf
+         into these 3 files
+       * support/regression/Makefile: changed ALL_PORTS into a usefull default
+       * support/regression/ports/mcs51-stack-auto/spec.mk: added sprintf
+       * support/regression/tests/bug-927659.c: removed dummy putchar, enabled
+         hc08 test
+       * support/regression/tests/zeropad.c: define idata as data for hc08
+
+2004-08-31 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
 
        * src/SDCCpeeph.c (labelIsReturnOnly): support hc08 rts opcode also
        * src/SDCCpeeph.c (buildLabelRefCountHash): assume function entry point
index d240f1a7e18b13e250a092e4f6c5674b3590cfa0..7e903b9f71c7fc9da412f582214e84725f9eb62c 100644 (file)
@@ -1,7 +1,7 @@
-/** Z80 specific features.
+/** default features.
  */
-#ifndef __SDC51_ASM_Z80_FEATURES_H
-#define __SDC51_ASM_Z80_FEATURES_H   1
+#ifndef __SDC51_ASM_FEATURES_H
+#define __SDC51_ASM_FEATURES_H   1
 
 #define _REENTRANT     reentrant
 #define _CODE          code
index 714b02ad0fbb1a9d562da866f8a0f4e64f03f61a..803c1bb04f7c88f068038f438cfac9dbdb8e3455 100644 (file)
@@ -1,25 +1,25 @@
 /*-------------------------------------------------------------------------
   stdio.h - ANSI functions forward declarations
+
              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
 
    This program is free software; you can redistribute it and/or modify it
    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!
 -------------------------------------------------------------------------*/
 
 #ifndef __SDC51_STDIO_H
 
 #include <sdcc-lib.h>
 
+#ifndef NULL
+  #define NULL (void *)0
+#endif
+
+#ifndef _SIZE_T_DEFINED
+#define _SIZE_T_DEFINED
+  typedef unsigned int size_t;
+#endif
+
+typedef void (*pfn_outputchar)(char c, void* p) _REENTRANT;
+
+extern int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list ap);
+
+/*-----------------------------------------------------------------------*/
+
 extern void printf_small (char *,...) _REENTRANT;
-extern int printf (const char *,...) _REENTRANT;
+extern int printf (const char *,...);
 extern int vprintf (const char *, va_list);
-extern int sprintf (const char *, const char *, ...) _REENTRANT;
-extern int vsprintf (const char *, const char *, va_list);
+extern int sprintf (char *, const char *, ...);
+extern int vsprintf (char *, const char *, va_list);
 extern int puts(const char *);
 extern char *gets(char *);
 extern char getchar(void);
index 317863ea45f75c09f37edd208d1d6ca2d6bde1a3..419859bfe94ede8b5961950c9d17dac55bef0ce6 100644 (file)
@@ -51,19 +51,21 @@ SOURCES             = _atof.c _atoi.c _atol.c _autobaud.c _bp.c _schar2fs.c \
                  _sint2fs.c _iscntrl.c _isdigit.c _isgraph.c \
                  _islower.c _isprint.c _ispunct.c _isspace.c \
                  _isupper.c _isxdigit.c _itoa.c _ltoa.c \
-                  _slong2fs.c _memcmp.c \
-                 _memcpy.c _memmove.c _memset.c _modsint.c _modslong.c \
-                 _moduint.c _modulong.c _mulint.c _mullong.c \
+                 _slong2fs.c \
+                 _memcmp.c _memcpy.c _memmove.c _memset.c \
+                 _modsint.c _modslong.c _moduint.c _modulong.c \
+                 _mulint.c _mullong.c \
                  _ser.c _setjmp.c \
-                 _spx.c _startup.c _strchr.c _strcmp.c _strcpy.c \
+                 _spx.c _startup.c \
+                 _strcat.c _strchr.c _strcmp.c _strcpy.c \
                  _strcspn.c _strlen.c _strncat.c _strncmp.c \
                  _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
                  _strstr.c _strtok.c \
                  _uchar2fs.c _uint2fs.c _ulong2fs.c \
                  calloc.c malloc.c realloc.c free.c \
                  serial.c ser_ir.c printfl.c \
-                 printf_large.c vprintf.c puts.c gets.c \
-                 assert.c _strcat.c time.c printf_fast.c bpx.c \
+                 printf_large.c sprintf.c vprintf.c puts.c gets.c \
+                 assert.c time.c printf_fast.c bpx.c \
                  fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \
                  cosf.c logf.c log10f.c sqrtf.c tancotf.c tanf.c cotf.c \
                  asincosf.c asinf.c acosf.c atanf.c atan2f.c sincoshf.c \
@@ -74,14 +76,15 @@ OBJECTS             = $(patsubst %.c,$(PORTDIR)/%.rel,$(SOURCES))
 Z80SOURCES      = _atof.c _atoi.c \
                  _iscntrl.c _isdigit.c _isgraph.c \
                  _islower.c _isprint.c _ispunct.c _isspace.c \
-                 _isupper.c _isxdigit.c _memcmp.c \
-                 _memcpy.c _memmove.c _memset.c \
-                 _startup.c _strchr.c _strcmp.c _strcpy.c \
+                 _isupper.c _isxdigit.c \
+                 _memcmp.c _memcpy.c _memmove.c _memset.c \
+                 _startup.c \
+                 _strcat.c _strchr.c _strcmp.c _strcpy.c \
                  _strcspn.c _strlen.c _strncat.c _strncmp.c \
                  _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
                  _strstr.c _strtok.c \
                  puts.c gets.c \
-                 assert.c _strcat.c \
+                 assert.c \
                  _modslong.c _modulong.c \
                  _mullong.c \
                  _divslong.c _divulong.c \
@@ -107,7 +110,7 @@ XA51SOURCES      = _atof.c _atoi.c _atol.c _schar2fs.c \
                  _isupper.c _isxdigit.c _slong2fs.c _memcmp.c \
                  _memcpy.c _memmove.c _memset.c _modsint.c _modslong.c \
                  _moduint.c _modulong.c _mulint.c _mullong.c \
-                 _strchr.c _strcmp.c _strcpy.c \
+                 _strcat.c _strchr.c _strcmp.c _strcpy.c \
                  _strcspn.c _strlen.c _strncat.c _strncmp.c \
                  _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
                  _strstr.c _strtok.c \
@@ -115,7 +118,7 @@ XA51SOURCES      = _atof.c _atoi.c _atol.c _schar2fs.c \
                  calloc.c malloc.c realloc.c free.c \
                  puts.c gets.c \
                  printf_large.c puts.c gets.c \
-                 assert.c _strcat.c time.c \
+                 assert.c time.c \
                  fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \
                  cosf.c logf.c log10f.c sqrtf.c tancotf.c tanf.c cotf.c \
                  asincosf.c asinf.c acosf.c atanf.c atan2f.c sincoshf.c \
@@ -132,16 +135,18 @@ HC08SOURCES       = _atof.c _atoi.c _atol.c _schar2fs.c \
                  _sint2fs.c _iscntrl.c _isdigit.c _isgraph.c \
                  _islower.c _isprint.c _ispunct.c _isspace.c \
                  _isupper.c _isxdigit.c _itoa.c _ltoa.c \
-                  _slong2fs.c _memcmp.c \
-                 _memcpy.c _memmove.c _memset.c _modsint.c _modslong.c \
-                 _moduint.c _modulong.c \
-                 _spx.c _startup.c _strchr.c _strcmp.c _strcpy.c \
+                 _slong2fs.c \
+                 _memcmp.c _memcpy.c _memmove.c _memset.c \
+                 _modsint.c _modslong.c _moduint.c _modulong.c \
+                 _spx.c _startup.c \
+                 _strcat.c _strchr.c _strcmp.c _strcpy.c \
                  _strcspn.c _strlen.c _strncat.c _strncmp.c \
                  _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
                  _strstr.c _strtok.c \
                  _uchar2fs.c _uint2fs.c _ulong2fs.c \
                  calloc.c malloc.c realloc.c free.c \
-                 assert.c _strcat.c time.c \
+                 printf_large.c sprintf.c vprintf.c \
+                 assert.c time.c \
                  fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \
                  cosf.c logf.c log10f.c sqrtf.c tancotf.c tanf.c cotf.c \
                  asincosf.c asinf.c acosf.c atanf.c atan2f.c sincoshf.c \
index 77ef0bdff153a4576587e0a01a200a72f7c0a53f..30c09e82f0b011513c23c3b4c4418b1b83bbb0c0 100644 (file)
@@ -9,12 +9,12 @@ _isupper
 _isxdigit
 _itoa
 _ltoa
+_strcat
 _strchr
 _strcmp
 _strcpy
 _strcspn
 _strlen
-_strcat
 _strncat
 _strncmp
 _strncpy
@@ -48,6 +48,7 @@ gets
 printfl
 printf_large
 printf_fast
+sprintf
 vprintf
 assert
 time
index d7ec601b54236fcb84d49163c996c56f8b173895..d50552725c61ecf0ffecb3c4293a0d1907304e81 100644 (file)
 /*-------------------------------------------------------------------------
-  printf.c - formatted output conversion
+  printf_large.c - formatted output conversion
+
              Written By - Martijn van Balen aed@iae.nl (1999)
+             Added %f By - johan.knol@iduna.nl (2000)
+             Refactored by - Maarten Brock (2004)
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is free software; you can redistribute it and/or modify it
-   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,
+   This library 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.
-   
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 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 SDCC_STACK_AUTO
+  #ifdef ASM_ALLOWED
+    /* Eventually we should get rid of ASM_ALLOWED completely as it   */
+    /* prevents portability, clobbers this source and brings only 2%  */
+    /* optimization. A better alternative is a completely handcrafted */
+    /* asm version if needed. */
+    #undef ASM_ALLOWED
+  #endif
+#endif
+
+#if defined(__ds390)
+#define USE_FLOATS 1
+#endif
+
 #include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
 #include <stdio.h>
 
-int printf (const char *format, ...) _REENTRANT
+#define PTR value.ptr
+
+#ifdef SDCC_ds390
+#define NULL_STRING "<NULL>"
+#define NULL_STRING_LENGTH 6
+#endif
+
+/****************************************************************************/
+
+//typedef char * ptr_t;
+#define ptr_t char *
+
+#ifdef toupper
+#undef toupper
+#endif
+
+//#define toupper(c) ((c)&=~0x20)
+#define toupper(c) ((c)&=0xDF)
+
+#if defined (SDCC_STACK_AUTO) || defined (SDCC_hc08)
+ //as long as bit/bool cannot be used reentrant
+ #define BOOL char
+#else
+ #define BOOL bit
+#endif
+
+typedef union
 {
-  va_list arg;
-  int done;
+  unsigned char  byte[5];
+  long           l;
+  unsigned long  ul;
+  float          f;
+  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;
+
+  #ifdef ASM_ALLOWED
+    static bit   lsd;
+
+    /* this one NEEDS to be in data */
+    static data value_t value;
+  #else
+    static value_t value;
+  #endif
+#endif
 
-  va_start (arg, format);
-  done = vprintf (format, arg);
-  va_end (arg);
+/****************************************************************************/
 
-  return done;
+#ifdef SDCC_STACK_AUTO
+  static void output_digit( unsigned char n, BOOL lower_case, pfn_outputchar output_char, void* p )
+#else
+  static void output_digit( unsigned char n )
+#endif
+  {
+    output_char( n <= 9 ? '0'+n :
+               (lower_case ? n+(char)('a'-10) : n+(char)('A'-10)), p );
+  }
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef SDCC_STACK_AUTO
+  #define OUTPUT_2DIGITS( B )  output_2digits( B, lower_case, output_char, p )
+  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 )
+  static void output_2digits( unsigned char b )
+  {
+    output_digit( b>>4   );
+    output_digit( b&0x0F );
+  }
+#endif
+
+/*--------------------------------------------------------------------------*/
+
+#if defined ASM_ALLOWED
+static void calculate_digit( unsigned char radix )
+{
+  unsigned char i;
+
+  for( i = 32; i != 0; i-- )
+  {
+_asm
+  clr  c
+  mov  a,_value+0
+  rlc  a
+  mov  _value+0,a
+  mov  a,_value+1
+  rlc  a
+  mov  _value+1,a
+  mov  a,_value+2
+  rlc  a
+  mov  _value+2,a
+  mov  a,_value+3
+  rlc  a
+  mov  _value+3,a
+  mov  a,_value+4
+  rlc  a
+  mov  _value+4,a
+_endasm;
+    if (radix <= value.byte[4] )
+    {
+      value.byte[4] -= radix;
+      value.byte[0]++;
+    }
+  }
 }
+#elif defined SDCC_STACK_AUTO
+static void calculate_digit( value_t* value, unsigned char radix )
+{
+  unsigned char i;
+
+  for( i = 32; i != 0; i-- )
+  {
+    value->byte[4] = (value->byte[4] << 1) | (value->ul >> 31) & 0x01;
+    value->ul <<= 1;
 
-int sprintf (const char *buf, const char *format, ...) _REENTRANT
+    if (radix <= value->byte[4] )
+    {
+      value->byte[4] -= radix;
+      value->byte[0]++;
+    }
+  }
+}
+#else
+static void calculate_digit( unsigned char radix )
 {
-  va_list arg;
-  int done;
+  unsigned char i;
 
-  va_start (arg, format);
-  done = vsprintf (buf, format, arg);
-  va_end (arg);
+  for( i = 32; i != 0; i-- )
+  {
+    value.byte[4] = (value.byte[4] << 1) | (value.ul >> 31) & 0x01;
+    value.ul <<= 1;
 
-  return done;
+    if (radix <= value.byte[4] )
+    {
+      value.byte[4] -= radix;
+      value.byte[0]++;
+    }
+  }
 }
+#endif
+
+#if USE_FLOATS
+
+/* This is a very inefficient but direct approach, since we have no math
+   library yet (e.g. log()).
+   It does most of the modifiers, but has some restrictions. E.g. the
+   abs(float) shouldn't be bigger than an unsigned long (that's
+   about 4294967295), but still makes it usefull for most real-life
+   applications.
+*/
+
+#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)
+#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
+{
+  char negative=0;
+  unsigned long integerPart;
+  float decimalPart;
+  char fpBuffer[128];
+  char fpBI=0, fpBD;
+  unsigned char minWidth, i;
+  int charsOutputted=0;
+
+  // save the sign
+  if (f<0) {
+    negative=1;
+    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) {
+      output_char ('-', p);
+      charsOutputted++;
+    } else {
+      if (sign) {
+        output_char ('+', p);
+        charsOutputted++;
+      }
+    }
+    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;
+  }
+
+  // split the float
+  integerPart=f;
+  decimalPart=f-integerPart;
+
+  // fill the buffer with the integerPart (in reversed order!)
+  while (integerPart) {
+    fpBuffer[fpBI++]='0' + integerPart%10;
+    integerPart /= 10;
+  }
+  if (!fpBI) {
+    // we need at least a 0
+    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;
+  if (i=reqDecimals /* that's an assignment */) {
+    do {
+      decimalPart *= 10.0;
+      // truncate the float
+      integerPart=decimalPart;
+      fpBuffer[fpBD++]='0' + integerPart;
+      decimalPart-=integerPart;
+    } while (--i);
+  }
+
+  minWidth=fpBI; // we need at least these
+  minWidth+=reqDecimals?reqDecimals+1:0; // maybe these
+  if (negative || sign || space)
+    minWidth++; // and maybe even this :)
+
+  if (!left && reqWidth>i) {
+    if (zero) {
+      if (negative)
+      {
+        output_char('-', p);
+        charsOutputted++;
+      }
+      else if (sign)
+      {
+        output_char('+', p);
+        charsOutputted++;
+      }
+      else if (space)
+      {
+        output_char(' ', p);
+        charsOutputted++;
+      }
+      while (reqWidth-->minWidth)
+      {
+        output_char('0', p);
+        charsOutputted++;
+      }
+    } else {
+      while (reqWidth-->minWidth)
+      {
+        output_char(' ', p);
+        charsOutputted++;
+      }
+      if (negative)
+      {
+        output_char('-', p);
+        charsOutputted++;
+      }
+      else if (sign)
+      {
+        output_char('+', p);
+        charsOutputted++;
+      }
+      else if (space)
+      {
+        output_char(' ', p);
+        charsOutputted++;
+      }
+    }
+  } else {
+    if (negative)
+    {
+      output_char('-', p);
+      charsOutputted++;
+    }
+    else if (sign)
+    {
+      output_char('+', p);
+      charsOutputted++;
+    }
+    else if (space)
+    {
+      output_char(' ', p);
+      charsOutputted++;
+    }
+  }
+
+  // output the integer part
+  i=fpBI-1;
+  do {
+    output_char (fpBuffer[i], p);
+    charsOutputted++;
+  } while (i--);
+
+  // ouput the decimal part
+  if (reqDecimals) {
+    output_char ('.', p);
+    charsOutputted++;
+    i=fpBI;
+    while (reqDecimals--)
+    {
+      output_char (fpBuffer[i++], p);
+      charsOutputted++;
+    }
+  }
+
+  if (left && reqWidth>minWidth) {
+    while (reqWidth-->minWidth)
+    {
+      output_char(' ', p);
+      charsOutputted++;
+    }
+  }
+  return charsOutputted;
+}
+#endif
+
+int _print_format (pfn_outputchar pfn, void* pvoid, const char *format, va_list ap)
+{
+  BOOL   left_justify;
+  BOOL   zero_padding;
+  BOOL   prefix_sign;
+  BOOL   prefix_space;
+  BOOL   signed_argument;
+  BOOL   char_argument;
+  BOOL   long_argument;
+  BOOL   float_argument;
+#ifdef SDCC_STACK_AUTO
+  BOOL   lower_case;
+  value_t value;
+#endif
+#ifndef ASM_ALLOWED
+  BOOL   lsd;
+#endif
+
+  unsigned char radix;
+  int charsOutputted;
+  unsigned char  width;
+  signed char decimals;
+  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 )
+        {
+          output_char( *PTR++, p );
+          charsOutputted++;
+        }
+
+        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 = 0;
+
+        // store value in byte[0] (LSB) ... byte[3] (MSB)
+        if (char_argument)
+        {
+          value.l = va_arg(ap,char);
+          if (!signed_argument)
+          {
+            value.byte[1] = 0x00;
+            value.byte[2] = 0x00;
+            value.byte[3] = 0x00;
+          }
+        }
+        else if (long_argument)
+        {
+          value.l = va_arg(ap,long);
+        }
+        else // must be int
+        {
+          value.l = va_arg(ap,int);
+          if (!signed_argument)
+          {
+            value.byte[2] = 0x00;
+            value.byte[3] = 0x00;
+          }
+        }
+
+        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 defined ASM_ALLOWED
+_asm
+  jb   _lsd,1$
+  pop  b                ; b = <lsd>
+  mov  a,_value+4       ; a = <msd>
+  swap a
+  orl  b,a              ; b = <msd><lsd>
+  push b
+  sjmp 2$
+1$:
+  mov  a,_value+4       ; a = <lsd>
+  push acc
+2$:
+_endasm;
+#else
+          if (!lsd)
+          {
+            store = (value.byte[4] << 4) | (value.byte[4] >> 4) | store;
+          }
+          else
+          {
+            store = value.byte[4];
+          }
+#endif
+          length++;
+          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
+          // 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;
+#ifdef ASM_ALLOWED
+_asm
+  jb   _lsd,3$
+  pop  acc              ; a = <msd><lsd>
+  nop                   ; to disable the "optimizer"
+  push acc
+  swap a
+  anl  a,#0x0F          ; a = <msd>
+  sjmp 4$
+3$:
+  pop  acc
+  anl  a,#0x0F          ; a = <lsd>
+4$:
+  mov  _value+4,a
+_endasm;
+#else
+          if (!lsd)
+          {
+            value.byte[4] = store >> 4;
+          }
+          else
+          {
+            value.byte[4] = store & 0x0F;
+          }
+#endif
+#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;
+}
+
+/****************************************************************************/
index 75a3f84ab23e189704645aa19a9a387bb0b6981d..07b5cac365d817ece1ea3cd4df1cab459e40ef69 100644 (file)
   vprintf.c - formatted output conversion
 
              Written By - Martijn van Balen aed@iae.nl (1999)
-            Added %f By - johan.knol@iduna.nl (2000)
+             Refactored by - Maarten Brock (2004)
 
-   This program is free software; you can redistribute it and/or modify it
-   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 library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful,
+   This library 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.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser 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.
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 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!
 -------------------------------------------------------------------------*/
 
-/* 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
-
-#ifdef SDCC_ds390
-#define NULL_STRING "<NULL>"
-#define NULL_STRING_LENGTH 6
-#endif
-
-/****************************************************************************/
-
-//typedef char * ptr_t;
-#define ptr_t char *
-
-#ifdef toupper
-#undef toupper
-#endif
-
-//#define toupper(c) ((c)&=~0x20)
-#define toupper(c) ((c)&=0xDF)
-
-typedef union
-{
-  unsigned char  byte[5];
-  long           l;
-  unsigned long  ul;
-  float          f;
-  char           *p;
-} value_t;
-
-
-static code char memory_id[] = "IXCP-";
-
-static ptr_t output_ptr;
-static bit   output_to_string;
-static bit   lower_case;
-static bit   lsd;
-
-/* this one NEEDS to be in data */
-static data value_t value;
-
-static unsigned char radix;
-
-// this makes the whole dammed thing nonreentrent
-static int charsOutputted;
-
-/****************************************************************************/
-
-static void output_char( char c ) reentrant
-{
-  if (output_to_string)
-  {
-    *output_ptr++ = c;
-  }
-  else
-  {
-    putchar( c );
-  }
-  charsOutputted++;
-}
-
-/*--------------------------------------------------------------------------*/
-
-static void output_digit( unsigned char n ) reentrant
+static void put_char_to_stdout( char c, void* p ) _REENTRANT
 {
-  output_char( n <= 9 ? '0'+n : 
-              (lower_case ? n+(char)('a'-10) : n+(char)('A'-10)) );
+  p;  //make compiler happy
+  putchar( c );
 }
 
-/*--------------------------------------------------------------------------*/
-
-static void output_2digits( unsigned char b ) reentrant
-{
-  output_digit( b>>4 );
-  output_digit( b&0x0F );
-}
-        
-/*--------------------------------------------------------------------------*/
-
-static void calculate_digit( void )
-{
-  unsigned char i;
-
-  for( i = 32; i != 0; i-- )
-  {
-_asm
-  clr  c
-  mov  a,_value+0  
-  rlc  a
-  mov  _value+0,a
-  mov  a,_value+1
-  rlc  a
-  mov  _value+1,a
-  mov  a,_value+2
-  rlc  a
-  mov  _value+2,a
-  mov  a,_value+3
-  rlc  a
-  mov  _value+3,a
-  mov  a,_value+4
-  rlc  a
-  mov  _value+4,a
-_endasm;
-
-    if (radix <= value.byte[4] )
-    {
-      value.byte[4] -= radix;
-      value.byte[0]++;
-    }
-  }
-}
-
-#if USE_FLOATS
-
-/* This is a very inefficient but direct approach, since we have no math
-   library yet (e.g. log()).
-   It does most of the modifiers, but has some restrictions. E.g. the 
-   abs(float) shouldn't be bigger than an unsigned long (that's 
-   about 4294967295), but still makes it usefull for most real-life
-   applications.
-*/
-
-#define DEFAULT_FLOAT_PRECISION 6
-
-static void output_float (float f, unsigned char reqWidth, 
-                         signed char reqDecimals,
-                         bit left, bit zero, bit sign, bit space)
+int vprintf (const char *format, va_list ap)
 {
-  char negative=0;
-  unsigned long integerPart;
-  float decimalPart;
-  char fpBuffer[128];
-  char fpBI=0, fpBD;
-  unsigned char minWidth, i;
-
-  // save the sign
-  if (f<0) {
-    negative=1;
-    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;
-
-  // fill the buffer with the integerPart (in reversed order!)
-  while (integerPart) {
-    fpBuffer[fpBI++]='0' + integerPart%10;
-    integerPart /= 10;
-  }
-  if (!fpBI) {
-    // we need at least a 0
-    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;
-  if (i=reqDecimals /* that's an assignment */) {
-    do {
-      decimalPart *= 10.0;
-      // truncate the float
-      integerPart=decimalPart;
-      fpBuffer[fpBD++]='0' + integerPart;
-      decimalPart-=integerPart;
-    } while (--i);
-  }
-  
-  minWidth=fpBI; // we need at least these
-  minWidth+=reqDecimals?reqDecimals+1:0; // maybe these
-  if (negative || sign || space)
-    minWidth++; // and maybe even this :)
-  
-  if (!left && reqWidth>i) {
-    if (zero) {
-      if (negative) output_char('-');
-      else if (sign) output_char('+');
-      else if (space) output_char(' ');
-      while (reqWidth-->minWidth)
-       output_char ('0');
-    } else {
-      while (reqWidth-->minWidth)
-       output_char (' ');
-      if (negative) output_char('-');
-      else if (sign) output_char('+');
-      else if (space) output_char (' ');
-    }
-  } else {
-    if (negative) output_char('-');
-    else if (sign) output_char('+');
-    else if (space) output_char(' ');
-  }
-
-  // output the integer part
-  i=fpBI-1;
-  do {
-    output_char (fpBuffer[i]);
-  } while (i--);
-  
-  // ouput the decimal part
-  if (reqDecimals) {
-    output_char ('.');
-    i=fpBI;
-    while (reqDecimals--)
-      output_char (fpBuffer[i++]);
-  }
-
-  if (left && reqWidth>minWidth) {
-    while (reqWidth-->minWidth)
-      output_char(' ');
-  }
+  return _print_format( put_char_to_stdout, NULL, format, ap );
 }
-#endif
 
-/*--------------------------------------------------------------------------*/
-
-int vsprintf (const char *buf, const char *format, va_list ap)
+int printf (const char *format, ...)
 {
-  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 = 0;
-  }
-  else
-  {
-    output_to_string = 1;
-  }
-
-#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);
-       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) );
-       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( ' ' );
-         }
-       }
-
-        while ( *PTR )
-         output_char( *PTR++ );
-
-       if ( left_justify && (length < width))
-       {
-         width -= length;
-         while( width-- != 0 )
-         {
-           output_char( ' ' );
-         }
-       }
-       break;
-
-      case 'P':
-       PTR = va_arg(ap,ptr_t);
-
-#ifdef SDCC_ds390
-       output_char(memory_id[(value.byte[3] > 3) ? 4 : value.byte[3]] );
-       output_char(':');
-       output_char('0');
-       output_char('x');
-       output_2digits(value.byte[2]);
-       output_2digits(value.byte[1]);
-       output_2digits(value.byte[0]);
-#else
-       output_char( memory_id[(value.byte[2] > 3) ? 4 : value.byte[2]] );
-       output_char(':');
-       output_char('0');
-       output_char('x');
-       if ((value.byte[2] != 0x00 /* DSEG */) &&
-           (value.byte[2] != 0x03 /* SSEG */))
-         output_2digits( value.byte[1] );
-       output_2digits( value.byte[0] );
-#endif
-       break;
-
-      case 'D':
-      case 'I':
-       signed_argument = 1;
-       radix = 10;
-       break;
-
-      case 'O':
-       radix = 8;
-       break;
+  va_list arg;
+  int i;
 
-      case 'U':
-       radix = 10;
-       break;
+  va_start (arg, format);
+  i = _print_format( put_char_to_stdout, NULL, format, arg );
+  va_end (arg);
 
-      case 'X':
-       radix = 16;
-       break;
-
-      case 'F':
-       float_argument=1;
-       break;
-       
-      default:
-       // nothing special, just output the character
-       output_char( c );
-       break;
-      }
-
-      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;
-#else
-       // ignore b and l conversion spec for now
-       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"
-
-        // store value in byte[0] (LSB) ... byte[3] (MSB)
-       if (char_argument)
-       {
-         value.l = va_arg(ap,char);
-         if (!signed_argument)
-         {
-           value.byte[1] = 0x00;
-           value.byte[2] = 0x00;
-           value.byte[3] = 0x00;
-         }
-       }
-       else if (long_argument)
-       {
-         value.l = va_arg(ap,long);
-       }
-       else // must be int
-       {
-         value.l = va_arg(ap,int);
-         if (!signed_argument)
-         {
-           value.byte[2] = 0x00;
-           value.byte[3] = 0x00;
-         }
-       }
-
-        if ( signed_argument )
-        {
-          if (value.l < 0)
-            value.l = -value.l;
-          else
-            signed_argument = 0;
-        }
-
-       length=0;
-        lsd = 1;
-
-       do {
-          value.byte[4] = 0;
-         calculate_digit();
-
-_asm
-  jb   _lsd,1$
-  pop  b                ; b = <lsd>
-  mov  a,_value+4       ; a = <msd>
-  swap a
-  orl  b,a              ; b = <msd><lsd>
-  push b
-  sjmp 2$
-1$:
-  mov  a,_value+4       ; a = <lsd>
-  push acc
-2$:
-_endasm;
-
-         length++;
-          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
-          // at least one character is 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( ' ' );
-           width--;
-         }
-       }
-
-        if (signed_argument) // this now means the original value was negative
-        {
-          output_char( '-' );
-         // adjust width to compensate for this character
-         width--;
-        }
-        else if (length != 0)
-       {
-         // value > 0
-         if (prefix_sign)
-         {
-           output_char( '+' );
-           // adjust width to compensate for this character
-           width--;
-         }
-         else if (prefix_space)
-         {
-           output_char( ' ' );
-           // adjust width to compensate for this character
-            width--;
-         }
-       }
-
-       /* prepend zeroes/spaces if needed */
-       if (!left_justify)
-         while ( width-- > length )
-         {
-           output_char( zero_padding ? '0' : ' ' );
-         }
-       else
-       {
-         /* spaces are appended after the digits */
-         if (width > length)
-           width -= length;
-         else
-           width = 0;
-       }
-
-       /* output the digits */
-       while( length-- )
-       {
-          lsd = ~lsd;
-
-_asm
-  jb   _lsd,3$
-  pop  acc              ; a = <msd><lsd>
-  nop                   ; to disable the "optimizer"
-  push acc
-  swap a
-  anl  a,#0x0F          ; a = <msd>
-  sjmp 4$
-3$:
-  pop  acc
-  anl  a,#0x0F          ; a = <lsd>
-4$:
-  mov  _value+4,a
-_endasm;
-
-         output_digit( value.byte[4] );
-       }
-       if (left_justify)
-         while (width-- > 0)
-           output_char(' ');
-      }
-    }
-    else
-    {
-      // nothing special, just output the character
-      output_char( c );
-    }
-  }
-
-  // Copy \0 to the end of buf
-  // Modified by JB 17/12/99
-  if (output_to_string) {
-    output_char(0);
-    return charsOutputted-1;
-  } else {
-    return charsOutputted;
-  }
-}
-
-/*--------------------------------------------------------------------------*/
-
-int vprintf (const char *format, va_list ap)
-{
-  return vsprintf( 0, format, ap );
+  return i;
 }
index 0253dd531ce7473d4f0b656c83f6e743988dc021..a9c09980c705ae5052ac79068e1587f7ec9f6468 100644 (file)
@@ -38,7 +38,7 @@
 
 # Uncomment this to show only errors and the summary.
 # Comment this out for debugging.
-#.SILENT:
+.SILENT:
 
 # All original tests live in TESTS_DIR and below
 TESTS_DIR = tests
@@ -60,7 +60,7 @@ GENERATE_CASES = generate-cases.py
 # Each directory under ports/ is used as a port name.  Each port is tested.
 # Each port must have a spec.mk which describes how to build the object
 # files and how to run the emulator.
-ALL_PORTS = $(filter-out CVS xa51 mcs51 mcs51-large mcs51-stack-auto ds390 gbz80 hc08,$(notdir $(wildcard $(PORTS_DIR)/*)))
+ALL_PORTS = $(filter-out CVS xa51 ucz80 gbz80,$(notdir $(wildcard $(PORTS_DIR)/*)))
 
 # These  ports will be cleaned with 'make clean'
 CLEAN_PORTS = $(filter-out CVS,$(notdir $(wildcard $(PORTS_DIR)/*)))
index b94a4bc07a28cf7c505b22448d7959eb48462cb3..cbf31b843a42f454f35c5846f6877026b6b456fb 100644 (file)
@@ -30,15 +30,16 @@ SOURCES = _atoi.c _atol.c _autobaud.c _bp.c _schar2fs.c \
           _modsint.c _modslong.c _moduint.c _modulong.c \
           _mulint.c _mullong.c \
           _ser.c _setjmp.c \
-          _spx.c _startup.c _strchr.c _strcmp.c _strcpy.c \
+          _spx.c _startup.c \
+          _strcat.c _strchr.c _strcmp.c _strcpy.c \
           _strcspn.c _strlen.c _strncat.c _strncmp.c \
           _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
           _strstr.c _strtok.c \
           _uchar2fs.c _uint2fs.c _ulong2fs.c \
           calloc.c malloc.c realloc.c free.c \
           serial.c ser_ir.c printfl.c \
-          printf_large.c vprintf.c puts.c gets.c \
-          assert.c _strcat.c time.c printf_fast.c bpx.c
+          printf_large.c sprintf.c vprintf.c puts.c gets.c \
+          assert.c time.c printf_fast.c bpx.c
 
 OBJECTS = $(patsubst %.c,$(LIBDIR)/%.rel,$(SOURCES))
 MODULES = $(patsubst %.c,%,$(SOURCES))
index 520bb75ca8aef6bd4aae1fb9cf89da6c653cabd9..5e809a0c81bf86483d95317ce98cb46c992cf034 100644 (file)
@@ -16,7 +16,7 @@ foo(unsigned char a, ...) REENTRANT
   va_start (argptr, a);
   b = va_arg (argptr, int);
   va_end (argptr);
-  
+
   return b;
 }
 
@@ -34,17 +34,10 @@ testReverse(void)
 
 /*************************************************************/
 
-#if !defined(PORT_HOST) && !defined(SDCC_ds390)
-void putchar (char c)
-{
-  c;
-}
-#endif
-
 void
 testAddFunc(void)
 {
-#if !defined(SDCC_z80) && !defined(SDCC_hc08)
+#ifndef SDCC_z80
   char buf[5];
   unsigned char count = 0;
 
@@ -56,4 +49,3 @@ testAddFunc(void)
   ASSERT(1);
 #endif
 }
-//#endif
index e04bb8848dc1d7d890d29c4e989f1b79774b47ce..05069b46d53b8191d498503c77b662e9cbdd88d0 100644 (file)
@@ -25,8 +25,9 @@ typedef unsigned int size_t;
 # define xdata
 # define code
 #endif
+
 #if defined(SDCC_hc08)
-# define idata
+# define idata data
 #endif
 
 const char *string1 = "\x00\x01";