gdb/testsuite/tui: implement _csi_P proc
[binutils-gdb.git] / gdb / testsuite / gdb.tui / tuiterm.exp
1 # Copyright 2022 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 # Unit-test Term, the testsuite's terminal implementation that is used to test
17 # the TUI.
18
19 tuiterm_env
20
21 # Validate the cursor position.
22 #
23 # EXPECTED_CUR_COL and EXPECTED_CUR_ROW are the expected cursor column and row
24 # positions.
25
26 proc check_cursor_position { test expected_cur_col expected_cur_row } {
27 with_test_prefix $test {
28 gdb_assert {$expected_cur_col == ${Term::_cur_col}} "column"
29 gdb_assert {$expected_cur_row == ${Term::_cur_row}} "row"
30 }
31 }
32
33 # Validate the terminal contents and cursor position.
34 #
35 # EXPECTED_CONTENTS must be a list of strings, one element for each terminal
36 # line.
37 #
38 # EXPECTED_CUR_COL and EXPECTED_CUR_ROW are passed to check_cursor_position.
39
40 proc check { test expected_contents expected_cur_col expected_cur_row } {
41 with_test_prefix $test {
42 # Check term contents.
43 set regexp "^"
44
45 foreach line $expected_contents {
46 append regexp $line
47 append regexp "\n"
48 }
49
50 append regexp "$"
51 Term::check_contents "contents" $regexp
52 }
53
54 check_cursor_position $test $expected_cur_col $expected_cur_row
55 }
56
57 proc setup_terminal { cols rows } {
58 setenv TERM ansi
59 Term::_setup $rows $cols
60 }
61
62 # Most tests are fine with a small terminal. This proc initializes the terminal
63 # with 8 columns and 4 rows, with the following content:
64 #
65 # abcdefgh
66 # ijklmnop
67 # qrstuvwx
68 # yz01234
69 #
70 # The bottom right cell is left blank: trying to write to it using _insert
71 # would move the cursor past the screen, causing a scroll, but scrolling is
72 # not implemented at the moment.
73
74 proc setup_small {} {
75 setup_terminal 8 4
76
77 Term::_insert "abcdefgh"
78 Term::_insert "ijklmnop"
79 Term::_insert "qrstuvwx"
80 Term::_insert "yz01234"
81
82 check "check after setup" {
83 "abcdefgh"
84 "ijklmnop"
85 "qrstuvwx"
86 "yz01234 "
87 } 7 3
88 }
89
90 # Some tests require a larger terminal. This proc initializes the terminal with
91 # 80 columns and 25 rows, but leaves the content empty.
92
93 proc setup_large {} {
94 setup_terminal 80 25
95 }
96
97 # Each proc below tests a control character or sequence individually.
98
99 proc test_backspace {} {
100 # Note: the backspace (BS) control character only moves the cursor left,
101 # it does not delete characters.
102
103 Term::_move_cursor 1 2
104
105 Term::_ctl_0x08
106 check "backspace one" {
107 "abcdefgh"
108 "ijklmnop"
109 "qrstuvwx"
110 "yz01234 "
111 } 0 2
112
113 # Cursor should not move if it is already at column 0.
114 Term::_ctl_0x08
115 check "backspace 2" {
116 "abcdefgh"
117 "ijklmnop"
118 "qrstuvwx"
119 "yz01234 "
120 } 0 2
121 }
122
123 proc test_linefeed { } {
124 Term::_move_cursor 1 2
125 Term::_ctl_0x0a
126 check "linefeed" {
127 "abcdefgh"
128 "ijklmnop"
129 "qrstuvwx"
130 "yz01234 "
131 } 1 3
132 }
133
134 proc test_carriage_return { } {
135 Term::_move_cursor 1 2
136 Term::_ctl_0x0d
137 check "carriage return 1" {
138 "abcdefgh"
139 "ijklmnop"
140 "qrstuvwx"
141 "yz01234 "
142 } 0 2
143
144 Term::_ctl_0x0d
145 check "carriage return 2" {
146 "abcdefgh"
147 "ijklmnop"
148 "qrstuvwx"
149 "yz01234 "
150 } 0 2
151 }
152
153 proc test_insert_characters { } {
154 Term::_move_cursor 1 2
155
156 Term::_csi_@
157 check "insert characters 1" {
158 "abcdefgh"
159 "ijklmnop"
160 "q rstuvw"
161 "yz01234 "
162 } 1 2
163
164 Term::_csi_@ 20
165 check "insert characters 2" {
166 "abcdefgh"
167 "ijklmnop"
168 "q "
169 "yz01234 "
170 } 1 2
171
172 Term::_move_cursor 0 1
173 Term::_csi_@ 6
174 check "insert characters 3" {
175 "abcdefgh"
176 " ij"
177 "q "
178 "yz01234 "
179 } 0 1
180 }
181
182 proc test_cursor_up { } {
183 Term::_move_cursor 2 3
184
185 Term::_csi_A
186 check "cursor up 1" {
187 "abcdefgh"
188 "ijklmnop"
189 "qrstuvwx"
190 "yz01234 "
191 } 2 2
192
193 Term::_csi_A 2
194 check "cursor up 2" {
195 "abcdefgh"
196 "ijklmnop"
197 "qrstuvwx"
198 "yz01234 "
199 } 2 0
200
201 Term::_csi_A 1
202 check "cursor up 3" {
203 "abcdefgh"
204 "ijklmnop"
205 "qrstuvwx"
206 "yz01234 "
207 } 2 0
208 }
209
210 proc test_cursor_down { } {
211 Term::_move_cursor 1 0
212
213 Term::_csi_B
214 check "cursor down 1" {
215 "abcdefgh"
216 "ijklmnop"
217 "qrstuvwx"
218 "yz01234 "
219 } 1 1
220
221 Term::_csi_B 2
222 check "cursor down 2" {
223 "abcdefgh"
224 "ijklmnop"
225 "qrstuvwx"
226 "yz01234 "
227 } 1 3
228
229 Term::_csi_B 1
230 check "cursor down 3" {
231 "abcdefgh"
232 "ijklmnop"
233 "qrstuvwx"
234 "yz01234 "
235 } 1 3
236 }
237
238 proc test_cursor_forward { } {
239 Term::_move_cursor 0 1
240
241 Term::_csi_C
242 check "cursor forward 1" {
243 "abcdefgh"
244 "ijklmnop"
245 "qrstuvwx"
246 "yz01234 "
247 } 1 1
248
249 Term::_csi_C 6
250 check "cursor forward 2" {
251 "abcdefgh"
252 "ijklmnop"
253 "qrstuvwx"
254 "yz01234 "
255 } 7 1
256
257 Term::_csi_C 1
258 check "cursor forward 3" {
259 "abcdefgh"
260 "ijklmnop"
261 "qrstuvwx"
262 "yz01234 "
263 } 7 1
264 }
265
266 proc test_cursor_backward { } {
267 Term::_move_cursor 7 1
268
269 Term::_csi_D
270 check "cursor backward 1" {
271 "abcdefgh"
272 "ijklmnop"
273 "qrstuvwx"
274 "yz01234 "
275 } 6 1
276
277 Term::_csi_D 6
278 check "cursor backward 2" {
279 "abcdefgh"
280 "ijklmnop"
281 "qrstuvwx"
282 "yz01234 "
283 } 0 1
284
285 Term::_csi_D 1
286 check "cursor backward 3" {
287 "abcdefgh"
288 "ijklmnop"
289 "qrstuvwx"
290 "yz01234 "
291 } 0 1
292 }
293
294 proc test_cursor_next_line { } {
295 Term::_move_cursor 2 0
296
297 Term::_csi_E
298 check "cursor next line 1" {
299 "abcdefgh"
300 "ijklmnop"
301 "qrstuvwx"
302 "yz01234 "
303 } 0 1
304
305 Term::_move_cursor 2 1
306 Term::_csi_E 2
307 check "cursor next line 2" {
308 "abcdefgh"
309 "ijklmnop"
310 "qrstuvwx"
311 "yz01234 "
312 } 0 3
313
314 Term::_move_cursor 2 3
315 Term::_csi_E 1
316 check "cursor next line 3" {
317 "abcdefgh"
318 "ijklmnop"
319 "qrstuvwx"
320 "yz01234 "
321 } 0 3
322 }
323
324 proc test_cursor_previous_line { } {
325 Term::_move_cursor 2 3
326
327 Term::_csi_F
328 check "cursor previous line 1" {
329 "abcdefgh"
330 "ijklmnop"
331 "qrstuvwx"
332 "yz01234 "
333 } 0 2
334
335 Term::_move_cursor 2 2
336 Term::_csi_F 2
337 check "cursor previous line 2" {
338 "abcdefgh"
339 "ijklmnop"
340 "qrstuvwx"
341 "yz01234 "
342 } 0 0
343
344 Term::_move_cursor 2 0
345 Term::_csi_F 1
346 check "cursor previous line 3" {
347 "abcdefgh"
348 "ijklmnop"
349 "qrstuvwx"
350 "yz01234 "
351 } 0 0
352 }
353
354 proc test_horizontal_absolute { } {
355 Term::_move_cursor 2 2
356 Term::_csi_G
357 check "cursor horizontal absolute 1" {
358 "abcdefgh"
359 "ijklmnop"
360 "qrstuvwx"
361 "yz01234 "
362 } 0 2
363
364 Term::_move_cursor 2 2
365 Term::_csi_G 4
366 check "cursor horizontal absolute 2" {
367 "abcdefgh"
368 "ijklmnop"
369 "qrstuvwx"
370 "yz01234 "
371 } 3 2
372 }
373
374 proc test_cursor_position { } {
375 Term::_move_cursor 1 1
376
377 Term::_csi_H 3 5
378 check "cursor horizontal absolute 2" {
379 "abcdefgh"
380 "ijklmnop"
381 "qrstuvwx"
382 "yz01234 "
383 } 4 2
384 }
385
386 proc test_cursor_horizontal_forward_tabulation { } {
387 Term::_move_cursor 5 2
388 Term::_csi_I
389 check_cursor_position "default param" 8 2
390
391 Term::_csi_I 2
392 check_cursor_position "explicit param" 24 2
393
394 Term::_move_cursor 77 2
395 Term::_csi_I 5
396 check_cursor_position "try to go past the end" 79 2
397 }
398
399 proc test_erase_in_display { } {
400 Term::_move_cursor 5 2
401 Term::_csi_J
402 check "erase in display, cursor to end with default param" {
403 "abcdefgh"
404 "ijklmnop"
405 "qrstu "
406 " "
407 } 5 2
408
409 Term::_move_cursor 3 2
410 Term::_csi_J 0
411 check "erase in display, cursor to end with explicit param" {
412 "abcdefgh"
413 "ijklmnop"
414 "qrs "
415 " "
416 } 3 2
417
418 Term::_move_cursor 2 1
419 Term::_csi_J 1
420 check "erase in display, beginning to cursor" {
421 " "
422 " lmnop"
423 "qrs "
424 " "
425 } 2 1
426
427 Term::_move_cursor 5 1
428 Term::_csi_J 2
429 check "erase in display, entire display" {
430 " "
431 " "
432 " "
433 " "
434 } 5 1
435 }
436
437 proc test_erase_in_line { } {
438 Term::_move_cursor 5 2
439 Term::_csi_K
440 check "erase in line, cursor to end with default param" {
441 "abcdefgh"
442 "ijklmnop"
443 "qrstu "
444 "yz01234 "
445 } 5 2
446
447 Term::_move_cursor 3 2
448 Term::_csi_K 0
449 check "erase in line, cursor to end with explicit param" {
450 "abcdefgh"
451 "ijklmnop"
452 "qrs "
453 "yz01234 "
454 } 3 2
455
456 Term::_move_cursor 3 1
457 Term::_csi_K 1
458 check "erase in line, beginning to cursor" {
459 "abcdefgh"
460 " mnop"
461 "qrs "
462 "yz01234 "
463 } 3 1
464
465 Term::_move_cursor 3 0
466 Term::_csi_K 2
467 check "erase in line, entire line" {
468 " "
469 " mnop"
470 "qrs "
471 "yz01234 "
472 } 3 0
473 }
474
475 proc test_delete_line { } {
476 Term::_move_cursor 3 2
477 Term::_csi_M
478 check "delete line, default param" {
479 "abcdefgh"
480 "ijklmnop"
481 "yz01234 "
482 " "
483 } 3 2
484
485 Term::_move_cursor 3 0
486 Term::_csi_M 2
487 check "delete line, explicit param" {
488 "yz01234 "
489 " "
490 " "
491 " "
492 } 3 0
493 }
494
495 proc test_delete_character { } {
496 Term::_move_cursor 2 1
497
498 Term::_csi_P
499 check "delete character, default param" {
500 "abcdefgh"
501 "ijlmnop "
502 "qrstuvwx"
503 "yz01234 "
504 } 2 1
505
506 Term::_csi_P 3
507 check "delete character, explicit param" {
508 "abcdefgh"
509 "ijop "
510 "qrstuvwx"
511 "yz01234 "
512 } 2 1
513
514 Term::_csi_P 12
515 check "delete character, more than number of columns" {
516 "abcdefgh"
517 "ij "
518 "qrstuvwx"
519 "yz01234 "
520 } 2 1
521 }
522
523 proc test_erase_character { } {
524 Term::_move_cursor 3 2
525 Term::_csi_X
526 check "erase character, default param" {
527 "abcdefgh"
528 "ijklmnop"
529 "qrs uvwx"
530 "yz01234 "
531 } 3 2
532
533 Term::_move_cursor 1 3
534 Term::_csi_X 4
535 check "erase character, explicit param" {
536 "abcdefgh"
537 "ijklmnop"
538 "qrs uvwx"
539 "y 34 "
540 } 1 3
541 }
542
543 proc test_cursor_backward_tabulation { } {
544 Term::_move_cursor 77 2
545 Term::_csi_Z
546 check_cursor_position "default param" 72 2
547
548 Term::_csi_Z 2
549 check_cursor_position "explicit param" 56 2
550
551 Term::_move_cursor 6 2
552 Term::_csi_Z 12
553 check_cursor_position "try to go past the beginning" 0 2
554 }
555
556 proc test_repeat { } {
557 Term::_move_cursor 2 1
558 set Term::_last_char X
559
560 Term::_csi_b 3
561 check "repeat" {
562 "abcdefgh"
563 "ijXXXnop"
564 "qrstuvwx"
565 "yz01234 "
566 } 5 1
567 }
568
569 proc test_vertical_line_position_absolute { } {
570 Term::_move_cursor 2 1
571
572 Term::_csi_d
573 check "default param" {
574 "abcdefgh"
575 "ijklmnop"
576 "qrstuvwx"
577 "yz01234 "
578 } 2 0
579
580 Term::_csi_d 3
581 check "explicit param" {
582 "abcdefgh"
583 "ijklmnop"
584 "qrstuvwx"
585 "yz01234 "
586 } 2 2
587
588 Term::_csi_d 100
589 check "try to move off-display" {
590 "abcdefgh"
591 "ijklmnop"
592 "qrstuvwx"
593 "yz01234 "
594 } 2 3
595 }
596
597 # Run proc TEST_PROC_NAME with a "small" terminal.
598
599 proc run_one_test_small { test_proc_name } {
600 save_vars { env(TERM) stty_init } {
601 setup_small
602 eval $test_proc_name
603 }
604 }
605
606 # Run proc TEST_PROC_NAME with a "large" terminal.
607
608 proc run_one_test_large { test_proc_name } {
609 save_vars { env(TERM) stty_init } {
610 setup_large
611 eval $test_proc_name
612 }
613 }
614
615 foreach_with_prefix test {
616 test_backspace
617 test_linefeed
618 test_carriage_return
619 test_insert_characters
620 test_cursor_up
621 test_cursor_down
622 test_cursor_forward
623 test_cursor_backward
624 test_cursor_next_line
625 test_cursor_previous_line
626 test_horizontal_absolute
627 test_cursor_position
628 test_erase_in_display
629 test_erase_in_line
630 test_delete_line
631 test_delete_character
632 test_erase_character
633 test_repeat
634 test_vertical_line_position_absolute
635 } {
636 run_one_test_small $test
637 }
638
639 foreach_with_prefix test {
640 test_cursor_horizontal_forward_tabulation
641 test_cursor_backward_tabulation
642 } {
643 run_one_test_large $test
644 }