about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--lr.12
-rw-r--r--lr.c13
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);