diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/message.c | 49 | ||||
-rw-r--r-- | src/testdir/test_expr.vim | 17 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 62 insertions, 6 deletions
diff --git a/src/message.c b/src/message.c index 513f2888da..a7398f6eb0 100644 --- a/src/message.c +++ b/src/message.c @@ -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 */ diff --git a/src/testdir/test_expr.vim b/src/testdir/test_expr.vim index e835854031..a7ad65eef4 100644 --- a/src/testdir/test_expr.vim +++ b/src/testdir/test_expr.vim @@ -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', '')) diff --git a/src/version.c b/src/version.c index bb933d2bd6..0395201c69 100644 --- a/src/version.c +++ b/src/version.c @@ -764,6 +764,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2221, +/**/ 2220, /**/ 2219, |