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().
Files:      src/eval.c, src/json.c, src/testdir/test_json.vim


*** ../vim-7.4.1406/src/eval.c  2016-02-23 17:13:56.877032330 +0100
--- src/eval.c  2016-02-23 21:19:22.203128950 +0100
***************
*** 628,633 ****
--- 628,636 ----
  static void f_invert(typval_T *argvars, typval_T *rettv);
  static void f_isdirectory(typval_T *argvars, typval_T *rettv);
  static void f_islocked(typval_T *argvars, typval_T *rettv);
+ #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+ static void f_isnan(typval_T *argvars, typval_T *rettv);
+ #endif
  static void f_items(typval_T *argvars, typval_T *rettv);
  #ifdef FEAT_JOB
  # ifdef FEAT_CHANNEL
***************
*** 8320,8325 ****
--- 8323,8331 ----
      {"invert",                1, 1, f_invert},
      {"isdirectory",   1, 1, f_isdirectory},
      {"islocked",      1, 1, f_islocked},
+ #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+     {"isnan",         1, 1, f_isnan},
+ #endif
      {"items",         1, 1, f_items},
  #ifdef FEAT_JOB
  # ifdef FEAT_CHANNEL
***************
*** 14740,14745 ****
--- 14746,14763 ----
      clear_lval(&lv);
  }
  
+ #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+ /*
+  * "isnan()" function
+  */
+     static void
+ f_isnan(typval_T *argvars, typval_T *rettv)
+ {
+     rettv->vval.v_number = argvars[0].v_type == VAR_FLOAT
+                                           && isnan(argvars[0].vval.v_float);
+ }
+ #endif
+ 
  static void dict_list(typval_T *argvars, typval_T *rettv, int what);
  
  /*
*** ../vim-7.4.1406/src/json.c  2016-02-20 15:26:38.299827771 +0100
--- src/json.c  2016-02-23 21:11:39.991974796 +0100
***************
*** 16,21 ****
--- 16,27 ----
  #include "vim.h"
  
  #if defined(FEAT_EVAL) || defined(PROTO)
+ 
+ #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
+   /* for isnan() and isinf() */
+ # include <math.h>
+ #endif
+ 
  static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int 
options);
  static int json_decode_item(js_read_T *reader, typval_T *res, int options);
  
***************
*** 267,274 ****
  
        case VAR_FLOAT:
  #ifdef FEAT_FLOAT
!           vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float);
!           ga_concat(gap, numbuf);
            break;
  #endif
        case VAR_UNKNOWN:
--- 273,292 ----
  
        case VAR_FLOAT:
  #ifdef FEAT_FLOAT
! # if defined(HAVE_MATH_H)
!           if ((options & JSON_JS) && isnan(val->vval.v_float))
!               ga_concat(gap, (char_u *)"NaN");
!           else if ((options & JSON_JS) && isinf(val->vval.v_float))
!               ga_concat(gap, (char_u *)"Infinity");
!           else if (isnan(val->vval.v_float) || isinf(val->vval.v_float))
!               ga_concat(gap, (char_u *)"null");
!           else
! # endif
!           {
!               vim_snprintf((char *)numbuf, NUMBUFLEN, "%g",
!                                                          val->vval.v_float);
!               ga_concat(gap, numbuf);
!           }
            break;
  #endif
        case VAR_UNKNOWN:
***************
*** 720,728 ****
                }
                return OK;
            }
            /* check for truncated name */
            len = (int)(reader->js_end - (reader->js_buf + reader->js_used));
!           if ((len < 5 && STRNICMP((char *)p, "false", len) == 0)
                    || (len < 4 && (STRNICMP((char *)p, "true", len) == 0
                               ||  STRNICMP((char *)p, "null", len) == 0)))
                return MAYBE;
--- 738,773 ----
                }
                return OK;
            }
