diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Modules/zutil.c | 56 |
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; } } |