2 /* struct module -- pack values into and (out of) strings */
4 /* New version supporting byte order, alignment and size options,
5 character strings, and unsigned numbers */
7 static char struct__doc__
[] = "\
8 Functions to convert between Python values and C structs.\n\
9 Python strings are used to hold the data representing the C struct\n\
10 and also as format strings to describe the layout of data in the C struct.\n\
12 The optional first format char indicates byte ordering and alignment:\n\
13 @: native w/native alignment(default)\n\
14 =: native w/standard alignment\n\
15 <: little-endian, std. alignment\n\
16 >: big-endian, std. alignment\n\
17 !: network, std (same as >)\n\
19 The remaining chars indicate types of args and must match exactly;\n\
20 these can be preceded by a decimal repeat count:\n\
21 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
22 h:short; H:unsigned short; i:int; I:unsigned int;\n\
23 l:long; L:unsigned long; f:float; d:double.\n\
24 Special cases (preceding decimal count indicates length):\n\
25 s:string (array of char); p: pascal string (w. count byte).\n\
26 Special case (only available in native format):\n\
27 P:an integer type that is wide enough to hold a pointer.\n\
28 Whitespace between formats is ignored.\n\
30 The variable struct.error is an exception raised on errors.";
39 static PyObject
*StructError
;
42 /* Define various structs to figure out the alignments of types */
46 ** XXXX We have a problem here. There are no unique alignment rules
47 ** on the PowerPC mac.
50 #pragma options align=mac68k
52 #endif /* __MWERKS__ */
54 typedef struct { char c
; short x
; } s_short
;
55 typedef struct { char c
; int x
; } s_int
;
56 typedef struct { char c
; long x
; } s_long
;
57 typedef struct { char c
; float x
; } s_float
;
58 typedef struct { char c
; double x
; } s_double
;
59 typedef struct { char c
; void *x
; } s_void_p
;
61 #define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
62 #define INT_ALIGN (sizeof(s_int) - sizeof(int))
63 #define LONG_ALIGN (sizeof(s_long) - sizeof(long))
64 #define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
65 #define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
66 #define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *))
68 #define STRINGIFY(x) #x
71 #pragma options align=reset
74 /* Helper routine to get a Python integer and raise the appropriate error
78 get_long(PyObject
*v
, long *p
)
80 long x
= PyInt_AsLong(v
);
81 if (x
== -1 && PyErr_Occurred()) {
82 if (PyErr_ExceptionMatches(PyExc_TypeError
))
83 PyErr_SetString(StructError
,
84 "required argument is not an integer");
92 /* Same, but handling unsigned long */
95 get_ulong(PyObject
*v
, unsigned long *p
)
97 if (PyLong_Check(v
)) {
98 unsigned long x
= PyLong_AsUnsignedLong(v
);
99 if (x
== (unsigned long)(-1) && PyErr_Occurred())
105 return get_long(v
, (long *)p
);
110 /* Floating point helpers */
112 /* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
113 Point Arithmetic). See the following URL:
114 http://www.psc.edu/general/software/packages/ieee/ieee.html */
116 /* XXX Inf/NaN are not handled quite right (but underflow is!) */
119 pack_float(double x
, /* The number to pack */
120 char *p
, /* Where to pack the high order byte */
121 int incr
) /* 1 for big-endian; -1 for little-endian */
137 /* Normalize f to be in the range [1.0, 2.0) */
138 if (0.5 <= f
&& f
< 1.0) {
146 PyErr_SetString(PyExc_SystemError
,
147 "frexp() result out of range");
152 /* XXX 128 itself is reserved for Inf/NaN */
153 PyErr_SetString(PyExc_OverflowError
,
154 "float too large to pack with f format");
158 /* Gradual underflow */
159 f
= ldexp(f
, 126 + e
);
162 else if (!(e
== 0 && f
== 0.0)) {
164 f
-= 1.0; /* Get rid of leading 1 */
167 f
*= 8388608.0; /* 2**23 */
168 fbits
= (long) floor(f
+ 0.5); /* Round */
171 *p
= (s
<<7) | (e
>>1);
175 *p
= (char) (((e
&1)<<7) | (fbits
>>16));
179 *p
= (fbits
>>8) & 0xFF;
190 pack_double(double x
, /* The number to pack */
191 char *p
, /* Where to pack the high order byte */
192 int incr
) /* 1 for big-endian; -1 for little-endian */
208 /* Normalize f to be in the range [1.0, 2.0) */
209 if (0.5 <= f
&& f
< 1.0) {
217 PyErr_SetString(PyExc_SystemError
,
218 "frexp() result out of range");
223 /* XXX 1024 itself is reserved for Inf/NaN */
224 PyErr_SetString(PyExc_OverflowError
,
225 "float too large to pack with d format");
228 else if (e
< -1022) {
229 /* Gradual underflow */
230 f
= ldexp(f
, 1022 + e
);
233 else if (!(e
== 0 && f
== 0.0)) {
235 f
-= 1.0; /* Get rid of leading 1 */
238 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
239 f
*= 268435456.0; /* 2**28 */
240 fhi
= (long) floor(f
); /* Truncate */
242 f
*= 16777216.0; /* 2**24 */
243 flo
= (long) floor(f
+ 0.5); /* Round */
246 *p
= (s
<<7) | (e
>>4);
250 *p
= (char) (((e
&0xF)<<4) | (fhi
>>24));
254 *p
= (fhi
>>16) & 0xFF;
258 *p
= (fhi
>>8) & 0xFF;
266 *p
= (flo
>>16) & 0xFF;
270 *p
= (flo
>>8) & 0xFF;
282 unpack_float(const char *p
, /* Where the high order byte is */
283 int incr
) /* 1 for big-endian; -1 for little-endian */
292 e
= (*p
& 0x7F) << 1;
297 f
= (*p
& 0x7F) << 16;
301 f
|= (*p
& 0xFF) << 8;
307 x
= (double)f
/ 8388608.0;
309 /* XXX This sadly ignores Inf/NaN issues */
321 return PyFloat_FromDouble(x
);
325 unpack_double(const char *p
, /* Where the high order byte is */
326 int incr
) /* 1 for big-endian; -1 for little-endian */
335 e
= (*p
& 0x7F) << 4;
340 fhi
= (*p
& 0xF) << 24;
344 fhi
|= (*p
& 0xFF) << 16;
348 fhi
|= (*p
& 0xFF) << 8;
356 flo
= (*p
& 0xFF) << 16;
360 flo
|= (*p
& 0xFF) << 8;
367 x
= (double)fhi
+ (double)flo
/ 16777216.0; /* 2**24 */
368 x
/= 268435456.0; /* 2**28 */
370 /* XXX This sadly ignores Inf/NaN */
382 return PyFloat_FromDouble(x
);
386 /* The translation function for each format character is table driven */
388 typedef struct _formatdef
{
392 PyObject
* (*unpack
)(const char *,
393 const struct _formatdef
*);
394 int (*pack
)(char *, PyObject
*,
395 const struct _formatdef
*);
399 nu_char(const char *p
, const formatdef
*f
)
401 return PyString_FromStringAndSize(p
, 1);
405 nu_byte(const char *p
, const formatdef
*f
)
407 return PyInt_FromLong((long) *(signed char *)p
);
411 nu_ubyte(const char *p
, const formatdef
*f
)
413 return PyInt_FromLong((long) *(unsigned char *)p
);
417 nu_short(const char *p
, const formatdef
*f
)
419 return PyInt_FromLong((long) *(short *)p
);
423 nu_ushort(const char *p
, const formatdef
*f
)
425 return PyInt_FromLong((long) *(unsigned short *)p
);
429 nu_int(const char *p
, const formatdef
*f
)
431 return PyInt_FromLong((long) *(int *)p
);
435 nu_uint(const char *p
, const formatdef
*f
)
437 unsigned int x
= *(unsigned int *)p
;
438 return PyLong_FromUnsignedLong((unsigned long)x
);
442 nu_long(const char *p
, const formatdef
*f
)
444 return PyInt_FromLong(*(long *)p
);
448 nu_ulong(const char *p
, const formatdef
*f
)
450 return PyLong_FromUnsignedLong(*(unsigned long *)p
);
454 nu_float(const char *p
, const formatdef
*f
)
457 memcpy((char *)&x
, p
, sizeof(float));
458 return PyFloat_FromDouble((double)x
);
462 nu_double(const char *p
, const formatdef
*f
)
465 memcpy((char *)&x
, p
, sizeof(double));
466 return PyFloat_FromDouble(x
);
470 nu_void_p(const char *p
, const formatdef
*f
)
472 return PyLong_FromVoidPtr(*(void **)p
);
476 np_byte(char *p
, PyObject
*v
, const formatdef
*f
)
479 if (get_long(v
, &x
) < 0)
481 if (x
< -128 || x
> 127){
482 PyErr_SetString(StructError
,
483 "byte format requires -128<=number<=127");
491 np_ubyte(char *p
, PyObject
*v
, const formatdef
*f
)
494 if (get_long(v
, &x
) < 0)
496 if (x
< 0 || x
> 255){
497 PyErr_SetString(StructError
,
498 "ubyte format requires 0<=number<=255");
506 np_char(char *p
, PyObject
*v
, const formatdef
*f
)
508 if (!PyString_Check(v
) || PyString_Size(v
) != 1) {
509 PyErr_SetString(StructError
,
510 "char format require string of length 1");
513 *p
= *PyString_AsString(v
);
518 np_short(char *p
, PyObject
*v
, const formatdef
*f
)
521 if (get_long(v
, &x
) < 0)
523 if (x
< SHRT_MIN
|| x
> SHRT_MAX
){
524 PyErr_SetString(StructError
,
525 "short format requires " STRINGIFY(SHRT_MIN
)
526 "<=number<=" STRINGIFY(SHRT_MAX
));
529 * (short *)p
= (short)x
;
534 np_ushort(char *p
, PyObject
*v
, const formatdef
*f
)
537 if (get_long(v
, &x
) < 0)
539 if (x
< 0 || x
> USHRT_MAX
){
540 PyErr_SetString(StructError
,
541 "short format requires 0<=number<=" STRINGIFY(USHRT_MAX
));
544 * (unsigned short *)p
= (unsigned short)x
;
549 np_int(char *p
, PyObject
*v
, const formatdef
*f
)
552 if (get_long(v
, &x
) < 0)
559 np_uint(char *p
, PyObject
*v
, const formatdef
*f
)
562 if (get_ulong(v
, &x
) < 0)
564 * (unsigned int *)p
= x
;
569 np_long(char *p
, PyObject
*v
, const formatdef
*f
)
572 if (get_long(v
, &x
) < 0)
579 np_ulong(char *p
, PyObject
*v
, const formatdef
*f
)
582 if (get_ulong(v
, &x
) < 0)
584 * (unsigned long *)p
= x
;
589 np_float(char *p
, PyObject
*v
, const formatdef
*f
)
591 float x
= (float)PyFloat_AsDouble(v
);
592 if (x
== -1 && PyErr_Occurred()) {
593 PyErr_SetString(StructError
,
594 "required argument is not a float");
597 memcpy(p
, (char *)&x
, sizeof(float));
602 np_double(char *p
, PyObject
*v
, const formatdef
*f
)
604 double x
= PyFloat_AsDouble(v
);
605 if (x
== -1 && PyErr_Occurred()) {
606 PyErr_SetString(StructError
,
607 "required argument is not a float");
610 memcpy(p
, (char *)&x
, sizeof(double));
615 np_void_p(char *p
, PyObject
*v
, const formatdef
*f
)
617 void *x
= PyLong_AsVoidPtr(v
);
618 if (x
== NULL
&& PyErr_Occurred()) {
619 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
620 if (PyErr_ExceptionMatches(PyExc_TypeError
))
621 PyErr_SetString(StructError
,
622 "required argument is not an integer");
629 static formatdef native_table
[] = {
630 {'x', sizeof(char), 0, NULL
},
631 {'b', sizeof(char), 0, nu_byte
, np_byte
},
632 {'B', sizeof(char), 0, nu_ubyte
, np_ubyte
},
633 {'c', sizeof(char), 0, nu_char
, np_char
},
634 {'s', sizeof(char), 0, NULL
},
635 {'p', sizeof(char), 0, NULL
},
636 {'h', sizeof(short), SHORT_ALIGN
, nu_short
, np_short
},
637 {'H', sizeof(short), SHORT_ALIGN
, nu_ushort
, np_ushort
},
638 {'i', sizeof(int), INT_ALIGN
, nu_int
, np_int
},
639 {'I', sizeof(int), INT_ALIGN
, nu_uint
, np_uint
},
640 {'l', sizeof(long), LONG_ALIGN
, nu_long
, np_long
},
641 {'L', sizeof(long), LONG_ALIGN
, nu_ulong
, np_ulong
},
642 {'f', sizeof(float), FLOAT_ALIGN
, nu_float
, np_float
},
643 {'d', sizeof(double), DOUBLE_ALIGN
, nu_double
, np_double
},
644 {'P', sizeof(void *), VOID_P_ALIGN
, nu_void_p
, np_void_p
},
649 bu_int(const char *p
, const formatdef
*f
)
654 x
= (x
<<8) | (*p
++ & 0xFF);
656 /* Extend the sign bit. */
657 if (SIZEOF_LONG
> f
->size
)
658 x
|= -(x
& (1L << (8*f
->size
- 1)));
659 return PyInt_FromLong(x
);
663 bu_uint(const char *p
, const formatdef
*f
)
668 x
= (x
<<8) | (*p
++ & 0xFF);
671 return PyLong_FromUnsignedLong(x
);
673 return PyInt_FromLong((long)x
);
677 bu_float(const char *p
, const formatdef
*f
)
679 return unpack_float(p
, 1);
683 bu_double(const char *p
, const formatdef
*f
)
685 return unpack_double(p
, 1);
689 bp_int(char *p
, PyObject
*v
, const formatdef
*f
)
693 if (get_long(v
, &x
) < 0)
704 bp_uint(char *p
, PyObject
*v
, const formatdef
*f
)
708 if (get_ulong(v
, &x
) < 0)
719 bp_float(char *p
, PyObject
*v
, const formatdef
*f
)
721 double x
= PyFloat_AsDouble(v
);
722 if (x
== -1 && PyErr_Occurred()) {
723 PyErr_SetString(StructError
,
724 "required argument is not a float");
727 return pack_float(x
, p
, 1);
731 bp_double(char *p
, PyObject
*v
, const formatdef
*f
)
733 double x
= PyFloat_AsDouble(v
);
734 if (x
== -1 && PyErr_Occurred()) {
735 PyErr_SetString(StructError
,
736 "required argument is not a float");
739 return pack_double(x
, p
, 1);
742 static formatdef bigendian_table
[] = {
744 {'b', 1, 0, bu_int
, bp_int
},
745 {'B', 1, 0, bu_uint
, bp_int
},
746 {'c', 1, 0, nu_char
, np_char
},
749 {'h', 2, 0, bu_int
, bp_int
},
750 {'H', 2, 0, bu_uint
, bp_uint
},
751 {'i', 4, 0, bu_int
, bp_int
},
752 {'I', 4, 0, bu_uint
, bp_uint
},
753 {'l', 4, 0, bu_int
, bp_int
},
754 {'L', 4, 0, bu_uint
, bp_uint
},
755 {'f', 4, 0, bu_float
, bp_float
},
756 {'d', 8, 0, bu_double
, bp_double
},
761 lu_int(const char *p
, const formatdef
*f
)
766 x
= (x
<<8) | (p
[--i
] & 0xFF);
768 /* Extend the sign bit. */
769 if (SIZEOF_LONG
> f
->size
)
770 x
|= -(x
& (1L << (8*f
->size
- 1)));
771 return PyInt_FromLong(x
);
775 lu_uint(const char *p
, const formatdef
*f
)
780 x
= (x
<<8) | (p
[--i
] & 0xFF);
783 return PyLong_FromUnsignedLong(x
);
785 return PyInt_FromLong((long)x
);
789 lu_float(const char *p
, const formatdef
*f
)
791 return unpack_float(p
+3, -1);
795 lu_double(const char *p
, const formatdef
*f
)
797 return unpack_double(p
+7, -1);
801 lp_int(char *p
, PyObject
*v
, const formatdef
*f
)
805 if (get_long(v
, &x
) < 0)
816 lp_uint(char *p
, PyObject
*v
, const formatdef
*f
)
820 if (get_ulong(v
, &x
) < 0)
831 lp_float(char *p
, PyObject
*v
, const formatdef
*f
)
833 double x
= PyFloat_AsDouble(v
);
834 if (x
== -1 && PyErr_Occurred()) {
835 PyErr_SetString(StructError
,
836 "required argument is not a float");
839 return pack_float(x
, p
+3, -1);
843 lp_double(char *p
, PyObject
*v
, const formatdef
*f
)
845 double x
= PyFloat_AsDouble(v
);
846 if (x
== -1 && PyErr_Occurred()) {
847 PyErr_SetString(StructError
,
848 "required argument is not a float");
851 return pack_double(x
, p
+7, -1);
854 static formatdef lilendian_table
[] = {
856 {'b', 1, 0, lu_int
, lp_int
},
857 {'B', 1, 0, lu_uint
, lp_int
},
858 {'c', 1, 0, nu_char
, np_char
},
861 {'h', 2, 0, lu_int
, lp_int
},
862 {'H', 2, 0, lu_uint
, lp_uint
},
863 {'i', 4, 0, lu_int
, lp_int
},
864 {'I', 4, 0, lu_uint
, lp_uint
},
865 {'l', 4, 0, lu_int
, lp_int
},
866 {'L', 4, 0, lu_uint
, lp_uint
},
867 {'f', 4, 0, lu_float
, lp_float
},
868 {'d', 8, 0, lu_double
, lp_double
},
873 static const formatdef
*
874 whichtable(char **pfmt
)
876 const char *fmt
= (*pfmt
)++; /* May be backed out of later */
879 return lilendian_table
;
881 case '!': /* Network byte order is big-endian */
882 return bigendian_table
;
883 case '=': { /* Host byte order -- different from native in aligment! */
885 char *p
= (char *) &n
;
887 return lilendian_table
;
889 return bigendian_table
;
892 --*pfmt
; /* Back out of pointer increment */
900 /* Get the table entry for a format code */
902 static const formatdef
*
903 getentry(int c
, const formatdef
*f
)
905 for (; f
->format
!= '\0'; f
++) {
906 if (f
->format
== c
) {
910 PyErr_SetString(StructError
, "bad char in struct format");
915 /* Align a size according to a format code */
918 align(int size
, int c
, const formatdef
*e
)
920 if (e
->format
== c
) {
922 size
= ((size
+ e
->alignment
- 1)
931 /* calculate the size of a format string */
934 calcsize(const char *fmt
, const formatdef
*f
)
939 int size
, num
, itemsize
, x
;
943 while ((c
= *s
++) != '\0') {
946 if ('0' <= c
&& c
<= '9') {
948 while ('0' <= (c
= *s
++) && c
<= '9') {
949 x
= num
*10 + (c
- '0');
953 "overflow in item count");
968 size
= align(size
, c
, e
);
971 if (x
/itemsize
!= num
|| size
< 0) {
972 PyErr_SetString(StructError
,
973 "total struct size too long");
982 static char calcsize__doc__
[] = "\
983 calcsize(fmt) -> int\n\
984 Return size of C struct described by format string fmt.\n\
985 See struct.__doc__ for more on format strings.";
988 struct_calcsize(PyObject
*self
, PyObject
*args
)
994 if (!PyArg_ParseTuple(args
, "s:calcsize", &fmt
))
996 f
= whichtable(&fmt
);
997 size
= calcsize(fmt
, f
);
1000 return PyInt_FromLong((long)size
);
1004 static char pack__doc__
[] = "\
1005 pack(fmt, v1, v2, ...) -> string\n\
1006 Return string containing values v1, v2, ... packed according to fmt.\n\
1007 See struct.__doc__ for more on format strings.";
1010 struct_pack(PyObject
*self
, PyObject
*args
)
1012 const formatdef
*f
, *e
;
1013 PyObject
*format
, *result
, *v
;
1017 char *s
, *res
, *restart
, *nres
;
1020 if (args
== NULL
|| !PyTuple_Check(args
) ||
1021 (n
= PyTuple_Size(args
)) < 1)
1023 PyErr_SetString(PyExc_TypeError
,
1024 "struct.pack requires at least one argument");
1027 format
= PyTuple_GetItem(args
, 0);
1028 if (!PyArg_Parse(format
, "s", &fmt
))
1030 f
= whichtable(&fmt
);
1031 size
= calcsize(fmt
, f
);
1034 result
= PyString_FromStringAndSize((char *)NULL
, size
);
1040 res
= restart
= PyString_AsString(result
);
1042 while ((c
= *s
++) != '\0') {
1043 if (isspace((int)c
))
1045 if ('0' <= c
&& c
<= '9') {
1047 while ('0' <= (c
= *s
++) && c
<= '9')
1048 num
= num
*10 + (c
- '0');
1058 nres
= restart
+ align((int)(res
-restart
), c
, e
);
1059 /* Fill padd bytes with zeros */
1062 if (num
== 0 && c
!= 's')
1066 /* doesn't consume arguments */
1067 memset(res
, '\0', num
);
1072 PyErr_SetString(StructError
,
1073 "insufficient arguments to pack");
1076 v
= PyTuple_GetItem(args
, i
++);
1080 /* num is string size, not repeat count */
1082 if (!PyString_Check(v
)) {
1083 PyErr_SetString(StructError
,
1084 "argument for 's' must be a string");
1087 n
= PyString_Size(v
);
1091 memcpy(res
, PyString_AsString(v
), n
);
1093 memset(res
+n
, '\0', num
-n
);
1097 else if (c
== 'p') {
1098 /* num is string size + 1,
1099 to fit in the count byte */
1101 num
--; /* now num is max string size */
1102 if (!PyString_Check(v
)) {
1103 PyErr_SetString(StructError
,
1104 "argument for 'p' must be a string");
1107 n
= PyString_Size(v
);
1111 memcpy(res
+1, PyString_AsString(v
), n
);
1113 /* no real need, just to be nice */
1114 memset(res
+1+n
, '\0', num
-n
);
1115 *res
++ = n
; /* store the length byte */
1120 if (e
->pack(res
, v
, e
) < 0)
1124 } while (--num
> 0);
1128 PyErr_SetString(StructError
,
1129 "too many arguments for pack format");
1141 static char unpack__doc__
[] = "\
1142 unpack(fmt, string) -> (v1, v2, ...)\n\
1143 Unpack the string, containing packed C structure data, according\n\
1144 to fmt. Requires len(string)==calcsize(fmt).\n\
1145 See struct.__doc__ for more on format strings.";
1148 struct_unpack(PyObject
*self
, PyObject
*args
)
1150 const formatdef
*f
, *e
;
1151 char *str
, *start
, *fmt
, *s
;
1156 if (!PyArg_ParseTuple(args
, "ss#:unpack", &fmt
, &start
, &len
))
1158 f
= whichtable(&fmt
);
1159 size
= calcsize(fmt
, f
);
1163 PyErr_SetString(StructError
,
1164 "unpack str size does not match format");
1167 res
= PyList_New(0);
1172 while ((c
= *s
++) != '\0') {
1173 if (isspace((int)c
))
1175 if ('0' <= c
&& c
<= '9') {
1177 while ('0' <= (c
= *s
++) && c
<= '9')
1178 num
= num
*10 + (c
- '0');
1188 str
= start
+ align((int)(str
-start
), c
, e
);
1189 if (num
== 0 && c
!= 's')
1198 /* num is string size, not repeat count */
1199 v
= PyString_FromStringAndSize(str
, num
);
1205 else if (c
== 'p') {
1206 /* num is string buffer size,
1208 int n
= *(unsigned char*)str
;
1209 /* first byte (unsigned) is string size */
1212 v
= PyString_FromStringAndSize(str
+1, n
);
1219 v
= e
->unpack(str
, e
);
1224 if (v
== NULL
|| PyList_Append(res
, v
) < 0)
1227 } while (--num
> 0);
1230 v
= PyList_AsTuple(res
);
1240 /* List of functions */
1242 static PyMethodDef struct_methods
[] = {
1243 {"calcsize", struct_calcsize
, METH_VARARGS
, calcsize__doc__
},
1244 {"pack", struct_pack
, METH_VARARGS
, pack__doc__
},
1245 {"unpack", struct_unpack
, METH_VARARGS
, unpack__doc__
},
1246 {NULL
, NULL
} /* sentinel */
1250 /* Module initialization */
1257 /* Create the module and add the functions */
1258 m
= Py_InitModule4("struct", struct_methods
, struct__doc__
,
1259 (PyObject
*)NULL
, PYTHON_API_VERSION
);
1261 /* Add some symbolic constants to the module */
1262 d
= PyModule_GetDict(m
);
1263 StructError
= PyErr_NewException("struct.error", NULL
, NULL
);
1264 if (StructError
== NULL
)
1266 PyDict_SetItemString(d
, "error", StructError
);