mirror of git://sourceware.org/git/glibc.git
vfprintf: Reuse work_buffer in group_number
This commit is contained in:
parent
12d5853e22
commit
edc1686af0
|
@ -1,3 +1,9 @@
|
||||||
|
2017-06-29 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
* stdio-common/vfprintf.c (group_number): Add front_ptr argument.
|
||||||
|
Use it to make the temporary copy at the start of the work buffer.
|
||||||
|
(process_arg): Adjust call to group_number.
|
||||||
|
|
||||||
2017-06-29 Florian Weimer <fweimer@redhat.com>
|
2017-06-29 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
* stdio-common/vfprintf.c (printf_positional): Use struct
|
* stdio-common/vfprintf.c (printf_positional): Use struct
|
||||||
|
|
|
@ -595,9 +595,8 @@ static const uint8_t jump_table[] =
|
||||||
string = _itoa (number.longlong, workend, base, \
|
string = _itoa (number.longlong, workend, base, \
|
||||||
spec == L_('X')); \
|
spec == L_('X')); \
|
||||||
if (group && grouping) \
|
if (group && grouping) \
|
||||||
string = group_number (string, workend, grouping, \
|
string = group_number (work_buffer, string, workend, \
|
||||||
thousands_sep); \
|
grouping, thousands_sep); \
|
||||||
\
|
|
||||||
if (use_outdigits && base == 10) \
|
if (use_outdigits && base == 10) \
|
||||||
string = _i18n_number_rewrite (string, workend, workend); \
|
string = _i18n_number_rewrite (string, workend, workend); \
|
||||||
} \
|
} \
|
||||||
|
@ -653,9 +652,8 @@ static const uint8_t jump_table[] =
|
||||||
string = _itoa_word (number.word, workend, base, \
|
string = _itoa_word (number.word, workend, base, \
|
||||||
spec == L_('X')); \
|
spec == L_('X')); \
|
||||||
if (group && grouping) \
|
if (group && grouping) \
|
||||||
string = group_number (string, workend, grouping, \
|
string = group_number (work_buffer, string, workend, \
|
||||||
thousands_sep); \
|
grouping, thousands_sep); \
|
||||||
\
|
|
||||||
if (use_outdigits && base == 10) \
|
if (use_outdigits && base == 10) \
|
||||||
string = _i18n_number_rewrite (string, workend, workend); \
|
string = _i18n_number_rewrite (string, workend, workend); \
|
||||||
} \
|
} \
|
||||||
|
@ -1237,8 +1235,8 @@ static int printf_unknown (FILE *, const struct printf_info *,
|
||||||
const void *const *) __THROW;
|
const void *const *) __THROW;
|
||||||
|
|
||||||
/* Group digits of number string. */
|
/* Group digits of number string. */
|
||||||
static CHAR_T *group_number (CHAR_T *, CHAR_T *, const char *, THOUSANDS_SEP_T)
|
static CHAR_T *group_number (CHAR_T *, CHAR_T *, CHAR_T *, const char *,
|
||||||
__THROW internal_function;
|
THOUSANDS_SEP_T);
|
||||||
|
|
||||||
/* The function itself. */
|
/* The function itself. */
|
||||||
int
|
int
|
||||||
|
@ -2123,16 +2121,20 @@ printf_unknown (FILE *s, const struct printf_info *info,
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Group the digits according to the grouping rules of the current locale.
|
/* Group the digits from W to REAR_PTR according to the grouping rules
|
||||||
The interpretation of GROUPING is as in `struct lconv' from <locale.h>. */
|
of the current locale. The interpretation of GROUPING is as in
|
||||||
|
`struct lconv' from <locale.h>. The grouped number extends from
|
||||||
|
the returned pointer until REAR_PTR. FRONT_PTR to W is used as a
|
||||||
|
scratch area. */
|
||||||
static CHAR_T *
|
static CHAR_T *
|
||||||
internal_function
|
group_number (CHAR_T *front_ptr, CHAR_T *w, CHAR_T *rear_ptr,
|
||||||
group_number (CHAR_T *w, CHAR_T *rear_ptr, const char *grouping,
|
const char *grouping, THOUSANDS_SEP_T thousands_sep)
|
||||||
THOUSANDS_SEP_T thousands_sep)
|
|
||||||
{
|
{
|
||||||
|
/* Length of the current group. */
|
||||||
int len;
|
int len;
|
||||||
CHAR_T *src, *s;
|
|
||||||
#ifndef COMPILE_WPRINTF
|
#ifndef COMPILE_WPRINTF
|
||||||
|
/* Length of the separator (in wide mode, the separator is always a
|
||||||
|
single wide character). */
|
||||||
int tlen = strlen (thousands_sep);
|
int tlen = strlen (thousands_sep);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2145,26 +2147,34 @@ group_number (CHAR_T *w, CHAR_T *rear_ptr, const char *grouping,
|
||||||
len = *grouping++;
|
len = *grouping++;
|
||||||
|
|
||||||
/* Copy existing string so that nothing gets overwritten. */
|
/* Copy existing string so that nothing gets overwritten. */
|
||||||
src = (CHAR_T *) alloca ((rear_ptr - w) * sizeof (CHAR_T));
|
memmove (front_ptr, w, (rear_ptr - w) * sizeof (CHAR_T));
|
||||||
s = (CHAR_T *) __mempcpy (src, w,
|
CHAR_T *s = front_ptr + (rear_ptr - w);
|
||||||
(rear_ptr - w) * sizeof (CHAR_T));
|
|
||||||
w = rear_ptr;
|
w = rear_ptr;
|
||||||
|
|
||||||
/* Process all characters in the string. */
|
/* Process all characters in the string. */
|
||||||
while (s > src)
|
while (s > front_ptr)
|
||||||
{
|
{
|
||||||
*--w = *--s;
|
*--w = *--s;
|
||||||
|
|
||||||
if (--len == 0 && s > src)
|
if (--len == 0 && s > front_ptr)
|
||||||
{
|
{
|
||||||
/* A new group begins. */
|
/* A new group begins. */
|
||||||
#ifdef COMPILE_WPRINTF
|
#ifdef COMPILE_WPRINTF
|
||||||
*--w = thousands_sep;
|
if (w != s)
|
||||||
|
*--w = thousands_sep;
|
||||||
|
else
|
||||||
|
/* Not enough room for the separator. */
|
||||||
|
goto copy_rest;
|
||||||
#else
|
#else
|
||||||
int cnt = tlen;
|
int cnt = tlen;
|
||||||
do
|
if (tlen < w - s)
|
||||||
*--w = thousands_sep[--cnt];
|
do
|
||||||
while (cnt > 0);
|
*--w = thousands_sep[--cnt];
|
||||||
|
while (cnt > 0);
|
||||||
|
else
|
||||||
|
/* Not enough room for the separator. */
|
||||||
|
goto copy_rest;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (*grouping == CHAR_MAX
|
if (*grouping == CHAR_MAX
|
||||||
|
@ -2173,17 +2183,16 @@ group_number (CHAR_T *w, CHAR_T *rear_ptr, const char *grouping,
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* No further grouping to be done.
|
copy_rest:
|
||||||
Copy the rest of the number. */
|
/* No further grouping to be done. Copy the rest of the
|
||||||
do
|
number. */
|
||||||
*--w = *--s;
|
memmove (w, s, (front_ptr -s) * sizeof (CHAR_T));
|
||||||
while (s > src);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (*grouping != '\0')
|
else if (*grouping != '\0')
|
||||||
/* The previous grouping repeats ad infinitum. */
|
|
||||||
len = *grouping++;
|
len = *grouping++;
|
||||||
else
|
else
|
||||||
|
/* The previous grouping repeats ad infinitum. */
|
||||||
len = grouping[-1];
|
len = grouping[-1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue