LibraryLoader.java
package edu.udel.cis.vsl.tass.front.minimp.lib;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import edu.udel.cis.vsl.tass.config.RunConfiguration;
import edu.udel.cis.vsl.tass.config.VerifyConfiguration;
import edu.udel.cis.vsl.tass.front.minimp.ast.declaration.ASTDeclarationIF;
import edu.udel.cis.vsl.tass.front.minimp.ast.declaration.ASTFunctionDeclaration;
import edu.udel.cis.vsl.tass.front.minimp.ast.declaration.ASTVariableDeclaration;
import edu.udel.cis.vsl.tass.front.minimp.ast.misc.AST;
import edu.udel.cis.vsl.tass.front.minimp.parser.TreeParser;
import edu.udel.cis.vsl.tass.model.IF.SyntaxException;
import edu.udel.cis.vsl.tass.util.Sourceable;
public class LibraryLoader {
Map<String, LibraryIF> cache = new HashMap<String, LibraryIF>();
/**
* Get the library with the give name. The source should be the source
* object for the "#include ..." line in the source file. It is used to
* report error if the library is not found.
*
* NOTE: the "name" of the library is something like "stdlib.h" but the
* library file that is loaded will be "libstdlib.c" in the directory
* defined by "tass.library.path", which is currently the directory
* .../tass/lib.
*/
public LibraryIF loadLibrary(Sourceable source, String name)
throws SyntaxException {
LibraryIF library = cache.get(name);
if (library != null)
return library;
library = load(source, name);
cache.put(name, library);
return library;
}
private LibraryIF load(Sourceable source, String name)
throws SyntaxException {
LibraryIF library = new Library(name);
RunConfiguration configuration = new VerifyConfiguration();
TreeParser parser = null;
int index = name.lastIndexOf('.');
if (index == -1)
name = name + ".c";
else
name = name.substring(0, index + 1) + "c";
String fileName = System.getProperty("tass.library.path") + "/lib"
+ name;
try {
parser = new TreeParser(fileName, configuration, null);
} catch (IOException e) {
throw new SyntaxException(source, "Failed to load library: "
+ fileName);
}
AST parsedLibrary = parser.processAST();
// TODO: the library loaded might include other libraries...
Collection<String> subLibs = parsedLibrary.getLibraryNames();
List<ASTFunctionDeclaration> functionList = parsedLibrary
.getFunctionList();
List<ASTVariableDeclaration> inputs = new LinkedList<ASTVariableDeclaration>();
for (ASTDeclarationIF d : parsedLibrary.getGlobalVariableList()) {
if (!(d instanceof ASTVariableDeclaration)) {
throw new SyntaxException(source, "Global variable "
+ d.getName().toString() + " should be a variable.");
} else {
inputs.add((ASTVariableDeclaration) d);
}
}
((Library) library).addInputs(inputs);
((Library) library).addFunctions(functionList);
((Library) library).addTypes(parsedLibrary.getTypeNameMap());
((Library) library).addConstants(parsedLibrary.getConstantMap());
((Library) library).addLibrariesUsed(subLibs);
return library;
}
}