1 /* 2 * Copyright (c) 2009, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.openjdk.asmtools.jcoder; 24 25 import org.openjdk.asmtools.common.Tool; 26 import org.openjdk.asmtools.util.I18NResourceBundle; 27 import org.openjdk.asmtools.util.ProductInfo; 28 29 import java.io.*; 30 import java.util.ArrayList; 31 import java.util.HashMap; 32 33 /** 34 * 35 * 36 */ 37 public class Main extends Tool { 38 39 public static final I18NResourceBundle i18n 40 = I18NResourceBundle.getBundleForClass(Main.class); 41 42 public Main(PrintWriter out, String programName) { 43 super(out, programName); 44 printCannotReadMsg = (fname) -> error(i18n.getString("jcoder.error.cannot_read", fname)); 45 } 46 47 public Main(PrintStream out, String program) { 48 this(new PrintWriter(out), program); 49 } 50 51 @Override 52 public void usage() { 53 println(i18n.getString("jcoder.usage")); 54 println(i18n.getString("jcoder.opt.nowrite")); 55 println(i18n.getString("jcoder.opt.ignore")); 56 println(i18n.getString("jcoder.opt.d")); 57 println(i18n.getString("jcoder.opt.version")); 58 } 59 60 /** 61 * Run the compiler 62 */ 63 public synchronized boolean compile(String argv[]) { 64 File destDir = null; 65 boolean traceFlag = false; 66 DebugFlag = () -> false; 67 long tm = System.currentTimeMillis(); 68 ArrayList<String> v = new ArrayList<>(); 69 boolean nowrite = false; 70 boolean ignore = false; 71 int nwarnings = 0; 72 HashMap<String, String> macros = new HashMap<>(); 73 macros.put("VERSION", "3;45"); 74 75 // Parse arguments 76 for (int i = 0; i < argv.length; i++) { 77 String arg = argv[i]; 78 if (!arg.startsWith("-")) { 79 v.add(arg); 80 } else if (arg.startsWith("-D")) { 81 int argLength = arg.length(); 82 if (argLength == 2) { 83 error(i18n.getString("jcoder.error.D_needs_macro")); 84 return false; 85 } 86 int index = arg.indexOf('='); 87 if (index == -1) { 88 error(i18n.getString("jcoder.error.D_needs_macro")); 89 return false; 90 } 91 String macroId = arg.substring(2, index); 92 index++; 93 if (argLength == index) { 94 error(i18n.getString("jcoder.error.D_needs_macro")); 95 return false; 96 } 97 String macro; 98 if (arg.charAt(index) == '"') { 99 index++; 100 if (argLength == index || arg.charAt(argLength - 1) != '"') { 101 error(i18n.getString("jcoder.error.no_closing_quota")); 102 return false; 103 } 104 macro = arg.substring(index, argLength - 1); 105 } else { 106 macro = arg.substring(index, argLength); 107 } 108 macros.put(macroId, macro); 109 } else if (arg.equals("-vv")) { 110 DebugFlag = () -> true; 111 traceFlag = true; 112 } else if (arg.equals("-v")) { 113 traceFlag = true; 114 } else if (arg.equals("-nowrite")) { 115 nowrite = true; 116 } else if (arg.equals("-ignore")) { 117 ignore = true; 118 } else if (arg.equals("-d")) { 119 if ((i + 1) == argv.length) { 120 error(i18n.getString("jcoder.error.d_requires_argument")); 121 usage(); 122 return false; 123 } 124 destDir = new File(argv[++i]); 125 if (!destDir.exists()) { 126 error(i18n.getString("jcoder.error.does_not_exist", destDir)); 127 return false; 128 } 129 } else if (arg.equals("-version")) { 130 println(ProductInfo.FULL_VERSION); 131 } else { 132 error(i18n.getString("jcoder.error.invalid_option", arg)); 133 usage(); 134 return false; 135 } 136 } 137 if (v.isEmpty()) { 138 usage(); 139 return false; 140 } 141 // compile all input files 142 try { 143 for (String inpname : v) { 144 SourceFile env; 145 Jcoder p; 146 147 DataInputStream dataInputStream = getDataInputStream(inpname); 148 if( dataInputStream == null ) { 149 nerrors++; 150 continue; 151 } 152 env = new SourceFile(this, dataInputStream, inpname, out); 153 env.traceFlag = traceFlag; 154 env.debugInfoFlag = DebugFlag.getAsBoolean(); 155 p = new Jcoder(env, macros); 156 p.parseFile(); 157 env.traceln("END PARSER"); 158 env.closeInp(); 159 160 nerrors += env.nerrors; 161 nwarnings += env.nwarnings; 162 if (nowrite || (nerrors > 0 & !ignore)) { 163 continue; 164 } 165 try { 166 env.traceln("WRITE"); 167 p.write(destDir); 168 } catch (FileNotFoundException ex) { 169 error(i18n.getString("jcoder.error.cannot_write", ex.getMessage())); 170 } 171 } 172 } catch (Error ee) { 173 ee.printStackTrace(); 174 error(i18n.getString("jcoder.error.fatal_error")); 175 } catch (Exception ee) { 176 ee.printStackTrace(); 177 error(i18n.getString("jcoder.error.fatal_exception")); 178 } 179 180 boolean errs = nerrors > 0; 181 boolean warns = nwarnings > 0; 182 if (!errs && !warns) { 183 return true; 184 } 185 println(errs ? (nerrors > 1 ? (nerrors + " errors") : "1 error") 186 : "" + ((errs && warns) ? ", " : "") + (warns ? (nwarnings > 1 ? (nwarnings + " warnings") : "1 warning") : "")); 187 return !errs; 188 } 189 190 /** 191 * main program 192 */ 193 public static void main(String[] argv) { 194 Main compiler = new Main(new PrintWriter(System.out), "jcoder"); 195 System.exit(compiler.compile(argv) ? 0 : 1); 196 } 197 }