xref: /titanic_50/usr/src/cmd/localedef/time.c (revision 2d08521bd15501c8370ba2153b9cca4f094979d0)
16b5e5868SGarrett D'Amore /*
26b5e5868SGarrett D'Amore  * This file and its contents are supplied under the terms of the
36b5e5868SGarrett D'Amore  * Common Development and Distribution License ("CDDL"), version 1.0.
45aec55ebSGarrett D'Amore  * You may only use this file in accordance with the terms of version
55aec55ebSGarrett D'Amore  * 1.0 of the CDDL.
66b5e5868SGarrett D'Amore  *
76b5e5868SGarrett D'Amore  * A full copy of the text of the CDDL should have accompanied this
86b5e5868SGarrett D'Amore  * source.  A copy of the CDDL is also available via the Internet at
96b5e5868SGarrett D'Amore  * http://www.illumos.org/license/CDDL.
106b5e5868SGarrett D'Amore  */
116b5e5868SGarrett D'Amore 
126b5e5868SGarrett D'Amore /*
13*2d08521bSGarrett D'Amore  * Copyright 2013 Garrett D'Amore <garrett@damore.org>
146b5e5868SGarrett D'Amore  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
156b5e5868SGarrett D'Amore  */
166b5e5868SGarrett D'Amore 
176b5e5868SGarrett D'Amore /*
186b5e5868SGarrett D'Amore  * LC_TIME database generation routines for localedef.
196b5e5868SGarrett D'Amore  */
206b5e5868SGarrett D'Amore 
216b5e5868SGarrett D'Amore #include <stdio.h>
226b5e5868SGarrett D'Amore #include <stdlib.h>
236b5e5868SGarrett D'Amore #include <errno.h>
246b5e5868SGarrett D'Amore #include <sys/types.h>
256b5e5868SGarrett D'Amore #include <string.h>
266b5e5868SGarrett D'Amore #include <unistd.h>
276b5e5868SGarrett D'Amore #include "localedef.h"
286b5e5868SGarrett D'Amore #include "parser.tab.h"
296b5e5868SGarrett D'Amore #include "timelocal.h"
306b5e5868SGarrett D'Amore 
31*2d08521bSGarrett D'Amore struct lc_time tm;
326b5e5868SGarrett D'Amore 
336b5e5868SGarrett D'Amore void
init_time(void)346b5e5868SGarrett D'Amore init_time(void)
356b5e5868SGarrett D'Amore {
366b5e5868SGarrett D'Amore 	(void) memset(&tm, 0, sizeof (tm));
376b5e5868SGarrett D'Amore }
386b5e5868SGarrett D'Amore 
396b5e5868SGarrett D'Amore void
add_time_str(wchar_t * wcs)406b5e5868SGarrett D'Amore add_time_str(wchar_t *wcs)
416b5e5868SGarrett D'Amore {
426b5e5868SGarrett D'Amore 	char	*str;
436b5e5868SGarrett D'Amore 
446b5e5868SGarrett D'Amore 	if ((str = to_mb_string(wcs)) == NULL) {
456b5e5868SGarrett D'Amore 		INTERR;
466b5e5868SGarrett D'Amore 		return;
476b5e5868SGarrett D'Amore 	}
486b5e5868SGarrett D'Amore 	free(wcs);
496b5e5868SGarrett D'Amore 
506b5e5868SGarrett D'Amore 	switch (last_kw) {
516b5e5868SGarrett D'Amore 	case T_D_T_FMT:
526b5e5868SGarrett D'Amore 		tm.c_fmt = str;
536b5e5868SGarrett D'Amore 		break;
546b5e5868SGarrett D'Amore 	case T_D_FMT:
556b5e5868SGarrett D'Amore 		tm.x_fmt = str;
566b5e5868SGarrett D'Amore 		break;
576b5e5868SGarrett D'Amore 	case T_T_FMT:
586b5e5868SGarrett D'Amore 		tm.X_fmt = str;
596b5e5868SGarrett D'Amore 		break;
606b5e5868SGarrett D'Amore 	case T_T_FMT_AMPM:
616b5e5868SGarrett D'Amore 		tm.ampm_fmt = str;
626b5e5868SGarrett D'Amore 		break;
636b5e5868SGarrett D'Amore 	case T_DATE_FMT:
646b5e5868SGarrett D'Amore 		/*
656b5e5868SGarrett D'Amore 		 * This one is a Solaris extension, Too bad date just
666b5e5868SGarrett D'Amore 		 * doesn't use %c, which would be simpler.
676b5e5868SGarrett D'Amore 		 */
686b5e5868SGarrett D'Amore 		tm.date_fmt = str;
696b5e5868SGarrett D'Amore 		break;
706b5e5868SGarrett D'Amore 	case T_ERA_D_FMT:
716b5e5868SGarrett D'Amore 	case T_ERA_T_FMT:
726b5e5868SGarrett D'Amore 	case T_ERA_D_T_FMT:
736b5e5868SGarrett D'Amore 		/* Silently ignore it. */
746b5e5868SGarrett D'Amore 		break;
756b5e5868SGarrett D'Amore 	default:
766b5e5868SGarrett D'Amore 		free(str);
776b5e5868SGarrett D'Amore 		INTERR;
786b5e5868SGarrett D'Amore 		break;
796b5e5868SGarrett D'Amore 	}
806b5e5868SGarrett D'Amore }
816b5e5868SGarrett D'Amore 
826b5e5868SGarrett D'Amore static void
add_list(const char * ptr[],char * str,int limit)836b5e5868SGarrett D'Amore add_list(const char *ptr[], char *str, int limit)
846b5e5868SGarrett D'Amore {
856b5e5868SGarrett D'Amore 	int	i;
866b5e5868SGarrett D'Amore 	for (i = 0; i < limit; i++) {
876b5e5868SGarrett D'Amore 		if (ptr[i] == NULL) {
886b5e5868SGarrett D'Amore 			ptr[i] = str;
896b5e5868SGarrett D'Amore 			return;
906b5e5868SGarrett D'Amore 		}
916b5e5868SGarrett D'Amore 	}
926b5e5868SGarrett D'Amore 	errf(_("too many list elements"));
936b5e5868SGarrett D'Amore }
946b5e5868SGarrett D'Amore 
956b5e5868SGarrett D'Amore void
add_time_list(wchar_t * wcs)966b5e5868SGarrett D'Amore add_time_list(wchar_t *wcs)
976b5e5868SGarrett D'Amore {
986b5e5868SGarrett D'Amore 	char *str;
996b5e5868SGarrett D'Amore 
1006b5e5868SGarrett D'Amore 	if ((str = to_mb_string(wcs)) == NULL) {
1016b5e5868SGarrett D'Amore 		INTERR;
1026b5e5868SGarrett D'Amore 		return;
1036b5e5868SGarrett D'Amore 	}
1046b5e5868SGarrett D'Amore 	free(wcs);
1056b5e5868SGarrett D'Amore 
1066b5e5868SGarrett D'Amore 	switch (last_kw) {
1076b5e5868SGarrett D'Amore 	case T_ABMON:
1086b5e5868SGarrett D'Amore 		add_list(tm.mon, str, 12);
1096b5e5868SGarrett D'Amore 		break;
1106b5e5868SGarrett D'Amore 	case T_MON:
1116b5e5868SGarrett D'Amore 		add_list(tm.month, str, 12);
1126b5e5868SGarrett D'Amore 		break;
1136b5e5868SGarrett D'Amore 	case T_ABDAY:
1146b5e5868SGarrett D'Amore 		add_list(tm.wday, str, 7);
1156b5e5868SGarrett D'Amore 		break;
1166b5e5868SGarrett D'Amore 	case T_DAY:
1176b5e5868SGarrett D'Amore 		add_list(tm.weekday, str, 7);
1186b5e5868SGarrett D'Amore 		break;
1196b5e5868SGarrett D'Amore 	case T_AM_PM:
1206b5e5868SGarrett D'Amore 		if (tm.am == NULL) {
1216b5e5868SGarrett D'Amore 			tm.am = str;
1226b5e5868SGarrett D'Amore 		} else if (tm.pm == NULL) {
1236b5e5868SGarrett D'Amore 			tm.pm = str;
1246b5e5868SGarrett D'Amore 		} else {
1256b5e5868SGarrett D'Amore 			errf(_("too many list elements"));
1266b5e5868SGarrett D'Amore 		}
1276b5e5868SGarrett D'Amore 		break;
1286b5e5868SGarrett D'Amore 	case T_ALT_DIGITS:
1296b5e5868SGarrett D'Amore 	case T_ERA:
1306b5e5868SGarrett D'Amore 		free(str);
1316b5e5868SGarrett D'Amore 		break;
1326b5e5868SGarrett D'Amore 	default:
1336b5e5868SGarrett D'Amore 		free(str);
1346b5e5868SGarrett D'Amore 		INTERR;
1356b5e5868SGarrett D'Amore 		break;
1366b5e5868SGarrett D'Amore 	}
1376b5e5868SGarrett D'Amore }
1386b5e5868SGarrett D'Amore 
1396b5e5868SGarrett D'Amore void
check_time_list(void)1406b5e5868SGarrett D'Amore check_time_list(void)
1416b5e5868SGarrett D'Amore {
1426b5e5868SGarrett D'Amore 	switch (last_kw) {
1436b5e5868SGarrett D'Amore 	case T_ABMON:
1446b5e5868SGarrett D'Amore 		if (tm.mon[11] != NULL)
1456b5e5868SGarrett D'Amore 			return;
1466b5e5868SGarrett D'Amore 		break;
1476b5e5868SGarrett D'Amore 	case T_MON:
1486b5e5868SGarrett D'Amore 		if (tm.month[11] != NULL)
1496b5e5868SGarrett D'Amore 			return;
1506b5e5868SGarrett D'Amore 		break;
1516b5e5868SGarrett D'Amore 	case T_ABDAY:
1526b5e5868SGarrett D'Amore 		if (tm.wday[6] != NULL)
1536b5e5868SGarrett D'Amore 			return;
1546b5e5868SGarrett D'Amore 		break;
1556b5e5868SGarrett D'Amore 	case T_DAY:
1566b5e5868SGarrett D'Amore 		if (tm.weekday[6] != NULL)
1576b5e5868SGarrett D'Amore 			return;
1586b5e5868SGarrett D'Amore 		break;
1596b5e5868SGarrett D'Amore 	case T_AM_PM:
1606b5e5868SGarrett D'Amore 		if (tm.pm != NULL)
1616b5e5868SGarrett D'Amore 			return;
1626b5e5868SGarrett D'Amore 		break;
1636b5e5868SGarrett D'Amore 	case T_ERA:
1646b5e5868SGarrett D'Amore 	case T_ALT_DIGITS:
1656b5e5868SGarrett D'Amore 		return;
1666b5e5868SGarrett D'Amore 	default:
1676b5e5868SGarrett D'Amore 		errf(_("unknown list"));
1686b5e5868SGarrett D'Amore 		break;
1696b5e5868SGarrett D'Amore 	}
1706b5e5868SGarrett D'Amore 
1716b5e5868SGarrett D'Amore 	errf(_("too few items in list (%d)"), last_kw);
1726b5e5868SGarrett D'Amore }
1736b5e5868SGarrett D'Amore 
1746b5e5868SGarrett D'Amore void
reset_time_list(void)1756b5e5868SGarrett D'Amore reset_time_list(void)
1766b5e5868SGarrett D'Amore {
1776b5e5868SGarrett D'Amore 	int i;
1786b5e5868SGarrett D'Amore 	switch (last_kw) {
1796b5e5868SGarrett D'Amore 	case T_ABMON:
1806b5e5868SGarrett D'Amore 		for (i = 0; i < 12; i++) {
1816b5e5868SGarrett D'Amore 			free((char *)tm.mon[i]);
1826b5e5868SGarrett D'Amore 			tm.mon[i] = NULL;
1836b5e5868SGarrett D'Amore 		}
1846b5e5868SGarrett D'Amore 		break;
1856b5e5868SGarrett D'Amore 	case T_MON:
1866b5e5868SGarrett D'Amore 		for (i = 0; i < 12; i++) {
1876b5e5868SGarrett D'Amore 			free((char *)tm.month[i]);
1886b5e5868SGarrett D'Amore 			tm.month[i] = NULL;
1896b5e5868SGarrett D'Amore 		}
1906b5e5868SGarrett D'Amore 		break;
1916b5e5868SGarrett D'Amore 	case T_ABDAY:
1926b5e5868SGarrett D'Amore 		for (i = 0; i < 7; i++) {
1936b5e5868SGarrett D'Amore 			free((char *)tm.wday[i]);
1946b5e5868SGarrett D'Amore 			tm.wday[i] = NULL;
1956b5e5868SGarrett D'Amore 		}
1966b5e5868SGarrett D'Amore 		break;
1976b5e5868SGarrett D'Amore 	case T_DAY:
1986b5e5868SGarrett D'Amore 		for (i = 0; i < 7; i++) {
1996b5e5868SGarrett D'Amore 			free((char *)tm.weekday[i]);
2006b5e5868SGarrett D'Amore 			tm.weekday[i] = NULL;
2016b5e5868SGarrett D'Amore 		}
2026b5e5868SGarrett D'Amore 		break;
2036b5e5868SGarrett D'Amore 	case T_AM_PM:
2046b5e5868SGarrett D'Amore 		free((char *)tm.am);
2056b5e5868SGarrett D'Amore 		tm.am = NULL;
2066b5e5868SGarrett D'Amore 		free((char *)tm.pm);
2076b5e5868SGarrett D'Amore 		tm.pm = NULL;
2086b5e5868SGarrett D'Amore 		break;
2096b5e5868SGarrett D'Amore 	}
2106b5e5868SGarrett D'Amore }
2116b5e5868SGarrett D'Amore 
2126b5e5868SGarrett D'Amore 
2136b5e5868SGarrett D'Amore void
dump_time(void)2146b5e5868SGarrett D'Amore dump_time(void)
2156b5e5868SGarrett D'Amore {
2166b5e5868SGarrett D'Amore 	FILE *f;
2176b5e5868SGarrett D'Amore 	int i;
2186b5e5868SGarrett D'Amore 
2196b5e5868SGarrett D'Amore 	if ((f = open_category()) == NULL) {
2206b5e5868SGarrett D'Amore 		return;
2216b5e5868SGarrett D'Amore 	}
2226b5e5868SGarrett D'Amore 
2236b5e5868SGarrett D'Amore 	for (i = 0; i < 12; i++) {
2246b5e5868SGarrett D'Amore 		if (putl_category(tm.mon[i], f) == EOF) {
2256b5e5868SGarrett D'Amore 			return;
2266b5e5868SGarrett D'Amore 		}
2276b5e5868SGarrett D'Amore 	}
2286b5e5868SGarrett D'Amore 	for (i = 0; i < 12; i++) {
2296b5e5868SGarrett D'Amore 		if (putl_category(tm.month[i], f) == EOF) {
2306b5e5868SGarrett D'Amore 			return;
2316b5e5868SGarrett D'Amore 		}
2326b5e5868SGarrett D'Amore 	}
2336b5e5868SGarrett D'Amore 	for (i = 0; i < 7; i++) {
2346b5e5868SGarrett D'Amore 		if (putl_category(tm.wday[i], f) == EOF) {
2356b5e5868SGarrett D'Amore 			return;
2366b5e5868SGarrett D'Amore 		}
2376b5e5868SGarrett D'Amore 	}
2386b5e5868SGarrett D'Amore 	for (i = 0; i < 7; i++) {
2396b5e5868SGarrett D'Amore 		if (putl_category(tm.weekday[i], f) == EOF) {
2406b5e5868SGarrett D'Amore 			return;
2416b5e5868SGarrett D'Amore 		}
2426b5e5868SGarrett D'Amore 	}
2436b5e5868SGarrett D'Amore 
2446b5e5868SGarrett D'Amore 	/*
2456b5e5868SGarrett D'Amore 	 * NOTE: If date_fmt is not specified, then we'll default to
2466b5e5868SGarrett D'Amore 	 * using the %c for date.  This is reasonable for most
2476b5e5868SGarrett D'Amore 	 * locales, although for reasons that I don't understand
2486b5e5868SGarrett D'Amore 	 * Solaris historically has had a seperate format for date.
2496b5e5868SGarrett D'Amore 	 */
2506b5e5868SGarrett D'Amore 	if ((putl_category(tm.X_fmt, f) == EOF) ||
2516b5e5868SGarrett D'Amore 	    (putl_category(tm.x_fmt, f) == EOF) ||
2526b5e5868SGarrett D'Amore 	    (putl_category(tm.c_fmt, f) == EOF) ||
2536b5e5868SGarrett D'Amore 	    (putl_category(tm.am, f) == EOF) ||
2546b5e5868SGarrett D'Amore 	    (putl_category(tm.pm, f) == EOF) ||
2556b5e5868SGarrett D'Amore 	    (putl_category(tm.date_fmt ? tm.date_fmt : tm.c_fmt, f) == EOF) ||
2566b5e5868SGarrett D'Amore 	    (putl_category(tm.ampm_fmt, f) == EOF)) {
2576b5e5868SGarrett D'Amore 		return;
2586b5e5868SGarrett D'Amore 	}
2596b5e5868SGarrett D'Amore 	close_category(f);
2606b5e5868SGarrett D'Amore }
261