]> git.sur5r.net Git - i3/i3/blobdiff - src/match.c
Implement support for PCRE regular expressions for all criteria (for_window, commands...
[i3/i3] / src / match.c
index 3a346117340a9c880d66a70f99fcd91bee242df4..85d2eaabc5cf520d93937b5202c2125e6820df2f 100644 (file)
@@ -52,16 +52,19 @@ bool match_is_empty(Match *match) {
 void match_copy(Match *dest, Match *src) {
     memcpy(dest, src, sizeof(Match));
 
-#define STRDUP(field) do { \
+/* The DUPLICATE_REGEX macro creates a new regular expression from the
+ * ->pattern of the old one. It therefore does use a little more memory then
+ *  with a refcounting system, but it’s easier this way. */
+#define DUPLICATE_REGEX(field) do { \
     if (src->field != NULL) \
-        dest->field = sstrdup(src->field); \
+        dest->field = regex_new(src->field->pattern); \
 } while (0)
 
-    STRDUP(title);
-    STRDUP(mark);
-    STRDUP(application);
-    STRDUP(class);
-    STRDUP(instance);
+    DUPLICATE_REGEX(title);
+    DUPLICATE_REGEX(mark);
+    DUPLICATE_REGEX(application);
+    DUPLICATE_REGEX(class);
+    DUPLICATE_REGEX(instance);
 }
 
 /*
@@ -71,9 +74,9 @@ void match_copy(Match *dest, Match *src) {
 bool match_matches_window(Match *match, i3Window *window) {
     LOG("checking window %d (%s)\n", window->id, window->class_class);
 
-    /* TODO: pcre, full matching, … */
     if (match->class != NULL) {
-        if (window->class_class != NULL && strcasecmp(match->class, window->class_class) == 0) {
+        if (window->class_class != NULL &&
+            regex_matches(match->class, window->class_class)) {
             LOG("window class matches (%s)\n", window->class_class);
         } else {
             LOG("window class does not match\n");
@@ -82,7 +85,8 @@ bool match_matches_window(Match *match, i3Window *window) {
     }
 
     if (match->instance != NULL) {
-        if (window->class_instance != NULL && strcasecmp(match->instance, window->class_instance) == 0) {
+        if (window->class_instance != NULL &&
+            regex_matches(match->instance, window->class_instance)) {
             LOG("window instance matches (%s)\n", window->class_instance);
         } else {
             LOG("window instance does not match\n");
@@ -99,9 +103,9 @@ bool match_matches_window(Match *match, i3Window *window) {
         }
     }
 
-    /* TODO: pcre match */
     if (match->title != NULL) {
-        if (window->name_json != NULL && strcasecmp(match->title, window->name_json) == 0) {
+        if (window->name_json != NULL &&
+            regex_matches(match->title, window->name_json)) {
             LOG("title matches (%s)\n", window->name_json);
         } else {
             LOG("title does not match\n");