mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-29 22:30:24 +01:00
util/u_printf: properly handle %%
Cc: mesa-stable
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29776>
(cherry picked from commit d51a14aab8)
This commit is contained in:
parent
6e61244d0f
commit
ce2f8fa7b2
3 changed files with 43 additions and 7 deletions
|
|
@ -34,7 +34,7 @@
|
|||
"description": "util/u_printf: properly handle %%",
|
||||
"nominated": true,
|
||||
"nomination_type": 0,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": null,
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -217,5 +217,5 @@ TEST_F(u_printf_test, util_printf_mixed_multiple)
|
|||
add_arg<float>(3.0);
|
||||
add_arg<float, 4>(floats);
|
||||
|
||||
EXPECT_EQ(parse(), "ABCED\n-5 6\n%%%%mesa 10 3.000000 1.0,2.0,3.0,4.0 ");
|
||||
EXPECT_EQ(parse(), "ABCED\n-5 6\n%%mesa 10 3.000000 1.0,2.0,3.0,4.0 ");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,42 @@ size_t u_printf_length(const char *fmt, va_list untouched_args)
|
|||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to print plain format strings without arguments as some post-processing
|
||||
* will be required:
|
||||
* - %% needs to be printed as %
|
||||
*/
|
||||
static void
|
||||
u_printf_plain_sized(FILE *out, const char* format, size_t len)
|
||||
{
|
||||
bool found = false;
|
||||
size_t last = 0;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (!found && format[i] == '%') {
|
||||
found = true;
|
||||
} else if (found && format[i] == '%') {
|
||||
/* print one character less so we only print a single % */
|
||||
fwrite(format + last, i - last - 1, 1, out);
|
||||
|
||||
last = i;
|
||||
found = false;
|
||||
} else {
|
||||
/* We should never end up here with an actual format token */
|
||||
assert(!found);
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite(format + last, len - last, 1, out);
|
||||
}
|
||||
|
||||
static void
|
||||
u_printf_plain(FILE *out, const char* format)
|
||||
{
|
||||
u_printf_plain_sized(out, format, strlen(format));
|
||||
}
|
||||
|
||||
static void
|
||||
u_printf_impl(FILE *out, const char *buffer, size_t buffer_size,
|
||||
const u_printf_info *info,
|
||||
|
|
@ -122,7 +158,7 @@ u_printf_impl(FILE *out, const char *buffer, size_t buffer_size,
|
|||
buf_pos += sizeof(fmt_idx);
|
||||
|
||||
if (!fmt->num_args) {
|
||||
fprintf(out, "%s", format);
|
||||
u_printf_plain(out, format);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +167,7 @@ u_printf_impl(FILE *out, const char *buffer, size_t buffer_size,
|
|||
size_t spec_pos = util_printf_next_spec_pos(format, 0);
|
||||
|
||||
if (spec_pos == -1) {
|
||||
fprintf(out, "%s", format);
|
||||
u_printf_plain(out, format);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -140,13 +176,13 @@ u_printf_impl(FILE *out, const char *buffer, size_t buffer_size,
|
|||
|
||||
/* print the part before the format token */
|
||||
if (token != format)
|
||||
fwrite(format, token - format, 1, out);
|
||||
u_printf_plain_sized(out, format, token - format);
|
||||
|
||||
char *print_str = strndup(token, next_format - token);
|
||||
/* rebase spec_pos so we can use it with print_str */
|
||||
spec_pos += format - token;
|
||||
|
||||
/* print the formated part */
|
||||
/* print the formatted part */
|
||||
if (print_str[spec_pos] == 's') {
|
||||
uint64_t idx;
|
||||
memcpy(&idx, &buffer[buf_pos], 8);
|
||||
|
|
@ -233,7 +269,7 @@ u_printf_impl(FILE *out, const char *buffer, size_t buffer_size,
|
|||
}
|
||||
|
||||
/* print remaining */
|
||||
fprintf(out, "%s", format);
|
||||
u_printf_plain(out, format);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue