[Python-checkins] python/dist/src/Modules structmodule.c,2.51,2.51.8.1

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Mon, 23 Sep 2002 13:54:06 -0700


Update of /cvsroot/python/python/dist/src/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv31421

Modified Files:
      Tag: release22-maint
	structmodule.c 
Log Message:
Backport 2.57 from trunk:

(Most of) SF patch 601369 (Christos Georgiou): obmalloc,structmodule:
64bit, big endian (issue 2 only).

This adds a bunch of memcpy calls via a temporary variable to avoid
alignment errors.  That's needed for some platforms.


Index: structmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v
retrieving revision 2.51
retrieving revision 2.51.8.1
diff -C2 -d -r2.51 -r2.51.8.1
*** structmodule.c	24 Oct 2001 20:37:10 -0000	2.51
--- structmodule.c	23 Sep 2002 20:54:04 -0000	2.51.8.1
***************
*** 1,3 ****
- 
  /* struct module -- pack values into and (out of) strings */
  
--- 1,2 ----
***************
*** 484,487 ****
--- 483,494 ----
  
  /* Native mode routines. ****************************************************/
+ /* NOTE:
+    In all n[up]_<type> routines handling types larger than 1 byte, there is
+    *no* guarantee that the p pointer is properly aligned for each type,
+    therefore memcpy is called.  An intermediate variable is used to
+    compensate for big-endian architectures.
+    Normally both the intermediate variable and the memcpy call will be
+    skipped by C optimisation in little-endian architectures (gcc >= 2.91
+    does this). */
  
  static PyObject *
***************
*** 506,510 ****
  nu_short(const char *p, const formatdef *f)
  {
! 	return PyInt_FromLong((long) *(short *)p);
  }
  
--- 513,519 ----
  nu_short(const char *p, const formatdef *f)
  {
! 	short x;
! 	memcpy((char *)&x, p, sizeof x);
! 	return PyInt_FromLong((long)x);
  }
  
***************
*** 512,516 ****
  nu_ushort(const char *p, const formatdef *f)
  {
! 	return PyInt_FromLong((long) *(unsigned short *)p);
  }
  
--- 521,527 ----
  nu_ushort(const char *p, const formatdef *f)
  {
! 	unsigned short x;
! 	memcpy((char *)&x, p, sizeof x);
! 	return PyInt_FromLong((long)x);
  }
  
***************
*** 518,522 ****
  nu_int(const char *p, const formatdef *f)
  {
! 	return PyInt_FromLong((long) *(int *)p);
  }
  
--- 529,535 ----
  nu_int(const char *p, const formatdef *f)
  {
! 	int x;
! 	memcpy((char *)&x, p, sizeof x);
! 	return PyInt_FromLong((long)x);
  }
  
***************
*** 524,528 ****
  nu_uint(const char *p, const formatdef *f)
  {
! 	unsigned int x = *(unsigned int *)p;
  	return PyLong_FromUnsignedLong((unsigned long)x);
  }
--- 537,542 ----
  nu_uint(const char *p, const formatdef *f)
  {
! 	unsigned int x;
! 	memcpy((char *)&x, p, sizeof x);
  	return PyLong_FromUnsignedLong((unsigned long)x);
  }
***************
*** 531,535 ****
  nu_long(const char *p, const formatdef *f)
  {
! 	return PyInt_FromLong(*(long *)p);
  }
  
--- 545,551 ----
  nu_long(const char *p, const formatdef *f)
  {
! 	long x;
! 	memcpy((char *)&x, p, sizeof x);
! 	return PyInt_FromLong(x);
  }
  
***************
*** 537,541 ****
  nu_ulong(const char *p, const formatdef *f)
  {
! 	return PyLong_FromUnsignedLong(*(unsigned long *)p);
  }
  
--- 553,559 ----
  nu_ulong(const char *p, const formatdef *f)
  {
! 	unsigned long x;
! 	memcpy((char *)&x, p, sizeof x);
! 	return PyLong_FromUnsignedLong(x);
  }
  
***************
*** 548,554 ****
  nu_longlong(const char *p, const formatdef *f)
  {
- 	/* p may not be properly aligned */
  	LONG_LONG x;
! 	memcpy(&x, p, sizeof(LONG_LONG));
  	return PyLong_FromLongLong(x);
  }
--- 566,571 ----
  nu_longlong(const char *p, const formatdef *f)
  {
  	LONG_LONG x;
! 	memcpy((char *)&x, p, sizeof x);
  	return PyLong_FromLongLong(x);
  }
***************
*** 557,565 ****
  nu_ulonglong(const char *p, const formatdef *f)
  {
- 	/* p may not be properly aligned */
  	unsigned LONG_LONG x;
! 	memcpy(&x, p, sizeof(unsigned LONG_LONG));
  	return PyLong_FromUnsignedLongLong(x);
  }
  #endif
  
--- 574,582 ----
  nu_ulonglong(const char *p, const formatdef *f)
  {
  	unsigned LONG_LONG x;
! 	memcpy((char *)&x, p, sizeof x);
  	return PyLong_FromUnsignedLongLong(x);
  }
+ 
  #endif
  
***************
*** 568,572 ****
  {
  	float x;
! 	memcpy((char *)&x, p, sizeof(float));
  	return PyFloat_FromDouble((double)x);
  }
--- 585,589 ----
  {
  	float x;
! 	memcpy((char *)&x, p, sizeof x);
  	return PyFloat_FromDouble((double)x);
  }
***************
*** 576,580 ****
  {
  	double x;
! 	memcpy((char *)&x, p, sizeof(double));
  	return PyFloat_FromDouble(x);
  }
