# Copyright (C) 2003-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 GCC; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

# This file is just 'sed -e 's/77/fortran/g' \
#			 -e 's/f2c/gfortran' g77.exp > gfortran.exp'
#
# with some minor modifications to make it work.

#
# gfortran support library routines
#
load_lib prune.exp
load_lib gcc-defs.exp
load_lib timeout.exp
load_lib target-libpath.exp
load_lib target-supports.exp

#
# GFORTRAN_UNDER_TEST is the compiler under test.
#


set gpp_compile_options ""


#
# gfortran_version -- extract and print the version number of the compiler
#

proc gfortran_version { } {
    global GFORTRAN_UNDER_TEST
    
    gfortran_init

    # ignore any arguments after the command
    set compiler [lindex $GFORTRAN_UNDER_TEST 0]
    
    # verify that the compiler exists
    if { [is_remote host] || [which $compiler] != 0 } then {
	set tmp [remote_exec host "$compiler -v"]
	set status [lindex $tmp 0]
	set output [lindex $tmp 1]
	regexp " version \[^\n\r\]*" $output version
	if { $status == 0 && [info exists version] } then {
	    if [is_remote host] {
		clone_output "$compiler $version\n"
	    } else {
		clone_output "[which $compiler] $version\n"
	    }
	} else {
	    clone_output "Couldn't determine version of [which $compiler]\n"
	}
    } else {
	# compiler does not exist (this should have already been detected)
	warning "$compiler does not exist"
    }
}

#
# gfortran_link_flags -- provide new version of gfortran_link_flags
# (originally from libgloss.exp) which knows about the gcc tree structure
#

proc gfortran_link_flags { paths } {
    global srcdir
    global ld_library_path
    global GFORTRAN_UNDER_TEST
    global shlib_ext

    set gccpath ${paths}
    set libio_dir ""
    set flags ""
    set ld_library_path "."
    set shlib_ext [get_shlib_extension]
    verbose "shared lib extension: $shlib_ext"

    if { $gccpath != "" } {
      if [file exists "${gccpath}/libgfortran/.libs/libgfortran.a"] {
          # Some targets use libgfortran.a%s in their specs, so they need a -B option
          # for uninstalled testing.
          append flags "-B${gccpath}/libgfortran/.libs "
          append flags "-L${gccpath}/libgfortran/.libs "
          append ld_library_path ":${gccpath}/libgfortran/.libs"
      }
      if [file exists "${gccpath}/libgfortran/.libs/libgfortran.${shlib_ext}"] {
	  append flags "-L${gccpath}/libgfortran/.libs "
	  append ld_library_path ":${gccpath}/libgfortran/.libs"
      }
      if [file exists "${gccpath}/libgfortran/libgforbegin.a"] {
          append flags "-L${gccpath}/libgfortran "
      }
      if [file exists "${gccpath}/libquadmath/.libs/libquadmath.a"] {
          # Some targets use libquadmath.a%s in their specs, so they need a -B option
          # for uninstalled testing.
          append flags "-B${gccpath}/libquadmath/.libs "
          append flags "-L${gccpath}/libquadmath/.libs "
          append ld_library_path ":${gccpath}/libquadmath/.libs"
      }
      if [file exists "${gccpath}/libquadmath/.libs/libquadmath.${shlib_ext}"] {
	  append flags "-L${gccpath}/libquadmath/.libs "
	  append ld_library_path ":${gccpath}/libquadmath/.libs"
      }
      if [file exists "${gccpath}/libiberty/libiberty.a"] {
          append flags "-L${gccpath}/libiberty "
      }
      append ld_library_path \
	[gcc-set-multilib-library-path $GFORTRAN_UNDER_TEST ]
    }

    set_ld_library_path_env_vars

    return "$flags"
}

#
# gfortran_init -- called at the start of each subdir of tests
#

