aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sway/criteria.c61
1 files changed, 27 insertions, 34 deletions
diff --git a/sway/criteria.c b/sway/criteria.c
index bd99461d..ee6d4d1c 100644
--- a/sway/criteria.c
+++ b/sway/criteria.c
@@ -2,7 +2,7 @@
2#include <stdlib.h> 2#include <stdlib.h>
3#include <stdio.h> 3#include <stdio.h>
4#include <stdbool.h> 4#include <stdbool.h>
5#include <regex.h> 5#include <pcre.h>
6#include "sway/criteria.h" 6#include "sway/criteria.h"
7#include "sway/container.h" 7#include "sway/container.h"
8#include "sway/config.h" 8#include "sway/config.h"
@@ -23,17 +23,16 @@ enum criteria_type { // *must* keep in sync with criteria_strings[]
23 CRIT_LAST 23 CRIT_LAST
24}; 24};
25 25
26// this *must* match the ordering in criteria_type enum 26static const char * const criteria_strings[CRIT_LAST] = {
27static const char * const criteria_strings[] = { 27 [CRIT_CLASS] = "class",
28 "class", 28 [CRIT_CON_MARK] = "con_mark",
29 "con_mark", 29 [CRIT_ID] = "id",
30 "id", 30 [CRIT_INSTANCE] = "instance",
31 "instance", 31 [CRIT_TITLE] = "title",
32 "title", 32 [CRIT_URGENT] = "urgent", // either "latest" or "oldest" ...
33 "urgent", // either "latest" or "oldest" ... 33 [CRIT_WINDOW_ROLE] = "window_role",
34 "window_role", 34 [CRIT_WINDOW_TYPE] = "window_type",
35 "window_type", 35 [CRIT_WORKSPACE] = "workspace"
36 "workspace"
37}; 36};
38 37
39/** 38/**
@@ -42,18 +41,13 @@ static const char * const criteria_strings[] = {
42 */ 41 */
43struct crit_token { 42struct crit_token {
44 enum criteria_type type; 43 enum criteria_type type;
45 regex_t *regex; 44 pcre *regex;
46 char *raw; 45 char *raw;
47}; 46};
48 47
49static void free_crit_token(struct crit_token *crit) { 48static void free_crit_token(struct crit_token *crit) {
50 if (crit->regex) { 49 pcre_free(crit->regex);
51 regfree(crit->regex); 50 free(crit->raw);
52 free(crit->regex);
53 }
54 if (crit->raw) {
55 free(crit->raw);
56 }
57 free(crit); 51 free(crit);
58} 52}
59 53
@@ -190,18 +184,17 @@ static char *parse_criteria_name(enum criteria_type *type, char *name) {
190} 184}
191 185
192// Returns error string on failure or NULL otherwise. 186// Returns error string on failure or NULL otherwise.
193static char *generate_regex(regex_t **regex, char *value) { 187static char *generate_regex(pcre **regex, char *value) {
194 *regex = calloc(1, sizeof(regex_t)); 188 const char *reg_err;
195 int err = regcomp(*regex, value, REG_NOSUB); 189 int offset;
196 if (err != 0) { 190
197 char *reg_err = malloc(64); 191 *regex = pcre_compile(value, PCRE_UTF8 | PCRE_UCP, &reg_err, &offset, NULL);
198 regerror(err, *regex, reg_err, 64);
199 192
193 if (!*regex) {
200 const char *fmt = "Regex compilation (for '%s') failed: %s"; 194 const char *fmt = "Regex compilation (for '%s') failed: %s";
201 int len = strlen(fmt) + strlen(value) + strlen(reg_err) - 3; 195 int len = strlen(fmt) + strlen(value) + strlen(reg_err) - 3;
202 char *error = malloc(len); 196 char *error = malloc(len);
203 snprintf(error, len, fmt, value, reg_err); 197 snprintf(error, len, fmt, value, reg_err);
204 free(reg_err);
205 return error; 198 return error;
206 } 199 }
207 return NULL; 200 return NULL;
@@ -245,8 +238,8 @@ ect_cleanup:
245 return error; 238 return error;
246} 239}
247 240
248static int regex_cmp(const char *item, const regex_t *regex) { 241static int regex_cmp(const char *item, const pcre *regex) {
249 return regexec(regex, item, 0, NULL, 0); 242 return pcre_exec(regex, NULL, item, strlen(item), 0, 0, NULL, 0);
250} 243}
251 244
252// test a single view if it matches list of criteria tokens (all of them). 245// test a single view if it matches list of criteria tokens (all of them).
@@ -266,7 +259,7 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) {
266 if (focused->class && strcmp(cont->class, focused->class) == 0) { 259 if (focused->class && strcmp(cont->class, focused->class) == 0) {
267 matches++; 260 matches++;
268 } 261 }
269 } else if (crit->regex && regexec(crit->regex, cont->class, 0, NULL, 0) == 0) { 262 } else if (crit->regex && regex_cmp(cont->class, crit->regex) == 0) {
270 matches++; 263 matches++;
271 } 264 }
272 break; 265 break;
@@ -281,7 +274,7 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) {
281 case CRIT_ID: 274 case CRIT_ID:
282 if (!cont->app_id) { 275 if (!cont->app_id) {
283 // ignore 276 // ignore
284 } else if (crit->regex && regexec(crit->regex, cont->app_id, 0, NULL, 0) == 0) { 277 } else if (crit->regex && regex_cmp(cont->app_id, crit->regex) == 0) {
285 matches++; 278 matches++;
286 } 279 }
287 break; 280 break;
@@ -293,7 +286,7 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) {
293 if (focused->instance && strcmp(cont->instance, focused->instance) == 0) { 286 if (focused->instance && strcmp(cont->instance, focused->instance) == 0) {
294 matches++; 287 matches++;
295 } 288 }
296 } else if (crit->regex && regexec(crit->regex, cont->instance, 0, NULL, 0) == 0) { 289 } else if (crit->regex && regex_cmp(cont->instance, crit->regex) == 0) {
297 matches++; 290 matches++;
298 } 291 }
299 break; 292 break;
@@ -305,7 +298,7 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) {
305 if (focused->name && strcmp(cont->name, focused->name) == 0) { 298 if (focused->name && strcmp(cont->name, focused->name) == 0) {
306 matches++; 299 matches++;
307 } 300 }
308 } else if (crit->regex && regexec(crit->regex, cont->name, 0, NULL, 0) == 0) { 301 } else if (crit->regex && regex_cmp(cont->name, crit->regex) == 0) {
309 matches++; 302 matches++;
310 } 303 }
311 break; 304 break;
@@ -325,7 +318,7 @@ static bool criteria_test(swayc_t *cont, list_t *tokens) {
325 if (focused_ws->name && strcmp(cont_ws->name, focused_ws->name) == 0) { 318 if (focused_ws->name && strcmp(cont_ws->name, focused_ws->name) == 0) {
326 matches++; 319 matches++;
327 } 320 }
328 } else if (crit->regex && regexec(crit->regex, cont_ws->name, 0, NULL, 0) == 0) { 321 } else if (crit->regex && regex_cmp(cont_ws->name, crit->regex) == 0) {
329 matches++; 322 matches++;
330 } 323 }
331 break; 324 break;