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);
}
示例#2
0
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;
}
示例#5
0
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;
}
示例#6
0
bool KviKvsVariantList::nextAsString(QString & szBuffer)
{
	KviKvsVariant * v = next();
	if(!v)
		return false;
	v->asString(szBuffer);
	return true;
}
示例#7
0
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;
}
示例#8
0
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;
}
示例#9
0
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;
	}
示例#14
0
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;
}
示例#15
0
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;
}
示例#17
0
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, &params, &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;
}
示例#18
0
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;
	}
}