Merge branch '1.7.x'

This commit is contained in:
Alexey Sokolov
2018-06-04 22:30:53 +01:00
12 changed files with 145 additions and 47 deletions

View File

@@ -30,6 +30,12 @@
#define ZNC_LVREFQUAL
#endif
#ifdef SWIG
#define ZNC_MSG_DEPRECATED(msg)
#else
#define ZNC_MSG_DEPRECATED(msg) __attribute__((deprecated(msg)))
#endif
#include <znc/zncconfig.h>
#include <znc/ZNCString.h>
#include <znc/Nick.h>
@@ -55,7 +61,8 @@ class CIRCNetwork;
* - `nick` is the sender, which can be obtained with GetNick()
* - `cmd` is command, which is obtained via GetCommand()
* - `0`, `1`, ... are parameters, available via GetParam(n), which removes the
* leading colon (:). If you don't want to remove the colon, use GetParams().
* leading colon (:). If you don't want to remove the colon, use
* GetParamsColon().
*
* For certain events, like a PRIVMSG, convienience commands like GetChan() and
* GetNick() are available, this is not true for all CMessage extensions.
@@ -114,9 +121,15 @@ class CMessage {
void SetCommand(const CString& sCommand);
const VCString& GetParams() const { return m_vsParams; }
CString GetParams(unsigned int uIdx, unsigned int uLen = -1) const;
void SetParams(const VCString& vsParams);
/// @deprecated use GetParamsColon() instead.
CString GetParams(unsigned int uIdx, unsigned int uLen = -1) const
ZNC_MSG_DEPRECATED("Use GetParamsColon() instead") {
return GetParamsColon(uIdx, uLen);
}
CString GetParamsColon(unsigned int uIdx, unsigned int uLen = -1) const;
CString GetParam(unsigned int uIdx) const;
void SetParam(unsigned int uIdx, const CString& sParam);
@@ -244,7 +257,7 @@ REGISTER_ZNC_MESSAGE(CJoinMessage);
class CModeMessage : public CTargetMessage {
public:
CString GetModes() const { return GetParams(1).TrimPrefix_n(":"); }
CString GetModes() const { return GetParamsColon(1).TrimPrefix_n(":"); }
};
REGISTER_ZNC_MESSAGE(CModeMessage);

View File

@@ -76,7 +76,7 @@ class CAdminLogMod : public CModule {
Log("[" + GetUser()->GetUserName() + "/" + GetNetwork()->GetName() +
"] disconnected from IRC: " +
GetNetwork()->GetCurrentServer()->GetName() + " [" +
Message.GetParams(1) + "]",
Message.GetParamsColon(1) + "]",
LOG_NOTICE);
}
return CONTINUE;

View File

@@ -32,9 +32,12 @@ class CFloodDetachMod : public CModule {
AddCommand("Secs", t_d("[<limit>]"),
t_d("Show or set number of seconds in the time interval"),
[=](const CString& sLine) { SecsCommand(sLine); });
AddCommand("Lines", t_d("[<limit>]"), t_d("blahblah: description"),
AddCommand("Lines", t_d("[<limit>]"),
t_d("Show or set number of lines in the time interval"),
[=](const CString& sLine) { LinesCommand(sLine); });
AddCommand("Silent", t_d("[yes|no]"), t_d("blahblah: description"),
AddCommand("Silent", "[yes|no]",
t_d("Show or set whether to notify you about detaching and "
"attaching back"),
[=](const CString& sLine) { SilentCommand(sLine); });
}

View File

@@ -73,21 +73,24 @@ namespace std {
};
}
%include "modperl/CString.i"
%template(_stringlist) std::list<CString>;
%typemap(out) std::list<CString> {
std::list<CString>::const_iterator i;
unsigned int j;
int len = $1.size();
SV **svs = new SV*[len];
for (i=$1.begin(), j=0; i!=$1.end(); i++, j++) {
svs[j] = sv_newmortal();
SwigSvFromString(svs[j], *i);
}
AV *myav = av_make(len, svs);
delete[] svs;
$result = newRV_noinc((SV*) myav);
sv_2mortal($result);
argvi++;
%typemap(out) VCString {
EXTEND(sp, $1.size());
for (int i = 0; i < $1.size(); ++i) {
SV* x = newSV(0);
SwigSvFromString(x, $1[i]);
$result = sv_2mortal(x);
argvi++;
}
}
%typemap(out) const VCString& {
EXTEND(sp, $1->size());
for (int i = 0; i < $1->size(); ++i) {
SV* x = newSV(0);
SwigSvFromString(x, (*$1)[i]);
$result = sv_2mortal(x);
argvi++;
}
}
%template(VIRCNetworks) std::vector<CIRCNetwork*>;
@@ -176,26 +179,18 @@ class MCString : public std::map<CString, CString> {};
%}
%extend CModule {
std::list<CString> _GetNVKeys() {
std::list<CString> res;
for (MCString::iterator i = $self->BeginNV(); i != $self->EndNV(); ++i) {
res.push_back(i->first);
}
return res;
}
VCString GetNVKeys() {
VCString result;
for (auto i = $self->BeginNV(); i != $self->EndNV(); ++i) {
result.push_back(i->first);
}
return result;
}
bool ExistsNV(const CString& sName) {
return $self->EndNV() != $self->FindNV(sName);
}
}
%perlcode %{
package ZNC::CModule;
sub GetNVKeys {
my $result = _GetNVKeys(@_);
return @$result;
}
%}
%extend CModules {
void push_back(CModule* p) {
$self->push_back(p);

View File

@@ -7,6 +7,7 @@
Remove unrelated stuff from top of file which is included by default
s/std::string/CString/g
s/std_string/CString/g
Add "%traits_ptypen(CString);"
*/
//
@@ -17,6 +18,7 @@
%feature("naturalvar") CString;
class CString;
%traits_ptypen(CString);
/*@SWIG:/swig/3.0.8/typemaps/CStrings.swg,70,%typemaps_CString@*/
@@ -74,7 +76,7 @@ SWIG_AsVal_CString (PyObject * obj, CString *val)
}
/*@SWIG@*/
/*@SWIG:/swig/3.0.8/typemaps/CStrings.swg,38,%CString_from@*/
%fragment("SWIG_" "From" "_" {CString},"header",fragment="SWIG_FromCharPtrAndSize") {
%fragment("SWIG_" "From" "_" {CString},"header",fragment="SWIG_FromCharPtrAndSize", fragment="StdTraits") {
SWIGINTERNINLINE PyObject *
SWIG_From_CString (const CString& s)
{

View File

@@ -304,7 +304,7 @@ class CRouteRepliesMod : public CModule {
// If there are arguments to a mode change,
// we must not route it.
if (!Message.GetParams(2).empty()) return CONTINUE;
if (!Message.GetParamsColon(2).empty()) return CONTINUE;
// Grab the mode change parameter
CString sMode = Message.GetParam(1);

View File

@@ -144,7 +144,7 @@ class CSChat : public CModule {
EModRet OnUserRawMessage(CMessage& msg) override {
if (!msg.GetCommand().Equals("schat")) return CONTINUE;
const CString sParams = msg.GetParams(0);
const CString sParams = msg.GetParamsColon(0);
if (sParams.empty()) {
PutModule("SChat User Area ...");
OnModCommand("help");

View File

@@ -1204,7 +1204,7 @@ bool CClient::OnPingMessage(CMessage& Message) {
// All PONGs are generated by ZNC. We will still forward this to
// the ircd, but all PONGs from irc will be blocked.
if (!Message.GetParams().empty())
PutClient(":irc.znc.in PONG irc.znc.in " + Message.GetParams(0));
PutClient(":irc.znc.in PONG irc.znc.in " + Message.GetParamsColon(0));
else
PutClient(":irc.znc.in PONG irc.znc.in");
return false;
@@ -1305,10 +1305,10 @@ bool CClient::OnOtherMessage(CMessage& Message) {
CString sModCommand;
if (sTarget.TrimPrefix(m_pUser->GetStatusPrefix())) {
sModCommand = Message.GetParams(1);
sModCommand = Message.GetParamsColon(1);
} else {
sTarget = "status";
sModCommand = Message.GetParams(0);
sModCommand = Message.GetParamsColon(0);
}
if (sTarget.Equals("status")) {
@@ -1330,7 +1330,7 @@ bool CClient::OnOtherMessage(CMessage& Message) {
return true;
}
CString sPatterns = Message.GetParams(0);
CString sPatterns = Message.GetParamsColon(0);
if (sPatterns.empty()) {
PutStatusNotice(t_s("Usage: /attach <#chans>"));
@@ -1352,7 +1352,7 @@ bool CClient::OnOtherMessage(CMessage& Message) {
return true;
}
CString sPatterns = Message.GetParams(0);
CString sPatterns = Message.GetParamsColon(0);
if (sPatterns.empty()) {
PutStatusNotice(t_s("Usage: /detach <#chans>"));

View File

@@ -761,7 +761,7 @@ bool CIRCSock::OnNumericMessage(CNumericMessage& Message) {
CChan* pChan = m_pNetwork->FindChan(Message.GetParam(1));
if (pChan) {
pChan->SetModes(Message.GetParams(2));
pChan->SetModes(Message.GetParamsColon(2));
// We don't SetModeKnown(true) here,
// because a 329 will follow

View File

@@ -48,7 +48,7 @@ void CMessage::SetCommand(const CString& sCommand) {
InitType();
}
CString CMessage::GetParams(unsigned int uIdx, unsigned int uLen) const {
CString CMessage::GetParamsColon(unsigned int uIdx, unsigned int uLen) const {
if (m_vsParams.empty() || uLen == 0) {
return "";
}
@@ -151,7 +151,7 @@ CString CMessage::ToString(unsigned int uFlags) const {
if (!sMessage.empty()) {
sMessage += " ";
}
sMessage += GetParams(0);
sMessage += GetParamsColon(0);
}
return sMessage;

View File

@@ -152,5 +152,89 @@ TEST_F(ZNCTest, ModperlSocket) {
client.ReadUntil("received 4 bytes");
}
TEST_F(ZNCTest, ModpythonVCString) {
if (QProcessEnvironment::systemEnvironment().value(
"DISABLED_ZNC_PERL_PYTHON_TEST") == "1") {
return;
}
auto znc = Run();
znc->CanLeak();
InstallModule("test.py", R"(
import znc
class test(znc.Module):
def OnUserRawMessage(self, msg):
self.PutModule(str(msg.GetParams()))
return znc.CONTINUE
)");
auto ircd = ConnectIRCd();
auto client = LoginClient();
client.Write("znc loadmod modpython");
client.Write("znc loadmod test");
client.Write("PRIVMSG *test :foo");
client.ReadUntil("'*test', 'foo'");
}
TEST_F(ZNCTest, ModperlVCString) {
if (QProcessEnvironment::systemEnvironment().value(
"DISABLED_ZNC_PERL_PYTHON_TEST") == "1") {
return;
}
auto znc = Run();
znc->CanLeak();
InstallModule("test.pm", R"(
package test;
use base 'ZNC::Module';
sub OnUserRawMessage {
my ($self, $msg) = @_;
my @params = $msg->GetParams;
$self->PutModule("@params");
return $ZNC::CONTINUE;
}
1;
)");
auto ircd = ConnectIRCd();
auto client = LoginClient();
client.Write("znc loadmod modperl");
client.Write("znc loadmod test");
client.Write("PRIVMSG *test :foo");
client.ReadUntil(":*test foo");
}
TEST_F(ZNCTest, ModperlNV) {
if (QProcessEnvironment::systemEnvironment().value(
"DISABLED_ZNC_PERL_PYTHON_TEST") == "1") {
return;
}
auto znc = Run();
znc->CanLeak();
InstallModule("test.pm", R"(
package test;
use base 'ZNC::Module';
sub OnLoad {
my $self = shift;
$self->SetNV('a', 'X');
$self->NV->{b} = 'Y';
my @k = keys %{$self->NV};
$self->PutModule("@k");
return $ZNC::CONTINUE;
}
1;
)");
auto ircd = ConnectIRCd();
auto client = LoginClient();
client.Write("znc loadmod modperl");
client.Write("znc loadmod test");
client.ReadUntil(":a b");
}
} // namespace
} // namespace znc_inttest

1
translations/id-ID Normal file
View File

@@ -0,0 +1 @@
SelfName Indonesian