diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | lr.1 | 2 | ||||
-rw-r--r-- | lr.c | 13 |
3 files changed, 13 insertions, 4 deletions
diff --git a/README.md b/README.md index 4ba11d3..30b11b1 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ Default: `n`. <str> ::= " ([^"] | "")+ " -- use "" for a single " inside " - <typetest> ::= type ( == | = ) ( b | c | d | p | f | l ) + <typetest> ::= type ( == | = | != ) ( b | c | d | p | f | l ) <modetest> ::= mode ( == | = -- exact permissions | & -- check if all bits of <octal> set diff --git a/lr.1 b/lr.1 index 880d69f..d422344 100644 --- a/lr.1 +++ b/lr.1 @@ -256,7 +256,7 @@ tests are given by the following EBNF: <str> ::= " ([^"] | "")+ " -- use "" for a single " inside " -<typetest> ::= type ( == | = ) ( b | c | d | p | f | l ) +<typetest> ::= type ( == | = | != ) ( b | c | d | p | f | l ) <modetest> ::= mode ( == | = -- exact permissions | & -- check if all bits of <octal> set diff --git a/lr.c b/lr.c index 41054e0..e1348df 100644 --- a/lr.c +++ b/lr.c @@ -327,8 +327,11 @@ parse_inner() static struct expr * parse_type() { + int negate = 0; + if (token("type")) { - if (token("==") || token("=")) { // TODO != + if (token("==") || token("=") + || (token("!=") && ++negate)) { struct expr *e = mkexpr(EXPR_TYPE); if (token("b")) e->a.filetype = TYPE_BLOCK; @@ -348,7 +351,13 @@ parse_type() parse_error("invalid file type '%c'", *pos); else parse_error("no file type given"); - return e; + if (negate) { + struct expr *not = mkexpr(EXPR_NOT); + not->a.expr = e; + return not; + } else { + return e; + } } else { parse_error("invalid file type comparison at '%.15s'", pos); |