tag.c
changeset 191 56fee1dc9d53
parent 178 e848966a1ac6
child 194 655e38416bb8
equal deleted inserted replaced
190:713dcc7d2c42 191:56fee1dc9d53
     3  * See LICENSE file for license details.
     3  * See LICENSE file for license details.
     4  */
     4  */
     5 #include "dwm.h"
     5 #include "dwm.h"
     6 #include <regex.h>
     6 #include <regex.h>
     7 #include <stdio.h>
     7 #include <stdio.h>
       
     8 #include <stdlib.h>
     8 #include <string.h>
     9 #include <string.h>
     9 #include <sys/types.h>
    10 #include <sys/types.h>
    10 #include <X11/Xutil.h>
    11 #include <X11/Xutil.h>
    11 
    12 
    12 /* static */
       
    13 
    13 
    14 typedef struct {
    14 typedef struct {
    15 	const char *pattern;
    15 	const char *clpattern;
    16 	const unsigned int *tags;
    16 	const char *tpattern;
    17 	Bool isfloat;
    17 	Bool isfloat;
    18 } Rule;
    18 } Rule;
    19 
    19 
       
    20 typedef struct {
       
    21 	regex_t *clregex;
       
    22 	regex_t *tregex;
       
    23 } RReg;
       
    24 
       
    25 /* static */
       
    26 
    20 TAGS
    27 TAGS
    21 RULES
    28 RULES
       
    29 
       
    30 static RReg *rreg = NULL;
       
    31 static unsigned int len = 0;
    22 
    32 
    23 void (*arrange)(Arg *) = DEFMODE;
    33 void (*arrange)(Arg *) = DEFMODE;
    24 
    34 
    25 /* extern */
    35 /* extern */
    26 
    36 
   136 	for(; c && !c->tags[tsel]; c = c->prev);
   146 	for(; c && !c->tags[tsel]; c = c->prev);
   137 	return c;
   147 	return c;
   138 }
   148 }
   139 
   149 
   140 void
   150 void
       
   151 initrregs()
       
   152 {
       
   153 	unsigned int i;
       
   154 	regex_t *reg;
       
   155 
       
   156 	if(rreg)
       
   157 		return;
       
   158 	len = sizeof(rule) / sizeof(rule[0]);
       
   159 	rreg = emallocz(len * sizeof(RReg));
       
   160 
       
   161 	for(i = 0; i < len; i++) {
       
   162 		if(rule[i].clpattern) {
       
   163 			reg = emallocz(sizeof(regex_t));
       
   164 			if(regcomp(reg, rule[i].clpattern, 0))
       
   165 				free(reg);
       
   166 			else
       
   167 				rreg[i].clregex = reg;
       
   168 		}
       
   169 		if(rule[i].tpattern) {
       
   170 			reg = emallocz(sizeof(regex_t));
       
   171 			if(regcomp(reg, rule[i].tpattern, 0))
       
   172 				free(reg);
       
   173 			else
       
   174 				rreg[i].tregex = reg;
       
   175 		}
       
   176 	}
       
   177 }
       
   178 
       
   179 void
   141 replacetag(Arg *arg)
   180 replacetag(Arg *arg)
   142 {
   181 {
   143 	int i;
   182 	int i;
   144 
   183 
   145 	if(!sel)
   184 	if(!sel)
   152 
   191 
   153 void
   192 void
   154 settags(Client *c)
   193 settags(Client *c)
   155 {
   194 {
   156 	char classinst[256];
   195 	char classinst[256];
   157 	static unsigned int len = sizeof(rule) / sizeof(rule[0]);
   196 	unsigned int i, j;
   158 	unsigned int i, j, n;
       
   159 	regex_t regex;
       
   160 	regmatch_t tmp;
   197 	regmatch_t tmp;
   161 	Bool matched = False;
   198 	Bool matched = False;
   162 	XClassHint ch;
   199 	XClassHint ch;
   163 
   200 
   164 	if(XGetClassHint(dpy, c->win, &ch)) {
   201 	if(XGetClassHint(dpy, c->win, &ch)) {
   165 		snprintf(classinst, sizeof(classinst), "%s:%s",
   202 		snprintf(classinst, sizeof(classinst), "%s:%s",
   166 				ch.res_class ? ch.res_class : "",
   203 				ch.res_class ? ch.res_class : "",
   167 				ch.res_name ? ch.res_name : "");
   204 				ch.res_name ? ch.res_name : "");
   168 		for(i = 0; !matched && i < len; i++) {
   205 		for(i = 0; !matched && i < len; i++)
   169 			if(!regcomp(&regex, rule[i].pattern, 0)) {
   206 			if(rreg[i].clregex && !regexec(rreg[i].clregex, classinst, 1, &tmp, 0)) {
   170 				if(!regexec(&regex, classinst, 1, &tmp, 0)) {
   207 				c->isfloat = rule[i].isfloat;
   171 					n = rule[i].tags ?
   208 				for(j = 0; rreg[i].tregex && j < ntags; j++) {
   172 						sizeof(rule[i].tags) / sizeof(rule[i].tags[0]) : 0;
   209 					if(!regexec(rreg[i].tregex, tags[j], 1, &tmp, 0)) {
   173 					matched = n != 0;
   210 						matched = True;
   174 					for(j = 0; j < n; j++)
   211 						c->tags[j] = True;
   175 						c->tags[rule[i].tags[j]] = True;
   212 					}
   176 					c->isfloat = rule[i].isfloat;
       
   177 				}
   213 				}
   178 				regfree(&regex);
   214 			}
   179 			}
       
   180 		}
       
   181 		if(ch.res_class)
   215 		if(ch.res_class)
   182 			XFree(ch.res_class);
   216 			XFree(ch.res_class);
   183 		if(ch.res_name)
   217 		if(ch.res_name)
   184 			XFree(ch.res_name);
   218 			XFree(ch.res_name);
   185 	}
   219 	}