#! /bin/sh

# Copyright (c) 1998, 1999 Cygnus Solutions
# Written by Tom Tromey <tromey@cygnus.com>

# This file is part of Mauve.

# Mauve 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 2, or (at your option)
# any later version.

# Mauve 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 Mauve; see the file COPYING.  If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.  */


# Choose the tests we want to run.
# Usage: choose [-verbose] output-directory [tag] ...
# Run in the source directory.
# See README for information on tags.

verbose=
spectags=
tags=
file_specs=

if test "$1" = "-verbose"; then
   verbose=yes
   shift
fi

outdir="$1"
shift

# Some tags imply other tags.  For instance, JDK1.2 implies JDK1.1 and
# JDK1.0.  This makes it easier to keep the tags up to date in the
# source -- we only have to keep track of differences (as opposed to
# editing every source file when a new tag is added).  If we see an
# otherwise-unrecognized tag, and the file `mauve-TAG' exists, then we
# treat the contents of that file as a list of implied tags.
taglist=${1+"$@"}
seen_dashdash=
while test -n "$taglist"; do
   set $taglist
   i="$1"
   shift
   taglist=${1+"$@"}

   case "$i" in
    X--)
       seen_dashdash=yes
       ;;
    !!java.*)
       echo "Invalid tag: $i" 1>&2
       exit 1
       ;;
    !java.* | java.* | !javax.* | javax.*)
       file="`echo $i | tr . /`"
       file_specs="$file_specs $file"
       ;;
    not-a-test)
       # You can't specify this.
       :
       ;;
    JAVA2)
       tags="$tags JDK1.0 JDK1.1 JDK1.2 $i"
       test -z "$seen_dashdash" && spectags="$spectags $i"
       ;;
    JDK1.2)
       tags="$tags JDK1.0 JDK1.1 JAVA2 $i"
       test -z "$seen_dashdash" && spectags="$spectags $i"
       ;;
    JDK1.1)
       tags="$tags JDK1.0 JLS1.1 $i"
       test -z "$seen_dashdash" && spectags="$spectags $i"
       ;;
    JDK1.0)
       tags="$tags JLS1.0"
       test -z "$seen_dashdash" && spectags="$spectags $i"
       ;;
    JLS1.1)
       tags="$tags JDK1.0 JDK1.1"
       test -z "$seen_dashdash" && spectags="$spectags $i"
       ;;
    JLS1.0)
       tags="$tags JDK1.0"
       test -z "$seen_dashdash" && spectags="$spectags $i"
       ;;
    *)
       file=
       # Always prefer a tag file in the build directory.
       if test -f "$outdir/mauve-$i"; then
	  file="$outdir/mauve-$i"
       else
	  if test -f "mauve-$i"; then
	     file="mauve-$i"
	  fi
       fi
       if test -n "$file"; then
	  # We don't want tags from a file to be treated as specified
	  # on the command line.  So we add a `X--' before the
	  # expansion.  We don't use just `--' as this would confuse
	  # `set'.
	  taglist="$taglist X-- `sed -e 's/#.*$//g' $file`"
       fi
       tags="$tags $i"
       test -z "$seen_dashdash" && spectags="$spectags $i"
       ;;
   esac
done

# By default, use JDK1.1.
test -z "$tags" && tags="JDK1.0 JDK1.1"

test -n "$verbose" && echo "tags = $tags"
test -n "$verbose" && echo "spectags = $spectags"
test -n "$verbose" && echo "file_specs = $file_specs"

choices=/tmp/choices-$$
echo "CHOICES =" > $choices
classes=/tmp/classes-$$
: > $classes
usesfile=/tmp/uses-$$
: > $usesfile

