1 /* 2 * Copyright (c) 2009, 2015, 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 23 * questions. 24 */ 25 26 package build.tools.charsetmapping; 27 28 import java.io.*; 29 import java.util.ArrayList; 30 import java.util.Scanner; 31 import java.util.LinkedHashMap; 32 import java.util.Locale; 33 34 public class Main { 35 36 public static void main(String args[]) throws Throwable { 37 int SRC_DIR = 0; 38 int DST_DIR = 1; 39 int TYPE = 2; 40 int CHARSETS = 3; 41 int OS = 4; 42 int TEMPLATE = 5; 43 int EXT_SRC = 6; 44 45 if (args.length < 3 ) { 46 System.out.println("Usage: java -jar charsetmapping.jar src dst spiType charsets os [template]"); 47 System.exit(1); 48 } 49 boolean isStandard = "stdcs".equals(args[TYPE]); 50 boolean isExtended = "extcs".equals(args[TYPE]); 51 if (isStandard || isExtended) { 52 LinkedHashMap<String, Charset> charsets = getCharsets( 53 new File(args[SRC_DIR], args[CHARSETS])); 54 String[] osStdcs = getOSStdCSList(new File(args[SRC_DIR], args[OS])); 55 boolean hasBig5_HKSCS = false; 56 boolean hasMS950_HKSCS_XP = false; 57 for (String name : osStdcs) { 58 Charset cs = charsets.get(name); 59 if (cs != null) { 60 cs.pkgName = "sun.nio.cs"; 61 } 62 if (name.equals("Big5_HKSCS")) { 63 hasBig5_HKSCS = true; 64 } else if (name.equals("MS950_HKSCS_XP")) { 65 hasMS950_HKSCS_XP = true; 66 } 67 } 68 for (Charset cs : charsets.values()) { 69 if (isStandard && cs.pkgName.equals("sun.nio.cs.ext") || 70 isExtended && cs.pkgName.equals("sun.nio.cs")) { 71 continue; 72 } 73 verbose(cs); 74 switch (cs.type) { 75 case "template": 76 SRC.genClass(cs, args[EXT_SRC], args[DST_DIR]); 77 break; 78 case "sbcs": 79 SBCS.genClass(cs, args[SRC_DIR], args[DST_DIR], 80 "SingleByte-X.java.template"); 81 break; 82 case "source": 83 break; // source file, do nothing 84 default: // dbcs 85 DBCS.genClass("dbcs".equals(cs.type) ? 86 "" : "_" + cs.type.toUpperCase(Locale.ENGLISH), 87 cs, args[SRC_DIR], args[DST_DIR], 88 "DoubleByte-X.java.template"); 89 } 90 } 91 // provider StandardCharsets.java / ExtendedCharsets.java 92 SPI.genClass(args[TYPE], charsets, args[SRC_DIR], args[DST_DIR], args[TEMPLATE]); 93 94 // HKSCSMapping2008/XP.java goes together with Big5/MS950XP_HKSCS 95 if (isStandard && hasBig5_HKSCS || isExtended && !hasBig5_HKSCS) { 96 HKSCS.genClass2008(args[SRC_DIR], args[DST_DIR], 97 isStandard ? "sun.nio.cs" : "sun.nio.cs.ext"); 98 } 99 if (isStandard && hasMS950_HKSCS_XP || isExtended && !hasMS950_HKSCS_XP) { 100 HKSCS.genClassXP(args[SRC_DIR], args[DST_DIR], 101 isStandard ? "sun.nio.cs" : "sun.nio.cs.ext"); 102 } 103 } else if ("euctw".equals(args[TYPE])) { 104 EUC_TW.genClass(args); 105 } else if ("sjis0213".equals(args[TYPE])) { 106 JIS0213.genClass(args); 107 } else if ("hkscs".equals(args[TYPE])) { 108 HKSCS.genClass2001(args); 109 } 110 } 111 112 private static LinkedHashMap<String, Charset> getCharsets(File cslist) 113 throws Throwable 114 { 115 LinkedHashMap<String, Charset> charsets = new LinkedHashMap<>(); 116 try (Scanner s = new Scanner(cslist)) { 117 Charset cs = null; 118 ArrayList<String> names = new ArrayList<>(); 119 while (s.hasNextLine()) { 120 String line = s.nextLine(); 121 if (line.startsWith("#") || line.length() == 0) { 122 continue; 123 } 124 String[] tokens = line.split("\\s+"); 125 if (tokens.length < 2) { 126 continue; 127 } 128 if ("charset".equals(tokens[0])) { 129 if (cs != null) { 130 cs.aliases = names.toArray(new String[names.size()]); 131 charsets.put(cs.clzName, cs); 132 cs = null; 133 names.clear(); 134 } 135 if (tokens.length < 3) { 136 throw new RuntimeException("Error: incorrect charset line [" + line + "]"); 137 } 138 if ((cs = charsets.get(tokens[2])) != null) { 139 throw new RuntimeException("Error: deplicate charset line [" + line + "]"); 140 } 141 cs = new Charset(); 142 cs.csName = tokens[1]; 143 cs.clzName = tokens[2]; 144 } else { 145 String key = tokens[1]; // leading empty str 146 switch (key) { 147 case "alias": 148 if (tokens.length < 3) { 149 throw new RuntimeException("Error: incorrect alias line [" + line + "]"); 150 } else if (names != null) { 151 names.add(tokens[2]); // ALIAS_NAME 152 } 153 break; 154 case "package": 155 cs.pkgName = tokens[2]; 156 break; 157 case "type": 158 cs.type = tokens[2]; 159 break; 160 case "hisname": 161 cs.hisName = tokens[2]; 162 break; 163 case "ascii": 164 cs.isASCII = Boolean.parseBoolean(tokens[2]); 165 break; 166 case "minmax": 167 cs.b1Min = toInteger(tokens[2]); 168 cs.b1Max = toInteger(tokens[3]); 169 cs.b2Min = toInteger(tokens[4]); 170 cs.b2Max = toInteger(tokens[5]); 171 break; 172 case "internal": 173 cs.isInternal = Boolean.parseBoolean(tokens[2]); 174 break; 175 default: // ignore 176 } 177 } 178 } 179 if (cs != null) { 180 cs.aliases = names.toArray(new String[names.size()]); 181 charsets.put(cs.clzName, cs); 182 } 183 } 184 return charsets; 185 } 186 187 private static String[] getOSStdCSList(File stdcsos) throws Throwable 188 { 189 ArrayList<String> names = new ArrayList<>(); 190 if (stdcsos.exists()) { 191 try (Scanner s = new Scanner(stdcsos)) { 192 while (s.hasNextLine()) { 193 String line = s.nextLine(); 194 int i = line.indexOf('#'); 195 if (i != -1) { 196 line = line.substring(0, i); 197 } 198 line = line.trim(); 199 if (line.length() != 0) { 200 names.add(line); 201 } 202 } 203 } 204 } 205 return names.toArray(new String[names.size()]); 206 } 207 208 static void verbose(Charset cs) { 209 System.err.printf("%s, %s, %s, %s, %s %b%n", 210 cs.clzName, cs.csName, cs.hisName, cs.pkgName, cs.type, cs.isASCII); 211 } 212 213 static int toInteger(String s) { 214 return (s.startsWith("0x") || s.startsWith("0X")) 215 ? Integer.valueOf(s.substring(2), 16) 216 : Integer.valueOf(s); 217 } 218 }