]> granicus.if.org Git - python/commitdiff
Handle errors when generating a warning.
authorNeal Norwitz <nnorwitz@gmail.com>
Sun, 5 Aug 2007 03:23:31 +0000 (03:23 +0000)
committerNeal Norwitz <nnorwitz@gmail.com>
Sun, 5 Aug 2007 03:23:31 +0000 (03:23 +0000)
The value is always written to the returned pointer if getting it was
successful, even if a warning causes an error. (This probably doesn't matter
as the caller will probably discard the value.)

Will backport.

Python/structmember.c

index 4da0c7861c3ed7eaeba8686f7631f81299116161..7cfa620a176499c851cc9330ea2fe240d3c3bd15 100644 (file)
@@ -156,6 +156,12 @@ PyMember_Set(char *addr, struct memberlist *mlist, const char *name, PyObject *v
        return -1;
 }
 
+#define WARN(msg)                                      \
+    do {                                               \
+       if (PyErr_Warn(PyExc_RuntimeWarning, msg) < 0)  \
+               return -1;                              \
+    } while (0)
+
 int
 PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
 {
@@ -178,60 +184,54 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
        addr += l->offset;
        switch (l->type) {
        case T_BYTE:{
-               long long_val;
-               long_val = PyInt_AsLong(v);
+               long long_val = PyInt_AsLong(v);
                if ((long_val == -1) && PyErr_Occurred())
                        return -1;
+               *(char*)addr = (char)long_val;
                /* XXX: For compatibility, only warn about truncations
                   for now. */
                if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
-                       PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to char");
-               *(char*)addr = (char)long_val;
+                       WARN("Truncation of value to char");
                break;
                }
        case T_UBYTE:{
-               long long_val;
-               long_val = PyInt_AsLong(v);
+               long long_val = PyInt_AsLong(v);
                if ((long_val == -1) && PyErr_Occurred())
                        return -1;
-               if ((long_val > UCHAR_MAX) || (long_val < 0))
-                       PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned char");
                *(unsigned char*)addr = (unsigned char)long_val;
+               if ((long_val > UCHAR_MAX) || (long_val < 0))
+                       WARN("Truncation of value to unsigned char");
                break;
                }
        case T_SHORT:{
-               long long_val;
-               long_val = PyInt_AsLong(v);
+               long long_val = PyInt_AsLong(v);
                if ((long_val == -1) && PyErr_Occurred())
                        return -1;
-               if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
-                       PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to short");
                *(short*)addr = (short)long_val;
+               if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
+                       WARN("Truncation of value to short");
                break;
                }
        case T_USHORT:{
-               long long_val;
-               long_val = PyInt_AsLong(v);
+               long long_val = PyInt_AsLong(v);
                if ((long_val == -1) && PyErr_Occurred())
                        return -1;
-               if ((long_val > USHRT_MAX) || (long_val < 0))
-                       PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned short");
                *(unsigned short*)addr = (unsigned short)long_val;
+               if ((long_val > USHRT_MAX) || (long_val < 0))
+                       WARN("Truncation of value to unsigned short");
                break;
                }
        case T_INT:{
-               long long_val;
-               long_val = PyInt_AsLong(v);
+               long long_val = PyInt_AsLong(v);
                if ((long_val == -1) && PyErr_Occurred())
                        return -1;
-               if ((long_val > INT_MAX) || (long_val < INT_MIN))
-                       PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to int");
                *(int *)addr = (int)long_val;
+               if ((long_val > INT_MAX) || (long_val < INT_MIN))
+                       WARN("Truncation of value to int");
                break;
                }
        case T_UINT:{
-               unsigned long ulong_val;
-               ulong_val = PyLong_AsUnsignedLong(v);
+               unsigned long ulong_val = PyLong_AsUnsignedLong(v);
                if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
                        /* XXX: For compatibility, accept negative int values
                           as well. */
@@ -239,11 +239,12 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
                        ulong_val = PyLong_AsLong(v);
                        if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
                                return -1;
-                       PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
-               }
+                       *(unsigned int *)addr = (unsigned int)ulong_val;
+                       WARN("Writing negative value into unsigned field");
+               } else
+                       *(unsigned int *)addr = (unsigned int)ulong_val;
                if (ulong_val > UINT_MAX)
-                       PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned int");
-               *(unsigned int *)addr = (unsigned int)ulong_val;
+                       WARN("Truncation of value to unsigned int");
                break;
                }
        case T_LONG:{
@@ -260,9 +261,10 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
                           as well. */
                        PyErr_Clear();
                        *(unsigned long*)addr = PyLong_AsLong(v);
-                       if ((*(unsigned long*)addr == (unsigned int)-1) && PyErr_Occurred())
+                       if ((*(unsigned long*)addr == (unsigned int)-1)
+                           && PyErr_Occurred())
                                return -1;
-                       PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
+                       WARN("Writing negative value into unsigned field");
                }
                break;
                }
@@ -274,8 +276,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
                break;
                }
        case T_FLOAT:{
-               double double_val;
-               double_val = PyFloat_AsDouble(v);
+               double double_val = PyFloat_AsDouble(v);
                if ((double_val == -1) && PyErr_Occurred())
                        return -1;
                *(float*)addr = (float)double_val;