--- exp_clib.c.orig
+++ exp_clib.c
@@ -85,6 +85,8 @@ would appreciate credit if this program
 #ifndef _STDLIB
 #define _STDLIB
 
+#include <tcl.h>
+
 extern void		abort _ANSI_ARGS_((void));
 extern double		atof _ANSI_ARGS_((CONST char *string));
 extern int		atoi _ANSI_ARGS_((CONST char *string));
@@ -115,7 +117,6 @@ extern unsigned long	strtoul _ANSI_ARGS_
 #include <stdlib.h>		/* for malloc */
 #endif
 
-#include <tcl.h>
 #include "expect.h"
 #define TclRegError exp_TclRegError
 
@@ -1466,6 +1467,467 @@ TclGetRegError()
  */
 
 /*
+ * following stolen from tcl8.0.4/generic/tclPosixStr.c
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Exp_ErrnoMsg --
+ *
+ *	Return a human-readable message corresponding to a given
+ *	errno value.
+ *
+ * Results:
+ *	The return value is the standard POSIX error message for
+ *	errno.  This procedure is used instead of strerror because
+ *	strerror returns slightly different values on different
+ *	machines (e.g. different capitalizations), which cause
+ *	problems for things such as regression tests.  This procedure
+ *	provides messages for most standard errors, then it calls
+ *	strerror for things it doesn't understand.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static
+char *
+Exp_ErrnoMsg(err)
+    int err;			/* Error number (such as in errno variable). */
+{
+    switch (err) {
+#ifdef E2BIG
+	case E2BIG: return "argument list too long";
+#endif
+#ifdef EACCES
+	case EACCES: return "permission denied";
+#endif
+#ifdef EADDRINUSE
+	case EADDRINUSE: return "address already in use";
+#endif
+#ifdef EADDRNOTAVAIL
+	case EADDRNOTAVAIL: return "can't assign requested address";
+#endif
+#ifdef EADV
+	case EADV: return "advertise error";
+#endif
+#ifdef EAFNOSUPPORT
+	case EAFNOSUPPORT: return "address family not supported by protocol family";
+#endif
+#ifdef EAGAIN
+	case EAGAIN: return "resource temporarily unavailable";
+#endif
+#ifdef EALIGN
+	case EALIGN: return "EALIGN";
+#endif
+#if defined(EALREADY) && (!defined(EBUSY) || (EALREADY != EBUSY ))
+	case EALREADY: return "operation already in progress";
+#endif
+#ifdef EBADE
+	case EBADE: return "bad exchange descriptor";
+#endif
+#ifdef EBADF
+	case EBADF: return "bad file number";
+#endif
+#ifdef EBADFD
+	case EBADFD: return "file descriptor in bad state";
+#endif
+#ifdef EBADMSG
+	case EBADMSG: return "not a data message";
+#endif
+#ifdef EBADR
+	case EBADR: return "bad request descriptor";
+#endif
+#ifdef EBADRPC
+	case EBADRPC: return "RPC structure is bad";
+#endif
+#ifdef EBADRQC
+	case EBADRQC: return "bad request code";
+#endif
+#ifdef EBADSLT
+	case EBADSLT: return "invalid slot";
+#endif
+#ifdef EBFONT
+	case EBFONT: return "bad font file format";
+#endif
+#ifdef EBUSY
+	case EBUSY: return "file busy";
+#endif
+#ifdef ECHILD
+	case ECHILD: return "no children";
+#endif
+#ifdef ECHRNG
+	case ECHRNG: return "channel number out of range";
+#endif
+#ifdef ECOMM
+	case ECOMM: return "communication error on send";
+#endif
+#ifdef ECONNABORTED
+	case ECONNABORTED: return "software caused connection abort";
+#endif
+#ifdef ECONNREFUSED
+	case ECONNREFUSED: return "connection refused";
+#endif
+#ifdef ECONNRESET
+	case ECONNRESET: return "connection reset by peer";
+#endif
+#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
+	case EDEADLK: return "resource deadlock avoided";
+#endif
+#if defined(EDEADLOCK) && (!defined(EDEADLK) || (EDEADLOCK != EDEADLK))
+	case EDEADLOCK: return "resource deadlock avoided";
+#endif
+#ifdef EDESTADDRREQ
+	case EDESTADDRREQ: return "destination address required";
+#endif
+#ifdef EDIRTY
+	case EDIRTY: return "mounting a dirty fs w/o force";
+#endif
+#ifdef EDOM
+	case EDOM: return "math argument out of range";
+#endif
+#ifdef EDOTDOT
+	case EDOTDOT: return "cross mount point";
+#endif
+#ifdef EDQUOT
+	case EDQUOT: return "disk quota exceeded";
+#endif
+#ifdef EDUPPKG
+	case EDUPPKG: return "duplicate package name";
+#endif
+#ifdef EEXIST
+	case EEXIST: return "file already exists";
+#endif
+#ifdef EFAULT
+	case EFAULT: return "bad address in system call argument";
+#endif
+#ifdef EFBIG
+	case EFBIG: return "file too large";
+#endif
+#ifdef EHOSTDOWN
+	case EHOSTDOWN: return "host is down";
+#endif
+#ifdef EHOSTUNREACH
+	case EHOSTUNREACH: return "host is unreachable";
+#endif
+#if defined(EIDRM) && (!defined(EINPROGRESS) || (EIDRM != EINPROGRESS))
+	case EIDRM: return "identifier removed";
+#endif
+#ifdef EINIT
+	case EINIT: return "initialization error";
+#endif
+#ifdef EINPROGRESS
+	case EINPROGRESS: return "operation now in progress";
+#endif
+#ifdef EINTR
+	case EINTR: return "interrupted system call";
+#endif
+#ifdef EINVAL
+	case EINVAL: return "invalid argument";
+#endif
+#ifdef EIO
+	case EIO: return "I/O error";
+#endif
+#ifdef EISCONN
+	case EISCONN: return "socket is already connected";
+#endif
+#ifdef EISDIR
+	case EISDIR: return "illegal operation on a directory";
+#endif
+#ifdef EISNAME
+	case EISNAM: return "is a name file";
+#endif
+#ifdef ELBIN
+	case ELBIN: return "ELBIN";
+#endif
+#ifdef EL2HLT
+	case EL2HLT: return "level 2 halted";
+#endif
+#ifdef EL2NSYNC
+	case EL2NSYNC: return "level 2 not synchronized";
+#endif
+#ifdef EL3HLT
+	case EL3HLT: return "level 3 halted";
+#endif
+#ifdef EL3RST
+	case EL3RST: return "level 3 reset";
+#endif
+#ifdef ELIBACC
+	case ELIBACC: return "can not access a needed shared library";
+#endif
+#ifdef ELIBBAD
+	case ELIBBAD: return "accessing a corrupted shared library";
+#endif
+#ifdef ELIBEXEC
+	case ELIBEXEC: return "can not exec a shared library directly";
+#endif
+#ifdef ELIBMAX
+	case ELIBMAX: return
+		"attempting to link in more shared libraries than system limit";
+#endif
+#ifdef ELIBSCN
+	case ELIBSCN: return ".lib section in a.out corrupted";
+#endif
+#ifdef ELNRNG
+	case ELNRNG: return "link number out of range";
+#endif
+#if defined(ELOOP) && (!defined(ENOENT) || (ELOOP != ENOENT))
+	case ELOOP: return "too many levels of symbolic links";
+#endif
+#ifdef EMFILE
+	case EMFILE: return "too many open files";
+#endif
+#ifdef EMLINK
+	case EMLINK: return "too many links";
+#endif
+#ifdef EMSGSIZE
+	case EMSGSIZE: return "message too long";
+#endif
+#ifdef EMULTIHOP
+	case EMULTIHOP: return "multihop attempted";
+#endif
+#ifdef ENAMETOOLONG
+	case ENAMETOOLONG: return "file name too long";
+#endif
+#ifdef ENAVAIL
+	case ENAVAIL: return "not available";
+#endif
+#ifdef ENET
+	case ENET: return "ENET";
+#endif
+#ifdef ENETDOWN
+	case ENETDOWN: return "network is down";
+#endif
+#ifdef ENETRESET
+	case ENETRESET: return "network dropped connection on reset";
+#endif
+#ifdef ENETUNREACH
+	case ENETUNREACH: return "network is unreachable";
+#endif
+#ifdef ENFILE
+	case ENFILE: return "file table overflow";
+#endif
+#ifdef ENOANO
+	case ENOANO: return "anode table overflow";
+#endif
+#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
+	case ENOBUFS: return "no buffer space available";
+#endif
+#ifdef ENOCSI
+	case ENOCSI: return "no CSI structure available";
+#endif
+#if defined(ENODATA) && (!defined(ECONNREFUSED) || (ENODATA != ECONNREFUSED))
+	case ENODATA: return "no data available";
+#endif
+#ifdef ENODEV
+	case ENODEV: return "no such device";
+#endif
+#ifdef ENOENT
+	case ENOENT: return "no such file or directory";
+#endif
+#ifdef ENOEXEC
+	case ENOEXEC: return "exec format error";
+#endif
+#ifdef ENOLCK
+	case ENOLCK: return "no locks available";
+#endif
+#ifdef ENOLINK
+	case ENOLINK: return "link has be severed";
+#endif
+#ifdef ENOMEM
+	case ENOMEM: return "not enough memory";
+#endif
+#ifdef ENOMSG
+	case ENOMSG: return "no message of desired type";
+#endif
+#ifdef ENONET
+	case ENONET: return "machine is not on the network";
+#endif
+#ifdef ENOPKG
+	case ENOPKG: return "package not installed";
+#endif
+#ifdef ENOPROTOOPT
+	case ENOPROTOOPT: return "bad proocol option";
+#endif
+#ifdef ENOSPC
+	case ENOSPC: return "no space left on device";
+#endif
+#if defined(ENOSR) && (!defined(ENAMETOOLONG) || (ENAMETOOLONG != ENOSR))
+	case ENOSR: return "out of stream resources";
+#endif
+#if defined(ENOSTR) && (!defined(ENOTTY) || (ENOTTY != ENOSTR))
+	case ENOSTR: return "not a stream device";
+#endif
+#ifdef ENOSYM
+	case ENOSYM: return "unresolved symbol name";
+#endif
+#ifdef ENOSYS
+	case ENOSYS: return "function not implemented";
+#endif
+#ifdef ENOTBLK
+	case ENOTBLK: return "block device required";
+#endif
+#ifdef ENOTCONN
+	case ENOTCONN: return "socket is not connected";
+#endif
+#ifdef ENOTDIR
+	case ENOTDIR: return "not a directory";
+#endif
+#if defined(ENOTEMPTY) && (!defined(EEXIST) || (ENOTEMPTY != EEXIST))
+	case ENOTEMPTY: return "directory not empty";
+#endif
+#ifdef ENOTNAM
+	case ENOTNAM: return "not a name file";
+#endif
+#ifdef ENOTSOCK
+	case ENOTSOCK: return "socket operation on non-socket";
+#endif
+#ifdef ENOTSUP
+	case ENOTSUP: return "operation not supported";
+#endif
+#ifdef ENOTTY
+	case ENOTTY: return "inappropriate device for ioctl";
+#endif
+#ifdef ENOTUNIQ
+	case ENOTUNIQ: return "name not unique on network";
+#endif
+#ifdef ENXIO
+	case ENXIO: return "no such device or address";
+#endif
+#if defined(EOPNOTSUPP) &&  (!defined(ENOTSUP) || (ENOTSUP != EOPNOTSUPP))
+	case EOPNOTSUPP: return "operation not supported on socket";
+#endif
+#ifdef EPERM
+	case EPERM: return "not owner";
+#endif
+#if defined(EPFNOSUPPORT) && (!defined(ENOLCK) || (ENOLCK != EPFNOSUPPORT))
+	case EPFNOSUPPORT: return "protocol family not supported";
+#endif
+#ifdef EPIPE
+	case EPIPE: return "broken pipe";
+#endif
+#ifdef EPROCLIM
+	case EPROCLIM: return "too many processes";
+#endif
+#ifdef EPROCUNAVAIL
+	case EPROCUNAVAIL: return "bad procedure for program";
+#endif
+#ifdef EPROGMISMATCH
+	case EPROGMISMATCH: return "program version wrong";
+#endif
+#ifdef EPROGUNAVAIL
+	case EPROGUNAVAIL: return "RPC program not available";
+#endif
+#ifdef EPROTO
+	case EPROTO: return "protocol error";
+#endif
+#ifdef EPROTONOSUPPORT
+	case EPROTONOSUPPORT: return "protocol not suppored";
+#endif
+#ifdef EPROTOTYPE
+	case EPROTOTYPE: return "protocol wrong type for socket";
+#endif
+#ifdef ERANGE
+	case ERANGE: return "math result unrepresentable";
+#endif
+#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
+	case EREFUSED: return "EREFUSED";
+#endif
+#ifdef EREMCHG
+	case EREMCHG: return "remote address changed";
+#endif
+#ifdef EREMDEV
+	case EREMDEV: return "remote device";
+#endif
+#ifdef EREMOTE
+	case EREMOTE: return "pathname hit remote file system";
+#endif
+#ifdef EREMOTEIO
+	case EREMOTEIO: return "remote i/o error";
+#endif
+#ifdef EREMOTERELEASE
+	case EREMOTERELEASE: return "EREMOTERELEASE";
+#endif
+#ifdef EROFS
+	case EROFS: return "read-only file system";
+#endif
+#ifdef ERPCMISMATCH
+	case ERPCMISMATCH: return "RPC version is wrong";
+#endif
+#ifdef ERREMOTE
+	case ERREMOTE: return "object is remote";
+#endif
+#ifdef ESHUTDOWN
+	case ESHUTDOWN: return "can't send afer socket shutdown";
+#endif
+#ifdef ESOCKTNOSUPPORT
+	case ESOCKTNOSUPPORT: return "socket type not supported";
+#endif
+#ifdef ESPIPE
+	case ESPIPE: return "invalid seek";
+#endif
+#ifdef ESRCH
+	case ESRCH: return "no such process";
+#endif
+#ifdef ESRMNT
+	case ESRMNT: return "srmount error";
+#endif
+#ifdef ESTALE
+	case ESTALE: return "stale remote file handle";
+#endif
+#ifdef ESUCCESS
+	case ESUCCESS: return "Error 0";
+#endif
+#if defined(ETIME) && (!defined(ELOOP) || (ETIME != ELOOP))
+	case ETIME: return "timer expired";
+#endif
+#if defined(ETIMEDOUT) && (!defined(ENOSTR) || (ETIMEDOUT != ENOSTR))
+	case ETIMEDOUT: return "connection timed out";
+#endif
+#ifdef ETOOMANYREFS
+	case ETOOMANYREFS: return "too many references: can't splice";
+#endif
+#ifdef ETXTBSY
+	case ETXTBSY: return "text file or pseudo-device busy";
+#endif
+#ifdef EUCLEAN
+	case EUCLEAN: return "structure needs cleaning";
+#endif
+#ifdef EUNATCH
+	case EUNATCH: return "protocol driver not attached";
+#endif
+#ifdef EUSERS
+	case EUSERS: return "too many users";
+#endif
+#ifdef EVERSION
+	case EVERSION: return "version mismatch";
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
+	case EWOULDBLOCK: return "operation would block";
+#endif
+#ifdef EXDEV
+	case EXDEV: return "cross-domain link";
+#endif
+#ifdef EXFULL
+	case EXFULL: return "message tables full";
+#endif
+	default:
+#ifdef NO_STRERROR
+	    return "unknown POSIX error";
+#else
+	    return strerror(errno);
+#endif
+    }
+}
+
+/*
+ * end of excerpt from tcl8.0.X/generic/tclPosixStr.c
+ */
+
+/*
  * stolen from exp_log.c - this function is called from the Expect library
  * but the one that the library supplies calls Tcl functions.  So we supply
  * our own.
@@ -1859,7 +2321,7 @@ char *argv[];	/* some compiler complains
 		 * (line 512) does not generate a warning !
 		 */
 
