summaryrefslogtreecommitdiff
path: root/Src/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Modules')
-rw-r--r--Src/Modules/zutil.c56
1 files changed, 42 insertions, 14 deletions
diff --git a/Src/Modules/zutil.c b/Src/Modules/zutil.c
index 3ed1f9e16..e3e4c8353 100644
--- a/Src/Modules/zutil.c
+++ b/Src/Modules/zutil.c
@@ -58,9 +58,27 @@ static Style zstyles, zlstyles;
/* Memory stuff. */
+/*
+ * Free the information for one of the patterns associated with
+ * a style.
+ *
+ * If the style s is passed, prev is the previous pattern in the list,
+ * found when scanning. We use this to update the list of patterns.
+ * If this results in their being no remaining patterns, the style
+ * itself is removed from the list of styles. This isn't optimised,
+ * since it's not a very frequent operation; we simply scan down the list
+ * to find the previous entry.
+ */
static void
-freestypat(Stypat p)
+freestypat(Stypat p, Style s, Stypat prev)
{
+ if (s) {
+ if (prev)
+ prev->next = p->next;
+ else
+ s->pats = p->next;
+ }
+
zsfree(p->pat);
freepatprog(p->prog);
if (p->vals)
@@ -68,6 +86,20 @@ freestypat(Stypat p)
if (p->eval)
freeeprog(p->eval);
zfree(p, sizeof(*p));
+
+ if (s && !s->pats) {
+ /* No patterns left, free style */
+ if (s == zstyles) {
+ zstyles = s->next;
+ } else {
+ Style s2;
+ for (s2 = zstyles; s2->next != s; s2 = s2->next)
+ ;
+ s2->next = s->next;
+ }
+ zsfree(s->name);
+ zfree(s, sizeof(*s));
+ }
}
static void
@@ -80,7 +112,7 @@ freeallstyles(void)
sn = s->next;
for (p = s->pats; p; p = pn) {
pn = p->next;
- freestypat(p);
+ freestypat(p, NULL, NULL);
}
zsfree(s->name);
zfree(s, sizeof(*s));
@@ -96,8 +128,9 @@ getstyle(char *name)
Style s;
for (s = zstyles; s; s = s->next)
- if (!strcmp(name, s->name))
+ if (!strcmp(name, s->name)) {
return s;
+ }
return NULL;
}
@@ -397,27 +430,22 @@ bin_zstyle(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
for (q = NULL, p = s->pats; p;
q = p, p = p->next) {
if (!strcmp(p->pat, pat)) {
- if (q)
- q->next = p->next;
- else
- s->pats = p->next;
- freestypat(p);
+ freestypat(p, s, q);
break;
}
}
}
}
} else {
+ Style next;
Stypat p, q;
- for (s = zstyles; s; s = s->next) {
+ /* careful! style itself may be deleted */
+ for (s = zstyles; s; s = next) {
+ next = s->next;
for (q = NULL, p = s->pats; p; q = p, p = p->next) {
if (!strcmp(p->pat, args[1])) {
- if (q)
- q->next = p->next;
- else
- s->pats = p->next;
- freestypat(p);
+ freestypat(p, s, q);
break;
}
}