/*******************************************************************************
* GenBoap.cc Boap output
* T.Barnaby, BEAM Ltd, 2/5/03
*******************************************************************************
*/
#define DEBUG 1
#define DODATA 0
#include <stdio.h>
#include <stdarg.h>
#include <strings.h>
#include <GenBoap.h>
#include <bidl.h>
void GenBoap::produceIntC(Node* n){
BIter i;
BString s;
BString c;
BList<Node*>* nl;
switch(n->nodeType()){
case Node::TMODULE:
omodule = n->name();
ofileIntC.writeLine(BString("namespace ") + omodule + " {\n");
ofileIntC.indentMore();
ofileIntC.writeLine(BString("const BUInt32 apiVersion = ") + oapiVersion + ";\n\n");
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceIntC(n->nodes()[i]);
}
ofileIntC.indentLess();
ofileIntC.writeLine("}\n");
break;
case Node::TINTERFACE:
ointerface = n->name();
// Client
ofileIntC.writeLine(BString("class ") + ointerface + " : public BoapClientObject {\n");
ofileIntC.writeLine("public:\n");
ofileIntC.indentMore();
ofileIntC.writeLine(BString("\t") + ointerface + "(BString name = \"\");\n");
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceIntC(n->nodes()[i]);
}
ofileIntC.indentLess();
ofileIntC.writeLine("private:\n");
ofileIntC.writeLine("};\n");
break;
case Node::TLIST:
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceIntC(n->nodes()[i]);
}
break;
#if DODATA
case Node::TSTRUCT:
if((n->nodes().number() == 2) && n->node(1)){
ofileIntC.writeLine(BString("struct ") + n->name() + " : public " + n->node(1)->name() + " {\n");
}
else {
ofileIntC.writeLine(BString("struct ") + n->name() + " {\n");
}
ofileIntC.indentMore();
nl = &n->node(0)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
s = getTypeName(nl->get(i)->node(0)) + "\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 = "";
ofileIntC.writeLine(s + c + ";\n");
}
ofileIntC.indentLess();
ofileIntC.writeLine("};\n\n");
break;
#endif
case Node::TFUNC:
s = s + getTypeName(n->node(0)) + " ";
s = s + n->name() + "(";
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
if(i != nl->begin())
s = s + ", ";
if(nl->get(i)->node(0)->name() == "in"){
s = s + getTypeName(nl->get(i)->node(1)) + " ";
}
else if(nl->get(i)->node(0)->name() == "inref"){
s = s + "const " + getTypeName(nl->get(i)->node(1)) + "& ";
}
else {
s = s + getTypeName(nl->get(i)->node(1)) + "& ";
}
s = s + nl->get(i)->node(2)->name();
}
s = s + ");";
if(n->node(2) && n->node(2)->nodeType() == Node::TCOMMENT)
s = s + "\t//" + n->node(2)->name();
ofileIntC.writeLine(s + "\n");
break;
case Node::TCOMMENT:
s = BString("//") + n->name() + "\n";
ofileIntC.writeLine(s);
break;
case Node::TAPIVERSION:
oapiVersion = n->name().retInt();
break;
default:
break;
}
}
void GenBoap::produceIntS(Node* n){
BIter i;
BString s;
BList<Node*>* nl;
switch(n->nodeType()){
case Node::TMODULE:
omodule = n->name();
ofileIntS.writeLine(BString("namespace ") + omodule + " {\n");
ofileIntS.indentMore();
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceIntS(n->nodes()[i]);
}
ofileIntS.indentLess();
ofileIntS.writeLine("}\n");
break;
case Node::TINTERFACE:
ointerface = n->name();
// Server
ofileIntS.writeLine(BString("class ") + ointerface + "Service : public BoapServiceObject {\n");
ofileIntS.writeLine("public:\n");
ofileIntS.indentMore();
ofileIntS.writeLine(BString("\t") + ointerface + "Service(BoapServer& server, BString name);\n");
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceIntS(n->nodes()[i]);
}
ofileIntS.indentLess();
ofileIntS.writeLine("};\n");
break;
case Node::TLIST:
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceIntS(n->nodes()[i]);
}
break;
case Node::TSTRUCT:
break;
case Node::TFUNC:
s = BString("BError do") + n->name() + "(BoapServerConnection* conn, BoapPacket& rx, BoapPacket& tx);\n";
ofileIntS.writeLine(s);
s = "virtual ";
s = s + getTypeName(n->node(0)) + " ";
s = s + n->name() + "(";
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
if(i != nl->begin())
s = s + ", ";
if(nl->get(i)->node(0)->name() == "in"){
s = s + getTypeName(nl->get(i)->node(1)) + " ";
}
else if(nl->get(i)->node(0)->name() == "inref"){
s = s + "const " + getTypeName(nl->get(i)->node(1)) + "& ";
}
else {
s = s + getTypeName(nl->get(i)->node(1)) + "& ";
}
s = s + nl->get(i)->node(2)->name();
}
s = s + ") = 0;\n";
ofileIntS.writeLine(s);
break;
default:
break;
}
}
void GenBoap::produceIntT(Node* n){
BIter i;
BString s;
BList<Node*>* nl;
switch(n->nodeType()){
case Node::TMODULE:
omodule = n->name();
ofileIntT.writeLine(BString("using namespace ") + omodule + ";\n\n");
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceIntT(n->nodes()[i]);
}
break;
case Node::TINTERFACE:
ointerface = n->name();
// Server
ofileIntT.writeLine(BString("class ") + ointerface + "Server : public " + omodule + "::" + ointerface + "Service {\n");
ofileIntT.writeLine("public:\n");
ofileIntT.indentMore();
ofileIntT.writeLine(BString("\t") + ointerface + "Server(BoapServer& server, BString name);\n");
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceIntT(n->nodes()[i]);
}
ofileIntT.indentLess();
ofileIntT.writeLine("};\n\n");
break;
case Node::TLIST:
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceIntT(n->nodes()[i]);
}
break;
case Node::TSTRUCT:
break;
case Node::TFUNC:
s = "";
s = s + getTypeName(n->node(0)) + " ";
s = s + n->name() + "(";
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
if(i != nl->begin())
s = s + ", ";
if(nl->get(i)->node(0)->name() == "in"){
s = s + getTypeName(nl->get(i)->node(1)) + " ";
}
else if(nl->get(i)->node(0)->name() == "inref"){
s = s + "const " + getTypeName(nl->get(i)->node(1)) + "& ";
}
else {
s = s + getTypeName(nl->get(i)->node(1)) + "& ";
}
s = s + nl->get(i)->node(2)->name();
}
s = s + ");\n";
ofileIntT.writeLine(s);
break;
default:
break;
}
}
void GenBoap::produceImpT(Node* n){
BString s;
BIter i;
BList<Node*>* nl;
switch(n->nodeType()){
case Node::TMODULE:
omodule = n->name();
ofileImpT.writeLine(BString("using namespace ") + omodule + ";\n\n");
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceImpT(n->nodes()[i]);
}
break;
case Node::TINTERFACE:
ointerface = n->name();
ofileImpT.writeLine(ointerface + "Server::" + ointerface + "Server(BoapServer& server, BString name) : " + ointerface + "Service(server, name){\n");
ofileImpT.writeLine("}\n\n");
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceImpT(n->nodes()[i]);
}
break;
case Node::TLIST:
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceImpT(n->nodes()[i]);
}
break;
case Node::TFUNC:
s = "";
s = s + getTypeName(n->node(0)) + " ";
s = s + ointerface + "Server::" + n->name() + "(";
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
if(i != nl->begin())
s = s + ", ";
if(nl->get(i)->node(0)->name() == "in"){
s = s + getTypeName(nl->get(i)->node(1)) + " ";
}
else if(nl->get(i)->node(0)->name() == "inref"){
s = s + "const " + getTypeName(nl->get(i)->node(1)) + "& ";
}
else {
s = s + getTypeName(nl->get(i)->node(1)) + "& ";
}
s = s + nl->get(i)->node(2)->name();
}
s = s + "){\n";
ofileImpT.writeLine(s);
ofileImpT.indentMore();
if(getTypeName(n->node(0)) == "BError"){
s = getTypeName(n->node(0)) + "\terr;\n\n";
ofileImpT.writeLine(s);
s = "return err;\n";
ofileImpT.writeLine(s);
}
else {
s = getTypeName(n->node(0)) + "\tret;\n\n";
ofileImpT.writeLine(s);
s = "return ret;\n";
ofileImpT.writeLine(s);
}
ofileImpT.indentLess();
ofileImpT.writeLine("}\n\n");
break;
default:
break;
}
}
void GenBoap::pushPopVar(FileIndent& file, int push, BString func, Node* type, BString name){
BIter i;
BList<Node*>* nl;
Type* t;
Type* dt;
BString s;
BString swapType;
// printf("GenBoap::pushPopVar: Func(%s) Type(%s) Name(%s)\n", func.retStr(), type->name().retStr(), name.retStr());
if(t = gtypelist.search(type->name())){
// printf("DoType: %p Derived(%p)\n", type, t->derived());
if(dt = t->derived()){
nl = &dt->node()->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
pushPopVar(file, push, func, nl->get(i)->node(0), name + "." + nl->get(i)->node(1)->name());
}
}
nl = &t->node()->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
pushPopVar(file, push, func, nl->get(i)->node(0), name + "." + nl->get(i)->node(1)->name());
}
}
else if(type->nodeType() == Node::TTYPELIST){
if(push){
file.writeLine("{\n");
file.indentMore();
file.writeLine(BString("BIter i") + opushPopDepth + ";\n");
file.writeLine(func + "(" + name + ".number());\n");
s = BString("for(i") + opushPopDepth + " = " + name + ".begin(); !" + name + ".isEnd(i" + opushPopDepth + "); " + name + ".next(i" + opushPopDepth + ")){\n";
file.writeLine(s);
file.indentMore();
pushPopVar(file, push, func, type->node(0), name + "[i" + opushPopDepth++ + "]");
opushPopDepth--;
file.indentLess();
file.writeLine("}\n");
file.indentLess();
file.writeLine("}\n");
}
else {
file.writeLine("{\n");
file.indentMore();
file.writeLine(BString("Int32 n") + opushPopDepth + ";\n");
s = getTypeName(type->node(0)) + " v" + opushPopDepth + ";\n";
file.writeLine(s);
file.writeLine(name + ".clear();\n");
file.writeLine(func + "(n" + opushPopDepth + ");\n");
file.writeLine(BString("while(n") + opushPopDepth + "--){\n");
file.indentMore();
pushPopVar(file, push, func, type->node(0), BString("v") + opushPopDepth++);
opushPopDepth--;
file.writeLine(name + ".append(v" + opushPopDepth + ");\n");
file.indentLess();
file.writeLine("}\n");
file.indentLess();
file.writeLine("}\n");
}
}
else if(type->nodeType() == Node::TTYPEARRAY){
// Check if raw data copy can be used
#ifdef ZAP
printf("GenBoap::Checking For Raw Type: %s\n", getTypeName(type->node(0)).retStr());
printf("GenBoap::IsRawType: %d\n", isRawType(type->node(0)));
printf("\n");
#endif
if(isRawType(type->node(0))){
#ifdef ZAP
printf("Push raw array of type: %s (%s)\n", getTypeName(type->node(0)).retStr(), getTypeSwapList(type->node(0)).retStr());
#endif
swapType = getTypeSwapList(type->node(0));
if(push){
file.writeLine("{\n");
file.indentMore();
file.writeLine(func + "(" + name + ".size());\n");
file.writeLine(func + "(" + name + ".size() * sizeof(" + getTypeName(type->node(0)) + "), " + name + ".data(), \"" + swapType + "\");\n");
file.indentLess();
file.writeLine("}\n");
}
else {
file.writeLine("{\n");
file.indentMore();
file.writeLine(BString("UInt32 n") + opushPopDepth + ";\n");
file.writeLine(func + "(n" + opushPopDepth + ");\n");
file.writeLine(name + ".resize(n" + opushPopDepth + ");\n");
file.writeLine(func + "(n" + opushPopDepth + " * sizeof(" + getTypeName(type->node(0)) + "), " + name + ".data(), \"" + swapType + "\");\n");
file.indentLess();
file.writeLine("}\n");
}
}
else {
if(push){
file.writeLine("{\n");
file.indentMore();
file.writeLine(BString("UInt32 i") + opushPopDepth + ";\n");
file.writeLine(func + "(" + name + ".size());\n");
s = BString("for(i") + opushPopDepth + " = 0; i" + opushPopDepth + " < " + name + ".size(); i" + opushPopDepth + "++){\n";
file.writeLine(s);
file.indentMore();
pushPopVar(file, push, func, type->node(0), name + "[i" + opushPopDepth++ + "]");
opushPopDepth--;
file.indentLess();
file.writeLine("}\n");
file.indentLess();
file.writeLine("}\n");
}
else {
file.writeLine("{\n");
file.indentMore();
file.writeLine(BString("UInt32 n") + opushPopDepth + ";\n");
s = getTypeName(type->node(0)) + " v" + opushPopDepth + ";\n";
file.writeLine(s);
file.writeLine(func + "(n" + opushPopDepth + ");\n");
file.writeLine(name + ".resize(n" + opushPopDepth + ");\n");
file.writeLine(BString("for(UInt32 i = 0; i < n") + opushPopDepth + "; i++){\n");
file.indentMore();
pushPopVar(file, push, func, type->node(0), BString("v") + opushPopDepth++);
opushPopDepth--;
file.writeLine(name + "[i] = v" + opushPopDepth + ";\n");
file.indentLess();
file.writeLine("}\n");
file.indentLess();
file.writeLine("}\n");
}
}
}
else {
file.writeLine(func + "(" + name + ");\n");
}
}
void GenBoap::produceFuncC(Node* n){
BIter i;
BString s;
BList<Node*>* nl;
BString retType;
retType = getTypeName(n->node(0));
ofileImpC.writeLine("BError\terr;\n");
ofileImpC.writeLine(retType + "\tret;\n");
ofileImpC.writeLine("BoapPacketHead\ttxhead;\n");
ofileImpC.writeLine("BoapPacketHead\trxhead;\n");
ofileImpC.writeLine("\n");
ofileImpC.writeLine("olock.lock();\n");
ofileImpC.writeLine(BString("if(err = connectService(oname)){\n"));
ofileImpC.indentMore();
ofileImpC.writeLine("olock.unlock();\n");
ofileImpC.writeLine(BString("return err;\n"));
ofileImpC.indentLess();
ofileImpC.writeLine("}\n");
ofileImpC.writeLine("\n");
ofileImpC.writeLine(BString("txhead.type = BoapMagic | BoapTypeRpc;\n"));
ofileImpC.writeLine(BString("txhead.service = oservice;\n"));
ofileImpC.writeLine(BString("txhead.cmd = ") + ofuncNum + ";\n");
ofileImpC.writeLine("otx.pushHead(txhead);\n");
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
if(nl->get(i)->node(0)->name() == "in")
pushPopVar(ofileImpC, 1, "otx.push", nl->get(i)->node(1), nl->get(i)->node(2)->name());
}
ofileImpC.writeLine("if(err = performCall(otx, orx)){\n");
ofileImpC.indentMore();
ofileImpC.writeLine("olock.unlock();\n");
if(retType == "BError")
ofileImpC.writeLine("return err;\n");
else
ofileImpC.writeLine("throw err;\n");
ofileImpC.indentLess();
ofileImpC.writeLine("}\n");
ofileImpC.writeLine("orx.popHead(rxhead);\n");
ofileImpC.writeLine("orx.pop(ret);\n");
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
if(nl->get(i)->node(0)->name() == "out")
pushPopVar(ofileImpC, 0, "orx.pop", nl->get(i)->node(1), nl->get(i)->node(2)->name());
}
ofileImpC.writeLine("olock.unlock();\n");
ofileImpC.writeLine("return ret;\n");
}
void GenBoap::produceImpC(Node* n){
BString s;
BIter i;
BList<Node*>* nl;
switch(n->nodeType()){
case Node::TMODULE:
omodule = n->name();
ofileImpC.writeLine(BString("namespace ") + omodule + " {\n");
ofileImpC.indentMore();
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceImpC(n->nodes()[i]);
}
ofileImpC.indentLess();
ofileImpC.writeLine("}\n");
break;
case Node::TINTERFACE:
ointerface = n->name();
ofuncNum = 16;
ofileImpC.writeLine(ointerface + "::" + ointerface + "(BString name) : BoapClientObject(name){\n");
ofileImpC.indentMore();
ofileImpC.writeLine(BString("oapiVersion = ") + oapiVersion + ";\n");
ofileImpC.indentLess();
ofileImpC.writeLine("}\n");
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceImpC(n->nodes()[i]);
}
break;
case Node::TLIST:
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceImpC(n->nodes()[i]);
}
break;
case Node::TFUNC:
s = s + getTypeName(n->node(0)) + " ";
s = s + ointerface + "::" + n->name() + "(";
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
if(i != nl->begin())
s = s + ", ";
if(nl->get(i)->node(0)->name() == "in"){
s = s + getTypeName(nl->get(i)->node(1)) + " ";
}
else if(nl->get(i)->node(0)->name() == "inref"){
s = s + "const " + getTypeName(nl->get(i)->node(1)) + "& ";
}
else {
s = s + getTypeName(nl->get(i)->node(1)) + "& ";
}
s = s + nl->get(i)->node(2)->name();
}
s = s + "){\n";
ofileImpC.writeLine(s);
ofileImpC.indentMore();
produceFuncC(n);
ofileImpC.indentLess();
ofileImpC.writeLine("}\n\n");
ofuncNum++;
break;
case Node::TAPIVERSION:
oapiVersion = n->name().retInt();
break;
default:
break;
}
}
void GenBoap::produceFuncS(Node* n){
BIter i;
BString s;
BList<Node*>* nl;
BString retType;
retType = getTypeName(n->node(0));
ofileImpS.writeLine("BError\terr;\n");
ofileImpS.writeLine("BoapPacketHead\trxhead;\n");
ofileImpS.writeLine("BoapPacketHead\ttxhead;\n");
ofileImpS.writeLine(retType + "\tret;\n");
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
s = getTypeName(nl->get(i)->node(1)) + "\t";
s = s + nl->get(i)->node(2)->name() + ";\n";
ofileImpS.writeLine(s);
}
ofileImpS.writeLine("\n");
ofileImpS.writeLine("rx.popHead(rxhead);\n");
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
if(nl->get(i)->node(0)->name() == "in")
pushPopVar(ofileImpS, 0, "rx.pop", nl->get(i)->node(1), nl->get(i)->node(2)->name());
}
s = BString("ret = ") + n->name() + "(";
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
if(i != nl->begin())
s = s + ", ";
s = s + nl->get(i)->node(2)->name();
}
s = s + ");\n";
ofileImpS.writeLine(s);
ofileImpS.writeLine("txhead.type = BoapMagic | BoapTypeRpcReply;\n");
ofileImpS.writeLine("txhead.service = rxhead.service;\n");
ofileImpS.writeLine("txhead.cmd = rxhead.cmd;\n");
ofileImpS.writeLine("tx.pushHead(txhead);\n");
ofileImpS.writeLine("tx.push(ret);\n");
nl = &n->node(1)->nodes();
for(nl->start(i); !nl->isEnd(i); nl->next(i)){
if(nl->get(i)->node(0)->name() == "out")
pushPopVar(ofileImpS, 1, "tx.push", nl->get(i)->node(1), nl->get(i)->node(2)->name());
}
ofileImpS.writeLine("return err;\n");
}
void GenBoap::produceFuncAdd(Node* n){
BString s;
BIter i;
switch(n->nodeType()){
case Node::TLIST:
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceFuncAdd(n->nodes()[i]);
}
break;
case Node::TFUNC:
s = s + "ofuncList.append(BoapFuncEntry(" + ofuncNum + ", ";
s = s + "(BoapFunc)&" + ointerface + "Service::do" + n->name() + "));\n";
ofileImpS.writeLine(s);
ofuncNum++;
break;
default:
break;
}
}
void GenBoap::produceImpS(Node* n){
BString s;
BIter i;
switch(n->nodeType()){
case Node::TMODULE:
omodule = n->name();
ofileImpS.writeLine(BString("namespace ") + omodule + " {\n");
ofileImpS.indentMore();
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceImpS(n->nodes()[i]);
}
ofileImpS.indentLess();
ofileImpS.writeLine("}\n");
break;
case Node::TINTERFACE:
ointerface = n->name();
ofuncNum = 16;
ofileImpS.writeLine(ointerface + "Service::" + ointerface + "Service(BoapServer& server, BString name) : BoapServiceObject(server, name){\n");
ofileImpS.indentMore();
ofileImpS.writeLine(BString("oapiVersion = ") + oapiVersion + ";\n");
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceFuncAdd(n->nodes()[i]);
}
ofileImpS.indentLess();
ofileImpS.writeLine("}\n");
ofuncNum = 16;
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceImpS(n->nodes()[i]);
}
break;
case Node::TLIST:
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
produceImpS(n->nodes()[i]);
}
break;
case Node::TFUNC:
s = "BError ";
s = s + ointerface + "Service::do" + n->name();
s = s + "(BoapServerConnection* conn, BoapPacket& rx, BoapPacket& tx){\n";
ofileImpS.writeLine(s);
ofileImpS.indentMore();
produceFuncS(n);
ofileImpS.indentLess();
ofileImpS.writeLine("}\n\n");
ofuncNum++;
break;
case Node::TAPIVERSION:
oapiVersion = n->name().retInt();
break;
default:
break;
}
}
BError GenBoap::produceHeaderIntC(){
BError err;
BString fileName = ofileName + "C.h";
BString fileNameUpper = ofileName + "C_H";
fileNameUpper.toUpper();
ofileIntC.printf("/*******************************************************************************\n");
ofileIntC.printf(" *\t%s\tProduced by Bidl\n", fileName.retStr());
ofileIntC.printf(" *******************************************************************************\n");
ofileIntC.printf(" */\n");
ofileIntC.printf("\n");
ofileIntC.printf("#ifndef %s\n", fileNameUpper.retStr());
ofileIntC.printf("#define %s 1\n\n", fileNameUpper.retStr());
ofileIntC.printf("#include <stdlib.h>\n");
ofileIntC.printf("#include <stdint.h>\n");
ofileIntC.printf("#include <Boap.h>\n");
ofileIntC.printf("#include <BString.h>\n");
ofileIntC.printf("#include <BList.h>\n");
ofileIntC.printf("#include <BArray.h>\n");
#ifdef ZAP1
ofileIntC.printf("#include <BObjDate.h>\n");
ofileIntC.printf("#include <BObjData.h>\n");
#endif
#if !DODATA
ofileIntC.printf("#include <%s>\n\n", (ofileName + "D.h").retStr());
#endif
ofileIntC.printf("\n");
return err;
}
BError GenBoap::produceHeaderIntS(){
BError err;
BString fileName = ofileName + "S.h";
BString fileNameUpper = ofileName + "S_H";
fileNameUpper.toUpper();
ofileIntS.printf("/*******************************************************************************\n");
ofileIntS.printf(" *\t%s\tProduced by Bidl\n", fileName.retStr());
ofileIntS.printf(" *******************************************************************************\n");
ofileIntS.printf(" */\n");
ofileIntS.printf("\n");
ofileIntS.printf("#ifndef %s\n", fileNameUpper.retStr());
ofileIntS.printf("#define %s 1\n\n", fileNameUpper.retStr());
ofileIntS.printf("#include <stdint.h>\n");
ofileIntS.printf("#include <Boap.h>\n");
ofileIntS.printf("#include <BString.h>\n\n");
ofileIntS.printf("#include <%sC.h>\n", ofileName.retStr());
ofileIntS.printf("\n");
return err;
}
BError GenBoap::produceHeaderIntT(){
BError err;
BString fileName = ofileName + "T.h";
BString fileNameUpper = ofileName + "T_H";
fileNameUpper.toUpper();
ofileIntT.printf("/*******************************************************************************\n");
ofileIntT.printf(" *\t%s\tProduced by Bidl\n", fileName.retStr());
ofileIntT.printf(" *******************************************************************************\n");
ofileIntT.printf(" */\n");
ofileIntT.printf("\n");
ofileIntT.printf("#ifndef %s\n", fileNameUpper.retStr());
ofileIntT.printf("#define %s 1\n\n", fileNameUpper.retStr());
ofileIntT.printf("#include <BString.h>\n");
ofileIntT.printf("#include <BList.h>\n");
ofileIntT.printf("#include <BArray.h>\n");
ofileIntT.printf("#include <%s>\n", (ofileName + "S.h").retStr());
ofileIntT.printf("\n");
return err;
}
BError GenBoap::produceHeaderImpT(){
BError err;
BString fileName = ofileName + "T.cc";
BString fileNameUpper = ofileName + "T_H";
fileNameUpper.toUpper();
ofileImpT.printf("/*******************************************************************************\n");
ofileImpT.printf(" *\t%s\tProduced by Bidl\n", fileName.retStr());
ofileImpT.printf(" *******************************************************************************\n");
ofileImpT.printf(" */\n");
ofileImpT.printf("\n");
ofileImpT.printf("#include <stdlib.h>\n");
ofileImpT.printf("#include <stdint.h>\n");
ofileImpT.printf("#include <%s>\n", (ofileName + "T.h").retStr());
ofileImpT.printf("\n");
return err;
}
BError GenBoap::produceTrailerInt(){
BError err;
ofileIntC.printf("#endif\n");
ofileIntS.printf("#endif\n");
ofileIntT.printf("#endif\n");
return err;
}
BError GenBoap::produceHeaderImpC(){
BError err;
ofileImpC.printf("/*******************************************************************************\n");
ofileImpC.printf(" *\t%s\tProduced by Bidl\n", (ofileName + ".cc").retStr());
ofileImpC.printf(" *******************************************************************************\n");
ofileImpC.printf(" */\n");
ofileImpC.printf("\n");
ofileImpC.printf("#include <%s>\n", (ofileName + "C.h").retStr());
ofileImpC.printf("\n");
return err;
}
BError GenBoap::produceHeaderImpS(){
BError err;
ofileImpS.printf("/*******************************************************************************\n");
ofileImpS.printf(" *\t%s\tProduced by Bidl\n", (ofileName + ".cc").retStr());
ofileImpS.printf(" *******************************************************************************\n");
ofileImpS.printf(" */\n");
ofileImpS.printf("\n");
ofileImpS.printf("#include <%s>\n", (ofileName + "C.h").retStr());
ofileImpS.printf("#include <%s>\n", (ofileName + "S.h").retStr());
ofileImpS.printf("\n");
return err;
}
BString GenBoap::getTypeSwapList(Node* n){
BString typeName;
Type* t;
BIter i;
BString typeList;
typeName = n->name();
// printf("isRawType: %d %s\n", n->nodeType(), typeName.retStr());
if(n->nodeType() == Node::TTYPEARRAY){
return "";
}
else if(n->nodeType() == Node::TTYPE){
if(typeName == "Int8") return "1";
else if(typeName == "UInt8") return "1";
else if(typeName == "Int16") return "2";
else if(typeName == "UInt16") return "2";
else if(typeName == "Int32") return "4";
else if(typeName == "UInt32") return "4";
else if(typeName == "Bool") return "4";
else if(typeName == "String") return "";
else if(typeName == "Error") return "";
else if(typeName == "Date") return "";
else if(typeName == "DateTime") return "";
else if(typeName == "Id") return "";
else if(typeName == "ObjData") return "";
else {
if(t = gtypelist.search(typeName)){
if(t->node()){
return getTypeSwapList(t->node());
}
}
else
return "";
}
}
else if(n->nodes().number()){
for(n->nodes().start(i); !n->nodes().isEnd(i); n->nodes().next(i)){
typeList += getTypeSwapList(n->nodes()[i]);
}
return typeList;
}
return "";
}
GenBoap::GenBoap(){
ofuncNum = 0;
opushPopDepth = 0;
oapiVersion = 0;
setUseBObjects(0);
}
GenBoap::~GenBoap(){
}
BError GenBoap::produce(Node* n, BString fileName){
BError err;
// dprintf("GenBoap::produce: %x\n", n);
ofileName = fileName;
ofileIntC.open(fileName + "C.h", "w");
ofileIntS.open(fileName + "S.h", "w");
ofileImpC.open(fileName + "C.cc", "w");
ofileImpS.open(fileName + "S.cc", "w");
ofileIntT.open(fileName + "T.h", "w");
ofileImpT.open(fileName + "T.cc", "w");
// File Headers
produceHeaderIntC();
produceHeaderIntS();
produceHeaderImpC();
produceHeaderImpS();
produceHeaderIntT();
produceHeaderImpT();
// Generate code
produceIntC(n);
produceIntS(n);
produceImpC(n);
produceImpS(n);
// Generate Base
produceIntT(n);
produceImpT(n);
// Generate trailers
produceTrailerInt();
ofileImpS.close();
ofileImpC.close();
ofileIntS.close();
ofileIntC.close();
ofileIntT.close();
ofileImpT.close();
return err;
}