static bool eval_not(struct w_query_ctx *ctx, struct watchman_file *file, void *data) { w_query_expr *expr = data; return !w_query_expr_evaluate(expr, ctx, file); }
static bool eval_list(struct w_query_ctx *ctx, struct watchman_file *file, void *data) { struct w_expr_list *list = data; size_t i; for (i = 0; i < list->num; i++) { bool res = w_query_expr_evaluate( list->exprs[i], ctx, file); if (!res && list->allof) { return false; } if (res && !list->allof) { return true; } } return list->allof; }
bool w_query_process_file( w_query *query, struct w_query_ctx *ctx, struct watchman_file *file) { struct watchman_rule_match *m; if (ctx->wholename) { w_string_delref(ctx->wholename); ctx->wholename = NULL; } ctx->file = file; // For fresh instances, only return files that currently exist. if (!ctx->since.is_timestamp && ctx->since.clock.is_fresh_instance && !file->exists) { return true; } // We produce an output for this file if there is no expression, // or if the expression matched. if (query->expr && !w_query_expr_evaluate(query->expr, ctx, file)) { // No matched return true; } // Need more room? if (ctx->num_results + 1 > ctx->num_allocd) { uint32_t new_num = ctx->num_allocd ? ctx->num_allocd * 2 : 64; struct watchman_rule_match *res; res = realloc(ctx->results, new_num * sizeof(*res)); if (!res) { w_log(W_LOG_ERR, "out of memory while capturing matches!\n"); return false; } ctx->results = res; ctx->num_allocd = new_num; } m = &ctx->results[ctx->num_results++]; m->root_number = ctx->root->number; m->relname = w_query_ctx_get_wholename(ctx); if (!m->relname) { w_log(W_LOG_ERR, "out of memory while capturing matches!\n"); return false; } w_string_addref(m->relname); m->file = file; if (ctx->since.is_timestamp) { m->is_new = w_timeval_compare(ctx->since.timestamp, file->ctime.tv) > 0; } else if (ctx->since.clock.is_fresh_instance) { m->is_new = true; } else { m->is_new = file->ctime.ticks > ctx->since.clock.ticks; } return true; }