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

load_lib "trace-support.exp"

standard_testfile
set executable $testfile
set expfile $testfile.exp


if [prepare_for_testing $expfile $executable $srcfile \
        {debug nowarnings}] {
    untested "failed to prepare for trace tests"
    return -1
}

if ![runto_main] {
    fail "Can't run to main to check for trace support"
    return -1
}

if ![gdb_target_supports_trace] {
    unsupported "target does not support trace"
    return -1
}

# Verify that the sequence of commands "tstart tstop tstart" works well.

proc test_tstart_tstop_tstart { } {
    with_test_prefix "tstart_tstop_tstart" {
	global executable
	global hex

	# Start with a fresh gdb.
	clean_restart ${executable}
	if ![runto_main] {
	    fail "Can't run to main"
	    return -1
	}

	gdb_test "trace func1" "Tracepoint \[0-9\] at $hex: file.*"
	gdb_test_no_output "tstart"

	gdb_test "break end" "Breakpoint \[0-9\] at $hex: file.*"
	gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" \
	    "continue to end"

	gdb_test_no_output "tstop"

	gdb_test_no_output "tstart"
    }
}

# Verify the sequence of commands "tstart tstart" works well.

proc test_tstart_tstart { } {
    with_test_prefix "tstart_tstart" {
	global executable
	global hex

	# Start with a fresh gdb.
	clean_restart ${executable}
	if ![runto_main] {
	    fail "Can't run to main"
	    return -1
	}

	gdb_test "trace func1" "Tracepoint \[0-9\] at $hex: file.*"
	gdb_test_no_output "tstart"

	set test "tstart again"
	gdb_test_multiple "tstart" $test {
	    -re "A trace is running already.  Start a new run.*y or n.*" {
		# Send 'y' and make sure that we don't get any error.
		gdb_test_no_output "y" $test
	    }
	}
    }
}

# Verify that trace stops clearly when trace buffer is full.

proc test_buffer_full_tstart { } {
    with_test_prefix "buffer_full_tstart" {
	global executable
	global hex

	# Start with a fresh gdb.
	clean_restart ${executable}
	if ![runto_main] {
	    fail "Can't run to main"
	    return -1
	}

	gdb_test "trace func2" "Tracepoint \[0-9\] at $hex: file.*"
	gdb_trace_setactions "collect buf: define actions" \
	    "" \
	    "collect buf" "^$"

	gdb_test_no_output "tstart"
	gdb_test "break end" "Breakpoint \[0-9\] at $hex: file.*"
	gdb_test "continue" "Continuing\\.\[ \r\n\]+Breakpoint.*" "continue to end"

	gdb_test "tstatus" ".*buffer was full.*"
	gdb_test_no_output "tstart"
    }
}

test_tstart_tstop_tstart

test_tstart_tstart

test_buffer_full_tstart
