Improved some error messages for command line processing.
[python/dscho.git] / Modules / structmodule.c
blobaf8f1e53c064ba3b9e718461f98d64450d2e1256
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* struct module -- pack values into and (out of) strings */
34 /* New version supporting byte order, alignment and size options,
35 character strings, and unsigned numbers */
37 static char struct__doc__[] = "\
38 Functions to convert between Python values and C structs.\n\
39 Python strings are used to hold the data representing the C struct\n\
40 and also as format strings to describe the layout of data in the C struct.\n\
41 \n\
42 The optional first format char indicates byte ordering and alignment:\n\
43 @: native w/native alignment(default)\n\
44 =: native w/standard alignment\n\
45 <: little-endian, std. alignment\n\
46 >: big-endian, std. alignment\n\
47 !: network, std (same as >)\n\
48 \n\
49 The remaining chars indicate types of args and must match exactly;\n\
50 these can be preceded by a decimal repeat count:\n\
51 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
52 h:short; H:unsigned short; i:int; I:unsigned int;\n\
53 l:long; L:unsigned long; f:float; d:double.\n\
54 Special cases (preceding decimal count indicates length):\n\
55 s:string (array of char); p: pascal string (w. count byte).\n\
56 Whitespace between formats is ignored.\n\
57 \n\
58 The variable struct.error is an exception raised on errors.";
60 #include "Python.h"
61 #include "mymath.h"
63 #include <limits.h>
64 #include <ctype.h>
67 /* Exception */
69 static PyObject *StructError;
72 /* Define various structs to figure out the alignments of types */
74 #ifdef __MWERKS__
76 ** XXXX We have a problem here. There are no unique alignment rules
77 ** on the PowerPC mac.
79 #ifdef __powerc
80 #pragma options align=mac68k
81 #endif
82 #endif /* __MWERKS__ */
84 typedef struct { char c; short x; } s_short;
85 typedef struct { char c; int x; } s_int;
86 typedef struct { char c; long x; } s_long;
87 typedef struct { char c; float x; } s_float;
88 typedef struct { char c; double x; } s_double;
90 #define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
91 #define INT_ALIGN (sizeof(s_int) - sizeof(int))
92 #define LONG_ALIGN (sizeof(s_long) - sizeof(long))
93 #define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
94 #define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
96 #ifdef __powerc
97 #pragma options align=reset
98 #endif
100 /* Helper routine to get a Python integer and raise the appropriate error
101 if it isn't one */
103 static int
104 get_long(v, p)
105 PyObject *v;
106 long *p;
108 long x = PyInt_AsLong(v);
109 if (x == -1 && PyErr_Occurred()) {
110 if (PyErr_ExceptionMatches(PyExc_TypeError))
111 PyErr_SetString(StructError,
112 "required argument is not an integer");
113 return -1;
115 *p = x;
116 return 0;
120 /* Same, but handling unsigned long */
122 static int
123 get_ulong(v, p)
124 PyObject *v;
125 unsigned long *p;
127 if (PyLong_Check(v)) {
128 unsigned long x = PyLong_AsUnsignedLong(v);
129 if (x == (unsigned long)(-1) && PyErr_Occurred())
130 return -1;
131 *p = x;
132 return 0;
134 else {
135 return get_long(v, (long *)p);
140 /* Floating point helpers */
142 /* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
143 Point Arithmetic). See the following URL:
144 http://www.psc.edu/general/software/packages/ieee/ieee.html */
146 /* XXX Inf/NaN are not handled quite right (but underflow is!) */
148 static int
149 pack_float(x, p, incr)
150 double x; /* The number to pack */
151 char *p; /* Where to pack the high order byte */
152 int incr; /* 1 for big-endian; -1 for little-endian */
154 int s;
155 int e;
156 double f;
157 long fbits;
159 if (x < 0) {
160 s = 1;
161 x = -x;
163 else
164 s = 0;
166 f = frexp(x, &e);
168 /* Normalize f to be in the range [1.0, 2.0) */
169 if (0.5 <= f && f < 1.0) {
170 f *= 2.0;
171 e--;
173 else if (f == 0.0) {
174 e = 0;
176 else {
177 PyErr_SetString(PyExc_SystemError,
178 "frexp() result out of range");
179 return -1;
182 if (e >= 128) {
183 /* XXX 128 itself is reserved for Inf/NaN */
184 PyErr_SetString(PyExc_OverflowError,
185 "float too large to pack with f format");
186 return -1;
188 else if (e < -126) {
189 /* Gradual underflow */
190 f = ldexp(f, 126 + e);
191 e = 0;
193 else if (!(e == 0 && f == 0.0)) {
194 e += 127;
195 f -= 1.0; /* Get rid of leading 1 */
198 f *= 8388608.0; /* 2**23 */
199 fbits = (long) floor(f + 0.5); /* Round */
201 /* First byte */
202 *p = (s<<7) | (e>>1);
203 p += incr;
205 /* Second byte */
206 *p = (char) (((e&1)<<7) | (fbits>>16));
207 p += incr;
209 /* Third byte */
210 *p = (fbits>>8) & 0xFF;
211 p += incr;
213 /* Fourth byte */
214 *p = fbits&0xFF;
216 /* Done */
217 return 0;
220 static int
221 pack_double(x, p, incr)
222 double x; /* The number to pack */
223 char *p; /* Where to pack the high order byte */
224 int incr; /* 1 for big-endian; -1 for little-endian */
226 int s;
227 int e;
228 double f;
229 long fhi, flo;
231 if (x < 0) {
232 s = 1;
233 x = -x;
235 else
236 s = 0;
238 f = frexp(x, &e);
240 /* Normalize f to be in the range [1.0, 2.0) */
241 if (0.5 <= f && f < 1.0) {
242 f *= 2.0;
243 e--;
245 else if (f == 0.0) {
246 e = 0;
248 else {
249 PyErr_SetString(PyExc_SystemError,
250 "frexp() result out of range");
251 return -1;
254 if (e >= 1024) {
255 /* XXX 1024 itself is reserved for Inf/NaN */
256 PyErr_SetString(PyExc_OverflowError,
257 "float too large to pack with d format");
258 return -1;
260 else if (e < -1022) {
261 /* Gradual underflow */
262 f = ldexp(f, 1022 + e);
263 e = 0;
265 else if (!(e == 0 && f == 0.0)) {
266 e += 1023;
267 f -= 1.0; /* Get rid of leading 1 */
270 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
271 f *= 268435456.0; /* 2**28 */
272 fhi = (long) floor(f); /* Truncate */
273 f -= (double)fhi;
274 f *= 16777216.0; /* 2**24 */
275 flo = (long) floor(f + 0.5); /* Round */
277 /* First byte */
278 *p = (s<<7) | (e>>4);
279 p += incr;
281 /* Second byte */
282 *p = (char) (((e&0xF)<<4) | (fhi>>24));
283 p += incr;
285 /* Third byte */
286 *p = (fhi>>16) & 0xFF;
287 p += incr;
289 /* Fourth byte */
290 *p = (fhi>>8) & 0xFF;
291 p += incr;
293 /* Fifth byte */
294 *p = fhi & 0xFF;
295 p += incr;
297 /* Sixth byte */
298 *p = (flo>>16) & 0xFF;
299 p += incr;
301 /* Seventh byte */
302 *p = (flo>>8) & 0xFF;
303 p += incr;
305 /* Eighth byte */
306 *p = flo & 0xFF;
307 p += incr;
309 /* Done */
310 return 0;
313 static PyObject *
314 unpack_float(p, incr)
315 char *p; /* Where the high order byte is */
316 int incr; /* 1 for big-endian; -1 for little-endian */
318 int s;
319 int e;
320 long f;
321 double x;
323 /* First byte */
324 s = (*p>>7) & 1;
325 e = (*p & 0x7F) << 1;
326 p += incr;
328 /* Second byte */
329 e |= (*p>>7) & 1;
330 f = (*p & 0x7F) << 16;
331 p += incr;
333 /* Third byte */
334 f |= (*p & 0xFF) << 8;
335 p += incr;
337 /* Fourth byte */
338 f |= *p & 0xFF;
340 x = (double)f / 8388608.0;
342 /* XXX This sadly ignores Inf/NaN issues */
343 if (e == 0)
344 e = -126;
345 else {
346 x += 1.0;
347 e -= 127;
349 x = ldexp(x, e);
351 if (s)
352 x = -x;
354 return PyFloat_FromDouble(x);
357 static PyObject *
358 unpack_double(p, incr)
359 char *p; /* Where the high order byte is */
360 int incr; /* 1 for big-endian; -1 for little-endian */
362 int s;
363 int e;
364 long fhi, flo;
365 double x;
367 /* First byte */
368 s = (*p>>7) & 1;
369 e = (*p & 0x7F) << 4;
370 p += incr;
372 /* Second byte */
373 e |= (*p>>4) & 0xF;
374 fhi = (*p & 0xF) << 24;
375 p += incr;
377 /* Third byte */
378 fhi |= (*p & 0xFF) << 16;
379 p += incr;
381 /* Fourth byte */
382 fhi |= (*p & 0xFF) << 8;
383 p += incr;
385 /* Fifth byte */
386 fhi |= *p & 0xFF;
387 p += incr;
389 /* Sixth byte */
390 flo = (*p & 0xFF) << 16;
391 p += incr;
393 /* Seventh byte */
394 flo |= (*p & 0xFF) << 8;
395 p += incr;
397 /* Eighth byte */
398 flo |= *p & 0xFF;
399 p += incr;
401 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
402 x /= 268435456.0; /* 2**28 */
404 /* XXX This sadly ignores Inf/NaN */
405 if (e == 0)
406 e = -1022;
407 else {
408 x += 1.0;
409 e -= 1023;
411 x = ldexp(x, e);
413 if (s)
414 x = -x;
416 return PyFloat_FromDouble(x);
420 /* The translation function for each format character is table driven */
422 typedef struct _formatdef {
423 char format;
424 int size;
425 int alignment;
426 PyObject* (*unpack) Py_PROTO((const char *,
427 const struct _formatdef *));
428 int (*pack) Py_PROTO((char *,
429 PyObject *,
430 const struct _formatdef *));
431 } formatdef;
433 static PyObject *
434 nu_char(p, f)
435 const char *p;
436 const formatdef *f;
438 return PyString_FromStringAndSize(p, 1);
441 static PyObject *
442 nu_byte(p, f)
443 const char *p;
444 const formatdef *f;
446 return PyInt_FromLong((long) *(signed char *)p);
449 static PyObject *
450 nu_ubyte(p, f)
451 const char *p;
452 const formatdef *f;
454 return PyInt_FromLong((long) *(unsigned char *)p);
457 static PyObject *
458 nu_short(p, f)
459 const char *p;
460 const formatdef *f;
462 return PyInt_FromLong((long) *(short *)p);
465 static PyObject *
466 nu_ushort(p, f)
467 const char *p;
468 const formatdef *f;
470 return PyInt_FromLong((long) *(unsigned short *)p);
473 static PyObject *
474 nu_int(p, f)
475 const char *p;
476 const formatdef *f;
478 return PyInt_FromLong((long) *(int *)p);
481 static PyObject *
482 nu_uint(p, f)
483 const char *p;
484 const formatdef *f;
486 unsigned int x = *(unsigned int *)p;
487 return PyLong_FromUnsignedLong((unsigned long)x);
490 static PyObject *
491 nu_long(p, f)
492 const char *p;
493 const formatdef *f;
495 return PyInt_FromLong(*(long *)p);
498 static PyObject *
499 nu_ulong(p, f)
500 const char *p;
501 const formatdef *f;
503 return PyLong_FromUnsignedLong(*(unsigned long *)p);
506 static PyObject *
507 nu_float(p, f)
508 const char *p;
509 const formatdef *f;
511 float x;
512 memcpy((char *)&x, p, sizeof(float));
513 return PyFloat_FromDouble((double)x);
516 static PyObject *
517 nu_double(p, f)
518 const char *p;
519 const formatdef *f;
521 double x;
522 memcpy((char *)&x, p, sizeof(double));
523 return PyFloat_FromDouble(x);
526 static int
527 np_byte(p, v, f)
528 char *p;
529 PyObject *v;
530 const formatdef *f;
532 long x;
533 if (get_long(v, &x) < 0)
534 return -1;
535 *p = (char)x;
536 return 0;
539 static int
540 np_char(p, v, f)
541 char *p;
542 PyObject *v;
543 const formatdef *f;
545 if (!PyString_Check(v) || PyString_Size(v) != 1) {
546 PyErr_SetString(StructError,
547 "char format require string of length 1");
548 return -1;
550 *p = *PyString_AsString(v);
551 return 0;
554 static int
555 np_short(p, v, f)
556 char *p;
557 PyObject *v;
558 const formatdef *f;
560 long x;
561 if (get_long(v, &x) < 0)
562 return -1;
563 * (short *)p = (short)x;
564 return 0;
567 static int
568 np_int(p, v, f)
569 char *p;
570 PyObject *v;
571 const formatdef *f;
573 long x;
574 if (get_long(v, &x) < 0)
575 return -1;
576 * (int *)p = x;
577 return 0;
580 static int
581 np_uint(p, v, f)
582 char *p;
583 PyObject *v;
584 const formatdef *f;
586 unsigned long x;
587 if (get_ulong(v, &x) < 0)
588 return -1;
589 * (unsigned int *)p = x;
590 return 0;
593 static int
594 np_long(p, v, f)
595 char *p;
596 PyObject *v;
597 const formatdef *f;
599 long x;
600 if (get_long(v, &x) < 0)
601 return -1;
602 * (long *)p = x;
603 return 0;
606 static int
607 np_ulong(p, v, f)
608 char *p;
609 PyObject *v;
610 const formatdef *f;
612 unsigned long x;
613 if (get_ulong(v, &x) < 0)
614 return -1;
615 * (unsigned long *)p = x;
616 return 0;
619 static int
620 np_float(p, v, f)
621 char *p;
622 PyObject *v;
623 const formatdef *f;
625 float x = (float)PyFloat_AsDouble(v);
626 if (x == -1 && PyErr_Occurred()) {
627 PyErr_SetString(StructError,
628 "required argument is not a float");
629 return -1;
631 memcpy(p, (char *)&x, sizeof(float));
632 return 0;
635 static int
636 np_double(p, v, f)
637 char *p;
638 PyObject *v;
639 const formatdef *f;
641 double x = PyFloat_AsDouble(v);
642 if (x == -1 && PyErr_Occurred()) {
643 PyErr_SetString(StructError,
644 "required argument is not a float");
645 return -1;
647 memcpy(p, (char *)&x, sizeof(double));
648 return 0;
651 static formatdef native_table[] = {
652 {'x', sizeof(char), 0, NULL},
653 {'b', sizeof(char), 0, nu_byte, np_byte},
654 {'B', sizeof(char), 0, nu_ubyte, np_byte},
655 {'c', sizeof(char), 0, nu_char, np_char},
656 {'s', sizeof(char), 0, NULL},
657 {'p', sizeof(char), 0, NULL},
658 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
659 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
660 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
661 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
662 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
663 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
664 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
665 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
669 static PyObject *
670 bu_int(p, f)
671 const char *p;
672 const formatdef *f;
674 long x = 0;
675 int i = f->size;
676 do {
677 x = (x<<8) | (*p++ & 0xFF);
678 } while (--i > 0);
679 i = 8*(sizeof(long) - f->size);
680 if (i) {
681 x <<= i;
682 x >>= i;
684 return PyInt_FromLong(x);
687 static PyObject *
688 bu_uint(p, f)
689 const char *p;
690 const formatdef *f;
692 unsigned long x = 0;
693 int i = f->size;
694 do {
695 x = (x<<8) | (*p++ & 0xFF);
696 } while (--i > 0);
697 if (f->size >= 4)
698 return PyLong_FromUnsignedLong(x);
699 else
700 return PyInt_FromLong((long)x);
703 static PyObject *
704 bu_float(p, f)
705 const char *p;
706 const formatdef *f;
708 return unpack_float(p, 1);
711 static PyObject *
712 bu_double(p, f)
713 const char *p;
714 const formatdef *f;
716 return unpack_double(p, 1);
719 static int
720 bp_int(p, v, f)
721 char *p;
722 PyObject *v;
723 const formatdef *f;
725 long x;
726 int i;
727 if (get_long(v, &x) < 0)
728 return -1;
729 i = f->size;
730 do {
731 p[--i] = (char)x;
732 x >>= 8;
733 } while (i > 0);
734 return 0;
737 static int
738 bp_uint(p, v, f)
739 char *p;
740 PyObject *v;
741 const formatdef *f;
743 unsigned long x;
744 int i;
745 if (get_ulong(v, &x) < 0)
746 return -1;
747 i = f->size;
748 do {
749 p[--i] = (char)x;
750 x >>= 8;
751 } while (i > 0);
752 return 0;
755 static int
756 bp_float(p, v, f)
757 char *p;
758 PyObject *v;
759 const formatdef *f;
761 double x = PyFloat_AsDouble(v);
762 if (x == -1 && PyErr_Occurred()) {
763 PyErr_SetString(StructError,
764 "required argument is not a float");
765 return -1;
767 return pack_float(x, p, 1);
770 static int
771 bp_double(p, v, f)
772 char *p;
773 PyObject *v;
774 const formatdef *f;
776 double x = PyFloat_AsDouble(v);
777 if (x == -1 && PyErr_Occurred()) {
778 PyErr_SetString(StructError,
779 "required argument is not a float");
780 return -1;
782 return pack_double(x, p, 1);
785 static formatdef bigendian_table[] = {
786 {'x', 1, 0, NULL},
787 {'b', 1, 0, bu_int, bp_int},
788 {'B', 1, 0, bu_uint, bp_int},
789 {'c', 1, 0, nu_char, np_char},
790 {'s', 1, 0, NULL},
791 {'p', 1, 0, NULL},
792 {'h', 2, 0, bu_int, bp_int},
793 {'H', 2, 0, bu_uint, bp_uint},
794 {'i', 4, 0, bu_int, bp_int},
795 {'I', 4, 0, bu_uint, bp_uint},
796 {'l', 4, 0, bu_int, bp_int},
797 {'L', 4, 0, bu_uint, bp_uint},
798 {'f', 4, 0, bu_float, bp_float},
799 {'d', 8, 0, bu_double, bp_double},
803 static PyObject *
804 lu_int(p, f)
805 const char *p;
806 const formatdef *f;
808 long x = 0;
809 int i = f->size;
810 do {
811 x = (x<<8) | (p[--i] & 0xFF);
812 } while (i > 0);
813 i = 8*(sizeof(long) - f->size);
814 if (i) {
815 x <<= i;
816 x >>= i;
818 return PyInt_FromLong(x);
821 static PyObject *
822 lu_uint(p, f)
823 const char *p;
824 const formatdef *f;
826 unsigned long x = 0;
827 int i = f->size;
828 do {
829 x = (x<<8) | (p[--i] & 0xFF);
830 } while (i > 0);
831 if (f->size >= 4)
832 return PyLong_FromUnsignedLong(x);
833 else
834 return PyInt_FromLong((long)x);
837 static PyObject *
838 lu_float(p, f)
839 const char *p;
840 const formatdef *f;
842 return unpack_float(p+3, -1);
845 static PyObject *
846 lu_double(p, f)
847 const char *p;
848 const formatdef *f;
850 return unpack_double(p+7, -1);
853 static int
854 lp_int(p, v, f)
855 char *p;
856 PyObject *v;
857 const formatdef *f;
859 long x;
860 int i;
861 if (get_long(v, &x) < 0)
862 return -1;
863 i = f->size;
864 do {
865 *p++ = (char)x;
866 x >>= 8;
867 } while (--i > 0);
868 return 0;
871 static int
872 lp_uint(p, v, f)
873 char *p;
874 PyObject *v;
875 const formatdef *f;
877 unsigned long x;
878 int i;
879 if (get_ulong(v, &x) < 0)
880 return -1;
881 i = f->size;
882 do {
883 *p++ = (char)x;
884 x >>= 8;
885 } while (--i > 0);
886 return 0;
889 static int
890 lp_float(p, v, f)
891 char *p;
892 PyObject *v;
893 const formatdef *f;
895 double x = PyFloat_AsDouble(v);
896 if (x == -1 && PyErr_Occurred()) {
897 PyErr_SetString(StructError,
898 "required argument is not a float");
899 return -1;
901 return pack_float(x, p+3, -1);
904 static int
905 lp_double(p, v, f)
906 char *p;
907 PyObject *v;
908 const formatdef *f;
910 double x = PyFloat_AsDouble(v);
911 if (x == -1 && PyErr_Occurred()) {
912 PyErr_SetString(StructError,
913 "required argument is not a float");
914 return -1;
916 return pack_double(x, p+7, -1);
919 static formatdef lilendian_table[] = {
920 {'x', 1, 0, NULL},
921 {'b', 1, 0, lu_int, lp_int},
922 {'B', 1, 0, lu_uint, lp_int},
923 {'c', 1, 0, nu_char, np_char},
924 {'s', 1, 0, NULL},
925 {'p', 1, 0, NULL},
926 {'h', 2, 0, lu_int, lp_int},
927 {'H', 2, 0, lu_uint, lp_uint},
928 {'i', 4, 0, lu_int, lp_int},
929 {'I', 4, 0, lu_uint, lp_uint},
930 {'l', 4, 0, lu_int, lp_int},
931 {'L', 4, 0, lu_uint, lp_uint},
932 {'f', 4, 0, lu_float, lp_float},
933 {'d', 8, 0, lu_double, lp_double},
938 static const formatdef *
939 whichtable(pfmt)
940 const char **pfmt;
942 const char *fmt = (*pfmt)++; /* May be backed out of later */
943 switch (*fmt) {
944 case '<':
945 return lilendian_table;
946 case '>':
947 case '!': /* Network byte order is big-endian */
948 return bigendian_table;
949 case '=': { /* Host byte order -- different from native in aligment! */
950 int n = 1;
951 char *p = (char *) &n;
952 if (*p == 1)
953 return lilendian_table;
954 else
955 return bigendian_table;
957 default:
958 --*pfmt; /* Back out of pointer increment */
959 /* Fall through */
960 case '@':
961 return native_table;
966 /* Get the table entry for a format code */
968 static const formatdef *
969 getentry(c, f)
970 int c;
971 const formatdef *f;
973 for (; f->format != '\0'; f++) {
974 if (f->format == c) {
975 return f;
978 PyErr_SetString(StructError, "bad char in struct format");
979 return NULL;
983 /* Align a size according to a format code */
985 static int
986 align(size, c, e)
987 int size;
988 int c;
989 const formatdef *e;
991 if (e->format == c) {
992 if (e->alignment) {
993 size = ((size + e->alignment - 1)
994 / e->alignment)
995 * e->alignment;
998 return size;
1002 /* calculate the size of a format string */
1004 static int
1005 calcsize(fmt, f)
1006 const char *fmt;
1007 const formatdef *f;
1009 const formatdef *e;
1010 const char *s;
1011 char c;
1012 int size, num, itemsize, x;
1014 s = fmt;
1015 size = 0;
1016 while ((c = *s++) != '\0') {
1017 if (isspace((int)c))
1018 continue;
1019 if ('0' <= c && c <= '9') {
1020 num = c - '0';
1021 while ('0' <= (c = *s++) && c <= '9') {
1022 x = num*10 + (c - '0');
1023 if (x/10 != num) {
1024 PyErr_SetString(
1025 StructError,
1026 "overflow in item count");
1027 return -1;
1029 num = x;
1031 if (c == '\0')
1032 break;
1034 else
1035 num = 1;
1037 e = getentry(c, f);
1038 if (e == NULL)
1039 return -1;
1040 itemsize = e->size;
1041 size = align(size, c, e);
1042 x = num * itemsize;
1043 size += x;
1044 if (x/itemsize != num || size < 0) {
1045 PyErr_SetString(StructError,
1046 "total struct size too long");
1047 return -1;
1051 return size;
1055 static char calcsize__doc__[] = "\
1056 calcsize(fmt) -> int\n\
1057 Return size of C struct described by format string fmt.\n\
1058 See struct.__doc__ for more on format strings.";
1060 static PyObject *
1061 struct_calcsize(self, args)
1062 PyObject *self; /* Not used */
1063 PyObject *args;
1065 char *fmt;
1066 const formatdef *f;
1067 int size;
1069 if (!PyArg_ParseTuple(args, "s", &fmt))
1070 return NULL;
1071 f = whichtable(&fmt);
1072 size = calcsize(fmt, f);
1073 if (size < 0)
1074 return NULL;
1075 return PyInt_FromLong((long)size);
1079 static char pack__doc__[] = "\
1080 pack(fmt, v1, v2, ...) -> string\n\
1081 Return string containing values v1, v2, ... packed according to fmt.\n\
1082 See struct.__doc__ for more on format strings.";
1084 static PyObject *
1085 struct_pack(self, args)
1086 PyObject *self; /* Not used */
1087 PyObject *args;
1089 const formatdef *f, *e;
1090 PyObject *format, *result, *v;
1091 char *fmt;
1092 int size, num;
1093 int i, n;
1094 char *s, *res, *restart, *nres;
1095 char c;
1097 if (args == NULL || !PyTuple_Check(args) ||
1098 (n = PyTuple_Size(args)) < 1)
1100 PyErr_BadArgument();
1101 return NULL;
1103 format = PyTuple_GetItem(args, 0);
1104 if (!PyArg_Parse(format, "s", &fmt))
1105 return NULL;
1106 f = whichtable(&fmt);
1107 size = calcsize(fmt, f);
1108 if (size < 0)
1109 return NULL;
1110 result = PyString_FromStringAndSize((char *)NULL, size);
1111 if (result == NULL)
1112 return NULL;
1114 s = fmt;
1115 i = 1;
1116 res = restart = PyString_AsString(result);
1118 while ((c = *s++) != '\0') {
1119 if (isspace((int)c))
1120 continue;
1121 if ('0' <= c && c <= '9') {
1122 num = c - '0';
1123 while ('0' <= (c = *s++) && c <= '9')
1124 num = num*10 + (c - '0');
1125 if (c == '\0')
1126 break;
1128 else
1129 num = 1;
1131 e = getentry(c, f);
1132 if (e == NULL)
1133 goto fail;
1134 nres = restart + align((int)(res-restart), c, e);
1135 /* Fill padd bytes with zeros */
1136 while (res < nres)
1137 *res++ = '\0';
1138 if (num == 0 && c != 's')
1139 continue;
1140 do {
1141 if (c == 'x') {
1142 /* doesn't consume arguments */
1143 memset(res, '\0', num);
1144 res += num;
1145 break;
1147 if (i >= n) {
1148 PyErr_SetString(StructError,
1149 "insufficient arguments to pack");
1150 goto fail;
1152 v = PyTuple_GetItem(args, i++);
1153 if (v == NULL)
1154 goto fail;
1155 if (c == 's') {
1156 /* num is string size, not repeat count */
1157 int n;
1158 if (!PyString_Check(v)) {
1159 PyErr_SetString(StructError,
1160 "argument for 's' must be a string");
1161 goto fail;
1163 n = PyString_Size(v);
1164 if (n > num)
1165 n = num;
1166 if (n > 0)
1167 memcpy(res, PyString_AsString(v), n);
1168 if (n < num)
1169 memset(res+n, '\0', num-n);
1170 res += num;
1171 break;
1173 else if (c == 'p') {
1174 /* num is string size + 1,
1175 to fit in the count byte */
1176 int n;
1177 num--; /* now num is max string size */
1178 if (!PyString_Check(v)) {
1179 PyErr_SetString(StructError,
1180 "argument for 'p' must be a string");
1181 goto fail;
1183 n = PyString_Size(v);
1184 if (n > num)
1185 n = num;
1186 if (n > 0)
1187 memcpy(res+1, PyString_AsString(v), n);
1188 if (n < num)
1189 /* no real need, just to be nice */
1190 memset(res+1+n, '\0', num-n);
1191 *res++ = n; /* store the length byte */
1192 res += num;
1193 break;
1195 else {
1196 if (e->pack(res, v, e) < 0)
1197 goto fail;
1198 res += e->size;
1200 } while (--num > 0);
1203 if (i < n) {
1204 PyErr_SetString(StructError,
1205 "too many arguments for pack format");
1206 goto fail;
1209 return result;
1211 fail:
1212 Py_DECREF(result);
1213 return NULL;
1217 static char unpack__doc__[] = "\
1218 unpack(fmt, string) -> (v1, v2, ...)\n\
1219 Unpack the string, containing packed C structure data, according\n\
1220 to fmt. Requires len(string)==calcsize(fmt).\n\
1221 See struct.__doc__ for more on format strings.";
1223 static PyObject *
1224 struct_unpack(self, args)
1225 PyObject *self; /* Not used */
1226 PyObject *args;
1228 const formatdef *f, *e;
1229 char *str, *start, *fmt, *s;
1230 char c;
1231 int len, size, num;
1232 PyObject *res, *v;
1234 if (!PyArg_ParseTuple(args, "ss#", &fmt, &start, &len))
1235 return NULL;
1236 f = whichtable(&fmt);
1237 size = calcsize(fmt, f);
1238 if (size < 0)
1239 return NULL;
1240 if (size != len) {
1241 PyErr_SetString(StructError,
1242 "unpack str size does not match format");
1243 return NULL;
1245 res = PyList_New(0);
1246 if (res == NULL)
1247 return NULL;
1248 str = start;
1249 s = fmt;
1250 while ((c = *s++) != '\0') {
1251 if (isspace((int)c))
1252 continue;
1253 if ('0' <= c && c <= '9') {
1254 num = c - '0';
1255 while ('0' <= (c = *s++) && c <= '9')
1256 num = num*10 + (c - '0');
1257 if (c == '\0')
1258 break;
1260 else
1261 num = 1;
1263 e = getentry(c, f);
1264 if (e == NULL)
1265 goto fail;
1266 str = start + align((int)(str-start), c, e);
1267 if (num == 0 && c != 's')
1268 continue;
1270 do {
1271 if (c == 'x') {
1272 str += num;
1273 break;
1275 if (c == 's') {
1276 /* num is string size, not repeat count */
1277 v = PyString_FromStringAndSize(str, num);
1278 if (v == NULL)
1279 goto fail;
1280 str += num;
1281 num = 0;
1283 else if (c == 'p') {
1284 /* num is string buffer size,
1285 not repeat count */
1286 int n = *(unsigned char*)str;
1287 /* first byte (unsigned) is string size */
1288 if (n >= num)
1289 n = num-1;
1290 v = PyString_FromStringAndSize(str+1, n);
1291 if (v == NULL)
1292 goto fail;
1293 str += num;
1294 num = 0;
1296 else {
1297 v = e->unpack(str, e);
1298 if (v == NULL)
1299 goto fail;
1300 str += e->size;
1302 if (v == NULL || PyList_Append(res, v) < 0)
1303 goto fail;
1304 Py_DECREF(v);
1305 } while (--num > 0);
1308 v = PyList_AsTuple(res);
1309 Py_DECREF(res);
1310 return v;
1312 fail:
1313 Py_DECREF(res);
1314 return NULL;
1318 /* List of functions */
1320 static PyMethodDef struct_methods[] = {
1321 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1322 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1323 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
1324 {NULL, NULL} /* sentinel */
1328 /* Module initialization */
1330 void
1331 initstruct()
1333 PyObject *m, *d;
1335 /* Create the module and add the functions */
1336 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1337 (PyObject*)NULL, PYTHON_API_VERSION);
1339 /* Add some symbolic constants to the module */
1340 d = PyModule_GetDict(m);
1341 StructError = PyErr_NewException("struct.error", NULL, NULL);
1342 if (StructError == NULL)
1343 return;
1344 PyDict_SetItemString(d, "error", StructError);