expect.texi 5.6 KB

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