diff Python/structmember.c @ 42454:648577cc688a legacy-trunk

Handle errors when generating a warning. 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.
author Neal Norwitz <nnorwitz@gmail.com>
date Sun, 05 Aug 2007 03:23:31 +0000
parents 37189e375ec7
children a8dd8874ff2d
line wrap: on
line diff
--- a/Python/structmember.c	Sat Aug 04 04:10:18 2007 +0000
+++ b/Python/structmember.c	Sun Aug 05 03:23:31 2007 +0000
@@ -156,6 +156,12 @@
 	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 @@
 	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;
+		*(unsigned char*)addr = (unsigned char)long_val;
 		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;
+			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;
+		*(short*)addr = (short)long_val;
 		if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
-			PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to short");
-		*(short*)addr = (short)long_val;
+			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;
+		*(unsigned short*)addr = (unsigned short)long_val;
 		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;
+			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;
+		*(int *)addr = (int)long_val;
 		if ((long_val > INT_MAX) || (long_val < INT_MIN))
-			PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to int");
-		*(int *)addr = (int)long_val;
+			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 @@
 			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 @@
 			   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 @@
 		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;