mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-19 11:31:26 +01:00
35745: ztrftime: Pass everything unhandled to the system strftime()
This commit is contained in:
parent
5951ac13ed
commit
e402747dd6
3 changed files with 122 additions and 25 deletions
|
@ -1,3 +1,8 @@
|
|||
2015-07-09 Mikael Magnusson <mikachu@gmail.com>
|
||||
|
||||
* 35745: Src/utils.c, Test/V09datetime.ztst: ztrftime: Pass
|
||||
everything unhandled to the system strftime()
|
||||
|
||||
2015-07-09 Oliver Kiddle <opk@zsh.org>
|
||||
|
||||
* 35748: Completion/Zsh/Type/_ps1234,
|
||||
|
|
79
Src/utils.c
79
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;
|
||||
}
|
||||
|
|
63
Test/V09datetime.ztst
Normal file
63
Test/V09datetime.ztst
Normal file
|
@ -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
|
Loading…
Reference in a new issue