xref: /dragonfly/lib/libc/stdio/xprintf_time.c (revision 6d7019e6)
1e0f95098SPeter Avalos /*-
2e0f95098SPeter Avalos  * Copyright (c) 2005 Poul-Henning Kamp
3e0f95098SPeter Avalos  * Copyright (c) 1990, 1993
4e0f95098SPeter Avalos  *	The Regents of the University of California.  All rights reserved.
5e0f95098SPeter Avalos  *
6e0f95098SPeter Avalos  * This code is derived from software contributed to Berkeley by
7e0f95098SPeter Avalos  * Chris Torek.
8e0f95098SPeter Avalos  *
9e0f95098SPeter Avalos  * Redistribution and use in source and binary forms, with or without
10e0f95098SPeter Avalos  * modification, are permitted provided that the following conditions
11e0f95098SPeter Avalos  * are met:
12e0f95098SPeter Avalos  * 1. Redistributions of source code must retain the above copyright
13e0f95098SPeter Avalos  *    notice, this list of conditions and the following disclaimer.
14e0f95098SPeter Avalos  * 2. Redistributions in binary form must reproduce the above copyright
15e0f95098SPeter Avalos  *    notice, this list of conditions and the following disclaimer in the
16e0f95098SPeter Avalos  *    documentation and/or other materials provided with the distribution.
17e0f95098SPeter Avalos  * 3. Neither the name of the University nor the names of its contributors
18e0f95098SPeter Avalos  *    may be used to endorse or promote products derived from this software
19e0f95098SPeter Avalos  *    without specific prior written permission.
20e0f95098SPeter Avalos  *
21e0f95098SPeter Avalos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22e0f95098SPeter Avalos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23e0f95098SPeter Avalos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24e0f95098SPeter Avalos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25e0f95098SPeter Avalos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26e0f95098SPeter Avalos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27e0f95098SPeter Avalos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28e0f95098SPeter Avalos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29e0f95098SPeter Avalos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30e0f95098SPeter Avalos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31e0f95098SPeter Avalos  * SUCH DAMAGE.
32e0f95098SPeter Avalos  *
33e0f95098SPeter Avalos  * $FreeBSD: src/lib/libc/stdio/xprintf_time.c,v 1.3 2006/02/04 14:35:01 phk Exp $
34e0f95098SPeter Avalos  */
35e0f95098SPeter Avalos 
36e0f95098SPeter Avalos #include "namespace.h"
37e0f95098SPeter Avalos #include <stdio.h>
38e0f95098SPeter Avalos #include <wchar.h>
39e0f95098SPeter Avalos #include <stdint.h>
40e0f95098SPeter Avalos #include <assert.h>
41e0f95098SPeter Avalos #include <sys/time.h>
42e0f95098SPeter Avalos #include "un-namespace.h"
43e0f95098SPeter Avalos #include "printf.h"
44e0f95098SPeter Avalos 
45e0f95098SPeter Avalos int
__printf_arginfo_time(const struct printf_info * pi __unused,size_t n,int * argt)46*6d7019e6SSascha Wildner __printf_arginfo_time(const struct printf_info *pi __unused, size_t n,
47*6d7019e6SSascha Wildner 		      int *argt)
48e0f95098SPeter Avalos {
49e0f95098SPeter Avalos 
50e0f95098SPeter Avalos 	assert(n >= 1);
51e0f95098SPeter Avalos 	argt[0] = PA_POINTER;
52e0f95098SPeter Avalos 	return (1);
53e0f95098SPeter Avalos }
54e0f95098SPeter Avalos #define	MINUTE 60
55e0f95098SPeter Avalos #define	HOUR	(60 * MINUTE)
56e0f95098SPeter Avalos #define	DAY	(24 * HOUR)
57e0f95098SPeter Avalos #define	YEAR	(365 * DAY)
58e0f95098SPeter Avalos 
59e0f95098SPeter Avalos int
__printf_render_time(struct __printf_io * io,const struct printf_info * pi,const void * const * arg)60e0f95098SPeter Avalos __printf_render_time(struct __printf_io *io, const struct printf_info *pi,
61e0f95098SPeter Avalos 		     const void *const *arg)
62e0f95098SPeter Avalos {
63e0f95098SPeter Avalos 	char buf[100];
64e0f95098SPeter Avalos 	char *p;
65e0f95098SPeter Avalos 	struct timeval *tv;
66e0f95098SPeter Avalos 	struct timespec *ts;
67e0f95098SPeter Avalos 	time_t *tp;
68e0f95098SPeter Avalos 	intmax_t t, tx;
69e0f95098SPeter Avalos 	int i, prec, nsec;
70e0f95098SPeter Avalos 
71e0f95098SPeter Avalos 	prec = 0;
72e0f95098SPeter Avalos 	if (pi->is_long) {
73e0f95098SPeter Avalos 		tv = *((struct timeval **)arg[0]);
74e0f95098SPeter Avalos 		t = tv->tv_sec;
75e0f95098SPeter Avalos 		nsec = tv->tv_usec * 1000;
76e0f95098SPeter Avalos 		prec = 6;
77e0f95098SPeter Avalos 	} else if (pi->is_long_double) {
78e0f95098SPeter Avalos 		ts = *((struct timespec **)arg[0]);
79e0f95098SPeter Avalos 		t = ts->tv_sec;
80e0f95098SPeter Avalos 		nsec = ts->tv_nsec;
81e0f95098SPeter Avalos 		prec = 9;
82e0f95098SPeter Avalos 	} else {
83e0f95098SPeter Avalos 		tp = *((time_t **)arg[0]);
84e0f95098SPeter Avalos 		t = *tp;
85e0f95098SPeter Avalos 	}
86e0f95098SPeter Avalos 
87e0f95098SPeter Avalos 	p = buf;
88e0f95098SPeter Avalos 	if (pi->alt) {
89e0f95098SPeter Avalos 		tx = t;
90e0f95098SPeter Avalos 		if (t >= YEAR) {
91e0f95098SPeter Avalos 			p += sprintf(p, "%jdy", t / YEAR);
92e0f95098SPeter Avalos 			t %= YEAR;
93e0f95098SPeter Avalos 		}
94e0f95098SPeter Avalos 		if (t >= DAY && t != 0) {
95e0f95098SPeter Avalos 			p += sprintf(p, "%jdd", t / DAY);
96e0f95098SPeter Avalos 			t %= DAY;
97e0f95098SPeter Avalos 		}
98e0f95098SPeter Avalos 		if (t >= HOUR && t != 0) {
99e0f95098SPeter Avalos 			p += sprintf(p, "%jdh", t / HOUR);
100e0f95098SPeter Avalos 			t %= HOUR;
101e0f95098SPeter Avalos 		}
102e0f95098SPeter Avalos 		if (t >= MINUTE && t != 0) {
103e0f95098SPeter Avalos 			p += sprintf(p, "%jdm", t / MINUTE);
104e0f95098SPeter Avalos 			t %= MINUTE;
105e0f95098SPeter Avalos 		}
106e0f95098SPeter Avalos 		if (t != 0 || tx == 0)
107e0f95098SPeter Avalos 			p += sprintf(p, "%jds", t);
108e0f95098SPeter Avalos 	} else  {
109e0f95098SPeter Avalos 		p += sprintf(p, "%jd", (intmax_t)t);
110e0f95098SPeter Avalos 	}
111e0f95098SPeter Avalos 	if (pi->is_long || pi->is_long_double) {
112e0f95098SPeter Avalos 		if (pi->prec >= 0)
113e0f95098SPeter Avalos 			prec = pi->prec;
114e0f95098SPeter Avalos 		for (i = prec; i < 9; i++)
115e0f95098SPeter Avalos 			nsec /= 10;
116e0f95098SPeter Avalos 		p += sprintf(p, ".%.*d", prec, nsec);
117e0f95098SPeter Avalos 	}
118e0f95098SPeter Avalos 	return(__printf_out(io, pi, buf, p - buf));
119e0f95098SPeter Avalos }
120