# 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:
