return NOTMUCH_STATUS_SUCCESS;
}
+static notmuch_status_t
+resolve_binding (notmuch_database_t *notmuch, const _sexp_binding_t *env, const char *name,
+ const _sexp_binding_t **out)
+{
+ for (; env; env = env->next) {
+ if (strcmp (name, env->name) == 0) {
+ *out = env;
+ return NOTMUCH_STATUS_SUCCESS;
+ }
+ }
+
+ _notmuch_database_log (notmuch, "undefined parameter '%s'\n", name);
+ return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
+}
+
+static notmuch_status_t
+_sexp_expand_term (notmuch_database_t *notmuch,
+ const _sexp_prefix_t *prefix,
+ const _sexp_binding_t *env,
+ const sexp_t *sx,
+ const char **out)
+{
+ notmuch_status_t status;
+
+ if (! out)
+ return NOTMUCH_STATUS_NULL_POINTER;
+
+ while (sx->ty == SEXP_VALUE && sx->aty == SEXP_BASIC && sx->val[0] == ',') {
+ const char *name = sx->val + 1;
+ const _sexp_binding_t *binding;
+
+ status = resolve_binding (notmuch, env, name, &binding);
+ if (status)
+ return status;
+
+ sx = binding->sx;
+ env = binding->context;
+ }
+
+ if (sx->ty != SEXP_VALUE) {
+ _notmuch_database_log (notmuch, "'%s' expects single atom as argument\n",
+ prefix->name);
+ return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
+ }
+
+ *out = sx->val;
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
static notmuch_status_t
_sexp_parse_wildcard (notmuch_database_t *notmuch,
const _sexp_prefix_t *parent,
notmuch_status_t
_sexp_parse_regex (notmuch_database_t *notmuch,
const _sexp_prefix_t *prefix, const _sexp_prefix_t *parent,
- unused(const _sexp_binding_t *env),
- std::string val, Xapian::Query &output)
+ const _sexp_binding_t *env,
+ const sexp_t *term, Xapian::Query &output)
{
if (! parent) {
_notmuch_database_log (notmuch, "illegal '%s' outside field\n",
}
std::string msg; /* ignored */
+ const char *str;
+ notmuch_status_t status;
+
+ status = _sexp_expand_term (notmuch, prefix, env, term, &str);
+ if (status)
+ return status;
return _notmuch_regexp_to_query (notmuch, Xapian::BAD_VALUENO, parent->name,
- val, output, msg);
+ str, output, msg);
}
const _sexp_binding_t *env, const char *name,
Xapian::Query &output)
{
- for (; env; env = env->next) {
- if (strcmp (name, env->name) == 0) {
- return _sexp_to_xapian_query (notmuch, parent, env->context, env->sx,
- output);
- }
- }
- _notmuch_database_log (notmuch, "undefined parameter %s\n", name);
- return NOTMUCH_STATUS_BAD_QUERY_SYNTAX;
+ notmuch_status_t status;
+
+ const _sexp_binding_t *binding;
+
+ status = resolve_binding (notmuch, env, name, &binding);
+ if (status)
+ return status;
+
+ return _sexp_to_xapian_query (notmuch, parent, binding->context, binding->sx,
+ output);
}
static notmuch_status_t
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, env, sx->list->next->val, output);
+ if (prefix->xapian_op == Xapian::Query::OP_WILDCARD) {
+ const char *str;
+ status = _sexp_expand_term (notmuch, prefix, env, sx->list->next, &str);
+ if (status)
+ return status;
+
+ return _sexp_parse_wildcard (notmuch, parent, env, str, output);
+ }
if (prefix->flags & SEXP_FLAG_DO_REGEX) {
- return _sexp_parse_regex (notmuch, prefix, parent, env, sx->list->next->val, output);
+ return _sexp_parse_regex (notmuch, prefix, parent, env, sx->list->next, output);
}
if (prefix->flags & SEXP_FLAG_DO_EXPAND) {