cStringIO.c revision 037b3ee44e7de00b4653d73d4808c0f679a909a7
1
2#include "Python.h"
3#include "import.h"
4#include "cStringIO.h"
5#include "structmember.h"
6
7PyDoc_STRVAR(cStringIO_module_documentation,
8"A simple fast partial StringIO replacement.\n"
9"\n"
10"This module provides a simple useful replacement for\n"
11"the StringIO module that is written in C.  It does not provide the\n"
12"full generality of StringIO, but it provides enough for most\n"
13"applications and is especially useful in conjunction with the\n"
14"pickle module.\n"
15"\n"
16"Usage:\n"
17"\n"
18"  from cStringIO import StringIO\n"
19"\n"
20"  an_output_stream=StringIO()\n"
21"  an_output_stream.write(some_stuff)\n"
22"  ...\n"
23"  value=an_output_stream.getvalue()\n"
24"\n"
25"  an_input_stream=StringIO(a_string)\n"
26"  spam=an_input_stream.readline()\n"
27"  spam=an_input_stream.read(5)\n"
28"  an_input_stream.seek(0)           # OK, start over\n"
29"  spam=an_input_stream.read()       # and read it all\n"
30"  \n"
31"If someone else wants to provide a more complete implementation,\n"
32"go for it. :-)  \n"
33"\n"
34"cStringIO.c,v 1.29 1999/06/15 14:10:27 jim Exp\n");
35
36#define UNLESS(E) if (!(E))
37
38
39/* Declaration for file-like objects that manage data as strings
40
41   The IOobject type should be though of as a common base type for
42   Iobjects, which provide input (read-only) StringIO objects and
43   Oobjects, which provide read-write objects.  Most of the methods
44   depend only on common data.
45*/
46
47typedef struct {
48  PyObject_HEAD
49  char *buf;
50  int pos, string_size;
51} IOobject;
52
53#define IOOOBJECT(O) ((IOobject*)(O))
54
55/* Declarations for objects of type StringO */
56
57typedef struct { /* Subtype of IOobject */
58  PyObject_HEAD
59  char *buf;
60  int pos, string_size;
61
62  int buf_size, softspace;
63} Oobject;
64
65/* Declarations for objects of type StringI */
66
67typedef struct { /* Subtype of IOobject */
68  PyObject_HEAD
69  char *buf;
70  int pos, string_size;
71  /* We store a reference to the object here in order to keep
72     the buffer alive during the lifetime of the Iobject. */
73  PyObject *pbuf;
74} Iobject;
75
76/* IOobject (common) methods */
77
78PyDoc_STRVAR(IO_flush__doc__, "flush(): does nothing.");
79
80static int
81IO__opencheck(IOobject *self) {
82        UNLESS (self->buf) {
83                PyErr_SetString(PyExc_ValueError,
84                                "I/O operation on closed file");
85                return 0;
86        }
87        return 1;
88}
89
90static PyObject *
91IO_get_closed(IOobject *self, void *closure)
92{
93	PyObject *result = Py_False;
94
95	if (self->buf == NULL)
96		result = Py_True;
97	Py_INCREF(result);
98	return result;
99}
100
101static PyGetSetDef file_getsetlist[] = {
102	{"closed", (getter)IO_get_closed, NULL, "True if the file is closed"},
103	{0},
104};
105
106static PyObject *
107IO_flush(IOobject *self, PyObject *unused) {
108
109        UNLESS (IO__opencheck(self)) return NULL;
110
111        Py_INCREF(Py_None);
112        return Py_None;
113}
114
115PyDoc_STRVAR(IO_getval__doc__,
116"getvalue([use_pos]) -- Get the string value."
117"\n"
118"If use_pos is specified and is a true value, then the string returned\n"
119"will include only the text up to the current file position.\n");
120
121static PyObject *
122IO_cgetval(PyObject *self) {
123        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
124        return PyString_FromStringAndSize(((IOobject*)self)->buf,
125                                          ((IOobject*)self)->pos);
126}
127
128static PyObject *
129IO_getval(IOobject *self, PyObject *args) {
130        PyObject *use_pos=Py_None;
131        int s;
132
133        UNLESS (IO__opencheck(self)) return NULL;
134        UNLESS (PyArg_UnpackTuple(args,"getval", 0, 1,&use_pos)) return NULL;
135
136        if (PyObject_IsTrue(use_pos)) {
137                  s=self->pos;
138                  if (s > self->string_size) s=self->string_size;
139        }
140        else
141                  s=self->string_size;
142        return PyString_FromStringAndSize(self->buf, s);
143}
144
145PyDoc_STRVAR(IO_isatty__doc__, "isatty(): always returns 0");
146
147static PyObject *
148IO_isatty(IOobject *self, PyObject *unused) {
149	Py_INCREF(Py_False);
150        return Py_False;
151}
152
153PyDoc_STRVAR(IO_read__doc__,
154"read([s]) -- Read s characters, or the rest of the string");
155
156static int
157IO_cread(PyObject *self, char **output, int  n) {
158        int l;
159
160        UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
161        l = ((IOobject*)self)->string_size - ((IOobject*)self)->pos;
162        if (n < 0 || n > l) {
163                n = l;
164                if (n < 0) n=0;
165        }
166
167        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
168        ((IOobject*)self)->pos += n;
169        return n;
170}
171
172static PyObject *
173IO_read(IOobject *self, PyObject *args) {
174        int n = -1;
175        char *output;
176
177        UNLESS (PyArg_ParseTuple(args, "|i:read", &n)) return NULL;
178
179        if ( (n=IO_cread((PyObject*)self,&output,n)) < 0) return NULL;
180
181        return PyString_FromStringAndSize(output, n);
182}
183
184PyDoc_STRVAR(IO_readline__doc__, "readline() -- Read one line");
185
186static int
187IO_creadline(PyObject *self, char **output) {
188        char *n, *s;
189        int l;
190
191        UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
192
193        for (n = ((IOobject*)self)->buf + ((IOobject*)self)->pos,
194               s = ((IOobject*)self)->buf + ((IOobject*)self)->string_size;
195             n < s && *n != '\n'; n++);
196        if (n < s) n++;
197
198        *output=((IOobject*)self)->buf + ((IOobject*)self)->pos;
199        l = n - ((IOobject*)self)->buf - ((IOobject*)self)->pos;
200        ((IOobject*)self)->pos += l;
201        return l;
202}
203
204static PyObject *
205IO_readline(IOobject *self, PyObject *args) {
206        int n, m=-1;
207        char *output;
208
209        if (args)
210                UNLESS (PyArg_ParseTuple(args, "|i:readline", &m)) return NULL;
211
212        if( (n=IO_creadline((PyObject*)self,&output)) < 0) return NULL;
213        if (m >= 0 && m < n) {
214                m = n - m;
215                n -= m;
216                self->pos -= m;
217        }
218        return PyString_FromStringAndSize(output, n);
219}
220
221PyDoc_STRVAR(IO_readlines__doc__, "readlines() -- Read all lines");
222
223static PyObject *
224IO_readlines(IOobject *self, PyObject *args) {
225	int n;
226	char *output;
227	PyObject *result, *line;
228        int hint = 0, length = 0;
229
230        UNLESS (PyArg_ParseTuple(args, "|i:readlines", &hint)) return NULL;
231
232	result = PyList_New(0);
233	if (!result)
234		return NULL;
235
236	while (1){
237		if ( (n = IO_creadline((PyObject*)self,&output)) < 0)
238                        goto err;
239		if (n == 0)
240			break;
241		line = PyString_FromStringAndSize (output, n);
242		if (!line)
243                        goto err;
244		PyList_Append (result, line);
245		Py_DECREF (line);
246                length += n;
247                if (hint > 0 && length >= hint)
248			break;
249	}
250	return result;
251 err:
252        Py_DECREF(result);
253        return NULL;
254}
255
256PyDoc_STRVAR(IO_reset__doc__,
257"reset() -- Reset the file position to the beginning");
258
259static PyObject *
260IO_reset(IOobject *self, PyObject *unused) {
261
262        UNLESS (IO__opencheck(self)) return NULL;
263
264        self->pos = 0;
265
266        Py_INCREF(Py_None);
267        return Py_None;
268}
269
270PyDoc_STRVAR(IO_tell__doc__, "tell() -- get the current position.");
271
272static PyObject *
273IO_tell(IOobject *self, PyObject *unused) {
274
275        UNLESS (IO__opencheck(self)) return NULL;
276
277        return PyInt_FromLong(self->pos);
278}
279
280PyDoc_STRVAR(IO_truncate__doc__,
281"truncate(): truncate the file at the current position.");
282
283static PyObject *
284IO_truncate(IOobject *self, PyObject *args) {
285        int pos = -1;
286
287        UNLESS (IO__opencheck(self)) return NULL;
288        UNLESS (PyArg_ParseTuple(args, "|i:truncate", &pos)) return NULL;
289        if (pos < 0) pos = self->pos;
290
291        if (self->string_size > pos) self->string_size = pos;
292        self->pos = self->string_size;
293
294        Py_INCREF(Py_None);
295        return Py_None;
296}
297
298static PyObject *
299IO_iternext(Iobject *self)
300{
301	PyObject *next;
302	next = IO_readline((IOobject *)self, NULL);
303	if (!next)
304		return NULL;
305	if (!PyString_GET_SIZE(next)) {
306		Py_DECREF(next);
307		PyErr_SetNone(PyExc_StopIteration);
308		return NULL;
309	}
310	return next;
311}
312
313
314
315
316/* Read-write object methods */
317
318PyDoc_STRVAR(O_seek__doc__,
319"seek(position)       -- set the current position\n"
320"seek(position, mode) -- mode 0: absolute; 1: relative; 2: relative to EOF");
321
322static PyObject *
323O_seek(Oobject *self, PyObject *args) {
324        int position, mode = 0;
325
326        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
327        UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode))
328                return NULL;
329
330        if (mode == 2) {
331                position += self->string_size;
332        }
333        else if (mode == 1) {
334                position += self->pos;
335        }
336
337        if (position > self->buf_size) {
338                  self->buf_size*=2;
339                  if (self->buf_size <= position) self->buf_size=position+1;
340                  UNLESS (self->buf = (char*)
341                          realloc(self->buf,self->buf_size)) {
342                      self->buf_size=self->pos=0;
343                      return PyErr_NoMemory();
344                    }
345          }
346        else if (position < 0) position=0;
347
348        self->pos=position;
349
350        while (--position >= self->string_size) self->buf[position]=0;
351
352        Py_INCREF(Py_None);
353        return Py_None;
354}
355
356PyDoc_STRVAR(O_write__doc__,
357"write(s) -- Write a string to the file"
358"\n\nNote (hack:) writing None resets the buffer");
359
360
361static int
362O_cwrite(PyObject *self, char *c, int  l) {
363        int newl;
364        Oobject *oself;
365
366        UNLESS (IO__opencheck(IOOOBJECT(self))) return -1;
367        oself = (Oobject *)self;
368
369        newl = oself->pos+l;
370        if (newl >= oself->buf_size) {
371            oself->buf_size *= 2;
372            if (oself->buf_size <= newl)
373                    oself->buf_size = newl+1;
374            UNLESS (oself->buf =
375                    (char*)realloc(oself->buf, oself->buf_size)) {
376                    PyErr_SetString(PyExc_MemoryError,"out of memory");
377                    oself->buf_size = oself->pos = 0;
378                    return -1;
379              }
380          }
381
382        memcpy(oself->buf+oself->pos,c,l);
383
384        oself->pos += l;
385
386        if (oself->string_size < oself->pos) {
387            oself->string_size = oself->pos;
388        }
389
390        return l;
391}
392
393static PyObject *
394O_write(Oobject *self, PyObject *args) {
395        char *c;
396        int l;
397
398        UNLESS (PyArg_ParseTuple(args, "t#:write", &c, &l)) return NULL;
399
400        if (O_cwrite((PyObject*)self,c,l) < 0) return NULL;
401
402        Py_INCREF(Py_None);
403        return Py_None;
404}
405
406PyDoc_STRVAR(O_close__doc__, "close(): explicitly release resources held.");
407
408static PyObject *
409O_close(Oobject *self, PyObject *unused) {
410        if (self->buf != NULL) free(self->buf);
411        self->buf = NULL;
412
413        self->pos = self->string_size = self->buf_size = 0;
414
415        Py_INCREF(Py_None);
416        return Py_None;
417}
418
419PyDoc_STRVAR(O_writelines__doc__,
420"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
421"\n"
422"Note that newlines are not added.  The sequence can be any iterable object\n"
423"producing strings. This is equivalent to calling write() for each string.");
424static PyObject *
425O_writelines(Oobject *self, PyObject *args) {
426	PyObject *it, *s;
427
428	it = PyObject_GetIter(args);
429	if (it == NULL)
430		return NULL;
431	while ((s = PyIter_Next(it)) != NULL) {
432		int n;
433		char *c;
434		if (PyString_AsStringAndSize(s, &c, &n) == -1) {
435			Py_DECREF(it);
436			Py_DECREF(s);
437			return NULL;
438		}
439		if (O_cwrite((PyObject *)self, c, n) == -1) {
440			Py_DECREF(it);
441			Py_DECREF(s);
442			return NULL;
443		}
444		Py_DECREF(s);
445	}
446	Py_DECREF(it);
447	Py_RETURN_NONE;
448}
449
450static struct PyMethodDef O_methods[] = {
451  /* Common methods: */
452  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
453  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
454  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
455  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
456  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
457  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
458  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
459  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
460  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
461
462  /* Read-write StringIO specific  methods: */
463  {"close",      (PyCFunction)O_close,      METH_NOARGS,  O_close__doc__},
464  {"seek",       (PyCFunction)O_seek,       METH_VARARGS, O_seek__doc__},
465  {"write",	 (PyCFunction)O_write,      METH_VARARGS, O_write__doc__},
466  {"writelines", (PyCFunction)O_writelines, METH_O,	  O_writelines__doc__},
467  {NULL,	 NULL}		/* sentinel */
468};
469
470static PyMemberDef O_memberlist[] = {
471	{"softspace",	T_INT,	offsetof(Oobject, softspace),	0,
472	 "flag indicating that a space needs to be printed; used by print"},
473	 /* getattr(f, "closed") is implemented without this table */
474	{NULL} /* Sentinel */
475};
476
477static void
478O_dealloc(Oobject *self) {
479        if (self->buf != NULL)
480                free(self->buf);
481        PyObject_Del(self);
482}
483
484PyDoc_STRVAR(Otype__doc__, "Simple type for output to strings.");
485
486static PyTypeObject Otype = {
487  PyObject_HEAD_INIT(NULL)
488  0,	       			/*ob_size*/
489  "cStringIO.StringO",   	/*tp_name*/
490  sizeof(Oobject),       	/*tp_basicsize*/
491  0,	       			/*tp_itemsize*/
492  /* methods */
493  (destructor)O_dealloc,	/*tp_dealloc*/
494  (printfunc)0,			/*tp_print*/
495  0,		 		/*tp_getattr */
496  0,		 		/*tp_setattr */
497  (cmpfunc)0,			/*tp_compare*/
498  (reprfunc)0,			/*tp_repr*/
499  0,				/*tp_as_number*/
500  0,				/*tp_as_sequence*/
501  0,				/*tp_as_mapping*/
502  (hashfunc)0,			/*tp_hash*/
503  (ternaryfunc)0,		/*tp_call*/
504  (reprfunc)0,			/*tp_str*/
505  0,				/*tp_getattro */
506  0,				/*tp_setattro */
507  0,				/*tp_as_buffer */
508  Py_TPFLAGS_DEFAULT,		/*tp_flags*/
509  Otype__doc__, 		/*tp_doc */
510  0,				/*tp_traverse */
511  0,				/*tp_clear */
512  0,				/*tp_richcompare */
513  0,				/*tp_weaklistoffset */
514  PyObject_SelfIter,		/*tp_iter */
515  (iternextfunc)IO_iternext,	/*tp_iternext */
516  O_methods,			/*tp_methods */
517  O_memberlist,			/*tp_members */
518  file_getsetlist,		/*tp_getset */
519};
520
521static PyObject *
522newOobject(int  size) {
523        Oobject *self;
524
525        self = PyObject_New(Oobject, &Otype);
526        if (self == NULL)
527                return NULL;
528        self->pos=0;
529        self->string_size = 0;
530        self->softspace = 0;
531
532        UNLESS (self->buf = (char *)malloc(size)) {
533                  PyErr_SetString(PyExc_MemoryError,"out of memory");
534                  self->buf_size = 0;
535                  return NULL;
536          }
537
538        self->buf_size=size;
539        return (PyObject*)self;
540}
541
542/* End of code for StringO objects */
543/* -------------------------------------------------------- */
544
545static PyObject *
546I_close(Iobject *self, PyObject *unused) {
547        Py_XDECREF(self->pbuf);
548        self->pbuf = NULL;
549        self->buf = NULL;
550
551        self->pos = self->string_size = 0;
552
553        Py_INCREF(Py_None);
554        return Py_None;
555}
556
557static PyObject *
558I_seek(Iobject *self, PyObject *args) {
559        int position, mode = 0;
560
561        UNLESS (IO__opencheck(IOOOBJECT(self))) return NULL;
562        UNLESS (PyArg_ParseTuple(args, "i|i:seek", &position, &mode))
563                return NULL;
564
565        if (mode == 2) position += self->string_size;
566        else if (mode == 1) position += self->pos;
567
568        if (position < 0) position=0;
569
570        self->pos=position;
571
572        Py_INCREF(Py_None);
573        return Py_None;
574}
575
576static struct PyMethodDef I_methods[] = {
577  /* Common methods: */
578  {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},
579  {"getvalue",  (PyCFunction)IO_getval,   METH_VARARGS, IO_getval__doc__},
580  {"isatty",    (PyCFunction)IO_isatty,   METH_NOARGS,  IO_isatty__doc__},
581  {"read",	(PyCFunction)IO_read,     METH_VARARGS, IO_read__doc__},
582  {"readline",	(PyCFunction)IO_readline, METH_VARARGS, IO_readline__doc__},
583  {"readlines",	(PyCFunction)IO_readlines,METH_VARARGS, IO_readlines__doc__},
584  {"reset",	(PyCFunction)IO_reset,	  METH_NOARGS,  IO_reset__doc__},
585  {"tell",      (PyCFunction)IO_tell,     METH_NOARGS,  IO_tell__doc__},
586  {"truncate",  (PyCFunction)IO_truncate, METH_VARARGS, IO_truncate__doc__},
587
588  /* Read-only StringIO specific  methods: */
589  {"close",     (PyCFunction)I_close,    METH_NOARGS,  O_close__doc__},
590  {"seek",      (PyCFunction)I_seek,     METH_VARARGS, O_seek__doc__},
591  {NULL,	NULL}
592};
593
594static void
595I_dealloc(Iobject *self) {
596  Py_XDECREF(self->pbuf);
597  PyObject_Del(self);
598}
599
600
601PyDoc_STRVAR(Itype__doc__,
602"Simple type for treating strings as input file streams");
603
604static PyTypeObject Itype = {
605  PyObject_HEAD_INIT(NULL)
606  0,					/*ob_size*/
607  "cStringIO.StringI",			/*tp_name*/
608  sizeof(Iobject),			/*tp_basicsize*/
609  0,					/*tp_itemsize*/
610  /* methods */
611  (destructor)I_dealloc,		/*tp_dealloc*/
612  (printfunc)0,				/*tp_print*/
613  0,		 			/* tp_getattr */
614  (setattrfunc)0,			/*tp_setattr*/
615  (cmpfunc)0,				/*tp_compare*/
616  (reprfunc)0,				/*tp_repr*/
617  0,					/*tp_as_number*/
618  0,					/*tp_as_sequence*/
619  0,					/*tp_as_mapping*/
620  (hashfunc)0,				/*tp_hash*/
621  (ternaryfunc)0,			/*tp_call*/
622  (reprfunc)0,				/*tp_str*/
623  0,					/* tp_getattro */
624  0,					/* tp_setattro */
625  0,					/* tp_as_buffer */
626  Py_TPFLAGS_DEFAULT,			/* tp_flags */
627  Itype__doc__,				/* tp_doc */
628  0,					/* tp_traverse */
629  0,					/* tp_clear */
630  0,					/* tp_richcompare */
631  0,					/* tp_weaklistoffset */
632  PyObject_SelfIter,			/* tp_iter */
633  (iternextfunc)IO_iternext,		/* tp_iternext */
634  I_methods,				/* tp_methods */
635  0,					/* tp_members */
636  file_getsetlist,			/* tp_getset */
637};
638
639static PyObject *
640newIobject(PyObject *s) {
641  Iobject *self;
642  char *buf;
643  int size;
644
645  if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) {
646      PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found",
647		   s->ob_type->tp_name);
648      return NULL;
649  }
650  UNLESS (self = PyObject_New(Iobject, &Itype)) return NULL;
651  Py_INCREF(s);
652  self->buf=buf;
653  self->string_size=size;
654  self->pbuf=s;
655  self->pos=0;
656
657  return (PyObject*)self;
658}
659
660/* End of code for StringI objects */
661/* -------------------------------------------------------- */
662
663
664PyDoc_STRVAR(IO_StringIO__doc__,
665"StringIO([s]) -- Return a StringIO-like stream for reading or writing");
666
667static PyObject *
668IO_StringIO(PyObject *self, PyObject *args) {
669  PyObject *s=0;
670
671  if (!PyArg_UnpackTuple(args, "StringIO", 0, 1, &s)) return NULL;
672
673  if (s) return newIobject(s);
674  return newOobject(128);
675}
676
677/* List of methods defined in the module */
678
679static struct PyMethodDef IO_methods[] = {
680  {"StringIO",	(PyCFunction)IO_StringIO,
681   METH_VARARGS,	IO_StringIO__doc__},
682  {NULL,		NULL}		/* sentinel */
683};
684
685
686/* Initialization function for the module (*must* be called initcStringIO) */
687
688static struct PycStringIO_CAPI CAPI = {
689  IO_cread,
690  IO_creadline,
691  O_cwrite,
692  IO_cgetval,
693  newOobject,
694  newIobject,
695  &Itype,
696  &Otype,
697};
698
699#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
700#define PyMODINIT_FUNC void
701#endif
702PyMODINIT_FUNC
703initcStringIO(void) {
704  PyObject *m, *d, *v;
705
706
707  /* Create the module and add the functions */
708  m = Py_InitModule4("cStringIO", IO_methods,
709		     cStringIO_module_documentation,
710		     (PyObject*)NULL,PYTHON_API_VERSION);
711
712  /* Add some symbolic constants to the module */
713  d = PyModule_GetDict(m);
714
715  /* Export C API */
716  Itype.ob_type=&PyType_Type;
717  Otype.ob_type=&PyType_Type;
718  if (PyType_Ready(&Otype) < 0) return;
719  if (PyType_Ready(&Itype) < 0) return;
720  PyDict_SetItemString(d,"cStringIO_CAPI",
721		       v = PyCObject_FromVoidPtr(&CAPI,NULL));
722  Py_XDECREF(v);
723
724  /* Export Types */
725  PyDict_SetItemString(d,"InputType",  (PyObject*)&Itype);
726  PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype);
727
728  /* Maybe make certain warnings go away */
729  if (0) PycString_IMPORT;
730}
731