ยปCore Development>Code coverage>Python/structmember.c

Python code coverage for Python/structmember.c

#countcontent
1n/a
2n/a/* Map C struct members to Python object attributes */
3n/a
4n/a#include "Python.h"
5n/a
6n/a#include "structmember.h"
7n/a
8n/aPyObject *
9n/aPyMember_GetOne(const char *addr, PyMemberDef *l)
10n/a{
11n/a PyObject *v;
12n/a
13n/a addr += l->offset;
14n/a switch (l->type) {
15n/a case T_BOOL:
16n/a v = PyBool_FromLong(*(char*)addr);
17n/a break;
18n/a case T_BYTE:
19n/a v = PyLong_FromLong(*(char*)addr);
20n/a break;
21n/a case T_UBYTE:
22n/a v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
23n/a break;
24n/a case T_SHORT:
25n/a v = PyLong_FromLong(*(short*)addr);
26n/a break;
27n/a case T_USHORT:
28n/a v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
29n/a break;
30n/a case T_INT:
31n/a v = PyLong_FromLong(*(int*)addr);
32n/a break;
33n/a case T_UINT:
34n/a v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
35n/a break;
36n/a case T_LONG:
37n/a v = PyLong_FromLong(*(long*)addr);
38n/a break;
39n/a case T_ULONG:
40n/a v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
41n/a break;
42n/a case T_PYSSIZET:
43n/a v = PyLong_FromSsize_t(*(Py_ssize_t*)addr);
44n/a break;
45n/a case T_FLOAT:
46n/a v = PyFloat_FromDouble((double)*(float*)addr);
47n/a break;
48n/a case T_DOUBLE:
49n/a v = PyFloat_FromDouble(*(double*)addr);
50n/a break;
51n/a case T_STRING:
52n/a if (*(char**)addr == NULL) {
53n/a Py_INCREF(Py_None);
54n/a v = Py_None;
55n/a }
56n/a else
57n/a v = PyUnicode_FromString(*(char**)addr);
58n/a break;
59n/a case T_STRING_INPLACE:
60n/a v = PyUnicode_FromString((char*)addr);
61n/a break;
62n/a case T_CHAR:
63n/a v = PyUnicode_FromStringAndSize((char*)addr, 1);
64n/a break;
65n/a case T_OBJECT:
66n/a v = *(PyObject **)addr;
67n/a if (v == NULL)
68n/a v = Py_None;
69n/a Py_INCREF(v);
70n/a break;
71n/a case T_OBJECT_EX:
72n/a v = *(PyObject **)addr;
73n/a if (v == NULL)
74n/a PyErr_SetString(PyExc_AttributeError, l->name);
75n/a Py_XINCREF(v);
76n/a break;
77n/a case T_LONGLONG:
78n/a v = PyLong_FromLongLong(*(long long *)addr);
79n/a break;
80n/a case T_ULONGLONG:
81n/a v = PyLong_FromUnsignedLongLong(*(unsigned long long *)addr);
82n/a break;
83n/a case T_NONE:
84n/a v = Py_None;
85n/a Py_INCREF(v);
86n/a break;
87n/a default:
88n/a PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
89n/a v = NULL;
90n/a }
91n/a return v;
92n/a}
93n/a
94n/a#define WARN(msg) \
95n/a do { \
96n/a if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) \
97n/a return -1; \
98n/a } while (0)
99n/a
100n/aint
101n/aPyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
102n/a{
103n/a PyObject *oldv;
104n/a
105n/a addr += l->offset;
106n/a
107n/a if ((l->flags & READONLY))
108n/a {
109n/a PyErr_SetString(PyExc_AttributeError, "readonly attribute");
110n/a return -1;
111n/a }
112n/a if (v == NULL) {
113n/a if (l->type == T_OBJECT_EX) {
114n/a /* Check if the attribute is set. */
115n/a if (*(PyObject **)addr == NULL) {
116n/a PyErr_SetString(PyExc_AttributeError, l->name);
117n/a return -1;
118n/a }
119n/a }
120n/a else if (l->type != T_OBJECT) {
121n/a PyErr_SetString(PyExc_TypeError,
122n/a "can't delete numeric/char attribute");
123n/a return -1;
124n/a }
125n/a }
126n/a switch (l->type) {
127n/a case T_BOOL:{
128n/a if (!PyBool_Check(v)) {
129n/a PyErr_SetString(PyExc_TypeError,
130n/a "attribute value type must be bool");
131n/a return -1;
132n/a }
133n/a if (v == Py_True)
134n/a *(char*)addr = (char) 1;
135n/a else
136n/a *(char*)addr = (char) 0;
137n/a break;
138n/a }
139n/a case T_BYTE:{
140n/a long long_val = PyLong_AsLong(v);
141n/a if ((long_val == -1) && PyErr_Occurred())
142n/a return -1;
143n/a *(char*)addr = (char)long_val;
144n/a /* XXX: For compatibility, only warn about truncations
145n/a for now. */
146n/a if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
147n/a WARN("Truncation of value to char");
148n/a break;
149n/a }
150n/a case T_UBYTE:{
151n/a long long_val = PyLong_AsLong(v);
152n/a if ((long_val == -1) && PyErr_Occurred())
153n/a return -1;
154n/a *(unsigned char*)addr = (unsigned char)long_val;
155n/a if ((long_val > UCHAR_MAX) || (long_val < 0))
156n/a WARN("Truncation of value to unsigned char");
157n/a break;
158n/a }
159n/a case T_SHORT:{
160n/a long long_val = PyLong_AsLong(v);
161n/a if ((long_val == -1) && PyErr_Occurred())
162n/a return -1;
163n/a *(short*)addr = (short)long_val;
164n/a if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
165n/a WARN("Truncation of value to short");
166n/a break;
167n/a }
168n/a case T_USHORT:{
169n/a long long_val = PyLong_AsLong(v);
170n/a if ((long_val == -1) && PyErr_Occurred())
171n/a return -1;
172n/a *(unsigned short*)addr = (unsigned short)long_val;
173n/a if ((long_val > USHRT_MAX) || (long_val < 0))
174n/a WARN("Truncation of value to unsigned short");
175n/a break;
176n/a }
177n/a case T_INT:{
178n/a long long_val = PyLong_AsLong(v);
179n/a if ((long_val == -1) && PyErr_Occurred())
180n/a return -1;
181n/a *(int *)addr = (int)long_val;
182n/a if ((long_val > INT_MAX) || (long_val < INT_MIN))
183n/a WARN("Truncation of value to int");
184n/a break;
185n/a }
186n/a case T_UINT:{
187n/a unsigned long ulong_val = PyLong_AsUnsignedLong(v);
188n/a if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) {
189n/a /* XXX: For compatibility, accept negative int values
190n/a as well. */
191n/a PyErr_Clear();
192n/a ulong_val = PyLong_AsLong(v);
193n/a if ((ulong_val == (unsigned long)-1) &&
194n/a PyErr_Occurred())
195n/a return -1;
196n/a *(unsigned int *)addr = (unsigned int)ulong_val;
197n/a WARN("Writing negative value into unsigned field");
198n/a } else
199n/a *(unsigned int *)addr = (unsigned int)ulong_val;
200n/a if (ulong_val > UINT_MAX)
201n/a WARN("Truncation of value to unsigned int");
202n/a break;
203n/a }
204n/a case T_LONG:{
205n/a *(long*)addr = PyLong_AsLong(v);
206n/a if ((*(long*)addr == -1) && PyErr_Occurred())
207n/a return -1;
208n/a break;
209n/a }
210n/a case T_ULONG:{
211n/a *(unsigned long*)addr = PyLong_AsUnsignedLong(v);
212n/a if ((*(unsigned long*)addr == (unsigned long)-1)
213n/a && PyErr_Occurred()) {
214n/a /* XXX: For compatibility, accept negative int values
215n/a as well. */
216n/a PyErr_Clear();
217n/a *(unsigned long*)addr = PyLong_AsLong(v);
218n/a if ((*(unsigned long*)addr == (unsigned long)-1)
219n/a && PyErr_Occurred())
220n/a return -1;
221n/a WARN("Writing negative value into unsigned field");
222n/a }
223n/a break;
224n/a }
225n/a case T_PYSSIZET:{
226n/a *(Py_ssize_t*)addr = PyLong_AsSsize_t(v);
227n/a if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1)
228n/a && PyErr_Occurred())
229n/a return -1;
230n/a break;
231n/a }
232n/a case T_FLOAT:{
233n/a double double_val = PyFloat_AsDouble(v);
234n/a if ((double_val == -1) && PyErr_Occurred())
235n/a return -1;
236n/a *(float*)addr = (float)double_val;
237n/a break;
238n/a }
239n/a case T_DOUBLE:
240n/a *(double*)addr = PyFloat_AsDouble(v);
241n/a if ((*(double*)addr == -1) && PyErr_Occurred())
242n/a return -1;
243n/a break;
244n/a case T_OBJECT:
245n/a case T_OBJECT_EX:
246n/a Py_XINCREF(v);
247n/a oldv = *(PyObject **)addr;
248n/a *(PyObject **)addr = v;
249n/a Py_XDECREF(oldv);
250n/a break;
251n/a case T_CHAR: {
252n/a const char *string;
253n/a Py_ssize_t len;
254n/a
255n/a string = PyUnicode_AsUTF8AndSize(v, &len);
256n/a if (string == NULL || len != 1) {
257n/a PyErr_BadArgument();
258n/a return -1;
259n/a }
260n/a *(char*)addr = string[0];
261n/a break;
262n/a }
263n/a case T_STRING:
264n/a case T_STRING_INPLACE:
265n/a PyErr_SetString(PyExc_TypeError, "readonly attribute");
266n/a return -1;
267n/a case T_LONGLONG:{
268n/a long long value;
269n/a *(long long*)addr = value = PyLong_AsLongLong(v);
270n/a if ((value == -1) && PyErr_Occurred())
271n/a return -1;
272n/a break;
273n/a }
274n/a case T_ULONGLONG:{
275n/a unsigned long long value;
276n/a /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong
277n/a doesn't ??? */
278n/a if (PyLong_Check(v))
279n/a *(unsigned long long*)addr = value = PyLong_AsUnsignedLongLong(v);
280n/a else
281n/a *(unsigned long long*)addr = value = PyLong_AsLong(v);
282n/a if ((value == (unsigned long long)-1) && PyErr_Occurred())
283n/a return -1;
284n/a break;
285n/a }
286n/a default:
287n/a PyErr_Format(PyExc_SystemError,
288n/a "bad memberdescr type for %s", l->name);
289n/a return -1;
290n/a }
291n/a return 0;
292n/a}