--- 593,597 ----
  {
  	double x;
! 	memcpy((char *)&x, p, sizeof x);
  	return PyFloat_FromDouble(x);
  }
***************
*** 583,587 ****
  nu_void_p(const char *p, const formatdef *f)
  {
! 	return PyLong_FromVoidPtr(*(void **)p);
  }
  
--- 600,606 ----
  nu_void_p(const char *p, const formatdef *f)
  {
! 	void *x;
! 	memcpy((char *)&x, p, sizeof x);
! 	return PyLong_FromVoidPtr(x);
  }
  
***************
*** 632,635 ****
--- 651,655 ----
  {
  	long x;
+ 	short y;
  	if (get_long(v, &x) < 0)
  		return -1;
***************
*** 637,644 ****
  		PyErr_SetString(StructError,
  				"short format requires " STRINGIFY(SHRT_MIN)
!                                 "<=number<=" STRINGIFY(SHRT_MAX));
  		return -1;
  	}
! 	* (short *)p = (short)x;
  	return 0;
  }
--- 657,665 ----
  		PyErr_SetString(StructError,
  				"short format requires " STRINGIFY(SHRT_MIN)
! 				"<=number<=" STRINGIFY(SHRT_MAX));
  		return -1;
  	}
! 	y = (short)x;
! 	memcpy(p, (char *)&y, sizeof y);
  	return 0;
  }
***************
*** 648,651 ****
--- 669,673 ----
  {
  	long x;
+ 	unsigned short y;
  	if (get_long(v, &x) < 0)
  		return -1;
***************
*** 655,659 ****
  		return -1;
  	}
! 	* (unsigned short *)p = (unsigned short)x;
  	return 0;
  }
--- 677,682 ----
  		return -1;
  	}
! 	y = (unsigned short)x;
! 	memcpy(p, (char *)&y, sizeof y);
  	return 0;
  }
***************
*** 663,669 ****
  {
  	long x;
  	if (get_long(v, &x) < 0)
  		return -1;
! 	* (int *)p = x;
  	return 0;
  }
--- 686,694 ----
  {
  	long x;
+ 	int y;
  	if (get_long(v, &x) < 0)
  		return -1;
! 	y = (int)x;
! 	memcpy(p, (char *)&y, sizeof y);
  	return 0;
  }
***************
*** 673,679 ****
  {
  	unsigned long x;
  	if (get_ulong(v, &x) < 0)
  		return -1;
! 	* (unsigned int *)p = x;
  	return 0;
  }
--- 698,706 ----
  {
  	unsigned long x;
+ 	unsigned int y;
  	if (get_ulong(v, &x) < 0)
  		return -1;
! 	y = (unsigned int)x;
! 	memcpy(p, (char *)&y, sizeof y);
  	return 0;
  }
***************
*** 685,689 ****
  	if (get_long(v, &x) < 0)
  		return -1;
! 	* (long *)p = x;
  	return 0;
  }
--- 712,716 ----
  	if (get_long(v, &x) < 0)
  		return -1;
! 	memcpy(p, (char *)&x, sizeof x);
  	return 0;
  }
***************
*** 695,699 ****
  	if (get_ulong(v, &x) < 0)
  		return -1;
! 	* (unsigned long *)p = x;
  	return 0;
  }
--- 722,726 ----
  	if (get_ulong(v, &x) < 0)
  		return -1;
! 	memcpy(p, (char *)&x, sizeof x);
  	return 0;
  }
***************
*** 707,711 ****
  	if (get_longlong(v, &x) < 0)
  		return -1;
! 	memcpy(p, &x, sizeof(LONG_LONG));
  	return 0;
  }
--- 734,738 ----
  	if (get_longlong(v, &x) < 0)
  		return -1;
! 	memcpy(p, (char *)&x, sizeof x);
  	return 0;
  }
***************
*** 717,721 ****
  	if (get_ulonglong(v, &x) < 0)
  		return -1;
! 	memcpy(p, &x, sizeof(unsigned LONG_LONG));
  	return 0;
  }
--- 744,748 ----
  	if (get_ulonglong(v, &x) < 0)
  		return -1;
! 	memcpy(p, (char *)&x, sizeof x);
  	return 0;
  }
***************
*** 731,735 ****
  		return -1;
  	}
! 	memcpy(p, (char *)&x, sizeof(float));
  	return 0;
  }
--- 758,762 ----
  		return -1;
  	}
! 	memcpy(p, (char *)&x, sizeof x);
  	return 0;
  }
***************
*** 759,763 ****
  		return -1;
  	}
! 	*(void **)p = x;
  	return 0;
  }
--- 786,790 ----
  		return -1;
  	}
! 	memcpy(p, (char *)&x, sizeof x);
  	return 0;
  }
***************
*** 1219,1223 ****
  		if (x/itemsize != num || size < 0) {
  			PyErr_SetString(StructError,
!                                         "total struct size too long");
  			return -1;
  		}
--- 1246,1250 ----
  		if (x/itemsize != num || size < 0) {
  			PyErr_SetString(StructError,
! 					"total struct size too long");
  			return -1;
  		}
***************
*** 1268,1272 ****
  	if (args == NULL || !PyTuple_Check(args) ||
  	    (n = PyTuple_Size(args)) < 1)
!         {
  		PyErr_SetString(PyExc_TypeError,
  			"struct.pack requires at least one argument");
--- 1295,1299 ----
  	if (args == NULL || !PyTuple_Check(args) ||
  	    (n = PyTuple_Size(args)) < 1)
! 	{
  		PyErr_SetString(PyExc_TypeError,
  			"struct.pack requires at least one argument");