# Copyright (C) 2011-2012 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 file is part of the GDB testsuite.  It tests the mechanism
# for defining the prompt in Python.

standard_testfile

# We need to use TCL's exec to get the pid.
if [is_remote target] then {
    return 0
}

load_lib gdb-python.exp
load_lib prompt.exp

# Start with a fresh gdb.

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir

# Skip all tests if Python scripting is not enabled.
if { [skip_python_tests] } { continue }
gdb_exit

if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
    return -1
}

global GDBFLAGS
set saved_gdbflags $GDBFLAGS
set GDBFLAGS [concat $GDBFLAGS " -ex \"set height 0\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"set width 0\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"python p = list()\""]
set prompt_func "python def foo(x): global p; p.append(x);  return \'(Foo) \'"
set GDBFLAGS [concat $GDBFLAGS " -ex \"$prompt_func\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"python gdb.prompt_hook=foo\""]

set tmp_gdbflags $GDBFLAGS
set gdb_prompt_fail $gdb_prompt

global gdb_prompt
# Does not include the space at the end of the prompt.
# gdb_test expects it not to be there.
set gdb_prompt "\[(\]Foo\[)\]"

set GDBFLAGS [concat $tmp_gdbflags " -ex \"set editing on\""]
prompt_gdb_start
gdb_test "python x = len(p); print gdb.execute(\"show prompt\", to_string = True)" \
	 ".*prompt is \"$gdb_prompt \".*" \
	 "show prompt gets the correct result"
gdb_test "python print x, len(p)" "1 2" \
	 "retrieving the prompt causes no extra prompt_hook calls"
gdb_test "python print \"'\" + str(p\[0\]) + \"'\"" "'$gdb_prompt_fail '" \
	 "prompt_hook argument is default prompt."
gdb_exit


set GDBFLAGS [concat $tmp_gdbflags " -ex \"set editing off\""]
prompt_gdb_start
gdb_test "python x = len(p); print gdb.execute(\"show prompt\", to_string = True)" \
	 ".*prompt is \"$gdb_prompt \".*" \
	 "show prompt gets the correct result 2"
gdb_test "python print x, len(p)" "1 2" \
	 "retrieving the prompt causes no extra prompt_hook calls 2"
gdb_test "python print \"'\" + str(p\[0\]) + \"'\"" "'$gdb_prompt_fail '" \
	 "prompt_hook argument is default prompt. 2"
gdb_exit

# Start the program running and then wait for a bit, to be sure
# that it can be attached to.
set testpid [eval exec $binfile &]
exec sleep 2
if { [istarget "*-*-cygwin*"] } {
    # testpid is the Cygwin PID, GDB uses the Windows PID, which might be
    # different due to the way fork/exec works.
    set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
}

set GDBFLAGS [concat $tmp_gdbflags " -ex \"set target-async on\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"set pagination off\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"set editing on\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"attach $testpid\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"continue&\""]

# sync_execution = 1 is_running = 1
prompt_gdb_start
gdb_test "python x = len(p); print gdb.execute(\"show prompt\", to_string = True)" \
	 ".*prompt is \"$gdb_prompt \".*" \
	 "show prompt gets the correct result 3"
gdb_test "python print x, len(p)" "1 2" \
	 "retrieving the prompt causes no extra prompt_hook calls 3"
gdb_test "python print \"'\" + str(p\[0\]) + \"'\"" "'$gdb_prompt_fail '" \
	 "prompt_hook argument is default prompt. 3"
gdb_exit

set GDBFLAGS [concat $tmp_gdbflags " -ex \"set target-async on\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"set pagination off\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"set editing on\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"attach $testpid\""]
set GDBFLAGS [concat $GDBFLAGS " -ex \"interrupt\""]

# sync_execution = 1 is_running = 0
prompt_gdb_start
gdb_test "python x = len(p); print gdb.execute(\"show prompt\", to_string = True)" \
	 ".*prompt is \"$gdb_prompt \".*" \
	 "show prompt gets the correct result 4"
gdb_test "python print x, len(p)" "1 2" \
	 "retrieving the prompt causes no extra prompt_hook calls 4"
gdb_test "python print \"'\" + str(p\[0\]) + \"'\"" "'$gdb_prompt_fail '" \
	 "prompt_hook argument is default prompt. 4"
gdb_exit

set GDBFLAGS $saved_gdbflags
return 0
