summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/unicode.rst15
-rw-r--r--Include/unicodeobject.h23
-rw-r--r--Objects/unicodeobject.c35
-rw-r--r--Python/formatter_unicode.c21
4 files changed, 76 insertions, 18 deletions
diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst
index 43e3d2f..3a8b38b 100644
--- a/Doc/c-api/unicode.rst
+++ b/Doc/c-api/unicode.rst
@@ -564,6 +564,21 @@ APIs:
.. versionadded:: 3.3
+.. c:function:: int PyUnicode_Fill(PyObject *unicode, Py_ssize_t start, \
+ Py_ssize_t length, Py_UCS4 fill_char)
+
+ Fill a string with a character: write *fill_char* into
+ ``unicode[start:start+length]``.
+
+ Fail if *fill_char* is bigger than the string maximum character, or if the
+ string has more than 1 reference.
+
+ Return the number of written character, or return ``-1`` and raise an
+ exception on error.
+
+ .. versionadded:: 3.3
+
+
.. c:function:: int PyUnicode_WriteChar(PyObject *unicode, Py_ssize_t index, \
Py_UCS4 character)
diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h
index dfd594e..6255dc3 100644
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -623,11 +623,11 @@ PyAPI_FUNC(PyObject*) _PyUnicode_Copy(
#endif
/* Copy character from one unicode object into another, this function performs
- character conversion when necessary and falls back to memcpy if possible.
+ character conversion when necessary and falls back to memcpy() if possible.
- Fail if to is too small (smaller than how_many or smaller than
+ Fail if to is too small (smaller than *how_many* or smaller than
len(from)-from_start), or if kind(from[from_start:from_start+how_many]) >
- kind(to), or if to has more than 1 reference.
+ kind(to), or if *to* has more than 1 reference.
Return the number of written character, or return -1 and raise an exception
on error.
@@ -650,6 +650,23 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_CopyCharacters(
);
#endif
+/* Fill a string with a character: write fill_char into
+ unicode[start:start+length].
+
+ Fail if fill_char is bigger than the string maximum character, or if the
+ string has more than 1 reference.
+
+ Return the number of written character, or return -1 and raise an exception
+ on error. */
+#ifndef Py_LIMITED_API
+PyAPI_FUNC(Py_ssize_t) PyUnicode_Fill(
+ PyObject *unicode,
+ Py_ssize_t start,
+ Py_ssize_t length,
+ Py_UCS4 fill_char
+ );
+#endif
+
/* Create a Unicode Object from the Py_UNICODE buffer u of the given
size.
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 9a9703a..5ca2c53 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -9818,6 +9818,41 @@ PyUnicode_Join(PyObject *separator, PyObject *seq)
} \
} while (0)
+Py_ssize_t
+PyUnicode_Fill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length,
+ Py_UCS4 fill_char)
+{
+ Py_ssize_t maxlen;
+ enum PyUnicode_Kind kind;
+ void *data;
+
+ if (!PyUnicode_Check(unicode)) {
+ PyErr_BadInternalCall();
+ return -1;
+ }
+ if (PyUnicode_READY(unicode) == -1)
+ return -1;
+ if (unicode_check_modifiable(unicode))
+ return -1;
+
+ if (fill_char > PyUnicode_MAX_CHAR_VALUE(unicode)) {
+ PyErr_SetString(PyExc_ValueError,
+ "fill character is bigger than "
+ "the string maximum character");
+ return -1;
+ }
+
+ maxlen = PyUnicode_GET_LENGTH(unicode) - start;
+ length = Py_MIN(maxlen, length);
+ if (length <= 0)
+ return 0;
+
+ kind = PyUnicode_KIND(unicode);
+ data = PyUnicode_DATA(unicode);
+ FILL(kind, data, fill_char, start, length);
+ return length;
+}
+
static PyObject *
pad(PyObject *self,
Py_ssize_t left,
diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c
index 6deb3cd..ef01511 100644
--- a/Python/formatter_unicode.c
+++ b/Python/formatter_unicode.c
@@ -317,15 +317,6 @@ calc_padding(Py_ssize_t nchars, Py_ssize_t width, Py_UCS4 align,
*n_rpadding = *n_total - nchars - *n_lpadding;
}
-static void
-unicode_fill(PyObject *str, Py_ssize_t start, Py_ssize_t end, Py_UCS4 ch)
-{
- int kind = PyUnicode_KIND(str);
- void *data = PyUnicode_DATA(str);
- while (start < end)
- PyUnicode_WRITE(kind, data, start++, ch);
-}
-
/* Do the padding, and return a pointer to where the caller-supplied
content goes. */
static Py_ssize_t
@@ -335,12 +326,12 @@ fill_padding(PyObject *s, Py_ssize_t start, Py_ssize_t nchars,
{
/* Pad on left. */
if (n_lpadding)
- unicode_fill(s, start, start + n_lpadding, fill_char);
+ PyUnicode_Fill(s, start, start + n_lpadding, fill_char);
/* Pad on right. */
if (n_rpadding)
- unicode_fill(s, start + nchars + n_lpadding,
- start + nchars + n_lpadding + n_rpadding, fill_char);
+ PyUnicode_Fill(s, start + nchars + n_lpadding,
+ start + nchars + n_lpadding + n_rpadding, fill_char);
/* Pointer to the user content. */
return start + n_lpadding;
@@ -557,7 +548,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
#endif
if (spec->n_lpadding) {
- unicode_fill(out, pos, pos + spec->n_lpadding, fill_char);
+ PyUnicode_Fill(out, pos, pos + spec->n_lpadding, fill_char);
pos += spec->n_lpadding;
}
if (spec->n_sign == 1) {
@@ -581,7 +572,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
pos += spec->n_prefix;
}
if (spec->n_spadding) {
- unicode_fill(out, pos, pos + spec->n_spadding, fill_char);
+ PyUnicode_Fill(out, pos, pos + spec->n_spadding, fill_char);
pos += spec->n_spadding;
}
@@ -640,7 +631,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
}
if (spec->n_rpadding) {
- unicode_fill(out, pos, pos + spec->n_rpadding, fill_char);
+ PyUnicode_Fill(out, pos, pos + spec->n_rpadding, fill_char);
pos += spec->n_rpadding;
}
return 0;