~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_static_tuple_c.h

  • Committer: John Arbash Meinel
  • Date: 2009-10-01 21:34:36 UTC
  • mto: (4679.6.1 2.1-export-c-api)
  • mto: This revision was merged to the branch mainline in revision 4735.
  • Revision ID: john@arbash-meinel.com-20091001213436-d7vbe0xr17eave03
Factor out some of the C API code into some helper headers.

This should make the process a bit easier, if we ever decide to do
something similar again.

Show diffs side-by-side

added added

removed removed

Lines of Context:
66
66
    PyObject *table[0];
67
67
} KeyIntern;
68
68
 
69
 
#define StaticTuple_CheckExact(op) (Py_TYPE(op) == &StaticTuple_Type)
70
69
#define StaticTuple_SET_ITEM(key, offset, val) \
71
70
    ((((StaticTuple*)(key))->items[(offset)]) = ((PyObject *)(val)))
72
71
#define StaticTuple_GET_ITEM(key, offset) (((StaticTuple*)key)->items[offset])
73
72
 
74
73
 
75
 
static const char *_C_API_NAME = "_C_API";
76
 
 
77
74
#ifdef STATIC_TUPLE_MODULE
78
75
/* Used when compiling _static_tuple_c.c */
79
76
 
80
77
static StaticTuple * StaticTuple_New(Py_ssize_t);
81
78
static StaticTuple * StaticTuple_intern(StaticTuple *self);
 
79
#define StaticTuple_CheckExact(op) (Py_TYPE(op) == &StaticTuple_Type)
82
80
 
83
81
#else
84
82
/* Used as the foreign api */
85
83
 
 
84
#include "_import_c_api.h"
 
85
 
86
86
static StaticTuple *(*StaticTuple_New)(Py_ssize_t);
87
87
static StaticTuple *(*StaticTuple_intern)(StaticTuple *);
88
88
static PyTypeObject *_p_StaticTuple_Type;
91
91
static int (*_StaticTuple_CheckExact)(PyObject *);
92
92
 
93
93
 
94
 
static int _import_function(PyObject *module, char *funcname,
95
 
                            void **f, char *signature)
96
 
{
97
 
    PyObject *d = NULL;
98
 
    PyObject *c_obj = NULL;
99
 
    char *desc = NULL;
100
 
 
101
 
    d = PyObject_GetAttrString(module, _C_API_NAME);
102
 
    if (!d) {
103
 
        // PyObject_GetAttrString sets an appropriate exception
104
 
        goto bad;
105
 
    }
106
 
    c_obj = PyDict_GetItemString(d, funcname);
107
 
    if (!c_obj) {
108
 
        // PyDict_GetItemString does not set an exception
109
 
        PyErr_Format(PyExc_AttributeError,
110
 
            "Module %s did not export a function named %s\n",
111
 
            PyModule_GetName(module), funcname);
112
 
        goto bad;
113
 
    }
114
 
    desc = (char *)PyCObject_GetDesc(c_obj);
115
 
    if (!desc || strcmp(desc, signature) != 0) {
116
 
        if (desc == NULL) {
117
 
            desc = "<null>";
118
 
        }
119
 
        PyErr_Format(PyExc_TypeError,
120
 
            "C function %s.%s has wrong signature (expected %s, got %s)",
121
 
                PyModule_GetName(module), funcname, signature, desc);
122
 
        goto bad;
123
 
    }
124
 
    *f = PyCObject_AsVoidPtr(c_obj);
125
 
    Py_DECREF(d);
126
 
    return 0;
127
 
bad:
128
 
    Py_XDECREF(d);
129
 
    return -1;
130
 
}
131
 
 
132
 
 
133
 
static PyTypeObject *
134
 
_import_type(PyObject *module, char *class_name)
135
 
{
136
 
    PyObject *type = NULL;
137
 
 
138
 
    type = PyObject_GetAttrString(module, class_name);
139
 
    if (!type) {
140
 
        goto bad;
141
 
    }
142
 
    if (!PyType_Check(type)) {
143
 
        PyErr_Format(PyExc_TypeError,
144
 
            "%s.%s is not a type object",
145
 
            PyModule_GetName(module), class_name);
146
 
        goto bad;
147
 
    }
148
 
    return (PyTypeObject *)type;
149
 
bad:
150
 
    Py_XDECREF(type);
151
 
    return NULL;
152
 
}
153
 
 
154
 
 
155
94
/* Return -1 and set exception on error, 0 on success */
156
95
static int
157
96
import_static_tuple_c(void)
158
97
{
159
 
    /* This is modeled after the implementation in Pyrex, which uses a
160
 
     * dictionary and descriptors, rather than using plain offsets into a
161
 
     * void ** array.
162
 
     */
163
 
    PyObject *module = NULL;
164
 
    
165
 
    module = PyImport_ImportModule("bzrlib._static_tuple_c");
166
 
    if (!module) goto bad;
167
 
    if (_import_function(module, "StaticTuple_New", (void **)&StaticTuple_New,
168
 
                         "StaticTuple *(Py_ssize_t)") < 0)
169
 
        goto bad;
170
 
    if (_import_function(module, "StaticTuple_intern",
171
 
                         (void **)&StaticTuple_intern,
172
 
                         "StaticTuple *(StaticTuple *)") < 0)
173
 
        goto bad;
174
 
    if (_import_function(module, "_StaticTuple_CheckExact",
175
 
                         (void **)&_StaticTuple_CheckExact,
176
 
                         "int(PyObject *)") < 0)
177
 
        goto bad;
178
 
    _p_StaticTuple_Type = _import_type(module, "StaticTuple");
179
 
    if (!_p_StaticTuple_Type) {
180
 
        goto bad;
181
 
    }
182
 
    Py_DECREF(module); 
183
 
    return 0;
184
 
bad:
185
 
    Py_XDECREF(module);
186
 
    return -1;
 
98
    struct function_description functions[] = {
 
99
        {"StaticTuple_New", (void **)&StaticTuple_New,
 
100
            "StaticTuple *(Py_ssize_t)"},
 
101
        {"StaticTuple_intern", (void **)&StaticTuple_intern,
 
102
            "StaticTuple *(StaticTuple *)"},
 
103
        {"_StaticTuple_CheckExact", (void **)&_StaticTuple_CheckExact,
 
104
            "int(PyObject *)"},
 
105
        {NULL}};
 
106
    struct type_description types[] = {
 
107
        {"StaticTuple", &_p_StaticTuple_Type},
 
108
        {NULL}};
 
109
    return _import_extension_module("bzrlib._static_tuple_c",
 
110
        functions, types);
187
111
}
188
112
 
189
113
#endif // !STATIC_TUPLE_MODULE