guile: use updated Query API

This commit is contained in:
Dirk-Jan C. Binnema 2020-11-03 10:01:44 +02:00
parent 2804087b3a
commit 3206b9db23
7 changed files with 79 additions and 252 deletions

View File

@ -28,17 +28,23 @@ AM_CPPFLAGS= \
# don't use -Werror, as it might break on other compilers
# use -Wno-unused-parameters, because some callbacks may not
# really need all the params they get
AM_CFLAGS=$(ASAN_CFLAGS) ${WARN_CFLAGS}
AM_CXXFLAGS=$(ASAN_CXXFLAGS) ${WARN_CXXFLAGS}
AM_CFLAGS= \
$(ASAN_CFLAGS) \
${WARN_CFLAGS} \
-Wno-suggest-attribute=noreturn \
-Wno-missing-prototypes \
-Wno-missing-declarations
lib_LTLIBRARIES= \
libguile-mu.la
libguile_mu_la_SOURCES= \
mu-guile.c \
mu-guile.h \
mu-guile-message.c \
mu-guile-message.h
mu-guile.cc \
mu-guile.hh \
mu-guile-message.cc \
mu-guile-message.hh
libguile_mu_la_CFLAGS=$(AM_CFLAGS)
libguile_mu_la_LIBADD= \
${top_builddir}/lib/libmu.la \
@ -61,10 +67,13 @@ mu_guile_TEXINFOS= \
BUILT_SOURCES=$(XFILES)
snarfcppopts= $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(AM_CPPFLAGS)
snarfcppopts= $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
SUFFIXES = .x .doc
.c.x:
$(GUILE_SNARF) -o $@ $< $(snarfcppopts)
$(AM_V_GEN) $(GUILE_SNARF) -o $@ $< $(snarfcppopts)
.cc.x:
$(AM_V_GEN) $(GUILE_SNARF) -o $@ $< $(snarfcppopts)
# FIXME: GUILE_SITEDIR would be better, but that
# breaks 'make distcheck'

View File

