package tools;
import java.io.*;
import java.util.*;
import java.util.regex.*;
public class SourceConverter
{
public static void main(String[] args) throws IOException
{
String outputDir = ".";
String outputPackage = "org.jpc.emulator.peripheral";
String inputFile = "/home/ian/jpc/bochs/bochs-2.6.1/iodev/floppy.cc";
String[] inputHeader = new String[] {"/home/ian/jpc/bochs/bochs-2.6.1/iodev/floppy.h", "floppy_include.txt"};
for (int i=0; i < args.length; i++)
{
if (args[i].equals("-output"))
{
outputDir = args[i+1];
i++;
}
else if (args[i].equals("-package"))
{
outputPackage = args[i+1];
i++;
}
else if (args[i].equals("-input"))
{
inputFile = args[i+1];
i++;
}
}
File outRoot = new File(outputDir);
File outDir = new File(outRoot, outputPackage.replaceAll("\\.", "/"));
File inFile = new File(inputFile);
String name = inFile.getName().replaceAll("\\.cc", "");
File outFile = new File(outDir, name + ".java");
StringBuilder b =new StringBuilder();
for (String header: inputHeader)
{
BufferedReader r = new BufferedReader(new FileReader(header));
String line;
while ((line = r.readLine()) != null)
b.append(line + "\n");
}
{
BufferedReader r = new BufferedReader(new FileReader(inFile));
String line;
while ((line = r.readLine()) != null)
b.append(line + "\n");
}
String result = convert(b.toString(), getRegex());
BufferedWriter w = new BufferedWriter(new FileWriter(outFile));
writeHeader(w, outputPackage, name);
w.write(result.toString());
writeFooter(w);
w.flush();
w.close();
}
private static void writeHeader(BufferedWriter w, String pack, String name) throws IOException {
w.append("package "+ pack+";\n\n");
w.append("import org.jpc.support.*;\n");
w.append("public class "+ name + "\n{\n");
w.append("private static final boolean DEBUG = false;\n");
}
private static void writeFooter(BufferedWriter w) throws IOException {
w.append("}");
}
private static List<Pair> getRegex() throws IOException
{
List<Pair> reg = new ArrayList();
BufferedReader r = new BufferedReader(new FileReader("floppy_regex.txt"));
String line;
while ((line = r.readLine()) != null)
reg.add(new Pair(line, r.readLine()));
return reg;
}
private static String[] complex_types = new String[] {"floppy_t", "floppy_type_t"};
private static String[] primitives = new String[] {"int"};
private static String[] functionsToDelete = new String[] {"int libfloppy_LTX_plugin_init", "void libfloppy_LTX_plugin_fini", "bx_floppy_ctrl_c", "~bx_floppy_ctrl_c"};
private static Map<String, Boolean> macros = new HashMap();
static {
macros.put("BX_DEBUGGER", false);
macros.put("BX_USE_FD_SMF", false);
}
private static String convert(String in, List<Pair> regex)
{
// simple regex
for (Pair p: regex)
in = in.replaceAll(p.key, p.value);
// more complex replacements (single layer structs)
for (String type: complex_types)
{
// definition
Pattern def = Pattern.compile("typedef struct \\{([\\w\\s;/\\*]+)\\} "+type+";");
Matcher matcher = def.matcher(in);
if (matcher.find())
{
String body = matcher.group(1);
String[] lines = body.trim().split("\n");
for (int i=0; i < lines.length; i++)
{
if (lines[i].length() == 0)
continue;
lines[i] = lines[i].substring(0, lines[i].indexOf(";")); // ignore comments after ;
lines[i] = lines[i].replaceAll("[\\s]+", " "); // contract spaces
}
String args = "";
for (String arg: lines)
{
if (arg.trim().length() == 0)
continue;
args += arg.trim() + ", ";
}
args = args.substring(0, args.length()-2);
String constructorBody = "";
for (String arg: lines)
{
if (arg.trim().length() == 0)
continue;
String name = arg.trim().split(" ")[1];
constructorBody += " this."+name + " = "+name+";\n";
}
in = in.replaceAll("typedef struct \\{([\\w\\s;/\\*]+)\\} "+type+";", "static class "+type+"\n{\n$1\n public "+type+"("+args+")\n {\n"+constructorBody+" }\n}");
}
// Array uses of type
while (true)
{
String pat = type + "[\\s]+([\\w]+)\\[[\\d]+\\][\\s]+=[\\s]+\\{([\\w\\s,\\{\\}]+)\\};";
Pattern arr = Pattern.compile(pat);
Matcher match = arr.matcher(in);
if (match.find())
{
String name = match.group(1);
String body = match.group(2);
// find array elements
String [] lines = body.trim().split("},");
String newbody = "";
for (int i=0; i < lines.length; i++)
{
if (lines[i].length() == 0)
continue;
lines[i] = lines[i].trim();
lines[i] = lines[i].replaceAll("[\\s]+", " "); // contract spaces
if (lines[i].startsWith("{"))
{
lines[i] = "new "+type+"("+lines[i].substring(1, lines[i].length()-1)+")";
}
newbody += " "+ lines[i]+", \n";
}
newbody = newbody.substring(0, newbody.length()-3);
String namedPat = type + "[\\s]+" + name + "\\[[\\d]+\\][\\s]+=[\\s]+\\{([\\w\\s,\\{\\}]+)\\};";
in = in.replaceAll(namedPat, type + "[] "+name + " = new "+type+"[] {\n"+newbody+"};");
continue;
}
break;
}
}
// arrays of primitive types
for (String type: primitives)
while (true)
{
String pat = type + "[\\s]+([\\w]+)\\[[\\d]+\\][\\s]+=[\\s]+\\{([\\w\\s,\\{\\}]+)\\};";
Pattern arr = Pattern.compile(pat);
Matcher match = arr.matcher(in);
if (match.find())
{
String name = match.group(1);
String body = match.group(2);
// find array elements
String [] lines = body.trim().split(",");
String newbody = "";
for (int i=0; i < lines.length; i++)
{
if (lines[i].length() == 0)
continue;
lines[i] = lines[i].trim();
lines[i] = lines[i].replaceAll("[\\s]+", " "); // contract spaces
newbody += lines[i]+", ";
}
newbody = newbody.substring(0, newbody.length()-2);
String namedPat = type + "[\\s]+" + name + "\\[[\\d]+\\][\\s]+=[\\s]+\\{([\\w\\s,\\{\\}]+)\\};";
in = in.replaceAll(namedPat, type + "[] "+name + " = new "+type+"[] {"+newbody+"};");
continue;
}
break;
}
// delete unnecessary functions
for (String func: functionsToDelete)
{
while (in.contains(func))
{
int start = in.indexOf(func);
int end = start+func.length();
while (in.charAt(end) != ')')
end++;
while (in.charAt(end) != '{')
end++;
// find matching bracket to opening bracket // assume they match and no comments contain {}'s!
int open = 1;
end++;
while (open > 0)
{
if (in.charAt(end) == '{')
{open++;System.out.println("Open: "+open + " " + in.substring(start, end+1));}
else if (in.charAt(end) == '}')
{open--;System.out.println("Open: "+open + " " + in.substring(start, end+1));}
end++;
}
//System.out.println("Removing: " + in.substring(start, end));
in = in.substring(0, start) + in.substring(end);
}
}
return in;
}
private static class Pair
{
String key, value;
public Pair(String key, String value)
{
this.key= key;
this.value = value;
}
}
}