unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
blob 9dbeaf119a4c3ab0dd0bd1780082b0891c24b897 14453 bytes (raw)
name: lib/parse-sexp.cc 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
 
#include "database-private.h"
#include "sexp.h"
#include "unicode-util.h"

#if HAVE_SFSEXP

/* _sexp is used for file scope symbols to avoid clashing with
 * definitions from sexp.h */

typedef enum {
    SEXP_FLAG_NONE	= 0,
    SEXP_FLAG_FIELD	= 1 << 0,
    SEXP_FLAG_BOOLEAN	= 1 << 1,
    SEXP_FLAG_SINGLE	= 1 << 2,
    SEXP_FLAG_WILDCARD	= 1 << 3,
    SEXP_FLAG_REGEX	= 1 << 4,
    SEXP_FLAG_DO_REGEX	= 1 << 5,
    SEXP_FLAG_EXPAND	= 1 << 6,
    SEXP_FLAG_DO_EXPAND = 1 << 7,
    SEXP_FLAG_ORPHAN	= 1 << 8,
} _sexp_flag_t;

/*
 * define bitwise operators to hide casts */

inline _sexp_flag_t
operator| (_sexp_flag_t a, _sexp_flag_t b)
{
    return static_cast<_sexp_flag_t>(
	static_cast<unsigned>(a) | static_cast<unsigned>(b));
}

inline _sexp_flag_t
operator& (_sexp_flag_t a, _sexp_flag_t b)
{
    return static_cast<_sexp_flag_t>(
	static_cast<unsigned>(a) & static_cast<unsigned>(b));
}

typedef struct  {
    const char *name;
    Xapian::Query::op xapian_op;
    Xapian::Query initial;
    _sexp_flag_t flags;
} _sexp_prefix_t;

static _sexp_prefix_t prefixes[] =
{
    { "and",            Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_NONE },
    { "attachment",     Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_FIELD | SEXP_FLAG_WILDCARD | SEXP_FLAG_EXPAND },
    { "body",           Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_FIELD },
    { "from",           Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_FIELD | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND },
    { "folder",         Xapian::Query::OP_OR,           Xapian::Query::MatchNothing,
      SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND },
    { "id",             Xapian::Query::OP_OR,           Xapian::Query::MatchNothing,
      SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX },
    { "infix",          Xapian::Query::OP_INVALID,      Xapian::Query::MatchAll,
      SEXP_FLAG_SINGLE | SEXP_FLAG_ORPHAN },
    { "is",             Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND },
    { "matching",       Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_DO_EXPAND },
    { "mid",            Xapian::Query::OP_OR,           Xapian::Query::MatchNothing,
      SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX },
    { "mimetype",       Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_FIELD | SEXP_FLAG_WILDCARD | SEXP_FLAG_EXPAND },
    { "not",            Xapian::Query::OP_AND_NOT,      Xapian::Query::MatchAll,
      SEXP_FLAG_NONE },
    { "of",             Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_DO_EXPAND },
    { "or",             Xapian::Query::OP_OR,           Xapian::Query::MatchNothing,
      SEXP_FLAG_NONE },
    { "path",           Xapian::Query::OP_OR,           Xapian::Query::MatchNothing,
      SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX },
    { "property",       Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND },
    { "query",          Xapian::Query::OP_INVALID,      Xapian::Query::MatchNothing,
      SEXP_FLAG_SINGLE | SEXP_FLAG_ORPHAN },
    { "regex",          Xapian::Query::OP_INVALID,      Xapian::Query::MatchAll,
      SEXP_FLAG_SINGLE | SEXP_FLAG_DO_REGEX },
    { "rx",             Xapian::Query::OP_INVALID,      Xapian::Query::MatchAll,
      SEXP_FLAG_SINGLE | SEXP_FLAG_DO_REGEX },
    { "starts-with",    Xapian::Query::OP_WILDCARD,     Xapian::Query::MatchAll,
      SEXP_FLAG_SINGLE },
    { "subject",        Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_FIELD | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND },
    { "tag",            Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND },
    { "thread",         Xapian::Query::OP_OR,           Xapian::Query::MatchNothing,
      SEXP_FLAG_FIELD | SEXP_FLAG_BOOLEAN | SEXP_FLAG_WILDCARD | SEXP_FLAG_REGEX | SEXP_FLAG_EXPAND },
    { "to",             Xapian::Query::OP_AND,          Xapian::Query::MatchAll,
      SEXP_FLAG_FIELD | SEXP_FLAG_WILDCARD | SEXP_FLAG_EXPAND },
    { }
};

