Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-01-22 16:03:42 +0300
committerCorinna Vinschen <corinna@vinschen.de>2010-01-22 16:03:42 +0300
commitfe57329f991a0b347d40a5c97d9a62285eb708fe (patch)
tree4e6a2b000d865212b1d854c9d0ce8b1f0e0d5e88 /newlib/libc/time/strftime.c
parent2d7f21da1e428214d8a18e3ebea9e822586b516f (diff)
* libc/locale/lmonetary.c (__monetary_load_locale): Take additional
parameters for wide char to multibyte conversion. Call __set_lc_monetary_from_win on Cygwin. * libc/locale/lmonetary.h: Make C++-safe. (__monetary_load_locale): Change declaration. * libc/locale/lnumeric.c (__numeric_load_locale): Take additional parameters for wide char to multibyte conversion. Call __set_lc_numeric_from_win on Cygwin. * libc/locale/lnumeric.h: Make C++-safe. (__numeric_load_locale): Change declaration. * libc/locale/locale.c (lconv): De-constify for Cygwin. (__set_charset_from_locale): Rename from __set_charset_from_codepage. Take locale as parameter instead of a codepage. (loadlocale): Allow "EUC-JP" for "EUCJP" and "EUC-KR" for "EUCKR". Change documnetation accordingly. Enable LC_COLLATE, LC_MONETARY, LC_NUMERIC, and LC_TIME handling on Cygwin. (_localeconv_r): On Cygwin, copy values from monetary and numeric domain if change has been noted. * libc/locale/nl_langinfo.c (nl_langinfo): Accommodate change of am/pm layout in struct lc_time_T. * libc/locale/timelocal.c (_C_time_locale): Accommodate redefinition of am/pm members. (__time_load_locale): Take additional parameters for wide char to multibyte conversion. Call __set_lc_time_from_win on Cygwin. * libc/locale/timelocal.h: Make C++-safe. (struct lc_time_T): Convert am and pm to a am_pm array for easier consumption by strftime and strptime. (__time_load_locale): Change declaration. * libc/time/strftime.c: Change documentation to reflect changes to strftime. Remove locale constant strings in favor of access to locale-specifc data. (_ctloc): Define access method for locale-specifc data. (TOLOWER): Define for tolower conversion. (strftime): Throughout, convert locale-specific formats to use locale-specific data. Add GNU-specific "%P" format. * libc/time/strptime.c: Remove locale constant strings in favor of access to locale-specifc data. (_ctloc): Define access method for locale-specifc data. (strptime): Throughout, convert locale-specific formats to use locale-specific data.
Diffstat (limited to 'newlib/libc/time/strftime.c')
-rw-r--r--newlib/libc/time/strftime.c168
1 files changed, 88 insertions, 80 deletions
diff --git a/newlib/libc/time/strftime.c b/newlib/libc/time/strftime.c
index e9849ac9b..95fb3019c 100644
--- a/newlib/libc/time/strftime.c
+++ b/newlib/libc/time/strftime.c
@@ -52,26 +52,26 @@ following ways:
o+
o %a
-A three-letter abbreviation for the day of the week. [tm_wday]
+The abbreviated weekday name according to the current locale. [tm_wday]
o %A
-The full name for the day of the week, one of `<<Sunday>>',
-`<<Monday>>', `<<Tuesday>>', `<<Wednesday>>', `<<Thursday>>',
-`<<Friday>>', or `<<Saturday>>'. [tm_wday]
+The full weekday name according to the current locale.
+In the default "C" locale, one of `<<Sunday>>', `<<Monday>>', `<<Tuesday>>',
+`<<Wednesday>>', `<Thursday>>', `<<Friday>>', `<<Saturday>>'. [tm_wday]
o %b
-A three-letter abbreviation for the month name. [tm_mon]
+The abbreviated month name according to the current locale. [tm_mon]
o %B
-The full name of the month, one of `<<January>>', `<<February>>',
+The full month name according to the current locale.
+In the default "C" locale, one of `<<January>>', `<<February>>',
`<<March>>', `<<April>>', `<<May>>', `<<June>>', `<<July>>',
`<<August>>', `<<September>>', `<<October>>', `<<November>>',
`<<December>>'. [tm_mon]
o %c
-A string representing the complete date and time, in the form
-`<<"%a %b %e %H:%M:%S %Y">>' (example "Mon Apr 01 13:13:13
-1992"). [tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday]
+The preferred date and time representation for the current locale.
+[tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday]
o %C
The century, that is, the year divided by 100 then truncated. For
@@ -93,8 +93,7 @@ The day of the month, formatted with leading space if single digit
o %E<<x>>
In some locales, the E modifier selects alternative representations of
-certain modifiers <<x>>. But in the "C" locale supported by newlib,
-it is ignored, and treated as %<<x>>.
+certain modifiers <<x>>. In newlib, it is ignored, and treated as %<<x>>.
o %F
A string representing the ISO 8601:2000 date format, in the form
@@ -115,8 +114,7 @@ Example: "%G" for Saturday 2nd January 1999 gives "1998", and for
Tuesday 30th December 1997 gives "1998". [tm_year, tm_wday, tm_yday]
o %h
-A three-letter abbreviation for the month name (synonym for
-"%b"). [tm_mon]
+Synonym for "%b". [tm_mon]
o %H
The hour (on a 24-hour clock), formatted with two digits (from
@@ -150,15 +148,19 @@ A newline character (`<<\n>>').
o %O<<x>>
In some locales, the O modifier selects alternative digit characters
-for certain modifiers <<x>>. But in the "C" locale supported by newlib, it
-is ignored, and treated as %<<x>>.
+for certain modifiers <<x>>. In newlib, it is ignored, and treated as %<<x>>.
o %p
-Either `<<AM>>' or `<<PM>>' as appropriate. [tm_hour]
+Either `<<AM>>' or `<<PM>>' as appropriate, or the corresponding strings for
+the current locale. [tm_hour]
+
+o %P
+Same as '<<%p>>', but in lowercase. This is a GNU extension. [tm_hour]
o %r
-The 12-hour time, to the second. Equivalent to "%I:%M:%S %p". [tm_sec,
-tm_min, tm_hour]
+Replaced by the time in a.m. and p.m. notation. In the "C" locale this
+is equivalent to "%I:%M:%S %p". In locales which don't define a.m./p.m.
+notations, the result is an empty string. [tm_sec, tm_min, tm_hour]
o %R
The 24-hour time, to the minute. Equivalent to "%H:%M". [tm_min, tm_hour]
@@ -198,12 +200,13 @@ Monday in a year, and earlier days are in week 0. Formatted with two
digits (from `<<00>>' to `<<53>>'). [tm_wday, tm_yday]
o %x
-A string representing the complete date, equivalent to "%m/%d/%y".
+Replaced by the preferred date representation in the current locale.
+In the "C" locale this is equivalent to "%m/%d/%y".
[tm_mon, tm_mday, tm_year]
o %X
-A string representing the full time of day (hours, minutes, and
-seconds), equivalent to "%H:%M:%S". [tm_sec, tm_min, tm_hour]
+Replaced by the preferred time representation in the current locale.
+In the "C" locale this is equivalent to "%H:%M:%S". [tm_sec, tm_min, tm_hour]
o %y
The last two digits of the year (from `<<00>>' to `<<99>>'). [tm_year]
@@ -263,7 +266,10 @@ the "C" locale settings.
#include <string.h>
#include <stdlib.h>
#include <limits.h>
+#include <ctype.h>
+#include <wctype.h>
#include "local.h"
+#include "../locale/timelocal.h"
/* Defines to make the file dual use for either strftime() or wcsftime().
* To get wcsftime, define MAKE_WCSFTIME.
@@ -276,13 +282,28 @@ the "C" locale settings.
# define CHAR char /* string type basis */
# define CQ(a) a /* character constant qualifier */
# define SFLG /* %s flag (null for normal char) */
+# define _ctloc(x) (ctloclen = strlen (ctloc = _CurrentTimeLocale->x), ctloc)
+# define TOLOWER(c) tolower((int)(unsigned char)(c))
# else
# define strftime wcsftime /* Alternate function name */
# define CHAR wchar_t /* string type basis */
# define CQ(a) L##a /* character constant qualifier */
# define snprintf swprintf /* wide-char equivalent function name */
# define strncmp wcsncmp /* wide-char equivalent function name */
+# define TOLOWER(c) towlower((wint_t)(c))
# define SFLG "l" /* %s flag (l for wide char) */
+# define CTLOCBUFLEN 256 /* Arbitrary big buffer size */
+ const wchar_t *
+ __ctloc (wchar_t *buf, const char *elem, size_t *len_ret)
+ {
+ buf[CTLOCBUFLEN - 1] = L'\0';
+ *len_ret = mbstowcs (buf, elem, CTLOCBUFLEN - 1);
+ if (*len_ret == (size_t) -1 )
+ *len_ret = 0;
+ return buf;
+ }
+# define _ctloc(x) (ctloc = __ctloc (ctlocbuf, _CurrentTimeLocale->x, \
+ &ctloclen))
#endif /* MAKE_WCSFTIME */
/* Enforce the coding assumptions that YEAR_BASE is positive. (%C, %Y, etc.) */
@@ -293,18 +314,6 @@ the "C" locale settings.
static _CONST int dname_len[7] =
{6, 6, 7, 9, 8, 6, 8};
-static _CONST CHAR *_CONST dname[7] =
-{CQ("Sunday"), CQ("Monday"), CQ("Tuesday"), CQ("Wednesday"),
- CQ("Thursday"), CQ("Friday"), CQ("Saturday")};
-
-static _CONST int mname_len[12] =
-{7, 8, 5, 5, 3, 4, 4, 6, 9, 7, 8, 8};
-
-static _CONST CHAR *_CONST mname[12] =
-{CQ("January"), CQ("February"), CQ("March"), CQ("April"),
- CQ("May"), CQ("June"), CQ("July"), CQ("August"),
- CQ("September"), CQ("October"), CQ("November"), CQ("December")};
-
/* Using the tm_year, tm_wday, and tm_yday components of TIM_P, return
-1, 0, or 1 as the adjustment to add to the year for the ISO week
numbering used in "%g%G%V", avoiding overflow. */
@@ -361,7 +370,13 @@ _DEFUN (strftime, (s, maxsize, format, tim_p),
{
size_t count = 0;
int i, len;
+ const CHAR *ctloc;
+#ifdef MAKE_WCSFTIME
+ CHAR ctlocbuf[CTLOCBUFLEN];
+#endif
+ size_t ctloclen;
+ struct lc_time_T *_CurrentTimeLocale = __get_current_time_locale ();
for (;;)
{
while (*format && *format != CQ('%'))
@@ -382,56 +397,68 @@ _DEFUN (strftime, (s, maxsize, format, tim_p),
switch (*format)
{
case CQ('a'):
- for (i = 0; i < 3; i++)
+ _ctloc (wday[tim_p->tm_wday]);
+ for (i = 0; i < ctloclen; i++)
{
if (count < maxsize - 1)
- s[count++] =
- dname[tim_p->tm_wday][i];
+ s[count++] = ctloc[i];
else
return 0;
}
break;
case CQ('A'):
- for (i = 0; i < dname_len[tim_p->tm_wday]; i++)
+ _ctloc (weekday[tim_p->tm_wday]);
+ for (i = 0; i < ctloclen; i++)
{
if (count < maxsize - 1)
- s[count++] =
- dname[tim_p->tm_wday][i];
+ s[count++] = ctloc[i];
else
return 0;
}
break;
case CQ('b'):
case CQ('h'):
- for (i = 0; i < 3; i++)
+ _ctloc (mon[tim_p->tm_mon]);
+ for (i = 0; i < ctloclen; i++)
{
if (count < maxsize - 1)
- s[count++] =
- mname[tim_p->tm_mon][i];
+ s[count++] = ctloc[i];
else
return 0;
}
break;
case CQ('B'):
- for (i = 0; i < mname_len[tim_p->tm_mon]; i++)
+ _ctloc (month[tim_p->tm_mon]);
+ for (i = 0; i < ctloclen; i++)
{
if (count < maxsize - 1)
- s[count++] =
- mname[tim_p->tm_mon][i];
+ s[count++] = ctloc[i];
else
return 0;
}
break;
case CQ('c'):
- {
- /* Recurse to avoid need to replicate %Y formation. */
- size_t adjust = strftime (&s[count], maxsize - count,
- CQ("%a %b %e %H:%M:%S %Y"), tim_p);
- if (adjust > 0)
- count += adjust;
- else
- return 0;
- }
+ _ctloc (c_fmt);
+ goto recurse;
+ case CQ('r'):
+ _ctloc (ampm_fmt);
+ goto recurse;
+ case CQ('x'):
+ _ctloc (x_fmt);
+ goto recurse;
+ case CQ('X'):
+ _ctloc (X_fmt);
+recurse:
+ if (*ctloc)
+ {
+ /* Recurse to avoid need to replicate %Y formation. */
+ size_t adjust = strftime (&s[count], maxsize - count, ctloc,
+ tim_p);
+ if (adjust > 0)
+ count += adjust;
+ else
+ return 0;
+ }
break;
case CQ('C'):
{
@@ -472,7 +499,6 @@ _DEFUN (strftime, (s, maxsize, format, tim_p),
if (len < 0 || (count+=len) >= maxsize) return 0;
break;
case CQ('D'):
- case CQ('x'):
/* %m/%d/%y */
len = snprintf (&s[count], maxsize - count,
CQ("%.2d/%.2d/%.2d"),
@@ -582,33 +608,16 @@ _DEFUN (strftime, (s, maxsize, format, tim_p),
return 0;
break;
case CQ('p'):
- if (count < maxsize - 1)
+ case CQ('P'):
+ _ctloc (am_pm[tim_p->tm_hour < 12 ? 0 : 1]);
+ for (i = 0; i < ctloclen; i++)
{
- if (tim_p->tm_hour < 12)
- s[count++] = CQ('A');
+ if (count < maxsize - 1)
+ s[count++] = (*format == CQ('P') ? TOLOWER (ctloc[i])
+ : ctloc[i]);
else
- s[count++] = CQ('P');
- }
- if (count < maxsize - 1)
- {
- s[count++] = CQ('M');
+ return 0;
}
- else
- return 0;
- break;
- case CQ('r'):
- {
- register int h12;
- h12 = (tim_p->tm_hour == 0 || tim_p->tm_hour == 12) ?
- 12 : tim_p->tm_hour % 12;
- len = snprintf (&s[count], maxsize - count,
- CQ("%.2d:%.2d:%.2d %cM"),
- h12,
- tim_p->tm_min,
- tim_p->tm_sec,
- (tim_p->tm_hour < 12) ? CQ('A') : CQ('P'));
- if (len < 0 || (count+=len) >= maxsize) return 0;
- }
break;
case CQ('R'):
len = snprintf (&s[count], maxsize - count, CQ("%.2d:%.2d"),
@@ -627,7 +636,6 @@ _DEFUN (strftime, (s, maxsize, format, tim_p),
return 0;
break;
case CQ('T'):
- case CQ('X'):
len = snprintf (&s[count], maxsize - count, CQ("%.2d:%.2d:%.2d"),
tim_p->tm_hour, tim_p->tm_min, tim_p->tm_sec);
if (len < 0 || (count+=len) >= maxsize) return 0;