-		expErrnoMsgSet(Tcl_ErrnoMsg);
+		expErrnoMsgSet(Exp_ErrnoMsg);
 	}
 
 	if (!file || !argv) sysreturn(EINVAL);
@@ -1949,7 +2411,7 @@ when trapping, see below in child half o
 		exp_debuglog("parent: waiting for sync byte\r\n");
 		cc = read(sync_fds[0],&sync_byte,1);
 		if (cc == -1) {
-		  exp_errorlog("parent sync byte read: %s\r\n",Tcl_ErrnoMsg(errno));
+		  exp_errorlog("parent sync byte read: %s\r\n",expErrnoMsg(errno));
 		  return -1;
 		}
 
@@ -1963,7 +2425,7 @@ when trapping, see below in child half o
 		exp_debuglog("parent: telling child to go ahead\r\n");
 		cc = write(sync2_fds[1]," ",1);
 		if (cc == -1) {
-		  exp_errorlog("parent sync byte write: %s\r\n",Tcl_ErrnoMsg(errno));
+		  exp_errorlog("parent sync byte write: %s\r\n",expErrnoMsg(errno));
 		  return -1;
 		}
 
@@ -2060,7 +2522,7 @@ when trapping, see below in child half o
 	    if (0 > (exp_pty[1] = exp_getptyslave(exp_ttycopy,exp_ttyinit,
 						exp_stty_init))) {
 		restore_error_fd
-		fprintf(stderr,"open(slave pty): %s\n",Tcl_ErrnoMsg(errno));
+		fprintf(stderr,"open(slave pty): %s\n",expErrnoMsg(errno));
 		exit(-1);
 	    }
 	    /* sanity check */
