# Copyright (C) 2012-2026 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 GCC; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

#
# ALGOL68 support library routines
#

load_lib prune.exp
load_lib gcc-defs.exp
load_lib timeout.exp
load_lib target-libpath.exp

#
# ALGOL68_UNDER_TEST is the compiler under test.
#

set algol68_compile_options ""


#
# algol68_include_flags -- include flags for the gcc tree structure
#

proc algol68_include_flags { paths } {
    global srcdir
    global TESTING_IN_BUILD_TREE

    set flags ""

    if { [is_remote host] || ![info exists TESTING_IN_BUILD_TREE] } {
	return "${flags}"
    }

    set gccpath ${paths}

    return "$flags"
}

#
# algol68_link_flags -- linker flags for the gcc tree structure
#

proc algol68_link_flags { paths } {
    global srcdir
    global ld_library_path
    global shlib_ext
    global ALGOL68_UNDER_TEST

    set gccpath ${paths}
    set flags ""
    set ld_library_path "."
    set shlib_ext [get_shlib_extension]
    verbose "shared lib extension: $shlib_ext"

    # We need to add options to locate libga68.
    set target_wants_B_option 0
    if { [istarget *-*-darwin9* ] || [istarget *-*-darwin\[12\]* ] } {
      set target_wants_B_option 1
    }

    if { $gccpath != "" } {
	if { [file exists "${gccpath}/libga68/.libs/libga68.a"] \
	     || [file exists "${gccpath}/libga68/.libs/libga68.${shlib_ext}"] } {
	    if { $target_wants_B_option } {
		append flags "-B${gccpath}/libga68/.libs "
	    } else {
		append flags "-L${gccpath}/libga68/.libs "
	    }
	    append ld_library_path ":${gccpath}/libga68/.libs"
	}
	if [file exists "${gccpath}/libiberty/libiberty.a"] {
	    append flags "-L${gccpath}/libiberty "
	}
	append ld_library_path [gcc-set-multilib-library-path $ALGOL68_UNDER_TEST]
    }

    set_ld_library_path_env_vars

    return "$flags"
}

#
# algol68_init -- called at the start of each subdir of tests
#

proc algol68_init { args } {
    global subdir
    global algol68_initialized
    global base_dir
    global tmpdir
    global libdir
    global gluefile wrap_flags
    global objdir srcdir
    global ALWAYS_ALGOL68FLAGS
    global TOOL_EXECUTABLE TOOL_OPTIONS
    global ALGOL68_UNDER_TEST
    global TESTING_IN_BUILD_TREE
    global gcc_warning_prefix
    global gcc_error_prefix
    global TEST_ALWAYS_FLAGS
    global algol68_init_set_ALGOL68_UNDER_TEST

    # We set LC_ALL and LANG to C so that we get the same error messages as expected.
    setenv LC_ALL C
    setenv LANG C

    # ALGOL68_UNDER_TEST as set below contains $specpath, which depends on
    # the used multilib config. Thus, its value may need to be reset;
    # that's tracked via algol68_init_set_ALGOL68_UNDER_TEST.
    if { ![info exists ALGOL68_UNDER_TEST]
	 || [info exists algol68_init_set_ALGOL68_UNDER_TEST] } then {
	if [info exists TOOL_EXECUTABLE] {
	    set ALGOL68_UNDER_TEST $TOOL_EXECUTABLE
	} else {
	    if { [is_remote host] || ! [info exists TESTING_IN_BUILD_TREE] } {
		set ALGOL68_UNDER_TEST [transform ga68]
	    } else {
		if [info exists TOOL_OPTIONS] {
	            set specpath [get_multilibs ${TOOL_OPTIONS}]
		} else {
		    set specpath [get_multilibs]
		}
		set algol68_init_set_ALGOL68_UNDER_TEST 1
		set ALGOL68_UNDER_TEST [findfile $base_dir/../../ga68 "$base_dir/../../ga68 -B$base_dir/../.. -B$specpath/libga68 -I$base_dir/../../.libs -I$specpath/libga68/.libs" [findfile $base_dir/ga68 "$base_dir/ga68 -B$base_dir" [transform ga68]]]
	    }
	}
    }

    if ![is_remote host] {
	if { [which $ALGOL68_UNDER_TEST] == 0 } then {
	    perror "ALGOL68_UNDER_TEST ($ALGOL68_UNDER_TEST) does not exist"
	    exit 1
	}
    }

    if ![info exists tmpdir] {
	set tmpdir "/tmp"
    }

    if [info exists gluefile] {
	unset gluefile
    }

    set gcc_warning_prefix "warning:"
    set gcc_error_prefix "(fatal )?error:"

    set ALWAYS_ALGOL68FLAGS ""

    # TEST_ALWAYS_FLAGS are flags that should be passed to every
    # compilation.  They are passed first to allow individual
    # tests to override them.
    if [info exists TEST_ALWAYS_FLAGS] {
	lappend ALWAYS_ALGOL68FLAGS "additional_flags=$TEST_ALWAYS_FLAGS"
    }

    if ![is_remote host] {
	if [info exists TOOL_OPTIONS] {
	    lappend ALWAYS_ALGOL68FLAGS "additional_flags=[algol68_include_flags [get_multilibs ${TOOL_OPTIONS}] ]"
	    lappend ALWAYS_ALGOL68FLAGS "ldflags=[algol68_link_flags [get_multilibs ${TOOL_OPTIONS}] ]"
	} else {
	    lappend ALWAYS_ALGOL68FLAGS "additional_flags=[algol68_include_flags [get_multilibs] ]"
	    lappend ALWAYS_ALGOL68FLAGS "ldflags=[algol68_link_flags [get_multilibs] ]"
	}
    }

    if [info exists TOOL_OPTIONS] {
	lappend ALWAYS_ALGOL68FLAGS "additional_flags=$TOOL_OPTIONS"
    }

    verbose -log "ALWAYS_ALGOL68FLAGS set to $ALWAYS_ALGOL68FLAGS"

    verbose "algol68 is initialized" 3
}

#
# algol68_target_compile -- compile a source file
#

proc algol68_target_compile { source dest type options } {
    global tmpdir
    global gluefile wrap_flags
    global ALWAYS_ALGOL68FLAGS
    global ALGOL68_UNDER_TEST
    global TEST_ALWAYS_FLAGS
    global individual_timeout

    # HACK: guard against infinite loops in the compiler
    set individual_timeout 20

    if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } {
	lappend options "libs=${gluefile}"
	lappend options "ldflags=${wrap_flags}"
    }

    lappend options "timeout=[timeout_value]"
    lappend options "compiler=$ALGOL68_UNDER_TEST"

    set options [concat "$ALWAYS_ALGOL68FLAGS" $options]
    set options [dg-additional-files-options $options $source $dest $type]
    set ret [target_compile $source $dest $type $options]
    unset individual_timeout
    return $ret
}
