diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2014-09-09 09:53:46 +0200 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2014-09-09 10:10:37 +0200 |
| commit | fac398accd9ef50cab9e89844964389cd48abe86 (patch) | |
| tree | 0bae75abc6e19ee65089e42cd98a18a18ae9359c | |
| parent | cfc447cff743d286b38aa3c686f297305148a202 (diff) | |
| download | vis-fac398accd9ef50cab9e89844964389cd48abe86.tar.gz vis-fac398accd9ef50cab9e89844964389cd48abe86.tar.xz | |
Fix a few memory leaks
| -rw-r--r-- | config.def.h | 7 | ||||
| -rw-r--r-- | main.c | 5 | ||||
| -rw-r--r-- | text.c | 1 | ||||
| -rw-r--r-- | vis.c | 58 | ||||
| -rw-r--r-- | vis.h | 2 | ||||
| -rw-r--r-- | window.c | 1 |
6 files changed, 53 insertions, 21 deletions
diff --git a/config.def.h b/config.def.h index f1f8d17..ec8e141 100644 --- a/config.def.h +++ b/config.def.h @@ -277,8 +277,7 @@ static void statusbar(WINDOW *win, bool active, const char *filename, size_t lin } static void quit(const Arg *arg) { - endwin(); - exit(0); + vis->running = false; } static void split(const Arg *arg) { @@ -509,9 +508,7 @@ static void prompt_enter(const Arg *arg) { switch (vis->prompt->title[0]) { case '/': case '?': - text_regex_free(vis->search_pattern); - if (!(vis->search_pattern = text_regex_new()) || - text_regex_compile(vis->search_pattern, s, REG_EXTENDED)) { + if (text_regex_compile(vis->search_pattern, s, REG_EXTENDED)) { action_reset(&action); } else { movement(&(const Arg){ .i = vis->prompt->title[0] == '/' ? @@ -166,8 +166,8 @@ static void setup() { } static void cleanup() { - vis_free(vis); endwin(); + //delscreen(set_term(NULL)); } static bool keymatch(Key *key0, Key *key1) { @@ -241,7 +241,7 @@ int main(int argc, char *argv[]) { struct timeval idle = { .tv_usec = 0 }, *timeout = NULL; Key key, key_prev, *key_mod = NULL; - for (;;) { + while (vis->running) { if (screen.need_resize) { resize_screen(&screen); vis_resize(vis, screen.w, screen.h); @@ -299,6 +299,7 @@ int main(int argc, char *argv[]) { timeout = &idle; } + vis_free(vis); cleanup(); return 0; } @@ -1058,6 +1058,7 @@ void text_regex_free(Regex *r) { if (!r) return; regfree(&r->regex); + free(r); } int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) { @@ -5,7 +5,7 @@ #include "util.h" static VisWin *vis_window_new_text(Vis *vis, Text *text); -static void vis_window_free(VisWin *win); +static void vis_window_free(Vis *vis, VisWin *win); static void vis_window_split_internal(Vis *vis, const char *filename); static void vis_windows_invalidate(Vis *vis, size_t start, size_t end); static void vis_window_draw(VisWin *win); @@ -219,14 +219,21 @@ void vis_update(Vis *vis) { window_update(vis->win->win); } -static void vis_window_free(VisWin *win) { +static void vis_window_free(Vis *vis, VisWin *win) { if (!win) return; window_free(win->win); if (win->statuswin) delwin(win->statuswin); - // XXX: open in other windows - text_free(win->text); + bool needed = false; + for (VisWin *w = vis ? vis->windows : NULL; w; w = w->next) { + if (w->text == win->text) { + needed = true; + break; + } + } + if (!needed) + text_free(win->text); free(win); } @@ -239,7 +246,7 @@ static VisWin *vis_window_new_text(Vis *vis, Text *text) { win->win = window_new(win->text); win->statuswin = newwin(1, vis->width, 0, 0); if (!win->win || !win->statuswin) { - vis_window_free(win); + vis_window_free(vis, win); return NULL; } window_cursor_watch(win->win, vis_window_cursor_moved, win); @@ -277,26 +284,49 @@ bool vis_window_new(Vis *vis, const char *filename) { return true; } +static void vis_window_detach(Vis *vis, VisWin *win) { + if (win->prev) + win->prev->next = win->next; + if (win->next) + win->next->prev = win->prev; + if (vis->windows == win) + vis->windows = win->next; + win->next = win->prev = NULL; +} + +void vis_window_close(Vis *vis) { + VisWin *win = vis->win; + vis->win = win->next ? win->next : win->prev; + vis_window_detach(vis, win); + vis_window_free(vis, win); +} + Vis *vis_new(int width, int height) { Vis *vis = calloc(1, sizeof(Vis)); if (!vis) return NULL; - if (!(vis->prompt = vis_prompt_new())) { - vis_free(vis); - return NULL; - } + if (!(vis->prompt = vis_prompt_new())) + goto err; + if (!(vis->search_pattern = text_regex_new())) + goto err; vis->width = width; vis->height = height; vis->windows_arrange = vis_windows_arrange_horizontal; + vis->running = true; return vis; +err: + vis_free(vis); + return NULL; } void vis_free(Vis *vis) { - for (VisWin *next, *win = vis->windows; win; win = next) { - next = win->next; - vis_window_free(win); - } + while (vis->windows) + vis_window_close(vis); vis_prompt_free(vis->prompt); + text_regex_free(vis->search_pattern); + for (int i = 0; i < REG_LAST; i++) + register_free(&vis->registers[i]); + vis_syntax_unload(vis); free(vis); } @@ -340,7 +370,7 @@ void vis_delete(Vis *vis, size_t pos, size_t len) { static void vis_prompt_free(Prompt *prompt) { if (!prompt) return; - vis_window_free(prompt->win); + vis_window_free(NULL, prompt->win); if (prompt->titlewin) delwin(prompt->titlewin); free(prompt->title); @@ -59,6 +59,7 @@ struct Vis { Regex *search_pattern; void (*windows_arrange)(Vis*); /* current layout which places the windows */ vis_statusbar_t statusbar; /* configurable user hook to draw statusbar */ + bool running; }; @@ -102,6 +103,7 @@ bool vis_syntax_load(Vis*, Syntax *syntaxes, Color *colors); void vis_syntax_unload(Vis*); bool vis_window_new(Vis*, const char *filename); +void vis_window_close(Vis *vis); void vis_window_split(Vis*, const char *filename); void vis_window_vsplit(Vis*, const char *filename); void vis_window_next(Vis*); @@ -459,6 +459,7 @@ void window_free(Win *win) { return; if (win->win) delwin(win->win); + free(win->lines); free(win); } |
