blob: 54ca63166eefb971182b0d67f1144239da5e5874 [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum02975121992-08-17 08:55:12 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum02975121992-08-17 08:55:12 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum02975121992-08-17 08:55:12 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum02975121992-08-17 08:55:12 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum02975121992-08-17 08:55:12 +000029
30******************************************************************/
31
32/* struct module -- pack values into and (out of) strings */
33
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000034/* New version supporting byte order, alignment and size options,
35 character strings, and unsigned numbers */
36
Barry Warsaw30695fa1996-12-12 23:32:31 +000037#include "Python.h"
Guido van Rossum74679b41997-01-02 22:21:36 +000038#include "mymath.h"
Guido van Rossum02975121992-08-17 08:55:12 +000039
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000040#include <limits.h>
Guido van Rossume20aef51997-08-26 20:39:54 +000041#include <ctype.h>
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000042
43
44/* Exception */
45
Barry Warsaw30695fa1996-12-12 23:32:31 +000046static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000047
48
49/* Define various structs to figure out the alignments of types */
50
Jack Jansen971e1df1995-02-02 14:29:10 +000051#ifdef __MWERKS__
52/*
53** XXXX We have a problem here. There are no unique alignment rules
54** on the PowerPC mac.
55*/
56#ifdef __powerc
57#pragma options align=mac68k
58#endif
59#endif /* __MWERKS__ */
60
Guido van Rossum02975121992-08-17 08:55:12 +000061typedef struct { char c; short x; } s_short;
62typedef struct { char c; int x; } s_int;
63typedef struct { char c; long x; } s_long;
64typedef struct { char c; float x; } s_float;
65typedef struct { char c; double x; } s_double;
66
67#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
68#define INT_ALIGN (sizeof(s_int) - sizeof(int))
69#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
70#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
71#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
72
Jack Jansen971e1df1995-02-02 14:29:10 +000073#ifdef __powerc
74#pragma options align=reset
75#endif
76
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000077/* Helper routine to get a Python integer and raise the appropriate error
78 if it isn't one */
79
80static int
81get_long(v, p)
82 PyObject *v;
83 long *p;
84{
85 long x = PyInt_AsLong(v);
86 if (x == -1 && PyErr_Occurred()) {
87 if (PyErr_Occurred() == PyExc_TypeError)
88 PyErr_SetString(StructError,
89 "required argument is not an integer");
90 return -1;
91 }
92 *p = x;
93 return 0;
94}
95
96
Guido van Rossum60c50611996-12-31 16:29:52 +000097/* Same, but handling unsigned long */
98
99static int
100get_ulong(v, p)
101 PyObject *v;
102 unsigned long *p;
103{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000104 if (PyLong_Check(v)) {
105 unsigned long x = PyLong_AsUnsignedLong(v);
106 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +0000107 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000108 *p = x;
109 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000110 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000111 else {
112 return get_long(v, (long *)p);
113 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000114}
115
116
Guido van Rossum74679b41997-01-02 22:21:36 +0000117/* Floating point helpers */
118
119/* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
120 Point Arithmetic). See the following URL:
121 http://www.psc.edu/general/software/packages/ieee/ieee.html */
122
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000123/* XXX Inf/NaN are not handled quite right (but underflow is!) */
Guido van Rossum74679b41997-01-02 22:21:36 +0000124
125static int
126pack_float(x, p, incr)
127 double x; /* The number to pack */
128 char *p; /* Where to pack the high order byte */
129 int incr; /* 1 for big-endian; -1 for little-endian */
130{
131 int s;
132 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000133 double f;
134 long fbits;
Guido van Rossum74679b41997-01-02 22:21:36 +0000135
136 if (x < 0) {
137 s = 1;
138 x = -x;
139 }
140 else
141 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000142
143 f = frexp(x, &e);
144
145 /* Normalize f to be in the range [1.0, 2.0) */
146 if (0.5 <= f && f < 1.0) {
147 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000148 e--;
149 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000150 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000151 e = 0;
152 }
153 else {
154 PyErr_SetString(PyExc_SystemError,
155 "frexp() result out of range");
156 return -1;
157 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000158
159 if (e >= 128) {
160 /* XXX 128 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000161 PyErr_SetString(PyExc_OverflowError,
162 "float too large to pack with f format");
163 return -1;
164 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000165 else if (e < -126) {
166 /* Gradual underflow */
167 f = ldexp(f, 126 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000168 e = 0;
169 }
Guido van Rossum74679b41997-01-02 22:21:36 +0000170 else {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000171 e += 127;
172 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000173 }
174
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000175 f *= 8388608.0; /* 2**23 */
176 fbits = (long) floor(f + 0.5); /* Round */
177
Guido van Rossum74679b41997-01-02 22:21:36 +0000178 /* First byte */
179 *p = (s<<7) | (e>>1);
180 p += incr;
181
182 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000183 *p = (char) (((e&1)<<7) | (fbits>>16));
Guido van Rossum74679b41997-01-02 22:21:36 +0000184 p += incr;
185
186 /* Third byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000187 *p = (fbits>>8) & 0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000188 p += incr;
189
190 /* Fourth byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000191 *p = fbits&0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000192
193 /* Done */
194 return 0;
195}
196
197static int
198pack_double(x, p, incr)
199 double x; /* The number to pack */
200 char *p; /* Where to pack the high order byte */
201 int incr; /* 1 for big-endian; -1 for little-endian */
202{
203 int s;
204 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000205 double f;
Guido van Rossum74679b41997-01-02 22:21:36 +0000206 long fhi, flo;
207
208 if (x < 0) {
209 s = 1;
210 x = -x;
211 }
212 else
213 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000214
215 f = frexp(x, &e);
216
217 /* Normalize f to be in the range [1.0, 2.0) */
218 if (0.5 <= f && f < 1.0) {
219 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000220 e--;
221 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000222 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000223 e = 0;
224 }
225 else {
226 PyErr_SetString(PyExc_SystemError,
227 "frexp() result out of range");
228 return -1;
229 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000230
231 if (e >= 1024) {
232 /* XXX 1024 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000233 PyErr_SetString(PyExc_OverflowError,
234 "float too large to pack with d format");
235 return -1;
236 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000237 else if (e < -1022) {
238 /* Gradual underflow */
239 f = ldexp(f, 1022 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000240 e = 0;
241 }
Guido van Rossum74679b41997-01-02 22:21:36 +0000242 else {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000243 e += 1023;
244 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000245 }
246
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000247 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
248 f *= 268435456.0; /* 2**28 */
249 fhi = (long) floor(f); /* Truncate */
250 f -= (double)fhi;
251 f *= 16777216.0; /* 2**24 */
252 flo = (long) floor(f + 0.5); /* Round */
253
Guido van Rossum74679b41997-01-02 22:21:36 +0000254 /* First byte */
255 *p = (s<<7) | (e>>4);
256 p += incr;
257
258 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000259 *p = (char) (((e&0xF)<<4) | (fhi>>24));
Guido van Rossum74679b41997-01-02 22:21:36 +0000260 p += incr;
261
262 /* Third byte */
263 *p = (fhi>>16) & 0xFF;
264 p += incr;
265
266 /* Fourth byte */
267 *p = (fhi>>8) & 0xFF;
268 p += incr;
269
270 /* Fifth byte */
271 *p = fhi & 0xFF;
272 p += incr;
273
274 /* Sixth byte */
275 *p = (flo>>16) & 0xFF;
276 p += incr;
277
278 /* Seventh byte */
279 *p = (flo>>8) & 0xFF;
280 p += incr;
281
282 /* Eighth byte */
283 *p = flo & 0xFF;
284 p += incr;
285
286 /* Done */
287 return 0;
288}
289
290static PyObject *
291unpack_float(p, incr)
292 char *p; /* Where the high order byte is */
293 int incr; /* 1 for big-endian; -1 for little-endian */
294{
295 int s;
296 int e;
297 long f;
298 double x;
299
300 /* First byte */
301 s = (*p>>7) & 1;
302 e = (*p & 0x7F) << 1;
303 p += incr;
304
305 /* Second byte */
306 e |= (*p>>7) & 1;
307 f = (*p & 0x7F) << 16;
308 p += incr;
309
310 /* Third byte */
311 f |= (*p & 0xFF) << 8;
312 p += incr;
313
314 /* Fourth byte */
315 f |= *p & 0xFF;
316
317 x = (double)f / 8388608.0;
318
319 /* XXX This sadly ignores Inf/NaN issues */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000320 if (e == 0)
321 e = -126;
322 else {
323 x += 1.0;
324 e -= 127;
325 }
326 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000327
328 if (s)
329 x = -x;
330
331 return PyFloat_FromDouble(x);
332}
333
334static PyObject *
335unpack_double(p, incr)
336 char *p; /* Where the high order byte is */
337 int incr; /* 1 for big-endian; -1 for little-endian */
338{
339 int s;
340 int e;
341 long fhi, flo;
342 double x;
343
344 /* First byte */
345 s = (*p>>7) & 1;
346 e = (*p & 0x7F) << 4;
347 p += incr;
348
349 /* Second byte */
350 e |= (*p>>4) & 0xF;
351 fhi = (*p & 0xF) << 24;
352 p += incr;
353
354 /* Third byte */
355 fhi |= (*p & 0xFF) << 16;
356 p += incr;
357
358 /* Fourth byte */
359 fhi |= (*p & 0xFF) << 8;
360 p += incr;
361
362 /* Fifth byte */
363 fhi |= *p & 0xFF;
364 p += incr;
365
366 /* Sixth byte */
367 flo = (*p & 0xFF) << 16;
368 p += incr;
369
370 /* Seventh byte */
371 flo |= (*p & 0xFF) << 8;
372 p += incr;
373
374 /* Eighth byte */
375 flo |= *p & 0xFF;
376 p += incr;
377
378 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
379 x /= 268435456.0; /* 2**28 */
380
381 /* XXX This sadly ignores Inf/NaN */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000382 if (e == 0)
383 e = -1022;
384 else {
385 x += 1.0;
386 e -= 1023;
387 }
388 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000389
390 if (s)
391 x = -x;
392
393 return PyFloat_FromDouble(x);
394}
395
396
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000397/* The translation function for each format character is table driven */
398
399typedef struct _formatdef {
400 char format;
401 int size;
402 int alignment;
403 PyObject* (*unpack) Py_PROTO((const char *,
404 const struct _formatdef *));
405 int (*pack) Py_PROTO((char *,
406 PyObject *,
407 const struct _formatdef *));
408} formatdef;
409
410static PyObject *
411nu_char(p, f)
412 const char *p;
413 const formatdef *f;
414{
415 return PyString_FromStringAndSize(p, 1);
416}
417
418static PyObject *
419nu_byte(p, f)
420 const char *p;
421 const formatdef *f;
422{
423 return PyInt_FromLong((long) *(signed char *)p);
424}
425
426static PyObject *
427nu_ubyte(p, f)
428 const char *p;
429 const formatdef *f;
430{
431 return PyInt_FromLong((long) *(unsigned char *)p);
432}
433
434static PyObject *
435nu_short(p, f)
436 const char *p;
437 const formatdef *f;
438{
439 return PyInt_FromLong((long) *(short *)p);
440}
441
442static PyObject *
443nu_ushort(p, f)
444 const char *p;
445 const formatdef *f;
446{
447 return PyInt_FromLong((long) *(unsigned short *)p);
448}
449
450static PyObject *
451nu_int(p, f)
452 const char *p;
453 const formatdef *f;
454{
455 return PyInt_FromLong((long) *(int *)p);
456}
457
458static PyObject *
459nu_uint(p, f)
460 const char *p;
461 const formatdef *f;
462{
463 unsigned int x = *(unsigned int *)p;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000464 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000465}
466
467static PyObject *
468nu_long(p, f)
469 const char *p;
470 const formatdef *f;
471{
472 return PyInt_FromLong(*(long *)p);
473}
474
475static PyObject *
476nu_ulong(p, f)
477 const char *p;
478 const formatdef *f;
479{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000480 return PyLong_FromUnsignedLong(*(unsigned long *)p);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000481}
482
483static PyObject *
484nu_float(p, f)
485 const char *p;
486 const formatdef *f;
487{
488 float x;
489 memcpy((char *)&x, p, sizeof(float));
490 return PyFloat_FromDouble((double)x);
491}
492
493static PyObject *
494nu_double(p, f)
495 const char *p;
496 const formatdef *f;
497{
498 double x;
499 memcpy((char *)&x, p, sizeof(double));
500 return PyFloat_FromDouble(x);
501}
502
503static int
504np_byte(p, v, f)
505 char *p;
506 PyObject *v;
507 const formatdef *f;
508{
509 long x;
510 if (get_long(v, &x) < 0)
511 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000512 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000513 return 0;
514}
515
516static int
517np_char(p, v, f)
518 char *p;
519 PyObject *v;
520 const formatdef *f;
521{
522 if (!PyString_Check(v) || PyString_Size(v) != 1) {
523 PyErr_SetString(StructError,
524 "char format require string of length 1");
525 return -1;
526 }
527 *p = *PyString_AsString(v);
528 return 0;
529}
530
531static int
532np_short(p, v, f)
533 char *p;
534 PyObject *v;
535 const formatdef *f;
536{
537 long x;
538 if (get_long(v, &x) < 0)
539 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000540 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000541 return 0;
542}
543
544static int
545np_int(p, v, f)
546 char *p;
547 PyObject *v;
548 const formatdef *f;
549{
550 long x;
551 if (get_long(v, &x) < 0)
552 return -1;
553 * (int *)p = x;
554 return 0;
555}
556
557static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000558np_uint(p, v, f)
559 char *p;
560 PyObject *v;
561 const formatdef *f;
562{
563 unsigned long x;
564 if (get_ulong(v, &x) < 0)
565 return -1;
566 * (unsigned int *)p = x;
567 return 0;
568}
569
570static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000571np_long(p, v, f)
572 char *p;
573 PyObject *v;
574 const formatdef *f;
575{
576 long x;
577 if (get_long(v, &x) < 0)
578 return -1;
579 * (long *)p = x;
580 return 0;
581}
582
583static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000584np_ulong(p, v, f)
585 char *p;
586 PyObject *v;
587 const formatdef *f;
588{
589 unsigned long x;
590 if (get_ulong(v, &x) < 0)
591 return -1;
592 * (unsigned long *)p = x;
593 return 0;
594}
595
596static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000597np_float(p, v, f)
598 char *p;
599 PyObject *v;
600 const formatdef *f;
601{
602 float x = (float)PyFloat_AsDouble(v);
603 if (x == -1 && PyErr_Occurred()) {
604 PyErr_SetString(StructError,
605 "required argument is not a float");
606 return -1;
607 }
608 memcpy(p, (char *)&x, sizeof(float));
609 return 0;
610}
611
612static int
613np_double(p, v, f)
614 char *p;
615 PyObject *v;
616 const formatdef *f;
617{
618 double x = PyFloat_AsDouble(v);
619 if (x == -1 && PyErr_Occurred()) {
620 PyErr_SetString(StructError,
621 "required argument is not a float");
622 return -1;
623 }
624 memcpy(p, (char *)&x, sizeof(double));
625 return 0;
626}
627
628static formatdef native_table[] = {
629 {'x', sizeof(char), 0, NULL},
630 {'b', sizeof(char), 0, nu_byte, np_byte},
631 {'B', sizeof(char), 0, nu_ubyte, np_byte},
632 {'c', sizeof(char), 0, nu_char, np_char},
633 {'s', sizeof(char), 0, NULL},
634 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
635 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
636 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000637 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000638 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000639 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000640 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
641 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
642 {0}
643};
644
645static PyObject *
646bu_int(p, f)
647 const char *p;
648 const formatdef *f;
649{
650 long x = 0;
651 int i = f->size;
652 do {
653 x = (x<<8) | (*p++ & 0xFF);
654 } while (--i > 0);
655 i = 8*(sizeof(long) - f->size);
656 if (i) {
657 x <<= i;
658 x >>= i;
659 }
660 return PyInt_FromLong(x);
661}
662
663static PyObject *
664bu_uint(p, f)
665 const char *p;
666 const formatdef *f;
667{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000668 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000669 int i = f->size;
670 do {
671 x = (x<<8) | (*p++ & 0xFF);
672 } while (--i > 0);
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000673 return PyLong_FromUnsignedLong(x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000674}
675
Guido van Rossum74679b41997-01-02 22:21:36 +0000676static PyObject *
677bu_float(p, f)
678 const char *p;
679 const formatdef *f;
680{
681 return unpack_float(p, 1);
682}
683
684static PyObject *
685bu_double(p, f)
686 const char *p;
687 const formatdef *f;
688{
689 return unpack_double(p, 1);
690}
691
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000692static int
693bp_int(p, v, f)
694 char *p;
695 PyObject *v;
696 const formatdef *f;
697{
698 long x;
699 int i;
700 if (get_long(v, &x) < 0)
701 return -1;
702 i = f->size;
703 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000704 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000705 x >>= 8;
706 } while (i > 0);
707 return 0;
708}
709
Guido van Rossum60c50611996-12-31 16:29:52 +0000710static int
711bp_uint(p, v, f)
712 char *p;
713 PyObject *v;
714 const formatdef *f;
715{
716 unsigned long x;
717 int i;
718 if (get_ulong(v, &x) < 0)
719 return -1;
720 i = f->size;
721 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000722 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000723 x >>= 8;
724 } while (i > 0);
725 return 0;
726}
727
Guido van Rossum74679b41997-01-02 22:21:36 +0000728static int
729bp_float(p, v, f)
730 char *p;
731 PyObject *v;
732 const formatdef *f;
733{
734 double x = PyFloat_AsDouble(v);
735 if (x == -1 && PyErr_Occurred()) {
736 PyErr_SetString(StructError,
737 "required argument is not a float");
738 return -1;
739 }
740 return pack_float(x, p, 1);
741}
742
743static int
744bp_double(p, v, f)
745 char *p;
746 PyObject *v;
747 const formatdef *f;
748{
749 double x = 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 return pack_double(x, p, 1);
756}
757
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000758static formatdef bigendian_table[] = {
759 {'x', 1, 0, NULL},
760 {'b', 1, 0, bu_int, bp_int},
761 {'B', 1, 0, bu_uint, bp_int},
762 {'c', 1, 0, nu_char, np_char},
763 {'s', 1, 0, NULL},
764 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000765 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000766 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000767 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000768 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000769 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000770 {'f', 4, 0, bu_float, bp_float},
771 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000772 {0}
773};
774
775static PyObject *
776lu_int(p, f)
777 const char *p;
778 const formatdef *f;
779{
780 long x = 0;
781 int i = f->size;
782 do {
783 x = (x<<8) | (p[--i] & 0xFF);
784 } while (i > 0);
785 i = 8*(sizeof(long) - f->size);
786 if (i) {
787 x <<= i;
788 x >>= i;
789 }
790 return PyInt_FromLong(x);
791}
792
793static PyObject *
794lu_uint(p, f)
795 const char *p;
796 const formatdef *f;
797{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000798 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000799 int i = f->size;
800 do {
801 x = (x<<8) | (p[--i] & 0xFF);
802 } while (i > 0);
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000803 return PyLong_FromUnsignedLong(x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000804}
805
Guido van Rossum74679b41997-01-02 22:21:36 +0000806static PyObject *
807lu_float(p, f)
808 const char *p;
809 const formatdef *f;
810{
811 return unpack_float(p+3, -1);
812}
813
814static PyObject *
815lu_double(p, f)
816 const char *p;
817 const formatdef *f;
818{
819 return unpack_double(p+7, -1);
820}
821
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000822static int
823lp_int(p, v, f)
824 char *p;
825 PyObject *v;
826 const formatdef *f;
827{
828 long x;
829 int i;
830 if (get_long(v, &x) < 0)
831 return -1;
832 i = f->size;
833 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000834 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000835 x >>= 8;
836 } while (--i > 0);
837 return 0;
838}
839
Guido van Rossum60c50611996-12-31 16:29:52 +0000840static int
841lp_uint(p, v, f)
842 char *p;
843 PyObject *v;
844 const formatdef *f;
845{
846 unsigned long x;
847 int i;
848 if (get_ulong(v, &x) < 0)
849 return -1;
850 i = f->size;
851 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000852 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000853 x >>= 8;
854 } while (--i > 0);
855 return 0;
856}
857
Guido van Rossum74679b41997-01-02 22:21:36 +0000858static int
859lp_float(p, v, f)
860 char *p;
861 PyObject *v;
862 const formatdef *f;
863{
864 double x = PyFloat_AsDouble(v);
865 if (x == -1 && PyErr_Occurred()) {
866 PyErr_SetString(StructError,
867 "required argument is not a float");
868 return -1;
869 }
870 return pack_float(x, p+3, -1);
871}
872
873static int
874lp_double(p, v, f)
875 char *p;
876 PyObject *v;
877 const formatdef *f;
878{
879 double x = PyFloat_AsDouble(v);
880 if (x == -1 && PyErr_Occurred()) {
881 PyErr_SetString(StructError,
882 "required argument is not a float");
883 return -1;
884 }
885 return pack_double(x, p+7, -1);
886}
887
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000888static formatdef lilendian_table[] = {
889 {'x', 1, 0, NULL},
890 {'b', 1, 0, lu_int, lp_int},
891 {'B', 1, 0, lu_uint, lp_int},
892 {'c', 1, 0, nu_char, np_char},
893 {'s', 1, 0, NULL},
894 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000895 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000896 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000897 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000898 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000899 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000900 {'f', 4, 0, lu_float, lp_float},
901 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000902 {0}
903};
904
905
906static const formatdef *
907whichtable(pfmt)
908 const char **pfmt;
909{
910 const char *fmt = (*pfmt)++; /* May be backed out of later */
911 switch (*fmt) {
912 case '<':
913 return lilendian_table;
914 case '>':
915 case '!': /* Network byte order is big-endian */
916 return bigendian_table;
917 case '=': { /* Host byte order -- different from native in aligment! */
918 int n = 1;
919 char *p = (char *) &n;
920 if (*p == 1)
921 return lilendian_table;
922 else
923 return bigendian_table;
924 }
925 default:
926 --*pfmt; /* Back out of pointer increment */
927 /* Fall through */
928 case '@':
929 return native_table;
930 }
931}
932
933
934/* Get the table entry for a format code */
935
936static const formatdef *
937getentry(c, f)
938 int c;
939 const formatdef *f;
940{
941 for (; f->format != '\0'; f++) {
942 if (f->format == c) {
943 return f;
944 }
945 }
946 PyErr_SetString(StructError, "bad char in struct format");
947 return NULL;
948}
949
950
Guido van Rossum02975121992-08-17 08:55:12 +0000951/* Align a size according to a format code */
952
953static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000954align(size, c, e)
Guido van Rossum02975121992-08-17 08:55:12 +0000955 int size;
956 int c;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000957 const formatdef *e;
Guido van Rossum02975121992-08-17 08:55:12 +0000958{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000959 if (e->format == c) {
960 if (e->alignment) {
961 size = ((size + e->alignment - 1)
962 / e->alignment)
963 * e->alignment;
964 }
Guido van Rossum02975121992-08-17 08:55:12 +0000965 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000966 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000967}
968
969
970/* calculate the size of a format string */
971
972static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000973calcsize(fmt, f)
974 const char *fmt;
975 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +0000976{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000977 const formatdef *e;
978 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +0000979 char c;
980 int size, num, itemsize, x;
981
982 s = fmt;
983 size = 0;
984 while ((c = *s++) != '\0') {
Guido van Rossume20aef51997-08-26 20:39:54 +0000985 if (isspace(c))
986 continue;
Guido van Rossum02975121992-08-17 08:55:12 +0000987 if ('0' <= c && c <= '9') {
988 num = c - '0';
989 while ('0' <= (c = *s++) && c <= '9') {
990 x = num*10 + (c - '0');
991 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000992 PyErr_SetString(
993 StructError,
994 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +0000995 return -1;
996 }
997 num = x;
998 }
999 if (c == '\0')
1000 break;
1001 }
1002 else
1003 num = 1;
1004
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001005 e = getentry(c, f);
1006 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +00001007 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001008 itemsize = e->size;
1009 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +00001010 x = num * itemsize;
1011 size += x;
1012 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001013 PyErr_SetString(StructError,
1014 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +00001015 return -1;
1016 }
Guido van Rossum02975121992-08-17 08:55:12 +00001017 }
1018
1019 return size;
1020}
1021
1022
1023/* pack(fmt, v1, v2, ...) --> string */
1024
Barry Warsaw30695fa1996-12-12 23:32:31 +00001025static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001026struct_calcsize(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001027 PyObject *self; /* Not used */
1028 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001029{
1030 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001031 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001032 int size;
1033
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001034 if (!PyArg_ParseTuple(args, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001035 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001036 f = whichtable(&fmt);
1037 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001038 if (size < 0)
1039 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001040 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001041}
1042
1043
1044/* pack(fmt, v1, v2, ...) --> string */
1045
Barry Warsaw30695fa1996-12-12 23:32:31 +00001046static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001047struct_pack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001048 PyObject *self; /* Not used */
1049 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001050{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001051 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001052 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001053 char *fmt;
1054 int size, num;
1055 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001056 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001057 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001058
Barry Warsaw30695fa1996-12-12 23:32:31 +00001059 if (args == NULL || !PyTuple_Check(args) ||
1060 (n = PyTuple_Size(args)) < 1)
1061 {
1062 PyErr_BadArgument();
Guido van Rossum02975121992-08-17 08:55:12 +00001063 return NULL;
1064 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001065 format = PyTuple_GetItem(args, 0);
1066 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001067 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001068 f = whichtable(&fmt);
1069 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001070 if (size < 0)
1071 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001072 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001073 if (result == NULL)
1074 return NULL;
1075
1076 s = fmt;
1077 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001078 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001079
1080 while ((c = *s++) != '\0') {
Guido van Rossume20aef51997-08-26 20:39:54 +00001081 if (isspace(c))
1082 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001083 if ('0' <= c && c <= '9') {
1084 num = c - '0';
1085 while ('0' <= (c = *s++) && c <= '9')
1086 num = num*10 + (c - '0');
1087 if (c == '\0')
1088 break;
1089 }
1090 else
1091 num = 1;
1092
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001093 e = getentry(c, f);
1094 if (e == NULL)
1095 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001096 nres = restart + align((int)(res-restart), c, e);
1097 /* Fill padd bytes with zeros */
1098 while (res < nres)
1099 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001100 if (num == 0 && c != 's')
1101 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001102 do {
1103 if (c == 'x') {
1104 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001105 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001106 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001107 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001108 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001109 if (i >= n) {
1110 PyErr_SetString(StructError,
1111 "insufficient arguments to pack");
1112 goto fail;
1113 }
1114 v = PyTuple_GetItem(args, i++);
1115 if (v == NULL)
1116 goto fail;
1117 if (c == 's') {
1118 /* num is string size, not repeat count */
1119 int n;
1120 if (!PyString_Check(v)) {
1121 PyErr_SetString(StructError,
1122 "argument for 's' must be a string");
1123 goto fail;
1124 }
1125 n = PyString_Size(v);
1126 if (n > num)
1127 n = num;
1128 if (n > 0)
1129 memcpy(res, PyString_AsString(v), n);
1130 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001131 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001132 res += num;
1133 break;
1134 }
1135 else {
1136 if (e->pack(res, v, e) < 0)
1137 goto fail;
1138 res += e->size;
1139 }
1140 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001141 }
1142
1143 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001144 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001145 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001146 goto fail;
1147 }
1148
1149 return result;
1150
1151 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001152 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001153 return NULL;
1154}
1155
1156
1157/* unpack(fmt, string) --> (v1, v2, ...) */
1158
Barry Warsaw30695fa1996-12-12 23:32:31 +00001159static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001160struct_unpack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001161 PyObject *self; /* Not used */
1162 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001163{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001164 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001165 char *str, *start, *fmt, *s;
1166 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001167 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001168 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001169
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001170 if (!PyArg_ParseTuple(args, "ss#", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001171 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001172 f = whichtable(&fmt);
1173 size = calcsize(fmt, f);
1174 if (size < 0)
1175 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001176 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001177 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001178 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001179 return NULL;
1180 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001181 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001182 if (res == NULL)
1183 return NULL;
1184 str = start;
1185 s = fmt;
1186 while ((c = *s++) != '\0') {
Guido van Rossume20aef51997-08-26 20:39:54 +00001187 if (isspace(c))
1188 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001189 if ('0' <= c && c <= '9') {
1190 num = c - '0';
1191 while ('0' <= (c = *s++) && c <= '9')
1192 num = num*10 + (c - '0');
1193 if (c == '\0')
1194 break;
1195 }
1196 else
1197 num = 1;
1198
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001199 e = getentry(c, f);
1200 if (e == NULL)
1201 goto fail;
1202 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001203 if (num == 0 && c != 's')
1204 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001205
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001206 do {
1207 if (c == 'x') {
1208 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001209 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001210 }
1211 if (c == 's') {
1212 /* num is string size, not repeat count */
1213 v = PyString_FromStringAndSize(str, num);
1214 if (v == NULL)
1215 goto fail;
1216 str += num;
1217 num = 0;
1218 }
1219 else {
1220 v = e->unpack(str, e);
1221 if (v == NULL)
1222 goto fail;
1223 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001224 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001225 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001226 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001227 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001228 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001229 }
1230
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001231 v = PyList_AsTuple(res);
1232 Py_DECREF(res);
1233 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001234
1235 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001236 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001237 return NULL;
1238}
1239
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001240
Guido van Rossum02975121992-08-17 08:55:12 +00001241/* List of functions */
1242
Barry Warsaw30695fa1996-12-12 23:32:31 +00001243static PyMethodDef struct_methods[] = {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001244 {"calcsize", struct_calcsize, METH_VARARGS},
1245 {"pack", struct_pack, METH_VARARGS},
1246 {"unpack", struct_unpack, METH_VARARGS},
Guido van Rossum02975121992-08-17 08:55:12 +00001247 {NULL, NULL} /* sentinel */
1248};
1249
1250
1251/* Module initialization */
1252
1253void
1254initstruct()
1255{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001256 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001257
1258 /* Create the module and add the functions */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001259 m = Py_InitModule("struct", struct_methods);
Guido van Rossum02975121992-08-17 08:55:12 +00001260
1261 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001262 d = PyModule_GetDict(m);
1263 StructError = PyString_FromString("struct.error");
1264 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001265
1266 /* Check for errors */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001267 if (PyErr_Occurred())
1268 Py_FatalError("can't initialize module struct");
Guido van Rossum02975121992-08-17 08:55:12 +00001269}