+ #ifdef FEAT_FLOAT
+           if (STRNICMP((char *)p, "NaN", 3) == 0)
+           {
+               reader->js_used += 3;
+               if (res != NULL)
+               {
+                   res->v_type = VAR_FLOAT;
+                   res->vval.v_float = 0.0 / 0.0;
+               }
+               return OK;
+           }
+           if (STRNICMP((char *)p, "Infinity", 8) == 0)
+           {
+               reader->js_used += 8;
+               if (res != NULL)
+               {
+                   res->v_type = VAR_FLOAT;
+                   res->vval.v_float = 1.0 / 0.0;
+               }
+               return OK;
+           }
+ #endif
            /* check for truncated name */
            len = (int)(reader->js_end - (reader->js_buf + reader->js_used));
!           if (
!                   (len < 5 && STRNICMP((char *)p, "false", len) == 0)
! #ifdef FEAT_FLOAT
!                   || (len < 8 && STRNICMP((char *)p, "Infinity", len) == 0)
!                   || (len < 3 && STRNICMP((char *)p, "NaN", len) == 0)
! #endif
                    || (len < 4 && (STRNICMP((char *)p, "true", len) == 0
                               ||  STRNICMP((char *)p, "null", len) == 0)))
                return MAYBE;
*** ../vim-7.4.1406/src/testdir/test_json.vim   2016-02-11 21:08:27.544531244 
+0100
--- src/testdir/test_json.vim   2016-02-23 21:25:52.651035682 +0100
***************
*** 16,23 ****
  let s:varmb = "s¢cĴgё"
  let s:jsonnr = '1234'
  let s:varnr = 1234
! let s:jsonfl = '12.34'
! let s:varfl = 12.34
  
  let s:jsonl1 = '[1,"a",3]'
  let s:varl1 = [1, "a", 3]
--- 16,31 ----
  let s:varmb = "s¢cĴgё"
  let s:jsonnr = '1234'
  let s:varnr = 1234
! if has('float')
!   let s:jsonfl = '12.34'
!   let s:varfl = 12.34
!   let s:jsoninf = 'null'
!   let s:jsinf = 'Infinity'
!   let s:varinf = 1.0 / 0.0
!   let s:jsonnan = 'null'
!   let s:jsnan = 'NaN'
!   let s:varnan = 0.0 / 0.0
! endif
  
  let s:jsonl1 = '[1,"a",3]'
  let s:varl1 = [1, "a", 3]
***************
*** 68,73 ****
--- 76,83 ----
    call assert_equal(s:jsonnr, json_encode(s:varnr))
    if has('float')
      call assert_equal(s:jsonfl, json_encode(s:varfl))
+     call assert_equal(s:jsoninf, json_encode(s:varinf))
+     call assert_equal(s:jsonnan, json_encode(s:varnan))
    endif
  
    call assert_equal(s:jsonl1, json_encode(s:varl1))
***************
*** 165,170 ****
--- 175,182 ----
    call assert_equal(s:jsonnr, js_encode(s:varnr))
    if has('float')
      call assert_equal(s:jsonfl, js_encode(s:varfl))
+     call assert_equal(s:jsinf, js_encode(s:varinf))
+     call assert_equal(s:jsnan, js_encode(s:varnan))
    endif
  
    call assert_equal(s:jsonl1, js_encode(s:varl1))
***************
*** 201,206 ****
--- 213,220 ----
    call assert_equal(s:varnr, js_decode(s:jsonnr))
    if has('float')
      call assert_equal(s:varfl, js_decode(s:jsonfl))
+     call assert_equal(s:varinf, js_decode(s:jsinf))
+     call assert_true(isnan(js_decode(s:jsnan)))
    endif
  
    call assert_equal(s:varl1, js_decode(s:jsonl1))
*** ../vim-7.4.1406/src/version.c       2016-02-23 20:43:58.725419739 +0100
--- src/version.c       2016-02-23 21:24:12.216088576 +0100
***************
*** 750,751 ****
--- 750,753 ----
  {   /* Add new patch number below this line */
+ /**/
+     1407,
  /**/

-- 
Two cows are standing together in a field.  One asks the other:
"So what do you think about this Mad Cow Disease?"
The other replies: "That doesn't concern me. I'm a helicopter."

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui