1 salcianu 1.1 // Option.java, created Wed Apr 9 13:52:03 2003 by salcianu 2 salcianu 1.1 // Copyright (C) 2003 Alexandru Salcianu <salcianu@MIT.EDU> 3 salcianu 1.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 salcianu 1.1 package harpoon.Util.Options; 5 salcianu 1.1 6 salcianu 1.1 import java.util.Map; 7 salcianu 1.1 import java.util.HashMap; 8 salcianu 1.1 import java.util.List; 9 salcianu 1.1 import java.util.LinkedList; 10 salcianu 1.1 import java.util.Iterator; 11 salcianu 1.1 import java.util.ListIterator; 12 salcianu 1.1 import java.util.StringTokenizer; 13 salcianu 1.1 14 salcianu 1.1 import java.io.PrintStream; 15 salcianu 1.1 16 salcianu 1.1 /** 17 salcianu 1.1 * <code>Option</code> 18 salcianu 1.1 * 19 salcianu 1.1 * @author Alexandru Salcianu <salcianu@MIT.EDU> 20 cananian 1.4 * @version $Id: Option.java,v 1.4 2004/02/08 03:21:58 cananian Exp $ 21 salcianu 1.1 */ 22 salcianu 1.1 public abstract class Option { 23 salcianu 1.1 24 salcianu 1.1 public Option(String optionName, String argSummary, String optArgSummary, 25 salcianu 1.1 String helpMessage) { 26 salcianu 1.1 this.optionName = optionName; 27 salcianu 1.1 28 salcianu 1.1 if(argSummary == null) argSummary = ""; 29 salcianu 1.1 if(optArgSummary == null) optArgSummary = ""; 30 salcianu 1.1 31 salcianu 1.1 StringTokenizer argTokenizer = new StringTokenizer(argSummary); 32 salcianu 1.1 StringTokenizer optArgTokenizer = new StringTokenizer(optArgSummary); 33 salcianu 1.1 34 salcianu 1.1 this.compArgs = new String[argTokenizer.countTokens()]; 35 salcianu 1.1 this.optArgs = new String[optArgTokenizer.countTokens()]; 36 salcianu 1.1 this.description = 37 salcianu 1.1 buildDescription(optionName, argTokenizer, optArgTokenizer); 38 salcianu 1.1 this.helpMessage = helpMessage; 39 salcianu 1.1 } 40 salcianu 1.1 41 salcianu 1.1 public Option(String optionName, String argSummary, String helpMessage) { 42 salcianu 1.1 this(optionName, argSummary, null, helpMessage); 43 salcianu 1.1 } 44 salcianu 1.1 45 salcianu 1.1 public Option(String optionName, String helpMessage) { 46 salcianu 1.1 this(optionName, null, null, helpMessage); 47 salcianu 1.1 } 48 salcianu 1.1 49 salcianu 1.1 public Option(String optionName) { 50 salcianu 1.1 this(optionName, null, null, null); 51 salcianu 1.1 } 52 salcianu 1.1 53 salcianu 1.1 protected final String optionName; 54 salcianu 1.1 protected final String[] compArgs; 55 salcianu 1.1 protected final String[] optArgs; 56 salcianu 1.1 protected final String description; 57 salcianu 1.1 protected final String helpMessage; 58 salcianu 1.1 59 salcianu 1.1 protected void setArg(int i, String arg) { compArgs[i] = arg; } 60 salcianu 1.1 public String getArg(int i) { return compArgs[i]; } 61 salcianu 1.1 62 salcianu 1.1 protected void setOptionalArg(int i, String arg) { optArgs[i] = arg; } 63 salcianu 1.1 public String getOptionalArg(int i) { return optArgs[i]; } 64 salcianu 1.1 65 salcianu 1.1 public String optionName() { return optionName; } 66 salcianu 1.1 public int numberArgs() { return compArgs.length; } 67 salcianu 1.1 public int numberOptionalArgs() { return optArgs.length; } 68 salcianu 1.1 public String description() { return description; } 69 salcianu 1.1 70 salcianu 1.1 public abstract void action(); 71 salcianu 1.1 72 salcianu 1.1 public void printHelp(PrintStream ps) { 73 salcianu 1.1 ps.println(description); 74 salcianu 1.1 if((helpMessage != null) && (helpMessage.length() > 0)) { 75 salcianu 1.1 ps.print("\t"); 76 salcianu 1.1 ps.println(helpMessage); 77 salcianu 1.1 } 78 salcianu 1.1 } 79 salcianu 1.1 80 salcianu 1.1 public String toString() { return optionName; } 81 salcianu 1.1 82 salcianu 1.1 83 salcianu 1.1 private static String buildDescription(String optionName, 84 salcianu 1.1 StringTokenizer argTok, 85 salcianu 1.1 StringTokenizer optArgTok) { 86 salcianu 1.1 StringBuffer sb = new StringBuffer(); 87 salcianu 1.1 88 salcianu 1.2 sb.append("-"); 89 salcianu 1.2 if(optionName.length() > 1) 90 salcianu 1.2 sb.append("-"); 91 salcianu 1.1 sb.append(optionName); 92 salcianu 1.1 93 salcianu 1.1 if(argTok.countTokens() > 0) { 94 salcianu 1.1 sb.append(" "); 95 salcianu 1.1 while(argTok.hasMoreTokens()) { 96 salcianu 1.1 sb.append(" "); 97 salcianu 1.1 sb.append(argTok.nextToken()); 98 salcianu 1.1 } 99 salcianu 1.1 } 100 salcianu 1.1 101 salcianu 1.1 if(optArgTok.countTokens() > 0) { 102 salcianu 1.1 sb.append(" ["); 103 salcianu 1.1 while(optArgTok.hasMoreTokens()) { 104 salcianu 1.1 sb.append(" "); 105 salcianu 1.1 sb.append(optArgTok.nextToken()); 106 salcianu 1.1 } 107 salcianu 1.1 sb.append(" ]"); 108 salcianu 1.1 } 109 salcianu 1.1 110 salcianu 1.1 return sb.toString(); 111 salcianu 1.1 } 112 salcianu 1.1 113 salcianu 1.1 114 cananian 1.3 public static String[] parseOptions(List<Option> options, 115 salcianu 1.1 String[] args) { 116 cananian 1.3 List<String> unparsedArgs = 117 salcianu 1.1 parseOptions(options, array2list(args)); 118 salcianu 1.1 return 119 cananian 1.3 unparsedArgs.toArray(new String[unparsedArgs.size()]); 120 salcianu 1.1 } 121 salcianu 1.1 122 salcianu 1.1 123 cananian 1.3 public static List<String> parseOptions(List<Option> options, 124 cananian 1.3 List<String> args) { 125 salcianu 1.1 126 cananian 1.3 Map<String,Option> arg2option = new HashMap<String,Option>(); 127 cananian 1.4 for(Option option : options) { 128 salcianu 1.1 arg2option.put(option.optionName(), option); 129 salcianu 1.1 } 130 salcianu 1.1 131 cananian 1.3 List<String> unparsedArgs = new LinkedList<String>(); 132 salcianu 1.1 133 cananian 1.3 for(ListIterator<String> it = args.listIterator(); it.hasNext();) { 134 cananian 1.3 String arg = it.next(); 135 salcianu 1.1 if(!isOption(arg) || !arg2option.containsKey(getOption(arg))) { 136 salcianu 1.1 unparsedArgs.add(arg); 137 salcianu 1.1 continue; 138 salcianu 1.1 } 139 salcianu 1.1 140 cananian 1.3 Option option = arg2option.get(getOption(arg)); 141 salcianu 1.1 parseOptionArgs(option, it); 142 salcianu 1.1 143 salcianu 1.1 option.action(); 144 salcianu 1.1 } 145 salcianu 1.1 146 salcianu 1.1 return unparsedArgs; 147 salcianu 1.1 } 148 salcianu 1.1 149 salcianu 1.1 // checks whether arg is an option (i.e., it starts with a '-') 150 salcianu 1.1 public static boolean isOption(String arg) { 151 salcianu 1.1 return (arg.length() > 0) && (arg.charAt(0) == '-'); 152 salcianu 1.1 } 153 salcianu 1.1 154 salcianu 1.1 // peels off all the '-' characters from the beginning of arg 155 salcianu 1.1 public static String getOption(String arg) { 156 salcianu 1.1 int i = 0; 157 salcianu 1.1 while((i < arg.length()) && (arg.charAt(i) == '-')) i++; 158 salcianu 1.1 assert i > 0 : arg + " is not an option at all"; 159 salcianu 1.1 return arg.substring(i); 160 salcianu 1.1 } 161 salcianu 1.1 162 salcianu 1.1 private static void parseOptionArgs(Option option, 163 cananian 1.3 ListIterator<String> it) { 164 salcianu 1.1 for(int i = 0; i < option.numberArgs(); i++) { 165 salcianu 1.1 String arg = null; 166 cananian 1.3 if(!it.hasNext() || isOption(arg = it.next())) { 167 salcianu 1.1 System.err.println("Error while parsing argument #" + i + 168 salcianu 1.1 " for option " + option); 169 salcianu 1.1 System.err.println("Help:"); 170 salcianu 1.1 option.printHelp(System.err); 171 salcianu 1.1 System.exit(1); 172 salcianu 1.1 } 173 salcianu 1.1 option.setArg(i, arg); 174 salcianu 1.1 } 175 salcianu 1.1 176 salcianu 1.1 for(int i = 0; i < option.numberOptionalArgs(); i++) { 177 salcianu 1.1 if(!it.hasNext()) break; 178 cananian 1.3 String arg = it.next(); 179 salcianu 1.1 if(isOption(arg)) { 180 salcianu 1.1 it.previous(); // put the arg back 181 salcianu 1.1 return; 182 salcianu 1.1 } 183 salcianu 1.1 option.setOptionalArg(i, arg); 184 salcianu 1.1 } 185 salcianu 1.1 } 186 salcianu 1.1 187 salcianu 1.1 188 salcianu 1.1 public static List/*<String>*/ array2list(String[] a) { 189 salcianu 1.1 List/*<String>*/ list = new LinkedList/*<String>*/(); 190 salcianu 1.1 for(int i = 0; i < a.length; i++) { 191 salcianu 1.1 if(a[i] != null) 192 salcianu 1.1 list.add(a[i]); 193 salcianu 1.1 } 194 salcianu 1.1 return list; 195 salcianu 1.1 } 196 salcianu 1.1 197 salcianu 1.1 198 salcianu 1.1 public static void main(String[] args) { 199 salcianu 1.1 List/*<Option>*/ options = new LinkedList/*<Option>*/(); 200 salcianu 1.1 options.add 201 salcianu 1.1 (new Option("fileoption", "<file>", "File to compile") { 202 salcianu 1.1 public void action() { 203 salcianu 1.1 System.out.println("Option " + description()); 204 salcianu 1.1 }}); 205 salcianu 1.1 options.add 206 salcianu 1.1 (new Option("fast") { 207 salcianu 1.1 public void action() { 208 salcianu 1.1 System.out.println("Option " + description()); 209 salcianu 1.1 }}); 210 salcianu 1.1 options.add 211 salcianu 1.1 (new Option("seriousOpt", "<arg1> <arg2>", 212 salcianu 1.1 "<optArg1> <optArg2> <optArg3>", 213 salcianu 1.1 "Serious arg!") { 214 salcianu 1.1 public void action() { 215 salcianu 1.1 System.out.println("Option " + description()); 216 salcianu 1.1 }}); 217 salcianu 1.1 218 salcianu 1.1 args = parseOptions(options, args); 219 salcianu 1.1 220 salcianu 1.1 System.out.print("Remaining options: [ "); 221 salcianu 1.1 for (int i = 0; i < args.length; i++) 222 salcianu 1.1 System.out.print(args[i] + " "); 223 salcianu 1.1 System.out.println("]"); 224 salcianu 1.1 } 225 salcianu 1.1 226 salcianu 1.1 }