From: libes@cme.nist.gov (Don Libes)
Newsgroups: comp.lang.tcl
Subject: Expect: status report given and advice sought
Date: 11 Jan 93 21:27:16 GMT
Organization: National Institute of Standards and Technology

A number of people have asked me about Tcl 6.5 and Expect.  No, they
don't work together.  I believe John will issue another version (or
patch) soon, so I'm not providing a patch for Expect until then.

I've completed revisions to Expect to make it work with Tk - I admit
it - it was more work than I originally thought!  I've been getting
pressure to use autoconf so I will probably try and integrate that
before I officially release this new version.  At the same time, I
figured I'd ask if anyone had any requests they've been holding back
for reasons of not introducing incompatibilities - mainly because I
want to introduce one...

In particular, I would like to remove the expect's ability to
associate each action with lists of patterns.  Instead, each action
will be limited to a single pattern.  "lists of patterns" are very
confusing and it seems pointless since the "-re" option does a much
better job providing alternation directly.  I should've removed it
when the "-re" option was added, but I didn't realize at the time how
efficient and easy regexps are.  (Yes, they have their quoting
problems, too, but they're much more understandable.)

In part I suspect everyone feels similarly, but what I'm wondering is:
do people have a significant investment in code that depends on the
current syntax.  I've always imagined that most people immediately
turn to regexp for even moderately complex patterns.

If this is the case, it may not bother many people at all.  Most
simple things will work as before including:

	expect foobar
	expect "foobar"
	expect "foo\ bar"

However, some things won't work as before.  For example, the following
will behave differently - now the braces will be considered as part of
the pattern.

	expect "{foo bar}"

Here are my choices:

0) I'd really like to dump the "list of patterns" feature entirely.
However, if people feel strongly enough, I'm willing to do this:

1) Users that want the old behavior must call expect_version with an
appropriately-old version number.  Else you get the new behavior.
This would allow at worst a one-line change to scripts.

2) Have a flag (haven't thought of a good name yet) that says "the
following token is a list of glob-style patterns".

3) Both 1 and 2.

Note that I don't take this step lightly.  This will mean a change to
the major version number of Expect (3 to 4).  John tells me that
incompatibilities introduced by 7.0 may be very small, but it may make
my indecision a moot point.

The remaining changes to Expect should not introduce any other
incompatibilities.  Here's a quick summary:

New commands
------------

getpid		returns pid of current process.

send_log	Sends string to log file.

send_spawn	Alias for "send".  (Useful in environments where send
		is already used (i.e., Tk).

Old commands - new functionality
--------------------------------

spawn -noecho	Turns off echoing of spawn command and arguments to stdout.

interact	Now understand more than two processes, regexps, etc.
		Details below.

The remainder of this covers changes to interact.

-re

The following pattern is used as a regular expression.  The
side-effects are exactly as in "expect" except that the results are
written to the array "interact_out".

Regular expressions will match the longest string received.  In
particular, if a pattern can match the current input, it will do so
even if it is possible to extend the match by waiting for future
characters.

-input spawn_id

names a spawn_id from which to get input.  All following flags and
patterns apply to this input until another -input flag appears.

Two -inputs are assumed, $user_spawn_id and $spawn_id.  If one -input
is actually specified, it overrides $user_spawn_id.  If a second
-input is specified, it overrides $spawn_id.  Additional -input flags
may be specified.

-output spawn_id

directs all characters from the previous -input to the named spawn_id.
Multiple -output flags can appear after a single -input in which case
all characters are sent to all of the named spawn_ids.

If an -input flag appears with no -output flag, characters will be
discarded.

The two implied -inputs default to having their outputs specified as
$spawn_id and $user_spawn_id (in reverse).

If no -input appears, -output implies "-input $user_spawn_id".
(Similarly, with patterns that do not have a -input.)

-echo

sends characters that match the following pattern back to the spawn_id
that generated them as each character is read.  This may be useful
when the user needs to see feedback from partially typed patterns.

Note that if a pattern is being echoed but eventually fails to match,
the characters are sent to the spawned process.  If the spawned
process then echoes them, the user will see the characters twice.
-echo is probably only appropriate in situations where the user is
unlikely to not complete the pattern.  For example, the following
excerpt is from rftp, the recursive-ftp script, where the user is
prompted to enter ~g, ~p, or ~l, to get, put, or list the current
directory recursively.  These are so far away from the normal ftp
commands, that the user is unlikely to type ~ followed by anything
else, except mistakenly, in which case, they'll probably just ignore
the result anyway.

	interact {
		-echo ~g {getcurdirectory 1}
		-echo ~l {getcurdirectory 0}
		-echo ~p {putcurdirectory}
	}



-flush

sends characters that match the following pattern on to the -output
spawn_ids as characters are read.

This is useful when you wish to let a program echo back the pattern.
For example, the following might be used to monitor where a person is
dialing (a Hayes-style modem).  Each time "atd" is seen the script
logs the rest of the line.

	proc lognumber {} {
		interact -flush -f -re "(.*)\r" return
		puts $log "[exec date]: dialed $interact_out(1,string)"
	}

	interact -flush -f "atd" lognumber

-eof

is a special pattern matching EOF.  -eof applies to the most recent
-input or -output, except when -eof precedes all -input and -output
flags in which case it applies to all spawned process that do not have
an -eof flag.

A default -eof is provided with the action "return", so that interact
simply returns upon any EOFs.

-timeout <sec>

is a special pattern whose action is executed after <sec> seconds of
no unread characters.

If -timeout precedes all -input flags, it applies to all -input
flags, otherwise it applies to only the previous one.  -timeout
applies to the most recent -input, except when -timeout precedes all
-input flags in which case it applies to all spawned process that do
not have an -timeout flag.

Using different timeouts could be used to autologout users who have
not typed anything for awhile but who still get frequent system
messages.  For examples:

	interact -input $user_spawn_id -output $spawn_id -timeout 3600

By default, there is no timeout.  The Tcl variable "timeout" has no
affect on this timeout.

-i

Like other commands which take a -i flag, this introduces a
replacement for the current spawn_id when no other -input or -output
flags are used.
Newsgroups: comp.lang.tcl