/******************************************************************************* * GenData.cc BEAM Data output * T.Barnaby, BEAM Ltd, 12/9/03 ******************************************************************************* */ #define DEBUG 1 #include <stdio.h> #include <stdarg.h> #include <strings.h> #include <GenData.h> #include <bidl.h> void GenData::produceInt(Node* n){ BIter i; BString s; 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: typeName = BString("") + n->name(); if((n->nodes().number() == 2) && n->node(1)){ ofileInt.writeLine(BString("class ") + typeName + " : public " + getTypeName(n->node(1), 1) + " {\n"); } else { ofileInt.writeLine(BString("class ") + typeName + " {\n"); } ofileInt.writeLine(BString("class ") + typeName + " {\n"); ofileInt.writeLine("public:\n"); ofileInt.indentMore(); ofileInt.writeLine(typeName + "();\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), 1) + "\t"; s = s + nl->get(i)->node(1)->name(); ofileInt.writeLine(s + ";\n"); } ofileInt.indentLess(); ofileInt.writeLine("};\n\n"); break; case Node::TENUM: s = ""; if(n->node(0)){ s = s + n->node(0)->name() + " "; } nl = &n->node(1)->nodes(); for(nl->start(i); !nl->isEnd(i); nl->next(i)){ if(s.len()) s += ", "; s += nl->get(i)->name(); } ofileInt.writeLine(BString("enum { " + s + "};\n"); break; default: break; } } void GenData::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: typeName = BString("") + n->name(); parentTypeName = ""; if((n->nodes().number() == 2) && n->node(1)){ parentTypeName = getTypeName(n->node(1), 1); } ofileImp.writeLine("\n"); ofileImp.writeLine(BString("// ") + typeName + " Object Implementation\n"); if((n->nodes().number() == 2) && n->node(1)){ ofileImp.writeLine(typeName + "::" + typeName + "(){\n"); } else { ofileImp.writeLine(typeName + "::" + typeName + "(){\n"); } ofileImp.indentMore(); ofileImp.indentLess(); ofileImp.writeLine("}\n"); otypeNum++; break; default: break; } } BError GenData::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"); 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"); } ofileInt.printf("\n"); return err; } BError GenData::produceTrailerInt(){ BError err; ofileInt.printf("#endif\n"); return err; } BError GenData::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()); ofileImp.printf("#include <BType.h>\n"); ofileImp.printf("\n"); return err; } BError GenData::produceTrailerImp(){ BError err; // 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"); return err; } GenData::GenData(){ otypeDomain = 0; otypeNum = 1; } GenData::~GenData(){ } BError GenData::produce(Node* n, BString fileName){ BError err; // dprintf("GenData::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; }