commit ebff664fd47dd86ca4aa0a2e1f681e754bd9fa23
parent dff6fb2502cec103edb8bc3fad2aa4143bb37165
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Wed, 15 Mar 2006 10:35:38 +0100
proceeded with tag separation
Diffstat:
5 files changed, 79 insertions(+), 58 deletions(-)
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -570,24 +570,6 @@ cid2index(unsigned short id)
return -1;
}
-void
-client2tags(Client *c, char *tags, unsigned int tagsz)
-{
- unsigned int i, len = 0, l;
-
- tags[0] = 0;
- for(i = 0; i < c->ntag; i++) {
- l = strlen(c->tag[i]);
- if(len + l + 1 >= tagsz)
- return;
- if(len)
- tags[len++] = ' ';
- memcpy(tags + len, c->tag[i], l);
- len += l;
- tags[len] = 0;
- }
-}
-
Bool
clienthastag(Client *c, const char *t)
{
diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c
@@ -522,11 +522,11 @@ type2stat(Stat *stat, char *wname, Qid *dir)
switch(dir_type) {
case FsDclient:
f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
- client2tags(f->client, buf, sizeof(buf));
+ tags2str(buf, sizeof(buf), f->client->tag, f->client->ntag);
return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE);
break;
case FsDGclient:
- client2tags(client[dir_i1], buf, sizeof(buf));
+ tags2str(buf, sizeof(buf), client[dir_i1]->tag, client[dir_i1]->ntag);
return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE);
break;
default:
@@ -1055,12 +1055,15 @@ xread(IXPConn *c, Fcall *fcall)
case FsFtags:
switch(m->qid.dir_type) {
case FsDclient:
- client2tags(tag[i1]->area[i2]->frame[i3]->client, buf, sizeof(buf));
- if((fcall->count = strlen(buf)))
- memcpy(p, buf, fcall->count);
+ {
+ Client *c = tag[i1]->area[i2]->frame[i3]->client;
+ tags2str(buf, sizeof(buf), c->tag, c->ntag);
+ if((fcall->count = strlen(buf)))
+ memcpy(p, buf, fcall->count);
+ }
break;
case FsDGclient:
- client2tags(client[i1], buf, sizeof(buf));
+ tags2str(buf, sizeof(buf), client[i1]->tag, client[i1]->ntag);
if((fcall->count = strlen(buf)))
memcpy(p, buf, fcall->count);
break;
@@ -1258,10 +1261,10 @@ xwrite(IXPConn *c, Fcall *fcall)
buf[fcall->count] = 0;
if(m->qid.dir_type == FsDclient) {
f = tag[i1]->area[i2]->frame[i3];
- f->client->ntag = str2tags(buf, f->client->tag);
+ f->client->ntag = str2tags(f->client->tag, buf);
}
else
- client[i1]->ntag = str2tags(buf, client[i1]->tag);
+ client[i1]->ntag = str2tags(client[i1]->tag, buf);
update_tags();
break;
case FsFgeom:
diff --git a/cmd/wm/rule.c b/cmd/wm/rule.c
@@ -19,24 +19,24 @@
typedef struct {
char regex[256];
- char tag[8][32];
+ char tag[MAX_TAGS][MAX_TAGLEN];
unsigned int ntag;
} Rule;
enum {
IGNORE,
- PATTERN,
+ REGEX,
TAGS
};
-/* free the result */
static Rule *
parse(char *data, unsigned int *n)
{
- Rule *rules;
+ static Rule *rule = nil;
+ static unsigned int rulesz = 0;
unsigned int i;
int mode = IGNORE;
- char *p, *regex, *tags;
+ char *p, *r, *t, regex[256], tags[MAX_TAGLEN];
if(!data || !strlen(data))
return nil;
@@ -46,68 +46,73 @@ parse(char *data, unsigned int *n)
if(*p == '\n')
(*n)++;
- rules = cext_emallocz(sizeof(Rule) * (*n));
+ if(*n > rulesz) {
+ if(rule)
+ free(rule);
+ rule = cext_emallocz(sizeof(Rule) * (*n));
+ rulesz = *n;
+ }
i = 0;
for(p = data; *p; p++)
switch(mode) {
case IGNORE:
if(*p == '/') {
- mode = PATTERN;
- regex = rules[i].regex;
+ mode = REGEX;
+ r = regex;
}
else if(*p == '>') {
mode = TAGS;
- tags = rules[i].tag[0];
+ t = tags;
}
break;
- case PATTERN:
+ case REGEX:
if(*p == '/') {
mode = IGNORE;
- *regex = 0;
+ *r = 0;
+ cext_strlcpy(rule[i].regex, regex, sizeof(rule[i].regex));
}
else {
- *regex = *p;
- regex++;
+ *r = *p;
+ r++;
}
break;
case TAGS:
if(*p == '\n' || *(p + 1) == 0) {
- *tags = 0;
+ *t = 0;
+ rule[i].ntag = str2tags(rule[i].tag, tags);
mode = IGNORE;
i++;
}
else {
if(*p == ' ' || *p == '\t') {
- if(*tags == 0)
+ if(tags[0] == 0)
continue; /* skip prefixed whitespaces */
- *tags = 0;
- tags = rules[i].tag[++rules[i].ntag];
}
else
- *tags = *p;
- tags++;
+ *t = *p;
+ t++;
}
break;
}
- return rules;
+ return rule;
}
static void
-match(Rule *rule, unsigned int rulesz, Client *c, const char *prop)
+match(Rule *rule, unsigned int rulez, Client *c, const char *prop)
{
unsigned int i, j;
regex_t regex;
regmatch_t tmpregm;
c->ntag = 0;
- for(i = 0; i < rulesz && c->ntag < 8; i++) {
+ for(i = 0; i < rulez && c->ntag < MAX_TAGS; i++) {
Rule r = rule[i];
if(!regcomp(®ex, r.regex, 0)) {
if(!regexec(®ex, prop, 1, &tmpregm, 0)) {
- for(j = 0; c->ntag < 8 && j < r.ntag; j++) {
+ for(j = 0; c->ntag < MAX_TAGS && j < r.ntag; j++) {
cext_strlcpy(c->tag[c->ntag], r.tag[j], sizeof(c->tag[c->ntag]));
c->ntag++;
}
@@ -121,13 +126,25 @@ void
match_tags(Client *c)
{
unsigned int n;
- Rule *rules;
+ Rule *rule;
if(!def.rules)
return;
- rules = parse(def.rules, &n);
- match(rules, n, c, c->name);
- match(rules, n, c, c->classinst);
- free(rules);
+ rule = parse(def.rules, &n);
+ {
+ unsigned int i,j;
+ for(i=0;i<n;i++) {
+ fprintf(stderr, "rule[%d].regex -> %s\n", i, rule[i].regex);
+ for(j=0;j<rule[i].ntag;j++)
+ fprintf(stderr, "rule[%d].tag[%d] -> %s\n", i, j, rule[i].tag[j]);
+ }
+ }
+ match(rule, n, c, c->name);
+ match(rule, n, c, c->classinst);
+ {
+ unsigned int i;
+ for(i = 0; i < c->ntag; i++)
+ fprintf(stderr, "c->tag[%d] -> %s\n", i, c->tag[i]);
+ }
}
diff --git a/cmd/wm/tag.c b/cmd/wm/tag.c
@@ -351,7 +351,7 @@ restack_tag(Tag *t)
}
unsigned int
-str2tags(const char *stags, char tags[MAX_TAGS][MAX_TAGLEN])
+str2tags(char tags[MAX_TAGS][MAX_TAGLEN], const char *stags)
{
unsigned int i, n;
char buf[256];
@@ -363,3 +363,22 @@ str2tags(const char *stags, char tags[MAX_TAGS][MAX_TAGLEN])
cext_strlcpy(tags[i], toks[i], MAX_TAGLEN);
return n;
}
+
+void
+tags2str(char *stags, unsigned int stagsz,
+ char tags[MAX_TAGS][MAX_TAGLEN], unsigned int ntags)
+{
+ unsigned int i, len = 0, l;
+
+ stags[0] = 0;
+ for(i = 0; i < ntags; i++) {
+ l = strlen(tags[i]);
+ if(len + l + 1 >= stagsz)
+ return;
+ if(len)
+ stags[len++] = ' ';
+ memcpy(stags + len, tags[i], l);
+ len += l;
+ stags[len] = 0;
+ }
+}
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -258,8 +258,6 @@ void send2area_client(Client *c, char *arg);
void resize_all_clients();
void focus(Client *c);
int cid2index(unsigned short id);
-void tags4client(Client *c, const char *tags);
-void client2tags(Client *c, char *tags, unsigned int tagsz);
Bool clienthastag(Client *c, const char *t);
/* event.c */
@@ -309,7 +307,9 @@ void detach_fromtag(Tag *t, Client *c);
void attach_totag(Tag *t, Client *c);
Client *sel_client_of_tag(Tag *t);
void restack_tag(Tag *t);
-unsigned int str2tags(const char *stags, char tags[MAX_TAGS][MAX_TAGLEN]);
+unsigned int str2tags(char tags[MAX_TAGS][MAX_TAGLEN], const char *stags);
+void tags2str(char *stags, unsigned int stagsz,
+ char tags[MAX_TAGS][MAX_TAGLEN], unsigned int ntags);
/* wm.c */
void scan_wins();