From 16a673847d818d802c7903167b74ccaeaef86f44 Mon Sep 17 00:00:00 2001 From: Christian Neukirchen Date: Fri, 23 Oct 2015 14:23:35 +0200 Subject: better mode comparisons --- lr.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) (limited to 'lr.c') diff --git a/lr.c b/lr.c index 09c50dd..f31f495 100644 --- a/lr.c +++ b/lr.c @@ -101,6 +101,8 @@ enum op { EXPR_REGEXI, EXPR_PRUNE, EXPR_TYPE, + EXPR_ALLSET, + EXPR_ANYSET }; enum prop { @@ -191,6 +193,24 @@ parse_num(long *r) } } +int +parse_octal(long *r) +{ + if (*pos >= '0' && *pos <= '7') { + long n = 0; + while (*pos >= '0' && *pos <= '7') { + n *= 8; + n += *pos - '0'; + pos++; + } + ws(); + *r = n; + return 1; + } else { + return 0; + } +} + enum op parse_op() { @@ -332,6 +352,34 @@ parse_strcmp() return 0; } +struct expr * +parse_mode() +{ + struct expr *e = malloc(sizeof (struct expr)); + long n; + + e->a.prop = PROP_MODE; + + if (token("==")) { + e->op = EXPR_EQ; + } else if (token("&")) { + e->op = EXPR_ALLSET; + } else if (token("|")) { + e->op = EXPR_ANYSET; + } else { + parse_error("invalid mode comparison"); + } + + if (parse_octal(&n)) { + e->b.num = n; + printf("%d\n", n); + } else { + parse_error("invalid mode"); + } + + return e; +} + struct expr * parse_cmp() { @@ -351,7 +399,7 @@ parse_cmp() else if (token("links")) prop = PROP_LINKS; else if (token("mode")) - prop = PROP_MODE; + return parse_mode(); else if (token("mtime")) prop = PROP_MTIME; else if (token("size")) @@ -474,6 +522,8 @@ eval(struct expr *e, struct fileinfo *fi) case EXPR_EQ: case EXPR_GE: case EXPR_GT: + case EXPR_ALLSET: + case EXPR_ANYSET: { long v = 0; switch (e->a.prop) { @@ -496,6 +546,8 @@ eval(struct expr *e, struct fileinfo *fi) case EXPR_EQ: return v == e->b.num; case EXPR_GE: return v >= e->b.num; case EXPR_GT: return v > e->b.num; + case EXPR_ALLSET: return (v & e->b.num) == e->b.num; + case EXPR_ANYSET: return (v & e->b.num) > 0; } } case EXPR_TYPE: -- cgit 1.4.1