guile: update, but disable for now

It's not ready for the new Message
This commit is contained in:
Dirk-Jan C. Binnema 2022-04-28 22:42:25 +03:00
parent 3ac3ce7828
commit 852c7044d9
6 changed files with 66 additions and 111 deletions

View File

@ -1,4 +1,4 @@
## Copyright (C) 2008-2020 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ## Copyright (C) 2008-2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
## ##
## This program is free software; you can redistribute it and/or modify ## 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 ## it under the terms of the GNU General Public License as published by
@ -16,11 +16,11 @@
include $(top_srcdir)/gtest.mk include $(top_srcdir)/gtest.mk
if BUILD_GUILE #if BUILD_GUILE
guile=guile #guile=guile
else #else
guile= guile=
endif #endif
if BUILD_MU4E if BUILD_MU4E
mu4e=mu4e mu4e=mu4e

View File

@ -49,9 +49,7 @@ snarf_x=snarf_gen.process(snarf_srcs)
lib_guile_mu = shared_module( lib_guile_mu = shared_module(
'guile-mu', 'guile-mu',
[ 'mu-guile.cc', [ 'mu-guile.cc',
'mu-guile.hh',
'mu-guile-message.cc', 'mu-guile-message.cc',
'mu-guile-message.hh',
snarf_x ], snarf_x ],
dependencies: [guile_dep, glib_dep, lib_mu_dep, config_h_dep, thread_dep ], dependencies: [guile_dep, glib_dep, lib_mu_dep, config_h_dep, thread_dep ],
install: true) install: true)

View File

