OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [expect/] [example/] [term_expect] - Blame information for rev 1778

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
#!/usr/local/bin/expectk --
2
 
3
# Name: tkterm - terminal emulator using Expect and Tk text widget, v1.0
4
# Author: Don Libes, July '94
5
 
6
# This is primarily for regression testing character-graphic applications.
7
# You can certainly use it as a terminal emulator - however many features
8
# in a real terminal emulator are not supported (although I'll probably
9
# add some of them later).
10
 
11
###############################
12
# Quick overview of this emulator
13
###############################
14
# Very good attributes:
15
#   Understands both termcap and terminfo
16
#   Understands meta-key (zsh, emacs, etc work)
17
#   Is fast
18
#   Understands X selections
19
#   Looks best with fixed-width font but doesn't require it
20
# Good-enough-for-starters attributes:
21
#   Understands one kind of standout mode (reverse video)
22
# Should-be-fixed-soon attributes:
23
#   Does not support scrollbar or resize
24
# Probably-wont-be-fixed-soon attributes:
25
#   Assumes only one terminal exists
26
 
27
###############################################
28
# To try out this package, just run it.  Using it in
29
# your scripts is simple.  Here are directions:
30
###############################################
31
# 0) make sure Expect is linked into your Tk-based program (or vice versa)
32
# 1) modify the variables/procedures below these comments appropriately
33
# 2) source this file
34
# 3) pack the text widget ($term) if you have so configured it (see
35
#    "term_alone" below).  As distributed, it packs into . automatically.
36
 
37
#############################################
38
# Variables that must be initialized before using this:
39
#############################################
40
set rows 24             ;# number of rows in term
41
set cols 80             ;# number of columns in term
42
set term .t             ;# name of text widget used by term
43
set term_alone 1        ;# if 1, directly pack term into .
44
                        ;# else you must pack
45
set termcap 1           ;# if your applications use termcap
46
set terminfo 1          ;# if your applications use terminfo
47
                        ;# (you can use both, but note that
48
                        ;# starting terminfo is slow)
49
set term_shell $env(SHELL) ;# program to run in term
50
 
51
#############################################
52
# Readable variables of interest
53
#############################################
54
# cur_row               ;# current row where insert marker is
55
# cur_col               ;# current col where insert marker is
56
# term_spawn_id         ;# spawn id of term
57
 
58
#############################################
59
# Procs you may want to initialize before using this:
60
#############################################
61
 
62
# term_exit is called if the spawned process exits
63
proc term_exit {} {
64
        exit
65
}
66
 
67
# term_chars_changed is called after every change to the displayed chars
68
# You can use if you want matches to occur in the background (a la bind)
69
# If you want to test synchronously, then just do so - you don't need to
70
# redefine this procedure.
71
proc term_chars_changed {} {
72
}
73
 
74
# term_cursor_changed is called after the cursor is moved
75
proc term_cursor_changed {} {
76
}
77
 
78
# Example tests you can make
79
#
80
# Test if cursor is at some specific location
81
# if {$cur_row == 1 && $cur_col == 0} ...
82
#
83
# Test if "foo" exists anywhere in line 4
84
# if {[string match *foo* [$term get 4.0 4.end]]}
85
#
86
# Test if "foo" exists at line 4 col 7
87
# if {[string match foo* [$term get 4.7 4.end]]}
88
#
89
# Test if a specific character at row 4 col 5 is in standout
90
# if {-1 != [lsearch [$term tag names 4.5] standout]} ...
91
#
92
# Return contents of screen
93
# $term get 1.0 end
94
#
95
# Return indices of first string on lines 4 to 6 that is in standout mode
96
# $term tag nextrange standout 4.0 6.end
97
#
98
# Replace all occurrences of "foo" with "bar" on screen
99
# for {set i 1} {$i<=$rows} {incr i} {
100
#       regsub -all "foo" [$term get $i.0 $i.end] "bar" x
101
#       $term delete $i.0 $i.end
102
#       $term insert $i.0 $x
103
# }
104
 
105
#############################################
106
# End of things of interest
107
#############################################
108
 
109
 
