Skip to content

Commit 09ac807

Browse files
committed
Add PyUnicodeWriter_Format()
1 parent 95bc158 commit 09ac807

2 files changed

Lines changed: 41 additions & 15 deletions

File tree

Include/cpython/unicodeobject.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,10 @@ PyAPI_FUNC(int) PyUnicodeWriter_WriteSubstring(
470470
PyObject *str,
471471
Py_ssize_t start,
472472
Py_ssize_t stop);
473+
PyAPI_FUNC(int) PyUnicodeWriter_Format(
474+
PyUnicodeWriter *writer,
475+
const char *format,
476+
...);
473477

474478
/* --- Manage the default encoding ---------------------------------------- */
475479

Objects/unicodeobject.c

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2858,23 +2858,21 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer,
28582858
return f;
28592859
}
28602860

2861-
PyObject *
2862-
PyUnicode_FromFormatV(const char *format, va_list vargs)
2861+
static int
2862+
unicode_from_format(_PyUnicodeWriter *writer, const char *format, va_list vargs)
28632863
{
2864+
writer->min_length += strlen(format) + 100;
2865+
writer->overallocate = 1;
2866+
28642867
va_list vargs2;
28652868
const char *f;
2866-
_PyUnicodeWriter writer;
2867-
2868-
_PyUnicodeWriter_Init(&writer);
2869-
writer.min_length = strlen(format) + 100;
2870-
writer.overallocate = 1;
28712869

28722870
// Copy varags to be able to pass a reference to a subfunction.
28732871
va_copy(vargs2, vargs);
28742872

28752873
for (f = format; *f; ) {
28762874
if (*f == '%') {
2877-
f = unicode_fromformat_arg(&writer, f, &vargs2);
2875+
f = unicode_fromformat_arg(writer, f, &vargs2);
28782876
if (f == NULL)
28792877
goto fail;
28802878
}
@@ -2898,21 +2896,33 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
28982896
len = p - f;
28992897

29002898
if (*p == '\0')
2901-
writer.overallocate = 0;
2899+
writer->overallocate = 0;
29022900

2903-
if (_PyUnicodeWriter_WriteASCIIString(&writer, f, len) < 0)
2901+
if (_PyUnicodeWriter_WriteASCIIString(writer, f, len) < 0)
29042902
goto fail;
29052903

29062904
f = p;
29072905
}
29082906
}
29092907
va_end(vargs2);
2910-
return _PyUnicodeWriter_Finish(&writer);
2908+
return 0;
29112909

29122910
fail:
29132911
va_end(vargs2);
2914-
_PyUnicodeWriter_Dealloc(&writer);
2915-
return NULL;
2912+
return -1;
2913+
}
2914+
2915+
PyObject *
2916+
PyUnicode_FromFormatV(const char *format, va_list vargs)
2917+
{
2918+
_PyUnicodeWriter writer;
2919+
_PyUnicodeWriter_Init(&writer);
2920+
2921+
if (unicode_from_format(&writer, format, vargs) < 0) {
2922+
_PyUnicodeWriter_Dealloc(&writer);
2923+
return NULL;
2924+
}
2925+
return _PyUnicodeWriter_Finish(&writer);
29162926
}
29172927

29182928
PyObject *
@@ -2927,6 +2937,18 @@ PyUnicode_FromFormat(const char *format, ...)
29272937
return ret;
29282938
}
29292939

2940+
int
2941+
PyUnicodeWriter_Format(PyUnicodeWriter *writer, const char *format, ...)
2942+
{
2943+
_PyUnicodeWriter *_writer = (_PyUnicodeWriter*)writer;
2944+
2945+
va_list vargs;
2946+
va_start(vargs, format);
2947+
int ret = unicode_from_format(_writer, format, vargs);
2948+
va_end(vargs);
2949+
return ret;
2950+
}
2951+
29302952
static Py_ssize_t
29312953
unicode_get_widechar_size(PyObject *unicode)
29322954
{
@@ -13098,9 +13120,9 @@ _PyUnicodeWriter_Init(_PyUnicodeWriter *writer)
1309813120
/* ASCII is the bare minimum */
1309913121
writer->min_char = 127;
1310013122

13101-
/* use a value smaller than PyUnicode_1BYTE_KIND() so
13123+
/* use a kind value smaller than PyUnicode_1BYTE_KIND so
1310213124
_PyUnicodeWriter_PrepareKind() will copy the buffer. */
13103-
writer->kind = 0;
13125+
assert(writer->kind == 0);
1310413126
assert(writer->kind <= PyUnicode_1BYTE_KIND);
1310513127
}
1310613128

0 commit comments

Comments
 (0)