14297a3b0SGarrett D'Amore /*
2*2d08521bSGarrett D'Amore * Copyright 2013 Garrett D'Amore <garrett@damore.org>
36b5e5868SGarrett D'Amore * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
44297a3b0SGarrett D'Amore * Copyright (c) 2001, 2003 Alexey Zelkin <phantom@FreeBSD.org>
54297a3b0SGarrett D'Amore * All rights reserved.
64297a3b0SGarrett D'Amore *
74297a3b0SGarrett D'Amore * Redistribution and use in source and binary forms, with or without
84297a3b0SGarrett D'Amore * modification, are permitted provided that the following conditions
94297a3b0SGarrett D'Amore * are met:
104297a3b0SGarrett D'Amore * 1. Redistributions of source code must retain the above copyright
114297a3b0SGarrett D'Amore * notice, this list of conditions and the following disclaimer.
124297a3b0SGarrett D'Amore * 2. Redistributions in binary form must reproduce the above copyright
134297a3b0SGarrett D'Amore * notice, this list of conditions and the following disclaimer in the
144297a3b0SGarrett D'Amore * documentation and/or other materials provided with the distribution.
154297a3b0SGarrett D'Amore *
164297a3b0SGarrett D'Amore * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
174297a3b0SGarrett D'Amore * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
184297a3b0SGarrett D'Amore * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
194297a3b0SGarrett D'Amore * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
204297a3b0SGarrett D'Amore * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
214297a3b0SGarrett D'Amore * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
224297a3b0SGarrett D'Amore * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
234297a3b0SGarrett D'Amore * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
244297a3b0SGarrett D'Amore * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
254297a3b0SGarrett D'Amore * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
264297a3b0SGarrett D'Amore * SUCH DAMAGE.
274297a3b0SGarrett D'Amore */
284297a3b0SGarrett D'Amore
294297a3b0SGarrett D'Amore #include "lint.h"
304297a3b0SGarrett D'Amore #include <langinfo.h>
314297a3b0SGarrett D'Amore #include <limits.h>
324297a3b0SGarrett D'Amore #include <locale.h>
334297a3b0SGarrett D'Amore #include <stdlib.h>
344297a3b0SGarrett D'Amore #include <string.h>
354297a3b0SGarrett D'Amore
364297a3b0SGarrett D'Amore #include "lnumeric.h"
374297a3b0SGarrett D'Amore #include "lmessages.h"
384297a3b0SGarrett D'Amore #include "lmonetary.h"
394297a3b0SGarrett D'Amore #include "timelocal.h"
40*2d08521bSGarrett D'Amore #include "localeimpl.h"
414297a3b0SGarrett D'Amore
424297a3b0SGarrett D'Amore #define _REL(BASE) ((int)item-BASE)
434297a3b0SGarrett D'Amore
444297a3b0SGarrett D'Amore #pragma weak _nl_langinfo = nl_langinfo
454297a3b0SGarrett D'Amore
464297a3b0SGarrett D'Amore char *
nl_langinfo_l(nl_item item,locale_t loc)47*2d08521bSGarrett D'Amore nl_langinfo_l(nl_item item, locale_t loc)
484297a3b0SGarrett D'Amore {
494297a3b0SGarrett D'Amore char *ret, *s, *cs;
50*2d08521bSGarrett D'Amore struct locdata *ldata;
51*2d08521bSGarrett D'Amore const struct lc_monetary *lmon = loc->monetary;
52*2d08521bSGarrett D'Amore const struct lc_numeric *lnum = loc->numeric;
53*2d08521bSGarrett D'Amore const struct lc_messages *lmsgs = loc->messages;
54*2d08521bSGarrett D'Amore const struct lc_time *ltime = loc->time;
554297a3b0SGarrett D'Amore
564297a3b0SGarrett D'Amore switch (item) {
574297a3b0SGarrett D'Amore case CODESET:
584297a3b0SGarrett D'Amore ret = "";
594297a3b0SGarrett D'Amore /*
604297a3b0SGarrett D'Amore * The codeset is the suffix of a locale, for most it will
61*2d08521bSGarrett D'Amore * will be UTF-8, as in "en_US.UTF-8". Short form locales are
624297a3b0SGarrett D'Amore * not supported. Note also that although FreeBSD uses
634297a3b0SGarrett D'Amore * US-ASCII, Solaris historically has reported "646" for the
644297a3b0SGarrett D'Amore * C locale.
65*2d08521bSGarrett D'Amore *
66*2d08521bSGarrett D'Amore * Note that this code will need to change if we ever support
67*2d08521bSGarrett D'Amore * POSIX defined locale variants (suffixes with an @ sign)
684297a3b0SGarrett D'Amore */
69*2d08521bSGarrett D'Amore ldata = loc->locdata[LC_CTYPE];
70*2d08521bSGarrett D'Amore s = ldata ? ldata->l_lname : NULL;
71*2d08521bSGarrett D'Amore if (s != NULL) {
724297a3b0SGarrett D'Amore if ((cs = strchr(s, '.')) != NULL)
734297a3b0SGarrett D'Amore ret = cs + 1;
744297a3b0SGarrett D'Amore else if (strcmp(s, "C") == 0 || strcmp(s, "POSIX") == 0)
754297a3b0SGarrett D'Amore ret = "646";
764297a3b0SGarrett D'Amore }
774297a3b0SGarrett D'Amore break;
784297a3b0SGarrett D'Amore case D_T_FMT:
79*2d08521bSGarrett D'Amore ret = (char *)ltime->c_fmt;
804297a3b0SGarrett D'Amore break;
814297a3b0SGarrett D'Amore case D_FMT:
82*2d08521bSGarrett D'Amore ret = (char *)ltime->x_fmt;
834297a3b0SGarrett D'Amore break;
844297a3b0SGarrett D'Amore case T_FMT:
85*2d08521bSGarrett D'Amore ret = (char *)ltime->X_fmt;
864297a3b0SGarrett D'Amore break;
874297a3b0SGarrett D'Amore case T_FMT_AMPM:
88*2d08521bSGarrett D'Amore ret = (char *)ltime->ampm_fmt;
894297a3b0SGarrett D'Amore break;
904297a3b0SGarrett D'Amore case AM_STR:
91*2d08521bSGarrett D'Amore ret = (char *)ltime->am;
924297a3b0SGarrett D'Amore break;
934297a3b0SGarrett D'Amore case PM_STR:
94*2d08521bSGarrett D'Amore ret = (char *)ltime->pm;
954297a3b0SGarrett D'Amore break;
964297a3b0SGarrett D'Amore case DAY_1: case DAY_2: case DAY_3:
974297a3b0SGarrett D'Amore case DAY_4: case DAY_5: case DAY_6: case DAY_7:
98*2d08521bSGarrett D'Amore ret = (char *)ltime->weekday[_REL(DAY_1)];
994297a3b0SGarrett D'Amore break;
1004297a3b0SGarrett D'Amore case ABDAY_1: case ABDAY_2: case ABDAY_3:
1014297a3b0SGarrett D'Amore case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7:
102*2d08521bSGarrett D'Amore ret = (char *)ltime->wday[_REL(ABDAY_1)];
1034297a3b0SGarrett D'Amore break;
1044297a3b0SGarrett D'Amore case MON_1: case MON_2: case MON_3: case MON_4:
1054297a3b0SGarrett D'Amore case MON_5: case MON_6: case MON_7: case MON_8:
1064297a3b0SGarrett D'Amore case MON_9: case MON_10: case MON_11: case MON_12:
107*2d08521bSGarrett D'Amore ret = (char *)ltime->month[_REL(MON_1)];
1084297a3b0SGarrett D'Amore break;
1094297a3b0SGarrett D'Amore case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4:
1104297a3b0SGarrett D'Amore case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8:
1114297a3b0SGarrett D'Amore case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12:
112*2d08521bSGarrett D'Amore ret = (char *)ltime->mon[_REL(ABMON_1)];
1134297a3b0SGarrett D'Amore break;
1144297a3b0SGarrett D'Amore case ERA:
1154297a3b0SGarrett D'Amore /* XXX: need to be implemented */
1164297a3b0SGarrett D'Amore ret = "";
1174297a3b0SGarrett D'Amore break;
1184297a3b0SGarrett D'Amore case ERA_D_FMT:
1194297a3b0SGarrett D'Amore /* XXX: need to be implemented */
1204297a3b0SGarrett D'Amore ret = "";
1214297a3b0SGarrett D'Amore break;
1224297a3b0SGarrett D'Amore case ERA_D_T_FMT:
1234297a3b0SGarrett D'Amore /* XXX: need to be implemented */
1244297a3b0SGarrett D'Amore ret = "";
1254297a3b0SGarrett D'Amore break;
1264297a3b0SGarrett D'Amore case ERA_T_FMT:
1274297a3b0SGarrett D'Amore /* XXX: need to be implemented */
1284297a3b0SGarrett D'Amore ret = "";
1294297a3b0SGarrett D'Amore break;
1304297a3b0SGarrett D'Amore case ALT_DIGITS:
1314297a3b0SGarrett D'Amore /* XXX: need to be implemented */
1324297a3b0SGarrett D'Amore ret = "";
1334297a3b0SGarrett D'Amore break;
1344297a3b0SGarrett D'Amore case RADIXCHAR:
135*2d08521bSGarrett D'Amore ret = (char *)lnum->decimal_point;
1364297a3b0SGarrett D'Amore break;
1374297a3b0SGarrett D'Amore case THOUSEP:
138*2d08521bSGarrett D'Amore ret = (char *)lnum->thousands_sep;
1394297a3b0SGarrett D'Amore break;
1404297a3b0SGarrett D'Amore case YESEXPR:
141*2d08521bSGarrett D'Amore ret = (char *)lmsgs->yesexpr;
1424297a3b0SGarrett D'Amore break;
1434297a3b0SGarrett D'Amore case NOEXPR:
144*2d08521bSGarrett D'Amore ret = (char *)lmsgs->noexpr;
1454297a3b0SGarrett D'Amore break;
1464297a3b0SGarrett D'Amore /*
147*2d08521bSGarrett D'Amore * YESSTR and NOSTR items were removed from Issue 7. But
148*2d08521bSGarrett D'Amore * older applications might still need them. Their use is
149*2d08521bSGarrett D'Amore * discouraged.
1504297a3b0SGarrett D'Amore */
1514297a3b0SGarrett D'Amore case YESSTR: /* LEGACY */
152*2d08521bSGarrett D'Amore ret = (char *)lmsgs->yesstr;
1534297a3b0SGarrett D'Amore break;
1544297a3b0SGarrett D'Amore case NOSTR: /* LEGACY */
155*2d08521bSGarrett D'Amore ret = (char *)lmsgs->nostr;
1564297a3b0SGarrett D'Amore break;
1574297a3b0SGarrett D'Amore /*
1584297a3b0SGarrett D'Amore * SUSv2 special formatted currency string
1594297a3b0SGarrett D'Amore */
1604297a3b0SGarrett D'Amore case CRNCYSTR:
161*2d08521bSGarrett D'Amore ret = lmon->crncystr;
1624297a3b0SGarrett D'Amore break;
163*2d08521bSGarrett D'Amore
1644297a3b0SGarrett D'Amore case _DATE_FMT: /* Solaris specific extension */
165*2d08521bSGarrett D'Amore ret = (char *)ltime->date_fmt;
1664297a3b0SGarrett D'Amore break;
1674297a3b0SGarrett D'Amore /*
1684297a3b0SGarrett D'Amore * Note that FreeBSD also had a private D_MD_ORDER, but that appears
1694297a3b0SGarrett D'Amore * to have been specific to FreeBSD, so we have not included it here.
1704297a3b0SGarrett D'Amore */
1714297a3b0SGarrett D'Amore default:
1724297a3b0SGarrett D'Amore ret = "";
1734297a3b0SGarrett D'Amore }
1744297a3b0SGarrett D'Amore return (ret);
1754297a3b0SGarrett D'Amore }
176*2d08521bSGarrett D'Amore
177*2d08521bSGarrett D'Amore char *
nl_langinfo(nl_item item)178*2d08521bSGarrett D'Amore nl_langinfo(nl_item item)
179*2d08521bSGarrett D'Amore {
180*2d08521bSGarrett D'Amore return (nl_langinfo_l(item, uselocale(NULL)));
181*2d08521bSGarrett D'Amore }
182