unix-other.texi 4.7 KB

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