begin porting

v2
Tony Olagbaiye 3 years ago
parent 8fb40cad8d
commit 6e3e5ce115
No known key found for this signature in database
GPG Key ID: 9E2FF3BDEBDFC910

@ -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)")))

@ -1,66 +1,37 @@
# -*- mode: sh; -*-
# Thanks <https://github.com/direnv/direnv/issues/73#issuecomment-152284914>
export_function()
{
local name=$1
local alias_dir=$PWD/.direnv/aliases
mkdir -p "$alias_dir"
PATH_add "$alias_dir"
local target="$alias_dir/$name"
if declare -f "$name" >/dev/null; then
echo "#!$SHELL" > "$target"
declare -f "$name" >> "$target" 2>/dev/null
# Notice that we add shell variables to the function trigger.
echo "$name \$*" >> "$target"
chmod +x "$target"
fi
}
use_guix()
{
# Recreate a garbage collector root.
gcroots="$HOME/.config/guix/gcroots"
mkdir -p "$gcroots"
gcroot="$gcroots/guix"
if [ -L "$gcroot" ]
then
rm -v "$gcroot"
fi
export CC=gcc CXX=g++
# Miscellaneous packages.
ENVIRONMENTS=(
weechat # Debug runs
)
# Miscellaneous packages.
ENVIRONMENTS=(
weechat # Debug runs
)
# Environment packages.
PACKAGES=(
autoconf # Deps with autoreconf
autoconf-archive # Deps with m4 tooling
automake # Deps with automake
libtool # Deps with libtool
make # Makefile and deps with makefiles
cmake # Deps with cmake
gcc-toolchain@11 # Compilation
pkg-config # Deps configuration and configuration of deps deps
patchelf # Fix linkage (guix)
bear # Generate compile_commands.json for language servers
universal-ctags # Generate tags (make tags)
weechat # Weechat includes
libxml2 # Dep (libxml2)
libstrophe # Dep (strophe)
libgcrypt # Dep (gcrypt)
libsignal-protocol-c # Dep (libsignal)
lmdb # Dep (lmdb)
rnp # Dep (rnpgp)
)
# Thanks <https://lists.gnu.org/archive/html/guix-devel/2016-09/msg00859.html>
eval "$(guix environment --search-paths --root="$gcroot" ${ENVIRONMENTS[@]} --ad-hoc ${PACKAGES[@]} "$@")"
export CC=gcc
}
# Environment packages.
PACKAGES=(
autoconf # Deps with autoreconf
autoconf-archive # Deps with m4 tooling
automake # Deps with automake
libtool # Deps with libtool
make # Deps with makefiles
cmake # Deps with cmake
doctest # Testing
gcc-toolchain@11 # Compilation
pkg-config # Deps configuration and configuration of deps deps
patchelf # Fix linkage (guix)
bear # Generate compile_commands.json for language servers
universal-ctags # Generate tags (make tags)
weechat # Weechat includes
libxml2 # Dep (libxml2)
libstrophe # Dep (strophe)
libgcrypt # Dep (gcrypt)
libsignal-protocol-c # Dep (libsignal)
lmdb lmdbxx # Dep (lmdb)
rnp # Dep (rnpgp)
)
use guix \
${ENVIRONMENTS[@]} --ad-hoc ${PACKAGES[@]} \
--with-debug-info=weechat\
--with-debug-info=libstrophe\
--with-debug-info=libsignal-protocol-c\

3
.gitmodules vendored

@ -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

1
deps/diff vendored

@ -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…
Cancel
Save