Allow predicates to be negated
authorMichael Spang <mspang@csclub.uwaterloo.ca>
Sun, 13 Dec 2009 07:53:53 +0000 (02:53 -0500)
committerMichael Spang <mspang@csclub.uwaterloo.ca>
Tue, 22 Dec 2009 03:11:49 +0000 (22:11 -0500)
Signed-off-by: Michael Spang <mspang@csclub.uwaterloo.ca>
inapt.cc
parser.rl

index c74df8c..f968d2e 100644 (file)
--- a/inapt.cc
+++ b/inapt.cc
@@ -183,6 +183,11 @@ static void usage() {
     exit(2);
 }
 
+static bool test_macro(const char *macro, set<string> *defines) {
+    return (*macro != '!' && defines->find(macro) != defines->end())
+            || (*macro == '!' && defines->find(macro + 1) == defines->end());
+}
+
 static void eval_block(inapt_block *block, set<string> *defines, std::vector<inapt_action *> *final_actions) {
     if (!block)
         return;
@@ -190,7 +195,7 @@ static void eval_block(inapt_block *block, set<string> *defines, std::vector<ina
     for (vector<inapt_action *>::iterator i = block->actions.begin(); i < block->actions.end(); i++) {
         bool ok = true;
         for (vector<const char *>::iterator j = (*i)->predicates.begin(); j < (*i)->predicates.end(); j++) {
-            if (defines->find(*j) == defines->end()) {
+            if (!test_macro(*j, defines)) {
                 ok = false;
                 break;
             }
@@ -200,7 +205,7 @@ static void eval_block(inapt_block *block, set<string> *defines, std::vector<ina
     }
 
     for (vector<inapt_conditional *>::iterator i = block->children.begin(); i < block->children.end(); i++) {
-        if (defines->find((*i)->condition) != defines->end())
+        if (test_macro((*i)->condition, defines))
             eval_block((*i)->then_block, defines, final_actions);
         else
             eval_block((*i)->else_block, defines, final_actions);
index f09a6e3..6c38e5b 100644 (file)
--- a/parser.rl
+++ b/parser.rl
@@ -103,7 +103,7 @@ using namespace std;
     newline = '\n' @newline;
     comment = '#' (any - '\n')* newline;
     whitespace = [\t\v\f\r ] | comment | newline;
-    macro = alpha (alpha | digit | '-' | '+' | '.')*;
+    macro = '!'? alpha (alpha | digit | '-' | '+' | '.')*;
     package_name = ((lower | digit) (lower | digit | '+' | '-' | '.')+) >strstart;
     pkg_predicate = '@' macro >strstart %pkg_predicate whitespace+;
     cmd_predicate = '@' macro >strstart %cmd_predicate whitespace+;