diff options
author | Monty <monty@mariadb.org> | 2020-08-13 20:17:00 +0300 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2021-05-19 22:27:29 +0200 |
commit | 5c7d243b29257fe02edaea42730893d4d185ced5 (patch) | |
tree | 06cf893181aba06ec9af8a29a3440f79e23277ec /strings | |
parent | 8dd6ad573ce3c0bc72e2ec47f9833f6dc774cecf (diff) | |
download | mariadb-git-5c7d243b29257fe02edaea42730893d4d185ced5.tar.gz |
Add support for minimum field width for strings to my_vsnprintf()
This patch adds support for right aligned strings and numbers.
Left alignment is left as an exercise for anyone needing it.
MDEV-25612 "Assertion `to <= end' failed in process_args" fixed.
(Was caused by the original version of this patch)
Diffstat (limited to 'strings')
-rw-r--r-- | strings/my_vsnprintf.c | 58 |
1 files changed, 46 insertions, 12 deletions
diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index a2e3f9b738d..aefca1fb3ee 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -224,12 +224,27 @@ err: */ static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end, - size_t width, char *par, uint print_type, - my_bool nice_cut) + longlong length_arg, size_t width, char *par, + uint print_type, my_bool nice_cut) { int well_formed_error; uint dots= 0; size_t plen, left_len= (size_t) (end - to) + 1, slen=0; + my_bool left_fill= 1; + size_t length; + + /* + The sign of the length argument specific the string should be right + or left adjusted + */ + if (length_arg < 0) + { + length= (size_t) -length_arg; + left_fill= 0; + } + else + length= (size_t) length_arg; + if (!par) par = (char*) "(null)"; @@ -239,7 +254,10 @@ static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end, if (plen > width) plen= width; if (left_len <= plen) + { plen = left_len - 1; + length= plen; + } if ((slen > plen)) { if (plen < 3) @@ -259,24 +277,34 @@ static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end, plen= slen= strnlen(par, width); dots= 0; if (left_len <= plen) + { plen = left_len - 1; + length= plen; + } } plen= my_well_formed_length(cs, par, par + plen, width, &well_formed_error); if (print_type & ESCAPED_ARG) { + const char *org_to= to; to= backtick_string(cs, to, end, par, plen + dots, '`', MY_TEST(dots)); + plen= (size_t) (to - org_to); dots= 0; } else - to= strnmov(to,par,plen); - - if (dots) { - for (; dots; dots--) - *(to++)= '.'; - *(to)= 0; + if (left_fill) + { + if (plen + dots < length) + to= strfill(to, length - plen - dots, ' '); + } + to= strnmov(to,par,plen); + if (dots) + to= strfill(to, dots, '.'); } + + if (!left_fill && plen + dots < length) + to= strfill(to, length - plen - dots, ' '); return to; } @@ -494,11 +522,16 @@ start: case 's': case 'T': { + longlong min_field_width; char *par= args_arr[print_arr[i].arg_idx].str_arg; width= (print_arr[i].flags & WIDTH_ARG) ? (size_t)args_arr[print_arr[i].width].longlong_arg : print_arr[i].width; - to= process_str_arg(cs, to, end, width, par, print_arr[i].flags, + min_field_width= (print_arr[i].flags & LENGTH_ARG) + ? args_arr[print_arr[i].length].longlong_arg + : (longlong) print_arr[i].length; + to= process_str_arg(cs, to, end, min_field_width, width, par, + print_arr[i].flags, (print_arr[i].arg_type == 'T')); break; } @@ -565,7 +598,7 @@ start: *to++= ' '; *to++= '"'; my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg); - to= process_str_arg(cs, to, real_end, width, errmsg_buff, + to= process_str_arg(cs, to, real_end, 0, width, errmsg_buff, print_arr[i].flags, 1); if (real_end > to) *to++= '"'; } @@ -693,7 +726,8 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n, if (*fmt == 's' || *fmt == 'T') /* String parameter */ { reg2 char *par= va_arg(ap, char *); - to= process_str_arg(cs, to, end, width, par, print_type, (*fmt == 'T')); + to= process_str_arg(cs, to, end, (longlong) length, width, par, + print_type, (*fmt == 'T')); continue; } else if (*fmt == 'b') /* Buffer parameter */ @@ -751,7 +785,7 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n, *to++= ' '; *to++= '"'; my_strerror(errmsg_buff, sizeof(errmsg_buff), (int) larg); - to= process_str_arg(cs, to, real_end, width, errmsg_buff, + to= process_str_arg(cs, to, real_end, 0, width, errmsg_buff, print_type, 1); if (real_end > to) *to++= '"'; } |