| /* |
| * Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Sun designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Sun in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| * CA 95054 USA or visit www.sun.com if you need additional information or |
| * have any questions. |
| */ |
| |
| package com.sun.tools.javac.main; |
| |
| import java.io.PrintWriter; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| import com.sun.tools.javac.util.Log; |
| import com.sun.tools.javac.util.Options; |
| |
| /** |
| * TODO: describe com.sun.tools.javac.main.JavacOption |
| * |
| * <p><b>This is NOT part of any API supported by Sun Microsystems. |
| * If you write code that depends on this, you do so at your own |
| * risk. This code and its internal interfaces are subject to change |
| * or deletion without notice.</b></p> |
| */ |
| public interface JavacOption { |
| |
| OptionKind getKind(); |
| |
| /** Does this option take a (separate) operand? |
| * @return true if this option takes a separate operand |
| */ |
| boolean hasArg(); |
| |
| /** Does argument string match option pattern? |
| * @param arg the command line argument string |
| * @return true if {@code arg} matches this option |
| */ |
| boolean matches(String arg); |
| |
| /** Process an option with an argument. |
| * @param options the accumulated set of analyzed options |
| * @param option the option to be processed |
| * @param arg the arg for the option to be processed |
| * @return true if an error was detected |
| */ |
| boolean process(Options options, String option, String arg); |
| |
| /** Process the option with no argument. |
| * @param options the accumulated set of analyzed options |
| * @param option the option to be processed |
| * @return true if an error was detected |
| */ |
| boolean process(Options options, String option); |
| |
| OptionName getName(); |
| |
| enum OptionKind { |
| NORMAL, |
| EXTENDED, |
| HIDDEN, |
| } |
| |
| enum ChoiceKind { |
| ONEOF, |
| ANYOF |
| } |
| |
| /** This class represents an option recognized by the main program |
| */ |
| static class Option implements JavacOption { |
| |
| /** Option string. |
| */ |
| OptionName name; |
| |
| /** Documentation key for arguments. |
| */ |
| String argsNameKey; |
| |
| /** Documentation key for description. |
| */ |
| String descrKey; |
| |
| /** Suffix option (-foo=bar or -foo:bar) |
| */ |
| boolean hasSuffix; |
| |
| /** The kind of choices for this option, if any. |
| */ |
| ChoiceKind choiceKind; |
| |
| /** The choices for this option, if any, and whether or not the choices |
| * are hidden |
| */ |
| Map<String,Boolean> choices; |
| |
| Option(OptionName name, String argsNameKey, String descrKey) { |
| this.name = name; |
| this.argsNameKey = argsNameKey; |
| this.descrKey = descrKey; |
| char lastChar = name.optionName.charAt(name.optionName.length()-1); |
| hasSuffix = lastChar == ':' || lastChar == '='; |
| } |
| |
| Option(OptionName name, String descrKey) { |
| this(name, null, descrKey); |
| } |
| |
| Option(OptionName name, String descrKey, ChoiceKind choiceKind, String... choices) { |
| this(name, descrKey, choiceKind, createChoices(choices)); |
| } |
| |
| private static Map<String,Boolean> createChoices(String... choices) { |
| Map<String,Boolean> map = new LinkedHashMap<String,Boolean>(); |
| for (String c: choices) |
| map.put(c, false); |
| return map; |
| } |
| |
| Option(OptionName name, String descrKey, ChoiceKind choiceKind, |
| Map<String,Boolean> choices) { |
| this(name, null, descrKey); |
| if (choiceKind == null || choices == null) |
| throw new NullPointerException(); |
| this.choiceKind = choiceKind; |
| this.choices = choices; |
| } |
| |
| @Override |
| public String toString() { |
| return name.optionName; |
| } |
| |
| public boolean hasArg() { |
| return argsNameKey != null && !hasSuffix; |
| } |
| |
| public boolean matches(String option) { |
| if (!hasSuffix) |
| return option.equals(name.optionName); |
| |
| if (!option.startsWith(name.optionName)) |
| return false; |
| |
| if (choices != null) { |
| String arg = option.substring(name.optionName.length()); |
| if (choiceKind == ChoiceKind.ONEOF) |
| return choices.keySet().contains(arg); |
| else { |
| for (String a: arg.split(",+")) { |
| if (!choices.keySet().contains(a)) |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| /** Print a line of documentation describing this option, if standard. |
| * @param out the stream to which to write the documentation |
| */ |
| void help(PrintWriter out) { |
| String s = " " + helpSynopsis(); |
| out.print(s); |
| for (int j = Math.min(s.length(), 28); j < 29; j++) out.print(" "); |
| Log.printLines(out, Main.getLocalizedString(descrKey)); |
| } |
| |
| String helpSynopsis() { |
| StringBuilder sb = new StringBuilder(); |
| sb.append(name); |
| if (argsNameKey == null) { |
| if (choices != null) { |
| String sep = "{"; |
| for (Map.Entry<String,Boolean> e: choices.entrySet()) { |
| if (!e.getValue()) { |
| sb.append(sep); |
| sb.append(e.getKey()); |
| sep = ","; |
| } |
| } |
| sb.append("}"); |
| } |
| } else { |
| if (!hasSuffix) |
| sb.append(" "); |
| sb.append(Main.getLocalizedString(argsNameKey)); |
| } |
| |
| return sb.toString(); |
| } |
| |
| /** Print a line of documentation describing this option, if non-standard. |
| * @param out the stream to which to write the documentation |
| */ |
| void xhelp(PrintWriter out) {} |
| |
| /** Process the option (with arg). Return true if error detected. |
| */ |
| public boolean process(Options options, String option, String arg) { |
| if (options != null) { |
| if (choices != null) { |
| if (choiceKind == ChoiceKind.ONEOF) { |
| // some clients like to see just one of option+choice set |
| for (String s: choices.keySet()) |
| options.remove(option + s); |
| String opt = option + arg; |
| options.put(opt, opt); |
| // some clients like to see option (without trailing ":") |
| // set to arg |
| String nm = option.substring(0, option.length() - 1); |
| options.put(nm, arg); |
| } else { |
| // set option+word for each word in arg |
| for (String a: arg.split(",+")) { |
| String opt = option + a; |
| options.put(opt, opt); |
| } |
| } |
| } |
| options.put(option, arg); |
| } |
| return false; |
| } |
| |
| /** Process the option (without arg). Return true if error detected. |
| */ |
| public boolean process(Options options, String option) { |
| if (hasSuffix) |
| return process(options, name.optionName, option.substring(name.optionName.length())); |
| else |
| return process(options, option, option); |
| } |
| |
| public OptionKind getKind() { return OptionKind.NORMAL; } |
| |
| public OptionName getName() { return name; } |
| }; |
| |
| /** A nonstandard or extended (-X) option |
| */ |
| static class XOption extends Option { |
| XOption(OptionName name, String argsNameKey, String descrKey) { |
| super(name, argsNameKey, descrKey); |
| } |
| XOption(OptionName name, String descrKey) { |
| this(name, null, descrKey); |
| } |
| XOption(OptionName name, String descrKey, ChoiceKind kind, String... choices) { |
| super(name, descrKey, kind, choices); |
| } |
| XOption(OptionName name, String descrKey, ChoiceKind kind, Map<String,Boolean> choices) { |
| super(name, descrKey, kind, choices); |
| } |
| @Override |
| void help(PrintWriter out) {} |
| @Override |
| void xhelp(PrintWriter out) { super.help(out); } |
| @Override |
| public OptionKind getKind() { return OptionKind.EXTENDED; } |
| }; |
| |
| /** A hidden (implementor) option |
| */ |
| static class HiddenOption extends Option { |
| HiddenOption(OptionName name) { |
| super(name, null, null); |
| } |
| HiddenOption(OptionName name, String argsNameKey) { |
| super(name, argsNameKey, null); |
| } |
| @Override |
| void help(PrintWriter out) {} |
| @Override |
| void xhelp(PrintWriter out) {} |
| @Override |
| public OptionKind getKind() { return OptionKind.HIDDEN; } |
| }; |
| |
| } |