1 /*- 2 * Copyright (c) 2001 Alexey Zelkin 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <locale.h> 30 #include <langinfo.h> 31 #include <limits.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include "../stdtime/timelocal.h" 35 #include "lnumeric.h" 36 #include "lmonetary.h" 37 #include "lmessages.h" 38 39 #define TRANSITION_PERIOD_HACK 40 41 #define _REL(BASE) ((int)item-BASE) 42 43 char * 44 nl_langinfo(nl_item item) { 45 46 char *ret, *s, *cs; 47 static char *csym = NULL; 48 #ifdef TRANSITION_PERIOD_HACK 49 static char *cset = NULL; 50 #endif /* TRANSITION_PERIOD_HACK */ 51 52 switch (item) { 53 case CODESET: 54 ret = ""; 55 if ((s = setlocale(LC_CTYPE, NULL)) != NULL) { 56 if ((cs = strchr(s, '.')) != NULL) { 57 ret = cs + 1; 58 #ifdef TRANSITION_PERIOD_HACK 59 if (strncmp(ret, "ISO_", 4) == 0) { 60 int slen = strlen(ret); 61 62 if ((cset = reallocf(cset, slen)) != NULL) { 63 strcpy(cset, "ISO"); 64 strcat(cset, ret + 4); 65 ret = cset; 66 } else 67 ret = ""; 68 } else if (strcmp(ret, "EUC") == 0) { 69 if (strncmp(s, "ja_JP", 5) == 0) 70 ret = "eucJP"; 71 else if (strncmp(s, "ko_KR", 5) == 0) 72 ret = "eucKR"; 73 else if (strncmp(s, "zh_CN", 5) == 0) 74 ret = "eucCN"; 75 } else if (strcmp(ret, "ASCII") == 0) 76 ret = "US-ASCII"; 77 #endif /* TRANSITION_PERIOD_HACK */ 78 } else if (strcmp(s, "C") == 0 || 79 strcmp(s, "POSIX") == 0 80 #ifdef TRANSITION_PERIOD_HACK 81 || strstr(s, "ASCII") != NULL 82 #endif /* TRANSITION_PERIOD_HACK */ 83 ) 84 ret = "US-ASCII"; 85 } 86 break; 87 case D_T_FMT: 88 ret = (char *) __get_current_time_locale()->c_fmt; 89 break; 90 case D_FMT: 91 ret = (char *) __get_current_time_locale()->x_fmt; 92 break; 93 case T_FMT: 94 ret = (char *) __get_current_time_locale()->X_fmt; 95 break; 96 case T_FMT_AMPM: 97 ret = (char *) __get_current_time_locale()->ampm_fmt; 98 break; 99 case AM_STR: 100 ret = (char *) __get_current_time_locale()->am; 101 break; 102 case PM_STR: 103 ret = (char *) __get_current_time_locale()->pm; 104 break; 105 case DAY_1: case DAY_2: case DAY_3: 106 case DAY_4: case DAY_5: case DAY_6: case DAY_7: 107 ret = (char*) __get_current_time_locale()->weekday[_REL(DAY_1)]; 108 break; 109 case ABDAY_1: case ABDAY_2: case ABDAY_3: 110 case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7: 111 ret = (char*) __get_current_time_locale()->wday[_REL(ABDAY_1)]; 112 break; 113 case MON_1: case MON_2: case MON_3: case MON_4: 114 case MON_5: case MON_6: case MON_7: case MON_8: 115 case MON_9: case MON_10: case MON_11: case MON_12: 116 ret = (char*) __get_current_time_locale()->month[_REL(MON_1)]; 117 break; 118 case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4: 119 case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8: 120 case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12: 121 ret = (char*) __get_current_time_locale()->mon[_REL(ABMON_1)]; 122 break; 123 case ERA: 124 /* XXX: need to be implemented */ 125 ret = ""; 126 break; 127 case ERA_D_FMT: 128 /* XXX: need to be implemented */ 129 ret = ""; 130 break; 131 case ERA_D_T_FMT: 132 /* XXX: need to be implemented */ 133 ret = ""; 134 break; 135 case ERA_T_FMT: 136 /* XXX: need to be implemented */ 137 ret = ""; 138 break; 139 case ALT_DIGITS: 140 /* XXX: need to be implemented */ 141 ret = ""; 142 break; 143 case RADIXCHAR: 144 ret = (char*) __get_current_numeric_locale()->decimal_point; 145 break; 146 case THOUSEP: 147 ret = (char*) __get_current_numeric_locale()->thousands_sep; 148 break; 149 case YESEXPR: 150 ret = (char*) __get_current_messages_locale()->yesexpr; 151 break; 152 case NOEXPR: 153 ret = (char*) __get_current_messages_locale()->noexpr; 154 break; 155 /* All items marked with LEGACY are available, but not recomended 156 * by SUSv2 to be used in portable applications since they're subject 157 * to remove in future specification editions 158 */ 159 case YESSTR: /* LEGACY */ 160 ret = (char*) __get_current_messages_locale()->yesstr; 161 break; 162 case NOSTR: /* LEGACY */ 163 ret = (char*) __get_current_messages_locale()->nostr; 164 break; 165 case CRNCYSTR: 166 ret = ""; 167 cs = (char*) __get_current_monetary_locale()->currency_symbol; 168 if (*cs != '\0') { 169 char pos = localeconv()->p_cs_precedes; 170 171 if (pos == localeconv()->n_cs_precedes) { 172 char psn = '\0'; 173 174 if (pos == CHAR_MAX) { 175 if (strcmp(cs, __get_current_monetary_locale()->mon_decimal_point) == 0) 176 psn = '.'; 177 } else 178 psn = pos ? '-' : '+'; 179 if (psn != '\0') { 180 int clen = strlen(cs); 181 182 if ((csym = reallocf(csym, clen + 2)) != NULL) { 183 *csym = psn; 184 strcpy(csym + 1, cs); 185 ret = csym; 186 } 187 } 188 } 189 } 190 break; 191 case D_MD_ORDER: /* local extension */ 192 ret = (char *) __get_current_time_locale()->md_order; 193 break; 194 default: 195 ret = ""; 196 } 197 return (ret); 198 } 199