diff options
author | phk <phk@FreeBSD.org> | 2006-01-25 12:45:24 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2006-01-25 12:45:24 +0000 |
commit | a6d0508dd8c4beb88be6d5ca4b35e12db40e8312 (patch) | |
tree | 8b1b9e153704a2e4059c4a81c88f8bdaa0817a60 | |
parent | b52efc57bec49fd584f1580087664aff15a10168 (diff) | |
download | FreeBSD-src-a6d0508dd8c4beb88be6d5ca4b35e12db40e8312.zip FreeBSD-src-a6d0508dd8c4beb88be6d5ca4b35e12db40e8312.tar.gz |
Make the %V{is} extension handle a NULL pointer like %s does: output "(null)"
Add %M{essage} extension which prints an errno value as the
corresponding string if possible or numerically otherwise.
It is not currently possible to do the syslog(3) like %m extension
because errno would need to get capatured on entry to the first
function in the printf family, so %M requires you to supply errno
as an argument.
Add %Q{uote} extension which will print a string in double quotes with
appropriate back-slash escapes (only) if necessary.
-rw-r--r-- | include/printf.h | 16 | ||||
-rw-r--r-- | lib/libc/stdio/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/stdio/xprintf.c | 10 | ||||
-rw-r--r-- | lib/libc/stdio/xprintf_errno.c | 65 | ||||
-rw-r--r-- | lib/libc/stdio/xprintf_quote.c | 108 | ||||
-rw-r--r-- | lib/libc/stdio/xprintf_vis.c | 2 |
6 files changed, 199 insertions, 5 deletions
diff --git a/include/printf.h b/include/printf.h index d16ad6e..59fa282 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 495c85f..357bfa9 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 3b27782..c7814fa 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 0000000..0c2be46 --- /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 <namespace.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <wchar.h> +#include <vis.h> +#include <assert.h> +#include <sys/time.h> +#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 0000000..bd40a16 --- /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 <namespace.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <wchar.h> +#include <vis.h> +#include <assert.h> +#include <sys/time.h> +#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 2f8d63e..819f09f 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 |