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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [expect/] [example/] [tkterm] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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