diff --git a/extern/cloop/src/cloop/Action.cpp b/extern/cloop/src/cloop/Action.cpp index 1eb934cba9..bba8b6379e 100644 --- a/extern/cloop/src/cloop/Action.cpp +++ b/extern/cloop/src/cloop/Action.cpp @@ -94,39 +94,84 @@ void DefAction::generate(const ActionParametersBlock& apb, unsigned ident) switch(apb.language) { case LANGUAGE_C: - if (!apb.statusName.empty()) + if (!apb.method->statusName.empty()) { identify(apb, ident); fprintf(apb.out, "CLOOP_setVersionError(%s, \"%s%s\", cloopVTable->version, %d);\n", - apb.statusName.c_str(), apb.prefix.c_str(), + apb.method->statusName.c_str(), apb.prefix.c_str(), apb.interface->name.c_str(), apb.method->version); } break; case LANGUAGE_CPP: - if (!apb.statusName.empty()) + if (!apb.method->statusName.empty()) { identify(apb, ident); fprintf(apb.out, "%s::setVersionError(%s, \"%s%s\", cloopVTable->version, %d);\n", - apb.exceptionClass.c_str(), apb.statusName.c_str(), apb.prefix.c_str(), + apb.exceptionClass.c_str(), apb.method->statusName.c_str(), apb.prefix.c_str(), apb.interface->name.c_str(), apb.method->version); identify(apb, ident); fprintf(apb.out, "%s::checkException(%s);\n", - apb.exceptionClass.c_str(), apb.statusName.c_str()); + apb.exceptionClass.c_str(), apb.method->statusName.c_str()); } break; case LANGUAGE_PASCAL: - if (!apb.statusName.empty() && !apb.exceptionClass.empty()) + if (!apb.method->statusName.empty() && !apb.exceptionClass.empty()) { identify(apb, ident); fprintf(apb.out, "%s.setVersionError(%s, \'%s%s\', vTable.version, %d);\n", - apb.exceptionClass.c_str(), apb.statusName.c_str(), apb.prefix.c_str(), + apb.exceptionClass.c_str(), apb.method->statusName.c_str(), apb.prefix.c_str(), apb.interface->name.c_str(), apb.method->version); } break; } break; + + case DEF_IGNORE: + if (apb.method->returnTypeRef.token.type != Token::TYPE_VOID || + apb.method->returnTypeRef.isPointer) + { + identify(apb, ident); + + switch(apb.language) + { + case LANGUAGE_C: + case LANGUAGE_CPP: + fprintf(apb.out, "return 0;\n"); + break; + + case LANGUAGE_PASCAL: + { + const char* sResult = "nil"; + if (!apb.method->returnTypeRef.isPointer) + { + switch (apb.method->returnTypeRef.token.type) + { + case Token::TYPE_STRING: + break; + + case Token::TYPE_BOOLEAN: + sResult = "false"; + break; + + case Token::TYPE_IDENTIFIER: + if (apb.method->returnTypeRef.type == BaseType::TYPE_INTERFACE) + break; + + // fallthru + default: + sResult = "0"; + break; + } + } + + fprintf(apb.out, "Result := %s;\n", sResult); + } + break; + } + } + break; } } diff --git a/extern/cloop/src/cloop/Action.h b/extern/cloop/src/cloop/Action.h index 1de5031be5..99157ec3bb 100644 --- a/extern/cloop/src/cloop/Action.h +++ b/extern/cloop/src/cloop/Action.h @@ -37,7 +37,6 @@ struct ActionParametersBlock Language language; const std::string& prefix; const std::string& exceptionClass; - const std::string& statusName; Interface* interface; Method* method; }; @@ -91,7 +90,7 @@ public: class DefAction : public Action { public: - enum DefType { DEF_NOT_IMPLEMENTED }; + enum DefType { DEF_NOT_IMPLEMENTED, DEF_IGNORE }; DefAction(DefType dt) : defType(dt) diff --git a/extern/cloop/src/cloop/Generator.cpp b/extern/cloop/src/cloop/Generator.cpp index 01fa4a2900..b64bcc1ca0 100644 --- a/extern/cloop/src/cloop/Generator.cpp +++ b/extern/cloop/src/cloop/Generator.cpp @@ -357,15 +357,8 @@ void CppGenerator::generate() fprintf(out, "\n\t\t"); - string statusName; - - if (!method->parameters.empty() && - parser->exceptionInterface && - method->parameters.front()->typeRef.token.text == parser->exceptionInterface->name) - { - statusName = method->parameters.front()->name; + if (!method->statusName.empty()) fprintf(out, "template "); - } fprintf(out, "%s %s(", convertType(method->returnTypeRef).c_str(), method->name.c_str()); @@ -379,7 +372,7 @@ void CppGenerator::generate() if (k != method->parameters.begin()) fprintf(out, ", "); - if (k == method->parameters.begin() && !statusName.empty()) + if (k == method->parameters.begin() && !method->statusName.empty()) fprintf(out, "StatusType* %s", parameter->name.c_str()); else { @@ -397,7 +390,7 @@ void CppGenerator::generate() fprintf(out, "\t\t\t{\n"); const string exceptionClass("StatusType"); - ActionParametersBlock apb = {out, LANGUAGE_CPP, prefix, exceptionClass, statusName, interface, method}; + ActionParametersBlock apb = {out, LANGUAGE_CPP, prefix, exceptionClass, interface, method}; if (method->notImplementedAction) method->notImplementedAction->generate(apb, 4); @@ -419,11 +412,11 @@ void CppGenerator::generate() fprintf(out, "\t\t\t}\n"); } - if (!statusName.empty()) + if (!method->statusName.empty()) { fprintf(out, "\t\t\t"); - fprintf(out, "StatusType::clearException(%s)", statusName.c_str()); + fprintf(out, "StatusType::clearException(%s)", method->statusName.c_str()); fprintf(out, ";\n"); } @@ -694,7 +687,19 @@ void CppGenerator::generate() } } - fprintf(out, ")%s = 0;\n", (method->isConst ? " const" : "")); + fprintf(out, ")%s", (method->isConst ? " const" : "")); + + if (method->stubAction) + { + const string exceptionClass("StatusType"); + ActionParametersBlock apb = {out, LANGUAGE_CPP, prefix, exceptionClass, interface, method}; + + fprintf(out, "\n\t\t{\n"); + method->stubAction->generate(apb, 3); + fprintf(out, "\t\t}\n"); + } + else + fprintf(out, " = 0;\n"); } fprintf(out, "\t};\n"); @@ -1184,7 +1189,10 @@ void PascalGenerator::generate() if (!isProcedure) fprintf(out, ": %s", convertType(method->returnTypeRef).c_str()); - fprintf(out, "; virtual; abstract;\n"); + fprintf(out, "; virtual;"); + if (!method->stubAction) + fprintf(out, " abstract;"); + fprintf(out, "\n"); } fprintf(out, "\tend;\n\n"); @@ -1209,15 +1217,6 @@ void PascalGenerator::generate() bool isProcedure = method->returnTypeRef.token.type == Token::TYPE_VOID && !method->returnTypeRef.isPointer; - string statusName; - - if (!method->parameters.empty() && - parser->exceptionInterface && - method->parameters.front()->typeRef.token.text == parser->exceptionInterface->name) - { - statusName = method->parameters.front()->name; - } - fprintf(out, "%s %s.%s(", (isProcedure ? "procedure" : "function"), escapeName(interface->name, true).c_str(), @@ -1248,8 +1247,7 @@ void PascalGenerator::generate() { fprintf(out, "\tif (vTable.version < %d) then begin\n", method->version); - ActionParametersBlock apb = {out, LANGUAGE_PASCAL, prefix, exceptionClass, - statusName, interface, method}; + ActionParametersBlock apb = {out, LANGUAGE_PASCAL, prefix, exceptionClass, interface, method}; if (method->notImplementedAction) method->notImplementedAction->generate(apb, 2); @@ -1290,8 +1288,8 @@ void PascalGenerator::generate() if (ident > 1) fprintf(out, "\tend;\n"); - if (!statusName.empty() && !exceptionClass.empty()) - fprintf(out, "\t%s.checkException(%s);\n", exceptionClass.c_str(), escapeName(statusName).c_str()); + if (!method->statusName.empty() && !exceptionClass.empty()) + fprintf(out, "\t%s.checkException(%s);\n", exceptionClass.c_str(), escapeName(method->statusName).c_str()); fprintf(out, "end;\n\n"); } @@ -1315,6 +1313,8 @@ void PascalGenerator::generate() bool isProcedure = method->returnTypeRef.token.type == Token::TYPE_VOID && !method->returnTypeRef.isPointer; + ActionParametersBlock apb = {out, LANGUAGE_PASCAL, prefix, exceptionClass, interface, method}; + fprintf(out, "%s %sImpl_%sDispatcher(this: %s", (isProcedure ? "procedure" : "function"), escapeName(interface->name, true).c_str(), @@ -1337,39 +1337,7 @@ void PascalGenerator::generate() fprintf(out, "; cdecl;\n"); fprintf(out, "begin\n"); - - if (!isProcedure) - { - if (method->returnTypeRef.isPointer) { - fprintf(out, "\tResult := nil;\n"); - } - else - { - const char* sResult; - switch (method->returnTypeRef.token.type) - { - case Token::TYPE_STRING: - sResult = "nil"; - break; - - case Token::TYPE_BOOLEAN: - sResult = "false"; - break; - - case Token::TYPE_IDENTIFIER: - if (method->returnTypeRef.type == BaseType::TYPE_INTERFACE) - { - sResult = "nil"; - break; - } - // fallthru - default: - sResult = "0"; - break; - } - fprintf(out, "\tResult := %s;\n", sResult); - } - } + DefAction(DefAction::DEF_IGNORE).generate(apb, 1); if (!exceptionClass.empty()) fprintf(out, "\ttry\n\t"); @@ -1411,8 +1379,35 @@ void PascalGenerator::generate() fprintf(out, "\tend\n"); } - fprintf(out, "end;\n\n"); + + if (method->stubAction) + { + fprintf(out, "%s %sImpl.%s(", + (isProcedure ? "procedure" : "function"), + escapeName(interface->name, true).c_str(), + escapeName(method->name).c_str()); + + for (vector::iterator k = method->parameters.begin(); + k != method->parameters.end(); + ++k) + { + Parameter* parameter = *k; + + fprintf(out, "%s%s", + k == method->parameters.begin() ? "" : "; ", + convertParameter(*parameter).c_str()); + } + + fprintf(out, ")"); + if (!isProcedure) + fprintf(out, ": %s", convertType(method->returnTypeRef).c_str()); + fprintf(out, ";\n"); + + fprintf(out, "begin\n"); + method->stubAction->generate(apb, 1); + fprintf(out, "end;\n\n"); + } } fprintf(out, "var\n"); diff --git a/extern/cloop/src/cloop/Lexer.cpp b/extern/cloop/src/cloop/Lexer.cpp index 93e9280a64..3d399950cb 100644 --- a/extern/cloop/src/cloop/Lexer.cpp +++ b/extern/cloop/src/cloop/Lexer.cpp @@ -112,6 +112,8 @@ Token& Lexer::getToken(Token& token) token.type = Token::TYPE_CALL; else if (token.text == "defaultAction") token.type = Token::TYPE_DEFAULT_ACTION; + else if (token.text == "stub") + token.type = Token::TYPE_STUB; // types else if (token.text == "void") token.type = Token::TYPE_VOID; diff --git a/extern/cloop/src/cloop/Lexer.h b/extern/cloop/src/cloop/Lexer.h index f146d5b450..3a72a9dc12 100644 --- a/extern/cloop/src/cloop/Lexer.h +++ b/extern/cloop/src/cloop/Lexer.h @@ -47,6 +47,7 @@ struct Token TYPE_INTERFACE, TYPE_NOT_IMPLEMENTED, TYPE_NOT_IMPLEMENTED_ACTION, + TYPE_STUB, TYPE_STRUCT, TYPE_TYPEDEF, TYPE_VERSION, diff --git a/extern/cloop/src/cloop/Parser.cpp b/extern/cloop/src/cloop/Parser.cpp index 90bd7e9403..1330331a71 100644 --- a/extern/cloop/src/cloop/Parser.cpp +++ b/extern/cloop/src/cloop/Parser.cpp @@ -94,7 +94,7 @@ void Parser::parse() } } - // Check types. + // Check types, assign statusName to methods. for (vector::iterator i = interfaces.begin(); i != interfaces.end(); ++i) { @@ -115,6 +115,13 @@ void Parser::parse() Parameter* parameter = *k; checkType(parameter->typeRef); } + + if (!method->parameters.empty() && + exceptionInterface && + method->parameters.front()->typeRef.token.text == exceptionInterface->name) + { + method->statusName = method->parameters.front()->name; + } } } } @@ -194,6 +201,7 @@ void Parser::parseItem() { Expr* notImplementedExpr = nullptr; Action* notImplementedAction = nullptr; + Action* stubAction = nullptr; std::string onError; while (lexer->getToken(token).type == TOKEN('[')) @@ -224,6 +232,12 @@ void Parser::parseItem() notImplementedAction = parseAction(DefAction::DEF_NOT_IMPLEMENTED); break; + case Token::TYPE_STUB: + if (stubAction) + syntaxError(token); + stubAction = parseAction(DefAction::DEF_IGNORE); + break; + default: syntaxError(token); break; @@ -248,7 +262,7 @@ void Parser::parseItem() } getToken(token, TOKEN('(')); - parseMethod(typeRef, name, notImplementedExpr, onError, notImplementedAction); + parseMethod(typeRef, name, notImplementedExpr, onError, notImplementedAction, stubAction); } void Parser::parseConstant(const TypeRef& typeRef, const string& name) @@ -326,7 +340,7 @@ Action* Parser::parseDefAction(DefAction::DefType dt) } void Parser::parseMethod(const TypeRef& returnTypeRef, const string& name, Expr* notImplementedExpr, - const string& onError, Action* notImplementedAction) + const string& onError, Action* notImplementedAction, Action* stubAction) { Method* method = new Method(); interface->methods.push_back(method); @@ -336,6 +350,7 @@ void Parser::parseMethod(const TypeRef& returnTypeRef, const string& name, Expr* method->version = interface->version; method->notImplementedExpr = notImplementedExpr; method->notImplementedAction = notImplementedAction; + method->stubAction = stubAction; method->onErrorFunction = onError; if (lexer->getToken(token).type != TOKEN(')')) diff --git a/extern/cloop/src/cloop/Parser.h b/extern/cloop/src/cloop/Parser.h index 6dc3ca9138..82f98a12d7 100644 --- a/extern/cloop/src/cloop/Parser.h +++ b/extern/cloop/src/cloop/Parser.h @@ -101,6 +101,7 @@ public: Method() : notImplementedExpr(NULL), notImplementedAction(NULL), + stubAction(NULL), version(0), isConst(false) { @@ -111,9 +112,11 @@ public: std::vector parameters; Expr* notImplementedExpr; Action* notImplementedAction; + Action* stubAction; unsigned version; bool isConst; std::string onErrorFunction; + std::string statusName; }; @@ -178,7 +181,7 @@ public: void parseItem(); void parseConstant(const TypeRef& typeRef, const std::string& name); void parseMethod(const TypeRef& returnTypeRef, const std::string& name, Expr* notImplementedExpr, - const std::string& onErrorFunction, Action* notImplementedAction); + const std::string& onErrorFunction, Action* notImplementedAction, Action* stubAction); Expr* parseExpr(); Expr* parseLogicalExpr();