1
0
mirror of https://github.com/djcb/mu.git synced 2024-06-27 07:35:16 +02:00

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

View File

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

View File

@ -17,9 +17,10 @@
** **
*/ */
#include "mu-guile.hh"
#include <config.h> #include <config.h>
#include <locale.h> #include <locale.h>
#include <glib-object.h> #include <glib-object.h>
#pragma GCC diagnostic push #pragma GCC diagnostic push
@ -27,16 +28,11 @@
#include <libguile.h> #include <libguile.h>
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#include <mu-runtime.h>
#include <mu-query.h>
#include <mu-runtime.h> #include <mu-runtime.h>
#include <mu-store.hh> #include <mu-store.hh>
#include <mu-query.h> #include <mu-query.hh>
#include <mu-msg.h> #include <mu-msg.h>
#include "mu-guile.h"
SCM SCM
mu_guile_scm_from_str (const char *str) 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_FAILED_CONVERSION_QUESTION_MARK);
} }
SCM SCM
mu_guile_error (const char *func_name, int status, mu_guile_error (const char *func_name, int status,
const char *fmt, SCM args) const char *fmt, SCM args)
@ -75,68 +70,46 @@ mu_guile_g_error (const char *func_name, GError *err)
/* there can be only one */ /* there can be only one */
static MuGuile *_singleton = NULL; static std::unique_ptr<Mu::Query> QuerySingleton;
static gboolean 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, ""); setlocale (LC_ALL, "");
if (!mu_runtime_init (muhome, "guile", FALSE)) if (!mu_runtime_init (muhome, "guile", FALSE))
return FALSE; return FALSE;
err = NULL; Mu::Store store{mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB)};
store = mu_store_new_readable QuerySingleton = std::make_unique<Mu::Query>(store);
(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;
return TRUE; return TRUE;
errexit: } catch (...) {
mu_guile_g_error (__func__, err); return FALSE;
g_clear_error (&err);
return FALSE;
} }
static void static void
mu_guile_uninit_instance (void) mu_guile_uninit_instance ()
{ {
g_return_if_fail (_singleton); QuerySingleton.reset();
mu_query_destroy (_singleton->query);
g_free (_singleton);
_singleton = NULL;
mu_runtime_uninit (); mu_runtime_uninit ();
} }
MuGuile* Mu::Query&
mu_guile_instance (void) mu_guile_query ()
{ {
g_return_val_if_fail (_singleton, NULL); if (!QuerySingleton)
return _singleton; g_error("mu guile not initialized");
return *QuerySingleton.get();
} }
gboolean 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; return SCM_UNSPECIFIED;
output = scm_to_utf8_string (str); 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); free (output);
return SCM_UNSPECIFIED; 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 ** 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 ** under the terms of the GNU General Public License as published by the
@ -21,22 +21,14 @@
#define __MU_GUILE_H__ #define __MU_GUILE_H__
#include <glib.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 * get the singleton Query instance
*
* @return the instance or NULL in case of error
*/ */
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 * @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); SCM mu_guile_scm_from_str (const char *str);
/** /**
* Initialize this mu guile module. * Initialize this mu guile module.
* *
@ -93,7 +84,4 @@ SCM mu_guile_scm_from_str (const char *str);
*/ */
void* mu_guile_init (void *data); void* mu_guile_init (void *data);
G_END_DECLS
#endif /*__MU_GUILE_H__*/ #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 ## 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 ## under the terms of the GNU General Public License as published by the
@ -21,9 +21,9 @@ AM_CPPFLAGS=$(XAPIAN_CXXFLAGS) \
$(GLIB_CFLAGS) \ $(GLIB_CFLAGS) \
-I${top_srcdir} \ -I${top_srcdir} \
-I${top_srcdir}/lib \ -I${top_srcdir}/lib \
-DMU_TESTMAILDIR=\"${top_srcdir}/lib/testdir\" \ -DMU_TESTMAILDIR=\"${abs_top_srcdir}/lib/testdir\" \
-DMU_TESTMAILDIR2=\"${top_srcdir}/lib/testdir2\" \ -DMU_TESTMAILDIR2=\"${abs_top_srcdir}/lib/testdir2\" \
-DMU_TESTMAILDIR3=\"${top_srcdir}/lib/testdir3\" \ -DMU_TESTMAILDIR3=\"${abs_top_srcdir}/lib/testdir3\" \
-DMU_PROGRAM=\"${abs_top_builddir}/mu/mu\" \ -DMU_PROGRAM=\"${abs_top_builddir}/mu/mu\" \
-DMU_GUILE_MODULE_PATH=\"${abs_top_srcdir}/guile/\" \ -DMU_GUILE_MODULE_PATH=\"${abs_top_srcdir}/guile/\" \
-DMU_GUILE_LIBRARY_PATH=\"${abs_top_builddir}/guile/.libs\" \ -DMU_GUILE_LIBRARY_PATH=\"${abs_top_builddir}/guile/.libs\" \
@ -39,14 +39,8 @@ AM_LDFLAGS=$(ASAN_LDFLAGS)
noinst_PROGRAMS= $(TEST_PROGS) noinst_PROGRAMS= $(TEST_PROGS)
TEST_PROGS += test-mu-guile # TEST_PROGS += test-mu-guile
test_mu_guile_SOURCES= test-mu-guile.c dummy.cc # test_mu_guile_SOURCES= test-mu-guile.cc
test_mu_guile_LDADD=${top_builddir}/lib/libtestmucommon.la # test_mu_guile_LDADD=${top_builddir}/lib/libtestmucommon.la
# we need to use dummy.cc to enforce c++ linking... EXTRA_DIST=test-mu-guile.scm test-mu-guile.cc
BUILT_SOURCES= \
dummy.cc
dummy.cc:
touch dummy.cc
EXTRA_DIST=test-mu-guile.scm

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;
}