# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2011
# Free Software Foundation

proc load_gcc_lib { filename } {
    global srcdir loaded_libs

    load_file $srcdir/../../gcc/testsuite/lib/$filename
    set loaded_libs($filename) ""
}

load_lib libgloss.exp
load_lib dg.exp
load_gcc_lib target-libpath.exp

# GCJ_UNDER_TEST is the compiler under test.

global tmpdir

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

# This is like `prune_warnings', but it also prunes away a warning
# from the bytecode front end that we don't care about.
proc libjava_prune_warnings {text} {
    set text [prune_warnings $text]
    set tlist [split $text \n]
    set len [llength $tlist]
    for {set i [expr {$len - 1}]} {$i >= 2} {incr i -1} {
	if {[string match "*unreachable bytecode*" [lindex $tlist $i]]} {
	    # Delete this line, all other unreachable warnings and the previous
	    # two lines containing the method and class.
	    set j [expr {$i - 1}]
	    while {[string match "*unreachable bytecode*" [lindex $tlist $j]]} {
		incr j -1
	    }
	    incr j -1
	    set tlist [lreplace $tlist $j $i]
	    set i $j
	}
    }
    return [join $tlist \n]
}

# This is like `target_compile' but it does some surgery to work
# around stupid DejaGNU bugs.  In particular DejaGNU has very poor
# quoting, so for instance a `$' will be re-evaluated at spawn time.
# We don't want that.
proc libjava_tcompile {source destfile type options} {
    # This strange-looking expression really does quote the `$'.
    regsub -all -- {\$} $source {\$} source
    regsub -all -- {\$} $destfile {\$} destfile
    return [target_compile $source $destfile $type $options]
}

# Read an `xfail' file if it exists.  Returns a list of xfail tokens.
proc libjava_read_xfail {file} {
    if {! [file exists $file]} {
	return ""
    }
    set fd [open $file r]
    set tokens [string trim [read $fd]]
    close $fd
    return $tokens
}

# Find a particular executable.  FIXME: this relies on DejaGnu
# internals.  These should probably be exposed in a better way.
proc libjava_find_program {prog} {
    global tool_root_dir

    set file [lookfor_file $tool_root_dir $prog]
    if { $file == "" } {
	set file [lookfor_file $tool_root_dir gcc/$prog];
    }
    if {$file == ""} {
	set file $prog
    }
    return $file
}

# Find `gcjh'.
proc find_gcjh {} {
    return [libjava_find_program gjavah]
}

proc find_javac {} {
    global SUN_JAVAC GCJ_UNDER_TEST env libgcj_jar
    # If JDK doesn't run on your platform but some other
    # JDK-compatible javac does, you may set SUN_JAVAC to point to it.
    # One of the most important properties of a SUN_JAVAC is that it
    # must create class-files even for classes that have not been
    # specified in the command line, but that were needed to compile
    # those that have.  For example, Pizza won't do it, but you can
    # use `kaffe sun.tools.javac.Main', if you have Sun's classes.zip
    # in the kaffe's default search path.
    if {![info exists SUN_JAVAC]} {
	if {[info exists env(SUN_JAVAC)]} {
	    set SUN_JAVAC $env(SUN_JAVAC)
	} else {
	    set SUN_JAVAC "$GCJ_UNDER_TEST -C -I$libgcj_jar"
	}
    }
    return $SUN_JAVAC
}

proc bytecompile_file { file objdir {classpath {}} } {
    global env
    set dirname [file dirname $file]

    set javac [find_javac]
    if {$classpath != ""} then {
        set env(CLASSPATH) $classpath
    }
    set here [pwd]
    cd $dirname
    send_log "byte compile: $javac -g [list $file] -d $objdir 2>@ stdout\n"
    if {[catch {
	set q [eval exec "$javac -g [list $file] -d $objdir 2>@ stdout"]
    } msg]} then {
	send_log "couldn't compile $file: $msg\n"
	set r 0
    } else {
	set r 1
    }
    cd $here
    return $r
}

