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

# Utilities for python-scripting related tests.

# Run a command in GDB, and report a failure if a Python exception is thrown.
# If report_pass is true, report a pass if no exception is thrown.

proc gdb_py_test_silent_cmd { cmd name report_pass } {
    global gdb_prompt

    gdb_test_multiple $cmd $name {
	-re "Error occurred in Python:.*$gdb_prompt $" { fail $name }
	-re "Traceback.*$gdb_prompt $" { fail $name }
	-re "$gdb_prompt $"            { if $report_pass { pass $name } }
    }
}

# Return the result of python expression EXPR.  DEFAULT is returned if
# there's an error.  TEST is the test message to use.  It can be
# omitted, in which case a test message is built from EXP.  This is
# modeled after get_integer_valueof.

proc get_python_valueof { exp default {test ""} } {
    global gdb_prompt

    if {$test == ""} {
	set test "get python valueof \"${exp}\""
    }

    set val ${default}
    gdb_test_multiple "python print (\"valueof: %s\" % (${exp}))" "$test" {
	-re "valueof: (\[^\r\n\]*)\[\r\n\]*$gdb_prompt $" {
	    set val $expect_out(1,string)
	    pass "$test"
	}
	timeout {
	    fail "$test (timeout)"
	}
    }
    return ${val}
}

# Return true if Python module NAME is available, otherwise, return
# false.

proc gdb_py_module_available { name } {
    set available "unknown"
    gdb_test_multiple "python import ${name}" "" {
	-re -wrap "ModuleNotFoundError.*: No module named '${name}'.*" {
	    set available false
	}
	-re -wrap "ImportError: No module named '?${name}'?.*" {
	    set available false
	}
	-re -wrap "python import ${name}" {
	    set available true
	}
    }

    if { $available == "unknown" } {
	perror "unexpected output from python import"
	set available false
    }

    return ${available}
}

# Run a memory leak test within the Python script FILENAME.  This proc
# checks that the required Python modules are available, sets up the
# syspath so that the helper module can be found (in the same
# directory as FILENAME), then loads FILENAME to run the test.
proc gdb_py_run_memory_leak_test { filename testname } {
    if { ![gdb_py_module_available "tracemalloc"] } {
	unsupported "$testname (tracemalloc module not available)"
    }

    gdb_test_no_output -nopass "python import sys"
    gdb_test_no_output -nopass \
	"python sys.path.insert(0, \"[file dirname $filename]\")" \
	"setup sys.path"

    set pyfile [gdb_remote_download host ${filename}]

    # Source the Python script, this runs the test, and either prints
    # PASS, or throws an exception.
    gdb_test "source ${pyfile}" "^PASS" $testname
}
