about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2014-08-14 09:56:43 +0100
committerPeter Stephenson <pws@zsh.org>2014-08-14 09:56:43 +0100
commit5bcf00979fc5e01dd6fddff965aa871491f8b48b (patch)
tree9babd6320b123720ae5d10e8c43d6a7c78a11d5a
parente0966c819c2dcd9d5dbada5588220219d15ee7ec (diff)
downloadzsh-5bcf00979fc5e01dd6fddff965aa871491f8b48b.tar.gz
zsh-5bcf00979fc5e01dd6fddff965aa871491f8b48b.tar.xz
zsh-5bcf00979fc5e01dd6fddff965aa871491f8b48b.zip
33002: tcp_expect -P pm tags matches with a string
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/tcpsys.yo13
-rw-r--r--Functions/TCP/tcp_expect35
3 files changed, 45 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 3686a1c52..9ab2d4970 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-08-14  Peter Stephenson  <p.stephenson@samsung.com>
+
+	* 33002: Doc/Zsh/tcpsys.yo, Functions/TCP/tcp_expect: add option
+	-P to tcp_expect for tagging matches with a string rather than
+	a parameter index.
+
 2014-08-13  Oliver Kiddle  <opk@zsh.org>
 
 	* 32925: Completion/Zsh/Command/_kill: complete process groups,
diff --git a/Doc/Zsh/tcpsys.yo b/Doc/Zsh/tcpsys.yo
index 1e26054ce..406785997 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.
 )
 findex(tcp_expect)
-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 1c63b8def..eef39ad06 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
 fi
 
 # 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
 	fi
-	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
   fi
   tcp_expect_lines+=($TCP_LINE)
   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
     fi
   done