set libjava_initialized 0

#
# Build the status wrapper library as needed.
#
proc libjava_init { args } {
    global wrapper_file;
    global wrap_compile_flags;
    global libjava_initialized libjava_uses_threads
    global GCJ_UNDER_TEST
    global TOOL_EXECUTABLE
    global env objdir
    global env libgcj_jar
    global tool_root_dir
    global libjava_libgcc_s_path
    global target_triplet
    global libjava_version

    # 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

    # Many hosts now default to a non-ASCII C locale, however, so
    # they can set a charset encoding here if they need.
    if { [ishost "*-*-cygwin*"] } {
      setenv LC_ALL C.ASCII
      setenv LANG C.ASCII
    }

    if { $libjava_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)] {
		set GCJ_UNDER_TEST $env(GCJ)
	    } else {
		set GCJ_UNDER_TEST "[find_gcj]"
	    }
	}
    }

    # Find the libgcj jar file.

    # FIXME: This finds libgcj.spec for the default multilib.
    # If thread models differ between multilibs, this has to be moved
    # to libjava_arguments
    set specdir [libjava_find_spec]

    set text [eval exec "$GCJ_UNDER_TEST -B$specdir -v 2>@ stdout"]
    regexp " version \[^\n\r\]*" $text version
    set libjava_version [lindex $version 1]

    verbose "version: $libjava_version"

    set libgcj_jar [glob $objdir/../libgcj-$libjava_version.jar]
    verbose "jar file is $libgcj_jar"

    # The -B is so we find libgcj.spec.
    regexp -- "Thread model: (\[^\n\]+)\n" $text ignore model
    set libjava_uses_threads [expr {! ($model == "no"
				       || $model == "none"
				       || $model == "single")}]

    # Always set encoding used by gcj.
    append GCJ_UNDER_TEST " --encoding=UTF-8"

    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."
	}
    }

    # Finally, add the gcc build directory so that we can find the
    # shared libgcc.  This, like much of dejagnu, is hideous.
    set libjava_libgcc_s_path {}

    if { [istarget "*-*-darwin*"] } {
	set so_extension "dylib"
    } elseif { [istarget "*-*-cygwin*"] || [istarget "*-*-mingw*"] } {
	set so_extension "dll"
    } else {
	set so_extension "so"
    }
    set gccdir [lookfor_file $tool_root_dir gcc/libgcc_s.${so_extension}]
    if {$gccdir != ""} {
	set gccdir [file dirname $gccdir]
	lappend libjava_libgcc_s_path $gccdir
	verbose "libjava_libgcc_s_path = $libjava_libgcc_s_path"
	set compiler ${gccdir}/xgcc
	if { [is_remote host] == 0 && [which $compiler] != 0 } {
	    foreach i "[exec $compiler --print-multi-lib]" {
		set mldir ""
		regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
		set mldir [string trimright $mldir "\;@"]
		if { "$mldir" == "." } {
		    continue
		}
		if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.${so_extension}.*]] >= 1 } {
		    lappend libjava_libgcc_s_path "${gccdir}/${mldir}"
		}
	    }
	}
    }

    set libjava_initialized 1
}

# Find a library.  We know where libtool puts the actual libraries,
# and we look there.  The implementation is fairly hacky.  We can't
# compile with -nodefaultlibs, because that will also eliminate the
# system libraries we need.  In order to have gcj still work, it must
# find the appropriate libraries so we must add -L options for their
# paths.  However we can't simply use those libraries; we still need
# libtool for linking.
# Don't return the the lib${name}.la files here, since this causes the
# libraries to be linked twice: once as lib${name}.so/dylib and another time
# via gcj's implicit -l${name}.  This is both unnecessary and causes the
# Solaris ld to warn: attempted multiple inclusion of file.  This warning
# is not ignored by the dejagnu framework and cannot be disabled.
proc libjava_find_lib {dir name} {
    global base_dir
    set gp [get_multilibs]
    foreach extension {so dll dylib sl a} {
	foreach sub {.libs _libs} {
	    if {$gp != ""} {
		if {[file exists $gp/$dir/$sub/lib${name}.${extension}]} then {
		    # Just return the `-L' option.  The library itself
		    # will be picked up via the spec file.
		    return "-L$gp/$dir/$sub"
		}
	    }
	    # Just return the `-L' option.  The library itself will be
	    # picked up via the spec file.
	    set lib [findfile \
		       $base_dir/../../$dir/$sub/lib${name}.${extension} \
		       "-L$base_dir/../../$dir/$sub" \
		       ""]
	    if {$lib != ""} {
		return $lib
	    }
	}
    }
    return ""
}

