cPickle release 0.3 from Jim Fulton
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 <graminit.h>
+#define Py_eval_input eval_input
+#endif Py_eval_input
+
 #include <errno.h>
 
 #define UNLESS(E) if (!(E))
@@ -127,7 +134,7 @@
 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 @@
 {
     PyObject *v;
 
-    if (v = PyObject_GetItem(o,key))
+    if((v = PyObject_GetItem(o,key)))
     {
         Py_DECREF(v);
         return 1;
@@ -276,6 +283,13 @@
 
 
 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 @@
 
 
 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 @@
     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 @@
         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 @@
 
         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 @@
 
 #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 @@
 
 
 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 @@
             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 @@
         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 @@
             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 @@
             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 @@
             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 @@
         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 @@
     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 @@
 
         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 @@
     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 @@
         }
     }
 
-    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 @@
     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 @@
         }
         
         callable = PyTuple_GET_ITEM(t, 0);
+
         arg_tup = PyTuple_GET_ITEM(t, 1);
 
         if (size > 2) {
@@ -1680,10 +1708,20 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
     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 @@
   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 @@
       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 @@
 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_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 @@
 
 /****************************************************************************
  $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 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.
+ Revision 1.41  1997/06/20 19:45:10  jim
+ Fixed dumb bug in __main__ fix. :-(
 
- 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.
+ Revision 1.40  1997/06/19 18:57:36  jim
+ Added ident string.
 
- Revision 2.4  1997/04/09 17:47:47  guido
- Give PyErr_Format a new name and make it static.
+ 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.
 
- Revision 2.3  1997/04/09 17:36:32  guido
- Jim Fulton's version 2.2.
+ - 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.
+
+ - Changed to use SIZEOF_LONG macro to avoid warnings on 32-bit machines.
+
+ - 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 1.38  1997/05/07 17:06:43  jim
+ Added clear_memo method to pickler.
+
+ 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 @@
 "  \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 @@
 
 #define UNLESS(E) if(!(E))
 
-/* ----------------------------------------------------- */
-
 /* Declarations for objects of type StringO */
 
 typedef struct {
@@ -160,10 +102,6 @@
   int pos, string_size, buf_size, closed, softspace;
 } Oobject;
 
-staticforward PyTypeObject Otype;
-
-/* ---------------------------------------------------------------- */
-
 /* Declarations for objects of type StringI */
 
 typedef struct {
@@ -173,10 +111,6 @@
   PyObject *pbuf;
 } Iobject;
 
-staticforward PyTypeObject Itype;
-
-/* ---------------------------------------------------------------- */
-
 static char O_reset__doc__[] = 
 "reset() -- Reset the file position to the beginning"
 ;
@@ -343,7 +277,14 @@
 
 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 @@
   {"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 @@
   {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 @@
   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 @@
   {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 @@
   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 @@
   /* 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.
+
+ *****************************************************************************/