nl_langinfo.c revision 290494
1336815Sdim/*- 2336815Sdim * Copyright (c) 2001, 2003 Alexey Zelkin <phantom@FreeBSD.org> 3336815Sdim * All rights reserved. 4336815Sdim * 5336815Sdim * Copyright (c) 2011 The FreeBSD Foundation 6336815Sdim * All rights reserved. 7336815Sdim * Portions of this software were developed by David Chisnall 8336815Sdim * under sponsorship from the FreeBSD Foundation. 9336815Sdim * 10336815Sdim * Redistribution and use in source and binary forms, with or without 11336815Sdim * modification, are permitted provided that the following conditions 12336815Sdim * are met: 13336815Sdim * 1. Redistributions of source code must retain the above copyright 14336815Sdim * notice, this list of conditions and the following disclaimer. 15336815Sdim * 2. Redistributions in binary form must reproduce the above copyright 16336815Sdim * notice, this list of conditions and the following disclaimer in the 17336815Sdim * documentation and/or other materials provided with the distribution. 18336815Sdim * 19336815Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20336815Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21336815Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22336815Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23336815Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24336815Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25336815Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26336815Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27336815Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28336815Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29336815Sdim * SUCH DAMAGE. 30336815Sdim */ 31336815Sdim 32336815Sdim#include <sys/cdefs.h> 33336815Sdim__FBSDID("$FreeBSD: head/lib/libc/locale/nl_langinfo.c 290494 2015-11-07 12:43:35Z bapt $"); 34336815Sdim 35336815Sdim#include <langinfo.h> 36336815Sdim#include <limits.h> 37336815Sdim#include <locale.h> 38336815Sdim#include <stdlib.h> 39336815Sdim#include <string.h> 40336815Sdim#include <runetype.h> 41336815Sdim#include <wchar.h> 42336815Sdim 43336815Sdim#include "mblocal.h" 44336815Sdim#include "lnumeric.h" 45336815Sdim#include "lmessages.h" 46336815Sdim#include "lmonetary.h" 47336815Sdim#include "../stdtime/timelocal.h" 48336815Sdim 49336815Sdim#define _REL(BASE) ((int)item-BASE) 50336815Sdim 51336815Sdimchar * 52336815Sdimnl_langinfo_l(nl_item item, locale_t loc) 53336815Sdim{ 54336815Sdim char *ret, *cs; 55336815Sdim const char *s; 56336815Sdim FIX_LOCALE(loc); 57336815Sdim 58336815Sdim switch (item) { 59336815Sdim case CODESET: 60336815Sdim s = XLOCALE_CTYPE(loc)->runes->__encoding; 61336815Sdim if (strcmp(s, "EUC-CN") == 0) 62336815Sdim ret = "eucCN"; 63336815Sdim else if (strcmp(s, "EUC-JP") == 0) 64336815Sdim ret = "eucJP"; 65336815Sdim else if (strcmp(s, "EUC-KR") == 0) 66336815Sdim ret = "eucKR"; 67336815Sdim else if (strcmp(s, "EUC-TW") == 0) 68336815Sdim ret = "eucTW"; 69336815Sdim else if (strcmp(s, "BIG5") == 0) 70336815Sdim ret = "Big5"; 71336815Sdim else if (strcmp(s, "MSKanji") == 0) 72336815Sdim ret = "SJIS"; 73336815Sdim else if (strcmp(s, "NONE") == 0) 74336815Sdim ret = "US-ASCII"; 75336815Sdim else if (strncmp(s, "NONE:", 5) == 0) 76336815Sdim ret = (char *)(s + 5); 77336815Sdim else 78336815Sdim ret = (char *)s; 79336815Sdim break; 80336815Sdim case D_T_FMT: 81336815Sdim ret = (char *) __get_current_time_locale(loc)->c_fmt; 82336815Sdim break; 83336815Sdim case D_FMT: 84336815Sdim ret = (char *) __get_current_time_locale(loc)->x_fmt; 85336815Sdim break; 86336815Sdim case T_FMT: 87336815Sdim ret = (char *) __get_current_time_locale(loc)->X_fmt; 88336815Sdim break; 89336815Sdim case T_FMT_AMPM: 90336815Sdim ret = (char *) __get_current_time_locale(loc)->ampm_fmt; 91336815Sdim break; 92336815Sdim case AM_STR: 93336815Sdim ret = (char *) __get_current_time_locale(loc)->am; 94336815Sdim break; 95336815Sdim case PM_STR: 96336815Sdim ret = (char *) __get_current_time_locale(loc)->pm; 97336815Sdim break; 98336815Sdim case DAY_1: case DAY_2: case DAY_3: 99336815Sdim case DAY_4: case DAY_5: case DAY_6: case DAY_7: 100336815Sdim ret = (char*) __get_current_time_locale(loc)->weekday[_REL(DAY_1)]; 101336815Sdim break; 102336815Sdim case ABDAY_1: case ABDAY_2: case ABDAY_3: 103336815Sdim case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7: 104336815Sdim ret = (char*) __get_current_time_locale(loc)->wday[_REL(ABDAY_1)]; 105336815Sdim break; 106336815Sdim case MON_1: case MON_2: case MON_3: case MON_4: 107336815Sdim case MON_5: case MON_6: case MON_7: case MON_8: 108336815Sdim case MON_9: case MON_10: case MON_11: case MON_12: 109336815Sdim ret = (char*) __get_current_time_locale(loc)->month[_REL(MON_1)]; 110336815Sdim break; 111336815Sdim case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4: 112336815Sdim case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8: 113336815Sdim case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12: 114336815Sdim ret = (char*) __get_current_time_locale(loc)->mon[_REL(ABMON_1)]; 115336815Sdim break; 116336815Sdim case ALTMON_1: case ALTMON_2: case ALTMON_3: case ALTMON_4: 117336815Sdim case ALTMON_5: case ALTMON_6: case ALTMON_7: case ALTMON_8: 118336815Sdim case ALTMON_9: case ALTMON_10: case ALTMON_11: case ALTMON_12: 119336815Sdim ret = (char*) 120336815Sdim __get_current_time_locale(loc)->alt_month[_REL(ALTMON_1)]; 121336815Sdim break; 122336815Sdim case ERA: 123336815Sdim /* XXX: need to be implemented */ 124336815Sdim ret = ""; 125336815Sdim break; 126336815Sdim case ERA_D_FMT: 127336815Sdim /* XXX: need to be implemented */ 128336815Sdim ret = ""; 129336815Sdim break; 130336815Sdim case ERA_D_T_FMT: 131336815Sdim /* XXX: need to be implemented */ 132336815Sdim ret = ""; 133336815Sdim break; 134344779Sdim case ERA_T_FMT: 135336815Sdim /* XXX: need to be implemented */ 136336815Sdim ret = ""; 137336815Sdim break; 138336815Sdim case ALT_DIGITS: 139336815Sdim /* XXX: need to be implemented */ 140336815Sdim ret = ""; 141336815Sdim break; 142336815Sdim case RADIXCHAR: 143336815Sdim ret = (char*) __get_current_numeric_locale(loc)->decimal_point; 144336815Sdim break; 145336815Sdim case THOUSEP: 146336815Sdim ret = (char*) __get_current_numeric_locale(loc)->thousands_sep; 147336815Sdim break; 148336815Sdim case YESEXPR: 149336815Sdim ret = (char*) __get_current_messages_locale(loc)->yesexpr; 150336815Sdim break; 151336815Sdim case NOEXPR: 152336815Sdim ret = (char*) __get_current_messages_locale(loc)->noexpr; 153336815Sdim break; 154336815Sdim /* 155336815Sdim * YESSTR and NOSTR items marked with LEGACY are available, but not 156336815Sdim * recomended by SUSv2 to be used in portable applications since 157336815Sdim * they're subject to remove in future specification editions. 158336815Sdim */ 159336815Sdim case YESSTR: /* LEGACY */ 160336815Sdim ret = (char*) __get_current_messages_locale(loc)->yesstr; 161336815Sdim break; 162336815Sdim case NOSTR: /* LEGACY */ 163336815Sdim ret = (char*) __get_current_messages_locale(loc)->nostr; 164336815Sdim break; 165336815Sdim /* 166336815Sdim * SUSv2 special formatted currency string 167336815Sdim */ 168336815Sdim case CRNCYSTR: 169336815Sdim ret = ""; 170336815Sdim cs = (char*) __get_current_monetary_locale(loc)->currency_symbol; 171336815Sdim if (*cs != '\0') { 172336815Sdim char pos = localeconv_l(loc)->p_cs_precedes; 173336815Sdim 174336815Sdim if (pos == localeconv_l(loc)->n_cs_precedes) { 175336815Sdim char psn = '\0'; 176336815Sdim 177336815Sdim if (pos == CHAR_MAX) { 178336815Sdim if (strcmp(cs, __get_current_monetary_locale(loc)->mon_decimal_point) == 0) 179336815Sdim psn = '.'; 180336815Sdim } else 181336815Sdim psn = pos ? '-' : '+'; 182336815Sdim if (psn != '\0') { 183336815Sdim int clen = strlen(cs); 184336815Sdim 185336815Sdim if ((loc->csym = reallocf(loc->csym, clen + 2)) != NULL) { 186336815Sdim *loc->csym = psn; 187336815Sdim strcpy(loc->csym + 1, cs); 188336815Sdim ret = loc->csym; 189336815Sdim } 190336815Sdim } 191336815Sdim } 192336815Sdim } 193336815Sdim break; 194336815Sdim case D_MD_ORDER: /* FreeBSD local extension */ 195336815Sdim ret = (char *) __get_current_time_locale(loc)->md_order; 196336815Sdim break; 197336815Sdim default: 198336815Sdim ret = ""; 199336815Sdim } 200336815Sdim return (ret); 201336815Sdim} 202336815Sdim 203336815Sdimchar * 204336815Sdimnl_langinfo(nl_item item) 205336815Sdim{ 206336815Sdim return nl_langinfo_l(item, __get_locale()); 207336815Sdim} 208336815Sdim