110
unset env(DISPLAY)
111
set env(LINES) $rows
112
set env(COLUMNS) $cols
113
 
114
set env(TERM) "tt"
115
if $termcap {
116
    set env(TERMCAP) {tt:
117
        :cm=\E[%d;%dH:
118
        :up=\E[A:
119
        :nd=\E[C:
120
        :cl=\E[H\E[J:
121
        :do=^J:
122
        :so=\E[7m:
123
        :se=\E[m:
124
        :k1=\EOP:
125
        :k2=\EOQ:
126
        :k3=\EOR:
127
        :k4=\EOS:
128
        :k5=\EOT:
129
        :k6=\EOU:
130
        :k7=\EOV:
131
        :k8=\EOW:
132
        :k9=\EOX:
133
    }
134
}
135
 
136
if $terminfo {
137
    set env(TERMINFO) /tmp
138
    set ttsrc "/tmp/tt.src"
139
    set file [open $ttsrc w]
140
 
141
    puts $file {tt|textterm|Don Libes' tk text widget terminal emulator,
142
        cup=\E[%p1%d;%p2%dH,
143
        cuu1=\E[A,
144
        cuf1=\E[C,
145
        clear=\E[H\E[J,
146
        ind=\n,
147
        cr=\r,
148
        smso=\E[7m,
149
        rmso=\E[m,
150
        kf1=\EOP,
151
        kf2=\EOQ,
152
        kf3=\EOR,
153
        kf4=\EOS,
154
        kf5=\EOT,
155
        kf6=\EOU,
156
        kf7=\EOV,
157
        kf8=\EOW,
158
        kf9=\EOX,
159
    }
160
    close $file
161
 
162
    set oldpath $env(PATH)
163
    set env(PATH) "/usr/5bin:/usr/lib/terminfo"
164
    if 1==[catch {exec tic $ttsrc} msg] {
165
        puts "WARNING: tic failed - if you don't have terminfo support on"
166
        puts "your system, change \"set terminfo 1\" to \"set terminfo 0\"."
167
        puts "Here is the original error from running tic:"
168
        puts $msg
169
    }
170
    set env(PATH) $oldpath
171
 
172
    exec rm $ttsrc
173
}
174
 
175
set term_standout 0     ;# if in standout mode or not
176
 
177
log_user 0
178
 
179
# start a shell and text widget for its output
180
set stty_init "-tabs"
181
eval spawn $term_shell
182
stty rows $rows columns $cols < $spawn_out(slave,name)
183
set term_spawn_id $spawn_id
184
 
185
# this shouldn't be needed if Ousterhout fixes text bug
186
text $term -relief sunken -bd 1 -width $cols -height $rows -wrap none
187
 
188
if {$term_alone} {
189
        pack $term
190
}
191
 
192
$term tag configure standout -background  black -foreground white
193
 
194
proc term_clear {} {
195
        global term
196
 
197
        $term delete 1.0 end
198
        term_init
199
}
200
 
201
proc term_init {} {
202
        global rows cols cur_row cur_col term
203
 
204
        # initialize it with blanks to make insertions later more easily
205
        set blankline [format %*s $cols ""]\n
206
        for {set i 1} {$i <= $rows} {incr i} {
207
                $term insert $i.0 $blankline
208
        }
209
 
210
        set cur_row 1
211
        set cur_col 0
212
 
213
        $term mark set insert $cur_row.$cur_col
214
}
215
 
216
proc term_down {} {
217
        global cur_row rows cols term
218
 
219
        if {$cur_row < $rows} {
220
                incr cur_row
221
        } else {
222
                # already at last line of term, so scroll screen up
223
                $term delete 1.0 "1.end + 1 chars"
224
 
225
                # recreate line at end
226
                $term insert end [format %*s $cols ""]\n
227
        }
228
}
229
 
230
proc term_insert {s} {
231
        global cols cur_col cur_row
232
        global term term_standout
233
 
234
        set chars_rem_to_write [string length $s]
235
        set space_rem_on_line [expr $cols - $cur_col]
236
 
237
        if {$term_standout} {
238
                set tag_action "add"
239
        } else {
240
                set tag_action "remove"
241
        }
242
 
243
        ##################
244
        # write first line
245
        ##################
246
 
247
        if {$chars_rem_to_write > $space_rem_on_line} {
248
                set chars_to_write $space_rem_on_line
249
                set newline 1
250
        } else {
251
                set chars_to_write $chars_rem_to_write
252
                set newline 0
253
        }
254
 
255
        $term delete $cur_row.$cur_col $cur_row.[expr $cur_col + $chars_to_write]
256
        $term insert $cur_row.$cur_col [
257
                string range $s 0 [expr $space_rem_on_line-1]
258
        ]
259
 
260
        $term tag $tag_action standout $cur_row.$cur_col $cur_row.[expr $cur_col + $chars_to_write]
261
 
262
        # discard first line already written
263
        incr chars_rem_to_write -$chars_to_write
264
        set s [string range $s $chars_to_write end]
265
 
266
        # update cur_col
267
        incr cur_col $chars_to_write
268
        # update cur_row
269
        if $newline {
270
                term_down
271
        }
272
 
273
        ##################
274
        # write full lines
275
        ##################
276
        while {$chars_rem_to_write >= $cols} {
277
                $term delete $cur_row.0 $cur_row.end
278
                $term insert $cur_row.0 [string range $s 0 [expr $cols-1]]
279
                $term tag $tag_action standout $cur_row.0 $cur_row.end
280
 
281
                # discard line from buffer
282
                set s [string range $s $cols end]
283
                incr chars_rem_to_write -$cols
284
 
285
                set cur_col 0
286
                term_down
287
        }
288
 
289
        #################
290
        # write last line
291
        #################
292
 
293
        if {$chars_rem_to_write} {
294
                $term delete $cur_row.0 $cur_row.$chars_rem_to_write
295
                $term insert $cur_row.0 $s
296
                $term tag $tag_action standout $cur_row.0 $cur_row.$chars_rem_to_write
297
 
298
                set cur_col $chars_rem_to_write
299
        }
300
 
301
        term_chars_changed
302
}
303
 
304
proc term_update_cursor {} {
305
        global cur_row cur_col term
306
 
307
        $term mark set insert $cur_row.$cur_col
308
 
309
        term_cursor_changed
310
}
311
 
312
term_init
313
 
314
expect_background {
315
        -i $term_spawn_id
316
        -re "^\[^\x01-\x1f]+" {
317
                # Text
318
                term_insert $expect_out(0,string)
319
                term_update_cursor
320
        } "^\r" {
321
                # (cr,) Go to beginning of line
322
                set cur_col 0
323
                term_update_cursor
324
        } "^\n" {
325
                # (ind,do) Move cursor down one line
326
                term_down
327
                term_update_cursor
328
        } "^\b" {
329
                # Backspace nondestructively
330
                incr cur_col -1
331
                term_update_cursor
332
        } "^\a" {
333
                bell
334
        } "^\t" {
335
                # Tab, shouldn't happen
336
                send_error "got a tab!?"
337
        } eof {
338
                term_exit
339
        } "^\x1b\\\[A" {
340
                # (cuu1,up) Move cursor up one line
341
                incr cur_row -1
342
                term_update_cursor
343
        } "^\x1b\\\[C" {
344
                # (cuf1,nd) Non-destructive space
345
                incr cur_col
346
                term_update_cursor
347
        } -re "^\x1b\\\[(\[0-9]*);(\[0-9]*)H" {
348
                # (cup,cm) Move to row y col x
349
                set cur_row [expr $expect_out(1,string)+1]
350
                set cur_col $expect_out(2,string)
351
                term_update_cursor
352
        } "^\x1b\\\[H\x1b\\\[J" {
353
                # (clear,cl) Clear screen
354
                term_clear
355
                term_update_cursor
356
        } "^\x1b\\\[7m" {
357
                # (smso,so) Begin standout mode
358
                set term_standout 1
359
        } "^\x1b\\\[m" {
360
                # (rmso,se) End standout mode
361
                set term_standout 0
362
        }
363
}
364
 
365
bind $term  {
366
        focus %W
367
}
368
bind $term  {
369
        if {"%A" != ""} {
370
                exp_send -i $term_spawn_id "\033%A"
371
        }
372
}
373
bind $term  {
374
        exp_send -i $term_spawn_id -- %A
375
        break
376
}
377
 
378
bind $term      {exp_send -null}
379
bind $term              {exp_send -null}
380
 
381
bind $term  {exp_send -i $term_spawn_id "\033OP"}
382
bind $term  {exp_send -i $term_spawn_id "\033OQ"}
383
bind $term  {exp_send -i $term_spawn_id "\033OR"}
384
bind $term  {exp_send -i $term_spawn_id "\033OS"}
385
bind $term  {exp_send -i $term_spawn_id "\033OT"}
386
bind $term  {exp_send -i $term_spawn_id "\033OU"}
387
bind $term  {exp_send -i $term_spawn_id "\033OV"}
388
bind $term  {exp_send -i $term_spawn_id "\033OW"}
389
bind $term  {exp_send -i $term_spawn_id "\033OX"}
390
 
391
set term_counter 0
392
proc term_expect {args} {
393
        upvar timeout localTimeout
394
        upvar #0 timeout globalTimeout
395
        set timeout 10
396
        catch {set timeout $globalTimeout}
397
        catch {set timeout $localTimeout}
398
 
399
        global term_counter
400
        incr term_counter
401
        global [set strobe _data_[set term_counter]]
402
        global [set tstrobe _timer_[set term_counter]]
403
 
404
        proc term_chars_changed {} "uplevel #0 set $strobe 1"
405
 
406
        set $strobe 1
407
        set $tstrobe 0
408
 
409
        if {$timeout >= 0} {
410
                set mstimeout [expr 1000*$timeout]
411
                after $mstimeout "set $strobe 1; set $tstrobe 1"
412
                set timeout_act {}
413
        }
414
 
415
        set argc [llength $args]
416
        if {$argc%2 == 1} {
417
                lappend args {}
418
                incr argc
419
        }
420
 
421
        for {set i 0} {$i<$argc} {incr i 2} {
422
                set act_index [expr $i+1]
423
                if {[string compare timeout [lindex $args $i]] == 0} {
424
                        set timeout_act [lindex $args $act_index]
425
                        set args [lreplace $args $i $act_index]
426
                        incr argc -2
427
                        break
428
                }
429
        }
430
 
431
        while {![info exists act]} {
432
                if {![set $strobe]} {
433
                        tkwait var $strobe
434
                }
435
                set $strobe 0
436
 
437
                if {[set $tstrobe]} {
438
                        set act $timeout_act
439
                } else {
440
                        for {set i 0} {$i<$argc} {incr i 2} {
441
                                if {[uplevel [lindex $args $i]]} {
442
                                        set act [lindex $args [incr i]]
443
                                        break
444
                                }
445
                        }
446
                }
447
        }
448
 
449
        proc term_chars_changed {} {}
450
 
451
        if {$timeout >= 0} {
452
                after $mstimeout unset $strobe $tstrobe
453
        } else {
454
                unset $strobe $tstrobe
455
        }
456
 
457
        set code [catch {uplevel $act} string]
458
        if {$code >  4} {return -code $code $string}
459
        if {$code == 4} {return -code continue}
460
        if {$code == 3} {return -code break}
461
        if {$code == 2} {return -code return}
462
        if {$code == 1} {return -code error -errorinfo $errorInfo \
463
                                -errorcode $errorCode $string}
464
        return $string
465
}
466
 
467
##################################################
468
# user-supplied code goes below here
469
##################################################
470
 
471
set timeout 200
472
 
473
# for example, wait for a shell prompt
474
term_expect {regexp "%" [$term get 1.0 3.end]}
475
 
476
# invoke game of rogue
477
exp_send "myrogue\r"
478
 
479
# wait for strength of 18
480
term_expect \
481
        {regexp "Str: 18" [$term get 24.0 24.end]} {
482
                # do something
483
        } {timeout} {
484
                puts "ulp...timed out!"
485
        } {regexp "Str: 16" [$term get 24.0 24.end]}
486
 
487
# and so on...
488
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.