# Copyright 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 <http://www.gnu.org/licenses/>.

# This test exercises the gdb-gdb.py helper script that is generated
# into the GDB build directory.  This script is intended for use by
# developers to make debugging GDB easier.

load_lib selftest-support.exp

if [target_info exists gdb,noinferiorio] {
    verbose "Skipping because of no inferiorio capabilities."
    return
}

# Find the helper script in the GDB build directory.
set py_helper_script [file dirname $GDB]/gdb-gdb.py
if { ![file readable $py_helper_script] \
	 || [file type $py_helper_script] != "file" } {
    untested "failed to find gdb-gdb.py helper script"
    return
}

# Start GDB and check that we have python support.
gdb_start
if { [skip_python_tests] } {
    untested "skipped gdb-gdb.py tests due to lack of python support"
    return
}
gdb_exit

# The main test.  This is called by the self-test framework once GDB
# has been started on a copy of itself.
proc test_python_helper {} {
    global py_helper_script decimal hex gdb_prompt
    global inferior_spawn_id

    # Source the python helper script.  This script registers the
    # pretty printer for the object file called 'gdb', however, in our
    # selftests we rename 'gdb' to 'xgdb', so the pretty printer
    # doesn't get registered by default.
    #
    # So, after sourcing the script we do our own objfile scan and
    # register the pretty printer for the objfile called 'xgdb'.
    gdb_test_no_output "source $py_helper_script" \
	"source gdb-gdb.py helper script"
    gdb_test [multi_line_input \
		  "python" \
		  "for objfile in gdb.objfiles():" \
		  "  if os.path.basename(objfile.filename) == \"xgdb\":" \
		  "    objfile.pretty_printers.append(type_lookup_function)" \
		  "end"] ".*" \
	"register the type pretty printer"

    # Now place a breakpoint somewhere useful.  This can be any function that:
    # (a) is easy to reach by issuing a simple gdb command, and
    # (b) is unlikely to be modified very often within gdb, and
    # (c) has a parameter that is either a 'struct type *' or a 'struct value *'.
    gdb_breakpoint value_print

    # Adjust the prompt on the outer gdb, this just makes things a
    # little clearer when trying to unpick which GDB is active.
    gdb_test_multiple "set prompt (xgdb) " "set xgdb prompt" {
	-re "\[(\]xgdb\[)\].*\[(\]xgdb\[)\] $" {
	    pass $gdb_test_name
	}
    }

    # Send a command to the outer GDB to continue the inner GDB.  The
    # stop is being detected from the inner GDB, hence the use of -i
    # here.
    gdb_test_multiple "continue" "start inner gdb" {
	-i "$inferior_spawn_id"
	-re "\r\n$gdb_prompt $" {
	    pass $gdb_test_name
	}
    }

    # Send a command to the inner GDB (hence send_inferior), this
    # should result in the outer GDB stopping at the breakpoint we
    # just created.
    send_inferior "print 1\n"
    gdb_test_multiple "" "hit breakpoint in inner gdb" {
	-re "Breakpoint $decimal, value_print.*\\(xgdb\\) $" {
	    pass $gdb_test_name
	}
    }

    # Now inspect the type of parameter VAL, this should trigger the
    # pretty printers.
    set answer [multi_line \
		    "${decimal} = " \
		    "{pointer_type = 0x0," \
		    " reference_type = 0x0," \
		    " chain = 0x0," \
		    " instance_flags = 0," \
		    " length = $decimal," \
		    " main_type = $hex}" \
		    "\\(xgdb\\) $"]
    gdb_test_multiple "print *val->type" "pretty print type" {
	-re "$answer" {
	    pass $gdb_test_name
	}
	-re "There is no member named.*\r\n\\(xgdb\\) $" {
	    fail $gdb_test_name
	}
    }

    set answer [multi_line \
		    "$decimal = " \
		    "{name = $hex \"int\"," \
		    " code = TYPE_CODE_INT," \
		    " flags = \[^\r\n\]+," \
		    " owner = $hex \\(gdbarch\\)," \
		    " target_type = 0x0," \
		    " type_specific_field = TYPE_SPECIFIC_NONE}" \
		    "\\(xgdb\\) $"]
    gdb_test_multiple "print *val->type->main_type" "pretty print type->main_type" {
	-re "$answer" {
	    pass $gdb_test_name
	}
	-re "There is no member named.*\r\n\\(xgdb\\) $" {
	    fail $gdb_test_name
	}
    }

    return 0
}

# Use the self-test framework to run the test.
do_self_tests captured_main test_python_helper
