# Copyright (C) 2003, 2004 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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

    set gccpath ${paths}
    set libio_dir ""
    set flags ""
    set ld_library_path "."

    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/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];

    return [target_compile $source $dest $type $options]
}
