# Copyright 2004-2020 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/>.

# Call target_compile with SOURCE DEST TYPE and OPTIONS as argument,
# after having temporarily changed the current working directory to
# BUILDDIR.

proc target_compile_ada_from_dir {builddir source dest type options} {
    set saved_cwd [pwd]

    global board
    set board [target_info name]
    set save_multilib_flag [board_info $board multilib_flags]
    set multilib_flag ""
    foreach op $save_multilib_flag {
	if { $op == "-pie" || $op == "-no-pie" } {
	    # Pretend gnatmake supports -pie/-no-pie, route it to
	    # linker.
	    append multilib_flag " -largs $op -margs"
	} else {
	    append multilib_flag " $op"
	}
    }
    if { $multilib_flag != "" } {
	unset_board_info "multilib_flags"
	set_board_info multilib_flags "$multilib_flag"
    }

    catch {
        cd $builddir
        return [target_compile $source $dest $type $options]
    } result options
    cd $saved_cwd

    if { $save_multilib_flag != "" } {
	unset_board_info "multilib_flags"
	set_board_info multilib_flags $save_multilib_flag
    }

    return -options $options $result
}

# Compile some Ada code.

proc gdb_compile_ada {source dest type options} {

    set srcdir [file dirname $source]
    set gprdir [file dirname $srcdir]
    set objdir [file dirname $dest]

    # Although strictly not necessary, we force the recompilation
    # of all units (additional_flags=-f).  This is what is done
    # when using GCC to build programs in the other languages,
    # and it avoids using a stray objfile file from a long-past
    # run, for instance.
    append options " ada"
    append options " additional_flags=-f"
    append options " additional_flags=-I$srcdir"

    set result [target_compile_ada_from_dir \
                    $objdir [file tail $source] $dest $type $options]

    # The Ada build always produces some output, even when the build
    # succeeds. Thus, we can not use the output the same way we do in
    # gdb_compile to determine whether the build has succeeded or not.
    # We therefore simply check whether the dest file has been created
    # or not. Unless not present, the build has succeeded.
    if [file exists $dest] { set result "" }
    gdb_compile_test $source $result
    return $result
}

# Like standard_testfile, but for Ada.  Historically the Ada tests
# used a different naming convention from many of the other gdb tests,
# and this difference was preserved during the conversion to
# standard_testfile.  DIR defaults to the base name of the test case;
# but can be overridden to find sources in a different subdirectory of
# gdb.ada.

proc standard_ada_testfile {base_file {dir ""}} {
    global gdb_test_file_name srcdir subdir
    global testdir testfile srcfile binfile

    if {$dir == ""} {
	set testdir $gdb_test_file_name
    } else {
	set testdir $dir
    }

    set testfile $base_file
    set srcfile $srcdir/$subdir/$testdir/$testfile.adb
    set binfile [standard_output_file $testfile]
}

# A helper function to find the appropriate version of a tool.
# TOOL is the tool's name, e.g., "gnatbind" or "gnatlink".

proc find_ada_tool {tool} {
    set upper [string toupper $tool]

    set targname ${upper}_FOR_TARGET
    global $targname
    if {[info exists $targname]} {
	return $targname
    }

    global tool_root_dir
    set root "$tool_root_dir/gcc"
    set result ""

    if {![is_remote host]} {
        set result [lookfor_file $root $tool]
    }

    if {$result == ""} {
        set result [transform $tool]
    }

    return $result
}

# Return 1 if gnatmake is at least version $MAJOR.x.x

proc gnatmake_version_at_least { major } {
    set gnatmake [gdb_find_gnatmake]
    set gnatmake [lindex [split $gnatmake] 0]
    set output [exec $gnatmake --version]
    if { [regexp {GNATMAKE ([^ .]+).([^ .]+).([^ .]+)} $output \
	      match gnatmake_major gnatmake_minor gnatmake_micro] } {
	if { $gnatmake_major >= $major } {
	    return 1
	} else {
	    return 0
	}
    }

    # Unknown, return 1
    return 1
}
