forked from Jaysyn/PRC8
Updated Release Archive
Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
This commit is contained in:
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/Main$1.class
Normal file
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/Main$1.class
Normal file
Binary file not shown.
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/Main.class
Normal file
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/Main.class
Normal file
Binary file not shown.
222
nwn/nwnprc/DocGen/trunk/prc/makedep/Main.java
Normal file
222
nwn/nwnprc/DocGen/trunk/prc/makedep/Main.java
Normal file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* A system for calculating nwscript dependencies. Makes some assumptions specific
|
||||
* to the PRC setup.
|
||||
*/
|
||||
package prc.makedep;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
import static prc.Main.*;
|
||||
|
||||
|
||||
/**
|
||||
* Calculates nwscript dependencies.
|
||||
*
|
||||
* Usage: makedep [-aio?] targetlist
|
||||
* Options:
|
||||
* -a Append to outputfile. This option must be defined before -o
|
||||
* -n Ignore include file if not found
|
||||
* -sPATH[,PATH...] List of source directories
|
||||
* -oFILE Use FILE as outputfile, stdout assumed
|
||||
* -?, --help This text
|
||||
*
|
||||
*
|
||||
* @author Ornedan
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
static Map<String, NSSNode> scripts = new LinkedHashMap<String, NSSNode>();
|
||||
|
||||
protected static boolean append = false,
|
||||
ignoreMissing = false,
|
||||
error = false;
|
||||
static PrintStream oStrm = System.out;
|
||||
|
||||
/**
|
||||
* Main method. Entrypoint to the program
|
||||
*
|
||||
* @param args The arguments. See readMe() for accepted ones
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
HashMap<String, String> targetList = new LinkedHashMap<String, String>();
|
||||
List<String> targetListFileNames = new ArrayList<String>();
|
||||
boolean targetsFromStdin = false;
|
||||
|
||||
// Parse arguments
|
||||
for(int i = 0; i < args.length; i++) {//[-aio?] targetslist+
|
||||
// Parameter parseage
|
||||
String param = args[i];
|
||||
if(param.startsWith("-")) {
|
||||
if(param.startsWith("-s")) {
|
||||
getFiles(param.substring(2));
|
||||
}
|
||||
else if(param.startsWith("-o")) {
|
||||
setOutput(param.substring(2));
|
||||
}
|
||||
else {
|
||||
if(param.equals("--help")) readMe();
|
||||
else if(param.equals("-")) {
|
||||
targetsFromStdin = true;
|
||||
}
|
||||
else {
|
||||
for(char c : param.substring(1).toCharArray()){
|
||||
switch(c) {
|
||||
case 'a':
|
||||
append = true;
|
||||
break;
|
||||
case 'n':
|
||||
ignoreMissing = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
System.out.println("Unknown parameter: " + c);
|
||||
case '?':
|
||||
readMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// It's a targets list file
|
||||
targetListFileNames.add(param);
|
||||
}
|
||||
}
|
||||
|
||||
// Read targets from stdin if so specified
|
||||
Scanner scan;
|
||||
String targetName;
|
||||
if(targetsFromStdin) {
|
||||
scan = new Scanner(System.in);
|
||||
while(scan.hasNextLine()) {
|
||||
targetName = scan.nextLine().toLowerCase();
|
||||
// Strip everything after the .ncs from the line
|
||||
targetName = targetName.substring(0, targetName.indexOf(".ncs") + 4);
|
||||
targetList.put(NSSNode.getScriptName(targetName), targetName);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the target file list
|
||||
File targetListFile;
|
||||
for(String fileName : targetListFileNames) {
|
||||
targetListFile = new File(fileName);
|
||||
// Read the contents
|
||||
try {
|
||||
scan = new Scanner(targetListFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
err_pr.println("Error: Could not find file: " + fileName);
|
||||
error = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
while(scan.hasNextLine()) {
|
||||
targetName = scan.nextLine().toLowerCase();
|
||||
// Strip everything after the .ncs from the line
|
||||
targetName = targetName.substring(0, targetName.indexOf(".ncs") + 4);
|
||||
targetList.put(NSSNode.getScriptName(targetName), targetName);
|
||||
}
|
||||
}
|
||||
|
||||
// Input sanity checks
|
||||
if(targetList.size() == 0) {
|
||||
err_pr.println("Error: No targets specified.");
|
||||
error = true;
|
||||
}
|
||||
for(String target : targetList.keySet()) {
|
||||
if(scripts.get(target.toLowerCase()) == null) {
|
||||
err_pr.println("Error: Script file for target " + target + " not found in given source directories.");
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Terminate if errored
|
||||
if(error) System.exit(1);
|
||||
|
||||
// TODO: Load the files concurrently. I suspect it will give a slight performance boost
|
||||
//NSSNode[] debugArr = debugMap.values().toArray(new NSSNode[0]);
|
||||
for(NSSNode script: scripts.values())
|
||||
script.linkDirect();
|
||||
|
||||
// Check for errors again
|
||||
if(error) System.exit(1);
|
||||
|
||||
|
||||
// Start a depth-first-search to find all the include trees
|
||||
for(NSSNode node : scripts.values()){
|
||||
node.linkFullyAndGetIncludes(null);
|
||||
//node.printSelf(oStrm, append);
|
||||
}
|
||||
|
||||
// Do the printing
|
||||
for(String target : targetList.keySet()) {
|
||||
scripts.get(target.toLowerCase()).printSelf(oStrm, append, targetList.get(target));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints usage and terminates.
|
||||
*/
|
||||
private static void readMe() {
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
System.out.println("Usage: makedep [-aio?] targetslist+\n" +
|
||||
"Options:\n" +
|
||||
"-a Append to outputfile. This option must be defined before -o\n"+
|
||||
"-n Ignore include file if not found\n"+
|
||||
"-sPATH[,PATH...] List of source directories\n"+
|
||||
"-oFILE Use FILE as outputfile, stdout assumed\n" +
|
||||
"- Read targets from stdin. Same format as targets list files\n"+
|
||||
"-?, --help This text\n"+
|
||||
"\n"+
|
||||
"targetslist Name of a file containing a list of object (.ncs) files to\n"+
|
||||
" generate a make targets for.\n" +
|
||||
" File format is one path-to-target per line."
|
||||
);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks in the directories specified by the given list for .nss
|
||||
* files and adds them to the sources list.
|
||||
*
|
||||
* @param pathList comma-separated list of directories to look in
|
||||
*/
|
||||
private static void getFiles(String pathList){
|
||||
String[] paths = pathList.split(",");
|
||||
File[] files;
|
||||
String temp;
|
||||
for(String path : paths){
|
||||
files = new File(path).listFiles(new FileFilter(){
|
||||
public boolean accept(File file){
|
||||
return file.getName().endsWith(".nss");
|
||||
}
|
||||
});
|
||||
for(File file: files){
|
||||
temp = NSSNode.getScriptName(file.getName()).toLowerCase();
|
||||
if(!scripts.containsKey(temp))
|
||||
scripts.put(temp, new NSSNode(file.getPath()));
|
||||
else{
|
||||
err_pr.println("Error: Duplicate script file: " + temp);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the output to write the results to to a file specified by the
|
||||
* given filename.
|
||||
* If the file is not found, the program terminates.
|
||||
*
|
||||
* @param outFileName Name of the file to print results to
|
||||
*/
|
||||
private static void setOutput(String outFileName){
|
||||
try{
|
||||
oStrm = new PrintStream(new FileOutputStream(outFileName, append), true);
|
||||
}catch(FileNotFoundException e){
|
||||
err_pr.println("Error: Missing output file " + outFileName + "\nTerminating!");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/MakedepChecker$Node.class
Normal file
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/MakedepChecker$Node.class
Normal file
Binary file not shown.
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/MakedepChecker.class
Normal file
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/MakedepChecker.class
Normal file
Binary file not shown.
89
nwn/nwnprc/DocGen/trunk/prc/makedep/MakedepChecker.java
Normal file
89
nwn/nwnprc/DocGen/trunk/prc/makedep/MakedepChecker.java
Normal file
@@ -0,0 +1,89 @@
|
||||
package prc.makedep;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class MakedepChecker {
|
||||
private static class Node{
|
||||
private HashSet<String> deps = new HashSet<String>();
|
||||
private String full;
|
||||
|
||||
public Node(String full, String sdeps) {
|
||||
this.full = full;
|
||||
String[] sdepsar = sdeps.split(" ");
|
||||
for(String s : sdepsar)
|
||||
if(!s.equals(""))
|
||||
deps.add(s);
|
||||
}
|
||||
|
||||
public void compare(Node another){
|
||||
if(!(this.deps.containsAll(another.deps) && another.deps.containsAll(this.deps))){
|
||||
System.out.println("Differing lines:\n " + this.full + "\n " + another.full);
|
||||
if(!this.deps.containsAll(another.deps)){
|
||||
System.out.println(" Missing in olds:");
|
||||
HashSet<String> temp = another.deps;
|
||||
temp.removeAll(this.deps);
|
||||
for(String s : temp)
|
||||
System.out.println(" " + s);
|
||||
}
|
||||
if(!another.deps.containsAll(this.deps)){
|
||||
System.out.println(" Missing in news:");
|
||||
HashSet<String> temp = this.deps;
|
||||
temp.removeAll(another.deps);
|
||||
for(String s : temp)
|
||||
System.out.println(" " + s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Throwable{
|
||||
// Load old and new lists
|
||||
File odf = new File("oldmakedep.txt");
|
||||
File ndf = new File("newmakedep.txt");
|
||||
|
||||
HashMap<String, Node> olds = new HashMap<String, Node>();
|
||||
HashMap<String, Node> news = new HashMap<String, Node>();
|
||||
|
||||
Scanner scan = new Scanner(odf);
|
||||
while(scan.hasNextLine()){
|
||||
String s = scan.nextLine();
|
||||
if(s.equals(""))
|
||||
continue;
|
||||
String[] ss = s.split(":");
|
||||
olds.put(ss[0], new Node(s, ss[1]));
|
||||
}
|
||||
scan = new Scanner(ndf);
|
||||
while(scan.hasNextLine()){
|
||||
String s = scan.nextLine();
|
||||
if(s.equals(""))
|
||||
continue;
|
||||
String[] ss = s.split(":");
|
||||
news.put(ss[0], new Node(s, ss[1]));
|
||||
}
|
||||
|
||||
if(!(olds.keySet().containsAll(news.keySet()) &&
|
||||
news.keySet().containsAll(olds.keySet())
|
||||
)){
|
||||
System.out.println("Differing line counts!");
|
||||
|
||||
Set<String> foo = olds.keySet();
|
||||
foo.removeAll(news.keySet());
|
||||
System.out.println("Files not defined in news:");
|
||||
for(String s : foo)
|
||||
System.out.println(s);
|
||||
|
||||
|
||||
foo = news.keySet();
|
||||
foo.removeAll(olds.keySet());
|
||||
System.out.println("Files not defined in olds:");
|
||||
for(String s : foo)
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
for(String key : olds.keySet()){
|
||||
olds.get(key).compare(news.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/NSSNode$STATES.class
Normal file
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/NSSNode$STATES.class
Normal file
Binary file not shown.
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/NSSNode.class
Normal file
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/NSSNode.class
Normal file
Binary file not shown.
259
nwn/nwnprc/DocGen/trunk/prc/makedep/NSSNode.java
Normal file
259
nwn/nwnprc/DocGen/trunk/prc/makedep/NSSNode.java
Normal file
@@ -0,0 +1,259 @@
|
||||
package prc.makedep;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import static prc.Main.*;
|
||||
|
||||
/**
|
||||
* A node in an NWScript include tree.
|
||||
*
|
||||
* @author Ornedan
|
||||
*/
|
||||
public class NSSNode {
|
||||
private static enum STATES{
|
||||
/**
|
||||
* This node has not been visited yet in the full linking phase.
|
||||
*/
|
||||
UNSTARTED,
|
||||
/**
|
||||
* The depth-first-search has reached this node, but has not returned to it yet.
|
||||
*/
|
||||
WORKING,
|
||||
/**
|
||||
* All the includes for this node have been resolved.
|
||||
*/
|
||||
DONE};
|
||||
|
||||
private STATES state = STATES.UNSTARTED;
|
||||
|
||||
/**
|
||||
* While the node is in WORKING state, it's includes have not been resolved yet.
|
||||
* So, if a circular include is found, it is added here so that this node's includes
|
||||
* can be added to it's list once the DFS returns to this node.
|
||||
*/
|
||||
private HashSet<NSSNode> mergeLater = new HashSet<NSSNode>();
|
||||
|
||||
/**
|
||||
* A container for marking files that are already being handled during a merging cascade.
|
||||
*/
|
||||
private static HashSet<NSSNode> inMerge;
|
||||
|
||||
/**
|
||||
* The nodes included directly by this node via #include statements.
|
||||
*/
|
||||
private HashSet<NSSNode> adjenct = new LinkedHashSet<NSSNode>();
|
||||
|
||||
/**
|
||||
* The nodes included by this node either directly or via intermediary steps. Also,
|
||||
* each file is considered to include itself in order to make printing include lists
|
||||
* a bit less complex.
|
||||
*/
|
||||
private HashSet<NSSNode> includes = new LinkedHashSet<NSSNode>();
|
||||
|
||||
/**
|
||||
* The first node to call linkFullyAndGetIncludes() on this node.
|
||||
*/
|
||||
public NSSNode priCaller;
|
||||
|
||||
/**
|
||||
* The path used to reference this file.
|
||||
*/
|
||||
public String fileName;
|
||||
|
||||
/**
|
||||
* Creates a new, unlinked NSSNode
|
||||
*
|
||||
* @param fileName
|
||||
*/
|
||||
public NSSNode(String fileName) {
|
||||
fileName = fileName.toLowerCase();
|
||||
// Make sure the file exists
|
||||
if(!new File(fileName).exists()){
|
||||
Main.error = true;
|
||||
err_pr.println("Error: Missing script file: " + fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
// Each node is dependent on itself
|
||||
includes.add(this);
|
||||
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Link this script file to those files it directly includes.
|
||||
*/
|
||||
public void linkDirect(){
|
||||
// Load the text for this file
|
||||
File file = new File(fileName);
|
||||
char[] cArray = new char[(int)file.length()];
|
||||
try{
|
||||
FileReader fr = new FileReader(fileName);
|
||||
fr.read(cArray);
|
||||
fr.close();
|
||||
}catch(Exception e){
|
||||
err_pr.println("Error: Error while reading file: " + fileName);
|
||||
Main.error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Debuggage
|
||||
if(fileName.indexOf("psi_inc_psifunc") != -1)
|
||||
System.currentTimeMillis();
|
||||
//*/
|
||||
|
||||
|
||||
String[] directIncludes = NWScript.findIncludes(new String(cArray));
|
||||
|
||||
for(String name : directIncludes){
|
||||
name = name.toLowerCase();
|
||||
NSSNode adj = Main.scripts.get(name);
|
||||
if(adj != null){
|
||||
if(adjenct.contains(adj))
|
||||
//System.out.println("Warning: " + getScriptName(fileName) + " includes " + getScriptName(adj.fileName) + " multiple times");
|
||||
System.out.printf("Warning: %-16s includes %-16s multiple times\n",
|
||||
getScriptName(fileName),
|
||||
getScriptName(adj.fileName)
|
||||
);
|
||||
adjenct.add(adj);
|
||||
}else if(!Main.ignoreMissing){
|
||||
System.out.println("Script file not found: " + name);
|
||||
Main.error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the full list of files included by this script.
|
||||
*
|
||||
* @param caller the node calling this function recursively passes a reference
|
||||
* to itself. Used in cases where the target node was already in
|
||||
* WORKING state.
|
||||
* @return HashSet containing the fully resolved list of files included by this one
|
||||
*/
|
||||
public HashSet<NSSNode> linkFullyAndGetIncludes(NSSNode caller) {
|
||||
if(state != STATES.UNSTARTED)
|
||||
if(state == STATES.DONE)
|
||||
return includes;
|
||||
else{
|
||||
// Add to a list to merge include lists later once this node is done
|
||||
NSSNode toMergeLater = caller;
|
||||
while(toMergeLater != this){
|
||||
mergeLater.add(toMergeLater);
|
||||
toMergeLater = toMergeLater.priCaller;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/* Debuggage stuff
|
||||
if(//fileName.indexOf("ss_ep_psionicsal") != -1 ||
|
||||
//fileName.indexOf("psi_inc_psifunc") != -1 ||
|
||||
//fileName.indexOf("prc_alterations") != -1 ||
|
||||
//fileName.indexOf("bonsum_shapelem") != -1 ||
|
||||
fileName.indexOf("pnp_shft_poly") != -1 ||
|
||||
false
|
||||
)
|
||||
System.currentTimeMillis();
|
||||
//*/
|
||||
// Mark the node as work-in-progress, so it won't be handled again
|
||||
state = STATES.WORKING;
|
||||
priCaller = caller;
|
||||
// Initialize the includes list for this script with the direct includes
|
||||
includes.addAll(adjenct);
|
||||
|
||||
HashSet<NSSNode> temp;
|
||||
for(NSSNode adj : adjenct){
|
||||
temp = adj.linkFullyAndGetIncludes(this);
|
||||
if(temp != null)
|
||||
includes.addAll(temp);
|
||||
}
|
||||
|
||||
// Do the delayed include list merges
|
||||
inMerge = new HashSet<NSSNode>();
|
||||
this.doMerge();
|
||||
/*for(NSSNode node : mergeLater)
|
||||
node.includes.addAll(this.includes);*/
|
||||
inMerge = null;
|
||||
|
||||
state = STATES.DONE;
|
||||
return includes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the include list of this file with all files that included this one while
|
||||
* it was still being worked on. Recurses to each of these files in order to update
|
||||
* files dependent on them.
|
||||
*/
|
||||
private void doMerge(){
|
||||
for(NSSNode node : mergeLater){
|
||||
if(!inMerge.contains(node)){
|
||||
inMerge.add(node);
|
||||
node.includes.addAll(this.includes);
|
||||
node.doMerge();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name used in include statements for the given filename.
|
||||
*
|
||||
* @param path the path to parse
|
||||
* @return string, name used in include statements
|
||||
*/
|
||||
public static String getScriptName(String path) {
|
||||
// Cut out the .nss or .ncs
|
||||
try{
|
||||
path = path.substring(0, path.indexOf(".nss") != -1 ? path.indexOf(".nss") : path.indexOf(".ncs"));
|
||||
}catch(Exception e){
|
||||
err_pr.println(path);
|
||||
}
|
||||
|
||||
// Cut out the directories, if present
|
||||
if(path.indexOf(File.separator) != -1)
|
||||
path = path.substring(path.lastIndexOf(File.separator) + 1, path.length());
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints this node's list of includes to a stream.
|
||||
*
|
||||
* @param strm stream to print to
|
||||
* @param append if this is <code>true</code>, the PrintStream's <code>append</code> methods
|
||||
* are used instead of <code>print</code> methods.
|
||||
* @param target name of the object file to be built from this script
|
||||
*/
|
||||
public void printSelf(PrintStream strm, boolean append, String target) {
|
||||
String lineSeparator = System.getProperty("line.separator");
|
||||
if(append){
|
||||
//strm.append(fileName.replace(".nss", ".ncs") + ":"/* + fileName*/);
|
||||
strm.append(target + ":");
|
||||
for(NSSNode include : includes)
|
||||
strm.append(" " + include.fileName);
|
||||
strm.append(lineSeparator + lineSeparator);
|
||||
}else{
|
||||
strm.print(target + ":");
|
||||
for(NSSNode include : includes)
|
||||
strm.print(" " + include.fileName);
|
||||
strm.print(lineSeparator + lineSeparator);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A test main.
|
||||
*
|
||||
* @param args Ye olde parameters. Doesn't accept any
|
||||
*/
|
||||
public static void main(String[] args){
|
||||
System.out.println(getScriptName("C:\\foo\\bar\\meh.nss"));
|
||||
System.out.println(getScriptName("boo.nss"));
|
||||
System.out.println(getScriptName("lar\\floob.nss"));
|
||||
}
|
||||
|
||||
/**
|
||||
* An NSSNode's string representation is it's filename.
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString(){return fileName;}
|
||||
}
|
||||
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/NWScript$1.class
Normal file
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/NWScript$1.class
Normal file
Binary file not shown.
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/NWScript$STATES.class
Normal file
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/NWScript$STATES.class
Normal file
Binary file not shown.
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/NWScript.class
Normal file
BIN
nwn/nwnprc/DocGen/trunk/prc/makedep/NWScript.class
Normal file
Binary file not shown.
144
nwn/nwnprc/DocGen/trunk/prc/makedep/NWScript.java
Normal file
144
nwn/nwnprc/DocGen/trunk/prc/makedep/NWScript.java
Normal file
@@ -0,0 +1,144 @@
|
||||
package prc.makedep;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
|
||||
|
||||
/**
|
||||
* A class for parsing NWScript files.
|
||||
*
|
||||
* @author Ornedan
|
||||
*/
|
||||
public class NWScript {
|
||||
private static enum STATES{
|
||||
/**
|
||||
* Normal code, can switch to the other modes from here.
|
||||
*/
|
||||
NORMAL,
|
||||
/**
|
||||
* String mode. Exited by an unescaped " (technically should be ended
|
||||
* by a new line as well, but we assume the code is not that badly fubar'd).
|
||||
*/
|
||||
STRING,
|
||||
/**
|
||||
* Singe line comment, started by //. Exited by a newline.
|
||||
*/
|
||||
SCOMMENT,
|
||||
/**
|
||||
* Multi-line comment.
|
||||
*/
|
||||
MCOMMENT
|
||||
};
|
||||
|
||||
private static Matcher matcher = Pattern.compile("#include[ \t\u000B\f\r]*\"(.*)\"").matcher("");
|
||||
|
||||
|
||||
/**
|
||||
* Parses the given source text for #include directives and returns the names of
|
||||
* the files included.
|
||||
*
|
||||
* @param srcText contents of a nwscript source file
|
||||
* @return array of String containing the names of files included by this one
|
||||
*/
|
||||
public static String[] findIncludes(CharSequence srcText){
|
||||
StringBuffer wip = new StringBuffer(srcText);
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
|
||||
removeComments(wip);
|
||||
|
||||
// Parse for remaining #include statements
|
||||
//#include[ \t\x0B\f\r]*"(.*)"
|
||||
matcher.reset(wip);
|
||||
//String debug;
|
||||
while(matcher.find()){
|
||||
//debug = matcher.group(1);
|
||||
//list.add(debug);
|
||||
list.add(matcher.group(1));
|
||||
}
|
||||
|
||||
|
||||
return list.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the contents of comments with spaces.
|
||||
*
|
||||
* @param sbuf Stringbuffer containing nwscript to strip comments from
|
||||
*/
|
||||
private static void removeComments(StringBuffer sbuf){
|
||||
STATES state = STATES.NORMAL;
|
||||
char prev = '\u0000', cur;
|
||||
boolean evenBSlash = true;
|
||||
|
||||
for(int i = 0; i < sbuf.length(); i++){
|
||||
cur = sbuf.charAt(i);
|
||||
switch(state){
|
||||
case NORMAL:
|
||||
if(prev == '/'){
|
||||
if(cur == '/'){
|
||||
state = STATES.SCOMMENT;
|
||||
sbuf.setCharAt(i - 1, ' ');
|
||||
sbuf.setCharAt(i, ' ');
|
||||
}
|
||||
else if(cur == '*'){
|
||||
state = STATES.MCOMMENT;
|
||||
sbuf.setCharAt(i - 1, ' ');
|
||||
sbuf.setCharAt(i, ' ');
|
||||
|
||||
// Null current so that /*/ won't get mistakenly detected as having closed
|
||||
cur = ' ';
|
||||
}
|
||||
}
|
||||
else if(cur == '\"')
|
||||
state = STATES.STRING;
|
||||
break;
|
||||
case STRING:
|
||||
if(cur == '\"'){
|
||||
if(evenBSlash)
|
||||
state = STATES.NORMAL;
|
||||
}
|
||||
else if(cur == '\\')
|
||||
evenBSlash = !evenBSlash;
|
||||
else
|
||||
evenBSlash = true;
|
||||
break;
|
||||
case SCOMMENT:
|
||||
if(cur == '\n')
|
||||
state = STATES.NORMAL;
|
||||
else
|
||||
sbuf.setCharAt(i, ' ');
|
||||
break;
|
||||
case MCOMMENT:
|
||||
if(prev == '*' && cur == '/')
|
||||
state = STATES.NORMAL;
|
||||
|
||||
sbuf.setCharAt(i, ' ');
|
||||
break;
|
||||
}
|
||||
|
||||
prev = cur;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test main
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
findIncludes(
|
||||
"/**\n" +
|
||||
" * Mof! \" \"\n" +
|
||||
" */\n" +
|
||||
"#include \"test\"\n" +
|
||||
"#include \"tset\"\n" +
|
||||
"/*/ */\n"+
|
||||
"\n"+
|
||||
"void main()\n"+
|
||||
"{// Rar!\n"+
|
||||
" florb(); /* call florb */\n"+
|
||||
" /* another call */ florb();\n"+
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user