proc gfortran_init { args } {
    global subdir
    global gpp_initialized
    global base_dir
    global tmpdir
    global libdir
    global gluefile wrap_flags
    global objdir srcdir
    global ALWAYS_GFORTRANFLAGS
    global TOOL_EXECUTABLE TOOL_OPTIONS
    global GFORTRAN_UNDER_TEST
    global TESTING_IN_BUILD_TREE
    global gcc_warning_prefix
    global gcc_error_prefix
    global TEST_ALWAYS_FLAGS

    # We set LC_ALL and LANG to C so that we get the same error messages as expected.
    setenv LC_ALL C
    setenv LANG C

    set gcc_warning_prefix "\[Ww\]arning:"
    set gcc_error_prefix "(Fatal )?\[Ee\]rror:"

    # Many hosts now default to a non-ASCII C locale, however, so
    # they can set a charset encoding here if they need.
    if { [ishost "*-*-cygwin*"] } {
      setenv LC_ALL C.ASCII
      setenv LANG C.ASCII
    }

    if ![info exists GFORTRAN_UNDER_TEST] then {
	if [info exists TOOL_EXECUTABLE] {
	    set GFORTRAN_UNDER_TEST $TOOL_EXECUTABLE
	} else {
	    if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } {
		set GFORTRAN_UNDER_TEST [transform gfortran]
	    } else {
		if [info exists TOOL_OPTIONS] {
	            set specpath [get_multilibs ${TOOL_OPTIONS}]
		} else {
		    set specpath [get_multilibs]
		}
		set GFORTRAN_UNDER_TEST [findfile $base_dir/../../gfortran "$base_dir/../../gfortran -B$base_dir/../../ -B$specpath/libgfortran/" [findfile $base_dir/gfortran "$base_dir/gfortran -B$base_dir/" [transform gfortran]]]
	    }
	}
    }

    if ![is_remote host] {
	if { [which $GFORTRAN_UNDER_TEST] == 0 } then {
	    perror "GFORTRAN_UNDER_TEST ($GFORTRAN_UNDER_TEST) does not exist"
	    exit 1
	}
    }
    if ![info exists tmpdir] {
	set tmpdir "/tmp"
    }

    if [info exists gluefile] {
	unset gluefile
    }

    gfortran_maybe_build_wrapper "${tmpdir}/gfortran-testglue.o"

    set ALWAYS_GFORTRANFLAGS ""

    # TEST_ALWAYS_FLAGS are flags that should be passed to every
    # compilation.  They are passed first to allow individual
    # tests to override them.
    if [info exists TEST_ALWAYS_FLAGS] {
	lappend ALWAYS_GFORTRANFLAGS "additional_flags=$TEST_ALWAYS_FLAGS"
    }

    if ![is_remote host] {
	if [info exists TOOL_OPTIONS] {
	    lappend ALWAYS_GFORTRANFLAGS "ldflags=[gfortran_link_flags [get_multilibs ${TOOL_OPTIONS}] ]"
	} else {
	    lappend ALWAYS_GFORTRANFLAGS "ldflags=[gfortran_link_flags [get_multilibs] ]"
	}
    }

    if [info exists TOOL_OPTIONS] {
	lappend ALWAYS_GFORTRANFLAGS "additional_flags=$TOOL_OPTIONS"
    }

    # On the SPU, most of the fortran test cases exceed local store size.
    # Use automatic overlay support to make them fit.
    if { [check_effective_target_spu_auto_overlay] } {
	lappend ALWAYS_GFORTRANFLAGS "ldflags=-Wl,--auto-overlay"
	lappend ALWAYS_GFORTRANFLAGS "ldflags=-Wl,--reserved-space=131072"
    }

    verbose -log "ALWAYS_GFORTRANFLAGS set to $ALWAYS_GFORTRANFLAGS"

    verbose "gfortran is initialized" 3
}

#
# gfortran_target_compile -- compile a source file
#

proc gfortran_target_compile { source dest type options } {
    global tmpdir
    global gluefile wrap_flags
    global ALWAYS_GFORTRANFLAGS
    global GFORTRAN_UNDER_TEST

    if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } {
	lappend options "libs=${gluefile}"
	lappend options "ldflags=${wrap_flags}"
    }

    lappend options "compiler=$GFORTRAN_UNDER_TEST"
    lappend options "timeout=[timeout_value]"

    set options [concat "$ALWAYS_GFORTRANFLAGS" $options]
    set options [dg-additional-files-options $options $source]
    return [target_compile $source $dest $type $options]
}
