On Thu, Jul 23, 2009 at 07:04:56PM +0200, Tobias Gasser wrote: 
> i just applied the patch from the book for 4.4.0 in chapter 5: 
> hunk #1 succeeded at 6467 (offset 97 lines).  
> 
> no real problems during compiling the book.  

I've only compiled the temp-toolchain so far but I haven't had any issues.
I took the liberty of diffing the expect spawn patch against 5.43.0, all 
those offsets are starting to look a bit messy. The patch is attached.
Submitted By: LFS Book <lfs-b...@linuxfromscratch.org>
Date: 2003-10-05
Initial Package Version: 5.38
Origin: Redhat RPM (Patch by HJ Lu)
Description: NA
--- expect-5.43-orig/exp_chan.c 2005-02-08 02:01:20.000000000 +0000
+++ expect-5.43/exp_chan.c      2009-07-24 02:18:01.612058155 +0100
@@ -622,6 +622,7 @@
     esPtr->buffer = Tcl_NewStringObj("",0);
     Tcl_IncrRefCount(esPtr->buffer);
     esPtr->umsize = exp_default_match_max;
+    esPtr->umsize_changed = exp_default_match_max_changed;
     /* this will reallocate object with an appropriate sized buffer */
     expAdjust(esPtr);
 
--- expect-5.43-orig/exp_command.h      2004-07-30 16:35:28.000000000 +0100
+++ expect-5.43/exp_command.h   2009-07-24 02:18:01.613058109 +0100
@@ -30,6 +30,7 @@
 EXTERN char *          exp_get_var _ANSI_ARGS_((Tcl_Interp *,char *));
 
 EXTERN int exp_default_match_max;
+EXTERN int exp_default_match_max_changed;
 EXTERN int exp_default_parity;
 EXTERN int exp_default_rm_nulls;
 EXTERN int exp_default_close_on_eof;
@@ -103,6 +104,7 @@
     int msize;         /* # of bytes that buffer can hold (max) */
     int umsize;                /* # of bytes (min) that is guaranteed to match 
*/
                        /* this comes from match_max command */
+    int umsize_changed;        /* is umsize changed by user?  */
     int printed;       /* # of bytes written to stdout (if logging on) */
                         /* but not actually returned via a match yet */
     int echoed;                /* additional # of bytes (beyond "printed" 
above) */
--- expect-5.43-orig/expect.c   2004-07-07 00:26:02.000000000 +0100
+++ expect-5.43/expect.c        2009-07-24 02:18:01.614807080 +0100
@@ -41,8 +41,17 @@
 #include "tcldbg.h"
 #endif
 
+/* The initial length is 2000. We increment it by 2000. The maximum
+   is 8MB (0x800000).  */
+#define EXP_MATCH_MAX          2000
+#define EXP_MATCH_INC          2000
+#define EXP_MATCH_STEP_LIMIT   0x700000
+#define EXP_MATCH_LIMIT                0x800000
+#define EXP_MATCH_LIMIT_QUOTE  "0x800000"
+
 /* initial length of strings that we can guarantee patterns can match */
-int exp_default_match_max =    2000;
+int exp_default_match_max =    EXP_MATCH_MAX;
+int exp_default_match_max_changed = 0;
 #define INIT_EXPECT_TIMEOUT_LIT        "10"    /* seconds */
 #define INIT_EXPECT_TIMEOUT    10      /* seconds */
 int exp_default_parity =       TRUE;
@@ -1619,6 +1628,76 @@
     return newsize;
 }
 
