Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitda5855e

Browse files
authored
gh-112301: Use literal format strings in unicode_fromformat_arg (GH-124203)
1 parent162d152 commitda5855e

File tree

1 file changed

+35
-43
lines changed

1 file changed

+35
-43
lines changed

‎Objects/unicodeobject.c‎

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2694,11 +2694,6 @@ unicode_fromformat_write_wcstr(_PyUnicodeWriter *writer, const wchar_t *str,
26942694
#defineF_SIZE 3
26952695
#defineF_PTRDIFF 4
26962696
#defineF_INTMAX 5
2697-
staticconstchar*constformats[]= {"%d","%ld","%lld","%zd","%td","%jd"};
2698-
staticconstchar*constformats_o[]= {"%o","%lo","%llo","%zo","%to","%jo"};
2699-
staticconstchar*constformats_u[]= {"%u","%lu","%llu","%zu","%tu","%ju"};
2700-
staticconstchar*constformats_x[]= {"%x","%lx","%llx","%zx","%tx","%jx"};
2701-
staticconstchar*constformats_X[]= {"%X","%lX","%llX","%zX","%tX","%jX"};
27022697

27032698
staticconstchar*
27042699
unicode_fromformat_arg(_PyUnicodeWriter*writer,
@@ -2840,47 +2835,44 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer,
28402835
case'd':case'i':
28412836
case'o':case'u':case'x':case'X':
28422837
{
2843-
/* used by sprintf */
28442838
charbuffer[MAX_INTMAX_CHARS];
2845-
constchar*fmt=NULL;
2846-
switch (*f) {
2847-
case'o':fmt=formats_o[sizemod];break;
2848-
case'u':fmt=formats_u[sizemod];break;
2849-
case'x':fmt=formats_x[sizemod];break;
2850-
case'X':fmt=formats_X[sizemod];break;
2851-
default:fmt=formats[sizemod];break;
2852-
}
2853-
intissigned= (*f=='d'||*f=='i');
2839+
2840+
// Fill buffer using sprinf, with one of many possible format
2841+
// strings, like "%llX" for `long long` in hexadecimal.
2842+
// The type/size is in `sizemod`; the format is in `*f`.
2843+
2844+
// Use macros with nested switches to keep the sprintf format strings
2845+
// as compile-time literals, avoiding warnings and maybe allowing
2846+
// optimizations.
2847+
2848+
// `SPRINT` macro does one sprintf
2849+
// Example usage: SPRINT("l", "X", unsigned long) expands to
2850+
// sprintf(buffer, "%" "l" "X", va_arg(*vargs, unsigned long))
2851+
#defineSPRINT(SIZE_SPEC,FMT_CHAR,TYPE) \
2852+
sprintf(buffer, "%" SIZE_SPEC FMT_CHAR, va_arg(*vargs, TYPE))
2853+
2854+
// One inner switch to handle all format variants
2855+
#defineDO_SPRINTS(SIZE_SPEC,SIGNED_TYPE,UNSIGNED_TYPE) \
2856+
switch (*f) { \
2857+
case 'o': len = SPRINT(SIZE_SPEC, "o", UNSIGNED_TYPE); break; \
2858+
case 'u': len = SPRINT(SIZE_SPEC, "u", UNSIGNED_TYPE); break; \
2859+
case 'x': len = SPRINT(SIZE_SPEC, "x", UNSIGNED_TYPE); break; \
2860+
case 'X': len = SPRINT(SIZE_SPEC, "X", UNSIGNED_TYPE); break; \
2861+
default: len = SPRINT(SIZE_SPEC, "d", SIGNED_TYPE); break; \
2862+
}
2863+
2864+
// Outer switch to handle all the sizes/types
28542865
switch (sizemod) {
2855-
caseF_LONG:
2856-
len=issigned ?
2857-
sprintf(buffer,fmt,va_arg(*vargs,long)) :
2858-
sprintf(buffer,fmt,va_arg(*vargs,unsignedlong));
2859-
break;
2860-
caseF_LONGLONG:
2861-
len=issigned ?
2862-
sprintf(buffer,fmt,va_arg(*vargs,longlong)) :
2863-
sprintf(buffer,fmt,va_arg(*vargs,unsignedlong long));
2864-
break;
2865-
caseF_SIZE:
2866-
len=issigned ?
2867-
sprintf(buffer,fmt,va_arg(*vargs,Py_ssize_t)) :
2868-
sprintf(buffer,fmt,va_arg(*vargs,size_t));
2869-
break;
2870-
caseF_PTRDIFF:
2871-
len=sprintf(buffer,fmt,va_arg(*vargs,ptrdiff_t));
2872-
break;
2873-
caseF_INTMAX:
2874-
len=issigned ?
2875-
sprintf(buffer,fmt,va_arg(*vargs,intmax_t)) :
2876-
sprintf(buffer,fmt,va_arg(*vargs,uintmax_t));
2877-
break;
2878-
default:
2879-
len=issigned ?
2880-
sprintf(buffer,fmt,va_arg(*vargs,int)) :
2881-
sprintf(buffer,fmt,va_arg(*vargs,unsignedint));
2882-
break;
2866+
caseF_LONG:DO_SPRINTS("l",long,unsignedlong);break;
2867+
caseF_LONGLONG:DO_SPRINTS("ll",longlong,unsignedlong long);break;
2868+
caseF_SIZE:DO_SPRINTS("z",Py_ssize_t,size_t);break;
2869+
caseF_PTRDIFF:DO_SPRINTS("t",ptrdiff_t,ptrdiff_t);break;
2870+
caseF_INTMAX:DO_SPRINTS("j",intmax_t,uintmax_t);break;
2871+
default:DO_SPRINTS("",int,unsignedint);break;
28832872
}
2873+
#undef SPRINT
2874+
#undef DO_SPRINTS
2875+
28842876
assert(len >=0);
28852877

28862878
intsign= (buffer[0]=='-');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp