* Changed many files to use mkvalue() instead of newtupleobject().
* Fixcprt.py: added [-y file] option, do only files younger than file.
* modsupport.[ch]: added vmkvalue().
* intobject.c: use mkvalue().
* stringobject.c: added "formatstring"; renamed string* to string_*;
  ceval.c: call formatstring for string % value.
* longobject.c: close memory leak in divmod.
* parsetok.c: set result node to NULL when returning an error.
diff --git a/Include/modsupport.h b/Include/modsupport.h
index 28821d9..bb809c7 100644
--- a/Include/modsupport.h
+++ b/Include/modsupport.h
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -24,9 +24,21 @@
 
 /* Module support interface */
 
+#ifdef HAVE_PROTOTYPES
+#define USE_STDARG
+#endif
+
+#ifdef USE_STDARG
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
 extern object *initmodule PROTO((char *, struct methodlist *));
 extern int getargs PROTO((object *, char *, ...));
+extern int vgetargs PROTO((object *, char *, va_list));
 extern object *mkvalue PROTO((char *, ...));
+extern object *vmkvalue PROTO((char *, va_list));
 
 #define getnoarg(v) getargs(v, "")
 #define getintarg(v, a) getargs(v, "i", a)
diff --git a/Include/stringobject.h b/Include/stringobject.h
index 2fb386b..2a3d47a 100644
--- a/Include/stringobject.h
+++ b/Include/stringobject.h
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -58,6 +58,7 @@
 extern char *getstringvalue PROTO((object *));
 extern void joinstring PROTO((object **, object *));
 extern int resizestring PROTO((object **, int));
+extern object *formatstring PROTO((object *, object *));
 
 /* Macro, trading safety for speed */
 #define GETSTRINGVALUE(op) ((op)->ob_sval)
diff --git a/Modules/almodule.c b/Modules/almodule.c
index aef2eee..d986d34 100644
--- a/Modules/almodule.c
+++ b/Modules/almodule.c
@@ -1,6 +1,6 @@
 /**********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
diff --git a/Modules/clmodule.c b/Modules/clmodule.c
index 8220862..a9a378e 100644
--- a/Modules/clmodule.c
+++ b/Modules/clmodule.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
diff --git a/Modules/flmodule.c b/Modules/flmodule.c
index dca39ad..00cf12c 100644
--- a/Modules/flmodule.c
+++ b/Modules/flmodule.c
@@ -1,6 +1,6 @@
 /**********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -614,18 +614,12 @@
 	object *args;
 {
 	float f1, f2;
-	object *arg;
 	
 	if (!getnoarg(args)) return NULL;
 	
 	(*func) (obj, &f1, &f2);
-	
-	arg = newtupleobject (2);
-	if (arg == NULL) return NULL;
 
-	settupleitem (arg, 0, newfloatobject (f1));
-	settupleitem (arg, 1, newfloatobject (f2));
-	return arg;
+	return mkvalue("(ff)", f1, f2);
 }
 
 #ifdef UNUSED
@@ -966,20 +960,13 @@
 	object *args;
 {
 	int i0, i1, i2;
-	object *arg;
 
 	if (!getnoarg(args))
 		return NULL;
 
 	fl_get_clock (g->ob_generic, &i0, &i1, &i2);
 
-	arg = newtupleobject (3);
-	if (arg == NULL) return NULL;
-
-	settupleitem (arg, 0, newintobject (i0));
-	settupleitem (arg, 1, newintobject (i1));
-	settupleitem (arg, 2, newintobject (i2));
-	return arg;
+	return mkvalue("(iii)", i0, i1, i2);
 }
 
 static struct methodlist clock_methods[] = {
@@ -2064,11 +2051,9 @@
 			if (my_event_callback == NULL)
 				return newintobject(-1L);
 			dev = fl_qread(&val);
-			arg = newtupleobject(2);
+			arg = mkvalue("(ih)", dev, val);
 			if (arg == NULL)
 				return NULL;
-			settupleitem(arg, 0, newintobject((long)dev));
-			settupleitem(arg, 1, newintobject((long)val));
 			res = call_object(my_event_callback, arg);
 			XDECREF(res);
 			DECREF(arg);
@@ -2085,11 +2070,9 @@
 			INCREF(g);
 			return ((object *) g);
 		}
-		arg = newtupleobject(2);
-		INCREF(g);
-		settupleitem(arg, 0, (object *)g);
-		INCREF(g->ob_callback_arg);
-		settupleitem(arg, 1, g->ob_callback_arg);
+		arg = mkvalue("(OO)", (object *)g, g->ob_callback_arg);
+		if (arg == NULL)
+			return NULL;
 		res = call_object(g->ob_callback, arg);
 		XDECREF(res);
 		DECREF(arg);
@@ -2259,18 +2242,12 @@
 	object *self;
 	object *args;
 {
-	long retval;
-	short arg1;
+	int dev;
+	short val;
 	BGN_SAVE
-	retval = fl_qread(&arg1);
+	dev = fl_qread(&val);
 	END_SAVE
-	{
-		object *v = newtupleobject(2);
-		if (v == NULL) return NULL;
-		settupleitem(v, 0, newintobject(retval));
-		settupleitem(v, 1, newintobject((long)arg1));
-		return v;
-	}
+	return mkvalue("(ih)", dev, val);
 }
 
 static object *
@@ -2336,21 +2313,12 @@
 {
 	int arg;
 	short r, g, b;
-	object *v;
 
 	if (!getintarg(args, &arg)) return NULL;
 
 	fl_getmcolor(arg, &r, &g, &b);
 
-	v = newtupleobject(3);
-
-	if (v == NULL) return NULL;
-
-	settupleitem(v, 0, newintobject((long)r));
-	settupleitem(v, 1, newintobject((long)g));
-	settupleitem(v, 2, newintobject((long)b));
-
-	return v;
+	return mkvalue("(hhh)", r, g, b);
 }
 
 static object *
@@ -2358,21 +2326,13 @@
 	object *self;
 	object *args;
 {
-	float x, y ;
-	object *v;
+	float x, y;
 
 	if (!getnoarg(args)) return NULL;
 	
 	fl_get_mouse(&x, &y);
 
-	v = newtupleobject(2);
-
-	if (v == NULL) return NULL;
-
-	settupleitem(v, 0, newfloatobject(x));
-	settupleitem(v, 1, newfloatobject(y));
-
-	return v;
+	return mkvalue("(ff)", x, y);
 }
 
 static object *
diff --git a/Modules/fmmodule.c b/Modules/fmmodule.c
index f3df6ce..8d54d97 100644
--- a/Modules/fmmodule.c
+++ b/Modules/fmmodule.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -134,22 +134,15 @@
 		err_setstr(RuntimeError, "error in fmgetfontinfo");
 		return NULL;
 	}
-	v = newtupleobject(8);
-	if (v == NULL)
-		return NULL;
-#define SET(i, member) settupleitem(v, i, newintobject(info.member))
-	SET(0, printermatched);
-	SET(1, fixed_width);
-	SET(2, xorig);
-	SET(3, yorig);
-	SET(4, xsize);
-	SET(5, ysize);
-	SET(6, height);
-	SET(7, nglyphs);
-#undef SET
-	if (err_occurred())
-		return NULL;
-	return v;
+	return mkvalue("(llllllll)",
+		       info.printermatched,
+		       info.fixed_width,
+		       info.xorig,
+		       info.yorig,
+		       info.xsize,
+		       info.ysize,
+		       info.height,
+		       info.nglyphs);
 }
 
 #if 0
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index 00aa5eb..1521133 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -136,7 +136,6 @@
 	object *self;
 	object *args;
 {
-	object *v;
 	double x;
 	int i;
 	if (!getdoublearg(args, &x))
@@ -146,16 +145,7 @@
 	CHECK(x);
 	if (errno != 0)
 		return math_error();
-	v = newtupleobject(2);
-	if (v != NULL) {
-		settupleitem(v, 0, newfloatobject(x));
-		settupleitem(v, 1, newintobject((long)i));
-		if (err_occurred()) {
-			DECREF(v);
-			v = NULL;
-		}
-	}
-	return v;
+	return mkvalue("(di)", x, i);
 }
 
 static object *
@@ -181,7 +171,6 @@
 	object *self;
 	object *args;
 {
-	object *v;
 	double x, y;
 	if (!getdoublearg(args, &x))
 		return NULL;
@@ -190,16 +179,7 @@
 	CHECK(x);
 	if (errno != 0)
 		return math_error();
-	v = newtupleobject(2);
-	if (v != NULL) {
-		settupleitem(v, 0, newfloatobject(x));
-		settupleitem(v, 1, newfloatobject(y));
-		if (err_occurred()) {
-			DECREF(v);
-			v = NULL;
-		}
-	}
-	return v;
+	return mkvalue("(dd)", x, y);
 }
 
 static struct methodlist math_methods[] = {
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index a600115..4e84407 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -216,26 +216,17 @@
 	END_SAVE
 	if (res != 0)
 		return posix_error();
-	v = newtupleobject(10);
-	if (v == NULL)
-		return NULL;
-#define SET(i, st_member) settupleitem(v, i, newintobject((long)st.st_member))
-	SET(0, st_mode);
-	SET(1, st_ino);
-	SET(2, st_dev);
-	SET(3, st_nlink);
-	SET(4, st_uid);
-	SET(5, st_gid);
-	SET(6, st_size);
-	SET(7, st_atime);
-	SET(8, st_mtime);
-	SET(9, st_ctime);
-#undef SET
-	if (err_occurred()) {
-		DECREF(v);
-		return NULL;
-	}
-	return v;
+	v = mkvalue("(llllllllll)",
+		    (long)st.st_mode,
+		    (long)st.st_ino,
+		    (long)st.st_dev,
+		    (long)st.st_nlink,
+		    (long)st.st_uid,
+		    (long)st.st_gid,
+		    (long)st.st_size,
+		    (long)st.st_atime,
+		    (long)st.st_mtime,
+		    (long)st.st_ctime);
 }
 
 
@@ -477,21 +468,12 @@
 	END_SAVE
 	if (res < 0)
 		return posix_error();
-	v = newtupleobject(5);
-	if (v == NULL)
-		return NULL;
-#define SET(i, member) settupleitem(v, i, newstringobject(u.member))
-	SET(0, sysname);
-	SET(1, nodename);
-	SET(2, release);
-	SET(3, version);
-	SET(4, machine);
-#undef SET
-	if (err_occurred()) {
-		DECREF(v);
-		return NULL;
-	}
-	return v;
+	return mkvalue("(sssss)",
+		       u.sysname,
+		       u.nodename,
+		       u.release,
+		       u.version,
+		       u.machine);
 }
 #endif /* NO_UNAME */
 
diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c
index 4d787ba..eb7a1cc 100644
--- a/Modules/pwdmodule.c
+++ b/Modules/pwdmodule.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -38,25 +38,14 @@
 static object *mkpwent(p)
 	struct passwd *p;
 {
-	object *v;
-	if ((v = newtupleobject(7)) == NULL)
-		return NULL;
-#define ISET(i, member) settupleitem(v, i, newintobject((long)p->member))
-#define SSET(i, member) settupleitem(v, i, newstringobject(p->member))
-	SSET(0, pw_name);
-	SSET(1, pw_passwd);
-	ISET(2, pw_uid);
-	ISET(3, pw_gid);
-	SSET(4, pw_gecos);
-	SSET(5, pw_dir);
-	SSET(6, pw_shell);
-#undef SSET
-#undef ISET
-	if (err_occurred()) {
-		DECREF(v);
-		return NULL;
-	}
-	return v;
+	return mkvalue("(ssllsss)",
+		       p->pw_name,
+		       p->pw_passwd,
+		       (long)p->pw_uid,
+		       (long)p->pw_gid,
+		       p->pw_gecos,
+		       p->pw_dir,
+		       p->pw_shell);
 }
 
 static object *pwd_getpwuid(self, args)
@@ -130,32 +119,24 @@
 {
 	object *v, *w;
 	char **member;
-	if ((v = newtupleobject(4)) == NULL)
-		return NULL;
-#define ISET(i, member) settupleitem(v, i, newintobject((long)p->member))
-#define SSET(i, member) settupleitem(v, i, newstringobject(p->member))
-	SSET(0, gr_name);
-	SSET(1, gr_passwd);
-	ISET(2, gr_gid);
-#undef SSET
-#undef ISET
-	if (err_occurred()) {
-		DECREF(v);
-		return NULL;
-	}
 	if ((w = newlistobject(0)) == NULL) {
 		DECREF(v);
 		return NULL;
 	}
-	(void) settupleitem(v, 3, w); /* Cannot fail; eats refcnt */
 	for (member = p->gr_mem; *member != NULL; member++) {
 		object *x = newstringobject(*member);
 		if (x == NULL || addlistitem(w, x) != 0) {
 			XDECREF(x);
-			DECREF(v);
+			DECREF(w);
 			return NULL;
 		}
 	}
+	v = mkvalue("(sslO)",
+		       p->gr_name,
+		       p->gr_passwd,
+		       (long)p->gr_gid,
+		       w);
+	DECREF(w);
 	return v;
 }
 
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 99a9213..de80b82 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 2a0e291..0e20307 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 1e6fdb6..95b85f5 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -49,7 +49,7 @@
 	if (bases == NULL) {
 		bases = newtupleobject(0);
 		if (bases == NULL)
-			return err_nomem();
+			return NULL;
 	}
 	else
 		INCREF(bases);
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 1a1598c..e563583 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -28,6 +28,7 @@
    for any kind of float exception without losing portability. */
 
 #include "allobjects.h"
+#include "modsupport.h"
 
 #include <errno.h>
 #ifndef errno
@@ -222,16 +223,7 @@
 		mod += wx;
 		div -= 1.0;
 	}
-	t = newtupleobject(2);
-	if (t != NULL) {
-		settupleitem(t, 0, newfloatobject(div));
-		settupleitem(t, 1, newfloatobject(mod));
-		if (err_occurred()) {
-			DECREF(t);
-			t = NULL;
-		}
-	}
-	return t;
+	return mkvalue("(dd)", div, mod);
 }
 
 static object *
diff --git a/Objects/intobject.c b/Objects/intobject.c
index e10dab2..858458c 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -25,6 +25,7 @@
 /* Integer object implementation */
 
 #include "allobjects.h"
+#include "modsupport.h"
 
 /* Standard Booleans */
 
@@ -252,18 +253,7 @@
 	long d, m;
 	if (i_divmod(x, y, &d, &m) < 0)
 		return NULL;
-	v = newtupleobject(2);
-	v0 = newintobject(d);
-	v1 = newintobject(m);
-	if (v == NULL || v0 == NULL || v1 == NULL ||
-		settupleitem(v, 0, v0) != 0 ||
-		settupleitem(v, 1, v1) != 0) {
-		XDECREF(v);
-		XDECREF(v0);
-		XDECREF(v1);
-		v = NULL;
-	}
-	return v;
+	return mkvalue("(ll)", d, m);
 }
 
 static object *
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 4c5ede5..38473e2 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -844,8 +844,10 @@
 		    (temp = (longobject *) long_sub(div, one)) == NULL) {
 			DECREF(mod);
 			DECREF(div);
+			XDECREF(one);
 			return -1;
 		}
+		DECREF(one);
 		DECREF(div);
 		div = temp;
 	}
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 9f8de92..25f12fc 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -61,7 +61,7 @@
 }
 
 void
-stringdealloc(op)
+string_dealloc(op)
 	object *op;
 {
 	DEL(op);
@@ -92,7 +92,7 @@
 /* Methods */
 
 static int
-stringprint(op, fp, flags)
+string_print(op, fp, flags)
 	stringobject *op;
 	FILE *fp;
 	int flags;
@@ -119,7 +119,7 @@
 }
 
 static object *
-stringrepr(op)
+string_repr(op)
 	register stringobject *op;
 {
 	/* XXX overflow? */
@@ -155,14 +155,14 @@
 }
 
 static int
-stringlength(a)
+string_length(a)
 	stringobject *a;
 {
 	return a->ob_size;
 }
 
 static object *
-stringconcat(a, bb)
+string_concat(a, bb)
 	register stringobject *a;
 	register object *bb;
 {
@@ -198,7 +198,7 @@
 }
 
 static object *
-stringrepeat(a, n)
+string_repeat(a, n)
 	register stringobject *a;
 	register int n;
 {
@@ -228,7 +228,7 @@
 /* String slice a[i:j] consists of characters a[i] ... a[j-1] */
 
 static object *
-stringslice(a, i, j)
+string_slice(a, i, j)
 	register stringobject *a;
 	register int i, j; /* May be negative! */
 {
@@ -258,7 +258,7 @@
 static object *characters[UCHAR_MAX + 1];
 
 static object *
-stringitem(a, i)
+string_item(a, i)
 	stringobject *a;
 	register int i;
 {
@@ -282,7 +282,7 @@
 }
 
 static int
-stringcompare(a, b)
+string_compare(a, b)
 	stringobject *a, *b;
 {
 	int len_a = a->ob_size, len_b = b->ob_size;
@@ -294,11 +294,11 @@
 }
 
 static sequence_methods string_as_sequence = {
-	stringlength,	/*sq_length*/
-	stringconcat,	/*sq_concat*/
-	stringrepeat,	/*sq_repeat*/
-	stringitem,	/*sq_item*/
-	stringslice,	/*sq_slice*/
+	string_length,	/*sq_length*/
+	string_concat,	/*sq_concat*/
+	string_repeat,	/*sq_repeat*/
+	string_item,	/*sq_item*/
+	string_slice,	/*sq_slice*/
 	0,		/*sq_ass_item*/
 	0,		/*sq_ass_slice*/
 };
@@ -309,12 +309,12 @@
 	"string",
 	sizeof(stringobject),
 	sizeof(char),
-	stringdealloc,	/*tp_dealloc*/
-	stringprint,	/*tp_print*/
+	string_dealloc,	/*tp_dealloc*/
+	string_print,	/*tp_print*/
 	0,		/*tp_getattr*/
 	0,		/*tp_setattr*/
-	stringcompare,	/*tp_compare*/
-	stringrepr,	/*tp_repr*/
+	string_compare,	/*tp_compare*/
+	string_repr,	/*tp_repr*/
 	0,		/*tp_as_number*/
 	&string_as_sequence,	/*tp_as_sequence*/
 	0,		/*tp_as_mapping*/
@@ -328,7 +328,7 @@
 	register object *v;
 	if (*pv == NULL || w == NULL || !is_stringobject(*pv))
 		return;
-	v = stringconcat((stringobject *) *pv, w);
+	v = string_concat((stringobject *) *pv, w);
 	DECREF(*pv);
 	*pv = v;
 }
@@ -373,3 +373,344 @@
 	sv->ob_sval[newsize] = '\0';
 	return 0;
 }
+
+/* Helpers for formatstring */
+
+static object *
+getnextarg(args, arglen, p_argidx)
+	object *args;
+	int arglen;
+	int *p_argidx;
+{
+	int argidx = *p_argidx;
+	if (argidx < arglen) {
+		(*p_argidx)++;
+		if (arglen < 0)
+			return args;
+		else
+			return gettupleitem(args, argidx);
+	}
+	err_setstr(TypeError, "not enough arguments for format string");
+	return NULL;
+}
+
+#define F_LJUST (1<<0)
+#define F_SIGN	(1<<1)
+#define F_BLANK (1<<2)
+#define F_ALT	(1<<3)
+#define F_ZERO	(1<<4)
+
+extern double fabs PROTO((double));
+
+static char *
+formatfloat(flags, prec, type, v)
+	int flags;
+	int prec;
+	int type;
+	object *v;
+{
+	char fmt[20];
+	static char buf[120];
+	double x;
+	if (!getargs(v, "d;float argument required", &x))
+		return NULL;
+	if (prec < 0)
+		prec = 6;
+	if (prec > 50)
+		prec = 50; /* Arbitrary limitation */
+	if (type == 'f' && fabs(x)/1e25 >= 1e25)
+		type = 'g';
+	sprintf(fmt, "%%%s.%d%c", (flags&F_ALT) ? "#" : "", prec, type);
+	sprintf(buf, fmt, x);
+	return buf;
+}
+
+static char *
+formatint(flags, prec, type, v)
+	int flags;
+	int prec;
+	int type;
+	object *v;
+{
+	char fmt[20];
+	static char buf[50];
+	long x;
+	if (!getargs(v, "l;int argument required", &x))
+		return NULL;
+	if (prec < 0)
+		prec = 1;
+	sprintf(fmt, "%%%s.%dl%c", (flags&F_ALT) ? "#" : "", prec, type);
+	sprintf(buf, fmt, x);
+	return buf;
+}
+
+static char *
+formatchar(v)
+	object *v;
+{
+	static char buf[2];
+	if (is_stringobject(v)) {
+		if (!getargs(v, "c;%c requires int or char", &buf[0]))
+			return NULL;
+	}
+	else {
+		if (!getargs(v, "b;%c requires int or char", &buf[0]))
+			return NULL;
+	}
+	buf[1] = '\0';
+	return buf;
+}
+
+/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */
+
+object *
+formatstring(format, args)
+	object *format;
+	object *args;
+{
+	char *fmt, *res;
+	int fmtcnt, rescnt, reslen, arglen, argidx;
+	object *result;
+	if (format == NULL || !is_stringobject(format) || args == NULL) {
+		err_badcall();
+		return NULL;
+	}
+	reslen = rescnt = 100;
+	result = newsizedstringobject((char *)NULL, reslen);
+	if (result == NULL)
+		return NULL;
+	res = getstringvalue(result);
+	fmt = getstringvalue(format);
+	fmtcnt = getstringsize(format);
+	if (is_tupleobject(args)) {
+		arglen = gettuplesize(args);
+		argidx = 0;
+	}
+	else {
+		arglen = -1;
+		argidx = -2;
+	}
+	while (--fmtcnt >= 0) {
+		if (*fmt != '%') {
+			if (--rescnt < 0) {
+				rescnt = reslen;
+				reslen = reslen * 2; /* Maybe less when big? */
+				if (resizestring(&result, reslen) < 0)
+					return NULL;
+				res = getstringvalue(result) + rescnt;
+				rescnt = reslen - rescnt;
+			}
+			*res++ = *fmt++;
+		}
+		else {
+			/* Got a format specifier */
+			int flags = 0;
+			char *fmtstart = fmt++;
+			int width = -1;
+			int prec = -1;
+			int size = 0;
+			int c;
+			int fill;
+			object *v;
+			char *buf;
+			int sign;
+			int len;
+			while (--fmtcnt >= 0) {
+				switch (c = *fmt++) {
+				case '-': flags |= F_LJUST; continue;
+				case '+': flags |= F_SIGN; continue;
+				case ' ': flags |= F_BLANK; continue;
+				case '#': flags |= F_ALT; continue;
+				case '0': flags |= F_ZERO; continue;
+				}
+				break;
+			}
+			if (c == '*') {
+				v = getnextarg(args, arglen, &argidx);
+				if (v == NULL)
+					goto error;
+				if (!is_intobject(v)) {
+					err_setstr(TypeError, "* wants int");
+					goto error;
+				}
+				width = getintvalue(v);
+				if (width < 0)
+					width = 0;
+				if (--fmtcnt >= 0)
+					c = *fmt++;
+			}
+			else if (isdigit(c)) {
+				width = c - '0';
+				while (--fmtcnt >= 0) {
+					c = *fmt++;
+					if (!isdigit(c))
+						break;
+					if ((width*10) / 10 != width) {
+						err_setstr(ValueError,
+							   "width too big");
+						goto error;
+					}
+					width = width*10 + (c - '0');
+				}
+			}
+			if (c == '.') {
+				prec = 0;
+				if (--fmtcnt >= 0)
+					c = *fmt++;
+				if (c == '*') {
+					v = getnextarg(args, arglen, &argidx);
+					if (v == NULL)
+						goto error;
+					if (!is_intobject(v)) {
+						err_setstr(TypeError,
+							   "* wants int");
+						goto error;
+					}
+					prec = getintvalue(v);
+					if (prec < 0)
+						prec = 0;
+					if (--fmtcnt >= 0)
+						c = *fmt++;
+				}
+				else if (isdigit(c)) {
+					prec = c - '0';
+					while (--fmtcnt >= 0) {
+						c = *fmt++;
+						if (!isdigit(c))
+							break;
+						if ((prec*10) / 10 != prec) {
+							err_setstr(ValueError,
+							    "prec too big");
+							goto error;
+						}
+						prec = prec*10 + (c - '0');
+					}
+				}
+			} /* prec */
+			if (fmtcnt >= 0) {
+				if (c == 'h' || c == 'l' || c == 'L') {
+					size = c;
+					if (--fmtcnt >= 0)
+						c = *fmt++;
+				}
+			}
+			if (fmtcnt < 0) {
+				err_setstr(ValueError, "incomplete format");
+				goto error;
+			}
+			if (c != '%') {
+				v = getnextarg(args, arglen, &argidx);
+				if (v == NULL)
+					goto error;
+			}
+			sign = 0;
+			fill = ' ';
+			switch (c) {
+			case '%':
+				buf = "%";
+				len = 1;
+				break;
+			case 's':
+				if (!is_stringobject(v)) {
+					err_setstr(TypeError,
+						   "%s wants string");
+					goto error;
+				}
+				buf = getstringvalue(v);
+				len = getstringsize(v);
+				if (prec >= 0 && len > prec)
+					len = prec;
+				break;
+			case 'i':
+			case 'd':
+			case 'u':
+			case 'o':
+			case 'x':
+			case 'X':
+				if (c == 'i')
+					c = 'd';
+				buf = formatint(flags, prec, c, v);
+				if (buf == NULL)
+					goto error;
+				len = strlen(buf);
+				sign = (c == 'd');
+				if (flags&F_ZERO)
+					fill = '0';
+				break;
+			case 'e':
+			case 'E':
+			case 'f':
+			case 'g':
+			case 'G':
+				buf = formatfloat(flags, prec, c, v);
+				if (buf == NULL)
+					goto error;
+				len = strlen(buf);
+				sign = 1;
+				if (flags&F_ZERO)
+					fill = '0';
+				break;
+			case 'c':
+				buf = formatchar(v);
+				if (buf == NULL)
+					goto error;
+				len = strlen(buf);
+				break;
+			default:
+				err_setstr(ValueError,
+					   "unsupported format character");
+				goto error;
+			}
+			if (sign) {
+				if (*buf == '-' || *buf == '+') {
+					sign = *buf++;
+					len--;
+				}
+				else if (flags & F_SIGN)
+					sign = '+';
+				else if (flags & F_BLANK)
+					sign = ' ';
+				else
+					sign = '\0';
+			}
+			if (width < len)
+				width = len;
+			if (rescnt < width + (sign != '\0')) {
+				rescnt = reslen;
+				reslen = reslen + width + 100;
+				if (resizestring(&result, reslen) < 0)
+					return NULL;
+				res = getstringvalue(result) + rescnt;
+				rescnt = reslen - rescnt;
+			}
+			if (sign) {
+				*res++ = sign;
+				rescnt--;
+				if (width > len)
+					width--;
+			}
+			if (width > len && !(flags&F_LJUST)) {
+				do {
+					--rescnt;
+					*res++ = fill;
+				} while (--width > len);
+			}
+			memcpy(res, buf, len);
+			res += len;
+			rescnt -= len;
+			while (--width >= len) {
+				--rescnt;
+				*res++ = ' ';
+			}
+		} /* '%' */
+	} /* until end */
+	if (argidx < arglen) {
+		err_setstr(TypeError, "not all arguments converted");
+		goto error;
+	}
+	resizestring(&result, reslen - rescnt);
+	return result;
+ error:
+	DECREF(result);
+	return NULL;
+}
diff --git a/Parser/parsetok.c b/Parser/parsetok.c
index ec0437e..32bb8b5 100644
--- a/Parser/parsetok.c
+++ b/Parser/parsetok.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -168,8 +168,11 @@
 				*n_ret = ps->p_tree;
 				ps->p_tree = NULL;
 			}
-			else if (tok->lineno <= 1 && tok->done == E_EOF)
-				ret = E_EOF;
+			else {
+				*n_ret = NULL;
+				if (tok->lineno <= 1 && tok->done == E_EOF)
+					ret = E_EOF;
+			}
 			break;
 		}
 	}
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 97c1303..4213fc3 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
diff --git a/Python/ceval.c b/Python/ceval.c
index 727bc0c..97f38ab 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1671,6 +1671,9 @@
 		DECREF(w);
 		return x;
 	}
+	if (is_stringobject(v)) {
+		return formatstring(v, w);
+	}
 	err_setstr(TypeError, "bad operand type(s) for %");
 	return NULL;
 }
diff --git a/Python/errors.c b/Python/errors.c
index 5814dd7..9f53255 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -1,6 +1,6 @@
 /***********************************************************
-Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
-Netherlands.
+Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Amsterdam, The Netherlands.
 
                         All Rights Reserved
 
@@ -56,6 +56,7 @@
 */
 
 #include "allobjects.h"
+#include "modsupport.h"
 
 #include <errno.h>
 #ifndef errno
@@ -153,13 +154,11 @@
 		err_set(KeyboardInterrupt);
 		return NULL;
 	}
-	v = newtupleobject(2);
+	v = mkvalue("(is)", errno, strerror(errno));
 	if (v != NULL) {
-		settupleitem(v, 0, newintobject((long)errno));
-		settupleitem(v, 1, newstringobject(strerror(errno)));
+		err_setval(exc, v);
+		DECREF(v);
 	}
