1 package com.thaiopensource.datatype.xsd.regex.test; 2 3 import com.thaiopensource.datatype.xsd.regex.Regex; 4 import com.thaiopensource.datatype.xsd.regex.RegexEngine; 5 import com.thaiopensource.datatype.xsd.regex.RegexSyntaxException; 6 import com.thaiopensource.util.Utf16; 7 import com.thaiopensource.util.Service; 8 9 import java.io.BufferedReader ; 10 import java.io.FileInputStream ; 11 import java.io.InputStreamReader ; 12 import java.io.IOException ; 13 import java.util.Enumeration ; 14 15 public class CategoryTest { 16 static private final String categories = "LMNPZSC"; 17 static private final String subCategories = "LuLlLtLmLoMnMcMeNdNlNoPcPdPsPePiPfPoZsZlZpSmScSkSoCcCfCoCn"; 18 19 private final Regex[] categoryPosRegexes = new Regex[categories.length()]; 20 private final Regex[] categoryNegRegexes = new Regex[categories.length()]; 21 private final Regex[] subCategoryPosRegexes = new Regex[subCategories.length()/2]; 22 private final Regex[] subCategoryNegRegexes = new Regex[subCategories.length()/2]; 23 24 static public void main(String [] args) throws IOException , RegexSyntaxException { 25 if (args.length != 2) { 26 System.err.println("usage: " + CategoryTest.class.getName() + " engineClass UnicodeData"); 27 System.exit(2); 28 } 29 BufferedReader r = new BufferedReader (new InputStreamReader (new FileInputStream (args[1]))); 30 Enumeration e = new Service(RegexEngine.class).getProviders(); 31 RegexEngine engine; 32 for (;;) { 33 if (!e.hasMoreElements()) { 34 System.err.println("couldn't find regex engine"); 35 System.exit(2); 36 } 37 engine = (RegexEngine)e.nextElement(); 38 if (engine.getClass().getName().equals(args[0])) 39 break; 40 } 41 int nFail = new CategoryTest(engine).testAll(r); 42 System.err.println(nFail + " tests failed"); 43 System.exit(nFail > 0 ? 1 : 0); 44 } 45 46 CategoryTest(RegexEngine engine) throws RegexSyntaxException { 47 for (int i = 0, len = categories.length(); i < len; i++) { 48 String ch = categories.substring(i, i + 1); 49 categoryPosRegexes[i] = engine.compile("\\p{" + ch + "}"); 50 categoryNegRegexes[i] = engine.compile("\\P{" + ch + "}"); 51 } 52 for (int i = 0, len = subCategories.length(); i < len; i += 2) { 53 String name = subCategories.substring(i, i + 2); 54 subCategoryPosRegexes[i/2] = engine.compile("\\p{" + name + "}"); 55 subCategoryNegRegexes[i/2] = engine.compile("\\P{" + name + "}"); 56 } 57 } 58 59 int testAll(BufferedReader r) throws IOException { 60 int lastCode = -1; 61 for (;;) { 62 String line = r.readLine(); 63 if (line == null) 64 break; 65 int semi = line.indexOf(';'); 66 if (semi < 0) 67 continue; 68 int code = Integer.parseInt(line.substring(0, semi), 16); 69 int semi2 = line.indexOf(';', semi + 1); 70 String name = line.substring(semi, semi2); 71 String category = line.substring(semi2 + 1, semi2 + 3); 72 if (lastCode + 1 != code) { 73 String missingCategory = name.endsWith(", Last>") ? category : "Cn"; 74 for (int i = lastCode + 1; i < code; i++) 75 test(i, missingCategory); 76 } 77 test(code, category); 78 lastCode = code; 79 } 80 for (++lastCode; lastCode < 0x110000; lastCode++) 81 test(lastCode, "Cn"); 82 return nFail; 83 } 84 85 void test(int ch, String category) { 86 if (!isXmlChar(ch)) 87 return; 88 if (subCategories.indexOf(category) < 0) { 89 System.err.println("Missing category: " + category); 90 System.exit(2); 91 } 92 for (int i = 0, len = categories.length(); i < len; i++) 93 check(ch, categoryPosRegexes[i], categoryNegRegexes[i], 94 category.charAt(0) == categories.charAt(i), 95 categories.substring(i, i + 1)); 96 for (int i = 0, len = subCategories.length(); i < len; i += 2) 97 check(ch, subCategoryPosRegexes[i/2], subCategoryNegRegexes[i/2], 98 category.equals(subCategories.substring(i, i + 2)), 99 subCategories.substring(i, i + 2)); 100 } 101 102 void check(int ch, Regex pos, Regex neg, boolean inPos, String cat) { 103 String str; 104 if (ch > 0xFFFF) 105 str = new String (new char[]{ Utf16.surrogate1(ch), Utf16.surrogate2(ch) }); 106 else 107 str = new String (new char[]{ (char)ch }); 108 if (pos.matches(str) != inPos ) 109 fail(ch, cat); 110 if (neg.matches(str) != !inPos) 111 fail(ch, "-" + cat); 112 } 113 114 int nFail = 0; 115 116 void fail(int ch, String cat) { 117 nFail++; 118 System.err.println("Failed: " + Integer.toHexString(ch) + "/" + cat); 119 } 120 121 static boolean isXmlChar(int code) { 122 switch (code) { 123 case '\r': case '\n': case '\t': 124 return true; 125 case 0xFFFE: case 0xFFFF: 126 return false; 127 default: 128 if (code < 0x20) 129 return false; 130 if (code >= 0xD800 && code < 0xE000) 131 return false; 132 return true; 133 } 134 } 135 } 136 | Popular Tags |