#! /bin/sh

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

# Copyright (c) 2002 Free Software Foundation, Inc.
# Adapted by Mark Wielaard <mark@klomp.org>

# 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, 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.  */

# Choose the tests we want to run. Output generated in file 'test_classes'.
# Usage: choose-classes [-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
test -z "$outdir" \
      && echo "Usage: choose-classes [-verbose] output-directory [tag] ..." \
      && exit -1

# 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.*)
   !java.* | java.* | !javax.* | javax.* | !gnu.* | gnu.*)
      file="`echo $i | tr . /`"
      file_specs="$file_specs $file"
      ;;
   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"

classes=/tmp/classes-$$
: > $classes

#(cd gnu/testlet; find java javax -name '*.java' -print) |
(cd gnu/testlet; find gnu -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 / .`"
      if test "$istest" = yes; then
         echo $class >> $classes
         test -n "$verbose" && echo "Chose $class"
      else
         test -n "$verbose" && echo " ... excluded because not-a-test"
      fi
   fi
done

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

exit 0
