# Copyright 2009, 2010 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 multi-exec / multi-process features that work for all configurations,
# even ones that cannot run multiple processes simultaneously.

set testfile "base"

set exec1 "hello"
set srcfile1 ${exec1}.c
set binfile1 ${objdir}/${subdir}/${exec1}

set exec2 "hangout"
set srcfile2 ${exec2}.c
set binfile2 ${objdir}/${subdir}/${exec2}

set exec3 "goodbye"
set srcfile3 ${exec3}.c
set binfile3 ${objdir}/${subdir}/${exec3}

if { [prepare_for_testing ${testfile}.exp ${exec1} "${srcfile1}" {debug nowarnings}] } {
    return -1
}

if { [prepare_for_testing ${testfile}.exp ${exec2} "${srcfile2}" {debug nowarnings}] } {
    return -1
}

if { [prepare_for_testing ${testfile}.exp ${exec3} "${srcfile3}" {debug nowarnings}] } {
    return -1
}

clean_restart ${exec1}

# Add an empty inferior space, switch to it, and load a main
# executable into it.
gdb_test "add-inferior" "Added inferior 2.*" "add empty inferior 2"
gdb_test "inferior 2" "Switching to inferior 2.*" "switch to inferior 2"
gdb_test "file ${binfile2}" ".*" "load ${exec2} file in inferior 2"

# Add a new inferior space and load a main executable into it in one
# command.
gdb_test "add-inferior -exec ${binfile3}" \
    "Added inferior 3.*" \
    "add inferior 3 with -exec ${exec3}"

# Check that we have multiple spaces.

gdb_test "info inferiors" \
    "Executable.*${exec3}.*${exec2}.*${exec1}.*"

# Test that we have multiple symbol tables.

gdb_test "inferior 1" ".*" "switch to inferior 1"
gdb_test "info functions commonfun" \
    "${srcfile1}.*" \
    "'info functions commonfun' in inferior 1"

gdb_test "inferior 3" ".*" "switch to inferior 3"
gdb_test "info functions commonfun" \
    "${srcfile3}.*" \
    "'info functions commonfun' in inferior 3"

gdb_test "inferior 1" ".*" "switch back to inferior 1"

gdb_test_no_output "set listsize 1"

gdb_test "list commonfun" "from hello.*" "list commonfun in hello"

gdb_test "print hglob" "1"

gdb_test "print glob" "92" "print glob (${exec1})"


gdb_test "inferior 3" ".*" "switch to inferior 3 to print globals"

gdb_test "print gglob" "2"

gdb_test "print glob" "45" "print glob (${exec3})"

gdb_test "list commonfun" "from goodbye.*" "list commonfun in goodbye"


# Let's run the hello program.
gdb_test "inferior 1" ".*" "switch to inferior 1 to run it"

if { ![runto_main] } then {
    return -1
}

gdb_test "break hello" ".*"
gdb_test "continue" "Breakpoint \[0-9\].*, hello.*"
