Example #1
0
File: Message.cpp Project: BtbN/znc
void CMessage::Parse(CString sMessage) {
    // <tags>
    m_mssTags.clear();
    if (sMessage.StartsWith("@")) {
        VCString vsTags;
        sMessage.Token(0).TrimPrefix_n("@").Split(";", vsTags, false);
        for (const CString& sTag : vsTags) {
            CString sKey = sTag.Token(0, false, "=", true);
            CString sValue = sTag.Token(1, true, "=", true);
            m_mssTags[sKey] =
                sValue.Escape(CString::EMSGTAG, CString::CString::EASCII);
        }
        sMessage = sMessage.Token(1, true);
    }

    //  <message>  ::= [':' <prefix> <SPACE> ] <command> <params> <crlf>
    //  <prefix>   ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ]
    //  <command>  ::= <letter> { <letter> } | <number> <number> <number>
    //  <SPACE>    ::= ' ' { ' ' }
    //  <params>   ::= <SPACE> [ ':' <trailing> | <middle> <params> ]
    //  <middle>   ::= <Any *non-empty* sequence of octets not including SPACE
    //                 or NUL or CR or LF, the first of which may not be ':'>
    //  <trailing> ::= <Any, possibly *empty*, sequence of octets not including
    //                   NUL or CR or LF>

    // <prefix>
    if (sMessage.TrimPrefix(":")) {
        m_Nick.Parse(sMessage.Token(0));
        sMessage = sMessage.Token(1, true);
    }

    // <command>
    m_sCommand = sMessage.Token(0);
    sMessage = sMessage.Token(1, true);

    // <params>
    m_bColon = false;
    m_vsParams.clear();
    while (!sMessage.empty()) {
        m_bColon = sMessage.TrimPrefix(":");
        if (m_bColon) {
            m_vsParams.push_back(sMessage);
            sMessage.clear();
        } else {
            m_vsParams.push_back(sMessage.Token(0));
            sMessage = sMessage.Token(1, true);
        }
    }

    InitType();
}
Example #2
0
CString CTemplate::GetValue(const CString& sArgs, bool bFromIf) {
	CTemplateLoopContext* pContext = GetCurLoopContext();
	CString sName = sArgs.Token(0);
	CString sRest = sArgs.Token(1, true);
	CString sRet;

	while (sRest.Replace(" =", "=", "\"", "\"")) {}
	while (sRest.Replace("= ", "=", "\"", "\"")) {}

	VCString vArgs;
	MCString msArgs;
	//sRest.Split(" ", vArgs, false, "\"", "\"");
	sRest.QuoteSplit(vArgs);

	for (unsigned int a = 0; a < vArgs.size(); a++) {
		const CString& sArg = vArgs[a];

		msArgs[sArg.Token(0, false, "=").AsUpper()] = sArg.Token(1, true, "=");
	}

	/* We have no CConfig in ZNC land
	 * Hmm... Actually, we do have it now.
	if (msArgs.find("CONFIG") != msArgs.end()) {
		sRet = CConfig::GetValue(sName);
	} else*/ if (msArgs.find("ROWS") != msArgs.end()) {
		vector<CTemplate*>* pLoop = GetLoop(sName);
		sRet = CString((pLoop) ? pLoop->size() : 0);
	} else if (msArgs.find("TOP") == msArgs.end() && pContext) {
		sRet = pContext->GetValue(sArgs, bFromIf);

		if (!sRet.empty()) {
			return sRet;
		}
	} else {
		if (sName.Left(1) == "*") {
			sName.LeftChomp(1);
			MCString::iterator it = find(sName);
			sName = (it != end()) ? it->second : "";
		}

		MCString::iterator it = find(sName);
		sRet = (it != end()) ? it->second : "";
	}

	vector<CSmartPtr<CTemplateTagHandler> >& vspTagHandlers = GetTagHandlers();

	if (!vspTagHandlers.empty()) { // @todo this should go up to the top to grab handlers
		CTemplate* pTmpl = GetCurTemplate();

		if (sRet.empty()) {
			for (unsigned int j = 0; j < vspTagHandlers.size(); j++) {
				CSmartPtr<CTemplateTagHandler> spTagHandler = vspTagHandlers[j];
				CString sCustomOutput;

				if (!bFromIf && spTagHandler->HandleVar(*pTmpl, sArgs.Token(0), sArgs.Token(1, true), sCustomOutput)) {
					sRet = sCustomOutput;
					break;
				} else if (bFromIf && spTagHandler->HandleIf(*pTmpl, sArgs.Token(0), sArgs.Token(1, true), sCustomOutput)) {
					sRet = sCustomOutput;
					break;
				}
			}
		}

		for (unsigned int j = 0; j < vspTagHandlers.size(); j++) {
			CSmartPtr<CTemplateTagHandler> spTagHandler = vspTagHandlers[j];

			if (spTagHandler->HandleValue(*pTmpl, sRet, msArgs)) {
				break;
			}
		}
	}

	if (!bFromIf) {
		if (sRet.empty()) {
			sRet = ResolveLiteral(msArgs["DEFAULT"]);
		}

		MCString::iterator it = msArgs.find("ESC");

		if (it != msArgs.end()) {
			VCString vsEscs;
			it->second.Split(",", vsEscs, false);

			for (unsigned int a = 0; a < vsEscs.size(); a++) {
				sRet.Escape(CString::ToEscape(vsEscs[a]));
			}
		} else {
			sRet.Escape(m_spOptions->GetEscapeFrom(), m_spOptions->GetEscapeTo());
		}
	}

	return sRet;
}