0
0
mirror of https://github.com/vim/vim.git synced 2025-10-04 05:25:06 -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

@@ -5884,6 +5884,7 @@ printf({fmt}, {expr1} ...) *printf()*
%04x hex number padded with zeros to at least 4 characters
%X hex number using upper case letters
%o octal number
%08b binary number padded with zeros to at least 8 chars
%f floating point number in the form 123.456
%e floating point number in the form 1.234e3
%E floating point number in the form 1.234E3
@@ -5910,6 +5911,9 @@ printf({fmt}, {expr1} ...) *printf()*
character of the output string to a zero (except
if a zero value is printed with an explicit
precision of zero).
For b and B conversions, a non-zero result has
the string "0b" (or "0B" for B conversions)
prepended to it.
For x and X conversions, a non-zero result has
the string "0x" (or "0X" for X conversions)
prepended to it.
@@ -5917,8 +5921,8 @@ printf({fmt}, {expr1} ...) *printf()*
0 (zero) Zero padding. For all conversions the converted
value is padded on the left with zeros rather
than blanks. If a precision is given with a
numeric conversion (d, o, x, and X), the 0 flag
is ignored.
numeric conversion (d, b, B, o, x, and X), the 0
flag is ignored.
- A negative field width flag; the converted value
is to be left adjusted on the field boundary.
@@ -5966,12 +5970,13 @@ printf({fmt}, {expr1} ...) *printf()*
The conversion specifiers and their meanings are:
*printf-d* *printf-o* *printf-x* *printf-X*
doxX The Number argument is converted to signed decimal
(d), unsigned octal (o), or unsigned hexadecimal (x
and X) notation. The letters "abcdef" are used for
x conversions; the letters "ABCDEF" are used for X
conversions.
*printf-d* *printf-b* *printf-B* *printf-o*
*printf-x* *printf-X*
dbBoxX The Number argument is converted to signed decimal
(d), unsigned binary (b and B), unsigned octal (o), or
unsigned hexadecimal (x and X) notation. The letters
"abcdef" are used for x conversions; the letters
"ABCDEF" are used for X conversions.
The precision, if any, gives the minimum number of
digits that must appear; if the converted value
requires fewer digits, it is padded on the left with

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 */

View File

@@ -163,6 +163,23 @@ function Test_printf_spec_s()
call assert_equal(string(function('printf', ['%s'])), printf('%s', function('printf', ['%s'])))
endfunc
function Test_printf_spec_b()
call assert_equal("0", printf('%b', 0))
call assert_equal("00001100", printf('%08b', 12))
call assert_equal("11111111", printf('%08b', 0xff))
call assert_equal(" 1111011", printf('%10b', 123))
call assert_equal("0001111011", printf('%010b', 123))
call assert_equal(" 0b1111011", printf('%#10b', 123))
call assert_equal("0B01111011", printf('%#010B', 123))
call assert_equal("1001001100101100000001011010010", printf('%b', 1234567890))
if has('num64')
call assert_equal("11100000100100010000110000011011101111101111001", printf('%b', 123456789012345))
call assert_equal("1111111111111111111111111111111111111111111111111111111111111111", printf('%b', -1))
else
call assert_equal("11111111111111111111111111111111", printf('%b', -1))
endif
endfunc
func Test_substitute_expr()
let g:val = 'XXX'
call assert_equal('XXX', substitute('yyy', 'y*', '\=g:val', ''))

View File

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