mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
'strftime' and 'strptime' honor the locale encoding.
Fixes <https://bugs.gnu.org/35920>. Reported by Christopher Lam <christopher.lck@gmail.com>. * libguile/stime.c (scm_strftime): Use 'scm_to_locale_stringn' instead of 'scm_to_utf8_stringn'. (scm_strptime): Likewise, and use 'scm_string_length' instead of 'u8_strnlen'. * test-suite/tests/time.test ("strftime")["strftime passes wide characters"]: Wrap body in 'with-locale'. ["strftime fr_FR.utf8", "strftime fr_FR.iso88591"]: New tests. ("strptime")["strftime fr_FR.utf8", "strftime fr_FR.iso88591"]: New tests.
This commit is contained in:
parent
63f54a7bc6
commit
ab2fd70ef1
2 changed files with 43 additions and 16 deletions
|
@ -662,9 +662,9 @@ SCM_DEFINE (scm_strftime, "strftime", 2, 0, 0,
|
|||
SCM_VALIDATE_STRING (1, format);
|
||||
bdtime2c (stime, &t, SCM_ARG2, FUNC_NAME);
|
||||
|
||||
/* Convert string to UTF-8 so that non-ASCII characters in the
|
||||
format are passed through unchanged. */
|
||||
fmt = scm_to_utf8_stringn (format, &len);
|
||||
/* Convert the format string to the locale encoding, as the underlying
|
||||
'strftime' C function expects. */
|
||||
fmt = scm_to_locale_stringn (format, &len);
|
||||
|
||||
/* Ugly hack: strftime can return 0 if its buffer is too small,
|
||||
but some valid time strings (e.g. "%p") can sometimes produce
|
||||
|
@ -727,7 +727,7 @@ SCM_DEFINE (scm_strftime, "strftime", 2, 0, 0,
|
|||
#endif
|
||||
}
|
||||
|
||||
result = scm_from_utf8_string (tbuf + 1);
|
||||
result = scm_from_locale_string (tbuf + 1);
|
||||
free (tbuf);
|
||||
free (myfmt);
|
||||
#if HAVE_STRUCT_TM_TM_ZONE
|
||||
|
@ -754,16 +754,16 @@ SCM_DEFINE (scm_strptime, "strptime", 2, 0, 0,
|
|||
{
|
||||
struct tm t;
|
||||
char *fmt, *str, *rest;
|
||||
size_t used_len;
|
||||
SCM used_len;
|
||||
long zoff;
|
||||
|
||||
SCM_VALIDATE_STRING (1, format);
|
||||
SCM_VALIDATE_STRING (2, string);
|
||||
|
||||
/* Convert strings to UTF-8 so that non-ASCII characters are passed
|
||||
through unchanged. */
|
||||
fmt = scm_to_utf8_string (format);
|
||||
str = scm_to_utf8_string (string);
|
||||
/* Convert strings to the locale encoding, as the underlying
|
||||
'strptime' C function expects. */
|
||||
fmt = scm_to_locale_string (format);
|
||||
str = scm_to_locale_string (string);
|
||||
|
||||
/* initialize the struct tm */
|
||||
#define tm_init(field) t.field = 0
|
||||
|
@ -807,14 +807,14 @@ SCM_DEFINE (scm_strptime, "strptime", 2, 0, 0,
|
|||
zoff = 0;
|
||||
#endif
|
||||
|
||||
/* Compute the number of UTF-8 characters. */
|
||||
used_len = u8_strnlen ((scm_t_uint8*) str, rest-str);
|
||||
/* Compute the number of characters parsed. */
|
||||
used_len = scm_string_length (scm_from_locale_stringn (str, rest-str));
|
||||
scm_remember_upto_here_2 (format, string);
|
||||
free (str);
|
||||
free (fmt);
|
||||
|
||||
return scm_cons (filltime (&t, zoff, NULL),
|
||||
scm_from_signed_integer (used_len));
|
||||
used_len);
|
||||
}
|
||||
#undef FUNC_NAME
|
||||
#endif /* HAVE_STRPTIME */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
;;;; time.test --- test suite for Guile's time functions -*- scheme -*-
|
||||
;;;; Jim Blandy <jimb@red-bean.com> --- June 1999, 2004
|
||||
;;;;
|
||||
;;;; Copyright (C) 1999, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
;;;; Copyright (C) 1999, 2004, 2006, 2007, 2008, 2019 Free Software Foundation, Inc.
|
||||
;;;;
|
||||
;;;; This library is free software; you can redistribute it and/or
|
||||
;;;; modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -204,8 +204,9 @@
|
|||
|
||||
(pass-if-equal "strftime passes wide characters"
|
||||
"\u0100"
|
||||
(let ((t (localtime (current-time))))
|
||||
(substring (strftime "\u0100%Z" t) 0 1)))
|
||||
(with-locale "en_US.utf8"
|
||||
(let ((t (localtime (current-time))))
|
||||
(substring (strftime "\u0100%Z" t) 0 1))))
|
||||
|
||||
(with-test-prefix "C99 %z format"
|
||||
|
||||
|
@ -229,7 +230,17 @@
|
|||
(putenv "TZ=EST+5")
|
||||
(tzset)
|
||||
(let ((tm (localtime 86400)))
|
||||
(strftime "%z" tm))))))
|
||||
(strftime "%z" tm))))
|
||||
|
||||
(pass-if-equal "strftime fr_FR.utf8"
|
||||
" 1 février 1970"
|
||||
(with-locale "fr_FR.utf8"
|
||||
(strftime "%e %B %Y" (gmtime (* 31 24 3600)))))
|
||||
|
||||
(pass-if-equal "strftime fr_FR.iso88591" ;<https://bugs.gnu.org/35920>
|
||||
" 1 février 1970"
|
||||
(with-locale "fr_FR.iso88591"
|
||||
(strftime "%e %B %Y" (gmtime (* 31 24 3600)))))))
|
||||
|
||||
;;;
|
||||
;;; strptime
|
||||
|
@ -261,6 +272,22 @@
|
|||
(let ((tm (car (strptime "%s" "86400"))))
|
||||
(eqv? 0 (tm:gmtoff tm))))
|
||||
|
||||
(pass-if-equal "strftime fr_FR.utf8"
|
||||
'(1 2 1999)
|
||||
(with-locale "fr_FR.utf8"
|
||||
(let ((tm (car (strptime "%e %B %Y" " 1 février 1999"))))
|
||||
(list (tm:mday tm)
|
||||
(+ 1 (tm:mon tm))
|
||||
(+ 1900 (tm:year tm))))))
|
||||
|
||||
(pass-if-equal "strftime fr_FR.iso88591" ;<https://bugs.gnu.org/35920>
|
||||
'(1 2 1999)
|
||||
(with-locale "fr_FR.iso88591"
|
||||
(let ((tm (car (strptime "%e %B %Y" " 1 février 1999"))))
|
||||
(list (tm:mday tm)
|
||||
(+ 1 (tm:mon tm))
|
||||
(+ 1900 (tm:year tm))))))
|
||||
|
||||
;; prior to guile 1.6.9 and 1.8.1 we didn't pass tm_gmtoff back from
|
||||
;; strptime
|
||||
(pass-if "gmtoff on EST+5"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue