stdio: support %c
[neatlibc.git] / stdio.c
blob4283b9477095397f3849db5daad206a66001a1c5
1 #include <stdarg.h>
2 #include <stdio.h>
3 #include <unistd.h>
5 static char *putstr(char *d, char *s)
7 while (*s)
8 *d++ = *s++;
9 return d;
12 static int digits(unsigned long n, int base)
14 int i;
15 for (i = 0; n; i++)
16 n /= base;
17 return i ? i : 1;
20 static char *digs = "0123456789abcdef";
22 static char *putint(char *s, unsigned long n, int base, int sign)
24 int d;
25 int i;
26 if (sign && n & 0x80000000) {
27 *s++ = '-';
28 n = -n;
30 d = digits(n, base);
31 for (i = 0; i < d; i++) {
32 s[d - i - 1] = digs[n % base];
33 n /= base;
35 return s + d;
38 int vsprintf(char *dst, char *fmt, va_list ap)
40 char *d = dst;
41 char *s = fmt;
42 while (*s) {
43 int c = *s++;
44 if (c != '%') {
45 *d++ = c;
46 continue;
48 switch ((c = *s++)) {
49 case 'd':
50 d = putint(d, va_arg(ap, long), 10, 1);
51 break;
52 case 'u':
53 d = putint(d, va_arg(ap, long), 10, 0);
54 break;
55 case 'x':
56 d = putint(d, va_arg(ap, long), 16, 0);
57 break;
58 case 'c':
59 *d++ = va_arg(ap, int);
60 break;
61 case 's':
62 d = putstr(d, va_arg(ap, char *));
63 break;
64 case '\0':
65 s--;
66 break;
67 default:
68 *d++ = c;
71 *d = '\0';
72 return d - dst;
75 static char buf[1 << 12];
77 int printf(char *fmt, ...)
79 va_list ap;
80 int ret;
81 va_start(ap, fmt);
82 ret = vsprintf(buf, fmt, ap);
83 va_end(ap);
84 return write(1, buf, ret);
87 int sprintf(char *dst, char *fmt, ...)
89 va_list ap;
90 int ret;
91 va_start(ap, fmt);
92 ret = vsprintf(dst, fmt, ap);
93 va_end(ap);
94 return ret;