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