14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin * Glenn Fowler
254887Schin * AT&T Research
264887Schin *
274887Schin * time conversion translation support
284887Schin */
294887Schin
304887Schin #include <ast.h>
314887Schin #include <cdt.h>
324887Schin #include <iconv.h>
334887Schin #include <mc.h>
344887Schin #include <tm.h>
35*12068SRoger.Faulkner@Oracle.COM #include <ast_nl_types.h>
364887Schin
374887Schin #include "lclib.h"
384887Schin
394887Schin static struct
404887Schin {
414887Schin char* format;
424887Schin Lc_info_t* locale;
434887Schin char null[1];
444887Schin } state;
454887Schin
464887Schin /*
474887Schin * this is unix dadgummit
484887Schin */
494887Schin
504887Schin static int
standardized(Lc_info_t * li,register char ** b)514887Schin standardized(Lc_info_t* li, register char** b)
524887Schin {
534887Schin if ((li->lc->language->flags & (LC_debug|LC_default)) || streq(li->lc->language->code, "en"))
544887Schin {
554887Schin b[TM_TIME] = "%H:%M:%S";
564887Schin b[TM_DATE] = "%m/%d/%y";
574887Schin b[TM_DEFAULT] = "%a %b %e %T %Z %Y";
584887Schin return 1;
594887Schin }
604887Schin return 0;
614887Schin }
624887Schin
634887Schin /*
644887Schin * fix up LC_TIME data after loading
654887Schin */
664887Schin
674887Schin static void
fixup(Lc_info_t * li,register char ** b)684887Schin fixup(Lc_info_t* li, register char** b)
694887Schin {
704887Schin register char** v;
714887Schin register char** e;
724887Schin register int n;
734887Schin
744887Schin static int must[] =
754887Schin {
764887Schin TM_TIME,
774887Schin TM_DATE,
784887Schin TM_DEFAULT,
794887Schin TM_CTIME,
804887Schin TM_DATE_1,
814887Schin TM_INTERNATIONAL,
824887Schin TM_RECENT,
834887Schin TM_DISTANT,
844887Schin TM_MERIDIAN_TIME,
854887Schin };
864887Schin
874887Schin standardized(li, b);
884887Schin for (v = b, e = b + TM_NFORM; v < e; v++)
894887Schin if (!*v)
904887Schin *v = state.null;
914887Schin for (n = 0; n < elementsof(must); n++)
924887Schin if (!*b[must[n]])
934887Schin b[must[n]] = tm_data.format[must[n]];
944887Schin if (li->lc->flags & LC_default)
954887Schin for (n = 0; n < TM_NFORM; n++)
964887Schin if (!*b[n])
974887Schin b[n] = tm_data.format[n];
984887Schin if (strchr(b[TM_UT], '%'))
994887Schin {
1004887Schin tm_info.deformat = b[TM_UT];
1014887Schin for (n = TM_UT; n < TM_DT; n++)
1024887Schin b[n] = state.null;
1034887Schin }
1044887Schin else
1054887Schin tm_info.deformat = b[TM_DEFAULT];
1064887Schin tm_info.format = b;
1074887Schin if (!(tm_info.deformat = state.format))
1084887Schin tm_info.deformat = tm_info.format[TM_DEFAULT];
1094887Schin li->data = (void*)b;
1104887Schin }
1114887Schin
1124887Schin #if _WINIX
1134887Schin
1144887Schin #include <ast_windows.h>
1154887Schin
1164887Schin typedef struct Map_s
1174887Schin {
1184887Schin LCID native;
1194887Schin int local;
1204887Schin } Map_t;
1214887Schin
1224887Schin static const Map_t map[] =
1234887Schin {
1244887Schin LOCALE_S1159, (TM_MERIDIAN+0),
1254887Schin LOCALE_S2359, (TM_MERIDIAN+1),
1264887Schin LOCALE_SABBREVDAYNAME1, (TM_DAY_ABBREV+1),
1274887Schin LOCALE_SABBREVDAYNAME2, (TM_DAY_ABBREV+2),
1284887Schin LOCALE_SABBREVDAYNAME3, (TM_DAY_ABBREV+3),
1294887Schin LOCALE_SABBREVDAYNAME4, (TM_DAY_ABBREV+4),
1304887Schin LOCALE_SABBREVDAYNAME5, (TM_DAY_ABBREV+5),
1314887Schin LOCALE_SABBREVDAYNAME6, (TM_DAY_ABBREV+6),
1324887Schin LOCALE_SABBREVDAYNAME7, (TM_DAY_ABBREV+0),
1334887Schin LOCALE_SABBREVMONTHNAME1, (TM_MONTH_ABBREV+0),
1344887Schin LOCALE_SABBREVMONTHNAME2, (TM_MONTH_ABBREV+1),
1354887Schin LOCALE_SABBREVMONTHNAME3, (TM_MONTH_ABBREV+2),
1364887Schin LOCALE_SABBREVMONTHNAME4, (TM_MONTH_ABBREV+3),
1374887Schin LOCALE_SABBREVMONTHNAME5, (TM_MONTH_ABBREV+4),
1384887Schin LOCALE_SABBREVMONTHNAME6, (TM_MONTH_ABBREV+5),
1394887Schin LOCALE_SABBREVMONTHNAME7, (TM_MONTH_ABBREV+6),
1404887Schin LOCALE_SABBREVMONTHNAME8, (TM_MONTH_ABBREV+7),
1414887Schin LOCALE_SABBREVMONTHNAME9, (TM_MONTH_ABBREV+8),
1424887Schin LOCALE_SABBREVMONTHNAME10, (TM_MONTH_ABBREV+9),
1434887Schin LOCALE_SABBREVMONTHNAME11, (TM_MONTH_ABBREV+10),
1444887Schin LOCALE_SABBREVMONTHNAME12, (TM_MONTH_ABBREV+11),
1454887Schin LOCALE_SDAYNAME1, (TM_DAY+1),
1464887Schin LOCALE_SDAYNAME2, (TM_DAY+2),
1474887Schin LOCALE_SDAYNAME3, (TM_DAY+3),
1484887Schin LOCALE_SDAYNAME4, (TM_DAY+4),
1494887Schin LOCALE_SDAYNAME5, (TM_DAY+5),
1504887Schin LOCALE_SDAYNAME6, (TM_DAY+6),
1514887Schin LOCALE_SDAYNAME7, (TM_DAY+0),
1524887Schin LOCALE_SMONTHNAME1, (TM_MONTH+0),
1534887Schin LOCALE_SMONTHNAME2, (TM_MONTH+1),
1544887Schin LOCALE_SMONTHNAME3, (TM_MONTH+2),
1554887Schin LOCALE_SMONTHNAME4, (TM_MONTH+3),
1564887Schin LOCALE_SMONTHNAME5, (TM_MONTH+4),
1574887Schin LOCALE_SMONTHNAME6, (TM_MONTH+5),
1584887Schin LOCALE_SMONTHNAME7, (TM_MONTH+6),
1594887Schin LOCALE_SMONTHNAME8, (TM_MONTH+7),
1604887Schin LOCALE_SMONTHNAME9, (TM_MONTH+8),
1614887Schin LOCALE_SMONTHNAME10, (TM_MONTH+9),
1624887Schin LOCALE_SMONTHNAME11, (TM_MONTH+10),
1634887Schin LOCALE_SMONTHNAME12, (TM_MONTH+11),
1644887Schin };
1654887Schin
1664887Schin #undef extern
1674887Schin
1684887Schin /*
1694887Schin * convert ms word date spec w to posix strftime format f
1704887Schin * next char after f returned
1714887Schin * the caller already made sure f is big enough
1724887Schin */
1734887Schin
1744887Schin static char*
word2posix(register char * f,register char * w,int alternate)1754887Schin word2posix(register char* f, register char* w, int alternate)
1764887Schin {
1774887Schin register char* r;
1784887Schin register int c;
1794887Schin register int p;
1804887Schin register int n;
1814887Schin
1824887Schin while (*w)
1834887Schin {
1844887Schin p = 0;
1854887Schin r = w;
1864887Schin while (*++w == *r);
1874887Schin if ((n = w - r) > 3 && alternate)
1884887Schin n--;
1894887Schin switch (*r)
1904887Schin {
1914887Schin case 'a':
1924887Schin case 'A':
1934887Schin if (!strncasecmp(w, "am/pm", 5))
1944887Schin w += 5;
1954887Schin else if (!strncasecmp(w, "a/p", 3))
1964887Schin w += 3;
1974887Schin c = 'p';
1984887Schin break;
1994887Schin case 'd':
2004887Schin switch (n)
2014887Schin {
2024887Schin case 1:
2034887Schin p = '-';
2044887Schin /*FALLTHROUGH*/
2054887Schin case 2:
2064887Schin c = 'd';
2074887Schin break;
2084887Schin case 3:
2094887Schin c = 'a';
2104887Schin break;
2114887Schin default:
2124887Schin c = 'A';
2134887Schin break;
2144887Schin }
2154887Schin break;
2164887Schin case 'h':
2174887Schin switch (n)
2184887Schin {
2194887Schin case 1:
2204887Schin p = '-';
2214887Schin /*FALLTHROUGH*/
2224887Schin default:
2234887Schin c = 'I';
2244887Schin break;
2254887Schin }
2264887Schin break;
2274887Schin case 'H':
2284887Schin switch (n)
2294887Schin {
2304887Schin case 1:
2314887Schin p = '-';
2324887Schin /*FALLTHROUGH*/
2334887Schin default:
2344887Schin c = 'H';
2354887Schin break;
2364887Schin }
2374887Schin break;
2384887Schin case 'M':
2394887Schin switch (n)
2404887Schin {
2414887Schin case 1:
2424887Schin p = '-';
2434887Schin /*FALLTHROUGH*/
2444887Schin case 2:
2454887Schin c = 'm';
2464887Schin break;
2474887Schin case 3:
2484887Schin c = 'b';
2494887Schin break;
2504887Schin default:
2514887Schin c = 'B';
2524887Schin break;
2534887Schin }
2544887Schin break;
2554887Schin case 'm':
2564887Schin switch (n)
2574887Schin {
2584887Schin case 1:
2594887Schin p = '-';
2604887Schin /*FALLTHROUGH*/
2614887Schin default:
2624887Schin c = 'M';
2634887Schin break;
2644887Schin }
2654887Schin break;
2664887Schin case 's':
2674887Schin switch (n)
2684887Schin {
2694887Schin case 1:
2704887Schin p = '-';
2714887Schin /*FALLTHROUGH*/
2724887Schin default:
2734887Schin c = 'S';
2744887Schin break;
2754887Schin }
2764887Schin break;
2774887Schin case 'y':
2784887Schin switch (n)
2794887Schin {
2804887Schin case 1:
2814887Schin p = '-';
2824887Schin /*FALLTHROUGH*/
2834887Schin case 2:
2844887Schin c = 'y';
2854887Schin break;
2864887Schin default:
2874887Schin c = 'Y';
2884887Schin break;
2894887Schin }
2904887Schin break;
2914887Schin case '\'':
2924887Schin if (n & 1)
2934887Schin for (w = r + 1; *w; *f++ = *w++)
2944887Schin if (*w == '\'')
2954887Schin {
2964887Schin w++;
2974887Schin break;
2984887Schin }
2994887Schin continue;
3004887Schin case '%':
3014887Schin while (r < w)
3024887Schin {
3034887Schin *f++ = *r++;
3044887Schin *f++ = *r++;
3054887Schin }
3064887Schin continue;
3074887Schin default:
3084887Schin while (r < w)
3094887Schin *f++ = *r++;
3104887Schin continue;
3114887Schin }
3124887Schin *f++ = '%';
3134887Schin if (p)
3144887Schin *f++ = '-';
3154887Schin *f++ = c;
3164887Schin }
3174887Schin *f++ = 0;
3184887Schin return f;
3194887Schin }
3204887Schin
3214887Schin /*
3224887Schin * load the native LC_TIME data for the current locale
3234887Schin */
3244887Schin
3254887Schin static void
native_lc_time(Lc_info_t * li)3264887Schin native_lc_time(Lc_info_t* li)
3274887Schin {
3284887Schin register char* s;
3294887Schin register char* t;
3304887Schin register char** b;
3314887Schin register int n;
3324887Schin register int m;
3334887Schin register int i;
3344887Schin LCID lcid;
3354887Schin int nt;
3364887Schin int ns;
3374887Schin int nl;
3384887Schin int clock_24;
3394887Schin int leading_0;
3404887Schin char buf[256];
3414887Schin
3424887Schin lcid = li->lc->index;
3434887Schin nt = 2 * GetLocaleInfo(lcid, LOCALE_STIME, 0, 0) + 7; /* HH:MM:SS */
3444887Schin ns = 3 * GetLocaleInfo(lcid, LOCALE_SSHORTDATE, 0, 0);
3454887Schin nl = 3 * GetLocaleInfo(lcid, LOCALE_SLONGDATE, 0, 0);
3464887Schin n = nt + ns + nl;
3474887Schin for (i = 0; i < elementsof(map); i++)
3484887Schin n += GetLocaleInfo(lcid, map[i].native, 0, 0);
3494887Schin if (!(b = newof(0, char*, TM_NFORM, n)))
3504887Schin return;
3514887Schin s = (char*)(b + TM_NFORM);
3524887Schin for (i = 0; i < elementsof(map); i++)
3534887Schin {
3544887Schin if (!(m = GetLocaleInfo(lcid, map[i].native, s, n)))
3554887Schin goto bad;
3564887Schin b[map[i].local] = s;
3574887Schin s += m;
3584887Schin }
3594887Schin if (!standardized(li, b))
3604887Schin {
3614887Schin /*
3624887Schin * synthesize TM_TIME format from the ms word template
3634887Schin */
3644887Schin
3654887Schin if (!GetLocaleInfo(lcid, LOCALE_ITIME, buf, sizeof(buf)))
3664887Schin goto bad;
3674887Schin clock_24 = atoi(buf);
3684887Schin if (!GetLocaleInfo(lcid, LOCALE_ITLZERO, buf, sizeof(buf)))
3694887Schin goto bad;
3704887Schin leading_0 = atoi(buf);
3714887Schin if (!GetLocaleInfo(lcid, LOCALE_STIME, buf, sizeof(buf)))
3724887Schin goto bad;
3734887Schin b[TM_TIME] = s;
3744887Schin *s++ = '%';
3754887Schin if (!leading_0)
3764887Schin *s++ = '-';
3774887Schin *s++ = clock_24 ? 'H' : 'I';
3784887Schin for (t = buf; *s = *t++; s++);
3794887Schin *s++ = '%';
3804887Schin if (!leading_0)
3814887Schin *s++ = '-';
3824887Schin *s++ = 'M';
3834887Schin for (t = buf; *s = *t++; s++);
3844887Schin *s++ = '%';
3854887Schin if (!leading_0)
3864887Schin *s++ = '-';
3874887Schin *s++ = 'S';
3884887Schin *s++ = 0;
3894887Schin
3904887Schin /*
3914887Schin * synthesize TM_DATE format
3924887Schin */
3934887Schin
3944887Schin if (!GetLocaleInfo(lcid, LOCALE_SSHORTDATE, buf, sizeof(buf)))
3954887Schin goto bad;
3964887Schin b[TM_DATE] = s;
3974887Schin s = word2posix(s, buf, 1);
3984887Schin
3994887Schin /*
4004887Schin * synthesize TM_DEFAULT format
4014887Schin */
4024887Schin
4034887Schin if (!GetLocaleInfo(lcid, LOCALE_SLONGDATE, buf, sizeof(buf)))
4044887Schin goto bad;
4054887Schin b[TM_DEFAULT] = s;
4064887Schin s = word2posix(s, buf, 1);
4074887Schin strcpy(s - 1, " %X");
4084887Schin }
4094887Schin
4104887Schin /*
4114887Schin * done
4124887Schin */
4134887Schin
4144887Schin fixup(li, b);
4154887Schin return;
4164887Schin bad:
4174887Schin free(b);
4184887Schin }
4194887Schin
4204887Schin #else
4214887Schin
4224887Schin #if _lib_nl_langinfo && _hdr_langinfo
4234887Schin
4244887Schin #if _hdr_nl_types
4254887Schin #include <nl_types.h>
4264887Schin #endif
4274887Schin
4284887Schin #include <langinfo.h>
4294887Schin
4304887Schin typedef struct Map_s
4314887Schin {
4324887Schin int native;
4334887Schin int local;
4344887Schin } Map_t;
4354887Schin
4364887Schin static const Map_t map[] =
4374887Schin {
4384887Schin AM_STR, (TM_MERIDIAN+0),
4394887Schin PM_STR, (TM_MERIDIAN+1),
4404887Schin ABDAY_1, (TM_DAY_ABBREV+0),
4414887Schin ABDAY_2, (TM_DAY_ABBREV+1),
4424887Schin ABDAY_3, (TM_DAY_ABBREV+2),
4434887Schin ABDAY_4, (TM_DAY_ABBREV+3),
4444887Schin ABDAY_5, (TM_DAY_ABBREV+4),
4454887Schin ABDAY_6, (TM_DAY_ABBREV+5),
4464887Schin ABDAY_7, (TM_DAY_ABBREV+6),
4474887Schin ABMON_1, (TM_MONTH_ABBREV+0),
4484887Schin ABMON_2, (TM_MONTH_ABBREV+1),
4494887Schin ABMON_3, (TM_MONTH_ABBREV+2),
4504887Schin ABMON_4, (TM_MONTH_ABBREV+3),
4514887Schin ABMON_5, (TM_MONTH_ABBREV+4),
4524887Schin ABMON_6, (TM_MONTH_ABBREV+5),
4534887Schin ABMON_7, (TM_MONTH_ABBREV+6),
4544887Schin ABMON_8, (TM_MONTH_ABBREV+7),
4554887Schin ABMON_9, (TM_MONTH_ABBREV+8),
4564887Schin ABMON_10, (TM_MONTH_ABBREV+9),
4574887Schin ABMON_11, (TM_MONTH_ABBREV+10),
4584887Schin ABMON_12, (TM_MONTH_ABBREV+11),
4594887Schin DAY_1, (TM_DAY+0),
4604887Schin DAY_2, (TM_DAY+1),
4614887Schin DAY_3, (TM_DAY+2),
4624887Schin DAY_4, (TM_DAY+3),
4634887Schin DAY_5, (TM_DAY+4),
4644887Schin DAY_6, (TM_DAY+5),
4654887Schin DAY_7, (TM_DAY+6),
4664887Schin MON_1, (TM_MONTH+0),
4674887Schin MON_2, (TM_MONTH+1),
4684887Schin MON_3, (TM_MONTH+2),
4694887Schin MON_4, (TM_MONTH+3),
4704887Schin MON_5, (TM_MONTH+4),
4714887Schin MON_6, (TM_MONTH+5),
4724887Schin MON_7, (TM_MONTH+6),
4734887Schin MON_8, (TM_MONTH+7),
4744887Schin MON_9, (TM_MONTH+8),
4754887Schin MON_10, (TM_MONTH+9),
4764887Schin MON_11, (TM_MONTH+10),
4774887Schin MON_12, (TM_MONTH+11),
4788462SApril.Chin@Sun.COM #ifdef _DATE_FMT
4798462SApril.Chin@Sun.COM _DATE_FMT, TM_DEFAULT,
4808462SApril.Chin@Sun.COM #else
4814887Schin D_T_FMT, TM_DEFAULT,
4828462SApril.Chin@Sun.COM #endif
4834887Schin D_FMT, TM_DATE,
4844887Schin T_FMT, TM_TIME,
4854887Schin #ifdef ERA
4864887Schin ERA, TM_ERA,
4874887Schin ERA_D_T_FMT, TM_ERA_DEFAULT,
4884887Schin ERA_D_FMT, TM_ERA_DATE,
4894887Schin ERA_T_FMT, TM_ERA_TIME,
4904887Schin #endif
4914887Schin #ifdef ALT_DIGITS
4924887Schin ALT_DIGITS, TM_DIGITS,
4934887Schin #endif
4944887Schin };
4954887Schin
4964887Schin static void
native_lc_time(Lc_info_t * li)4974887Schin native_lc_time(Lc_info_t* li)
4984887Schin {
4994887Schin register char* s;
5004887Schin register char* t;
5014887Schin register char** b;
5024887Schin register int n;
5034887Schin register int i;
5044887Schin
5054887Schin n = 0;
5064887Schin for (i = 0; i < elementsof(map); i++)
507*12068SRoger.Faulkner@Oracle.COM {
508*12068SRoger.Faulkner@Oracle.COM if (!(t = nl_langinfo(map[i].native)))
509*12068SRoger.Faulkner@Oracle.COM t = tm_data.format[map[i].local];
510*12068SRoger.Faulkner@Oracle.COM n += strlen(t) + 1;
511*12068SRoger.Faulkner@Oracle.COM }
5124887Schin if (!(b = newof(0, char*, TM_NFORM, n)))
5134887Schin return;
5144887Schin s = (char*)(b + TM_NFORM);
5154887Schin for (i = 0; i < elementsof(map); i++)
5164887Schin {
5174887Schin b[map[i].local] = s;
518*12068SRoger.Faulkner@Oracle.COM if (!(t = nl_langinfo(map[i].native)))
519*12068SRoger.Faulkner@Oracle.COM t = tm_data.format[map[i].local];
5204887Schin while (*s++ = *t++);
5214887Schin }
5224887Schin fixup(li, b);
5234887Schin }
5244887Schin
5254887Schin #else
5264887Schin
5274887Schin #define native_lc_time(li) ((li->data=(void*)(tm_info.format=tm_data.format)),(tm_info.deformat=tm_info.format[TM_DEFAULT]))
5284887Schin
5294887Schin #endif
5304887Schin
5314887Schin #endif
5324887Schin
5334887Schin /*
5344887Schin * load the LC_TIME data for the current locale
5354887Schin */
5364887Schin
5374887Schin static void
load(Lc_info_t * li)5384887Schin load(Lc_info_t* li)
5394887Schin {
5404887Schin register char* s;
5414887Schin register char** b;
5424887Schin register char** v;
5434887Schin register char** e;
5444887Schin unsigned char* u;
5454887Schin ssize_t n;
5464887Schin iconv_t cvt;
5474887Schin Sfio_t* sp;
5484887Schin Sfio_t* tp;
5494887Schin char path[PATH_MAX];
5504887Schin
5514887Schin if (b = (char**)li->data)
5524887Schin {
5534887Schin tm_info.format = b;
5544887Schin if (!(tm_info.deformat = state.format))
5554887Schin tm_info.deformat = tm_info.format[TM_DEFAULT];
5564887Schin return;
5574887Schin }
5584887Schin tm_info.format = tm_data.format;
5594887Schin if (!(tm_info.deformat = state.format))
5604887Schin tm_info.deformat = tm_info.format[TM_DEFAULT];
5614887Schin if (mcfind(path, NiL, NiL, LC_TIME, 0) && (sp = sfopen(NiL, path, "r")))
5624887Schin {
5634887Schin n = sfsize(sp);
5644887Schin tp = 0;
5654887Schin if (u = (unsigned char*)sfreserve(sp, 3, 1))
5664887Schin {
5674887Schin if (u[0] == 0xef && u[1] == 0xbb && u[2] == 0xbf && (cvt = iconv_open("", "utf")) != (iconv_t)(-1))
5684887Schin {
5694887Schin if (tp = sfstropen())
5704887Schin {
5714887Schin sfread(sp, u, 3);
5724887Schin n = iconv_move(cvt, sp, tp, SF_UNBOUND, NiL);
5734887Schin }
5744887Schin iconv_close(cvt);
5754887Schin }
5764887Schin if (!tp)
5774887Schin sfread(sp, u, 0);
5784887Schin }
5794887Schin if (b = newof(0, char*, TM_NFORM, n + 2))
5804887Schin {
5814887Schin v = b;
5824887Schin e = b + TM_NFORM;
5834887Schin s = (char*)e;
5844887Schin if (tp && memcpy(s, sfstrbase(tp), n) || !tp && sfread(sp, s, n) == n)
5854887Schin {
5864887Schin s[n] = '\n';
5874887Schin while (v < e)
5884887Schin {
5894887Schin *v++ = s;
5904887Schin if (!(s = strchr(s, '\n')))
5914887Schin break;
5924887Schin *s++ = 0;
5934887Schin }
5944887Schin fixup(li, b);
5954887Schin }
5964887Schin else
5974887Schin free(b);
5984887Schin }
5994887Schin if (tp)
6004887Schin sfclose(tp);
6014887Schin sfclose(sp);
6024887Schin }
6034887Schin else
6044887Schin native_lc_time(li);
6054887Schin }
6064887Schin
6074887Schin /*
6084887Schin * check that tm_info.format matches the current locale
6094887Schin */
6104887Schin
6114887Schin char**
tmlocale(void)6124887Schin tmlocale(void)
6134887Schin {
6144887Schin Lc_info_t* li;
6154887Schin
6164887Schin if (!tm_info.format)
6174887Schin {
6184887Schin tm_info.format = tm_data.format;
6194887Schin if (!tm_info.deformat)
6204887Schin tm_info.deformat = tm_info.format[TM_DEFAULT];
6214887Schin else if (tm_info.deformat != tm_info.format[TM_DEFAULT])
6224887Schin state.format = tm_info.deformat;
6234887Schin }
6244887Schin li = LCINFO(AST_LC_TIME);
6254887Schin if (!li->data)
6264887Schin load(li);
6274887Schin return tm_info.format;
6284887Schin }
629