This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: expect module


| Second, I don't understand the usage of `$' in regular expressions
| here.  Or, rather, I think I understand it, but I don't like it.  The
| manual implies that $ will match newlines.  In reality it matches the
| end of any string -- rendering it useless for my purposes.  The
| appended program demonstrates the problem: the regex is matched
| individually for each character of /etc/passwd.  This behavior
| suprised me; I think it would be more natural if a `$' in an expect
| regex matched only a newline.  (In this case it might be possible for
| expect-strings to automatically notice when line-by-line mode could be
| entered.  (But an explicit flag is good enough for me.))
| 
| Tom
| 
| (use-modules (ice-9 expect))
| (with-input-from-file "/etc/passwd"
|   (lambda ()
|     (while (char-ready?)
| 	   (expect-strings
| 	    ("^.*$"
| 	     => (lambda all
| 		  (display all)
| 		  (newline)))))))

I think this fixes the problem.  It makes an incompatible change to 
the underlying "expect" macro: the match procedures take an extra
argument which gets the next char peeked from the stream.

--- /home/ghouston/guile-core-nonstdio1/ice-9/expect.scm	Tue Oct 20 18:09:20 1998
+++ ./expect.scm	Mon Mar 15 20:37:33 1999
@@ -37,6 +37,7 @@
 (defmacro-public expect clauses
   (let ((s (gentemp))
 	(c (gentemp))
+	(nc (gentemp))
 	(port (gentemp))
 	(timeout (gentemp)))
     `(let ((,s "")
@@ -57,7 +58,8 @@
 	     (if expect-timeout-proc
 		 (expect-timeout-proc ,s)
 		 #f)
-	     (let ((,c (read-char ,port)))
+	     (let ((,c (read-char ,port))
+		   (,nc (peek-char ,port)))
 	       (if expect-char-proc
 		   (expect-char-proc ,c))
 	       (cond ((eof-object? ,c)
@@ -78,7 +80,7 @@
 			      (cdr tests)
 			      (cdr exprs)
 			      (cons
-			       `((,(car tests) ,s)
+			       `((,(car tests) ,s ,nc)
 				 ,@(cond ((null? (car exprs))
 					  '())
 					 ((eq? (caar exprs) '=>)
@@ -90,7 +92,7 @@
 							 (list (car exprs))
 							 #f)
 					      `((apply ,(cadar exprs)
-						       (,(car tests) ,s)))))
+						       (,(car tests) ,s ,nc)))))
 					 (else 
 					  (car exprs))))
 			       body)))))
@@ -112,8 +114,10 @@
 				(cons `(,rxname (make-regexp ,(car tests)
 							     regexp/newline))
 				      defs)
-				(cons `((lambda (s)
-					  (expect-regexec ,rxname s))
+				(cons `((lambda (s next-char)
+					  (expect-regexec
+					   ,rxname s
+					   (eof-object? next-char)))
 					,@(car exprs))
 				      body))))))))
 
@@ -130,8 +134,8 @@
 			     relative))))))
 
 ;;; convert a match object to a list of strings, for the => syntax.
-(define-public (expect-regexec rx s)
-  (let ((match (regexp-exec rx s)))
+(define-public (expect-regexec rx s eof-next?)
+  (let ((match (regexp-exec rx s 0 (if eof-next? 0 regexp/noteol))))
     (if match
 	(do ((i (- (match:count match) 1) (- i 1))
 	     (result '() (cons (match:substring match i) result)))