static notmuch_status_t _sexp_to_xapian_query (notmuch_database_t *notmuch,
					       const _sexp_prefix_t *parent,
					       const sexp_t *sx,
					       Xapian::Query &output);

static notmuch_status_t
_sexp_combine_query (notmuch_database_t *notmuch,
		     const _sexp_prefix_t *parent,
		     Xapian::Query::op operation,
		     Xapian::Query left,
		     const sexp_t *sx,
		     Xapian::Query &output)
{
    Xapian::Query subquery;

    notmuch_status_t status;

    /* if we run out elements, return accumulator */

    if (! sx) {
	output = left;
	return NOTMUCH_STATUS_SUCCESS;
    }

    status = _sexp_to_xapian_query (notmuch, parent, sx, subquery);
    if (status)
	return status;

    return _sexp_combine_query (notmuch,
				parent,
				operation,
				Xapian::Query (operation, left, subquery),
				sx->next, output);
}

static notmuch_status_t
_sexp_parse_phrase (std::string term_prefix, const char *phrase, Xapian::Query &output)
{
    Xapian::Utf8Iterator p (phrase);
    Xapian::Utf8Iterator end;
    std::vector<std::string> terms;

    while (p != end) {
	Xapian::Utf8Iterator start;
	while (p != end && ! Xapian::Unicode::is_wordchar (*p))
	    p++;

	if (p == end)
	    break;

	start = p;

	while (p != end && Xapian::Unicode::is_wordchar (*p))
	    p++;

	if (p != start) {
	    std::string word (start, p);
	    word = Xapian::Unicode::tolower (word);
	    terms.push_back (term_prefix + word);
	}
    }
    output = Xapian::Query (Xapian::Query::OP_PHRASE, terms.begin (), terms.end ());
    return NOTMUCH_STATUS_SUCCESS;
}

static notmuch_status_t
_sexp_parse_wildcard (notmuch_database_t *notmuch,
		      const _sexp_prefix_t *parent,
		      std::string match,
		      Xapian::Query &output)
{

    std::string term_prefix = parent ? _notmuch_database_prefix (notmuch, parent->name) : "";

    if (parent && ! (parent->flags & SEXP_FLAG_WILDCARD)) {
	_notmuch_database_log (notmuch, "'%s' does not support wildcard queries\n", parent->name);
	return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
    }

    output = Xapian::Query (Xapian::Query::OP_WILDCARD,
			    term_prefix + Xapian::Unicode::tolower (match));
    return NOTMUCH_STATUS_SUCCESS;
}

static notmuch_status_t
_sexp_parse_one_term (notmuch_database_t *notmuch, std::string term_prefix, const sexp_t *sx,
		      Xapian::Query &output)
{
    Xapian::Stem stem = *(notmuch->stemmer);

    if (sx->aty == SEXP_BASIC && unicode_word_utf8 (sx->val)) {
	std::string term = Xapian::Unicode::tolower (sx->val);

	output = Xapian::Query ("Z" + term_prefix + stem (term));
	return NOTMUCH_STATUS_SUCCESS;
    } else {
	return _sexp_parse_phrase (term_prefix, sx->val, output);
    }

}

notmuch_status_t
_sexp_parse_regex (notmuch_database_t *notmuch,
		   const _sexp_prefix_t *prefix, const _sexp_prefix_t *parent,
		   std::string val, Xapian::Query &output)
{
    if (! parent) {
	_notmuch_database_log (notmuch, "illegal '%s' outside field\n",
			       prefix->name);
	return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
    }

    if (! (parent->flags & SEXP_FLAG_REGEX)) {
	_notmuch_database_log (notmuch, "'%s' not supported in field '%s'\n",
			       prefix->name, parent->name);
	return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
    }

    std::string msg; /* ignored */

    return _notmuch_regexp_to_query (notmuch, Xapian::BAD_VALUENO, parent->name,
				     val, output, msg);
}


static notmuch_status_t
_sexp_expand_query (notmuch_database_t *notmuch,
		    const _sexp_prefix_t *prefix, const _sexp_prefix_t *parent,
		    const sexp_t *sx, Xapian::Query &output)
{
    Xapian::Query subquery;
    notmuch_status_t status;
    std::string msg;

    if (! (parent->flags & SEXP_FLAG_EXPAND)) {
	_notmuch_database_log (notmuch, "'%s' unsupported inside '%s'\n", prefix->name, parent->name);
	return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
    }

    status = _sexp_combine_query (notmuch, NULL, prefix->xapian_op, prefix->initial, sx, subquery);
    if (status)
	return status;

    status = _notmuch_query_expand (notmuch, parent->name, subquery, output, msg);
    if (status) {
	_notmuch_database_log (notmuch, "error expanding query %s\n", msg.c_str ());
    }
    return status;
}

