| # Copyright 2022-2024 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 <http://www.gnu.org/licenses/>. | |
| # 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 | |
| require allow_python_tests | |
| clean_restart | |
| # 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"] |