case F_EXPR_NEG:
n->right = right;
break;
-
}
return (struct filter_node *) n;
}
if (!rc)
rc = cast_node(fltr, ln, type, n->right, &r);
if (!rc)
- rc = filter_compare_params(fltr, ln, oper, l, r, status);
+ rc = filter_compare_params(fltr, oper, l, r, status);
filter_unref_node((struct filter_node *) l);
filter_unref_node((struct filter_node *) r);
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <regex.h>
#include "smartcolsP.h"
struct list_head pr_params;
struct libscols_column *col;
char *holder_name;
+ regex_t *re;
unsigned int has_value :1;
};
return (struct filter_node *) n;
}
+int filter_compile_param(struct libscols_filter *fltr, struct filter_param *n)
+{
+ int rc;
+
+ if (n->re)
+ return 0;
+ if (!n->val.str)
+ return -EINVAL;
+
+ n->re = calloc(1, sizeof(regex_t));
+ if (!n->re)
+ return -ENOMEM;
+
+ rc = regcomp(n->re, n->val.str, REG_NOSUB | REG_EXTENDED);
+ if (rc) {
+ size_t size = regerror(rc, n->re, NULL, 0);
+
+ fltr->errmsg = malloc(size + 1);
+ if (!fltr->errmsg)
+ return -ENOMEM;
+ regerror(rc, n->re, fltr->errmsg, size);
+ return -EINVAL;
+ }
+ return 0;
+}
+
static struct filter_param *copy_param(struct filter_param *n)
{
return (struct filter_param *) filter_new_param(NULL,
memset(&n->val, 0, sizeof(n->val));
n->has_value = 0;
-}
+ if (n->re) {
+ regfree(n->re);
+ free(n->re);
+ }
+}
void filter_free_param(struct filter_param *n)
{
case F_EXPR_GT:
*status = xstrcmp(l->val.str, r->val.str) > 0;
break;
+ case F_EXPR_REG:
+ if (!r->re)
+ return -EINVAL;
+ *status = regexec(r->re, l->val.str ? : "", 0, NULL, 0) == 0;
+ break;
+ case F_EXPR_NREG:
+ if (!r->re)
+ return -EINVAL;
+ *status = regexec(r->re, l->val.str ? : "", 0, NULL, 0) != 0;
+ break;
default:
return -EINVAL;
}
/* call filter_cast_param() to be sure that param data are ready (fetched from
* holder, etc.) */
int filter_compare_params(struct libscols_filter *fltr __attribute__((__unused__)),
- struct libscols_line *ln __attribute__((__unused__)),
enum filter_etype oper,
struct filter_param *l,
struct filter_param *r,
| expr T_LT expr { $$ = filter_new_expr(fltr, F_EXPR_LT, $1, $3); }
| expr T_GE expr { $$ = filter_new_expr(fltr, F_EXPR_GE, $1, $3); }
| expr T_GT expr { $$ = filter_new_expr(fltr, F_EXPR_GT, $1, $3); }
- | expr T_REG expr { $$ = filter_new_expr(fltr, F_EXPR_REG, $1, $3); }
- | expr T_NREG expr { $$ = filter_new_expr(fltr, F_EXPR_NREG, $1, $3); }
+
+ | expr T_REG expr {
+ if (filter_compile_param(fltr, (struct filter_param *) $3) != 0)
+ YYERROR;
+ $$ = filter_new_expr(fltr, F_EXPR_REG, $1, $3);
+ }
+
+ | expr T_NREG expr {
+ if (filter_compile_param(fltr, (struct filter_param *) $3) != 0)
+ YYERROR;
+ $$ = filter_new_expr(fltr, F_EXPR_NREG, $1, $3);
+ }
;
param:
struct libscols_filter *fltr,
char const *msg)
{
- if (msg) {
+ if (msg && fltr) {
+ if (fltr->errmsg)
+ free(fltr->errmsg);
fltr->errmsg = strdup(msg);
if (!fltr->errmsg)
return;
struct filter_node *n, int *status);
/* param */
+int filter_compile_param(struct libscols_filter *fltr, struct filter_param *n);
void filter_dump_param(struct ul_jsonwrt *json, struct filter_param *n);
int filter_eval_param(struct libscols_filter *fltr, struct libscols_line *ln,
struct filter_param *n, int *status);
struct libscols_iter *itr, struct filter_param **prm);
int filter_compare_params(struct libscols_filter *fltr,
- struct libscols_line *ln,
enum filter_etype oper,
struct filter_param *l,
struct filter_param *r,