(cd gnu/testlet; find java javax -name '*.java' -print) |
while read file; do
   exact_match=no
   test -n "$verbose" && echo "Examining $file"
   if test -n "$file_specs"; then
      ok=yes
      for pat in $file_specs; do
	 # PAT can be like `java.lang' or `!java.lang'.
	 # If `!FILE' matches `PAT', then we know the pattern
	 # starts with `!' and is an exclusion pattern.
	 # Otherwise, if `!FILE' matches `!PAT', then we know that
	 # the file should be included.
	 case "!$file" in
	  ${pat}*)
	     ok=no
	     test -n "$verbose" && echo "  ... excluded by $pat"
	     ;;
	  !${pat}.java)
	     # If the tag list includes an exact match, then we
	     # unconditionally accept it.
	     ok=yes
	     exact_match=yes
	     test -n "$verbose" && echo "  ... included by $pat (exact match)"
	     ;;
	  !${pat}*)
	     ok=yes
	     test -n "$verbose" && echo "  ... included by $pat"
	     ;;
	 esac
      done
   else
      ok=yes
   fi

   if test "$ok" = no; then
      continue
   fi

   # Surround value with spaces so that case statements will work
   # correctly.
   taglist=" `grep '^// Tags:' gnu/testlet/$file | sed -e 's,^// Tags:,,'` "
   istest=yes
   case "$taglist" in
    *\ not-a-test\ *)
       istest=no
       ;;
   esac

   # For an exact match, we don't look at the tags.
   if test "$exact_match" = no; then
      ok=no
      # If any tag on the tag list matches, then we are ok.
      for tag in $tags; do
	 case "$taglist" in
	    *" ${tag} "*)
	    ok=yes
	    break
	    ;;
	 esac
      done

      # If any specified tag hits a `not' tag, then we are not ok.
      if test "$ok" = yes; then
	 for tag in $spectags; do
	    case "$taglist" in
	       *" !${tag} "*)
	         ok=no
		 test -n "$verbose" && echo "File $file has tag !$tag"
		 break
		 ;;
	    esac
	 done
      else
	 test -n "$verbose" && echo "  ... excluded because no tag matched"
      fi
   fi

   if test "$ok" = yes; then
      class="gnu.testlet.`echo $file | sed -e 's/\.java$//' | tr / .`"
      dirpart="`echo $file | sed -e 's,/[^/]*$,,'`"
      echo " gnu/testlet/$file" >> $choices
      if test "$istest" = yes; then
	 echo $class >> $classes
	 test -n "$verbose" && echo "Chose $class"

	 # Now that we know we're going to use this class, see
	 # what other support classes this test requires.
         useslist=" `grep '^// Uses:' gnu/testlet/$file | sed -e 's,^// Uses:,,'` "
         for used in $useslist; do
	   usedfile=$dirpart/$used.java
	   echo "gnu/testlet/$usedfile" >> $usesfile
         done

      fi
   fi
done

# Now uniquify the list of auxiliary files we used, and add them to
# the list of choices.  I think neither `uniq' nor `sort -u' is
# portable, so we do it by hand.
previous=
sort $usesfile |
while read next; do
   if test "$previous" != "$next"; then
      echo " $next" >> $choices
      previous=$next
   fi
done

# Add a backslash to the end of every line except the last one.
sed -e '$ !s/$/ \\/' < $choices > /tmp/x-$$
mv /tmp/x-$$ $choices
echo >> $choices

# Due to a weirdness in GNU make, we want to list the dependencies
# explicitly here.  This is really nasty.  But if we remove this, then
# SimpleTestHarness will never be built, because its dependencies
# won't include the .o files (but, strangely, the link line will).
sed -e 's/CHOICES =/SimpleTestHarness:/' \
   -e 's/\.java/.o/g' $choices > /tmp/x-$$
cat /tmp/x-$$ >> $choices
rm /tmp/x-$$

if test -f $outdir/choices \
   && cmp $choices $outdir/choices > /dev/null 2>&1; then
   # Files are the same.
   rm $choices $classes
else
   mv $choices $outdir/choices
   mv $classes $outdir/classes
fi
rm $usesfile

exit 0
