16 static int intern_printf(int out, char *buf, size_t sz, const char *fmt, va_list ap);
17 static int intern_scanf(const char *instr, FILE *infile, const char *fmt, va_list ap);
18 static void bwrite(int out, char *buf, size_t buf_sz, char *str, int sz);
19 /*static int readchar(const char *str, FILE *fp);*/
27 int puts(const char *s)
36 /* -- printf and friends -- */
38 int printf(const char *fmt, ...)
44 res = intern_printf(OUT_DEF, 0, 0, fmt, ap);
49 int vprintf(const char *fmt, va_list ap)
51 return intern_printf(OUT_DEF, 0, 0, fmt, ap);
54 int sprintf(char *buf, const char *fmt, ...)
60 res = intern_printf(OUT_BUF, buf, 0, fmt, ap);
65 int vsprintf(char *buf, const char *fmt, va_list ap)
67 return intern_printf(OUT_BUF, buf, 0, fmt, ap);
70 int snprintf(char *buf, size_t sz, const char *fmt, ...)
76 res = intern_printf(OUT_BUF, buf, sz, fmt, ap);
81 int vsnprintf(char *buf, size_t sz, const char *fmt, va_list ap)
83 return intern_printf(OUT_BUF, buf, sz, fmt, ap);
86 int fprintf(FILE *fp, const char *fmt, ...)
92 res = vfprintf(fp, fmt, ap);
97 int vfprintf(FILE *fp, const char *fmt, va_list ap)
99 if(fp == stdout || fp == stderr) {
100 return vprintf(fmt, ap);
103 panic("*fprintf for anything other than stdout/stderr, not implemented yet\n");
107 int ser_printf(const char *fmt, ...)
113 res = intern_printf(OUT_SER, 0, 0, fmt, ap);
118 int ser_vprintf(const char *fmt, va_list ap)
120 return intern_printf(OUT_SER, 0, 0, fmt, ap);
123 void perror(const char *s)
125 printf("%s: %s\n", s, strerror(errno));
130 return con_getchar();
133 /* intern_printf provides all the functionality needed by all the printf
135 * - buf: optional buffer onto which the formatted results are written. If null
136 * then the output goes to the terminal through putchar calls. This is used
137 * by the (v)sprintf variants which write to an array of char.
138 * - sz: optional maximum size of the output, 0 means unlimited. This is used
139 * by the (v)snprintf variants to avoid buffer overflows.
140 * The rest are obvious, format string and variable argument list.
142 static char *convc = "dioxXucsfeEgGpn%";
144 #define IS_CONV(c) strchr(convc, c)
146 #define BUF(x) ((x) ? (x) + cnum : (x))
147 #define SZ(x) ((x) ? (x) - cnum : (x))
149 static int intern_printf(int out, char *buf, size_t sz, const char *fmt, va_list ap)
154 const char *fstart = 0;
185 bwrite(out, BUF(buf), SZ(sz), "0x", 2);
197 bwrite(out, BUF(buf), SZ(sz), "0", 1);
205 unum = va_arg(ap, unsigned int);
206 utoa(unum, conv_buf, base);
208 num = va_arg(ap, int);
209 itoa(num, conv_buf, base);
212 for(i=0; conv_buf[i]; i++) {
213 conv_buf[i] = toupper(conv_buf[i]);
217 slen = strlen(conv_buf);
220 if(!unsig && sign && num >= 0) {
221 bwrite(out, BUF(buf), SZ(sz), "+", 1);
224 bwrite(out, BUF(buf), SZ(sz), conv_buf, slen);
228 for(i=slen; i<fwidth; i++) {
229 bwrite(out, BUF(buf), SZ(sz), (char*)&padc, 1);
233 if(!unsig && sign && num >= 0) {
234 bwrite(out, BUF(buf), SZ(sz), "+", 1);
237 bwrite(out, BUF(buf), SZ(sz), conv_buf, slen);
244 char c = va_arg(ap, int);
245 bwrite(out, BUF(buf), SZ(sz), &c, 1);
251 str = va_arg(ap, char*);
255 bwrite(out, BUF(buf), SZ(sz), str, slen);
259 for(i=slen; i<fwidth; i++) {
260 bwrite(out, BUF(buf), SZ(sz), (char*)&padc, 1);
264 bwrite(out, BUF(buf), SZ(sz), str, slen);
270 *va_arg(ap, int*) = cnum;
277 /* restore default conversion state */
310 const char *fw = fmt;
311 while(*fmt && isdigit(*fmt)) fmt++;
320 bwrite(out, BUF(buf), SZ(sz), (char*)fmt++, 1);
330 static char *sconvc = "diouxcsefg%";
332 #define IS_SCONV(c) strchr(sconvc, c)
334 static int intern_scanf(const char *instr, FILE *infile, const char *fmt, va_list ap)
336 return -1; /* TODO */
341 /* bwrite is called by intern_printf to transparently handle writing into a
342 * buffer or to the terminal
344 static void bwrite(int out, char *buf, size_t buf_sz, char *str, int sz)
349 if(buf_sz && buf_sz <= sz) sz = buf_sz;
351 memcpy(buf, str, sz);
355 for(i=0; i<sz; i++) {
361 for(i=0; i<sz; i++) {
374 static int readchar(const char *str, FILE *fp)
376 static const char *orig_str;
377 static const char *sptr;
380 if(str == orig_str) {
381 if(!*sptr) return -1;
384 orig_str = sptr = str;
385 return readchar(str, fp);