aboutsummaryrefslogtreecommitdiff
path: root/newlib/libc/time/strftime.c
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2016-07-24 20:00:34 +0200
committerCorinna Vinschen <corinna@vinschen.de>2016-08-15 10:56:58 +0200
commitc1b7d9d93dc8e88693162c0d984a114371919fdd (patch)
tree25842a96b7ae037393ebc3d96803a376e7beff45 /newlib/libc/time/strftime.c
parent8493c1631643fada62384768408852bc0fa6ff44 (diff)
downloadnewlib-c1b7d9d93dc8e88693162c0d984a114371919fdd.zip
newlib-c1b7d9d93dc8e88693162c0d984a114371919fdd.tar.gz
newlib-c1b7d9d93dc8e88693162c0d984a114371919fdd.tar.bz2
Implement per-locale string functions
strcasecmp_l, strcoll_l, strncasecmp_l, strxfrm_l, wcscasecmp_l, wcscoll_l, wcstrncasecmp_l, wcstrxfrm_l, strftime_l. Add missing CHEWOUT_FILES from previous patch. TODO: strfmon_l. Signed-off by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'newlib/libc/time/strftime.c')
-rw-r--r--newlib/libc/time/strftime.c100
1 files changed, 62 insertions, 38 deletions
diff --git a/newlib/libc/time/strftime.c b/newlib/libc/time/strftime.c
index 12c37eb..0d5bbd5 100644
--- a/newlib/libc/time/strftime.c
+++ b/newlib/libc/time/strftime.c
@@ -4,7 +4,7 @@
/*
* strftime.c
* Original Author: G. Haley
- * Additions from: Eric Blake
+ * Additions from: Eric Blake, Corinna Vinschen
* Changes to allow dual use as wcstime, also: Craig Howland
*
* Places characters into the array pointed to by s as controlled by the string
@@ -17,16 +17,23 @@
/*
FUNCTION
-<<strftime>>---convert date and time to a formatted string
+<<strftime>>, <<strftime_l>>---convert date and time to a formatted string
INDEX
strftime
+INDEX
+ strftime_l
+
ANSI_SYNOPSIS
#include <time.h>
size_t strftime(char *restrict <[s]>, size_t <[maxsize]>,
const char *restrict <[format]>,
const struct tm *restrict <[timp]>);
+ size_t strftime_l(char *restrict <[s]>, size_t <[maxsize]>,
+ const char *restrict <[format]>,
+ const struct tm *restrict <[timp]>,
+ locale_t <[locale]>);
TRAD_SYNOPSIS
#include <time.h>
@@ -41,6 +48,9 @@ DESCRIPTION
<[timp]>) into a null-terminated string, starting at <[s]> and occupying
no more than <[maxsize]> characters.
+<<strftime_l>> is like <<strftime>> but creates a string in a format
+as expected in locale <[locale]>.
+
You control the format of the output using the string at <[format]>.
<<*<[format]>>> can contain two kinds of specifications: text to be
copied literally into the formatted string, and time conversion
@@ -258,11 +268,13 @@ value beforehand to distinguish between failure and an empty string.
This implementation does not support <<s>> being NULL, nor overlapping
<<s>> and <<format>>.
-<<strftime>> requires no supporting OS subroutines.
+<<strftime_l>> is POSIX-1.2008.
+
+<<strftime>> and <<strftime_l>> require no supporting OS subroutines.
BUGS
-<<strftime>> ignores the LC_TIME category of the current locale, hard-coding
-the "C" locale settings.
+(NOT Cygwin:) <<strftime>> ignores the LC_TIME category of the current
+locale, hard-coding the "C" locale settings.
*/
#include <newlib.h>
@@ -662,39 +674,16 @@ conv_to_alt_digits (CHAR *buf, size_t bufsiz, unsigned num, alt_digits_t *adi)
return 0;
}
-static size_t __strftime (CHAR *, size_t, const CHAR *, const struct tm *,
- era_info_t **, alt_digits_t **);
-
-size_t
-_DEFUN (strftime, (s, maxsize, format, tim_p),
- CHAR *__restrict s _AND
- size_t maxsize _AND
- _CONST CHAR *__restrict format _AND
- _CONST struct tm *__restrict tim_p)
-{
- era_info_t *era_info = NULL;
- alt_digits_t *alt_digits = NULL;
- size_t ret = __strftime (s, maxsize, format, tim_p, &era_info, &alt_digits);
- if (era_info)
- free_era_info (era_info);
- if (alt_digits)
- free_alt_digits (alt_digits);
- return ret;
-}
-
static size_t
__strftime (CHAR *s, size_t maxsize, const CHAR *format,
- const struct tm *tim_p, era_info_t **era_info,
- alt_digits_t **alt_digits)
-#else /* !_WANT_C99_TIME_FORMATS */
-# define __strftime(s,m,f,t,e,a) strftime((s),(m),(f),(t))
+ const struct tm *tim_p, struct __locale_t *locale,
+ era_info_t **era_info, alt_digits_t **alt_digits)
+#else
+static size_t
+__strftime (CHAR *s, size_t maxsize, const CHAR *format,
+ const struct tm *tim_p, struct __locale_t *locale)
-size_t
-_DEFUN (strftime, (s, maxsize, format, tim_p),
- CHAR *__restrict s _AND
- size_t maxsize _AND
- _CONST CHAR *__restrict format _AND
- _CONST struct tm *__restrict tim_p)
+#define __strftime(s,m,f,t,l,e,a) __strftime((s),(m),(f),(t),(l))
#endif /* !_WANT_C99_TIME_FORMATS */
{
size_t count = 0;
@@ -709,7 +698,7 @@ _DEFUN (strftime, (s, maxsize, format, tim_p),
unsigned long width;
int tzset_called = 0;
- const struct lc_time_T *_CurrentTimeLocale = __get_current_time_locale ();
+ const struct lc_time_T *_CurrentTimeLocale = __get_locale_time (locale);
for (;;)
{
while (*format && *format != CQ('%'))
@@ -840,7 +829,7 @@ recurse:
{
/* Recurse to avoid need to replicate %Y formation. */
len = __strftime (&s[count], maxsize - count, ctloc, tim_p,
- era_info, alt_digits);
+ locale, era_info, alt_digits);
if (len > 0)
count += len;
else
@@ -957,7 +946,7 @@ recurse:
}
STRCPY (fmt, CQ("Y-%m-%d"));
len = __strftime (&s[count], maxsize - count, fmtbuf, tim_p,
- era_info, alt_digits);
+ locale, era_info, alt_digits);
if (len > 0)
count += len;
else
@@ -1447,6 +1436,41 @@ recurse:
return count;
}
+size_t
+_DEFUN (strftime, (s, maxsize, format, tim_p),
+ CHAR *__restrict s _AND
+ size_t maxsize _AND
+ _CONST CHAR *__restrict format _AND
+ _CONST struct tm *__restrict tim_p)
+{
+ era_info_t *era_info = NULL;
+ alt_digits_t *alt_digits = NULL;
+ size_t ret = __strftime (s, maxsize, format, tim_p, __get_current_locale (),
+ &era_info, &alt_digits);
+ if (era_info)
+ free_era_info (era_info);
+ if (alt_digits)
+ free_alt_digits (alt_digits);
+ return ret;
+}
+
+#if !defined(MAKE_WCSFTIME)
+size_t
+strftime_l (char *__restrict s, size_t maxsize, const char *__restrict format,
+ const struct tm *__restrict tim_p, struct __locale_t *locale)
+{
+ era_info_t *era_info = NULL;
+ alt_digits_t *alt_digits = NULL;
+ size_t ret = __strftime (s, maxsize, format, tim_p, locale,
+ &era_info, &alt_digits);
+ if (era_info)
+ free_era_info (era_info);
+ if (alt_digits)
+ free_alt_digits (alt_digits);
+ return ret;
+}
+#endif
+
/* The remainder of this file can serve as a regression test. Compile
* with -D_REGRESSION_TEST. */
#if defined(_REGRESSION_TEST) /* [Test code: */