Fix null pointer dereference in process_debug_info()
[binutils-gdb.git] / gdb / testsuite / gdb.tui / tuiterm.exp
blobcf87ee20e490a976b94af6c2abbabffc30e35e88
1 # Copyright 2022-2024 Free Software Foundation, Inc.
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.
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.
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/>.
16 # Unit-test Term, the testsuite's terminal implementation that is used to test
17 # the TUI.
19 tuiterm_env
21 # Validate the cursor position.
23 # EXPECTED_CUR_COL and EXPECTED_CUR_ROW are the expected cursor column and row
24 # positions.
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"
33 # Validate the terminal contents and cursor position.
35 # EXPECTED_CONTENTS must be a list of strings, one element for each terminal
36 # line.
38 # EXPECTED_CUR_COL and EXPECTED_CUR_ROW are passed to check_cursor_position.
40 proc check { test expected_contents expected_cur_col expected_cur_row } {
41 with_test_prefix $test {
42 # Check term contents.
43 set regexp "^"
45 foreach line $expected_contents {
46 append regexp $line
47 append regexp "\n"
50 append regexp "$"
51 Term::check_contents "contents" $regexp
54 check_cursor_position $test $expected_cur_col $expected_cur_row
57 proc setup_terminal { cols rows } {
58 setenv TERM ansi
59 Term::_setup $rows $cols
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:
65 # abcdefgh
66 # ijklmnop
67 # qrstuvwx
68 # yz01234
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.
74 proc setup_small {} {
75 setup_terminal 8 4
77 Term::_insert "abcdefgh"
78 Term::_insert "ijklmnop"
79 Term::_insert "qrstuvwx"
80 Term::_insert "yz01234"
82 check "check after setup" {
83 "abcdefgh"
84 "ijklmnop"
85 "qrstuvwx"
86 "yz01234 "
87 } 7 3
90 # Some tests require a larger terminal. This proc initializes the terminal with
91 # 80 columns and 25 rows, but leaves the content empty.
93 proc setup_large {} {
94 setup_terminal 80 25
97 # Each proc below tests a control character or sequence individually.
99 proc test_backspace {} {
100 # Note: the backspace (BS) control character only moves the cursor left,
101 # it does not delete characters.
103 Term::_move_cursor 1 2
105 Term::_ctl_0x08
106 check "backspace one" {
107 "abcdefgh"
108 "ijklmnop"
109 "qrstuvwx"
110 "yz01234 "
111 } 0 2
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
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
134 proc test_linefeed_scroll { } {
135 Term::_move_cursor 0 3
136 Term::_ctl_0x0a
137 check "linefeed_scroll" {
138 "ijklmnop"
139 "qrstuvwx"
140 "yz01234 "
141 "yz01234 "
142 } 0 3
143 Term::dump_screen
146 proc test_carriage_return { } {
147 Term::_move_cursor 1 2
148 Term::_ctl_0x0d
149 check "carriage return 1" {
150 "abcdefgh"
151 "ijklmnop"
152 "qrstuvwx"
153 "yz01234 "
154 } 0 2
156 Term::_ctl_0x0d
157 check "carriage return 2" {
158 "abcdefgh"
159 "ijklmnop"
160 "qrstuvwx"
161 "yz01234 "
162 } 0 2
165 proc test_insert_characters { } {
166 Term::_move_cursor 1 2
168 Term::_csi_@
169 check "insert characters 1" {
170 "abcdefgh"
171 "ijklmnop"
172 "q rstuvw"
173 "yz01234 "
174 } 1 2
176 Term::_csi_@ 20
177 check "insert characters 2" {
178 "abcdefgh"
179 "ijklmnop"
180 "q "
181 "yz01234 "
182 } 1 2
184 Term::_move_cursor 0 1
185 Term::_csi_@ 6
186 check "insert characters 3" {
187 "abcdefgh"
188 " ij"
189 "q "
190 "yz01234 "
191 } 0 1
194 proc test_pan_down { } {
195 Term::_move_cursor 1 2
196 Term::_csi_S
197 check "pan down, default arg" {
198 "ijklmnop"
199 "qrstuvwx"
200 "yz01234 "
202 } 1 2
204 Term::_csi_S 2
205 check "pan down, explicit arg" {
206 "yz01234 "
210 } 1 2
212 Term::_csi_S 100
213 check "pan down, excessive arg" {
218 } 1 2
221 proc test_pan_up { } {
222 Term::_move_cursor 1 2
223 Term::_csi_T
224 check "pan down, default arg" {
226 "abcdefgh"
227 "ijklmnop"
228 "qrstuvwx"
229 } 1 2
231 Term::_csi_T 2
232 check "pan down, explicit arg" {
236 "abcdefgh"
237 } 1 2
239 Term::_csi_T 100
240 check "pan down, excessive arg" {
245 } 1 2
248 proc test_cursor_up { } {
249 Term::_move_cursor 2 3
251 Term::_csi_A
252 check "cursor up 1" {
253 "abcdefgh"
254 "ijklmnop"
255 "qrstuvwx"
256 "yz01234 "
257 } 2 2
259 Term::_csi_A 2
260 check "cursor up 2" {
261 "abcdefgh"
262 "ijklmnop"
263 "qrstuvwx"
264 "yz01234 "
265 } 2 0
267 Term::_csi_A 1
268 check "cursor up 3" {
269 "abcdefgh"
270 "ijklmnop"
271 "qrstuvwx"
272 "yz01234 "
273 } 2 0
276 proc test_cursor_down { } {
277 Term::_move_cursor 1 0
279 Term::_csi_B
280 check "cursor down 1" {
281 "abcdefgh"
282 "ijklmnop"
283 "qrstuvwx"
284 "yz01234 "
285 } 1 1
287 Term::_csi_B 2
288 check "cursor down 2" {
289 "abcdefgh"
290 "ijklmnop"
291 "qrstuvwx"
292 "yz01234 "
293 } 1 3
295 Term::_csi_B 1
296 check "cursor down 3" {
297 "abcdefgh"
298 "ijklmnop"
299 "qrstuvwx"
300 "yz01234 "
301 } 1 3
304 proc test_cursor_forward { } {
305 Term::_move_cursor 0 1
307 Term::_csi_C
308 check "cursor forward 1" {
309 "abcdefgh"
310 "ijklmnop"
311 "qrstuvwx"
312 "yz01234 "
313 } 1 1
315 Term::_csi_C 6
316 check "cursor forward 2" {
317 "abcdefgh"
318 "ijklmnop"
319 "qrstuvwx"
320 "yz01234 "
321 } 7 1
323 Term::_csi_C 1
324 check "cursor forward 3" {
325 "abcdefgh"
326 "ijklmnop"
327 "qrstuvwx"
328 "yz01234 "
329 } 7 1
332 proc test_cursor_backward { } {
333 Term::_move_cursor 7 1
335 Term::_csi_D
336 check "cursor backward 1" {
337 "abcdefgh"
338 "ijklmnop"
339 "qrstuvwx"
340 "yz01234 "
341 } 6 1
343 Term::_csi_D 6
344 check "cursor backward 2" {
345 "abcdefgh"
346 "ijklmnop"
347 "qrstuvwx"
348 "yz01234 "
349 } 0 1
351 Term::_csi_D 1
352 check "cursor backward 3" {
353 "abcdefgh"
354 "ijklmnop"
355 "qrstuvwx"
356 "yz01234 "
357 } 0 1
360 proc test_cursor_next_line { } {
361 Term::_move_cursor 2 0
363 Term::_csi_E
364 check "cursor next line 1" {
365 "abcdefgh"
366 "ijklmnop"
367 "qrstuvwx"
368 "yz01234 "
369 } 0 1
371 Term::_move_cursor 2 1
372 Term::_csi_E 2
373 check "cursor next line 2" {
374 "abcdefgh"
375 "ijklmnop"
376 "qrstuvwx"
377 "yz01234 "
378 } 0 3
380 Term::_move_cursor 2 3
381 Term::_csi_E 1
382 check "cursor next line 3" {
383 "abcdefgh"
384 "ijklmnop"
385 "qrstuvwx"
386 "yz01234 "
387 } 0 3
390 proc test_cursor_previous_line { } {
391 Term::_move_cursor 2 3
393 Term::_csi_F
394 check "cursor previous line 1" {
395 "abcdefgh"
396 "ijklmnop"
397 "qrstuvwx"
398 "yz01234 "
399 } 0 2
401 Term::_move_cursor 2 2
402 Term::_csi_F 2
403 check "cursor previous line 2" {
404 "abcdefgh"
405 "ijklmnop"
406 "qrstuvwx"
407 "yz01234 "
408 } 0 0
410 Term::_move_cursor 2 0
411 Term::_csi_F 1
412 check "cursor previous line 3" {
413 "abcdefgh"
414 "ijklmnop"
415 "qrstuvwx"
416 "yz01234 "
417 } 0 0
420 proc test_horizontal_absolute { } {
421 Term::_move_cursor 2 2
422 Term::_csi_G
423 check "cursor horizontal absolute 1" {
424 "abcdefgh"
425 "ijklmnop"
426 "qrstuvwx"
427 "yz01234 "
428 } 0 2
430 Term::_move_cursor 2 2
431 Term::_csi_G 4
432 check "cursor horizontal absolute 2" {
433 "abcdefgh"
434 "ijklmnop"
435 "qrstuvwx"
436 "yz01234 "
437 } 3 2
440 proc test_cursor_position { } {
441 Term::_move_cursor 1 1
443 Term::_csi_H 3 5
444 check "cursor horizontal absolute 2" {
445 "abcdefgh"
446 "ijklmnop"
447 "qrstuvwx"
448 "yz01234 "
449 } 4 2
452 proc test_cursor_horizontal_forward_tabulation { } {
453 Term::_move_cursor 5 2
454 Term::_csi_I
455 check_cursor_position "default param" 8 2
457 Term::_csi_I 2
458 check_cursor_position "explicit param" 24 2
460 Term::_move_cursor 77 2
461 Term::_csi_I 5
462 check_cursor_position "try to go past the end" 79 2
465 proc test_erase_in_display { } {
466 Term::_move_cursor 5 2
467 Term::_csi_J
468 check "erase in display, cursor to end with default param" {
469 "abcdefgh"
470 "ijklmnop"
471 "qrstu "
473 } 5 2
475 Term::_move_cursor 3 2
476 Term::_csi_J 0
477 check "erase in display, cursor to end with explicit param" {
478 "abcdefgh"
479 "ijklmnop"
480 "qrs "
482 } 3 2
484 Term::_move_cursor 2 1
485 Term::_csi_J 1
486 check "erase in display, beginning to cursor" {
488 " lmnop"
489 "qrs "
491 } 2 1
493 Term::_move_cursor 5 1
494 Term::_csi_J 2
495 check "erase in display, entire display" {
500 } 5 1
503 proc test_erase_in_line { } {
504 Term::_move_cursor 5 2
505 Term::_csi_K
506 check "erase in line, cursor to end with default param" {
507 "abcdefgh"
508 "ijklmnop"
509 "qrstu "
510 "yz01234 "
511 } 5 2
513 Term::_move_cursor 3 2
514 Term::_csi_K 0
515 check "erase in line, cursor to end with explicit param" {
516 "abcdefgh"
517 "ijklmnop"
518 "qrs "
519 "yz01234 "
520 } 3 2
522 Term::_move_cursor 3 1
523 Term::_csi_K 1
524 check "erase in line, beginning to cursor" {
525 "abcdefgh"
526 " mnop"
527 "qrs "
528 "yz01234 "
529 } 3 1
531 Term::_move_cursor 3 0
532 Term::_csi_K 2
533 check "erase in line, entire line" {
535 " mnop"
536 "qrs "
537 "yz01234 "
538 } 3 0
541 proc test_delete_line { } {
542 Term::_move_cursor 3 2
543 Term::_csi_M
544 check "delete line, default param" {
545 "abcdefgh"
546 "ijklmnop"
547 "yz01234 "
549 } 3 2
551 Term::_move_cursor 3 0
552 Term::_csi_M 2
553 check "delete line, explicit param" {
554 "yz01234 "
558 } 3 0
561 proc test_delete_character { } {
562 Term::_move_cursor 2 1
564 Term::_csi_P
565 check "delete character, default param" {
566 "abcdefgh"
567 "ijlmnop "
568 "qrstuvwx"
569 "yz01234 "
570 } 2 1
572 Term::_csi_P 3
573 check "delete character, explicit param" {
574 "abcdefgh"
575 "ijop "
576 "qrstuvwx"
577 "yz01234 "
578 } 2 1
580 Term::_csi_P 12
581 check "delete character, more than number of columns" {
582 "abcdefgh"
583 "ij "
584 "qrstuvwx"
585 "yz01234 "
586 } 2 1
589 proc test_erase_character { } {
590 Term::_move_cursor 3 2
591 Term::_csi_X
592 check "erase character, default param" {
593 "abcdefgh"
594 "ijklmnop"
595 "qrs uvwx"
596 "yz01234 "
597 } 3 2
599 Term::_move_cursor 1 3
600 Term::_csi_X 4
601 check "erase character, explicit param" {
602 "abcdefgh"
603 "ijklmnop"
604 "qrs uvwx"
605 "y 34 "
606 } 1 3
609 proc test_cursor_backward_tabulation { } {
610 Term::_move_cursor 77 2
611 Term::_csi_Z
612 check_cursor_position "default param" 72 2
614 Term::_csi_Z 2
615 check_cursor_position "explicit param" 56 2
617 Term::_move_cursor 6 2
618 Term::_csi_Z 12
619 check_cursor_position "try to go past the beginning" 0 2
622 proc test_repeat { } {
623 Term::_move_cursor 2 1
624 set Term::_last_char X
626 Term::_csi_b 3
627 check "repeat" {
628 "abcdefgh"
629 "ijXXXnop"
630 "qrstuvwx"
631 "yz01234 "
632 } 5 1
635 proc test_vertical_line_position_absolute { } {
636 Term::_move_cursor 2 1
638 Term::_csi_d
639 check "default param" {
640 "abcdefgh"
641 "ijklmnop"
642 "qrstuvwx"
643 "yz01234 "
644 } 2 0
646 Term::_csi_d 3
647 check "explicit param" {
648 "abcdefgh"
649 "ijklmnop"
650 "qrstuvwx"
651 "yz01234 "
652 } 2 2
654 Term::_csi_d 100
655 check "try to move off-display" {
656 "abcdefgh"
657 "ijklmnop"
658 "qrstuvwx"
659 "yz01234 "
660 } 2 3
663 proc test_insert_line { } {
664 Term::_move_cursor 2 1
665 Term::_csi_L
666 check "insert line, default param" {
667 "abcdefgh"
669 "ijklmnop"
670 "qrstuvwx"
671 } 2 1
673 Term::_move_cursor 2 0
674 Term::_csi_L 2
675 check "insert line, explicit param" {
678 "abcdefgh"
680 } 2 0
682 Term::_csi_L 12
683 check "insert line, insert more lines than display has" {
688 } 2 0
691 proc test_attrs {} {
692 foreach { attr vals } {
693 reverse {
695 27 0
697 underline {
699 24 0
701 intensity {
702 1 bold
703 2 dim
704 22 normal
706 invisible {
708 28 0
710 blinking {
712 25 0
714 fg {
715 30 black
716 31 red
717 32 green
718 33 yellow
719 34 blue
720 35 magenta
721 36 cyan
722 37 white
723 39 default
725 bg {
726 40 black
727 41 red
728 42 green
729 43 yellow
730 44 blue
731 45 magenta
732 46 cyan
733 47 white
734 49 default
737 setup_terminal 12 1
738 set re ""
739 foreach { arg val } $vals {
740 Term::_insert "a"
741 Term::_csi_m $arg
742 append re "a<$attr:$val>"
745 Term::_insert "a"
746 append re "a"
748 set re "^$re *$"
750 set line [Term::get_line_with_attrs 0]
751 gdb_assert { [regexp $re $line] } "attribute: $attr"
755 # Run proc TEST_PROC_NAME with a "small" terminal.
757 proc run_one_test_small { test_proc_name } {
758 save_vars { env(TERM) stty_init } {
759 setup_small
760 eval $test_proc_name
764 # Run proc TEST_PROC_NAME with a "large" terminal.
766 proc run_one_test_large { test_proc_name } {
767 save_vars { env(TERM) stty_init } {
768 setup_large
769 eval $test_proc_name
773 foreach_with_prefix test {
774 test_backspace
775 test_linefeed
776 test_linefeed_scroll
777 test_carriage_return
778 test_insert_characters
779 test_cursor_up
780 test_cursor_down
781 test_cursor_forward
782 test_cursor_backward
783 test_cursor_next_line
784 test_cursor_previous_line
785 test_horizontal_absolute
786 test_cursor_position
787 test_erase_in_display
788 test_erase_in_line
789 test_delete_line
790 test_delete_character
791 test_erase_character
792 test_repeat
793 test_vertical_line_position_absolute
794 test_insert_line
795 test_pan_up
796 test_pan_down
798 run_one_test_small $test
801 foreach_with_prefix test {
802 test_cursor_horizontal_forward_tabulation
803 test_cursor_backward_tabulation
805 run_one_test_large $test
808 test_attrs