mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 22:02:27 +00:00
python-3.6.zip added from Github
README.cosmo contains the necessary links.
This commit is contained in:
parent
75fc601ff5
commit
0c4c56ff39
4219 changed files with 1968626 additions and 0 deletions
324
third_party/python/Objects/capsule.c
vendored
Normal file
324
third_party/python/Objects/capsule.c
vendored
Normal file
|
@ -0,0 +1,324 @@
|
|||
/* Wrap void * pointers to be passed between C modules */
|
||||
|
||||
#include "Python.h"
|
||||
|
||||
/* Internal structure of PyCapsule */
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
void *pointer;
|
||||
const char *name;
|
||||
void *context;
|
||||
PyCapsule_Destructor destructor;
|
||||
} PyCapsule;
|
||||
|
||||
|
||||
|
||||
static int
|
||||
_is_legal_capsule(PyCapsule *capsule, const char *invalid_capsule)
|
||||
{
|
||||
if (!capsule || !PyCapsule_CheckExact(capsule) || capsule->pointer == NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, invalid_capsule);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define is_legal_capsule(capsule, name) \
|
||||
(_is_legal_capsule(capsule, \
|
||||
name " called with invalid PyCapsule object"))
|
||||
|
||||
|
||||
static int
|
||||
name_matches(const char *name1, const char *name2) {
|
||||
/* if either is NULL, */
|
||||
if (!name1 || !name2) {
|
||||
/* they're only the same if they're both NULL. */
|
||||
return name1 == name2;
|
||||
}
|
||||
return !strcmp(name1, name2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject *
|
||||
PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
|
||||
{
|
||||
PyCapsule *capsule;
|
||||
|
||||
if (!pointer) {
|
||||
PyErr_SetString(PyExc_ValueError, "PyCapsule_New called with null pointer");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
capsule = PyObject_NEW(PyCapsule, &PyCapsule_Type);
|
||||
if (capsule == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
capsule->pointer = pointer;
|
||||
capsule->name = name;
|
||||
capsule->context = NULL;
|
||||
capsule->destructor = destructor;
|
||||
|
||||
return (PyObject *)capsule;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyCapsule_IsValid(PyObject *o, const char *name)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
|
||||
return (capsule != NULL &&
|
||||
PyCapsule_CheckExact(capsule) &&
|
||||
capsule->pointer != NULL &&
|
||||
name_matches(capsule->name, name));
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
PyCapsule_GetPointer(PyObject *o, const char *name)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
|
||||
if (!is_legal_capsule(capsule, "PyCapsule_GetPointer")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!name_matches(name, capsule->name)) {
|
||||
PyErr_SetString(PyExc_ValueError, "PyCapsule_GetPointer called with incorrect name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return capsule->pointer;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
PyCapsule_GetName(PyObject *o)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
|
||||
if (!is_legal_capsule(capsule, "PyCapsule_GetName")) {
|
||||
return NULL;
|
||||
}
|
||||
return capsule->name;
|
||||
}
|
||||
|
||||
|
||||
PyCapsule_Destructor
|
||||
PyCapsule_GetDestructor(PyObject *o)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
|
||||
if (!is_legal_capsule(capsule, "PyCapsule_GetDestructor")) {
|
||||
return NULL;
|
||||
}
|
||||
return capsule->destructor;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
PyCapsule_GetContext(PyObject *o)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
|
||||
if (!is_legal_capsule(capsule, "PyCapsule_GetContext")) {
|
||||
return NULL;
|
||||
}
|
||||
return capsule->context;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyCapsule_SetPointer(PyObject *o, void *pointer)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
|
||||
if (!pointer) {
|
||||
PyErr_SetString(PyExc_ValueError, "PyCapsule_SetPointer called with null pointer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!is_legal_capsule(capsule, "PyCapsule_SetPointer")) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
capsule->pointer = pointer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyCapsule_SetName(PyObject *o, const char *name)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
|
||||
if (!is_legal_capsule(capsule, "PyCapsule_SetName")) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
capsule->name = name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyCapsule_SetDestructor(PyObject *o, PyCapsule_Destructor destructor)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
|
||||
if (!is_legal_capsule(capsule, "PyCapsule_SetDestructor")) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
capsule->destructor = destructor;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyCapsule_SetContext(PyObject *o, void *context)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
|
||||
if (!is_legal_capsule(capsule, "PyCapsule_SetContext")) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
capsule->context = context;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
PyCapsule_Import(const char *name, int no_block)
|
||||
{
|
||||
PyObject *object = NULL;
|
||||
void *return_value = NULL;
|
||||
char *trace;
|
||||
size_t name_length = (strlen(name) + 1) * sizeof(char);
|
||||
char *name_dup = (char *)PyMem_MALLOC(name_length);
|
||||
|
||||
if (!name_dup) {
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
|
||||
memcpy(name_dup, name, name_length);
|
||||
|
||||
trace = name_dup;
|
||||
while (trace) {
|
||||
char *dot = strchr(trace, '.');
|
||||
if (dot) {
|
||||
*dot++ = '\0';
|
||||
}
|
||||
|
||||
if (object == NULL) {
|
||||
if (no_block) {
|
||||
object = PyImport_ImportModuleNoBlock(trace);
|
||||
} else {
|
||||
object = PyImport_ImportModule(trace);
|
||||
if (!object) {
|
||||
PyErr_Format(PyExc_ImportError, "PyCapsule_Import could not import module \"%s\"", trace);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PyObject *object2 = PyObject_GetAttrString(object, trace);
|
||||
Py_DECREF(object);
|
||||
object = object2;
|
||||
}
|
||||
if (!object) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
trace = dot;
|
||||
}
|
||||
|
||||
/* compare attribute name to module.name by hand */
|
||||
if (PyCapsule_IsValid(object, name)) {
|
||||
PyCapsule *capsule = (PyCapsule *)object;
|
||||
return_value = capsule->pointer;
|
||||
} else {
|
||||
PyErr_Format(PyExc_AttributeError,
|
||||
"PyCapsule_Import \"%s\" is not valid",
|
||||
name);
|
||||
}
|
||||
|
||||
EXIT:
|
||||
Py_XDECREF(object);
|
||||
if (name_dup) {
|
||||
PyMem_FREE(name_dup);
|
||||
}
|
||||
return return_value;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
capsule_dealloc(PyObject *o)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
if (capsule->destructor) {
|
||||
capsule->destructor(o);
|
||||
}
|
||||
PyObject_DEL(o);
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
capsule_repr(PyObject *o)
|
||||
{
|
||||
PyCapsule *capsule = (PyCapsule *)o;
|
||||
const char *name;
|
||||
const char *quote;
|
||||
|
||||
if (capsule->name) {
|
||||
quote = "\"";
|
||||
name = capsule->name;
|
||||
} else {
|
||||
quote = "";
|
||||
name = "NULL";
|
||||
}
|
||||
|
||||
return PyUnicode_FromFormat("<capsule object %s%s%s at %p>",
|
||||
quote, name, quote, capsule);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyDoc_STRVAR(PyCapsule_Type__doc__,
|
||||
"Capsule objects let you wrap a C \"void *\" pointer in a Python\n\
|
||||
object. They're a way of passing data through the Python interpreter\n\
|
||||
without creating your own custom type.\n\
|
||||
\n\
|
||||
Capsules are used for communication between extension modules.\n\
|
||||
They provide a way for an extension module to export a C interface\n\
|
||||
to other extension modules, so that extension modules can use the\n\
|
||||
Python import mechanism to link to one another.\n\
|
||||
");
|
||||
|
||||
PyTypeObject PyCapsule_Type = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
"PyCapsule", /*tp_name*/
|
||||
sizeof(PyCapsule), /*tp_basicsize*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
capsule_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
0, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_reserved*/
|
||||
capsule_repr, /*tp_repr*/
|
||||
0, /*tp_as_number*/
|
||||
0, /*tp_as_sequence*/
|
||||
0, /*tp_as_mapping*/
|
||||
0, /*tp_hash*/
|
||||
0, /*tp_call*/
|
||||
0, /*tp_str*/
|
||||
0, /*tp_getattro*/
|
||||
0, /*tp_setattro*/
|
||||
0, /*tp_as_buffer*/
|
||||
0, /*tp_flags*/
|
||||
PyCapsule_Type__doc__ /*tp_doc*/
|
||||
};
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue