X-Git-Url: https://git.librecmc.org/?p=oweals%2Fjsonpath.git;a=blobdiff_plain;f=matcher.c;h=d2a8767c7ca399a204e0c52dcc4b69d6885c8880;hp=85bd1c5a97833950ceacf4cfb0b18da11a19052f;hb=c7e938d6582a436dddc938539e72dd1320625c54;hpb=cd6629fc75787cbfcbec12282bd738373bc46ac6 diff --git a/matcher.c b/matcher.c index 85bd1c5..d2a8767 100644 --- a/matcher.c +++ b/matcher.c @@ -17,6 +17,7 @@ #include "parser.h" #include "matcher.h" + static struct json_object * jp_match_next(struct jp_opcode *ptr, struct json_object *root, struct json_object *cur, @@ -130,6 +131,99 @@ jp_cmp(struct jp_opcode *op, struct json_object *root, struct json_object *cur) } } +static bool +jp_regmatch(struct jp_opcode *op, struct json_object *root, struct json_object *cur) +{ + struct jp_opcode left, right; + char lbuf[22], rbuf[22], *lval, *rval; + int err, rflags = REG_NOSUB | REG_NEWLINE; + regex_t preg; + + + if (!jp_resolve(root, cur, op->down, &left) || + !jp_resolve(root, cur, op->down->sibling, &right)) + return false; + + if (left.type == T_REGEXP) + { + switch (right.type) + { + case T_BOOL: + lval = right.num ? "true" : "false"; + break; + + case T_NUMBER: + snprintf(lbuf, sizeof(lbuf), "%d", right.num); + lval = lbuf; + break; + + case T_STRING: + lval = right.str; + break; + + default: + return false; + } + + rval = left.str; + rflags = left.num; + } + else + { + switch (left.type) + { + case T_BOOL: + lval = left.num ? "true" : "false"; + break; + + case T_NUMBER: + snprintf(lbuf, sizeof(lbuf), "%d", left.num); + lval = lbuf; + break; + + case T_STRING: + lval = left.str; + break; + + default: + return false; + } + + switch (right.type) + { + case T_BOOL: + rval = right.num ? "true" : "false"; + break; + + case T_NUMBER: + snprintf(rbuf, sizeof(rbuf), "%d", right.num); + rval = rbuf; + break; + + case T_STRING: + rval = right.str; + break; + + case T_REGEXP: + rval = right.str; + rflags = right.num; + break; + + default: + return false; + } + } + + if (regcomp(&preg, rval, rflags)) + return false; + + err = regexec(&preg, lval, 0, NULL, 0); + + regfree(&preg); + + return err ? false : true; +} + static bool jp_expr(struct jp_opcode *op, struct json_object *root, struct json_object *cur, int idx, const char *key, jp_match_cb_t cb, void *priv) @@ -149,6 +243,9 @@ jp_expr(struct jp_opcode *op, struct json_object *root, struct json_object *cur, case T_GE: return jp_cmp(op, root, cur); + case T_MATCH: + return jp_regmatch(op, root, cur); + case T_ROOT: return !!jp_match(op, root, NULL, NULL);