2001-04-09 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
[bpt/guile.git] / doc / expect.texi
CommitLineData
38a93523
NJ
1@node Expect
2@chapter Expect
3
4The macros in this section are made available with:
5
6@smalllisp
7(use-modules (ice-9 expect))
8@end smalllisp
9
10@code{expect} is a macro for selecting actions based on the output from
11a port. The name comes from a tool of similar functionality by Don Libes.
12Actions can be taken when a particular string is matched, when a timeout
13occurs, or when end-of-file is seen on the port. The @code{expect} macro
14is described below; @code{expect-strings} is a front-end to @code{expect}
15based on regexec (see the regular expression documentation).
16
17@defmac expect-strings clause @dots{}
18By default, @code{expect-strings} will read from the current input port.
19The first term in each clause consists of an expression evaluating to
20a string pattern (regular expression). As characters
21are read one-by-one from the port, they are accumulated in a buffer string
22which is matched against each of the patterns. When a
23pattern matches, the remaining expression(s) in
24the clause are evaluated and the value of the last is returned. For example:
25
26@smalllisp
27(with-input-from-file "/etc/passwd"
28 (lambda ()
29 (expect-strings
30 ("^nobody" (display "Got a nobody user.\n")
31 (display "That's no problem.\n"))
32 ("^daemon" (display "Got a daemon user.\n")))))
33@end smalllisp
34
35The regular expression is compiled with the @code{REG_NEWLINE} flag, so
36that the ^ and $ anchors will match at any newline, not just at the start
37and end of the string.
38
39There are two other ways to write a clause:
40
41The expression(s) to evaluate
42can be omitted, in which case the result of the regular expression match
43(converted to strings, as obtained from regexec with match-pick set to "")
44will be returned if the pattern matches.
45
46The symbol @code{=>} can be used to indicate that the expression is a
47procedure which will accept the result of a successful regular expression
48match. E.g.,
49
50@smalllisp
51("^daemon" => write)
52("^d\\(aemon\\)" => (lambda args (for-each write args)))
53("^da\\(em\\)on" => (lambda (all sub)
54 (write all) (newline)
55 (write sub) (newline)))
56@end smalllisp
57
58The order of the substrings corresponds to the order in which the
59opening brackets occur.
60
61A number of variables can be used to control the behaviour
62of @code{expect} (and @code{expect-strings}).
63Most have default top-level bindings to the value @code{#f},
64which produces the default behaviour.
65They can be redefined at the
66top level or locally bound in a form enclosing the expect expression.
67
68@table @code
69@item expect-port
70A port to read characters from, instead of the current input port.
71@item expect-timeout
72@code{expect} will terminate after this number of
73seconds, returning @code{#f} or the value returned by expect-timeout-proc.
74@item expect-timeout-proc
75A procedure called if timeout occurs. The procedure takes a single argument:
76the accumulated string.
77@item expect-eof-proc
78A procedure called if end-of-file is detected on the input port. The
79procedure takes a single argument: the accumulated string.
80@item expect-char-proc
81A procedure to be called every time a character is read from the
82port. The procedure takes a single argument: the character which was read.
83@item expect-strings-compile-flags
84Flags to be used when compiling a regular expression, which are passed
85to @code{make-regexp} @xref{Regexp Functions}. The default value
86is @code{regexp/newline}.
87@item expect-strings-exec-flags
88Flags to be used when executing a regular expression, which are
89passed to regexp-exec @xref{Regexp Functions}.
90The default value is @code{regexp/noteol}, which prevents @code{$}
91from matching the end of the string while it is still accumulating,
92but still allows it to match after a line break or at the end of file.
93@end table
94
95Here's an example using all of the variables:
96
97@smalllisp
98(let ((expect-port (open-input-file "/etc/passwd"))
99 (expect-timeout 1)
100 (expect-timeout-proc
101 (lambda (s) (display "Times up!\n")))
102 (expect-eof-proc
103 (lambda (s) (display "Reached the end of the file!\n")))
104 (expect-char-proc display)
105 (expect-strings-compile-flags (logior regexp/newline regexp/icase))
106 (expect-strings-exec-flags 0))
107 (expect-strings
108 ("^nobody" (display "Got a nobody user\n"))))
109@end smalllisp
110@end defmac
111
112@defmac expect clause @dots{}
113@code{expect} is used in the same way as @code{expect-strings},
114but tests are specified not as patterns, but as procedures. The
115procedures are called in turn after each character is read from the
116port, with two arguments: the value of the accumulated string and
117a flag to indicate whether end-of-file has been reached. The flag
118will usually be @code{#f}, but if end-of-file is reached, the procedures
119are called an additional time with the final accumulated string and
120@code{#t}.
121
122The test is successful if the procedure returns a non-false value.
123
124If the @code{=>} syntax is used, then if the test succeeds it must return
125a list containing the arguments to be provided to the corresponding
126expression.
127
128In the following example, a string will only be matched at the beginning
129of the file:
130
131@smalllisp
132(let ((expect-port (open-input-file "/etc/passwd")))
133 (expect
134 ((lambda (s eof?) (string=? s "fnord!"))
135 (display "Got a nobody user!\n"))))
136@end smalllisp
137
138The control variables described for @code{expect-strings} also
139influence the behaviour of @code{expect}, with the exception of
140variables whose names begin with @code{expect-strings-}.
141@end defmac