Skip to content

Commit 08243d2

Browse files
committed
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 #1332) Add more tests.
1 parent 03c60c1 commit 08243d2

File tree

6 files changed

+47
-3
lines changed

6 files changed

+47
-3
lines changed

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,6 +2091,7 @@ test_arglist \
20912091
test_delete \
20922092
test_diffmode \
20932093
test_digraph \
2094+
test_functions \
20942095
test_display \
20952096
test_ex_undo \
20962097
test_execute_func \

src/evalfunc.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11066,10 +11066,13 @@ f_sqrt(typval_T *argvars, typval_T *rettv)
1106611066
f_str2float(typval_T *argvars, typval_T *rettv)
1106711067
{
1106811068
char_u *p = skipwhite(get_tv_string(&argvars[0]));
11069+
int isneg = (*p == '-');
1106911070

11070-
if (*p == '+')
11071+
if (*p == '+' || *p == '-')
1107111072
p = skipwhite(p + 1);
1107211073
(void)string2float(p, &rettv->vval.v_float);
11074+
if (isneg)
11075+
rettv->vval.v_float *= -1;
1107311076
rettv->v_type = VAR_FLOAT;
1107411077
}
1107511078
#endif
@@ -11084,6 +11087,7 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
1108411087
char_u *p;
1108511088
varnumber_T n;
1108611089
int what;
11090+
int isneg;
1108711091

1108811092
if (argvars[1].v_type != VAR_UNKNOWN)
1108911093
{
@@ -11096,7 +11100,8 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
1109611100
}
1109711101

1109811102
p = skipwhite(get_tv_string(&argvars[0]));
11099-
if (*p == '+')
11103+
isneg = (*p == '-');
11104+
if (*p == '+' || *p == '-')
1110011105
p = skipwhite(p + 1);
1110111106
switch (base)
1110211107
{
@@ -11106,7 +11111,11 @@ f_str2nr(typval_T *argvars, typval_T *rettv)
1110611111
default: what = 0;
1110711112
}
1110811113
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+
1111011119
}
1111111120

1111211121
#ifdef HAVE_STRFTIME

src/testdir/test_alot.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ source test_filter_cmd.vim
1818
source test_filter_map.vim
1919
source test_float_func.vim
2020
source test_fnamemodify.vim
21+
source test_functions.vim
2122
source test_glob2regpat.vim
2223
source test_goto.vim
2324
source test_help_tagjump.vim

src/testdir/test_float_func.vim

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,22 @@ endfunc
165165

166166
func Test_str2float()
167167
call assert_equal('1.0', string(str2float('1')))
168+
call assert_equal('1.0', string(str2float(' 1 ')))
169+
call assert_equal('1.0', string(str2float(' 1.0 ')))
168170
call assert_equal('1.23', string(str2float('1.23')))
169171
call assert_equal('1.23', string(str2float('1.23abc')))
170172
call assert_equal('1.0e40', string(str2float('1e40')))
173+
174+
call assert_equal('1.0', string(str2float('+1')))
175+
call assert_equal('1.0', string(str2float('+1')))
176+
call assert_equal('1.0', string(str2float(' +1 ')))
177+
call assert_equal('1.0', string(str2float(' + 1 ')))
178+
179+
call assert_equal('-1.0', string(str2float('-1')))
180+
call assert_equal('-1.0', string(str2float('-1')))
181+
call assert_equal('-1.0', string(str2float(' -1 ')))
182+
call assert_equal('-1.0', string(str2float(' - 1 ')))
183+
171184
call assert_equal('inf', string(str2float('1e1000')))
172185
call assert_equal('inf', string(str2float('inf')))
173186
call assert_equal('-inf', string(str2float('-inf')))

src/testdir/test_functions.vim

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
" Tests for various functions.
2+
3+
func Test_str2nr()
4+
call assert_equal(0, str2nr(''))
5+
call assert_equal(1, str2nr('1'))
6+
call assert_equal(1, str2nr(' 1 '))
7+
8+
call assert_equal(1, str2nr('+1'))
9+
call assert_equal(1, str2nr('+ 1'))
10+
call assert_equal(1, str2nr(' + 1 '))
11+
12+
call assert_equal(-1, str2nr('-1'))
13+
call assert_equal(-1, str2nr('- 1'))
14+
call assert_equal(-1, str2nr(' - 1 '))
15+
16+
call assert_equal(123456789, str2nr('123456789'))
17+
call assert_equal(-123456789, str2nr('-123456789'))
18+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
167,
767769
/**/
768770
166,
769771
/**/

0 commit comments

Comments
 (0)