# Copyright 2018-2021 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Test CLI output styling. standard_testfile # Compile the test executable. set test_macros 0 set options debug get_compiler_info if { [test_compiler_info "gcc-*"] } { lappend options additional_flags=-g3 set test_macros 1 } elseif { [test_compiler_info "clang-*"] } { lappend options additional_flags=-fdebug-macro set test_macros 1 } if {[build_executable "failed to build" $testfile $srcfile $options]} { return -1 } # The tests in this file are run multiple times with GDB's styles # disabled one at a time. This variable is the style that is # currently disabled. set currently_disabled_style "" # A wrapper around the 'style' function found in gdb-utils.exp, # filter out requests for the disabled style. proc limited_style { str style } { global currently_disabled_style if { $style != $currently_disabled_style } { return [style $str $style] } return $str } # A wrapper around 'clean_restart' from gdb.exp, this performs the # normal clean_restart, but then disables the currently disabled # style. proc clean_restart_and_disable { args } { global currently_disabled_style eval "clean_restart $args" if { $currently_disabled_style != "" } { set st $currently_disabled_style gdb_test_no_output "set style $st background none" "" gdb_test_no_output "set style $st foreground none" "" gdb_test_no_output "set style $st intensity normal" "" } } # The core of this test script. Run some tests of different aspects # of GDB's styling. # # Within this proc always use LIMITED_STYLE instead of STYLE, and # CLEAN_RESTART_AND_DISABLE instead of CLEAN_RESTART, this ensures # that the test operates as expected as styles are disabled. proc run_style_tests { } { global testfile srcfile hex binfile test_macros global currently_disabled_style decimal hex save_vars { env(TERM) } { # We need an ANSI-capable terminal to get the output. setenv TERM ansi # Restart GDB with the correct TERM variable setting, this # means that GDB will enable styling. clean_restart_and_disable ${binfile} set readnow [readnow] if {![runto_main]} { fail "style tests failed" return } # Check that the source highlighter has not stripped away the # leading newlines. set main_line [gdb_get_line_number "break here"] gdb_test "list $main_line,$main_line" "return.*some_called_function.*" gdb_test_no_output "set style enabled off" set argv "" gdb_test_multiple "frame" "frame without styling" { -re -wrap "main \\(argc=.*, (argv=$hex)\\).*style\\.c:\[0-9\].*" { set argv $expect_out(1,string) pass $gdb_test_name } } gdb_test_no_output "set style enabled on" set main_expr [limited_style main function] set base_file_expr [limited_style ".*style\\.c" file] set file_expr "$base_file_expr:\[0-9\]+" set arg_expr [limited_style "arg." variable] gdb_test "frame" \ [multi_line \ "#0\\s+$main_expr\\s+\\($arg_expr=$decimal,\\s+$arg_expr=$hex\\)\\s+at\\s+$file_expr" \ "\[0-9\]+\\s+.*return.* break here .*"] gdb_test "info breakpoints" "$main_expr at $file_expr.*" gdb_test_no_output "set style sources off" gdb_test "frame" \ "\r\n\[^\033\]*break here.*" \ "frame without sources styling" gdb_test_no_output "set style sources on" gdb_test "break -q main" "file $base_file_expr.*" gdb_test "print &main" " = .* [limited_style $hex address] <$main_expr>" # Regression test for a bug where line-wrapping would occur at # the wrong spot with styling. There were different bugs at # different widths, so try two. foreach width {20 30} { set argv_len [string length $argv] if { $argv_len == 0 } { continue } # There was also a bug where the styling could be wrong in # the line listing; this is why the words from the source # code are spelled out in the final result line of the # test. set re1_styled \ [multi_line \ "#0\\s+$main_expr\\s+\\($arg_expr=$decimal,\\s+" \ "\\s+$arg_expr=$hex\\)" \ "\\s+at\\s+$file_expr" \ "\[0-9\]+\\s+.*return.* break here .*"] set re2_styled \ [multi_line \ "#0\\s+$main_expr\\s+\\($arg_expr=.*" \ "\\s+$arg_expr=$hex\\)\\s+at\\s+$file_expr" \ "\[0-9\]+\\s+.*return.* break here .*"] # The length of the line containing argv containing: # - 4 leading spaces # - argv string # - closing parenthesis set line_len [expr 4 + $argv_len + 1] if { $line_len > $width } { # At on the next line. set re_styled $re1_styled } else { # At on the same line as argv. set re_styled $re2_styled } gdb_test_no_output "set width $width" gdb_test "frame" $re_styled "frame when width=$width" } # Reset width back to 0. gdb_test_no_output "set width 0" "" if {$test_macros} { set macro_line [gdb_get_line_number "\#define SOME_MACRO"] gdb_test "info macro SOME_MACRO" \ "Defined at $base_file_expr:$macro_line\r\n#define SOME_MACRO 23" } gdb_test_no_output "set width 0" set main [limited_style main function] set func [limited_style some_called_function function] # Somewhere should see the call to the function. gdb_test "disassemble main" \ [concat "Dump of assembler code for function $main:.*" \ "[limited_style $hex address].*$func.*"] set ifield [limited_style int_field variable] set sfield [limited_style string_field variable] set efield [limited_style e_field variable] set evalue [limited_style VALUE_TWO variable] gdb_test "print struct_value" \ "\{$ifield = 23,.*$sfield = .*,.*$efield = $evalue.*" set ffield [limited_style field variable] set cstart [string_to_regexp "/* XXX "] set cend [string_to_regexp " */"] set p1field [limited_style "$cstart.*$decimal.*-bit.*padding.*$cend" \ highlight] set p2field [limited_style "$cstart.*$decimal.*-byte.*padding.*$cend" \ highlight] gdb_test "ptype/o just_bitfield_value" \ [multi_line \ ".* type = struct just_bitfield {" \ ".* unsigned int $ffield : 3;" \ "$p1field" \ "$p2field" \ "" \ ".* total size.*: *$decimal *$cend" \ " *}.*"] set address_style_expr [limited_style ".*\".*address.*\".*style.*" address] set color "blue" if { $currently_disabled_style == "address" } { set color "none" } gdb_test "show style address foreground" \ "The ${address_style_expr} foreground color is: ${color}" \ "style name and style word styled using its own style in show style" set aliases_expr [limited_style ".*aliases.*" title] set breakpoints_expr [limited_style ".*breakpoints.*" title] gdb_test "help" \ [multi_line \ "List of classes of commands:" \ "" \ "${aliases_expr} -- User-defined aliases of other commands\." \ "${breakpoints_expr} -- Making program stop at certain points\." \ ".*" \ ] \ "help classes of commands styled with title" set taas_expr [limited_style ".*taas.*" title] set tfaas_expr [limited_style ".*tfaas.*" title] set cut_for_thre_expr [limited_style "cut for 'thre" highlight] gdb_test "apropos -v cut for 'thre" \ [multi_line \ "" \ "${taas_expr}" \ "Apply a command to all .*" \ "Usage:.*" \ "short${cut_for_thre_expr}ad apply.*" \ "" \ "${tfaas_expr}" \ "Apply a command to all .*" \ "Usage:.*" \ "short${cut_for_thre_expr}ad apply.*" \ ] clean_restart_and_disable set quoted [string_to_regexp $binfile] set pass_re "Reading symbols from [limited_style $quoted file]\.\.\." if { $readnow } { set pass_re \ [multi_line \ $pass_re \ "Expanding full symbols from [limited_style $quoted file]\.\.\."] } gdb_test "file $binfile" \ $pass_re \ "filename is styled when loading symbol file" \ "Are you sure you want to change the file.*" \ "y" gdb_test "pwd" "Working directory [limited_style .*? file].*" gdb_test_no_output "set print repeat 3" gdb_test "print {0,0,0,0,0,0,0,0}" \ " = \\{0 [limited_style {} metadata]\\}" gdb_test "show logging file" \ "The current logfile is \"[limited_style .*? file]\"\\..*" # Check warnings are styled by setting a rubbish data # directory. gdb_test "set data-directory Makefile" \ "warning: [limited_style .*? file] is not a directory\\..*" gdb_test "show data-directory" \ "GDB's data directory is \"[limited_style .*? file]\"\\..*" # Check that deprecation styles command names. gdb_test_no_output "maintenance deprecate p \"new_p\"" \ "maintenance deprecate p \"new_p\" /1/" gdb_test "p 5" \ "Warning: '[limited_style p title]', an alias for the command '[limited_style print title]', is deprecated.*Use '[limited_style new_p title]'.*" \ "p deprecated warning, with replacement" # Check that the version string is styled in the output of 'show # version', and that this styling can be disabled. set vers [style "GNU gdb.*" version] gdb_test "show version" "${vers}.*" \ "version is styled in 'show version'" } } # A separate test from the above as the styled text this checks can't # currently be disabled (the text is printed too early in GDB's # startup process). proc test_startup_version_string { } { gdb_exit gdb_spawn # Deliberate use of base STYLE proc here as the style of the # startup version string can't (currently) be controlled. set vers [style "GNU gdb.*" version] gdb_test "" "${vers}.*" "version is styled at startup" } # Run tests with all styles in their default state. with_test_prefix "all styles enabled" { run_style_tests } # Now, for each style in turn. Disable that style only and run the # test again. Things in that style should NOT now be styled. foreach style { title file function highlight variable \ address metadata } { set currently_disabled_style $style with_test_prefix "disable style $style" { run_style_tests } } # Finally, check the styling of the version string during startup. test_startup_version_string