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

# Copyright 1998-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 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)] && $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 java_initialized

    if { $java_initialized != 1 } { java_init }

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

    set result [target_compile $srcfile ${binfile} executable $args]
    gdb_compile_test $srcfile $result
    return $result
}

# Auxiliary function to set the language to java.
# The result is 1 (true) for success, 0 (false) for failure.

proc set_lang_java {} {
    if [gdb_test_no_output "set language java"] {
	return 0
    }
    if [gdb_test "show language" ".* source language is \"java\"." \
	   "set language to \"java\""] {
	return 0
    }
    return 1
}

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