static notmuch_status_t
_sexp_parse_infix (notmuch_database_t *notmuch, const sexp_t *sx, Xapian::Query &output)
{
    try {
	output = notmuch->query_parser->parse_query (sx->val, NOTMUCH_QUERY_PARSER_FLAGS);
    } catch (const Xapian::QueryParserError &error) {
	_notmuch_database_log (notmuch, "Syntax error in infix query: %s\n", sx->val);
	return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
    } catch (const Xapian::Error &error) {
	if (! notmuch->exception_reported) {
	    _notmuch_database_log (notmuch,
				   "A Xapian exception occurred parsing query: %s\n",
				   error.get_msg ().c_str ());
	    _notmuch_database_log_append (notmuch,
					  "Query string was: %s\n",
					  sx->val);
	    notmuch->exception_reported = true;
	    return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
	}
    }
    return NOTMUCH_STATUS_SUCCESS;
}

static notmuch_status_t
_sexp_parse_header (notmuch_database_t *notmuch, const _sexp_prefix_t *parent,
		    const sexp_t *sx, Xapian::Query &output)
{
    _sexp_prefix_t user_prefix;

    user_prefix.name = sx->list->val;
    user_prefix.flags = SEXP_FLAG_FIELD | SEXP_FLAG_WILDCARD;

    if (parent) {
	_notmuch_database_log (notmuch, "nested field: '%s' inside '%s'\n",
			       sx->list->val, parent->name);
	return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
    }

    parent = &user_prefix;

    return _sexp_combine_query (notmuch, parent, Xapian::Query::OP_AND, Xapian::Query::MatchAll,
				sx->list->next, output);
}

/* Here we expect the s-expression to be a proper list, with first
 * element defining and operation, or as a special case the empty
 * list */

static notmuch_status_t
_sexp_to_xapian_query (notmuch_database_t *notmuch, const _sexp_prefix_t *parent, const sexp_t *sx,
		       Xapian::Query &output)
{
    if (sx->ty == SEXP_VALUE) {
	std::string term_prefix = parent ? _notmuch_database_prefix (notmuch, parent->name) : "";

	if (sx->aty == SEXP_BASIC && strcmp (sx->val, "*") == 0) {
	    return _sexp_parse_wildcard (notmuch, parent, "", output);
	}

	if (parent && (parent->flags & SEXP_FLAG_BOOLEAN)) {
	    output = Xapian::Query (term_prefix + sx->val);
	    return NOTMUCH_STATUS_SUCCESS;
	}

	if (parent) {
	    return _sexp_parse_one_term (notmuch, term_prefix, sx, output);
	} else {
	    Xapian::Query accumulator;
	    for (_sexp_prefix_t *prefix = prefixes; prefix->name; prefix++) {
		if (prefix->flags & SEXP_FLAG_FIELD) {
		    notmuch_status_t status;
		    Xapian::Query subquery;
		    term_prefix = _notmuch_database_prefix (notmuch, prefix->name);
		    status = _sexp_parse_one_term (notmuch, term_prefix, sx, subquery);
		    if (status)
			return status;
		    accumulator = Xapian::Query (Xapian::Query::OP_OR, accumulator, subquery);
		}
	    }
	    output = accumulator;
	    return NOTMUCH_STATUS_SUCCESS;
	}
    }

    /* Empty list */
    if (! sx->list) {
	output = Xapian::Query::MatchAll;
	return NOTMUCH_STATUS_SUCCESS;
    }

    if (sx->list->ty == SEXP_LIST) {
	_notmuch_database_log (notmuch, "unexpected list in field/operation position\n",
			       sx->list->val);
	return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
    }

    /* Check for user defined field */
    if (_notmuch_string_map_get (notmuch->user_prefix, sx->list->val)) {
	return _sexp_parse_header (notmuch, parent, sx, output);
    }

    for (_sexp_prefix_t *prefix = prefixes; prefix && prefix->name; prefix++) {
	if (strcmp (prefix->name, sx->list->val) == 0) {
	    if (prefix->flags & SEXP_FLAG_FIELD) {
		if (parent) {
		    _notmuch_database_log (notmuch, "nested field: '%s' inside '%s'\n",
					   prefix->name, parent->name);
		    return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
		}
		parent = prefix;
	    }

	    if (parent && (prefix->flags & SEXP_FLAG_ORPHAN)) {
		_notmuch_database_log (notmuch, "'%s' not supported inside '%s'\n",
				       prefix->name, parent->name);
		return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
	    }

	    if ((prefix->flags & SEXP_FLAG_SINGLE) &&
		(! sx->list->next || sx->list->next->next || sx->list->next->ty != SEXP_VALUE)) {
		_notmuch_database_log (notmuch, "'%s' expects single atom as argument\n",
				       prefix->name);
		return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
	    }

	    if (strcmp (prefix->name, "infix") == 0) {
		return _sexp_parse_infix (notmuch, sx->list->next, output);
	    }

	    if (strcmp (prefix->name, "query") == 0) {
		return _notmuch_query_name_to_query (notmuch, sx->list->next->val, output);
	    }

	    if (prefix->xapian_op == Xapian::Query::OP_WILDCARD)
		return _sexp_parse_wildcard (notmuch, parent, sx->list->next->val, output);

	    if (prefix->flags & SEXP_FLAG_DO_REGEX) {
		return _sexp_parse_regex (notmuch, prefix, parent, sx->list->next->val, output);
	    }

	    if (prefix->flags & SEXP_FLAG_DO_EXPAND) {
		return _sexp_expand_query (notmuch, prefix, parent, sx->list->next, output);
	    }

	    return _sexp_combine_query (notmuch, parent, prefix->xapian_op, prefix->initial,
					sx->list->next, output);
	}
    }

    _notmuch_database_log (notmuch, "unknown prefix '%s'\n", sx->list->val);
    return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
}

