Patch 8.1.2326

32 views
Skip to first unread message

Bram Moolenaar

unread,
Nov 21, 2019, 9:37:11 AM11/21/19
to vim...@googlegroups.com

Patch 8.1.2326
Problem: Cannot parse a date/time string.
Solution: Add strptime(). (Stephen Wall, closes #)
Files: runtime/doc/eval.txt, runtime/doc/usr_41.txt, src/auto/configure,
src/config.h.in, src/configure.ac, src/evalfunc.c, src/os_unix.h,
src/testdir/test_functions.vim


*** ../vim-8.1.2325/runtime/doc/eval.txt 2019-11-16 18:21:57.986848040 +0100
--- runtime/doc/eval.txt 2019-11-21 15:04:08.613993187 +0100
***************
*** 2770,2776 ****
strcharpart({str}, {start} [, {len}])
String {len} characters of {str} at {start}
strdisplaywidth({expr} [, {col}]) Number display length of the String {expr}
! strftime({format} [, {time}]) String time in specified format
strgetchar({str}, {index}) Number get char {index} from {str}
stridx({haystack}, {needle} [, {start}])
Number index of {needle} in {haystack}
--- 2770,2776 ----
strcharpart({str}, {start} [, {len}])
String {len} characters of {str} at {start}
strdisplaywidth({expr} [, {col}]) Number display length of the String {expr}
! strftime({format} [, {time}]) String format time with a specified format
strgetchar({str}, {index}) Number get char {index} from {str}
stridx({haystack}, {needle} [, {start}])
Number index of {needle} in {haystack}
***************
*** 2778,2783 ****
--- 2778,2785 ----
strlen({expr}) Number length of the String {expr}
strpart({str}, {start} [, {len}])
String {len} characters of {str} at {start}
+ strptime({format}, {timestring})
+ Number Convert {timestring} to unix timestamp
strridx({haystack}, {needle} [, {start}])
Number last index of {needle} in {haystack}
strtrans({expr}) String translate string to make it printable
***************
*** 2885,2891 ****
win_id2win({expr}) Number get window nr from window ID
win_screenpos({nr}) List get screen position of window {nr}
win_splitmove({nr}, {target} [, {options}])
! none move window {nr} to split of {target}
winbufnr({nr}) Number buffer number of window {nr}
wincol() Number window column of the cursor
winheight({nr}) Number height of window {nr}
--- 2887,2893 ----
win_id2win({expr}) Number get window nr from window ID
win_screenpos({nr}) List get screen position of window {nr}
win_splitmove({nr}, {target} [, {options}])
! Number move window {nr} to split of {target}
winbufnr({nr}) Number buffer number of window {nr}
wincol() Number window column of the cursor
winheight({nr}) Number height of window {nr}
***************
*** 6608,6614 ****

localtime() *localtime()*
Return the current time, measured as seconds since 1st Jan
! 1970. See also |strftime()| and |getftime()|.


log({expr}) *log()*
--- 6616,6622 ----

localtime() *localtime()*
Return the current time, measured as seconds since 1st Jan
! 1970. See also |strftime()|, |strptime()| and |getftime()|.


log({expr}) *log()*
***************
*** 7054,7059 ****
--- 7062,7068 ----

Can also be used as a |method|: >
GetText()->matchstrpos('word')
+ <
*max()*
max({expr}) Return the maximum value of all items in {expr}.
{expr} can be a list or a dictionary. For a dictionary,
***************
*** 9242,9248 ****
{format} depends on your system, thus this is not portable!
See the manual page of the C function strftime() for the
format. The maximum length of the result is 80 characters.
! See also |localtime()| and |getftime()|.
The language can be changed with the |:language| command.
Examples: >
:echo strftime("%c") Sun Apr 27 11:49:23 1997
--- 9269,9275 ----
{format} depends on your system, thus this is not portable!
See the manual page of the C function strftime() for the
format. The maximum length of the result is 80 characters.
! See also |localtime()|, |getftime()| and |strptime()|.
The language can be changed with the |:language| command.
Examples: >
:echo strftime("%c") Sun Apr 27 11:49:23 1997
***************
*** 9287,9292 ****
--- 9314,9320 ----

Can also be used as a |method|: >
GetHaystack()->stridx(needle)
+ <
*string()*
string({expr}) Return {expr} converted to a String. If {expr} is a Number,
Float, String, Blob or a composition of them, then the result
***************
*** 9342,9347 ****
--- 9370,9403 ----
Can also be used as a |method|: >
GetText()->strpart(5)

+ strptime({format}, {timestring}) *strptime()*
+ The result is a Number, which is a unix timestamp representing
+ the date and time in {timestring}, which is expected to match
+ the format specified in {format}.
+
+ The accepted {format} depends on your system, thus this is not
+ portable! See the manual page of the C function strptime()
+ for the format. Especially avoid "%c". The value of $TZ also
+ matters.
+
+ If the {timestring} cannot be parsed with {format} zero is
+ returned. If you do not know the format of {timestring} you
+ can try different {format} values until you get a non-zero
+ result.
+
+ See also |strftime()|.
+ Examples: >
+ :echo strptime("%Y %b %d %X", "1997 Apr 27 11:49:23")
+ < 862156163 >
+ :echo strftime("%c", strptime("%y%m%d %T", "970427 11:53:55"))
+ < Sun Apr 27 11:53:55 1997 >
+ :echo strftime("%c", strptime("%Y%m%d%H%M%S", "19970427115355") + 3600)
+ < Sun Apr 27 12:53:55 1997
+
+ Not available on all systems. To check use: >
+ :if exists("*strptime")
+
+
strridx({haystack}, {needle} [, {start}]) *strridx()*
The result is a Number, which gives the byte index in
{haystack} of the last occurrence of the String {needle}.
*** ../vim-8.1.2325/runtime/doc/usr_41.txt 2019-07-13 21:18:51.468469559 +0200
--- runtime/doc/usr_41.txt 2019-11-21 13:50:04.513247470 +0100
***************
*** 796,801 ****
--- 796,802 ----
getftime() get last modification time of a file
localtime() get current time in seconds
strftime() convert time to a string
+ strptime() convert a date/time string to time
reltime() get the current or elapsed time accurately
reltimestr() convert reltime() result to a string
reltimefloat() convert reltime() result to a Float
*** ../vim-8.1.2325/src/auto/configure 2019-11-17 19:07:38.341132068 +0100
--- src/auto/configure 2019-11-21 14:07:02.679652312 +0100
***************
*** 12572,12579 ****
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \
! strnicmp strpbrk strtol tgetent towlower towupper iswupper tzset \
! usleep utime utimes mblen ftruncate unsetenv posix_openpt
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
--- 12572,12579 ----
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \
! strnicmp strpbrk strptime strtol tgetent towlower towupper iswupper \
! tzset usleep utime utimes mblen ftruncate unsetenv posix_openpt
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
*** ../vim-8.1.2325/src/config.h.in 2019-06-18 22:53:19.014129858 +0200
--- src/config.h.in 2019-11-21 13:45:23.988516112 +0100
***************
*** 206,211 ****
--- 206,212 ----
#undef HAVE_STRNCASECMP
#undef HAVE_STRNICMP
#undef HAVE_STRPBRK
+ #undef HAVE_STRPTIME
#undef HAVE_STRTOL
#undef HAVE_CANBERRA
#undef HAVE_ST_BLKSIZE
*** ../vim-8.1.2325/src/configure.ac 2019-11-17 19:07:38.337132077 +0100
--- src/configure.ac 2019-11-21 13:45:23.988516112 +0100
***************
*** 3744,3751 ****
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \
! strnicmp strpbrk strtol tgetent towlower towupper iswupper tzset \
! usleep utime utimes mblen ftruncate unsetenv posix_openpt)
AC_FUNC_SELECT_ARGTYPES
AC_FUNC_FSEEKO

