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");
|