--- /dev/null
+/* $Id: ProtothreadProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.protothread;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.StringTokenizer;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import dol.datamodel.pn.Channel;
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.datamodel.pn.SourceCode;
+import dol.util.CodePrintStream;
+import dol.util.Sed;
+import dol.visitor.PNVisitor;
+
+/**
+ *
+ */
+public class ProtothreadProcessVisitor extends PNVisitor {
+
+ /**
+ * Constructor.
+ */
+ public ProtothreadProcessVisitor(String dir) {
+ _dir = dir;
+ }
+
+ /**
+ *
+ */
+ public void visitComponent(ProcessNetwork x) {
+ try {
+ Vector<String> processList = new Vector<String>();
+ for (Process p : x.getProcessList()) {
+ String basename = p.getBasename();
+ if (!processList.contains(basename)) {
+ processList.add(basename);
+ p.accept(this);
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("Process Visitor: exception " +
+ "occured: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ *
+ */
+ public void visitComponent(Process p) {
+ try {
+ _createCppFile(p);
+ _createHeaderFile(p);
+ _adaptSources(p);
+ }
+ catch (Exception e) {
+ System.out.println("Process Visitor: exception "
+ + "occured: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ *
+ */
+ private void _createCppFile(Process p)
+ throws IOException {
+ String classname = p.getBasename() + "Wrapper";
+ String filename = _dir + _delimiter + classname + ".cpp";
+ OutputStream file = new FileOutputStream(filename);
+ CodePrintStream ps = new CodePrintStream(file);
+
+ ps.printPrefixln("#include \"" + classname + ".h\"");
+ ps.printPrefixln("#include \"dolSupport.h\"");
+ ps.printPrefixln("#include <string.h>");
+ ps.println();
+ for (SourceCode sr : p.getSrcList()) {
+ ps.printPrefixln("#include \"" + "../processes/"
+ + sr.getLocality() + "\"");
+ }
+ ps.println();
+ ps.printPrefixln(classname + "::" + classname
+ + "(char* name, int iteratorIndex[4]) :");
+ ps.printPrefixln(" ProcessWrapper(name, iteratorIndex)");
+ ps.printLeftBracket();
+ //ps.printPrefixln("_state = new struct _local_states;");
+ //ps.printPrefixln("memcpy(_state, " + p.getBasename() + ".local, "
+ // + "sizeof(struct _local_states));");
+ //ps.printPrefixln("memcpy(&_process, &" + p.getBasename()
+ // + ", sizeof(DOLProcess));");
+ ps.printPrefixln("_state = (LocalState)new "
+ + p.getBasename().substring(0, 1).toUpperCase()
+ + p.getBasename().substring(1) + "_State;");
+ ps.printPrefixln("_process.init = " + p.getBasename() + "_init;");
+ ps.printPrefixln("_process.fire = " + p.getBasename() + "_fire;");
+ ps.printPrefixln("_process.local = _state;");
+ ps.printPrefixln("_process.wptr = (void*)&_wrapper_data;");
+ ps.printPrefixln("_wrapper_data.wrapper = this;");
+ ps.printRightBracket();
+ ps.println();
+ ps.printPrefixln(classname + "::~" + classname + "()");
+ ps.printLeftBracket();
+ ps.printPrefixln("if (_state)");
+ ps.printPrefixln(" delete ("
+ + p.getBasename().substring(0, 1).toUpperCase()
+ + p.getBasename().substring(1) + "_State*)_state;");
+ //ps.printPrefixln(" delete _state;");
+ ps.printRightBracket();
+ }
+
+ /**
+ *
+ */
+ private void _createHeaderFile(Process p)
+ throws IOException {
+ String classname = p.getBasename() + "Wrapper";
+ String filename = _dir + _delimiter + classname + ".h";
+ OutputStream file = new FileOutputStream(filename);
+ CodePrintStream ps = new CodePrintStream(file);
+
+ ps.printPrefixln("#ifndef " + classname.toUpperCase()
+ + "_H");
+ ps.printPrefixln("#define " + classname.toUpperCase()
+ + "_H");
+ ps.println();
+ ps.printPrefixln("#include \"ProcessWrapper.h\"");
+ ps.printPrefixln("#include \"Fifo.h\"");
+ ps.printPrefixln("#include \"WindowedFifo.h\"");
+ ps.println();
+ ps.printPrefixln("class " + classname + ";");
+ ps.println();
+ ps.printPrefixln("typedef struct _" + p.getBasename()
+ + "_data {");
+ ps.printPrefixln(" int lc;");
+ ps.printPrefixln(" " + classname + " *wrapper;");
+ ps.printPrefixln("} " + p.getBasename() + "_data;");
+ ps.println();
+ ps.printPrefixln("class " + classname +
+ " : public ProcessWrapper");
+ ps.printLeftBracket();
+ ps.printPrefixln("public:");
+ ps.printPrefixln(" " + classname + "(char* name, "
+ + "int iteratorIndex[4]);");
+ ps.printPrefixln(" virtual ~" + classname + "();");
+ ps.println();
+
+ Vector<String> basenames = new Vector<String>();
+ for (Port port : p.getPortList()) {
+ if (!basenames.contains(port.getBasename())) {
+ basenames.add(port.getBasename());
+ } else {
+ continue;
+ }
+
+ Channel c = (Channel)port.getPeerResource();
+ if (port.getName().equals(port.getBasename())) {
+ if (c.getType().equals("fifo")) {
+ ps.printPrefixln(" Fifo* _port" + port.getName()
+ + "Fifo;");
+ } else if (c.getType().equals("wfifo")) {
+ ps.printPrefixln(" WindowedFifo* _port"
+ + port.getName() + "Fifo;");
+ }
+ } else {
+ if (c.getType().equals("fifo")) {
+ ps.printPrefix(" Fifo* _port"
+ + port.getBasename()
+ + "Fifo");
+ } else if (c.getType().equals("wfifo")) {
+ ps.printPrefix(" WindowedFifo* _port"
+ + port.getBasename()
+ + "Fifo");
+ }
+ StringTokenizer tokenizer =
+ new StringTokenizer(port.getRange(), ";");
+ while (tokenizer.hasMoreTokens()) {
+ ps.print("[" + tokenizer.nextToken()
+ + "]");
+ }
+ ps.println(";");
+ }
+ }
+ ps.println("");
+ ps.printPrefixln("protected:");
+ ps.printPrefixln(" struct _local_states *_state;");
+ ps.printPrefixln(" " + p.getBasename()
+ + "_data _wrapper_data;");
+ ps.printRightBracket();
+
+ ps.printPrefixln(";");
+ ps.println();
+ ps.printPrefixln("#endif");
+ }
+
+ /**
+ * Make modifications to source files of a process.
+ * Port names need to be strings for the SystemC code generation.
+ * Therefore, in the header files integer port names are put into
+ * quotation marks.
+ *
+ * @param p process whose sources should be adapted
+ * @throws IOException
+ */
+ protected void _adaptSources(Process p) throws IOException {
+ Sed sed = new Sed();
+ //modify header file
+ for (Port port : p.getPortList()) {
+ String processHeaderFile;
+
+ for (SourceCode sr : p.getSrcList()) {
+ processHeaderFile = _dir + _delimiter + ".."
+ + _delimiter + "processes" + _delimiter
+ + sr.getLocality().
+ replaceAll("(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
+
+ sed.sed(processHeaderFile,
+ "(#define[ ]+PORT_\\w*[ ]+)\"?"
+ + port.getBasename() + "\"?",
+ "$1 " + "static_cast<" + p.getBasename()
+ + "Wrapper *>((static_cast<" + p.getBasename()
+ + "_data *>(p->wptr))->wrapper)->_port"
+ + port.getBasename() + "Fifo");
+ }
+ }
+
+ //modify source file
+ for (SourceCode sr : p.getSrcList()) {
+ String processSourceFile = _dir + _delimiter + ".."
+ + _delimiter + "processes" + _delimiter
+ + sr.getLocality();
+
+ String line;
+ StringBuffer buffer = new StringBuffer();
+ FileInputStream fileInputStream = new FileInputStream(
+ processSourceFile);
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(fileInputStream));
+ while((line = reader.readLine()) != null) {
+ buffer.append(line + "\n");
+ }
+ reader.close();
+
+ String file = buffer.toString();
+ //insert PT_BEGIN() at beginning of fire() function
+ file = file.replaceAll(
+ "(int[ ]*" + p.getBasename()
+ + "_fire[ ]*\\([ ]*DOLProcess[ ]*\\*p[ ]*\\)"
+ + "[\\s\\S&&[^\\{]]*)\\{",
+ "$1" + System.getProperty("line.separator") + "{"
+ + System.getProperty("line.separator") +
+ " PT_BEGIN((pt*)(p->wptr));");
+
+ //replace last return statement in fire function by PT_END()
+ //find beginning of fire function
+ Matcher matcher = Pattern.compile(
+ "(int[ ]*" + p.getBasename()
+ + "_fire[ ]*\\([ ]*DOLProcess[ ]*\\*p[ ]*\\)"
+ + "[\\s\\S&&[^\\{]]*)\\{").matcher(file);
+ matcher.find();
+ int i = 0;
+ try {
+ i = matcher.start();
+ } catch (Exception e) {
+ System.out.println("Error: could not find "
+ + p.getBasename() + "_fire() function in "
+ + processSourceFile + ".");
+ e.printStackTrace();
+ }
+ int openBraces = 0; //counter for open curly braces
+ //position of last return statement
+ int lastReturnStartPosition = 0;
+ int lastReturnEndPosition = 0;
+ while (i < file.length()) {
+ //ignore single-line comments
+ if (i < (file.length() - 1) &&
+ file.substring(i, i + 2).equals("//")) {
+ while (!file.substring(i, i + 1).equals("\n")) {
+ i++;
+ }
+ }
+ //ignore multi-line comments
+ else if (i < (file.length() - 1) &&
+ file.substring(i, i + 2).equals("/*")) {
+ while (!file.substring(i, i + 2).equals("*/")) {
+ i++;
+ }
+ }
+ //ignore strings
+ else if (file.substring(i, i + 1).equals("\"")) {
+ matcher = Pattern.compile("[\\s\\S&&[^\\\\]]\\\"").
+ matcher(file);
+ matcher.find(i + 1);
+ i = matcher.start() + 1;
+ }
+ else if (i < (file.length() - 5) &&
+ file.substring(i, i + 6).equals("return")) {
+ lastReturnStartPosition = i;
+ while (!file.substring(i, i + 1).equals(";")) {
+ i++;
+ }
+ lastReturnEndPosition = i;
+ } else if (file.substring(i, i + 1).equals("{")) {
+ openBraces++;
+ } else if (file.substring(i, i + 1).equals("}")) {
+ openBraces--;
+ if (openBraces == 0) {
+ break;
+ }
+ }
+ i++;
+ }
+
+ file = file.substring(0, lastReturnStartPosition) + "/* "
+ + file.substring(lastReturnStartPosition,
+ lastReturnEndPosition + 1)
+ + " (commented out by DOL) */"
+ + System.getProperty("line.separator")
+ + " PT_END((pt*)(p->wptr));"
+ + System.getProperty("line.separator")
+ + file.substring(lastReturnEndPosition + 2,
+ file.length());
+
+ BufferedWriter out = new BufferedWriter(new
+ FileWriter(processSourceFile));
+ out.write(file);
+ out.close();
+ }
+ }
+
+ protected String _dir = null;
+ CodePrintStream _wrapperHeader;
+}