0
0
mirror of https://github.com/vim/vim.git synced 2025-10-17 07:44:28 -04:00

patch 7.4.2221

Problem:    printf() does not support binary format.
Solution:   Add %b and %B. (Ozaki Kiichi)
This commit is contained in:
Bram Moolenaar
2016-08-16 21:58:41 +02:00
parent e5a8f35b42
commit 91984b9034
4 changed files with 75 additions and 14 deletions

View File

@@ -4091,12 +4091,14 @@ vim_vsnprintf(
char length_modifier = '\0';
/* temporary buffer for simple numeric->string conversion */
# ifdef FEAT_FLOAT
# if defined(FEAT_FLOAT)
# define TMP_LEN 350 /* On my system 1e308 is the biggest number possible.
* That sounds reasonable to use as the maximum
* printable. */
# elif defined(FEAT_NUM64)
# define TMP_LEN 66
# else
# define TMP_LEN 32
# define TMP_LEN 34
# endif
char tmp[TMP_LEN];
@@ -4343,9 +4345,13 @@ vim_vsnprintf(
}
break;
case 'd': case 'u': case 'o': case 'x': case 'X': case 'p':
case 'd': case 'u':
case 'b': case 'B':
case 'o':
case 'x': case 'X':
case 'p':
{
/* NOTE: the u, o, x, X and p conversion specifiers
/* NOTE: the u, b, o, x, X and p conversion specifiers
* imply the value is unsigned; d implies a signed
* value */
@@ -4370,6 +4376,9 @@ vim_vsnprintf(
uvarnumber_T ullong_arg = 0;
# endif
/* only defined for b convertion */
uvarnumber_T bin_arg = 0;
/* pointer argument value -only defined for p
* conversion */
void *ptr_arg = NULL;
@@ -4386,6 +4395,17 @@ vim_vsnprintf(
if (ptr_arg != NULL)
arg_sign = 1;
}
else if (fmt_spec == 'b' || fmt_spec == 'B')
{
bin_arg =
# if defined(FEAT_EVAL)
tvs != NULL ?
(uvarnumber_T)tv_nr(tvs, &arg_idx) :
# endif
va_arg(ap, uvarnumber_T);
if (bin_arg != 0)
arg_sign = 1;
}
else if (fmt_spec == 'd')
{
/* signed */
@@ -4492,7 +4512,8 @@ vim_vsnprintf(
else if (alternate_form)
{
if (arg_sign != 0
&& (fmt_spec == 'x' || fmt_spec == 'X') )
&& (fmt_spec == 'b' || fmt_spec == 'B'
|| fmt_spec == 'x' || fmt_spec == 'X') )
{
tmp[str_arg_l++] = '0';
tmp[str_arg_l++] = fmt_spec;
@@ -4508,7 +4529,7 @@ vim_vsnprintf(
{
/* When zero value is formatted with an explicit
* precision 0, the resulting formatted string is
* empty (d, i, u, o, x, X, p). */
* empty (d, i, u, b, B, o, x, X, p). */
}
else
{
@@ -4541,6 +4562,22 @@ vim_vsnprintf(
if (fmt_spec == 'p')
str_arg_l += sprintf(tmp + str_arg_l, f, ptr_arg);
else if (fmt_spec == 'b' || fmt_spec == 'B')
{
char b[8 * sizeof(uvarnumber_T)];
size_t b_l = 0;
uvarnumber_T bn = bin_arg;
do
{
b[sizeof(b) - ++b_l] = '0' + (bn & 0x1);
bn >>= 1;
}
while (bn != 0);
memcpy(tmp + str_arg_l, b + sizeof(b) - b_l, b_l);
str_arg_l += b_l;
}
else if (fmt_spec == 'd')
{
/* signed */