# Copyright (C) 1993-2024 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
    }

    # Gotta quote dollar-signs because they get mangled by the
    # shell otherwise.  Since get_standard_section_names returns
    # quoted section names, we first remove the original quote
    # and then requote.
    regsub -all {\\\$} "$progargs" {$} progargs
    regsub -all {\$} "$progargs" {\$} progargs

    send_log "$prog $progargs\n"
    verbose "$prog $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 }
}
