From: Mikael Magnusson <mikachu@gmail.com>
To: zsh-workers@zsh.org
Subject: PATCH: ztrftime: Pass everything unhandled to the system strftime()
Date: Thu, 9 Jul 2015 11:58:07 +0200 [thread overview]
Message-ID: <1436435887-28736-1-git-send-email-mikachu@gmail.com> (raw)
In-Reply-To: <20150709094122.17abacc8@pwslap01u.europe.root.pri>
This seems to work, I've added tests, and a comment.
See also threads 35725 and 35734.
---
Src/utils.c | 79 +++++++++++++++++++++++++++++++++++----------------
Test/V09datetime.ztst | 63 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 117 insertions(+), 25 deletions(-)
create mode 100644 Test/V09datetime.ztst
Eagerly awaiting reports of systems that handle %04y but not %#A.
diff --git a/Src/utils.c b/Src/utils.c
index 13fc96a..8ff575f 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -2883,7 +2883,7 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec)
int hr12;
#ifdef HAVE_STRFTIME
int decr;
- char tmp[4];
+ char *fmtstart;
#else
static char *astr[] =
{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
@@ -2899,7 +2899,11 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec)
int strip;
int digs = 3;
+#ifdef HAVE_STRFTIME
+ fmtstart =
+#endif
fmt++;
+
if (*fmt == '-') {
strip = 1;
fmt++;
@@ -2924,6 +2928,21 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec)
*/
if (ztrftimebuf(&bufsize, 2))
return -1;
+#ifdef HAVE_STRFTIME
+ /* Our internal handling doesn't handle padding and other gnu extensions,
+ * so here we detect them and pass over to strftime(). We don't want
+ * to do this unconditionally though, as we have some extensions that
+ * strftime() doesn't have (%., %f, %L and %K) */
+morefmt:
+ if (!((fmt - fmtstart == 1) || (fmt - fmtstart == 2 && strip) || *fmt == '.')) {
+ while (*fmt && strchr("OE^#_-0123456789", *fmt))
+ fmt++;
+ if (*fmt) {
+ fmt++;
+ goto strftimehandling;
+ }
+ }
+#endif
switch (*fmt++) {
case '.':
if (ztrftimebuf(&bufsize, digs))
@@ -2939,10 +2958,10 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec)
sprintf(buf, "%0*ld", digs, usec);
buf += digs;
break;
- case 'd':
- if (tm->tm_mday > 9 || !strip)
- *buf++ = '0' + tm->tm_mday / 10;
- *buf++ = '0' + tm->tm_mday % 10;
+ case '\0':
+ /* Guard against premature end of string */
+ *buf++ = '%';
+ fmt--;
break;
case 'f':
strip = 1;
@@ -2983,6 +3002,12 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec)
*buf++ = '0' + (hr12 % 10);
break;
+#ifndef HAVE_STRFTIME
+ case 'd':
+ if (tm->tm_mday > 9 || !strip)
+ *buf++ = '0' + tm->tm_mday / 10;
+ *buf++ = '0' + tm->tm_mday % 10;
+ break;
case 'm':
if (tm->tm_mon > 8 || !strip)
*buf++ = '0' + (tm->tm_mon + 1) / 10;
@@ -3003,18 +3028,8 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec)
*buf++ = '0' + (tm->tm_year / 10) % 10;
*buf++ = '0' + tm->tm_year % 10;
break;
- case '\0':
- /* Guard against premature end of string */
- *buf++ = '%';
- fmt--;
- break;
-#ifndef HAVE_STRFTIME
case 'Y':
{
- /*
- * Not worth handling this natively if
- * strftime has it.
- */
int year, digits, testyear;
year = tm->tm_year + 1900;
digits = 1;
@@ -3048,24 +3063,38 @@ ztrftime(char *buf, int bufsize, char *fmt, struct tm *tm, long usec)
if (fmt[-1] != '%')
*buf++ = fmt[-1];
#else
+ case 'E':
+ case 'O':
+ case '^':
+ case '#':
+ case '_':
+ case '-':
+ case '0' ... '9':
+ goto morefmt;
+strftimehandling:
default:
/*
* Remember we've already allowed for two characters
* in the accounting in bufsize (but nowhere else).
*/
- *buf = '\1';
- sprintf(tmp, strip ? "%%-%c" : "%%%c", fmt[-1]);
- if (!strftime(buf, bufsize + 2, tmp, tm))
{
- if (*buf) {
- buf[0] = '\0';
- return -1;
+ int size = fmt - fmtstart;
+ char *tmp = zhalloc(size + 1);
+ strncpy(tmp, fmtstart, size);
+ tmp[size] = '\0';
+ *buf = '\1';
+ if (!strftime(buf, bufsize + 2, tmp, tm))
+ {
+ if (*buf) {
+ buf[0] = '\0';
+ return -1;
+ }
+ return 0;
}
- return 0;
+ decr = strlen(buf);
+ buf += decr;
+ bufsize -= decr - 2;
}
- decr = strlen(buf);
- buf += decr;
- bufsize -= decr - 2;
#endif
break;
}
diff --git a/Test/V09datetime.ztst b/Test/V09datetime.ztst
new file mode 100644
index 0000000..c69e31e
--- /dev/null
+++ b/Test/V09datetime.ztst
@@ -0,0 +1,63 @@
+%prep
+
+ if ! (zmodload zsh/datetime >/dev/null 2>/dev/null); then
+ ZTST_unimplemented="can't load the zsh/datetime module for testing"
+ fi
+ setopt multibyte
+ zmodload zsh/datetime
+ unset LC_ALL
+ LC_TIME=C
+ if [[ "$(strftime %04y 1)" = "0070" ]]; then
+ [[ "$(LC_TIME=ja_JP.UTF-8 strftime %OS 1)" = 一 ]] || {
+ print -u $ZTST_fd "Not testing alternate date format extensions (missing ja_JP.UTF-8 locale)"
+ skip_japanese=1
+ }
+ else
+ print -u $ZTST_fd "Skipping strftime extension tests"
+ skip_extensions=1
+ fi
+
+%test
+
+ strftime %y 0
+ strftime %Y 1000000000
+ strftime %x 1200000000
+ strftime %X 1200000001
+0:basic format specifiers
+>70
+>2001
+>01/10/08
+>22:20:01
+
+ strftime %-m_%f_%K_%L 1181000000
+ strftime %6. 0
+0:zsh extensions
+>6_5_1_1
+>000000
+
+ [[ $skip_japanese = 1 ]] && repeat 5; do echo skipped; done || (
+ LC_TIME=ja_JP.UTF-8
+ strftime %Ey 1000000000
+ strftime %Oy 1000000000
+ strftime %Ex 1000000000
+ strftime %OS 1000000000
+ strftime %03Ey 650000000
+ )
+0:alternate format extensions
+*>skipped|13
+>skipped|一
+>skipped|平成13年09月09日
+>skipped|四十
+>skipped|002
+
+ [[ $skip_extensions = 1 ]] && repeat 4; do echo skipped; done || (
+ strftime '%#A' 0
+ strftime '%^_10B' 0
+ strftime %03Ey 650000000
+ strftime %-Oe 0
+ )
+0:various extensions
+*>skipped|THURSDAY
+>skipped| JANUARY
+>skipped|090
+>skipped|1
--
2.4.0
next prev parent reply other threads:[~2015-07-09 10:04 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-07 23:15 PATCH: Make ztrftime pass more things to strftime Mikael Magnusson
2015-07-07 23:21 ` Mikael Magnusson
2015-07-08 10:53 ` Peter Stephenson
2015-07-09 5:16 ` Mikael Magnusson
2015-07-09 8:41 ` Peter Stephenson
2015-07-09 9:58 ` Mikael Magnusson [this message]
2015-07-09 10:17 ` PATCH: ztrftime: Pass everything unhandled to the system strftime() Peter Stephenson
2015-07-10 13:37 ` Peter Stephenson
2015-07-10 16:18 ` Skipping tests (was Re: PATCH: ztrftime: Pass everything ...) Bart Schaefer
2015-07-10 16:23 ` Peter Stephenson
2015-07-10 18:31 ` PATCH: ztrftime: Pass everything unhandled to the system strftime() Daniel Shahaf
2015-07-10 23:54 ` ZTST_skip (was Re: PATCH: ztrftime ...) Bart Schaefer
2015-07-09 15:52 ` PATCH: ztrftime: Pass everything unhandled to the system strftime() Jun T.
2015-07-10 14:53 ` Jun T.
2015-07-10 18:23 ` Mikael Magnusson
2015-07-27 11:56 ` Jun T.
2015-07-27 13:31 ` Mikael Magnusson
2015-07-27 16:50 ` Jun T.
2015-07-27 17:01 ` Jun T.
2015-09-01 13:53 ` Oliver Kiddle
2015-09-01 14:07 ` Peter Stephenson
2015-09-01 21:16 ` PATCH: Avoid gcc case syntax Mikael Magnusson
2015-07-08 14:03 ` PATCH: Make ztrftime pass more things to strftime Jun T.
2015-07-09 4:36 ` Mikael Magnusson
2015-07-08 10:39 ` Peter Stephenson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1436435887-28736-1-git-send-email-mikachu@gmail.com \
--to=mikachu@gmail.com \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).