From 3261ba98a2c0f7644bbaf7890a3906c42cfdb807 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sun, 6 Dec 2020 01:15:43 -0500 Subject: vim-patch:8.1.2326: cannot parse a date/time string Problem: Cannot parse a date/time string. Solution: Add strptime(). (Stephen Wall, closes #) https://github.com/vim/vim/commit/10455d43fef041309ce0613fa792c635dd71e3a8 N/A patches for version.c: vim-patch:8.1.2344: Cygwin: warning for using strptime() Problem: Cygwin: warning for using strptime(). Solution: Move defining _XOPEN_SOURCE and __USE_XOPEN to vim.h. (Ken Takata, closes vim/vim#5265) Use 700 for _XOPEN_SOURCE for mkdtemp(). https://github.com/vim/vim/commit/6a228c6463935a73c8f21142cb7368545cfee317 --- src/nvim/eval.lua | 1 + src/nvim/eval/funcs.c | 30 ++++++++++++++++++++++++++++++ src/nvim/os/time.c | 16 ++++++++++++++++ src/nvim/testdir/test_functions.vim | 29 ++++++++++++++++++++++++++--- 4 files changed, 73 insertions(+), 3 deletions(-) (limited to 'src/nvim') diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index e94d7831b0..d1a3ae3ff8 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -341,6 +341,7 @@ return { string={args=1}, strlen={args=1}, strpart={args={2, 4}}, + strptime={args=2}, strridx={args={2, 3}}, strtrans={args=1}, strwidth={args=1}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 01d23654de..145a7a4733 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -10189,6 +10189,36 @@ static void f_strpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_string = (char_u *)xmemdupz(p + n, (size_t)len); } +// "strptime({format}, {timestring})" function +static void f_strptime(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + char fmt_buf[NUMBUFLEN]; + char str_buf[NUMBUFLEN]; + + struct tm tmval = { 0 }; + char *fmt = (char *)tv_get_string_buf(&argvars[0], fmt_buf); + char *str = (char *)tv_get_string_buf(&argvars[1], str_buf); + + vimconv_T conv = { + .vc_type = CONV_NONE, + }; + char_u *enc = enc_locale(); + convert_setup(&conv, p_enc, enc); + if (conv.vc_type != CONV_NONE) { + fmt = (char *)string_convert(&conv, (char_u *)fmt, NULL); + } + if (fmt == NULL + || os_strptime(str, fmt, &tmval) == NULL + || (rettv->vval.v_number = mktime(&tmval)) == -1) { + rettv->vval.v_number = 0; + } + if (conv.vc_type != CONV_NONE) { + xfree(fmt); + } + convert_setup(&conv, NULL, NULL); + xfree(enc); +} + /* * "strridx()" function */ diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 5cf628935f..e7e0dc4013 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -196,6 +196,22 @@ char *os_ctime(char *result, size_t result_len) return os_ctime_r(&rawtime, result, result_len); } +/// Portable version of POSIX strptime() +/// +/// @param str[in] string to convert +/// @param format[in] format to parse "str" +/// @param tm[out] time representation of "str" +/// @return Pointer to first unprocessed character or NULL +char *os_strptime(const char *str, const char *format, struct tm *tm) + FUNC_ATTR_NONNULL_ALL +{ +#ifdef HAVE_STRPTIME + return strptime(str, format, tm); +#else + return NULL; +#endif +} + /// Obtains the current Unix timestamp. /// /// @return Seconds since epoch. diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 5dae8d681a..5efd27d016 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -1,5 +1,7 @@ " Tests for various functions. + source shared.vim +source check.vim " Must be done first, since the alternate buffer must be unset. func Test_00_bufexists() @@ -171,9 +173,8 @@ func Test_str2nr() endfunc func Test_strftime() - if !exists('*strftime') - return - endif + 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(). @@ -214,6 +215,28 @@ func Test_strftime() 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() if !has('unix') return -- cgit From 93e9cf4b6c24945a7fda9e624b73cf8c315994e7 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sun, 6 Dec 2020 11:02:06 -0500 Subject: vim-patch:8.1.2398: strptime() test fails on Japanese Mac Problem: strptime() test fails on Japanese Mac. Solution: Use %T instead of %X. https://github.com/vim/vim/commit/9a838fe543b69582b0773f7c38a57f16fb32d765 --- src/nvim/testdir/test_functions.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim') diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 5efd27d016..ea75aec52c 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -223,7 +223,7 @@ func Test_strptime() endif let $TZ = 'UTC' - call assert_equal(1484653763, strptime('%Y-%m-%d %X', '2017-01-17 11:49:23')) + call assert_equal(1484653763, strptime('%Y-%m-%d %T', '2017-01-17 11:49:23')) call assert_fails('call strptime()', 'E119:') call assert_fails('call strptime("xxx")', 'E119:') -- cgit From a7e0b0edbc2143b4efd6beda0498ef18789a2bdf Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sun, 6 Dec 2020 11:05:22 -0500 Subject: vim-patch:8.2.0949: strptime() does not use DST MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Strptime() does not use DST. Solution: Set the tm_isdst field to -1. (Tomáš Janoušek, closes vim/vim#6230) https://github.com/vim/vim/commit/ea1233fccf4f52f2b4eaab3788a087878d1336fc --- src/nvim/eval/funcs.c | 4 +++- src/nvim/testdir/test_functions.vim | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/nvim') diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 145a7a4733..650b4e3882 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -10195,7 +10195,9 @@ static void f_strptime(typval_T *argvars, typval_T *rettv, FunPtr fptr) char fmt_buf[NUMBUFLEN]; char str_buf[NUMBUFLEN]; - struct tm tmval = { 0 }; + struct tm tmval = { + .tm_isdst = -1, + }; char *fmt = (char *)tv_get_string_buf(&argvars[0], fmt_buf); char *str = (char *)tv_get_string_buf(&argvars[1], str_buf); diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index ea75aec52c..145da3070b 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -225,6 +225,10 @@ func Test_strptime() call assert_equal(1484653763, strptime('%Y-%m-%d %T', '2017-01-17 11:49:23')) + " Force DST and check that it's considered + let $TZ = 'WINTER0SUMMER,J1,J365' + call assert_equal(1484653763 - 3600, strptime('%Y-%m-%d %T', '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", '')) -- cgit From 423f3bc3e2d6aa8245a2cda1c4e7663387383ab7 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 27 Mar 2021 10:55:11 -0400 Subject: test/old: skip Test_strptime() on Windows POSIX strptime does not exist in Windows. There is a C++ workaround but I don't know how to use it. Julia ported BSD's "strptime()" but I can't compile the file or embed the relevant code into src/nvim/os/time.c I cannot use "#ifdef" in eval.lua because of function hashing. "#ifdef" is required to point "strptime()" to NULL such that "CheckFunction strptime" fails. --- src/nvim/testdir/test_functions.vim | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim') diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index 145da3070b..555f549743 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -217,6 +217,7 @@ endfunc func Test_strptime() CheckFunction strptime + CheckNotMSWindows if exists('$TZ') let tz = $TZ -- cgit