diff --git a/include/printf.h b/include/printf.h index d16ad6e778cd..59fa282cf359 100644 --- a/include/printf.h +++ b/include/printf.h @@ -124,16 +124,28 @@ int register_printf_function(int spec, printf_function *render, printf_arginfo_f int register_printf_render(int spec, printf_render *render, printf_arginfo_function *arginfo); int register_printf_render_std(const unsigned char *specs); +/* vprintf_errno.c */ +printf_arginfo_function __printf_arginfo_errno; +printf_render __printf_render_errno; + /* vprintf_float.c */ printf_arginfo_function __printf_arginfo_float; printf_render __printf_render_float; +/* vprintf_hexdump.c */ +printf_arginfo_function __printf_arginfo_hexdump; +printf_render __printf_render_hexdump; + /* vprintf_int.c */ printf_arginfo_function __printf_arginfo_ptr; printf_arginfo_function __printf_arginfo_int; printf_render __printf_render_ptr; printf_render __printf_render_int; +/* vprintf_quoute.c */ +printf_arginfo_function __printf_arginfo_quote; +printf_render __printf_render_quote; + /* vprintf_str.c */ printf_arginfo_function __printf_arginfo_chr; printf_render __printf_render_chr; @@ -144,10 +156,6 @@ printf_render __printf_render_str; printf_arginfo_function __printf_arginfo_time; printf_render __printf_render_time; -/* vprintf_hexdump.c */ -printf_arginfo_function __printf_arginfo_hexdump; -printf_render __printf_render_hexdump; - /* vprintf_vis.c */ printf_arginfo_function __printf_arginfo_vis; printf_render __printf_render_vis; diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc index 495c85f9e910..357bfa9360c6 100644 --- a/lib/libc/stdio/Makefile.inc +++ b/lib/libc/stdio/Makefile.inc @@ -24,7 +24,8 @@ SRCS+= _flock_stub.c asprintf.c clrerr.c fclose.c fdopen.c feof.c ferror.c \ wsetup.c SRCS+= xprintf.c xprintf_float.c xprintf_int.c xprintf_str.c -SRCS+= xprintf_hexdump.c xprintf_time.c xprintf_vis.c +SRCS+= xprintf_errno.c xprintf_hexdump.c xprintf_quote.c +SRCS+= xprintf_time.c xprintf_vis.c MAN+= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetwln.3 fgetws.3 \ flockfile.3 \ diff --git a/lib/libc/stdio/xprintf.c b/lib/libc/stdio/xprintf.c index 3b2778200879..c7814fa7edf2 100644 --- a/lib/libc/stdio/xprintf.c +++ b/lib/libc/stdio/xprintf.c @@ -655,6 +655,16 @@ register_printf_render_std(const unsigned char *specs) __printf_render_hexdump, __printf_arginfo_hexdump); break; + case 'M': + register_printf_render(*specs, + __printf_render_errno, + __printf_arginfo_errno); + break; + case 'Q': + register_printf_render(*specs, + __printf_render_quote, + __printf_arginfo_quote); + break; case 'T': register_printf_render(*specs, __printf_render_time, diff --git a/lib/libc/stdio/xprintf_errno.c b/lib/libc/stdio/xprintf_errno.c new file mode 100644 index 000000000000..0c2be46a6d70 --- /dev/null +++ b/lib/libc/stdio/xprintf_errno.c @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "printf.h" + +int +__printf_arginfo_errno(const struct printf_info *pi __unused, size_t n, int *argt) +{ + + assert(n >= 1); + argt[0] = PA_INT; + return (1); +} + +int +__printf_render_errno(struct __printf_io *io, const struct printf_info *pi __unused, const void *const *arg) +{ + int ret, error; + char buf[64]; + const char *p; + + ret = 0; + error = *((const int *)arg[0]); + if (error >= 0 && error < sys_nerr) { + p = strerror(error); + return (__printf_out(io, pi, p, strlen(p))); + } + sprintf(buf, "errno=%d/0x%x", error, error); + ret += __printf_out(io, pi, buf, strlen(buf)); + __printf_flush(io); + return(ret); +} diff --git a/lib/libc/stdio/xprintf_quote.c b/lib/libc/stdio/xprintf_quote.c new file mode 100644 index 000000000000..bd40a165d886 --- /dev/null +++ b/lib/libc/stdio/xprintf_quote.c @@ -0,0 +1,108 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "printf.h" + +int +__printf_arginfo_quote(const struct printf_info *pi __unused, size_t n, int *argt) +{ + + assert(n >= 1); + argt[0] = PA_POINTER; + return (1); +} + +int +__printf_render_quote(struct __printf_io *io, const struct printf_info *pi __unused, const void *const *arg) +{ + const char *str, *p, *t, *o; + char *q, *r; + int i, ret; + + str = *((const char *const *)arg[0]); + if (str == NULL) + return (__printf_out(io, pi, "\"(null)\"", 8)); + i = 0; + if (*str == '\0') + i++; + else if (*str == '#') + i++; + else { + for (p = str; *p; p++) + if (isspace(*p) || *p == '\\' || *p == '"') + i++; + } + if (!i) + return (__printf_out(io, pi, str, strlen(str))); + + q = malloc(strlen(str) * 5); + assert(q != NULL); + r = q; + ret = __printf_out(io, pi, "\"", 1); + t = str; + for (p = str; *p; p++) { + o = NULL; + if (*p == '\\') + o = "\\\\"; + else if (*p == '\n') + o = "\\n"; + else if (*p == '\r') + o = "\\r"; + else if (*p == '\t') + o = "\\t"; + else if (*p == ' ') + o = " "; + else if (*p == '"') + o = "\\\""; + else if (isspace(*p)) { + sprintf(r, "\\%03o", *p); + o = r; + r += strlen(r) + 1; + } else + continue; + if (p != t) { + ret += __printf_out(io, pi, t, p - t); + t = p + 1; + } + ret += __printf_out(io, pi, o, strlen(o)); + } + if (p != t) + ret += __printf_out(io, pi, t, p - t); + ret += __printf_out(io, pi, "\"", 1); + __printf_flush(io); + return(ret); +} diff --git a/lib/libc/stdio/xprintf_vis.c b/lib/libc/stdio/xprintf_vis.c index 2f8d63e1a8a3..819f09ff1d8f 100644 --- a/lib/libc/stdio/xprintf_vis.c +++ b/lib/libc/stdio/xprintf_vis.c @@ -54,6 +54,8 @@ __printf_render_vis(struct __printf_io *io, const struct printf_info *pi, const ret = 0; p = *((char **)arg[0]); + if (p == NULL) + return (__printf_out(io, pi, "(null)", 6)); if (pi->prec >= 0) l = pi->prec; else