# Copyright 2005, 2007, 2008, 2009 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 was written by Wu Zhou. (woodzltc@cn.ibm.com)

# This file is part of the gdb testsuite.  It contains tests for evaluating
# Fortran subarray expression.

if $tracelevel then {
	strace $tracelevel
}

if { [skip_fortran_tests] } { return -1 }

set testfile "subarray"
set srcfile ${testfile}.f
set binfile ${objdir}/${subdir}/${testfile}

if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
	executable {debug f77}] != ""} {
    return -1
}

gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}

if ![runto MAIN__] then {
    perror "couldn't run to breakpoint MAIN__"
    continue
}

# Try to set breakpoint at the last write statement.

set bp_location [gdb_get_line_number "str(:)"]
gdb_test "break $bp_location" \
    "Breakpoint.*at.* file .*$srcfile, line $bp_location\\." \
    "breakpoint at the last write statement"
gdb_test "continue" \
    "Continuing\\..*Breakpoint.*" \
    "continue to breakpoint"

# Test four different kinds of subarray expression evaluation.

set test "print str(2:4)"
gdb_test_multiple $test $test {
    -re "\\$\[0-9\]+ = 'bcd'\r\n$gdb_prompt $" {
	pass $test
    }
    -re "\\$\[0-9\]+ = \\(98 'b', 99 'c', 100 'd'\\)\r\n$gdb_prompt $" {
	# Compiler should produce string, not an array of characters.
	setup_xfail "*-*-*"
	fail $test
    }
}

set test "print str(:3)"
gdb_test_multiple $test $test {
    -re "\\$\[0-9\]+ = 'abc'\r\n$gdb_prompt $" {
	pass $test
    }
    -re "\\$\[0-9\]+ = \\(97 'a', 98 'b', 99 'c'\\)\r\n$gdb_prompt $" {
	# Compiler should produce string, not an array of characters.
	setup_xfail "*-*-*"
	fail $test
    }
}

set test "print str(5:)"
gdb_test_multiple $test $test {
    -re "\\$\[0-9\]+ = 'efg'\r\n$gdb_prompt $" {
	pass $test
    }
    -re "\\$\[0-9\]+ = \\(101 'e', 102 'f', 103 'g'\\)\r\n$gdb_prompt $" {
	# Compiler should produce string, not an array of characters.
	setup_xfail "*-*-*"
	fail $test
    }
}

set test "print str(:)"
gdb_test_multiple $test $test {
    -re "\\$\[0-9\]+ = 'abcdefg'\r\n$gdb_prompt $" {
	pass $test
    }
    -re "\\$\[0-9\]+ = \\(97 'a', 98 'b', 99 'c', 100 'd', 101 'e', 102 'f', 103 'g'\\)\r\n$gdb_prompt $" {
	# Compiler should produce string, not an array of characters.
	setup_xfail "*-*-*"
	fail $test
    }
}

gdb_test "print array(2:4)" "\\$\[0-9\]+ = \\(2, 3, 4\\)"
gdb_test "print array(:3)" "\\$\[0-9\]+ = \\(1, 2, 3\\)"
gdb_test "print array(5:)" "\\$\[0-9\]+ = \\(5, 6, 7\\)"
gdb_test "print array(:)" "\\$\[0-9\]+ = \\(1, 2, 3, 4, 5, 6, 7\\)"
