diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-08-16 21:58:41 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-08-16 21:58:41 +0200 |
commit | 91984b9034d3b698459622be277d963e0c6df60e (patch) | |
tree | 329479725a833a6bc5ae7b42cf7c1686c6542597 /src/message.c | |
parent | e5a8f35b4286135f3469f3b00a6c2220553d9658 (diff) |
patch 7.4.2221v7.4.2221
Problem: printf() does not support binary format.
Solution: Add %b and %B. (Ozaki Kiichi)
Diffstat (limited to 'src/message.c')
-rw-r--r-- | src/message.c | 49 |
1 files changed, 43 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 */ |