]> git.donarmstrong.com Git - lilypond.git/blob - guile18/doc/sources/unix-other.texi
Import guile-1.8 as multiple upstream tarball component
[lilypond.git] / guile18 / doc / sources / unix-other.texi
1 @node Other Unix
2 @chapter Other Unix-specific facilities
3
4 @menu
5 * Expect::              Expect, for pattern matching from a port.
6 @end menu
7
8 @node Expect
9 @section Expect: Pattern Matching from a Port
10
11 @code{expect} is a macro for selecting actions based on the output from
12 a port.  The name comes from a tool of similar functionality by Don Libes.
13 Actions can be taken when a particular string is matched, when a timeout
14 occurs, or when end-of-file is seen on the port.  The @code{expect} macro
15 is described below; @code{expect-strings} is a front-end to @code{expect}
16 based on regexec @xref{Regular expressions}.
17
18 Using these macros requires for now:
19 @smalllisp
20 (load-from-path "ice-9/expect")
21 @end smalllisp
22
23 @defun expect-strings clause @dots{}
24 By default, @code{expect-strings} will read from the current input port.
25 The first term in each clause consists of an expression evaluating to
26 a string pattern (regular expression).  As characters
27 are read one-by-one from the port, they are accumulated in a buffer string
28 which is matched against each of the patterns.  When a
29 pattern matches, the remaining expression(s) in
30 the clause are evaluated and the value of the last is returned.  For example:
31
32 @smalllisp
33 (with-input-from-file "/etc/passwd"
34   (lambda ()
35     (expect-strings
36       ("^nobody" (display "Got a nobody user.\n")
37                  (display "That's no problem.\n"))
38       ("^daemon" (display "Got a daemon user.\n")))))
39 @end smalllisp
40
41 The regular expression is compiled with the @code{REG_NEWLINE} flag, so
42 that the @code{^} and @code{$} anchors will match at any newline, not
43 just at the start
44 and end of the string.
45
46 There are two other ways to write a clause:
47
48 The expression(s) to evaluate on a match
49 can be omitted, in which case the result of the match
50 (converted to strings, as obtained from regexec with @var{match-pick}
51 set to @code{""}) will be returned if the pattern matches.
52
53 The symbol @code{=>} can be used to indicate that there is a single
54 expression to evaluate on a match, which must be a 
55 procedure which will accept the result of a successful match (converted
56 to strings, as obtained from regexec with @var{match-pick} set to
57 @code{""}).  E.g.,
58
59 @smalllisp
60 ("^daemon" => write)
61 ("^d\\(aemon\\)" => (lambda args (map write args)))
62 ("^da\\(em\\)on" => (lambda (all sub)
63                          (write all)
64                          (write sub)))
65 @end smalllisp
66
67 The order of the substrings corresponds to the order in which the
68 opening brackets occur in the regular expression.
69
70 A number of variables can be used to control the behaviour
71 of @code{expect} (and @code{expect-strings}).
72 By default they are all bound at the top level to
73 the value @code{#f}, which produces the default behaviour.
74 They can be redefined at the
75 top level or locally bound in a form enclosing the @code{expect} expression.
76
77 @table @code
78 @item expect-port
79 A port to read characters from, instead of the current input port.
80 @item expect-timeout
81 @code{expect} will terminate after this number of
82 seconds, returning @code{#f} or the value returned by
83 @code{expect-timeout-proc}.
84 @item expect-timeout-proc
85 A procedure called if timeout occurs.  The procedure takes a single argument:
86 the accumulated string.
87 @item expect-eof-proc
88 A procedure called if end-of-file is detected on the input port.  The
89 procedure takes a single argument: the accumulated string.
90 @item expect-char-proc
91 A procedure to be called every time a character is read from the
92 port.  The procedure takes a single argument: the character which was read.
93 @end table
94
95 Here'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
106      ("^nobody"  (display "Got a nobody user\n"))))
107 @end smalllisp
108 @end defun
109
110 @defun expect clause @dots{}
111 @code{expect} is used in the same way as @code{expect-strings},
112 but tests are specified not as patterns, but as procedures.  The
113 procedures are called in turn after each character is read from the
114 port, with the value of the accumulated string as the argument.  The
115 test is successful if the procedure returns a non-false value.
116
117 If the @code{=>} syntax is used, then if the test succeeds it must return
118 a list containing the arguments to be provided to the corresponding
119 expression.
120
121 In the following example, a string will only be matched at the beginning
122 of the file:
123 @smalllisp
124 (let ((expect-port (open-input-file "/etc/passwd")))
125   (expect
126      ((lambda (s) (string=? s "fnord!"))
127         (display "Got a nobody user!\n"))))
128 @end smalllisp
129
130 The control variables described for @code{expect-strings} can also
131 be used with @code{expect}.
132 @end defun