1 33 package org.jruby.util; 34 35 import java.io.BufferedReader ; 36 import java.io.File ; 37 import java.io.FileInputStream ; 38 import java.io.IOException ; 39 import java.io.InputStreamReader ; 40 import java.io.Reader ; 41 import java.io.StringReader ; 42 import java.util.ArrayList ; 43 import java.util.List ; 44 45 import org.jruby.Main; 46 import org.jruby.exceptions.MainExitException; 47 48 public class CommandlineParser { 49 private final String [] arguments; 50 private Main main; 51 52 private ArrayList loadPaths = new ArrayList (); 53 private StringBuffer inlineScript = new StringBuffer (); 54 private boolean hasInlineScript = false; 55 private String scriptFileName = null; 56 private ArrayList requiredLibraries = new ArrayList (); 57 private boolean benchmarking = false; 58 private boolean assumeLoop = false; 59 private boolean assumePrinting = false; 60 private boolean processLineEnds = false; 61 private boolean split = false; 62 private boolean verbose = false; 63 private boolean debug = false; 64 private boolean showVersion = false; 65 private boolean endOfArguments = false; 66 private String [] scriptArguments = null; 67 private boolean shouldRunInterpreter = true; 68 69 private boolean objectSpaceEnabled = true; 70 private boolean compilerEnabled = false; 71 private boolean yarv = false; 72 private boolean yarvCompile = false; 73 private KCode kcode = KCode.NONE; 74 75 public int argumentIndex = 0; 76 public int characterIndex = 0; 77 78 public CommandlineParser(Main main, String [] arguments) { 79 this.arguments = arguments; 80 this.main = main; 81 processArguments(); 82 } 83 84 private void processArguments() { 85 86 while (argumentIndex < arguments.length && isInterpreterArgument(arguments[argumentIndex])) { 87 processArgument(); 88 argumentIndex++; 89 } 90 91 if (!hasInlineScript) { 92 if (argumentIndex < arguments.length) { 93 setScriptFileName(arguments[argumentIndex]); argumentIndex++; 95 } 96 } 97 98 99 scriptArguments = new String [arguments.length - argumentIndex]; 101 System.arraycopy(arguments, argumentIndex, getScriptArguments(), 0, getScriptArguments().length); 102 } 103 104 private boolean isInterpreterArgument(String argument) { 105 return argument.charAt(0) == '-' && !endOfArguments; 106 } 107 108 private void processArgument() { 109 String argument = arguments[argumentIndex]; 110 FOR : for (characterIndex = 1; characterIndex < argument.length(); characterIndex++) { 111 switch (argument.charAt(characterIndex)) { 112 case 'h' : 113 main.printUsage(); 114 shouldRunInterpreter = false; 115 break; 116 case 'I' : 117 String s = grabValue(" -I must be followed by a directory name to add to lib path"); 118 String [] ls = s.split(java.io.File.pathSeparator); 119 for(int i=0;i<ls.length;i++) { 120 loadPaths.add(ls[i]); 121 } 122 break FOR; 123 case 'r' : 124 requiredLibraries.add(grabValue("-r must be followed by a package to require")); 125 break FOR; 126 case 'e' : 127 inlineScript.append(grabValue(" -e must be followed by an expression to evaluate")); 128 inlineScript.append('\n'); 129 hasInlineScript = true; 130 break FOR; 131 case 'b' : 132 benchmarking = true; 133 break; 134 case 'p' : 135 assumePrinting = true; 136 assumeLoop = true; 137 break; 138 case 'O' : 139 objectSpaceEnabled = false; 140 break; 141 case 'C' : 142 compilerEnabled = true; 143 break; 144 case 'y' : 145 yarv = true; 146 break; 147 case 'Y' : 148 yarvCompile = true; 149 break; 150 case 'n' : 151 assumeLoop = true; 152 break; 153 case 'a' : 154 split = true; 155 break; 156 case 'd' : 157 debug = true; 158 verbose = true; 159 break; 160 case 'l' : 161 processLineEnds = true; 162 break; 163 case 'v' : 164 verbose = true; 165 setShowVersion(true); 166 break; 167 case 'w' : 168 verbose = true; 169 break; 170 case 'K': 171 String eArg = grabValue("provide a value for -K"); 175 kcode = KCode.create(null, eArg); 176 break; 177 case 'S': 178 scriptFileName = System.getProperty("jruby.home") + "/bin/" + grabValue("provide a value for -S"); 179 hasInlineScript = true; 180 endOfArguments = true; break FOR; 182 case '-' : 183 if (argument.equals("--version")) { 184 setShowVersion(true); 185 break FOR; 186 } else if(argument.equals("--debug")) { 187 debug = true; 188 verbose = true; 189 break; 190 } else if (argument.equals("--help")) { 191 main.printUsage(); 192 shouldRunInterpreter = false; 193 break; 194 } else if (argument.equals("--command")) { 195 requiredLibraries.add("jruby/commands"); 196 characterIndex = argument.length(); 197 inlineScript.append("JRuby::Commands." + grabValue("provide a command to execute")); 198 inlineScript.append("\n"); 199 hasInlineScript = true; 200 endOfArguments = true; 201 break; 202 } else { 203 if (argument.equals("--")) { 204 endOfArguments = true; 207 break; 208 } 209 } 210 default : 211 throw new MainExitException(1, "unknown option " + argument.charAt(characterIndex)); 212 } 213 } 214 } 215 216 private String grabValue(String errorMessage) { 217 characterIndex++; 218 if (characterIndex < arguments[argumentIndex].length()) { 219 return arguments[argumentIndex].substring(characterIndex); 220 } 221 argumentIndex++; 222 if (argumentIndex < arguments.length) { 223 return arguments[argumentIndex]; 224 } 225 226 MainExitException mee = new MainExitException(1, "invalid argument " + argumentIndex + "\n" + errorMessage); 227 mee.setUsageError(true); 228 229 throw mee; 230 } 231 232 public String inlineScript() { 233 return inlineScript.toString(); 234 } 235 236 public List requiredLibraries() { 237 return requiredLibraries; 238 } 239 240 public List loadPaths() { 241 return loadPaths; 242 } 243 244 public boolean shouldRunInterpreter() { 245 return isShouldRunInterpreter(); 246 } 247 248 private boolean isSourceFromStdin() { 249 return getScriptFileName() == null; 250 } 251 252 public Reader getScriptSource() { 253 try { 254 if (hasInlineScript) { 257 if (scriptFileName != null) { 258 File file = new File (getScriptFileName()); 259 return new BufferedReader (new InputStreamReader (new FileInputStream (file), KCode.NONE.decoder())); 260 } 261 return new StringReader (inlineScript()); 262 } else if (isSourceFromStdin()) { 263 return new InputStreamReader (System.in, KCode.NONE.decoder()); 264 } else { 265 File file = new File (getScriptFileName()); 266 return new BufferedReader (new InputStreamReader (new FileInputStream (file), KCode.NONE.decoder())); 267 } 268 } catch (IOException e) { 269 throw new MainExitException(1, "Error opening script file: " + e.getMessage()); 270 } 271 } 272 273 public String displayedFileName() { 274 if (hasInlineScript) { 275 if (scriptFileName != null) { 276 return scriptFileName; 277 } else { 278 return "-e"; 279 } 280 } else if (isSourceFromStdin()) { 281 return "-"; 282 } else { 283 return getScriptFileName(); 284 } 285 } 286 287 private void setScriptFileName(String scriptFileName) { 288 this.scriptFileName = scriptFileName; 289 } 290 291 public String getScriptFileName() { 292 return scriptFileName; 293 } 294 295 public boolean isBenchmarking() { 296 return benchmarking; 297 } 298 299 public boolean isAssumeLoop() { 300 return assumeLoop; 301 } 302 303 public boolean isAssumePrinting() { 304 return assumePrinting; 305 } 306 307 public boolean isProcessLineEnds() { 308 return processLineEnds; 309 } 310 311 public boolean isSplit() { 312 return split; 313 } 314 315 public boolean isVerbose() { 316 return verbose; 317 } 318 319 public boolean isDebug() { 320 return debug; 321 } 322 323 public boolean isShowVersion() { 324 return showVersion; 325 } 326 327 protected void setShowVersion(boolean showVersion) { 328 this.showVersion = showVersion; 329 this.shouldRunInterpreter = false; 330 } 331 332 public String [] getScriptArguments() { 333 return scriptArguments; 334 } 335 336 public boolean isShouldRunInterpreter() { 337 return shouldRunInterpreter; 338 } 339 340 public boolean isObjectSpaceEnabled() { 341 return objectSpaceEnabled; 342 } 343 344 public boolean isCompilerEnabled() { 345 return compilerEnabled; 346 } 347 348 public boolean isYARVEnabled() { 349 return yarv; 350 } 351 352 public boolean isYARVCompileEnabled() { 353 return yarvCompile; 354 } 355 356 public KCode getKCode() { 357 return kcode; 358 } 359 } 360 | Popular Tags |