aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2016-08-05 20:05:24 +0200
committerChristian Neukirchen <chneukirchen@gmail.com>2016-08-05 20:05:24 +0200
commit1d67157f0901bcb8eaeaa3c70c7d9204e3ceb6a1 (patch)
treeb50348493b3a3393054a5aa9ebedecbf561a4374
parent516c3ec6f26e59efe174e1d73afbf82d653efa89 (diff)
downloadmblaze-1d67157f0901bcb8eaeaa3c70c7d9204e3ceb6a1.tar.gz
seq: add thread selectors
-rw-r--r--man/mmsg.723
-rw-r--r--seq.c129
2 files changed, 145 insertions, 7 deletions
diff --git a/man/mmsg.7 b/man/mmsg.7
index e903aa4..f792bac 100644
--- a/man/mmsg.7
+++ b/man/mmsg.7
@@ -8,6 +8,7 @@
This manpage documents the message syntax used
by the tools
.Xr maddr 1 ,
+.Xr magrep 1 ,
.Xr mflag 1 ,
.Xr mhdr 1 ,
.Xr mless 1 ,
@@ -31,7 +32,7 @@ to all messages in the
directory.
.Pp
Sequences have the format
-.Sq Ar start Ns Li \&: Ns Ar stop ,
+.Sq Ar start Ns Cm ":" Ns Ar stop ,
where
.Ar start
and
@@ -49,14 +50,28 @@ is the empty string,
.Li \&-1
will be used instead.
Thus,
-.Sq Li \&:
+.Sq Cm ":"
represents the whole sequence.
If the sequence does not contain a
-.Sq Li \&: ,
+.Sq Cm ":" ,
it is considered to be a single message, equivalent to the range
-.Sq Ar start Ns Li \&: Ns Ar start
+.Sq Ar start Ns Cm ":" Ns Ar start
of size one.
.Pp
+If the sequence is threaded, the following
+syntax may be used:
+.Sq Ar msg Ns Cm "="
+refers to the whole thread that contains
+.Ar msg .
+.Sq Ar msg Ns Cm "^"
+refers to the parent of the message
+.Ar msg
+and may be repeated to refer to grand-parents.
+.Sq Ar msg Ns Cm "_"
+refers to the subthread headed by
+.Ar msg
+(i.e. all messages below with more indentation).
+.Pp
There are four special shortcuts:
.Bl -tag -width 3n
.It Sq Li \&.
diff --git a/seq.c b/seq.c
index fd541b3..de1d24c 100644
--- a/seq.c
+++ b/seq.c
@@ -203,16 +203,135 @@ parse_relnum(char *a, long cur, long last, long *out)
}
static int
-parse_range(char *a, long *start, long *stop, long cur, long lines)
+parse_thread(char *map, long a, long *starto, long *stopo)
+{
+ char *s, *t;
+ long line;
+
+ long start = 0, stop = 0, state = 0;
+
+ for (s = map, line = 0; s; s = t+1) {
+ t = strchr(s, '\n');
+ if (!t)
+ break;
+ line++;
+ if (!iswsp(*s)) {
+ if (state == 0) {
+ start = line;
+ } else if (state == 1) {
+ stop = line - 1;
+ state = 2;
+ break;
+ }
+ }
+ if (line == a)
+ state = 1;
+ while (*s && iswsp(*s))
+ s++;
+ }
+
+ if (state == 1) {
+ stop = line;
+ state = 2;
+ }
+ if (state == 2) {
+ *starto = start;
+ *stopo = stop;
+ return 1;
+ }
+ return 0;
+}
+
+static int
+parse_subthread(char *map, long a, long *stopo)
+{
+ char *s, *t;
+ long line;
+
+ long stop = 0;
+ int minindent = -1;
+
+ for (s = map, line = 0; s; s = t+1) {
+ t = strchr(s, '\n');
+ if (!t)
+ break;
+ line++;
+ int indent = 0;
+ while (*s && iswsp(*s)) {
+ s++;
+ indent++;
+ }
+ if (line == a)
+ minindent = indent;
+ if (line > a && indent <= minindent) {
+ stop = line - 1;
+ break;
+ }
+ }
+
+ if (line < a)
+ return 0;
+
+ if (minindent == -1)
+ stop = line;
+
+ *stopo = stop;
+
+ return 1;
+}
+
+static int
+parse_parent(char *map, long *starto, long *stopo)
+{
+ char *s, *t;
+ long line;
+
+ int previndent[32] = { 0 };
+
+ for (s = map, line = 0; s; s = t+1) {
+ t = strchr(s, '\n');
+ if (!t)
+ break;
+ line++;
+ int indent = 0;
+ while (*s && iswsp(*s)) {
+ s++;
+ indent++;
+ }
+ if (indent > 31)
+ indent = 31;
+ previndent[indent] = line;
+ if (line == *starto) {
+ if (previndent[indent-1]) {
+ *starto = *stopo = previndent[indent-1];
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int
+parse_range(char *map, char *a, long *start, long *stop, long cur, long lines)
{
*start = *stop = 1;
- while (*a && *a != ':') {
+ while (*a && *a != ':' && *a != '=' && *a != '_' && *a != '^') {
char *b = parse_relnum(a, cur, lines, start);
if (a == b)
return 0;
a = b;
}
+
+ while (*a == '^') {
+ a++;
+ if (!parse_parent(map, start, stop))
+ return 0;
+ }
+
if (*a == ':') {
a++;
if (!*a) {
@@ -222,6 +341,10 @@ parse_range(char *a, long *start, long *stop, long cur, long lines)
if (a == b)
return 0;
}
+ } else if (*a == '=') {
+ return parse_thread(map, *start, start, stop);
+ } else if (*a == '_') {
+ return parse_subthread(map, *start, stop);
} else if (!*a) {
*stop = *start;
} else {
@@ -279,7 +402,7 @@ blaze822_seq_next(char *map, char *range, struct blaze822_seq_iter *iter)
find_cur(map, iter);
if (!iter->start) {
- if (!parse_range(range, &iter->start, &iter->stop,
+ if (!parse_range(map, range, &iter->start, &iter->stop,
iter->cur, iter->lines)) {
fprintf(stderr, "can't parse range: %s\n", range);
return 0;