Logo Search packages:      
Sourcecode: mauve version File versions  Download package

UnicodeBase.java

//Uses: CharInfo

/* Copyright (C) 1999 Artur Biesiadowski
   Copyright (C) 2004 Stephen Crawley
   Copyright (C) 2007 Joshua Sumali

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.  */

package gnu.testlet.java.lang.Character;

import java.io.*;

import gnu.testlet.Testlet;
import gnu.testlet.TestHarness;
import gnu.testlet.ResourceNotFoundException;

public abstract class UnicodeBase implements Testlet {

      public static boolean testDeprecated;
      public static boolean verbose;
      public static boolean benchmark;

      public int failures;
      public int tests;
      TestHarness harness;

      private Reader bir;
      private StringBuffer sb;

      public UnicodeBase()
      {
      }

      public UnicodeBase(TestHarness aHarness, String filename) 
      throws ResourceNotFoundException, FileNotFoundException
      {
            harness = aHarness;
            bir = harness.getResourceReader("gnu#testlet#java#lang#Character#" +
                        filename);
      }

      private String getNext(Reader r) throws IOException
      {
            sb = new StringBuffer();
            while (r.ready())
            {
                  char ch = (char) r.read();
                  if (ch == '\r')
                  {
                        continue;
                  }
                  else if (ch == ';' ||  ch == '\n')
                  {
                        return sb.toString();
                  }
                  else
                        sb.append(ch);
            }
            return sb.toString();
      }

      public void performTests() throws IOException{

            //actual test loop
            CharInfo ci = new CharInfo();
            while (bir.ready())
            {
                  String str;
                  ci = new CharInfo();
                  // 0 - Code value
                  str = getNext(bir);
                  int code = Integer.parseInt(str, 16);
                  ci.code = code;

                  // 1 - Character name
                  ci.name = getNext(bir);
                  // 2 - General category
                  ci.category = getNext(bir);
                  // 3 - Canonical combining classes
                  getNext(bir);
                  // 4 - Bidirectional category
                  getNext(bir);
                  // 5 - Character decomposition mapping
                  getNext(bir);
                  // 6 - Decimal digit value
                  str = getNext(bir);
                  if (!str.equals(""))
                        ci.decimalDigit = Integer.parseInt(str, 10);
                  else
                        ci.decimalDigit = -1;
                  // 7 - Digit value
                  str = getNext(bir);
                  if (!str.equals(""))
                        ci.digit = Integer.parseInt(str, 10);
                  else
                        ci.digit = -1;

                  // 8 - Numeric value
                  str = getNext(bir);
                  if (str.equals(""))
                  {
                        ci.numericValue = -1;
                  }
                  else
                  {
                        try {
                              ci.numericValue = Integer.parseInt(str, 10);
                              if (ci.numericValue < 0)
                                    ci.numericValue = -2;
                        } 
                        catch (NumberFormatException e)
                        {
                              ci.numericValue = -2;
                        }
                  }
                  // 9 - Mirrored
                  getNext(bir);
                  // 10 - Unicode 1.0 name
                  getNext(bir);
                  // 11 - ISO 10646 comment field
                  getNext(bir);
                  // 12 - Upper case mapping
                  str = getNext(bir);
                  if (!str.equals(""))
                        ci.uppercase = Integer.parseInt(str, 16);
                  else 
                        ci.uppercase = ci.code;
                  // 13 - Lower case mapping
                  str = getNext(bir);
                  if (!str.equals(""))
                        ci.lowercase = Integer.parseInt(str, 16);
                  else 
                        ci.lowercase = ci.code;
                  // 14 - Title case mapping
                  str = getNext(bir);
                  if (!str.equals(""))
                        ci.titlecase = Integer.parseInt(str, 16);
                  else 
                        ci.titlecase = ci.code;

                  // Character.digit() only treats "Nd" as decimal digits, not "No" 
                  // or "Nl".  Tweak the character defns accordingly.
                  if (ci.digit != -1 && !("Nd".equals(ci.category))) 
                        ci.digit = -1;

                  //test the char
                  testChar(ci);
            }


            // Fill in the character ranges that are reserved in Unicode 3.0
            CharInfo ch = new CharInfo();
            ch.name = "CJK Ideograph";
            ch.category = "Lo";
            ch.decimalDigit = -1;
            ch.digit = -1;
            ch.numericValue = -1;
            for (int i = 0x4E01; i <= 0x9FA4; i++)
            {
                  ch.code = i;
                  testChar(ch);
            }

            ch = new CharInfo();
            ch.name = "CJK Ideograph Extension A";
            ch.category = "Lo";
            ch.decimalDigit = -1;
            ch.digit = -1;
            ch.numericValue = -1;
            for (int i = 0x3400; i <= 0x4DB5; i++)
            {
                  ch.code = i;
                  testChar(ch);
            }

            ch = new CharInfo();
            ch.name = "Hangul Syllable";
            ch.category = "Lo";
            ch.decimalDigit = -1;
            ch.digit = -1;
            ch.numericValue = -1;
            for (int i = 0xAC01; i <= 0xD7A2; i++)
            {
                  ch.code = i;
                  testChar(ch);
            }

            ch = new CharInfo();
            ch.name = "CJK Compatibility Ideograph";
            ch.category = "Lo";
            ch.decimalDigit = -1;
            ch.digit = -1;
            ch.numericValue = -1;
            for (int i = 0xF901; i <= 0xFA2C; i++)
            {
                  ch.code = i;
                  testChar(ch);
            }

            ch = new CharInfo();
            ch.name = "Surrogate";
            ch.category= "Cs";
            ch.decimalDigit = -1;
            ch.digit = -1;
            ch.numericValue = -1;
            for (int i = 0xD800; i <= 0xDFFFl; i++)
            {
                  ch.code = i;
                  testChar(ch);
            }

            ch = new CharInfo();
            ch.name = "Private Use";
            ch.category = "Co";
            ch.decimalDigit = -1;
            ch.digit = -1;
            ch.numericValue = -1;
            for (int i = 0xE000; i <= 0xF8FF; i++)
            {
                  ch.code = i;
                  testChar(ch);
            }
      }

      private void testChar(CharInfo c){

            //All the checkPassed() calls are commented out since if they're
            //included, this creates too many getStackTrace() calls in
            //RunnerProcess.java, resulting in the heap running out of memory.
            
            // isLowerCase
            //char i = (char) x;
            if ("Ll".equals(c.category) != Character.isLowerCase( c.code))
            {
                  reportError(c,
                              (Character.isLowerCase(c.code) ? "lowercase" :
                              "not-lowercase"));

            }
            //else checkPassed();

            // isUpperCase
            if ("Lu".equals(c.category) != Character.isUpperCase(c.code))
            {
                  reportError(c,
                              (Character.isUpperCase((char) c.code) ? "uppercase" :
                              "not-uppercase"));
            }
            //else checkPassed();

            // isTitleCase
            if ( "Lt".equals(c.category) !=
                  Character.isTitleCase(c.code))
            {
                  reportError(c,
                              (Character.isTitleCase((char) c.code) ? "titlecase" :
                              "not-titlecase"));
            }
            //else checkPassed();

            // isDigit
            if ("Nd".equals(c.category) != Character.isDigit(c.code))
            {
                  reportError(c,
                              (Character.isDigit((char) c.code) ? "digit" : "not-digit"));
            }
            //else checkPassed();

            // isDefined
            if (!c.category.equals("Cn") != Character.isDefined(c.code))
            {
                  reportError(c,
                              (Character.isDefined((char) c.code) ? "defined" : 
                              "not-defined"));
            }
            //else checkPassed();

            // isLetter
            if ((c.category.charAt(0) == 'L') != 
                  Character.isLetter(c.code))
            {
                  reportError(c,
                              (Character.isLetter((char) c.code) ? "letter" : 
                              "not-letter"));
            }
            //else checkPassed();

            // isLetterOrDigit
            if (Character.isLetterOrDigit(c.code) !=
                  (Character.isLetter(c.code) || Character.isDigit(c.code)))
            {
                  reportError(c,
                              (Character.isLetterOrDigit(c.code) ? "letterordigit" :
                              "not-letterordigit"));
            }
            //else checkPassed();

            // isSpaceChar
            if ((c.category.charAt(0) == 'Z') != Character.isSpaceChar(c.code))
            {
                  reportError(c,
                              (Character.isSpaceChar(c.code) ? "spacechar" : 
                              "not-spacechar"));
            }
            //else checkPassed();

            // isWhiteSpace
            if (whitespace(c) != Character.isWhitespace(c.code))
            {
                  reportError(c,
                              Character.isWhitespace(c.code) ? "whitespace" : 
                  "not-whitespace");
            }
            //else checkPassed();

            // isISOControl
            if (((c.code <= 0x001F) || range(c.code, 0x007F, 0x009F)) !=
                  Character.isISOControl(c.code))
            {
                  reportError(c,
                              Character.isISOControl(c.code) ? "isocontrol" :
                  "not-isocontrol");
            }
            //else checkPassed();

            int type = Character.getType(c.code);
            String typeStr = null;
            switch (type)
            {
            case Character.UNASSIGNED: typeStr = "Cn"; break;
            case Character.UPPERCASE_LETTER: typeStr = "Lu"; break;
            case Character.LOWERCASE_LETTER: typeStr = "Ll"; break;
            case Character.TITLECASE_LETTER: typeStr = "Lt"; break;
            case Character.MODIFIER_LETTER: typeStr = "Lm"; break;
            case Character.OTHER_LETTER: typeStr = "Lo"; break;
            case Character.NON_SPACING_MARK: typeStr = "Mn"; break;
            case Character.ENCLOSING_MARK: typeStr = "Me"; break;
            case Character.COMBINING_SPACING_MARK: typeStr = "Mc"; break;
            case Character.DECIMAL_DIGIT_NUMBER: typeStr = "Nd"; break;
            case Character.LETTER_NUMBER: typeStr = "Nl"; break;
            case Character.OTHER_NUMBER: typeStr = "No"; break;
            case Character.SPACE_SEPARATOR: typeStr = "Zs"; break;
            case Character.LINE_SEPARATOR: typeStr = "Zl"; break;
            case Character.PARAGRAPH_SEPARATOR: typeStr = "Zp"; break;
            case Character.CONTROL: typeStr = "Cc"; break;
            case Character.FORMAT: typeStr = "Cf"; break;
            case Character.PRIVATE_USE: typeStr = "Co"; break;
            case Character.SURROGATE: typeStr = "Cs"; break;
            case Character.DASH_PUNCTUATION: typeStr = "Pd"; break;
            case Character.START_PUNCTUATION: typeStr = "Ps"; break;
            case Character.END_PUNCTUATION: typeStr = "Pe"; break;
            case Character.CONNECTOR_PUNCTUATION: typeStr = "Pc"; break;
            case Character.FINAL_QUOTE_PUNCTUATION: typeStr = "Pf"; break;
            case Character.INITIAL_QUOTE_PUNCTUATION: typeStr = "Pi"; break;
            case Character.OTHER_PUNCTUATION: typeStr = "Po"; break;
            case Character.MATH_SYMBOL: typeStr = "Sm"; break;
            case Character.CURRENCY_SYMBOL: typeStr = "Sc"; break;
            case Character.MODIFIER_SYMBOL: typeStr = "Sk"; break;
            case Character.OTHER_SYMBOL: typeStr = "So"; break;
            default: typeStr = "ERROR (" + type + ")"; break;
            }

            if (!(c.category.equals(typeStr) ||
                        (typeStr.equals("Ps") && c.category.equals("Pi")) ||
                        (typeStr.equals("Pe") && c.category.equals("Pf"))))
            {
                  reportError(stringChar(c) + " is reported to be type " + typeStr +
                              " instead of " + c.category);
            }
            //else checkPassed();

            // isJavaIdentifierStart
            if (identifierStart(c) != Character.isJavaIdentifierStart(c.code))
            {
                  reportError(c,
                              Character.isJavaIdentifierStart(c.code) ?
                                          "javaindentifierstart" : "not-javaidentifierstart");
            }
            //else checkPassed();

            // isJavaIdentifierPart
            typeStr = c.category;
            if ((typeStr.charAt(0) == 'L' ||
                        typeStr.equals("Sc") ||
                        typeStr.equals("Pc") ||
                        typeStr.equals("Nd") ||
                        typeStr.equals("Nl") ||
                        typeStr.equals("Mc") ||
                        typeStr.equals("Mn") ||
                        typeStr.equals("Cf") ||
                        (typeStr.equals("Cc") && ignorable(c))) != 
                              Character.isJavaIdentifierPart(c.code))
            {
                  reportError(c,
                              Character.isJavaIdentifierPart(c.code) ? 
                                          "javaidentifierpart" : "not-javaidentifierpart");
            }
            //else checkPassed();

            //isUnicodeIdentifierStart
            if (unicodeIdentifierStart(c) != Character.isUnicodeIdentifierStart(c.code))
            {
                  reportError(c,
                              Character.isUnicodeIdentifierStart(c.code) ? 
                                          "unicodeidentifierstart" : 
                  "not-unicodeidentifierstart");
            }
            //else checkPassed();

            //isUnicodeIdentifierPart;
            typeStr = c.category;
            if ((typeStr.charAt(0) == 'L' ||
                        typeStr.equals("Pc") ||
                        typeStr.equals("Nd") ||
                        typeStr.equals("Nl") ||
                        typeStr.equals("Mc") ||
                        typeStr.equals("Mn") ||
                        typeStr.equals("Cf") ||
                        (typeStr.equals("Cc") && ignorable(c))) != 
                              Character.isUnicodeIdentifierPart(c.code))
            {
                  reportError(c,
                              Character.isUnicodeIdentifierPart(c.code) ?
                                          "unicodeidentifierpart" : "not-unicodeidentifierpart");
            }
            //else checkPassed();


            //isIdentifierIgnorable
            if (ignorable(c) != Character.isIdentifierIgnorable(c.code))
            {
                  reportError(c,
                              Character.isIdentifierIgnorable(c.code) ? 
                                          "identifierignorable": "not-identifierignorable");
            }
            //else checkPassed();


            // toLowerCase
            int lowerCase = (c.lowercase != 0 ?
                        c.lowercase : c.code);
            if (Character.toLowerCase(c.code) != lowerCase)
            {
                  reportError(stringChar(c) + " has wrong lowercase form of " +
                              c.lowercase +" instead of " +
                              stringChar(c));
            }
            //else checkPassed();

            // toUpperCase

            int upperCase = (c.uppercase != 0 ?
                        c.uppercase : c.code);
            if (Character.toUpperCase(c.code) != upperCase)
            {
                  reportError(stringChar(c) +
                              " has wrong uppercase form of " +
                              c.uppercase +
                              " instead of " +
                              stringChar(c));
            }
            //else checkPassed();

            // toTitleCase
            int titleCase = (c.titlecase != 0 ? c.titlecase :
                  (c.uppercase != 0 ? 
                              c.uppercase : c.code));
            if ("Lt".equals(c.category))
            {
                  titleCase = c.code;
            }

            if (Character.toTitleCase(c.code) != titleCase)
            {
                  reportError(stringChar(c) +
                              " has wrong titlecase form of " +
                              c.titlecase +
                              " instead of " + 
                              stringChar(c));
            }
            //else checkPassed();

            // digit
            boolean radixPassed = true;
            for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX;
            radix++)
            {
                  //special cases for A-Za-z and their fullwidth counterparts
                  if (range(c.code,'A','Z')){
                        c.digit = c.code - 'A' + 10;
                  } 
                  else if (range(c.code,'a','z')){
                        c.digit = c.code - 'a' + 10;
                  } 
                  else if (range(c.code,0xff21,0xff3a)){
                        c.digit = c.code - 0xff21 + 10;
                  } 
                  else if (range(c.code,0xff41,0xff5a)){
                        c.digit = c.code - 0xff41 + 10;
                  }
                  int digit = c.digit;
                  if (digit >= radix) 
                        digit = -1;
                  if (Character.digit( c.code, radix) != digit)
                  {
                        reportError(stringChar(c) + " has wrong digit form of " +
                                    Character.digit(c.code, radix) + " for radix " + 
                                    radix + " instead of " + digit +
                                    "(" + c.digit + ")");
                        radixPassed = false;
                  }
                  //else checkPassed();
            }
            if (radixPassed)
                  checkPassed();


