mirror of https://github.com/bqv/weechat-xmpp
begin porting
parent
8fb40cad8d
commit
6e3e5ce115
@ -0,0 +1,15 @@
|
|||||||
|
;;; Directory Local Variables
|
||||||
|
;;; For more information see (info "(emacs) Directory Variables")
|
||||||
|
|
||||||
|
((c-mode
|
||||||
|
(eval . (setq-local gud-gdb-command-name
|
||||||
|
(string-join `("gdb"
|
||||||
|
"-ex 'handle SIGPIPE nostop noprint pass'"
|
||||||
|
,(concat "--args weechat -a -P 'alias,buflist,exec,irc' -r '/plugin load "
|
||||||
|
(expand-file-name "xmpp.so" (projectile-project-root))
|
||||||
|
"'"))
|
||||||
|
" ")))
|
||||||
|
(flycheck-clang-warnings . ("all" "extra" "error-implicit-function-declaration" "no-missing-field-initializers"))
|
||||||
|
(flycheck-clang-language-standard . "c++17")
|
||||||
|
(flycheck-checker . c/c++-clang)
|
||||||
|
(projectile-project-compilation-cmd . "make && (make test || true)")))
|
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "deps/diff"]
|
||||||
|
path = deps/diff
|
||||||
|
url = https://github.com/kristapsdz/libdiff
|
@ -0,0 +1,116 @@
|
|||||||
|
ifdef DEBUG
|
||||||
|
DBGCFLAGS=-fsanitize=address -fsanitize=undefined -fsanitize=leak
|
||||||
|
DBGLDFLAGS=-lasan -lubsan -llsan
|
||||||
|
endif
|
||||||
|
|
||||||
|
RM=rm -f
|
||||||
|
FIND=find
|
||||||
|
|
||||||
|
INCLUDES=-Ilibstrophe \
|
||||||
|
$(shell xml2-config --cflags) \
|
||||||
|
$(shell pkg-config --cflags librnp-0) \
|
||||||
|
$(shell pkg-config --cflags libsignal-protocol-c)
|
||||||
|
CFLAGS+=$(DBGCFLAGS) \
|
||||||
|
-fno-omit-frame-pointer -fPIC \
|
||||||
|
-std=gnu99 -gdwarf-4 \
|
||||||
|
-Wall -Wextra \
|
||||||
|
-Werror-implicit-function-declaration \
|
||||||
|
-Wno-missing-field-initializers \
|
||||||
|
-D_XOPEN_SOURCE=700 \
|
||||||
|
$(INCLUDES)
|
||||||
|
CPPFLAGS+=$(DBGCFLAGS) \
|
||||||
|
-fno-omit-frame-pointer -fPIC \
|
||||||
|
-std=c++17 -gdwarf-4 \
|
||||||
|
-Wall -Wextra \
|
||||||
|
-Wno-missing-field-initializers \
|
||||||
|
$(INCLUDES)
|
||||||
|
LDFLAGS+=$(DBGLDFLAGS) \
|
||||||
|
-shared -gdwarf-4 \
|
||||||
|
$(DBGCFLAGS)
|
||||||
|
LDLIBS=-lstrophe \
|
||||||
|
-lpthread \
|
||||||
|
$(shell xml2-config --libs) \
|
||||||
|
$(shell pkg-config --libs librnp-0) \
|
||||||
|
$(shell pkg-config --libs libsignal-protocol-c) \
|
||||||
|
-lgcrypt \
|
||||||
|
-llmdb
|
||||||
|
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
LIBDIR ?= $(PREFIX)/lib
|
||||||
|
|
||||||
|
HDRS=plugin.hh
|
||||||
|
SRCS=plugin.cpp
|
||||||
|
DEPS=deps/diff/libdiff.a
|
||||||
|
TSTS=$(patsubst %.cpp,tests/%.cc,$(SRCS)) tests/main.cc
|
||||||
|
OBJS=$(patsubst %.cpp,.%.o,$(SRCS))
|
||||||
|
JOBS=$(patsubst tests/%.cc,tests/.%.o,$(TSTS))
|
||||||
|
|
||||||
|
all: weechat-xmpp
|
||||||
|
weechat-xmpp: $(DEPS) xmpp.so
|
||||||
|
|
||||||
|
xmpp.so: $(OBJS) $(DEPS) $(HDRS)
|
||||||
|
$(CXX) $(LDFLAGS) -o $@ $(OBJS) $(DEPS) $(LDLIBS)
|
||||||
|
which patchelf >/dev/null && \
|
||||||
|
patchelf --set-rpath $(LIBRARY_PATH):$(shell realpath $(shell dirname $(shell gcc --print-libgcc-file-name))/../../../) xmpp.so && \
|
||||||
|
patchelf --shrink-rpath xmpp.so || true
|
||||||
|
|
||||||
|
.%.o: %.cpp
|
||||||
|
@$(CXX) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
tests/.%.o: tests/%.cc
|
||||||
|
@$(CXX) $(CPPFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
deps/diff/libdiff.a:
|
||||||
|
git submodule update --init --recursive
|
||||||
|
cd deps/diff && ./configure
|
||||||
|
$(MAKE) -C deps/diff CFLAGS=-fPIC
|
||||||
|
diff: deps/diff/libdiff.a
|
||||||
|
|
||||||
|
tests/run: xmpp.so $(JOBS)
|
||||||
|
$(CXX) $(CPPFLAGS) -o tests/run xmpp.so $(JOBS) $(LDLIBS)
|
||||||
|
which patchelf >/dev/null && \
|
||||||
|
patchelf --set-rpath $(PWD):$(LIBRARY_PATH):$(shell realpath $(shell dirname $(shell gcc --print-libgcc-file-name))/../../../) tests/run && \
|
||||||
|
patchelf --shrink-rpath tests/run || true
|
||||||
|
|
||||||
|
test: tests/run
|
||||||
|
tests/run
|
||||||
|
|
||||||
|
debug: xmpp.so
|
||||||
|
env LD_PRELOAD=$(DEBUG) gdb -ex "handle SIGPIPE nostop noprint pass" --args \
|
||||||
|
weechat -a -P 'alias,buflist,exec,irc' -r '/plugin load ./xmpp.so'
|
||||||
|
|
||||||
|
depend: .depend
|
||||||
|
|
||||||
|
.depend: $(SRCS)
|
||||||
|
$(RM) ./.depend
|
||||||
|
$(CXX) $(CPPFLAGS) -MM $^>>./.depend
|
||||||
|
|
||||||
|
tidy:
|
||||||
|
$(FIND) . -name "*.o" -delete
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) -f $(OBJS)
|
||||||
|
$(MAKE) -C deps/diff clean || true
|
||||||
|
git submodule foreach --recursive git clean -xfd || true
|
||||||
|
git submodule foreach --recursive git reset --hard || true
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
$(RM) *~ .depend
|
||||||
|
|
||||||
|
install: xmpp.so
|
||||||
|
ifeq ($(shell id -u),0)
|
||||||
|
mkdir -p $(DESTDIR)$(LIBDIR)/weechat/plugins
|
||||||
|
cp xmpp.so $(DESTDIR)$(LIBDIR)/weechat/plugins/xmpp.so
|
||||||
|
chmod 644 $(DESTDIR)$(LIBDIR)/weechat/plugins/xmpp.so
|
||||||
|
else
|
||||||
|
mkdir -p ~/.weechat/plugins
|
||||||
|
cp xmpp.so ~/.weechat/plugins/xmpp.so
|
||||||
|
chmod 755 ~/.weechat/plugins/xmpp.so
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: check
|
||||||
|
|
||||||
|
check:
|
||||||
|
clang-check --analyze *.c *.cc *.cpp
|
||||||
|
|
||||||
|
include .depend
|
@ -0,0 +1 @@
|
|||||||
|
Subproject commit aadb3d7fe4dcb4b212c77e4fc6c2599826aeb50a
|
@ -0,0 +1,132 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, version 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#include "plugin.hh"
|
||||||
|
|
||||||
|
#define WEECHAT_XMPP_PLUGIN_NAME "xmpp"
|
||||||
|
#define WEECHAT_XMPP_PLUGIN_VERSION "0.2.0"
|
||||||
|
|
||||||
|
namespace c {
|
||||||
|
extern "C" {
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <strophe.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "account.h"
|
||||||
|
#include "connection.h"
|
||||||
|
#include "command.h"
|
||||||
|
#include "input.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "completion.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TIMER_INTERVAL_SEC 0.01
|
||||||
|
|
||||||
|
struct t_hook *weechat_xmpp_process_timer = NULL;
|
||||||
|
|
||||||
|
struct t_gui_bar_item *weechat_xmpp_typing_bar_item = NULL;
|
||||||
|
|
||||||
|
bool weechat_plugin_init()
|
||||||
|
{
|
||||||
|
if (!config__init())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
config__read();
|
||||||
|
|
||||||
|
connection__init();
|
||||||
|
|
||||||
|
command__init();
|
||||||
|
|
||||||
|
completion__init();
|
||||||
|
|
||||||
|
weechat_xmpp_process_timer = weechat_hook_timer(TIMER_INTERVAL_SEC * 1000, 0, 0,
|
||||||
|
&account__timer_cb,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
if (!weechat_bar_search("typing"))
|
||||||
|
{
|
||||||
|
weechat_bar_new("typing", "off", "400", "window", "${typing}",
|
||||||
|
"bottom", "horizontal", "vertical",
|
||||||
|
"1", "1", "default", "default", "default", "default",
|
||||||
|
"off", "xmpp_typing");
|
||||||
|
}
|
||||||
|
|
||||||
|
weechat_xmpp_typing_bar_item = weechat_bar_item_new("xmpp_typing",
|
||||||
|
&buffer__typing_bar_cb,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
weechat_hook_signal("input_text_changed", &input__text_changed_cb, NULL, NULL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void weechat_plugin_end()
|
||||||
|
{
|
||||||
|
if (weechat_xmpp_typing_bar_item)
|
||||||
|
weechat_bar_item_remove(weechat_xmpp_typing_bar_item);
|
||||||
|
|
||||||
|
if (weechat_xmpp_process_timer)
|
||||||
|
weechat_unhook(weechat_xmpp_process_timer);
|
||||||
|
|
||||||
|
config__write();
|
||||||
|
|
||||||
|
account__disconnect_all();
|
||||||
|
|
||||||
|
account__free_all();
|
||||||
|
|
||||||
|
xmpp_shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace weechat {
|
||||||
|
plugin::plugin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin::plugin(plugin_ptr ptr)
|
||||||
|
: plugin_ptr(std::move(ptr)) {
|
||||||
|
this->m_name = WEECHAT_XMPP_PLUGIN_NAME;
|
||||||
|
this->m_version = WEECHAT_XMPP_PLUGIN_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin::plugin(struct t_weechat_plugin *ptr)
|
||||||
|
: plugin(std::move(weechat::plugin_ptr(
|
||||||
|
ptr, [this] (struct t_weechat_plugin *) { }
|
||||||
|
))) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool plugin::init(std::vector<std::string>) {
|
||||||
|
weechat_printf(nullptr, "%s: It works!", this->name().data());
|
||||||
|
return weechat_plugin_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool plugin::end() {
|
||||||
|
weechat_plugin_end();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin plugin::instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
WEECHAT_PLUGIN_NAME(WEECHAT_XMPP_PLUGIN_NAME);
|
||||||
|
WEECHAT_PLUGIN_DESCRIPTION(N_("XMPP client protocol"));
|
||||||
|
WEECHAT_PLUGIN_AUTHOR("bqv <weechat@fron.io>");
|
||||||
|
WEECHAT_PLUGIN_VERSION(WEECHAT_XMPP_PLUGIN_VERSION);
|
||||||
|
WEECHAT_PLUGIN_LICENSE("MPL2");
|
||||||
|
WEECHAT_PLUGIN_PRIORITY(5500);
|
||||||
|
|
||||||
|
int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
weechat::plugin::instance = std::move(weechat::plugin(plugin));
|
||||||
|
std::vector<std::string> args(argv, argv+argc);
|
||||||
|
return weechat::plugin::instance.init(args) ? WEECHAT_RC_OK : WEECHAT_RC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int weechat_plugin_end(struct t_weechat_plugin *)
|
||||||
|
{
|
||||||
|
return weechat::plugin::instance.end() ? WEECHAT_RC_OK : WEECHAT_RC_ERROR;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, version 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
#include <weechat/weechat-plugin.h>
|
||||||
|
|
||||||
|
#define weechat_plugin ::weechat::plugin::instance.get()
|
||||||
|
|
||||||
|
namespace weechat {
|
||||||
|
extern "C" {
|
||||||
|
//__attribute__((visibility("default")))
|
||||||
|
int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[]);
|
||||||
|
int weechat_plugin_end(struct t_weechat_plugin *plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::unique_ptr<
|
||||||
|
struct t_weechat_plugin,
|
||||||
|
std::function<void(struct t_weechat_plugin *)>> plugin_ptr;
|
||||||
|
|
||||||
|
class plugin : public plugin_ptr {
|
||||||
|
public:
|
||||||
|
plugin();
|
||||||
|
plugin(plugin_ptr ptr);
|
||||||
|
plugin(struct t_weechat_plugin *ptr);
|
||||||
|
|
||||||
|
inline std::string const& name() const { return this->m_name; }
|
||||||
|
inline std::string const& version() const { return this->m_version; }
|
||||||
|
|
||||||
|
bool init(std::vector<std::string> args);
|
||||||
|
bool end();
|
||||||
|
|
||||||
|
static plugin instance;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_name;
|
||||||
|
std::string m_version;
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||||
|
|
||||||
|
#include <doctest/doctest.h>
|
@ -0,0 +1,18 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <doctest/doctest.h>
|
||||||
|
|
||||||
|
#include "../plugin.hh"
|
||||||
|
|
||||||
|
TEST_CASE("placeholder")
|
||||||
|
{
|
||||||
|
int argc = 2;
|
||||||
|
const char *argv[2] = {"a", "b"};
|
||||||
|
|
||||||
|
SUBCASE("takes no arguments")
|
||||||
|
{
|
||||||
|
CHECK(argc != 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
weechat::plugin c;
|
||||||
|
CHECK(&c.name() == NULL);
|
||||||
|
}
|
Loading…
Reference in New Issue