# Copyright 2003-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/>.

# Find a pathname to a file that we would execute if the shell was asked
# to run $arg using the current PATH.

proc find_gdb { arg } {

    # If the arg directly specifies an existing executable file, then
    # simply use it.

    if [file executable $arg] then {
	return $arg
    }

    set result [which $arg]
    if [string match "/" [ string range $result 0 0 ]] then {
	return $result
    }

    # If everything fails, just return the unqualified pathname as default
    # and hope for best.

    return $arg
}

# A helper proc that sets up for self-testing.
# EXECUTABLE is the gdb to use.
# FUNCTION is the function to break in, either captured_main
# or captured_command_loop.
# Return 0 in case of success, -1 in case of failure, and -2 in case of
# skipping the test-case.

proc selftest_setup { executable function } {
    global gdb_prompt
    global timeout
    global INTERNAL_GDBFLAGS

    # load yourself into the debugger
    # This can take a relatively long time, particularly for testing where
    # the executable is being accessed over a network, or where gdb does not
    # support partial symbols for a particular target and has to load the
    # entire symbol table.  Set the timeout to 10 minutes, which should be
    # adequate for most environments (it *has* timed out with 5 min on a
    # SPARCstation SLC under moderate load, so this isn't unreasonable).
    # After gdb is started, set the timeout to 30 seconds for the duration
    # of this test, and then back to the original value.

    set oldtimeout $timeout
    set timeout 600
    verbose "Timeout is now $timeout seconds" 2

    global gdb_file_cmd_debug_info
    set gdb_file_cmd_debug_info "unset"

    set result [gdb_load $executable]
    set timeout $oldtimeout
    verbose "Timeout is now $timeout seconds" 2

    if { $result != 0 } then {
	return -1
    }

    if { $gdb_file_cmd_debug_info != "debug" } then {
	untested "no debug information, skipping testcase."
	return -2
    }

    # Set a breakpoint at $function.
    if { [gdb_breakpoint $function "no-message"] != 1 } {
	untested "Cannot set breakpoint at $function, skipping testcase."
	return -2
    }

    # run yourself
    # It may take a very long time for the inferior gdb to start (lynx),
    # so we bump it back up for the duration of this command.
    set timeout 600

    set description "run until breakpoint at $function"
    gdb_test_multiple "run $INTERNAL_GDBFLAGS" "$description" {
        -re "Starting program.*Breakpoint \[0-9\]+,.*$function \\(.*\\).* at .*main.c:.*$gdb_prompt $" {
            pass "$description"
        }
        -re "Starting program.*Breakpoint \[0-9\]+,.*$function \\(.*\\).*$gdb_prompt $" {
            xfail "$description (line numbers scrambled?)"
        }
        -re "vfork: No more processes.*$gdb_prompt $" {
            fail "$description (out of virtual memory)"
            set timeout $oldtimeout
            verbose "Timeout is now $timeout seconds" 2
            return -1
        }
        -re ".*$gdb_prompt $" {
            fail "$description"
            set timeout $oldtimeout
            verbose "Timeout is now $timeout seconds" 2
            return -1
        }
    }

    set timeout $oldtimeout
    verbose "Timeout is now $timeout seconds" 2

    return 0
}

# A simple way to run some self-tests.

proc do_self_tests {function body} {
    global GDB tool

    # Are we testing with a remote board?  In that case, the target
    # won't have access to the GDB's auxilliary data files
    # (data-directory, etc.).  It's simpler to just skip.
    if [is_remote target] {
	return
    }

    # ... or seemingly testing with a cross debugger?  Likely GDB
    # wouldn't be able to debug itself then...
    if ![isnative] {
	return
    }

    # ... or with a stub-like server?  I.e., gdbserver + "target
    # remote"?  In that case we won't be able to pass command line
    # arguments to GDB, and selftest_setup wants to do exactly that.
    if [use_gdb_stub] {
	return
    }

    # Run the test with self.  Copy the file executable file in case
    # this OS doesn't like to edit its own text space.

    set GDB_FULLPATH [find_gdb $GDB]

    if {[is_remote host]} {
	set xgdb x$tool
    } else {
	set xgdb [standard_output_file x$tool]
    }

    # Remove any old copy lying around.
    remote_file host delete $xgdb

    gdb_start
    set file [remote_download host $GDB_FULLPATH $xgdb]

    set result [selftest_setup $file $function]
    if {$result == 0} then {
	set result [uplevel $body]
    }

    gdb_exit
    catch "remote_file host delete $file"

    if {$result == -1} then {
	warning "Couldn't test self"
    }
}
