aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2017-06-30 13:28:05 +0200
committerLeah Neukirchen <leah@vuxu.org>2017-06-30 13:28:05 +0200
commit841984f6453b351efec3953c5b53fc56a6b1d91c (patch)
treea51d98ffa1e00cd8b06ebe678471e02e2a83115b
parentef08f99d234da21d0f27dc9c7ca175e2ba3f2588 (diff)
downloadmblaze-841984f6453b351efec3953c5b53fc56a6b1d91c.tar.gz
mthread: add optional message support
-rw-r--r--man/mthread.110
-rw-r--r--mthread.c36
2 files changed, 43 insertions, 3 deletions
diff --git a/man/mthread.1 b/man/mthread.1
index d4fd69f..6ff3495 100644
--- a/man/mthread.1
+++ b/man/mthread.1
@@ -7,6 +7,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl v
+.Op Fl S Ar msg
.Op Ar msgs\ ...
.Sh DESCRIPTION
.Nm
@@ -30,6 +31,15 @@ The options are as follows:
.Bl -tag -width Ds
.It Fl v
Do not prune unresolved Message-IDs at the top-level.
+.It Fl S Ar msg
+Treat
+.Ar msg
+as optional message(s) that will be added to threads only in case they
+are referenced.
+Threads where all messages are optional are suppressed.
+You can use
+.Fl S
+to add outbox folders and complete threads where your replies were missing.
.El
.Sh EXIT STATUS
.Ex -std
diff --git a/mthread.c b/mthread.c
index b54b714..f275826 100644
--- a/mthread.c
+++ b/mthread.c
@@ -21,6 +21,7 @@
#include "blaze822.h"
static int vflag;
+static int optional;
struct container {
char *mid;
@@ -30,6 +31,7 @@ struct container {
struct container *parent;
struct container *child;
struct container *next;
+ int optional;
};
static void *mids;
@@ -80,6 +82,7 @@ midcont(char *mid)
c->file = 0;
c->msg = 0;
c->date = -1;
+ c->optional = 0;
c->parent = c->child = c->next = 0;
return *(struct container **)tsearch(c, &mids, midorder);
} else {
@@ -95,6 +98,7 @@ store_id(char *file, struct message *msg)
c = midcont(mid(msg));
c->file = strdup(file);
c->msg = msg;
+ c->optional = optional;
return c;
}
@@ -279,6 +283,7 @@ find_roots()
top->date = -1;
top->file = 0;
top->next = top->child = top->parent = 0;
+ top->optional = 0;
top->mid = "(top)";
lastc = top;
@@ -301,11 +306,25 @@ prune_tree(struct container *c, int depth)
c->file = c->child->file;
c->msg = c->child->msg;
c->date = c->child->date;
+ c->optional = c->child->optional;
c->child = c->child->child;
}
} while ((c = c->next));
}
+int
+alloptional(struct container *c)
+{
+ do {
+ if (!c->optional && c->file)
+ return 0;
+ if (c->child && !alloptional(c->child))
+ return 0;
+ } while ((c = c->next));
+
+ return 1;
+}
+
static int
dateorder(const void *a, const void *b)
{
@@ -328,7 +347,7 @@ sort_tree(struct container *c, int depth)
for (r = c->child, i = 0; r; r = r->next, i++)
sort_tree(r, depth+1);
- if (i == 1) // no sort needed
+ if (i == 1) // no sort needed
return;
struct container **a = calloc(sizeof (struct container *), i);
@@ -353,6 +372,12 @@ void
print_tree(struct container *c, int depth)
{
do {
+ // skip toplevel threads when they are unresolved or all optional
+ if (depth <= 1 &&
+ (c->optional || !c->file) &&
+ (!c->child || alloptional(c->child)))
+ continue;
+
if (depth >= 0) {
int i;
for (i = 0; i < depth; i++)
@@ -373,14 +398,19 @@ main(int argc, char *argv[])
{
int c, i;
- while ((c = getopt(argc, argv, "v")) != -1)
+ optional = 1;
+
+ while ((c = getopt(argc, argv, "S:v")) != -1)
switch(c) {
+ case 'S': blaze822_loop1(optarg, thread); break;
case 'v': vflag = 1; break;
default:
- fprintf(stderr, "Usage: mthread [-v] [msgs...]\n");
+ fprintf(stderr, "Usage: mthread [-v] [-S dir] [msgs...]\n");
exit(1);
}
+ optional = 0;
+
if (argc == optind && isatty(0))
i = blaze822_loop1(":", thread);
else