notmuch_status_t
_notmuch_sexp_string_to_xapian_query (notmuch_database_t *notmuch, const char *querystr,
				      Xapian::Query &output)
{
    const sexp_t *sx = NULL;
    char *buf = talloc_strdup (notmuch, querystr);

    sx = parse_sexp (buf, strlen (querystr));
    if (! sx) {
	_notmuch_database_log (notmuch, "invalid s-expression: '%s'\n", querystr);
	return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
    }

    return _sexp_to_xapian_query (notmuch, NULL, sx, output);
}
#endif

debug log:

solving e582e350 ...
found e582e350 in https://yhetil.org/notmuch/20210812170728.1348333-28-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-28-david@tethera.net/
found a1783f86 in https://yhetil.org/notmuch/20210812170728.1348333-26-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-26-david@tethera.net/
found 61dd8f7d in https://yhetil.org/notmuch/20210812170728.1348333-25-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-25-david@tethera.net/
found 3c99a7e0 in https://yhetil.org/notmuch/20210812170728.1348333-24-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-24-david@tethera.net/
found f48c94be in https://yhetil.org/notmuch/20210812170728.1348333-23-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-23-david@tethera.net/
found 48728edb in https://yhetil.org/notmuch/20210812170728.1348333-20-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-20-david@tethera.net/
found 56bd7e4b in https://yhetil.org/notmuch/20210812170728.1348333-17-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-17-david@tethera.net/
found caffbe59 in https://yhetil.org/notmuch/20210730125607.2165433-16-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210812170728.1348333-16-david@tethera.net/
found d717efc5 in https://yhetil.org/notmuch/20210812170728.1348333-15-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-15-david@tethera.net/
found 9727c57d in https://yhetil.org/notmuch/20210812170728.1348333-14-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-14-david@tethera.net/
found 4adfc4c5 in https://yhetil.org/notmuch/20210812170728.1348333-13-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-13-david@tethera.net/
found a5d41f30 in https://yhetil.org/notmuch/20210730125607.2165433-11-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210812170728.1348333-11-david@tethera.net/
found 97bfecbd in https://yhetil.org/notmuch/20210812170728.1348333-10-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-10-david@tethera.net/
found 1be5e209 in https://yhetil.org/notmuch/20210812170728.1348333-9-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-9-david@tethera.net/
found 1ce3c9d4 in https://yhetil.org/notmuch/20210812170728.1348333-7-david@tethera.net/ ||
	https://yhetil.org/notmuch/20210730125607.2165433-7-david@tethera.net/

applying [1/15] https://yhetil.org/notmuch/20210812170728.1348333-7-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
new file mode 100644
index 00000000..1ce3c9d4

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-7-david@tethera.net/ for 1ce3c9d4
index at:
100644 1ce3c9d42e8ce614ed481153018d744f276290ca	lib/parse-sexp.cc