# Find libgcj.spec.  We need to use the file corresponding to the multilib
# under test since they might differ.  Append a trailing slash since this
# is used with -B.
proc libjava_find_spec {} {
    global objdir
    return "$objdir/../"
}

# Find `gij'.  Return empty string if not found.
proc libjava_find_gij {} {
    global base_dir objdir

    set gijdir [lookfor_file [get_multilibs] libjava];
    # Fall back if get_multilibs fails.
    if {$gijdir == ""} {
      set gijdir "$objdir/.."
    }
    if {! [file exists $gijdir/gij]} {
	return ""
    }
    return $gijdir/gij
}

# Remove a bunch of files.
proc gcj_cleanup {args} {
    foreach file $args {
	if {[string match *.o $file]} {
	    verbose "removing [file rootname $file].lo"
	    file delete -force [file rootname $file].lo
	}
	file delete -force -- $file
	verbose "removing $file"
    }
    # It is simplest to do this instead of trying to figure out what
    # bits in .libs ought to be removed.
    catch {system "rm -rf .libs"}
}

# Compute arguments needed for compiler.  MODE is a libtool mode:
# either compile or link.
proc libjava_arguments {{mode compile}} {
    global base_dir
    global LIBJAVA
    global srcdir subdir objdir
    global TOOL_OPTIONS
    global GCJ_UNDER_TEST
    global tmpdir
    global runtests
    global env
    global tool_root_dir
    global libgcj_jar
    global libjava_libgcc_s_path
    global libjava_ld_library_path
    global ld_library_path
    global target_triplet

    if [info exists LIBJAVA] {
	set libjava $LIBJAVA;
    } else {
	set libjava [libjava_find_lib libjava gcj]
    }

    verbose "using LIBJAVA = $libjava" 2
    set args ""

    # Basically we want to build up a colon separated path list from
    # the value of $libjava.

    set lpath "."
    foreach dir [list $libjava] {
	foreach item [split $dir " "] {
	    switch -glob -- $item {
		"-L*" {
		    lappend lpath [string range $item 2 end]
		}
	    }
	}
    }

    set lpath [concat $lpath $libjava_libgcc_s_path]
    verbose "lpath = $lpath ; libgcc_s_path = $libjava_libgcc_s_path"
    set ld_library_path [join $lpath :]
    set libjava_ld_library_path "$ld_library_path"

    # That's enough to make things work for the normal case.
    # If we wanted to handle an arbitrary value of libjava,
    # then we'd have to do a lot more work.

    set_ld_library_path_env_vars
    if [info exists env(LD_LIBRARY_PATH)] {
	verbose "LD_LIBRARY_PATH = $env(LD_LIBRARY_PATH)"
    }

    # Determine CLASSPATH separator
    if { [string match "i?86-pc-mingw32*" $target_triplet] } {
	set sep ";"
    } else {
	set sep ":"
    }

    # Set the CLASSPATH environment variable
    global env
    set env(CLASSPATH) \
	[join [list . $srcdir/$subdir $objdir $libgcj_jar] $sep]
    verbose "CLASSPATH is $env(CLASSPATH)"

    # Disable all warnings, as ecj is rather chatty.
    lappend args "additional_flags=-w"

    if {$mode == "link"} {
	global wrapper_file wrap_compile_flags
	lappend args "additional_flags=$wrap_compile_flags"

	if { [regexp "linux" $target_triplet] } {
	    lappend args "additional_flags=-specs=libgcj-test.spec"
	}

	lappend args "libs=$wrapper_file"
	lappend args "libs=$libjava"
	lappend args debug
    }

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

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

    # Determine libgcj.spec corresponding to multilib under test.
    set specdir [libjava_find_spec]

    # Search for libtool.  We need it to link.
    set found_compiler 0
    set d [file normalize $objdir]
    foreach x {. .. ../.. ../../..} {
	if {[file exists $d/$x/libtool]} then {
	    # We have to run silently to avoid DejaGNU lossage.
	    lappend args \
	      "compiler=$d/$x/libtool --silent --tag=GCJ --mode=$mode $GCJ_UNDER_TEST -B$specdir"
	    set found_compiler 1
	    break
	}
    }
    if {! $found_compiler} {
	# Append -B$specdir so that we find libgcj.spec before it
	# is installed.
	lappend args "compiler=$GCJ_UNDER_TEST -B$specdir"
    }

    # Avoid libtool wrapper scripts when possible.
    # but not if libtool warnings results in FAILs
    if {$mode == "link"} {
	if {! [istarget "*-*-cygwin*"] && ! [istarget "*-*-mingw*"]
	    && ! [istarget "*-*-darwin*"] } { 
	    lappend args "additional_flags=-no-install"
	}
	if { [istarget "*-*-darwin*"] } {
	    lappend args "additional_flags=-bind_at_load"
	    lappend args "additional_flags=-multiply_defined suppress"
	}
	if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"] || [istarget "*-*-darwin2*"] } {
	    lappend args "additional_flags=-Wl,-allow_stack_execute"
	}

    }

    return $args
}