--- 3744,3751 ----
memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \
getpgid setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \
sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \
! strnicmp strpbrk strptime strtol tgetent towlower towupper iswupper \
! tzset usleep utime utimes mblen ftruncate unsetenv posix_openpt)
AC_FUNC_SELECT_ARGTYPES
AC_FUNC_FSEEKO

*** ../vim-8.1.2325/src/evalfunc.c 2019-11-16 18:21:57.990848019 +0100
--- src/evalfunc.c 2019-11-21 14:52:42.967501521 +0100
***************
*** 20,27 ****
# include <float.h>
#endif

! #ifdef MACOS_X
! # include <time.h> // for time_t
#endif

#ifdef FEAT_FLOAT
--- 20,27 ----
# include <float.h>
#endif

! #if defined(MACOS_X)
! # include <time.h> // for time_t
#endif

#ifdef FEAT_FLOAT
***************
*** 237,242 ****
--- 237,245 ----
static void f_strlen(typval_T *argvars, typval_T *rettv);
static void f_strcharpart(typval_T *argvars, typval_T *rettv);
static void f_strpart(typval_T *argvars, typval_T *rettv);
+ #ifdef HAVE_STRPTIME
+ static void f_strptime(typval_T *argvars, typval_T *rettv);
+ #endif
static void f_strridx(typval_T *argvars, typval_T *rettv);
static void f_strtrans(typval_T *argvars, typval_T *rettv);
static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv);
***************
*** 738,743 ****
--- 741,749 ----
{"string", 1, 1, FEARG_1, f_string},
{"strlen", 1, 1, FEARG_1, f_strlen},
{"strpart", 2, 3, FEARG_1, f_strpart},
+ #ifdef HAVE_STRPTIME
+ {"strptime", 2, 2, FEARG_1, f_strptime},
+ #endif
{"strridx", 2, 3, FEARG_1, f_strridx},
{"strtrans", 1, 1, FEARG_1, f_strtrans},
{"strwidth", 1, 1, FEARG_1, f_strwidth},
***************
*** 7412,7417 ****
--- 7418,7457 ----
rettv->vval.v_string = vim_strnsave(p + n, len);
}

