mirror of
https://github.com/python/cpython.git
synced 2026-10-28 18:35:21 +08:00
108 lines
2.6 KiB
C
108 lines
2.6 KiB
C
#include "pyconfig.h" // Py_GIL_DISABLED
|
|
#ifdef Py_GIL_DISABLED
|
|
# define Py_TARGET_ABI3T 0x030f0000
|
|
#else
|
|
// Need limited C API version 3.13 for PyMem_RawFree()
|
|
# define Py_LIMITED_API 0x030d0000
|
|
#endif
|
|
|
|
#include "parts.h"
|
|
|
|
static PyObject *
|
|
codec_namereplace_errors(PyObject *Py_UNUSED(module), PyObject *exc)
|
|
{
|
|
assert(exc != NULL);
|
|
return PyCodec_NameReplaceErrors(exc);
|
|
}
|
|
|
|
|
|
// Test Py_DecodeLocale()
|
|
static PyObject *
|
|
decode_locale(PyObject *Py_UNUSED(module), PyObject *arg)
|
|
{
|
|
const char *str;
|
|
Py_ssize_t unused_len;
|
|
// Accept embedded null bytes
|
|
if (PyArg_Parse(arg, "y#", &str, &unused_len) < 0) {
|
|
return NULL;
|
|
}
|
|
|
|
const size_t size_canary = (size_t)-123;
|
|
size_t size = size_canary;
|
|
wchar_t *wstr = Py_DecodeLocale(str, &size);
|
|
|
|
if (wstr == NULL) {
|
|
if (size == (size_t)-1) {
|
|
PyErr_NoMemory();
|
|
}
|
|
else if (size == (size_t)-2) {
|
|
PyErr_SetString(PyExc_RuntimeError, "decode error");
|
|
}
|
|
else {
|
|
PyErr_Format(PyExc_SystemError,
|
|
"unknown Py_DecodeLocale() return value: %zd",
|
|
(Py_ssize_t)size);
|
|
}
|
|
return NULL;
|
|
}
|
|
assert(wstr != NULL);
|
|
assert(size != size_canary);
|
|
|
|
PyObject *result = PyUnicode_FromWideChar(wstr, size);
|
|
PyMem_RawFree(wstr);
|
|
return result;
|
|
}
|
|
|
|
|
|
// Test Py_EncodeLocale()
|
|
static PyObject *
|
|
encode_locale(PyObject *Py_UNUSED(module), PyObject *arg)
|
|
{
|
|
PyObject *unicode;
|
|
if (PyArg_Parse(arg, "U", &unicode) < 0) {
|
|
return NULL;
|
|
}
|
|
|
|
// Accept embedded null characters
|
|
Py_ssize_t unused_wlen;
|
|
wchar_t *wstr = PyUnicode_AsWideCharString(unicode, &unused_wlen);
|
|
if (wstr == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
const size_t error_pos_canary = (size_t)-123;
|
|
size_t error_pos = error_pos_canary;
|
|
char *str = Py_EncodeLocale(wstr, &error_pos);
|
|
PyMem_Free(wstr);
|
|
|
|
if (str == NULL) {
|
|
if (error_pos == (size_t)-1) {
|
|
return PyErr_NoMemory();
|
|
}
|
|
else {
|
|
assert(error_pos != error_pos_canary);
|
|
return PyErr_Format(PyExc_RuntimeError,
|
|
"encode error: pos=%zd", error_pos);
|
|
}
|
|
}
|
|
assert(error_pos == error_pos_canary);
|
|
|
|
PyObject *result = PyBytes_FromString(str);
|
|
PyMem_Free(str);
|
|
return result;
|
|
}
|
|
|
|
|
|
static PyMethodDef test_methods[] = {
|
|
{"codec_namereplace_errors", codec_namereplace_errors, METH_O},
|
|
{"decode_locale", decode_locale, METH_O},
|
|
{"encode_locale", encode_locale, METH_O},
|
|
{NULL},
|
|
};
|
|
|
|
int
|
|
_PyTestLimitedCAPI_Init_Codec(PyObject *module)
|
|
{
|
|
return PyModule_AddFunctions(module, test_methods);
|
|
}
|