# Copyright (C) 2003, 2004, 2005 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 2 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, write to the Free Software
# Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

# 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 target-libpath.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"] {
          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}/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

    # 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

    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 {
		set GFORTRAN_UNDER_TEST [findfile $base_dir/../../gfortran "$base_dir/../../gfortran -B$base_dir/../../" [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 ""

    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"
    }

    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"

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