OSDN Git Service

e6b37444b5382bb82788c24605cfc51d4b4bfd96
[pf3gnuchains/gcc-fork.git] / libjava / testsuite / lib / libjava.exp
1 # Copyright (C) 1998, 1999, 2000 Free Software Foundation
2
3 load_lib "libgloss.exp"
4
5 # GCJ_UNDER_TEST is the compiler under test.
6
7 global tmpdir
8
9 if ![info exists tmpdir] {
10     set tmpdir "/tmp"
11 }
12
13 # This is like `target_compile' but it does some surgery to work
14 # around stupid DejaGNU bugs.  In particular DejaGNU has very poor
15 # quoting, so for instance a `$' will be re-evaluated at spawn time.
16 # We don't want that.
17 proc libjava_tcompile {source destfile type options} {
18     # This strange-looking expression really does quote the `$'.
19     regsub -all -- {\$} $source {\$} source
20     regsub -all -- {\$} $destfile {\$} destfile
21     verbose "Now source = $source"
22     verbose "Now destfile = $destfile"
23     return [target_compile $source $destfile $type $options]
24 }
25
26 # Read an `xfail' file if it exists.  Returns a list of xfail tokens.
27 proc libjava_read_xfail {file} {
28     if {! [file exists $file]} {
29         return ""
30     }
31     set fd [open $file r]
32     set tokens [string trim [read $fd]]
33     close $fd
34     return $tokens
35 }
36
37 # Find a particular executable.  FIXME: this relies on DejaGnu
38 # internals.  These should probably be exposed in a better way.
39 proc libjava_find_program {prog} {
40     global tool_root_dir
41
42     set file [lookfor_file $tool_root_dir $prog]
43     if { $file == "" } {
44         set file [lookfor_file $tool_root_dir gcc/$prog];
45     }
46     if {$file == ""} {
47         set file $prog
48     }
49     return $file
50 }
51
52 # Find `jv-scan'.
53 proc find_jvscan {} {
54     return [libjava_find_program jv-scan]
55 }
56
57 # Find `gcjh'.
58 proc find_gcjh {} {
59     return [libjava_find_program gcjh]
60 }
61
62 proc find_javac {} {
63     global SUN_JAVAC GCJ_UNDER_TEST env
64     # If JDK doesn't run on your platform but some other
65     # JDK-compatible javac does, you may set SUN_JAVAC to point to it.
66     # One of the most important properties of a SUN_JAVAC is that it
67     # must create class-files even for classes that have not been
68     # specified in the command line, but that were needed to compile
69     # those that have.  For example, Pizza won't do it, but you can
70     # use `kaffe sun.tools.javac.Main', if you have Sun's classes.zip
71     # in the kaffe's default search path.
72     if {![info exists SUN_JAVAC]} {
73         if {[info exists env(SUN_JAVAC)]} {
74             set SUN_JAVAC $env(SUN_JAVAC)
75         } else {
76             set SUN_JAVAC "$GCJ_UNDER_TEST -C"
77         }
78     }
79     return $SUN_JAVAC
80 }
81
82 proc bytecompile_file { file objdir {classpath {}} } {
83     global env
84     set dirname [file dirname $file]
85
86     set javac [find_javac]
87     catch {unset env(CLASSPATH)}
88     if {$classpath != ""} then {
89         set env(CLASSPATH) $classpath
90     }
91     if {[catch {
92         set here [pwd]
93         cd $dirname
94         set q [eval exec "$javac [list $file] -d $objdir 2>@ stdout"]
95         cd $here
96         # "return" a result
97         set q $q
98     } msg]} then {
99         verbose "couldn't compile $file: $msg"
100         set r 0
101     } else {
102         set r 1
103     }
104     return $r
105 }
106
107 set libjava_initialized 0
108
109 #
110 # Build the status wrapper library as needed.
111 #
112 proc libjava_init { args } {
113     global wrapper_file;
114     global wrap_compile_flags;
115     global libjava_initialized
116     global GCJ_UNDER_TEST
117     global TOOL_EXECUTABLE
118     global original_ld_library_path
119     global env
120
121     if { $libjava_initialized == 1 } { return; }
122
123     if ![info exists GCJ_UNDER_TEST] {
124         if [info exists TOOL_EXECUTABLE] {
125             set GCJ_UNDER_TEST $TOOL_EXECUTABLE;
126         } else {
127             if [info exists env(GCJ)] {
128                 set GCJ_UNDER_TEST $env(GCJ)
129             } else {
130                 set GCJ_UNDER_TEST "[find_gcj]"
131             }
132         }
133     }
134
135     if [info exists env(LD_LIBRARY_PATH)] {
136         set original_ld_library_path $env(LD_LIBRARY_PATH)
137     } else {
138         if [info exists env(SHLIB_PATH)] {
139             set original_ld_library_path $env(SHLIB_PATH)
140         } else {
141             set original_ld_library_path ""
142         }
143     }
144
145     set wrapper_file "";
146     set wrap_compile_flags "";
147     if [target_info exists needs_status_wrapper] {
148         set result [build_wrapper "testglue.o"];
149         if { $result != "" } {
150             set wrapper_file [lindex $result 0];
151             set wrap_compile_flags [lindex $result 1];
152         } else {
153             warning "Status wrapper failed to build."
154         }
155     }
156
157     set libjava_initialized 1
158 }
159
160 # Find a library.  We know where libtool puts the actual libraries,
161 # and we look there.  The implementation is fairly hacky.  We can't
162 # compile with -nodefaultlibs, because that will also eliminate the
163 # system libraries we need.  In order to have gcj still work, it must
164 # find the appropriate libraries so we must add -L options for their
165 # paths.  However we can't simply use those libraries; we still need
166 # libtool for linking.
167 proc libjava_find_lib {dir name} {
168     global base_dir
169     set gp [get_multilibs]
170     foreach sub {.libs _libs} {
171         if {$gp != ""} {
172             if {[file exists $gp/$dir/$sub/lib${name}.a]} then {
173                 return "$gp/$dir/lib${name}.la -L$gp/$dir/$sub"
174             }
175         }
176         set lib [findfile $base_dir/../../$dir/$sub/lib${name}.a \
177                    "$base_dir/../../$dir/lib${name}.la -L$base_dir/../../$dir/$sub" \
178                    ""]
179         if {$lib != ""} {
180             return $lib
181         }
182     }
183     return ""
184 }
185
186 # Compute arguments needed for compiler.  MODE is a libtool mode:
187 # either compile or link.
188 proc libjava_arguments {{mode compile}} {
189     global base_dir
190     global LIBJAVA
191     global LIBGC
192     global LIBQTHREADS
193     global LIBZ
194     global srcdir subdir objdir
195     global TOOL_OPTIONS
196     global GCJ_UNDER_TEST
197     global tmpdir
198     global runtests
199     global env
200
201     if [info exists LIBJAVA] {
202         set libjava $LIBJAVA;
203     } else {
204         set libjava [libjava_find_lib libjava gcj]
205     }
206
207     if [info exists LIBGC] {
208         set libgc $LIBGC;
209     } else {
210         set libgc [libjava_find_lib boehm-gc gcjgc]
211     }
212
213     if [info exists LIBQTHREADS] {
214         set libqthreads $LIBQTHREADS
215     } else {
216         set libqthreads [libjava_find_lib qthreads gcjcoop]
217     }
218
219     if [info exists LIBZ] {
220         set libz $LIBZ
221     } else {
222         set libz [libjava_find_lib zlib zgcj]
223     }
224
225     # FIXME: there's no way to determine whether -lpthread is
226     # required.  We should get this info from configure, or it should
227     # just be in the compiler driver.
228
229     verbose "using LIBJAVA = $libjava" 2
230     verbose "using LIBGC = $libgc" 2
231     verbose "using LIBQTHREADS = $libqthreads" 2
232     verbose "using LIBZ = $libz" 2
233     set args ""
234
235     # Basically we want to build up a colon separated path list from
236     # the value of $libjava.
237
238     # First strip away any -L arguments.
239     regsub -all -- "-L" $libjava "" ld_library_path
240
241     # Then remove any -lgcj argument.
242     regsub -all -- " -lgcj.*" $ld_library_path "" ld_library_path
243
244     # First strip away any -L arguments.
245     regsub -all -- "-L" $libgc $ld_library_path ld_library_path
246
247     # Then remove any -lgcjgc argument.
248     regsub -all -- " -lgcjgc.*" $ld_library_path "" ld_library_path
249
250     # That's enough to make things work for the normal case.
251     # If we wanted to handle an arbitrary value of libjava,
252     # then we'd have to do a lot more work.
253
254     # Set variables the dynamic linker looks at.
255     global original_ld_library_path
256     setenv LD_LIBRARY_PATH "$ld_library_path:$original_ld_library_path"
257     setenv SHLIB_PATH "$ld_library_path:$original_ld_library_path"
258
259     # Set the CLASSPATH environment variable
260     verbose "CLASSPATH is .:$srcdir/$subdir:$objdir:$objdir/../libgcj.zip"
261     global env
262     set env(CLASSPATH) ".:$srcdir/$subdir:$objdir:$objdir/../libgcj.zip"
263
264     global wrapper_file wrap_compile_flags;
265     lappend args "additional_flags=$wrap_compile_flags";
266     lappend args "libs=$wrapper_file";
267     lappend args "libs=$libjava";
268     lappend args "libs=$libgc";
269     lappend args "libs=$libqthreads"
270     lappend args "libs=$libz"
271     lappend args debug
272
273     if { [target_info needs_status_wrapper]!="" && [info exists gluefile] } {
274         lappend args "libs=${gluefile}"
275         lappend args "ldflags=$wrap_flags"
276     }
277
278     if [info exists TOOL_OPTIONS] {
279         lappend args "additional_flags=$TOOL_OPTIONS"
280     }
281
282     # Search for libtool.  We need it to link.
283     set found_compiler 0
284     set d [absolute $objdir]
285     foreach x {. .. ../.. ../../..} {
286         if {[file exists $d/$x/libtool]} then {
287             # We have to run silently to avoid DejaGNU lossage.
288             lappend args \
289               "compiler=$d/$x/libtool --silent --tag=GCJ --mode=$mode $GCJ_UNDER_TEST -B$objdir/../"
290             set found_compiler 1
291             break
292         }
293     }
294     if {! $found_compiler} {
295         # Append -B$objdir/../ so that we find libgcj.spec before it
296         # is installed.
297         lappend args "compiler=$GCJ_UNDER_TEST -B$objdir/../"
298     }
299
300     return $args
301 }
302
303
304 #
305 # Run the test specified by srcfile and resultfile. compile_args and
306 # exec_args are options telling this proc how to work.
307 #
308 proc test_libjava_from_source { options srcfile compile_args inpfile resultfile exec_args } {
309     global base_dir
310     global LIBJAVA
311     global LIBGC
312     global srcdir subdir objdir
313     global TOOL_OPTIONS
314     global GCJ_UNDER_TEST
315     global tmpdir
316     global runtests
317
318     # Make opts into an array.
319     set opts(_) x
320     unset opts(_)
321     foreach item $exec_args {
322         set opts($item) x
323     }
324
325     set errname [file rootname [file tail $srcfile]]
326     if {! [runtest_file_p $runtests $errname]} {
327         return
328     }
329
330     if {[info exists opts(no-link)]} {
331         set mode compile
332     } else {
333         set mode link
334     }
335     set args [libjava_arguments $mode]
336     if {! [info exists opts(no-link)]} {
337         # Add the --main flag
338         lappend args "additional_flags=--main=[file rootname [file tail $srcfile]]"
339         if { $compile_args != "" } {
340             lappend args "additional_flags=$compile_args"
341         }
342     }
343
344     regsub "^.*/(\[^/.\]+)\[.\]\[^/]*$" "$srcfile" "\\1" out
345     set executable "${objdir}/$out"
346     if {[info exists opts(no-link)]} {
347         append executable ".o"
348         set target object
349     } else {
350         set target executable
351     }
352     if { $compile_args != "" } {
353         set errname "$errname $compile_args"
354     }
355
356     set x [prune_warnings \
357              [libjava_tcompile $srcfile "$executable" $target $args]]
358     if {[info exists opts(xfail-gcj)]} {
359         setup_xfail *-*-*
360     }
361     if { $x != "" } {
362         verbose "target_compile failed: $x" 2
363
364         if {[info exists opts(shouldfail)]} {
365             pass "$errname compilation from source"
366             return
367         }
368
369         fail "$errname compilation from source"
370         if {[info exists opts(xfail-gcj)] || ! [info exists opts(no-exec)]} {
371             setup_xfail "*-*-*"
372             fail "$errname execution from source compiled test"
373             setup_xfail "*-*-*"
374             fail "$errname output from source compiled test"
375         }
376         return
377     }
378     if {[info exists opts(shouldfail)]} {
379         fail "$errname compilation from source"
380         return
381     }
382     pass "$errname compilation from source"
383
384     if {[info exists opts(no-exec)]
385         || [info exists opts(no-link)]} {
386         return
387     }
388
389     set result [libjava_load $executable "" "$inpfile"];
390     set status [lindex $result 0];
391     set output [lindex $result 1];
392     if {[info exists opts(xfail-exec)]} then {
393         setup_xfail *-*-*
394     }
395     $status "$errname execution from source compiled test"
396     if { $status != "pass" } {
397         setup_xfail "*-*-*"
398         fail "$errname execution from source compiled test"
399         return;
400     }
401
402     verbose "resultfile is $resultfile"
403     set id [open $resultfile r];
404     set expected ""
405     append expected [read $id];
406     regsub -all "\r" "$output" "" output;
407     regsub "\n*$" $expected "" expected
408     regsub "\n*$" $output "" output
409     regsub "^\n*" $expected "" expected
410     regsub "^\n*" $output "" output
411     regsub -all "\[ \t\]\[ \t\]*" $expected " " expected
412     regsub -all "\[ \t\]*\n\n*" $expected "\n" expected
413     regsub -all "\[ \t\]\[ \t\]*" $output " " output
414     regsub -all "\[ \t\]*\n\n*" $output "\n" output
415     verbose "expected is $expected"
416     verbose "actual is $output"
417     set passed 0;
418     if {$options == "regexp_match"} {
419         if [regexp $expected $output] {
420             set passed 1;
421         }
422     } else {
423         if { $expected == $output } {
424             set passed 1;
425         }
426     }
427     if {[info exists opts(xfail-output)]} {
428         setup_xfail *-*-*
429     }
430     if { $passed == 1 } {
431         pass "$errname output from source compiled test"
432     } else {
433         clone_output "expected was $expected"
434         clone_output "output was $output"
435         fail "$errname output from source compiled test"
436     }
437     close $id;
438 }
439
440 #
441 # Run the test specified by srcfile and resultfile. compile_args and
442 # exec_args are options telling this proc how to work.
443 #
444 proc test_libjava_from_javac { options srcfile compile_args inpfile resultfile exec_args } {
445     global base_dir
446     global LIBJAVA
447     global LIBGC
448     global srcdir subdir objdir
449     global TOOL_OPTIONS
450     global GCJ_UNDER_TEST
451     global tmpdir
452     global runtests
453
454     # Make opts into an array.
455     set opts(_) x
456     unset opts(_)
457     foreach item $exec_args {
458         set opts($item) x
459     }
460
461     set errname [file rootname [file tail $srcfile]]
462     if {! [runtest_file_p $runtests $errname]} {
463         return
464     }
465
466     # bytecompile files with Sun's compiler for now.
467     set bc_ok [bytecompile_file $srcfile $objdir]
468
469     set javac [find_javac]
470     # This is an ugly heuristic but it will have to do.
471     if {[string match *gcj* $javac]} {
472         set tag gcjC
473     } else {
474         set tag javac
475     }
476     if {[info exists opts(xfail-$tag)]} {
477         setup_xfail *-*-*
478     }
479     if {! $bc_ok} then {
480         if {[info exists opts(shouldfail)]} {
481             pass "$errname byte compilation"
482             return
483         }
484         fail "$errname byte compilation"
485         setup_xfail "*-*-*"
486         fail "$errname compilation from bytecode"
487         if {! [info exists opts(no-exec)]} {
488             setup_xfail "*-*-*"
489             fail "$errname execution from bytecode->native test"
490             setup_xfail "*-*-*"
491             fail "$errname output from bytecode->native test"
492         }
493         return
494     }
495     if {[info exists opts(shouldfail)]} {
496         fail "$errname byte compilation"
497         return
498     }
499     pass "$errname byte compilation"
500
501     # Find name to use for --main, and name of all class files.
502     set jvscan [find_jvscan]
503     verbose "jvscan is $jvscan"
504     set main_name [string trim \
505                      [prune_warnings \
506                         [libjava_tcompile $srcfile "" none \
507                            "compiler=$jvscan additional_flags=--print-main"]]]
508     verbose "main name is $main_name"
509     set class_out [string trim \
510                      [prune_warnings \
511                         [libjava_tcompile $srcfile "" none \
512                            "compiler=$jvscan additional_flags=--list-class"]]]
513     verbose "class list is $class_out"
514
515     if {[string match "*parse error*" $main_name]
516         || [string match "*parse error*" $class_out]} {
517         # Do the remaining fails.
518         setup_xfail "*-*-*"
519         fail "$errname compilation from bytecode"
520         if {! [info exists opts(no-exec)]} {
521             setup_xfail "*-*-*"
522             fail "$errname execution from bytecode->native test"
523             setup_xfail "*-*-*"
524             fail "$errname output from bytecode->native test"
525         }
526         return
527     }
528
529     # Turn "a b" into "a.class b.class".
530     # Also, turn "foo.bar" into "foo/bar.class".
531     set class_files {}
532     foreach file [split [string trim $class_out]] {
533         set file [join [split $file .] /]
534         lappend class_files $objdir/$file.class
535     }
536
537     # Usually it is an error for a test program not to have a `main'
538     # method.  However, for no-exec tests it is ok.  Treat no-link
539     # like no-exec here.
540     if {[info exists opts(no-link)]} {
541         set opts(no-exec) x
542     }
543     set largs {}
544
545     if {[info exists opts(no-exec)]} {
546         set type object
547         set mode compile
548     } elseif {$main_name == ""} {
549         perror "No `main' given in program $errname"
550         return
551     } else {
552         set type executable
553         lappend largs "additional_flags=--main=$main_name"
554         set executable "${objdir}/$main_name"
555         set mode link
556     }
557
558     # Initial arguments.
559     set args [libjava_arguments $mode]
560     eval lappend args $largs
561
562     if { $compile_args != "" } {
563         lappend args "additional_flags=$compile_args"
564     }
565
566     if { $compile_args != "" } {
567         set errname "$errname $compile_args"
568     }
569
570     verbose "compilation command = $args" 2
571     # When compiling and not linking, we have to build each .o
572     # separately.  We do this because DejaGNU's target_compile won't
573     # accept an empty "destfile" argument when the mode is "compile".
574     if {$mode == "compile"} {
575         foreach c_file $class_files {
576             set executable [file rootname [file tail $c_file]].o
577             set x [prune_warnings \
578                      [libjava_tcompile $c_file "$executable" $type $args]]
579             if {$x != ""} {
580                 break
581             }
582         }
583     } else {
584         set x [prune_warnings \
585                  [libjava_tcompile $class_files "$executable" $type $args]]
586     }
587     if {[info exists opts(xfail-byte)]} {
588         setup_xfail *-*-*
589     }
590     if { $x != "" } {
591         verbose "target_compile failed: $x" 2
592         fail "$errname compilation from bytecode"
593         setup_xfail "*-*-*"
594         if {! [info exists opts(no-exec)]} {
595             fail "$errname execution from bytecode->native test"
596             setup_xfail "*-*-*"
597             fail "$errname output from bytecode->native test"
598         }
599         return;
600     }
601     pass "$errname compilation from bytecode"
602
603     if {[info exists opts(no-exec)]} {
604         return
605     }
606
607     set result [libjava_load $executable "" "$inpfile"];
608     set status [lindex $result 0];
609     set output [lindex $result 1];
610     if {[info exists opts(xfail-exec)]} {
611         setup_xfail *-*-*
612     }
613     $status "$errname execution from bytecode->native test"
614     if { $status != "pass" } {
615         setup_xfail "*-*-*"
616         fail "$errname output from bytecode->native test"
617         return;
618     }
619
620     verbose "resultfile is $resultfile"
621     set id [open $resultfile r];
622     set expected ""
623     append expected [read $id];
624     regsub -all "\r" "$output" "" output;
625     regsub "\n*$" $expected "" expected
626     regsub "\n*$" $output "" output
627     regsub "^\n*" $expected "" expected
628     regsub "^\n*" $output "" output
629     regsub -all "\[ \t\]\[ \t\]*" $expected " " expected
630     regsub -all "\[ \t\]*\n\n*" $expected "\n" expected
631     regsub -all "\[ \t\]\[ \t\]*" $output " " output
632     regsub -all "\[ \t\]*\n\n*" $output "\n" output
633     verbose "expected is $expected"
634     verbose "actual is $output"
635     set passed 0;
636     if {[info exists opts(xfail-output)]} {
637         setup_xfail *-*-*
638     }
639     if {$options == "regexp_match"} {
640         if [regexp $expected $output] {
641             set passed 1;
642         }
643     } else {
644         if { $expected == $output } {
645             set passed 1;
646         }
647     }
648     if { $passed == 1 } {
649         pass "$errname output from bytecode->native test"
650     } else {
651         clone_output "expected was $expected"
652         clone_output "output was $output"
653         fail "$errname output from bytecode->native test"
654     }
655     close $id;
656 }
657
658 #
659 # Run the test specified by srcfile and resultfile. compile_args and
660 # exec_args are options telling this proc how to work.
661 #   `no-link'     don't try to link the program
662 #   `no-exec'     don't try to run the test
663 #   `xfail-gcj'   compilation from source will fail
664 #   `xfail-javac' compilation with javac will fail
665 #   `xfail-gcjC'  compilation with gcj -C will fail
666 #   `shouldfail'  compilation from source is supposed to fail
667 #                 This is different from xfail, which marks a known
668 #                 failure that we just havne't fixed.
669 #                 A compilation marked this way should fail with any
670 #                 front end.
671 #   `xfail-byte'  compilation from bytecode will fail
672 #   `xfail-exec'  exec will fail
673 #   `xfail-output' output will be wrong
674 #
675 proc test_libjava { options srcfile compile_args inpfile resultfile exec_args } {
676     test_libjava_from_source $options $srcfile $compile_args $inpfile $resultfile $exec_args
677     test_libjava_from_javac $options $srcfile $compile_args $inpfile $resultfile $exec_args
678  }
679
680 #
681 # libjava_version -- extract and print the version number of libjavap
682 #
683 proc default_libjava_version {} {
684 }
685
686 proc default_libjava_start { } {
687 }
688
689 # Local Variables:
690 # tcl-indent-level:4
691 # End: