175067f4fSPoul-Henning Kamp /*- 2*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 3*8a16b7a1SPedro F. Giffuni * 475067f4fSPoul-Henning Kamp * Copyright (c) 2005 Poul-Henning Kamp 575067f4fSPoul-Henning Kamp * Copyright (c) 1990, 1993 675067f4fSPoul-Henning Kamp * The Regents of the University of California. All rights reserved. 775067f4fSPoul-Henning Kamp * 875067f4fSPoul-Henning Kamp * This code is derived from software contributed to Berkeley by 975067f4fSPoul-Henning Kamp * Chris Torek. 1075067f4fSPoul-Henning Kamp * 1175067f4fSPoul-Henning Kamp * Redistribution and use in source and binary forms, with or without 1275067f4fSPoul-Henning Kamp * modification, are permitted provided that the following conditions 1375067f4fSPoul-Henning Kamp * are met: 1475067f4fSPoul-Henning Kamp * 1. Redistributions of source code must retain the above copyright 1575067f4fSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer. 1675067f4fSPoul-Henning Kamp * 2. Redistributions in binary form must reproduce the above copyright 1775067f4fSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer in the 1875067f4fSPoul-Henning Kamp * documentation and/or other materials provided with the distribution. 1975067f4fSPoul-Henning Kamp * 3. Neither the name of the University nor the names of its contributors 2075067f4fSPoul-Henning Kamp * may be used to endorse or promote products derived from this software 2175067f4fSPoul-Henning Kamp * without specific prior written permission. 2275067f4fSPoul-Henning Kamp * 2375067f4fSPoul-Henning Kamp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2475067f4fSPoul-Henning Kamp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2575067f4fSPoul-Henning Kamp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2675067f4fSPoul-Henning Kamp * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2775067f4fSPoul-Henning Kamp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2875067f4fSPoul-Henning Kamp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2975067f4fSPoul-Henning Kamp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3075067f4fSPoul-Henning Kamp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3175067f4fSPoul-Henning Kamp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3275067f4fSPoul-Henning Kamp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3375067f4fSPoul-Henning Kamp * SUCH DAMAGE. 3475067f4fSPoul-Henning Kamp * 3575067f4fSPoul-Henning Kamp * $FreeBSD$ 3675067f4fSPoul-Henning Kamp */ 3775067f4fSPoul-Henning Kamp #include <namespace.h> 3875067f4fSPoul-Henning Kamp #include <stdio.h> 3975067f4fSPoul-Henning Kamp #include <wchar.h> 4075067f4fSPoul-Henning Kamp #include <stdint.h> 4175067f4fSPoul-Henning Kamp #include <assert.h> 4275067f4fSPoul-Henning Kamp #include <sys/time.h> 4375067f4fSPoul-Henning Kamp #include "printf.h" 4475067f4fSPoul-Henning Kamp 4575067f4fSPoul-Henning Kamp int 4675067f4fSPoul-Henning Kamp __printf_arginfo_time(const struct printf_info *pi, size_t n, int *argt) 4775067f4fSPoul-Henning Kamp { 4875067f4fSPoul-Henning Kamp 4975067f4fSPoul-Henning Kamp assert(n >= 1); 5075067f4fSPoul-Henning Kamp argt[0] = PA_POINTER; 5175067f4fSPoul-Henning Kamp return (1); 5275067f4fSPoul-Henning Kamp } 5375067f4fSPoul-Henning Kamp #define MINUTE 60 5475067f4fSPoul-Henning Kamp #define HOUR (60 * MINUTE) 5575067f4fSPoul-Henning Kamp #define DAY (24 * HOUR) 5675067f4fSPoul-Henning Kamp #define YEAR (365 * DAY) 5775067f4fSPoul-Henning Kamp 5875067f4fSPoul-Henning Kamp int 5975067f4fSPoul-Henning Kamp __printf_render_time(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) 6075067f4fSPoul-Henning Kamp { 6175067f4fSPoul-Henning Kamp char buf[100]; 6275067f4fSPoul-Henning Kamp char *p; 6375067f4fSPoul-Henning Kamp struct timeval *tv; 6475067f4fSPoul-Henning Kamp struct timespec *ts; 6575067f4fSPoul-Henning Kamp time_t *tp; 668dcefe61SPoul-Henning Kamp intmax_t t, tx; 67a9cf49abSPawel Jakub Dawidek int i, prec, nsec, ret; 6875067f4fSPoul-Henning Kamp 6975067f4fSPoul-Henning Kamp if (pi->is_long) { 7075067f4fSPoul-Henning Kamp tv = *((struct timeval **)arg[0]); 7175067f4fSPoul-Henning Kamp t = tv->tv_sec; 7275067f4fSPoul-Henning Kamp nsec = tv->tv_usec * 1000; 7375067f4fSPoul-Henning Kamp prec = 6; 7475067f4fSPoul-Henning Kamp } else if (pi->is_long_double) { 7575067f4fSPoul-Henning Kamp ts = *((struct timespec **)arg[0]); 7675067f4fSPoul-Henning Kamp t = ts->tv_sec; 7775067f4fSPoul-Henning Kamp nsec = ts->tv_nsec; 7875067f4fSPoul-Henning Kamp prec = 9; 7975067f4fSPoul-Henning Kamp } else { 8075067f4fSPoul-Henning Kamp tp = *((time_t **)arg[0]); 8175067f4fSPoul-Henning Kamp t = *tp; 82750a395bSGarrett Wollman nsec = 0; 83750a395bSGarrett Wollman prec = 0; 8475067f4fSPoul-Henning Kamp } 85f03ca724SPawel Jakub Dawidek if (pi->is_long || pi->is_long_double) { 86f03ca724SPawel Jakub Dawidek if (pi->prec >= 0) 87f03ca724SPawel Jakub Dawidek prec = pi->prec; 88f03ca724SPawel Jakub Dawidek if (prec == 0) 89f03ca724SPawel Jakub Dawidek nsec = 0; 90f03ca724SPawel Jakub Dawidek } 9175067f4fSPoul-Henning Kamp 9275067f4fSPoul-Henning Kamp p = buf; 9375067f4fSPoul-Henning Kamp if (pi->alt) { 948dcefe61SPoul-Henning Kamp tx = t; 9575067f4fSPoul-Henning Kamp if (t >= YEAR) { 9675067f4fSPoul-Henning Kamp p += sprintf(p, "%jdy", t / YEAR); 9775067f4fSPoul-Henning Kamp t %= YEAR; 9875067f4fSPoul-Henning Kamp } 99f03ca724SPawel Jakub Dawidek if (tx >= DAY && (t != 0 || prec != 0)) { 10075067f4fSPoul-Henning Kamp p += sprintf(p, "%jdd", t / DAY); 10175067f4fSPoul-Henning Kamp t %= DAY; 10275067f4fSPoul-Henning Kamp } 103f03ca724SPawel Jakub Dawidek if (tx >= HOUR && (t != 0 || prec != 0)) { 10475067f4fSPoul-Henning Kamp p += sprintf(p, "%jdh", t / HOUR); 10575067f4fSPoul-Henning Kamp t %= HOUR; 10675067f4fSPoul-Henning Kamp } 107f03ca724SPawel Jakub Dawidek if (tx >= MINUTE && (t != 0 || prec != 0)) { 10875067f4fSPoul-Henning Kamp p += sprintf(p, "%jdm", t / MINUTE); 10975067f4fSPoul-Henning Kamp t %= MINUTE; 11075067f4fSPoul-Henning Kamp } 111f03ca724SPawel Jakub Dawidek if (t != 0 || tx == 0 || prec != 0) 112f0107b2cSPoul-Henning Kamp p += sprintf(p, "%jds", t); 11375067f4fSPoul-Henning Kamp } else { 11475067f4fSPoul-Henning Kamp p += sprintf(p, "%jd", (intmax_t)t); 11575067f4fSPoul-Henning Kamp } 116f03ca724SPawel Jakub Dawidek if (prec != 0) { 11775067f4fSPoul-Henning Kamp for (i = prec; i < 9; i++) 11875067f4fSPoul-Henning Kamp nsec /= 10; 11975067f4fSPoul-Henning Kamp p += sprintf(p, ".%.*d", prec, nsec); 12075067f4fSPoul-Henning Kamp } 121a9cf49abSPawel Jakub Dawidek ret = __printf_out(io, pi, buf, p - buf); 122a9cf49abSPawel Jakub Dawidek __printf_flush(io); 123a9cf49abSPawel Jakub Dawidek return (ret); 12475067f4fSPoul-Henning Kamp } 125