+ #ifdef HAVE_STRPTIME
+ /*
+ * "strptime({format}, {timestring})" function
+ */
+ static void
+ f_strptime(typval_T *argvars, typval_T *rettv)
+ {
+ struct tm tmval;
+ char_u *fmt;
+ char_u *str;
+ vimconv_T conv;
+ char_u *enc;
+
+ vim_memset(&tmval, NUL, sizeof(tmval));
+ fmt = tv_get_string(&argvars[0]);
+ str = tv_get_string(&argvars[1]);
+
+ conv.vc_type = CONV_NONE;
+ enc = enc_locale();
+ convert_setup(&conv, p_enc, enc);
+ if (conv.vc_type != CONV_NONE)
+ fmt = string_convert(&conv, fmt, NULL);
+ if (fmt == NULL
+ || strptime((char *)str, (char *)fmt, &tmval) == NULL
+ || (rettv->vval.v_number = mktime(&tmval)) == -1)
+ rettv->vval.v_number = 0;
+
+ if (conv.vc_type != CONV_NONE)
+ vim_free(fmt);
+ convert_setup(&conv, NULL, NULL);
+ vim_free(enc);
+ }
+ #endif
+
/*
* "strridx()" function
*/
*** ../vim-8.1.2325/src/os_unix.h 2019-09-04 20:59:10.491409987 +0200
--- src/os_unix.h 2019-11-21 14:25:14.741654669 +0100
***************
*** 127,135 ****
# endif
#endif

