Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: tcp_expect can tag matches by string

I discovered I needed this yesterday.  This is going to be of no
interest to the vast majority of users.  (I originally said "the fast
majority" but it covers users who consider themselves slow.)

diff --git a/Doc/Zsh/tcpsys.yo b/Doc/Zsh/tcpsys.yo
index 1e26054..4067859 100644
--- a/Doc/Zsh/tcpsys.yo
+++ b/Doc/Zsh/tcpsys.yo
@@ -299,7 +299,7 @@ programme or function it is generally better to handle reading data by a
 more explicit method.
-xitem(tt(tcp_expect [ -q ] [ -p) var(var) tt(] [ -t ) var(to) tt(| -T) var(TO)tt(]))
+xitem(tt(tcp_expect [ -q ] [ -p ) var(var) tt( | -P ) var(var) tt(] [ -t ) var(to) tt(| -T) var(TO)tt(]))
 item(tt(    [ -a | -s) var(sess) tt(... | -l) var(sess)tt(,... ]) var(pattern) ...)(
 Wait for input matching any of the given var(pattern)s from any of the
 specified sessions.  Input is ignored until an input line matches one of
@@ -332,7 +332,16 @@ the caller needs to know which of the patterns matched, the option tt(-p)
 var(var) can be used; on return, tt($var) is set to the number of the
 pattern using ordinary zsh indexing, i.e. the first is 1, and so on.  Note
 the absence of a `tt($)' in front of var(var).  To avoid clashes, the
-parameter cannot begin with `tt(_expect)'.
+parameter cannot begin with `tt(_expect)'.  The index -1 is used if
+there is a timeout and 0 if there is no match.
+The option tt(-P) var(var) works similarly to tt(-p), but instead of
+numerical indexes the regular arguments must begin with a prefix
+followed by a colon: that prefix is then used as a tag to which var(var)
+is set when the argument matches.  The tag tt(timeout) is used if there
+is a timeout and the empty string if there is no match.  Note it is
+acceptable for different arguments to start with the same prefix if the
+matches do not need to be distinguished.
 The option tt(-q) is passed directly down to tt(tcp_read).
diff --git a/Functions/TCP/tcp_expect b/Functions/TCP/tcp_expect
index 1c63b8d..eef39ad 100644
--- a/Functions/TCP/tcp_expect
+++ b/Functions/TCP/tcp_expect
@@ -25,6 +25,15 @@
 #	   set it to 0.
 #	   To avoid namespace clashes, the parameter's name must
 #	   not begin with `_expect'.
+#   -P pv  This is similar to -p, however in this case the
+#          arguments to tcp_expect following the options are expected
+#          to start with a prefix "<tag>:".  The parameter $pv is
+#          then set to the value "<tag>" rather than the numeric
+#          index of the parameter.  The string "timeout" is used
+#          as the tag for a timeout specified by -t and -T and
+#          on a failed match the variable is set to the empty string.
+#          It is not an error for multiple arguments to have
+#          the same tag or to use a reserved value of the tag.
 #   -q     Quiet, passed down to tcp_read.  Bad option and argument
 #          usage is always reported.
 #   -s sess
@@ -45,18 +54,18 @@ if [[ ${(t)SECONDS} != float* ]]; then
 # Variables are all named _expect_* to avoid problems with the -p param.
-local _expect_opt _expect_pvar
+local _expect_opt _expect_pvar _expect_state _expect_arg _expect_ind
 local -a _expect_read_args
 float _expect_to1 _expect_to_all _expect_to _expect_new_to
-integer _expect_i _expect_stat
+integer _expect_i _expect_stat _expect_states
-while getopts "al:p:qs:t:T:" _expect_opt; do
+while getopts "al:p:P:qs:t:T:" _expect_opt; do
   case $_expect_opt in
     (a) _expect_read_args+=(-a)
     (l) _expect_read_args+=(-l $OPTARG)
-    (p) _expect_pvar=$OPTARG
+    ([pP]) _expect_pvar=$OPTARG
 	if [[ $_expect_pvar != [a-zA-Z_][a-zA-Z_0-9]# ]]; then
 	  print "invalid parameter name: $_expect_pvar" >&2
 	  return 1
@@ -65,7 +74,12 @@ while getopts "al:p:qs:t:T:" _expect_opt; do
 	  print "$0: parameter names staring \`_expect' are reserved."
 	  return 1
-	eval "$_expect_pvar=0"
+	if [[ $_expect_opt = "P" ]]; then
+	  eval "$_expect_pvar=0"
+	  _expect_states=1
+	else
+	  eval "$_expect_pvar="
+	fi
     (q) _expect_read_args+=(-q)
@@ -112,8 +126,15 @@ while true; do
   for (( _expect_i = 1; _expect_i <= $#; _expect_i++ )); do
-    if [[ "$TCP_LINE" = ${~argv[_expect_i]} ]]; then
-      [[ -n $_expect_pvar ]] && eval "$_expect_pvar=\$_expect_i"
+    if [[ _expect_states -ne 0 && $argv[_expect_i] = (#b)([^:]#):(*) ]]; then
+      _expect_ind=$match[1]
+      _expect_arg=$match[2]
+    else
+      _expect_ind=$_expect_i
+      _expect_arg=$argv[_expect_i]
+    fi
+    if [[ "$TCP_LINE" = ${~_expect_arg} ]]; then
+      [[ -n $_expect_pvar ]] && eval "$_expect_pvar=\$_expect_ind"
       return 0

Peter Stephenson <p.stephenson@xxxxxxxxxxx>  Principal Software Engineer
Tel: +44 (0)1223 434724                Samsung Cambridge Solution Centre
St John's House, St John's Innovation Park, Cowley Road,
Cambridge, CB4 0DS, UK

Messages sorted by: Reverse Date, Date, Thread, Author