blob: ddccc89c23297f8a42967c27d582f8b10c43341f [file] [log] [blame]
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001/***********************************************************
Guido van Rossum6d023c91995-01-04 19:12:13 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumdce2e3d1991-06-04 19:42:30 +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 Rossumdce2e3d1991-06-04 19:42:30 +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 Rossumdce2e3d1991-06-04 19:42:30 +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 Rossumdce2e3d1991-06-04 19:42:30 +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 Rossumdce2e3d1991-06-04 19:42:30 +000029
30******************************************************************/
31
32/* Write Python objects to files and read them back.
33 This is intended for writing and reading compiled Python code only;
34 a true persistent storage facility would be much harder, since
35 it would have to take circular links and sharing into account. */
36
Guido van Rossum79f25d91997-04-29 20:08:16 +000037#include "Python.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000038#include "longintrepr.h"
39#include "compile.h"
40#include "marshal.h"
41
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000042#define TYPE_NULL '0'
43#define TYPE_NONE 'N'
Guido van Rossume449af71996-10-11 16:25:41 +000044#define TYPE_ELLIPSIS '.'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000045#define TYPE_INT 'i'
Guido van Rossumb0c168c1996-12-05 23:15:02 +000046#define TYPE_INT64 'I'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000047#define TYPE_FLOAT 'f'
Guido van Rossum8a5c5d21996-01-12 01:09:56 +000048#define TYPE_COMPLEX 'x'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000049#define TYPE_LONG 'l'
50#define TYPE_STRING 's'
51#define TYPE_TUPLE '('
52#define TYPE_LIST '['
53#define TYPE_DICT '{'
Guido van Rossum681d79a1995-07-18 14:51:37 +000054#define TYPE_CODE 'c'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000055#define TYPE_UNKNOWN '?'
56
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000057typedef struct {
58 FILE *fp;
Guido van Rossumf2150601996-06-26 20:41:23 +000059 int error;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000060 /* If fp == NULL, the following are valid: */
Guido van Rossum79f25d91997-04-29 20:08:16 +000061 PyObject *str;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000062 char *ptr;
63 char *end;
64} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000065
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000066#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
67 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
68 else w_more(c, p)
69
70static void
71w_more(c, p)
72 char c;
73 WFILE *p;
74{
75 int size, newsize;
76 if (p->str == NULL)
77 return; /* An error already occurred */
Guido van Rossum79f25d91997-04-29 20:08:16 +000078 size = PyString_Size(p->str);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000079 newsize = size + 1024;
Guido van Rossum79f25d91997-04-29 20:08:16 +000080 if (_PyString_Resize(&p->str, newsize) != 0) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000081 p->ptr = p->end = NULL;
82 }
83 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +000084 p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
85 p->end =
86 PyString_AS_STRING((PyStringObject *)p->str) + newsize;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000087 *p->ptr++ = c;
88 }
89}
90
91static void
92w_string(s, n, p)
93 char *s;
94 int n;
95 WFILE *p;
96{
97 if (p->fp != NULL) {
98 fwrite(s, 1, n, p->fp);
99 }
100 else {
101 while (--n >= 0) {
102 w_byte(*s, p);
103 s++;
104 }
105 }
106}
107
108static void
109w_short(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000110 int x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000111 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000112{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000113 w_byte( x & 0xff, p);
114 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000115}
116
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000117static void
118w_long(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000119 long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000120 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000121{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000122 w_byte((int)( x & 0xff), p);
123 w_byte((int)((x>> 8) & 0xff), p);
124 w_byte((int)((x>>16) & 0xff), p);
125 w_byte((int)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000126}
127
Guido van Rossumc1547d91996-12-10 15:39:04 +0000128#if SIZEOF_LONG > 4
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000129static void
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000130w_long64(x, p)
131 long x;
132 WFILE *p;
133{
134 w_long(x, p);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000135 w_long(x>>32, p);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000136}
Guido van Rossumc1547d91996-12-10 15:39:04 +0000137#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000138
139static void
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000140w_object(v, p)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000141 PyObject *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000142 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000143{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000144 int i, n;
Guido van Rossumd076c731998-10-07 19:42:25 +0000145 PyBufferProcs *pb;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000146
Guido van Rossum730806d1998-04-10 22:27:42 +0000147 if (v == NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000148 w_byte(TYPE_NULL, p);
Guido van Rossum730806d1998-04-10 22:27:42 +0000149 }
150 else if (v == Py_None) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000151 w_byte(TYPE_NONE, p);
Guido van Rossum730806d1998-04-10 22:27:42 +0000152 }
153 else if (v == Py_Ellipsis) {
154 w_byte(TYPE_ELLIPSIS, p);
155 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000156 else if (PyInt_Check(v)) {
157 long x = PyInt_AS_LONG((PyIntObject *)v);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000158#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000159 long y = x>>31;
160 if (y && y != -1) {
161 w_byte(TYPE_INT64, p);
162 w_long64(x, p);
163 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000164 else
165#endif
166 {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000167 w_byte(TYPE_INT, p);
168 w_long(x, p);
169 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000170 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000171 else if (PyLong_Check(v)) {
172 PyLongObject *ob = (PyLongObject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000173 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000174 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000175 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000176 if (n < 0)
177 n = -n;
178 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000179 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000180 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000181 else if (PyFloat_Check(v)) {
182 extern void PyFloat_AsString
183 Py_PROTO((char *, PyFloatObject *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000184 char buf[256]; /* Plenty to format any double */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000185 PyFloat_AsString(buf, (PyFloatObject *)v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000186 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000187 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000188 w_byte(n, p);
189 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000190 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000191#ifndef WITHOUT_COMPLEX
Guido van Rossum79f25d91997-04-29 20:08:16 +0000192 else if (PyComplex_Check(v)) {
193 extern void PyFloat_AsString
194 Py_PROTO((char *, PyFloatObject *));
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000195 char buf[256]; /* Plenty to format any double */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000196 PyFloatObject *temp;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000197 w_byte(TYPE_COMPLEX, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000198 temp = (PyFloatObject*)PyFloat_FromDouble(
199 PyComplex_RealAsDouble(v));
200 PyFloat_AsString(buf, temp);
201 Py_DECREF(temp);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000202 n = strlen(buf);
203 w_byte(n, p);
204 w_string(buf, n, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000205 temp = (PyFloatObject*)PyFloat_FromDouble(
206 PyComplex_ImagAsDouble(v));
207 PyFloat_AsString(buf, temp);
208 Py_DECREF(temp);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000209 n = strlen(buf);
210 w_byte(n, p);
211 w_string(buf, n, p);
212 }
213#endif
Guido van Rossum79f25d91997-04-29 20:08:16 +0000214 else if (PyString_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000215 w_byte(TYPE_STRING, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000216 n = PyString_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000217 w_long((long)n, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000218 w_string(PyString_AsString(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000219 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000220 else if (PyTuple_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000221 w_byte(TYPE_TUPLE, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000222 n = PyTuple_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000223 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000224 for (i = 0; i < n; i++) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000225 w_object(PyTuple_GET_ITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000226 }
227 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000228 else if (PyList_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000229 w_byte(TYPE_LIST, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000230 n = PyList_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000231 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000232 for (i = 0; i < n; i++) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000233 w_object(PyList_GetItem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000234 }
235 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000236 else if (PyDict_Check(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000237 int pos;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000238 PyObject *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000239 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000240 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000241 pos = 0;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000242 while (PyDict_Next(v, &pos, &key, &value)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000243 w_object(key, p);
244 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000245 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000246 w_object((PyObject *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000247 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000248 else if (PyCode_Check(v)) {
249 PyCodeObject *co = (PyCodeObject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000250 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000251 w_short(co->co_argcount, p);
252 w_short(co->co_nlocals, p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000253 w_short(co->co_stacksize, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000254 w_short(co->co_flags, p);
Guido van Rossumd076c731998-10-07 19:42:25 +0000255 w_object(co->co_code, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000256 w_object(co->co_consts, p);
257 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000258 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000259 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000260 w_object(co->co_name, p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000261 w_short(co->co_firstlineno, p);
262 w_object(co->co_lnotab, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000263 }
Guido van Rossumd076c731998-10-07 19:42:25 +0000264 else if ((pb = v->ob_type->tp_as_buffer) != NULL &&
265 pb->bf_getsegcount != NULL &&
266 pb->bf_getreadbuffer != NULL &&
267 (*pb->bf_getsegcount)(v, NULL) == 1)
268 {
269 /* Write unknown buffer-style objects as a string */
270 char *s;
271 w_byte(TYPE_STRING, p);
272 n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
273 w_long((long)n, p);
274 w_string(s, n, p);
275 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000276 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000277 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000278 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000279 }
280}
281
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000282void
Guido van Rossum79f25d91997-04-29 20:08:16 +0000283PyMarshal_WriteLongToFile(x, fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000284 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000285 FILE *fp;
286{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000287 WFILE wf;
288 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000289 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000290 w_long(x, &wf);
291}
292
293void
Guido van Rossum79f25d91997-04-29 20:08:16 +0000294PyMarshal_WriteObjectToFile(x, fp)
295 PyObject *x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000296 FILE *fp;
297{
298 WFILE wf;
299 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000300 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000301 w_object(x, &wf);
302}
303
304typedef WFILE RFILE; /* Same struct with different invariants */
305
Guido van Rossum8d617a61995-03-09 12:12:11 +0000306#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
307
308#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000309
310static int
311r_string(s, n, p)
312 char *s;
313 int n;
314 RFILE *p;
315{
316 if (p->fp != NULL)
317 return fread(s, 1, n, p->fp);
318 if (p->end - p->ptr < n)
319 n = p->end - p->ptr;
320 memcpy(s, p->ptr, n);
321 p->ptr += n;
322 return n;
323}
324
325static int
326r_short(p)
327 RFILE *p;
328{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000329 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000330 x = r_byte(p);
331 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000332 /* XXX If your short is > 16 bits, add sign-extension here!!! */
333 return x;
334}
335
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000336static long
337r_long(p)
338 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000339{
340 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000341 register FILE *fp = p->fp;
342 if (fp) {
343 x = getc(fp);
344 x |= (long)getc(fp) << 8;
345 x |= (long)getc(fp) << 16;
346 x |= (long)getc(fp) << 24;
347 }
348 else {
349 x = rs_byte(p);
350 x |= (long)rs_byte(p) << 8;
351 x |= (long)rs_byte(p) << 16;
352 x |= (long)rs_byte(p) << 24;
353 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000354#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000355 /* Sign extension for 64-bit machines */
356 x <<= (8*sizeof(long) - 32);
357 x >>= (8*sizeof(long) - 32);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000358#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000359 return x;
360}
361
362static long
363r_long64(p)
364 RFILE *p;
365{
366 register long x;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000367 x = r_long(p);
368#if SIZEOF_LONG > 4
369 x = (x & 0xFFFFFFFF) | (r_long(p) << 32);
370#else
371 if (r_long(p) != 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000372 PyObject *f = PySys_GetObject("stderr");
Guido van Rossumc1547d91996-12-10 15:39:04 +0000373 if (f != NULL)
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000374 (void) PyFile_WriteString(
Guido van Rossumc1547d91996-12-10 15:39:04 +0000375 "Warning: un-marshal 64-bit int in 32-bit mode\n",
376 f);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000377 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000378#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000379 return x;
380}
381
Guido van Rossum79f25d91997-04-29 20:08:16 +0000382static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000383r_object(p)
384 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000385{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000386 PyObject *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000387 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000388 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000389
390 switch (type) {
391
392 case EOF:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000393 PyErr_SetString(PyExc_EOFError,
394 "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000395 return NULL;
396
397 case TYPE_NULL:
398 return NULL;
399
400 case TYPE_NONE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000401 Py_INCREF(Py_None);
402 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000403
Guido van Rossume449af71996-10-11 16:25:41 +0000404 case TYPE_ELLIPSIS:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000405 Py_INCREF(Py_Ellipsis);
Guido van Rossume449af71996-10-11 16:25:41 +0000406 return Py_Ellipsis;
Guido van Rossum8861b741996-07-30 16:49:37 +0000407
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000408 case TYPE_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000409 return PyInt_FromLong(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000410
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000411 case TYPE_INT64:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000412 return PyInt_FromLong(r_long64(p));
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000413
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000414 case TYPE_LONG:
415 {
416 int size;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000417 PyLongObject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000418 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000419 size = n<0 ? -n : n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000420 ob = _PyLong_New(size);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000421 if (ob == NULL)
422 return NULL;
423 ob->ob_size = n;
424 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000425 ob->ob_digit[i] = r_short(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000426 return (PyObject *)ob;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000427 }
428
429 case TYPE_FLOAT:
430 {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000431 extern double atof Py_PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000432 char buf[256];
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000433 double dx;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000434 n = r_byte(p);
435 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000436 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000437 "EOF read where object expected");
438 return NULL;
439 }
440 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000441 PyFPE_START_PROTECT("atof", return 0)
442 dx = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000443 PyFPE_END_PROTECT(dx)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000444 return PyFloat_FromDouble(dx);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000445 }
446
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000447#ifndef WITHOUT_COMPLEX
448 case TYPE_COMPLEX:
449 {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000450 extern double atof Py_PROTO((const char *));
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000451 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000452 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000453 n = r_byte(p);
454 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000455 PyErr_SetString(PyExc_EOFError,
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000456 "EOF read where object expected");
457 return NULL;
458 }
459 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000460 PyFPE_START_PROTECT("atof", return 0)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000461 c.real = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000462 PyFPE_END_PROTECT(c)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000463 n = r_byte(p);
464 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000465 PyErr_SetString(PyExc_EOFError,
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000466 "EOF read where object expected");
467 return NULL;
468 }
469 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000470 PyFPE_START_PROTECT("atof", return 0)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000471 c.imag = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000472 PyFPE_END_PROTECT(c)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000473 return PyComplex_FromCComplex(c);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000474 }
475#endif
476
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000477 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000478 n = r_long(p);
Guido van Rossuma45cb451998-06-08 20:27:29 +0000479 if (n < 0) {
480 PyErr_SetString(PyExc_ValueError, "bad marshal data");
481 return NULL;
482 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000483 v = PyString_FromStringAndSize((char *)NULL, n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000484 if (v != NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000485 if (r_string(PyString_AsString(v), (int)n, p) != n) {
486 Py_DECREF(v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000487 v = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000488 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000489 "EOF read where object expected");
490 }
491 }
492 return v;
493
494 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000495 n = r_long(p);
Guido van Rossuma45cb451998-06-08 20:27:29 +0000496 if (n < 0) {
497 PyErr_SetString(PyExc_ValueError, "bad marshal data");
498 return NULL;
499 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000500 v = PyTuple_New((int)n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000501 if (v == NULL)
502 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000503 for (i = 0; i < n; i++) {
504 v2 = r_object(p);
505 if ( v2 == NULL ) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000506 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000507 v = NULL;
508 break;
509 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000510 PyTuple_SET_ITEM(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000511 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000512 return v;
513
514 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000515 n = r_long(p);
Guido van Rossuma45cb451998-06-08 20:27:29 +0000516 if (n < 0) {
517 PyErr_SetString(PyExc_ValueError, "bad marshal data");
518 return NULL;
519 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000520 v = PyList_New((int)n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000521 if (v == NULL)
522 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000523 for (i = 0; i < n; i++) {
524 v2 = r_object(p);
525 if ( v2 == NULL ) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000526 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000527 v = NULL;
528 break;
529 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000530 PyList_SetItem(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000531 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000532 return v;
533
Guido van Rossum64b45521991-06-07 13:58:22 +0000534 case TYPE_DICT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000535 v = PyDict_New();
Guido van Rossum64b45521991-06-07 13:58:22 +0000536 if (v == NULL)
537 return NULL;
538 for (;;) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000539 PyObject *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000540 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000541 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000542 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000543 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000544 if (val != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000545 PyDict_SetItem(v, key, val);
546 Py_DECREF(key);
547 Py_XDECREF(val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000548 }
549 return v;
550
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000551 case TYPE_CODE:
552 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000553 int argcount = r_short(p);
554 int nlocals = r_short(p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000555 int stacksize = r_short(p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000556 int flags = r_short(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000557 PyObject *code = NULL;
558 PyObject *consts = NULL;
559 PyObject *names = NULL;
560 PyObject *varnames = NULL;
561 PyObject *filename = NULL;
562 PyObject *name = NULL;
Guido van Rossum0f4bbd21997-02-14 21:12:56 +0000563 int firstlineno = 0;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000564 PyObject *lnotab = NULL;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000565
566 code = r_object(p);
567 if (code) consts = r_object(p);
568 if (consts) names = r_object(p);
569 if (names) varnames = r_object(p);
570 if (varnames) filename = r_object(p);
571 if (filename) name = r_object(p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000572 if (name) {
573 firstlineno = r_short(p);
574 lnotab = r_object(p);
575 }
Jack Jansen9513f2c1995-10-27 13:21:28 +0000576
Guido van Rossum79f25d91997-04-29 20:08:16 +0000577 if (!PyErr_Occurred()) {
578 v = (PyObject *) PyCode_New(
Guido van Rossum98a9b311997-01-17 21:07:08 +0000579 argcount, nlocals, stacksize, flags,
Guido van Rossum681d79a1995-07-18 14:51:37 +0000580 code, consts, names, varnames,
Guido van Rossumd031c891997-01-24 03:44:17 +0000581 filename, name, firstlineno, lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000582 }
583 else
584 v = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000585 Py_XDECREF(code);
586 Py_XDECREF(consts);
587 Py_XDECREF(names);
588 Py_XDECREF(varnames);
589 Py_XDECREF(filename);
590 Py_XDECREF(name);
Guido van Rossum6fc06e71997-07-26 23:30:18 +0000591 Py_XDECREF(lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000592
593 }
594 return v;
595
596 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000597 /* Bogus data got written, which isn't ideal.
598 This will let you keep working and recover. */
Guido van Rossuma45cb451998-06-08 20:27:29 +0000599 PyErr_SetString(PyExc_ValueError, "bad marshal data");
600 return NULL;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000601
602 }
603}
604
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000605long
Guido van Rossum79f25d91997-04-29 20:08:16 +0000606PyMarshal_ReadLongFromFile(fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000607 FILE *fp;
608{
609 RFILE rf;
610 rf.fp = fp;
611 return r_long(&rf);
612}
613
Guido van Rossum79f25d91997-04-29 20:08:16 +0000614PyObject *
615PyMarshal_ReadObjectFromFile(fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000616 FILE *fp;
617{
618 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000619 if (PyErr_Occurred()) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000620 fprintf(stderr, "XXX rd_object called with exception set\n");
621 return NULL;
622 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000623 rf.fp = fp;
624 return r_object(&rf);
625}
626
Guido van Rossum79f25d91997-04-29 20:08:16 +0000627PyObject *
628PyMarshal_ReadObjectFromString(str, len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000629 char *str;
630 int len;
631{
632 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000633 if (PyErr_Occurred()) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000634 fprintf(stderr, "XXX rds_object called with exception set\n");
635 return NULL;
636 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000637 rf.fp = NULL;
638 rf.str = NULL;
639 rf.ptr = str;
640 rf.end = str + len;
641 return r_object(&rf);
642}
643
Guido van Rossum79f25d91997-04-29 20:08:16 +0000644PyObject *
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000645PyMarshal_WriteObjectToString(x) /* wrs_object() */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000646 PyObject *x;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000647{
648 WFILE wf;
649 wf.fp = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000650 wf.str = PyString_FromStringAndSize((char *)NULL, 50);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000651 if (wf.str == NULL)
652 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000653 wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
654 wf.end = wf.ptr + PyString_Size(wf.str);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000655 wf.error = 0;
656 w_object(x, &wf);
657 if (wf.str != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000658 _PyString_Resize(&wf.str,
659 (int) (wf.ptr -
660 PyString_AS_STRING((PyStringObject *)wf.str)));
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000661 if (wf.error) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000662 Py_XDECREF(wf.str);
663 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000664 return NULL;
665 }
666 return wf.str;
667}
668
Guido van Rossum64b45521991-06-07 13:58:22 +0000669/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000670
Guido van Rossum79f25d91997-04-29 20:08:16 +0000671static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000672marshal_dump(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000673 PyObject *self;
674 PyObject *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000675{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000676 WFILE wf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000677 PyObject *x;
678 PyObject *f;
679 if (!PyArg_Parse(args, "(OO)", &x, &f))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000680 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000681 if (!PyFile_Check(f)) {
682 PyErr_SetString(PyExc_TypeError,
683 "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000684 return NULL;
685 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000686 wf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000687 wf.str = NULL;
688 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000689 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000690 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000691 if (wf.error) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000692 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
Guido van Rossumf2150601996-06-26 20:41:23 +0000693 return NULL;
694 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000695 Py_INCREF(Py_None);
696 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000697}
698
Guido van Rossum79f25d91997-04-29 20:08:16 +0000699static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000700marshal_load(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000701 PyObject *self;
702 PyObject *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000703{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000704 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000705 PyObject *f;
706 PyObject *v;
707 if (!PyArg_Parse(args, "O", &f))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000708 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000709 if (!PyFile_Check(f)) {
710 PyErr_SetString(PyExc_TypeError,
711 "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000712 return NULL;
713 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000714 rf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000715 rf.str = NULL;
716 rf.ptr = rf.end = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000717 PyErr_Clear();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000718 v = r_object(&rf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000719 if (PyErr_Occurred()) {
720 Py_XDECREF(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000721 v = NULL;
722 }
723 return v;
724}
725
Guido van Rossum79f25d91997-04-29 20:08:16 +0000726static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000727marshal_dumps(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000728 PyObject *self;
729 PyObject *args;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000730{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000731 PyObject *x;
732 if (!PyArg_Parse(args, "O", &x))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000733 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000734 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000735}
736
Guido van Rossum79f25d91997-04-29 20:08:16 +0000737static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000738marshal_loads(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000739 PyObject *self;
740 PyObject *args;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000741{
742 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000743 PyObject *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000744 char *s;
745 int n;
Guido van Rossum5bd893b1998-10-08 01:45:47 +0000746 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000747 return NULL;
748 rf.fp = NULL;
749 rf.str = args;
750 rf.ptr = s;
751 rf.end = s + n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000752 PyErr_Clear();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000753 v = r_object(&rf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000754 if (PyErr_Occurred()) {
755 Py_XDECREF(v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000756 v = NULL;
757 }
758 return v;
759}
760
Guido van Rossum79f25d91997-04-29 20:08:16 +0000761static PyMethodDef marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000762 {"dump", marshal_dump},
763 {"load", marshal_load},
764 {"dumps", marshal_dumps},
765 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000766 {NULL, NULL} /* sentinel */
767};
768
769void
Guido van Rossum79f25d91997-04-29 20:08:16 +0000770PyMarshal_Init()
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000771{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000772 (void) Py_InitModule("marshal", marshal_methods);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000773}