Implement missing POSIX function nl_langinfo_l
Change nl_langinfo to nl_langinfo_l using locale given as argument. Remove outdated TRANSITION_PERIOD_HACK. The codeset is stored in the locale for quite some time now. For !MB_CAPABLE targets, just return "US_ASCII" as codeset. Implement nl_langinfo by calling nl_langinfo_l. Export nl_langinfo_l from Cygwin DLL and bump minor API version number. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
7630e38462
commit
216054fa77
|
@ -32,6 +32,9 @@
|
||||||
#include <newlib.h>
|
#include <newlib.h>
|
||||||
#include <sys/config.h>
|
#include <sys/config.h>
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
#if __POSIX_VISIBLE >= 200809
|
||||||
|
#include <sys/_locale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef int nl_item;
|
typedef int nl_item;
|
||||||
|
|
||||||
|
@ -310,7 +313,10 @@ enum __nl_item
|
||||||
};
|
};
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
char *nl_langinfo(nl_item);
|
char *nl_langinfo (nl_item);
|
||||||
|
#if __POSIX_VISIBLE >= 200809
|
||||||
|
char *nl_langinfo_l (nl_item, locale_t);
|
||||||
|
#endif
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
#endif /* !_LANGINFO_H_ */
|
#endif /* !_LANGINFO_H_ */
|
||||||
|
|
|
@ -34,26 +34,22 @@
|
||||||
|
|
||||||
#include "setlocale.h"
|
#include "setlocale.h"
|
||||||
|
|
||||||
#ifndef __CYGWIN__
|
|
||||||
#define TRANSITION_PERIOD_HACK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef offsetoff
|
#undef offsetoff
|
||||||
#define _O(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
|
#define _O(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
|
||||||
|
|
||||||
#define _NLITEM(cat,memb) { { cat:__get_current_##cat##_locale }, \
|
#define _NLITEM(cat,memb) { { cat:__get_##cat##_locale }, \
|
||||||
_O (struct lc_##cat##_T, memb) }
|
_O (struct lc_##cat##_T, memb) }
|
||||||
|
|
||||||
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
|
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
|
||||||
static struct _nl_item_t
|
static struct _nl_item_t
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
const struct lc_ctype_T * (*ctype)(void);
|
const struct lc_ctype_T * (*ctype)(struct __locale_t *);
|
||||||
const struct lc_time_T * (*time)(void);
|
const struct lc_time_T * (*time)(struct __locale_t *);
|
||||||
const struct lc_numeric_T * (*numeric)(void);
|
const struct lc_numeric_T * (*numeric)(struct __locale_t *);
|
||||||
const struct lc_monetary_T * (*monetary)(void);
|
const struct lc_monetary_T * (*monetary)(struct __locale_t *);
|
||||||
const struct lc_messages_T * (*messages)(void);
|
const struct lc_messages_T * (*messages)(struct __locale_t *);
|
||||||
void * (*base)(void);
|
void * (*base)(struct __locale_t *);
|
||||||
};
|
};
|
||||||
_off_t offset;
|
_off_t offset;
|
||||||
} nl_ext[] =
|
} nl_ext[] =
|
||||||
|
@ -172,47 +168,42 @@ static struct _nl_item_t
|
||||||
|
|
||||||
#define _REL(BASE) ((int)item-BASE)
|
#define _REL(BASE) ((int)item-BASE)
|
||||||
|
|
||||||
char *
|
char *nl_langinfo_l (nl_item item, struct __locale_t *locale)
|
||||||
_DEFUN(nl_langinfo, (item),
|
|
||||||
nl_item item)
|
|
||||||
{
|
{
|
||||||
char *ret, *cs;
|
char *ret, *cs;
|
||||||
#ifndef __CYGWIN__
|
#ifndef __CYGWIN__
|
||||||
char *s;
|
char *s;
|
||||||
#endif
|
#endif
|
||||||
static char *csym = NULL;
|
static char *csym = NULL;
|
||||||
#ifdef TRANSITION_PERIOD_HACK
|
|
||||||
static char *cset = NULL;
|
|
||||||
#endif /* TRANSITION_PERIOD_HACK */
|
|
||||||
char *nptr;
|
char *nptr;
|
||||||
|
|
||||||
switch (item) {
|
switch (item) {
|
||||||
#ifdef __HAVE_LOCALE_INFO__
|
#ifdef __HAVE_LOCALE_INFO__
|
||||||
case _NL_MESSAGES_CODESET:
|
case _NL_MESSAGES_CODESET:
|
||||||
ret = (char *) __get_current_messages_locale ()->codeset;
|
ret = (char *) __get_messages_locale (locale)->codeset;
|
||||||
goto do_codeset;
|
goto do_codeset;
|
||||||
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
|
#ifdef __HAVE_LOCALE_INFO_EXTENDED__
|
||||||
case _NL_TIME_CODESET:
|
case _NL_TIME_CODESET:
|
||||||
ret = (char *) __get_current_time_locale ()->codeset;
|
ret = (char *) __get_time_locale (locale)->codeset;
|
||||||
goto do_codeset;
|
goto do_codeset;
|
||||||
case _NL_NUMERIC_CODESET:
|
case _NL_NUMERIC_CODESET:
|
||||||
ret = (char *) __get_current_numeric_locale ()->codeset;
|
ret = (char *) __get_numeric_locale (locale)->codeset;
|
||||||
goto do_codeset;
|
goto do_codeset;
|
||||||
case _NL_MONETARY_CODESET:
|
case _NL_MONETARY_CODESET:
|
||||||
ret = (char *) __get_current_monetary_locale ()->codeset;
|
ret = (char *) __get_monetary_locale (locale)->codeset;
|
||||||
goto do_codeset;
|
goto do_codeset;
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
case _NL_COLLATE_CODESET:
|
case _NL_COLLATE_CODESET:
|
||||||
{
|
{
|
||||||
ret = (char *) __get_current_collate_locale ()->codeset;
|
ret = (char *) __get_collate_locale (locale)->codeset;
|
||||||
goto do_codeset;
|
goto do_codeset;
|
||||||
}
|
}
|
||||||
#endif /* __CYGWIN__ */
|
#endif /* __CYGWIN__ */
|
||||||
#endif /* __HAVE_LOCALE_INFO_EXTENDED__ */
|
#endif /* __HAVE_LOCALE_INFO_EXTENDED__ */
|
||||||
#endif /* __HAVE_LOCALE_INFO__ */
|
#endif /* __HAVE_LOCALE_INFO__ */
|
||||||
case CODESET:
|
case CODESET:
|
||||||
#ifdef __CYGWIN__
|
#ifdef _MB_CAPABLE
|
||||||
ret = (char *) __current_locale_charset ();
|
ret = (char *) __locale_charset (locale);
|
||||||
#endif
|
#endif
|
||||||
do_codeset:
|
do_codeset:
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
|
@ -255,112 +246,75 @@ do_codeset:
|
||||||
fine by libiconv. */
|
fine by libiconv. */
|
||||||
ret = "CP932";
|
ret = "CP932";
|
||||||
}
|
}
|
||||||
#else
|
#elif !defined (_MB_CAPABLE)
|
||||||
ret = "";
|
ret = "US-ASCII";
|
||||||
if ((s = setlocale(LC_CTYPE, NULL)) != NULL) {
|
|
||||||
if ((cs = strchr(s, '.')) != NULL) {
|
|
||||||
ret = cs + 1;
|
|
||||||
#ifdef TRANSITION_PERIOD_HACK
|
|
||||||
if (strncmp(ret, "ISO_", 4) == 0) {
|
|
||||||
int slen = strlen(ret);
|
|
||||||
|
|
||||||
nptr = realloc(cset, slen);
|
|
||||||
|
|
||||||
if (!nptr && cset)
|
|
||||||
free (cset);
|
|
||||||
|
|
||||||
cset = nptr;
|
|
||||||
if (cset != NULL) {
|
|
||||||
strcpy(cset, "ISO");
|
|
||||||
strcat(cset, ret + 4);
|
|
||||||
ret = cset;
|
|
||||||
} else
|
|
||||||
ret = "";
|
|
||||||
} else if (strcmp(ret, "EUC") == 0) {
|
|
||||||
if (strncmp(s, "ja_JP", 5) == 0)
|
|
||||||
ret = "eucJP";
|
|
||||||
else if (strncmp(s, "ko_KR", 5) == 0)
|
|
||||||
ret = "eucKR";
|
|
||||||
else if (strncmp(s, "zh_CN", 5) == 0)
|
|
||||||
ret = "eucCN";
|
|
||||||
} else if (strcmp(ret, "ASCII") == 0)
|
|
||||||
ret = "US-ASCII";
|
|
||||||
#endif /* TRANSITION_PERIOD_HACK */
|
|
||||||
} else if (strcmp(s, "C") == 0 ||
|
|
||||||
strcmp(s, "POSIX") == 0
|
|
||||||
#ifdef TRANSITION_PERIOD_HACK
|
|
||||||
|| strstr(s, "ASCII") != NULL
|
|
||||||
#endif /* TRANSITION_PERIOD_HACK */
|
|
||||||
)
|
|
||||||
ret = "US-ASCII";
|
|
||||||
}
|
|
||||||
#endif /* __CYGWIN__ */
|
#endif /* __CYGWIN__ */
|
||||||
break;
|
break;
|
||||||
case D_T_FMT:
|
case D_T_FMT:
|
||||||
ret = (char *) __get_current_time_locale()->c_fmt;
|
ret = (char *) __get_time_locale (locale)->c_fmt;
|
||||||
break;
|
break;
|
||||||
case D_FMT:
|
case D_FMT:
|
||||||
ret = (char *) __get_current_time_locale()->x_fmt;
|
ret = (char *) __get_time_locale (locale)->x_fmt;
|
||||||
break;
|
break;
|
||||||
case T_FMT:
|
case T_FMT:
|
||||||
ret = (char *) __get_current_time_locale()->X_fmt;
|
ret = (char *) __get_time_locale (locale)->X_fmt;
|
||||||
break;
|
break;
|
||||||
case T_FMT_AMPM:
|
case T_FMT_AMPM:
|
||||||
ret = (char *) __get_current_time_locale()->ampm_fmt;
|
ret = (char *) __get_time_locale (locale)->ampm_fmt;
|
||||||
break;
|
break;
|
||||||
case AM_STR:
|
case AM_STR:
|
||||||
ret = (char *) __get_current_time_locale()->am_pm[0];
|
ret = (char *) __get_time_locale (locale)->am_pm[0];
|
||||||
break;
|
break;
|
||||||
case PM_STR:
|
case PM_STR:
|
||||||
ret = (char *) __get_current_time_locale()->am_pm[1];
|
ret = (char *) __get_time_locale (locale)->am_pm[1];
|
||||||
break;
|
break;
|
||||||
case DAY_1: case DAY_2: case DAY_3:
|
case DAY_1: case DAY_2: case DAY_3:
|
||||||
case DAY_4: case DAY_5: case DAY_6: case DAY_7:
|
case DAY_4: case DAY_5: case DAY_6: case DAY_7:
|
||||||
ret = (char*) __get_current_time_locale()->weekday[_REL(DAY_1)];
|
ret = (char*) __get_time_locale (locale)->weekday[_REL(DAY_1)];
|
||||||
break;
|
break;
|
||||||
case ABDAY_1: case ABDAY_2: case ABDAY_3:
|
case ABDAY_1: case ABDAY_2: case ABDAY_3:
|
||||||
case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7:
|
case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7:
|
||||||
ret = (char*) __get_current_time_locale()->wday[_REL(ABDAY_1)];
|
ret = (char*) __get_time_locale (locale)->wday[_REL(ABDAY_1)];
|
||||||
break;
|
break;
|
||||||
case MON_1: case MON_2: case MON_3: case MON_4:
|
case MON_1: case MON_2: case MON_3: case MON_4:
|
||||||
case MON_5: case MON_6: case MON_7: case MON_8:
|
case MON_5: case MON_6: case MON_7: case MON_8:
|
||||||
case MON_9: case MON_10: case MON_11: case MON_12:
|
case MON_9: case MON_10: case MON_11: case MON_12:
|
||||||
ret = (char*) __get_current_time_locale()->month[_REL(MON_1)];
|
ret = (char*) __get_time_locale (locale)->month[_REL(MON_1)];
|
||||||
break;
|
break;
|
||||||
case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4:
|
case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4:
|
||||||
case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8:
|
case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8:
|
||||||
case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12:
|
case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12:
|
||||||
ret = (char*) __get_current_time_locale()->mon[_REL(ABMON_1)];
|
ret = (char*) __get_time_locale (locale)->mon[_REL(ABMON_1)];
|
||||||
break;
|
break;
|
||||||
case ERA:
|
case ERA:
|
||||||
ret = (char*) __get_current_time_locale()->era;
|
ret = (char*) __get_time_locale (locale)->era;
|
||||||
break;
|
break;
|
||||||
case ERA_D_FMT:
|
case ERA_D_FMT:
|
||||||
ret = (char*) __get_current_time_locale()->era_d_fmt;
|
ret = (char*) __get_time_locale (locale)->era_d_fmt;
|
||||||
break;
|
break;
|
||||||
case ERA_D_T_FMT:
|
case ERA_D_T_FMT:
|
||||||
ret = (char*) __get_current_time_locale()->era_d_t_fmt;
|
ret = (char*) __get_time_locale (locale)->era_d_t_fmt;
|
||||||
break;
|
break;
|
||||||
case ERA_T_FMT:
|
case ERA_T_FMT:
|
||||||
ret = (char*) __get_current_time_locale()->era_t_fmt;
|
ret = (char*) __get_time_locale (locale)->era_t_fmt;
|
||||||
break;
|
break;
|
||||||
case ALT_DIGITS:
|
case ALT_DIGITS:
|
||||||
ret = (char*) __get_current_time_locale()->alt_digits;
|
ret = (char*) __get_time_locale (locale)->alt_digits;
|
||||||
break;
|
break;
|
||||||
case _DATE_FMT: /* GNU extension */
|
case _DATE_FMT: /* GNU extension */
|
||||||
ret = (char*) __get_current_time_locale()->date_fmt;
|
ret = (char*) __get_time_locale (locale)->date_fmt;
|
||||||
break;
|
break;
|
||||||
case RADIXCHAR:
|
case RADIXCHAR:
|
||||||
ret = (char*) __get_current_numeric_locale()->decimal_point;
|
ret = (char*) __get_numeric_locale (locale)->decimal_point;
|
||||||
break;
|
break;
|
||||||
case THOUSEP:
|
case THOUSEP:
|
||||||
ret = (char*) __get_current_numeric_locale()->thousands_sep;
|
ret = (char*) __get_numeric_locale (locale)->thousands_sep;
|
||||||
break;
|
break;
|
||||||
case YESEXPR:
|
case YESEXPR:
|
||||||
ret = (char*) __get_current_messages_locale()->yesexpr;
|
ret = (char*) __get_messages_locale (locale)->yesexpr;
|
||||||
break;
|
break;
|
||||||
case NOEXPR:
|
case NOEXPR:
|
||||||
ret = (char*) __get_current_messages_locale()->noexpr;
|
ret = (char*) __get_messages_locale (locale)->noexpr;
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
* All items marked with LEGACY are available, but not recomended
|
* All items marked with LEGACY are available, but not recomended
|
||||||
|
@ -368,22 +322,22 @@ do_codeset:
|
||||||
* to remove in future specification editions
|
* to remove in future specification editions
|
||||||
*/
|
*/
|
||||||
case YESSTR: /* LEGACY */
|
case YESSTR: /* LEGACY */
|
||||||
ret = (char*) __get_current_messages_locale()->yesstr;
|
ret = (char*) __get_messages_locale (locale)->yesstr;
|
||||||
break;
|
break;
|
||||||
case NOSTR: /* LEGACY */
|
case NOSTR: /* LEGACY */
|
||||||
ret = (char*) __get_current_messages_locale()->nostr;
|
ret = (char*) __get_messages_locale (locale)->nostr;
|
||||||
break;
|
break;
|
||||||
case CRNCYSTR:
|
case CRNCYSTR:
|
||||||
ret = "";
|
ret = "";
|
||||||
cs = (char*) __get_current_monetary_locale()->currency_symbol;
|
cs = (char*) __get_monetary_locale (locale)->currency_symbol;
|
||||||
if (*cs != '\0') {
|
if (*cs != '\0') {
|
||||||
char pos = localeconv()->p_cs_precedes;
|
char pos = __localeconv_l (locale)->p_cs_precedes;
|
||||||
|
|
||||||
if (pos == localeconv()->n_cs_precedes) {
|
if (pos == __localeconv_l (locale)->n_cs_precedes) {
|
||||||
char psn = '\0';
|
char psn = '\0';
|
||||||
|
|
||||||
if (pos == CHAR_MAX) {
|
if (pos == CHAR_MAX) {
|
||||||
if (strcmp(cs, __get_current_monetary_locale()->mon_decimal_point) == 0)
|
if (strcmp(cs, __get_monetary_locale (locale)->mon_decimal_point) == 0)
|
||||||
psn = '.';
|
psn = '.';
|
||||||
} else
|
} else
|
||||||
psn = pos ? '-' : '+';
|
psn = pos ? '-' : '+';
|
||||||
|
@ -406,11 +360,11 @@ do_codeset:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case D_MD_ORDER: /* local extension */
|
case D_MD_ORDER: /* local extension */
|
||||||
ret = (char *) __get_current_time_locale()->md_order;
|
ret = (char *) __get_time_locale (locale)->md_order;
|
||||||
break;
|
break;
|
||||||
#ifdef __HAVE_LOCALE_INFO__
|
#ifdef __HAVE_LOCALE_INFO__
|
||||||
case _NL_CTYPE_MB_CUR_MAX:
|
case _NL_CTYPE_MB_CUR_MAX:
|
||||||
ret = (char *) __get_current_ctype_locale()->mb_cur_max;
|
ret = (char *) __get_ctype_locale (locale)->mb_cur_max;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
@ -418,7 +372,7 @@ do_codeset:
|
||||||
if (item > _NL_LOCALE_EXTENDED_FIRST_ENTRY
|
if (item > _NL_LOCALE_EXTENDED_FIRST_ENTRY
|
||||||
&& item < _NL_LOCALE_EXTENDED_LAST_ENTRY) {
|
&& item < _NL_LOCALE_EXTENDED_LAST_ENTRY) {
|
||||||
int idx = item - _NL_LOCALE_EXTENDED_FIRST_ENTRY - 1;
|
int idx = item - _NL_LOCALE_EXTENDED_FIRST_ENTRY - 1;
|
||||||
return *(char **) ((char *) (*nl_ext[idx].base)()
|
return *(char **) ((char *) (*nl_ext[idx].base)(locale)
|
||||||
+ nl_ext[idx].offset);
|
+ nl_ext[idx].offset);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -426,3 +380,8 @@ do_codeset:
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *nl_langinfo (nl_item item)
|
||||||
|
{
|
||||||
|
return nl_langinfo_l (item, __get_current_locale ());
|
||||||
|
}
|
||||||
|
|
|
@ -939,6 +939,7 @@ nexttowardl NOSIGFE
|
||||||
nftw SIGFE
|
nftw SIGFE
|
||||||
nice SIGFE
|
nice SIGFE
|
||||||
nl_langinfo SIGFE
|
nl_langinfo SIGFE
|
||||||
|
nl_langinfo_l SIGFE
|
||||||
nrand48 NOSIGFE
|
nrand48 NOSIGFE
|
||||||
ntohl NOSIGFE
|
ntohl NOSIGFE
|
||||||
ntohs NOSIGFE
|
ntohs NOSIGFE
|
||||||
|
|
|
@ -466,12 +466,13 @@ details. */
|
||||||
301: Export strtod_l, strtof_l, strtol_l, strtold_l, strtoll_l, strtoul_l,
|
301: Export strtod_l, strtof_l, strtol_l, strtold_l, strtoll_l, strtoul_l,
|
||||||
strtoull_l, wcstod_l, wcstof_l, wcstol_l, wcstold_l, wcstoll_l,
|
strtoull_l, wcstod_l, wcstof_l, wcstol_l, wcstold_l, wcstoll_l,
|
||||||
wcstoul_l, wcstoull_l.
|
wcstoul_l, wcstoull_l.
|
||||||
|
302: Export nl_langinfo_l.
|
||||||
|
|
||||||
Note that we forgot to bump the api for ualarm, strtoll, strtoull,
|
Note that we forgot to bump the api for ualarm, strtoll, strtoull,
|
||||||
sigaltstack, sethostname. */
|
sigaltstack, sethostname. */
|
||||||
|
|
||||||
#define CYGWIN_VERSION_API_MAJOR 0
|
#define CYGWIN_VERSION_API_MAJOR 0
|
||||||
#define CYGWIN_VERSION_API_MINOR 301
|
#define CYGWIN_VERSION_API_MINOR 302
|
||||||
|
|
||||||
/* There is also a compatibity version number associated with the shared memory
|
/* There is also a compatibity version number associated with the shared memory
|
||||||
regions. It is incremented when incompatible changes are made to the shared
|
regions. It is incremented when incompatible changes are made to the shared
|
||||||
|
|
Loading…
Reference in New Issue