# Link a bunch of objects into a program.  MAIN is the name of the
# class holding `main'.  Return 0 on failure.
proc gcj_link {program main files {options {}}} {
    set arguments [libjava_arguments link]
    if {[llength $options]} {
	eval lappend arguments $options
    }
    lappend arguments "additional_flags=--main=$main"
    set x [libjava_prune_warnings \
	     [libjava_tcompile $files $program executable $arguments]]
    if {$x != ""} {
	verbose "link failure: $x" 2
	fail "linking $program"
	setup_xfail "*-*-*"
	fail "running $program"
	return 0
    }

    pass "linking $program"
    return 1
}

# Invoke the program and see what happens.  Return 0 on failure.
proc gcj_invoke {program expectFile ld_library_additions} {
  global env
  global libjava_ld_library_path
  global ld_library_path

  set ld_library_path "$libjava_ld_library_path"
  if {[llength $ld_library_additions] > 0} {
    append ld_library_path :[join $ld_library_additions :]
  }

  set_ld_library_path_env_vars
  if [info exists env(LD_LIBRARY_PATH)] {
    verbose "LD_LIBRARY_PATH=$env(LD_LIBRARY_PATH)"
  }

  set result [libjava_load ./$program]
  set status [lindex $result 0]
  set output [lindex $result 1]

  # Restore setting
  restore_ld_library_path_env_vars

  if {$status != "pass"} {
    verbose "got $output"
    fail "$program run"
    untested "$program output"
    return 0
  }

  set id [open $expectFile r]
  set expected [read $id]
  close $id

  if {! [string compare $output $expected]} {
    pass "$program output"
    return 1
  } else {
    fail "$program output"
    return 0
  }
}

