/******************************************************************************* * 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; 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")) return; typeName = BString("") + n->name(); if((n->nodes().number() == 2) && n->node(1)){ ofileInt.writeLine(BString("class ") + typeName + " : public " + getTypeName(n->node(1), 1) + " {\n"); oisBObject = 1; } else { ofileInt.writeLine(BString("class ") + typeName + " {\n"); oisBObject = 0; } ofileInt.writeLine("public:\n"); ofileInt.indentMore(); if(oisBObject){ 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 + ", "; s = s + getTypeName(nl->get(i)->node(0), 0) + " p" + nl->get(i)->node(1)->name(); } ofileInt.writeLine(typeName + "(" + s + ");\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), oisBObject) + "\t"; s = s + "" + nl->get(i)->node(1)->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"); 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 += ", "; 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; 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")) return; typeName = BString("") + n->name(); parentTypeName = ""; if((n->nodes().number() == 2) && n->node(1)){ parentTypeName = getTypeName(n->node(1), 1); oisBObject = 1; } else { oisBObject = 0; } ofileImp.writeLine("\n"); ofileImp.writeLine(BString("// ") + typeName + " Object Implementation\n"); if(oisBObject){ 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"); } if((n->nodes().number() == 2) && n->node(1)){ ofileImp.writeLine(typeName + "::" + typeName + "(){\n"); ofileImp.writeLine("}\n"); } else { // 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 + ", "; 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 = ""; 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(oisBObject){ 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"); } 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\n"); ofileInt.printf("#include <BList.h>\n"); ofileInt.printf("#include <BArray.h>\n"); #ifdef ZAP1 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"); #endif ofileInt.printf("\n"); return err; } BError GenBData::produceTrailerInt(){ BError err; 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; oisBObject = 0; } 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; }