diff options
-rw-r--r-- | sway/criteria.c | 61 |
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 | 26 | static const char * const criteria_strings[CRIT_LAST] = { |
27 | static 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 | */ |
43 | struct crit_token { | 42 | struct 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 | ||
49 | static void free_crit_token(struct crit_token *crit) { | 48 | static 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. |
193 | static char *generate_regex(regex_t **regex, char *value) { | 187 | static 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, ®_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 | ||
248 | static int regex_cmp(const char *item, const regex_t *regex) { | 241 | static 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; |