1 /* 2 * Copyright 2013 Garrett D'Amore <garrett@damore.org> 3 * Copyright 2010 Nexenta Systems, Inc. All rights reserved. 4 * Copyright (c) 2001, 2003 Alexey Zelkin <phantom@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include "lint.h" 30 #include <langinfo.h> 31 #include <limits.h> 32 #include <locale.h> 33 #include <stdlib.h> 34 #include <string.h> 35 36 #include "lnumeric.h" 37 #include "lmessages.h" 38 #include "lmonetary.h" 39 #include "timelocal.h" 40 #include "localeimpl.h" 41 42 #define _REL(BASE) ((int)item-BASE) 43 44 #pragma weak _nl_langinfo = nl_langinfo 45 46 char * 47 nl_langinfo_l(nl_item item, locale_t loc) 48 { 49 char *ret, *s, *cs; 50 struct locdata *ldata; 51 const struct lc_monetary *lmon = loc->monetary; 52 const struct lc_numeric *lnum = loc->numeric; 53 const struct lc_messages *lmsgs = loc->messages; 54 const struct lc_time *ltime = loc->time; 55 56 switch (item) { 57 case CODESET: 58 ret = ""; 59 /* 60 * The codeset is the suffix of a locale, for most it will 61 * will be UTF-8, as in "en_US.UTF-8". Short form locales are 62 * not supported. Note also that although FreeBSD uses 63 * US-ASCII, Solaris historically has reported "646" for the 64 * C locale. 65 * 66 * Note that this code will need to change if we ever support 67 * POSIX defined locale variants (suffixes with an @ sign) 68 */ 69 ldata = loc->locdata[LC_CTYPE]; 70 s = ldata ? ldata->l_lname : NULL; 71 if (s != NULL) { 72 if ((cs = strchr(s, '.')) != NULL) 73 ret = cs + 1; 74 else if (strcmp(s, "C") == 0 || strcmp(s, "POSIX") == 0) 75 ret = "646"; 76 } 77 break; 78 case D_T_FMT: 79 ret = (char *)ltime->c_fmt; 80 break; 81 case D_FMT: 82 ret = (char *)ltime->x_fmt; 83 break; 84 case T_FMT: 85 ret = (char *)ltime->X_fmt; 86 break; 87 case T_FMT_AMPM: 88 ret = (char *)ltime->ampm_fmt; 89 break; 90 case AM_STR: 91 ret = (char *)ltime->am; 92 break; 93 case PM_STR: 94 ret = (char *)ltime->pm; 95 break; 96 case DAY_1: case DAY_2: case DAY_3: 97 case DAY_4: case DAY_5: case DAY_6: case DAY_7: 98 ret = (char *)ltime->weekday[_REL(DAY_1)]; 99 break; 100 case ABDAY_1: case ABDAY_2: case ABDAY_3: 101 case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7: 102 ret = (char *)ltime->wday[_REL(ABDAY_1)]; 103 break; 104 case MON_1: case MON_2: case MON_3: case MON_4: 105 case MON_5: case MON_6: case MON_7: case MON_8: 106 case MON_9: case MON_10: case MON_11: case MON_12: 107 ret = (char *)ltime->month[_REL(MON_1)]; 108 break; 109 case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4: 110 case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8: 111 case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12: 112 ret = (char *)ltime->mon[_REL(ABMON_1)]; 113 break; 114 case ERA: 115 /* XXX: need to be implemented */ 116 ret = ""; 117 break; 118 case ERA_D_FMT: 119 /* XXX: need to be implemented */ 120 ret = ""; 121 break; 122 case ERA_D_T_FMT: 123 /* XXX: need to be implemented */ 124 ret = ""; 125 break; 126 case ERA_T_FMT: 127 /* XXX: need to be implemented */ 128 ret = ""; 129 break; 130 case ALT_DIGITS: 131 /* XXX: need to be implemented */ 132 ret = ""; 133 break; 134 case RADIXCHAR: 135 ret = (char *)lnum->decimal_point; 136 break; 137 case THOUSEP: 138 ret = (char *)lnum->thousands_sep; 139 break; 140 case YESEXPR: 141 ret = (char *)lmsgs->yesexpr; 142 break; 143 case NOEXPR: 144 ret = (char *)lmsgs->noexpr; 145 break; 146 /* 147 * YESSTR and NOSTR items were removed from Issue 7. But 148 * older applications might still need them. Their use is 149 * discouraged. 150 */ 151 case YESSTR: /* LEGACY */ 152 ret = (char *)lmsgs->yesstr; 153 break; 154 case NOSTR: /* LEGACY */ 155 ret = (char *)lmsgs->nostr; 156 break; 157 /* 158 * SUSv2 special formatted currency string 159 */ 160 case CRNCYSTR: 161 ret = lmon->crncystr; 162 break; 163 164 case _DATE_FMT: /* Solaris specific extension */ 165 ret = (char *)ltime->date_fmt; 166 break; 167 /* 168 * Note that FreeBSD also had a private D_MD_ORDER, but that appears 169 * to have been specific to FreeBSD, so we have not included it here. 170 */ 171 default: 172 ret = ""; 173 } 174 return (ret); 175 } 176 177 char * 178 nl_langinfo(nl_item item) 179 { 180 return (nl_langinfo_l(item, uselocale(NULL))); 181 }