static w_query_expr *size_parser(w_query *query, json_t *term) { struct w_query_int_compare *comp; if (!json_is_array(term)) { ignore_result(asprintf(&query->errmsg, "Expected array for 'size' term")); return NULL; } comp = calloc(1, sizeof(*comp)); if (!comp) { ignore_result(asprintf(&query->errmsg, "out of memory")); return NULL; } if (!parse_int_compare(term, comp, &query->errmsg)) { free(comp); return NULL; } return w_query_expr_new(eval_size, free, comp); }
// ["dirname", "foo"] -> ["dirname", "foo", ["depth", "ge", 0]] static w_query_expr *dirname_parser_inner(w_query *query, json_t *term, bool caseless) { const char *which = caseless ? "idirname" : "dirname"; struct dirname_data *data; json_t *name; struct w_query_int_compare depth_comp; if (!json_is_array(term)) { ignore_result(asprintf(&query->errmsg, "Expected array for '%s' term", which)); return NULL; } if (json_array_size(term) < 2) { ignore_result(asprintf(&query->errmsg, "Invalid number of arguments for '%s' term", which)); return NULL; } if (json_array_size(term) > 3) { ignore_result(asprintf(&query->errmsg, "Invalid number of arguments for '%s' term", which)); return NULL; } name = json_array_get(term, 1); if (!json_is_string(name)) { ignore_result(asprintf(&query->errmsg, "Argument 2 to '%s' must be a string", which)); return NULL; } if (json_array_size(term) == 3) { json_t *depth; depth = json_array_get(term, 2); if (!json_is_array(depth)) { ignore_result(asprintf(&query->errmsg, "Invalid number of arguments for '%s' term", which)); return NULL; } if (!parse_int_compare(depth, &depth_comp, &query->errmsg)) { return NULL; } if (strcmp("depth", json_string_value(json_array_get(depth, 0)))) { ignore_result(asprintf(&query->errmsg, "Third parameter to '%s' should be a relational depth term", which)); return NULL; } } else { depth_comp.operand = 0; depth_comp.op = W_QUERY_ICMP_GE; } data = calloc(1, sizeof(*data)); if (!data) { ignore_result(asprintf(&query->errmsg, "out of memory")); return NULL; } data->dirname = w_string_new(json_string_value(name)); data->startswith = caseless ? w_string_startswith_caseless : w_string_startswith; data->depth = depth_comp; return w_query_expr_new(eval_dirname, dispose_dirname, data); }