@ -42,14 +42,6 @@ constexpr auto MU_GUILE_MSG_FIELD_ID_TIMESTAMP = Field::id_size() + 1;
static SCM SYMB_PRIO_LOW, SYMB_PRIO_NORMAL, SYMB_PRIO_HIGH; static SCM SYMB_PRIO_LOW, SYMB_PRIO_NORMAL, SYMB_PRIO_HIGH;
static std::array<SCM, AllMessageFlagInfos.size()> SYMB_FLAGS; static std::array<SCM, AllMessageFlagInfos.size()> SYMB_FLAGS;
static SCM SYMB_CONTACT_TO, SYMB_CONTACT_CC, SYMB_CONTACT_BCC, SYMB_CONTACT_FROM; static SCM SYMB_CONTACT_TO, SYMB_CONTACT_CC, SYMB_CONTACT_BCC, SYMB_CONTACT_FROM;
struct MuMsgWrapper {
MuMsgWrapper(const Message& msg, bool unrefme):
_msg{msg}, _unrefme(unrefme)
{}
Message _msg;
bool _unrefme;
};
static long MSG_TAG; static long MSG_TAG;
static gboolean static gboolean
@ -59,21 +51,23 @@ mu_guile_scm_is_msg(SCM scm)
} }
SCM SCM
mu_guile_msg_to_scm(const Message& msg) mu_guile_msg_to_scm(Message&& msg)
{ {
MuMsgWrapper* msgwrap; void *data{scm_gc_malloc(sizeof(Message), "msg")};
auto msgptr = reinterpret_cast<MuMsgWrapper*>(
scm_gc_malloc(sizeof(MuMsgWrapper), "msg"));
msgwrap->_msg = std::move(msg);
msgwrap->_unrefme = false;
msgwrap = (MuMsgWrapper*)scm_gc_malloc(sizeof(MuMsgWrapper), "msg"); SCM_RETURN_NEWSMOB(MSG_TAG,
msgwrap->_msg = msg;
msgwrap->_unrefme = FALSE;
SCM_RETURN_NEWSMOB(MSG_TAG, msgwrap); msgwrap);
} }
typedef struct { struct FlagData {
Flags flags; Flags flags;
SCM lst; SCM lst;
} FlagData; };
#define MU_GUILE_INITIALIZED_OR_ERROR \ #define MU_GUILE_INITIALIZED_OR_ERROR \
do { \ do { \
@ -120,7 +114,7 @@ msg_string_list_field(const Message& msg, Field::Id field_id)
SCM scmlst{SCM_EOL}; SCM scmlst{SCM_EOL};
for (auto&& val: msg.document().string_vec_value(field_id)) { for (auto&& val: msg.document().string_vec_value(field_id)) {
SCM item; SCM item;
item = scm_list_1(mu_guile_scm_from_str(val.c_str())); item = scm_list_1(mu_guile_scm_from_string(val));
scmlst = scm_append_x(scm_list_2(scmlst, item)); scmlst = scm_append_x(scm_list_2(scmlst, item));
} }
@ -131,7 +125,7 @@ static SCM
get_body(const Message& msg, bool html) get_body(const Message& msg, bool html)
{ {
if (const auto body = html ? msg.body_html() : msg.body_text(); body) if (const auto body = html ? msg.body_html() : msg.body_text(); body)
return mu_guile_scm_from_str(body->c_str()); return mu_guile_scm_from_string(*body);
else else
return SCM_BOOL_F; return SCM_BOOL_F;
} }
@ -177,7 +171,7 @@ SCM_DEFINE(get_field,
switch (field_opt->type) { switch (field_opt->type) {
case Field::Type::String: case Field::Type::String:
return mu_guile_scm_from_str(msg.document().string_value(field_opt->id).c_str()); return mu_guile_scm_from_string(msg.document().string_value(field_opt->id));
case Field::Type::ByteSize: case Field::Type::ByteSize:
case Field::Type::TimeT: case Field::Type::TimeT:
case Field::Type::Integer: case Field::Type::Integer:
@ -200,8 +194,8 @@ contacts_to_list(const Message& msg, Option<Field::Id> field_id)
for (auto&& contact: contacts) { for (auto&& contact: contacts) {
SCM item{scm_list_1( SCM item{scm_list_1(
scm_cons(mu_guile_scm_from_str(contact.name.c_str()), scm_cons(mu_guile_scm_from_string(contact.name),
mu_guile_scm_from_str(contact.email.c_str())))}; mu_guile_scm_from_string(contact.email)))};
list = scm_append_x(scm_list_2(list, item)); list = scm_append_x(scm_list_2(list, item));
} }
@ -258,50 +252,12 @@ SCM_DEFINE(get_contacts,
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
/* explicitly close the file backend, so we won't run out of fds */ /* explicitly close the file backend, so we won't run out of fds */
msg.u
return list; return list;
} }
#undef FUNC_NAME #undef FUNC_NAME
struct _AttInfo {
SCM attlist;
gboolean attachments_only;
};
typedef struct _AttInfo AttInfo;
static void
each_part(MuMsg* msg, MuMsgPart* part, AttInfo* attinfo)
{
char *mime_type, *filename;
SCM elm;
if (!part->type)
return;
if (attinfo->attachments_only && !mu_msg_part_maybe_attachment(part))
return;
mime_type = g_strdup_printf("%s/%s", part->type, part->subtype);
filename = mu_msg_part_get_filename(part, FALSE);
elm = scm_list_5(
/* msg */
mu_guile_scm_from_str(mu_msg_get_path(msg)),
/* index */
scm_from_uint(part->index),
/* filename or #f */
filename ? mu_guile_scm_from_str(filename) : SCM_BOOL_F,
/* mime-type */
mime_type ? mu_guile_scm_from_str(mime_type) : SCM_BOOL_F,
/* size */
part->size > 0 ? scm_from_uint(part->size) : SCM_BOOL_F);
g_free(mime_type);
g_free(filename);
attinfo->attlist = scm_cons(elm, attinfo->attlist);
}
SCM_DEFINE(get_parts, SCM_DEFINE(get_parts,
"mu:c:get-parts", "mu:c:get-parts",
1, 1,
@ -314,26 +270,44 @@ SCM_DEFINE(get_parts,
#define FUNC_NAME s_get_parts #define FUNC_NAME s_get_parts
{ {
MuMsgWrapper* msgwrap; MuMsgWrapper* msgwrap;
AttInfo attinfo;
MU_GUILE_INITIALIZED_OR_ERROR; MU_GUILE_INITIALIZED_OR_ERROR;
SCM_ASSERT(mu_guile_scm_is_msg(MSG), MSG, SCM_ARG1, FUNC_NAME); SCM_ASSERT(mu_guile_scm_is_msg(MSG), MSG, SCM_ARG1, FUNC_NAME);
SCM_ASSERT(scm_is_bool(ATTS_ONLY), ATTS_ONLY, SCM_ARG2, FUNC_NAME); SCM_ASSERT(scm_is_bool(ATTS_ONLY), ATTS_ONLY, SCM_ARG2, FUNC_NAME);
attinfo.attlist = SCM_EOL; /* empty list */ SCM attlist = SCM_EOL; /* empty list */
attinfo.attachments_only = ATTS_ONLY == SCM_BOOL_T ? TRUE : FALSE; bool attachments_only = ATTS_ONLY == SCM_BOOL_T ? TRUE : FALSE;
msgwrap = (MuMsgWrapper*)SCM_CDR(MSG); const Message& msg{reinterpret_cast<MuMsgWrapper*>(SCM_CDR(MSG))->_msg};
mu_msg_part_foreach(msgwrap->_msg, size_t n{};
MU_MSG_OPTION_NONE, for (auto&& part: msg.parts()) {
(MuMsgPartForeachFunc)each_part,
&attinfo); if (attachments_only && !part.is_attachment())
continue;
const auto mime_type{part.mime_type()};
const auto filename{part.cooked_filename()};
SCM elm = scm_list_5(
/* msg */
mu_guile_scm_from_string(msgwrap->_msg.path()),
/* index */
scm_from_uint(n++),
/* filename or #f */
filename ? mu_guile_scm_from_string(*filename) : SCM_BOOL_F,
/* mime-type */
mime_type ? mu_guile_scm_from_string(*mime_type) : SCM_BOOL_F,
/* size */
part.size() > 0 ? scm_from_uint(part.size()) : SCM_BOOL_F);
attlist = scm_cons(elm, attlist);
}
/* explicitly close the file backend, so we won't run of fds */ /* explicitly close the file backend, so we won't run of fds */
mu_msg_unload_msg_file(msgwrap->_msg); msg.unload_mime_message();
return attinfo.attlist; return attlist;
} }
#undef FUNC_NAME #undef FUNC_NAME
@ -346,22 +320,19 @@ SCM_DEFINE(get_header,
"Get an arbitrary HEADER from MSG.\n") "Get an arbitrary HEADER from MSG.\n")
#define FUNC_NAME s_get_header #define FUNC_NAME s_get_header
{ {
MuMsgWrapper* msgwrap;
char* header;
SCM val;
MU_GUILE_INITIALIZED_OR_ERROR; MU_GUILE_INITIALIZED_OR_ERROR;
SCM_ASSERT(mu_guile_scm_is_msg(MSG), MSG, SCM_ARG1, FUNC_NAME); SCM_ASSERT(mu_guile_scm_is_msg(MSG), MSG, SCM_ARG1, FUNC_NAME);
SCM_ASSERT(scm_is_string(HEADER) || HEADER == SCM_UNDEFINED, HEADER, SCM_ARG2, FUNC_NAME); SCM_ASSERT(scm_is_string(HEADER) || HEADER == SCM_UNDEFINED, HEADER, SCM_ARG2, FUNC_NAME);
msgwrap = (MuMsgWrapper*)SCM_CDR(MSG); const Message& msg{reinterpret_cast<MuMsgWrapper*>(SCM_CDR(MSG))->_msg};
header = scm_to_utf8_string(HEADER);
val = mu_guile_scm_from_str(mu_msg_get_header(msgwrap->_msg, header)); char *header = scm_to_utf8_string(HEADER);
SCM val = mu_guile_scm_from_string(msg.header(header).value_or(""));
free(header); free(header);
/* explicitly close the file backend, so we won't run of fds */ /* explicitly close the file backend, so we won't run of fds */
mu_msg_unload_msg_file(msgwrap->_msg); msg.unload_mime_message();
return val; return val;
} }
@ -409,7 +380,7 @@ SCM_DEFINE(for_each_message,
for (auto&& mi : *res) { for (auto&& mi : *res) {
if (auto msg{mi.message()}; msg) { if (auto msg{mi.message()}; msg) {
auto msgsmob{mu_guile_msg_to_scm(msg)}; auto msgsmob{mu_guile_msg_to_scm(std::move(msg.value()))};
scm_call_1(FUNC, msgsmob); scm_call_1(FUNC, msgsmob);
} }
} }
@ -464,17 +435,6 @@ define_vars(void)
} }
static SCM
msg_mark(SCM msg_smob)
{
MuMsgWrapper* msgwrap;
msgwrap = (MuMsgWrapper*)SCM_CDR(msg_smob);
msgwrap->_unrefme = TRUE;
return SCM_UNSPECIFIED;
}
static size_t static size_t
msg_free(SCM msg_smob) msg_free(SCM msg_smob)
{ {
@ -510,7 +470,6 @@ mu_guile_message_init(void* data)
{ {
MSG_TAG = scm_make_smob_type("msg", sizeof(MuMsgWrapper)); MSG_TAG = scm_make_smob_type("msg", sizeof(MuMsgWrapper));
scm_set_smob_mark(MSG_TAG, msg_mark);
scm_set_smob_free(MSG_TAG, msg_free); scm_set_smob_free(MSG_TAG, msg_free);
scm_set_smob_print(MSG_TAG, msg_print); scm_set_smob_print(MSG_TAG, msg_print);

View File

@ -35,13 +35,12 @@
using namespace Mu; using namespace Mu;
SCM SCM
mu_guile_scm_from_str(const char* str) mu_guile_scm_from_string(const std::string& str)
{ {
if (!str) if (str.empty())
return SCM_BOOL_F; return SCM_BOOL_F;
else else
return scm_from_stringn(str, return scm_from_stringn(str.c_str(), str.size(),
strlen(str),
"UTF-8", "UTF-8",
SCM_FAILED_CONVERSION_QUESTION_MARK); SCM_FAILED_CONVERSION_QUESTION_MARK);
} }

View File

@ -59,15 +59,14 @@ SCM mu_guile_g_error(const char* func_name, GError* err);
SCM mu_guile_error(const char* func_name, int status, const char* fmt, SCM args); SCM mu_guile_error(const char* func_name, int status, const char* fmt, SCM args);
/** /**
* convert a const char* into an SCM -- either a string or, if str == * convert a string into an SCM -- . It assumes str is in UTF8 encoding, and
* NULL, #f. It assumes str is in UTF8 encoding, and replace * replace characters with '?' if needed.
* characters with '?' if needed.
* *
* @param str a string or NULL * @param str a string
* *
* @return a guile string or #f * @return a guile string or #f for empty
*/ */
SCM mu_guile_scm_from_str(const char* str); SCM mu_guile_scm_from_string(const std::string& str);
/** /**
* Initialize this mu guile module. * Initialize this mu guile module.

View File

@ -180,7 +180,7 @@ endif
if not get_option('guile').disabled() and guile_dep.found() if not get_option('guile').disabled() and guile_dep.found()
config_h_data.set('BUILD_GUILE', 1) config_h_data.set('BUILD_GUILE', 1)
config_h_data.set_quoted('GUILE_BINARY', 'guile') config_h_data.set_quoted('GUILE_BINARY', 'guile')
subdir('guile') #3subdir('guile')
endif endif
config_h_data.set_quoted('MU_PROGRAM', mu.full_path()) config_h_data.set_quoted('MU_PROGRAM', mu.full_path())