You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ConfigParser.java 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /* *******************************************************************
  2. * Copyright (c) 1999-2001 Xerox Corporation,
  3. * 2002 Palo Alto Research Center, Incorporated (PARC).
  4. * All rights reserved.
  5. * This program and the accompanying materials are made available
  6. * under the terms of the Eclipse Public License v1.0
  7. * which accompanies this distribution and is available at
  8. * http://www.eclipse.org/legal/epl-v10.html
  9. *
  10. * Contributors:
  11. * Xerox/PARC initial implementation
  12. * ******************************************************************/
  13. package org.aspectj.ajdt.ajc;
  14. import java.io.BufferedReader;
  15. import java.io.File;
  16. import java.io.FileFilter;
  17. import java.io.FileReader;
  18. import java.io.IOException;
  19. import java.util.ArrayList;
  20. import java.util.LinkedList;
  21. import java.util.List;
  22. public class ConfigParser {
  23. Location location;
  24. protected File relativeDirectory = null;
  25. protected List<File> files = new LinkedList<File>();
  26. protected List<File> xmlfiles = new ArrayList<File>();
  27. private boolean fileParsed = false;
  28. protected static String CONFIG_MSG = "build config error: ";
  29. public List<File> getFiles() {
  30. return files;
  31. }
  32. public List<File> getXmlFiles() {
  33. return xmlfiles;
  34. }
  35. public void parseCommandLine(String[] argsArray) throws ParseException {
  36. location = new CommandLineLocation();
  37. LinkedList<Arg> args = new LinkedList<Arg>();
  38. for (int i = 0; i < argsArray.length; i++) {
  39. args.add(new Arg(argsArray[i], location));
  40. }
  41. parseArgs(args);
  42. }
  43. public void parseConfigFile(File configFile) throws ParseException {
  44. if (fileParsed == true) {
  45. throw new ParseException(CONFIG_MSG + "The file has already been parsed.", null);
  46. } else {
  47. parseConfigFileHelper(configFile);
  48. }
  49. }
  50. /**
  51. * @throws ParseException if the config file has already been prased.
  52. */
  53. private void parseConfigFileHelper(File configFile) {
  54. if (!configFile.exists()) {
  55. showError("file does not exist: " + configFile.getPath());
  56. return;
  57. }
  58. LinkedList<Arg> args = new LinkedList<Arg>();
  59. int lineNum = 0;
  60. try {
  61. BufferedReader stream = new BufferedReader(new FileReader(configFile));
  62. String line = null;
  63. while ((line = stream.readLine()) != null) {
  64. lineNum += 1;
  65. line = stripWhitespaceAndComments(line);
  66. if (line.length() == 0) {
  67. continue;
  68. }
  69. args.add(new Arg(line, new CPSourceLocation(configFile, lineNum)));
  70. }
  71. stream.close();
  72. } catch (IOException e) {
  73. location = new CPSourceLocation(configFile, lineNum);
  74. showError("error reading config file: " + e.toString());
  75. }
  76. File oldRelativeDirectory = relativeDirectory; // for nested arg files;
  77. relativeDirectory = configFile.getParentFile();
  78. parseArgs(args);
  79. relativeDirectory = oldRelativeDirectory;
  80. fileParsed = true;
  81. }
  82. File getCurrentDir() {
  83. return location.getDirectory();
  84. }
  85. String stripSingleLineComment(String s, String commentString) {
  86. int commentStart = s.indexOf(commentString);
  87. if (commentStart == -1) {
  88. return s;
  89. } else {
  90. return s.substring(0, commentStart);
  91. }
  92. }
  93. String stripWhitespaceAndComments(String s) {
  94. s = stripSingleLineComment(s, "//");
  95. s = stripSingleLineComment(s, "#");
  96. s = s.trim();
  97. if (s.startsWith("\"") && s.endsWith("\"")) {
  98. if (s.length() == 1) {
  99. return "";
  100. } else {
  101. s = s.substring(1, s.length() - 1);
  102. }
  103. }
  104. return s;
  105. }
  106. /**
  107. * ??? We would like to call a showNonFatalError method here to show all errors in config files before aborting the compilation
  108. */
  109. protected void addFile(File sourceFile) {
  110. if (!sourceFile.isFile()) {
  111. showError("source file does not exist: " + sourceFile.getPath());
  112. }
  113. files.add(sourceFile);
  114. }
  115. protected void addXmlFile(File xmlFile) {
  116. if (!xmlFile.isFile()) {
  117. showError("XML file does not exist: " + xmlFile.getPath());
  118. }
  119. xmlfiles.add(xmlFile);
  120. }
  121. void addFileOrPattern(File sourceFile) {
  122. if (sourceFile.getName().charAt(0) == '*') {
  123. if (sourceFile.getName().equals("*.java")) {
  124. addFiles(sourceFile.getParentFile(), new FileFilter() {
  125. public boolean accept(File f) {
  126. return f != null && f.getName().endsWith(".java");
  127. }
  128. });
  129. } else if (sourceFile.getName().equals("*.aj")) {
  130. addFiles(sourceFile.getParentFile(), new FileFilter() {
  131. public boolean accept(File f) {
  132. return f != null && f.getName().endsWith(".aj");
  133. }
  134. });
  135. } else {
  136. addFile(sourceFile);
  137. }
  138. } else {
  139. addFile(sourceFile);
  140. }
  141. }
  142. void addFiles(File dir, FileFilter filter) {
  143. if (dir == null) {
  144. dir = new File(System.getProperty("user.dir"));
  145. }
  146. if (!dir.isDirectory()) {
  147. showError("can't find " + dir.getPath());
  148. } else {
  149. File[] files = dir.listFiles(filter);
  150. if (files.length == 0) {
  151. showWarning("no matching files found in: " + dir);
  152. }
  153. for (int i = 0; i < files.length; i++) {
  154. addFile(files[i]);
  155. }
  156. }
  157. }
  158. protected void parseOption(String arg, LinkedList args) {
  159. showWarning("unrecognized option: " + arg);
  160. }
  161. protected void showWarning(String message) {
  162. if (location != null) {
  163. message += " at " + location.toString();
  164. }
  165. System.err.println(CONFIG_MSG + message);
  166. }
  167. protected void showError(String message) {
  168. throw new ParseException(CONFIG_MSG + message, location);
  169. }
  170. void parseArgs(LinkedList args) {
  171. while (args.size() > 0) {
  172. parseOneArg(args);
  173. }
  174. }
  175. protected Arg removeArg(LinkedList args) {
  176. if (args.size() == 0) {
  177. showError("value missing");
  178. return null;
  179. } else {
  180. return (Arg) args.removeFirst();
  181. }
  182. }
  183. protected String removeStringArg(LinkedList args) {
  184. Arg arg = removeArg(args);
  185. if (arg == null) {
  186. return null;
  187. }
  188. return arg.getValue();
  189. }
  190. /**
  191. * aop.xml configuration files can be passed on the command line.
  192. */
  193. boolean isXml(String s) {
  194. return s.endsWith(".xml");
  195. }
  196. boolean isSourceFileName(String s) {
  197. if (s.endsWith(".java")) {
  198. return true;
  199. }
  200. if (s.endsWith(".aj")) {
  201. return true;
  202. }
  203. // if (s.endsWith(".ajava")) {
  204. // showWarning(".ajava is deprecated, replace with .aj or .java: " + s);
  205. // return true;
  206. // }
  207. return false;
  208. }
  209. void parseOneArg(LinkedList args) {
  210. Arg arg = removeArg(args);
  211. String v = arg.getValue();
  212. location = arg.getLocation();
  213. if (v.startsWith("@")) {
  214. parseImportedConfigFile(v.substring(1));
  215. } else if (v.equals("-argfile")) {
  216. parseConfigFileHelper(makeFile(removeArg(args).getValue()));
  217. } else if (isSourceFileName(v)) {
  218. addFileOrPattern(makeFile(v));
  219. } else if (isXml(v)) {
  220. addXmlFile(makeFile(v));
  221. } else {
  222. parseOption(arg.getValue(), args);
  223. }
  224. }
  225. protected void parseImportedConfigFile(String relativeFilePath) {
  226. parseConfigFileHelper(makeFile(relativeFilePath));
  227. }
  228. public File makeFile(String name) {
  229. if (relativeDirectory != null) {
  230. return makeFile(relativeDirectory, name);
  231. } else {
  232. return makeFile(getCurrentDir(), name);
  233. }
  234. }
  235. private File makeFile(File dir, String name) {
  236. name = name.replace('/', File.separatorChar);
  237. File ret = new File(name);
  238. boolean isAbsolute = ret.isAbsolute() || (ret.exists() && ret.getPath().startsWith(File.separator));
  239. if (!isAbsolute && (dir != null)) {
  240. ret = new File(dir, name);
  241. }
  242. try {
  243. ret = ret.getCanonicalFile();
  244. } catch (IOException ioEx) {
  245. // proceed without canonicalization
  246. // so nothing to do here
  247. }
  248. return ret;
  249. }
  250. protected static class Arg {
  251. private Location location;
  252. private String value;
  253. public Arg(String value, Location location) {
  254. this.value = value;
  255. this.location = location;
  256. }
  257. public void setValue(String value) {
  258. this.value = value;
  259. }
  260. public void setLocation(Location location) {
  261. this.location = location;
  262. }
  263. public String getValue() {
  264. return value;
  265. }
  266. public Location getLocation() {
  267. return location;
  268. }
  269. }
  270. static abstract class Location {
  271. public abstract File getFile();
  272. public abstract File getDirectory();
  273. public abstract int getLine();
  274. public abstract String toString();
  275. }
  276. static class CPSourceLocation extends Location {
  277. private int line;
  278. private File file;
  279. public CPSourceLocation(File file, int line) {
  280. this.line = line;
  281. this.file = file;
  282. }
  283. public File getFile() {
  284. return file;
  285. }
  286. public File getDirectory() {
  287. return file.getParentFile();
  288. }
  289. public int getLine() {
  290. return line;
  291. }
  292. public String toString() {
  293. return file.getPath() + ":" + line;
  294. }
  295. }
  296. static class CommandLineLocation extends Location {
  297. public File getFile() {
  298. return new File(System.getProperty("user.dir"));
  299. }
  300. public File getDirectory() {
  301. return new File(System.getProperty("user.dir"));
  302. }
  303. public int getLine() {
  304. return -1;
  305. }
  306. public String toString() {
  307. return "command-line";
  308. }
  309. }
  310. public static class ParseException extends RuntimeException {
  311. private Location location;
  312. public ParseException(String message, Location location) {
  313. super(message);
  314. this.location = location;
  315. }
  316. public int getLine() {
  317. if (location == null) {
  318. return -1;
  319. }
  320. return location.getLine();
  321. }
  322. public File getFile() {
  323. if (location == null) {
  324. return null;
  325. }
  326. return location.getFile();
  327. }
  328. }
  329. }