diff options
Diffstat (limited to 'lib/libc/stdio/xprintf_time.c')
-rw-r--r-- | lib/libc/stdio/xprintf_time.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/lib/libc/stdio/xprintf_time.c b/lib/libc/stdio/xprintf_time.c new file mode 100644 index 0000000..b566aa0 --- /dev/null +++ b/lib/libc/stdio/xprintf_time.c @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 2005 Poul-Henning Kamp + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * 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. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 <wchar.h> +#include <stdint.h> +#include <assert.h> +#include <sys/time.h> +#include "printf.h" + +int +__printf_arginfo_time(const struct printf_info *pi, size_t n, int *argt) +{ + + assert(n >= 1); + argt[0] = PA_POINTER; + return (1); +} +#define MINUTE 60 +#define HOUR (60 * MINUTE) +#define DAY (24 * HOUR) +#define YEAR (365 * DAY) + +int +__printf_render_time(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) +{ + char buf[100]; + char *p; + struct timeval *tv; + struct timespec *ts; + time_t *tp; + intmax_t t; + int i, prec, nsec; + + prec = 0; + if (pi->is_long) { + tv = *((struct timeval **)arg[0]); + t = tv->tv_sec; + nsec = tv->tv_usec * 1000; + prec = 6; + } else if (pi->is_long_double) { + ts = *((struct timespec **)arg[0]); + t = ts->tv_sec; + nsec = ts->tv_nsec; + prec = 9; + } else { + tp = *((time_t **)arg[0]); + t = *tp; + } + + p = buf; + if (pi->alt) { + if (t >= YEAR) { + p += sprintf(p, "%jdy", t / YEAR); + t %= YEAR; + } + if (t >= DAY && t != 0) { + p += sprintf(p, "%jdd", t / DAY); + t %= DAY; + } + if (t >= HOUR && t != 0) { + p += sprintf(p, "%jdh", t / HOUR); + t %= HOUR; + } + if (t >= MINUTE && t != 0) { + p += sprintf(p, "%jdm", t / MINUTE); + t %= MINUTE; + } + if (t != 0) + p += sprintf(p, "%jd", t); + } else { + p += sprintf(p, "%jd", (intmax_t)t); + } + if (pi->is_long || pi->is_long_double) { + if (pi->prec >= 0) + prec = pi->prec; + for (i = prec; i < 9; i++) + nsec /= 10; + p += sprintf(p, ".%.*d", prec, nsec); + } + return(__printf_out(io, pi, buf, p - buf)); +} |