# This test code is part of GDB, the GNU debugger.

# Copyright 1998, 1999, 2000, 2003, 2004, 2006, 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/>.

load_lib "libgloss.exp"

# GCJ_UNDER_TEST is the compiler under test.

global tmpdir

if ![info exists tmpdir] {
    set tmpdir "/tmp"
}

set java_initialized 0

#
# Build the status wrapper library as needed.
#
proc java_init { args } {
    global wrapper_file;
    global wrap_compile_flags;
    global java_initialized
    global GCJ_UNDER_TEST
    global TOOL_EXECUTABLE
    global env

    if { $java_initialized == 1 } { return; }

    if ![info exists GCJ_UNDER_TEST] {
	if [info exists TOOL_EXECUTABLE] {
	    set GCJ_UNDER_TEST $TOOL_EXECUTABLE;
	} else {
	    if [info exists env(GCJ)] {
		set GCJ_UNDER_TEST $env(GCJ)
	    } else {
		global tool_root_dir
		global target_alias
		
		if ![is_remote host] {
		    set file [lookfor_file $tool_root_dir gcj];
		    if { $file == "" } {
			set file [lookfor_file $tool_root_dir gcc/gcj];
		    }
		    if { $file != "" } {
			set CC "$file -B[file dirname $file]/ --specs=$tool_root_dir/$target_alias/libjava/libgcj-test.spec";
		    } else {
			set CC [transform gcj];
		    }
		} else {
		    set CC [transform gcj]
		}
		set GCJ_UNDER_TEST $CC
	    }
	}
    }

    set wrapper_file "";
    set wrap_compile_flags "";
    if [target_info exists needs_status_wrapper] {
	set result [build_wrapper "testglue.o"];
	if { $result != "" } {
	    set wrapper_file [lindex $result 0];
	    set wrap_compile_flags [lindex $result 1];
	} else {
	    warning "Status wrapper failed to build."
	}
    }

    set java_initialized 1
}

#
# Run the test specified by srcfile and resultfile. compile_args and
# exec_args are options telling this proc how to work.
#
proc compile_java_from_source { srcfile binfile compile_args } {
    global GCJ_UNDER_TEST
    global runtests
    global java_initialized

    if { $java_initialized != 1 } { java_init }

    set errname [file rootname [file tail $srcfile]]
    if {! [runtest_file_p $runtests $errname]} {
        return
    }

    set args "compiler=$GCJ_UNDER_TEST"
    lappend args "additional_flags=--main=[file rootname [file tail $srcfile]]"
    if { $compile_args != "" } {
	lappend args "additional_flags=$compile_args"
    }

    if { $compile_args != "" } {
	set errname "$errname $compile_args"
    }

    set x [target_compile $srcfile ${binfile} executable $args]
    if { $x != "" } {
	verbose "target_compile failed: $x" 2
	return "$errname compilation from source";
    }
}

# Local Variables:
# tcl-indent-level:4
# End:
