summaryrefslogtreecommitdiff
path: root/strings
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2020-08-13 20:17:00 +0300
committerSergei Golubchik <serg@mariadb.org>2021-05-19 22:27:29 +0200
commit5c7d243b29257fe02edaea42730893d4d185ced5 (patch)
tree06cf893181aba06ec9af8a29a3440f79e23277ec /strings
parent8dd6ad573ce3c0bc72e2ec47f9833f6dc774cecf (diff)
downloadmariadb-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.c58
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++= '"';
}