/******************************************************************************* * GenBData.cc BEAM Data output * T.Barnaby, BEAM Ltd, 12/9/03 ******************************************************************************* */ #define DEBUG 1 #include <stdio.h> #include <stdarg.h> #include <strings.h> #include <GenBData.h> #include <bidl.h> void GenBData::produceInt(Node* n){ BIter i; BString s; BString s1; BString c; BList<Node*>* nl; BString typeName; BString baseClass; switch(n->nodeType()){ case Node::TMODULE: omodule = n->name(); ofileInt.writeLine(BString("namespace ") + omodule + " {\n"); ofileInt.indentMore(); for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){ produceInt(n->nodes()[i]); } ofileInt.indentLess(); ofileInt.writeLine("}\n"); break; case Node::TLIST: for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){ produceInt(n->nodes()[i]); } break; case Node::TSTRUCT: // Ignore internal objects if((n->name() == "BObjData") || (n->name() == "BObject") || (n->name() == "BObj")) return; typeName = BString("") + n->name(); baseClass = getBaseClass(n); if((baseClass ==" BObjData") || (baseClass == "BObject")){ oobjType = ObjTypeBObject; ofileInt.writeLine(BString("class ") + typeName + " : public " + getTypeName(n->node(1)->node(0), 1) + " {\n"); } else if(baseClass == "BObj"){ oobjType = ObjTypeBObj; ofileInt.writeLine(BString("class ") + typeName + " : public " + getTypeName(n->node(1)->node(0), 1) + " {\n"); } else { ofileInt.writeLine(BString("class ") + typeName + " {\n"); oobjType = ObjTypeStd; } ofileInt.writeLine("public:\n"); ofileInt.indentMore(); if(oobjType == ObjTypeBObject){ ofileInt.writeLine(typeName + "();\n"); ofileInt.writeLine("static BObject* createObj();\n"); ofileInt.writeLine("static BType otype;\n"); ofileInt.writeLine("BType& getType();\n"); ofileInt.writeLine("BMemberList getMemberList();\n"); } else { // Add default constructor // ofileInt.writeLine(typeName + "();\n"); // Add constructer to initialise parameters nl = &n->node(0)->nodes(); s = ""; for(nl->start(i); !nl->isEnd(i); nl->next(i)){ if(i != nl->begin()) s = s + ", "; if(nl->get(i)->nodeType() == Node::TSTRUCTITEM_ARRAYFIXED){ s = s + getTypeName(nl->get(i)->node(0), 0) + "* p" + nl->get(i)->node(1)->name(); s = s + " = 0"; } else { s = s + getTypeName(nl->get(i)->node(0), 0) + " p" + nl->get(i)->node(1)->name(); s = s + " = " + getTypeName(nl->get(i)->node(0), 0) + "()"; } } ofileInt.writeLine(typeName + "(" + s + ");\n"); if(oobjType == ObjTypeBObj){ ofileInt.writeLine("BString getType();\n"); ofileInt.writeLine("BError setMembers(BDictString& members);\n"); ofileInt.writeLine("BError setMember(BString name, BString value);\n"); ofileInt.writeLine("BError getMembers(BDictString& members);\n"); ofileInt.writeLine("BError getMember(BString name, BString& value);\n"); } } ofileInt.indentLess(); ofileInt.writeLine("public:\n"); ofileInt.indentMore(); nl = &n->node(0)->nodes(); for(nl->start(i); !nl->isEnd(i); nl->next(i)){ s = getTypeName(nl->get(i)->node(0), oobjType == ObjTypeBObject) + "\t"; s = s + "" + nl->get(i)->node(1)->name(); if(nl->get(i)->nodeType() == Node::TSTRUCTITEM_ARRAYFIXED){ s = s + "[" + nl->get(i)->node(2)->name() + "]"; } if(nl->get(i)->node(2) && nl->get(i)->node(2)->nodeType() == Node::TCOMMENT) c = BString("\t//") + nl->get(i)->node(2)->name(); else c = ""; ofileInt.writeLine(s + ";" + c + "\n"); } ofileInt.indentLess(); ofileInt.writeLine("};\n\n"); if(ooptions.hasKey("qt4")){ opostNamespace += BString("Q_DECLARE_METATYPE(") + omodule + "::" + typeName + ");\n"; } break; case Node::TCOMMENT: s = BString("//") + n->name() + "\n"; ofileInt.writeLine(s); break; case Node::TENUM: s = "enum "; if(n->node(0)){ s = s + n->node(0)->name() + " "; } else { s = s + "\t"; } s = s + "\t{ "; s1 = ""; nl = &n->node(1)->nodes(); for(nl->start(i); !nl->isEnd(i); nl->next(i)){ if(s1.len()) s1 += ", "; if(nl->get(i)->nodes().number() == 2){ s1 += nl->get(i)->node(0)->name(); s1 += " = "; s1 += nl->get(i)->node(1)->name(); } else { s1 += nl->get(i)->name(); } } ofileInt.writeLine(s + s1 + "};\n\n"); break; default: break; } } void GenBData::produceImp(Node* n){ BString s; BIter i; BList<Node*>* nl; BString typeName; BString parentTypeName; BString baseClass; switch(n->nodeType()){ case Node::TMODULE: omodule = n->name(); ofileImp.writeLine(BString("namespace ") + omodule + " {\n"); ofileImp.indentMore(); for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){ produceImp(n->nodes()[i]); } ofileImp.indentLess(); ofileImp.writeLine("}\n"); break; case Node::TLIST: for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){ produceImp(n->nodes()[i]); } break; case Node::TTYPEDOMAIN: otypeDomain = atoi(n->name()); break; case Node::TSTRUCT: if((n->name() == "BObjData") || (n->name() == "BObject") || (n->name() == "BObj")) return; typeName = BString("") + n->name(); baseClass = getBaseClass(n); if((baseClass ==" BObjData") || (baseClass == "BObject")){ oobjType = ObjTypeBObject; parentTypeName = getTypeName(n->node(1)->node(0), 1); } else if(baseClass == "BObj"){ oobjType = ObjTypeBObj; parentTypeName = getTypeName(n->node(1)->node(0), 1); } else { oobjType = ObjTypeStd; } ofileImp.writeLine("\n"); ofileImp.writeLine(BString("// ") + typeName + " Object Implementation\n"); if(oobjType == ObjTypeBObject){ ofileImp.writeLine(BString("BType ") + typeName + "::otype = btypesList.appendType(BType(\"" + typeName + "\", " + BString(otypeDomain) + ", " + BString(otypeNum) + ", createObj));\n"); ofileImp.writeLine(BString("BType& ") + typeName + "::getType(){\n"); ofileImp.indentMore(); ofileImp.writeLine(BString("return otype;\n")); ofileImp.indentLess(); ofileImp.writeLine("}\n"); ofileImp.writeLine(BString("BObject* ") + typeName + "::createObj(){\n"); ofileImp.indentMore(); ofileImp.writeLine(BString("return new ") + typeName + ";\n"); ofileImp.indentLess(); ofileImp.writeLine("}\n"); } // Add default constructor // ofileImp.writeLine(typeName + "::" + typeName + "(){\n"); // ofileImp.writeLine("}\n"); // Add constructer to initialise parameters nl = &n->node(0)->nodes(); s = ""; for(nl->start(i); !nl->isEnd(i); nl->next(i)){ if(i != nl->begin()) s = s + ", "; if(nl->get(i)->nodeType() == Node::TSTRUCTITEM_ARRAYFIXED){ s = s + getTypeName(nl->get(i)->node(0), 0) + "* p" + nl->get(i)->node(1)->name(); } else { s = s + getTypeName(nl->get(i)->node(0), 0) + " p" + nl->get(i)->node(1)->name(); } } ofileImp.writeLine(typeName + "::" + typeName + "(" + s + "){\n"); ofileImp.indentMore(); nl = &n->node(0)->nodes(); for(nl->start(i); !nl->isEnd(i); nl->next(i)){ s = ""; if(nl->get(i)->nodeType() == Node::TSTRUCTITEM_ARRAYFIXED){ s = s + "if(p" + nl->get(i)->node(1)->name() + "){\n"; ofileImp.writeLine(s); ofileImp.indentMore(); s = ""; s = s + "memcpy(" + nl->get(i)->node(1)->name(); s = s + ", p" + nl->get(i)->node(1)->name(); s = s + ", sizezof(" + nl->get(i)->node(1)->name() +"));"; ofileImp.writeLine(s + "\n"); ofileImp.indentLess(); ofileImp.writeLine("}\n"); } else { s = s + "" + nl->get(i)->node(1)->name(); s = s + " = p" + nl->get(i)->node(1)->name(); ofileImp.writeLine(s + ";\n"); } } ofileImp.indentLess(); ofileImp.writeLine("}\n"); if(oobjType == ObjTypeBObject){ ofileImp.writeLine(BString("BMemberList ") + typeName + "::getMemberList(){\n"); ofileImp.indentMore(); ofileImp.writeLine("BMemberList\tl;\n\n"); ofileImp.writeLine(BString("l = ") + parentTypeName + "::getMemberList();\n"); nl = &n->node(0)->nodes(); for(nl->start(i); !nl->isEnd(i); nl->next(i)){ s = nl->get(i)->node(1)->name(); ofileImp.writeLine(BString("l.append(BMember(\"") + s + "\", &" + s + "));\n"); } ofileImp.writeLine("return l;\n"); ofileImp.indentLess(); ofileImp.writeLine("}\n"); } if(oobjType == ObjTypeBObj){ int first; ofileImp.writeLine(BString("BString ") + typeName + "::getType(){ return \"" + typeName + "\"; }\n"); ofileImp.writeLine(BString("BError ") + typeName + "::getMembers(BDictString& members){\n"); ofileImp.indentMore(); ofileImp.writeLine("BError\terr;\n\n"); nl = &n->node(0)->nodes(); for(nl->start(i); !nl->isEnd(i); nl->next(i)){ s = nl->get(i)->node(1)->name(); if(s == "timePeriod") ofileImp.writeLine(s + ".getMembers(members);\n"); else ofileImp.writeLine(BString("toBString(") + s + ", members[\"" + s + "\"]);\n"); } ofileImp.writeLine("return err;\n"); ofileImp.indentLess(); ofileImp.writeLine("}\n"); ofileImp.writeLine(BString("BError ") + typeName + "::getMember(BString name, BString& value){\n"); ofileImp.indentMore(); ofileImp.writeLine("BError\terr;\n\n"); nl = &n->node(0)->nodes(); first = 1; for(nl->start(i); !nl->isEnd(i); nl->next(i)){ s = nl->get(i)->node(1)->name(); if(s != "timePeriod"){ if(first){ ofileImp.writeLine(BString("if(name == \"") + s + "\") toBString(" + s + ", value);\n"); first = 0; } else { ofileImp.writeLine(BString("else if(name == \"") + s + "\") toBString(" + s + ", value);\n"); } } } ofileImp.writeLine("return err;\n"); ofileImp.indentLess(); ofileImp.writeLine("}\n"); ofileImp.writeLine(BString("BError ") + typeName + "::setMembers(BDictString& members){\n"); ofileImp.indentMore(); ofileImp.writeLine("BError\terr;\n\n"); nl = &n->node(0)->nodes(); for(nl->start(i); !nl->isEnd(i); nl->next(i)){ s = nl->get(i)->node(1)->name(); if(s == "timePeriod") ofileImp.writeLine(s + ".setMembers(members);\n"); else ofileImp.writeLine(BString("fromBString(members[\"") + s + "\"], " + s + ");\n"); } ofileImp.writeLine("return err;\n"); ofileImp.indentLess(); ofileImp.writeLine("}\n"); ofileImp.writeLine(BString("BError ") + typeName + "::setMember(BString name, BString value){\n"); ofileImp.indentMore(); ofileImp.writeLine("BError\terr;\n\n"); nl = &n->node(0)->nodes(); first = 1; for(nl->start(i); !nl->isEnd(i); nl->next(i)){ s = nl->get(i)->node(1)->name(); if(s != "timePeriod"){ if(first){ ofileImp.writeLine(BString("if(name == \"") + s + "\") fromBString(value, " + s + ");\n"); first = 0; } else { ofileImp.writeLine(BString("else if(name == \"") + s + "\") fromBString(value, " + s + ");\n"); } } } ofileImp.writeLine("return err;\n"); ofileImp.indentLess(); ofileImp.writeLine("}\n"); } otypeNum++; break; default: break; } } BError GenBData::produceHeaderInt(){ BError err; BString fileName = ofileName + "D.h"; BString fileNameUpper = ofileName + "D_H"; fileNameUpper.toUpper(); ofileInt.printf("/*******************************************************************************\n"); ofileInt.printf(" *\t%s\tProduced by Bidl\n", fileName.retStr()); ofileInt.printf(" *******************************************************************************\n"); ofileInt.printf(" */\n"); ofileInt.printf("\n"); ofileInt.printf("#ifndef %s\n", fileNameUpper.retStr()); ofileInt.printf("#define %s 1\n\n", fileNameUpper.retStr()); ofileInt.printf("#include <Boap.h>\n"); ofileInt.printf("#include <BObj.h>\n"); ofileInt.printf("#include <BDate.h>\n"); ofileInt.printf("#include <BTimeStamp.h>\n"); ofileInt.printf("#include <BComplex.h>\n"); ofileInt.printf("#include <BList.h>\n"); ofileInt.printf("#include <BArray.h>\n"); if(getUseBObjects()){ ofileInt.printf("#include <BObjData.h>\n"); ofileInt.printf("#include <BObjInt.h>\n"); ofileInt.printf("#include <BObjString.h>\n"); ofileInt.printf("#include <BObjDate.h>\n"); ofileInt.printf("#include <BObjDateTime.h>\n"); ofileInt.printf("#include <BObjListVar.h>\n"); } if(ooptions.hasKey("qt4")){ ofileInt.printf("#include <QtCore/qmetatype.h>\n"); } ofileInt.printf("\n"); return err; } BError GenBData::produceTrailerInt(){ BError err; ofileInt.printf("%s\n", opostNamespace.retStr()); ofileInt.printf("#endif\n"); return err; } BError GenBData::produceHeaderImp(){ BError err; ofileImp.printf("/*******************************************************************************\n"); ofileImp.printf(" *\t%s\tProduced by Bidl\n", (ofileName + ".cc").retStr()); ofileImp.printf(" *******************************************************************************\n"); ofileImp.printf(" */\n"); ofileImp.printf("\n"); ofileImp.printf("#include <%s>\n", (ofileName + "D.h").retStr()); #ifdef ZAP1 ofileImp.printf("#include <BType.h>\n"); #endif ofileImp.printf("\n"); return err; } BError GenBData::produceTrailerImp(){ BError err; #ifdef ZAP1 // Produce Python Init ofileImp.writeLine("\n// Python module init\n"); ofileImp.writeLine("#include <Python.h>\n"); ofileImp.writeLine("\n"); ofileImp.writeLine("static PyMethodDef methods[] = {\n"); ofileImp.indentMore(); ofileImp.writeLine("{NULL, NULL}\n"); ofileImp.indentLess(); ofileImp.writeLine("};\n"); ofileImp.writeLine(BString("extern \"C\" void initlib") + omodule + "(){\n"); ofileImp.indentMore(); ofileImp.writeLine(BString("Py_InitModule(\"lib") + omodule + "\", methods);\n"); ofileImp.indentLess(); ofileImp.writeLine("}\n"); #endif return err; } GenBData::GenBData(){ otypeDomain = 0; otypeNum = 1; oobjType = ObjTypeStd; } GenBData::~GenBData(){ } BError GenBData::produce(Node* n, BString fileName){ BError err; // dprintf("GenBData::produce: %p\n", n); ofileName = fileName; ofileInt.open(ofileName + "D.h", "w"); ofileImp.open(ofileName + "D.cc", "w"); // File Headers produceHeaderInt(); produceHeaderImp(); // Generate code produceInt(n); produceImp(n); // Generate trailers produceTrailerInt(); produceTrailerImp(); ofileImp.close(); ofileInt.close(); return err; }