KviKvsRWEvaluationResult * KviKvsTreeNodeHashElement::evaluateReadWriteInObjectScope(KviKvsObject *o,KviKvsRunTimeContext * c) { KviKvsVariant key; if(!m_pKey->evaluateReadOnly(c,&key))return 0; QString szKey; key.asString(szKey); if(szKey.isEmpty()) { c->warning(this,__tr2qs_ctx("Hash key evaluated to empty string: fix the script","kvs")); } KviKvsRWEvaluationResult * result; if(o)result = m_pSource->evaluateReadWriteInObjectScope(o,c); else result = m_pSource->evaluateReadWrite(c); if(!result)return 0; if(!result->result()->isHash()) { // convert to hash in some way //#warning "Supply a *real* conversion from other types to array ?" if(!result->result()->isNothing()) { QString szType; result->result()->getTypeName(szType); c->warning(this,__tr2qs_ctx("The argument of the {} subscript didn't evaluate to a hash: automatic conversion from %Q supplied","kvs"),&szType); } result->result()->setHash(new KviKvsHash()); } return new KviKvsHashElement(result,result->result()->hash()->get(szKey),result->result()->hash(),szKey); }
int KviKvsScript::run(KviWindow * pWnd, KviKvsVariantList * pParams, QString & szRetVal, int iRunFlags, KviKvsExtendedRunTimeData * pExtData) { KviKvsVariant retVal; int iRet = run(pWnd, pParams, &retVal, iRunFlags, pExtData); retVal.asString(szRetVal); return iRet; }
bool KviKvsTreeNodeMultipleParameterIdentifier::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer) { KviKvsVariant * v = c->parameterList()->at(m_iStart); if(!v) { pBuffer->setNothing(); return true; } QString sz; v->asString(sz); if(m_iEnd >= m_iStart) { // only up to m_iEnd int idx = m_iStart; for(v = c->parameterList()->next(); v && (idx < m_iEnd); v = c->parameterList()->next()) { sz += QChar(' '); v->appendAsString(sz); idx++; } } else { // all up to the end of the list for(v = c->parameterList()->next(); v; v = c->parameterList()->next()) { sz += QChar(' '); v->appendAsString(sz); } } pBuffer->setString(sz); return true; }
bool KviKvsTreeNodeSpecialCommandSwitchLabelRegexp::execute(KviKvsRunTimeContext * c,KviKvsVariant * pRealParameter, bool * bPassThrough) { if(!(*bPassThrough)) { KviKvsVariant v; if(!m_pParameter->evaluateReadOnly(c,&v))return false; QString reg; v.asString(reg); // QRegExp rx(reg,false,false); QRegExp rx(reg,Qt::CaseInsensitive,QRegExp::RegExp); QString val; pRealParameter->asString(val); if(!rx.exactMatch(val))return true; // no match } *bPassThrough = true; if(m_pInstruction) { if(!m_pInstruction->execute(c))return false; // might be a break too } if(m_bHasTerminatingBreak) { c->setBreakPending(); return false; } return true; }
bool urllist_module_event_onUrl(KviKvsModuleEventCall * c) { KviKvsVariant * vUrl = c->firstParam(); QString szUrl; if(vUrl)vUrl->asString(szUrl); if (check_url(c->window(),szUrl) == 0) { KviUrl *tmp = new KviUrl; QString tmpTimestamp; QDate d = QDate::currentDate(); QString date; date.sprintf("%d-%d%d-%d%d",d.year(),d.month() / 10,d.month() % 10,d.day() / 10,d.day() % 10); tmpTimestamp = "["+date+"]"+" ["; tmpTimestamp += QTime::currentTime().toString()+"]"; tmp->url = szUrl; tmp->window = c->window()->plainTextCaption(); tmp->count = 1; tmp->timestamp = tmpTimestamp; g_pList->append(tmp); for (UrlDlgList *tmpitem=g_pUrlDlgList->first();tmpitem;tmpitem=g_pUrlDlgList->next()) { if (tmpitem->dlg) { QString tmpCount; tmpCount.setNum(tmp->count); tmpitem->dlg->addUrl(QString(tmp->url), QString(tmp->window), tmpCount, QString(tmp->timestamp)); tmpitem->dlg->windowListItem()->highlight(false); } } } return true; }
bool KviKvsVariantList::nextAsString(QString & szBuffer) { KviKvsVariant * v = next(); if(!v) return false; v->asString(szBuffer); return true; }
int KviKvsScript::evaluateAsString(const QString & szCode, KviWindow * pWindow, KviKvsVariantList * pParams, QString & szRetVal) { // static helper KviKvsVariant ret; KviKvsScript s("kvirc::corecall(evaluate)", szCode, Parameter); int iRet = s.run(pWindow, pParams, &ret, PreserveParams); ret.asString(szRetVal); return iRet; }
void KviWindow::getDefaultLogFileName(QString & szBuffer, QDate date, bool bGzip, unsigned int uDatetimeFormat) { QString szLog; // dynamic log path QString szDynamicPath = KVI_OPTION_STRING(KviOption_stringLogsDynamicPath).trimmed(); if(!szDynamicPath.isEmpty()) { KviQString::escapeKvs(&szDynamicPath, KviQString::PermitVariables | KviQString::PermitFunctions); KviKvsVariant vRet; if(KviKvsScript::evaluate(szDynamicPath, this, nullptr, &vRet)) vRet.asString(szDynamicPath); } g_pApp->getLocalKvircDirectory(szLog, KviApplication::Log, szDynamicPath); KviQString::ensureLastCharIs(szLog, KVI_PATH_SEPARATOR_CHAR); //ensure the directory exists KviFileUtils::makeDir(szLog); QString szDate; switch(uDatetimeFormat) { case 1: szDate = date.toString(Qt::ISODate); break; case 2: szDate = date.toString(Qt::SystemLocaleShortDate); break; case 0: default: szDate = date.toString("yyyy.MM.dd"); break; } szDate.replace('_', '-'); // this would confuse the log viewer KviFileUtils::cleanFileName(szDate); QString szBase; getBaseLogFileName(szBase); KviFileUtils::encodeFileName(szBase); szBase = szBase.toLower(); szBase.replace("%%2e", "%2e"); QString szTmp; if(bGzip) szTmp = "%1_%2_%3.log.gz"; else szTmp = "%1_%2_%3.log"; szLog.append(QString(szTmp).arg(typeString(), szBase, szDate)); szBuffer = szLog; }
static bool theme_kvs_cmd_pack(KviKvsModuleCommandCall * c) { QString szPath, szName, szVersion, szDescription, szAuthor, szImage; KviKvsArrayCast aCast; KVSM_PARAMETERS_BEGIN(c) KVSM_PARAMETER("package_path", KVS_PT_NONEMPTYSTRING, 0, szPath) KVSM_PARAMETER("package_name", KVS_PT_NONEMPTYSTRING, 0, szName) KVSM_PARAMETER("package_version", KVS_PT_NONEMPTYSTRING, 0, szVersion) KVSM_PARAMETER("package_description", KVS_PT_STRING, 0, szDescription) KVSM_PARAMETER("package_author", KVS_PT_NONEMPTYSTRING, 0, szAuthor) KVSM_PARAMETER("package_image", KVS_PT_STRING, 0, szImage) KVSM_PARAMETER("theme", KVS_PT_ARRAYCAST, 0, aCast) KVSM_PARAMETERS_END(c) KviKvsArray * pArray = aCast.array(); if((!pArray) || (pArray->size() < 1)) { c->error(__tr2qs_ctx("No themes specified", "theme")); return false; } kvs_uint_t s = pArray->size(); QStringList lThemeList; for(kvs_uint_t i = 0; i < s; i++) { KviKvsVariant * v = pArray->at(i); if(!v) continue; // ? QString szVal; v->asString(szVal); if(szVal.isEmpty()) continue; lThemeList.append(szVal); } KviPointerList<KviThemeInfo> lThemeInfoList; lThemeInfoList.setAutoDelete(true); Q_FOREACH(QString szTheme, lThemeList) { KviThemeInfo * pInfo = new KviThemeInfo(); if(!pInfo->load(szTheme, KviThemeInfo::External)) { QString szErr = pInfo->lastError(); c->error(__tr2qs_ctx("Failed to load theme from directory %Q: %Q", "theme"), &szTheme, &szErr); delete pInfo; return false; } lThemeInfoList.append(pInfo); }
bool KviKvsTreeNodeSpecialCommandSwitchLabelCase::execute(KviKvsRunTimeContext * c,KviKvsVariant * pRealParameter, bool * bPassThrough) { if(!(*bPassThrough)) { KviKvsVariant v; if(!m_pParameter->evaluateReadOnly(c,&v))return false; KviKvsNumber num; if(pRealParameter->asNumber(num)) { KviKvsNumber num2; if(!v.asNumber(num2))return true; // a number and a non number can't match if(num.isInteger()) { if(num2.isInteger()) { if(num.integer() != num2.integer())return true; } else { if(((double)(num.integer())) != num2.real())return true; } } else { if(num2.isInteger()) { if(num.real() != ((double)(num2.integer())))return true; } else { if(num.real() != num2.real())return true; } } } else { // string comparision, case insensitive QString reg; v.asString(reg); QString val; pRealParameter->asString(val); if(reg.toLower() != val.toLower())return true; } } *bPassThrough = true; if(m_pInstruction) { if(!m_pInstruction->execute(c))return false; // might be a break too } if(m_bHasTerminatingBreak) { c->setBreakPending(); return false; } return true; }
bool KviKvsTreeNodeSpecialCommandDefpopup::execute(KviKvsRunTimeContext * c) { KviKvsVariant v; if(!m_pPopupName->evaluateReadOnly(c,&v))return false; QString szName; v.asString(szName); KviKvsSwitchList swl; if(m_pSwitches) { if(!(m_pSwitches->evaluate(c,&swl)))return false; } KviKvsPopupMenu * pPopup = KviKvsPopupManager::instance()->lookup(szName); bool bWasAlreadyThere; if(!pPopup) { if(m_pMainPopup->isEmpty())return true; // we wanted to remove it anyway: exit silently // we want to create it pPopup = new KviKvsPopupMenu(szName); KviKvsPopupManager::instance()->add(szName,pPopup); bWasAlreadyThere = false; } else { bWasAlreadyThere = true; if(pPopup->isHardLocked()) { c->error(__tr2qs_ctx("The popup '%s' is actually locked: 'self-modifications' are not allowed","kvs"),&szName); return false; } if(m_pMainPopup->isEmpty()) { // we want to remove it KviKvsPopupManager::instance()->remove(szName); return true; } // we want to (re)create it if(!swl.find('m',"--merge"))pPopup->doClear(); } if(!m_pMainPopup->fill(c,pPopup)) { if(!bWasAlreadyThere)KviKvsPopupManager::instance()->remove(szName); return false; } KviKvsPopupManager::instance()->emitRefresh(szName); return true; }
bool KviKvsTreeNodeHashElement::evaluateReadOnlyInObjectScope(KviKvsObject *o,KviKvsRunTimeContext * c,KviKvsVariant * pBuffer) { KviKvsVariant key; if(!m_pKey->evaluateReadOnly(c,&key))return false; QString szKey; key.asString(szKey); if(szKey.isEmpty()) { c->warning(this,__tr2qs_ctx("Hash key evaluated to empty string: fix the script","kvs")); pBuffer->setNothing(); return true; } KviKvsVariant val; if(o) { if(!m_pSource->evaluateReadOnlyInObjectScope(o,c,&val))return false; } else { if(!m_pSource->evaluateReadOnly(c,&val))return false; } if(!val.isHash()) { if(!val.isNothing()) { QString szType; val.getTypeName(szType); c->warning(this,__tr2qs_ctx("The argument of the {} subscript didn't evaluate to a hash: automatic conversion from type '%Q' supplied","kvs"),&szType); } pBuffer->setNothing(); return true; } KviKvsVariant * v = val.hash()->find(szKey); if(!v) { pBuffer->setNothing(); return true; } pBuffer->copyFrom(v); return true; }
bool process(KviKvsVariantList * pVariantList, KviKvsRunTimeContext * pContext, KviKvsParameterProcessor::ParameterFormat * pFmtArray) { KviKvsVariant * v = pVariantList->first(); while(pFmtArray->szName) { if(!v) { // parameter not present // it MUST be optional if(!(pFmtArray->uFlags & KVS_PF_OPTIONAL)) { // bad luck QString szError = QString(__tr2qs_ctx("Missing non-optional parameter \"%1\"", "kvs")).arg(pFmtArray->szName); pContext->error(szError); return false; } // ok, missing but optional (all the following are implicitly optional too) // set to default values do { setDefaultValue(pFmtArray); pFmtArray++; } while(pFmtArray->szName); return true; } // here we do only "light" casts: hard ones must be done explicitly by the user switch(pFmtArray->uType) { case KVS_PT_STRING: v->asString(*((QString *)(pFmtArray->pContainer))); if(pFmtArray->uFlags & KVS_PF_APPENDREMAINING) { v = pVariantList->next(); while(v) { *((QString *)(pFmtArray->pContainer)) += QChar(' '); v->appendAsString(*((QString *)(pFmtArray->pContainer))); v = pVariantList->next(); } return true; } break; case KVS_PT_STRINGLIST: { ((QStringList *)(pFmtArray->pContainer))->clear(); QString pSz; v->asString(pSz); ((QStringList *)(pFmtArray->pContainer))->append(pSz); v = pVariantList->next(); while(v) { v->asString(pSz); ((QStringList *)(pFmtArray->pContainer))->append(pSz); v = pVariantList->next(); } return true; } break; case KVS_PT_VARIANTLIST: { ((KviKvsVariantList *)(pFmtArray->pContainer))->clear(); ((KviKvsVariantList *)(pFmtArray->pContainer))->setAutoDelete(false); ((KviKvsVariantList *)(pFmtArray->pContainer))->append(v); v = pVariantList->next(); while(v) { ((KviKvsVariantList *)(pFmtArray->pContainer))->append(v); v = pVariantList->next(); } return true; } break; case KVS_PT_NONEMPTYSTRING: { v->asString(*((QString *)(pFmtArray->pContainer))); bool bDoReturn = false; if(pFmtArray->uFlags & KVS_PF_APPENDREMAINING) { v = pVariantList->next(); while(v) { *((QString *)(pFmtArray->pContainer)) += QChar(' '); v->appendAsString(*((QString *)(pFmtArray->pContainer))); v = pVariantList->next(); } bDoReturn = true; } if(((QString *)(pFmtArray->pContainer))->isEmpty()) { QString szError = QString(__tr2qs_ctx("Invalid data type for parameter \"%1\": found empty string while a non empty one was expected", "kvs")).arg(pFmtArray->szName); pContext->error(szError); return false; } if(bDoReturn) return true; } break; case KVS_PT_CSTRING: { QString tmp; v->asString(tmp); if(pFmtArray->uFlags & KVS_PF_APPENDREMAINING) { v = pVariantList->next(); while(v) { *((QByteArray *)(pFmtArray->pContainer)) += ' '; v->appendAsString(tmp); v = pVariantList->next(); } *((QByteArray *)(pFmtArray->pContainer)) = tmp.toUtf8(); return true; } *((QByteArray *)(pFmtArray->pContainer)) = tmp.toUtf8(); } break; case KVS_PT_NONEMPTYCSTRING: { QString tmp; v->asString(tmp); bool bDoReturn = false; if(pFmtArray->uFlags & KVS_PF_APPENDREMAINING) { v = pVariantList->next(); while(v) { *((QByteArray *)(pFmtArray->pContainer)) += ' '; v->appendAsString(tmp); v = pVariantList->next(); } *((QByteArray *)(pFmtArray->pContainer)) = tmp.toUtf8(); bDoReturn = true; } *((QByteArray *)(pFmtArray->pContainer)) = tmp.toUtf8(); if(((QByteArray *)(pFmtArray->pContainer))->isEmpty()) { QString szError = QString(__tr2qs_ctx("Invalid data type for parameter \"%1\": found empty string while a non empty one was expected", "kvs")).arg(pFmtArray->szName); pContext->error(szError); return false; } if(bDoReturn) return true; } break; case KVS_PT_INT: if(!v->asInteger(*((kvs_int_t *)(pFmtArray->pContainer)))) { if(!handleParameterTypeError(pContext, pFmtArray, v, "integer")) return false; } break; case KVS_PT_UINT: { kvs_int_t iTmp; if(!v->asInteger(iTmp)) { if(!handleParameterTypeError(pContext, pFmtArray, v, "unsigned integer")) return false; } if(iTmp < 0) { QString szError = QString(__tr2qs_ctx("Invalid data type for parameter \"%1\": found signed integer \"%2\" where type 'unsigned integer' was expected", "kvs")).arg(pFmtArray->szName).arg(iTmp); pContext->error(szError); return false; } *((kvs_uint_t *)(pFmtArray->pContainer)) = (kvs_uint_t)iTmp; } break; case KVS_PT_DOUBLE: if(!v->asReal(*((kvs_real_t *)(pFmtArray->pContainer)))) { if(!handleParameterTypeError(pContext, pFmtArray, v, "real")) return false; } break; case KVS_PT_HASH: if(!v->isHash()) { if(!handleParameterTypeError(pContext, pFmtArray, v, "hash")) return false; } else { *((KviKvsHash **)(pFmtArray->pContainer)) = v->hash(); } break; case KVS_PT_ARRAYCAST: v->castToArray((KviKvsArrayCast *)(pFmtArray->pContainer)); break; case KVS_PT_ARRAY: if(!v->isArray()) { if(!handleParameterTypeError(pContext, pFmtArray, v, "array")) return false; } else { *((KviKvsArray **)(pFmtArray->pContainer)) = v->array(); } break; case KVS_PT_BOOL: // this never fails: anything is converted to a boolean *((bool *)(pFmtArray->pContainer)) = v->asBoolean(); break; case KVS_PT_VARIANT: *((KviKvsVariant **)(pFmtArray->pContainer)) = v; break; case KVS_PT_HOBJECT: if(!v->asHObject(*((kvs_hobject_t *)(pFmtArray->pContainer)))) { if(!handleParameterTypeError(pContext, pFmtArray, v, "hobject")) return false; } break; case KVS_PT_IGNORE: // ignore break; default: qDebug("Internal error in KviKvsParameterProcessor::processAsParameters(): unknown parameter type %d", pFmtArray->uType); return false; break; } pFmtArray++; v = pVariantList->next(); } return true; }
KVSO_CLASS_FUNCTION(xmlReader, parse) { KviKvsVariant * pVariantData; KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("string_or_memorybuffer_object", KVS_PT_VARIANT, 0, pVariantData) KVSO_PARAMETERS_END(c) #ifdef QT_NO_XML fatalError(__tr2qs_ctx("XML support not available in the Qt library")); c->returnValue()->setBoolean(false); #else m_szLastError = ""; KviXmlHandler handler(this); QXmlInputSource source; if(pVariantData->isHObject()) { KviKvsObject * pObject; kvs_hobject_t hObject; pVariantData->asHObject(hObject); pObject = KviKvsKernel::instance()->objectController()->lookupObject(hObject); if(!pObject) { c->warning(__tr2qs_ctx("Data parameter is not an object", "objects")); return true; } if(pObject->inheritsClass("memorybuffer")) { source.setData(*((KvsObject_memoryBuffer *)pObject)->pBuffer()); } else { c->warning(__tr2qs_ctx("Data parameter is not a memorybuffer object", "objects")); return true; } } else if(pVariantData->isString()) { QString szString; pVariantData->asString(szString); // We have a problem here.. most kvirc functions already interpret the data // read from files. We should have binary data handling features to get this to work correctly. // The following snippet of code tries to provide a best-effort workaround. QByteArray utf8data = szString.toUtf8(); QByteArray data = utf8data; data.truncate(utf8data.length()); // don't include the null terminator in data source.setData(data); //qDebug("PARSING(%s) LEN(%d)",szString.toUtf8().data(),szString.toUtf8().length()); } else { c->warning(__tr2qs_ctx("Data is not a memorybuffer object or string", "objects")); return true; } QXmlSimpleReader reader; reader.setContentHandler(&handler); reader.setErrorHandler(&handler); c->returnValue()->setBoolean(reader.parse(source)); #endif return true; }
static bool perl_kvs_cmd_begin(KviKvsModuleCommandCall * c) { // This command is somewhat special in the fact that has a dedicated // parsing routine in the KVS core parser. // The parser sets the perl code as the first parameter of our call, // the remaining params are the context name and the arguments QString szCode,szContext; KviKvsVariantList vList; KVSM_PARAMETERS_BEGIN(c) KVSM_PARAMETER("code",KVS_PT_STRING,0,szCode) KVSM_PARAMETER("context",KVS_PT_STRING,KVS_PF_OPTIONAL,szContext) KVSM_PARAMETER("args",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,vList) KVSM_PARAMETERS_END(c) KVS_CHECK_MODULE_STATE(m,c) #ifdef COMPILE_PERL_SUPPORT KviPerlCoreCtrlCommand_execute ex; ex.uSize = sizeof(KviPerlCoreCtrlCommand_execute); ex.pKvsContext = c->context(); ex.szContext = szContext; ex.szCode = szCode; for(KviKvsVariant * v = vList.first();v;v = vList.next()) { QString tmp; v->asString(tmp); ex.lArgs.append(tmp); } ex.bQuiet = c->switches()->find('q',"quiet"); if(!g_pPerlCoreModule->ctrl(KVI_PERLCORECTRLCOMMAND_EXECUTE,&ex)) { if(!c->switches()->find('q',"quiet")) c->warning(__tr2qs_ctx("The perlcore module failed to execute the code: something is wrong with the perl support","perl")); return true; } if(!ex.lWarnings.isEmpty()) { for(QStringList::Iterator it = ex.lWarnings.begin();it != ex.lWarnings.end();++it) c->warning(*it); } if(!ex.bExitOk) { if(!c->switches()->find('q',"quiet")) { if(c->switches()->find('f',"fail-on-error")) { c->warning(__tr2qs_ctx("Perl execution error:","perl")); c->warning(ex.szError); return false; } else { c->warning(__tr2qs_ctx("Perl execution error:","perl")); c->error(ex.szError); } } } if(!c->switches()->find('n',"no-return")) c->context()->returnValue()->setString(ex.szRetVal); #endif //COMPILE_PERL_SUPPORT return true; }
bool KviKvsTreeNodeSpecialCommandClass::execute(KviKvsRunTimeContext * c) { KviKvsVariantList l; if(!m_pParams->evaluate(c,&l))return false; KviKvsVariant * pClassName = l.first(); if(!pClassName) { c->error(this,__tr2qs_ctx("Missing class name","kvs")); return false; } KviKvsVariant * pBaseClassName = l.next(); QString szClassName; QString szBaseClassName; pClassName->asString(szClassName); QRegExp re("[\\w:]+"); if(!re.exactMatch(szClassName)) { c->error(this,__tr2qs_ctx("Class names can contain only letters, digits, underscores and '::' namespace separators","kvs")); return false; } if(pBaseClassName) pBaseClassName->asString(szBaseClassName); if(szClassName.isEmpty()) { c->error(this,__tr2qs_ctx("Missing class name","kvs")); return false; } if(szBaseClassName.isEmpty())szBaseClassName = "object"; // avoid infinite recursion in loading the base class if(KviQString::equalCI(szBaseClassName,szClassName)) { c->error(__tr2qs_ctx("A class can't be a subclass of itself","kvs")); return false; } KviKvsObjectClass * pBaseClass = KviKvsKernel::instance()->objectController()->lookupClass(szBaseClassName); if(!pBaseClass) { c->error(this,__tr2qs_ctx("Couln't find base class named '%Q'","kvs"),&szBaseClassName); return false; } // walk the inheritance tree of the base class in order to detect loops KviKvsObjectClass * pClass = pBaseClass; while(pClass) { if(KviQString::equalCI(pClass->name(),szClassName)) { c->error(this,__tr2qs_ctx("Detected a loop in the inheritance tree of the base class '%Q': redefine that class first","kvs"),&szBaseClassName); return false; } pClass = pClass->parentClass(); } KviKvsObjectClass * pActualClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName,true); if(pActualClass) { c->error(this,__tr2qs_ctx("Can't override the builtin class '%Q'","kvs"),&szClassName); return false; } pActualClass = new KviKvsObjectClass(pBaseClass,szClassName,0,false); for(KviKvsTreeNodeSpecialCommandClassFunctionDefinition * d = m_pFunctions->first();d;d = m_pFunctions->next()) { pActualClass->registerFunctionHandler(d->name(),d->buffer(),d->reminder(),d->handlerFlags()); } return true; }
bool KviKvsProcessAsyncOperation::trigger(CallbackEvent e, const QString & szData) { if(m_bDeletePending) return false; if(!g_pApp->windowExists(m_pData->pWnd)) { if(m_pData->iFlags & KVI_KVS_PROCESSDESCRIPTOR_KILLIFNOWINDOW) { return true; } m_pData->pWnd = g_pApp->activeConsole(); } if(m_pData->pCallback) { KviKvsVariantList params; params.setAutoDelete(true); switch(e) { case EventStdout: params.append(new KviKvsVariant(QString("stdout"))); break; case EventStderr: params.append(new KviKvsVariant(QString("stderr"))); break; case EventTerminated: params.append(new KviKvsVariant(QString("terminated"))); break; case EventStarted: params.append(new KviKvsVariant(QString("started"))); break; case EventPing: params.append(new KviKvsVariant(QString("ping"))); break; default: qDebug("Oops! Unknown trigger() CallbackEvent parameter in QProcessDescriptor::trigger()"); return false; break; } params.append(new KviKvsVariant(szData)); if(m_pData->pMagic) { KviKvsVariant * pTmp = new KviKvsVariant(); pTmp->copyFrom(m_pData->pMagic); params.append(pTmp); } KviKvsVariant retVal; int iRet = m_pData->pCallback->run(m_pData->pWnd, ¶ms, &retVal, KviKvsScript::PreserveParams, m_pExtendedRunTimeData); if(!iRet) { m_pData->pWnd->output(KVI_OUT_PARSERERROR, __tr2qs_ctx("Error triggered from process callback handler: killing process", "kvs")); return true; } if(!retVal.isNothing()) { QString sz; retVal.asString(sz); m_pProcess->write(sz.toUtf8().data()); } if(iRet & KviKvsScript::HaltEncountered) { // halt encountered: kill the process return true; } } return false; }
void KviIrcContext::terminateConnectionRequest(bool bForce, const QString & szQuitMsg, bool bSimulateUnexpectedDisconnect) { if(!connection()) return; // hm ? connection()->stateData()->setSimulateUnexpectedDisconnect(bSimulateUnexpectedDisconnect); switch(m_eState) { case Connected: { // was connected : send a quit and abort the connection bool bQuitSentJustNow = false; if(!connection()->stateData()->sentQuit()) { KVS_TRIGGER_EVENT_0(KviEvent_OnDisconnectRequest, m_pConsole); QString szQuit = szQuitMsg; if(szQuit.isEmpty()) szQuit = KVI_OPTION_STRING(KviOption_stringQuitMessage); KviQString::escapeKvs(&szQuit, KviQString::PermitVariables | KviQString::PermitFunctions); QString buffer; KviKvsVariant ret; if(KviKvsScript::evaluate(szQuit, console(), nullptr, &ret)) ret.asString(buffer); else buffer = szQuit; QByteArray dat = connection()->encodeText(buffer); connection()->stateData()->setSentQuit(); connection()->sendFmtData("QUIT :%s", dat.data() ? dat.data() : ""); // here theoretically we COULD get disconnected bQuitSentJustNow = true; } // else it was already sent anyway if(KVI_OPTION_BOOL(KviOption_boolForceBrutalQuit) || bForce || (!bQuitSentJustNow)) { if(!bQuitSentJustNow) { // idle for some milliseconds in order to allow the quit message to reach // the remote end without breaking the connection KviThread::msleep(100); } // and brutally abort the connection (if it still exists!!!) if(connection()) connection()->abort(); } else { if(bQuitSentJustNow) m_pConsole->outputNoFmt(KVI_OUT_SYSTEMMESSAGE, __tr2qs("Sent QUIT, waiting for the server to close the connection...")); } } break; case PendingReconnection: case Connecting: case LoggingIn: // was waiting for connection or login, just abort it: it will trigger an error anyway // though act as if we sent the quit message, so we'll not treat the disconnection as "unexpected". connection()->stateData()->setSentQuit(); connection()->abort(); break; default: // should never end here! KVI_ASSERT(false); break; } }