fix float overflow checki in printf_fast_f, bug #1525093
[fw/sdcc] / device / lib / z80 / printf.c
index b6b4fbee137b345f9f26a62137c7900548397660..65c25b9732de3f67423291f52d37a502d49ea267 100644 (file)
@@ -1,51 +1,53 @@
 /** Simple printf implementation
-    Again a stub - will use the std one later...
+    This stub has been replaced by the std printf_large / sprintf / vprintf
 */
 
-#define NULL 0
+#include <stdarg.h>
+#include <stdio.h>
 
-/* A hack because I dont understand how va_arg works...
-   sdcc pushes right to left with the real sizes, not cast up
-   to an int.
-   so printf(int, char, long)
-   results in push long, push char, push int
-   On the z80 the stack grows down, so the things seem to be in
-   the correct order.
- */
+#define STATIC
 
-typedef char * va_list;
-#define va_start(list, last)   list = (char *)&last + sizeof(last)
-#define va_arg(list, type)     *(type *)list; list += sizeof(type);
-
-typedef void EMIT(char c, void *pData);
-
-
-static void _printhex(unsigned u, EMIT *emitter, void *pData)
+static void _printn(unsigned u, unsigned base, char issigned, volatile void (*emitter)(char, void *), void *pData)
 {
     const char *_hex = "0123456789ABCDEF";
-    if (u >= 0x10)
-       _printhex(u/0x10, emitter, pData);
-    (*emitter)(_hex[u&0x0f], pData);
+    if (issigned && ((int)u < 0)) {
+       (*emitter)('-', pData);
+       u = (unsigned)-((int)u);
+    }
+    if (u >= base)
+       _printn(u/base, base, 0, emitter, pData);
+    (*emitter)(_hex[u%base], pData);
 }
 
-static void _printf(const char *format, EMIT *emitter, void *pData, va_list va)
+STATIC void _printf(const char *format, volatile void (*emitter)(char, void *), void *pData, va_list va)
 {
     while (*format) {
        if (*format == '%') {
            switch (*++format) {
            case 'c': {
-               char c = va_arg(va, char);
+               char c = (char)va_arg(va, int);
                (*emitter)(c, pData);
                break;
            }
            case 'u':
+               {
+                   unsigned u = va_arg(va, unsigned);
+                   _printn(u, 10, 0, emitter, pData);
+                   break;
+               }
            case 'd':
                {
                    unsigned u = va_arg(va, unsigned);
-                   _printhex(u, emitter, pData);
+                   _printn(u, 10, 1, emitter, pData);
+                   break;
+               }
+           case 'x':
+               {
+                   unsigned u = va_arg(va, unsigned);
+                   _printn(u, 16, 0, emitter, pData);
                    break;
                }
-           case 's': 
+           case 's':
                {
                    char *s = va_arg(va, char *);
                    while (*s) {
@@ -64,15 +66,38 @@ static void _printf(const char *format, EMIT *emitter, void *pData, va_list va)
 
 void putchar(char c);
 
-static void _char_emitter(char c, void *pData)
+STATIC void _char_emitter(char c, void *pData)
 {
+    /* PENDING: Make the compiler happy. */
+    pData = 0;
+
     putchar(c);
 }
 
-void printf(const char *format, ...)
+int printf(const char *format, ...)
 {
     va_list va;
     va_start(va, format);
 
     _printf(format, _char_emitter, NULL, va);
+
+    /* PENDING: What to return? */
+    return 0;
+}
+
+STATIC void _buf_emitter(char c, void *pData)
+{
+  *((*((char **)pData)))++ = c;
+}
+
+int sprintf(char *pInto, const char *format, ...)
+{
+    va_list va;
+    va_start(va, format);
+
+    _printf(format, _buf_emitter, &pInto, va);
+    *pInto++ = '\0';
+
+    /* PENDING: What to return? */
+    return 0;
 }