# Copyright 2022-2023 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 how GDB reformats the documentation string of commands # implemented in Python for use as the help text of those same # commands. load_lib gdb-python.exp # Check that Python is supported. clean_restart if { [skip_python_tests] } { continue } # A global counter used to number the tests. set idx 0 # Run a test, create both a command and a parameter with INPUT_DOCS as # the Python documentation string, load the command and parameter into # GDB, and then ask for the help text of the command, and the show and # set help for the parameter. The output from GDB should match # EXPECTED_OUTPUT in each case. # # The INPUT_DOCS must start with 2 space characters, followed by the # 3-quote characters to start the doc string, and must end with the # final 3-quote characters. If this is not true then an error is # thrown, and this function immediately returns. proc test { input_docs expected_output } { global idx set local_idx $idx incr idx with_test_prefix "test ${local_idx}" { # The tests in this script don't have descriptive names, # rather they use the global IDX to generate a unique name for # each test. To make it easier to track down a failing test, # we print out the test name and the input string. verbose -log "Start of: test_cmd ${local_idx}" verbose -log "Input:\n${input_docs}" if { [string range $input_docs 0 4] != " \"\"\"" } { perror "Input string does not start with the required pattern" return } if { [string range $input_docs end-2 end] != "\"\"\"" } { perror "Input string does not end with the required pattern" return } set python_filename [standard_output_file "${::gdb_test_file_name}-${local_idx}.py"] set fd [open $python_filename w] puts $fd "class test_cmd (gdb.Command):" puts $fd $input_docs puts $fd "" puts $fd " def __init__ (self):" puts $fd " super ().__init__ (\"test-cmd\", gdb.COMMAND_OBSCURE)" puts $fd "" puts $fd " def invoke (self, arg, from_tty):" puts $fd " print (\"In test-cmd\")" puts $fd "" puts $fd "class test_param (gdb.Parameter):" puts $fd $input_docs puts $fd "" puts $fd " show_doc = \"This is the show doc line\"" puts $fd " set_doc = \"This is the set doc line\"" puts $fd "" puts $fd " def __init__ (self):" puts $fd " super ().__init__ (\"test-param\", gdb.COMMAND_OBSCURE, gdb.PARAM_BOOLEAN)" puts $fd "" puts $fd " def get_show_string (self, value):" puts $fd " return \"The state is '\" + value + \"'\"" puts $fd "" puts $fd "test_param ()" puts $fd "test_cmd ()" puts $fd "" puts $fd "print(\"Loaded OK.\")" close $fd set remote_python_file \ [gdb_remote_download host $python_filename] clean_restart gdb_test "source ${remote_python_file}" \ "Loaded OK\\." \ "source python command file" # Use gdb_test_multiple here as plain gdb_test will allow # excess blank lines between the expected_output pattern and # the gdb_prompt - a core part of this test is that we are # checking that such blank lines are removed - so we can't use # gdb_test here. gdb_test_multiple "help test-cmd" "" { -re "^help test-cmd\r\n" { exp_continue } -re "^$expected_output\r\n$::gdb_prompt $" { pass $gdb_test_name } } gdb_test_multiple "help set test-param" "" { -re "^help set test-param\r\n" { exp_continue } -re "^This is the set doc line\r\n" { exp_continue } -re "^$expected_output\r\n$::gdb_prompt $" { pass $gdb_test_name } } gdb_test_multiple "help show test-param" "" { -re "^help show test-param\r\n" { exp_continue } -re "^This is the show doc line\r\n" { exp_continue } -re "^$expected_output\r\n$::gdb_prompt $" { pass $gdb_test_name } } } } # The first test is pretty vanilla. First line starts immediately # after the opening quotes, and closing quotes are immediately after # the last line. test \ [multi_line_input \ " \"\"\"This is the first line." \ "" \ " This is the third line.\"\"\""] \ [multi_line \ "This is the first line\\." \ "" \ "This is the third line\\."] # In this test the first line starts on the line after the opening # quotes. The blank line in the middle is still completely empty. test \ [multi_line_input \ " \"\"\"" \ " This is the first line." \ "" \ " This is the third line.\"\"\""] \ [multi_line \ "This is the first line\\." \ "" \ "This is the third line\\."] # This test adds an indented line in the middle, we expect the # relative indentation to be retained. test\ [multi_line_input \ " \"\"\"" \ " This is the first line." \ " Indented second line." \ " This is the third line.\"\"\""] \ [multi_line \ "This is the first line\\." \ " Indented second line\\." \ "This is the third line\\."] # The indentation moves to the first line. test\ [multi_line_input \ " \"\"\"" \ " Indented first line." \ " This is the second line." \ " This is the third line.\"\"\""] \ [multi_line \ " Indented first line\\." \ "This is the second line\\." \ "This is the third line\\."] # The indentation moves to the last line. test\ [multi_line_input \ " \"\"\"" \ " This is the first line." \ " This is the second line." \ " Indented third line.\"\"\""] \ [multi_line \ "This is the first line\\." \ "This is the second line\\." \ " Indented third line\\."] # Tests using different amounts of white-space on a line of its own. # We test with the white-space at the beginning, end, and in the # middle of the doc string. foreach line [list "" " " " " " " " "] { # Blank lines at the beginning should be removed. test \ [multi_line_input \ " \"\"\"" \ $line \ " This is the first line." \ " Indented second line." \ " This is the third line.\"\"\""] \ [multi_line \ "This is the first line\\." \ " Indented second line\\." \ "This is the third line\\."] # As should blank lines at the end. test \ [multi_line_input \ " \"\"\"" \ " This is the first line." \ " Indented second line." \ " This is the third line." \ $line \ " \"\"\""] \ [multi_line \ "This is the first line\\." \ " Indented second line\\." \ "This is the third line\\."] # While blank lines in the middle should have all white-space # removed. test \ [multi_line_input \ " \"\"\"" \ " This is the first line." \ $line \ " This is the third line." \ $line \ " \"\"\""] \ [multi_line \ "This is the first line\\." \ "" \ "This is the third line\\."] } # Check for correct handling of closing quotes being on a line of # their own. test\ [multi_line_input \ " \"\"\" " \ " This is the first line." \ " Indented second line." \ " This is the third line." \ " \"\"\""] \ [multi_line \ "This is the first line\\." \ " Indented second line\\." \ "This is the third line\\." ] # Check with a single 'x' character before the closing quotes. Make # sure we don't drop this character. test\ [multi_line_input \ " \"\"\" " \ " This is the first line." \ " Indented second line." \ " This is the third line." \ " x\"\"\""] \ [multi_line \ "This is the first line\\." \ " Indented second line\\." \ "This is the third line\\." \ "x"]