blob: a42f639e67bbd97842be9eaee65e674e3a5edca1 [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>
41
42
43/* Exception */
44
Barry Warsaw30695fa1996-12-12 23:32:31 +000045static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000046
47
48/* Define various structs to figure out the alignments of types */
49
Jack Jansen971e1df1995-02-02 14:29:10 +000050#ifdef __MWERKS__
51/*
52** XXXX We have a problem here. There are no unique alignment rules
53** on the PowerPC mac.
54*/
55#ifdef __powerc
56#pragma options align=mac68k
57#endif
58#endif /* __MWERKS__ */
59
Guido van Rossum02975121992-08-17 08:55:12 +000060typedef struct { char c; short x; } s_short;
61typedef struct { char c; int x; } s_int;
62typedef struct { char c; long x; } s_long;
63typedef struct { char c; float x; } s_float;
64typedef struct { char c; double x; } s_double;
65
66#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
67#define INT_ALIGN (sizeof(s_int) - sizeof(int))
68#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
69#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
70#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
71
Jack Jansen971e1df1995-02-02 14:29:10 +000072#ifdef __powerc
73#pragma options align=reset
74#endif
75
Guido van Rossum02975121992-08-17 08:55:12 +000076
Guido van Rossum60c50611996-12-31 16:29:52 +000077/* Global that will contain 2**<bits-per-long> */
78
79static PyObject *offset = NULL;
80
81
82/* Helper to create 2**<bits-per-long> */
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000083/* XXX This assumes 2's complement arithmetic */
84
85static PyObject *
Guido van Rossum60c50611996-12-31 16:29:52 +000086init_offset()
87{
88 PyObject *result = NULL;
89 PyObject *one = PyLong_FromLong(1L);
90 PyObject *shiftcount = PyLong_FromLong(8 * sizeof(long));
91 if (one == NULL || shiftcount == NULL)
92 goto finally;
93 result = PyNumber_Lshift(one, shiftcount);
94 finally:
95 Py_XDECREF(one);
96 Py_XDECREF(shiftcount);
97 return result;
98}
99
100
101/* Helper to add offset to a number */
102
103static PyObject *
104add_offset(v)
105 PyObject *v;
106{
107 PyObject *result = NULL;
108 if (offset == NULL) {
109 if ((offset = init_offset()) == NULL)
110 goto finally;
111 }
112 result = PyNumber_Add(v, offset);
113 finally:
114 return result;
115}
116
117
118/* Same, but subtracting */
119
120static PyObject *
121sub_offset(v)
122 PyObject *v;
123{
124 PyObject *result = NULL;
125 if (offset == NULL) {
126 if ((offset = init_offset()) == NULL)
127 goto finally;
128 }
129 result = PyNumber_Subtract(v, offset);
130 finally:
131 return result;
132}
133
134
135/* Helper routine to turn a (signed) long into an unsigned long */
136
137static PyObject *
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000138make_ulong(x)
139 long x;
140{
141 PyObject *v = PyLong_FromLong(x);
142 if (x < 0 && v != NULL) {
Guido van Rossum60c50611996-12-31 16:29:52 +0000143 PyObject *w = add_offset(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000144 Py_DECREF(v);
Guido van Rossum60c50611996-12-31 16:29:52 +0000145 return w;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000146 }
147 else
148 return v;
149}
150
151/* Helper routine to get a Python integer and raise the appropriate error
152 if it isn't one */
153
154static int
155get_long(v, p)
156 PyObject *v;
157 long *p;
158{
159 long x = PyInt_AsLong(v);
160 if (x == -1 && PyErr_Occurred()) {
161 if (PyErr_Occurred() == PyExc_TypeError)
162 PyErr_SetString(StructError,
163 "required argument is not an integer");
164 return -1;
165 }
166 *p = x;
167 return 0;
168}
169
170
Guido van Rossum60c50611996-12-31 16:29:52 +0000171/* Same, but handling unsigned long */
172
173static int
174get_ulong(v, p)
175 PyObject *v;
176 unsigned long *p;
177{
178 long x = PyInt_AsLong(v);
179 PyObject *exc;
180 if (x == -1 && (exc = PyErr_Occurred()) != NULL) {
181 if (exc == PyExc_OverflowError) {
182 /* Try again after subtracting offset */
183 PyObject *w;
184 PyErr_Clear();
185 if ((w = sub_offset(v)) == NULL)
186 return -1;
187 x = PyInt_AsLong(w);
188 Py_DECREF(w);
189 if (x != -1 || (exc = PyErr_Occurred()) == NULL)
190 goto okay;
191 }
192 if (exc == PyExc_TypeError)
193 PyErr_SetString(StructError,
194 "required argument is not an integer");
195 else
196 return -1;
197 }
198 okay:
199 *p = x;
200 return 0;
201}
202
203
Guido van Rossum74679b41997-01-02 22:21:36 +0000204/* Floating point helpers */
205
206/* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
207 Point Arithmetic). See the following URL:
208 http://www.psc.edu/general/software/packages/ieee/ieee.html */
209
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000210/* XXX Inf/NaN are not handled quite right (but underflow is!) */
Guido van Rossum74679b41997-01-02 22:21:36 +0000211
212static int
213pack_float(x, p, incr)
214 double x; /* The number to pack */
215 char *p; /* Where to pack the high order byte */
216 int incr; /* 1 for big-endian; -1 for little-endian */
217{
218 int s;
219 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000220 double f;
221 long fbits;
Guido van Rossum74679b41997-01-02 22:21:36 +0000222
223 if (x < 0) {
224 s = 1;
225 x = -x;
226 }
227 else
228 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000229
230 f = frexp(x, &e);
231
232 /* Normalize f to be in the range [1.0, 2.0) */
233 if (0.5 <= f && f < 1.0) {
234 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000235 e--;
236 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000237 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000238 e = 0;
239 }
240 else {
241 PyErr_SetString(PyExc_SystemError,
242 "frexp() result out of range");
243 return -1;
244 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000245
246 if (e >= 128) {
247 /* XXX 128 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000248 PyErr_SetString(PyExc_OverflowError,
249 "float too large to pack with f format");
250 return -1;
251 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000252 else if (e < -126) {
253 /* Gradual underflow */
254 f = ldexp(f, 126 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000255 e = 0;
256 }
Guido van Rossum74679b41997-01-02 22:21:36 +0000257 else {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000258 e += 127;
259 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000260 }
261
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000262 f *= 8388608.0; /* 2**23 */
263 fbits = (long) floor(f + 0.5); /* Round */
264
Guido van Rossum74679b41997-01-02 22:21:36 +0000265 /* First byte */
266 *p = (s<<7) | (e>>1);
267 p += incr;
268
269 /* Second byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000270 *p = ((e&1)<<7) | (fbits>>16);
Guido van Rossum74679b41997-01-02 22:21:36 +0000271 p += incr;
272
273 /* Third byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000274 *p = (fbits>>8) & 0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000275 p += incr;
276
277 /* Fourth byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000278 *p = fbits&0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000279
280 /* Done */
281 return 0;
282}
283
284static int
285pack_double(x, p, incr)
286 double x; /* The number to pack */
287 char *p; /* Where to pack the high order byte */
288 int incr; /* 1 for big-endian; -1 for little-endian */
289{
290 int s;
291 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000292 double f;
Guido van Rossum74679b41997-01-02 22:21:36 +0000293 long fhi, flo;
294
295 if (x < 0) {
296 s = 1;
297 x = -x;
298 }
299 else
300 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000301
302 f = frexp(x, &e);
303
304 /* Normalize f to be in the range [1.0, 2.0) */
305 if (0.5 <= f && f < 1.0) {
306 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000307 e--;
308 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000309 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000310 e = 0;
311 }
312 else {
313 PyErr_SetString(PyExc_SystemError,
314 "frexp() result out of range");
315 return -1;
316 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000317
318 if (e >= 1024) {
319 /* XXX 1024 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000320 PyErr_SetString(PyExc_OverflowError,
321 "float too large to pack with d format");
322 return -1;
323 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000324 else if (e < -1022) {
325 /* Gradual underflow */
326 f = ldexp(f, 1022 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000327 e = 0;
328 }
Guido van Rossum74679b41997-01-02 22:21:36 +0000329 else {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000330 e += 1023;
331 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000332 }
333
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000334 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
335 f *= 268435456.0; /* 2**28 */
336 fhi = (long) floor(f); /* Truncate */
337 f -= (double)fhi;
338 f *= 16777216.0; /* 2**24 */
339 flo = (long) floor(f + 0.5); /* Round */
340
Guido van Rossum74679b41997-01-02 22:21:36 +0000341 /* First byte */
342 *p = (s<<7) | (e>>4);
343 p += incr;
344
345 /* Second byte */
346 *p = ((e&0xF)<<4) | (fhi>>24);
347 p += incr;
348
349 /* Third byte */
350 *p = (fhi>>16) & 0xFF;
351 p += incr;
352
353 /* Fourth byte */
354 *p = (fhi>>8) & 0xFF;
355 p += incr;
356
357 /* Fifth byte */
358 *p = fhi & 0xFF;
359 p += incr;
360
361 /* Sixth byte */
362 *p = (flo>>16) & 0xFF;
363 p += incr;
364
365 /* Seventh byte */
366 *p = (flo>>8) & 0xFF;
367 p += incr;
368
369 /* Eighth byte */
370 *p = flo & 0xFF;
371 p += incr;
372
373 /* Done */
374 return 0;
375}
376
377static PyObject *
378unpack_float(p, incr)
379 char *p; /* Where the high order byte is */
380 int incr; /* 1 for big-endian; -1 for little-endian */
381{
382 int s;
383 int e;
384 long f;
385 double x;
386
387 /* First byte */
388 s = (*p>>7) & 1;
389 e = (*p & 0x7F) << 1;
390 p += incr;
391
392 /* Second byte */
393 e |= (*p>>7) & 1;
394 f = (*p & 0x7F) << 16;
395 p += incr;
396
397 /* Third byte */
398 f |= (*p & 0xFF) << 8;
399 p += incr;
400
401 /* Fourth byte */
402 f |= *p & 0xFF;
403
404 x = (double)f / 8388608.0;
405
406 /* XXX This sadly ignores Inf/NaN issues */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000407 if (e == 0)
408 e = -126;
409 else {
410 x += 1.0;
411 e -= 127;
412 }
413 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000414
415 if (s)
416 x = -x;
417
418 return PyFloat_FromDouble(x);
419}
420
421static PyObject *
422unpack_double(p, incr)
423 char *p; /* Where the high order byte is */
424 int incr; /* 1 for big-endian; -1 for little-endian */
425{
426 int s;
427 int e;
428 long fhi, flo;
429 double x;
430
431 /* First byte */
432 s = (*p>>7) & 1;
433 e = (*p & 0x7F) << 4;
434 p += incr;
435
436 /* Second byte */
437 e |= (*p>>4) & 0xF;
438 fhi = (*p & 0xF) << 24;
439 p += incr;
440
441 /* Third byte */
442 fhi |= (*p & 0xFF) << 16;
443 p += incr;
444
445 /* Fourth byte */
446 fhi |= (*p & 0xFF) << 8;
447 p += incr;
448
449 /* Fifth byte */
450 fhi |= *p & 0xFF;
451 p += incr;
452
453 /* Sixth byte */
454 flo = (*p & 0xFF) << 16;
455 p += incr;
456
457 /* Seventh byte */
458 flo |= (*p & 0xFF) << 8;
459 p += incr;
460
461 /* Eighth byte */
462 flo |= *p & 0xFF;
463 p += incr;
464
465 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
466 x /= 268435456.0; /* 2**28 */
467
468 /* XXX This sadly ignores Inf/NaN */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000469 if (e == 0)
470 e = -1022;
471 else {
472 x += 1.0;
473 e -= 1023;
474 }
475 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000476
477 if (s)
478 x = -x;
479
480 return PyFloat_FromDouble(x);
481}
482
483
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000484/* The translation function for each format character is table driven */
485
486typedef struct _formatdef {
487 char format;
488 int size;
489 int alignment;
490 PyObject* (*unpack) Py_PROTO((const char *,
491 const struct _formatdef *));
492 int (*pack) Py_PROTO((char *,
493 PyObject *,
494 const struct _formatdef *));
495} formatdef;
496
497static PyObject *
498nu_char(p, f)
499 const char *p;
500 const formatdef *f;
501{
502 return PyString_FromStringAndSize(p, 1);
503}
504
505static PyObject *
506nu_byte(p, f)
507 const char *p;
508 const formatdef *f;
509{
510 return PyInt_FromLong((long) *(signed char *)p);
511}
512
513static PyObject *
514nu_ubyte(p, f)
515 const char *p;
516 const formatdef *f;
517{
518 return PyInt_FromLong((long) *(unsigned char *)p);
519}
520
521static PyObject *
522nu_short(p, f)
523 const char *p;
524 const formatdef *f;
525{
526 return PyInt_FromLong((long) *(short *)p);
527}
528
529static PyObject *
530nu_ushort(p, f)
531 const char *p;
532 const formatdef *f;
533{
534 return PyInt_FromLong((long) *(unsigned short *)p);
535}
536
537static PyObject *
538nu_int(p, f)
539 const char *p;
540 const formatdef *f;
541{
542 return PyInt_FromLong((long) *(int *)p);
543}
544
545static PyObject *
546nu_uint(p, f)
547 const char *p;
548 const formatdef *f;
549{
550 unsigned int x = *(unsigned int *)p;
551#if INT_MAX == LONG_MAX
552 return make_ulong((long)x);
553#else
554 return PyInt_FromLong((long)x);
555#endif
556}
557
558static PyObject *
559nu_long(p, f)
560 const char *p;
561 const formatdef *f;
562{
563 return PyInt_FromLong(*(long *)p);
564}
565
566static PyObject *
567nu_ulong(p, f)
568 const char *p;
569 const formatdef *f;
570{
571 return make_ulong(*(long *)p);
572}
573
574static PyObject *
575nu_float(p, f)
576 const char *p;
577 const formatdef *f;
578{
579 float x;
580 memcpy((char *)&x, p, sizeof(float));
581 return PyFloat_FromDouble((double)x);
582}
583
584static PyObject *
585nu_double(p, f)
586 const char *p;
587 const formatdef *f;
588{
589 double x;
590 memcpy((char *)&x, p, sizeof(double));
591 return PyFloat_FromDouble(x);
592}
593
594static int
595np_byte(p, v, f)
596 char *p;
597 PyObject *v;
598 const formatdef *f;
599{
600 long x;
601 if (get_long(v, &x) < 0)
602 return -1;
603 *p = x;
604 return 0;
605}
606
607static int
608np_char(p, v, f)
609 char *p;
610 PyObject *v;
611 const formatdef *f;
612{
613 if (!PyString_Check(v) || PyString_Size(v) != 1) {
614 PyErr_SetString(StructError,
615 "char format require string of length 1");
616 return -1;
617 }
618 *p = *PyString_AsString(v);
619 return 0;
620}
621
622static int
623np_short(p, v, f)
624 char *p;
625 PyObject *v;
626 const formatdef *f;
627{
628 long x;
629 if (get_long(v, &x) < 0)
630 return -1;
631 * (short *)p = x;
632 return 0;
633}
634
635static int
636np_int(p, v, f)
637 char *p;
638 PyObject *v;
639 const formatdef *f;
640{
641 long x;
642 if (get_long(v, &x) < 0)
643 return -1;
644 * (int *)p = x;
645 return 0;
646}
647
648static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000649np_uint(p, v, f)
650 char *p;
651 PyObject *v;
652 const formatdef *f;
653{
654 unsigned long x;
655 if (get_ulong(v, &x) < 0)
656 return -1;
657 * (unsigned int *)p = x;
658 return 0;
659}
660
661static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000662np_long(p, v, f)
663 char *p;
664 PyObject *v;
665 const formatdef *f;
666{
667 long x;
668 if (get_long(v, &x) < 0)
669 return -1;
670 * (long *)p = x;
671 return 0;
672}
673
674static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000675np_ulong(p, v, f)
676 char *p;
677 PyObject *v;
678 const formatdef *f;
679{
680 unsigned long x;
681 if (get_ulong(v, &x) < 0)
682 return -1;
683 * (unsigned long *)p = x;
684 return 0;
685}
686
687static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000688np_float(p, v, f)
689 char *p;
690 PyObject *v;
691 const formatdef *f;
692{
693 float x = (float)PyFloat_AsDouble(v);
694 if (x == -1 && PyErr_Occurred()) {
695 PyErr_SetString(StructError,
696 "required argument is not a float");
697 return -1;
698 }
699 memcpy(p, (char *)&x, sizeof(float));
700 return 0;
701}
702
703static int
704np_double(p, v, f)
705 char *p;
706 PyObject *v;
707 const formatdef *f;
708{
709 double x = PyFloat_AsDouble(v);
710 if (x == -1 && PyErr_Occurred()) {
711 PyErr_SetString(StructError,
712 "required argument is not a float");
713 return -1;
714 }
715 memcpy(p, (char *)&x, sizeof(double));
716 return 0;
717}
718
719static formatdef native_table[] = {
720 {'x', sizeof(char), 0, NULL},
721 {'b', sizeof(char), 0, nu_byte, np_byte},
722 {'B', sizeof(char), 0, nu_ubyte, np_byte},
723 {'c', sizeof(char), 0, nu_char, np_char},
724 {'s', sizeof(char), 0, NULL},
725 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
726 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
727 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000728 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000729 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000730 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000731 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
732 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
733 {0}
734};
735
736static PyObject *
737bu_int(p, f)
738 const char *p;
739 const formatdef *f;
740{
741 long x = 0;
742 int i = f->size;
743 do {
744 x = (x<<8) | (*p++ & 0xFF);
745 } while (--i > 0);
746 i = 8*(sizeof(long) - f->size);
747 if (i) {
748 x <<= i;
749 x >>= i;
750 }
751 return PyInt_FromLong(x);
752}
753
754static PyObject *
755bu_uint(p, f)
756 const char *p;
757 const formatdef *f;
758{
759 long x = 0;
760 int i = f->size;
761 do {
762 x = (x<<8) | (*p++ & 0xFF);
763 } while (--i > 0);
764 if (f->size == sizeof(long))
765 return make_ulong(x);
766 else
767 return PyLong_FromLong(x);
768}
769
Guido van Rossum74679b41997-01-02 22:21:36 +0000770static PyObject *
771bu_float(p, f)
772 const char *p;
773 const formatdef *f;
774{
775 return unpack_float(p, 1);
776}
777
778static PyObject *
779bu_double(p, f)
780 const char *p;
781 const formatdef *f;
782{
783 return unpack_double(p, 1);
784}
785
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000786static int
787bp_int(p, v, f)
788 char *p;
789 PyObject *v;
790 const formatdef *f;
791{
792 long x;
793 int i;
794 if (get_long(v, &x) < 0)
795 return -1;
796 i = f->size;
797 do {
798 p[--i] = x;
799 x >>= 8;
800 } while (i > 0);
801 return 0;
802}
803
Guido van Rossum60c50611996-12-31 16:29:52 +0000804static int
805bp_uint(p, v, f)
806 char *p;
807 PyObject *v;
808 const formatdef *f;
809{
810 unsigned long x;
811 int i;
812 if (get_ulong(v, &x) < 0)
813 return -1;
814 i = f->size;
815 do {
816 p[--i] = x;
817 x >>= 8;
818 } while (i > 0);
819 return 0;
820}
821
Guido van Rossum74679b41997-01-02 22:21:36 +0000822static int
823bp_float(p, v, f)
824 char *p;
825 PyObject *v;
826 const formatdef *f;
827{
828 double x = PyFloat_AsDouble(v);
829 if (x == -1 && PyErr_Occurred()) {
830 PyErr_SetString(StructError,
831 "required argument is not a float");
832 return -1;
833 }
834 return pack_float(x, p, 1);
835}
836
837static int
838bp_double(p, v, f)
839 char *p;
840 PyObject *v;
841 const formatdef *f;
842{
843 double x = PyFloat_AsDouble(v);
844 if (x == -1 && PyErr_Occurred()) {
845 PyErr_SetString(StructError,
846 "required argument is not a float");
847 return -1;
848 }
849 return pack_double(x, p, 1);
850}
851
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000852static formatdef bigendian_table[] = {
853 {'x', 1, 0, NULL},
854 {'b', 1, 0, bu_int, bp_int},
855 {'B', 1, 0, bu_uint, bp_int},
856 {'c', 1, 0, nu_char, np_char},
857 {'s', 1, 0, NULL},
858 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000859 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000860 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000861 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000862 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000863 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000864 {'f', 4, 0, bu_float, bp_float},
865 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000866 {0}
867};
868
869static PyObject *
870lu_int(p, f)
871 const char *p;
872 const formatdef *f;
873{
874 long x = 0;
875 int i = f->size;
876 do {
877 x = (x<<8) | (p[--i] & 0xFF);
878 } while (i > 0);
879 i = 8*(sizeof(long) - f->size);
880 if (i) {
881 x <<= i;
882 x >>= i;
883 }
884 return PyInt_FromLong(x);
885}
886
887static PyObject *
888lu_uint(p, f)
889 const char *p;
890 const formatdef *f;
891{
892 long x = 0;
893 int i = f->size;
894 do {
895 x = (x<<8) | (p[--i] & 0xFF);
896 } while (i > 0);
897 if (f->size == sizeof(long))
898 return make_ulong(x);
899 else
900 return PyLong_FromLong(x);
901}
902
Guido van Rossum74679b41997-01-02 22:21:36 +0000903static PyObject *
904lu_float(p, f)
905 const char *p;
906 const formatdef *f;
907{
908 return unpack_float(p+3, -1);
909}
910
911static PyObject *
912lu_double(p, f)
913 const char *p;
914 const formatdef *f;
915{
916 return unpack_double(p+7, -1);
917}
918
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000919static int
920lp_int(p, v, f)
921 char *p;
922 PyObject *v;
923 const formatdef *f;
924{
925 long x;
926 int i;
927 if (get_long(v, &x) < 0)
928 return -1;
929 i = f->size;
930 do {
931 *p++ = x;
932 x >>= 8;
933 } while (--i > 0);
934 return 0;
935}
936
Guido van Rossum60c50611996-12-31 16:29:52 +0000937static int
938lp_uint(p, v, f)
939 char *p;
940 PyObject *v;
941 const formatdef *f;
942{
943 unsigned long x;
944 int i;
945 if (get_ulong(v, &x) < 0)
946 return -1;
947 i = f->size;
948 do {
949 *p++ = x;
950 x >>= 8;
951 } while (--i > 0);
952 return 0;
953}
954
Guido van Rossum74679b41997-01-02 22:21:36 +0000955static int
956lp_float(p, v, f)
957 char *p;
958 PyObject *v;
959 const formatdef *f;
960{
961 double x = PyFloat_AsDouble(v);
962 if (x == -1 && PyErr_Occurred()) {
963 PyErr_SetString(StructError,
964 "required argument is not a float");
965 return -1;
966 }
967 return pack_float(x, p+3, -1);
968}
969
970static int
971lp_double(p, v, f)
972 char *p;
973 PyObject *v;
974 const formatdef *f;
975{
976 double x = PyFloat_AsDouble(v);
977 if (x == -1 && PyErr_Occurred()) {
978 PyErr_SetString(StructError,
979 "required argument is not a float");
980 return -1;
981 }
982 return pack_double(x, p+7, -1);
983}
984
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000985static formatdef lilendian_table[] = {
986 {'x', 1, 0, NULL},
987 {'b', 1, 0, lu_int, lp_int},
988 {'B', 1, 0, lu_uint, lp_int},
989 {'c', 1, 0, nu_char, np_char},
990 {'s', 1, 0, NULL},
991 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000992 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000993 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000994 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000995 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000996 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000997 {'f', 4, 0, lu_float, lp_float},
998 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000999 {0}
1000};
1001
1002
1003static const formatdef *
1004whichtable(pfmt)
1005 const char **pfmt;
1006{
1007 const char *fmt = (*pfmt)++; /* May be backed out of later */
1008 switch (*fmt) {
1009 case '<':
1010 return lilendian_table;
1011 case '>':
1012 case '!': /* Network byte order is big-endian */
1013 return bigendian_table;
1014 case '=': { /* Host byte order -- different from native in aligment! */
1015 int n = 1;
1016 char *p = (char *) &n;
1017 if (*p == 1)
1018 return lilendian_table;
1019 else
1020 return bigendian_table;
1021 }
1022 default:
1023 --*pfmt; /* Back out of pointer increment */
1024 /* Fall through */
1025 case '@':
1026 return native_table;
1027 }
1028}
1029
1030
1031/* Get the table entry for a format code */
1032
1033static const formatdef *
1034getentry(c, f)
1035 int c;
1036 const formatdef *f;
1037{
1038 for (; f->format != '\0'; f++) {
1039 if (f->format == c) {
1040 return f;
1041 }
1042 }
1043 PyErr_SetString(StructError, "bad char in struct format");
1044 return NULL;
1045}
1046
1047
Guido van Rossum02975121992-08-17 08:55:12 +00001048/* Align a size according to a format code */
1049
1050static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001051align(size, c, e)
Guido van Rossum02975121992-08-17 08:55:12 +00001052 int size;
1053 int c;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001054 const formatdef *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001055{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001056 if (e->format == c) {
1057 if (e->alignment) {
1058 size = ((size + e->alignment - 1)
1059 / e->alignment)
1060 * e->alignment;
1061 }
Guido van Rossum02975121992-08-17 08:55:12 +00001062 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001063 return size;
Guido van Rossum02975121992-08-17 08:55:12 +00001064}
1065
1066
1067/* calculate the size of a format string */
1068
1069static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001070calcsize(fmt, f)
1071 const char *fmt;
1072 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001073{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001074 const formatdef *e;
1075 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +00001076 char c;
1077 int size, num, itemsize, x;
1078
1079 s = fmt;
1080 size = 0;
1081 while ((c = *s++) != '\0') {
1082 if ('0' <= c && c <= '9') {
1083 num = c - '0';
1084 while ('0' <= (c = *s++) && c <= '9') {
1085 x = num*10 + (c - '0');
1086 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001087 PyErr_SetString(
1088 StructError,
1089 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +00001090 return -1;
1091 }
1092 num = x;
1093 }
1094 if (c == '\0')
1095 break;
1096 }
1097 else
1098 num = 1;
1099
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001100 e = getentry(c, f);
1101 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +00001102 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001103 itemsize = e->size;
1104 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +00001105 x = num * itemsize;
1106 size += x;
1107 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001108 PyErr_SetString(StructError,
1109 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +00001110 return -1;
1111 }
Guido van Rossum02975121992-08-17 08:55:12 +00001112 }
1113
1114 return size;
1115}
1116
1117
1118/* pack(fmt, v1, v2, ...) --> string */
1119
Barry Warsaw30695fa1996-12-12 23:32:31 +00001120static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001121struct_calcsize(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001122 PyObject *self; /* Not used */
1123 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001124{
1125 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001126 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001127 int size;
1128
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001129 if (!PyArg_ParseTuple(args, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001130 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001131 f = whichtable(&fmt);
1132 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001133 if (size < 0)
1134 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001135 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001136}
1137
1138
1139/* pack(fmt, v1, v2, ...) --> string */
1140
Barry Warsaw30695fa1996-12-12 23:32:31 +00001141static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001142struct_pack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001143 PyObject *self; /* Not used */
1144 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001145{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001146 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001147 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001148 char *fmt;
1149 int size, num;
1150 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001151 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001152 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001153
Barry Warsaw30695fa1996-12-12 23:32:31 +00001154 if (args == NULL || !PyTuple_Check(args) ||
1155 (n = PyTuple_Size(args)) < 1)
1156 {
1157 PyErr_BadArgument();
Guido van Rossum02975121992-08-17 08:55:12 +00001158 return NULL;
1159 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001160 format = PyTuple_GetItem(args, 0);
1161 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001162 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001163 f = whichtable(&fmt);
1164 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001165 if (size < 0)
1166 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001167 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001168 if (result == NULL)
1169 return NULL;
1170
1171 s = fmt;
1172 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001173 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001174
1175 while ((c = *s++) != '\0') {
1176 if ('0' <= c && c <= '9') {
1177 num = c - '0';
1178 while ('0' <= (c = *s++) && c <= '9')
1179 num = num*10 + (c - '0');
1180 if (c == '\0')
1181 break;
1182 }
1183 else
1184 num = 1;
1185
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001186 e = getentry(c, f);
1187 if (e == NULL)
1188 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001189 nres = restart + align((int)(res-restart), c, e);
1190 /* Fill padd bytes with zeros */
1191 while (res < nres)
1192 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001193 if (num == 0 && c != 's')
1194 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001195 do {
1196 if (c == 'x') {
1197 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001198 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001199 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001200 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001201 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001202 if (i >= n) {
1203 PyErr_SetString(StructError,
1204 "insufficient arguments to pack");
1205 goto fail;
1206 }
1207 v = PyTuple_GetItem(args, i++);
1208 if (v == NULL)
1209 goto fail;
1210 if (c == 's') {
1211 /* num is string size, not repeat count */
1212 int n;
1213 if (!PyString_Check(v)) {
1214 PyErr_SetString(StructError,
1215 "argument for 's' must be a string");
1216 goto fail;
1217 }
1218 n = PyString_Size(v);
1219 if (n > num)
1220 n = num;
1221 if (n > 0)
1222 memcpy(res, PyString_AsString(v), n);
1223 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001224 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001225 res += num;
1226 break;
1227 }
1228 else {
1229 if (e->pack(res, v, e) < 0)
1230 goto fail;
1231 res += e->size;
1232 }
1233 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001234 }
1235
1236 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001237 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001238 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001239 goto fail;
1240 }
1241
1242 return result;
1243
1244 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001245 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001246 return NULL;
1247}
1248
1249
1250/* unpack(fmt, string) --> (v1, v2, ...) */
1251
Barry Warsaw30695fa1996-12-12 23:32:31 +00001252static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001253struct_unpack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001254 PyObject *self; /* Not used */
1255 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001256{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001257 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001258 char *str, *start, *fmt, *s;
1259 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001260 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001261 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001262
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001263 if (!PyArg_ParseTuple(args, "ss#", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001264 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001265 f = whichtable(&fmt);
1266 size = calcsize(fmt, f);
1267 if (size < 0)
1268 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001269 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001270 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001271 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001272 return NULL;
1273 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001274 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001275 if (res == NULL)
1276 return NULL;
1277 str = start;
1278 s = fmt;
1279 while ((c = *s++) != '\0') {
1280 if ('0' <= c && c <= '9') {
1281 num = c - '0';
1282 while ('0' <= (c = *s++) && c <= '9')
1283 num = num*10 + (c - '0');
1284 if (c == '\0')
1285 break;
1286 }
1287 else
1288 num = 1;
1289
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001290 e = getentry(c, f);
1291 if (e == NULL)
1292 goto fail;
1293 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001294 if (num == 0 && c != 's')
1295 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001296
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001297 do {
1298 if (c == 'x') {
1299 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001300 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001301 }
1302 if (c == 's') {
1303 /* num is string size, not repeat count */
1304 v = PyString_FromStringAndSize(str, num);
1305 if (v == NULL)
1306 goto fail;
1307 str += num;
1308 num = 0;
1309 }
1310 else {
1311 v = e->unpack(str, e);
1312 if (v == NULL)
1313 goto fail;
1314 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001315 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001316 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001317 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001318 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001319 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001320 }
1321
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001322 v = PyList_AsTuple(res);
1323 Py_DECREF(res);
1324 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001325
1326 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001327 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001328 return NULL;
1329}
1330
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001331
Guido van Rossum02975121992-08-17 08:55:12 +00001332/* List of functions */
1333
Barry Warsaw30695fa1996-12-12 23:32:31 +00001334static PyMethodDef struct_methods[] = {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001335 {"calcsize", struct_calcsize, METH_VARARGS},
1336 {"pack", struct_pack, METH_VARARGS},
1337 {"unpack", struct_unpack, METH_VARARGS},
Guido van Rossum02975121992-08-17 08:55:12 +00001338 {NULL, NULL} /* sentinel */
1339};
1340
1341
1342/* Module initialization */
1343
1344void
1345initstruct()
1346{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001347 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001348
1349 /* Create the module and add the functions */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001350 m = Py_InitModule("struct", struct_methods);
Guido van Rossum02975121992-08-17 08:55:12 +00001351
1352 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001353 d = PyModule_GetDict(m);
1354 StructError = PyString_FromString("struct.error");
1355 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001356
1357 /* Check for errors */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001358 if (PyErr_Occurred())
1359 Py_FatalError("can't initialize module struct");
Guido van Rossum02975121992-08-17 08:55:12 +00001360}