# Copyright (C) 1993-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, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.

# Please email any bugs, comments, and/or additions to this file to:
# bug-dejagnu@prep.ai.mit.edu

# This file was written by Rob Savoye <rob@cygnus.com>
# and extended by Ian Lance Taylor <ian@cygnus.com>

proc load_common_lib { name } {
    load_lib $name
}

load_common_lib binutils-common.exp

proc binutil_version { prog } {
    if ![is_remote host] {
	set path [which $prog]
	if {$path == 0} then {
	    perror "$prog can't be run, file not found."
	    return ""
	}
    } else {
	set path $prog
    }
    set state [remote_exec host $prog --version]
    set tmp "[lindex $state 1]\n"
    # Should find a way to discard constant parts, keep whatever's
    # left, so the version string could be almost anything at all...
    regexp "\[^\n\]* (cygnus-|)(\[-0-9.a-zA-Z-\]+)\[\r\n\].*" "$tmp" version cyg number
    if ![info exists number] then {
        return "$path (no version number)\n"
    }
    return "$path $number\n"
}

#
# default_binutils_run
#	run a program, returning the output
#	sets binutils_run_failed if the program does not exist
#	sets binutils_run_status to the exit status of the program
#
proc default_binutils_run { prog progargs } {
    global binutils_run_failed
    global binutils_run_status
    global host_triplet

    set binutils_run_failed 0
    if [info exists binutils_run_status] {
	unset binutils_run_status
    }

    if ![is_remote host] {
	if {[which $prog] == 0} then {
	    perror "$prog does not exist"
	    set binutils_run_failed 1
	    return ""
	}
    }

    # For objdump, automatically translate standard section
    # names to the targets one, if they are different.
    set sect_names [get_standard_section_names]
    if { $sect_names != "" && [string match "*objdump" $prog] } {
        regsub -- "-j \\.text" $progargs "-j [lindex $sect_names 0]" progargs
        regsub -- "-j \\.data" $progargs "-j [lindex $sect_names 1]" progargs
        regsub -- "-j \\.bss"  $progargs "-j [lindex $sect_names 2]" progargs
    }

    send_log "$prog $progargs\n"
    verbose "$prog $progargs"

    # Gotta quote dollar-signs because they get mangled by the
    # shell otherwise.
    regsub -all "\\$" "$progargs" "\\$" progargs

    set state [remote_exec host $prog $progargs]
    set binutils_run_status [lindex $state 0]
    set exec_output [prune_warnings [lindex $state 1]]
    if {![string match "" $exec_output]} then {
	send_log "$exec_output\n"
	verbose "$exec_output"
    } else {
	if { [lindex $state 0] != 0 } {
	    set exec_output "$prog exited with status [lindex $state 0]"
	    send_log "$exec_output\n"
	    verbose "$exec_output"
	}
    }
    return $exec_output
}

#
# default_binutils_assemble_flags
#	assemble a file
#
proc default_binutils_assemble_flags { source object asflags } {
    global srcdir
    global host_triplet

    # The HPPA assembler syntax is a little different than most, to make
    # the test source file assemble we need to run it through sed.
    #
    # This is a hack in that it won't scale well if other targets need
    # similar transformations to assemble.  We'll generalize the hack
    # if/when other targets need similar handling.
    if { [istarget "hppa*-*-*"] \
	     && ![istarget "*-*-linux*"] \
	     && ![istarget "*-*-netbsd*" ] } {
        set sed_file $srcdir/config/hppa.sed
	send_log "sed -f $sed_file < $source > asm.s\n"
	verbose "sed -f $sed_file < $source > asm.s"
	catch "exec sed -f $sed_file < $source > asm.s"
	set source asm.s
    }

    set exec_output [target_assemble $source $object $asflags]
    set exec_output [prune_warnings $exec_output]

    if [string match "" $exec_output] {
	return 1
    } else {
	send_log "$exec_output\n"
	verbose "$exec_output"
	return 0
    }
}

#
# exe_ext
#	Returns target executable extension, if any.
#
proc exe_ext {} {
    if { [istarget *-*-mingw*] || [istarget *-*-cygwin*] } {
        return ".exe"
    } else {
        return ""
    }
}

proc verbose_eval { expr { level 1 } } {
    global verbose
    if $verbose>$level then { eval verbose "$expr" $level }
}
