Mercurial > vim
comparison src/evalfunc.c @ 10555:fff45421182b v8.0.0167
patch 8.0.0167: str2nr()/str2float() fail with negative values
commit https://github.com/vim/vim/commit/08243d26d22ad44a857d02c90071578577b8a55d
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jan 10 16:12:29 2017 +0100
patch 8.0.0167: str2nr()/str2float() fail with negative values
Problem: str2nr() and str2float() do not always work with negative values.
Solution: Be more flexible about handling signs. (LemonBoy, closes https://github.com/vim/vim/issues/1332)
Add more tests.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 10 Jan 2017 16:15:04 +0100 |
parents | f83b6a0b6148 |
children | 82c2c450dad0 |
comparison
equal
deleted
inserted
replaced
10554:9dc3c9de4198 | 10555:fff45421182b |
---|---|
11064 */ | 11064 */ |
11065 static void | 11065 static void |
11066 f_str2float(typval_T *argvars, typval_T *rettv) | 11066 f_str2float(typval_T *argvars, typval_T *rettv) |
11067 { | 11067 { |
11068 char_u *p = skipwhite(get_tv_string(&argvars[0])); | 11068 char_u *p = skipwhite(get_tv_string(&argvars[0])); |
11069 | 11069 int isneg = (*p == '-'); |
11070 if (*p == '+') | 11070 |
11071 if (*p == '+' || *p == '-') | |
11071 p = skipwhite(p + 1); | 11072 p = skipwhite(p + 1); |
11072 (void)string2float(p, &rettv->vval.v_float); | 11073 (void)string2float(p, &rettv->vval.v_float); |
11074 if (isneg) | |
11075 rettv->vval.v_float *= -1; | |
11073 rettv->v_type = VAR_FLOAT; | 11076 rettv->v_type = VAR_FLOAT; |
11074 } | 11077 } |
11075 #endif | 11078 #endif |
11076 | 11079 |
11077 /* | 11080 /* |
11082 { | 11085 { |
11083 int base = 10; | 11086 int base = 10; |
11084 char_u *p; | 11087 char_u *p; |
11085 varnumber_T n; | 11088 varnumber_T n; |
11086 int what; | 11089 int what; |
11090 int isneg; | |
11087 | 11091 |
11088 if (argvars[1].v_type != VAR_UNKNOWN) | 11092 if (argvars[1].v_type != VAR_UNKNOWN) |
11089 { | 11093 { |
11090 base = (int)get_tv_number(&argvars[1]); | 11094 base = (int)get_tv_number(&argvars[1]); |
11091 if (base != 2 && base != 8 && base != 10 && base != 16) | 11095 if (base != 2 && base != 8 && base != 10 && base != 16) |
11094 return; | 11098 return; |
11095 } | 11099 } |
11096 } | 11100 } |
11097 | 11101 |
11098 p = skipwhite(get_tv_string(&argvars[0])); | 11102 p = skipwhite(get_tv_string(&argvars[0])); |
11099 if (*p == '+') | 11103 isneg = (*p == '-'); |
11104 if (*p == '+' || *p == '-') | |
11100 p = skipwhite(p + 1); | 11105 p = skipwhite(p + 1); |
11101 switch (base) | 11106 switch (base) |
11102 { | 11107 { |
11103 case 2: what = STR2NR_BIN + STR2NR_FORCE; break; | 11108 case 2: what = STR2NR_BIN + STR2NR_FORCE; break; |
11104 case 8: what = STR2NR_OCT + STR2NR_FORCE; break; | 11109 case 8: what = STR2NR_OCT + STR2NR_FORCE; break; |
11105 case 16: what = STR2NR_HEX + STR2NR_FORCE; break; | 11110 case 16: what = STR2NR_HEX + STR2NR_FORCE; break; |
11106 default: what = 0; | 11111 default: what = 0; |
11107 } | 11112 } |
11108 vim_str2nr(p, NULL, NULL, what, &n, NULL, 0); | 11113 vim_str2nr(p, NULL, NULL, what, &n, NULL, 0); |
11109 rettv->vval.v_number = n; | 11114 if (isneg) |
11115 rettv->vval.v_number = -n; | |
11116 else | |
11117 rettv->vval.v_number = n; | |
11118 | |
11110 } | 11119 } |
11111 | 11120 |
11112 #ifdef HAVE_STRFTIME | 11121 #ifdef HAVE_STRFTIME |
11113 /* | 11122 /* |
11114 * "strftime({format}[, {time}])" function | 11123 * "strftime({format}[, {time}])" function |