Allow predicate to specify alternatives
authorMichael Spang <mspang@csclub.uwaterloo.ca>
Mon, 21 Dec 2009 06:00:57 +0000 (01:00 -0500)
committerMichael Spang <mspang@csclub.uwaterloo.ca>
Tue, 22 Dec 2009 03:28:50 +0000 (22:28 -0500)
We can now specify any boolean expression using predicates. However the
expression must be in disjunctive normal form.

Signed-off-by: Michael Spang <mspang@csclub.uwaterloo.ca>
inapt.cc
parser.rl
util.cc
util.h

index f33a5b4..b115e44 100644 (file)
--- a/inapt.cc
+++ b/inapt.cc
@@ -110,6 +110,26 @@ static bool test_profile(const char *profile, std::set<std::string> *defines) {
             || (*profile == '!' && defines->find(profile + 1) == defines->end());
 }
 
+static bool test_anyprofile(std::string &profile, std::set<std::string> *defines) {
+    char *s = xstrdup(profile.c_str());
+    const char *c = strtok(s, "/");
+
+    if (test_profile(c, defines)) {
+        free(s);
+        return true;
+    }
+
+    while ((c = strtok(NULL, "/")) != NULL) {
+        if (test_profile(c, defines)) {
+            free(s);
+            return true;
+        }
+    }
+
+    free(s);
+    return false;
+}
+
 static pkgCache::PkgIterator eval_pkg(inapt_package *package, pkgCacheFile &cache) {
     pkgCache::PkgIterator pkg;
 
@@ -165,7 +185,7 @@ static pkgCache::PkgIterator eval_pkg(inapt_package *package, pkgCacheFile &cach
 static bool test_profiles(vector<std::string> *profiles, std::set<std::string> *defines) {
     bool ok = true;
     for (vector<std::string>::iterator j = profiles->begin(); j < profiles->end(); j++) {
-        if (!test_profile((*j).c_str(), defines)) {
+        if (!test_anyprofile(*j, defines)) {
             ok = false;
             break;
         }
@@ -429,7 +449,7 @@ int main(int argc, char *argv[]) {
                 _config->Set("Inapt::Purge", true);
                 break;
             case 'd':
-                debug_enabled = true;
+                debug_level++;
                 break;
             case 'o':
                 set_option(optarg);
index 1347b40..a73e7ab 100644 (file)
--- a/parser.rl
+++ b/parser.rl
@@ -112,7 +112,7 @@ using namespace std;
     whitespace = [\t\v\f\r ] | comment | newline;
     profile = alpha (alpha | digit | '-' | '+' | '.')*;
     package_name = ((lower | digit) (lower | digit | '+' | '-' | '.')+) >strstart;
-    predicate = '@' ('!'? profile) >strstart %predicate whitespace+;
+    predicate = '@' ('!'? profile ('/' '!'? profile)*) >strstart %predicate whitespace+;
     package_alternates = package_name >strstart %add_alternate ('/' package_name >strstart %add_alternate)*;
     package_list = ((whitespace+ predicate* package_alternates)+ %add_package whitespace*);
     profile_list = (whitespace+ profile >strstart %profile)* whitespace*;
diff --git a/util.cc b/util.cc
index f73bb21..4ef5619 100644 (file)
--- a/util.cc
+++ b/util.cc
@@ -11,7 +11,7 @@
 
 #include "util.h"
 
-bool debug_enabled = false;
+int debug_level = 0;
 
 static void errmsg(int prio, const char *prefix, const char *fmt, va_list args) {
     fprintf(stderr, "%s: ", prefix);
@@ -66,7 +66,15 @@ void notice(const char *msg, ...) {
 void debug(const char *msg, ...) {
     va_list args;
     va_start(args, msg);
-    if (debug_enabled)
+    if (debug_level)
+        errmsg(LOG_DEBUG, "debug", msg, args);
+    va_end(args);
+}
+
+void debugn(int level, const char *msg, ...) {
+    va_list args;
+    va_start(args, msg);
+    if (debug_level >= level)
         errmsg(LOG_DEBUG, "debug", msg, args);
     va_end(args);
 }
diff --git a/util.h b/util.h
index a0ed83d..bdf529d 100644 (file)
--- a/util.h
+++ b/util.h
@@ -25,6 +25,7 @@ PRINTF_LIKE(0) void error(const char *, ...);
 PRINTF_LIKE(0) void warn(const char *, ...);
 PRINTF_LIKE(0) void notice(const char *, ...);
 PRINTF_LIKE(0) void debug(const char *, ...);
+PRINTF_LIKE(1) void debugn(int level, const char *, ...);
 PRINTF_LIKE(0) void errorpe(const char *, ...);
 PRINTF_LIKE(0) void warnpe(const char *, ...);
 
@@ -73,6 +74,6 @@ static inline char *xstrndup(const char *s, size_t n) {
     return dup;
 }
 
-extern bool debug_enabled;
+extern int debug_level;
 
 #endif