xref: /freebsd/lib/libc/stdtime/timelocal.c (revision 5b5fa75acff11d871d0c90045f8c1a58fed85365)
137486f03SJoerg Wunsch /*-
2d915a14eSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3d915a14eSPedro F. Giffuni  *
452d6b430SAlexey Zelkin  * Copyright (c) 2001 Alexey Zelkin <phantom@FreeBSD.org>
537486f03SJoerg Wunsch  * Copyright (c) 1997 FreeBSD Inc.
637486f03SJoerg Wunsch  * All rights reserved.
737486f03SJoerg Wunsch  *
83c87aa1dSDavid Chisnall  * Copyright (c) 2011 The FreeBSD Foundation
9*5b5fa75aSEd Maste  *
103c87aa1dSDavid Chisnall  * Portions of this software were developed by David Chisnall
113c87aa1dSDavid Chisnall  * under sponsorship from the FreeBSD Foundation.
123c87aa1dSDavid Chisnall  *
1337486f03SJoerg Wunsch  * Redistribution and use in source and binary forms, with or without
1437486f03SJoerg Wunsch  * modification, are permitted provided that the following conditions
1537486f03SJoerg Wunsch  * are met:
1637486f03SJoerg Wunsch  * 1. Redistributions of source code must retain the above copyright
1737486f03SJoerg Wunsch  *    notice, this list of conditions and the following disclaimer.
1837486f03SJoerg Wunsch  * 2. Redistributions in binary form must reproduce the above copyright
1937486f03SJoerg Wunsch  *    notice, this list of conditions and the following disclaimer in the
2037486f03SJoerg Wunsch  *    documentation and/or other materials provided with the distribution.
2137486f03SJoerg Wunsch  *
2237486f03SJoerg Wunsch  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2337486f03SJoerg Wunsch  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2437486f03SJoerg Wunsch  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2537486f03SJoerg Wunsch  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2637486f03SJoerg Wunsch  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2737486f03SJoerg Wunsch  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2837486f03SJoerg Wunsch  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2937486f03SJoerg Wunsch  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3037486f03SJoerg Wunsch  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3137486f03SJoerg Wunsch  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3237486f03SJoerg Wunsch  * SUCH DAMAGE.
3337486f03SJoerg Wunsch  */
3437486f03SJoerg Wunsch 
35333fc21eSDavid E. O'Brien #include <sys/cdefs.h>
36333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$");
37333fc21eSDavid E. O'Brien 
3850bab1e6SAndrey A. Chernov #include <stddef.h>
3950bab1e6SAndrey A. Chernov 
404e862380SAlexey Zelkin #include "ldpart.h"
4137486f03SJoerg Wunsch #include "timelocal.h"
4237486f03SJoerg Wunsch 
433c87aa1dSDavid Chisnall struct xlocale_time {
443c87aa1dSDavid Chisnall 	struct xlocale_component header;
453c87aa1dSDavid Chisnall 	char *buffer;
463c87aa1dSDavid Chisnall 	struct lc_time_T locale;
473c87aa1dSDavid Chisnall };
483c87aa1dSDavid Chisnall 
493c87aa1dSDavid Chisnall struct xlocale_time __xlocale_global_time;
5037486f03SJoerg Wunsch 
51faeb1b82SAndrey A. Chernov #define	LCTIME_SIZE (sizeof(struct lc_time_T) / sizeof(char *))
52da3785efSDmitrij Tejblum 
5318f3e1e4SAlexey Zelkin static const struct lc_time_T	_C_time_locale = {
5437486f03SJoerg Wunsch 	{
5537486f03SJoerg Wunsch 		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
5637486f03SJoerg Wunsch 		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
5737486f03SJoerg Wunsch 	}, {
5837486f03SJoerg Wunsch 		"January", "February", "March", "April", "May", "June",
5937486f03SJoerg Wunsch 		"July", "August", "September", "October", "November", "December"
6037486f03SJoerg Wunsch 	}, {
6137486f03SJoerg Wunsch 		"Sun", "Mon", "Tue", "Wed",
6237486f03SJoerg Wunsch 		"Thu", "Fri", "Sat"
6337486f03SJoerg Wunsch 	}, {
6437486f03SJoerg Wunsch 		"Sunday", "Monday", "Tuesday", "Wednesday",
6537486f03SJoerg Wunsch 		"Thursday", "Friday", "Saturday"
6637486f03SJoerg Wunsch 	},
6737486f03SJoerg Wunsch 
6837486f03SJoerg Wunsch 	/* X_fmt */
6937486f03SJoerg Wunsch 	"%H:%M:%S",
7037486f03SJoerg Wunsch 
7137486f03SJoerg Wunsch 	/*
72bcbeac34SAlexey Zelkin 	 * x_fmt
73bcbeac34SAlexey Zelkin 	 * Since the C language standard calls for
74bcbeac34SAlexey Zelkin 	 * "date, using locale's date format," anything goes.
75bcbeac34SAlexey Zelkin 	 * Using just numbers (as here) makes Quakers happier;
76bcbeac34SAlexey Zelkin 	 * it's also compatible with SVR4.
7737486f03SJoerg Wunsch 	 */
7850b4c62cSAndrey A. Chernov 	"%m/%d/%y",
7937486f03SJoerg Wunsch 
8037486f03SJoerg Wunsch 	/*
81bcbeac34SAlexey Zelkin 	 * c_fmt
8237486f03SJoerg Wunsch 	 */
8350b4c62cSAndrey A. Chernov 	"%a %b %e %H:%M:%S %Y",
8437486f03SJoerg Wunsch 
8537486f03SJoerg Wunsch 	/* am */
8637486f03SJoerg Wunsch 	"AM",
8737486f03SJoerg Wunsch 
8837486f03SJoerg Wunsch 	/* pm */
8937486f03SJoerg Wunsch 	"PM",
9037486f03SJoerg Wunsch 
9137486f03SJoerg Wunsch 	/* date_fmt */
9250b4c62cSAndrey A. Chernov 	"%a %b %e %H:%M:%S %Z %Y",
93da3785efSDmitrij Tejblum 
94faeb1b82SAndrey A. Chernov 	/* alt_month
95bcbeac34SAlexey Zelkin 	 * Standalone months forms for %OB
96faeb1b82SAndrey A. Chernov 	 */
97da3785efSDmitrij Tejblum 	{
98da3785efSDmitrij Tejblum 		"January", "February", "March", "April", "May", "June",
99da3785efSDmitrij Tejblum 		"July", "August", "September", "October", "November", "December"
10011cd0d32SAndrey A. Chernov 	},
10111cd0d32SAndrey A. Chernov 
102faeb1b82SAndrey A. Chernov 	/* md_order
103bcbeac34SAlexey Zelkin 	 * Month / day order in dates
10411cd0d32SAndrey A. Chernov 	 */
105faeb1b82SAndrey A. Chernov 	"md",
10650bab1e6SAndrey A. Chernov 
10750bab1e6SAndrey A. Chernov 	/* ampm_fmt
108bcbeac34SAlexey Zelkin 	 * To determine 12-hour clock format time (empty, if N/A)
10950bab1e6SAndrey A. Chernov 	 */
11050bab1e6SAndrey A. Chernov 	"%I:%M:%S %p"
11137486f03SJoerg Wunsch };
11237486f03SJoerg Wunsch 
1133c87aa1dSDavid Chisnall static void destruct_time(void *v)
1141491b31eSAndrey A. Chernov {
1153c87aa1dSDavid Chisnall 	struct xlocale_time *l = v;
1163c87aa1dSDavid Chisnall 	if (l->buffer)
1173c87aa1dSDavid Chisnall 		free(l->buffer);
1183c87aa1dSDavid Chisnall 	free(l);
1193c87aa1dSDavid Chisnall }
1203c87aa1dSDavid Chisnall 
1213c87aa1dSDavid Chisnall #include <stdio.h>
1223c87aa1dSDavid Chisnall struct lc_time_T *
1233c87aa1dSDavid Chisnall __get_current_time_locale(locale_t loc)
1243c87aa1dSDavid Chisnall {
1253c87aa1dSDavid Chisnall 	return (loc->using_time_locale
1263c87aa1dSDavid Chisnall 		? &((struct xlocale_time *)loc->components[XLC_TIME])->locale
12718f3e1e4SAlexey Zelkin 		: (struct lc_time_T *)&_C_time_locale);
12818f3e1e4SAlexey Zelkin }
12937486f03SJoerg Wunsch 
1303c87aa1dSDavid Chisnall static int
1313c87aa1dSDavid Chisnall time_load_locale(struct xlocale_time *l, int *using_locale, const char *name)
1323c87aa1dSDavid Chisnall {
1333c87aa1dSDavid Chisnall 	struct lc_time_T *time_locale = &l->locale;
1343c87aa1dSDavid Chisnall 	return (__part_load_locale(name, using_locale,
1353c87aa1dSDavid Chisnall 			&l->buffer, "LC_TIME",
1363c87aa1dSDavid Chisnall 			LCTIME_SIZE, LCTIME_SIZE,
1373c87aa1dSDavid Chisnall 			(const char **)time_locale));
1383c87aa1dSDavid Chisnall }
13937486f03SJoerg Wunsch int
1401491b31eSAndrey A. Chernov __time_load_locale(const char *name)
1411491b31eSAndrey A. Chernov {
1423c87aa1dSDavid Chisnall 	return time_load_locale(&__xlocale_global_time,
1433c87aa1dSDavid Chisnall 			&__xlocale_global_locale.using_time_locale, name);
144da3785efSDmitrij Tejblum }
1453c87aa1dSDavid Chisnall void* __time_load(const char* name, locale_t loc)
1463c87aa1dSDavid Chisnall {
1473c87aa1dSDavid Chisnall 	struct xlocale_time *new = calloc(sizeof(struct xlocale_time), 1);
1483c87aa1dSDavid Chisnall 	new->header.header.destructor = destruct_time;
1493c87aa1dSDavid Chisnall 	if (time_load_locale(new, &loc->using_time_locale, name) == _LDP_ERROR)
1503c87aa1dSDavid Chisnall 	{
1513c87aa1dSDavid Chisnall 		xlocale_release(new);
1523c87aa1dSDavid Chisnall 		return NULL;
1533c87aa1dSDavid Chisnall 	}
1543c87aa1dSDavid Chisnall 	return new;
1553c87aa1dSDavid Chisnall }
1563c87aa1dSDavid Chisnall 
157