]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/python/contrib/Modules/_struct.c
Inital import
[l4.git] / l4 / pkg / python / contrib / Modules / _struct.c
1 /* struct module -- pack values into and (out of) strings */
2
3 /* New version supporting byte order, alignment and size options,
4    character strings, and unsigned numbers */
5
6 #define PY_SSIZE_T_CLEAN
7
8 #include "Python.h"
9 #include "structseq.h"
10 #include "structmember.h"
11 #include <ctype.h>
12
13 static PyTypeObject PyStructType;
14
15 /* compatibility macros */
16 #if (PY_VERSION_HEX < 0x02050000)
17 typedef int Py_ssize_t;
18 #endif
19
20 /* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input
21    numbers for explicit endians such that they fit in the given type, much
22    like explicit casting in C. A warning will be raised if the number did
23    not originally fit within the range of the requested type. If it is
24    not defined, then all range errors and overflow will be struct.error
25    exceptions. */
26
27 #define PY_STRUCT_OVERFLOW_MASKING 1
28
29 #ifdef PY_STRUCT_OVERFLOW_MASKING
30 static PyObject *pylong_ulong_mask = NULL;
31 static PyObject *pyint_zero = NULL;
32 #endif
33
34 /* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float
35    arguments for integer formats with a warning for backwards
36    compatibility. */
37
38 #define PY_STRUCT_FLOAT_COERCE 1
39
40 #ifdef PY_STRUCT_FLOAT_COERCE
41 #define FLOAT_COERCE "integer argument expected, got float"
42 #endif
43
44
45 /* The translation function for each format character is table driven */
46 typedef struct _formatdef {
47         char format;
48         Py_ssize_t size;
49         Py_ssize_t alignment;
50         PyObject* (*unpack)(const char *,
51                             const struct _formatdef *);
52         int (*pack)(char *, PyObject *,
53                     const struct _formatdef *);
54 } formatdef;
55
56 typedef struct _formatcode {
57         const struct _formatdef *fmtdef;
58         Py_ssize_t offset;
59         Py_ssize_t size;
60 } formatcode;
61
62 /* Struct object interface */
63
64 typedef struct {
65         PyObject_HEAD
66         Py_ssize_t s_size;
67         Py_ssize_t s_len;
68         formatcode *s_codes;
69         PyObject *s_format;
70         PyObject *weakreflist; /* List of weak references */
71 } PyStructObject;
72
73
74 #define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
75 #define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType)
76
77
78 /* Exception */
79
80 static PyObject *StructError;
81
82
83 /* Define various structs to figure out the alignments of types */
84
85
86 typedef struct { char c; short x; } st_short;
87 typedef struct { char c; int x; } st_int;
88 typedef struct { char c; long x; } st_long;
89 typedef struct { char c; float x; } st_float;
90 typedef struct { char c; double x; } st_double;
91 typedef struct { char c; void *x; } st_void_p;
92
93 #define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
94 #define INT_ALIGN (sizeof(st_int) - sizeof(int))
95 #define LONG_ALIGN (sizeof(st_long) - sizeof(long))
96 #define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
97 #define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
98 #define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
99
100 /* We can't support q and Q in native mode unless the compiler does;
101    in std mode, they're 8 bytes on all platforms. */
102 #ifdef HAVE_LONG_LONG
103 typedef struct { char c; PY_LONG_LONG x; } s_long_long;
104 #define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
105 #endif
106
107 #ifdef HAVE_C99_BOOL
108 #define BOOL_TYPE _Bool
109 typedef struct { char c; _Bool x; } s_bool;
110 #define BOOL_ALIGN (sizeof(s_bool) - sizeof(BOOL_TYPE))
111 #else
112 #define BOOL_TYPE char
113 #define BOOL_ALIGN 0
114 #endif
115
116 #define STRINGIFY(x)    #x
117
118 #ifdef __powerc
119 #pragma options align=reset
120 #endif
121
122 /* Helper to get a PyLongObject by hook or by crook.  Caller should decref. */
123
124 static PyObject *
125 get_pylong(PyObject *v)
126 {
127         PyNumberMethods *m;
128
129         assert(v != NULL);
130         if (PyInt_Check(v))
131                 return PyLong_FromLong(PyInt_AS_LONG(v));
132         if (PyLong_Check(v)) {
133                 Py_INCREF(v);
134                 return v;
135         }
136         m = Py_TYPE(v)->tp_as_number;
137         if (m != NULL && m->nb_long != NULL) {
138                 v = m->nb_long(v);
139                 if (v == NULL)
140                         return NULL;
141                 if (PyLong_Check(v))
142                         return v;
143                 Py_DECREF(v);
144         }
145         PyErr_SetString(StructError,
146                         "cannot convert argument to long");
147         return NULL;
148 }
149
150 /* Helper routine to get a Python integer and raise the appropriate error
151    if it isn't one */
152
153 static int
154 get_long(PyObject *v, long *p)
155 {
156         long x = PyInt_AsLong(v);
157         if (x == -1 && PyErr_Occurred()) {
158 #ifdef PY_STRUCT_FLOAT_COERCE
159                 if (PyFloat_Check(v)) {
160                         PyObject *o;
161                         int res;
162                         PyErr_Clear();
163                         if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
164                                 return -1;
165                         o = PyNumber_Int(v);
166                         if (o == NULL)
167                                 return -1;
168                         res = get_long(o, p);
169                         Py_DECREF(o);
170                         return res;
171                 }
172 #endif
173                 if (PyErr_ExceptionMatches(PyExc_TypeError))
174                         PyErr_SetString(StructError,
175                                         "required argument is not an integer");
176                 return -1;
177         }
178         *p = x;
179         return 0;
180 }
181
182
183 /* Same, but handling unsigned long */
184
185 #ifndef PY_STRUCT_OVERFLOW_MASKING
186
187 static int
188 get_ulong(PyObject *v, unsigned long *p)
189 {
190         if (PyLong_Check(v)) {
191                 unsigned long x = PyLong_AsUnsignedLong(v);
192                 if (x == (unsigned long)(-1) && PyErr_Occurred())
193                         return -1;
194                 *p = x;
195                 return 0;
196         }
197         if (get_long(v, (long *)p) < 0)
198                 return -1;
199         if (((long)*p) < 0) {
200                 PyErr_SetString(StructError,
201                                 "unsigned argument is < 0");
202                 return -1;
203         }
204         return 0;
205 }
206
207 #endif /* PY_STRUCT_OVERFLOW_MASKING */
208
209 #ifdef HAVE_LONG_LONG
210
211 /* Same, but handling native long long. */
212
213 static int
214 get_longlong(PyObject *v, PY_LONG_LONG *p)
215 {
216         PY_LONG_LONG x;
217
218         v = get_pylong(v);
219         if (v == NULL)
220                 return -1;
221         assert(PyLong_Check(v));
222         x = PyLong_AsLongLong(v);
223         Py_DECREF(v);
224         if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
225                 return -1;
226         *p = x;
227         return 0;
228 }
229
230 /* Same, but handling native unsigned long long. */
231
232 static int
233 get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
234 {
235         unsigned PY_LONG_LONG x;
236
237         v = get_pylong(v);
238         if (v == NULL)
239                 return -1;
240         assert(PyLong_Check(v));
241         x = PyLong_AsUnsignedLongLong(v);
242         Py_DECREF(v);
243         if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
244                 return -1;
245         *p = x;
246         return 0;
247 }
248
249 #endif
250
251 #ifdef PY_STRUCT_OVERFLOW_MASKING
252
253 /* Helper routine to get a Python integer and raise the appropriate error
254    if it isn't one */
255
256 #define INT_OVERFLOW "struct integer overflow masking is deprecated"
257
258 static int
259 get_wrapped_long(PyObject *v, long *p)
260 {
261         if (get_long(v, p) < 0) {
262                 if (PyLong_Check(v) &&
263                     PyErr_ExceptionMatches(PyExc_OverflowError)) {
264                         PyObject *wrapped;
265                         long x;
266                         PyErr_Clear();
267 #ifdef PY_STRUCT_FLOAT_COERCE
268                         if (PyFloat_Check(v)) {
269                                 PyObject *o;
270                                 int res;
271                                 PyErr_Clear();
272                                 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
273                                         return -1;
274                                 o = PyNumber_Int(v);
275                                 if (o == NULL)
276                                         return -1;
277                                 res = get_wrapped_long(o, p);
278                                 Py_DECREF(o);
279                                 return res;
280                         }
281 #endif
282                         if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
283                                 return -1;
284                         wrapped = PyNumber_And(v, pylong_ulong_mask);
285                         if (wrapped == NULL)
286                                 return -1;
287                         x = (long)PyLong_AsUnsignedLong(wrapped);
288                         Py_DECREF(wrapped);
289                         if (x == -1 && PyErr_Occurred())
290                                 return -1;
291                         *p = x;
292                 } else {
293                         return -1;
294                 }
295         }
296         return 0;
297 }
298
299 static int
300 get_wrapped_ulong(PyObject *v, unsigned long *p)
301 {
302         long x = (long)PyLong_AsUnsignedLong(v);
303         if (x == -1 && PyErr_Occurred()) {
304                 PyObject *wrapped;
305                 PyErr_Clear();
306 #ifdef PY_STRUCT_FLOAT_COERCE
307                 if (PyFloat_Check(v)) {
308                         PyObject *o;
309                         int res;
310                         PyErr_Clear();
311                         if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
312                                 return -1;
313                         o = PyNumber_Int(v);
314                         if (o == NULL)
315                                 return -1;
316                         res = get_wrapped_ulong(o, p);
317                         Py_DECREF(o);
318                         return res;
319                 }
320 #endif
321                 wrapped = PyNumber_And(v, pylong_ulong_mask);
322                 if (wrapped == NULL)
323                         return -1;
324                 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
325                         Py_DECREF(wrapped);
326                         return -1;
327                 }
328                 x = (long)PyLong_AsUnsignedLong(wrapped);
329                 Py_DECREF(wrapped);
330                 if (x == -1 && PyErr_Occurred())
331                         return -1;
332         }
333         *p = (unsigned long)x;
334         return 0;
335 }
336
337 #define RANGE_ERROR(x, f, flag, mask) \
338         do { \
339                 if (_range_error(f, flag) < 0) \
340                         return -1; \
341                 else \
342                         (x) &= (mask); \
343         } while (0)
344
345 #else
346
347 #define get_wrapped_long get_long
348 #define get_wrapped_ulong get_ulong
349 #define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
350
351 #endif
352
353 /* Floating point helpers */
354
355 static PyObject *
356 unpack_float(const char *p,  /* start of 4-byte string */
357              int le)         /* true for little-endian, false for big-endian */
358 {
359         double x;
360
361         x = _PyFloat_Unpack4((unsigned char *)p, le);
362         if (x == -1.0 && PyErr_Occurred())
363                 return NULL;
364         return PyFloat_FromDouble(x);
365 }
366
367 static PyObject *
368 unpack_double(const char *p,  /* start of 8-byte string */
369               int le)         /* true for little-endian, false for big-endian */
370 {
371         double x;
372
373         x = _PyFloat_Unpack8((unsigned char *)p, le);
374         if (x == -1.0 && PyErr_Occurred())
375                 return NULL;
376         return PyFloat_FromDouble(x);
377 }
378
379 /* Helper to format the range error exceptions */
380 static int
381 _range_error(const formatdef *f, int is_unsigned)
382 {
383         /* ulargest is the largest unsigned value with f->size bytes.
384          * Note that the simpler:
385          *     ((size_t)1 << (f->size * 8)) - 1
386          * doesn't work when f->size == sizeof(size_t) because C doesn't
387          * define what happens when a left shift count is >= the number of
388          * bits in the integer being shifted; e.g., on some boxes it doesn't
389          * shift at all when they're equal.
390          */
391         const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
392         assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
393         if (is_unsigned)
394                 PyErr_Format(StructError,
395                         "'%c' format requires 0 <= number <= %zu",
396                         f->format,
397                         ulargest);
398         else {
399                 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
400                 PyErr_Format(StructError,
401                         "'%c' format requires %zd <= number <= %zd",
402                         f->format,
403                         ~ largest,
404                         largest);
405         }
406 #ifdef PY_STRUCT_OVERFLOW_MASKING
407         {
408                 PyObject *ptype, *pvalue, *ptraceback;
409                 PyObject *msg;
410                 int rval;
411                 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
412                 assert(pvalue != NULL);
413                 msg = PyObject_Str(pvalue);
414                 Py_XDECREF(ptype);
415                 Py_XDECREF(pvalue);
416                 Py_XDECREF(ptraceback);
417                 if (msg == NULL)
418                         return -1;
419                 rval = PyErr_WarnEx(PyExc_DeprecationWarning,
420                                     PyString_AS_STRING(msg), 2);
421                 Py_DECREF(msg);
422                 if (rval == 0)
423                         return 0;
424         }
425 #endif
426         return -1;
427 }
428
429
430
431 /* A large number of small routines follow, with names of the form
432
433    [bln][up]_TYPE
434
435    [bln] distiguishes among big-endian, little-endian and native.
436    [pu] distiguishes between pack (to struct) and unpack (from struct).
437    TYPE is one of char, byte, ubyte, etc.
438 */
439
440 /* Native mode routines. ****************************************************/
441 /* NOTE:
442    In all n[up]_<type> routines handling types larger than 1 byte, there is
443    *no* guarantee that the p pointer is properly aligned for each type,
444    therefore memcpy is called.  An intermediate variable is used to
445    compensate for big-endian architectures.
446    Normally both the intermediate variable and the memcpy call will be
447    skipped by C optimisation in little-endian architectures (gcc >= 2.91
448    does this). */
449
450 static PyObject *
451 nu_char(const char *p, const formatdef *f)
452 {
453         return PyString_FromStringAndSize(p, 1);
454 }
455
456 static PyObject *
457 nu_byte(const char *p, const formatdef *f)
458 {
459         return PyInt_FromLong((long) *(signed char *)p);
460 }
461
462 static PyObject *
463 nu_ubyte(const char *p, const formatdef *f)
464 {
465         return PyInt_FromLong((long) *(unsigned char *)p);
466 }
467
468 static PyObject *
469 nu_short(const char *p, const formatdef *f)
470 {
471         short x;
472         memcpy((char *)&x, p, sizeof x);
473         return PyInt_FromLong((long)x);
474 }
475
476 static PyObject *
477 nu_ushort(const char *p, const formatdef *f)
478 {
479         unsigned short x;
480         memcpy((char *)&x, p, sizeof x);
481         return PyInt_FromLong((long)x);
482 }
483
484 static PyObject *
485 nu_int(const char *p, const formatdef *f)
486 {
487         int x;
488         memcpy((char *)&x, p, sizeof x);
489         return PyInt_FromLong((long)x);
490 }
491
492 static PyObject *
493 nu_uint(const char *p, const formatdef *f)
494 {
495         unsigned int x;
496         memcpy((char *)&x, p, sizeof x);
497 #if (SIZEOF_LONG > SIZEOF_INT)
498         return PyInt_FromLong((long)x);
499 #else
500         if (x <= ((unsigned int)LONG_MAX))
501                 return PyInt_FromLong((long)x);
502         return PyLong_FromUnsignedLong((unsigned long)x);
503 #endif
504 }
505
506 static PyObject *
507 nu_long(const char *p, const formatdef *f)
508 {
509         long x;
510         memcpy((char *)&x, p, sizeof x);
511         return PyInt_FromLong(x);
512 }
513
514 static PyObject *
515 nu_ulong(const char *p, const formatdef *f)
516 {
517         unsigned long x;
518         memcpy((char *)&x, p, sizeof x);
519         if (x <= LONG_MAX)
520                 return PyInt_FromLong((long)x);
521         return PyLong_FromUnsignedLong(x);
522 }
523
524 /* Native mode doesn't support q or Q unless the platform C supports
525    long long (or, on Windows, __int64). */
526
527 #ifdef HAVE_LONG_LONG
528
529 static PyObject *
530 nu_longlong(const char *p, const formatdef *f)
531 {
532         PY_LONG_LONG x;
533         memcpy((char *)&x, p, sizeof x);
534         if (x >= LONG_MIN && x <= LONG_MAX)
535                 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
536         return PyLong_FromLongLong(x);
537 }
538
539 static PyObject *
540 nu_ulonglong(const char *p, const formatdef *f)
541 {
542         unsigned PY_LONG_LONG x;
543         memcpy((char *)&x, p, sizeof x);
544         if (x <= LONG_MAX)
545                 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
546         return PyLong_FromUnsignedLongLong(x);
547 }
548
549 #endif
550
551 static PyObject *
552 nu_bool(const char *p, const formatdef *f)
553 {
554         BOOL_TYPE x;
555         memcpy((char *)&x, p, sizeof x);
556         return PyBool_FromLong(x != 0);
557 }
558
559
560 static PyObject *
561 nu_float(const char *p, const formatdef *f)
562 {
563         float x;
564         memcpy((char *)&x, p, sizeof x);
565         return PyFloat_FromDouble((double)x);
566 }
567
568 static PyObject *
569 nu_double(const char *p, const formatdef *f)
570 {
571         double x;
572         memcpy((char *)&x, p, sizeof x);
573         return PyFloat_FromDouble(x);
574 }
575
576 static PyObject *
577 nu_void_p(const char *p, const formatdef *f)
578 {
579         void *x;
580         memcpy((char *)&x, p, sizeof x);
581         return PyLong_FromVoidPtr(x);
582 }
583
584 static int
585 np_byte(char *p, PyObject *v, const formatdef *f)
586 {
587         long x;
588         if (get_long(v, &x) < 0)
589                 return -1;
590         if (x < -128 || x > 127){
591                 PyErr_SetString(StructError,
592                                 "byte format requires -128 <= number <= 127");
593                 return -1;
594         }
595         *p = (char)x;
596         return 0;
597 }
598
599 static int
600 np_ubyte(char *p, PyObject *v, const formatdef *f)
601 {
602         long x;
603         if (get_long(v, &x) < 0)
604                 return -1;
605         if (x < 0 || x > 255){
606                 PyErr_SetString(StructError,
607                                 "ubyte format requires 0 <= number <= 255");
608                 return -1;
609         }
610         *p = (char)x;
611         return 0;
612 }
613
614 static int
615 np_char(char *p, PyObject *v, const formatdef *f)
616 {
617         if (!PyString_Check(v) || PyString_Size(v) != 1) {
618                 PyErr_SetString(StructError,
619                                 "char format require string of length 1");
620                 return -1;
621         }
622         *p = *PyString_AsString(v);
623         return 0;
624 }
625
626 static int
627 np_short(char *p, PyObject *v, const formatdef *f)
628 {
629         long x;
630         short y;
631         if (get_long(v, &x) < 0)
632                 return -1;
633         if (x < SHRT_MIN || x > SHRT_MAX){
634                 PyErr_SetString(StructError,
635                                 "short format requires " STRINGIFY(SHRT_MIN)
636                                 " <= number <= " STRINGIFY(SHRT_MAX));
637                 return -1;
638         }
639         y = (short)x;
640         memcpy(p, (char *)&y, sizeof y);
641         return 0;
642 }
643
644 static int
645 np_ushort(char *p, PyObject *v, const formatdef *f)
646 {
647         long x;
648         unsigned short y;
649         if (get_long(v, &x) < 0)
650                 return -1;
651         if (x < 0 || x > USHRT_MAX){
652                 PyErr_SetString(StructError,
653                                 "ushort format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
654                 return -1;
655         }
656         y = (unsigned short)x;
657         memcpy(p, (char *)&y, sizeof y);
658         return 0;
659 }
660
661 static int
662 np_int(char *p, PyObject *v, const formatdef *f)
663 {
664         long x;
665         int y;
666         if (get_long(v, &x) < 0)
667                 return -1;
668 #if (SIZEOF_LONG > SIZEOF_INT)
669         if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
670                 RANGE_ERROR(x, f, 0, -1);
671 #endif
672         y = (int)x;
673         memcpy(p, (char *)&y, sizeof y);
674         return 0;
675 }
676
677 static int
678 np_uint(char *p, PyObject *v, const formatdef *f)
679 {
680         unsigned long x;
681         unsigned int y;
682         if (get_wrapped_ulong(v, &x) < 0)
683                 return -1;
684         y = (unsigned int)x;
685 #if (SIZEOF_LONG > SIZEOF_INT)
686         if (x > ((unsigned long)UINT_MAX))
687                 RANGE_ERROR(y, f, 1, -1);
688 #endif
689         memcpy(p, (char *)&y, sizeof y);
690         return 0;
691 }
692
693 static int
694 np_long(char *p, PyObject *v, const formatdef *f)
695 {
696         long x;
697         if (get_long(v, &x) < 0)
698                 return -1;
699         memcpy(p, (char *)&x, sizeof x);
700         return 0;
701 }
702
703 static int
704 np_ulong(char *p, PyObject *v, const formatdef *f)
705 {
706         unsigned long x;
707         if (get_wrapped_ulong(v, &x) < 0)
708                 return -1;
709         memcpy(p, (char *)&x, sizeof x);
710         return 0;
711 }
712
713 #ifdef HAVE_LONG_LONG
714
715 static int
716 np_longlong(char *p, PyObject *v, const formatdef *f)
717 {
718         PY_LONG_LONG x;
719         if (get_longlong(v, &x) < 0)
720                 return -1;
721         memcpy(p, (char *)&x, sizeof x);
722         return 0;
723 }
724
725 static int
726 np_ulonglong(char *p, PyObject *v, const formatdef *f)
727 {
728         unsigned PY_LONG_LONG x;
729         if (get_ulonglong(v, &x) < 0)
730                 return -1;
731         memcpy(p, (char *)&x, sizeof x);
732         return 0;
733 }
734 #endif
735
736
737 static int
738 np_bool(char *p, PyObject *v, const formatdef *f)
739 {
740         BOOL_TYPE y; 
741         y = PyObject_IsTrue(v);
742         memcpy(p, (char *)&y, sizeof y);
743         return 0;
744 }
745
746 static int
747 np_float(char *p, PyObject *v, const formatdef *f)
748 {
749         float x = (float)PyFloat_AsDouble(v);
750         if (x == -1 && PyErr_Occurred()) {
751                 PyErr_SetString(StructError,
752                                 "required argument is not a float");
753                 return -1;
754         }
755         memcpy(p, (char *)&x, sizeof x);
756         return 0;
757 }
758
759 static int
760 np_double(char *p, PyObject *v, const formatdef *f)
761 {
762         double x = PyFloat_AsDouble(v);
763         if (x == -1 && PyErr_Occurred()) {
764                 PyErr_SetString(StructError,
765                                 "required argument is not a float");
766                 return -1;
767         }
768         memcpy(p, (char *)&x, sizeof(double));
769         return 0;
770 }
771
772 static int
773 np_void_p(char *p, PyObject *v, const formatdef *f)
774 {
775         void *x;
776
777         v = get_pylong(v);
778         if (v == NULL)
779                 return -1;
780         assert(PyLong_Check(v));
781         x = PyLong_AsVoidPtr(v);
782         Py_DECREF(v);
783         if (x == NULL && PyErr_Occurred())
784                 return -1;
785         memcpy(p, (char *)&x, sizeof x);
786         return 0;
787 }
788
789 static formatdef native_table[] = {
790         {'x',   sizeof(char),   0,              NULL},
791         {'b',   sizeof(char),   0,              nu_byte,        np_byte},
792         {'B',   sizeof(char),   0,              nu_ubyte,       np_ubyte},
793         {'c',   sizeof(char),   0,              nu_char,        np_char},
794         {'s',   sizeof(char),   0,              NULL},
795         {'p',   sizeof(char),   0,              NULL},
796         {'h',   sizeof(short),  SHORT_ALIGN,    nu_short,       np_short},
797         {'H',   sizeof(short),  SHORT_ALIGN,    nu_ushort,      np_ushort},
798         {'i',   sizeof(int),    INT_ALIGN,      nu_int,         np_int},
799         {'I',   sizeof(int),    INT_ALIGN,      nu_uint,        np_uint},
800         {'l',   sizeof(long),   LONG_ALIGN,     nu_long,        np_long},
801         {'L',   sizeof(long),   LONG_ALIGN,     nu_ulong,       np_ulong},
802 #ifdef HAVE_LONG_LONG
803         {'q',   sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
804         {'Q',   sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
805 #endif
806         {'?',   sizeof(BOOL_TYPE),      BOOL_ALIGN,     nu_bool,        np_bool},
807         {'f',   sizeof(float),  FLOAT_ALIGN,    nu_float,       np_float},
808         {'d',   sizeof(double), DOUBLE_ALIGN,   nu_double,      np_double},
809         {'P',   sizeof(void *), VOID_P_ALIGN,   nu_void_p,      np_void_p},
810         {0}
811 };
812
813 /* Big-endian routines. *****************************************************/
814
815 static PyObject *
816 bu_int(const char *p, const formatdef *f)
817 {
818         long x = 0;
819         Py_ssize_t i = f->size;
820         const unsigned char *bytes = (const unsigned char *)p;
821         do {
822                 x = (x<<8) | *bytes++;
823         } while (--i > 0);
824         /* Extend the sign bit. */
825         if (SIZEOF_LONG > f->size)
826                 x |= -(x & (1L << ((8 * f->size) - 1)));
827         return PyInt_FromLong(x);
828 }
829
830 static PyObject *
831 bu_uint(const char *p, const formatdef *f)
832 {
833         unsigned long x = 0;
834         Py_ssize_t i = f->size;
835         const unsigned char *bytes = (const unsigned char *)p;
836         do {
837                 x = (x<<8) | *bytes++;
838         } while (--i > 0);
839         if (x <= LONG_MAX)
840                 return PyInt_FromLong((long)x);
841         return PyLong_FromUnsignedLong(x);
842 }
843
844 static PyObject *
845 bu_longlong(const char *p, const formatdef *f)
846 {
847 #ifdef HAVE_LONG_LONG
848         PY_LONG_LONG x = 0;
849         Py_ssize_t i = f->size;
850         const unsigned char *bytes = (const unsigned char *)p;
851         do {
852                 x = (x<<8) | *bytes++;
853         } while (--i > 0);
854         /* Extend the sign bit. */
855         if (SIZEOF_LONG_LONG > f->size)
856                 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
857         if (x >= LONG_MIN && x <= LONG_MAX)
858                 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
859         return PyLong_FromLongLong(x);
860 #else
861         return _PyLong_FromByteArray((const unsigned char *)p,
862                                       8,
863                                       0, /* little-endian */
864                                       1  /* signed */);
865 #endif
866 }
867
868 static PyObject *
869 bu_ulonglong(const char *p, const formatdef *f)
870 {
871 #ifdef HAVE_LONG_LONG
872         unsigned PY_LONG_LONG x = 0;
873         Py_ssize_t i = f->size;
874         const unsigned char *bytes = (const unsigned char *)p;
875         do {
876                 x = (x<<8) | *bytes++;
877         } while (--i > 0);
878         if (x <= LONG_MAX)
879                 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
880         return PyLong_FromUnsignedLongLong(x);
881 #else
882         return _PyLong_FromByteArray((const unsigned char *)p,
883                                       8,
884                                       0, /* little-endian */
885                                       0  /* signed */);
886 #endif
887 }
888
889 static PyObject *
890 bu_float(const char *p, const formatdef *f)
891 {
892         return unpack_float(p, 0);
893 }
894
895 static PyObject *
896 bu_double(const char *p, const formatdef *f)
897 {
898         return unpack_double(p, 0);
899 }
900
901 static PyObject *
902 bu_bool(const char *p, const formatdef *f)
903 {
904         char x;
905         memcpy((char *)&x, p, sizeof x);
906         return PyBool_FromLong(x != 0);
907 }
908
909 static int
910 bp_int(char *p, PyObject *v, const formatdef *f)
911 {
912         long x;
913         Py_ssize_t i;
914         if (get_wrapped_long(v, &x) < 0)
915                 return -1;
916         i = f->size;
917         if (i != SIZEOF_LONG) {
918                 if ((i == 2) && (x < -32768 || x > 32767))
919                         RANGE_ERROR(x, f, 0, 0xffffL);
920 #if (SIZEOF_LONG != 4)
921                 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
922                         RANGE_ERROR(x, f, 0, 0xffffffffL);
923 #endif
924 #ifdef PY_STRUCT_OVERFLOW_MASKING
925                 else if ((i == 1) && (x < -128 || x > 127))
926                         RANGE_ERROR(x, f, 0, 0xffL);
927 #endif
928         }
929         do {
930                 p[--i] = (char)x;
931                 x >>= 8;
932         } while (i > 0);
933         return 0;
934 }
935
936 static int
937 bp_uint(char *p, PyObject *v, const formatdef *f)
938 {
939         unsigned long x;
940         Py_ssize_t i;
941         if (get_wrapped_ulong(v, &x) < 0)
942                 return -1;
943         i = f->size;
944         if (i != SIZEOF_LONG) {
945                 unsigned long maxint = 1;
946                 maxint <<= (unsigned long)(i * 8);
947                 if (x >= maxint)
948                         RANGE_ERROR(x, f, 1, maxint - 1);
949         }
950         do {
951                 p[--i] = (char)x;
952                 x >>= 8;
953         } while (i > 0);
954         return 0;
955 }
956
957 static int
958 bp_longlong(char *p, PyObject *v, const formatdef *f)
959 {
960         int res;
961         v = get_pylong(v);
962         if (v == NULL)
963                 return -1;
964         res = _PyLong_AsByteArray((PyLongObject *)v,
965                                   (unsigned char *)p,
966                                   8,
967                                   0, /* little_endian */
968                                   1  /* signed */);
969         Py_DECREF(v);
970         return res;
971 }
972
973 static int
974 bp_ulonglong(char *p, PyObject *v, const formatdef *f)
975 {
976         int res;
977         v = get_pylong(v);
978         if (v == NULL)
979                 return -1;
980         res = _PyLong_AsByteArray((PyLongObject *)v,
981                                   (unsigned char *)p,
982                                   8,
983                                   0, /* little_endian */
984                                   0  /* signed */);
985         Py_DECREF(v);
986         return res;
987 }
988
989 static int
990 bp_float(char *p, PyObject *v, const formatdef *f)
991 {
992         double x = PyFloat_AsDouble(v);
993         if (x == -1 && PyErr_Occurred()) {
994                 PyErr_SetString(StructError,
995                                 "required argument is not a float");
996                 return -1;
997         }
998         return _PyFloat_Pack4(x, (unsigned char *)p, 0);
999 }
1000
1001 static int
1002 bp_double(char *p, PyObject *v, const formatdef *f)
1003 {
1004         double x = PyFloat_AsDouble(v);
1005         if (x == -1 && PyErr_Occurred()) {
1006                 PyErr_SetString(StructError,
1007                                 "required argument is not a float");
1008                 return -1;
1009         }
1010         return _PyFloat_Pack8(x, (unsigned char *)p, 0);
1011 }
1012
1013 static int
1014 bp_bool(char *p, PyObject *v, const formatdef *f)
1015 {
1016         char y; 
1017         y = PyObject_IsTrue(v);
1018         memcpy(p, (char *)&y, sizeof y);
1019         return 0;
1020 }
1021
1022 static formatdef bigendian_table[] = {
1023         {'x',   1,              0,              NULL},
1024 #ifdef PY_STRUCT_OVERFLOW_MASKING
1025         /* Native packers do range checking without overflow masking. */
1026         {'b',   1,              0,              nu_byte,        bp_int},
1027         {'B',   1,              0,              nu_ubyte,       bp_uint},
1028 #else
1029         {'b',   1,              0,              nu_byte,        np_byte},
1030         {'B',   1,              0,              nu_ubyte,       np_ubyte},
1031 #endif
1032         {'c',   1,              0,              nu_char,        np_char},
1033         {'s',   1,              0,              NULL},
1034         {'p',   1,              0,              NULL},
1035         {'h',   2,              0,              bu_int,         bp_int},
1036         {'H',   2,              0,              bu_uint,        bp_uint},
1037         {'i',   4,              0,              bu_int,         bp_int},
1038         {'I',   4,              0,              bu_uint,        bp_uint},
1039         {'l',   4,              0,              bu_int,         bp_int},
1040         {'L',   4,              0,              bu_uint,        bp_uint},
1041         {'q',   8,              0,              bu_longlong,    bp_longlong},
1042         {'Q',   8,              0,              bu_ulonglong,   bp_ulonglong},
1043         {'?',   1,              0,              bu_bool,        bp_bool},
1044         {'f',   4,              0,              bu_float,       bp_float},
1045         {'d',   8,              0,              bu_double,      bp_double},
1046         {0}
1047 };
1048
1049 /* Little-endian routines. *****************************************************/
1050
1051 static PyObject *
1052 lu_int(const char *p, const formatdef *f)
1053 {
1054         long x = 0;
1055         Py_ssize_t i = f->size;
1056         const unsigned char *bytes = (const unsigned char *)p;
1057         do {
1058                 x = (x<<8) | bytes[--i];
1059         } while (i > 0);
1060         /* Extend the sign bit. */
1061         if (SIZEOF_LONG > f->size)
1062                 x |= -(x & (1L << ((8 * f->size) - 1)));
1063         return PyInt_FromLong(x);
1064 }
1065
1066 static PyObject *
1067 lu_uint(const char *p, const formatdef *f)
1068 {
1069         unsigned long x = 0;
1070         Py_ssize_t i = f->size;
1071         const unsigned char *bytes = (const unsigned char *)p;
1072         do {
1073                 x = (x<<8) | bytes[--i];
1074         } while (i > 0);
1075         if (x <= LONG_MAX)
1076                 return PyInt_FromLong((long)x);
1077         return PyLong_FromUnsignedLong((long)x);
1078 }
1079
1080 static PyObject *
1081 lu_longlong(const char *p, const formatdef *f)
1082 {
1083 #ifdef HAVE_LONG_LONG
1084         PY_LONG_LONG x = 0;
1085         Py_ssize_t i = f->size;
1086         const unsigned char *bytes = (const unsigned char *)p;
1087         do {
1088                 x = (x<<8) | bytes[--i];
1089         } while (i > 0);
1090         /* Extend the sign bit. */
1091         if (SIZEOF_LONG_LONG > f->size)
1092                 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
1093         if (x >= LONG_MIN && x <= LONG_MAX)
1094                 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
1095         return PyLong_FromLongLong(x);
1096 #else
1097         return _PyLong_FromByteArray((const unsigned char *)p,
1098                                       8,
1099                                       1, /* little-endian */
1100                                       1  /* signed */);
1101 #endif
1102 }
1103
1104 static PyObject *
1105 lu_ulonglong(const char *p, const formatdef *f)
1106 {
1107 #ifdef HAVE_LONG_LONG
1108         unsigned PY_LONG_LONG x = 0;
1109         Py_ssize_t i = f->size;
1110         const unsigned char *bytes = (const unsigned char *)p;
1111         do {
1112                 x = (x<<8) | bytes[--i];
1113         } while (i > 0);
1114         if (x <= LONG_MAX)
1115                 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
1116         return PyLong_FromUnsignedLongLong(x);
1117 #else
1118         return _PyLong_FromByteArray((const unsigned char *)p,
1119                                       8,
1120                                       1, /* little-endian */
1121                                       0  /* signed */);
1122 #endif
1123 }
1124
1125 static PyObject *
1126 lu_float(const char *p, const formatdef *f)
1127 {
1128         return unpack_float(p, 1);
1129 }
1130
1131 static PyObject *
1132 lu_double(const char *p, const formatdef *f)
1133 {
1134         return unpack_double(p, 1);
1135 }
1136
1137 static int
1138 lp_int(char *p, PyObject *v, const formatdef *f)
1139 {
1140         long x;
1141         Py_ssize_t i;
1142         if (get_wrapped_long(v, &x) < 0)
1143                 return -1;
1144         i = f->size;
1145         if (i != SIZEOF_LONG) {
1146                 if ((i == 2) && (x < -32768 || x > 32767))
1147                         RANGE_ERROR(x, f, 0, 0xffffL);
1148 #if (SIZEOF_LONG != 4)
1149                 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
1150                         RANGE_ERROR(x, f, 0, 0xffffffffL);
1151 #endif
1152 #ifdef PY_STRUCT_OVERFLOW_MASKING
1153                 else if ((i == 1) && (x < -128 || x > 127))
1154                         RANGE_ERROR(x, f, 0, 0xffL);
1155 #endif
1156         }
1157         do {
1158                 *p++ = (char)x;
1159                 x >>= 8;
1160         } while (--i > 0);
1161         return 0;
1162 }
1163
1164 static int
1165 lp_uint(char *p, PyObject *v, const formatdef *f)
1166 {
1167         unsigned long x;
1168         Py_ssize_t i;
1169         if (get_wrapped_ulong(v, &x) < 0)
1170                 return -1;
1171         i = f->size;
1172         if (i != SIZEOF_LONG) {
1173                 unsigned long maxint = 1;
1174                 maxint <<= (unsigned long)(i * 8);
1175                 if (x >= maxint)
1176                         RANGE_ERROR(x, f, 1, maxint - 1);
1177         }
1178         do {
1179                 *p++ = (char)x;
1180                 x >>= 8;
1181         } while (--i > 0);
1182         return 0;
1183 }
1184
1185 static int
1186 lp_longlong(char *p, PyObject *v, const formatdef *f)
1187 {
1188         int res;
1189         v = get_pylong(v);
1190         if (v == NULL)
1191                 return -1;
1192         res = _PyLong_AsByteArray((PyLongObject*)v,
1193                                   (unsigned char *)p,
1194                                   8,
1195                                   1, /* little_endian */
1196                                   1  /* signed */);
1197         Py_DECREF(v);
1198         return res;
1199 }
1200
1201 static int
1202 lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1203 {
1204         int res;
1205         v = get_pylong(v);
1206         if (v == NULL)
1207                 return -1;
1208         res = _PyLong_AsByteArray((PyLongObject*)v,
1209                                   (unsigned char *)p,
1210                                   8,
1211                                   1, /* little_endian */
1212                                   0  /* signed */);
1213         Py_DECREF(v);
1214         return res;
1215 }
1216
1217 static int
1218 lp_float(char *p, PyObject *v, const formatdef *f)
1219 {
1220         double x = PyFloat_AsDouble(v);
1221         if (x == -1 && PyErr_Occurred()) {
1222                 PyErr_SetString(StructError,
1223                                 "required argument is not a float");
1224                 return -1;
1225         }
1226         return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1227 }
1228
1229 static int
1230 lp_double(char *p, PyObject *v, const formatdef *f)
1231 {
1232         double x = PyFloat_AsDouble(v);
1233         if (x == -1 && PyErr_Occurred()) {
1234                 PyErr_SetString(StructError,
1235                                 "required argument is not a float");
1236                 return -1;
1237         }
1238         return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1239 }
1240
1241 static formatdef lilendian_table[] = {
1242         {'x',   1,              0,              NULL},
1243 #ifdef PY_STRUCT_OVERFLOW_MASKING
1244         /* Native packers do range checking without overflow masking. */
1245         {'b',   1,              0,              nu_byte,        lp_int},
1246         {'B',   1,              0,              nu_ubyte,       lp_uint},
1247 #else
1248         {'b',   1,              0,              nu_byte,        np_byte},
1249         {'B',   1,              0,              nu_ubyte,       np_ubyte},
1250 #endif
1251         {'c',   1,              0,              nu_char,        np_char},
1252         {'s',   1,              0,              NULL},
1253         {'p',   1,              0,              NULL},
1254         {'h',   2,              0,              lu_int,         lp_int},
1255         {'H',   2,              0,              lu_uint,        lp_uint},
1256         {'i',   4,              0,              lu_int,         lp_int},
1257         {'I',   4,              0,              lu_uint,        lp_uint},
1258         {'l',   4,              0,              lu_int,         lp_int},
1259         {'L',   4,              0,              lu_uint,        lp_uint},
1260         {'q',   8,              0,              lu_longlong,    lp_longlong},
1261         {'Q',   8,              0,              lu_ulonglong,   lp_ulonglong},
1262         {'?',   1,              0,              bu_bool,        bp_bool}, /* Std rep not endian dep,
1263                 but potentially different from native rep -- reuse bx_bool funcs. */
1264         {'f',   4,              0,              lu_float,       lp_float},
1265         {'d',   8,              0,              lu_double,      lp_double},
1266         {0}
1267 };
1268
1269
1270 static const formatdef *
1271 whichtable(char **pfmt)
1272 {
1273         const char *fmt = (*pfmt)++; /* May be backed out of later */
1274         switch (*fmt) {
1275         case '<':
1276                 return lilendian_table;
1277         case '>':
1278         case '!': /* Network byte order is big-endian */
1279                 return bigendian_table;
1280         case '=': { /* Host byte order -- different from native in aligment! */
1281                 int n = 1;
1282                 char *p = (char *) &n;
1283                 if (*p == 1)
1284                         return lilendian_table;
1285                 else
1286                         return bigendian_table;
1287         }
1288         default:
1289                 --*pfmt; /* Back out of pointer increment */
1290                 /* Fall through */
1291         case '@':
1292                 return native_table;
1293         }
1294 }
1295
1296
1297 /* Get the table entry for a format code */
1298
1299 static const formatdef *
1300 getentry(int c, const formatdef *f)
1301 {
1302         for (; f->format != '\0'; f++) {
1303                 if (f->format == c) {
1304                         return f;
1305                 }
1306         }
1307         PyErr_SetString(StructError, "bad char in struct format");
1308         return NULL;
1309 }
1310
1311
1312 /* Align a size according to a format code */
1313
1314 static int
1315 align(Py_ssize_t size, char c, const formatdef *e)
1316 {
1317         if (e->format == c) {
1318                 if (e->alignment) {
1319                         size = ((size + e->alignment - 1)
1320                                 / e->alignment)
1321                                 * e->alignment;
1322                 }
1323         }
1324         return size;
1325 }
1326
1327
1328 /* calculate the size of a format string */
1329
1330 static int
1331 prepare_s(PyStructObject *self)
1332 {
1333         const formatdef *f;
1334         const formatdef *e;
1335         formatcode *codes;
1336
1337         const char *s;
1338         const char *fmt;
1339         char c;
1340         Py_ssize_t size, len, num, itemsize, x;
1341
1342         fmt = PyString_AS_STRING(self->s_format);
1343
1344         f = whichtable((char **)&fmt);
1345
1346         s = fmt;
1347         size = 0;
1348         len = 0;
1349         while ((c = *s++) != '\0') {
1350                 if (isspace(Py_CHARMASK(c)))
1351                         continue;
1352                 if ('0' <= c && c <= '9') {
1353                         num = c - '0';
1354                         while ('0' <= (c = *s++) && c <= '9') {
1355                                 x = num*10 + (c - '0');
1356                                 if (x/10 != num) {
1357                                         PyErr_SetString(
1358                                                 StructError,
1359                                                 "overflow in item count");
1360                                         return -1;
1361                                 }
1362                                 num = x;
1363                         }
1364                         if (c == '\0')
1365                                 break;
1366                 }
1367                 else
1368                         num = 1;
1369
1370                 e = getentry(c, f);
1371                 if (e == NULL)
1372                         return -1;
1373
1374                 switch (c) {
1375                         case 's': /* fall through */
1376                         case 'p': len++; break;
1377                         case 'x': break;
1378                         default: len += num; break;
1379                 }
1380
1381                 itemsize = e->size;
1382                 size = align(size, c, e);
1383                 x = num * itemsize;
1384                 size += x;
1385                 if (x/itemsize != num || size < 0) {
1386                         PyErr_SetString(StructError,
1387                                         "total struct size too long");
1388                         return -1;
1389                 }
1390         }
1391
1392         /* check for overflow */
1393         if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
1394                 PyErr_NoMemory();
1395                 return -1;
1396         }
1397
1398         self->s_size = size;
1399         self->s_len = len;
1400         codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1401         if (codes == NULL) {
1402                 PyErr_NoMemory();
1403                 return -1;
1404         }
1405         self->s_codes = codes;
1406
1407         s = fmt;
1408         size = 0;
1409         while ((c = *s++) != '\0') {
1410                 if (isspace(Py_CHARMASK(c)))
1411                         continue;
1412                 if ('0' <= c && c <= '9') {
1413                         num = c - '0';
1414                         while ('0' <= (c = *s++) && c <= '9')
1415                                 num = num*10 + (c - '0');
1416                         if (c == '\0')
1417                                 break;
1418                 }
1419                 else
1420                         num = 1;
1421
1422                 e = getentry(c, f);
1423
1424                 size = align(size, c, e);
1425                 if (c == 's' || c == 'p') {
1426                         codes->offset = size;
1427                         codes->size = num;
1428                         codes->fmtdef = e;
1429                         codes++;
1430                         size += num;
1431                 } else if (c == 'x') {
1432                         size += num;
1433                 } else {
1434                         while (--num >= 0) {
1435                                 codes->offset = size;
1436                                 codes->size = e->size;
1437                                 codes->fmtdef = e;
1438                                 codes++;
1439                                 size += e->size;
1440                         }
1441                 }
1442         }
1443         codes->fmtdef = NULL;
1444         codes->offset = size;
1445         codes->size = 0;
1446
1447         return 0;
1448 }
1449
1450 static PyObject *
1451 s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1452 {
1453         PyObject *self;
1454
1455         assert(type != NULL && type->tp_alloc != NULL);
1456
1457         self = type->tp_alloc(type, 0);
1458         if (self != NULL) {
1459                 PyStructObject *s = (PyStructObject*)self;
1460                 Py_INCREF(Py_None);
1461                 s->s_format = Py_None;
1462                 s->s_codes = NULL;
1463                 s->s_size = -1;
1464                 s->s_len = -1;
1465         }
1466         return self;
1467 }
1468
1469 static int
1470 s_init(PyObject *self, PyObject *args, PyObject *kwds)
1471 {
1472         PyStructObject *soself = (PyStructObject *)self;
1473         PyObject *o_format = NULL;
1474         int ret = 0;
1475         static char *kwlist[] = {"format", 0};
1476
1477         assert(PyStruct_Check(self));
1478
1479         if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1480                                          &o_format))
1481                 return -1;
1482
1483         Py_INCREF(o_format);
1484         Py_CLEAR(soself->s_format);
1485         soself->s_format = o_format;
1486
1487         ret = prepare_s(soself);
1488         return ret;
1489 }
1490
1491 static void
1492 s_dealloc(PyStructObject *s)
1493 {
1494         if (s->weakreflist != NULL)
1495                 PyObject_ClearWeakRefs((PyObject *)s);
1496         if (s->s_codes != NULL) {
1497                 PyMem_FREE(s->s_codes);
1498         }
1499         Py_XDECREF(s->s_format);
1500         Py_TYPE(s)->tp_free((PyObject *)s);
1501 }
1502
1503 static PyObject *
1504 s_unpack_internal(PyStructObject *soself, char *startfrom) {
1505         formatcode *code;
1506         Py_ssize_t i = 0;
1507         PyObject *result = PyTuple_New(soself->s_len);
1508         if (result == NULL)
1509                 return NULL;
1510
1511         for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1512                 PyObject *v;
1513                 const formatdef *e = code->fmtdef;
1514                 const char *res = startfrom + code->offset;
1515                 if (e->format == 's') {
1516                         v = PyString_FromStringAndSize(res, code->size);
1517                 } else if (e->format == 'p') {
1518                         Py_ssize_t n = *(unsigned char*)res;
1519                         if (n >= code->size)
1520                                 n = code->size - 1;
1521                         v = PyString_FromStringAndSize(res + 1, n);
1522                 } else {
1523                         v = e->unpack(res, e);
1524                 }
1525                 if (v == NULL)
1526                         goto fail;
1527                 PyTuple_SET_ITEM(result, i++, v);
1528         }
1529
1530         return result;
1531 fail:
1532         Py_DECREF(result);
1533         return NULL;
1534 }
1535
1536
1537 PyDoc_STRVAR(s_unpack__doc__,
1538 "S.unpack(str) -> (v1, v2, ...)\n\
1539 \n\
1540 Return tuple containing values unpacked according to this Struct's format.\n\
1541 Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1542 strings.");
1543
1544 static PyObject *
1545 s_unpack(PyObject *self, PyObject *inputstr)
1546 {
1547         char *start;
1548         Py_ssize_t len;
1549         PyObject *args=NULL, *result;
1550         PyStructObject *soself = (PyStructObject *)self;
1551         assert(PyStruct_Check(self));
1552         assert(soself->s_codes != NULL);
1553         if (inputstr == NULL)
1554                 goto fail;
1555         if (PyString_Check(inputstr) &&
1556                 PyString_GET_SIZE(inputstr) == soself->s_size) {
1557                         return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1558         }
1559         args = PyTuple_Pack(1, inputstr);
1560         if (args == NULL)
1561                 return NULL;
1562         if (!PyArg_ParseTuple(args, "s#:unpack", &start, &len))
1563                 goto fail;
1564         if (soself->s_size != len)
1565                 goto fail;
1566         result = s_unpack_internal(soself, start);
1567         Py_DECREF(args);
1568         return result;
1569
1570 fail:
1571         Py_XDECREF(args);
1572         PyErr_Format(StructError,
1573                 "unpack requires a string argument of length %zd",
1574                 soself->s_size);
1575         return NULL;
1576 }
1577
1578 PyDoc_STRVAR(s_unpack_from__doc__,
1579 "S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1580 \n\
1581 Return tuple containing values unpacked according to this Struct's format.\n\
1582 Unlike unpack, unpack_from can unpack values from any object supporting\n\
1583 the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1584 See struct.__doc__ for more on format strings.");
1585
1586 static PyObject *
1587 s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1588 {
1589         static char *kwlist[] = {"buffer", "offset", 0};
1590 #if (PY_VERSION_HEX < 0x02050000)
1591         static char *fmt = "z#|i:unpack_from";
1592 #else
1593         static char *fmt = "z#|n:unpack_from";
1594 #endif
1595         Py_ssize_t buffer_len = 0, offset = 0;
1596         char *buffer = NULL;
1597         PyStructObject *soself = (PyStructObject *)self;
1598         assert(PyStruct_Check(self));
1599         assert(soself->s_codes != NULL);
1600
1601         if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1602                                          &buffer, &buffer_len, &offset))
1603                 return NULL;
1604
1605         if (buffer == NULL) {
1606                 PyErr_Format(StructError,
1607                         "unpack_from requires a buffer argument");
1608                 return NULL;
1609         }
1610
1611         if (offset < 0)
1612                 offset += buffer_len;
1613
1614         if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1615                 PyErr_Format(StructError,
1616                         "unpack_from requires a buffer of at least %zd bytes",
1617                         soself->s_size);
1618                 return NULL;
1619         }
1620         return s_unpack_internal(soself, buffer + offset);
1621 }
1622
1623
1624 /*
1625  * Guts of the pack function.
1626  *
1627  * Takes a struct object, a tuple of arguments, and offset in that tuple of
1628  * argument for where to start processing the arguments for packing, and a
1629  * character buffer for writing the packed string.  The caller must insure
1630  * that the buffer may contain the required length for packing the arguments.
1631  * 0 is returned on success, 1 is returned if there is an error.
1632  *
1633  */
1634 static int
1635 s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1636 {
1637         formatcode *code;
1638         /* XXX(nnorwitz): why does i need to be a local?  can we use
1639            the offset parameter or do we need the wider width? */
1640         Py_ssize_t i;
1641
1642         memset(buf, '\0', soself->s_size);
1643         i = offset;
1644         for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1645                 Py_ssize_t n;
1646                 PyObject *v = PyTuple_GET_ITEM(args, i++);
1647                 const formatdef *e = code->fmtdef;
1648                 char *res = buf + code->offset;
1649                 if (e->format == 's') {
1650                         if (!PyString_Check(v)) {
1651                                 PyErr_SetString(StructError,
1652                                                 "argument for 's' must be a string");
1653                                 return -1;
1654                         }
1655                         n = PyString_GET_SIZE(v);
1656                         if (n > code->size)
1657                                 n = code->size;
1658                         if (n > 0)
1659                                 memcpy(res, PyString_AS_STRING(v), n);
1660                 } else if (e->format == 'p') {
1661                         if (!PyString_Check(v)) {
1662                                 PyErr_SetString(StructError,
1663                                                 "argument for 'p' must be a string");
1664                                 return -1;
1665                         }
1666                         n = PyString_GET_SIZE(v);
1667                         if (n > (code->size - 1))
1668                                 n = code->size - 1;
1669                         if (n > 0)
1670                                 memcpy(res + 1, PyString_AS_STRING(v), n);
1671                         if (n > 255)
1672                                 n = 255;
1673                         *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1674                 } else {
1675                         if (e->pack(res, v, e) < 0) {
1676                                 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1677                                         PyErr_SetString(StructError,
1678                                                         "long too large to convert to int");
1679                                 return -1;
1680                         }
1681                 }
1682         }
1683
1684         /* Success */
1685         return 0;
1686 }
1687
1688
1689 PyDoc_STRVAR(s_pack__doc__,
1690 "S.pack(v1, v2, ...) -> string\n\
1691 \n\
1692 Return a string containing values v1, v2, ... packed according to this\n\
1693 Struct's format. See struct.__doc__ for more on format strings.");
1694
1695 static PyObject *
1696 s_pack(PyObject *self, PyObject *args)
1697 {
1698         PyStructObject *soself;
1699         PyObject *result;
1700
1701         /* Validate arguments. */
1702         soself = (PyStructObject *)self;
1703         assert(PyStruct_Check(self));
1704         assert(soself->s_codes != NULL);
1705         if (PyTuple_GET_SIZE(args) != soself->s_len)
1706         {
1707                 PyErr_Format(StructError,
1708                         "pack requires exactly %zd arguments", soself->s_len);
1709                 return NULL;
1710         }
1711
1712         /* Allocate a new string */
1713         result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1714         if (result == NULL)
1715                 return NULL;
1716
1717         /* Call the guts */
1718         if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1719                 Py_DECREF(result);
1720                 return NULL;
1721         }
1722
1723         return result;
1724 }
1725
1726 PyDoc_STRVAR(s_pack_into__doc__,
1727 "S.pack_into(buffer, offset, v1, v2, ...)\n\
1728 \n\
1729 Pack the values v1, v2, ... according to this Struct's format, write \n\
1730 the packed bytes into the writable buffer buf starting at offset.  Note\n\
1731 that the offset is not an optional argument.  See struct.__doc__ for \n\
1732 more on format strings.");
1733
1734 static PyObject *
1735 s_pack_into(PyObject *self, PyObject *args)
1736 {
1737         PyStructObject *soself;
1738         char *buffer;
1739         Py_ssize_t buffer_len, offset;
1740
1741         /* Validate arguments.  +1 is for the first arg as buffer. */
1742         soself = (PyStructObject *)self;
1743         assert(PyStruct_Check(self));
1744         assert(soself->s_codes != NULL);
1745         if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
1746         {
1747                 PyErr_Format(StructError,
1748                              "pack_into requires exactly %zd arguments",
1749                              (soself->s_len + 2));
1750                 return NULL;
1751         }
1752
1753         /* Extract a writable memory buffer from the first argument */
1754         if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1755                                                                 (void**)&buffer, &buffer_len) == -1 ) {
1756                 return NULL;
1757         }
1758         assert( buffer_len >= 0 );
1759
1760         /* Extract the offset from the first argument */
1761         offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
1762         if (offset == -1 && PyErr_Occurred())
1763                 return NULL;
1764
1765         /* Support negative offsets. */
1766         if (offset < 0)
1767                 offset += buffer_len;
1768
1769         /* Check boundaries */
1770         if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1771                 PyErr_Format(StructError,
1772                              "pack_into requires a buffer of at least %zd bytes",
1773                              soself->s_size);
1774                 return NULL;
1775         }
1776
1777         /* Call the guts */
1778         if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1779                 return NULL;
1780         }
1781
1782         Py_RETURN_NONE;
1783 }
1784
1785 static PyObject *
1786 s_get_format(PyStructObject *self, void *unused)
1787 {
1788         Py_INCREF(self->s_format);
1789         return self->s_format;
1790 }
1791
1792 static PyObject *
1793 s_get_size(PyStructObject *self, void *unused)
1794 {
1795     return PyInt_FromSsize_t(self->s_size);
1796 }
1797
1798 /* List of functions */
1799
1800 static struct PyMethodDef s_methods[] = {
1801         {"pack",        s_pack,         METH_VARARGS, s_pack__doc__},
1802         {"pack_into",   s_pack_into,    METH_VARARGS, s_pack_into__doc__},
1803         {"unpack",      s_unpack,       METH_O, s_unpack__doc__},
1804         {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
1805                         s_unpack_from__doc__},
1806         {NULL,   NULL}          /* sentinel */
1807 };
1808
1809 PyDoc_STRVAR(s__doc__, "Compiled struct object");
1810
1811 #define OFF(x) offsetof(PyStructObject, x)
1812
1813 static PyGetSetDef s_getsetlist[] = {
1814         {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1815         {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1816         {NULL} /* sentinel */
1817 };
1818
1819 static
1820 PyTypeObject PyStructType = {
1821         PyVarObject_HEAD_INIT(NULL, 0)
1822         "Struct",
1823         sizeof(PyStructObject),
1824         0,
1825         (destructor)s_dealloc,  /* tp_dealloc */
1826         0,                                      /* tp_print */
1827         0,                                      /* tp_getattr */
1828         0,                                      /* tp_setattr */
1829         0,                                      /* tp_compare */
1830         0,                                      /* tp_repr */
1831         0,                                      /* tp_as_number */
1832         0,                                      /* tp_as_sequence */
1833         0,                                      /* tp_as_mapping */
1834         0,                                      /* tp_hash */
1835         0,                                      /* tp_call */
1836         0,                                      /* tp_str */
1837         PyObject_GenericGetAttr,        /* tp_getattro */
1838         PyObject_GenericSetAttr,        /* tp_setattro */
1839         0,                                      /* tp_as_buffer */
1840         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1841         s__doc__,                       /* tp_doc */
1842         0,                                      /* tp_traverse */
1843         0,                                      /* tp_clear */
1844         0,                                      /* tp_richcompare */
1845         offsetof(PyStructObject, weakreflist),  /* tp_weaklistoffset */
1846         0,                                      /* tp_iter */
1847         0,                                      /* tp_iternext */
1848         s_methods,                      /* tp_methods */
1849         NULL,                           /* tp_members */
1850         s_getsetlist,           /* tp_getset */
1851         0,                                      /* tp_base */
1852         0,                                      /* tp_dict */
1853         0,                                      /* tp_descr_get */
1854         0,                                      /* tp_descr_set */
1855         0,                                      /* tp_dictoffset */
1856         s_init,                         /* tp_init */
1857         PyType_GenericAlloc,/* tp_alloc */
1858         s_new,                          /* tp_new */
1859         PyObject_Del,           /* tp_free */
1860 };
1861
1862
1863 /* ---- Standalone functions  ---- */
1864
1865 #define MAXCACHE 100
1866 static PyObject *cache = NULL;
1867
1868 static PyObject *
1869 cache_struct(PyObject *fmt)
1870 {
1871         PyObject * s_object;
1872
1873         if (cache == NULL) {
1874                 cache = PyDict_New();
1875                 if (cache == NULL)
1876                         return NULL;
1877         }
1878
1879         s_object = PyDict_GetItem(cache, fmt);
1880         if (s_object != NULL) {
1881                 Py_INCREF(s_object);
1882                 return s_object;
1883         }
1884
1885         s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
1886         if (s_object != NULL) {
1887                 if (PyDict_Size(cache) >= MAXCACHE)
1888                         PyDict_Clear(cache);
1889                 /* Attempt to cache the result */
1890                 if (PyDict_SetItem(cache, fmt, s_object) == -1)
1891                         PyErr_Clear();
1892         }
1893         return s_object;
1894 }
1895
1896 PyDoc_STRVAR(clearcache_doc,
1897 "Clear the internal cache.");
1898
1899 static PyObject *
1900 clearcache(PyObject *self)
1901 {
1902         Py_CLEAR(cache);
1903         Py_RETURN_NONE;
1904 }
1905
1906 PyDoc_STRVAR(calcsize_doc,
1907 "Return size of C struct described by format string fmt.");
1908
1909 static PyObject *
1910 calcsize(PyObject *self, PyObject *fmt)
1911 {
1912         Py_ssize_t n;
1913         PyObject *s_object = cache_struct(fmt);
1914         if (s_object == NULL)
1915                 return NULL;
1916         n = ((PyStructObject *)s_object)->s_size;
1917         Py_DECREF(s_object);
1918         return PyInt_FromSsize_t(n);
1919 }
1920
1921 PyDoc_STRVAR(pack_doc,
1922 "Return string containing values v1, v2, ... packed according to fmt.");
1923
1924 static PyObject *
1925 pack(PyObject *self, PyObject *args)
1926 {
1927         PyObject *s_object, *fmt, *newargs, *result;
1928         Py_ssize_t n = PyTuple_GET_SIZE(args);
1929
1930         if (n == 0) {
1931                 PyErr_SetString(PyExc_TypeError, "missing format argument");
1932                 return NULL;
1933         }
1934         fmt = PyTuple_GET_ITEM(args, 0);
1935         newargs = PyTuple_GetSlice(args, 1, n);
1936         if (newargs == NULL)
1937                 return NULL;
1938
1939         s_object = cache_struct(fmt);
1940         if (s_object == NULL) {
1941                 Py_DECREF(newargs);
1942                 return NULL;
1943         }
1944         result = s_pack(s_object, newargs);
1945         Py_DECREF(newargs);
1946         Py_DECREF(s_object);
1947         return result;
1948 }
1949
1950 PyDoc_STRVAR(pack_into_doc,
1951 "Pack the values v1, v2, ... according to fmt.\n\
1952 Write the packed bytes into the writable buffer buf starting at offset.");
1953
1954 static PyObject *
1955 pack_into(PyObject *self, PyObject *args)
1956 {
1957         PyObject *s_object, *fmt, *newargs, *result;
1958         Py_ssize_t n = PyTuple_GET_SIZE(args);
1959
1960         if (n == 0) {
1961                 PyErr_SetString(PyExc_TypeError, "missing format argument");
1962                 return NULL;
1963         }
1964         fmt = PyTuple_GET_ITEM(args, 0);
1965         newargs = PyTuple_GetSlice(args, 1, n);
1966         if (newargs == NULL)
1967                 return NULL;
1968
1969         s_object = cache_struct(fmt);
1970         if (s_object == NULL) {
1971                 Py_DECREF(newargs);
1972                 return NULL;
1973         }
1974         result = s_pack_into(s_object, newargs);
1975         Py_DECREF(newargs);
1976         Py_DECREF(s_object);
1977         return result;
1978 }
1979
1980 PyDoc_STRVAR(unpack_doc,
1981 "Unpack the string containing packed C structure data, according to fmt.\n\
1982 Requires len(string) == calcsize(fmt).");
1983
1984 static PyObject *
1985 unpack(PyObject *self, PyObject *args)
1986 {
1987         PyObject *s_object, *fmt, *inputstr, *result;
1988
1989         if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr))
1990                 return NULL;
1991
1992         s_object = cache_struct(fmt);
1993         if (s_object == NULL)
1994                 return NULL;
1995         result = s_unpack(s_object, inputstr);
1996         Py_DECREF(s_object);
1997         return result;
1998 }
1999
2000 PyDoc_STRVAR(unpack_from_doc,
2001 "Unpack the buffer, containing packed C structure data, according to\n\
2002 fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).");
2003
2004 static PyObject *
2005 unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
2006 {
2007         PyObject *s_object, *fmt, *newargs, *result;
2008         Py_ssize_t n = PyTuple_GET_SIZE(args);
2009
2010         if (n == 0) {
2011                 PyErr_SetString(PyExc_TypeError, "missing format argument");
2012                 return NULL;
2013         }
2014         fmt = PyTuple_GET_ITEM(args, 0);
2015         newargs = PyTuple_GetSlice(args, 1, n);
2016         if (newargs == NULL)
2017                 return NULL;
2018
2019         s_object = cache_struct(fmt);
2020         if (s_object == NULL) {
2021                 Py_DECREF(newargs);
2022                 return NULL;
2023         }
2024         result = s_unpack_from(s_object, newargs, kwds);
2025         Py_DECREF(newargs);
2026         Py_DECREF(s_object);
2027         return result;
2028 }
2029
2030 static struct PyMethodDef module_functions[] = {
2031         {"_clearcache", (PyCFunction)clearcache,        METH_NOARGS,    clearcache_doc},
2032         {"calcsize",    calcsize,       METH_O,         calcsize_doc},
2033         {"pack",        pack,           METH_VARARGS,   pack_doc},
2034         {"pack_into",   pack_into,      METH_VARARGS,   pack_into_doc},
2035         {"unpack",      unpack,         METH_VARARGS,   unpack_doc},
2036         {"unpack_from", (PyCFunction)unpack_from,       
2037                         METH_VARARGS|METH_KEYWORDS,     unpack_from_doc},
2038         {NULL,   NULL}          /* sentinel */
2039 };
2040
2041
2042 /* Module initialization */
2043
2044 PyDoc_STRVAR(module_doc,
2045 "Functions to convert between Python values and C structs.\n\
2046 Python strings are used to hold the data representing the C struct\n\
2047 and also as format strings to describe the layout of data in the C struct.\n\
2048 \n\
2049 The optional first format char indicates byte order, size and alignment:\n\
2050  @: native order, size & alignment (default)\n\
2051  =: native order, std. size & alignment\n\
2052  <: little-endian, std. size & alignment\n\
2053  >: big-endian, std. size & alignment\n\
2054  !: same as >\n\
2055 \n\
2056 The remaining chars indicate types of args and must match exactly;\n\
2057 these can be preceded by a decimal repeat count:\n\
2058   x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
2059   h:short; H:unsigned short; i:int; I:unsigned int;\n\
2060   l:long; L:unsigned long; f:float; d:double.\n\
2061 Special cases (preceding decimal count indicates length):\n\
2062   s:string (array of char); p: pascal string (with count byte).\n\
2063 Special case (only available in native format):\n\
2064   P:an integer type that is wide enough to hold a pointer.\n\
2065 Special case (not in native mode unless 'long long' in platform C):\n\
2066   q:long long; Q:unsigned long long\n\
2067 Whitespace between formats is ignored.\n\
2068 \n\
2069 The variable struct.error is an exception raised on errors.\n");
2070
2071 PyMODINIT_FUNC
2072 init_struct(void)
2073 {
2074         PyObject *ver, *m;
2075
2076         ver = PyString_FromString("0.2");
2077         if (ver == NULL)
2078                 return;
2079
2080         m = Py_InitModule3("_struct", module_functions, module_doc);
2081         if (m == NULL)
2082                 return;
2083
2084         Py_TYPE(&PyStructType) = &PyType_Type;
2085         if (PyType_Ready(&PyStructType) < 0)
2086                 return;
2087
2088 #ifdef PY_STRUCT_OVERFLOW_MASKING
2089         if (pyint_zero == NULL) {
2090                 pyint_zero = PyInt_FromLong(0);
2091                 if (pyint_zero == NULL)
2092                         return;
2093         }
2094         if (pylong_ulong_mask == NULL) {
2095 #if (SIZEOF_LONG == 4)
2096                 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
2097 #else
2098                 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
2099 #endif
2100                 if (pylong_ulong_mask == NULL)
2101                         return;
2102         }
2103
2104 #else
2105         /* This speed trick can't be used until overflow masking goes away, because
2106            native endian always raises exceptions instead of overflow masking. */
2107
2108         /* Check endian and swap in faster functions */
2109         {
2110                 int one = 1;
2111                 formatdef *native = native_table;
2112                 formatdef *other, *ptr;
2113                 if ((int)*(unsigned char*)&one)
2114                         other = lilendian_table;
2115                 else
2116                         other = bigendian_table;
2117                 /* Scan through the native table, find a matching
2118                    entry in the endian table and swap in the
2119                    native implementations whenever possible
2120                    (64-bit platforms may not have "standard" sizes) */
2121                 while (native->format != '\0' && other->format != '\0') {
2122                         ptr = other;
2123                         while (ptr->format != '\0') {
2124                                 if (ptr->format == native->format) {
2125                                         /* Match faster when formats are
2126                                            listed in the same order */
2127                                         if (ptr == other)
2128                                                 other++;
2129                                         /* Only use the trick if the
2130                                            size matches */
2131                                         if (ptr->size != native->size)
2132                                                 break;
2133                                         /* Skip float and double, could be
2134                                            "unknown" float format */
2135                                         if (ptr->format == 'd' || ptr->format == 'f')
2136                                                 break;
2137                                         ptr->pack = native->pack;
2138                                         ptr->unpack = native->unpack;
2139                                         break;
2140                                 }
2141                                 ptr++;
2142                         }
2143                         native++;
2144                 }
2145         }
2146 #endif
2147
2148         /* Add some symbolic constants to the module */
2149         if (StructError == NULL) {
2150                 StructError = PyErr_NewException("struct.error", NULL, NULL);
2151                 if (StructError == NULL)
2152                         return;
2153         }
2154
2155         Py_INCREF(StructError);
2156         PyModule_AddObject(m, "error", StructError);
2157
2158         Py_INCREF((PyObject*)&PyStructType);
2159         PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
2160
2161         PyModule_AddObject(m, "__version__", ver);
2162
2163         PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
2164 #ifdef PY_STRUCT_OVERFLOW_MASKING
2165         PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
2166 #endif
2167 #ifdef PY_STRUCT_FLOAT_COERCE
2168         PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
2169 #endif
2170
2171 }