Home | History | Annotate | Line # | Download | only in locale
      1 /* $NetBSD: nl_langinfo.c,v 1.18 2017/01/10 17:50:24 christos Exp $ */
      2 
      3 /*-
      4  * Copyright (c)2008 Citrus Project,
      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 <sys/cdefs.h>
     30 __RCSID("$NetBSD: nl_langinfo.c,v 1.18 2017/01/10 17:50:24 christos Exp $");
     31 
     32 #include "namespace.h"
     33 #include <sys/types.h>
     34 #include <sys/localedef.h>
     35 #include <langinfo.h>
     36 #include <stddef.h>
     37 #define __SETLOCALE_SOURCE__
     38 #include <locale.h>
     39 #include <stdlib.h>
     40 #include <string.h>
     41 
     42 #include "runetype_local.h"
     43 #include "setlocale_local.h"
     44 
     45 static const char langinfo_category[] = {
     46     [ D_T_FMT ] = LC_TIME,
     47     [ D_FMT ] = LC_TIME,
     48     [ T_FMT ] = LC_TIME,
     49     [ T_FMT_AMPM ] = LC_TIME,
     50     [ AM_STR ] = LC_TIME,
     51     [ PM_STR ] = LC_TIME,
     52     [ DAY_1 ] = LC_TIME,
     53     [ DAY_2 ] = LC_TIME,
     54     [ DAY_3 ] = LC_TIME,
     55     [ DAY_4 ] = LC_TIME,
     56     [ DAY_5 ] = LC_TIME,
     57     [ DAY_6 ] = LC_TIME,
     58     [ DAY_7 ] = LC_TIME,
     59     [ ABDAY_1 ] = LC_TIME,
     60     [ ABDAY_2 ] = LC_TIME,
     61     [ ABDAY_3 ] = LC_TIME,
     62     [ ABDAY_4 ] = LC_TIME,
     63     [ ABDAY_5 ] = LC_TIME,
     64     [ ABDAY_6 ] = LC_TIME,
     65     [ ABDAY_7 ] = LC_TIME,
     66     [ MON_1 ] = LC_TIME,
     67     [ MON_2 ] = LC_TIME,
     68     [ MON_3 ] = LC_TIME,
     69     [ MON_4 ] = LC_TIME,
     70     [ MON_5 ] = LC_TIME,
     71     [ MON_6 ] = LC_TIME,
     72     [ MON_7 ] = LC_TIME,
     73     [ MON_8 ] = LC_TIME,
     74     [ MON_9 ] = LC_TIME,
     75     [ MON_10 ] = LC_TIME,
     76     [ MON_11 ] = LC_TIME,
     77     [ MON_12 ] = LC_TIME,
     78     [ ABMON_1 ] = LC_TIME,
     79     [ ABMON_2 ] = LC_TIME,
     80     [ ABMON_3 ] = LC_TIME,
     81     [ ABMON_4 ] = LC_TIME,
     82     [ ABMON_5 ] = LC_TIME,
     83     [ ABMON_6 ] = LC_TIME,
     84     [ ABMON_7 ] = LC_TIME,
     85     [ ABMON_8 ] = LC_TIME,
     86     [ ABMON_9 ] = LC_TIME,
     87     [ ABMON_10 ] = LC_TIME,
     88     [ ABMON_11 ] = LC_TIME,
     89     [ ABMON_12 ] = LC_TIME,
     90     [ RADIXCHAR ] = LC_NUMERIC,
     91     [ THOUSEP ] = LC_NUMERIC,
     92     [ YESSTR ] = LC_MESSAGES,
     93     [ YESEXPR ] = LC_MESSAGES,
     94     [ NOSTR ] = LC_MESSAGES,
     95     [ NOEXPR ] = LC_MESSAGES,
     96     [ CRNCYSTR ] = 0,
     97     [ CODESET ] = LC_CTYPE,
     98     [ ERA ] = 0,
     99     [ ERA_D_FMT ] = 0,
    100     [ ERA_D_T_FMT ] = 0,
    101     [ ERA_T_FMT ] = 0,
    102     [ ALT_DIGITS ] = 0,
    103 };
    104 
    105 #define offsetofu16(a, b) ((uint16_t)offsetof(a, b))
    106 
    107 static const uint16_t langinfo_offset[] = {
    108     [ D_T_FMT ] = offsetofu16(_TimeLocale, d_t_fmt),
    109     [ D_FMT ] = offsetofu16(_TimeLocale, d_fmt),
    110     [ T_FMT ] = offsetofu16(_TimeLocale, t_fmt),
    111     [ T_FMT_AMPM ] = offsetofu16(_TimeLocale, t_fmt_ampm),
    112     [ AM_STR ] = offsetofu16(_TimeLocale, am_pm[0]),
    113     [ PM_STR ] = offsetofu16(_TimeLocale, am_pm[1]),
    114     [ DAY_1 ] = offsetofu16(_TimeLocale, day[0]),
    115     [ DAY_2 ] = offsetofu16(_TimeLocale, day[1]),
    116     [ DAY_3 ] = offsetofu16(_TimeLocale, day[2]),
    117     [ DAY_4 ] = offsetofu16(_TimeLocale, day[3]),
    118     [ DAY_5 ] = offsetofu16(_TimeLocale, day[4]),
    119     [ DAY_6 ] = offsetofu16(_TimeLocale, day[5]),
    120     [ DAY_7 ] = offsetofu16(_TimeLocale, day[6]),
    121     [ ABDAY_1 ] = offsetofu16(_TimeLocale, abday[0]),
    122     [ ABDAY_2 ] = offsetofu16(_TimeLocale, abday[1]),
    123     [ ABDAY_3 ] = offsetofu16(_TimeLocale, abday[2]),
    124     [ ABDAY_4 ] = offsetofu16(_TimeLocale, abday[3]),
    125     [ ABDAY_5 ] = offsetofu16(_TimeLocale, abday[4]),
    126     [ ABDAY_6 ] = offsetofu16(_TimeLocale, abday[5]),
    127     [ ABDAY_7 ] = offsetofu16(_TimeLocale, abday[6]),
    128     [ MON_1 ] = offsetofu16(_TimeLocale, mon[0]),
    129     [ MON_2 ] = offsetofu16(_TimeLocale, mon[1]),
    130     [ MON_3 ] = offsetofu16(_TimeLocale, mon[2]),
    131     [ MON_4 ] = offsetofu16(_TimeLocale, mon[3]),
    132     [ MON_5 ] = offsetofu16(_TimeLocale, mon[4]),
    133     [ MON_6 ] = offsetofu16(_TimeLocale, mon[5]),
    134     [ MON_7 ] = offsetofu16(_TimeLocale, mon[6]),
    135     [ MON_8 ] = offsetofu16(_TimeLocale, mon[7]),
    136     [ MON_9 ] = offsetofu16(_TimeLocale, mon[8]),
    137     [ MON_10 ] = offsetofu16(_TimeLocale, mon[9]),
    138     [ MON_11 ] = offsetofu16(_TimeLocale, mon[10]),
    139     [ MON_12 ] = offsetofu16(_TimeLocale, mon[11]),
    140     [ ABMON_1 ] = offsetofu16(_TimeLocale, abmon[0]),
    141     [ ABMON_2 ] = offsetofu16(_TimeLocale, abmon[1]),
    142     [ ABMON_3 ] = offsetofu16(_TimeLocale, abmon[2]),
    143     [ ABMON_4 ] = offsetofu16(_TimeLocale, abmon[3]),
    144     [ ABMON_5 ] = offsetofu16(_TimeLocale, abmon[4]),
    145     [ ABMON_6 ] = offsetofu16(_TimeLocale, abmon[5]),
    146     [ ABMON_7 ] = offsetofu16(_TimeLocale, abmon[6]),
    147     [ ABMON_8 ] = offsetofu16(_TimeLocale, abmon[7]),
    148     [ ABMON_9 ] = offsetofu16(_TimeLocale, abmon[8]),
    149     [ ABMON_10 ] = offsetofu16(_TimeLocale, abmon[9]),
    150     [ ABMON_11 ] = offsetofu16(_TimeLocale, abmon[10]),
    151     [ ABMON_12 ] = offsetofu16(_TimeLocale, abmon[11]),
    152     [ RADIXCHAR ] = offsetofu16(_NumericLocale, decimal_point),
    153     [ THOUSEP ] = offsetofu16(_NumericLocale, thousands_sep),
    154     [ YESSTR ] = offsetofu16(_MessagesLocale, yesstr),
    155     [ YESEXPR ] = offsetofu16(_MessagesLocale, yesexpr),
    156     [ NOSTR ] = offsetofu16(_MessagesLocale, nostr),
    157     [ NOEXPR ] = offsetofu16(_MessagesLocale, noexpr),
    158     [ CRNCYSTR ] = 0,
    159     [ CODESET ] = offsetofu16(_RuneLocale, rl_codeset),
    160     [ ERA ] = 0,
    161     [ ERA_D_FMT ] = 0,
    162     [ ERA_D_T_FMT ] = 0,
    163     [ ERA_T_FMT ] = 0,
    164     [ ALT_DIGITS ] = 0,
    165 };
    166 
    167 __weak_alias(nl_langinfo_l, _nl_langinfo_l)
    168 
    169 char *
    170 nl_langinfo(nl_item item)
    171 {
    172 
    173 	return nl_langinfo_l(item, _current_locale());
    174 }
    175 
    176 char *
    177 nl_langinfo_l(nl_item item, locale_t loc)
    178 {
    179 	char *s;
    180 	int category;
    181 	size_t offset;
    182 
    183 	if (item < 0 || item >= (long)__arraycount(langinfo_category))
    184 		return __UNCONST(""); /* Outside the defined range */
    185 
    186 	category = langinfo_category[item];
    187 	if (category == 0)
    188 		return __UNCONST(""); /* Not in use */
    189 	offset = langinfo_offset[item];
    190 
    191 	memcpy(&s, (char *)loc->part_impl[category] + offset, sizeof(s));
    192 	if (s == NULL)
    193 		return __UNCONST("");
    194 	else
    195 		return s;
    196 }
    197