blob: 268db00691872cd49a30c2263003d9521c705e1c [file] [log] [blame]
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001/***********************************************************
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Write Python objects to files and read them back.
26 This is intended for writing and reading compiled Python code only;
27 a true persistent storage facility would be much harder, since
28 it would have to take circular links and sharing into account. */
29
30#include "allobjects.h"
Guido van Rossum2807d191992-03-27 17:23:17 +000031#include "modsupport.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000032#include "longintrepr.h"
33#include "compile.h"
34#include "marshal.h"
35
36#include <errno.h>
Guido van Rossum065d71e1991-06-04 20:23:28 +000037extern int errno;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000038
39#define TYPE_NULL '0'
40#define TYPE_NONE 'N'
41#define TYPE_INT 'i'
42#define TYPE_FLOAT 'f'
43#define TYPE_LONG 'l'
44#define TYPE_STRING 's'
45#define TYPE_TUPLE '('
46#define TYPE_LIST '['
47#define TYPE_DICT '{'
48#define TYPE_CODE 'C'
49#define TYPE_UNKNOWN '?'
50
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000051typedef struct {
52 FILE *fp;
53 /* If fp == NULL, the following are valid: */
54 object *str;
55 char *ptr;
56 char *end;
57} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000058
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000059#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
60 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
61 else w_more(c, p)
62
63static void
64w_more(c, p)
65 char c;
66 WFILE *p;
67{
68 int size, newsize;
69 if (p->str == NULL)
70 return; /* An error already occurred */
71 size = getstringsize(p->str);
72 newsize = size + 1024;
73 if (resizestring(&p->str, newsize) != 0) {
74 p->ptr = p->end = NULL;
75 }
76 else {
77 p->ptr = GETSTRINGVALUE((stringobject *)p->str) + size;
78 p->end = GETSTRINGVALUE((stringobject *)p->str) + newsize;
79 *p->ptr++ = c;
80 }
81}
82
83static void
84w_string(s, n, p)
85 char *s;
86 int n;
87 WFILE *p;
88{
89 if (p->fp != NULL) {
90 fwrite(s, 1, n, p->fp);
91 }
92 else {
93 while (--n >= 0) {
94 w_byte(*s, p);
95 s++;
96 }
97 }
98}
99
100static void
101w_short(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000102 int x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000103 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000104{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000105 w_byte( x & 0xff, p);
106 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000107}
108
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000109static void
110w_long(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000111 long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000112 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000113{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000114 w_byte((int)( x & 0xff), p);
115 w_byte((int)((x>> 8) & 0xff), p);
116 w_byte((int)((x>>16) & 0xff), p);
117 w_byte((int)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000118}
119
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000120static void
121w_object(v, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000122 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000123 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000124{
125 long i, n;
126
127 if (v == NULL)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000128 w_byte(TYPE_NULL, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000129 else if (v == None)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000130 w_byte(TYPE_NONE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000131 else if (is_intobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000132 w_byte(TYPE_INT, p);
133 w_long(getintvalue(v), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000134 }
135 else if (is_longobject(v)) {
136 longobject *ob = (longobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000137 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000138 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000139 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000140 if (n < 0)
141 n = -n;
142 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000143 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000144 }
145 else if (is_floatobject(v)) {
146 extern void float_buf_repr PROTO((char *, floatobject *));
147 char buf[256]; /* Plenty to format any double */
148 float_buf_repr(buf, (floatobject *)v);
149 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000150 w_byte(TYPE_FLOAT, p);
151 w_byte((int)n, p);
152 w_string(buf, (int)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000153 }
154 else if (is_stringobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000155 w_byte(TYPE_STRING, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000156 n = getstringsize(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000157 w_long(n, p);
158 w_string(getstringvalue(v), (int)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000159 }
160 else if (is_tupleobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000161 w_byte(TYPE_TUPLE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000162 n = gettuplesize(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000163 w_long(n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000164 for (i = 0; i < n; i++) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000165 w_object(gettupleitem(v, (int)i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000166 }
167 }
168 else if (is_listobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000169 w_byte(TYPE_LIST, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000170 n = getlistsize(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000171 w_long(n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000172 for (i = 0; i < n; i++) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000173 w_object(getlistitem(v, (int)i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000174 }
175 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000176 else if (is_dictobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000177 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000178 /* This one is NULL object terminated! */
179 n = getdictsize(v);
180 for (i = 0; i < n; i++) {
181 object *key, *val;
Guido van Rossum64b45521991-06-07 13:58:22 +0000182 key = getdict2key(v, (int)i);
183 if (key != NULL) {
Guido van Rossumb8813141991-08-16 09:01:55 +0000184 val = dict2lookup(v, key); /* Can't be NULL */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000185 w_object(key, p);
186 w_object(val, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000187 }
188 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000189 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000190 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000191 else if (is_codeobject(v)) {
192 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000193 w_byte(TYPE_CODE, p);
194 w_object((object *)co->co_code, p);
195 w_object(co->co_consts, p);
196 w_object(co->co_names, p);
197 w_object(co->co_filename, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000198 }
199 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000200 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000201 }
202}
203
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000204void
205wr_long(x, fp)
206 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000207 FILE *fp;
208{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000209 WFILE wf;
210 wf.fp = fp;
211 w_long(x, &wf);
212}
213
214void
215wr_object(x, fp)
216 object *x;
217 FILE *fp;
218{
219 WFILE wf;
220 wf.fp = fp;
221 w_object(x, &wf);
222}
223
224typedef WFILE RFILE; /* Same struct with different invariants */
225
226#define r_byte(p) ((p)->fp ? getc((p)->fp) \
227 : ((p)->ptr != (p)->end) ? *(p)->ptr++ : EOF)
228
229static int
230r_string(s, n, p)
231 char *s;
232 int n;
233 RFILE *p;
234{
235 if (p->fp != NULL)
236 return fread(s, 1, n, p->fp);
237 if (p->end - p->ptr < n)
238 n = p->end - p->ptr;
239 memcpy(s, p->ptr, n);
240 p->ptr += n;
241 return n;
242}
243
244static int
245r_short(p)
246 RFILE *p;
247{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000248 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000249 x = r_byte(p);
250 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000251 /* XXX If your short is > 16 bits, add sign-extension here!!! */
252 return x;
253}
254
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000255static long
256r_long(p)
257 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000258{
259 register long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000260 x = r_byte(p);
261 x |= (long)r_byte(p) << 8;
262 x |= (long)r_byte(p) << 16;
263 x |= (long)r_byte(p) << 24;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000264 /* XXX If your long is > 32 bits, add sign-extension here!!! */
265 return x;
266}
267
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000268static object *
269r_object(p)
270 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000271{
272 object *v;
273 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000274 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000275
276 switch (type) {
277
278 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000279 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000280 return NULL;
281
282 case TYPE_NULL:
283 return NULL;
284
285 case TYPE_NONE:
286 INCREF(None);
287 return None;
288
289 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000290 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000291
292 case TYPE_LONG:
293 {
294 int size;
295 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000296 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000297 size = n<0 ? -n : n;
298 ob = alloclongobject(size);
299 if (ob == NULL)
300 return NULL;
301 ob->ob_size = n;
302 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000303 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000304 return (object *)ob;
305 }
306
307 case TYPE_FLOAT:
308 {
Guido van Rossum2807d191992-03-27 17:23:17 +0000309 extern double strtod PROTO((const char *, char **));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000310 char buf[256];
311 double res;
312 char *end;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000313 n = r_byte(p);
314 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000315 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000316 "EOF read where object expected");
317 return NULL;
318 }
319 buf[n] = '\0';
320 errno = 0;
321 res = strtod(buf, &end);
322 if (*end != '\0') {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000323 err_setstr(ValueError, "bad float syntax");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000324 return NULL;
325 }
326 if (errno != 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000327 err_setstr(ValueError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000328 "float constant too large");
329 return NULL;
330 }
331 return newfloatobject(res);
332 }
333
334 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000335 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000336 v = newsizedstringobject((char *)NULL, n);
337 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000338 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000339 DECREF(v);
340 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000341 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000342 "EOF read where object expected");
343 }
344 }
345 return v;
346
347 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000348 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000349 v = newtupleobject((int)n);
350 if (v == NULL)
351 return v;
352 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000353 settupleitem(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000354 return v;
355
356 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000357 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000358 v = newlistobject((int)n);
359 if (v == NULL)
360 return v;
361 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000362 setlistitem(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000363 return v;
364
Guido van Rossum64b45521991-06-07 13:58:22 +0000365 case TYPE_DICT:
366 v = newdictobject();
367 if (v == NULL)
368 return NULL;
369 for (;;) {
370 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000371 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000372 if (key == NULL)
373 break;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000374 val = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000375 dict2insert(v, key, val);
376 DECREF(key);
377 XDECREF(val);
378 }
379 return v;
380
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000381 case TYPE_CODE:
382 {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000383 object *code = r_object(p);
384 object *consts = r_object(p);
385 object *names = r_object(p);
386 object *filename = r_object(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000387 if (!err_occurred()) {
388 v = (object *) newcodeobject(code,
389 consts, names, filename);
390 }
391 else
392 v = NULL;
393 XDECREF(code);
394 XDECREF(consts);
395 XDECREF(names);
396 XDECREF(filename);
397
398 }
399 return v;
400
401 default:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000402 err_setstr(TypeError, "read unknown object");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000403 return NULL;
404
405 }
406}
407
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000408long
409rd_long(fp)
410 FILE *fp;
411{
412 RFILE rf;
413 rf.fp = fp;
414 return r_long(&rf);
415}
416
417object *
418rd_object(fp)
419 FILE *fp;
420{
421 RFILE rf;
422 rf.fp = fp;
423 return r_object(&rf);
424}
425
Guido van Rossum64b45521991-06-07 13:58:22 +0000426/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000427
428static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000429marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000430 object *self;
431 object *args;
432{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000433 WFILE wf;
434 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000435 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000436 if (!getargs(args, "(OO)", &x, &f))
437 return NULL;
438 if (!is_fileobject(f)) {
439 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000440 return NULL;
441 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000442 wf.fp = getfilefile(f);
443 wf.str = NULL;
444 wf.ptr = wf.end = NULL;
445 w_object(x, &wf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000446 INCREF(None);
447 return None;
448}
449
450static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000451marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000452 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000453 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000454{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000455 RFILE rf;
456 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000457 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000458 if (!getargs(args, "O", &f))
459 return NULL;
460 if (!is_fileobject(f)) {
461 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000462 return NULL;
463 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000464 rf.fp = getfilefile(f);
465 rf.str = NULL;
466 rf.ptr = rf.end = NULL;
467 err_clear();
468 v = r_object(&rf);
469 if (err_occurred()) {
470 XDECREF(v);
471 v = NULL;
472 }
473 return v;
474}
475
476static object *
477marshal_dumps(self, args)
478 object *self;
479 object *args;
480{
481 WFILE wf;
482 object *x;
483 if (!getargs(args, "O", &x))
484 return NULL;
485 wf.fp = NULL;
486 wf.str = newsizedstringobject((char *)NULL, 50);
487 if (wf.str == NULL)
488 return NULL;
489 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
490 wf.end = wf.ptr + getstringsize(wf.str);
491 w_object(x, &wf);
492 if (wf.str != NULL)
493 resizestring(&wf.str,
494 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
495 return wf.str;
496}
497
498static object *
499marshal_loads(self, args)
500 object *self;
501 object *args;
502{
503 RFILE rf;
504 object *v;
505 char *s;
506 int n;
507 if (!getargs(args, "s#", &s, &n))
508 return NULL;
509 rf.fp = NULL;
510 rf.str = args;
511 rf.ptr = s;
512 rf.end = s + n;
513 err_clear();
514 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000515 if (err_occurred()) {
516 XDECREF(v);
517 v = NULL;
518 }
519 return v;
520}
521
522static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000523 {"dump", marshal_dump},
524 {"load", marshal_load},
525 {"dumps", marshal_dumps},
526 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000527 {NULL, NULL} /* sentinel */
528};
529
530void
531initmarshal()
532{
533 (void) initmodule("marshal", marshal_methods);
534}