/* gnu/regexp/RETokenPOSIX.java
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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.

GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.util.regex;

import gnu.java.lang.CPStringBuilder;

final class RETokenPOSIX extends REToken
{
  int type;
  boolean insens;
  boolean negated;

  static final int ALNUM = 0;
  static final int ALPHA = 1;
  static final int BLANK = 2;
  static final int CNTRL = 3;
  static final int DIGIT = 4;
  static final int GRAPH = 5;
  static final int LOWER = 6;
  static final int PRINT = 7;
  static final int PUNCT = 8;
  static final int SPACE = 9;
  static final int UPPER = 10;
  static final int XDIGIT = 11;

  // Array indices correspond to constants defined above.
  static final String[] s_nameTable = {
    "alnum", "alpha", "blank", "cntrl", "digit", "graph", "lower",
    "print", "punct", "space", "upper", "xdigit"
  };

  // The RE constructor uses this to look up the constant for a string
  static int intValue (String key)
  {
    for (int i = 0; i < s_nameTable.length; i++)
      {
        if (s_nameTable[i].equals (key))
          return i;
      }
    return -1;
  }

  RETokenPOSIX (int subIndex, int type, boolean insens, boolean negated)
  {
    super (subIndex);
    this.type = type;
    this.insens = insens;
    this.negated = negated;
  }

  int getMinimumLength ()
  {
    return 1;
  }

  int getMaximumLength ()
  {
    return 1;
  }

  REMatch matchThis (CharIndexed input, REMatch mymatch)
  {
    char ch = input.charAt (mymatch.index);
    boolean retval = matchOneChar (ch);
    if (retval)
      {
        ++mymatch.index;
        return mymatch;
      }
    return null;
  }

  boolean matchOneChar (char ch)
  {
    if (ch == CharIndexed.OUT_OF_BOUNDS)
      return false;

    boolean retval = false;
    switch (type)
      {
      case ALNUM:
        // Note that there is some debate over whether '_' should be included
        retval = Character.isLetterOrDigit (ch) || (ch == '_');
        break;
      case ALPHA:
        retval = Character.isLetter (ch);
        break;
      case BLANK:
        retval = ((ch == ' ') || (ch == '\t'));
        break;
      case CNTRL:
        retval = Character.isISOControl (ch);
        break;
      case DIGIT:
        retval = Character.isDigit (ch);
        break;
      case GRAPH:
        retval =
          (!(Character.isWhitespace (ch) || Character.isISOControl (ch)));
        break;
      case LOWER:
        retval = ((insens && Character.isLetter (ch))
                  || Character.isLowerCase (ch));
        break;
      case PRINT:
        retval =
          (!(Character.isWhitespace (ch) || Character.isISOControl (ch)))
          || (ch == ' ');
        break;
      case PUNCT:
        // This feels sloppy, especially for non-U.S. locales.
        retval = ("`~!@#$%^&*()-_=+[]{}\\|;:'\"/?,.<>".indexOf (ch) != -1);
        break;
      case SPACE:
        retval = Character.isWhitespace (ch);
        break;
      case UPPER:
        retval = ((insens && Character.isLetter (ch))
                  || Character.isUpperCase (ch));
        break;
      case XDIGIT:
        retval = (Character.isDigit (ch)
                  || ("abcdefABCDEF".indexOf (ch) != -1));
        break;
      }

    if (negated)
      retval = !retval;
    return retval;
  }

  boolean returnsFixedLengthMatches ()
  {
    return true;
  }

  int findFixedLengthMatches (CharIndexed input, REMatch mymatch, int max)
  {
    int index = mymatch.index;
    int numRepeats = 0;
    while (true)
      {
        if (numRepeats >= max)
          break;
        char ch = input.charAt (index++);
        if (!matchOneChar (ch))
          break;
        numRepeats++;
      }
    return numRepeats;
  }

  void dump (CPStringBuilder os)
  {
    if (negated)
      os.append ('^');
    os.append ("[:" + s_nameTable[type] + ":]");
  }
}
