diff options
author | Jurica Bradaric <jurica.bradaric@avl.com> | 2017-03-05 22:20:48 +0100 |
---|---|---|
committer | Jurica Bradaric <jurica.bradaric@avl.com> | 2017-03-06 21:35:48 +0100 |
commit | 2f80360e9acdb32f63633e8408c00de2ef972b3b (patch) | |
tree | 2cbcdbe4dc77dcf40c5622e90bc32cb25b841b9e | |
parent | 483e8257e5a28893bcd1de089715f82798d0f93a (diff) | |
download | rneovim-2f80360e9acdb32f63633e8408c00de2ef972b3b.tar.gz rneovim-2f80360e9acdb32f63633e8408c00de2ef972b3b.tar.bz2 rneovim-2f80360e9acdb32f63633e8408c00de2ef972b3b.zip |
vim-patch:7.4.2220
Problem: printf() gives an error when the argument for %s is not a string.
(Ozaki Kiichi)
Solution: Behave like invoking string() on the argument. (Ken Takata)
https://github.com/vim/vim/commit/e5a8f35b4286135f3469f3b00a6c2220553d9658
-rw-r--r-- | src/nvim/strings.c | 29 | ||||
-rw-r--r-- | src/nvim/testdir/test_expr.vim | 27 | ||||
-rw-r--r-- | src/nvim/version.c | 2 |
3 files changed, 52 insertions, 6 deletions
diff --git a/src/nvim/strings.c b/src/nvim/strings.c index 5b6fbf75a9..6bfb63251c 100644 --- a/src/nvim/strings.c +++ b/src/nvim/strings.c @@ -45,6 +45,7 @@ #include "nvim/window.h" #include "nvim/os/os.h" #include "nvim/os/shell.h" +#include "nvim/eval/encode.h" /* * Copy "string" into newly allocated memory. @@ -588,18 +589,30 @@ static varnumber_T tv_nr(typval_T *tvs, int *idxp) /// value. /// @param[in,out] idxp Index in a list. Will be incremented. /// +/// @param[out] tofree If "tofree" is NULL get_tv_string_chk() is used. Some +/// types (e.g. List) are not converted to a string. If +/// "tofree" is not NULL encode_tv2echo() is used. All +/// types are converted to a string with the same format as +/// ":echo". The caller must free "*tofree". +/// /// @return String value or NULL in case of error. -static char *tv_str(typval_T *tvs, int *idxp) - FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +static char *tv_str(typval_T *tvs, int *idxp, char_u **tofree) + FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_NONNULL_ARG(2) + FUNC_ATTR_WARN_UNUSED_RESULT { int idx = *idxp - 1; - char *s = NULL; + char *s = NULL; if (tvs[idx].v_type == VAR_UNKNOWN) { EMSG(_(e_printf)); } else { (*idxp)++; - s = (char *)get_tv_string_chk(&tvs[idx]); + if (tofree != NULL) { + s = encode_tv2echo(&tvs[idx], NULL); + *tofree = (char_u *)s; + } else { + s = (char *)get_tv_string_chk(&tvs[idx]); + } } return s; } @@ -813,6 +826,9 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, // current conversion specifier character char fmt_spec = '\0'; + // buffer for 's' and 'S' specs + char_u *tofree = NULL; + p++; // skip '%' // parse flags @@ -919,7 +935,8 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, case 's': case 'S': - str_arg = tvs ? tv_str(tvs, &arg_idx) : va_arg(ap, char *); + str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree) + : va_arg(ap, char *); if (!str_arg) { str_arg = "[NULL]"; str_arg_l = 6; @@ -1370,6 +1387,8 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap, str_l += pn; } } + + xfree(tofree); } } diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index 7ceef2834f..5aeb934e3a 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -107,6 +107,33 @@ func Test_setmatches() call assert_equal(exp, getmatches()) endfunc +function Test_printf_spec_s() + " number + call assert_equal("1234567890", printf('%s', 1234567890)) + + " string + call assert_equal("abcdefgi", printf('%s', "abcdefgi")) + + " float + if has('float') + call assert_equal("1.23", printf('%s', 1.23)) + endif + + " list + let value = [1, 'two', ['three', 4]] + call assert_equal(string(value), printf('%s', value)) + + " dict + let value = {'key1' : 'value1', 'key2' : ['list', 'value'], 'key3' : {'dict' : 'value'}} + call assert_equal(string(value), printf('%s', value)) + + " funcref + call assert_equal('printf', printf('%s', function('printf'))) + + " partial + call assert_equal(string(function('printf', ['%s'])), printf('%s', function('printf', ['%s']))) +endfunc + func Test_substitute_expr() let g:val = 'XXX' call assert_equal('XXX', substitute('yyy', 'y*', '\=g:val', '')) diff --git a/src/nvim/version.c b/src/nvim/version.c index 8fd9b4b74f..1e7785507f 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -220,7 +220,7 @@ static int included_patches[] = { // 2223, // 2222, // 2221, - // 2220, + 2220, 2219, // 2218 NA 2217, |