            // getNumericValue

            if (range(c.code,'A','Z') || range(c.code,'a','z')
                        || range(c.code,0xff21,0xff3a) || range(c.code,0xff41,0xff5a)){
                  if(c.numericValue != -1){
                        reportError(stringChar(c) + " has wrong numeric value of " +
                                    Character.getNumericValue(c.code) + " instead of -1");
                  }
            } else {

                  if (c.numericValue != Character.getNumericValue(c.code))
                  {
                        reportError(stringChar(c) + " has wrong numeric value of " +
                                    Character.getNumericValue(c.code) + " instead of " + 
                                    c.numericValue);
                  }

            }
            if (testDeprecated)
            {

                  // isJavaLetter
                  if (((char) c.code == '$' || (char) c.code == '_' 
                        || Character.isLetter(c.code)) !=   Character.isJavaLetter((char) c.code))
                  {
                        reportError(c,
                                    (Character.isJavaLetter((char) c.code)? "javaletter" : 
                                    "not-javaletter"));
                  }
                  //else checkPassed();

                  // isJavaLetterOrDigit
                  if ((Character.isJavaLetter((char) c.code) || Character.isDigit(c.code) ||
                              (char) c.code == '$' || (char) c.code == '_') !=
                                    Character.isJavaLetterOrDigit((char) c.code)
                  )
                  {
                        reportError(c,
                                    (Character.isJavaLetterOrDigit((char) c.code) ?
                                                "javaletterordigit" : "not-javaletterordigit"));
                  }
                  //else checkPassed();

                  // isSpace
                  if ((((char) c.code == ' ' || (char) c.code == '\t' 
                        || (char) c.code == '\n' || (char) c.code == '\r' ||
                        (char) c.code == '\f')) != Character.isSpace((char) c.code))
                  {
                        reportError(c,
                                    (Character.isSpace((char) c.code) ? "space" : "non-space"));
                  }
                  //else checkPassed();
            } // testDeprecated


      }

      protected void reportError(CharInfo c, String what)
      {
            harness.check(false, stringChar(c) +" incorrectly reported as " + what);
      }
      protected void reportError( String what)
      {
            harness.check(false, what);
      }
      protected void checkPassed()
      {
            harness.check(true);
      }

      public boolean range(int mid, int low, int high)
      {
            return (mid >= low && mid <= high);
      }

      public boolean whitespace(CharInfo c) 
      {
            return ((c.category.charAt(0) == 'Z' && 
                        c.code != 0x00a0 && c.code != 0x2007 && c.code != 0x202f) ||
                        range(c.code, 0x0009, 0x000D) || 
                        range(c.code, 0x001C, 0x001F));
      }

      //public String stringChar(int ch)
      public String stringChar(CharInfo c)
      {
            //return "Character " + Integer.toString(c.code,16) + ":"
            return "Character " + c.code + ":"
            + (char) c.code + ":" + c.name;
      }

      public boolean identifierStart(CharInfo c) 
      {
            return ("Ll".equals(c.category) || 
                        "Lu".equals(c.category) || 
                        "Lt".equals(c.category) || 
                        "Lm".equals(c.category) || 
                        "Lo".equals(c.category) || 
                        "Nl".equals(c.category) || 
                        "Sc".equals(c.category) || 
                        "Pc".equals(c.category));
      }

      public boolean unicodeIdentifierStart(CharInfo c) 
      {
            return ("Ll".equals(c.category) || 
                        "Lu".equals(c.category) || 
                        "Lt".equals(c.category) || 
                        "Lm".equals(c.category) || 

                        "Lo".equals(c.category) || 
                        "Nl".equals(c.category));
      }

      public boolean ignorable(CharInfo c)
      {
            return (range(c.code, 0x0000, 0x0008) ||
                        range(c.code, 0x000E, 0x001B) ||
                        range(c.code, 0x007f, 0x009f) ||
                        "Cf".equals(c.category));
      }
}

Generated by  Doxygen 1.6.0   Back to index