Skip to content

Commit d4ef36b

Browse files
committed
Implement Py_BuildValue format specifier 'u'
1 parent d7e3503 commit d4ef36b

File tree

1 file changed

+37
-7
lines changed

1 file changed

+37
-7
lines changed

graalpython/com.oracle.graal.python.cext/src/modsupport.c

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242

4343
#include <stdio.h>
4444

45+
#define FLAG_SIZE_T 1
46+
4547
static int getbuffer(PyObject *arg, Py_buffer *view, const char **errmsg) {
4648
if (PyObject_GetBuffer(arg, view, PyBUF_SIMPLE) != 0) {
4749
*errmsg = "bytes-like object";
@@ -287,7 +289,7 @@ typedef struct _build_stack {
287289
struct _build_stack* prev;
288290
} build_stack;
289291

290-
MUST_INLINE static PyObject* _PyTruffle_BuildValue(const char* format, va_list va) {
292+
MUST_INLINE static PyObject* _PyTruffle_BuildValue(const char* format, va_list va, int flags) {
291293
PyObject* (*converter)(void*) = NULL;
292294
int offset = 0;
293295
char argchar[2] = {'\0'};
@@ -343,8 +345,36 @@ MUST_INLINE static PyObject* _PyTruffle_BuildValue(const char* format, va_list v
343345
}
344346
break;
345347
case 'u':
346-
fprintf(stderr, "error: unsupported format 'u'\n");
347-
break;
348+
{
349+
PyObject *v;
350+
Py_UNICODE *u = va_arg(va, Py_UNICODE *);
351+
Py_ssize_t n;
352+
if (format[format_idx + 1] == '#') {
353+
if (flags & FLAG_SIZE_T)
354+
n = va_arg(va, Py_ssize_t);
355+
else {
356+
n = va_arg(va, int);
357+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
358+
"PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) {
359+
return NULL;
360+
}
361+
}
362+
format_idx++;
363+
} else {
364+
n = -1;
365+
}
366+
if (u == NULL) {
367+
v = Py_None;
368+
Py_INCREF(v);
369+
}
370+
else {
371+
if (n < 0) {
372+
n = wcslen(u);
373+
}
374+
v = PyUnicode_FromWideChar(u, n);
375+
}
376+
return v;
377+
}
348378
case 'i':
349379
case 'b':
350380
case 'h':
@@ -496,18 +526,18 @@ MUST_INLINE static PyObject* _PyTruffle_BuildValue(const char* format, va_list v
496526
}
497527

498528
PyObject* Py_VaBuildValue(const char *format, va_list va) {
499-
return _Py_VaBuildValue_SizeT(format, va);
529+
return _PyTruffle_BuildValue(format, va, FLAG_SIZE_T);
500530
}
501531

502532
PyObject* _Py_VaBuildValue_SizeT(const char *format, va_list va) {
503-
return _PyTruffle_BuildValue(format, va);
533+
return _PyTruffle_BuildValue(format, va, FLAG_SIZE_T);
504534
}
505535

506536
NO_INLINE
507537
PyObject* Py_BuildValue(const char *format, ...) {
508538
va_list args;
509539
va_start(args, format);
510-
PyObject* result = _PyTruffle_BuildValue(format, args);
540+
PyObject* result = _PyTruffle_BuildValue(format, args, 0);
511541
va_end(args);
512542
return result;
513543
}
@@ -516,7 +546,7 @@ NO_INLINE
516546
PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
517547
va_list args;
518548
va_start(args, format);
519-
PyObject* result = _PyTruffle_BuildValue(format, args);
549+
PyObject* result = _PyTruffle_BuildValue(format, args, FLAG_SIZE_T);
520550
va_end(args);
521551
return result;
522552
}

0 commit comments

Comments
 (0)