From 142eeb8339e4f3bcf40765377a1856bcc9a5ea66 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Wed, 13 Aug 1997 03:14:41 +0000 Subject: cPickle release 0.3 from Jim Fulton --- Include/cStringIO.h | 31 +++++-- Modules/cPickle.c | 151 ++++++++++++++++++++++----------- Modules/cStringIO.c | 238 ++++++++++++++++++++++++++-------------------------- 3 files changed, 245 insertions(+), 175 deletions(-) diff --git a/Include/cStringIO.h b/Include/cStringIO.h index 632177e..ceb9c16 100644 --- a/Include/cStringIO.h +++ b/Include/cStringIO.h @@ -70,12 +70,12 @@ This would typically be done in your init function. $Log$ - Revision 2.4 1997/04/09 18:04:08 guido - Got rid of the static decl of PyCObject_Import, which was a 1.4 - compatibility hack. + Revision 2.5 1997/08/13 03:14:08 guido + cPickle release 0.3 from Jim Fulton - Revision 2.3 1997/04/09 17:34:28 guido - Changed the way the C API was exported. Jim Fulton. + Revision 1.3 1997/06/13 19:44:02 jim + - changed to avoid warning of multiple declarations in 1.5 and + our 1.4. Revision 1.2 1997/01/27 14:13:05 jim Changed the way the C API was exported. @@ -121,7 +121,26 @@ static struct PycStringIO_CAPI { #define PycStringIO_OutputCheck(O) \ ((O)->ob_type==PycStringIO->OutputType) +static void * +xxxPyCObject_Import(char *module_name, char *name) +{ + PyObject *m, *c; + void *r=NULL; + + if((m=PyImport_ImportModule(module_name))) + { + if((c=PyObject_GetAttrString(m,name))) + { + r=PyCObject_AsVoidPtr(c); + Py_DECREF(c); + } + Py_DECREF(m); + } + + return r; +} + #define PycString_IMPORT \ - PycStringIO=PyCObject_Import("cStringIO", "cStringIO_CAPI") + PycStringIO=xxxPyCObject_Import("cStringIO", "cStringIO_CAPI") #endif /* CSTRINGIO_INCLUDED */ diff --git a/Modules/cPickle.c b/Modules/cPickle.c index b890b97..3e49387 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -53,13 +53,20 @@ */ static char cPickle_module_documentation[] = -"" +"C implementation and optimization of the Python pickle module\n" +"\n" +"$Id$\n" ; #include "Python.h" #include "cStringIO.h" #include "mymath.h" +#ifndef Py_eval_input +#include +#define Py_eval_input eval_input +#endif Py_eval_input + #include #define UNLESS(E) if (!(E)) @@ -127,7 +134,7 @@ static PyObject *empty_tuple; static PyObject *__class___str, *__getinitargs___str, *__dict___str, *__getstate___str, *__setstate___str, *__name___str, *__reduce___str, *write_str, *__safe_for_unpickling___str, *append_str, - *read_str, *readline_str; + *read_str, *readline_str, *__main___str; /* __builtins__ module */ static PyObject *builtins; @@ -183,7 +190,7 @@ cPickle_PyMapping_HasKey(o, key) { PyObject *v; - if (v = PyObject_GetItem(o,key)) + if((v = PyObject_GetItem(o,key))) { Py_DECREF(v); return 1; @@ -276,6 +283,13 @@ write_cStringIO(Picklerobject *self, char *s, int n) { static int +write_none(Picklerobject *self, char *s, int n) { + if (s == NULL) return 0; + return n; +} + + +static int write_other(Picklerobject *self, char *s, int n) { PyObject *py_str = 0, *junk = 0; int res = -1; @@ -490,7 +504,7 @@ readline_other(Unpicklerobject *self, char **s) { static char * -my_strndup(char *s, int l) +strndup(char *s, int l) { char *r; UNLESS(r=malloc((l+1)*sizeof(char))) return (char*)PyErr_NoMemory(); @@ -618,7 +632,7 @@ whichmodule(PyObject *global, PyObject *global_name) { PyObject *module = 0, *modules_dict = 0, *global_name_attr = 0, *name = 0; - if (module = PyDict_GetItem(class_map, global)) { + if ((module = PyDict_GetItem(class_map, global))) { Py_INCREF(module); return module; } @@ -630,7 +644,10 @@ whichmodule(PyObject *global, PyObject *global_name) { return NULL; i = 0; - while (j = PyDict_Next(modules_dict, &i, &name, &module)) { + while ((j = PyDict_Next(modules_dict, &i, &name, &module))) { + + if(PyObject_Compare(name, __main___str)==0) continue; + UNLESS(global_name_attr = PyObject_GetAttr(module, global_name)) { PyErr_Clear(); continue; @@ -645,12 +662,23 @@ whichmodule(PyObject *global, PyObject *global_name) { break; } + + /* The following implements the rule in pickle.py added in 1.5 + that used __main__ if no module is found. I don't actually + like this rule. jlf + */ + if(!j) { + j=1; + name=__main___str; + } + /* if (!j) { PyErr_Format(PicklingError, "Could not find module for %s.", "O", global_name); return NULL; } + */ PyDict_SetItem(class_map, global, name); @@ -755,7 +783,7 @@ save_float(Picklerobject *self, PyObject *args) { #ifdef FORMAT_1_3 if (self->bin) { - int s, e, i = -1; + int s, e; double f; long fhi, flo; char str[9], *p = str; @@ -859,7 +887,7 @@ save_float(Picklerobject *self, PyObject *args) { static int -save_string(Picklerobject *self, PyObject *args) { +save_string(Picklerobject *self, PyObject *args, int doput) { int size, len; size = PyString_Size(args); @@ -913,9 +941,9 @@ save_string(Picklerobject *self, PyObject *args) { return -1; } - if (size > 1) - if (put(self, args) < 0) - return -1; + if (doput) + if (put(self, args) < 0) + return -1; return 0; } @@ -946,7 +974,7 @@ save_tuple(Picklerobject *self, PyObject *args) { goto finally; if (len) { - if (has_key = cPickle_PyMapping_HasKey(self->memo, py_tuple_id) < 0) + if ((has_key = cPickle_PyMapping_HasKey(self->memo, py_tuple_id)) < 0) goto finally; if (has_key) { @@ -1031,7 +1059,7 @@ save_list(Picklerobject *self, PyObject *args) { goto finally; } - if (using_appends = (self->bin && (len > 1))) + if ((using_appends = (self->bin && (len > 1)))) if ((*self->write_func)(self, &MARKv, 1) < 0) goto finally; @@ -1096,7 +1124,7 @@ save_dict(Picklerobject *self, PyObject *args) { goto finally; } - if (using_setitems = (self->bin && (PyDict_Size(args) > 1))) + if ((using_setitems = (self->bin && (PyDict_Size(args) > 1)))) if ((*self->write_func)(self, &MARKv, 1) < 0) goto finally; @@ -1147,7 +1175,7 @@ save_inst(Picklerobject *self, PyObject *args) { goto finally; } - if (getinitargs_func = PyObject_GetAttr(args, __getinitargs___str)) { + if ((getinitargs_func = PyObject_GetAttr(args, __getinitargs___str))) { PyObject *element = 0; int i, len; @@ -1207,7 +1235,7 @@ save_inst(Picklerobject *self, PyObject *args) { goto finally; } - if (getstate_func = PyObject_GetAttr(args, __getstate___str)) { + if ((getstate_func = PyObject_GetAttr(args, __getstate___str))) { UNLESS(state = PyObject_CallObject(getstate_func, empty_tuple)) goto finally; } @@ -1403,12 +1431,11 @@ save_reduce(Picklerobject *self, PyObject *callable, return 0; } - static int save(Picklerobject *self, PyObject *args, int pers_save) { PyTypeObject *type; PyObject *py_ob_id = 0, *__reduce__ = 0, *t = 0, *arg_tup = 0, - *callable = 0, *state = 0, *junk = 0; + *callable = 0, *state = 0; int res = -1, tmp, size; if (!pers_save && self->pers_func) { @@ -1456,7 +1483,7 @@ save(Picklerobject *self, PyObject *args, int pers_save) { case 's': if ((type == &PyString_Type) && (PyString_Size(args) < 2)) { - res = save_string(self, args); + res = save_string(self, args, 0); goto finally; } } @@ -1485,7 +1512,7 @@ save(Picklerobject *self, PyObject *args, int pers_save) { switch (type->tp_name[0]) { case 's': if (type == &PyString_Type) { - res = save_string(self, args); + res = save_string(self, args, 1); goto finally; } @@ -1539,7 +1566,7 @@ save(Picklerobject *self, PyObject *args, int pers_save) { } } - if (__reduce__ = PyDict_GetItem(dispatch_table, (PyObject *)type)) { + if ((__reduce__ = PyDict_GetItem(dispatch_table, (PyObject *)type))) { Py_INCREF(__reduce__); UNLESS(self->arg) @@ -1556,7 +1583,7 @@ save(Picklerobject *self, PyObject *args, int pers_save) { else { PyErr_Clear(); - if (__reduce__ = PyObject_GetAttr(args, __reduce___str)) { + if ((__reduce__ = PyObject_GetAttr(args, __reduce___str))) { UNLESS(t = PyObject_CallObject(__reduce__, empty_tuple)) goto finally; } @@ -1586,6 +1613,7 @@ save(Picklerobject *self, PyObject *args, int pers_save) { } callable = PyTuple_GET_ITEM(t, 0); + arg_tup = PyTuple_GET_ITEM(t, 1); if (size > 2) { @@ -1680,10 +1708,20 @@ dump_special(Picklerobject *self, PyObject *args) { return Py_None; } +static PyObject * +Pickle_clear_memo(Picklerobject *self, PyObject *args) { + if(self->memo) PyDict_Clear(self->memo); + Py_INCREF(Py_None); + return Py_None; +} static struct PyMethodDef Pickler_methods[] = { - {"dump", (PyCFunction)Pickler_dump, 1, ""}, - {"dump_special", (PyCFunction)dump_special, 1, ""}, + {"dump", (PyCFunction)Pickler_dump, 1, + "dump(object) -- Write an object in pickle format"}, + {"dump_special", (PyCFunction)dump_special, 1, + ""}, + {"clear_memo", (PyCFunction)Pickle_clear_memo, 1, + "clear_memo() -- Clear the picklers memp"}, {NULL, NULL} /* sentinel */ }; @@ -1720,6 +1758,9 @@ newPicklerobject(PyObject *file, int bin) { else if (PycStringIO_OutputCheck(file)) { self->write_func = write_cStringIO; } + else if (file == Py_None) { + self->write_func = write_none; + } else { self->write_func = write_other; @@ -1903,8 +1944,6 @@ find_class(PyObject *py_module_name, PyObject *py_class_name) { char *module_name, *class_name; PyObject *res = NULL; - static PyObject *eval_dict = 0; - module_name = PyString_AS_STRING((PyStringObject *)py_module_name); class_name = PyString_AS_STRING((PyStringObject *)py_class_name); @@ -1917,7 +1956,7 @@ find_class(PyObject *py_module_name, PyObject *py_class_name) { PyTuple_SET_ITEM((PyTupleObject *)t, 1, py_class_name); Py_INCREF(py_class_name); - if (class = PyDict_GetItem(class_map, t)) { + if ((class = PyDict_GetItem(class_map, t))) { res = class; Py_INCREF(class); goto finally; @@ -1974,7 +2013,7 @@ load_int(Unpicklerobject *self) { long l; if ((len = (*self->readline_func)(self, &s)) < 0) return -1; - UNLESS(s=my_strndup(s,len)) return -1; + UNLESS(s=strndup(s,len)) return -1; errno = 0; l = strtol(s, &endptr, 0); @@ -2081,10 +2120,8 @@ load_long(Unpicklerobject *self) { char *end, *s; int len, res = -1; - static PyObject *arg = 0; - if ((len = (*self->readline_func)(self, &s)) < 0) return -1; - UNLESS(s=my_strndup(s,len)) return -1; + UNLESS(s=strndup(s,len)) return -1; UNLESS(l = PyLong_FromString(s, &end, 0)) goto finally; @@ -2110,7 +2147,7 @@ load_float(Unpicklerobject *self) { double d; if ((len = (*self->readline_func)(self, &s)) < 0) return -1; - UNLESS(s=my_strndup(s,len)) return -1; + UNLESS(s=strndup(s,len)) return -1; errno = 0; d = strtod(s, &endptr); @@ -2220,7 +2257,7 @@ load_string(Unpicklerobject *self) { static PyObject *eval_dict = 0; if ((len = (*self->readline_func)(self, &s)) < 0) return -1; - UNLESS(s=my_strndup(s,len)) return -1; + UNLESS(s=strndup(s,len)) return -1; UNLESS(eval_dict) UNLESS(eval_dict = Py_BuildValue("{s{}}", "__builtins__")) @@ -2471,7 +2508,7 @@ Instance_New(PyObject *cls, PyObject *args) PyObject *safe=0, *r=0; if (PyClass_Check(cls)) - if(r=PyInstance_New(cls, args, NULL)) return r; + if((r=PyInstance_New(cls, args, NULL))) return r; else goto err; @@ -2486,13 +2523,14 @@ Instance_New(PyObject *cls, PyObject *args) return NULL; } - if(r=PyObject_CallObject(cls, args)) return r; + if((r=PyObject_CallObject(cls, args))) return r; + err: { PyObject *tp, *v, *tb; PyErr_Fetch(&tp, &v, &tb); - if(r=Py_BuildValue("OOO",v,cls,args)) + if((r=Py_BuildValue("OOO",v,cls,args))) { Py_XDECREF(v); v=r; @@ -3207,7 +3245,7 @@ finally: static PyObject * load(Unpicklerobject *self) { - PyObject *stack = 0, *err = 0, *exc = 0, *val = 0, *tb = 0; + PyObject *stack = 0, *err = 0, *val = 0; int len; char *s; @@ -3777,6 +3815,7 @@ init_stuff(PyObject *module, PyObject *module_dict) { INIT_STR(__getstate__); INIT_STR(__setstate__); INIT_STR(__name__); + INIT_STR(__main__); INIT_STR(__reduce__); INIT_STR(write); INIT_STR(__safe_for_unpickling__); @@ -3873,22 +3912,36 @@ initcPickle() { /**************************************************************************** $Log$ - Revision 2.7 1997/05/16 16:36:52 guido - Renamed strndup to my_strndup to avoid conflict witth GNU libc. + Revision 2.8 1997/08/13 03:14:37 guido + cPickle release 0.3 from Jim Fulton + + Revision 1.41 1997/06/20 19:45:10 jim + Fixed dumb bug in __main__ fix. :-( + + Revision 1.40 1997/06/19 18:57:36 jim + Added ident string. + + Revision 1.39 1997/06/13 19:40:44 jim + - Various changes to make gcc -Wall -pedantic happy, including + extra parens elimination of unused vars. + + - Added check to avoid pickling module __main__ for classes that are + defined in other modules, in whichmodule + + - Changed to use Py_eval_input rather than eval_input. - Revision 2.6 1997/05/13 18:00:44 guido - Use compile-time test for 64-bit hardware instead of run-time test. - This silences some compilers. + - Changed to use SIZEOF_LONG macro to avoid warnings on 32-bit machines. - Revision 2.5 1997/05/07 17:46:13 guido - Instead of importing graminit.h whenever one of the three grammar 'root' - symbols is needed, define these in Python.h with a Py_ prefix. + - Added option of supplying None to pickler, which cases no data to be + written during pickling. This is slightly useful, in conjunction + with persistent_id attribute to find persistent sub-objects without + writing a pickle. - Revision 2.4 1997/04/09 17:47:47 guido - Give PyErr_Format a new name and make it static. + Revision 1.38 1997/05/07 17:06:43 jim + Added clear_memo method to pickler. - Revision 2.3 1997/04/09 17:36:32 guido - Jim Fulton's version 2.2. + Revision 1.37 1997/05/06 20:21:01 jim + Changed to only add strings to memo that have length greater than one. Revision 1.36 1997/03/11 22:05:02 chris write POP rather than POPMARK in non-binary mode diff --git a/Modules/cStringIO.c b/Modules/cStringIO.c index 104ab51..09b4051 100644 --- a/Modules/cStringIO.c +++ b/Modules/cStringIO.c @@ -51,70 +51,12 @@ If you have questions regarding this software, contact: - Jim Fulton, jim@digicool.com + info@digicool.com Digital Creations L.C. (540) 371-6909 - $Log$ - Revision 2.5 1997/04/11 19:56:06 guido - My own patch: support writable 'softspace' attribute. - - Revision 2.4 1997/04/09 17:35:33 guido - Unknown changes by Jim Fulton. - - Revision 1.16 1997/02/17 22:17:43 jim - *** empty log message *** - - Revision 1.14 1997/01/24 19:56:24 chris - undid last change - - Revision 1.13 1997/01/24 19:45:20 chris - extra byte in buffer no longer included in buf_size - - Revision 1.12 1997/01/24 19:38:28 chris - *** empty log message *** - - Revision 1.11 1997/01/23 20:45:01 jim - ANSIfied it. - Changed way C API was exported. - - Revision 1.10 1997/01/02 15:19:55 chris - checked in to be sure repository is up to date. - - Revision 1.9 1996/12/27 21:40:29 jim - Took out some lamosities in interface, like returning self from - write. - - Revision 1.8 1996/12/23 15:52:49 jim - Added ifdef to check for CObject before using it. - - Revision 1.7 1996/12/23 15:22:35 jim - Finished implementation, adding full compatibility with StringIO, and - then some. - - We still need to take out some cStringIO oddities. - - Revision 1.6 1996/10/15 18:42:07 jim - Added lots of casts to make warnings go away. - - Revision 1.5 1996/10/11 21:03:42 jim - *** empty log message *** - - Revision 1.4 1996/10/11 21:02:15 jim - *** empty log message *** - - Revision 1.3 1996/10/07 20:51:38 chris - *** empty log message *** - - Revision 1.2 1996/07/18 13:08:34 jfulton - *** empty log message *** - - Revision 1.1 1996/07/15 17:06:33 jfulton - Initial version. - - */ static char cStringIO_module_documentation[] = "A simple fast partial StringIO replacement.\n" @@ -142,6 +84,8 @@ static char cStringIO_module_documentation[] = " \n" "If someone else wants to provide a more complete implementation,\n" "go for it. :-) \n" +"\n" +"$Id$\n" ; #include "Python.h" @@ -150,8 +94,6 @@ static char cStringIO_module_documentation[] = #define UNLESS(E) if(!(E)) -/* ----------------------------------------------------- */ - /* Declarations for objects of type StringO */ typedef struct { @@ -160,10 +102,6 @@ typedef struct { int pos, string_size, buf_size, closed, softspace; } Oobject; -staticforward PyTypeObject Otype; - -/* ---------------------------------------------------------------- */ - /* Declarations for objects of type StringI */ typedef struct { @@ -173,10 +111,6 @@ typedef struct { PyObject *pbuf; } Iobject; -staticforward PyTypeObject Itype; - -/* ---------------------------------------------------------------- */ - static char O_reset__doc__[] = "reset() -- Reset the file position to the beginning" ; @@ -343,7 +277,14 @@ O_write(Oobject *self, PyObject *args) { static PyObject * O_getval(Oobject *self, PyObject *args) { - return PyString_FromStringAndSize(self->buf, self->pos); + PyObject *use_pos; + int s; + + use_pos=Py_None; + UNLESS(PyArg_ParseTuple(args,"|O",&use_pos)) return NULL; + if(PyObject_IsTrue(use_pos)) s=self->pos; + else s=self->string_size; + return PyString_FromStringAndSize(self->buf, s); } static PyObject * @@ -434,7 +375,12 @@ static struct PyMethodDef O_methods[] = { {"reset", (PyCFunction)O_reset, 0, O_reset__doc__}, {"seek", (PyCFunction)O_seek, 1, O_seek__doc__}, {"tell", (PyCFunction)O_tell, 0, O_tell__doc__}, - {"getvalue", (PyCFunction)O_getval, 0, "getvalue() -- Get the string value"}, + {"getvalue", (PyCFunction)O_getval, 1, + "getvalue([use_pos]) -- Get the string value." + "\n" + "If use_pos is specified and is a true value, then the string returned\n" + "will include only the text up to the current file position.\n" + }, {"truncate", (PyCFunction)O_truncate, 0, O_truncate__doc__}, {"isatty", (PyCFunction)O_isatty, 0, O_isatty__doc__}, {"close", (PyCFunction)O_close, 0, O_close__doc__}, @@ -443,32 +389,6 @@ static struct PyMethodDef O_methods[] = { {NULL, NULL} /* sentinel */ }; -/* ---------- */ - - -static PyObject * -newOobject(int size) { - Oobject *self; - - self = PyObject_NEW(Oobject, &Otype); - if (self == NULL) - return NULL; - self->pos=0; - self->closed = 0; - self->string_size = 0; - self->softspace = 0; - - UNLESS(self->buf=malloc(size*sizeof(char))) - { - PyErr_SetString(PyExc_MemoryError,"out of memory"); - self->buf_size = 0; - return NULL; - } - - self->buf_size=size; - return (PyObject*)self; -} - static void O_dealloc(Oobject *self) { @@ -527,6 +447,29 @@ static PyTypeObject Otype = { Otype__doc__ /* Documentation string */ }; +static PyObject * +newOobject(int size) { + Oobject *self; + + self = PyObject_NEW(Oobject, &Otype); + if (self == NULL) + return NULL; + self->pos=0; + self->closed = 0; + self->string_size = 0; + self->softspace = 0; + + UNLESS(self->buf=malloc(size*sizeof(char))) + { + PyErr_SetString(PyExc_MemoryError,"out of memory"); + self->buf_size = 0; + return NULL; + } + + self->buf_size=size; + return (PyObject*)self; +} + /* End of code for StringO objects */ /* -------------------------------------------------------- */ @@ -554,29 +497,6 @@ static struct PyMethodDef I_methods[] = { {NULL, NULL} /* sentinel */ }; -/* ---------- */ - - -static PyObject * -newIobject(PyObject *s) { - Iobject *self; - char *buf; - int size; - - UNLESS(buf=PyString_AsString(s)) return NULL; - UNLESS(-1 != (size=PyString_Size(s))) return NULL; - UNLESS(self = PyObject_NEW(Iobject, &Itype)) return NULL; - Py_INCREF(s); - self->buf=buf; - self->string_size=size; - self->pbuf=s; - self->pos=0; - self->closed = 0; - - return (PyObject*)self; -} - - static void I_dealloc(Iobject *self) { Py_DECREF(self->pbuf); @@ -617,6 +537,25 @@ static PyTypeObject Itype = { Itype__doc__ /* Documentation string */ }; +static PyObject * +newIobject(PyObject *s) { + Iobject *self; + char *buf; + int size; + + UNLESS(buf=PyString_AsString(s)) return NULL; + UNLESS(-1 != (size=PyString_Size(s))) return NULL; + UNLESS(self = PyObject_NEW(Iobject, &Itype)) return NULL; + Py_INCREF(s); + self->buf=buf; + self->string_size=size; + self->pbuf=s; + self->pos=0; + self->closed = 0; + + return (PyObject*)self; +} + /* End of code for StringI objects */ /* -------------------------------------------------------- */ @@ -676,8 +615,67 @@ initcStringIO() { /* Export Types */ PyDict_SetItemString(d,"InputType", (PyObject*)&Itype); PyDict_SetItemString(d,"OutputType", (PyObject*)&Otype); + + /* Maybe make certain warnings go away */ + if(0) PycString_IMPORT; /* Check for errors */ if (PyErr_Occurred()) Py_FatalError("can't initialize module cStringIO"); } + +/****************************************************************************** + + $Log$ + Revision 2.6 1997/08/13 03:14:41 guido + cPickle release 0.3 from Jim Fulton + + Revision 1.21 1997/06/19 18:51:42 jim + Added ident string. + + Revision 1.20 1997/06/13 20:50:50 jim + - Various changes to make gcc -Wall -pedantic happy, including + getting rid of staticforward declarations and adding pretend use + of two statics defined in .h file. + + Revision 1.19 1997/06/02 18:15:17 jim + Merged in guido's changes. + + Revision 1.18 1997/05/07 16:26:47 jim + getvalue() can nor be given an argument. If this argument is true, + then getvalue returns the text upto the current position. Otherwise + it returns all of the text. The default value of the argument is + false. + + Revision 1.17 1997/04/17 18:02:46 chris + getvalue() now returns entire string, not just the string up to + current position + + Revision 2.5 1997/04/11 19:56:06 guido + My own patch: support writable 'softspace' attribute. + + > Jim asked: What is softspace for? + + It's an old feature. The print statement uses this to remember + whether it should insert a space before the next item or not. + Implementation is in fileobject.c. + + Revision 1.11 1997/01/23 20:45:01 jim + ANSIfied it. + Changed way C API was exported. + + Revision 1.10 1997/01/02 15:19:55 chris + checked in to be sure repository is up to date. + + Revision 1.9 1996/12/27 21:40:29 jim + Took out some lamosities in interface, like returning self from + write. + + Revision 1.8 1996/12/23 15:52:49 jim + Added ifdef to check for CObject before using it. + + Revision 1.7 1996/12/23 15:22:35 jim + Finished implementation, adding full compatibility with StringIO, and + then some. + + *****************************************************************************/ -- cgit v0.12