001 /* 002 * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered 003 * by the modified BSD License. You should have received a copy of the 004 * modified BSD license with this compiler. 005 * 006 * Copyright (c) 2005-2008, Torbjorn Ekman 007 * All rights reserved. 008 */ 009 010 import java.util.*; 011 012 aspect AddOptionsToProgram { 013 public Options ASTNode$State.options = new Options(); 014 public Options ASTNode.options() { 015 return state().options; 016 } 017 } 018 019 public class Options { 020 static class Option { 021 public String name; 022 public boolean hasValue; 023 public boolean isCollection; 024 public Option(String name, boolean hasValue, boolean isCollection) { 025 this.name = name; 026 this.hasValue = hasValue; 027 this.isCollection = isCollection; 028 } 029 } 030 private Map options = new HashMap(); 031 private Map optionDescriptions = new HashMap(); 032 033 private HashSet files = new HashSet(); 034 public Collection files() { 035 return files; 036 } 037 038 public void initOptions() { 039 options = new HashMap(); 040 optionDescriptions = new HashMap(); 041 files = new HashSet(); 042 } 043 044 public void addKeyOption(String name) { 045 if(optionDescriptions.containsKey(name)) 046 throw new Error("Command line definition error: option description for " + name + " is multiply declared"); 047 optionDescriptions.put(name, new Option(name, false, false)); 048 } 049 050 public void addKeyValueOption(String name) { 051 if(optionDescriptions.containsKey(name)) 052 throw new Error("Command line definition error: option description for " + name + " is multiply declared"); 053 optionDescriptions.put(name, new Option(name, true, false)); 054 } 055 056 public void addKeyCollectionOption(String name) { 057 if(optionDescriptions.containsKey(name)) 058 throw new Error("Command line definition error: option description for " + name + " is multiply declared"); 059 optionDescriptions.put(name, new Option(name, true, true)); 060 } 061 062 public void addOptionDescription(String name, boolean value) { 063 if(optionDescriptions.containsKey(name)) 064 throw new Error("Command line definition error: option description for " + name + " is multiply declared"); 065 optionDescriptions.put(name, new Option(name, value, false)); 066 } 067 public void addOptionDescription(String name, boolean value, boolean isCollection) { 068 if(optionDescriptions.containsKey(name)) 069 throw new Error("Command line definition error: option description for " + name + " is multiply declared"); 070 optionDescriptions.put(name, new Option(name, value, isCollection)); 071 } 072 073 public void addOptions(String[] args) { 074 for(int i = 0; i < args.length; i++) { 075 String arg = args[i]; 076 if(arg.startsWith("@")) { 077 try { 078 String fileName = arg.substring(1,arg.length()); 079 java.io.StreamTokenizer tokenizer = new java.io.StreamTokenizer(new java.io.FileReader(fileName)); 080 tokenizer.resetSyntax(); 081 tokenizer.whitespaceChars(' ',' '); 082 tokenizer.whitespaceChars('\t','\t'); 083 tokenizer.whitespaceChars('\f','\f'); 084 tokenizer.whitespaceChars('\n','\n'); 085 tokenizer.whitespaceChars('\r','\r'); 086 tokenizer.wordChars(33,255); 087 ArrayList list = new ArrayList(); 088 int next = tokenizer.nextToken(); 089 while(next != java.io.StreamTokenizer.TT_EOF) { 090 if(next == java.io.StreamTokenizer.TT_WORD) { 091 list.add(tokenizer.sval); 092 } 093 next = tokenizer.nextToken(); 094 } 095 String[] newArgs = new String[list.size()]; 096 int index = 0; 097 for(Iterator iter = list.iterator(); iter.hasNext(); index++) { 098 newArgs[index] = (String)iter.next(); 099 } 100 addOptions(newArgs); 101 } catch (java.io.FileNotFoundException e) { 102 System.err.println("File not found: "+arg.substring(1)); 103 } catch (java.io.IOException e) { 104 System.err.println("Exception: "+e.getMessage()); 105 } 106 } 107 else if(arg.startsWith("-")) { 108 if(!optionDescriptions.containsKey(arg)) 109 throw new Error("Command line argument error: option " + arg + " is not defined"); 110 Option o = (Option)optionDescriptions.get(arg); 111 112 if(!o.isCollection && options.containsKey(arg)) 113 throw new Error("Command line argument error: option " + arg + " is multiply defined"); 114 115 if(o.hasValue && !o.isCollection) { 116 String value = null; 117 if(i + 1 > args.length - 1) 118 throw new Error("Command line argument error: value missing for key " + arg); 119 value = args[i+1]; 120 if(value.startsWith("-")) 121 throw new Error("Command line argument error: value missing for key " + arg); 122 i++; 123 options.put(arg, value); 124 } 125 else if(o.hasValue && o.isCollection) { 126 String value = null; 127 if(i + 1 > args.length - 1) 128 throw new Error("Command line argument error: value missing for key " + arg); 129 value = args[i+1]; 130 if(value.startsWith("-")) 131 throw new Error("Command line argument error: value missing for key " + arg); 132 i++; 133 Collection c = (Collection)options.get(arg); 134 if(c == null) 135 c = new ArrayList(); 136 c.add(value); 137 options.put(arg, c); 138 } 139 else { 140 options.put(arg, null); 141 } 142 } 143 else { 144 files.add(arg); 145 } 146 } 147 } 148 public boolean hasOption(String name) { 149 return options.containsKey(name); 150 } 151 public void setOption(String name) { 152 options.put(name, null); 153 } 154 public boolean hasValueForOption(String name) { 155 return options.containsKey(name) && options.get(name) != null; 156 } 157 public String getValueForOption(String name) { 158 if(!hasValueForOption(name)) 159 throw new Error("Command line argument error: key " + name + " does not have a value"); 160 return (String)options.get(name); 161 } 162 public void setValueForOption(String value, String option) { 163 options.put(option, value); 164 } 165 public Collection getValueCollectionForOption(String name) { 166 if(!hasValueForOption(name)) 167 throw new Error("Command line argument error: key " + name + " does not have a value"); 168 return (Collection)options.get(name); 169 } 170 171 public boolean verbose() { 172 return hasOption("-verbose"); 173 } 174 }