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:
@@ -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 */
|
||||
|
Reference in New Issue
Block a user