< prev index next >

make/jdk/src/classes/build/tools/generatecharacter/PrintCharacterRanges.java

Print this page


   1 /*
   2  * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  28 import java.lang.reflect.*;
  29 import java.util.*;
  30 
  31 /** Recovers and prints ranges for certain java.lang.Character
  32     properties. Useful for generating fast-path Latin-1 code. */
  33 
  34 public class PrintCharacterRanges {
  35   static class BooleanRange {
  36     private int begin;
  37     private int end;
  38 
  39     BooleanRange(int begin, int end) {
  40       this.begin = begin;
  41       this.end   = end;
  42     }
  43 
  44     int begin() { return begin; }
  45     int end()   { return end;   }
  46   }
  47 
  48   private static List/*<BooleanRange>*/ recoverBooleanRanges(String methodName) throws Exception {
  49     List result = new ArrayList();
  50     int currentRangeStart = -1;
  51     Method method = Character.class.getDeclaredMethod(methodName, new Class[] { Character.TYPE });
  52     if (method == null) {
  53       throw new RuntimeException("No method \"" + methodName + "\"(C) found");
  54     }
  55 
  56     for (int i = 0; i <= 255; i++) {
  57       boolean methodRes = ((Boolean) method.invoke(null, new Object[] { new Character((char) i) })).booleanValue();
  58       if (methodRes) {
  59         if (currentRangeStart < 0) {
  60           currentRangeStart = i;
  61         }
  62         if (i == 255) {
  63           result.add(new BooleanRange(currentRangeStart, i));
  64         }
  65       } else {
  66         if (currentRangeStart >= 0) {
  67           result.add(new BooleanRange(currentRangeStart, i - 1));
  68           currentRangeStart = -1;
  69         }
  70       }
  71     }
  72 
  73     return result;
  74   }
  75 
  76   private static String describe(int num) {
  77     StringBuffer s = new StringBuffer();
  78     s.append(num);
  79     s.append(" ('");
  80     if (num > 32 && num < 123) {
  81       s.append((char) num);
  82     } else {
  83       s.append("\\u");
  84       String hex = Long.toHexString(num).toUpperCase();
  85       for (int i = 0; i < (4 - hex.length()); i++) {
  86         s.append('0');
  87       }
  88       s.append(hex);
  89     }
  90     s.append("')");
  91     return s.toString();
  92   }
  93 
  94   private static void printBooleanRanges(List/*<BooleanRange>*/ ranges, String methodName) {
  95     System.out.print(methodName + ":");
  96     for (Iterator iter = ranges.iterator(); iter.hasNext();) {
  97       BooleanRange range = (BooleanRange) iter.next();
  98       System.out.print(" [ " + describe(range.begin()) + ", " + describe(range.end()) + " ]");
  99     }
 100     System.out.println("");
 101   }
 102 
 103   private static void recoverAndPrintBooleanRanges(String methodName) throws Exception {
 104     List ranges = recoverBooleanRanges(methodName);
 105     printBooleanRanges(ranges, methodName);
 106   }
 107 
 108   static class ShiftRange {
 109     private int begin;
 110     private int end;
 111     private int offset;
 112 
 113     ShiftRange(int begin, int end, int offset) {
 114       this.begin  = begin;
 115       this.end    = end;
 116       this.offset = offset;
 117     }
 118 
 119     int begin()  { return begin;  }
 120     int end()    { return end;    }
 121     int offset() { return offset; }
 122   }
 123 
 124   private static List/*<ShiftRange>*/ recoverShiftRanges(String methodName) throws Exception {
 125     List result = new ArrayList();
 126     int currentRangeStart = -1;
 127     int currentRangeOffset = -1;
 128     Method method = Character.class.getDeclaredMethod(methodName, new Class[] { Character.TYPE });
 129     if (method == null) {
 130       throw new RuntimeException("No method \"" + methodName + "\"(C) found");
 131     }
 132 
 133     for (int i = 0; i <= 255; i++) {
 134       char methodRes = ((Character) method.invoke(null, new Object[] { new Character((char) i) })).charValue();
 135       if (methodRes != i) {
 136         int offset = methodRes - i;
 137         if (currentRangeStart < 0) {
 138           currentRangeStart = i;
 139         } else if (offset != currentRangeOffset) {
 140           result.add(new ShiftRange(currentRangeStart, i - 1, currentRangeOffset));
 141           currentRangeStart = i;
 142         }
 143         currentRangeOffset = offset;
 144         if (i == 255) {
 145           result.add(new ShiftRange(currentRangeStart, i, currentRangeOffset));
 146         }
 147       } else {
 148         if (currentRangeStart >= 0) {
 149           result.add(new ShiftRange(currentRangeStart, i - 1, currentRangeOffset));
 150           currentRangeStart = -1;
 151         }
 152       }
 153     }
 154 
 155     return result;
 156   }
 157 
 158   private static void printShiftRanges(List/*<ShiftRange>*/ ranges, String methodName) {
 159     System.out.print(methodName + ":");
 160     boolean isFirst = true;
 161     for (Iterator iter = ranges.iterator(); iter.hasNext();) {
 162       ShiftRange range = (ShiftRange) iter.next();
 163       if (isFirst) {
 164         isFirst = false;
 165       } else {
 166         System.out.print(", ");
 167       }
 168       System.out.print(" [ " + describe(range.begin()) + ", " + describe(range.end()) + " ] -> [ " +
 169                        describe((range.begin() + range.offset())) + ", " + describe((range.end() + range.offset())) + " ] (" +
 170                        range.offset() + ")");
 171     }
 172     System.out.println("");
 173   }
 174 
 175   private static void recoverAndPrintShiftRanges(String methodName) throws Exception {
 176     List ranges = recoverShiftRanges(methodName);
 177     printShiftRanges(ranges, methodName);
 178   }
 179 
 180   public static void main(String[] args) {
 181     try {
 182       recoverAndPrintBooleanRanges("isDefined");
 183       recoverAndPrintBooleanRanges("isDigit");
 184       recoverAndPrintBooleanRanges("isIdentifierIgnorable");
 185       recoverAndPrintBooleanRanges("isISOControl");
 186       recoverAndPrintBooleanRanges("isJavaIdentifierPart");
 187       recoverAndPrintBooleanRanges("isJavaIdentifierStart");
 188       recoverAndPrintBooleanRanges("isLetter");
 189       recoverAndPrintBooleanRanges("isLetterOrDigit");
 190       recoverAndPrintBooleanRanges("isLowerCase");
 191       recoverAndPrintBooleanRanges("isMirrored");
 192       recoverAndPrintBooleanRanges("isSpaceChar");
 193       recoverAndPrintBooleanRanges("isTitleCase");
 194       recoverAndPrintBooleanRanges("isUnicodeIdentifierPart");
 195       recoverAndPrintBooleanRanges("isUnicodeIdentifierStart");
 196       recoverAndPrintBooleanRanges("isUpperCase");
   1 /*
   2  * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  28 import java.lang.reflect.*;
  29 import java.util.*;
  30 
  31 /** Recovers and prints ranges for certain java.lang.Character
  32     properties. Useful for generating fast-path Latin-1 code. */
  33 
  34 public class PrintCharacterRanges {
  35   static class BooleanRange {
  36     private int begin;
  37     private int end;
  38 
  39     BooleanRange(int begin, int end) {
  40       this.begin = begin;
  41       this.end   = end;
  42     }
  43 
  44     int begin() { return begin; }
  45     int end()   { return end;   }
  46   }
  47 
  48   private static List<BooleanRange> recoverBooleanRanges(String methodName) throws Exception {
  49     List<BooleanRange> result = new ArrayList<>();
  50     int currentRangeStart = -1;
  51     Method method = Character.class.getDeclaredMethod(methodName, new Class<?>[] { Character.TYPE });
  52     if (method == null) {
  53       throw new RuntimeException("No method \"" + methodName + "\"(C) found");
  54     }
  55 
  56     for (int i = 0; i <= 255; i++) {
  57       boolean methodRes = ((Boolean) method.invoke(null, new Object[] { Character.valueOf((char) i) })).booleanValue();
  58       if (methodRes) {
  59         if (currentRangeStart < 0) {
  60           currentRangeStart = i;
  61         }
  62         if (i == 255) {
  63           result.add(new BooleanRange(currentRangeStart, i));
  64         }
  65       } else {
  66         if (currentRangeStart >= 0) {
  67           result.add(new BooleanRange(currentRangeStart, i - 1));
  68           currentRangeStart = -1;
  69         }
  70       }
  71     }
  72 
  73     return result;
  74   }
  75 
  76   private static String describe(int num) {
  77     StringBuffer s = new StringBuffer();
  78     s.append(num);
  79     s.append(" ('");
  80     if (num > 32 && num < 123) {
  81       s.append((char) num);
  82     } else {
  83       s.append("\\u");
  84       String hex = Long.toHexString(num).toUpperCase();
  85       for (int i = 0; i < (4 - hex.length()); i++) {
  86         s.append('0');
  87       }
  88       s.append(hex);
  89     }
  90     s.append("')");
  91     return s.toString();
  92   }
  93 
  94   private static void printBooleanRanges(List<BooleanRange> ranges, String methodName) {
  95     System.out.print(methodName + ":");
  96     for (Iterator<BooleanRange> iter = ranges.iterator(); iter.hasNext();) {
  97       BooleanRange range = iter.next();
  98       System.out.print(" [ " + describe(range.begin()) + ", " + describe(range.end()) + " ]");
  99     }
 100     System.out.println("");
 101   }
 102 
 103   private static void recoverAndPrintBooleanRanges(String methodName) throws Exception {
 104     List<BooleanRange> ranges = recoverBooleanRanges(methodName);
 105     printBooleanRanges(ranges, methodName);
 106   }
 107 
 108   static class ShiftRange {
 109     private int begin;
 110     private int end;
 111     private int offset;
 112 
 113     ShiftRange(int begin, int end, int offset) {
 114       this.begin  = begin;
 115       this.end    = end;
 116       this.offset = offset;
 117     }
 118 
 119     int begin()  { return begin;  }
 120     int end()    { return end;    }
 121     int offset() { return offset; }
 122   }
 123 
 124   private static List<ShiftRange> recoverShiftRanges(String methodName) throws Exception {
 125     List<ShiftRange> result = new ArrayList<>();
 126     int currentRangeStart = -1;
 127     int currentRangeOffset = -1;
 128     Method method = Character.class.getDeclaredMethod(methodName, new Class<?>[] { Character.TYPE });
 129     if (method == null) {
 130       throw new RuntimeException("No method \"" + methodName + "\"(C) found");
 131     }
 132 
 133     for (int i = 0; i <= 255; i++) {
 134       char methodRes = ((Character) method.invoke(null, new Object[] { Character.valueOf((char) i) })).charValue();
 135       if (methodRes != i) {
 136         int offset = methodRes - i;
 137         if (currentRangeStart < 0) {
 138           currentRangeStart = i;
 139         } else if (offset != currentRangeOffset) {
 140           result.add(new ShiftRange(currentRangeStart, i - 1, currentRangeOffset));
 141           currentRangeStart = i;
 142         }
 143         currentRangeOffset = offset;
 144         if (i == 255) {
 145           result.add(new ShiftRange(currentRangeStart, i, currentRangeOffset));
 146         }
 147       } else {
 148         if (currentRangeStart >= 0) {
 149           result.add(new ShiftRange(currentRangeStart, i - 1, currentRangeOffset));
 150           currentRangeStart = -1;
 151         }
 152       }
 153     }
 154 
 155     return result;
 156   }
 157 
 158   private static void printShiftRanges(List<ShiftRange> ranges, String methodName) {
 159     System.out.print(methodName + ":");
 160     boolean isFirst = true;
 161     for (Iterator<ShiftRange> iter = ranges.iterator(); iter.hasNext();) {
 162       ShiftRange range = iter.next();
 163       if (isFirst) {
 164         isFirst = false;
 165       } else {
 166         System.out.print(", ");
 167       }
 168       System.out.print(" [ " + describe(range.begin()) + ", " + describe(range.end()) + " ] -> [ " +
 169                        describe((range.begin() + range.offset())) + ", " + describe((range.end() + range.offset())) + " ] (" +
 170                        range.offset() + ")");
 171     }
 172     System.out.println("");
 173   }
 174 
 175   private static void recoverAndPrintShiftRanges(String methodName) throws Exception {
 176     List<ShiftRange> ranges = recoverShiftRanges(methodName);
 177     printShiftRanges(ranges, methodName);
 178   }
 179 
 180   public static void main(String[] args) {
 181     try {
 182       recoverAndPrintBooleanRanges("isDefined");
 183       recoverAndPrintBooleanRanges("isDigit");
 184       recoverAndPrintBooleanRanges("isIdentifierIgnorable");
 185       recoverAndPrintBooleanRanges("isISOControl");
 186       recoverAndPrintBooleanRanges("isJavaIdentifierPart");
 187       recoverAndPrintBooleanRanges("isJavaIdentifierStart");
 188       recoverAndPrintBooleanRanges("isLetter");
 189       recoverAndPrintBooleanRanges("isLetterOrDigit");
 190       recoverAndPrintBooleanRanges("isLowerCase");
 191       recoverAndPrintBooleanRanges("isMirrored");
 192       recoverAndPrintBooleanRanges("isSpaceChar");
 193       recoverAndPrintBooleanRanges("isTitleCase");
 194       recoverAndPrintBooleanRanges("isUnicodeIdentifierPart");
 195       recoverAndPrintBooleanRanges("isUnicodeIdentifierStart");
 196       recoverAndPrintBooleanRanges("isUpperCase");
< prev index next >