Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / amd64 / bin / autoexpect
CommitLineData
920dae64
AT
1#!/bin/sh
2# \
3exec expect -- "$0" ${1+"$@"}
4# Name: autoexpect - generate an Expect script from watching a session
5#
6# Description:
7#
8# Given a program name, autoexpect will run that program. Otherwise
9# autoexpect will start a shell. Interact as desired. When done, exit
10# the program or shell. Autoexpect will create a script that reproduces
11# your interactions. By default, the script is named script.exp.
12# See the man page for more info.
13#
14# Author: Don Libes, NIST
15# Date: June 30 1995
16# Version: 1.4b
17
18set filename "script.exp"
19set verbose 1
20set conservative 0
21set promptmode 0
22set option_keys ""
23
24proc check_for_following {type} {
25 if {![llength [uplevel set argv]]} {
26 puts "autoexpect: [uplevel set flag] requires following $type"
27 exit 1
28 }
29}
30
31while {[llength $argv]>0} {
32 set flag [lindex $argv 0]
33 if {0==[regexp "^-" $flag]} break
34 set argv [lrange $argv 1 end]
35 switch -- $flag \
36 "-c" {
37 set conservative 1
38 } "-C" {
39 check_for_following character
40 lappend option_keys [lindex $argv 0] ctoggle
41 set argv [lrange $argv 1 end]
42 } "-p" {
43 set promptmode 1
44 } "-P" {
45 check_for_following character
46 lappend option_keys [lindex $argv 0] ptoggle
47 set argv [lrange $argv 1 end]
48 } "-Q" {
49 check_for_following character
50 lappend option_keys [lindex $argv 0] quote
51 set argv [lrange $argv 1 end]
52 } "-f" {
53 check_for_following filename
54 set filename [lindex $argv 0]
55 set argv [lrange $argv 1 end]
56 } "-quiet" {
57 set verbose 0
58 } default {
59 break
60 }
61}
62
63#############################################################
64# Variables Descriptions
65#############################################################
66# userbuf buffered characters from user
67# procbuf buffered characters from process
68# lastkey last key pressed by user
69# if undefined, last key came from process
70# echoing if the process is echoing
71#############################################################
72
73# Handle a character that came from user input (i.e., the keyboard)
74proc input {c} {
75 global userbuf lastkey
76
77 send -- $c
78 append userbuf $lastkey
79 set lastkey $c
80}
81
82# Handle a null character from the keyboard
83proc input_null {} {
84 global lastkey userbuf procbuf echoing
85
86 send -null
87
88 if {$lastkey == ""} {
89 if {$echoing} {
90 sendcmd "$userbuf"
91 }
92 if {$procbuf != ""} {
93 expcmd "$procbuf"
94 }
95 } else {
96 sendcmd "$userbuf"
97 if {$echoing} {
98 expcmd "$procbuf"
99 sendcmd "$lastkey"
100 }
101 }
102 cmd "send -null"
103 set userbuf ""
104 set procbuf ""
105 set lastkey ""
106 set echoing 0
107}
108
109# Handle a character that came from the process
110proc output {s} {
111 global lastkey procbuf userbuf echoing
112
113 send_user -raw -- $s
114
115 if {$lastkey == ""} {
116 if {!$echoing} {
117 append procbuf $s
118 } else {
119 sendcmd "$userbuf"
120 expcmd "$procbuf"
121 set echoing 0
122 set userbuf ""
123 set procbuf $s
124 }
125 return
126 }
127
128 regexp (.)(.*) $s dummy c tail
129 if {$c == $lastkey} {
130 if {$echoing} {
131 append userbuf $lastkey
132 set lastkey ""
133 } else {
134 if {$procbuf != ""} {
135 expcmd "$procbuf"
136 set procbuf ""
137 }
138 set echoing 1
139 }
140 append procbuf $s
141
142 if {[string length $tail]} {
143 sendcmd "$userbuf$lastkey"
144 set userbuf ""
145 set lastkey ""
146 set echoing 0
147 }
148 } else {
149 if {!$echoing} {
150 expcmd "$procbuf"
151 }
152 sendcmd "$userbuf$lastkey"
153 set procbuf $s
154 set userbuf ""
155 set lastkey ""
156 set echoing 0
157 }
158}
159
160# rewrite raw strings so that can appear as source code but still reproduce
161# themselves.
162proc expand {s} {
163 regsub -all "\\\\" $s "\\\\\\\\" s
164 regsub -all "\r" $s "\\r" s
165 regsub -all "\"" $s "\\\"" s
166 regsub -all "\\\[" $s "\\\[" s
167 regsub -all "\\\]" $s "\\\]" s
168 regsub -all "\\\$" $s "\\\$" s
169
170 return $s
171}
172
173# generate an expect command
174proc expcmd {s} {
175 global promptmode
176
177 if {$promptmode} {
178 regexp ".*\[\r\n]+(.*)" $s dummy s
179 }
180
181 cmd "expect -exact \"[expand $s]\""
182}
183
184# generate a send command
185proc sendcmd {s} {
186 global send_style conservative
187
188 if {$conservative} {
189 cmd "sleep .1"
190 }
191
192 cmd "send$send_style -- \"[expand $s]\""
193}
194
195# generate any command
196proc cmd {s} {
197 global fd
198 puts $fd "$s"
199}
200
201proc verbose_send_user {s} {
202 global verbose
203
204 if {$verbose} {
205 send_user -- $s
206 }
207}
208
209proc ctoggle {} {
210 global conservative send_style
211
212 if {$conservative} {
213 cmd "# conservative mode off - adding no delays"
214 verbose_send_user "conservative mode off\n"
215 set conservative 0
216 set send_style ""
217 } else {
218 cmd "# prompt mode on - adding delays"
219 verbose_send_user "conservative mode on\n"
220 set conservative 1
221 set send_style " -s"
222 }
223}
224
225proc ptoggle {} {
226 global promptmode
227
228 if {$promptmode} {
229 cmd "# prompt mode off - now looking for complete output"
230 verbose_send_user "prompt mode off\n"
231 set promptmode 0
232 } else {
233 cmd "# prompt mode on - now looking only for prompts"
234 verbose_send_user "prompt mode on\n"
235 set promptmode 1
236 }
237}
238
239# quote the next character from the user
240proc quote {} {
241 expect_user -re .
242 send -- $expect_out(buffer)
243}
244
245
246if {[catch {set fd [open $filename w]} msg]} {
247 puts $msg
248 exit
249}
250exec chmod +x $filename
251verbose_send_user "autoexpect started, file is $filename\n"
252
253# calculate a reasonable #! line
254set expectpath /usr/local/bin ;# prepare default
255foreach dir [split $env(PATH) :] { ;# now look for real location
256 if {[file executable $dir/expect] && ![file isdirectory $dir/expect]} {
257 set expectpath $dir
258 break
259 }
260}
261
262cmd "#![set expectpath]/expect -f
263#
264# This Expect script was generated by autoexpect on [timestamp -format %c]
265# Expect and autoexpect were both written by Don Libes, NIST."
266cmd {#
267# Note that autoexpect does not guarantee a working script. It
268# necessarily has to guess about certain things. Two reasons a script
269# might fail are:
270#
271# 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
272# etc.) and devices discard or ignore keystrokes that arrive "too
273# quickly" after prompts. If you find your new script hanging up at
274# one spot, try adding a short sleep just before the previous send.
275# Setting "force_conservative" to 1 (see below) makes Expect do this
276# automatically - pausing briefly before sending each character. This
277# pacifies every program I know of. The -c flag makes the script do
278# this in the first place. The -C flag allows you to define a
279# character to toggle this mode off and on.
280
281set force_conservative 0 ;# set to 1 to force conservative mode even if
282 ;# script wasn't run conservatively originally
283if {$force_conservative} {
284 set send_slow {1 .1}
285 proc send {ignore arg} {
286 sleep .1
287 exp_send -s -- $arg
288 }
289}
290
291#
292# 2) differing output - Some programs produce different output each time
293# they run. The "date" command is an obvious example. Another is
294# ftp, if it produces throughput statistics at the end of a file
295# transfer. If this causes a problem, delete these patterns or replace
296# them with wildcards. An alternative is to use the -p flag (for
297# "prompt") which makes Expect only look for the last line of output
298# (i.e., the prompt). The -P flag allows you to define a character to
299# toggle this mode off and on.
300#
301# Read the man page for more info.
302#
303# -Don
304
305}
306
307cmd "set timeout -1"
308if {$conservative} {
309 set send_style " -s"
310 cmd "set send_slow {1 .1}"
311} else {
312 set send_style ""
313}
314
315if {[llength $argv]>0} {
316 eval spawn -noecho $argv
317 cmd "spawn $argv"
318} else {
319 spawn -noecho $env(SHELL)
320 cmd "spawn \$env(SHELL)"
321}
322
323cmd "match_max 100000"
324
325set lastkey ""
326set procbuf ""
327set userbuf ""
328set echoing 0
329
330remove_nulls 0
331
332eval interact $option_keys {
333 -re . {
334 input $interact_out(0,string)
335 } -o -re .+ {
336 output $interact_out(0,string)
337 } eof {
338 cmd "expect eof"
339 return
340 }
341}
342
343close $fd
344verbose_send_user "autoexpect done, file is $filename\n"