0
0
mirror of https://github.com/vim/vim.git synced 2025-09-27 04:14:06 -04:00

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)
This commit is contained in:
Bram Moolenaar
2016-08-16 21:30:54 +02:00
parent f5a39447a8
commit e5a8f35b42
3 changed files with 50 additions and 7 deletions

View File

@@ -3887,7 +3887,7 @@ do_browse(
static char *e_printf = N_("E766: Insufficient arguments for printf()"); static char *e_printf = N_("E766: Insufficient arguments for printf()");
static varnumber_T tv_nr(typval_T *tvs, int *idxp); static varnumber_T tv_nr(typval_T *tvs, int *idxp);
static char *tv_str(typval_T *tvs, int *idxp); static char *tv_str(typval_T *tvs, int *idxp, char_u **tofree);
# ifdef FEAT_FLOAT # ifdef FEAT_FLOAT
static double tv_float(typval_T *tvs, int *idxp); static double tv_float(typval_T *tvs, int *idxp);
# endif # endif
@@ -3916,19 +3916,27 @@ tv_nr(typval_T *tvs, int *idxp)
/* /*
* Get string argument from "idxp" entry in "tvs". First entry is 1. * Get string argument from "idxp" entry in "tvs". First entry is 1.
* 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 echo_string() is used. All types are converted to
* a string with the same format as ":echo". The caller must free "*tofree".
* Returns NULL for an error. * Returns NULL for an error.
*/ */
static char * static char *
tv_str(typval_T *tvs, int *idxp) tv_str(typval_T *tvs, int *idxp, char_u **tofree)
{ {
int idx = *idxp - 1; int idx = *idxp - 1;
char *s = NULL; char *s = NULL;
static char_u numbuf[NUMBUFLEN];
if (tvs[idx].v_type == VAR_UNKNOWN) if (tvs[idx].v_type == VAR_UNKNOWN)
EMSG(_(e_printf)); EMSG(_(e_printf));
else else
{ {
++*idxp; ++*idxp;
if (tofree != NULL)
s = (char *)echo_string(&tvs[idx], tofree, numbuf, get_copyID());
else
s = (char *)get_tv_string_chk(&tvs[idx]); s = (char *)get_tv_string_chk(&tvs[idx]);
} }
return s; return s;
@@ -4113,6 +4121,10 @@ vim_vsnprintf(
/* current conversion specifier character */ /* current conversion specifier character */
char fmt_spec = '\0'; char fmt_spec = '\0';
/* buffer for 's' and 'S' specs */
char_u *tofree = NULL;
str_arg = NULL; str_arg = NULL;
p++; /* skip '%' */ p++; /* skip '%' */
@@ -4276,7 +4288,7 @@ vim_vsnprintf(
case 'S': case 'S':
str_arg = str_arg =
# if defined(FEAT_EVAL) # if defined(FEAT_EVAL)
tvs != NULL ? tv_str(tvs, &arg_idx) : tvs != NULL ? tv_str(tvs, &arg_idx, &tofree) :
# endif # endif
va_arg(ap, char *); va_arg(ap, char *);
if (str_arg == NULL) if (str_arg == NULL)
@@ -4367,7 +4379,8 @@ vim_vsnprintf(
length_modifier = '\0'; length_modifier = '\0';
ptr_arg = ptr_arg =
# if defined(FEAT_EVAL) # if defined(FEAT_EVAL)
tvs != NULL ? (void *)tv_str(tvs, &arg_idx) : tvs != NULL ? (void *)tv_str(tvs, &arg_idx,
NULL) :
# endif # endif
va_arg(ap, void *); va_arg(ap, void *);
if (ptr_arg != NULL) if (ptr_arg != NULL)
@@ -4877,6 +4890,7 @@ vim_vsnprintf(
str_l += pn; str_l += pn;
} }
} }
vim_free(tofree);
} }
} }

View File

@@ -136,6 +136,33 @@ function Test_printf_64bit()
endif endif
endfunc 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() func Test_substitute_expr()
let g:val = 'XXX' let g:val = 'XXX'
call assert_equal('XXX', substitute('yyy', 'y*', '\=g:val', '')) call assert_equal('XXX', substitute('yyy', 'y*', '\=g:val', ''))

View File

@@ -763,6 +763,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2220,
/**/ /**/
2219, 2219,
/**/ /**/