+/* returns # of bytes until we see a newline at the end or EOF.  */
+/*ARGSUSED*/
+static int
+expReadNewLine(interp,esPtr,save_flags) /* INTL */
+Tcl_Interp *interp;
+ExpState *esPtr;
+int save_flags;
+{
+    int size;
+    int exp_size;
+    int full_size;
+    int count;
+    char *str;
+
+    count = 0;
+    for (;;) {
+       exp_size = expSizeGet(esPtr);
+
+       /* When we reach the limit, we will only read one char at a
+          time.  */
+       if (esPtr->umsize >= EXP_MATCH_STEP_LIMIT)
+           size = TCL_UTF_MAX;
+       else
+           size = exp_size;
+
+       if (exp_size + TCL_UTF_MAX >= esPtr->msize) {
+           if (esPtr->umsize >= EXP_MATCH_LIMIT) {
+               expDiagLogU("WARNING: interact buffer is full. probably your 
program\r\n");
+               expDiagLogU("is not interactive or has a very long output line. 
The\r\n");
+               expDiagLogU("current limit is " EXP_MATCH_LIMIT_QUOTE ".\r\n");
+               expDiagLogU("Dumping first half of buffer in order to 
continue\r\n");
+               expDiagLogU("Recommend you enlarge the buffer.\r\n");
+               exp_buffer_shuffle(interp,esPtr,save_flags,EXPECT_OUT,"expect");
+               return count;
+           }
+           else {
+               esPtr->umsize += EXP_MATCH_INC;
+               expAdjust(esPtr);
+           }
+       }
+
+       full_size = esPtr->msize - (size / TCL_UTF_MAX);
+       size = Tcl_ReadChars(esPtr->channel,
+                       esPtr->buffer,
+                       full_size,
+                       1 /* append */);
+       if (size > 0) {
+           count += size;
+           /* We try again if there are more to read and we haven't
+              seen a newline at the end. */
+           if (size == full_size) {
+               str = Tcl_GetStringFromObj(esPtr->buffer, &size);
+               if (str[size - 1] != '\n')
+                   continue;
+           }
+       }
+       else {
+           /* It is even trickier. We got an error from read. We have
+              to recover from it. Let's make sure the size of
+              buffer is correct. It can be corrupted. */
+           str = Tcl_GetString(esPtr->buffer);
+           Tcl_SetObjLength(esPtr->buffer, strlen(str));
+       }
+
+       break;
+    }
+
+    return count;
+}
+
 /* returns # of bytes read or (non-positive) error of form EXP_XXX */
 /* returns 0 for end of file */
 /* If timeout is non-zero, set an alarm before doing the read, else assume */
@@ -1633,6 +1712,8 @@
 {
     int cc = EXP_TIMEOUT;
     int size = expSizeGet(esPtr);
+    int full_size;
+    int count;
 
     if (size + TCL_UTF_MAX >= esPtr->msize) 
        exp_buffer_shuffle(interp,esPtr,save_flags,EXPECT_OUT,"expect");
@@ -1649,11 +1730,43 @@
     }
 #endif
 
-    
+    /* FIXME: If we ask less than what is available in the tcl buffer
+       when tcl has seen EOF, we will throw away the remaining data
+       since the next read will get EOF. Since expect is line-oriented,
+       we exand our buffer to get EOF or the next newline at the end of
+       the input buffer. I don't know if it is the right fix.  H.J. */
+    count = 0;
+    full_size = esPtr->msize - (size / TCL_UTF_MAX);
     cc = Tcl_ReadChars(esPtr->channel,
-           esPtr->buffer,
-           esPtr->msize - (size / TCL_UTF_MAX),
-           1 /* append */);
+               esPtr->buffer,
+               full_size,
+               1 /* append */);
+    if (cc > 0) {
+       count += cc;
+       /* It gets very tricky. There are more to read. We will expand
+          our buffer and get EOF or a newline at the end unless the
+          buffer length has been changed.  */
+       if (cc == full_size) {
+           char *str;
+           str = Tcl_GetStringFromObj(esPtr->buffer, &size);
+           if (str[size - 1] != '\n') {
+               if (esPtr->umsize_changed) {
+                   char buf[20];       /* big enough for 64bit int in hex.  */
+                   snprintf(buf,sizeof(buf),"0x%x", esPtr->umsize);
+                   expDiagLogU("WARNING: interact buffer is not large enough 
to hold\r\n");
+                   expDiagLogU("all output. probably your program is not 
interactive or\r\n");
+                   expDiagLogU("has a very long output line. The current limit 
is ");
+                   expDiagLogU(buf);
+                   expDiagLogU(".\r\n");
+               }
+               else {
+                   cc = expReadNewLine(interp,esPtr,save_flags);
+                   if (cc > 0)
+                       count += cc;
+               }
+           }
+       }
+    }
     i_read_errno = errno;
 
 #ifdef SIMPLE_EVENT
@@ -1674,7 +1787,7 @@
        }
     }
 #endif
-    return cc; 
+    return count > 0 ? count : cc;
 }
 
 /*
@@ -2751,8 +2864,14 @@
        return(TCL_ERROR);
     }
 
-    if (Default) exp_default_match_max = size;
-    else esPtr->umsize = size;
+    if (Default) {
+       exp_default_match_max = size;
+       exp_default_match_max_changed = 1;
+    }
+    else {
+       esPtr->umsize = size;
+       esPtr->umsize_changed = 1;
+    }
 
     return(TCL_OK);
 }

Attachment: pgpxqHOZvck7O.pgp
Description: PGP signature

-- 
http://linuxfromscratch.org/mailman/listinfo/lfs-dev
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to