xref: /titanic_53/usr/src/cmd/localedef/time.c (revision 6b5e5868e7ebf1aff3a5abd7d0c4ef0e5fbf3648)
1*6b5e5868SGarrett D'Amore /*
2*6b5e5868SGarrett D'Amore  * This file and its contents are supplied under the terms of the
3*6b5e5868SGarrett D'Amore  * Common Development and Distribution License ("CDDL"), version 1.0.
4*6b5e5868SGarrett D'Amore  * You may only use this file in accordance with the terms version 1.0
5*6b5e5868SGarrett D'Amore  * of the CDDL.
6*6b5e5868SGarrett D'Amore  *
7*6b5e5868SGarrett D'Amore  * A full copy of the text of the CDDL should have accompanied this
8*6b5e5868SGarrett D'Amore  * source.  A copy of the CDDL is also available via the Internet at
9*6b5e5868SGarrett D'Amore  * http://www.illumos.org/license/CDDL.
10*6b5e5868SGarrett D'Amore  */
11*6b5e5868SGarrett D'Amore 
12*6b5e5868SGarrett D'Amore /*
13*6b5e5868SGarrett D'Amore  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
14*6b5e5868SGarrett D'Amore  */
15*6b5e5868SGarrett D'Amore 
16*6b5e5868SGarrett D'Amore /*
17*6b5e5868SGarrett D'Amore  * LC_TIME database generation routines for localedef.
18*6b5e5868SGarrett D'Amore  */
19*6b5e5868SGarrett D'Amore 
20*6b5e5868SGarrett D'Amore #include <stdio.h>
21*6b5e5868SGarrett D'Amore #include <stdlib.h>
22*6b5e5868SGarrett D'Amore #include <errno.h>
23*6b5e5868SGarrett D'Amore #include <sys/types.h>
24*6b5e5868SGarrett D'Amore #include <string.h>
25*6b5e5868SGarrett D'Amore #include <unistd.h>
26*6b5e5868SGarrett D'Amore #include "localedef.h"
27*6b5e5868SGarrett D'Amore #include "parser.tab.h"
28*6b5e5868SGarrett D'Amore #include "timelocal.h"
29*6b5e5868SGarrett D'Amore 
30*6b5e5868SGarrett D'Amore struct lc_time_T tm;
31*6b5e5868SGarrett D'Amore 
32*6b5e5868SGarrett D'Amore void
33*6b5e5868SGarrett D'Amore init_time(void)
34*6b5e5868SGarrett D'Amore {
35*6b5e5868SGarrett D'Amore 	(void) memset(&tm, 0, sizeof (tm));
36*6b5e5868SGarrett D'Amore }
37*6b5e5868SGarrett D'Amore 
38*6b5e5868SGarrett D'Amore void
39*6b5e5868SGarrett D'Amore add_time_str(wchar_t *wcs)
40*6b5e5868SGarrett D'Amore {
41*6b5e5868SGarrett D'Amore 	char	*str;
42*6b5e5868SGarrett D'Amore 
43*6b5e5868SGarrett D'Amore 	if ((str = to_mb_string(wcs)) == NULL) {
44*6b5e5868SGarrett D'Amore 		INTERR;
45*6b5e5868SGarrett D'Amore 		return;
46*6b5e5868SGarrett D'Amore 	}
47*6b5e5868SGarrett D'Amore 	free(wcs);
48*6b5e5868SGarrett D'Amore 
49*6b5e5868SGarrett D'Amore 	switch (last_kw) {
50*6b5e5868SGarrett D'Amore 	case T_D_T_FMT:
51*6b5e5868SGarrett D'Amore 		tm.c_fmt = str;
52*6b5e5868SGarrett D'Amore 		break;
53*6b5e5868SGarrett D'Amore 	case T_D_FMT:
54*6b5e5868SGarrett D'Amore 		tm.x_fmt = str;
55*6b5e5868SGarrett D'Amore 		break;
56*6b5e5868SGarrett D'Amore 	case T_T_FMT:
57*6b5e5868SGarrett D'Amore 		tm.X_fmt = str;
58*6b5e5868SGarrett D'Amore 		break;
59*6b5e5868SGarrett D'Amore 	case T_T_FMT_AMPM:
60*6b5e5868SGarrett D'Amore 		tm.ampm_fmt = str;
61*6b5e5868SGarrett D'Amore 		break;
62*6b5e5868SGarrett D'Amore 	case T_DATE_FMT:
63*6b5e5868SGarrett D'Amore 		/*
64*6b5e5868SGarrett D'Amore 		 * This one is a Solaris extension, Too bad date just
65*6b5e5868SGarrett D'Amore 		 * doesn't use %c, which would be simpler.
66*6b5e5868SGarrett D'Amore 		 */
67*6b5e5868SGarrett D'Amore 		tm.date_fmt = str;
68*6b5e5868SGarrett D'Amore 		break;
69*6b5e5868SGarrett D'Amore 	case T_ERA_D_FMT:
70*6b5e5868SGarrett D'Amore 	case T_ERA_T_FMT:
71*6b5e5868SGarrett D'Amore 	case T_ERA_D_T_FMT:
72*6b5e5868SGarrett D'Amore 		/* Silently ignore it. */
73*6b5e5868SGarrett D'Amore 		break;
74*6b5e5868SGarrett D'Amore 	default:
75*6b5e5868SGarrett D'Amore 		free(str);
76*6b5e5868SGarrett D'Amore 		INTERR;
77*6b5e5868SGarrett D'Amore 		break;
78*6b5e5868SGarrett D'Amore 	}
79*6b5e5868SGarrett D'Amore }
80*6b5e5868SGarrett D'Amore 
81*6b5e5868SGarrett D'Amore static void
82*6b5e5868SGarrett D'Amore add_list(const char *ptr[], char *str, int limit)
83*6b5e5868SGarrett D'Amore {
84*6b5e5868SGarrett D'Amore 	int	i;
85*6b5e5868SGarrett D'Amore 	for (i = 0; i < limit; i++) {
86*6b5e5868SGarrett D'Amore 		if (ptr[i] == NULL) {
87*6b5e5868SGarrett D'Amore 			ptr[i] = str;
88*6b5e5868SGarrett D'Amore 			return;
89*6b5e5868SGarrett D'Amore 		}
90*6b5e5868SGarrett D'Amore 	}
91*6b5e5868SGarrett D'Amore 	errf(_("too many list elements"));
92*6b5e5868SGarrett D'Amore }
93*6b5e5868SGarrett D'Amore 
94*6b5e5868SGarrett D'Amore void
95*6b5e5868SGarrett D'Amore add_time_list(wchar_t *wcs)
96*6b5e5868SGarrett D'Amore {
97*6b5e5868SGarrett D'Amore 	char *str;
98*6b5e5868SGarrett D'Amore 
99*6b5e5868SGarrett D'Amore 	if ((str = to_mb_string(wcs)) == NULL) {
100*6b5e5868SGarrett D'Amore 		INTERR;
101*6b5e5868SGarrett D'Amore 		return;
102*6b5e5868SGarrett D'Amore 	}
103*6b5e5868SGarrett D'Amore 	free(wcs);
104*6b5e5868SGarrett D'Amore 
105*6b5e5868SGarrett D'Amore 	switch (last_kw) {
106*6b5e5868SGarrett D'Amore 	case T_ABMON:
107*6b5e5868SGarrett D'Amore 		add_list(tm.mon, str, 12);
108*6b5e5868SGarrett D'Amore 		break;
109*6b5e5868SGarrett D'Amore 	case T_MON:
110*6b5e5868SGarrett D'Amore 		add_list(tm.month, str, 12);
111*6b5e5868SGarrett D'Amore 		break;
112*6b5e5868SGarrett D'Amore 	case T_ABDAY:
113*6b5e5868SGarrett D'Amore 		add_list(tm.wday, str, 7);
114*6b5e5868SGarrett D'Amore 		break;
115*6b5e5868SGarrett D'Amore 	case T_DAY:
116*6b5e5868SGarrett D'Amore 		add_list(tm.weekday, str, 7);
117*6b5e5868SGarrett D'Amore 		break;
118*6b5e5868SGarrett D'Amore 	case T_AM_PM:
119*6b5e5868SGarrett D'Amore 		if (tm.am == NULL) {
120*6b5e5868SGarrett D'Amore 			tm.am = str;
121*6b5e5868SGarrett D'Amore 		} else if (tm.pm == NULL) {
122*6b5e5868SGarrett D'Amore 			tm.pm = str;
123*6b5e5868SGarrett D'Amore 		} else {
124*6b5e5868SGarrett D'Amore 			errf(_("too many list elements"));
125*6b5e5868SGarrett D'Amore 		}
126*6b5e5868SGarrett D'Amore 		break;
127*6b5e5868SGarrett D'Amore 	case T_ALT_DIGITS:
128*6b5e5868SGarrett D'Amore 	case T_ERA:
129*6b5e5868SGarrett D'Amore 		free(str);
130*6b5e5868SGarrett D'Amore 		break;
131*6b5e5868SGarrett D'Amore 	default:
132*6b5e5868SGarrett D'Amore 		free(str);
133*6b5e5868SGarrett D'Amore 		INTERR;
134*6b5e5868SGarrett D'Amore 		break;
135*6b5e5868SGarrett D'Amore 	}
136*6b5e5868SGarrett D'Amore }
137*6b5e5868SGarrett D'Amore 
138*6b5e5868SGarrett D'Amore void
139*6b5e5868SGarrett D'Amore check_time_list(void)
140*6b5e5868SGarrett D'Amore {
141*6b5e5868SGarrett D'Amore 	switch (last_kw) {
142*6b5e5868SGarrett D'Amore 	case T_ABMON:
143*6b5e5868SGarrett D'Amore 		if (tm.mon[11] != NULL)
144*6b5e5868SGarrett D'Amore 			return;
145*6b5e5868SGarrett D'Amore 		break;
146*6b5e5868SGarrett D'Amore 	case T_MON:
147*6b5e5868SGarrett D'Amore 		if (tm.month[11] != NULL)
148*6b5e5868SGarrett D'Amore 			return;
149*6b5e5868SGarrett D'Amore 		break;
150*6b5e5868SGarrett D'Amore 	case T_ABDAY:
151*6b5e5868SGarrett D'Amore 		if (tm.wday[6] != NULL)
152*6b5e5868SGarrett D'Amore 			return;
153*6b5e5868SGarrett D'Amore 		break;
154*6b5e5868SGarrett D'Amore 	case T_DAY:
155*6b5e5868SGarrett D'Amore 		if (tm.weekday[6] != NULL)
156*6b5e5868SGarrett D'Amore 			return;
157*6b5e5868SGarrett D'Amore 		break;
158*6b5e5868SGarrett D'Amore 	case T_AM_PM:
159*6b5e5868SGarrett D'Amore 		if (tm.pm != NULL)
160*6b5e5868SGarrett D'Amore 			return;
161*6b5e5868SGarrett D'Amore 		break;
162*6b5e5868SGarrett D'Amore 	case T_ERA:
163*6b5e5868SGarrett D'Amore 	case T_ALT_DIGITS:
164*6b5e5868SGarrett D'Amore 		return;
165*6b5e5868SGarrett D'Amore 	default:
166*6b5e5868SGarrett D'Amore 		errf(_("unknown list"));
167*6b5e5868SGarrett D'Amore 		break;
168*6b5e5868SGarrett D'Amore 	}
169*6b5e5868SGarrett D'Amore 
170*6b5e5868SGarrett D'Amore 	errf(_("too few items in list (%d)"), last_kw);
171*6b5e5868SGarrett D'Amore }
172*6b5e5868SGarrett D'Amore 
173*6b5e5868SGarrett D'Amore void
174*6b5e5868SGarrett D'Amore reset_time_list(void)
175*6b5e5868SGarrett D'Amore {
176*6b5e5868SGarrett D'Amore 	int i;
177*6b5e5868SGarrett D'Amore 	switch (last_kw) {
178*6b5e5868SGarrett D'Amore 	case T_ABMON:
179*6b5e5868SGarrett D'Amore 		for (i = 0; i < 12; i++) {
180*6b5e5868SGarrett D'Amore 			free((char *)tm.mon[i]);
181*6b5e5868SGarrett D'Amore 			tm.mon[i] = NULL;
182*6b5e5868SGarrett D'Amore 		}
183*6b5e5868SGarrett D'Amore 		break;
184*6b5e5868SGarrett D'Amore 	case T_MON:
185*6b5e5868SGarrett D'Amore 		for (i = 0; i < 12; i++) {
186*6b5e5868SGarrett D'Amore 			free((char *)tm.month[i]);
187*6b5e5868SGarrett D'Amore 			tm.month[i] = NULL;
188*6b5e5868SGarrett D'Amore 		}
189*6b5e5868SGarrett D'Amore 		break;
190*6b5e5868SGarrett D'Amore 	case T_ABDAY:
191*6b5e5868SGarrett D'Amore 		for (i = 0; i < 7; i++) {
192*6b5e5868SGarrett D'Amore 			free((char *)tm.wday[i]);
193*6b5e5868SGarrett D'Amore 			tm.wday[i] = NULL;
194*6b5e5868SGarrett D'Amore 		}
195*6b5e5868SGarrett D'Amore 		break;
196*6b5e5868SGarrett D'Amore 	case T_DAY:
197*6b5e5868SGarrett D'Amore 		for (i = 0; i < 7; i++) {
198*6b5e5868SGarrett D'Amore 			free((char *)tm.weekday[i]);
199*6b5e5868SGarrett D'Amore 			tm.weekday[i] = NULL;
200*6b5e5868SGarrett D'Amore 		}
201*6b5e5868SGarrett D'Amore 		break;
202*6b5e5868SGarrett D'Amore 	case T_AM_PM:
203*6b5e5868SGarrett D'Amore 		free((char *)tm.am);
204*6b5e5868SGarrett D'Amore 		tm.am = NULL;
205*6b5e5868SGarrett D'Amore 		free((char *)tm.pm);
206*6b5e5868SGarrett D'Amore 		tm.pm = NULL;
207*6b5e5868SGarrett D'Amore 		break;
208*6b5e5868SGarrett D'Amore 	}
209*6b5e5868SGarrett D'Amore }
210*6b5e5868SGarrett D'Amore 
211*6b5e5868SGarrett D'Amore 
212*6b5e5868SGarrett D'Amore void
213*6b5e5868SGarrett D'Amore dump_time(void)
214*6b5e5868SGarrett D'Amore {
215*6b5e5868SGarrett D'Amore 	FILE *f;
216*6b5e5868SGarrett D'Amore 	int i;
217*6b5e5868SGarrett D'Amore 
218*6b5e5868SGarrett D'Amore 	if ((f = open_category()) == NULL) {
219*6b5e5868SGarrett D'Amore 		return;
220*6b5e5868SGarrett D'Amore 	}
221*6b5e5868SGarrett D'Amore 
222*6b5e5868SGarrett D'Amore 	for (i = 0; i < 12; i++) {
223*6b5e5868SGarrett D'Amore 		if (putl_category(tm.mon[i], f) == EOF) {
224*6b5e5868SGarrett D'Amore 			return;
225*6b5e5868SGarrett D'Amore 		}
226*6b5e5868SGarrett D'Amore 	}
227*6b5e5868SGarrett D'Amore 	for (i = 0; i < 12; i++) {
228*6b5e5868SGarrett D'Amore 		if (putl_category(tm.month[i], f) == EOF) {
229*6b5e5868SGarrett D'Amore 			return;
230*6b5e5868SGarrett D'Amore 		}
231*6b5e5868SGarrett D'Amore 	}
232*6b5e5868SGarrett D'Amore 	for (i = 0; i < 7; i++) {
233*6b5e5868SGarrett D'Amore 		if (putl_category(tm.wday[i], f) == EOF) {
234*6b5e5868SGarrett D'Amore 			return;
235*6b5e5868SGarrett D'Amore 		}
236*6b5e5868SGarrett D'Amore 	}
237*6b5e5868SGarrett D'Amore 	for (i = 0; i < 7; i++) {
238*6b5e5868SGarrett D'Amore 		if (putl_category(tm.weekday[i], f) == EOF) {
239*6b5e5868SGarrett D'Amore 			return;
240*6b5e5868SGarrett D'Amore 		}
241*6b5e5868SGarrett D'Amore 	}
242*6b5e5868SGarrett D'Amore 
243*6b5e5868SGarrett D'Amore 	/*
244*6b5e5868SGarrett D'Amore 	 * NOTE: If date_fmt is not specified, then we'll default to
245*6b5e5868SGarrett D'Amore 	 * using the %c for date.  This is reasonable for most
246*6b5e5868SGarrett D'Amore 	 * locales, although for reasons that I don't understand
247*6b5e5868SGarrett D'Amore 	 * Solaris historically has had a seperate format for date.
248*6b5e5868SGarrett D'Amore 	 */
249*6b5e5868SGarrett D'Amore 	if ((putl_category(tm.X_fmt, f) == EOF) ||
250*6b5e5868SGarrett D'Amore 	    (putl_category(tm.x_fmt, f) == EOF) ||
251*6b5e5868SGarrett D'Amore 	    (putl_category(tm.c_fmt, f) == EOF) ||
252*6b5e5868SGarrett D'Amore 	    (putl_category(tm.am, f) == EOF) ||
253*6b5e5868SGarrett D'Amore 	    (putl_category(tm.pm, f) == EOF) ||
254*6b5e5868SGarrett D'Amore 	    (putl_category(tm.date_fmt ? tm.date_fmt : tm.c_fmt, f) == EOF) ||
255*6b5e5868SGarrett D'Amore 	    (putl_category(tm.ampm_fmt, f) == EOF)) {
256*6b5e5868SGarrett D'Amore 		return;
257*6b5e5868SGarrett D'Amore 	}
258*6b5e5868SGarrett D'Amore 	close_category(f);
259*6b5e5868SGarrett D'Amore }
260