update fdprintf
authorLaurent Mazet <mazet@softndesign.org>
Sun, 22 Jan 2023 08:20:17 +0000 (09:20 +0100)
committerLaurent Mazet <mazet@softndesign.org>
Sun, 22 Jan 2023 08:20:17 +0000 (09:20 +0100)
fdprintf.c
fdprintf.h

index 238878dce42b2877ba90c719b9a62e46bfb4b945..46f27acb8f6b7a05032a4bd5d1038f90011b6061 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "fdprintf.h"
 
+int stdfdin = STDIN_FILENO;
 int stdfdout = STDOUT_FILENO;
 int stdfderr = STDERR_FILENO;
 
@@ -29,6 +30,51 @@ unsigned int nextpow (unsigned int x, int base) {
     return (n == 0) ? 1 : n;
 }
 
+char *itoa (char *str, unsigned u, unsigned int sz)
+{
+    unsigned int i = (sz == 0 ) ? nextpow (u, 10) : sz;
+    char *s = str;
+    while (i > 0) {
+        str[i - 1] = '0' + (u % 10);
+        u /= 10;
+        i--;
+        s++;
+    }
+    return s;
+}
+
+double tenpower(int n)
+{
+    double t = 1.0;
+    int i;
+    for (i = 0; i < n; i++) {
+        t *= 10;
+    }
+    for (i = 0; i > n; i--) {
+        t /= 10;
+    }
+    return t;
+}
+
+int getexponant (double *f, int maxexp)
+{
+    int exp = 0;
+    while (*f > 10) {
+        *f /= 10;
+        exp++;
+    }
+    while (*f < 1) {
+        *f *= 10;
+        exp--;
+    }
+    *f += tenpower (maxexp - 1);
+    if (*f >= 10) {
+        *f /= 10;
+        exp++;
+    }
+
+    return exp;
+}
 /* simple fprintf function */
 
 int fdprintf (int fd, const char *fmt, ...)
@@ -40,6 +86,7 @@ int fdprintf (int fd, const char *fmt, ...)
     va_start (ap, fmt);
     while (*fmt) {
         char *s;
+        double f = 0.0;
         int d = 0;
         unsigned int u;
         char c = *fmt++;
@@ -49,7 +96,7 @@ int fdprintf (int fd, const char *fmt, ...)
             *str++ = c;
         } else {
             int t = 0;
-               char w = '0';
+            char w = '0';
             int i, sz = 0;
             void *p = NULL;
 
@@ -65,6 +112,9 @@ int fdprintf (int fd, const char *fmt, ...)
 
             /* process format char */
             switch (*fmt++) {
+            case '%': /* percent */
+                *str++ = '%';
+                break;
             case 'c': /* char */
                 c = (char) va_arg (ap, int);
                 *str++ = c;
@@ -78,12 +128,38 @@ int fdprintf (int fd, const char *fmt, ...)
                 t = 1;
                 /* fall through */
             case 'u': /* unsigned int */
-                u = (t) ? (unsigned int)d : va_arg (ap, unsigned int);
-                for (i = nextpow (u, 10), s = str; i > 0; i--, s++) {
-                    str[i - 1] = '0' + (u % 10);
-                    u /= 10;
+                str = itoa (str, (t) ? (unsigned int)d : va_arg (ap, unsigned int), 0);
+                break;
+            case 'f': /* float */
+                f = va_arg (ap, double);
+                if (f == 0) {
+                    *str++ = '0';
+                    break;
+                }
+                if (f < 0) {
+                    *str++ = '-';
+                    f = -f;
+                }
+                if (sz == 0) sz = 6;
+                t = getexponant (&f, -sz);
+                u = (int)f;
+                str = itoa (str, u, 0);
+                d = (int)((f - u) * tenpower (sz));
+                if (d > 0) {
+                    *str++ = '.';
+                    str = itoa (str, d, sz);
+                }
+                while (*(str - 1) == '0') {
+                    str--;
+                }
+                if (t != 0) {
+                    *str++ = 'e';
+                    if (t < 0) {
+                        *str++ = '-';
+                        t = -t;
+                    }
+                    str = itoa (str, t, 0);
                 }
-                str = s;
                 break;
             case 'p': /* pointer */
                 *str++ = '0';
index 3094ef7ae44b3f8cad3ab39868175245176179ee..31369f7c4b178a87fa548c989442ecf967d50be9 100644 (file)
@@ -3,6 +3,7 @@
 
 int fdprintf (int fd, const char *fmt, ...);
 
+extern int stdfdin;
 extern int stdfdout;
 extern int stdfderr;