proc exec_gij {jarfile expectFile {ld_library_additions {}} {addl_flags {}}} {
  global env
  global libjava_ld_library_path
  global ld_library_path

  set ld_library_path "$libjava_ld_library_path"
  if {[llength $ld_library_additions] > 0} {
  append ld_library_path :[join $ld_library_additions :]
  }
	
  set_ld_library_path_env_vars
  if [info exists env(LD_LIBRARY_PATH)] {
    verbose "LD_LIBRARY_PATH=$env(LD_LIBRARY_PATH)"
  }
  
  set gij [libjava_find_gij]
  set classname [file rootname [file tail $jarfile]]
  
  puts "LD_LIBRARY_PATH=. $gij -cp $jarfile $addl_flags $classname"
	
  set result [libjava_load $gij "-cp $jarfile $addl_flags $classname"]
  set status [lindex $result 0]
  set output [lindex $result 1]

  restore_ld_library_path_env_vars

  if {$status != "pass"} {
    verbose "got $output"
    fail "$classname run"
    untested "$classname output"
    return 0
  }

  set id [open $expectFile r]
  set expected [read $id]
  close $id

  if {! [string compare $output $expected]} {
    pass "$classname output"
    return 1
  } else {
    fail "$classname output"
    return 0
  }
}

# Invoke a program and check its output.  EXECUTABLE is the program;
# ARGS are the arguments to the program.  Returns 1 if tests passed
# (or things were left untested), 0 otherwise.
proc libjava_invoke {errname testName optName executable inpfile resultfile
		      ld_library_additions args} {
    global env
    global libjava_ld_library_path
    global ld_library_path

    set ld_library_path "$libjava_ld_library_path"
    if {[llength $ld_library_additions] > 0} {
	append ld_library_path :[join $ld_library_additions :]
    }

    set_ld_library_path_env_vars
    if [info exists env(LD_LIBRARY_PATH)] {
	verbose "LD_LIBRARY_PATH=$env(LD_LIBRARY_PATH)"
    }

    upvar $optName opts

    if {[info exists opts(no-exec)]} {
	if {[info exists opts(need-threads)]} {
	    # This means we wanted to try to run it but we couldn't
	    # because threads aren't supported.  So we have to
	    # generate an `untested'.
	    untested "$errname execution - $testName"
	    untested "$errname output - $testName"
	}
	return 1
    }

    send_log "invoke: $executable $args $inpfile\n"

    set result [libjava_load $executable $args "$inpfile"]
    set status [lindex $result 0]
    set output [lindex $result 1]

    # Restore LD_LIBRARY_PATH setting.
    restore_ld_library_path_env_vars

    if {[info exists opts(xfail-exec)]} then {
	setup_xfail *-*-*
    }
    $status "$errname execution - $testName"
    if { $status != "pass" } {
	untested "$errname output - $testName"
	return 0
    }

    verbose "resultfile is $resultfile"
    set id [open $resultfile r]
    set expected ""
    append expected [read $id]
    regsub -all "\r" "$output" "" output
    regsub "\n*$" $expected "" expected
    regsub "\n*$" $output "" output
    regsub "^\n*" $expected "" expected
    regsub "^\n*" $output "" output
    regsub -all "\[ \t\]\[ \t\]*" $expected " " expected
    regsub -all "\[ \t\]*\n\n*" $expected "\n" expected
    regsub -all "\[ \t\]\[ \t\]*" $output " " output
    regsub -all "\[ \t\]*\n\n*" $output "\n" output
    verbose "expected is $expected"
    verbose "actual is $output"
    set passed 0
    if {[info exists opts(regexp_match)]} {
	if [regexp $expected $output] {
	    set passed 1
	}
    } else {
	if { $expected == $output } {
	    set passed 1
	}
    }
    if {[info exists opts(xfail-output)]} {
	setup_xfail *-*-*
    }
    if { $passed == 1 } {
	pass "$errname output - $testName"
    } else {
	fail "$errname output - $testName"
    }
    close $id

    return $passed
}

