mirror of
				git://git.code.sf.net/p/zsh/code
				synced 2025-10-31 18:10:56 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			120 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| # Expect one of a series of regular expressions from $TCP_SESS.
 | |
| # Can make backreferences to be handled by $match.  Returns 0 for
 | |
| # successful match, 1 for error, 2 for timeout.
 | |
| #
 | |
| # This function has no facility for conditionally calling code based
 | |
| # the regular expression found.  This should be done in the calling code
 | |
| # by testing $TCP_LINE, which contains the line which matched the
 | |
| # regular expression.  The complete set of lines read while waiting for
 | |
| # this line is available in the array $tcp_expect_lines (including $TCP_LINE
 | |
| # itself which will be the final element).  Alternatively, use -p pind
 | |
| # which sets $pind to the index of the pattern which matched.  It
 | |
| # will be set to 0 otherwise.
 | |
| #
 | |
| # Many of the options are passed straight down to tcp_read.
 | |
| #
 | |
| # Options:
 | |
| #   -a     Run tcp_expect across all sessions; the first pattern matched
 | |
| #          from any session is used.  The TCP output prompt can be
 | |
| #          used to decide which session matched.
 | |
| #   -l list
 | |
| #          Comma-separated list of sessions as for tcp_read.
 | |
| #   -p pv  If the Nth of a series of patterns matches, set the parameter
 | |
| #          whose name is given by $pv to N; in the case of a timeout,
 | |
| #          set it to -1; otherwise (unless the function exited prematurely),
 | |
| #	   set it to 0.
 | |
| #	   To avoid namespace clashes, the parameter's name must
 | |
| #	   not begin with `_expect'.
 | |
| #   -q     Quiet, passed down to tcp_read.  Bad option and argument
 | |
| #          usage is always reported.
 | |
| #   -s sess
 | |
| #          Expect from session sess.  May be repeated for multiple sessions.
 | |
| #   -t to  Timeout in seconds (may be floating point) per read operation.
 | |
| #          tcp_expect will only time out if every read operation takes longer
 | |
| #          than to
 | |
| #   -T TO  Overall timeout; tcp_expect will time out if the overall operation
 | |
| #          takes longer than this many seconds.
 | |
| emulate -L zsh
 | |
| setopt extendedglob
 | |
| 
 | |
| if [[ ${(t)SECONDS} != float* ]]; then
 | |
|     # If called from another function, use that
 | |
|     typeset -F TCP_SECONDS_START=$SECONDS
 | |
|     # Get extra accuracy by making SECONDS floating point locally
 | |
|     typeset -F SECONDS
 | |
| fi
 | |
| 
 | |
| # Variables are all named _expect_* to avoid problems with the -p param.
 | |
| local _expect_opt _expect_pvar
 | |
| local -a _expect_read_args
 | |
| float _expect_to1 _expect_to_all _expect_to _expect_new_to
 | |
| integer _expect_i _expect_stat
 | |
| 
 | |
| while getopts "al: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
 | |
| 	if [[ $_expect_pvar != [a-zA-Z_][a-zA-Z_0-9]# ]]; then
 | |
| 	  print "invalid parameter name: $_expect_pvar" >&2
 | |
| 	  return 1
 | |
| 	fi
 | |
| 	if [[ $_expect_pvar = _expect* ]]; then
 | |
| 	  print "$0: parameter names staring \`_expect' are reserved."
 | |
| 	  return 1
 | |
| 	fi
 | |
| 	eval "$_expect_pvar=0"
 | |
| 	;;
 | |
|     (q) _expect_read_args+=(-q)
 | |
|         ;;
 | |
|     (s) _expect_read_args+=(-s $OPTARG)
 | |
|         ;;
 | |
|     (t) _expect_to1=$OPTARG
 | |
| 	;;
 | |
|     (T) _expect_to_all=$(( SECONDS + $OPTARG ))
 | |
|         ;;
 | |
|     (\?) return 1
 | |
| 	 ;;
 | |
|     (*) print Unhandled option $_expect_opt, complain >&2
 | |
| 	return 1
 | |
| 	;;
 | |
|   esac
 | |
| done
 | |
| (( OPTIND > 1 )) && shift $(( OPTIND - 1 ))
 | |
| 
 | |
| typeset -ga tcp_expect_lines
 | |
| tcp_expect_lines=()
 | |
| while true; do
 | |
|   if (( _expect_to_all || _expect_to1 )); then
 | |
|     _expect_to=0
 | |
|     (( _expect_to1 )) && (( _expect_to = _expect_to1 ))
 | |
|     if (( _expect_to_all )); then
 | |
|       # overall timeout, see if it has already triggered
 | |
|       if (( (_expect_new_to = (_expect_to_all - SECONDS)) <= 0 )); then
 | |
| 	[[ -n $_expect_pvar ]] && eval "$_expect_pvar=-1"
 | |
| 	return 2
 | |
|       fi
 | |
|       if (( _expect_to <= 0 || _expect_new_to < _expect_to )); then
 | |
| 	_expect_to=$_expect_new_to
 | |
|       fi
 | |
|     fi
 | |
|     tcp_read $_expect_read_args -t $_expect_to
 | |
|     _expect_stat=$?
 | |
|   else
 | |
|     tcp_read $_expect_read_args -b
 | |
|     _expect_stat=$?
 | |
|   fi
 | |
|   if (( _expect_stat )); then
 | |
|     [[ -n $_expect_pvar ]] && eval "$_expect_pvar=-1"
 | |
|     return $_expect_stat
 | |
|   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"
 | |
|       return 0
 | |
|     fi
 | |
|   done
 | |
| done
 |