mirror of https://github.com/djcb/mu.git
mu: Update for new querying APIs
This commit is contained in:
parent
e282d80bc0
commit
01ced9a356
|
@ -80,25 +80,25 @@ test_cxxflags= \
|
||||||
-DABS_CURDIR=\"${abs_builddir}\" \
|
-DABS_CURDIR=\"${abs_builddir}\" \
|
||||||
-DABS_SRCDIR=\"${abs_srcdir}\"
|
-DABS_SRCDIR=\"${abs_srcdir}\"
|
||||||
|
|
||||||
TEST_PROGS += test-mu-query
|
TEST_PROGS += test-query
|
||||||
test_mu_query_SOURCES= test-mu-query.cc
|
test_query_SOURCES= test-mu-query.cc
|
||||||
test_mu_query_CXXFLAGS=$(test_cxxflags)
|
test_query_CXXFLAGS=$(test_cxxflags)
|
||||||
test_mu_query_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
test_query_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
||||||
|
|
||||||
TEST_PROGS += test-mu-cmd
|
TEST_PROGS += test-cmd
|
||||||
test_mu_cmd_SOURCES= test-mu-cmd.cc
|
test_cmd_SOURCES= test-mu-cmd.cc
|
||||||
test_mu_cmd_CXXFLAGS=$(test_cxxflags)
|
test_cmd_CXXFLAGS=$(test_cxxflags)
|
||||||
test_mu_cmd_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
test_cmd_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
||||||
|
|
||||||
TEST_PROGS += test-mu-cmd-cfind
|
TEST_PROGS += test-cmd-cfind
|
||||||
test_mu_cmd_cfind_SOURCES= test-mu-cmd-cfind.cc
|
test_cmd_cfind_SOURCES= test-mu-cmd-cfind.cc
|
||||||
test_mu_cmd_cfind_CXXFLAGS=$(test_cxxflags)
|
test_cmd_cfind_CXXFLAGS=$(test_cxxflags)
|
||||||
test_mu_cmd_cfind_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
test_cmd_cfind_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
||||||
|
|
||||||
TEST_PROGS += test-mu-threads
|
TEST_PROGS += test-threads
|
||||||
test_mu_threads_SOURCES= test-mu-threads.cc
|
test_threads_SOURCES= test-mu-threads.cc
|
||||||
test_mu_threads_CXXFLAGS=$(test_cxxflags)
|
test_threads_CXXFLAGS=$(test_cxxflags)
|
||||||
test_mu_threads_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
test_threads_LDADD=${top_builddir}/lib/libtestmucommon.la $(CODE_COVERAGE_LIBS)
|
||||||
|
|
||||||
TESTS=$(TEST_PROGS)
|
TESTS=$(TEST_PROGS)
|
||||||
include $(top_srcdir)/aminclude_static.am
|
include $(top_srcdir)/aminclude_static.am
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include "utils/mu-str.h"
|
#include "utils/mu-str.h"
|
||||||
#include "utils/mu-date.h"
|
#include "utils/mu-date.h"
|
||||||
|
|
||||||
|
using namespace Mu;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* guess the last name for the given name; clearly,
|
* guess the last name for the given name; clearly,
|
||||||
* this is just a rough guess for setting an initial value.
|
* this is just a rough guess for setting an initial value.
|
||||||
|
@ -404,7 +406,7 @@ cfind_params_valid (const MuConfig *opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
MuError
|
MuError
|
||||||
mu_cmd_cfind (const Mu::Store& store, const MuConfig *opts, GError **err)
|
Mu::mu_cmd_cfind (const Mu::Store& store, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
|
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
|
||||||
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_CFIND,
|
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_CFIND,
|
||||||
|
|
|
@ -22,12 +22,14 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "mu-msg.h"
|
#include "mu-msg.hh"
|
||||||
#include "mu-msg-part.h"
|
#include "mu-msg-part.hh"
|
||||||
|
|
||||||
#include "mu-cmd.hh"
|
#include "mu-cmd.hh"
|
||||||
#include "utils/mu-util.h"
|
#include "utils/mu-util.h"
|
||||||
#include "utils/mu-str.h"
|
#include "utils/mu-str.h"
|
||||||
|
|
||||||
|
using namespace Mu;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
save_part (MuMsg *msg, const char *targetdir, guint partidx, const MuConfig *opts)
|
save_part (MuMsg *msg, const char *targetdir, guint partidx, const MuConfig *opts)
|
||||||
|
@ -393,7 +395,7 @@ check_params (const MuConfig *opts, GError **err)
|
||||||
}
|
}
|
||||||
|
|
||||||
MuError
|
MuError
|
||||||
mu_cmd_extract (const MuConfig *opts, GError **err)
|
Mu::mu_cmd_extract (const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include "mu-msg.h"
|
#include "mu-msg.hh"
|
||||||
#include "mu-maildir.h"
|
#include "mu-maildir.hh"
|
||||||
|
#include "mu-query-match-deciders.hh"
|
||||||
#include "mu-query.hh"
|
#include "mu-query.hh"
|
||||||
#include "mu-msg-iter.h"
|
|
||||||
#include "mu-bookmarks.hh"
|
#include "mu-bookmarks.hh"
|
||||||
#include "mu-runtime.hh"
|
#include "mu-runtime.hh"
|
||||||
|
|
||||||
|
@ -40,15 +40,24 @@
|
||||||
#include "utils/mu-date.h"
|
#include "utils/mu-date.h"
|
||||||
|
|
||||||
#include "mu-cmd.hh"
|
#include "mu-cmd.hh"
|
||||||
#include "mu-threader.hh"
|
|
||||||
|
|
||||||
using namespace Mu;
|
using namespace Mu;
|
||||||
|
|
||||||
typedef gboolean (OutputFunc) (MuMsg *msg, MuMsgIter *iter,
|
struct OutputInfo{
|
||||||
const MuConfig *opts, GError **err);
|
Xapian::docid docid{};
|
||||||
|
bool is_first{};
|
||||||
|
bool is_last{};
|
||||||
|
Option<QueryMatch&> match_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr auto FirstOutput{OutputInfo{0, true, false}};
|
||||||
|
constexpr auto LastOutput{OutputInfo{0, false, true}};
|
||||||
|
|
||||||
|
using OutputFunc = std::function<bool(MuMsg*, const OutputInfo&,
|
||||||
|
const MuConfig*, GError**)>;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
print_internal (const Query& query, const gchar *expr, gboolean xapian,
|
print_internal (const Query& query, const std::string& expr, gboolean xapian,
|
||||||
gboolean warn, GError **err)
|
gboolean warn, GError **err)
|
||||||
{
|
{
|
||||||
std::cout << query.parse(expr, xapian) << "\n";
|
std::cout << query.parse(expr, xapian) << "\n";
|
||||||
|
@ -75,59 +84,35 @@ sort_field_from_string (const char* fieldstr, GError **err)
|
||||||
return mfid;
|
return mfid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MuMsg*
|
|
||||||
get_message (MuMsgIter *iter, time_t after)
|
|
||||||
{
|
|
||||||
MuMsg *msg;
|
|
||||||
|
|
||||||
if (mu_msg_iter_is_done (iter))
|
static Option<QueryResults>
|
||||||
return NULL;
|
|
||||||
|
|
||||||
msg = mu_msg_iter_get_msg_floating (iter);
|
|
||||||
if (!msg)
|
|
||||||
return NULL; /* error */
|
|
||||||
|
|
||||||
if (!mu_msg_is_readable (msg)) {
|
|
||||||
mu_msg_iter_next (iter);
|
|
||||||
return get_message (iter, after);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (after != 0 && after > mu_msg_get_timestamp (msg)) {
|
|
||||||
mu_msg_iter_next (iter);
|
|
||||||
return get_message (iter, after);
|
|
||||||
}
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MuMsgIter*
|
|
||||||
run_query (const Query& q, const std::string& expr, const MuConfig *opts, GError **err)
|
run_query (const Query& q, const std::string& expr, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
MuMsgIter *iter;
|
|
||||||
MuMsgFieldId sortid;
|
MuMsgFieldId sortid;
|
||||||
|
|
||||||
sortid = MU_MSG_FIELD_ID_NONE;
|
sortid = MU_MSG_FIELD_ID_NONE;
|
||||||
if (opts->sortfield) {
|
if (opts->sortfield) {
|
||||||
sortid = sort_field_from_string (opts->sortfield, err);
|
sortid = sort_field_from_string (opts->sortfield, err);
|
||||||
if (sortid == MU_MSG_FIELD_ID_NONE) /* error occurred? */
|
if (sortid == MU_MSG_FIELD_ID_NONE) /* error occurred? */
|
||||||
return FALSE;
|
return Nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mu::Query::Flags qflags{Query::Flags::None};
|
Mu::QueryFlags qflags{QueryFlags::None};
|
||||||
if (opts->reverse)
|
if (opts->reverse)
|
||||||
qflags |= Query::Flags::Descending;
|
qflags |= QueryFlags::Descending;
|
||||||
if (opts->skip_dups)
|
if (opts->skip_dups)
|
||||||
qflags |= Query::Flags::SkipDups;
|
qflags |= QueryFlags::SkipDuplicates;
|
||||||
if (opts->include_related)
|
if (opts->include_related)
|
||||||
qflags |= Query::Flags::IncludeRelated;
|
qflags |= QueryFlags::IncludeRelated;
|
||||||
if (opts->threads)
|
if (opts->threads)
|
||||||
qflags |= Query::Flags::Threading;
|
qflags |= QueryFlags::Threading;
|
||||||
|
|
||||||
return q.run(expr, sortid, qflags, opts->maxnum, err);
|
return q.run(expr, sortid, qflags, opts->maxnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
exec_cmd (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
exec_cmd (MuMsg *msg, const OutputInfo& info,
|
||||||
|
const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
gint status;
|
gint status;
|
||||||
char *cmdline, *escpath;
|
char *cmdline, *escpath;
|
||||||
|
@ -170,7 +155,7 @@ resolve_bookmark (const MuConfig *opts, GError **err)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar*
|
static Option<std::string>
|
||||||
get_query (const MuConfig *opts, GError **err)
|
get_query (const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
gchar *query, *bookmarkval;
|
gchar *query, *bookmarkval;
|
||||||
|
@ -179,14 +164,14 @@ get_query (const MuConfig *opts, GError **err)
|
||||||
if (!opts->bookmark && !opts->params[1]) {
|
if (!opts->bookmark && !opts->params[1]) {
|
||||||
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_IN_PARAMETERS,
|
g_set_error (err, MU_ERROR_DOMAIN, MU_ERROR_IN_PARAMETERS,
|
||||||
"error in parameters");
|
"error in parameters");
|
||||||
return NULL;
|
return Nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
bookmarkval = NULL;
|
bookmarkval = NULL;
|
||||||
if (opts->bookmark) {
|
if (opts->bookmark) {
|
||||||
bookmarkval = resolve_bookmark (opts, err);
|
bookmarkval = resolve_bookmark (opts, err);
|
||||||
if (!bookmarkval)
|
if (!bookmarkval)
|
||||||
return NULL;
|
return Nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
query = g_strjoinv (" ", &opts->params[1]);
|
query = g_strjoinv (" ", &opts->params[1]);
|
||||||
|
@ -199,7 +184,10 @@ get_query (const MuConfig *opts, GError **err)
|
||||||
|
|
||||||
g_free (bookmarkval);
|
g_free (bookmarkval);
|
||||||
|
|
||||||
return query;
|
std::string q{query};
|
||||||
|
g_free(query);
|
||||||
|
|
||||||
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Mu::Query
|
static Mu::Query
|
||||||
|
@ -239,10 +227,11 @@ prepare_links (const MuConfig *opts, GError **err)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static bool
|
||||||
output_link (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
output_link (MuMsg *msg, const OutputInfo& info,
|
||||||
|
const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
if (mu_msg_iter_is_first (iter) && !prepare_links (opts, err))
|
if (info.is_first && !prepare_links (opts, err))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return mu_maildir_link (mu_msg_get_path (msg),
|
return mu_maildir_link (mu_msg_get_path (msg),
|
||||||
|
@ -377,40 +366,27 @@ print_summary (MuMsg *msg, const MuConfig *opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
thread_indent (MuMsgIter *iter)
|
thread_indent (const QueryMatch& info)
|
||||||
{
|
{
|
||||||
const MuMsgIterThreadInfo *ti;
|
const auto is_root{any_of(info.flags & QueryMatch::Flags::Root)};
|
||||||
const char* threadpath;
|
const auto first_child{any_of(info.flags & QueryMatch::Flags::First)};
|
||||||
int i;
|
const auto last_child{any_of(info.flags & QueryMatch::Flags::Last)};
|
||||||
gboolean is_root, first_child, empty_parent, is_dup;
|
const auto empty_parent{any_of(info.flags & QueryMatch::Flags::Orphan)};
|
||||||
|
const auto is_dup{any_of(info.flags & QueryMatch::Flags::Duplicate)};
|
||||||
ti = mu_msg_iter_get_thread_info (iter);
|
const auto is_related{any_of(info.flags & QueryMatch::Flags::Related)};
|
||||||
if (!ti) {
|
|
||||||
g_printerr ("cannot get thread-info for message %u\n",
|
|
||||||
mu_msg_iter_get_docid (iter));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
threadpath = ti->threadpath;
|
|
||||||
/* fputs (threadpath, stdout); */
|
|
||||||
/* fputs (" ", stdout); */
|
|
||||||
|
|
||||||
is_root = ti->prop & MU_MSG_ITER_THREAD_PROP_ROOT;
|
|
||||||
first_child = ti->prop & MU_MSG_ITER_THREAD_PROP_FIRST_CHILD;
|
|
||||||
empty_parent = ti->prop & MU_MSG_ITER_THREAD_PROP_EMPTY_PARENT;
|
|
||||||
is_dup = ti->prop & MU_MSG_ITER_THREAD_PROP_DUP;
|
|
||||||
|
|
||||||
/* FIXME: count the colons... */
|
|
||||||
for (i = 0; *threadpath; ++threadpath)
|
|
||||||
i += (*threadpath == ':') ? 1 : 0;
|
|
||||||
|
|
||||||
/* indent */
|
/* indent */
|
||||||
while (i --> 0)
|
for (auto i = info.thread_level; i > 1; --i)
|
||||||
fputs (" ", stdout);
|
::fputs (" ", stdout);
|
||||||
|
|
||||||
if (!is_root) {
|
if (!is_root) {
|
||||||
fputs (first_child ? "`" : "|", stdout);
|
if (first_child)
|
||||||
fputs (empty_parent ? "*> " : is_dup ? "=> " : "-> ", stdout);
|
::fputs ("\\", stdout);
|
||||||
|
else if (last_child)
|
||||||
|
::fputs ("/", stdout);
|
||||||
|
else
|
||||||
|
::fputs (" ", stdout);
|
||||||
|
::fputs (empty_parent ? "*> " : is_dup ? "=> " : "-> ", stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,13 +422,16 @@ output_plain_fields (MuMsg *msg, const char *fields,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
output_plain (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
output_plain (MuMsg *msg, const OutputInfo& info, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
|
if (!msg)
|
||||||
|
return true;
|
||||||
|
|
||||||
/* we reuse the color (whatever that may be)
|
/* we reuse the color (whatever that may be)
|
||||||
* for message-priority for threads, too */
|
* for message-priority for threads, too */
|
||||||
ansi_color_maybe (MU_MSG_FIELD_ID_PRIO, !opts->nocolor);
|
ansi_color_maybe (MU_MSG_FIELD_ID_PRIO, !opts->nocolor);
|
||||||
if (opts->threads)
|
if (opts->threads && info.match_info)
|
||||||
thread_indent (iter);
|
thread_indent (*info.match_info);
|
||||||
|
|
||||||
output_plain_fields (msg, opts->fields, !opts->nocolor, opts->threads);
|
output_plain_fields (msg, opts->fields, !opts->nocolor, opts->threads);
|
||||||
|
|
||||||
|
@ -511,39 +490,32 @@ to_string (const Mu::Sexp& sexp, bool color, size_t level = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean
|
static bool
|
||||||
output_sexp (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
output_sexp (MuMsg *msg, const OutputInfo& info, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
const auto *ti{opts->threads ? mu_msg_iter_get_thread_info (iter) : NULL};
|
fputs(msg_to_sexp(msg, 0, {}, MU_MSG_OPTION_HEADERS_ONLY)
|
||||||
const auto sexp{Mu::msg_to_sexp(msg , mu_msg_iter_get_docid (iter), ti,
|
.to_sexp_string().c_str(), stdout);
|
||||||
MU_MSG_OPTION_HEADERS_ONLY)};
|
|
||||||
fputs (to_string(sexp, !opts->nocolor).c_str(), stdout);
|
|
||||||
fputs ("\n", stdout);
|
fputs ("\n", stdout);
|
||||||
|
return true;
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static bool
|
||||||
output_json (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
output_json (MuMsg *msg, const OutputInfo& info, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
const MuMsgIterThreadInfo *ti;
|
if (info.is_first) {
|
||||||
char *s;
|
|
||||||
|
|
||||||
if (mu_msg_iter_is_first(iter))
|
|
||||||
g_print ("[\n");
|
g_print ("[\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ti = opts->threads ? mu_msg_iter_get_thread_info (iter) : NULL;
|
if (info.is_last) {
|
||||||
s = mu_msg_to_json (msg, mu_msg_iter_get_docid (iter),
|
g_print("]\n");
|
||||||
ti, MU_MSG_OPTION_HEADERS_ONLY);
|
return true;
|
||||||
fputs (s, stdout);
|
}
|
||||||
g_free (s);
|
|
||||||
|
|
||||||
if (mu_msg_iter_is_last(iter))
|
g_print("%s\n", msg_to_sexp(msg, info.docid, {}, MU_MSG_OPTION_HEADERS_ONLY)
|
||||||
fputs("]\n", stdout);
|
.to_sexp_string().c_str());
|
||||||
else
|
|
||||||
fputs (",\n", stdout);
|
|
||||||
|
|
||||||
return TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -559,12 +531,18 @@ print_attr_xml (const char* elm, const char *str)
|
||||||
g_free (esc);
|
g_free (esc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static bool
|
||||||
output_xml (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
output_xml (MuMsg *msg, const OutputInfo& info, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
if (mu_msg_iter_is_first(iter)) {
|
if (info.is_first) {
|
||||||
g_print ("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
|
g_print ("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
|
||||||
g_print ("<messages>\n");
|
g_print ("<messages>\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.is_last) {
|
||||||
|
g_print ("</messages>\n");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_print ("\t<message>\n");
|
g_print ("\t<message>\n");
|
||||||
|
@ -580,13 +558,10 @@ output_xml (MuMsg *msg, MuMsgIter *iter, const MuConfig *opts, GError **err)
|
||||||
print_attr_xml ("maildir", mu_msg_get_maildir (msg));
|
print_attr_xml ("maildir", mu_msg_get_maildir (msg));
|
||||||
g_print ("\t</message>\n");
|
g_print ("\t</message>\n");
|
||||||
|
|
||||||
if (mu_msg_iter_is_last(iter))
|
return true;
|
||||||
g_print ("</messages>\n");
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static OutputFunc*
|
static OutputFunc
|
||||||
get_output_func (const MuConfig *opts, GError **err)
|
get_output_func (const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
switch (opts->format) {
|
switch (opts->format) {
|
||||||
|
@ -603,80 +578,68 @@ get_output_func (const MuConfig *opts, GError **err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static bool
|
||||||
output_query_results (MuMsgIter *iter, const MuConfig *opts, GError **err)
|
output_query_results (const QueryResults& qres, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
int count;
|
const auto output_func{get_output_func (opts, err)};
|
||||||
gboolean rv;
|
|
||||||
OutputFunc *output_func;
|
|
||||||
|
|
||||||
output_func = get_output_func (opts, err);
|
|
||||||
if (!output_func)
|
if (!output_func)
|
||||||
return FALSE;
|
return false;
|
||||||
|
|
||||||
for (count = 0, rv = TRUE; !mu_msg_iter_is_done(iter);
|
gboolean rv{true};
|
||||||
mu_msg_iter_next (iter)) {
|
output_func (NULL, FirstOutput, NULL, NULL);
|
||||||
|
|
||||||
MuMsg *msg;
|
for (auto&& item: qres) {
|
||||||
|
|
||||||
if (count == opts->maxnum)
|
auto msg{item.floating_msg()};
|
||||||
break;
|
|
||||||
msg = get_message (iter, opts->after);
|
|
||||||
if (!msg)
|
if (!msg)
|
||||||
break;
|
continue;
|
||||||
/* { */
|
|
||||||
/* const char* thread_id; */
|
|
||||||
/* thread_id = mu_msg_iter_get_thread_id (iter); */
|
|
||||||
/* g_print ("%s ", thread_id ? thread_id : "<none>"); */
|
|
||||||
|
|
||||||
/* } */
|
if (opts->after != 0 && mu_msg_get_timestamp(msg) < opts->after)
|
||||||
rv = output_func (msg, iter, opts, err);
|
continue;
|
||||||
|
|
||||||
|
rv = output_func (msg, {item.doc_id(), false, false, item.query_match()},
|
||||||
|
opts, err);
|
||||||
if (!rv)
|
if (!rv)
|
||||||
break;
|
break;
|
||||||
else
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rv && count == 0) {
|
|
||||||
mu_util_g_set_error (err, MU_ERROR_NO_MATCHES,
|
|
||||||
"no matches for search expression");
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
output_func (NULL, LastOutput, NULL, NULL);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
process_query (const Query& q, const gchar *expr, const MuConfig *opts, GError **err)
|
process_query (const Query& q, const std::string& expr, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
gboolean rv;
|
gboolean rv;
|
||||||
|
|
||||||
auto iter = run_query (q, expr, opts, err);
|
auto qres{run_query (q, expr, opts, err)};
|
||||||
if (!iter)
|
if (!qres)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
rv = output_query_results (iter, opts, err);
|
if (qres->empty()) {
|
||||||
mu_msg_iter_destroy (iter);
|
mu_util_g_set_error (err, MU_ERROR_NO_MATCHES,
|
||||||
|
"no matches for search expression");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return rv;
|
return output_query_results (*qres, opts, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
execute_find (const Store& store, const MuConfig *opts, GError **err)
|
execute_find (const Store& store, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
auto q{get_query_obj (store, err)};
|
auto q{get_query_obj (store, err)};
|
||||||
|
|
||||||
auto expr{get_query (opts, err)};
|
auto expr{get_query (opts, err)};
|
||||||
if (!expr)
|
if (!expr)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (opts->format == MU_CONFIG_FORMAT_XQUERY)
|
if (opts->format == MU_CONFIG_FORMAT_XQUERY)
|
||||||
return print_internal (q, expr, TRUE, FALSE, err);
|
return print_internal (q, *expr, TRUE, FALSE, err);
|
||||||
else if (opts->format == MU_CONFIG_FORMAT_MQUERY)
|
else if (opts->format == MU_CONFIG_FORMAT_MQUERY)
|
||||||
return print_internal (q, expr, FALSE,
|
return print_internal (q, *expr, FALSE,
|
||||||
opts->verbose, err);
|
opts->verbose, err);
|
||||||
else
|
else
|
||||||
return process_query (q, expr, opts, err);
|
return process_query (q, *expr, opts, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -742,7 +705,7 @@ query_params_valid (const MuConfig *opts, GError **err)
|
||||||
}
|
}
|
||||||
|
|
||||||
MuError
|
MuError
|
||||||
mu_cmd_find (const Store& store, const MuConfig *opts, GError **err)
|
Mu::mu_cmd_find (const Store& store, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
|
g_return_val_if_fail (opts, MU_ERROR_INTERNAL);
|
||||||
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_FIND,
|
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_FIND,
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "mu-msg.h"
|
#include "mu-msg.hh"
|
||||||
#include "index/mu-indexer.hh"
|
#include "index/mu-indexer.hh"
|
||||||
#include "mu-store.hh"
|
#include "mu-store.hh"
|
||||||
#include "mu-runtime.hh"
|
#include "mu-runtime.hh"
|
||||||
|
@ -81,7 +81,7 @@ print_stats (const Indexer::Progress& stats, bool color)
|
||||||
|
|
||||||
|
|
||||||
MuError
|
MuError
|
||||||
mu_cmd_index (Mu::Store& store, const MuConfig *opts, GError **err)
|
Mu::mu_cmd_index (Mu::Store& store, const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (opts, MU_ERROR);
|
g_return_val_if_fail (opts, MU_ERROR);
|
||||||
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_INDEX, MU_ERROR);
|
g_return_val_if_fail (opts->cmd == MU_CONFIG_CMD_INDEX, MU_ERROR);
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
|
|
||||||
#define COL(C) ((color)?C:"")
|
#define COL(C) ((color)?C:"")
|
||||||
|
|
||||||
|
using namespace Mu;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_script (const char *name, const char *oneline, const char *descr,
|
print_script (const char *name, const char *oneline, const char *descr,
|
||||||
gboolean color, gboolean verbose)
|
gboolean color, gboolean verbose)
|
||||||
|
@ -163,7 +165,7 @@ check_params (const MuConfig *opts, GError **err)
|
||||||
|
|
||||||
|
|
||||||
MuError
|
MuError
|
||||||
mu_cmd_script (const MuConfig *opts, GError **err)
|
Mu::mu_cmd_script (const MuConfig *opts, GError **err)
|
||||||
{
|
{
|
||||||
MuScriptInfo *msi;
|
MuScriptInfo *msi;
|
||||||
GSList *scripts;
|
GSList *scripts;
|
||||||
|
|
|
@ -88,7 +88,7 @@ output_sexp_stdout (Sexp&& sexp)
|
||||||
}
|
}
|
||||||
|
|
||||||
MuError
|
MuError
|
||||||
mu_cmd_server (const MuConfig *opts, GError **err) try {
|
Mu::mu_cmd_server (const MuConfig *opts, GError **err) try {
|
||||||
|
|
||||||
Store store{mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), false/*writable*/};
|
Store store{mu_runtime_path(MU_RUNTIME_PATH_XAPIANDB), false/*writable*/};
|
||||||
Server server{store, output_sexp_stdout};
|
Server server{store, output_sexp_stdout};
|
||||||
|
|
20
mu/mu-cmd.cc
20
mu/mu-cmd.cc
|
@ -29,13 +29,13 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
#include "mu-msg.h"
|
#include "mu-msg.hh"
|
||||||
#include "mu-msg-part.h"
|
#include "mu-msg-part.hh"
|
||||||
#include "mu-cmd.hh"
|
#include "mu-cmd.hh"
|
||||||
#include "mu-maildir.h"
|
#include "mu-maildir.hh"
|
||||||
#include "mu-contacts.hh"
|
#include "mu-contacts.hh"
|
||||||
#include "mu-runtime.hh"
|
#include "mu-runtime.hh"
|
||||||
#include "mu-flags.h"
|
#include "mu-flags.hh"
|
||||||
|
|
||||||
#include "utils/mu-util.h"
|
#include "utils/mu-util.h"
|
||||||
#include "utils/mu-str.h"
|
#include "utils/mu-str.h"
|
||||||
|
@ -45,15 +45,13 @@
|
||||||
|
|
||||||
#define VIEW_TERMINATOR '\f' /* form-feed */
|
#define VIEW_TERMINATOR '\f' /* form-feed */
|
||||||
|
|
||||||
|
using namespace Mu;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
view_msg_sexp (MuMsg *msg, const MuConfig *opts)
|
view_msg_sexp (MuMsg *msg, const MuConfig *opts)
|
||||||
{
|
{
|
||||||
char *sexp;
|
::fputs(msg_to_sexp(msg,0,{}, mu_config_get_msg_options(opts))
|
||||||
|
.to_sexp_string(). c_str(), stdout);
|
||||||
sexp = mu_msg_to_sexp (msg, 0, NULL, mu_config_get_msg_options(opts));
|
|
||||||
fputs (sexp, stdout);
|
|
||||||
g_free (sexp);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,7 +687,7 @@ check_params (const MuConfig *opts, GError **err)
|
||||||
}
|
}
|
||||||
|
|
||||||
MuError
|
MuError
|
||||||
mu_cmd_execute (const MuConfig *opts, GError **err) try
|
Mu::mu_cmd_execute (const MuConfig *opts, GError **err) try
|
||||||
{
|
{
|
||||||
MuError merr;
|
MuError merr;
|
||||||
|
|
||||||
|
|
10
mu/mu-cmd.hh
10
mu/mu-cmd.hh
|
@ -17,15 +17,14 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MU_CMD_H__
|
#ifndef MU_CMD_HH__
|
||||||
#define __MU_CMD_H__
|
#define MU_CMD_HH__
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <mu-config.hh>
|
#include <mu-config.hh>
|
||||||
#include <mu-store.hh>
|
#include <mu-store.hh>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
namespace Mu {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* execute the 'find' command
|
* execute the 'find' command
|
||||||
*
|
*
|
||||||
|
@ -107,6 +106,7 @@ MuError mu_cmd_index (Mu::Store& store, const MuConfig *opt, GError **err);
|
||||||
*/
|
*/
|
||||||
MuError mu_cmd_server (const MuConfig *opts, GError **err);
|
MuError mu_cmd_server (const MuConfig *opts, GError **err);
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
} // namespace Mu
|
||||||
|
|
||||||
#endif /*__MU_CMD_H__*/
|
#endif /*__MU_CMD_H__*/
|
||||||
|
|
|
@ -26,14 +26,13 @@
|
||||||
|
|
||||||
#include "mu-config.hh"
|
#include "mu-config.hh"
|
||||||
#include "mu-cmd.hh"
|
#include "mu-cmd.hh"
|
||||||
#include "mu-msg.h"
|
|
||||||
|
|
||||||
|
using namespace Mu;
|
||||||
|
|
||||||
static MuConfig MU_CONFIG;
|
static MuConfig MU_CONFIG;
|
||||||
|
|
||||||
#define color_maybe(C) (MU_CONFIG.nocolor ? "" : (C))
|
#define color_maybe(C) (MU_CONFIG.nocolor ? "" : (C))
|
||||||
|
|
||||||
|
|
||||||
static MuConfigFormat
|
static MuConfigFormat
|
||||||
get_output_format (const char *formatstr)
|
get_output_format (const char *formatstr)
|
||||||
{
|
{
|
||||||
|
@ -627,7 +626,7 @@ get_help_string (MuConfigCmd cmd, gboolean long_help)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mu_config_show_help (MuConfigCmd cmd)
|
Mu::mu_config_show_help (MuConfigCmd cmd)
|
||||||
{
|
{
|
||||||
GOptionContext *ctx;
|
GOptionContext *ctx;
|
||||||
GOptionGroup *group;
|
GOptionGroup *group;
|
||||||
|
@ -725,14 +724,12 @@ parse_params (int *argcp, char ***argvp, GError **err)
|
||||||
|
|
||||||
|
|
||||||
MuConfig*
|
MuConfig*
|
||||||
mu_config_init (int *argcp, char ***argvp, GError **err)
|
Mu::mu_config_init (int *argcp, char ***argvp, GError **err)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (argcp && argvp, NULL);
|
g_return_val_if_fail (argcp && argvp, NULL);
|
||||||
|
|
||||||
memset (&MU_CONFIG, 0, sizeof(MU_CONFIG));
|
memset (&MU_CONFIG, 0, sizeof(MU_CONFIG));
|
||||||
|
|
||||||
MU_CONFIG.maxnum = -1; /* By default, output all matching entries. */
|
|
||||||
|
|
||||||
if (!parse_cmd (argcp, argvp, err))
|
if (!parse_cmd (argcp, argvp, err))
|
||||||
goto errexit;
|
goto errexit;
|
||||||
|
|
||||||
|
@ -757,7 +754,7 @@ errexit:
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
mu_config_uninit (MuConfig *opts)
|
Mu::mu_config_uninit (MuConfig *opts)
|
||||||
{
|
{
|
||||||
if (!opts)
|
if (!opts)
|
||||||
return;
|
return;
|
||||||
|
@ -782,7 +779,7 @@ mu_config_uninit (MuConfig *opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
mu_config_param_num (const MuConfig *opts)
|
Mu::mu_config_param_num (const MuConfig *opts)
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
|
@ -794,7 +791,7 @@ mu_config_param_num (const MuConfig *opts)
|
||||||
|
|
||||||
|
|
||||||
MuMsgOptions
|
MuMsgOptions
|
||||||
mu_config_get_msg_options (const MuConfig *muopts)
|
Mu::mu_config_get_msg_options (const MuConfig *muopts)
|
||||||
{
|
{
|
||||||
int opts;
|
int opts;
|
||||||
|
|
||||||
|
|
|
@ -17,21 +17,20 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __MU_CONFIG_H__
|
#ifndef MU_CONFIG_HH__
|
||||||
#define __MU_CONFIG_H__
|
#define MU_CONFIG_HH__
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <sys/types.h> /* for mode_t */
|
#include <sys/types.h> /* for mode_t */
|
||||||
#include <mu-msg-fields.h>
|
#include <mu-msg-fields.h>
|
||||||
#include <mu-msg.h>
|
#include <mu-msg.hh>
|
||||||
#include <utils/mu-util.h>
|
#include <utils/mu-util.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
namespace Mu {
|
||||||
|
|
||||||
/* env var; if non-empty, color are disabled */
|
/* env var; if non-empty, color are disabled */
|
||||||
#define MU_NOCOLOR "MU_NOCOLOR"
|
#define MU_NOCOLOR "MU_NOCOLOR"
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MU_CONFIG_FORMAT_UNKNOWN = 0,
|
MU_CONFIG_FORMAT_UNKNOWN = 0,
|
||||||
|
|
||||||
|
@ -257,6 +256,6 @@ MuMsgOptions mu_config_get_msg_options (const MuConfig *opts);
|
||||||
*/
|
*/
|
||||||
void mu_config_show_help (const MuConfigCmd cmd);
|
void mu_config_show_help (const MuConfigCmd cmd);
|
||||||
|
|
||||||
G_END_DECLS
|
} // namespace Mu.
|
||||||
|
|
||||||
#endif /*__MU_CONFIG_H__*/
|
#endif /*__MU_CONFIG_H__*/
|
||||||
|
|
Loading…
Reference in New Issue