Mercurial > vim
comparison src/message.c @ 9892:41c5d59e7e10 v7.4.2220
commit https://github.com/vim/vim/commit/e5a8f35b4286135f3469f3b00a6c2220553d9658
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Aug 16 21:30:54 2016 +0200
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)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 16 Aug 2016 21:45:06 +0200 |
parents | a1b1405a33ca |
children | b01afb4e8f66 |
comparison
equal
deleted
inserted
replaced
9891:ec73a26cd6cf | 9892:41c5d59e7e10 |
---|---|
3885 | 3885 |
3886 #if defined(FEAT_EVAL) | 3886 #if defined(FEAT_EVAL) |
3887 static char *e_printf = N_("E766: Insufficient arguments for printf()"); | 3887 static char *e_printf = N_("E766: Insufficient arguments for printf()"); |
3888 | 3888 |
3889 static varnumber_T tv_nr(typval_T *tvs, int *idxp); | 3889 static varnumber_T tv_nr(typval_T *tvs, int *idxp); |
3890 static char *tv_str(typval_T *tvs, int *idxp); | 3890 static char *tv_str(typval_T *tvs, int *idxp, char_u **tofree); |
3891 # ifdef FEAT_FLOAT | 3891 # ifdef FEAT_FLOAT |
3892 static double tv_float(typval_T *tvs, int *idxp); | 3892 static double tv_float(typval_T *tvs, int *idxp); |
3893 # endif | 3893 # endif |
3894 | 3894 |
3895 /* | 3895 /* |
3914 return n; | 3914 return n; |
3915 } | 3915 } |
3916 | 3916 |
3917 /* | 3917 /* |
3918 * Get string argument from "idxp" entry in "tvs". First entry is 1. | 3918 * Get string argument from "idxp" entry in "tvs". First entry is 1. |
3919 * If "tofree" is NULL get_tv_string_chk() is used. Some types (e.g. List) | |
3920 * are not converted to a string. | |
3921 * If "tofree" is not NULL echo_string() is used. All types are converted to | |
3922 * a string with the same format as ":echo". The caller must free "*tofree". | |
3919 * Returns NULL for an error. | 3923 * Returns NULL for an error. |
3920 */ | 3924 */ |
3921 static char * | 3925 static char * |
3922 tv_str(typval_T *tvs, int *idxp) | 3926 tv_str(typval_T *tvs, int *idxp, char_u **tofree) |
3923 { | 3927 { |
3924 int idx = *idxp - 1; | 3928 int idx = *idxp - 1; |
3925 char *s = NULL; | 3929 char *s = NULL; |
3930 static char_u numbuf[NUMBUFLEN]; | |
3926 | 3931 |
3927 if (tvs[idx].v_type == VAR_UNKNOWN) | 3932 if (tvs[idx].v_type == VAR_UNKNOWN) |
3928 EMSG(_(e_printf)); | 3933 EMSG(_(e_printf)); |
3929 else | 3934 else |
3930 { | 3935 { |
3931 ++*idxp; | 3936 ++*idxp; |
3932 s = (char *)get_tv_string_chk(&tvs[idx]); | 3937 if (tofree != NULL) |
3938 s = (char *)echo_string(&tvs[idx], tofree, numbuf, get_copyID()); | |
3939 else | |
3940 s = (char *)get_tv_string_chk(&tvs[idx]); | |
3933 } | 3941 } |
3934 return s; | 3942 return s; |
3935 } | 3943 } |
3936 | 3944 |
3937 # ifdef FEAT_FLOAT | 3945 # ifdef FEAT_FLOAT |
4111 size_t zero_padding_insertion_ind = 0; | 4119 size_t zero_padding_insertion_ind = 0; |
4112 | 4120 |
4113 /* current conversion specifier character */ | 4121 /* current conversion specifier character */ |
4114 char fmt_spec = '\0'; | 4122 char fmt_spec = '\0'; |
4115 | 4123 |
4124 /* buffer for 's' and 'S' specs */ | |
4125 char_u *tofree = NULL; | |
4126 | |
4127 | |
4116 str_arg = NULL; | 4128 str_arg = NULL; |
4117 p++; /* skip '%' */ | 4129 p++; /* skip '%' */ |
4118 | 4130 |
4119 /* parse flags */ | 4131 /* parse flags */ |
4120 while (*p == '0' || *p == '-' || *p == '+' || *p == ' ' | 4132 while (*p == '0' || *p == '-' || *p == '+' || *p == ' ' |
4274 | 4286 |
4275 case 's': | 4287 case 's': |
4276 case 'S': | 4288 case 'S': |
4277 str_arg = | 4289 str_arg = |
4278 # if defined(FEAT_EVAL) | 4290 # if defined(FEAT_EVAL) |
4279 tvs != NULL ? tv_str(tvs, &arg_idx) : | 4291 tvs != NULL ? tv_str(tvs, &arg_idx, &tofree) : |
4280 # endif | 4292 # endif |
4281 va_arg(ap, char *); | 4293 va_arg(ap, char *); |
4282 if (str_arg == NULL) | 4294 if (str_arg == NULL) |
4283 { | 4295 { |
4284 str_arg = "[NULL]"; | 4296 str_arg = "[NULL]"; |
4365 if (fmt_spec == 'p') | 4377 if (fmt_spec == 'p') |
4366 { | 4378 { |
4367 length_modifier = '\0'; | 4379 length_modifier = '\0'; |
4368 ptr_arg = | 4380 ptr_arg = |
4369 # if defined(FEAT_EVAL) | 4381 # if defined(FEAT_EVAL) |
4370 tvs != NULL ? (void *)tv_str(tvs, &arg_idx) : | 4382 tvs != NULL ? (void *)tv_str(tvs, &arg_idx, |
4383 NULL) : | |
4371 # endif | 4384 # endif |
4372 va_arg(ap, void *); | 4385 va_arg(ap, void *); |
4373 if (ptr_arg != NULL) | 4386 if (ptr_arg != NULL) |
4374 arg_sign = 1; | 4387 arg_sign = 1; |
4375 } | 4388 } |
4875 : (size_t)pn); | 4888 : (size_t)pn); |
4876 } | 4889 } |
4877 str_l += pn; | 4890 str_l += pn; |
4878 } | 4891 } |
4879 } | 4892 } |
4893 vim_free(tofree); | |
4880 } | 4894 } |
4881 } | 4895 } |
4882 | 4896 |
4883 if (str_m > 0) | 4897 if (str_m > 0) |
4884 { | 4898 { |