8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:00:38 +01:00

Fixed CORE-6446: CLOOP envelopes is wrong in IStatus

This commit is contained in:
AlexPeshkoff 2021-03-16 18:39:41 +03:00
parent 7e1e9b3ecb
commit e039e015aa
8 changed files with 64 additions and 18 deletions

View File

@ -542,8 +542,17 @@ void CppGenerator::generate()
if (method->returnTypeRef.token.type != Token::TYPE_VOID ||
method->returnTypeRef.isPointer)
{
fprintf(out, "\t\t\t\treturn static_cast<%s>(0);\n",
convertType(method->returnTypeRef).c_str());
const char* ret = "\t\t\t\treturn";
if (method->onErrorFunction.length())
{
fprintf(out, "%s %s();\n",
ret, method->onErrorFunction.c_str());
}
else
{
fprintf(out, "%s static_cast<%s>(0);\n",
ret, convertType(method->returnTypeRef).c_str());
}
}
fprintf(out, "\t\t\t}\n");

View File

@ -96,6 +96,8 @@ Token& Lexer::getToken(Token& token)
token.type = Token::TYPE_TYPEDEF;
else if (token.text == "version")
token.type = Token::TYPE_VERSION;
else if (token.text == "onError")
token.type = Token::TYPE_ON_ERROR;
// types
else if (token.text == "void")
token.type = Token::TYPE_VOID;

View File

@ -49,6 +49,7 @@ struct Token
TYPE_STRUCT,
TYPE_TYPEDEF,
TYPE_VERSION,
TYPE_ON_ERROR,
// types
TYPE_VOID,
TYPE_BOOLEAN,

View File

@ -177,24 +177,43 @@ void Parser::parseTypedef()
void Parser::parseItem()
{
Expr* notImplementedExpr = NULL;
std::string onError;
lexer->getToken(token);
if (token.type == TOKEN('['))
while (lexer->getToken(token).type == TOKEN('['))
{
getToken(token, Token::TYPE_NOT_IMPLEMENTED); // This is the only attribute we allow now.
getToken(token, TOKEN('('));
notImplementedExpr = parseExpr();
getToken(token, TOKEN(')'));
getToken(token, TOKEN(']'));
lexer->getToken(token);
switch (token.type)
{
case Token::TYPE_NOT_IMPLEMENTED:
if (notImplementedExpr)
syntaxError(token);
getToken(token, TOKEN('('));
notImplementedExpr = parseExpr();
getToken(token, TOKEN(')'));
getToken(token, TOKEN(']'));
break;
case Token::TYPE_ON_ERROR:
if (onError.length())
syntaxError(token);
lexer->getToken(token);
if (token.type != Token::TYPE_IDENTIFIER)
syntaxError(token);
onError = token.text;
getToken(token, TOKEN(']'));
break;
default:
syntaxError(token);
break;
}
}
else
lexer->pushToken(token);
lexer->pushToken(token);
TypeRef typeRef(parseTypeRef());
string name(getToken(token, Token::TYPE_IDENTIFIER).text);
if (!notImplementedExpr && typeRef.isConst)
if ((!(notImplementedExpr || onError.length())) && typeRef.isConst)
{
if (lexer->getToken(token).type == TOKEN('='))
{
@ -207,7 +226,7 @@ void Parser::parseItem()
}
getToken(token, TOKEN('('));
parseMethod(typeRef, name, notImplementedExpr);
parseMethod(typeRef, name, notImplementedExpr, onError);
}
void Parser::parseConstant(const TypeRef& typeRef, const string& name)
@ -222,7 +241,7 @@ void Parser::parseConstant(const TypeRef& typeRef, const string& name)
getToken(token, TOKEN(';'));
}
void Parser::parseMethod(const TypeRef& returnTypeRef, const string& name, Expr* notImplementedExpr)
void Parser::parseMethod(const TypeRef& returnTypeRef, const string& name, Expr* notImplementedExpr, const string& onError)
{
Method* method = new Method();
interface->methods.push_back(method);
@ -231,6 +250,7 @@ void Parser::parseMethod(const TypeRef& returnTypeRef, const string& name, Expr*
method->name = name;
method->version = interface->version;
method->notImplementedExpr = notImplementedExpr;
method->onErrorFunction = onError;
if (lexer->getToken(token).type != TOKEN(')'))
{

View File

@ -107,6 +107,7 @@ public:
Expr* notImplementedExpr;
unsigned version;
bool isConst;
std::string onErrorFunction;
};
@ -159,7 +160,7 @@ public:
void parseTypedef();
void parseItem();
void parseConstant(const TypeRef& typeRef, const std::string& name);
void parseMethod(const TypeRef& returnTypeRef, const std::string& name, Expr* notImplementedExpr);
void parseMethod(const TypeRef& returnTypeRef, const std::string& name, Expr* notImplementedExpr, const std::string& onErrorFunction);
Expr* parseExpr();
Expr* parseLogicalExpr();

View File

@ -80,7 +80,9 @@ interface Status : Disposable
void setErrors(const intptr* value);
void setWarnings(const intptr* value);
[onError stubError]
const intptr* getErrors() const;
[onError stubError]
const intptr* getWarnings() const;
Status clone() const;

View File

@ -6603,7 +6603,7 @@ namespace Firebird
catch (...)
{
StatusType::catchException(0);
return static_cast<const intptr_t*>(0);
return stubError();
}
}
@ -6616,7 +6616,7 @@ namespace Firebird
catch (...)
{
StatusType::catchException(0);
return static_cast<const intptr_t*>(0);
return stubError();
}
}

View File

@ -93,6 +93,17 @@ struct PerformanceInfo
ISC_INT64 pin_records_fetched; // records fetched from statement/procedure
};
inline const intptr_t* stubError()
{
static const intptr_t codes[] = {
isc_arg_gds, isc_random,
isc_arg_string, (intptr_t) "Unrecognized exception in Status interface",
isc_arg_end
};
return codes;
}
} // namespace Firebird