|
|
@@ -0,0 +1,316 @@ |
|
|
|
/* ******************************************************************* |
|
|
|
* Copyright (c) 1999-2001 Xerox Corporation, |
|
|
|
* 2002 Palo Alto Research Center, Incorporated (PARC). |
|
|
|
* All rights reserved. |
|
|
|
* This program and the accompanying materials are made available |
|
|
|
* under the terms of the Eclipse Public License v1.0 |
|
|
|
* which accompanies this distribution and is available at |
|
|
|
* http://www.eclipse.org/legal/epl-v10.html |
|
|
|
* |
|
|
|
* Contributors: |
|
|
|
* Xerox/PARC initial implementation |
|
|
|
* ******************************************************************/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
package org.aspectj.ajdt.ajc; |
|
|
|
|
|
|
|
import java.io.BufferedReader; |
|
|
|
import java.io.File; |
|
|
|
import java.io.FileFilter; |
|
|
|
import java.io.FileReader; |
|
|
|
import java.io.IOException; |
|
|
|
import java.util.LinkedList; |
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
public class ConfigParser { |
|
|
|
Location location; |
|
|
|
protected File relativeDirectory = null; |
|
|
|
protected List files = new LinkedList(); |
|
|
|
private boolean fileParsed = false; |
|
|
|
protected static String CONFIG_MSG = "build config error: "; |
|
|
|
|
|
|
|
public List getFiles() { return files; } |
|
|
|
|
|
|
|
public void parseCommandLine(String[] argsArray) throws ParseException { |
|
|
|
location = new CommandLineLocation(); |
|
|
|
LinkedList args = new LinkedList(); |
|
|
|
for (int i = 0; i < argsArray.length; i++) { |
|
|
|
args.add(new Arg(argsArray[i], location)); |
|
|
|
} |
|
|
|
parseArgs(args); |
|
|
|
} |
|
|
|
|
|
|
|
public void parseConfigFile(File configFile) throws ParseException { |
|
|
|
if (fileParsed == true) { |
|
|
|
throw new ParseException(CONFIG_MSG + "The file has already been parsed.", null); |
|
|
|
} else { |
|
|
|
parseConfigFileHelper(configFile); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @throws ParseException if the config file has already been prased. |
|
|
|
*/ |
|
|
|
private void parseConfigFileHelper(File configFile) { |
|
|
|
if (!configFile.exists()) { |
|
|
|
showError("file does not exist: " + configFile.getPath()); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
LinkedList args = new LinkedList(); |
|
|
|
int lineNum = 0; |
|
|
|
|
|
|
|
try { |
|
|
|
BufferedReader stream = |
|
|
|
new BufferedReader(new FileReader(configFile)); |
|
|
|
String line = null; |
|
|
|
while ( (line = stream.readLine()) != null) { |
|
|
|
lineNum += 1; |
|
|
|
line = stripWhitespaceAndComments(line); |
|
|
|
if (line.length() == 0) continue; |
|
|
|
args.add(new Arg(line, new CPSourceLocation(configFile, lineNum))); |
|
|
|
} |
|
|
|
stream.close(); |
|
|
|
} catch (IOException e) { |
|
|
|
location = new CPSourceLocation(configFile, lineNum); |
|
|
|
showError("error reading config file: " + e.toString()); |
|
|
|
} |
|
|
|
File oldRelativeDirectory = relativeDirectory; // for nested arg files; |
|
|
|
relativeDirectory = configFile.getParentFile(); |
|
|
|
parseArgs(args); |
|
|
|
relativeDirectory = oldRelativeDirectory; |
|
|
|
fileParsed = true; |
|
|
|
} |
|
|
|
|
|
|
|
File getCurrentDir() { |
|
|
|
return location.getDirectory(); |
|
|
|
} |
|
|
|
|
|
|
|
String stripSingleLineComment(String s, String commentString) { |
|
|
|
int commentStart = s.indexOf(commentString); |
|
|
|
if (commentStart == -1) return s; |
|
|
|
else return s.substring(0, commentStart); |
|
|
|
} |
|
|
|
|
|
|
|
String stripWhitespaceAndComments(String s) { |
|
|
|
s = stripSingleLineComment(s, "//"); |
|
|
|
s = stripSingleLineComment(s, "#"); |
|
|
|
s = s.trim(); |
|
|
|
if (s.startsWith("\"") && s.endsWith("\"")) { |
|
|
|
s = s.substring(1, s.length()-1); |
|
|
|
} |
|
|
|
return s; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** ??? We would like to call a showNonFatalError method here |
|
|
|
* to show all errors in config files before aborting the compilation |
|
|
|
*/ |
|
|
|
protected void addFile(File sourceFile) { |
|
|
|
if (!sourceFile.isFile()) { |
|
|
|
showError("source file does not exist: " + sourceFile.getPath()); |
|
|
|
} |
|
|
|
|
|
|
|
files.add(sourceFile); |
|
|
|
} |
|
|
|
|
|
|
|
void addFileOrPattern(File sourceFile) { |
|
|
|
if (sourceFile.getName().equals("*.java")) { |
|
|
|
addFiles(sourceFile.getParentFile(), new FileFilter() { |
|
|
|
public boolean accept(File f) { |
|
|
|
return f != null && f.getName().endsWith(".java"); |
|
|
|
}}); |
|
|
|
} else if (sourceFile.getName().equals("*.aj")) { |
|
|
|
addFiles(sourceFile.getParentFile(), new FileFilter() { |
|
|
|
public boolean accept(File f) { |
|
|
|
return f != null && f.getName().endsWith(".aj"); |
|
|
|
}}); |
|
|
|
} else { |
|
|
|
addFile(sourceFile); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void addFiles(File dir, FileFilter filter) { |
|
|
|
if (dir == null) dir = new File(System.getProperty("user.dir")); |
|
|
|
|
|
|
|
if (!dir.isDirectory()) { |
|
|
|
showError("can't find " + dir.getPath()); |
|
|
|
} else { |
|
|
|
|
|
|
|
File[] files = dir.listFiles(filter); |
|
|
|
if (files.length == 0) { |
|
|
|
showWarning("no matching files found in: " + dir); |
|
|
|
} |
|
|
|
|
|
|
|
for (int i = 0; i < files.length; i++) { |
|
|
|
addFile(files[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected void parseOption(String arg, LinkedList args) { |
|
|
|
showWarning("unrecognized option: " + arg); |
|
|
|
} |
|
|
|
|
|
|
|
protected void showWarning(String message) { |
|
|
|
if (location != null) { |
|
|
|
message += " at " + location.toString(); |
|
|
|
} |
|
|
|
System.err.println(CONFIG_MSG + message); |
|
|
|
} |
|
|
|
|
|
|
|
protected void showError(String message) { |
|
|
|
throw new ParseException(CONFIG_MSG + message, location); |
|
|
|
} |
|
|
|
|
|
|
|
void parseArgs(LinkedList args) { |
|
|
|
while (args.size() > 0) parseOneArg(args); |
|
|
|
} |
|
|
|
|
|
|
|
protected Arg removeArg(LinkedList args) { |
|
|
|
if (args.size() == 0) { |
|
|
|
showError("value missing"); |
|
|
|
return null; |
|
|
|
} else { |
|
|
|
return (Arg)args.removeFirst(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected String removeStringArg(LinkedList args) { |
|
|
|
Arg arg = removeArg(args); |
|
|
|
if (arg == null) return null; |
|
|
|
return arg.getValue(); |
|
|
|
} |
|
|
|
|
|
|
|
boolean isSourceFileName(String s) { |
|
|
|
if (s.endsWith(".java")) return true; |
|
|
|
if (s.endsWith(".aj")) return true; |
|
|
|
if (s.endsWith(".ajava")) { |
|
|
|
showWarning(".ajava is deprecated, replace with .aj or .java: " + s); |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
void parseOneArg(LinkedList args) { |
|
|
|
Arg arg = removeArg(args); |
|
|
|
String v = arg.getValue(); |
|
|
|
location = arg.getLocation(); |
|
|
|
if (v.startsWith("@")) { |
|
|
|
parseImportedConfigFile(v.substring(1)); |
|
|
|
} else if (v.equals("-argfile")) { |
|
|
|
parseConfigFileHelper(makeFile(removeArg(args).getValue())); |
|
|
|
} else if (isSourceFileName(v)) { |
|
|
|
addFileOrPattern(makeFile(v)); |
|
|
|
} else { |
|
|
|
parseOption(arg.getValue(), args); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected void parseImportedConfigFile(String relativeFilePath) { |
|
|
|
parseConfigFileHelper(makeFile(relativeFilePath)); |
|
|
|
} |
|
|
|
|
|
|
|
public File makeFile(String name) { |
|
|
|
if (relativeDirectory != null) { |
|
|
|
return makeFile(relativeDirectory,name); |
|
|
|
} else { |
|
|
|
return makeFile(getCurrentDir(), name); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private File makeFile(File dir, String name) { |
|
|
|
name = name.replace('/', File.separatorChar); |
|
|
|
File ret = new File(name); |
|
|
|
boolean isAbsolute = ret.isAbsolute() |
|
|
|
|| (ret.exists() && ret.getPath().startsWith(File.separator)); |
|
|
|
if (!isAbsolute && (dir != null)) { |
|
|
|
ret = new File(dir, name); |
|
|
|
} |
|
|
|
try { |
|
|
|
ret = ret.getCanonicalFile(); |
|
|
|
} catch (IOException ioEx) { |
|
|
|
// proceed without canonicalization |
|
|
|
// so nothing to do here |
|
|
|
} |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected static class Arg { |
|
|
|
private Location location; |
|
|
|
private String value; |
|
|
|
public Arg(String value, Location location) { |
|
|
|
this.value = value; |
|
|
|
this.location = location; |
|
|
|
} |
|
|
|
|
|
|
|
public void setValue(String value) { |
|
|
|
this.value = value; |
|
|
|
} |
|
|
|
|
|
|
|
public void setLocation(Location location) { |
|
|
|
this.location = location; |
|
|
|
} |
|
|
|
|
|
|
|
public String getValue() { return value; } |
|
|
|
public Location getLocation() { return location; } |
|
|
|
} |
|
|
|
|
|
|
|
static abstract class Location { |
|
|
|
public abstract File getFile(); |
|
|
|
public abstract File getDirectory(); |
|
|
|
public abstract int getLine(); |
|
|
|
public abstract String toString(); |
|
|
|
} |
|
|
|
|
|
|
|
static class CPSourceLocation extends Location { |
|
|
|
private int line; |
|
|
|
private File file; |
|
|
|
public CPSourceLocation(File file, int line) { |
|
|
|
this.line = line; |
|
|
|
this.file = file; |
|
|
|
} |
|
|
|
|
|
|
|
public File getFile() { return file; } |
|
|
|
public File getDirectory() { return file.getParentFile(); } |
|
|
|
public int getLine() { return line; } |
|
|
|
|
|
|
|
public String toString() { |
|
|
|
return file.getPath()+":"+line; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static class CommandLineLocation extends Location { |
|
|
|
public File getFile() { |
|
|
|
return new File(System.getProperty("user.dir")); |
|
|
|
} |
|
|
|
|
|
|
|
public File getDirectory() { |
|
|
|
return new File(System.getProperty("user.dir")); |
|
|
|
} |
|
|
|
public int getLine() { return -1; } |
|
|
|
public String toString() { |
|
|
|
return "command-line"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public static class ParseException extends RuntimeException { |
|
|
|
private Location location; |
|
|
|
|
|
|
|
public ParseException(String message, Location location) { |
|
|
|
super(message); |
|
|
|
this.location = location; |
|
|
|
} |
|
|
|
|
|
|
|
public int getLine() { |
|
|
|
if (location == null) return -1; |
|
|
|
return location.getLine(); |
|
|
|
} |
|
|
|
public File getFile() { |
|
|
|
if (location == null) return null; |
|
|
|
return location.getFile(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |