2 * minimal printf for Human68k DOS
4 * written by Yasha (ITOH Yasufumi)
7 * $NetBSD: xprintf.c,v 1.3 2009/03/14 15:36:15 dsl Exp $
10 #include <sys/types.h>
18 #include <dos_errno.h>
23 * From ISO/IEC 9899:1990
24 * 7.9.6.1 The fprintf function
27 * The minimum value for the maximum number of characters
28 * produced by any single conversion shall be 509.
30 * so the following value shall not be smaller than 510
31 * if you want to conform ANSI C (it is only a guideline
32 * and maybe no sense on this code, of course :-).
34 #define PRINTF_BUFSZ 4096
37 * Shift-JIS kanji support
38 * (No special handling needed for EUC)
43 #define UC(c) ((unsigned char) (c))
44 #define IS_SJIS1(c) ((UC(c) > 0x80 && UC(c) < 0xa0) || \
45 (UC(c) >= 0xe0 && UC(c) <= 0xfc))
46 #define IS_SJIS2(c) (UC(c) >= 0x40 && UC(c) <= 0xfc && UC(c) != 0x7f)
49 #if !defined(__STDC__) && !defined(const)
53 extern const char *const __progname
;
55 static char * numstr(char *buf
, long val
, int base
, int sign
);
58 * convert number to string
59 * buf must have enough space
62 numstr(char *buf
, long val
, int base
, int sign
)
66 char *r
= rev
, *b
= buf
;
69 if (sign
&& val
< 0) {
78 *r
++ = "0123456789abcdef"[v
% base
];
91 * supported format: %x, %p, %s, %c, %d, %u, %o
92 * \n is converted to \r\n
94 * XXX argument/parameter types are not strictly handled
97 xvsnprintf(char *buf
, size_t len
, const char *fmt
, va_list ap
)
103 while (*fmt
&& len
> 1) {
106 if (IS_SJIS1(*fmt
) && IS_SJIS2(fmt
[1])) {
108 break; /* not enough space */
113 if (*fmt
== '\n' && (b
== buf
|| b
[-1] != '\r')) {
127 case '%': /* "%%" -> literal % */
133 s
= numstr(numbuf
, va_arg(ap
, long), 10, 1);
135 for ( ; *s
&& len
> 1; len
--)
140 s
= numstr(numbuf
, va_arg(ap
, long), 10, 0);
152 s
= numstr(numbuf
, va_arg(ap
, long), 16, 0);
156 s
= numstr(numbuf
, va_arg(ap
, long), 8, 0);
160 s
= va_arg(ap
, char *);
161 while (*s
&& len
> 1) {
163 if (IS_SJIS1(*s
) && IS_SJIS2(s
[1])) {
170 if (*s
== '\n' && (b
== buf
|| b
[-1] != '\r')) {
182 *b
++ = va_arg(ap
, int);
190 return (char *)b
- buf
;
194 #define VA_START(a, v) va_start(a, v)
196 #define VA_START(a, v) va_start(a)
201 xsnprintf(char *buf
, size_t len
, const char *fmt
, ...)
204 xsnprintf(buf
, len
, fmt
, va_alist
)
215 ret
= xvsnprintf(buf
, len
, fmt
, ap
);
222 xvfdprintf(int fd
, const char *fmt
, va_list ap
)
224 char buf
[PRINTF_BUFSZ
];
227 ret
= xvsnprintf(buf
, sizeof buf
, fmt
, ap
);
229 ret
= DOS_WRITE(fd
, buf
, ret
);
236 xprintf(const char *fmt
, ...)
239 xprintf(fmt
, va_alist
)
248 ret
= xvfdprintf(1, fmt
, ap
);
256 xerrprintf(const char *fmt
, ...)
259 xerrprintf(fmt
, va_alist
)
268 ret
= xvfdprintf(2, fmt
, ap
);
276 xerr(int eval
, const char *fmt
, ...)
278 xerr(eval
, fmt
, va_alist
)
287 xerrprintf("%s: ", __progname
);
290 xvfdprintf(2, fmt
, ap
);
294 xerrprintf("%s\n", dos_strerror(e
));
300 xerrx(int eval
, const char *fmt
, ...)
302 xerrx(eval
, fmt
, va_alist
)
310 xerrprintf("%s: ", __progname
);
313 xvfdprintf(2, fmt
, ap
);
322 xwarn(const char *fmt
, ...)
332 xerrprintf("%s: ", __progname
);
335 xvfdprintf(2, fmt
, ap
);
339 xerrprintf("%s\n", dos_strerror(e
));
344 xwarnx(const char *fmt
, ...)
346 xwarnx(fmt
, va_alist
)
353 xerrprintf("%s: ", __progname
);
356 xvfdprintf(2, fmt
, ap
);