aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2014-09-09 09:53:46 +0200
committerMarc André Tanner <mat@brain-dump.org>2014-09-09 10:10:37 +0200
commitfac398accd9ef50cab9e89844964389cd48abe86 (patch)
tree0bae75abc6e19ee65089e42cd98a18a18ae9359c
parentcfc447cff743d286b38aa3c686f297305148a202 (diff)
downloadvis-fac398accd9ef50cab9e89844964389cd48abe86.tar.gz
vis-fac398accd9ef50cab9e89844964389cd48abe86.tar.xz
Fix a few memory leaks
-rw-r--r--config.def.h7
-rw-r--r--main.c5
-rw-r--r--text.c1
-rw-r--r--vis.c58
-rw-r--r--vis.h2
-rw-r--r--window.c1
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] == '/' ?
diff --git a/main.c b/main.c
index f3435d8..1c4843d 100644
--- a/main.c
+++ b/main.c
@@ -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;
}
diff --git a/text.c b/text.c
index 3e7ce40..dac2b41 100644
--- a/text.c
+++ b/text.c
@@ -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) {
diff --git a/vis.c b/vis.c
index 8af9134..3760e43 100644
--- a/vis.c
+++ b/vis.c
@@ -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);
diff --git a/vis.h b/vis.h
index b7272b4..1dc7f7d 100644
--- a/vis.h
+++ b/vis.h
@@ -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*);
diff --git a/window.c b/window.c
index f4ab37e..9e54c46 100644
--- a/window.c
+++ b/window.c
@@ -459,6 +459,7 @@ void window_free(Win *win) {
return;
if (win->win)
delwin(win->win);
+ free(win->lines);
free(win);
}