[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: nl_langinfo and localized day/month names
From: |
Eli Zaretskii |
Subject: |
Re: nl_langinfo and localized day/month names |
Date: |
Sat, 05 Jul 2014 20:57:30 +0300 |
> Date: Sat, 05 Jul 2014 10:12:29 -0700
> From: Paul Eggert <address@hidden>
>
> Eli Zaretskii wrote:
> > Ping! Could someone please respond, and either accept the patch or
> > explain why it cannot be accepted?
>
> Since nobody has commented and it works for you I'm inclined to apply
> it, unless Daiki speaks up.
Thanks!
> Could you write a proper ChangeLog entry for it please? Typical
> Gnulib style is an initial line "modulenames: brief phrase". Also,
> please use only spaces to indent. Thanks.
Modified patch with ChangeLog entries attached below.
diff --git a/ChangeLog b/ChangeLog
index eccf03e..8a1a9c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2014-07-05 Eli Zaretskii <address@hidden>
+
+ nl_langinfo: CODESET on MS-Windows and more items from localeconv.
+ * lib/nl_langinfo.c (nl_langinfo) <known_tm>: New static variable.
+ [_WIN32 || __WIN32__ && !__CYGWIN__] <CODESET>: Try extracting the
+ codeset from the value returned by 'setlocale', before falling
+ back on GetACP. Compute the values of RADIXCHAR, THOUSEP,
+ GROUPING, CRNCYSTR, INT_CURR_SYMBOL, MON_DECIMAL_POINT,
+ MON_THOUSANDS_SEP, MON_GROUPING, POSITIVE_SIGN, NEGATIVE_SIGN,
+ FRAC_DIGITS, INT_FRAC_DIGITS, P_CS_PRECEDES, N_CS_PRECEDES,
+ P_SEP_BY_SPACE, N_SEP_BY_SPACE, P_SIGN_POSN, and N_SIGN_POSN from
+ the corresponding values returned by 'localeconv'. Compute the
+ values of AM_STR, PM_STR, DAY_n, ABDAY_n, MON_n, and ABMON_n by
+ calling 'strftime' with a suitably modified known_tm structure.
+
+ * lib/langinfo.in.h (DECIMAL_POINT, THOUSANDS_SEP, GROUPING)
+ (CURRENCY_SYMBOL, INT_CURR_SYMBOL, MON_DECIMAL_POINT)
+ (MON_THOUSANDS_SEP, MON_GROUPING, POSITIVE_SIGN, NEGATIVE_SIGN)
+ (FRAC_DIGITS, INT_FRAC_DIGITS, P_CS_PRECEDES, N_CS_PRECEDES)
+ (P_SEP_BY_SPACE, N_SEP_BY_SPACE, P_SIGN_POSN, N_SIGN_POSN): Define.
+
2014-07-05 Paul Eggert <address@hidden>
Bruno Haible has stepped down as maintainer.
diff --git a/lib/langinfo.in.h b/lib/langinfo.in.h
index 17f4b9b..d118d5d 100644
--- a/lib/langinfo.in.h
+++ b/lib/langinfo.in.h
@@ -49,7 +49,10 @@ typedef int nl_item;
# define CODESET 10000
/* nl_langinfo items of the LC_NUMERIC category */
# define RADIXCHAR 10001
+# define DECIMAL_POINT RADIXCHAR
# define THOUSEP 10002
+# define THOUSANDS_SEP THOUSEP
+# define GROUPING 10114
/* nl_langinfo items of the LC_TIME category */
# define D_T_FMT 10003
# define D_FMT 10004
@@ -102,6 +105,21 @@ typedef int nl_item;
# define ALT_DIGITS 10051
/* nl_langinfo items of the LC_MONETARY category */
# define CRNCYSTR 10052
+# define CURRENCY_SYMBOL CRNCYSTR
+# define INT_CURR_SYMBOL 10100
+# define MON_DECIMAL_POINT 10101
+# define MON_THOUSANDS_SEP 10102
+# define MON_GROUPING 10103
+# define POSITIVE_SIGN 10104
+# define NEGATIVE_SIGN 10105
+# define FRAC_DIGITS 10106
+# define INT_FRAC_DIGITS 10107
+# define P_CS_PRECEDES 10108
+# define N_CS_PRECEDES 10109
+# define P_SEP_BY_SPACE 10110
+# define N_SEP_BY_SPACE 10111
+# define P_SIGN_POSN 10112
+# define N_SIGN_POSN 10113
/* nl_langinfo items of the LC_MESSAGES category */
# define YESEXPR 10053
# define NOEXPR 10054
diff --git a/lib/nl_langinfo.c b/lib/nl_langinfo.c
index 287abfd..1fef26e 100644
--- a/lib/nl_langinfo.c
+++ b/lib/nl_langinfo.c
@@ -121,6 +121,7 @@ rpl_nl_langinfo (nl_item item)
# include <windows.h>
# include <stdio.h>
+# include <limits.h>
# else
@@ -129,22 +130,46 @@ rpl_nl_langinfo (nl_item item)
# endif
# include <locale.h>
+# include <time.h>
char *
nl_langinfo (nl_item item)
{
+ static struct tm known_tm = {
+ 0, 0, 0, /* 00:00:00 */
+ 5, 0, 114, /* Sunday January 5, 2014 */
+ 0, 4, -1
+ };
+ struct tm tmm;
+ static char nlbuf[100];
+
switch (item)
{
/* nl_langinfo items of the LC_CTYPE category */
case CODESET:
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+ /* The Windows API has a function returning the locale's
+ codepage as a number, but the value doesn't change according
+ to what the 'setlocale' call specified. So we use it as a
+ last resort, in case the string returned by 'setlocale'
+ doesn't specify the codepage. */
{
- static char buf[2 + 10 + 1];
+ char *current_locale = setlocale (LC_ALL, NULL);
+ char *pdot;
+
+ /* If they set different locales for different categories,
+ 'setlocale' will return a semi-colon separated list of
+ locale values. To make sure we use the correct one, we
+ choose LC_CTYPE. */
+ if (strchr (current_locale, ';'))
+ current_locale = setlocale (LC_CTYPE, NULL);
- /* The Windows API has a function returning the locale's codepage as
- a number. */
- sprintf (buf, "CP%u", GetACP ());
- return buf;
+ pdot = strrchr (current_locale, '.');
+ if (pdot)
+ sprintf (nlbuf, "CP%s", pdot + 1);
+ else
+ sprintf (nlbuf, "CP%u", GetACP ());
+ return nlbuf;
}
# elif defined __BEOS__
return "UTF-8";
@@ -153,9 +178,23 @@ nl_langinfo (nl_item item)
# endif
/* nl_langinfo items of the LC_NUMERIC category */
case RADIXCHAR:
- return localeconv () ->decimal_point;
+ {
+ char *c = localeconv () ->decimal_point;
+
+ if (*c == CHAR_MAX || *c == -1)
+ return "";
+ return c;
+ }
case THOUSEP:
- return localeconv () ->thousands_sep;
+ {
+ char *c = localeconv () ->thousands_sep;
+
+ if (*c == CHAR_MAX || *c == -1)
+ return "";
+ return c;
+ }
+ case GROUPING:
+ return localeconv () ->grouping;
/* nl_langinfo items of the LC_TIME category.
TODO: Really use the locale. */
case D_T_FMT:
@@ -170,93 +209,163 @@ nl_langinfo (nl_item item)
case T_FMT_AMPM:
return "%I:%M:%S %p";
case AM_STR:
- return "AM";
+ memcpy (&tmm, &known_tm, sizeof (known_tm));
+ tmm.tm_hour = 10;
+ if (!strftime (nlbuf, sizeof(nlbuf), "%p", &tmm))
+ return "AM";
+ return nlbuf;
case PM_STR:
- return "PM";
+ memcpy (&tmm, &known_tm, sizeof (known_tm));
+ tmm.tm_hour = 22;
+ if (!strftime (nlbuf, sizeof(nlbuf), "%p", &tmm))
+ return "PM";
+ return nlbuf;
case DAY_1:
- return "Sunday";
case DAY_2:
- return "Monday";
case DAY_3:
- return "Tuesday";
case DAY_4:
- return "Wednesday";
case DAY_5:
- return "Thursday";
case DAY_6:
- return "Friday";
case DAY_7:
- return "Saturday";
+ {
+ static char *days[] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+ "Friday", "Saturday"
+ };
+ memcpy (&tmm, &known_tm, sizeof (known_tm));
+ tmm.tm_mday += item - DAY_1;
+ tmm.tm_wday += item - DAY_1;
+ if (!strftime (nlbuf, sizeof(nlbuf), "%A", &tmm))
+ return days[item - DAY_1];
+ return nlbuf;
+ }
case ABDAY_1:
- return "Sun";
case ABDAY_2:
- return "Mon";
case ABDAY_3:
- return "Tue";
case ABDAY_4:
- return "Wed";
case ABDAY_5:
- return "Thu";
case ABDAY_6:
- return "Fri";
case ABDAY_7:
- return "Sat";
+ {
+ static char *abdays[] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+ memcpy (&tmm, &known_tm, sizeof (known_tm));
+ tmm.tm_mday += item - ABDAY_1;
+ tmm.tm_wday += item - ABDAY_1;
+ if (!strftime (nlbuf, sizeof(nlbuf), "%a", &tmm))
+ return abdays[item - ABDAY_1];
+ return nlbuf;
+ }
case MON_1:
- return "January";
case MON_2:
- return "February";
case MON_3:
- return "March";
case MON_4:
- return "April";
case MON_5:
- return "May";
case MON_6:
- return "June";
case MON_7:
- return "July";
case MON_8:
- return "August";
case MON_9:
- return "September";
case MON_10:
- return "October";
case MON_11:
- return "November";
case MON_12:
- return "December";
+ {
+ static char *months[] = {
+ "January", "February", "March", "April", "May", "June", "July",
+ "September", "October", "November", "December"
+ };
+ memcpy (&tmm, &known_tm, sizeof (known_tm));
+ tmm.tm_mon += item - MON_1;
+ if (!strftime (nlbuf, sizeof(nlbuf), "%B", &tmm))
+ return months[item - MON_1];
+ return nlbuf;
+ }
case ABMON_1:
- return "Jan";
case ABMON_2:
- return "Feb";
case ABMON_3:
- return "Mar";
case ABMON_4:
- return "Apr";
case ABMON_5:
- return "May";
case ABMON_6:
- return "Jun";
case ABMON_7:
- return "Jul";
case ABMON_8:
- return "Aug";
case ABMON_9:
- return "Sep";
case ABMON_10:
- return "Oct";
case ABMON_11:
- return "Nov";
case ABMON_12:
- return "Dec";
+ {
+ static char *abmonths[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
+ "Sep", "Oct", "Nov", "Dec"
+ };
+ memcpy (&tmm, &known_tm, sizeof (known_tm));
+ tmm.tm_mon += item - ABMON_1;
+ if (!strftime (nlbuf, sizeof(nlbuf), "%b", &tmm))
+ return abmonths[item - ABMON_1];
+ return nlbuf;
+ }
case ERA:
return "";
case ALT_DIGITS:
return "\0\0\0\0\0\0\0\0\0\0";
- /* nl_langinfo items of the LC_MONETARY category
- TODO: Really use the locale. */
+ /* nl_langinfo items of the LC_MONETARY category. */
case CRNCYSTR:
- return "-";
+ return localeconv () ->currency_symbol;
+ case INT_CURR_SYMBOL:
+ return localeconv () ->int_curr_symbol;
+ case MON_DECIMAL_POINT:
+ {
+ char *c = localeconv () ->mon_decimal_point;
+
+ if (*c == CHAR_MAX || *c == -1)
+ return "";
+ return c;
+ }
+ case MON_THOUSANDS_SEP:
+ {
+ char *c = localeconv () ->mon_thousands_sep;
+
+ if (*c == CHAR_MAX || *c == -1)
+ return "";
+ return c;
+ }
+ case MON_GROUPING:
+ return localeconv () ->mon_grouping;
+ case POSITIVE_SIGN:
+ return localeconv () ->positive_sign;
+ case NEGATIVE_SIGN:
+ return localeconv () ->negative_sign;
+ case FRAC_DIGITS:
+ nlbuf[0] = localeconv () ->frac_digits;
+ nlbuf[1] = '\0';
+ return nlbuf;
+ case INT_FRAC_DIGITS:
+ nlbuf[0] = localeconv () ->int_frac_digits;
+ nlbuf[1] = '\0';
+ return nlbuf;
+ case P_CS_PRECEDES:
+ nlbuf[0] = localeconv () ->p_cs_precedes;
+ nlbuf[1] = '\0';
+ return nlbuf;
+ case N_CS_PRECEDES:
+ nlbuf[0] = localeconv () ->n_cs_precedes;
+ nlbuf[1] = '\0';
+ return nlbuf;
+ case P_SEP_BY_SPACE:
+ nlbuf[0] = localeconv () ->p_sep_by_space;
+ nlbuf[1] = '\0';
+ return nlbuf;
+ case N_SEP_BY_SPACE:
+ nlbuf[0] = localeconv () ->n_sep_by_space;
+ nlbuf[1] = '\0';
+ return nlbuf;
+ case P_SIGN_POSN:
+ nlbuf[0] = localeconv () ->p_sign_posn;
+ nlbuf[1] = '\0';
+ return nlbuf;
+ case N_SIGN_POSN:
+ nlbuf[0] = localeconv () ->n_sign_posn;
+ nlbuf[1] = '\0';
+ return nlbuf;
/* nl_langinfo items of the LC_MESSAGES category
TODO: Really use the locale. */
case YESEXPR:
- Re: nl_langinfo and localized day/month names, Eli Zaretskii, 2014/07/02
- Re: nl_langinfo and localized day/month names, Ludovic Courtès, 2014/07/03
- Re: nl_langinfo and localized day/month names, Paul Eggert, 2014/07/05
- Re: nl_langinfo and localized day/month names,
Eli Zaretskii <=
- Re: nl_langinfo and localized day/month names, Eli Zaretskii, 2014/07/05
- Re: nl_langinfo and localized day/month names, Paul Eggert, 2014/07/05
- Re: nl_langinfo and localized day/month names, Eli Zaretskii, 2014/07/06
- Re: nl_langinfo and localized day/month names, Paul Eggert, 2014/07/07
- Re: nl_langinfo and localized day/month names, Eli Zaretskii, 2014/07/07
- Re: nl_langinfo and localized day/month names, Paul Eggert, 2014/07/07