6 static void bwrite(char *buf, size_t buf_sz, char *str, int sz);
7 static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap);
18 int puts(const char *s)
27 /* -- printf and friends -- */
29 static char *convc = "dioxXucsfeEgGpn%";
31 #define IS_CONV(c) strchr(convc, c)
33 int printf(const char *fmt, ...)
39 res = intern_printf(0, 0, fmt, ap);
44 int vprintf(const char *fmt, va_list ap)
46 return intern_printf(0, 0, fmt, ap);
49 int sprintf(char *buf, const char *fmt, ...)
55 res = intern_printf(buf, 0, fmt, ap);
60 int vsprintf(char *buf, const char *fmt, va_list ap)
62 return intern_printf(buf, 0, fmt, ap);
65 int snprintf(char *buf, size_t sz, const char *fmt, ...)
71 res = intern_printf(buf, sz, fmt, ap);
76 int vsnprintf(char *buf, size_t sz, const char *fmt, va_list ap)
78 return intern_printf(buf, sz, fmt, ap);
82 /* intern_printf provides all the functionality needed by all the printf
84 * - buf: optional buffer onto which the formatted results are written. If null
85 * then the output goes to the terminal through putchar calls. This is used
86 * by the (v)sprintf variants which write to an array of char.
87 * - sz: optional maximum size of the output, 0 means unlimited. This is used
88 * by the (v)snprintf variants to avoid buffer overflows.
89 * The rest are obvious, format string and variable argument list.
92 #define BUF(x) ((x) ? (x) + cnum : (x))
93 #define SZ(x) ((x) ? (x) - cnum : (x))
95 static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap)
100 const char *fstart = 0;
109 int left_align = 0; /* not implemented yet */
130 bwrite(BUF(buf), SZ(sz), "0x", 2);
141 bwrite(BUF(buf), SZ(sz), "0", 1);
148 utoa(va_arg(ap, unsigned int), conv_buf, base);
150 itoa(va_arg(ap, int), conv_buf, base);
153 for(i=0; conv_buf[i]; i++) {
154 conv_buf[i] = toupper(conv_buf[i]);
158 slen = strlen(conv_buf);
159 for(i=slen; i<fwidth; i++) {
160 bwrite(BUF(buf), SZ(sz), (char*)&padc, 1);
164 bwrite(BUF(buf), SZ(sz), conv_buf, strlen(conv_buf));
170 char c = va_arg(ap, int);
171 bwrite(BUF(buf), SZ(sz), &c, 1);
177 str = va_arg(ap, char*);
180 for(i=slen; i<fwidth; i++) {
181 bwrite(BUF(buf), SZ(sz), (char*)&padc, 1);
184 bwrite(BUF(buf), SZ(sz), str, slen);
189 *va_arg(ap, int*) = cnum;
196 /* restore default conversion state */
229 const char *fw = fmt;
230 while(*fmt && isdigit(*fmt)) fmt++;
239 bwrite(BUF(buf), SZ(sz), (char*)fmt++, 1);
248 /* bwrite is called by intern_printf to transparently handle writing into a
249 * buffer (if buf is non-null) or to the terminal (if buf is null).
251 static void bwrite(char *buf, size_t buf_sz, char *str, int sz)
254 if(buf_sz && buf_sz <= sz) sz = buf_sz - 1;
255 memcpy(buf, str, sz);
260 for(i=0; i<sz; i++) {