diff src/usr/printf.c @ 0:53676d1f5817 default tip

firsh commit
author tobaru
date Sun, 04 Feb 2018 17:54:49 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/usr/printf.c	Sun Feb 04 17:54:49 2018 +0900
@@ -0,0 +1,85 @@
+#include "types.h"
+#include "stat.h"
+#include "user.h"
+
+static void
+putc(int fd, char c)
+{
+    write(fd, &c, 1);
+}
+
+static void
+printint(int fd, int xx, int base, int sgn)
+{
+    static char digits[] = "0123456789ABCDEF";
+    char buf[16];
+    int i, neg;
+    uint x;
+    
+    neg = 0;
+    if(sgn && xx < 0){
+        neg = 1;
+        x = -xx;
+    } else {
+        x = xx;
+    }
+    
+    i = 0;
+    do{
+        buf[i++] = digits[x % base];
+    }while((x /= base) != 0);
+    if(neg)
+        buf[i++] = '-';
+    
+    while(--i >= 0)
+        putc(fd, buf[i]);
+}
+
+// Print to the given fd. Only understands %d, %x, %p, %s.
+void
+printf(int fd, char *fmt, ...)
+{
+    char *s;
+    int c, i, state;
+    uint *ap;
+    
+    state = 0;
+    ap = (uint*)(void*)&fmt + 1;
+    for(i = 0; fmt[i]; i++){
+        c = fmt[i] & 0xff;
+        if(state == 0){
+            if(c == '%'){
+                state = '%';
+            } else {
+                putc(fd, c);
+            }
+        } else if(state == '%'){
+            if(c == 'd'){
+                printint(fd, *ap, 10, 1);
+                ap++;
+            } else if(c == 'x' || c == 'p'){
+                printint(fd, *ap, 16, 0);
+                ap++;
+            } else if(c == 's'){
+                s = (char*)*ap;
+                ap++;
+                if(s == 0)
+                    s = "(null)";
+                while(*s != 0){
+                    putc(fd, *s);
+                    s++;
+                }
+            } else if(c == 'c'){
+                putc(fd, *ap);
+                ap++;
+            } else if(c == '%'){
+                putc(fd, c);
+            } else {
+                // Unknown % sequence.  Print it to draw attention.
+                putc(fd, '%');
+                putc(fd, c);
+            }
+            state = 0;
+        }
+    }
+}