/*******************************************************************************
* 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;
}