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:
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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', ''))
|
||||
|
@@ -763,6 +763,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2221,
|
||||
/**/
|
||||
2220,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user