@@ -2112,7 +2574,7 @@ when trapping, see below in child half o
  	(void) close(0);
  	if (open("/dev/tty", O_RDWR) < 0) {
 		restore_error_fd
- 		fprintf(stderr,"open(/dev/tty): %s\r\n",Tcl_ErrnoMsg(errno));
+ 		fprintf(stderr,"open(/dev/tty): %s\r\n",expErrnoMsg(errno));
  		exit(-1);
  	}
  	(void) close(1);
@@ -2132,7 +2594,7 @@ when trapping, see below in child half o
 	 */
 	if ((pid = fork()) == -1) {
 		restore_error_fd
-		fprintf(stderr,"second fork: %s\r\n",Tcl_ErrnoMsg(errno));
+		fprintf(stderr,"second fork: %s\r\n",expErrnoMsg(errno));
 		exit(-1);
 	}
 
@@ -2195,7 +2657,7 @@ when trapping, see below in child half o
 	cc = write(sync_fds[1]," ",1);
 	if (cc == -1) {
 		restore_error_fd
-		fprintf(stderr,"child: sync byte write: %s\r\n",Tcl_ErrnoMsg(errno));
+		fprintf(stderr,"child: sync byte write: %s\r\n",expErrnoMsg(errno));
 		exit(-1);
 	}
 	close(sync_fds[1]);
