Merge branch 'master' into procmule

This commit is contained in:
Dirk-Jan C. Binnema
2011-07-10 20:11:35 +03:00
23 changed files with 284 additions and 110 deletions

View File

@ -60,6 +60,7 @@ cc10:
line33: line33:
@$(PMCCABE) -c `find -name '*.c' -o -name '*.cc'` \ @$(PMCCABE) -c `find -name '*.c' -o -name '*.cc'` \
| grep -v mu-str-normalize.c \ | grep -v mu-str-normalize.c \
| grep -v config_options_group_find \
| grep -v tests \ | grep -v tests \
| awk '($$5 > 33)' | awk '($$5 > 33)'

View File

@ -149,6 +149,10 @@ AC_SUBST(XAPIAN_LIBS)
# also, this has nothing to do with Xapian's software version # also, this has nothing to do with Xapian's software version
AC_DEFINE(MU_XAPIAN_DB_VERSION,["9.7"], ['Schema' version of the database]) AC_DEFINE(MU_XAPIAN_DB_VERSION,["9.7"], ['Schema' version of the database])
#
# we need gtk (2 or 3) for some of the graphical tools
#
AC_ARG_WITH([gui], AC_ARG_WITH([gui],
[AS_HELP_STRING([--with-gui=gtk2|gtk3|none])], [AS_HELP_STRING([--with-gui=gtk2|gtk3|none])],
[gui=$withval],[gui=auto]) [gui=$withval],[gui=auto])
@ -175,7 +179,7 @@ AS_IF([test "x$gui" != "xnone" -a "x$have_gtk3" != "xyes"],[
gtk_version="`pkg-config --modversion gtk+-2.0`" gtk_version="`pkg-config --modversion gtk+-2.0`"
]) ])
# only an error if we explicitly asked for it # only an error if we explicitly asked for it
AS_IF([test "x$have_gtk2" = "xno" -a "x$gui" != "auto"], AS_IF([test "x$have_gtk2" = "xno" -a "x$gui" != "xauto"],
AC_MSG_ERROR([GTK+ 2.x not found])) AC_MSG_ERROR([GTK+ 2.x not found]))
AM_CONDITIONAL(HAVE_GTK,[test "x$have_gtk2" = "xyes" -o "x$have_gtk3" = "xyes" ]) AM_CONDITIONAL(HAVE_GTK,[test "x$have_gtk2" = "xyes" -o "x$have_gtk3" = "xyes" ])

View File

@ -1,4 +1,4 @@
.TH MU FIND 1 "June 2011" "User Manuals" .TH MU FIND 1 "July 2011" "User Manuals"
.SH NAME .SH NAME
@ -292,9 +292,6 @@ search parameters; the complete list:
s Message \fBs\fRubject s Message \fBs\fRubject
i Message-\fBi\fRd i Message-\fBi\fRd
m \fBm\fRaildir m \fBm\fRaildir
r \fBr\fReferences (message ids In-reply-to, References as
comma-separated list)
x \fBr\fTags (\fIX-Label\fR contents as comma-separated list)
.fi .fi
@ -377,6 +374,20 @@ Note: when \fBmu\fR creates a Maildir for these links, it automatically
inserts a \fI.noindex\fR file, to exclude the directory from \fBmu inserts a \fI.noindex\fR file, to exclude the directory from \fBmu
index\fR. index\fR.
.TP
\fB\-\-exec\fR=\fI<command>\fR
the \fB\-\-exec\fR command causes the \fIcommand\fR to be executed on each
matched message; for example, to see the raw text of all messages
matching 'milkshake', you could use:
.nf
$ mu find milkshake --exec='less'
.fi
which is roughly equivalent to:
.nf
$ mu find milkshake --fields="l" | xargs less
.fi
.TP .TP
\fB\-b\fR, \fB\-\-bookmark\fR=\fI<bookmark>\fR \fB\-b\fR, \fB\-\-bookmark\fR=\fI<bookmark>\fR
use a bookmarked search query. Using this option, a query from your bookmark use a bookmarked search query. Using this option, a query from your bookmark
@ -451,7 +462,6 @@ Find all unread messages with attachments:
.fi .fi
.SS Integrating mu find with mail clients .SS Integrating mu find with mail clients
.TP .TP

View File

@ -1,4 +1,4 @@
.TH MU VIEW 1 "May 2011" "User Manuals" .TH MU VIEW 1 "July 2011" "User Manuals"
.SH NAME .SH NAME
@ -25,10 +25,9 @@ any).
instead of displaying the full message, output a summary based upon the first instead of displaying the full message, output a summary based upon the first
lines of the message. lines of the message.
\fB\-\-separate\fR \fB\-\-terminate\fR
add an ascii \\014 (0x0c, or \fIform-feed\fR) between messages when displaying terminate messaages with a \\f (\fIform-feed\fR) characters when displaying
multiple messages. them. This is useful when you want to further process them.
.SH BUGS .SH BUGS

View File

@ -296,8 +296,6 @@ save_parts (const char *path, const char *filename, MuConfig *opts)
return rv; return rv;
} }
#define color_maybe(C) do{ if (color) fputs ((C),stdout);}while(0) #define color_maybe(C) do{ if (color) fputs ((C),stdout);}while(0)
static void static void

View File

@ -141,7 +141,7 @@ sort_field_from_string (const char* fieldstr)
static gboolean static gboolean
run_query_format (MuMsgIter *iter, MuConfig *opts, output_query_results (MuMsgIter *iter, MuConfig *opts,
OutputFormat format, size_t *count) OutputFormat format, size_t *count)
{ {
switch (format) { switch (format) {
@ -165,14 +165,12 @@ run_query_format (MuMsgIter *iter, MuConfig *opts,
} }
static gboolean static MuMsgIter*
run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, run_query (MuQuery *xapian, const gchar *query, MuConfig *opts, size_t *count)
OutputFormat format, size_t *count)
{ {
GError *err; GError *err;
MuMsgIter *iter; MuMsgIter *iter;
MuMsgFieldId sortid; MuMsgFieldId sortid;
gboolean rv;
sortid = MU_MSG_FIELD_ID_NONE; sortid = MU_MSG_FIELD_ID_NONE;
if (opts->sortfield) { if (opts->sortfield) {
@ -188,10 +186,25 @@ run_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
if (!iter) { if (!iter) {
g_warning ("error: %s", err->message); g_warning ("error: %s", err->message);
g_error_free (err); g_error_free (err);
return FALSE; return NULL;
} }
rv = run_query_format (iter, opts, format, count); return iter;
}
static gboolean
process_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
OutputFormat format, size_t *count)
{
MuMsgIter *iter;
gboolean rv;
iter = run_query (xapian, query, opts, count);
if (!iter)
return FALSE;
rv = output_query_results (iter, opts, format, count);
if (rv && count && *count == 0) if (rv && count && *count == 0)
g_warning ("no matching messages found"); g_warning ("no matching messages found");
@ -202,6 +215,66 @@ run_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
} }
static gboolean
exec_cmd (const char *path, const char *cmd)
{
gint status;
GError *err;
char *cmdline, *escpath;
gboolean rv;
if (access (path, R_OK) != 0) {
g_warning ("cannot read %s: %s", path, strerror(errno));
return FALSE;
}
escpath = g_strescape (path, NULL);
cmdline = g_strdup_printf ("%s %s", cmd, escpath);
err = NULL;
rv = g_spawn_command_line_sync (cmdline, NULL, NULL,
&status, &err);
g_free (cmdline);
g_free (escpath);
if (!rv) {
g_warning ("command returned %d on %s: %s\n",
status, path, err->message);
g_error_free (err);
return FALSE;
}
return TRUE;
}
static gboolean
exec_cmd_on_query (MuQuery *xapian, const gchar *query, MuConfig *opts,
size_t *count)
{
MuMsgIter *iter;
gboolean rv;
if (!(iter = run_query (xapian, query, opts, count)))
return FALSE;
for (rv = TRUE, *count = 0; !mu_msg_iter_is_done (iter); mu_msg_iter_next(iter)) {
rv = exec_cmd (mu_msg_get_path (mu_msg_iter_get_msg (iter, NULL)),
opts->exec);
if (rv)
++*count;
}
if (rv && count && *count == 0)
g_warning ("no matching messages found");
mu_msg_iter_destroy (iter);
return rv;
}
static gboolean static gboolean
format_params_valid (MuConfig *opts) format_params_valid (MuConfig *opts)
@ -489,8 +562,6 @@ ansi_reset_maybe (MuMsgFieldId mfid, gboolean color)
} }
static const char* static const char*
display_field (MuMsgIter *iter, MuMsgFieldId mfid) display_field (MuMsgIter *iter, MuMsgFieldId mfid)
{ {
@ -852,8 +923,10 @@ mu_cmd_find (MuConfig *opts)
if (format == FORMAT_XQUERY) if (format == FORMAT_XQUERY)
rv = print_xapian_query (xapian, query, &count); rv = print_xapian_query (xapian, query, &count);
else if (opts->exec)
rv = exec_cmd_on_query (xapian, query, opts, &count);
else else
rv = run_query (xapian, query, opts, format, &count); rv = process_query (xapian, query, opts, format, &count);
mu_query_destroy (xapian); mu_query_destroy (xapian);
g_free (query); g_free (query);

View File

@ -34,7 +34,7 @@
#include "mu-contacts.h" #include "mu-contacts.h"
#include "mu-runtime.h" #include "mu-runtime.h"
#define VIEW_SEPARATOR '\f' /* form-feed */ #define VIEW_TERMINATOR '\f' /* form-feed */
static void static void
@ -196,8 +196,8 @@ mu_cmd_view (MuConfig *opts)
if (rv != MU_EXITCODE_OK) if (rv != MU_EXITCODE_OK)
break; break;
/* add a separator between two messages? */ /* add a separator between two messages? */
if (opts->params[i+1] && opts->separate) if (opts->terminator)
g_print ("%c", VIEW_SEPARATOR); g_print ("%c", VIEW_TERMINATOR);
} }
return rv; return rv;

View File

@ -177,6 +177,8 @@ config_options_group_find (MuConfig *opts)
{"format", 'o', 0, G_OPTION_ARG_STRING, &opts->formatstr, {"format", 'o', 0, G_OPTION_ARG_STRING, &opts->formatstr,
"output format ('plain'(*), 'links', 'xml'," "output format ('plain'(*), 'links', 'xml',"
"'json', 'sexp', 'xquery')", NULL}, "'json', 'sexp', 'xquery')", NULL},
{"exec", 'e', 0, G_OPTION_ARG_STRING, &opts->exec,
"execute command on each match message", NULL},
{NULL, 0, 0, 0, NULL, NULL, NULL} {NULL, 0, 0, 0, NULL, NULL, NULL}
}; };
@ -243,8 +245,8 @@ config_options_group_view (MuConfig *opts)
GOptionEntry entries[] = { GOptionEntry entries[] = {
{"summary", 0, 0, G_OPTION_ARG_NONE, &opts->summary, {"summary", 0, 0, G_OPTION_ARG_NONE, &opts->summary,
"only show a short summary of the message (false)", NULL}, "only show a short summary of the message (false)", NULL},
{"separate", 0, 0, G_OPTION_ARG_NONE, &opts->separate, {"terminate", 0, 0, G_OPTION_ARG_NONE, &opts->terminator,
"separate messages with ascii-0x07 (form-feed)", NULL}, "terminate messages with ascii-0x07 (\\f, form-feed)", NULL},
{NULL, 0, 0, 0, NULL, NULL, NULL} {NULL, 0, 0, 0, NULL, NULL, NULL}
}; };

View File

@ -103,9 +103,12 @@ struct _MuConfig {
char *bookmark; /* use bookmark */ char *bookmark; /* use bookmark */
char *formatstr; /* output type char *formatstr; /* output type
* (plain,links,xml,json,sexp) */ * (plain,links,xml,json,sexp) */
char *exec; /* command to execute on the
* files for the matched
* messages */
/* options for view */ /* options for view */
gboolean separate; /* add separator between gboolean terminator; /* add separator \f between
* multiple messages in mu * multiple messages in mu
* view */ * view */

View File

@ -92,7 +92,7 @@ mu_msg_doc_get_str_list_field (MuMsgDoc *self, MuMsgFieldId mfid,
try { try {
/* return a comma-separated string as a GSList */ /* return a comma-separated string as a GSList */
const std::string s (self->doc().get_value(mfid)); const std::string s (self->doc().get_value(mfid));
return s.empty() ? NULL : mu_str_to_list(s.c_str(),','); return s.empty() ? NULL : mu_str_to_list(s.c_str(),',',TRUE);
} MU_XAPIAN_CATCH_BLOCK_RETURN(NULL); } MU_XAPIAN_CATCH_BLOCK_RETURN(NULL);
} }

View File

@ -204,16 +204,15 @@ static const MuMsgField FIELD_DATA[] = {
MU_MSG_FIELD_ID_REFS, MU_MSG_FIELD_ID_REFS,
MU_MSG_FIELD_TYPE_STRING_LIST, MU_MSG_FIELD_TYPE_STRING_LIST,
NULL, 'r', 'R', NULL, 'r', 'R',
FLAG_GMIME | FLAG_XAPIAN_VALUE | FLAG_GMIME | FLAG_XAPIAN_VALUE | FLAG_XAPIAN_PREFIX_ONLY
FLAG_XAPIAN_PREFIX_ONLY
}, },
{ {
MU_MSG_FIELD_ID_TAGS, MU_MSG_FIELD_ID_TAGS,
MU_MSG_FIELD_TYPE_STRING_LIST, MU_MSG_FIELD_TYPE_STRING_LIST,
"tag", 'x', 'X', "tag", 'x', 'X',
FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_VALUE | FLAG_GMIME | FLAG_XAPIAN_TERM | FLAG_XAPIAN_PREFIX_ONLY |
FLAG_XAPIAN_PREFIX_ONLY FLAG_NORMALIZE | FLAG_XAPIAN_ESCAPE
} }
}; };

View File

@ -715,7 +715,7 @@ get_tags (MuMsgFile *self)
obj = GMIME_OBJECT(self->_mime_msg); obj = GMIME_OBJECT(self->_mime_msg);
return mu_str_to_list (g_mime_object_get_header return mu_str_to_list (g_mime_object_get_header
(obj, "X-Label"), ','); (obj, "X-Label"), ',', TRUE);
} }

View File

@ -376,34 +376,6 @@ add_terms_values_str (Xapian::Document& doc, char *val,
} }
static void
add_terms_values_string_list (Xapian::Document& doc, MuMsg *msg,
MuMsgFieldId mfid)
{
const GSList *lst;
lst = mu_msg_get_field_string_list (msg, mfid);
if (lst && mu_msg_field_xapian_value (mfid)) {
gchar *str;
str = mu_str_from_list (lst, ',');
if (str)
doc.add_value ((Xapian::valueno)mfid, str);
g_free (str);
}
if (lst && mu_msg_field_xapian_term (mfid)) {
while (lst) {
doc.add_term (prefix(mfid) +
std::string((char*)lst->data, 0,
MU_STORE_MAX_TERM_LENGTH));
lst = g_slist_next ((GSList*)lst);
}
}
}
static void static void
add_terms_values_string (Xapian::Document& doc, MuMsg *msg, add_terms_values_string (Xapian::Document& doc, MuMsg *msg,
MuMsgFieldId mfid) MuMsgFieldId mfid)
@ -426,6 +398,47 @@ add_terms_values_string (Xapian::Document& doc, MuMsg *msg,
g_free (val); g_free (val);
} }
static void
add_terms_values_string_list (Xapian::Document& doc, MuMsg *msg,
MuMsgFieldId mfid)
{
const GSList *lst;
lst = mu_msg_get_field_string_list (msg, mfid);
if (lst && mu_msg_field_xapian_value (mfid)) {
gchar *str;
str = mu_str_from_list (lst, ',');
if (str)
doc.add_value ((Xapian::valueno)mfid, str);
g_free (str);
}
if (lst && mu_msg_field_xapian_term (mfid)) {
while (lst) {
size_t len;
char *val;
/* try stack-allocation, it's much faster*/
len = strlen ((char*)lst->data);
if (G_LIKELY(len < 1024))
val = (char*)g_alloca(len+1);
else
val = (char*)g_malloc(len+1);
strcpy (val, (char*)lst->data);
add_terms_values_str (doc, val, mfid);
if (!(G_LIKELY(len < 1024)))
g_free (val);
lst = g_slist_next ((GSList*)lst);
}
}
}
struct PartData { struct PartData {
PartData (Xapian::Document& doc, MuMsgFieldId mfid): PartData (Xapian::Document& doc, MuMsgFieldId mfid):
_doc (doc), _mfid(mfid) {} _doc (doc), _mfid(mfid) {}

View File

@ -399,7 +399,7 @@ mu_str_from_list (const GSList *lst, char sepa)
} }
GSList* GSList*
mu_str_to_list (const char *str, char sepa) mu_str_to_list (const char *str, char sepa, gboolean strip)
{ {
GSList *lst; GSList *lst;
gchar **strs, **cur; gchar **strs, **cur;
@ -413,8 +413,14 @@ mu_str_to_list (const char *str, char sepa)
sep[0] = sepa; sep[0] = sepa;
strs = g_strsplit (str, sep, -1); strs = g_strsplit (str, sep, -1);
for (cur = strs, lst = NULL; cur && *cur; ++cur) for (cur = strs, lst = NULL; cur && *cur; ++cur) {
lst = g_slist_prepend (lst, g_strdup(*cur)); char *elm;
elm = g_strdup(*cur);
if (strip)
elm = g_strstrip (elm);
lst = g_slist_prepend (lst, elm);
}
lst = g_slist_reverse (lst); lst = g_slist_reverse (lst);
g_strfreev (strs); g_strfreev (strs);

View File

@ -277,14 +277,15 @@ char* mu_str_from_list (const GSList *lst, char sepa);
/** /**
* convert a #sepa-separated list of strings in to a GSList * convert a #se0pa-separated list of strings in to a GSList
* *
* @param str a #sepa-separated list of strings * @param str a #sepa-separated list of strings
* @param the separator character * @param the separator character
* @param remove leading/trailing whitespace from the string
* *
* @return a newly allocated GSList (free with mu_str_free_list) * @return a newly allocated GSList (free with mu_str_free_list)
*/ */
GSList* mu_str_to_list (const char *str, char sepa); GSList* mu_str_to_list (const char *str, char sepa, gboolean strip);
/** /**

View File

@ -124,6 +124,7 @@ EXTRA_DIST= \
testdir2/bar/cur/mail4 \ testdir2/bar/cur/mail4 \
testdir2/bar/cur/mail5 \ testdir2/bar/cur/mail5 \
testdir2/bar/cur/181736.eml \ testdir2/bar/cur/181736.eml \
testdir2/bar/cur/mail6 \
testdir2/bar/tmp/.noindex \ testdir2/bar/tmp/.noindex \
testdir2/bar/new/.noindex \ testdir2/bar/new/.noindex \
testdir2/Foo/cur/mail5 \ testdir2/Foo/cur/mail5 \

View File

@ -115,7 +115,7 @@ test_mu_index (void)
store = mu_store_new (xpath, NULL, NULL); store = mu_store_new (xpath, NULL, NULL);
g_assert (store); g_assert (store);
g_assert_cmpuint (mu_store_count (store), ==, 8); g_assert_cmpuint (mu_store_count (store), ==, 9);
mu_store_destroy (store); mu_store_destroy (store);
g_free (muhome); g_free (muhome);
@ -498,7 +498,7 @@ test_mu_view_multi_separate (void)
tmpdir = test_mu_common_get_random_tmpdir(); tmpdir = test_mu_common_get_random_tmpdir();
g_assert (g_mkdir_with_parents (tmpdir, 0700) == 0); g_assert (g_mkdir_with_parents (tmpdir, 0700) == 0);
cmdline = g_strdup_printf ("%s view --separate --muhome=%s " cmdline = g_strdup_printf ("%s view --terminate --muhome=%s "
"%s%cbar%ccur%cmail5 " "%s%cbar%ccur%cmail5 "
"%s%cbar%ccur%cmail5", "%s%cbar%ccur%cmail5",
MU_PROGRAM, MU_PROGRAM,
@ -517,8 +517,7 @@ test_mu_view_multi_separate (void)
len = strlen(output); len = strlen(output);
/* g_print ("\n[%s](%u)\n", output, len); */ /* g_print ("\n[%s](%u)\n", output, len); */
g_assert_cmpuint (len,==,165); g_assert_cmpuint (len,==,166);
g_free (output); g_free (output);
g_free (cmdline); g_free (cmdline);

View File

@ -321,8 +321,8 @@ test_mu_msg_tags (void)
==, 1217530645); ==, 1217530645);
tags = mu_msg_get_tags (msg); tags = mu_msg_get_tags (msg);
g_assert_cmpstr ((char*)tags->data,==,"paradise"); g_assert_cmpstr ((char*)tags->data,==,"Paradise");
g_assert_cmpstr ((char*)tags->next->data,==,"lost"); g_assert_cmpstr ((char*)tags->next->data,==,"losT");
g_assert (tags->next->next == NULL); g_assert (tags->next->next == NULL);
mu_msg_unref (msg); mu_msg_unref (msg);

View File

@ -87,7 +87,6 @@ run_and_count_matches (const char *xpath, const char *query)
MuQuery *mquery; MuQuery *mquery;
MuMsgIter *iter; MuMsgIter *iter;
guint count1, count2; guint count1, count2;
GHashTable *hash;
mquery = mu_query_new (xpath, NULL); mquery = mu_query_new (xpath, NULL);
g_assert (query); g_assert (query);
@ -107,9 +106,6 @@ run_and_count_matches (const char *xpath, const char *query)
mu_query_destroy (mquery); mu_query_destroy (mquery);
g_assert (iter); g_assert (iter);
hash = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify)g_free, NULL);
assert_no_dups (iter); assert_no_dups (iter);
/* run query twice, to test mu_msg_iter_reset */ /* run query twice, to test mu_msg_iter_reset */
@ -450,6 +446,34 @@ test_mu_query_tags (void)
} }
static void
test_mu_query_tags_02 (void)
{
gchar *xpath;
int i;
QResults queries[] = {
{ "x:paradise", 1},
{ "tag:@NextActions", 1},
{ "x:queensrÿche", 1},
{ "tag:lost OR tag:operation:mindcrime", 2},
};
xpath = fill_database (MU_TESTMAILDIR2);
g_assert (xpath != NULL);
/* g_print ("(%s)\n", xpath); */
for (i = 0; i != G_N_ELEMENTS(queries); ++i) {
/* g_print ("%s\n", queries[i].query); */
g_assert_cmpuint (run_and_count_matches (xpath, queries[i].query),
==, queries[i].count);
}
g_free (xpath);
}
int int
@ -476,10 +500,12 @@ main (int argc, char *argv[])
test_mu_query_attach); test_mu_query_attach);
g_test_add_func ("/mu-query/test-mu-query-tags", g_test_add_func ("/mu-query/test-mu-query-tags",
test_mu_query_tags); test_mu_query_tags);
g_test_add_func ("/mu-query/test-mu-query-tags_02",
test_mu_query_tags_02);
/* g_log_set_handler (NULL, */ g_log_set_handler (NULL,
/* G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION, */ G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION,
/* (GLogFunc)black_hole, NULL); */ (GLogFunc)black_hole, NULL);
rv = g_test_run (); rv = g_test_run ();

View File

@ -324,18 +324,30 @@ test_mu_str_to_list (void)
{ {
{ {
const char *items[]= {"foo", "bar ", "cuux", NULL}; const char *items[]= {"foo", "bar ", "cuux", NULL};
GSList *lst = mu_str_to_list ("foo@bar@cuux",'@'); GSList *lst = mu_str_to_list ("foo@bar @cuux",'@', FALSE);
assert_cmplst (lst, items); assert_cmplst (lst, items);
mu_str_free_list (lst); mu_str_free_list (lst);
} }
{ {
GSList *lst = mu_str_to_list (NULL,'x'); GSList *lst = mu_str_to_list (NULL,'x',FALSE);
g_assert (lst == NULL); g_assert (lst == NULL);
mu_str_free_list (lst); mu_str_free_list (lst);
} }
} }
static void
test_mu_str_to_list_strip (void)
{
{
const char *items[]= {"foo", "bar", "cuux", NULL};
GSList *lst = mu_str_to_list ("foo@bar @cuux",'@', TRUE);
assert_cmplst (lst, items);
mu_str_free_list (lst);
}
}
static void static void
@ -474,6 +486,8 @@ main (int argc, char *argv[])
test_mu_str_from_list); test_mu_str_from_list);
g_test_add_func ("/mu-str/mu-str-to-list", g_test_add_func ("/mu-str/mu-str-to-list",
test_mu_str_to_list); test_mu_str_to_list);
g_test_add_func ("/mu-str/mu-str-to-list-strip",
test_mu_str_to_list_strip);
g_test_add_func ("/mu-str/mu_str_date_parse_hdwmy", g_test_add_func ("/mu-str/mu_str_date_parse_hdwmy",
test_mu_str_date_parse_hdwmy); test_mu_str_date_parse_hdwmy);

View File

@ -4,7 +4,7 @@ Subject: Fere libenter homines id quod volunt credunt
To: "Julius Caesar" <jc@example.com> To: "Julius Caesar" <jc@example.com>
Message-id: <3BE9E6535E3029448670913581E7A1A20D852173@emss35m06.us.lmco.com> Message-id: <3BE9E6535E3029448670913581E7A1A20D852173@emss35m06.us.lmco.com>
MIME-version: 1.0 MIME-version: 1.0
x-label: paradise,lost x-label: Paradise, losT
Content-type: text/plain; charset=us-ascii Content-type: text/plain; charset=us-ascii
Content-transfer-encoding: 7BIT Content-transfer-encoding: 7BIT
Precedence: high Precedence: high

View File

@ -0,0 +1,18 @@
Date: Thu, 31 Jul 2008 14:57:25 -0400
From: "Geoff Tate" <jeff@example.com>
Subject: eyes of a stranger
To: "Enrico Fermi" <enrico@example.com>
Message-id: <3BE9E6535E302944823E7A1A20D852173@msg.id>
MIME-version: 1.0
X-label: @NextActions, operation:mindcrime, Queensrÿche
Content-type: text/plain; charset=us-ascii
Content-transfer-encoding: 7BIT
Precedence: high
And I raise my head and stare
Into the eyes of a stranger
I've always known that the mirror never lies
People always turn away
From the eyes of a stranger
Afraid to know what
Lies behind the stare

View File

@ -32,11 +32,16 @@ If =mu= did not guess the right Maildir, you can set it explicitly:
#+html:<pre> $ mu find to:Jack subject:jellyfish tumbleweed</pre> #+html:<pre> $ mu find to:Jack subject:jellyfish tumbleweed</pre>
*** messages between 2 kilobytes and a 2Mb, written in December 2009 with an attachment from Bill *** messages between 2 kilobytes and a 2Mb, written in December 2009 with an attachment from Bill
#+html: $ mu find size:2k..2m date:20091201..20093112 flag:attach from:bill #+html:<pre> $ mu find size:2k..2m date:20091201..20093112 flag:attach from:bill</pre>
*** unread messages about soccer or socrates or ... *** signed messages about apples *OR* oranges
#+html:<pre> $ mu find flag:signed apples OR oranges</pre>
*** unread messages about things starting with 'soc' (soccer, society, socrates, ...)
#+html:<pre> $ mu find 'subject:soc*' flag:unread</pre> #+html:<pre> $ mu find 'subject:soc*' flag:unread</pre>
(search using the '*' wildcard is available since mu 0.9.6)
** Finding contacts ** Finding contacts
Contacts (names + email addresses) are cached separately, and can be Contacts (names + email addresses) are cached separately, and can be
@ -87,6 +92,20 @@ If =mu= did not guess the right Maildir, you can set it explicitly:
(since =mu= version 0.9.6) (since =mu= version 0.9.6)
** Integration with mail clients
The =mu-find= man page contains examples for =mutt= and =wanderlust=.
** Viewing messages
You can view message contents with =mu view=; it does not use the database
and simply takes a message file as it's argument:
#+html:<pre> $ mu view ~/Maildir/inbox/cur/message24</pre>
You can also use =--color= to get colorized output, and =--summary= to get a
summary of the message contents instead of the whole thing.
** Further processing of matched messages ** Further processing of matched messages
If you need to process the results of your queries with some other program, If you need to process the results of your queries with some other program,
@ -107,19 +126,7 @@ If =mu= did not guess the right Maildir, you can set it explicitly:
will give you a list of pancake-related messages in XML-format. will give you a list of pancake-related messages in XML-format.
** Integration with mail clients
The =mu-find= man page contains examples for =mutt= and =wanderlust=.
** Viewing messages
You can view message contents with =mu view=; it does not use the database
and simply takes a message file as it's argument:
#+html:<pre> $ mu view ~/Maildir/inbox/cur/message24</pre>
You can also use =--color= to get colorized output, and =--summary= to get a
summary of the message contents instead of the whole thing.
#+html:<hr/><div align="center">&copy; 2011 Dirk-Jan C. Binnema</div> #+html:<hr/><div align="center">&copy; 2011 Dirk-Jan C. Binnema</div>
#+begin_html #+begin_html