Add %[zt][diox] support to pretty-print
In the previous patch I haven't touched the gcc diagnostic routines, using HOST_SIZE_T_PRINT* for those is obviously undesirable because we want the strings to be translatable. We already have %w[diox] for HOST_WIDE_INT arguments, this patch adds t and z modifiers for those. 2024-02-10 Jakub Jelinek <jakub@redhat.com> gcc/ * pretty-print.cc (pp_integer_with_precision): Handle precision 3 for size_t and precision 4 for ptrdiff_t. Formatting fix. (pp_format): Document %{t,z}{d,i,u,o,x}. Implement t and z modifiers. Formatting fixes. (test_pp_format): Test t and z modifiers. * gcc.cc (read_specs): Use %td instead of %ld and casts to long. gcc/c-family/ * c-format.cc (gcc_diag_length_specs): Add t and z modifiers. (PP_FORMAT_CHAR_TABLE, gcc_gfc_char_table): Add entries for t and z modifiers. gcc/fortran/ * error.cc (error_print): Handle z and t modifiers on d, i and u. * check.cc (gfc_check_transfer): Use %zd instead of %ld and casts to long. * primary.cc (gfc_convert_to_structure_constructor): Use %td instead of %ld and casts to long.
This commit is contained in:
parent
89e93ce8b9
commit
8427290f33
6 changed files with 143 additions and 42 deletions
|
@ -512,6 +512,8 @@ static const format_length_info gcc_diag_length_specs[] =
|
|||
{
|
||||
{ "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
|
||||
{ "w", FMT_LEN_w, STD_C89, NO_FMT, 0 },
|
||||
{ "z", FMT_LEN_z, STD_C99, NO_FMT, 0 },
|
||||
{ "t", FMT_LEN_t, STD_C99, NO_FMT, 0 },
|
||||
{ NO_FMT, NO_FMT, 0 }
|
||||
};
|
||||
|
||||
|
@ -758,9 +760,9 @@ static const format_char_info asm_fprintf_char_table[] =
|
|||
by all pretty_printer instances within GCC. */
|
||||
|
||||
#define PP_FORMAT_CHAR_TABLE \
|
||||
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
|
||||
{ "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
|
||||
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
|
||||
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
|
||||
{ "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, T99_ST, T99_UPD, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
|
||||
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, T99_ST, T99_UPD, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
|
||||
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL }, \
|
||||
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "pq", "cR", NULL }, \
|
||||
{ "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "c", NULL }, \
|
||||
|
@ -833,8 +835,8 @@ static const format_char_info gcc_cxxdiag_char_table[] =
|
|||
static const format_char_info gcc_gfc_char_table[] =
|
||||
{
|
||||
/* C89 conversion specifiers. */
|
||||
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
|
||||
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
|
||||
{ "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
|
||||
{ "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, T99_ST, T99_UPD, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
|
||||
{ "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "", NULL },
|
||||
{ "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "q", "cR", NULL },
|
||||
|
||||
|
|
|
@ -6298,8 +6298,8 @@ gfc_check_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
|
|||
if (source_size < result_size)
|
||||
gfc_warning (OPT_Wsurprising,
|
||||
"Intrinsic TRANSFER at %L has partly undefined result: "
|
||||
"source size %ld < result size %ld", &source->where,
|
||||
(long) source_size, (long) result_size);
|
||||
"source size %zd < result size %zd", &source->where,
|
||||
source_size, result_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -536,7 +536,8 @@ error_print (const char *type, const char *format0, va_list argp)
|
|||
{
|
||||
enum { TYPE_CURRENTLOC, TYPE_LOCUS, TYPE_INTEGER, TYPE_UINTEGER,
|
||||
TYPE_LONGINT, TYPE_ULONGINT, TYPE_LLONGINT, TYPE_ULLONGINT,
|
||||
TYPE_HWINT, TYPE_HWUINT, TYPE_CHAR, TYPE_STRING, NOTYPE };
|
||||
TYPE_HWINT, TYPE_HWUINT, TYPE_CHAR, TYPE_STRING, TYPE_SIZE,
|
||||
TYPE_SSIZE, TYPE_PTRDIFF, NOTYPE };
|
||||
struct
|
||||
{
|
||||
int type;
|
||||
|
@ -553,6 +554,9 @@ error_print (const char *type, const char *format0, va_list argp)
|
|||
unsigned HOST_WIDE_INT hwuintval;
|
||||
char charval;
|
||||
const char * stringval;
|
||||
size_t sizeval;
|
||||
ssize_t ssizeval;
|
||||
ptrdiff_t ptrdiffval;
|
||||
} u;
|
||||
} arg[MAX_ARGS], spec[MAX_ARGS];
|
||||
/* spec is the array of specifiers, in the same order as they
|
||||
|
@ -662,6 +666,24 @@ error_print (const char *type, const char *format0, va_list argp)
|
|||
gcc_unreachable ();
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
c = *format++;
|
||||
if (c == 'u')
|
||||
arg[pos].type = TYPE_SIZE;
|
||||
else if (c == 'i' || c == 'd')
|
||||
arg[pos].type = TYPE_SSIZE;
|
||||
else
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
|
||||
case 't':
|
||||
c = *format++;
|
||||
if (c == 'u' || c == 'i' || c == 'd')
|
||||
arg[pos].type = TYPE_PTRDIFF;
|
||||
else
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
arg[pos].type = TYPE_CHAR;
|
||||
break;
|
||||
|
@ -742,6 +764,18 @@ error_print (const char *type, const char *format0, va_list argp)
|
|||
arg[pos].u.hwuintval = va_arg (argp, unsigned HOST_WIDE_INT);
|
||||
break;
|
||||
|
||||
case TYPE_SSIZE:
|
||||
arg[pos].u.ssizeval = va_arg (argp, ssize_t);
|
||||
break;
|
||||
|
||||
case TYPE_SIZE:
|
||||
arg[pos].u.sizeval = va_arg (argp, size_t);
|
||||
break;
|
||||
|
||||
case TYPE_PTRDIFF:
|
||||
arg[pos].u.ptrdiffval = va_arg (argp, ptrdiff_t);
|
||||
break;
|
||||
|
||||
case TYPE_CHAR:
|
||||
arg[pos].u.charval = (char) va_arg (argp, int);
|
||||
break;
|
||||
|
@ -839,6 +873,30 @@ error_print (const char *type, const char *format0, va_list argp)
|
|||
else
|
||||
error_hwint (spec[n++].u.hwuintval);
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
format++;
|
||||
if (*format == 'u')
|
||||
error_uinteger (spec[n++].u.sizeval);
|
||||
else
|
||||
error_integer (spec[n++].u.ssizeval);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
format++;
|
||||
if (*format == 'u')
|
||||
{
|
||||
ptrdiff_t ptrdiffval = spec[n++].u.ptrdiffval;
|
||||
if (sizeof (ptrdiff_t) == sizeof (int))
|
||||
error_uinteger ((unsigned) ptrdiffval);
|
||||
else if (sizeof (ptrdiff_t) == sizeof (long))
|
||||
error_uinteger ((unsigned long) ptrdiffval);
|
||||
else
|
||||
error_uinteger (ptrdiffval);
|
||||
}
|
||||
else
|
||||
error_integer (spec[n++].u.ptrdiffval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1190,14 +1190,14 @@ got_delim:
|
|||
{
|
||||
if (istart < 1)
|
||||
{
|
||||
gfc_error ("Substring start index (%ld) at %L below 1",
|
||||
(long) istart, &e->ref->u.ss.start->where);
|
||||
gfc_error ("Substring start index (%td) at %L below 1",
|
||||
istart, &e->ref->u.ss.start->where);
|
||||
return MATCH_ERROR;
|
||||
}
|
||||
if (iend > (ssize_t) length)
|
||||
{
|
||||
gfc_error ("Substring end index (%ld) at %L exceeds string "
|
||||
"length", (long) iend, &e->ref->u.ss.end->where);
|
||||
gfc_error ("Substring end index (%td) at %L exceeds string "
|
||||
"length", iend, &e->ref->u.ss.end->where);
|
||||
return MATCH_ERROR;
|
||||
}
|
||||
length = iend - istart + 1;
|
||||
|
@ -3240,8 +3240,8 @@ gfc_convert_to_structure_constructor (gfc_expr *e, gfc_symbol *sym, gfc_expr **c
|
|||
if (warn_line_truncation && c < e1)
|
||||
gfc_warning_now (OPT_Wcharacter_truncation,
|
||||
"CHARACTER expression will be truncated "
|
||||
"in constructor (%ld/%ld) at %L", (long int) c,
|
||||
(long int) e1, &actual->expr->where);
|
||||
"in constructor (%td/%td) at %L", c,
|
||||
e1, &actual->expr->where);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
30
gcc/gcc.cc
30
gcc/gcc.cc
|
@ -2410,8 +2410,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
|
|||
if (*p1++ != '<' || p[-2] != '>')
|
||||
fatal_error (input_location,
|
||||
"specs %%include syntax malformed after "
|
||||
"%ld characters",
|
||||
(long) (p1 - buffer + 1));
|
||||
"%td characters", p1 - buffer + 1);
|
||||
|
||||
p[-2] = '\0';
|
||||
new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
|
||||
|
@ -2431,8 +2430,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
|
|||
if (*p1++ != '<' || p[-2] != '>')
|
||||
fatal_error (input_location,
|
||||
"specs %%include syntax malformed after "
|
||||
"%ld characters",
|
||||
(long) (p1 - buffer + 1));
|
||||
"%td characters", p1 - buffer + 1);
|
||||
|
||||
p[-2] = '\0';
|
||||
new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
|
||||
|
@ -2458,8 +2456,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
|
|||
if (! ISALPHA ((unsigned char) *p1))
|
||||
fatal_error (input_location,
|
||||
"specs %%rename syntax malformed after "
|
||||
"%ld characters",
|
||||
(long) (p1 - buffer));
|
||||
"%td characters", p1 - buffer);
|
||||
|
||||
p2 = p1;
|
||||
while (*p2 && !ISSPACE ((unsigned char) *p2))
|
||||
|
@ -2468,8 +2465,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
|
|||
if (*p2 != ' ' && *p2 != '\t')
|
||||
fatal_error (input_location,
|
||||
"specs %%rename syntax malformed after "
|
||||
"%ld characters",
|
||||
(long) (p2 - buffer));
|
||||
"%td characters", p2 - buffer);
|
||||
|
||||
name_len = p2 - p1;
|
||||
*p2++ = '\0';
|
||||
|
@ -2479,8 +2475,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
|
|||
if (! ISALPHA ((unsigned char) *p2))
|
||||
fatal_error (input_location,
|
||||
"specs %%rename syntax malformed after "
|
||||
"%ld characters",
|
||||
(long) (p2 - buffer));
|
||||
"%td characters", p2 - buffer);
|
||||
|
||||
/* Get new spec name. */
|
||||
p3 = p2;
|
||||
|
@ -2490,8 +2485,7 @@ read_specs (const char *filename, bool main_p, bool user_p)
|
|||
if (p3 != p - 1)
|
||||
fatal_error (input_location,
|
||||
"specs %%rename syntax malformed after "
|
||||
"%ld characters",
|
||||
(long) (p3 - buffer));
|
||||
"%td characters", p3 - buffer);
|
||||
*p3 = '\0';
|
||||
|
||||
for (sl = specs; sl; sl = sl->next)
|
||||
|
@ -2530,8 +2524,8 @@ read_specs (const char *filename, bool main_p, bool user_p)
|
|||
}
|
||||
else
|
||||
fatal_error (input_location,
|
||||
"specs unknown %% command after %ld characters",
|
||||
(long) (p1 - buffer));
|
||||
"specs unknown %% command after %td characters",
|
||||
p1 - buffer);
|
||||
}
|
||||
|
||||
/* Find the colon that should end the suffix. */
|
||||
|
@ -2542,8 +2536,8 @@ read_specs (const char *filename, bool main_p, bool user_p)
|
|||
/* The colon shouldn't be missing. */
|
||||
if (*p1 != ':')
|
||||
fatal_error (input_location,
|
||||
"specs file malformed after %ld characters",
|
||||
(long) (p1 - buffer));
|
||||
"specs file malformed after %td characters",
|
||||
p1 - buffer);
|
||||
|
||||
/* Skip back over trailing whitespace. */
|
||||
p2 = p1;
|
||||
|
@ -2556,8 +2550,8 @@ read_specs (const char *filename, bool main_p, bool user_p)
|
|||
p = skip_whitespace (p1 + 1);
|
||||
if (p[1] == 0)
|
||||
fatal_error (input_location,
|
||||
"specs file malformed after %ld characters",
|
||||
(long) (p - buffer));
|
||||
"specs file malformed after %td characters",
|
||||
p - buffer);
|
||||
|
||||
p1 = p;
|
||||
/* Find next blank line or end of string. */
|
||||
|
|
|
@ -769,7 +769,30 @@ output_buffer::~output_buffer ()
|
|||
break; \
|
||||
\
|
||||
case 2: \
|
||||
pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, va_arg (ARG, long long T)); \
|
||||
pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, \
|
||||
va_arg (ARG, long long T)); \
|
||||
break; \
|
||||
\
|
||||
case 3: \
|
||||
if (T (-1) < T (0)) \
|
||||
pp_scalar (PP, "%" GCC_PRISZ F, \
|
||||
(fmt_size_t) va_arg (ARG, ssize_t)); \
|
||||
else \
|
||||
pp_scalar (PP, "%" GCC_PRISZ F, \
|
||||
(fmt_size_t) va_arg (ARG, size_t)); \
|
||||
break; \
|
||||
\
|
||||
case 4: \
|
||||
if (sizeof (ptrdiff_t) <= sizeof (int)) \
|
||||
pp_scalar (PP, "%" F, \
|
||||
(int) va_arg (ARG, ptrdiff_t)); \
|
||||
else if (sizeof (ptrdiff_t) <= sizeof (long)) \
|
||||
pp_scalar (PP, "%l" F, \
|
||||
(long int) va_arg (ARG, ptrdiff_t)); \
|
||||
else \
|
||||
pp_scalar (PP, "%" HOST_LONG_LONG_FORMAT F, \
|
||||
(long long int) \
|
||||
va_arg (ARG, ptrdiff_t)); \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
|
@ -1237,6 +1260,8 @@ on_end_quote (pretty_printer *pp,
|
|||
%ld, %li, %lo, %lu, %lx: long versions of the above.
|
||||
%lld, %lli, %llo, %llu, %llx: long long versions.
|
||||
%wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
|
||||
%zd, %zi, %zo, %zu, %zx: size_t versions.
|
||||
%td, %ti, %to, %tu, %tx: ptrdiff_t versions.
|
||||
%f: double
|
||||
%c: character.
|
||||
%s: string.
|
||||
|
@ -1422,7 +1447,7 @@ pp_format (pretty_printer *pp,
|
|||
obstack_1grow (&buffer->chunk_obstack, *p);
|
||||
p++;
|
||||
}
|
||||
while (strchr ("qwl+#", p[-1]));
|
||||
while (strchr ("qwlzt+#", p[-1]));
|
||||
|
||||
if (p[-1] == '.')
|
||||
{
|
||||
|
@ -1524,6 +1549,16 @@ pp_format (pretty_printer *pp,
|
|||
wide = true;
|
||||
continue;
|
||||
|
||||
case 'z':
|
||||
gcc_assert (!precision);
|
||||
precision = 3;
|
||||
continue;
|
||||
|
||||
case 't':
|
||||
gcc_assert (!precision);
|
||||
precision = 4;
|
||||
continue;
|
||||
|
||||
case 'l':
|
||||
/* We don't support precision beyond that of "long long". */
|
||||
gcc_assert (precision < 2);
|
||||
|
@ -1570,8 +1605,8 @@ pp_format (pretty_printer *pp,
|
|||
if (wide)
|
||||
pp_wide_integer (pp, va_arg (*text->m_args_ptr, HOST_WIDE_INT));
|
||||
else
|
||||
pp_integer_with_precision
|
||||
(pp, *text->m_args_ptr, precision, int, "d");
|
||||
pp_integer_with_precision (pp, *text->m_args_ptr, precision,
|
||||
int, "d");
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
|
@ -1579,8 +1614,8 @@ pp_format (pretty_printer *pp,
|
|||
pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
|
||||
va_arg (*text->m_args_ptr, unsigned HOST_WIDE_INT));
|
||||
else
|
||||
pp_integer_with_precision
|
||||
(pp, *text->m_args_ptr, precision, unsigned, "o");
|
||||
pp_integer_with_precision (pp, *text->m_args_ptr, precision,
|
||||
unsigned, "o");
|
||||
break;
|
||||
|
||||
case 's':
|
||||
|
@ -1599,8 +1634,8 @@ pp_format (pretty_printer *pp,
|
|||
pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
|
||||
va_arg (*text->m_args_ptr, unsigned HOST_WIDE_INT));
|
||||
else
|
||||
pp_integer_with_precision
|
||||
(pp, *text->m_args_ptr, precision, unsigned, "u");
|
||||
pp_integer_with_precision (pp, *text->m_args_ptr, precision,
|
||||
unsigned, "u");
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
|
@ -1629,8 +1664,8 @@ pp_format (pretty_printer *pp,
|
|||
pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
|
||||
va_arg (*text->m_args_ptr, unsigned HOST_WIDE_INT));
|
||||
else
|
||||
pp_integer_with_precision
|
||||
(pp, *text->m_args_ptr, precision, unsigned, "x");
|
||||
pp_integer_with_precision (pp, *text->m_args_ptr, precision,
|
||||
unsigned, "x");
|
||||
break;
|
||||
|
||||
case '.':
|
||||
|
@ -2774,6 +2809,18 @@ test_pp_format ()
|
|||
ASSERT_PP_FORMAT_2 ("17 12345678", "%wo %x", (HOST_WIDE_INT)15, 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("0xcafebabe 12345678", "%wx %x", (HOST_WIDE_INT)0xcafebabe,
|
||||
0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("-27 12345678", "%zd %x", (ssize_t)-27, 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("-5 12345678", "%zi %x", (ssize_t)-5, 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("10 12345678", "%zu %x", (size_t)10, 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("17 12345678", "%zo %x", (size_t)15, 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("cafebabe 12345678", "%zx %x", (size_t)0xcafebabe,
|
||||
0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("-27 12345678", "%td %x", (ptrdiff_t)-27, 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("-5 12345678", "%ti %x", (ptrdiff_t)-5, 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("10 12345678", "%tu %x", (ptrdiff_t)10, 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("17 12345678", "%to %x", (ptrdiff_t)15, 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("1afebabe 12345678", "%tx %x", (ptrdiff_t)0x1afebabe,
|
||||
0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("1.000000 12345678", "%f %x", 1.0, 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("A 12345678", "%c %x", 'A', 0x12345678);
|
||||
ASSERT_PP_FORMAT_2 ("hello world 12345678", "%s %x", "hello world",
|
||||
|
|
Loading…
Add table
Reference in a new issue