syscall: don't save ebp twice
[neatlibc.git] / stdio.c
blob7a4bd4d336d1bc9b61afa2c9722dde0e81fa1a79
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 's':
59 d = putstr(d, va_arg(ap, char *));
60 break;
61 case '\0':
62 s--;
63 break;
64 default:
65 *d++ = c;
68 *d = '\0';
69 return d - dst;
72 static char buf[1 << 12];
74 int printf(char *fmt, ...)
76 va_list ap;
77 int ret;
78 va_start(ap, fmt);
79 ret = vsprintf(buf, fmt, ap);
80 va_end(ap);
81 return write(1, buf, ret);
84 int sprintf(char *dst, char *fmt, ...)
86 va_list ap;
87 int ret;
88 va_start(ap, fmt);
89 ret = vsprintf(dst, fmt, ap);
90 va_end(ap);
91 return ret;