#if !defined(HAVE_SYS_TIME_H) || defined(TIME_WITH_SYS_TIME)
! # include <time.h> /* on some systems time.h should not be
! included together with sys/time.h */
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
--- 127,142 ----
# endif
#endif

+ // on some systems time.h should not be included together with sys/time.h
#if !defined(HAVE_SYS_TIME_H) || defined(TIME_WITH_SYS_TIME)
! // Needed for strptime()
! # ifndef _XOPEN_SOURCE
! # define _XOPEN_SOURCE
! # endif
! # ifndef __USE_XOPEN
! # define __USE_XOPEN
! # endif
! # include <time.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
*** ../vim-8.1.2325/src/testdir/test_functions.vim 2019-11-16 18:21:57.990848019 +0100
--- src/testdir/test_functions.vim 2019-11-21 14:55:38.525894449 +0100
***************
*** 181,189 ****
endfunc

func Test_strftime()
! if !exists('*strftime')
! return
! endif
" Format of strftime() depends on system. We assume
" that basic formats tested here are available and
" identical on all systems which support strftime().
--- 181,188 ----
endfunc

func Test_strftime()
! CheckFunction strftime
!
" Format of strftime() depends on system. We assume
" that basic formats tested here are available and
" identical on all systems which support strftime().
***************
*** 222,228 ****
--- 221,248 ----
else
unlet $TZ
endif
+ endfunc
+
+ func Test_strptime()
+ CheckFunction strptime
+
+ if exists('$TZ')
+ let tz = $TZ
+ endif
+ let $TZ = 'UTC'

+ call assert_equal(1484653763, strptime('%Y-%m-%d %X', '2017-01-17 11:49:23'))
+
+ call assert_fails('call strptime()', 'E119:')
+ call assert_fails('call strptime("xxx")', 'E119:')
+ call assert_equal(0, strptime("%Y", ''))
+ call assert_equal(0, strptime("%Y", "xxx"))
+
+ if exists('tz')
+ let $TZ = tz
+ else
+ unlet $TZ
+ endif
endfunc

func Test_resolve_unix()
*** ../vim-8.1.2325/src/version.c 2019-11-21 13:27:02.104312710 +0100
--- src/version.c 2019-11-21 13:50:34.172938327 +0100
***************
*** 743,744 ****
--- 743,746 ----
{ /* Add new patch number below this line */
+ /**/
+ 2326,
/**/

--
hundred-and-one symptoms of being an internet addict:
97. Your mother tells you to remember something, and you look for
a File/Save command.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Jun T

unread,
Dec 6, 2019, 12:30:00 AM12/6/19
to vim_dev


2019年11月21日木曜日 23時37分11秒 UTC+9 Bram Moolenaar:

Patch 8.1.2326
Problem:    Cannot parse a date/time string.
Solution:   Add strptime(). (Stephen Wall, closes #)

*** ../vim-8.1.2325/src/testdir/test_functions.vim        2019-11-16 18:21:57.990848019 +0100
--- src/testdir/test_functions.vim        2019-11-21 14:55:38.525894449 +0100
*** 222,228 ****
--- 221,248 ----
  (snip)

+   call assert_equal(1484653763, strptime('%Y-%m-%d %X', '2017-01-17 11:49:23'))

This fails on macOS with Japanese locale because the format %X is locale dependent.
 Please use '%Y-%m-%d %H:%M:%S' instead.

Bram Moolenaar

unread,
Dec 6, 2019, 6:45:37 AM12/6/19
to vim...@googlegroups.com, Jun T
According to the docs %T is locale independend. Let's try that.

--
Some of the well known MS-Windows errors:
EMEMORY Memory error caused by..., eh...
ELICENSE Your license has expired, give us more money!
EMOUSE Mouse moved, reinstall Windows
EILLEGAL Illegal error, you are not allowed to see this
EVIRUS Undetectable virus found
Reply all
Reply to author
Forward
0 new messages