Skip to content

Commit 067a51d

Browse files
committed
Add PyUnicodeWriter_Format()
1 parent 4526f51 commit 067a51d

File tree

2 files changed

+41
-15
lines changed

2 files changed

+41
-15
lines changed

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
@@ -2869,23 +2869,21 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer,
28692869
return f;
28702870
}
28712871

2872-
PyObject *
2873-
PyUnicode_FromFormatV(const char *format, va_list vargs)
2872+
static int
2873+
unicode_from_format(_PyUnicodeWriter *writer, const char *format, va_list vargs)
28742874
{
2875+
writer->min_length += strlen(format) + 100;
2876+
writer->overallocate = 1;
2877+
28752878
va_list vargs2;
28762879
const char *f;
2877-
_PyUnicodeWriter writer;
2878-
2879-
_PyUnicodeWriter_Init(&writer);
2880-
writer.min_length = strlen(format) + 100;
2881-
writer.overallocate = 1;
28822880

28832881
// Copy varags to be able to pass a reference to a subfunction.
28842882
va_copy(vargs2, vargs);
28852883

28862884
for (f = format; *f; ) {
28872885
if (*f == '%') {
2888-
f = unicode_fromformat_arg(&writer, f, &vargs2);
2886+
f = unicode_fromformat_arg(writer, f, &vargs2);
28892887
if (f == NULL)
28902888
goto fail;
28912889
}
@@ -2909,21 +2907,33 @@ PyUnicode_FromFormatV(const char *format, va_list vargs)
29092907
len = p - f;
29102908

29112909
if (*p == '\0')
2912-
writer.overallocate = 0;
2910+
writer->overallocate = 0;
29132911

2914-
if (_PyUnicodeWriter_WriteASCIIString(&writer, f, len) < 0)
2912+
if (_PyUnicodeWriter_WriteASCIIString(writer, f, len) < 0)
29152913
goto fail;
29162914

29172915
f = p;
29182916
}
29192917
}
29202918
va_end(vargs2);
2921-
return _PyUnicodeWriter_Finish(&writer);
2919+
return 0;
29222920

29232921
fail:
29242922
va_end(vargs2);
2925-
_PyUnicodeWriter_Dealloc(&writer);
2926-
return NULL;
2923+
return -1;
2924+
}
2925+
2926+
PyObject *
2927+
PyUnicode_FromFormatV(const char *format, va_list vargs)
2928+
{
2929+
_PyUnicodeWriter writer;
2930+
_PyUnicodeWriter_Init(&writer);
2931+
2932+
if (unicode_from_format(&writer, format, vargs) < 0) {
2933+
_PyUnicodeWriter_Dealloc(&writer);
2934+
return NULL;
2935+
}
2936+
return _PyUnicodeWriter_Finish(&writer);
29272937
}
29282938

29292939
PyObject *
@@ -2938,6 +2948,18 @@ PyUnicode_FromFormat(const char *format, ...)
29382948
return ret;
29392949
}
29402950

2951+
int
2952+
PyUnicodeWriter_Format(PyUnicodeWriter *writer, const char *format, ...)
2953+
{
2954+
_PyUnicodeWriter *_writer = (_PyUnicodeWriter*)writer;
2955+
2956+
va_list vargs;
2957+
va_start(vargs, format);
2958+
int ret = unicode_from_format(_writer, format, vargs);
2959+
va_end(vargs);
2960+
return ret;
2961+
}
2962+
29412963
static Py_ssize_t
29422964
unicode_get_widechar_size(PyObject *unicode)
29432965
{
@@ -13179,9 +13201,9 @@ _PyUnicodeWriter_Init(_PyUnicodeWriter *writer)
1317913201
/* ASCII is the bare minimum */
1318013202
writer->min_char = 127;
1318113203

13182-
/* use a value smaller than PyUnicode_1BYTE_KIND() so
13204+
/* use a kind value smaller than PyUnicode_1BYTE_KIND so
1318313205
_PyUnicodeWriter_PrepareKind() will copy the buffer. */
13184-
writer->kind = 0;
13206+
assert(writer->kind == 0);
1318513207
assert(writer->kind <= PyUnicode_1BYTE_KIND);
1318613208
}
1318713209

0 commit comments

Comments
 (0)