-	err_setval(exc, v);
-	XDECREF(v);
 	return NULL;
 }
 
diff --git a/Python/modsupport.c b/Python/modsupport.c
index b464c8e..d998ad8 100644
--- a/Python/modsupport.c
+++ b/Python/modsupport.c
@@ -28,17 +28,6 @@
 #include "modsupport.h"
 #include "import.h"
 
-#ifdef HAVE_PROTOTYPES
-#define USE_STDARG
-#endif
-
-#ifdef USE_STDARG
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-
 object *
 initmodule(name, methods)
 	char *name;
@@ -454,7 +443,7 @@
 	case '(':
 		return do_mktuple(p_format, p_va, ')',
 				  countformat(*p_format, ')'));
-
+		
 	case 'b':
 	case 'h':
 	case 'i':
@@ -466,7 +455,7 @@
 	case 'f':
 	case 'd':
 		return newfloatobject((double)va_arg(*p_va, double));
-
+		
 	case 'c':
 		{
 			char p[1];
@@ -532,32 +521,34 @@
 object *mkvalue(va_alist) va_dcl
 #endif
 {
-	int n;
-	char *f;
 	va_list va;
 	object* retval;
 #ifdef USE_STDARG
 	va_start(va, format);
 #else
 	char *format;
-	
 	va_start(va);
 	format = va_arg(va, char *);
 #endif
-	f = format;
-	n = countformat(f, '\0');
-	if (n < 0)
-		retval = NULL; /* Error in the format */
-	else if (n == 0) {
-		retval = None;
-		INCREF(retval);
-	}
-	else if (n == 1)
-		retval = do_mkvalue(&f, &va);
-	else
-		retval = do_mktuple(&f, &va, '\0', n);
+	retval = vmkvalue(format, va);
 	va_end(va);
-	if (retval == NULL)
-		fprintf(stderr, "format \"%s\", f \"%s\"\n", format, f);
 	return retval;
 }
+
+object *
+vmkvalue(format, va)
+	char *format;
+	va_list va;
+{
+	char *f = format;
+	int n = countformat(f, '\0');
+	if (n < 0)
+		return NULL;
+	if (n == 0) {
+		INCREF(None);
+		return None;
+	}
+	if (n == 1)
+		return do_mkvalue(&f, &va);
+	return do_mktuple(&f, &va, '\0', n);
+}