#
# Run the test specified by srcfile and resultfile. compile_args and
# exec_args are options telling this proc how to work.
#
proc test_libjava_from_source { options srcfile compile_args inpfile resultfile exec_args } {
    global base_dir
    global srcdir subdir objdir
    global TOOL_OPTIONS
    global GCJ_UNDER_TEST
    global tmpdir
    global runtests

    # Make opts into an array.
    set opts(_) x
    unset opts(_)
    foreach item $exec_args {
	set opts($item) x
    }

    # If we need threads and we don't have them then set the `no-exec'
    # flag.  This is case is also handled specially later.
    if {[info exists opts(need-threads)]} {
	global libjava_uses_threads
	if {! $libjava_uses_threads} {
	    set opts(no-exec) x
	}
    }

    set errname [file rootname [file tail $srcfile]]
    if {! [runtest_file_p $runtests $errname]} {
        return
    }

    if {[info exists opts(no-link)]} {
	set mode compile
    } else {
	set mode link
    }
    set args [libjava_arguments $mode]
    if {! [info exists opts(no-link)]} {
	# Add the --main flag
	lappend args "additional_flags=--main=[file rootname [file tail $srcfile]]"
	if { $compile_args != "" } {
	    lappend args "additional_flags=$compile_args"
	}
    }

    regsub "^.*/(\[^/.\]+)\[.\]\[^/]*$" "$srcfile" "\\1" out
    set executable "${objdir}/$out"
    if {[info exists opts(no-link)]} {
	append executable ".o"
	set target object
    } else {
        # DOS/win32 targets default to .exe if no suffix is given
        # We then try to delete a file that doesn't exist.  It is
        # simpler to add the suffix everywhere.
        append executable ".exe"
	set target executable
    }
    if { $compile_args != "" } {
	set errname "$errname $compile_args"
    }

    set removeList [list $executable]

    set x [libjava_prune_warnings \
	     [libjava_tcompile $srcfile "$executable" $target $args]]
    if {[info exists opts(xfail-gcj)]} {
	setup_xfail *-*-*
    }
    if { $x != "" } {
	verbose "target_compile failed: $x" 2

	if {[info exists opts(shouldfail)]} {
	    pass "$errname compilation from source"
	    eval gcj_cleanup $removeList
	    return
	}

	fail "$errname compilation from source"
	if {[info exists opts(xfail-gcj)]
	    || ! [info exists opts(no-exec)]
	    || [info exists opts(need-threads)]} {
	    untested "$errname execution from source compiled test"
	    untested "$errname output from source compiled test"
	}
	return
    }
    if {[info exists opts(shouldfail)]} {
	fail "$errname compilation from source"
	return
    }
    pass "$errname compilation from source"

    # Set up the options the way they are expected by libjava_invoke.
    if {[info exists opts(xfail-source-output)]} {
	set opts(xfail-output) x
    }
    if {[libjava_invoke $errname "source compiled test" opts $executable \
	   $inpfile $resultfile ""]} {
	# Everything ok, so clean up.
	eval gcj_cleanup $removeList
    }
}

#
# Run the test specified by srcfile and resultfile. compile_args and
# exec_args are options telling this proc how to work.
#   `no-link'     don't try to link the program
#   `no-exec'     don't try to run the test
#   `xfail-gcj'   compilation from source will fail
#   `xfail-javac' compilation with javac will fail
#   `xfail-gcjC'  compilation with gcj -C will fail
#   `shouldfail'  compilation from source is supposed to fail
#                 This is different from xfail, which marks a known
#                 failure that we just haven't fixed.
#                 A compilation marked this way should fail with any
#                 front end.
#   `xfail-byte'  compilation from bytecode will fail
#   `xfail-exec'  exec will fail
#   `xfail-output'
#                 output will be wrong
#   `xfail-byte-output'
#                 output will be wrong when compiled from bytecode
#   `xfail-source-output'
#                 output will be wrong when compiled from source code
#   `need-threads'
#                 test relies on thread support
#
proc test_libjava { options srcfile compile_args inpfile resultfile exec_args } {
    test_libjava_from_source $options $srcfile $compile_args $inpfile $resultfile $exec_args

    # Test BC-ABI compilation.
    set compile_args_bcabi $compile_args
    lappend compile_args_bcabi "-findirect-dispatch"
    test_libjava_from_source $options $srcfile $compile_args_bcabi $inpfile $resultfile $exec_args
}

#
# libjava_version -- extract and print the version number of libjavap
#
proc default_libjava_version {} {
}

proc default_libjava_start { } {
}

# Local Variables:
# tcl-indent-level:4
# End:
