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

# Test Machine interface (MI) operations
#
# Test MI watchpoint commands.
#
# The goal is not to test gdb functionality, which is done by other
# tests, but to verify the correct output response to MI operations.

load_lib mi-support.exp
set MIFLAGS "-i=mi"

gdb_exit

standard_testfile basics.c

if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
     untested "failed to compile"
     return -1
}

proc test_watchpoint_creation_and_listing {} {
    global mi_gdb_prompt
    global srcfile
    global hex

    set line_callee4_head [gdb_get_line_number "callee4 ("]
    set line_callee4_body [expr $line_callee4_head + 2]

    # Insert a watchpoint and list
    # Tests:
    # -break-watch C
    # -break-list

    mi_gdb_test "111-break-watch C" \
             "111\\^done,wpt=\{number=\"2\",exp=\"C\"\}" \
             "break-watch operation"

    mi_gdb_test "222-break-list" \
	    "222\\\^done,BreakpointTable=\{nr_rows=\".\",nr_cols=\".\",hdr=\\\[\{width=\".*\",alignment=\".*\",col_name=\"number\",colhdr=\"Num\"\}.*colhdr=\"Type\".*colhdr=\"Disp\".*colhdr=\"Enb\".*colhdr=\"Address\".*colhdr=\"What\".*\\\],body=\\\[bkpt=\{number=\"2\",type=\".*watchpoint\",disp=\"keep\",enabled=\"y\",what=\"C\",thread-groups=\\\[\"i1\"\\\],times=\"0\",original-location=\"C\"\}\\\]\}" \
                "list of watchpoints"

}

# UNUSED at the time
proc test_awatch_creation_and_listing {} {
    global mi_gdb_prompt
    global srcfile
    global hex

    set line_main_head [gdb_get_line_number "main ("]
    set line_main_body [expr $line_main_head + 2]

    # Insert an access watchpoint and list it
    # Tests:
    # -break-watch -a A
    # -break-list

    mi_gdb_test "333-break-watch -a A" \
             "333\\^done,bkpt=\{number=\"1\",addr=\"$hex\",file=\".*basics.c\",line=\"$line_main_body\"\}" \
             "break-watch -a operation"

    mi_gdb_test "444-break-list" \
	    "444\\^done,BreakpointTable=\{.*,hdr=\\\[.*\\\],body=\\\[bkpt=\{number=\"3\",type=\"watchpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"$line_main_body\",thread-groups=\\\[\"i1\"\\\],times=\"0\"\},.*\}\\\]\}" \
                "list of watchpoints awatch"

    mi_gdb_test "777-break-delete 3" \
	    "777\\^done" \
	    "delete access watchpoint"
}

# UNUSED at the time
proc test_rwatch_creation_and_listing {} {
    global mi_gdb_prompt
    global srcfile
    global hex

    set line_main_head [gdb_get_line_number "main ("]
    set line_main_body [expr $line_main_head + 2]

    # Insert a read watchpoint and list it.
    # Tests:
    # -break-watch -r B
    # -break-list

    mi_gdb_test "200-break-watch -r C" \
             "200\\^done,bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"callee4\",file=\".*basics.c\",line=\"$line_main_body\",times=\"0\"\}" \
             "break-watch -r operation"

    mi_gdb_test "300-break-list" \
	    "300\\^done,BreakpointTable=\{.*,hdr=\\\[.*\\\],body=\\\[bkpt=\{number=\"5\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"main\",file=\".*basics.c\",line=\"$line_main_body\",thread-groups=\\\[\"i1\"\\\],times=\"0\"\},.*\}\\\}\}" \
                "list of breakpoints"

    mi_gdb_test "177-break-delete 4" \
	    "177\\^done" \
	    "delete read watchpoint"
}

proc test_watchpoint_triggering {} {
    global mi_gdb_prompt
    global hex fullname_syntax srcfile

    set line_callee4_return_0     [gdb_get_line_number "return 0;"]
    set line_callee3_head         [gdb_get_line_number "callee3 ("]
    set line_callee3_close_brace  [expr $line_callee3_head + 3]

    # Continue execution until the watchpoint is reached,  continue again, 
    # to see the watchpoint go out of scope.
    # Does:
    # -exec-continue (Here wp triggers)
    # -exec-continue (Here wp goes out of scope)

    mi_execute_to "exec-continue" "watchpoint-trigger" "callee4" "" \
        ".*basics.c" $line_callee4_return_0 \
        {"" "wpt=\{number=\"2\",exp=\"C\"\},value=\{old=\".*\",new=\"3\"\}"} \
        "watchpoint trigger"

    mi_execute_to "exec-continue" "watchpoint-scope" "callee3" ".*" \
        ".*basics.c" $line_callee3_close_brace \
        {"" "wpnum=\"2\""} \
        "watchpoint trigger"
}

proc test_watchpoint_all {mi_mode type} {
    upvar srcdir srcdir
    upvar subdir subdir
    upvar binfile binfile

    if {$type == "hw" && [target_info exists gdb,no_hardware_watchpoints] } {
	return
    }

    mi_gdb_exit

    if {$mi_mode == "separate"} {
	set start_ops "separate-mi-tty"
    } else {
	set start_ops ""
    }
    if [mi_gdb_start $start_ops] {
	return
    }

    if {$type == "sw"} {
	set option 0
    } else {
	set option 1
    }
    mi_gdb_test "567-gdb-set can-use-hw-watchpoints $option" \
	"567\\^done" \
	"hw watchpoints toggle"

    mi_delete_breakpoints
    mi_gdb_reinitialize_dir $srcdir/$subdir
    mi_gdb_load ${binfile}

    mi_runto callee4
    test_watchpoint_creation_and_listing
    #test_rwatch_creation_and_listing
    #test_awatch_creation_and_listing
    test_watchpoint_triggering
}

if [gdb_debug_enabled] {
  # gdb debug doesn't work for separate-mi-tty.
  set modes {"main"}
} else {
  set modes {"main" "separate"}
}

# Run the tests twice, once using software watchpoints, and another
# with hardware watchpoints.
foreach_with_prefix mi-mode $modes {
    foreach_with_prefix wp-type {"sw" "hw"} {
	test_watchpoint_all ${mi-mode} ${wp-type}
    }
}
