]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: (filter) implement !~, an operator for regex unmatching
authorMasatake YAMATO <yamato@redhat.com>
Sun, 10 Oct 2021 18:59:35 +0000 (03:59 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Sun, 10 Oct 2021 19:00:12 +0000 (04:00 +0900)
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
misc-utils/lsfd-filter.c

index 7b525a61798a69ed5e277e56d1d0d0e30385daf9..0202b6a939c463b59731fe23e78a9fa213764979 100644 (file)
@@ -57,6 +57,7 @@ enum op2_type {
        OP2_GT,
        OP2_GE,
        OP2_RE_MATCH,
+       OP2_RE_UNMATCH,
 };
 
 struct token {
@@ -199,6 +200,7 @@ static bool op2_le (struct node *, struct node *, struct parameter*, struct libs
 static bool op2_gt (struct node *, struct node *, struct parameter*, struct libscols_line *);
 static bool op2_ge (struct node *, struct node *, struct parameter*, struct libscols_line *);
 static bool op2_re_match (struct node *, struct node *, struct parameter*, struct libscols_line *);
+static bool op2_re_unmatch (struct node *, struct node *, struct parameter*, struct libscols_line *);
 
 static bool op2_check_type_eq_or_bool_or_op(struct parser *, struct op2_class *, struct node *, struct node *);
 static bool op2_check_type_boolean_or_op   (struct parser *, struct op2_class *, struct node *, struct node *);
@@ -319,6 +321,11 @@ struct op2_class op2_classes [] = {
                .is_acceptable = op2_re_match,
                .check_type = op2_check_type_re,
        },
+       [OP2_RE_UNMATCH] = {
+               .name = "!~",
+               .is_acceptable = op2_re_unmatch,
+               .check_type = op2_check_type_re,
+       },
 };
 
 #define NODE_CLASS(NODE) (&node_classes[(NODE)->type])
@@ -509,6 +516,10 @@ static struct token *parser_read(struct parser *parser)
                        t->type = TOKEN_OP2;
                        t->val.op2 = OP2_NE;
                        break;
+               } else if (c0 == '~') {
+                       t->type = TOKEN_OP2;
+                       t->val.op2 = OP2_RE_UNMATCH;
+                       break;
                }
                parser_ungetc(parser, c0);
                t->type = TOKEN_OP1;
@@ -1161,6 +1172,12 @@ static bool op2_re_match(struct node *left, struct node *right,
        return (regexec(&VAL(right,re), str, 0, NULL, 0) == 0);
 }
 
+static bool op2_re_unmatch(struct node *left, struct node *right,
+                        struct parameter *params, struct libscols_line *ln)
+{
+       return !op2_re_match(left, right, params, ln);
+}
+
 static bool op2_check_type_boolean_or_op(struct parser* parser, struct op2_class *op2_class,
                                         struct node *left, struct node *right)
 {