Branch data Line data Source code
1 : : #define PY_SSIZE_T_CLEAN
2 : : #include "parts.h"
3 : : #include <stddef.h> // for offsetof()
4 : :
5 : :
6 : : // This defines two classes that contain all the simple member types, one
7 : : // using "new" Py_-prefixed API, and the other using "old" <structmember.h>.
8 : : // They should behave identically in Python.
9 : :
10 : : typedef struct {
11 : : char bool_member;
12 : : char byte_member;
13 : : unsigned char ubyte_member;
14 : : short short_member;
15 : : unsigned short ushort_member;
16 : : int int_member;
17 : : unsigned int uint_member;
18 : : long long_member;
19 : : unsigned long ulong_member;
20 : : Py_ssize_t pyssizet_member;
21 : : float float_member;
22 : : double double_member;
23 : : char inplace_member[6];
24 : : long long longlong_member;
25 : : unsigned long long ulonglong_member;
26 : : } all_structmembers;
27 : :
28 : : typedef struct {
29 : : PyObject_HEAD
30 : : all_structmembers structmembers;
31 : : } test_structmembers;
32 : :
33 : :
34 : : static struct PyMemberDef test_members_newapi[] = {
35 : : {"T_BOOL", Py_T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL},
36 : : {"T_BYTE", Py_T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL},
37 : : {"T_UBYTE", Py_T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL},
38 : : {"T_SHORT", Py_T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL},
39 : : {"T_USHORT", Py_T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL},
40 : : {"T_INT", Py_T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL},
41 : : {"T_UINT", Py_T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL},
42 : : {"T_LONG", Py_T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL},
43 : : {"T_ULONG", Py_T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL},
44 : : {"T_PYSSIZET", Py_T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL},
45 : : {"T_FLOAT", Py_T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
46 : : {"T_DOUBLE", Py_T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
47 : : {"T_STRING_INPLACE", Py_T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL},
48 : : {"T_LONGLONG", Py_T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL},
49 : : {"T_ULONGLONG", Py_T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL},
50 : : {NULL}
51 : : };
52 : :
53 : : static PyObject *
54 : 0 : test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
55 : : {
56 : : static char *keywords[] = {
57 : : "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT",
58 : : "T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_PYSSIZET",
59 : : "T_FLOAT", "T_DOUBLE", "T_STRING_INPLACE",
60 : : "T_LONGLONG", "T_ULONGLONG",
61 : : NULL};
62 : : static const char fmt[] = "|bbBhHiIlknfds#LK";
63 : : test_structmembers *ob;
64 : 0 : const char *s = NULL;
65 : 0 : Py_ssize_t string_len = 0;
66 : 0 : ob = PyObject_New(test_structmembers, type);
67 [ # # ]: 0 : if (ob == NULL) {
68 : 0 : return NULL;
69 : : }
70 : 0 : memset(&ob->structmembers, 0, sizeof(all_structmembers));
71 [ # # ]: 0 : if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords,
72 : : &ob->structmembers.bool_member,
73 : : &ob->structmembers.byte_member,
74 : : &ob->structmembers.ubyte_member,
75 : : &ob->structmembers.short_member,
76 : : &ob->structmembers.ushort_member,
77 : : &ob->structmembers.int_member,
78 : : &ob->structmembers.uint_member,
79 : : &ob->structmembers.long_member,
80 : : &ob->structmembers.ulong_member,
81 : : &ob->structmembers.pyssizet_member,
82 : : &ob->structmembers.float_member,
83 : : &ob->structmembers.double_member,
84 : : &s, &string_len,
85 : : &ob->structmembers.longlong_member,
86 : : &ob->structmembers.ulonglong_member))
87 : : {
88 : 0 : Py_DECREF(ob);
89 : 0 : return NULL;
90 : : }
91 [ # # ]: 0 : if (s != NULL) {
92 [ # # ]: 0 : if (string_len > 5) {
93 : 0 : Py_DECREF(ob);
94 : 0 : PyErr_SetString(PyExc_ValueError, "string too long");
95 : 0 : return NULL;
96 : : }
97 : 0 : strcpy(ob->structmembers.inplace_member, s);
98 : : }
99 : : else {
100 : 0 : strcpy(ob->structmembers.inplace_member, "");
101 : : }
102 : 0 : return (PyObject *)ob;
103 : : }
104 : :
105 : : static PyType_Slot test_structmembers_slots[] = {
106 : : {Py_tp_new, test_structmembers_new},
107 : : {Py_tp_members, test_members_newapi},
108 : : {0},
109 : : };
110 : :
111 : : static PyType_Spec test_structmembers_spec = {
112 : : .name = "_testcapi._test_structmembersType_NewAPI",
113 : : .flags = Py_TPFLAGS_DEFAULT,
114 : : .basicsize = sizeof(test_structmembers),
115 : : .slots = test_structmembers_slots,
116 : : };
117 : :
118 : : #include <structmember.h>
119 : :
120 : : static struct PyMemberDef test_members[] = {
121 : : {"T_BOOL", T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL},
122 : : {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL},
123 : : {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL},
124 : : {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL},
125 : : {"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL},
126 : : {"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL},
127 : : {"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL},
128 : : {"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL},
129 : : {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL},
130 : : {"T_PYSSIZET", T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL},
131 : : {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL},
132 : : {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL},
133 : : {"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL},
134 : : {"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL},
135 : : {"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL},
136 : : {NULL}
137 : : };
138 : :
139 : :
140 : : static void
141 : 0 : test_structmembers_free(PyObject *ob)
142 : : {
143 : 0 : PyObject_Free(ob);
144 : 0 : }
145 : :
146 : : /* Designated initializers would work too, but this does test the *old* API */
147 : : static PyTypeObject test_structmembersType_OldAPI= {
148 : : PyVarObject_HEAD_INIT(NULL, 0)
149 : : "test_structmembersType_OldAPI",
150 : : sizeof(test_structmembers), /* tp_basicsize */
151 : : 0, /* tp_itemsize */
152 : : test_structmembers_free, /* destructor tp_dealloc */
153 : : 0, /* tp_vectorcall_offset */
154 : : 0, /* tp_getattr */
155 : : 0, /* tp_setattr */
156 : : 0, /* tp_as_async */
157 : : 0, /* tp_repr */
158 : : 0, /* tp_as_number */
159 : : 0, /* tp_as_sequence */
160 : : 0, /* tp_as_mapping */
161 : : 0, /* tp_hash */
162 : : 0, /* tp_call */
163 : : 0, /* tp_str */
164 : : PyObject_GenericGetAttr, /* tp_getattro */
165 : : PyObject_GenericSetAttr, /* tp_setattro */
166 : : 0, /* tp_as_buffer */
167 : : 0, /* tp_flags */
168 : : "Type containing all structmember types",
169 : : 0, /* traverseproc tp_traverse */
170 : : 0, /* tp_clear */
171 : : 0, /* tp_richcompare */
172 : : 0, /* tp_weaklistoffset */
173 : : 0, /* tp_iter */
174 : : 0, /* tp_iternext */
175 : : 0, /* tp_methods */
176 : : test_members, /* tp_members */
177 : : 0,
178 : : 0,
179 : : 0,
180 : : 0,
181 : : 0,
182 : : 0,
183 : : 0,
184 : : 0,
185 : : test_structmembers_new, /* tp_new */
186 : : };
187 : :
188 : :
189 : : int
190 : 2 : _PyTestCapi_Init_Structmember(PyObject *m)
191 : : {
192 : : int res;
193 : 2 : res = PyType_Ready(&test_structmembersType_OldAPI);
194 [ - + ]: 2 : if (res < 0) {
195 : 0 : return -1;
196 : : }
197 : 2 : res = PyModule_AddObject(
198 : : m,
199 : : "_test_structmembersType_OldAPI",
200 : : (PyObject *)&test_structmembersType_OldAPI);
201 [ - + ]: 2 : if (res < 0) {
202 : 0 : return -1;
203 : : }
204 : :
205 : 2 : PyObject *test_structmembersType_NewAPI = PyType_FromModuleAndSpec(
206 : : m, &test_structmembers_spec, NULL);
207 [ - + ]: 2 : if (!test_structmembersType_NewAPI) {
208 : 0 : return -1;
209 : : }
210 : 2 : res = PyModule_AddType(m, (PyTypeObject*)test_structmembersType_NewAPI);
211 : 2 : Py_DECREF(test_structmembersType_NewAPI);
212 [ - + ]: 2 : if (res < 0) {
213 : 0 : return -1;
214 : : }
215 : :
216 : 2 : return 0;
217 : : }
|