From 01b5499eea24961f0163b0ca3728c649aad53bbf Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 24 Aug 2019 15:45:33 -0400 Subject: [PATCH 1/2] vim-patch:7.4.1407 Problem: json_encode() does not handle NaN and inf properly. (David Barnett) Solution: For JSON turn them into "null". For JS use "NaN" and "Infinity". Add isnan(). https://github.com/vim/vim/commit/f1b6ac72293e658bb6e68c5cfd926c405b1b6f34 --- runtime/doc/eval.txt | 5 +++++ src/nvim/eval.c | 7 +++++++ src/nvim/eval.lua | 1 + src/nvim/testdir/test_float_func.vim | 1 - 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index de2650baa4..811dbad559 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2190,6 +2190,7 @@ insert({list}, {item} [, {idx}]) invert({expr}) Number bitwise invert isdirectory({directory}) Number |TRUE| if {directory} is a directory islocked({expr}) Number |TRUE| if {expr} is locked +isnan({expr}) Number |TRUE| if {expr} is NaN id({expr}) String identifier of the container items({dict}) List key-value pairs in {dict} jobpid({id}) Number Returns pid of a job. @@ -5319,6 +5320,10 @@ items({dict}) *items()* entry and the value of this entry. The |List| is in arbitrary order. +isnan({expr}) *isnan()* + Return |TRUE| if {expr} is a float with value NaN. > + echo isnan(0.0 / 0.0) +< 1 jobpid({job}) *jobpid()* Return the PID (process id) of |job-id| {job}. diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1570af07d7..94dcbe0dcf 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -47,6 +47,7 @@ #include "nvim/indent_c.h" #include "nvim/indent.h" #include "nvim/mark.h" +#include "nvim/math.h" #include "nvim/mbyte.h" #include "nvim/memline.h" #include "nvim/memory.h" @@ -12028,6 +12029,12 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) clear_lval(&lv); } +// "isnan()" function +static void f_isnan(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT + && xisnan(argvars[0].vval.v_float); +} /// Turn a dictionary into a list /// diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 6b63003e69..bc3e612b0a 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -190,6 +190,7 @@ return { invert={args=1}, isdirectory={args=1}, islocked={args=1}, + isnan={args=1}, id={args=1}, items={args=1}, jobclose={args={1, 2}, func="f_chanclose"}, diff --git a/src/nvim/testdir/test_float_func.vim b/src/nvim/testdir/test_float_func.vim index 5ea5192994..a44c5a9e98 100644 --- a/src/nvim/testdir/test_float_func.vim +++ b/src/nvim/testdir/test_float_func.vim @@ -289,7 +289,6 @@ func Test_trunc() endfunc func Test_isnan() - throw 'skipped: Nvim does not support isnan()' call assert_equal(0, isnan(1.0)) call assert_equal(1, isnan(0.0/0.0)) call assert_equal(0, isnan(1.0/0.0)) From 1dc088ea7dff8921d5580078f31a3a660ee16dc0 Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sat, 24 Aug 2019 16:48:05 -0400 Subject: [PATCH 2/2] vim-patch:8.1.1111: it is not easy to check for infinity Problem: It is not easy to check for infinity. Solution: Add isinf(). (Ozaki Kiichi, closes vim/vim#3787) https://github.com/vim/vim/commit/fda1bff39f89775b20a2d88ef3903656d52f66ad --- runtime/doc/eval.txt | 10 ++++++++++ src/nvim/eval.c | 10 +++++++++- src/nvim/eval.lua | 1 + src/nvim/testdir/test_float_func.vim | 23 +++++++++++++++++------ 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 811dbad559..eac1493a7a 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2189,6 +2189,8 @@ insert({list}, {item} [, {idx}]) List insert {item} in {list} [before {idx}] invert({expr}) Number bitwise invert isdirectory({directory}) Number |TRUE| if {directory} is a directory +isinf({expr}) Number determine if {expr} is infinity value + (positive or negative) islocked({expr}) Number |TRUE| if {expr} is locked isnan({expr}) Number |TRUE| if {expr} is NaN id({expr}) String identifier of the container @@ -5285,6 +5287,14 @@ isdirectory({directory}) *isdirectory()* exist, or isn't a directory, the result is |FALSE|. {directory} is any expression, which is used as a String. +isinf({expr}) *isinf()* + Return 1 if {expr} is a positive infinity, or -1 a negative + infinity, otherwise 0. > + :echo isinf(1.0 / 0.0) +< 1 > + :echo isinf(-1.0 / 0.0) +< -1 + islocked({expr}) *islocked()* *E786* The result is a Number, which is |TRUE| when {expr} is the name of a locked variable. diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 94dcbe0dcf..7b620a03e6 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -11276,7 +11276,6 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr) #endif "tablineat", "tag_binary", - "tag_old_static", "termguicolors", "termresponse", "textobjects", @@ -12029,6 +12028,15 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) clear_lval(&lv); } +// "isinf()" function +static void f_isinf(typval_T *argvars, typval_T *rettv, FunPtr fptr) +{ + if (argvars[0].v_type == VAR_FLOAT + && xisinf(argvars[0].vval.v_float)) { + rettv->vval.v_number = argvars[0].vval.v_float > 0.0 ? 1 : -1; + } +} + // "isnan()" function static void f_isnan(typval_T *argvars, typval_T *rettv, FunPtr fptr) { diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index bc3e612b0a..a21e5a6f5d 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -189,6 +189,7 @@ return { insert={args={2, 3}}, invert={args=1}, isdirectory={args=1}, + isinf={args=1}, islocked={args=1}, isnan={args=1}, id={args=1}, diff --git a/src/nvim/testdir/test_float_func.vim b/src/nvim/testdir/test_float_func.vim index a44c5a9e98..154ef570e0 100644 --- a/src/nvim/testdir/test_float_func.vim +++ b/src/nvim/testdir/test_float_func.vim @@ -288,13 +288,24 @@ func Test_trunc() call assert_fails("call trunc('')", 'E808:') endfunc +func Test_isinf() + call assert_equal(1, isinf(1.0/0.0)) + call assert_equal(-1, isinf(-1.0/0.0)) + call assert_false(isinf(1.0)) + call assert_false(isinf(0.0/0.0)) + call assert_false(isinf('a')) + call assert_false(isinf([])) + call assert_false(isinf({})) +endfunc + func Test_isnan() - call assert_equal(0, isnan(1.0)) - call assert_equal(1, isnan(0.0/0.0)) - call assert_equal(0, isnan(1.0/0.0)) - call assert_equal(0, isnan('a')) - call assert_equal(0, isnan([])) - call assert_equal(0, isnan({})) + call assert_true(isnan(0.0/0.0)) + call assert_false(isnan(1.0)) + call assert_false(isnan(1.0/0.0)) + call assert_false(isnan(-1.0/0.0)) + call assert_false(isnan('a')) + call assert_false(isnan([])) + call assert_false(isnan({})) endfunc " This was converted from test65