@@ -2204,7 +2666,7 @@ when trapping, see below in child half o
 	cc = read(sync2_fds[0],&sync_byte,1);
 	if (cc == -1) {
 		restore_error_fd
-		exp_errorlog("child: sync byte read: %s\r\n",Tcl_ErrnoMsg(errno));
+		exp_errorlog("child: sync byte read: %s\r\n",expErrnoMsg(errno));
 		exit(-1);
 	}
 	close(sync2_fds[0]);
--- expect.h.orig
+++ expect.h
@@ -258,6 +258,46 @@ typedef long LONG;
 typedef struct Tcl_RegExp_ *Tcl_RegExp;
 
 /*
+ * The following declarations either map ckalloc and ckfree to
+ * malloc and free, or they map them to procedures with all sorts
+ * of debugging hooks defined in tclCkalloc.c.
+ */
+
+#ifdef TCL_MEM_DEBUG
+
+#  define Tcl_Alloc(x) Tcl_DbCkalloc(x, __FILE__, __LINE__)
+#  define Tcl_Free(x)  Tcl_DbCkfree(x, __FILE__, __LINE__)
+#  define Tcl_Realloc(x,y) Tcl_DbCkrealloc((x), (y),__FILE__, __LINE__)
+#  define ckalloc(x) Tcl_DbCkalloc(x, __FILE__, __LINE__)
+#  define ckfree(x)  Tcl_DbCkfree(x, __FILE__, __LINE__)
+#  define ckrealloc(x,y) Tcl_DbCkrealloc((x), (y),__FILE__, __LINE__)
+
+#else
+
+/*
+ * If USE_TCLALLOC is true, then we need to call Tcl_Alloc instead of
+ * the native malloc/free.  The only time USE_TCLALLOC should not be
+ * true is when compiling the Tcl/Tk libraries on Unix systems.  In this
+ * case we can safely call the native malloc/free directly as a performance
+ * optimization.
+ */
+
+#  if USE_TCLALLOC
+#     define ckalloc(x) Tcl_Alloc(x)
+#     define ckfree(x) Tcl_Free(x)
+#     define ckrealloc(x,y) Tcl_Realloc(x,y)
+#  else
+#     define ckalloc(x) malloc(x)
+#     define ckfree(x)  free(x)
+#     define ckrealloc(x,y) realloc(x,y)
+#  endif
+#  define Tcl_DumpActiveMemory(x)
+#  define Tcl_ValidateAllMemory(x,y)
+
+#endif /* !TCL_MEM_DEBUG */
+
+
+/*
  * These function have been renamed. The old names are deprecated, but we
  * define these macros for backwards compatibilty.
  */
--- example/chesslib.c.orig
+++ example/chesslib.c
@@ -1,6 +1,8 @@
 /* chesslib.c - test expectlib */
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include "expect.h"
 
 timedout()
--- example/Makefile.orig
+++ example/Makefile
@@ -1,4 +1,4 @@
-EXPVERSION = 5.31
+EXPVERSION = 5.45
 
 CC = gcc
 CPLUSPLUS = g++