@ -16,21 +16,20 @@
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#if HAVE_CONFIG_H
#include "mu-guile-message.hh"
#include <config.h>
#endif /*HAVE_CONFIG_H*/
#include "mu-guile-message.h"
#include <glib-object.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wredundant-decls"
#include <libguile.h>
#pragma GCC diagnostic pop
#include "mu-guile.h"
#include "mu-guile.hh"
#include <mu-runtime.h>
#include <mu-store.hh>
#include <mu-query.h>
#include <mu-query.hh>
#include <mu-msg.h>
#include <mu-msg-part.h>
@ -42,7 +41,7 @@ static SCM SYMB_PRIO_LOW, SYMB_PRIO_NORMAL, SYMB_PRIO_HIGH;
static SCM SYMB_FLAG_NEW, SYMB_FLAG_PASSED, SYMB_FLAG_REPLIED,
SYMB_FLAG_SEEN, SYMB_FLAG_TRASHED, SYMB_FLAG_DRAFT,
SYMB_FLAG_FLAGGED, SYMB_FLAG_SIGNED, SYMB_FLAG_ENCRYPTED,
SYMB_FLAG_HAS_ATTACH, SYMB_FLAG_UNREAD;
SYMB_FLAG_HAS_ATTACH, SYMB_FLAG_UNREAD, SYMB_FLAG_LIST;
static SCM SYMB_CONTACT_TO, SYMB_CONTACT_CC, SYMB_CONTACT_BCC,
SYMB_CONTACT_FROM;
@ -66,7 +65,7 @@ mu_guile_msg_to_scm (MuMsg *msg)
g_return_val_if_fail (msg, SCM_UNDEFINED);
msgwrap = scm_gc_malloc (sizeof (MuMsgWrapper), "msg");
msgwrap = (MuMsgWrapper*)scm_gc_malloc (sizeof (MuMsgWrapper), "msg");
msgwrap->_msg = msg;
msgwrap->_unrefme = FALSE;
@ -82,10 +81,11 @@ typedef struct _FlagData FlagData;
#define MU_GUILE_INITIALIZED_OR_ERROR \
do { if (!(mu_guile_initialized())) \
return mu_guile_error (FUNC_NAME, 0, \
mu_guile_error (FUNC_NAME, 0, \
"mu not initialized; call mu:initialize", \
SCM_UNDEFINED); \
} while (0)
return SCM_UNSPECIFIED; \
} while (0)
static void
@ -97,6 +97,7 @@ check_flag (MuFlags flag, FlagData *fdata)
return;
switch (flag) {
case MU_FLAG_NONE: break;
case MU_FLAG_NEW: flag_scm = SYMB_FLAG_NEW; break;
case MU_FLAG_PASSED: flag_scm = SYMB_FLAG_PASSED; break;
case MU_FLAG_REPLIED: flag_scm = SYMB_FLAG_REPLIED; break;
@ -108,6 +109,7 @@ check_flag (MuFlags flag, FlagData *fdata)
case MU_FLAG_ENCRYPTED: flag_scm = SYMB_FLAG_ENCRYPTED; break;
case MU_FLAG_HAS_ATTACH: flag_scm = SYMB_FLAG_HAS_ATTACH; break;
case MU_FLAG_UNREAD: flag_scm = SYMB_FLAG_UNREAD; break;
case MU_FLAG_LIST: flag_scm = SYMB_FLAG_LIST; break;
default: flag_scm = SCM_UNDEFINED;
}
@ -297,10 +299,11 @@ SCM_DEFINE (get_contacts, "mu:c:get-contacts", 2, 0, 0,
ecdata.ctype = MU_MSG_CONTACT_TYPE_BCC;
else if (scm_is_eq (CONTACT_TYPE, SYMB_CONTACT_FROM))
ecdata.ctype = MU_MSG_CONTACT_TYPE_FROM;
else
return mu_guile_error (FUNC_NAME, 0,
"invalid contact type",
else {
mu_guile_error (FUNC_NAME, 0, "invalid contact type",
SCM_UNDEFINED);
return SCM_UNSPECIFIED;
}
}
ecdata.lst = SCM_EOL;
@ -428,14 +431,12 @@ call_func (SCM FUNC, MuMsgIter *iter, const char* func_name)
static MuMsgIter*
get_query_iter (MuQuery *query, const char* expr, int maxnum)
get_query_iter (Mu::Query& query, const char* expr, int maxnum)
{
MuMsgIter *iter;
GError *err;
err = NULL;
iter = mu_query_run (query, expr, MU_MSG_FIELD_ID_NONE, maxnum,
MU_QUERY_FLAG_NONE, &err);
GError *err{};
auto iter = query.run (expr, MU_MSG_FIELD_ID_NONE,
Mu::Query::Flags::None, maxnum,
&err);
if (!iter) {
mu_guile_g_error ("<internal error>", err);
g_clear_error (&err);
@ -472,7 +473,7 @@ SCM_DEFINE (for_each_message, "mu:c:for-each-message", 3, 0, 0,
else
expr = scm_to_utf8_string(EXPR);
iter = get_query_iter (mu_guile_instance()->query, expr,
iter = get_query_iter (mu_guile_query(), expr,
scm_to_int(MAXNUM));
free (expr);
if (!iter)
@ -525,6 +526,8 @@ define_symbols (void)
SYMB_FLAG_ENCRYPTED = register_symbol ("mu:flag:encrypted");
SYMB_FLAG_HAS_ATTACH = register_symbol ("mu:flag:has-attach");
SYMB_FLAG_UNREAD = register_symbol ("mu:flag:unread");
SYMB_FLAG_LIST = register_symbol ("mu:flag:list");
}

View File

@ -17,12 +17,8 @@
**
*/
#ifndef __MU_GUILE_MESSAGE_H__
#define __MU_GUILE_MESSAGE_H__
#include <glib.h>
G_BEGIN_DECLS
#ifndef MU_GUILE_MESSAGE_H__
#define MU_GUILE_MESSAGE_H__
/**
* Initialize this mu guile module.
@ -33,6 +29,4 @@ G_BEGIN_DECLS
*/
void* mu_guile_message_init (void *data);
G_END_DECLS
#endif /*__MU_GUILE_MESSAGE_H__*/
#endif /*MU_GUILE_MESSAGE_HH__*/

View File

@ -17,9 +17,10 @@
**
*/
#include "mu-guile.hh"
#include <config.h>
#include <locale.h>
#include <glib-object.h>
#pragma GCC diagnostic push
@ -27,16 +28,11 @@
#include <libguile.h>
#pragma GCC diagnostic pop
#include <mu-runtime.h>
#include <mu-query.h>
#include <mu-runtime.h>
#include <mu-store.hh>
#include <mu-query.h>
#include <mu-query.hh>
#include <mu-msg.h>
#include "mu-guile.h"
SCM
mu_guile_scm_from_str (const char *str)
{
@ -47,7 +43,6 @@ mu_guile_scm_from_str (const char *str)
SCM_FAILED_CONVERSION_QUESTION_MARK);
}
SCM
mu_guile_error (const char *func_name, int status,
const char *fmt, SCM args)
@ -75,68 +70,46 @@ mu_guile_g_error (const char *func_name, GError *err)
/* there can be only one */
static MuGuile *_singleton = NULL;
static std::unique_ptr<Mu::Query> QuerySingleton;
static gboolean
mu_guile_init_instance (const char *muhome)
mu_guile_init_instance (const char *muhome) try
{
MuStore *store;
MuQuery *query;
GError *err;
setlocale (LC_ALL, "");
if (!mu_runtime_init (muhome, "guile", FALSE))
return FALSE;
err = NULL;
store = mu_store_new_readable
(mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB),
&err);
if (!store)
goto errexit;
query = mu_query_new (store, &err);
mu_store_unref (store);
if (!query)
goto errexit;
_singleton = g_new0 (MuGuile, 1);
_singleton->query = query;
Mu::Store store{mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB)};
QuerySingleton = std::make_unique<Mu::Query>(store);
return TRUE;
errexit:
mu_guile_g_error (__func__, err);
g_clear_error (&err);
return FALSE;
} catch (...) {
return FALSE;
}
static void
mu_guile_uninit_instance (void)
mu_guile_uninit_instance ()
{
g_return_if_fail (_singleton);
mu_query_destroy (_singleton->query);
g_free (_singleton);
_singleton = NULL;
QuerySingleton.reset();
mu_runtime_uninit ();
}
MuGuile*
mu_guile_instance (void)
Mu::Query&
mu_guile_query ()
{
g_return_val_if_fail (_singleton, NULL);
return _singleton;
if (!QuerySingleton)
g_error("mu guile not initialized");
return *QuerySingleton.get();
}
gboolean
mu_guile_initialized (void)
mu_guile_initialized ()
{
return _singleton != NULL;
return !!QuerySingleton;
}
@ -212,7 +185,7 @@ SCM_DEFINE (log_func, "mu:c:log", 1, 0, 1, (SCM LEVEL, SCM FRM, SCM ARGS),
return SCM_UNSPECIFIED;
output = scm_to_utf8_string (str);
g_log (G_LOG_DOMAIN, level, "%s", output);
g_log (G_LOG_DOMAIN, (GLogLevelFlags)level, "%s", output);
free (output);
return SCM_UNSPECIFIED;

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2011-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2011-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
@ -21,22 +21,14 @@
#define __MU_GUILE_H__
#include <glib.h>
#include <mu-query.h>
#include <libguile.h>
#include <mu-query.hh>
G_BEGIN_DECLS
struct _MuGuile {
MuQuery *query;
};
typedef struct _MuGuile MuGuile;
/**
* get the single MuGuile instance
*
* @return the instance or NULL in case of error
* get the singleton Query instance
*/
MuGuile *mu_guile_instance (void);
Mu::Query& mu_guile_query (void);
/**
@ -44,7 +36,7 @@ MuGuile *mu_guile_instance (void);
*
* @return TRUE if MuGuile is Initialized, FALSE otherwise
*/
gboolean mu_guile_initialized (void);
gboolean mu_guile_initialized ();
/**
@ -83,7 +75,6 @@ SCM mu_guile_error (const char *func_name, int status,
*/
SCM mu_guile_scm_from_str (const char *str);
/**
* Initialize this mu guile module.
*
@ -93,7 +84,4 @@ SCM mu_guile_scm_from_str (const char *str);
*/
void* mu_guile_init (void *data);
G_END_DECLS
#endif /*__MU_GUILE_H__*/

View File

@ -1,4 +1,4 @@
# Copyright (C) 2008-2013 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
# Copyright (C) 2008-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
##
## This program is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by the
@ -21,9 +21,9 @@ AM_CPPFLAGS=$(XAPIAN_CXXFLAGS) \
$(GLIB_CFLAGS) \
-I${top_srcdir} \
-I${top_srcdir}/lib \
-DMU_TESTMAILDIR=\"${top_srcdir}/lib/testdir\" \
-DMU_TESTMAILDIR2=\"${top_srcdir}/lib/testdir2\" \
-DMU_TESTMAILDIR3=\"${top_srcdir}/lib/testdir3\" \
-DMU_TESTMAILDIR=\"${abs_top_srcdir}/lib/testdir\" \
-DMU_TESTMAILDIR2=\"${abs_top_srcdir}/lib/testdir2\" \
-DMU_TESTMAILDIR3=\"${abs_top_srcdir}/lib/testdir3\" \
-DMU_PROGRAM=\"${abs_top_builddir}/mu/mu\" \
-DMU_GUILE_MODULE_PATH=\"${abs_top_srcdir}/guile/\" \
-DMU_GUILE_LIBRARY_PATH=\"${abs_top_builddir}/guile/.libs\" \
@ -39,14 +39,8 @@ AM_LDFLAGS=$(ASAN_LDFLAGS)
noinst_PROGRAMS= $(TEST_PROGS)
TEST_PROGS += test-mu-guile
test_mu_guile_SOURCES= test-mu-guile.c dummy.cc
test_mu_guile_LDADD=${top_builddir}/lib/libtestmucommon.la
# TEST_PROGS += test-mu-guile
# test_mu_guile_SOURCES= test-mu-guile.cc
# test_mu_guile_LDADD=${top_builddir}/lib/libtestmucommon.la
# we need to use dummy.cc to enforce c++ linking...
BUILT_SOURCES= \
dummy.cc
dummy.cc:
touch dummy.cc
EXTRA_DIST=test-mu-guile.scm
EXTRA_DIST=test-mu-guile.scm test-mu-guile.cc

View File

@ -1,134 +0,0 @@
/*
** Copyright (C) 2012-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <glib.h>
#include <glib/gstdio.h>
#include <lib/mu-query.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "test-mu-common.h"
#include <lib/mu-store.hh>
/* tests for the command line interface, uses testdir2 */
static gchar*
fill_database (void)
{
gchar *cmdline, *tmpdir;
GError *err;
tmpdir = test_mu_common_get_random_tmpdir();
cmdline = g_strdup_printf (
"/bin/sh -c '"
"%s init --muhome=%s --maildir=%s --quiet; "
"%s index --muhome=%s --quiet'",
MU_PROGRAM, tmpdir, MU_TESTMAILDIR2,
MU_PROGRAM, tmpdir);
if (g_test_verbose())
g_print ("%s\n", cmdline);
err = NULL;
if (!g_spawn_command_line_sync (cmdline, NULL, NULL,
NULL, &err)) {
g_printerr ("Error: %s\n", err ? err->message : "?");
g_assert (0);
}
g_free (cmdline);
return tmpdir;
}
static void
test_something (const char *what)
{
char *dir, *cmdline;
gint result;
dir = fill_database ();
cmdline = g_strdup_printf (
"LD_LIBRARY_PATH=%s %s -q -L %s -e main %s/test-mu-guile.scm "
"--muhome=%s --test=%s",
MU_GUILE_LIBRARY_PATH,
GUILE_BINARY,
MU_GUILE_MODULE_PATH,
ABS_SRCDIR,
dir,
what);
if (g_test_verbose ())
g_print ("cmdline: %s\n", cmdline);
result = system (cmdline);
g_assert (result == 0);
g_free (dir);
g_free (cmdline);
}
static void
test_mu_guile_queries (void)
{
test_something ("queries");
}
static void
test_mu_guile_messages (void)
{
test_something ("message");
}
static void
test_mu_guile_stats (void)
{
test_something ("stats");
}
int
main (int argc, char *argv[])
{
int rv;
g_test_init (&argc, &argv, NULL);
if (!set_en_us_utf8_locale())
return 0; /* don't error out... */
g_test_add_func ("/guile/queries", test_mu_guile_queries);
g_test_add_func ("/guile/message", test_mu_guile_messages);
g_test_add_func ("/guile/stats", test_mu_guile_stats);
g_log_set_handler (NULL,
G_LOG_LEVEL_MASK | G_LOG_LEVEL_WARNING|
G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION,
(GLogFunc)black_hole, NULL);
rv = g_test_run ();
return rv;
}