To: vim_dev@googlegroups.com Subject: Patch 8.2.3315 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3315 Problem: Cannot use single quote in a float number for readability. Solution: Support single quotes like in numbers. (closes #8713) Files: src/typval.c, src/float.c, src/proto/float.pro, src/json.c, src/viminfo.c, src/testdir/test_float_func.vim *** ../vim-8.2.3314/src/typval.c 2021-07-31 19:12:54.100411000 +0200 --- src/typval.c 2021-08-08 15:35:59.098482387 +0200 *************** *** 1704,1709 **** --- 1704,1710 ---- int want_string UNUSED) { int len; + int skip_quotes = current_sctx.sc_version >= 4; #ifdef FEAT_FLOAT char_u *p; int get_float = FALSE; *************** *** 1718,1724 **** if (**arg == '.') p = *arg; else ! p = skipdigits(*arg + 1); if (!want_string && p[0] == '.' && vim_isdigit(p[1])) { get_float = TRUE; --- 1719,1738 ---- if (**arg == '.') p = *arg; else ! { ! p = *arg + 1; ! if (skip_quotes) ! for (;;) ! { ! if (*p == '\'') ! ++p; ! if (!vim_isdigit(*p)) ! break; ! p = skipdigits(p); ! } ! else ! p = skipdigits(p); ! } if (!want_string && p[0] == '.' && vim_isdigit(p[1])) { get_float = TRUE; *************** *** 1740,1746 **** { float_T f; ! *arg += string2float(*arg, &f); if (evaluate) { rettv->v_type = VAR_FLOAT; --- 1754,1760 ---- { float_T f; ! *arg += string2float(*arg, &f, skip_quotes); if (evaluate) { rettv->v_type = VAR_FLOAT; *************** *** 1784,1790 **** varnumber_T n; // decimal, hex or octal number ! vim_str2nr(*arg, NULL, &len, current_sctx.sc_version >= 4 ? STR2NR_NO_OCT + STR2NR_QUOTE : STR2NR_ALL, &n, NULL, 0, TRUE); if (len == 0) --- 1798,1804 ---- varnumber_T n; // decimal, hex or octal number ! vim_str2nr(*arg, NULL, &len, skip_quotes ? STR2NR_NO_OCT + STR2NR_QUOTE : STR2NR_ALL, &n, NULL, 0, TRUE); if (len == 0) *** ../vim-8.2.3314/src/float.c 2021-07-27 22:00:39.745712396 +0200 --- src/float.c 2021-08-08 15:39:45.437854762 +0200 *************** *** 29,35 **** int string2float( char_u *text, ! float_T *value) // result stored here { char *s = (char *)text; float_T f; --- 29,36 ---- int string2float( char_u *text, ! float_T *value, // result stored here ! int skip_quotes) { char *s = (char *)text; float_T f; *************** *** 50,55 **** --- 51,82 ---- *value = NAN; return 3; } + if (skip_quotes && vim_strchr((char_u *)s, '\'') != NULL) + { + char_u buf[100]; + char_u *p = buf; + int quotes = 0; + + vim_strncpy(buf, (char_u *)s, 99); + p = buf; + for (;;) + { + // remove single quotes between digits, not in the exponent + if (*p == '\'') + { + ++quotes; + mch_memmove(p, p + 1, STRLEN(p)); + } + if (!vim_isdigit(*p)) + break; + p = skipdigits(p); + } + s = (char *)buf; + f = strtod(s, &s); + *value = f; + return (int)((char_u *)s - buf) + quotes; + } + f = strtod(s, &s); *value = f; return (int)((char_u *)s - text); *************** *** 488,503 **** { char_u *p; int isneg; if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) return; p = skipwhite(tv_get_string_strict(&argvars[0])); isneg = (*p == '-'); if (*p == '+' || *p == '-') p = skipwhite(p + 1); ! (void)string2float(p, &rettv->vval.v_float); if (isneg) rettv->vval.v_float *= -1; rettv->v_type = VAR_FLOAT; --- 515,533 ---- { char_u *p; int isneg; + int skip_quotes; if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL) return; + skip_quotes = argvars[1].v_type != VAR_UNKNOWN && tv_get_bool(&argvars[1]); + p = skipwhite(tv_get_string_strict(&argvars[0])); isneg = (*p == '-'); if (*p == '+' || *p == '-') p = skipwhite(p + 1); ! (void)string2float(p, &rettv->vval.v_float, skip_quotes); if (isneg) rettv->vval.v_float *= -1; rettv->v_type = VAR_FLOAT; *** ../vim-8.2.3314/src/proto/float.pro 2021-07-04 16:50:50.803781315 +0200 --- src/proto/float.pro 2021-08-08 15:40:02.157808687 +0200 *************** *** 1,5 **** /* float.c */ ! int string2float(char_u *text, float_T *value); void f_abs(typval_T *argvars, typval_T *rettv); void f_acos(typval_T *argvars, typval_T *rettv); void f_asin(typval_T *argvars, typval_T *rettv); --- 1,5 ---- /* float.c */ ! int string2float(char_u *text, float_T *value, int skip_quotes); void f_abs(typval_T *argvars, typval_T *rettv); void f_acos(typval_T *argvars, typval_T *rettv); void f_asin(typval_T *argvars, typval_T *rettv); *** ../vim-8.2.3314/src/json.c 2021-07-27 22:00:39.745712396 +0200 --- src/json.c 2021-08-08 15:01:55.640512660 +0200 *************** *** 791,802 **** { float_T f; ! len = string2float(p, &f); } else { cur_item->v_type = VAR_FLOAT; ! len = string2float(p, &cur_item->vval.v_float); } } else --- 791,803 ---- { float_T f; ! len = string2float(p, &f, FALSE); } else { cur_item->v_type = VAR_FLOAT; ! len = string2float(p, &cur_item->vval.v_float, ! FALSE); } } else *** ../vim-8.2.3314/src/viminfo.c 2021-05-07 17:55:51.971584412 +0200 --- src/viminfo.c 2021-08-08 15:02:03.952491057 +0200 *************** *** 1247,1253 **** (int)(tab - virp->vir_line + 1), TRUE); #ifdef FEAT_FLOAT else if (type == VAR_FLOAT) ! (void)string2float(tab + 1, &tv.vval.v_float); #endif else { --- 1247,1253 ---- (int)(tab - virp->vir_line + 1), TRUE); #ifdef FEAT_FLOAT else if (type == VAR_FLOAT) ! (void)string2float(tab + 1, &tv.vval.v_float, FALSE); #endif else { *** ../vim-8.2.3314/src/testdir/test_float_func.vim 2021-07-27 22:00:39.753712380 +0200 --- src/testdir/test_float_func.vim 2021-08-08 15:41:52.117506482 +0200 *************** *** 239,251 **** call assert_equal('nan', string(str2float('NaN'))) call assert_equal('nan', string(str2float(' nan '))) ! call assert_equal(1.2, str2float(1.2)) call CheckDefAndScriptFailure2(['str2float(1.2)'], 'E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1') call assert_fails("call str2float([])", 'E730:') call assert_fails("call str2float({})", 'E731:') call assert_fails("call str2float(function('string'))", 'E729:') endfunc func Test_float2nr() call assert_equal(1, float2nr(1.234)) call assert_equal(123, float2nr(1.234e2)) --- 239,266 ---- call assert_equal('nan', string(str2float('NaN'))) call assert_equal('nan', string(str2float(' nan '))) ! call assert_equal('123456.789', string(str2float("123'456.789", 1))) ! call assert_equal('123456.789', string(str2float("12'34'56.789", 1))) ! call assert_equal('123456.789', string(str2float("1'2'3'4'5'6.789", 1))) ! call assert_equal('1.0', string(str2float("1''2.3", 1))) ! call assert_equal('123456.7', string(str2float("123'456.7'89", 1))) ! ! call assert_equal(1.2, str2float(1.2, 0)) call CheckDefAndScriptFailure2(['str2float(1.2)'], 'E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1') call assert_fails("call str2float([])", 'E730:') call assert_fails("call str2float({})", 'E731:') call assert_fails("call str2float(function('string'))", 'E729:') endfunc + def Test_float_quotes() + call assert_equal('123456.789', string(123'456.789)) + call assert_equal('123456.789', string(12'34'56.789)) + call assert_equal('123456.789', string(1'2'3'4'5'6.789)) + + call assert_fails("echo string(1''2.3)", 'E116:') + call assert_fails("echo string(123'456.7'89)", 'E116:') + enddef + func Test_float2nr() call assert_equal(1, float2nr(1.234)) call assert_equal(123, float2nr(1.234e2)) *** ../vim-8.2.3314/src/version.c 2021-08-08 14:41:48.723930691 +0200 --- src/version.c 2021-08-08 15:42:13.281448474 +0200 *************** *** 757,758 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3315, /**/ -- Q: How does a UNIX Guru pick up a girl? A: look; grep; which; eval; nice; uname; talk; date; /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///