// compute the date corresponding to the IMM code DLLEXPORT double xlCalendarIMMDate (xloper * calculationDate_, char * immCode_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlCalendarIMMDate")); try { QL_ENSURE(! functionCall->calledByFunctionWizard(), ""); ObjectHandler::validateRange(calculationDate_, "calculation Date"); ObjectHandler::ConvertOper myOper(* calculationDate_); QuantLib::Date calculationDate( // calculation date myOper.missing() ? QuantLib::Date() : QuantLib::Date(static_cast<QuantLib::BigInteger>(myOper))); return QuantLib::Date( // next IMM date QuantLib::IMM::date( std::string(immCode_), calculationDate)).serialNumber(); } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall); return 0; } }
void call(const glbinding::Function<void, Arguments...> * function, Arguments&&... arguments) const { glbinding::FunctionCall functionCall(function); if (function->isEnabled(glbinding::CallbackMask::Parameters)) functionCall.parameters = glbinding::createValues(std::forward<Arguments>(arguments)...); if (function->isEnabled(glbinding::CallbackMask::Before)) function->before(functionCall); if (function->m_beforeCallback) { function->m_beforeCallback(std::forward<Arguments>(arguments)...); } basicCall(function, std::forward<Arguments>(arguments)...); if (function->m_afterCallback) { function->m_afterCallback(std::forward<Arguments>(arguments)...); } if (function->isEnabled(glbinding::CallbackMask::After)) function->after(functionCall); }
ReturnType call(const glbinding::Function<ReturnType, Arguments...> * function, Arguments&&... arguments) const { glbinding::FunctionCall functionCall(function); if (function->isEnabled(glbinding::CallbackMask::Parameters)) functionCall.parameters = glbinding::createValues(std::forward<Arguments>(arguments)...); if (function->isEnabled(glbinding::CallbackMask::Before)) function->before(functionCall); if (function->m_beforeCallback) { function->m_beforeCallback(std::forward<Arguments>(arguments)...); } ReturnType value = basicCall(function, std::forward<Arguments>(arguments)...); if (function->m_afterCallback) { function->m_afterCallback(value, std::forward<Arguments>(arguments)...); } if (function->isEnabled(glbinding::CallbackMask::After)) { if (function->isEnabled(glbinding::CallbackMask::ReturnValue)) functionCall.returnValue = glbinding::createValue(value); function->after(functionCall); } return value; }
/* enregistre un Bill australien */ DLLEXPORT xloper * xlInitiateBtf (const char * objectID_, const double * issueDate_, const double * maturityDate_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlInitiateBtf")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; // trigger pour provoquer le recalcul ObjectHandler::validateRange(trigger_, "trigger") ; // Construction du value object boost::shared_ptr<QuantLibAddin::ValueObjects::btfValueObject> myBondValueObject( new QuantLibAddin::ValueObjects::btfValueObject(objectID_, true)) ; // instanciation de l'instrument boost::shared_ptr<QuantLibAddin::btfObject> myBillObject( new QuantLibAddin::btfObject(myBondValueObject, QuantLib::Date(static_cast<QuantLib::BigInteger>(* maturityDate_)), QuantLib::Date(static_cast<QuantLib::BigInteger>(* issueDate_)), true)) ; // stockage de l'objet std::string returnValue = ObjectHandler::RepositoryXL::instance().storeObject(objectID_, myBillObject, true) ; // on force la réécriture static XLOPER returnOper ; ObjectHandler::scalarToOper(returnValue, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; ObjectHandler::scalarToOper(e.what(), returnOper) ; return & returnOper ; } } ;
// calculate gap end DLLEXPORT double xlCalendarPeriodCount (xloper * calculationDate_, const char * period_, xloper * calendar_, xloper * endDateConvention_, xloper * endOfMonth_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlCalendarPeriodCount")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; ObjectHandler::validateRange(calculationDate_ , "calculation Date" ); // range validation ObjectHandler::validateRange(calendar_ , "calendar" ); ObjectHandler::validateRange(endDateConvention_, "end Date Convention"); ObjectHandler::validateRange(endOfMonth_ , "end of Month" ); ObjectHandler::ConvertOper myOper1(* calculationDate_), // xloper myOper2(* calendar_), myOper3(* endDateConvention_), myOper4(* endOfMonth_) ; QuantLib::Date calculationDate( // calculation date myOper1.missing() ? QuantLib::Date() : QuantLib::Date(static_cast<QuantLib::BigInteger>(myOper1))) ; QuantLib::Calendar calendar( // calendar myOper2.missing() ? QuantLib::WeekendsOnly() : ObjectHandler::calendarFactory()(static_cast<std::string>(myOper2))) ; QuantLib::BusinessDayConvention endDateConvention( // business day convention myOper3.missing() ? QuantLib::Unadjusted : ObjectHandler::businessDayConventionFactory()(static_cast<std::string>(myOper3))) ; bool endOfMonth( // EOM rule myOper4.missing() ? false : static_cast<bool>(myOper4)) ; return calendar.advance(calculationDate, // period has to be provided ObjectHandler::periodFactory()(period_), endDateConvention, endOfMonth).serialNumber() ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; return 0.0 ; } }
/* fonction de calcul de la moyenne EWMA d'une série suivant un processus log-normal */ DLLEXPORT char * xlInitiateMatrix(const char * objectID_, const xloper * matrix_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlInitiateMatrix")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; // trigger pour provoquer le recalcul ObjectHandler::validateRange(trigger_, "trigger") ; /* conversion des xloper */ QuantLib::Matrix inputMatrix = ObjectHandler::operToMatrix(*matrix_, std::string("matrix_")) ; // value object boost::shared_ptr<QuantLibAddin::ValueObjects::matrixValueObject> myMatrixValueObject( new QuantLibAddin::ValueObjects::matrixValueObject(objectID_, true)) ; // new pointeur boost::shared_ptr<ObjectHandler::Object> myMatrixObject( new QuantLibAddin::matrixObject(myMatrixValueObject, inputMatrix, true)) ; // stockage de l'objet std::string returnValue = ObjectHandler::RepositoryXL::instance().storeObject(objectID_, myMatrixObject, true) ; static char ret[XL_MAX_STR_LEN] ; ObjectHandler::stringToChar(returnValue, ret) ; return ret ; } catch (std::exception & e) { static char ret[XL_MAX_STR_LEN] ; ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; ObjectHandler::stringToChar(e.what(), ret) ; return ret ; } } ;
Conversation::Conversation(const std::string &contact, QWidget *parent) : QWidget(parent), _contact(contact) { _call = false; _first = true; QLabel *name = new QLabel(tr(contact.c_str()), this); _textZone = new QLineEdit(this); _callButton = new QPushButton(this); _callButton->setIcon(QIcon("./gui/img/phone61.png")); _callButton->setIconSize(QSize(120, 120)); QPushButton *sendButton = new QPushButton(tr("Send"), this); _messageZone = new QTextEdit(this); QFont f("Calibri", 10, QFont::Bold); name->setFont(f); _messageZone->setStyleSheet("background-color:white;"); _messageZone->setReadOnly(true); /* Image */ std::stringstream pp; pp << "./gui/img/avatar" << g_PTUser.currentUser().getContactFromName(contact).getPic() << ".png"; QPixmap profilPicture(pp.str().c_str()); QLabel *imgP = new QLabel(this); imgP->setPixmap(profilPicture.scaled(432, 432, Qt::KeepAspectRatio)); /* --- */ int imgHeight = 432; int imgWidth = 432; /* MOVE */ connect(_callButton, SIGNAL(released()), this, SLOT(functionCall())); connect(sendButton, SIGNAL(released()), this, SLOT(functionText())); imgP->setGeometry(0, 0, imgHeight, imgWidth); name->setGeometry(10, imgHeight + 10, 160, 50); _messageZone->setGeometry(imgWidth, 0, 1370, 920); _textZone->setGeometry(imgWidth, 920, 1120, 100); sendButton->setGeometry(1660, 920, 100, 100); _callButton->setGeometry(130, 900, 120, 120); /* --- ¨*/ }
void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const int dealloc) { // Ignore function call? const bool ignore = bool(_settings->library.leakignore.find(tok->str()) != _settings->library.leakignore.end()); if (ignore) return; std::map<unsigned int, int> &alloctype = varInfo->alloctype; std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage; for (const Token *arg = tok->tokAt(2); arg; arg = arg->nextArgument()) { if (arg->str() == "new") arg = arg->next(); if ((Token::Match(arg, "%var% [-,)]") && arg->varId() > 0) || (Token::Match(arg, "& %var%") && arg->next()->varId() > 0)) { // goto variable if (arg->str() == "&") arg = arg->next(); // Is variable allocated? const auto var = alloctype.find(arg->varId()); if (var != alloctype.end()) { if (dealloc == NOALLOC) { // possible usage possibleUsage[arg->varId()] = tok->str(); if (var->second == DEALLOC && arg->previous()->str() == "&") varInfo->erase(arg->varId()); } else if (var->second == DEALLOC) { CheckOther checkOther(_tokenizer, _settings, _errorLogger); checkOther.doubleFreeError(tok, arg->str()); } else if (var->second != dealloc) { // mismatching allocation and deallocation mismatchError(tok, arg->str()); varInfo->erase(arg->varId()); } else { // deallocation var->second = DEALLOC; } } else if (dealloc != NOALLOC) { alloctype[arg->varId()] = DEALLOC; } } else if (Token::Match(arg, "%var% (")) { functionCall(arg, varInfo, dealloc); } } }
void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const std::string &dealloc) { std::map<unsigned int, std::string> &alloctype = varInfo->alloctype; std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage; // Ignore function call? const bool ignore = bool(cfgignore.find(tok->str()) != cfgignore.end()); //const bool use = bool(cfguse.find(tok->str()) != cfguse.end()); if (ignore) return; for (const Token *arg = tok->tokAt(2); arg; arg = arg->nextArgument()) { if ((Token::Match(arg, "%var% [-,)]") && arg->varId() > 0) || (Token::Match(arg, "& %var%") && arg->next()->varId() > 0)) { // goto variable if (arg->str() == "&") arg = arg->next(); // Is variable allocated? const std::map<unsigned int,std::string>::iterator var = alloctype.find(arg->varId()); if (var != alloctype.end()) { if (dealloc.empty()) { // possible usage possibleUsage[arg->varId()] = tok->str(); } else if (var->second == "dealloc") { CheckOther checkOther(_tokenizer, _settings, _errorLogger); checkOther.doubleFreeError(tok, arg->str()); } else if (var->second != dealloc) { // mismatching allocation and deallocation mismatchError(tok, arg->str()); varInfo->erase(arg->varId()); } else { // deallocation var->second = "dealloc"; } } else if (!dealloc.empty()) { alloctype[arg->varId()] = "dealloc"; } } else if (Token::Match(arg, "%var% (")) { functionCall(arg, varInfo, dealloc); } } }
DLLEXPORT xloper * xlMeanEWMA(const char * timeSeriesId_, const double * decay_, const double * valueDate_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlMeanEWMA")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; /* déclaration du trigger */ ObjectHandler::validateRange(trigger_, "trigger") ; /* récupération des séries */ OH_GET_REFERENCE(dataObject, timeSeriesId_, QuantLibAddin::TimeSeriesObject<double>, QuantLib::TimeSeries<double>) static XLOPER returnOper ; ObjectHandler::scalarToOper( meanEWMA(* dataObject, QuantLib::Date(static_cast<QuantLib::BigInteger>(* valueDate_)), decay_), returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; ObjectHandler::scalarToOper(e.what(), returnOper) ; return & returnOper ; } } ;
int Client::rpcCall(const std::string& fun, int* argTypes, void** args) const { FunctionSignature signature(fun, argTypes); int serverSocket = connectToServer(signature); if (serverSocket < 0) { return serverSocket; } Connection conn(serverSocket); FunctionCall functionCall(std::move(signature), args); if (conn.send(Message::Type::CALL, functionCall.serialize()) < 0) { conn.close(); return -1; } Message message; while (true) { int r = conn.read(&message); if (r < 0) { conn.close(); return -1; } else if (r > 0) { // Done conn.close(); break; } } if (message.type != Message::Type::CALL) { // Error return -1; } // Now we must deserialize the message auto callReturn = FunctionCall::deserialize(message); // Got the response back callReturn.writeDataTo(args); return 0; }
/* Fonction de calcul de l'accrued des instruments */ DLLEXPORT xloper * xlSwapConvexity (const char * instrumentId_, const char * curveId_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlSwapConvexity")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; // trigger pour provoquer le recalcul ObjectHandler::validateRange(trigger_, "trigger") ; QuantLib::Real returnValue ; OH_GET_REFERENCE(instrumentPtr, instrumentId_, QuantLibAddin::interestRateSwapObject, QuantLib::vanillaSwap2) //returnValue = instrumentPtr->dv01(); returnValue = 0; static XLOPER returnOper ; ObjectHandler::scalarToOper(returnValue, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; returnOper.xltype = xltypeErr ; returnOper.val.err = xlerrValue ; return & returnOper ; } } ;
void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const VarInfo::AllocInfo& allocation) { // Ignore function call? const bool ignore = bool(_settings->library.leakignore.find(tok->str()) != _settings->library.leakignore.end()); if (ignore) return; for (const Token *arg = tok->tokAt(2); arg; arg = arg->nextArgument()) { if (_tokenizer->isCPP() && arg->str() == "new") arg = arg->next(); if (Token::Match(arg, "%var% [-,)]") || Token::Match(arg, "& %var%")) { // goto variable if (arg->str() == "&") arg = arg->next(); // Is variable allocated? changeAllocStatus(varInfo, allocation, tok, arg); } else if (Token::Match(arg, "%name% (")) { functionCall(arg, varInfo, allocation); } } }
void call(const glbinding::Function<void, Arguments...> * function, Arguments&&... arguments) const { std::unique_ptr<glbinding::FunctionCall> functionCall(new glbinding::FunctionCall(function)); if (function->isAnyEnabled(glbinding::CallbackMask::Parameters | glbinding::CallbackMask::Logging)) { functionCall->parameters = glbinding::createValues(std::forward<Arguments>(arguments)...); } if (function->isEnabled(glbinding::CallbackMask::Before)) { function->before(*functionCall); } if (function->m_beforeCallback) { function->m_beforeCallback(std::forward<Arguments>(arguments)...); } basicCall(function, std::forward<Arguments>(arguments)...); if (function->m_afterCallback) { function->m_afterCallback(std::forward<Arguments>(arguments)...); } if (function->isEnabled(glbinding::CallbackMask::After)) { function->after(*functionCall); } if(function->isEnabled(glbinding::CallbackMask::Logging)) { glbinding::logging::log(functionCall.release()); } }
void CheckLeakAutoVar::checkScope(const Token * const startToken, VarInfo *varInfo, std::set<unsigned int> notzero) { std::map<unsigned int, int> &alloctype = varInfo->alloctype; std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage; const std::set<unsigned int> conditionalAlloc(varInfo->conditionalAlloc); // Parse all tokens const Token * const endToken = startToken->link(); for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) { // Deallocation and then dereferencing pointer.. if (tok->varId() > 0) { const std::map<unsigned int, int>::iterator var = alloctype.find(tok->varId()); if (var != alloctype.end()) { if (var->second == DEALLOC && !Token::Match(tok->previous(), "[;{},=] %var% =")) { deallocUseError(tok, tok->str()); } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) { varInfo->erase(tok->varId()); } else if (tok->strAt(-1) == "=") { varInfo->erase(tok->varId()); } } else if (Token::Match(tok->previous(), "& %var% = %var% ;")) { varInfo->referenced.insert(tok->tokAt(2)->varId()); } } if (tok->str() == "(" && tok->previous()->isName()) { functionCall(tok->previous(), varInfo, NOALLOC); tok = tok->link(); continue; } // look for end of statement if (!Token::Match(tok, "[;{}]") || Token::Match(tok->next(), "[;{}]")) continue; tok = tok->next(); if (!tok || tok == endToken) break; // parse statement // assignment.. if (tok->varId() && Token::Match(tok, "%var% =")) { // taking address of another variable.. if (Token::Match(tok->next(), "= %var% [+;]")) { if (tok->tokAt(2)->varId() != tok->varId()) { // If variable points at allocated memory => error leakIfAllocated(tok, *varInfo); // no multivariable checking currently => bail out for rhs variables for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) { if (tok2->str() == ";") { break; } if (tok2->varId()) { varInfo->erase(tok2->varId()); } } } } // is variable used in rhs? bool used_in_rhs = false; for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { if (tok2->str() == ";") { break; } if (tok->varId() == tok2->varId()) { used_in_rhs = true; break; } } // TODO: Better checking how the pointer is used in rhs? if (used_in_rhs) continue; // Variable has already been allocated => error if (conditionalAlloc.find(tok->varId()) == conditionalAlloc.end()) leakIfAllocated(tok, *varInfo); varInfo->erase(tok->varId()); // not a local variable nor argument? const Variable *var = tok->variable(); if (var && !var->isArgument() && !var->isLocal()) { continue; } // Don't check reference variables if (var && var->isReference()) continue; // allocation? if (Token::Match(tok->tokAt(2), "%type% (")) { int i = _settings->library.alloc(tok->tokAt(2)); if (i > 0) { alloctype[tok->varId()] = i; } } // Assigning non-zero value variable. It might be used to // track the execution for a later if condition. if (Token::Match(tok->tokAt(2), "%num% ;") && MathLib::toLongNumber(tok->strAt(2)) != 0) notzero.insert(tok->varId()); else if (Token::Match(tok->tokAt(2), "- %type% ;") && tok->tokAt(3)->isUpperCaseName()) notzero.insert(tok->varId()); else notzero.erase(tok->varId()); } // if/else else if (Token::simpleMatch(tok, "if (")) { // Parse function calls inside the condition for (const Token *innerTok = tok->tokAt(2); innerTok; innerTok = innerTok->next()) { if (innerTok->str() == ")") break; if (innerTok->str() == "(" && innerTok->previous()->isName()) { const int deallocId = _settings->library.dealloc(tok); functionCall(innerTok->previous(), varInfo, deallocId); innerTok = innerTok->link(); } } const Token *tok2 = tok->linkAt(1); if (Token::simpleMatch(tok2, ") {")) { VarInfo varInfo1(*varInfo); // VarInfo for if code VarInfo varInfo2(*varInfo); // VarInfo for else code if (Token::Match(tok->next(), "( %var% )")) { varInfo2.erase(tok->tokAt(2)->varId()); if (notzero.find(tok->tokAt(2)->varId()) != notzero.end()) varInfo2.clear(); } else if (Token::Match(tok->next(), "( ! %var% )|&&")) { varInfo1.erase(tok->tokAt(3)->varId()); } else if (Token::Match(tok->next(), "( %var% ( ! %var% ) )|&&")) { varInfo1.erase(tok->tokAt(5)->varId()); } else if (Token::Match(tok->next(), "( %var% < 0 )|&&")) { varInfo1.erase(tok->tokAt(2)->varId()); } else if (Token::Match(tok->next(), "( 0 > %var% )|&&")) { varInfo1.erase(tok->tokAt(4)->varId()); } else if (Token::Match(tok->next(), "( %var% > 0 )|&&")) { varInfo2.erase(tok->tokAt(2)->varId()); } else if (Token::Match(tok->next(), "( 0 < %var% )|&&")) { varInfo2.erase(tok->tokAt(4)->varId()); } checkScope(tok2->next(), &varInfo1, notzero); tok2 = tok2->linkAt(1); if (Token::simpleMatch(tok2, "} else {")) { checkScope(tok2->tokAt(2), &varInfo2, notzero); tok = tok2->linkAt(2)->previous(); } else { tok = tok2->previous(); } VarInfo old; old.swap(*varInfo); // Conditional allocation in varInfo1 std::map<unsigned int, int>::const_iterator it; for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) { if (varInfo2.alloctype.find(it->first) == varInfo2.alloctype.end() && old.alloctype.find(it->first) == old.alloctype.end()) { varInfo->conditionalAlloc.insert(it->first); } } // Conditional allocation in varInfo2 for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) { if (varInfo1.alloctype.find(it->first) == varInfo1.alloctype.end() && old.alloctype.find(it->first) == old.alloctype.end()) { varInfo->conditionalAlloc.insert(it->first); } } // Conditional allocation/deallocation for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) { if (it->second == DEALLOC && conditionalAlloc.find(it->first) != conditionalAlloc.end()) { varInfo->conditionalAlloc.erase(it->first); varInfo2.erase(it->first); } } for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) { if (it->second == DEALLOC && conditionalAlloc.find(it->first) != conditionalAlloc.end()) { varInfo->conditionalAlloc.erase(it->first); varInfo1.erase(it->first); } } alloctype.insert(varInfo1.alloctype.begin(), varInfo1.alloctype.end()); alloctype.insert(varInfo2.alloctype.begin(), varInfo2.alloctype.end()); possibleUsage.insert(varInfo1.possibleUsage.begin(), varInfo1.possibleUsage.end()); possibleUsage.insert(varInfo2.possibleUsage.begin(), varInfo2.possibleUsage.end()); } } // unknown control.. else if (Token::Match(tok, "%type% (") && Token::simpleMatch(tok->linkAt(1), ") {")) { varInfo->clear(); break; } // Function call.. else if (Token::Match(tok, "%type% (") && tok->str() != "return") { const int dealloc = _settings->library.dealloc(tok); functionCall(tok, varInfo, dealloc); tok = tok->next()->link(); // Handle scopes that might be noreturn if (dealloc == NOALLOC && Token::simpleMatch(tok, ") ; }")) { const std::string &functionName(tok->link()->previous()->str()); bool unknown = false; if (_tokenizer->IsScopeNoReturn(tok->tokAt(2), &unknown)) { if (!unknown) varInfo->clear(); else if (_settings->library.leakignore.find(functionName) == _settings->library.leakignore.end() && _settings->library.use.find(functionName) == _settings->library.use.end()) varInfo->possibleUsageAll(functionName); } } continue; } // return else if (tok->str() == "return") { ret(tok, *varInfo); varInfo->clear(); } // goto => weird execution path else if (tok->str() == "goto") { varInfo->clear(); } // continue/break else if (Token::Match(tok, "continue|break ;")) { varInfo->clear(); } // throw // TODO: if the execution leave the function then treat it as return else if (tok->str() == "throw") { varInfo->clear(); } } }
/* fonction de calcul de la matrice de variance-covariance d'un historique de taux */ DLLEXPORT xloper * xlCovarianceMatrixEWMA(const xloper * seriesId_, const double * decay_, const double * startDate_, const bool * norm_, const xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlCovarianceMatrixEWMA")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; /* déclaration du trigger */ ObjectHandler::validateRange(trigger_, "trigger") ; /* conversion des xloper */ std::vector<std::string> seriesId = ObjectHandler::operToVector<std::string>(* seriesId_, "seriesId") ; /* contrôle sur les dimensions */ QL_ENSURE(seriesId.size() >= 2, "unconsistent data set") ; /* on récupére les séries variationnelles */ std::vector<QuantLib::TimeSeries<double> > timeSeriesVector ; for (std::vector<std::string>::const_iterator It = seriesId.begin() ; It != seriesId.end() ; ++It) { OH_GET_REFERENCE(TimeSeriesPtr, * It, QuantLibAddin::TimeSeriesObject<double>, QuantLib::TimeSeries<double>) timeSeriesVector.push_back(* TimeSeriesPtr) ; } std::vector<QuantLib::TimeSeries<double> > nTimeSeriesVector ; /* selon le mode choisi */ if (* norm_ == true) { std::vector<QuantLib::TimeSeries<double> > deltaSeriesVector ; for (unsigned long i = 0 ; i < timeSeriesVector.size() ; i++) deltaSeriesVector.push_back( QuantLib::deltaTimeSeries<double>(timeSeriesVector[i])) ; /* création des vecteurs moyenne et std dev */ std::vector<double> mean ; std::vector<double> variance ; for (std::vector<QuantLib::TimeSeries<double> >::const_iterator It = deltaSeriesVector.begin() ; It < deltaSeriesVector.end() ; ++It) { variance.push_back(covarianceEWMA(* It, * It, QuantLib::Date(static_cast<QuantLib::BigInteger>(* startDate_)), decay_)) ; mean.push_back(meanEWMA(* It, QuantLib::Date(static_cast<QuantLib::BigInteger>(* startDate_)), decay_)) ; } /* Mode normé */ for (unsigned int i = 0 ; i < deltaSeriesVector.size() ; i++) { std::vector<double> tempValues ; std::vector<QuantLib::Date> tempDates ; for (QuantLib::TimeSeries<double>::const_iterator It = deltaSeriesVector[i].begin() ; It != deltaSeriesVector[i].end() ; ++It) { tempDates.push_back(It->first) ; tempValues.push_back((deltaSeriesVector[i][It->first] - mean[i]) / pow((deltaSeriesVector[i].size() + 1) * variance[i], 0.5)) ; } QuantLib::TimeSeries<double> tempSeries(tempDates.begin(), tempDates.end(), tempValues.begin()) ; nTimeSeriesVector.push_back(tempSeries) ; } } else { /* Mode non normé */ std::vector<double> mean ; for (std::vector<QuantLib::TimeSeries<double>>::const_iterator It = timeSeriesVector.begin() ; It < timeSeriesVector.end() ; ++It) mean.push_back(meanEWMA(* It, QuantLib::Date( static_cast<QuantLib::BigInteger>(* startDate_)), decay_)) ; /* on se contente de centrer les séries */ for (unsigned int i = 0 ; i < timeSeriesVector.size() ; i++) { std::vector<double> tempValues ; std::vector<QuantLib::Date> tempDates ; for (QuantLib::TimeSeries<double>::const_iterator It = timeSeriesVector[i].begin() ; It != timeSeriesVector[i].end() ; ++It) { tempDates.push_back(It->first) ; tempValues.push_back(timeSeriesVector[i][It->first] - mean[i]) ; } QuantLib::TimeSeries<double> tempSeries(tempDates.begin(), tempDates.end(), tempValues.begin()) ; nTimeSeriesVector.push_back(tempSeries) ; } } /* création de la matrice de retour */ QuantLib::Matrix returnMatrix( nTimeSeriesVector.size(), nTimeSeriesVector.size()) ; for (unsigned int i = 0 ; i < nTimeSeriesVector.size() ; i++) { for (unsigned int j = 0 ; j <= i ; j++) { returnMatrix[i][j] = covarianceEWMA(nTimeSeriesVector[i], nTimeSeriesVector[j], QuantLib::Date(static_cast<QuantLib::BigInteger>(* startDate_)), decay_) ; returnMatrix[j][i] = returnMatrix[i][j]; } } static OPER returnOper ; ObjectHandler::MatrixToOper(returnMatrix, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; return 0 ; } }
/* enregistre un helper pour un depôt */ DLLEXPORT xloper * xlInitiateDepositBootstrapHelper (const char * objectId_, const char * depositId_, const double * depositPrice_, const xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlInitiateDepositBootstrapHelper")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; // trigger pour provoquer le recalcul ObjectHandler::validateRange(trigger_, "trigger") ; OH_GET_REFERENCE(depositPtr, depositId_, QuantLibAddin::depositObject, QuantLib::deposit) // creation de la quote boost::shared_ptr<QuantLib::Quote> myQuote( new QuantLib::SimpleQuote(* depositPrice_)) ; // création du handler QuantLib::Handle<QuantLib::Quote> quoteHandler(myQuote) ; // creation du value object boost::shared_ptr<QuantLibAddin::ValueObjects::depositBootstrapHelperValueObject> depositValueObject( new QuantLibAddin::ValueObjects::depositBootstrapHelperValueObject(objectId_, true)) ; // creation du helper boost::shared_ptr<QuantLibAddin::depositBootstrapHelperObject> depositBootstrapObject( new QuantLibAddin::depositBootstrapHelperObject(depositValueObject, depositPtr, quoteHandler, true)) ; // stockage de l'objet std::string returnValue = ObjectHandler::RepositoryXL::instance().storeObject(objectId_, depositBootstrapObject, true) ; // on force la réécriture static XLOPER returnOper ; ObjectHandler::scalarToOper(returnValue, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; ObjectHandler::scalarToOper(e.what(), returnOper) ; return & returnOper ; } } ;
/* register a deposit for curve fitting */ DLLEXPORT xloper * xlInitiateDepositBootstrapHelper2 (const char * objectId_, const char * tenor_, const xloper * calendar_, const xloper * settlementDays_, const double * depositYield_, const xloper * annualBasis_, const xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlInitiateDepositBootstrapHelper2")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), ""); // range validation ObjectHandler::validateRange(trigger_ , "trigger" ); ObjectHandler::validateRange(calendar_ , "calendar" ); ObjectHandler::validateRange(settlementDays_, "settlement days"); ObjectHandler::validateRange(annualBasis_ , "annual basis" ); // OPER management ObjectHandler::ConvertOper myOper1(* calendar_ ), myOper2(* settlementDays_), myOper3(* annualBasis_ ); // creates a value object boost::shared_ptr<QuantLibAddin::ValueObjects::depositBootstrapHelperValueObject> depositValueObject( new QuantLibAddin::ValueObjects::depositBootstrapHelperValueObject( objectId_, true)) ; // quantlib objects QuantLib::Natural settlementDays( myOper2.missing() ? 2 : static_cast<long>(myOper2)) ; QuantLib::Calendar calendar( myOper1.missing() ? QuantLib::UnitedStates( QuantLib::UnitedStates::Settlement) : ObjectHandler::calendarFactory()( static_cast<std::string>(myOper1))); QuantLib::Date valueDate( calendar.advance( QuantLib::Settings::instance().evaluationDate().value(), settlementDays, QuantLib::Days)) ; QuantLib::DayCounter annualBasis( myOper3.missing() ? QuantLib::Actual360() : ObjectHandler::daycountFactory()( static_cast<std::string>(myOper3))); // creates the deposit boost::shared_ptr<QuantLib::deposit> myDepositPtr ( new QuantLib::deposit( valueDate, calendar.advance(valueDate, ObjectHandler::periodFactory()(tenor_)), calendar, settlementDays, QuantLib::Unadjusted)); // creates the helper boost::shared_ptr<QuantLibAddin::depositBootstrapHelperObject> depositBootstrapObject( new QuantLibAddin::depositBootstrapHelperObject( depositValueObject, myDepositPtr, QuantLib::Handle<QuantLib::Quote>( boost::shared_ptr<QuantLib::Quote>( new QuantLib::SimpleQuote( myDepositPtr->cleanPrice( *depositYield_, annualBasis, QuantLib::Simple, QuantLib::Once, QuantLib::Unadjusted, valueDate)))), true)); // storage of the object std::string returnValue = ObjectHandler::RepositoryXL::instance().storeObject( objectId_, depositBootstrapObject, true); static XLOPER returnOper ; ObjectHandler::scalarToOper(returnValue, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; ObjectHandler::scalarToOper(e.what(), returnOper) ; return & returnOper ; } };
/* enregistre un TIPS */ DLLEXPORT xloper * xlInitiateAussieNote (const char * objectID_, const double * issueDate_, xloper * effectiveDate_, xloper * firstCouponDate_, xloper * lastCouponDate_, const double * maturityDate_, const double * couponRate_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlInitiateAussieNote")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; // trigger pour provoquer le recalcul ObjectHandler::validateRange(trigger_, "trigger") ; ObjectHandler::validateRange(effectiveDate_, "effective Date") ; ObjectHandler::validateRange(firstCouponDate_, "first Coupon Date") ; ObjectHandler::validateRange(lastCouponDate_, "last Coupon Date") ; ObjectHandler::ConvertOper myOper1(* effectiveDate_) ; ObjectHandler::ConvertOper myOper2(* firstCouponDate_) ; ObjectHandler::ConvertOper myOper3(* lastCouponDate_) ; QuantLib::Date issueDate(static_cast<QuantLib::BigInteger>(* issueDate_)) ; QuantLib::Date effectiveDate(myOper1.missing() ? issueDate : static_cast<QuantLib::Date>(myOper1)) ; QuantLib::Date firstCouponDate(myOper2.missing() ? QuantLib::Date() : static_cast<QuantLib::Date>(myOper2)) ; QuantLib::Date lastCouponDate(myOper3.missing() ? QuantLib::Date() : static_cast<QuantLib::Date>(myOper3)) ; QuantLib::Date maturityDate(static_cast<QuantLib::BigInteger>(* maturityDate_)) ; // Construction du value object boost::shared_ptr<QuantLibAddin::ValueObjects::australianTreasuryNoteValueObject> myBondValueObject( new QuantLibAddin::ValueObjects::australianTreasuryNoteValueObject(objectID_, true)) ; // instanciation de l'instrument boost::shared_ptr<QuantLibAddin::australianTreasuryNoteObject> myBondObject( new QuantLibAddin::australianTreasuryNoteObject(myBondValueObject, issueDate, effectiveDate, firstCouponDate, lastCouponDate, maturityDate, QuantLib::Rate(* couponRate_), true)) ; // stockage de l'objet std::string returnValue = ObjectHandler::RepositoryXL::instance().storeObject(objectID_, myBondObject, true) ; // on force la réécriture static XLOPER returnOper ; ObjectHandler::scalarToOper(returnValue, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; ObjectHandler::scalarToOper(e.what(), returnOper) ; return & returnOper ; } } ;
/* Fonction de calcul du carry d'un bond */ DLLEXPORT xloper * xlInstrumentCarry (const char * instrumentId_, const double * startAccruedDate_, const double * endAccruedDate_, const double * instrumentYield_, const char * conventionId_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlInstrumentCarry")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; double returnValue ; // trigger pour provoquer le recalcul ObjectHandler::validateRange(trigger_, "trigger") ; // on récupère la convention OH_GET_REFERENCE(conventionPtr, conventionId_, QuantLibAddin::interestRateConventionObject, QuantLib::InterestRate) // on récupère l'instrument OH_GET_UNDERLYING(myBond, instrumentId_, QuantLibAddin::Bond, QuantLib::Bond) returnValue = myBond.cleanPrice(* instrumentYield_, conventionPtr->dayCounter(), conventionPtr->compounding(), conventionPtr->frequency(), conventionPtr->businessDayConvention(), myBond.settlementDate( QuantLib::Date(static_cast<QuantLib::BigInteger>(* endAccruedDate_)))) ; returnValue -= myBond.cleanPrice(* instrumentYield_, conventionPtr->dayCounter(), conventionPtr->compounding(), conventionPtr->frequency(), conventionPtr->businessDayConvention(), myBond.settlementDate( QuantLib::Date(static_cast<QuantLib::BigInteger>(* startAccruedDate_)))) ; // variable de retour static XLOPER returnOper ; ObjectHandler::scalarToOper(returnValue, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall); static XLOPER returnOper; returnOper.xltype = xltypeErr; returnOper.val.err = xlerrValue; return & returnOper; } }
/* Fonction de calcul d'un taux fixe de swap */ DLLEXPORT xloper * xlSwapFairFixedRate (const char * swapId_, const char * legId_, const char * curveId_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlSwapFairFixedRate")) ; try { QL_REQUIRE(! functionCall->calledByFunctionWizard(), "") ; // trigger pour provoquer le recalcul ObjectHandler::validateRange(trigger_, "trigger") ; // on récupère la courbe des taux OH_GET_OBJECT(curvePtr, curveId_, QuantLibAddin::YieldTermStructure) QuantLib::Handle<QuantLib::YieldTermStructure> YieldCurveLibObj = QuantLibAddin::CoerceHandle<QuantLibAddin::YieldTermStructure, QuantLib::YieldTermStructure>()(curvePtr) ; // setup de la date de pricing (reference date de la courbe) //QuantLib::Settings::instance().evaluationDate() = YieldCurveLibObj->referenceDate() ; // on récupère le swap OH_GET_OBJECT(objPtr, swapId_, ObjectHandler::Object) // calcul de la NPV totale des autres jambes QuantLib::Real fairRate = 0.0 ; // objet pour contrôle OH_GET_OBJECT(swapObj, swapId_, QuantLibAddin::interestRateSwapObject) // on spécialise le ptr OH_GET_REFERENCE(swapPtr, swapId_, QuantLibAddin::interestRateSwapObject, QuantLib::vanillaSwap2) // vérification que la jambe fait partie du swap QL_REQUIRE(swapObj->getLegType(std::string(legId_)) == "fixedLegUnitedStatesValueObject" || swapObj->getLegType(std::string(legId_)) == "fixedLegUnitedAustraliaValueObject", "unappropriate leg type") ; swapPtr->setPricingEngine(boost::shared_ptr<QuantLib::PricingEngine>( new QuantLib::DiscountingSwapEngine(YieldCurveLibObj))) ; // calcul de la NPV totale des autres jambes QuantLib::Size legRank = swapObj->getLegRank(std::string(legId_)) ; // on suppose que le taux est fixe (pas de step-up cpn) boost::shared_ptr<QuantLib::FixedRateCoupon> myCastedCashFlow = boost::dynamic_pointer_cast<QuantLib::FixedRateCoupon>(swapPtr->leg(legRank)[0]) ; fairRate = myCastedCashFlow->rate() - swapPtr->NPV()/(swapPtr->legBPS(legRank)/1.0e-4) ; static XLOPER returnOper ; ObjectHandler::scalarToOper(fairRate, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; ObjectHandler::scalarToOper(e.what(), returnOper) ; return & returnOper ; } } ;
// static int mutatorTest( BPatch_thread * appThread, BPatch_image * appImage ) { test_results_t test_stack_3_Mutator::executeTest() { bool passedTest; BPatch::bpatch->setInstrStackFrames(true); appProc->continueExecution(); static const frameInfo_t correct_frame_info[] = { #if defined( os_linux_test ) && (defined( arch_x86_test ) || defined( arch_x86_64_test )) { true, true, BPatch_frameNormal, "_dl_sysinfo_int80" }, #endif #if defined( os_aix_test ) && defined( arch_power_test ) /* AIX uses kill(), but the PC of a process in a syscall can not be correctly determined, and appears to be the address to which the syscall function will return. */ #elif defined( os_windows_test ) && (defined( arch_x86 ) || defined( arch_x86_64_test )) /* Windows/x86 does not use kill(), so its lowermost frame will be something unidentifiable in a system DLL. */ { false, false, BPatch_frameNormal, NULL }, #else { true, false, BPatch_frameNormal, "kill" }, #endif #if ! defined( os_windows_test ) /* Windows/x86's stop_process_() calls DebugBreak(); it's apparently normal to lose this frame. */ { true, false, BPatch_frameNormal, "stop_process_" }, #endif { true, false, BPatch_frameNormal, "test_stack_3_func3" }, { true, false, BPatch_frameTrampoline, NULL }, /* On AIX and x86 (and others), if our instrumentation fires before frame construction or after frame destruction, it's acceptable to not report the function (since, after all, it doesn't have a frame on the stack. */ { true, true, BPatch_frameNormal, "test_stack_3_func2" }, { true, false, BPatch_frameNormal, "test_stack_3_func1" }, { true, false, BPatch_frameNormal, "test_stack_3_mutateeTest" }, { true, false, BPatch_frameNormal, "main" } }; /* Wait for the mutatee to stop in test_stack_3_func1(). */ if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation") < 0) { appProc->terminateExecution(); return FAILED; } /* Instrument test_stack_3_func2() to call test_stack_3_func3(), which will trip another breakpoint. */ BPatch_Vector<BPatch_function *> instrumentedFunctions; const char *fName = "test_stack_3_func2"; appImage->findFunction(fName, instrumentedFunctions ); if (instrumentedFunctions.size() != 1) { // FIXME Print out a useful error message logerror("**Failed** test_stack_3\n"); logerror(" Unable to find function '%s'\n", fName); appProc->terminateExecution(); return FAILED; } BPatch_Vector<BPatch_point *> * functionEntryPoints = instrumentedFunctions[0]->findPoint( BPatch_entry ); if (functionEntryPoints->size() != 1) { // FIXME Print out a useful error message logerror("**Failed** test_stack_3\n"); logerror(" Unable to find entry point to function '%s'\n", fName); appProc->terminateExecution(); return FAILED; } BPatch_Vector<BPatch_function *> calledFunctions; const char *fName2 = "test_stack_3_func3"; appImage->findFunction(fName2, calledFunctions ); if (calledFunctions.size() != 1) { //FIXME Print out a useful error message logerror("**Failed** test_stack_3\n"); logerror(" Unable to find function '%s'\n", fName2); appProc->terminateExecution(); return FAILED; } BPatch_Vector<BPatch_snippet *> functionArguments; BPatch_funcCallExpr functionCall( * calledFunctions[0], functionArguments ); appProc->insertSnippet( functionCall, functionEntryPoints[0] ); /* Repeat for all three types of instpoints. */ BPatch_Vector<BPatch_point *> * functionCallPoints = instrumentedFunctions[0]->findPoint( BPatch_subroutine ); if (functionCallPoints->size() != 1) { logerror("**Failed** test_stack_3\n"); logerror(" Unable to find subroutine call points in '%s'\n", fName); appProc->terminateExecution(); return FAILED; } appProc->insertSnippet( functionCall, functionCallPoints[0] ); BPatch_Vector<BPatch_point *> * functionExitPoints = instrumentedFunctions[0]->findPoint( BPatch_exit ); if (functionExitPoints->size() != 1) { logerror("**Failed** test_stack_3\n"); logerror(" Unable to find exit points in '%s'\n", fName); appProc->terminateExecution(); return FAILED; } appProc->insertSnippet( functionCall, functionExitPoints[0] ); #if defined( DEBUG ) for( int i = 0; i < 80; i++ ) { ptrace( PTRACE_SINGLESTEP, appThread->getPid(), NULL, NULL ); } for( int i = 80; i < 120; i++ ) { ptrace( PTRACE_SINGLESTEP, appThread->getPid(), NULL, NULL ); BPatch_Vector<BPatch_frame> stack; appThread->getCallStack( stack ); dprintf("single-step stack walk, %d instructions after stop for instrumentation.\n", i ); for( unsigned i = 0; i < stack.size(); i++ ) { char name[ 40 ]; BPatch_function * func = stack[i].findFunction(); if( func == NULL ) { strcpy( name, "[UNKNOWN]" ); } else { func->getName( name, 40 ); } dprintf(" %10p: %s, fp = %p\n", stack[i].getPC(), name, stack[i].getFP() ); } /* end stack walk dumper */ dprintf("end of stack walk.\n" ); } /* end single-step iterator */ #endif /* defined( DEBUG ) */ /* After inserting the instrumentation, let it be called. */ appProc->continueExecution(); /* Wait for the mutatee to stop because of the instrumentation we just inserted. */ if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (entry)") < 0) { appProc->terminateExecution(); return FAILED; } passedTest = true; if( !checkStack( appThread, correct_frame_info, sizeof(correct_frame_info)/sizeof(frameInfo_t), 3, "getCallStack through instrumentation (entry)" ) ) { passedTest = false; } /* Repeat for other two types of instpoints. */ appProc->continueExecution(); /* Wait for the mutatee to stop because of the instrumentation we just inserted. */ if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (call)") < 0) { appProc->terminateExecution(); return FAILED; } if( !checkStack( appThread, correct_frame_info, sizeof(correct_frame_info)/sizeof(frameInfo_t), 3, "getCallStack through instrumentation (call)" ) ) { passedTest = false; } appProc->continueExecution(); /* Wait for the mutatee to stop because of the instrumentation we just inserted. */ if (waitUntilStopped( bpatch, appProc, 1, "getCallStack through instrumentation (exit)") < 0) { appProc->terminateExecution(); return FAILED; } if( !checkStack( appThread, correct_frame_info, sizeof(correct_frame_info)/sizeof(frameInfo_t), 3, "getCallStack through instrumentation (exit)" ) ) { passedTest = false; } if (passedTest) logerror("Passed test #3 (unwind through base and mini tramps)\n"); /* Return the mutatee to its normal state. */ appProc->continueExecution(); while (!appProc->isTerminated()) { // Workaround for issue with pgCC_high mutatee bpatch->waitForStatusChange(); } if (passedTest) return PASSED; return FAILED; } /* end mutatorTest3() */
/* Fonction de calcul de la NPV d'un swap ou d'une jambe */ DLLEXPORT xloper * xlSwapNPV (const char * instrumentId_, const char * discountCurveId_, xloper * forwardCurveId_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlSwapNPV")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; // validation ObjectHandler::validateRange(trigger_, "trigger") ; ObjectHandler::validateRange(forwardCurveId_, "forward Curve") ; // conversion des xloper ObjectHandler::ConvertOper myOper(* forwardCurveId_) ; // on récupère la courbe de discounting OH_GET_OBJECT(discountCurvePtr, discountCurveId_, ObjectHandler::Object) QuantLib::Handle<QuantLib::YieldTermStructure> discountCurveHandler = QuantLibAddin::CoerceHandle<QuantLibAddin::YieldTermStructure, QuantLib::YieldTermStructure>()(discountCurvePtr) ; // on récupère l'instrument OH_GET_REFERENCE(mySwap, instrumentId_, QuantLibAddin::interestRateSwapObject, QuantLib::vanillaSwap2) boost::shared_ptr<QuantLib::PricingEngine> myPricingEngine ; // ligature du pricing engine if (myOper.missing()) { myPricingEngine = boost::shared_ptr<QuantLib::PricingEngine>( new QuantLib::DiscountingSwapEngine(discountCurveHandler/*, discountCurveHandler*/)) ; //mySwap->setFixingIndex(* discountCurveHandler) ; } else { // on récupère la courbe forward OH_GET_OBJECT(forwardCurvePtr, static_cast<std::string>(myOper), ObjectHandler::Object) QuantLib::Handle<QuantLib::YieldTermStructure> forwardCurveHandler = QuantLibAddin::CoerceHandle<QuantLibAddin::YieldTermStructure, QuantLib::YieldTermStructure>()(forwardCurvePtr) ; myPricingEngine = boost::shared_ptr<QuantLib::PricingEngine>( new QuantLib::DiscountingSwapEngine(discountCurveHandler/*, forwardCurveHandler*/)) ; //mySwap->setFixingIndex(* forwardCurveHandler) ; } mySwap->setPricingEngine(myPricingEngine) ; static XLOPER returnOper ; ObjectHandler::scalarToOper(mySwap->NPV(), returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; ObjectHandler::scalarToOper(e.what(), returnOper) ; return & returnOper ; } } ;
/* enregistre une jambe à taux flottant */ DLLEXPORT xloper * xlInitiateFloatLegUnitedStates (const char * objectID_, const double * effectiveDate_, xloper * firstCouponDate_, xloper * lastCouponDate_, const double * maturityDate_, xloper * notional_, const char * indexId_, xloper * frequency_, xloper * daycounter_, xloper * spread_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlInitiatefloatLegUnitedStates")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; // vérification des codes erreur ObjectHandler::validateRange(trigger_, "trigger") ; ObjectHandler::validateRange(firstCouponDate_, "first Coupon Date") ; ObjectHandler::validateRange(lastCouponDate_, "last Coupon Date") ; ObjectHandler::validateRange(notional_, "notional") ; ObjectHandler::validateRange(frequency_, "frequency") ; ObjectHandler::validateRange(daycounter_, "daycounter") ; ObjectHandler::validateRange(spread_, "spread") ; // Création des oper ObjectHandler::ConvertOper myOper1(* firstCouponDate_), myOper2(* lastCouponDate_), myOper3(* notional_), myOper4(* frequency_), myOper5(* daycounter_), myOper6(* spread_) ; // création des dates et contrôles sur les dates intermédiaires QuantLib::Date effectiveDate(QuantLib::Date(static_cast<QuantLib::BigInteger>(* effectiveDate_))) ; QuantLib::Date maturityDate(QuantLib::Date(static_cast<QuantLib::BigInteger>(* maturityDate_))) ; QuantLib::Date firstCouponDate(myOper1.missing() ? QuantLib::Date() : QuantLib::Date(static_cast<QuantLib::BigInteger>(myOper1))) ; QuantLib::Date lastCouponDate(myOper2.missing() ? QuantLib::Date() : QuantLib::Date(static_cast<QuantLib::BigInteger>(myOper2))) ; QuantLib::Real notional(myOper3.missing() ? 100.0 : static_cast<QuantLib::Real>(myOper3)) ; QuantLib::Frequency frequency(myOper4.missing() ? QuantLib::Quarterly : ObjectHandler::frequencyFactory()(static_cast<std::string>(myOper4))) ; QuantLib::DayCounter daycounter(myOper5.missing() ? QuantLib::Actual360() : ObjectHandler::daycountFactory()(static_cast<std::string>(myOper5))) ; QuantLib::Spread spread(myOper6.missing() ? 0.0 : static_cast<QuantLib::Spread>(myOper6)) ; // on récupère l'index libor OH_GET_REFERENCE(iborIndexPtr, std::string(indexId_), QuantLibAddin::iborIndexObject, QuantLib::IborIndex) // Construction du value object boost::shared_ptr<QuantLibAddin::ValueObjects::floatLegUnitedStatesValueObject> myLegValueObject( new QuantLibAddin::ValueObjects::floatLegUnitedStatesValueObject(objectID_, true)) ; // instanciation de l'instrument boost::shared_ptr<QuantLibAddin::floatLegUnitedStatesObject> myLegObject( new QuantLibAddin::floatLegUnitedStatesObject(myLegValueObject, effectiveDate, firstCouponDate, lastCouponDate, maturityDate, iborIndexPtr, 2, frequency, daycounter, notional, spread, QuantLib::ModifiedFollowing, QuantLib::ModifiedFollowing, true, true)) ; // stockage de l'objet std::string returnValue = ObjectHandler::RepositoryXL::instance().storeObject(objectID_, myLegObject, true) ; // on force la réécriture static XLOPER returnOper ; ObjectHandler::scalarToOper(returnValue, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; ObjectHandler::scalarToOper(e.what(), returnOper) ; return & returnOper ; } } ;
void CheckLeakAutoVar::checkScope(const Token * const startToken, VarInfo *varInfo, std::set<unsigned int> notzero) { std::map<unsigned int, std::string> &alloctype = varInfo->alloctype; std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage; const std::set<unsigned int> conditionalAlloc(varInfo->conditionalAlloc); // Allocation functions. key = function name, value = allocation type std::map<std::string, std::string> allocFunctions(cfgalloc); allocFunctions["malloc"] = "malloc"; allocFunctions["strdup"] = "malloc"; allocFunctions["fopen"] = "fopen"; // Deallocation functions. key = function name, value = allocation type std::map<std::string, std::string> deallocFunctions(cfgdealloc); deallocFunctions["free"] = "malloc"; deallocFunctions["fclose"] = "fopen"; // Parse all tokens const Token * const endToken = startToken->link(); for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) { // Deallocation and then dereferencing pointer.. if (tok->varId() > 0) { const std::map<unsigned int, std::string>::iterator var = alloctype.find(tok->varId()); if (var != alloctype.end()) { if (var->second == "dealloc" && !Token::Match(tok->previous(), "[;{},=] %var% =")) { deallocUseError(tok, tok->str()); } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) { varInfo->erase(tok->varId()); } else if (Token::simpleMatch(tok->previous(), "=")) { varInfo->erase(tok->varId()); } } } if (tok->str() == "(" && tok->previous()->isName()) { functionCall(tok->previous(), varInfo, ""); tok = tok->link(); continue; } // look for end of statement if (!Token::Match(tok, "[;{}]") || Token::Match(tok->next(), "[;{}]")) continue; tok = tok->next(); if (tok == endToken) break; // parse statement // assignment.. if (tok && tok->varId() && Token::Match(tok, "%var% =")) { // taking address of another variable.. if (Token::Match(tok->next(), "= %var% [+;]")) { if (tok->tokAt(2)->varId() != tok->varId()) { // If variable points at allocated memory => error leakIfAllocated(tok, *varInfo); // no multivariable checking currently => bail out for rhs variables for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) { if (tok2->str() == ";") { break; } if (tok2->varId()) { varInfo->erase(tok2->varId()); } } } } // is variable used in rhs? bool used_in_rhs = false; for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { if (tok2->str() == ";") { break; } if (tok->varId() == tok2->varId()) { used_in_rhs = true; break; } } // TODO: Better checking how the pointer is used in rhs? if (used_in_rhs) continue; // Variable has already been allocated => error if (conditionalAlloc.find(tok->varId()) == conditionalAlloc.end()) leakIfAllocated(tok, *varInfo); varInfo->erase(tok->varId()); // not a local variable nor argument? const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok->varId()); if (var && !var->isArgument() && !var->isLocal()) { continue; } // Don't check reference variables if (var && var->isReference()) continue; // allocation? if (Token::Match(tok->tokAt(2), "%type% (")) { const std::map<std::string, std::string>::const_iterator it = allocFunctions.find(tok->strAt(2)); if (it != allocFunctions.end()) { alloctype[tok->varId()] = it->second; } } // Assigning non-zero value variable. It might be used to // track the execution for a later if condition. if (Token::Match(tok->tokAt(2), "%num% ;") && MathLib::toLongNumber(tok->strAt(2)) != 0) notzero.insert(tok->varId()); else if (Token::Match(tok->tokAt(2), "- %type% ;") && tok->tokAt(3)->isUpperCaseName()) notzero.insert(tok->varId()); else notzero.erase(tok->varId()); } // if/else else if (Token::simpleMatch(tok, "if (")) { // Parse function calls inside the condition for (const Token *innerTok = tok->tokAt(2); innerTok; innerTok = innerTok->next()) { if (innerTok->str() == ")") break; if (innerTok->str() == "(" && innerTok->previous()->isName()) { std::string dealloc; { const std::map<std::string, std::string>::iterator func = deallocFunctions.find(tok->str()); if (func != deallocFunctions.end()) { dealloc = func->second; } } functionCall(innerTok->previous(), varInfo, dealloc); innerTok = innerTok->link(); } } const Token *tok2 = tok->linkAt(1); if (Token::simpleMatch(tok2, ") {")) { VarInfo varInfo1(*varInfo); VarInfo varInfo2(*varInfo); if (Token::Match(tok->next(), "( %var% )")) { varInfo2.erase(tok->tokAt(2)->varId()); if (notzero.find(tok->tokAt(2)->varId()) != notzero.end()) varInfo2.clear(); } else if (Token::Match(tok->next(), "( ! %var% )|&&")) { varInfo1.erase(tok->tokAt(3)->varId()); } else if (Token::Match(tok->next(), "( %var% ( ! %var% ) )|&&")) { varInfo1.erase(tok->tokAt(5)->varId()); } checkScope(tok2->next(), &varInfo1, notzero); tok2 = tok2->linkAt(1); if (Token::simpleMatch(tok2, "} else {")) { checkScope(tok2->tokAt(2), &varInfo2, notzero); tok = tok2->linkAt(2)->previous(); } else { tok = tok2->previous(); } VarInfo old; old.swap(*varInfo); // Conditional allocation in varInfo1 std::map<unsigned int, std::string>::const_iterator it; for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) { if (varInfo2.alloctype.find(it->first) == varInfo2.alloctype.end() && old.alloctype.find(it->first) == old.alloctype.end()) { varInfo->conditionalAlloc.insert(it->first); } } // Conditional allocation in varInfo2 for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) { if (varInfo1.alloctype.find(it->first) == varInfo1.alloctype.end() && old.alloctype.find(it->first) == old.alloctype.end()) { varInfo->conditionalAlloc.insert(it->first); } } // Conditional allocation/deallocation for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) { if (it->second == "dealloc" && conditionalAlloc.find(it->first) != conditionalAlloc.end()) { varInfo->conditionalAlloc.erase(it->first); varInfo2.erase(it->first); } } for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) { if (it->second == "dealloc" && conditionalAlloc.find(it->first) != conditionalAlloc.end()) { varInfo->conditionalAlloc.erase(it->first); varInfo1.erase(it->first); } } alloctype.insert(varInfo1.alloctype.begin(), varInfo1.alloctype.end()); alloctype.insert(varInfo2.alloctype.begin(), varInfo2.alloctype.end()); possibleUsage.insert(varInfo1.possibleUsage.begin(), varInfo1.possibleUsage.end()); possibleUsage.insert(varInfo2.possibleUsage.begin(), varInfo2.possibleUsage.end()); } } // unknown control.. else if (Token::Match(tok, "%type% (") && Token::simpleMatch(tok->linkAt(1), ") {")) { varInfo->clear(); break; } // Function call.. else if (Token::Match(tok, "%type% (") && tok->str() != "return") { std::string dealloc; { const std::map<std::string, std::string>::iterator func = deallocFunctions.find(tok->str()); if (func != deallocFunctions.end()) { dealloc = func->second; } } functionCall(tok, varInfo, dealloc); tok = tok->next()->link(); // Handle scopes that might be noreturn if (dealloc.empty() && Token::simpleMatch(tok, ") ; }")) { const std::string &functionName(tok->link()->previous()->str()); bool unknown = false; if (cfgignore.find(functionName) == cfgignore.end() && cfguse.find(functionName) == cfguse.end() && _tokenizer->IsScopeNoReturn(tok->tokAt(2), &unknown)) { if (unknown) { //const std::string &functionName(tok->link()->previous()->str()); varInfo->possibleUsageAll(functionName); } else { varInfo->clear(); } } } continue; } // return else if (tok->str() == "return" || tok->str() == "throw") { ret(tok, *varInfo); varInfo->clear(); } } }
/* Fonction de calcul de l'accrued des instruments */ DLLEXPORT xloper * xlSwapDV01 (const char * instrumentId_, const char * curveId_, const char * conventionId_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlSwapDV01")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; // trigger pour provoquer le recalcul ObjectHandler::validateRange(trigger_, "trigger") ; QuantLib::Real returnValue ; // on récupère la courbe OH_GET_OBJECT(curvePtr, curveId_, ObjectHandler::Object) // on récupère la convention de taux OH_GET_OBJECT(conventionPtr, conventionId_, QuantLibAddin::interestRateConventionObject) QuantLib::Handle<QuantLib::YieldTermStructure> curveLibPtr = QuantLibAddin::CoerceHandle<QuantLibAddin::YieldTermStructure, QuantLib::YieldTermStructure>()(curvePtr) ; QuantLib::Handle<QuantLib::Quote> mySpread( new QuantLib::SimpleQuote(1.0 / 100)) ; // 1 bp QuantLib::Handle<QuantLib::YieldTermStructure> myShiftedCurve( new QuantLib::ZeroSpreadedTermStructure(curveLibPtr, mySpread, conventionPtr->compounding(), conventionPtr->frequency(), conventionPtr->daycounter())) ; // on récupère l'instrument OH_GET_OBJECT(instrumentPtr, instrumentId_, ObjectHandler::Object) /* IRS */ if (instrumentPtr->properties()->className() == "interestRateSwapValueObject") { QuantLib::Handle<QuantLib::vanillaSwap2> swapPtr = QuantLibAddin::CoerceHandle<QuantLibAddin::interestRateSwapObject, QuantLib::vanillaSwap2>()(instrumentPtr) ; returnValue = QuantLib::CashFlows::npv(swapPtr->leg(0), ** curveLibPtr, QuantLib::Unadjusted, QuantLib::Calendar(), false) * swapPtr->receivingLeg(0) ; returnValue += QuantLib::CashFlows::npv(swapPtr->leg(1), ** curveLibPtr, QuantLib::Unadjusted, QuantLib::Calendar(), false) * swapPtr->receivingLeg(1) ; returnValue -= QuantLib::CashFlows::npv(swapPtr->leg(0), ** myShiftedCurve, QuantLib::Unadjusted, QuantLib::Calendar(), false) * swapPtr->receivingLeg(0) ; returnValue -= QuantLib::CashFlows::npv(swapPtr->leg(1), ** myShiftedCurve, QuantLib::Unadjusted, QuantLib::Calendar(), false) * swapPtr->receivingLeg(1) ; } /* jambe fixe */ else if (instrumentPtr->properties()->className() == "fixedLegAustraliaValueObject" || instrumentPtr->properties()->className() == "fixedLegUnitedStatesValueObject"|| instrumentPtr->properties()->className() == "floatLegAustraliaValueObject" || instrumentPtr->properties()->className() == "floatLegUnitedStatesValueObject") { OH_GET_REFERENCE(instrumentLibObj, instrumentId_, QuantLibAddin::Leg, QuantLib::Leg) returnValue = QuantLib::CashFlows::npv(* instrumentLibObj, ** curveLibPtr, QuantLib::Unadjusted, QuantLib::Calendar(), false) ; returnValue -= QuantLib::CashFlows::npv(* instrumentLibObj, ** myShiftedCurve, QuantLib::Unadjusted, QuantLib::Calendar(), false) ; } else { // ici pour les autres instruments QL_FAIL("unknown instrument type") ; } static XLOPER returnOper ; ObjectHandler::scalarToOper(returnValue, returnOper) ; return & returnOper ; } catch (std::exception & e) { ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; returnOper.xltype = xltypeErr ; returnOper.val.err = xlerrValue ; return & returnOper ; } } ;
/* Fonction de calcul du nombre de flux restant */ DLLEXPORT xloper * xlInstrumentFlowCount (const char * instrumentId_, xloper * settlementDate_, xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlInstrumentFlowCount")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; /* recherche de code erreur */ ObjectHandler::validateRange(trigger_, "trigger") ; ObjectHandler::validateRange(settlementDate_, "settlement Date") ; /* on récupère l'instrument */ OH_GET_UNDERLYING(myBond, instrumentId_, QuantLibAddin::Bond, QuantLib::Bond) /* les XLOPER des date */ ObjectHandler::ConvertOper myOper(* settlementDate_) ; QuantLib::Date settlementDate( myOper.missing() ? QuantLib::Date() : QuantLib::Date(static_cast<QuantLib::BigInteger>(myOper))) ; QuantLib::Natural returnValue = 0; // increments for (std::vector<boost::shared_ptr<QuantLib::CashFlow> >::const_reverse_iterator It = myBond.cashflows().crbegin(); It != myBond.cashflows().crend(); It++) It->get()->date() > settlementDate ? returnValue++ : 0; static XLOPER returnOper ; ObjectHandler::scalarToOper(static_cast<double>(returnValue), returnOper) ; return & returnOper ; } catch (std::exception & e) { #ifdef _DEBUG OutputDebugString(e.what()) ; #endif ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall) ; static XLOPER returnOper ; returnOper.xltype = xltypeErr ; returnOper.val.err = xlerrValue ; return & returnOper ; } } ;
void CheckLeakAutoVar::checkScope(const Token * const startToken, VarInfo *varInfo, std::set<unsigned int> notzero) { std::map<unsigned int, VarInfo::AllocInfo> &alloctype = varInfo->alloctype; std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage; const std::set<unsigned int> conditionalAlloc(varInfo->conditionalAlloc); // Parse all tokens const Token * const endToken = startToken->link(); for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) { if (!tok->scope()->isExecutable()) { tok = tok->scope()->classEnd; if (!tok) // Ticket #6666 (crash upon invalid code) break; } // Deallocation and then dereferencing pointer.. if (tok->varId() > 0) { const std::map<unsigned int, VarInfo::AllocInfo>::const_iterator var = alloctype.find(tok->varId()); if (var != alloctype.end()) { if (var->second.status == VarInfo::DEALLOC && tok->strAt(-1) != "&" && (!Token::Match(tok, "%name% =") || tok->strAt(-1) == "*")) { deallocUseError(tok, tok->str()); } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) { varInfo->erase(tok->varId()); } else if (tok->strAt(-1) == "=") { varInfo->erase(tok->varId()); } } else if (Token::Match(tok->previous(), "& %name% = %var% ;")) { varInfo->referenced.insert(tok->tokAt(2)->varId()); } } if (tok->str() == "(" && tok->previous()->isName()) { VarInfo::AllocInfo allocation(0, VarInfo::NOALLOC); functionCall(tok->previous(), varInfo, allocation); tok = tok->link(); continue; } // look for end of statement if (!Token::Match(tok, "[;{}]") || Token::Match(tok->next(), "[;{}]")) continue; tok = tok->next(); if (!tok || tok == endToken) break; // parse statement, skip to last member while (Token::Match(tok, "%name% ::|. %name% !!(")) tok = tok->tokAt(2); // assignment.. if (Token::Match(tok, "%var% =")) { // taking address of another variable.. if (Token::Match(tok->next(), "= %var% [+;]")) { if (tok->tokAt(2)->varId() != tok->varId()) { // If variable points at allocated memory => error leakIfAllocated(tok, *varInfo); // no multivariable checking currently => bail out for rhs variables for (const Token *tok2 = tok; tok2; tok2 = tok2->next()) { if (tok2->str() == ";") { break; } if (tok2->varId()) { varInfo->erase(tok2->varId()); } } } } // is variable used in rhs? bool used_in_rhs = false; for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) { if (tok2->str() == ";") { break; } if (tok->varId() == tok2->varId()) { used_in_rhs = true; break; } } // TODO: Better checking how the pointer is used in rhs? if (used_in_rhs) continue; // Variable has already been allocated => error if (conditionalAlloc.find(tok->varId()) == conditionalAlloc.end()) leakIfAllocated(tok, *varInfo); varInfo->erase(tok->varId()); // not a local variable nor argument? const Variable *var = tok->variable(); if (var && !var->isArgument() && (!var->isLocal() || var->isStatic())) continue; // Don't check reference variables if (var && var->isReference()) continue; // non-pod variable if (_tokenizer->isCPP()) { if (!var) continue; // Possibly automatically deallocated memory if (!var->typeStartToken()->isStandardType() && Token::Match(tok, "%var% = new")) continue; } // allocation? if (tok->next()->astOperand2() && Token::Match(tok->next()->astOperand2()->previous(), "%type% (")) { int i = _settings->library.alloc(tok->next()->astOperand2()->previous()); if (i > 0) { alloctype[tok->varId()].type = i; alloctype[tok->varId()].status = VarInfo::ALLOC; } } else if (_tokenizer->isCPP() && tok->strAt(2) == "new") { alloctype[tok->varId()].type = -1; alloctype[tok->varId()].status = VarInfo::ALLOC; } // Assigning non-zero value variable. It might be used to // track the execution for a later if condition. if (Token::Match(tok->tokAt(2), "%num% ;") && MathLib::toLongNumber(tok->strAt(2)) != 0) notzero.insert(tok->varId()); else if (Token::Match(tok->tokAt(2), "- %type% ;") && tok->tokAt(3)->isUpperCaseName()) notzero.insert(tok->varId()); else notzero.erase(tok->varId()); } // if/else else if (Token::simpleMatch(tok, "if (")) { // Parse function calls inside the condition for (const Token *innerTok = tok->tokAt(2); innerTok; innerTok = innerTok->next()) { if (innerTok->str() == ")") break; if (innerTok->str() == "(" && innerTok->previous()->isName()) { VarInfo::AllocInfo allocation(_settings->library.dealloc(tok), VarInfo::DEALLOC); if (allocation.type == 0) allocation.status = VarInfo::NOALLOC; functionCall(innerTok->previous(), varInfo, allocation); innerTok = innerTok->link(); } } const Token *tok2 = tok->linkAt(1); if (Token::simpleMatch(tok2, ") {")) { VarInfo varInfo1(*varInfo); // VarInfo for if code VarInfo varInfo2(*varInfo); // VarInfo for else code // Recursively scan variable comparisons in condition std::stack<const Token *> tokens; tokens.push(tok->next()->astOperand2()); while (!tokens.empty()) { const Token *tok3 = tokens.top(); tokens.pop(); if (!tok3) continue; if (tok3->str() == "&&") { tokens.push(tok3->astOperand1()); tokens.push(tok3->astOperand2()); continue; } if (tok3->str() == "(" && Token::Match(tok3->astOperand1(), "UNLIKELY|LIKELY")) { tokens.push(tok3->astOperand2()); continue; } const Token *vartok = nullptr; if (astIsVariableComparison(tok3, "!=", "0", &vartok)) { varInfo2.erase(vartok->varId()); if (notzero.find(vartok->varId()) != notzero.end()) varInfo2.clear(); } else if (astIsVariableComparison(tok3, "==", "0", &vartok)) { varInfo1.erase(vartok->varId()); } else if (astIsVariableComparison(tok3, "<", "0", &vartok)) { varInfo1.erase(vartok->varId()); } else if (astIsVariableComparison(tok3, ">", "0", &vartok)) { varInfo2.erase(vartok->varId()); } else if (astIsVariableComparison(tok3, "==", "-1", &vartok)) { varInfo1.erase(vartok->varId()); } } checkScope(tok2->next(), &varInfo1, notzero); tok2 = tok2->linkAt(1); if (Token::simpleMatch(tok2, "} else {")) { checkScope(tok2->tokAt(2), &varInfo2, notzero); tok = tok2->linkAt(2)->previous(); } else { tok = tok2->previous(); } VarInfo old; old.swap(*varInfo); // Conditional allocation in varInfo1 std::map<unsigned int, VarInfo::AllocInfo>::const_iterator it; for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) { if (varInfo2.alloctype.find(it->first) == varInfo2.alloctype.end() && old.alloctype.find(it->first) == old.alloctype.end()) { varInfo->conditionalAlloc.insert(it->first); } } // Conditional allocation in varInfo2 for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) { if (varInfo1.alloctype.find(it->first) == varInfo1.alloctype.end() && old.alloctype.find(it->first) == old.alloctype.end()) { varInfo->conditionalAlloc.insert(it->first); } } // Conditional allocation/deallocation for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) { if (it->second.status == VarInfo::DEALLOC && conditionalAlloc.find(it->first) != conditionalAlloc.end()) { varInfo->conditionalAlloc.erase(it->first); varInfo2.erase(it->first); } } for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) { if (it->second.status == VarInfo::DEALLOC && conditionalAlloc.find(it->first) != conditionalAlloc.end()) { varInfo->conditionalAlloc.erase(it->first); varInfo1.erase(it->first); } } alloctype.insert(varInfo1.alloctype.begin(), varInfo1.alloctype.end()); alloctype.insert(varInfo2.alloctype.begin(), varInfo2.alloctype.end()); possibleUsage.insert(varInfo1.possibleUsage.begin(), varInfo1.possibleUsage.end()); possibleUsage.insert(varInfo2.possibleUsage.begin(), varInfo2.possibleUsage.end()); } } // unknown control.. (TODO: handle loops) else if ((Token::Match(tok, "%type% (") && Token::simpleMatch(tok->linkAt(1), ") {")) || Token::simpleMatch(tok, "do {")) { varInfo->clear(); break; } // return else if (tok->str() == "return") { ret(tok, *varInfo); varInfo->clear(); } // throw else if (_tokenizer->isCPP() && tok->str() == "throw") { bool tryFound = false; const Scope* scope = tok->scope(); while (scope && scope->isExecutable()) { if (scope->type == Scope::eTry) tryFound = true; scope = scope->nestedIn; } // If the execution leaves the function then treat it as return if (!tryFound) ret(tok, *varInfo); varInfo->clear(); } // Function call.. else if (Token::Match(tok, "%type% (")) { VarInfo::AllocInfo allocation(_settings->library.dealloc(tok), VarInfo::DEALLOC); if (allocation.type == 0) allocation.status = VarInfo::NOALLOC; functionCall(tok, varInfo, allocation); tok = tok->next()->link(); // Handle scopes that might be noreturn if (allocation.status == VarInfo::NOALLOC && Token::simpleMatch(tok, ") ; }")) { const std::string &functionName(tok->link()->previous()->str()); bool unknown = false; if (_tokenizer->IsScopeNoReturn(tok->tokAt(2), &unknown)) { if (!unknown) varInfo->clear(); else if (_settings->library.leakignore.find(functionName) == _settings->library.leakignore.end() && _settings->library.use.find(functionName) == _settings->library.use.end()) varInfo->possibleUsageAll(functionName); } } continue; } // delete else if (_tokenizer->isCPP() && tok->str() == "delete") { if (tok->strAt(1) == "[") tok = tok->tokAt(3); else tok = tok->next(); while (Token::Match(tok, "%name% ::|.")) tok = tok->tokAt(2); if (tok->varId() && tok->strAt(1) != "[") { VarInfo::AllocInfo allocation(-1, VarInfo::DEALLOC); changeAllocStatus(varInfo, allocation, tok, tok); } } // goto => weird execution path else if (tok->str() == "goto") { varInfo->clear(); } // continue/break else if (Token::Match(tok, "continue|break ;")) { varInfo->clear(); } } }
// register an interpolated curve object DLLEXPORT char * xlInitiateInterpolatedCurve(const char * objectID_ , xloper * calculationDate_, const char * curveCalendarId_, xloper * helperId_ , xloper * trigger_ ) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlInitiateInterpolatedCurve")) ; try { QL_ENSURE(! functionCall->calledByFunctionWizard(), "") ; // range validation ObjectHandler::validateRange(trigger_ , "trigger" ); ObjectHandler::validateRange(helperId_ , "helper Id" ); ObjectHandler::validateRange(calculationDate_, "calculation Date"); ObjectHandler::ConvertOper myOper1(* calculationDate_) ; // xlopers std::vector<std::string> helperId = ObjectHandler::operToVector<std::string>( * helperId_, "helper Id") ; QuantLib::Date currentDate( // initiate pricing date myOper1.missing() ? QuantLib::Date() : QuantLib::Date(static_cast<QuantLib::BigInteger>(myOper1))); std::vector<boost::shared_ptr<QuantLib::BootstrapHelper< // the helpers QuantLib::YieldTermStructure> > > helpers; for (std::vector<std::string>::const_iterator It = helperId.begin(); It != helperId.end(); ++It) { OH_GET_REFERENCE(helperPtr, * It, // get helper references QuantLibAddin::RateHelper, QuantLib::RateHelper); helpers.push_back(helperPtr); } // Construction du value object boost::shared_ptr<QuantLibAddin::ValueObjects::interpolatedCurveValueObject> curveValueObject( new QuantLibAddin::ValueObjects::interpolatedCurveValueObject( objectID_, currentDate.serialNumber(), true)) ; // creates the curve boost::shared_ptr<ObjectHandler::Object> myCurve( new QuantLibAddin::interpolatedCurveObject( curveValueObject, currentDate, helpers, true, std::vector<QuantLib::Handle<QuantLib::Quote> >(), // empty jump date std::vector<QuantLib::Date>(), CURVE_DEFAULT_ACCURACY)); // object storage std::string returnValue = ObjectHandler::RepositoryXL::instance().storeObject(objectID_, myCurve, true); static char ret[XL_MAX_STR_LEN] ; ObjectHandler::stringToChar(returnValue, ret); return ret; } catch (std::exception & e) { static char ret[XL_MAX_STR_LEN]; ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall); ObjectHandler::stringToChar(e.what(), ret); return ret; } } ;
// parametric fitted curve DLLEXPORT char * xlInitiateFittedBondDiscountCurve (const char * objectID_ , const xloper * evaluationDate_ , const xloper * settlementDate_ , const xloper * instruments_ , const xloper * quote_ , const char * calendarID_ , const char * fittingMethodID_ , const xloper * bondSelectionRule_, const xloper * trigger_) { boost::shared_ptr<ObjectHandler::FunctionCall> functionCall( new ObjectHandler::FunctionCall("xlInitiateFittedBondDiscountCurve")); try { QL_ENSURE(! functionCall->calledByFunctionWizard(), ""); // called by wizard ? ObjectHandler::validateRange(trigger_, "trigger" ); // validate range ObjectHandler::validateRange(settlementDate_, "settlement Date" ); ObjectHandler::validateRange(instruments_, "instruments" ); ObjectHandler::validateRange(quote_, "quotes" ); ObjectHandler::validateRange(bondSelectionRule_, "bond selection rule"); ObjectHandler::ConvertOper myOper1(* bondSelectionRule_); // bond selection rule oper QuantLib::bondSelectionRule myRule = // the rule (myOper1.missing() ? QuantLib::activeRule() : ObjectHandler::bondSelectionRuleFactory()( static_cast<std::string>(myOper1))); QuantLib::Calendar curveCalendar // calendar = ObjectHandler::calendarFactory()(calendarID_); ObjectHandler::ConvertOper oper1(* evaluationDate_); // evaluation date QuantLib::Date evaluationDate(oper1.missing() ? QuantLib::Date() : static_cast<QuantLib::Date>(oper1)); std::vector<std::string> instruments = // instrument ids ObjectHandler::operToVector<std::string>( * instruments_, "instruments"); std::vector<QuantLib::Real> quote = // quotes ObjectHandler::operToVector<double>( * quote_, "quote"); std::vector<boost::shared_ptr<QuantLib::BondHelper> > instrumentsObject; // helpers for (unsigned int i = 0 ; i < instruments.size() ; i++) { // capture individual bonds try { OH_GET_REFERENCE(instrumentPtr, // get a reference instruments[i], QuantLibAddin::Bond, QuantLib::Bond) if (quote[i] != 0.0 && instrumentPtr->isTradable()) { // valid quote ? QuantLib::RelinkableHandle<QuantLib::Quote> quoteHandle; // the handler quoteHandle.linkTo(boost::shared_ptr<QuantLib::Quote>( // link to the quote new QuantLib::SimpleQuote(quote[i]))); boost::shared_ptr<QuantLib::BondHelper> noteHelper( // the helper new QuantLib::BondHelper(quoteHandle, instrumentPtr)); instrumentsObject.push_back(noteHelper); // helper storage } } catch (...) {} // nothing on exception } ObjectHandler::ConvertOper oper2(* settlementDate_); // settlement date QuantLib::Date settlementDate(oper2.missing() ? instrumentsObject[0]->bond()->settlementDate(evaluationDate) : static_cast<QuantLib::Date>(oper2)); OH_GET_OBJECT(fittingMethodTemp, // fitting method selection fittingMethodID_, ObjectHandler::Object) std::string returnValue; if (fittingMethodTemp->properties()->className() // svensson ? == "stochasticFittingValueObject") { OH_GET_REFERENCE(fittingMethodPtr, fittingMethodID_, QuantLibAddin::stochasticFittingObject, QuantLib::stochasticFittingHelper) // build the value object boost::shared_ptr<QuantLibAddin::ValueObjects::fittedBondDiscountCurveValueObject> curveValueObject( new QuantLibAddin::ValueObjects::fittedBondDiscountCurveValueObject( objectID_, settlementDate.serialNumber(), true)); boost::shared_ptr<ObjectHandler::Object> myCurve( // instanciating the curve new QuantLibAddin::fittedBondDiscountCurveObject( curveValueObject, settlementDate, myRule.select(instrumentsObject, settlementDate), * fittingMethodPtr->fittingMethod(), fittingMethodPtr->initialVector(), fittingMethodPtr->randomMatrix(), fittingMethodPtr->accuracy(), fittingMethodPtr->maxEvaluationPercycle(), fittingMethodPtr->cyclesPerThread(), fittingMethodPtr->cycles(), 1.000, // simplex lambda true)) ; returnValue = // the value to return ObjectHandler::RepositoryXL::instance().storeObject(objectID_, myCurve , true ); } static char ret[XL_MAX_STR_LEN]; ObjectHandler::stringToChar(returnValue, ret); return ret; } catch (std::exception & e) { static char ret[XL_MAX_STR_LEN]; ObjectHandler::RepositoryXL::instance().logError(e.what(), functionCall); ObjectHandler::stringToChar(std::string(e.what()), ret); return ret; } };