size optimization
[compress.git] / fprintf.c
index 47b19c7124019bbae80bd40614ac109da52864ee..ff4f0353d1f947cd79e4bbba8690d0254efb3976 100644 (file)
--- a/fprintf.c
+++ b/fprintf.c
 */
 
 #include <stdarg.h>
-#include <stddef.h>
-#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
 
-inline unsigned int nextpow10 (unsigned int x) {
+#include "fprintf.h"
+
+int _fdout = STDOUT_FILENO;
+int _fderr = STDERR_FILENO;
+
+unsigned int nextpow (unsigned int x, int base) {
     unsigned int n = 0;
     while (x) {
         n++;
-        x = x / 10;
+        x = x / base;
     }
     return (n == 0) ? 1 : n;
 }
 
 /* simple fprintf function */
 
-size_t _fprintf (FILE *fid, const char *fmt, ...)
+int fdprintf (int fd, const char *fmt, ...)
 {
     char buffer[1024 + 1] = { 0 };
     char *str = buffer;
@@ -37,7 +42,6 @@ size_t _fprintf (FILE *fid, const char *fmt, ...)
         char *s;
         int d = 0;
         unsigned int u;
-        void *p;
         char c = *fmt++;
 
         /* copy standard char */
@@ -45,7 +49,19 @@ size_t _fprintf (FILE *fid, const char *fmt, ...)
             *str++ = c;
         } else {
             int t = 0;
-            size_t i;
+               char w = '0';
+            int i, sz = 0;
+            void *p = NULL;
+
+            /* stamp */
+            if ((*fmt == ' ') || (*fmt == '0')) {
+                w = *fmt++;
+            }
+
+            /* size */
+            if ((*fmt >= '1') && (*fmt <= '9')) {
+                sz = *fmt++ - '0';
+            }
 
             /* process format char */
             switch (*fmt++) {
@@ -63,19 +79,36 @@ size_t _fprintf (FILE *fid, const char *fmt, ...)
                 /* fall through */
             case 'u': /* unsigned int */
                 u = (t) ? (unsigned int)d : va_arg (ap, unsigned int);
-                for (i = nextpow10 (u), s = str; i > 0; i--, s++) {
+                for (i = nextpow (u, 10), s = str; i > 0; i--, s++) {
                     str[i - 1] = '0' + (u % 10);
                     u /= 10;
                 }
                 str = s;
                 break;
             case 'p': /* pointer */
-                p = va_arg (ap, void *);
                 *str++ = '0';
                 *str++ = 'x';
-                for (i = sizeof (void *) * 2; i > 0; i--) {
-                    char x = (char)(((uintptr_t)p >> (i * 4 - 4)) & 0xf);
-                    *str++ = (x > 9) ? 'a' + x - 10 : '0' + x;
+                w = '0';
+                sz = sizeof (void *) * 2;
+                p = va_arg (ap, void *);
+                /* fall through */
+            case 'x': /* integer hexa */
+                if (!p) {
+                    u = va_arg (ap, unsigned int);
+                    if (sz == 0) {
+                        sz = nextpow (u, 16);
+                    }
+                } else {
+                    u = (uintptr_t)p;
+                }
+                for (i = sz, t = 1; i > 0; i--) {
+                    char x = (char)((u >> (i * 4 - 4)) & 0xf);
+                    if ((t == 1) && (x == 0)) {
+                        *str++ = w;
+                    } else {
+                        *str++ = (x > 9) ? 'a' + x - 10 : '0' + x;
+                        t = 0;
+                    }
                 }
                 break;
             case 's': /* string */
@@ -91,12 +124,11 @@ size_t _fprintf (FILE *fid, const char *fmt, ...)
     va_end (ap);
 
     /* output string */
-    size_t n = str - buffer;
-    if (n < sizeof (buffer) - 1) {
-        fwrite (buffer, n, 1, fid);
-        return n;
+    int n = str - buffer;
+    if (n < (int)sizeof (buffer) - 1) {
+        return write (fd, buffer, n);
     }
     return 0;
 }
 
-/* vim: set ts=4 sw=4 et */
+/* vim: set ts=4 sw=4 et: */