applying [2/15] https://yhetil.org/notmuch/20210812170728.1348333-9-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
index 1ce3c9d4..1be5e209 100644

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-9-david@tethera.net/ for 1be5e209
index at:
100644 1be5e209576bdda3dc32ff030fa510f404aeb511	lib/parse-sexp.cc

applying [3/15] https://yhetil.org/notmuch/20210812170728.1348333-10-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc\r
index 1be5e209..97bfecbd 100644\r

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-10-david@tethera.net/ for 97bfecbd
index at:
100644 e9fb556ba685e3edb864c7a3bf5f2304abfa8b76	lib/parse-sexp.cc

applying [4/15] https://yhetil.org/notmuch/20210730125607.2165433-11-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc\r
index 97bfecbd..a5d41f30 100644\r

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210812170728.1348333-11-david@tethera.net/ for a5d41f30
index at:
100644 01ccb60e1217c2f8d814d7f57b6e395e1b41e72d	lib/parse-sexp.cc

applying [5/15] https://yhetil.org/notmuch/20210812170728.1348333-13-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc\r
index a5d41f30..4adfc4c5 100644\r

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-13-david@tethera.net/ for 4adfc4c5
index at:
100644 87e66817e681558400ad80797dac82d4d610d4b0	lib/parse-sexp.cc

applying [6/15] https://yhetil.org/notmuch/20210812170728.1348333-14-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc\r
index 4adfc4c5..9727c57d 100644\r

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-14-david@tethera.net/ for 9727c57d
index at:
100644 030d93de07100ee3acd8c16158c6c72145fcf477	lib/parse-sexp.cc

applying [7/15] https://yhetil.org/notmuch/20210812170728.1348333-15-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
index 9727c57d..d717efc5 100644

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-15-david@tethera.net/ for d717efc5
index at:
100644 95cb12c932ca27c8d9ca9abdbaef195b05e9965a	lib/parse-sexp.cc

applying [8/15] https://yhetil.org/notmuch/20210730125607.2165433-16-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
index d717efc5..caffbe59 100644

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210812170728.1348333-16-david@tethera.net/ for caffbe59
index at:
100644 8219ffa4f4b7ffb2802190271fedc143b7b6785f	lib/parse-sexp.cc

applying [9/15] https://yhetil.org/notmuch/20210812170728.1348333-17-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc\r
index caffbe59..56bd7e4b 100644\r

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-17-david@tethera.net/ for 56bd7e4b
index at:
100644 05db236e15c1dc69be1505ed0899747f39e6024a	lib/parse-sexp.cc

applying [10/15] https://yhetil.org/notmuch/20210812170728.1348333-20-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
index 56bd7e4b..48728edb 100644

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-20-david@tethera.net/ for 48728edb
index at:
100644 6a6cd6a24649666ba7e443f19e96f9e7835bc682	lib/parse-sexp.cc

applying [11/15] https://yhetil.org/notmuch/20210812170728.1348333-23-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
index 48728edb..f48c94be 100644

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-23-david@tethera.net/ for f48c94be
index at:
100644 245424d1d5640e01b64f316fe31048c287fb64b6	lib/parse-sexp.cc

applying [12/15] https://yhetil.org/notmuch/20210812170728.1348333-24-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
index f48c94be..3c99a7e0 100644

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-24-david@tethera.net/ for 3c99a7e0
index at:
100644 0243ba3825245a2be6673865864d6a6c181e406e	lib/parse-sexp.cc

applying [13/15] https://yhetil.org/notmuch/20210812170728.1348333-25-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
index 3c99a7e0..61dd8f7d 100644

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-25-david@tethera.net/ for 61dd8f7d
index at:
100644 cdf16377e5cf992c6286b25e74c30963a4584d13	lib/parse-sexp.cc

applying [14/15] https://yhetil.org/notmuch/20210812170728.1348333-26-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc
index 61dd8f7d..a1783f86 100644

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-26-david@tethera.net/ for a1783f86
index at:
100644 b94680301333c5befd952e1b9b3e7290eeda8de0	lib/parse-sexp.cc

applying [15/15] https://yhetil.org/notmuch/20210812170728.1348333-28-david@tethera.net/
diff --git a/lib/parse-sexp.cc b/lib/parse-sexp.cc\r
index a1783f86..e582e350 100644\r

Checking patch lib/parse-sexp.cc...
Applied patch lib/parse-sexp.cc cleanly.

skipping https://yhetil.org/notmuch/20210730125607.2165433-28-david@tethera.net/ for e582e350
index at:
100644 9dbeaf119a4c3ab0dd0bd1780082b0891c24b897	lib/parse-sexp.cc

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).