commit bf406bf2c7ad5025890a061780823576b65a67d7
parent 2e64aac7eba6791ed47514d37838b0d5d9d00cf1
Author: lumidify <nobody@lumidify.org>
Date: Sun, 24 Oct 2021 15:21:13 +0200
Free memory properly on exit
There are probably still a lot of things missing here.
Diffstat:
12 files changed, 74 insertions(+), 16 deletions(-)
diff --git a/buffer.c b/buffer.c
@@ -52,7 +52,6 @@ ledit_buffer_set_mode(ledit_buffer *buffer, enum ledit_mode mode) {
ledit_change_mode_group(buffer->undo);
}
-/* FIXME: destroy basic_attrs somewhere */
ledit_buffer *
ledit_buffer_create(ledit_common *common, ledit_theme *theme, ledit_window *window) {
if (basic_attrs == NULL) {
@@ -181,11 +180,18 @@ ledit_buffer_destroy(ledit_buffer *buffer) {
ledit_cache_destroy(buffer->cache);
ledit_undo_stack_destroy(buffer->undo);
free(buffer->lines);
- if (buffer->filename) free(buffer->filename);
+ if (buffer->filename)
+ free(buffer->filename);
free(buffer);
}
void
+ledit_buffer_cleanup(void) {
+ if (basic_attrs)
+ pango_attr_list_unref(basic_attrs);
+}
+
+void
ledit_buffer_normalize_line(ledit_line *line) {
if (line->gap < line->len) {
memmove(
@@ -231,6 +237,7 @@ ledit_buffer_set_line_selection(ledit_buffer *buffer, int line, int start_byte,
pango_attr_list_insert(list, attr2);
#endif
pango_layout_set_attributes(l->layout, list);
+ pango_attr_list_unref(list);
l->dirty = 1;
}
@@ -256,6 +263,7 @@ ledit_buffer_set_line_cursor_attrs(ledit_buffer *buffer, int line, int index) {
pango_attr_list_insert(list, attr2);
#endif
pango_layout_set_attributes(l->layout, list);
+ pango_attr_list_unref(list);
} else {
pango_layout_set_attributes(l->layout, basic_attrs);
}
diff --git a/cache.c b/cache.c
@@ -10,9 +10,9 @@
ledit_cache *
ledit_cache_create(ledit_common *common) {
- (void)common; /* FIXME: remove argument */
/* FIXME: prevent overflow */
ledit_cache *cache = ledit_malloc(sizeof(ledit_cache));
+ cache->dpy = common->dpy;
cache->entries = ledit_malloc(20 * sizeof(ledit_cache_pixmap));
for (int i = 0; i < 20; i++) {
cache->entries[i].pixmap = None;
diff --git a/keys_basic.c b/keys_basic.c
@@ -62,6 +62,21 @@ static struct {
struct key_stack_elem *stack;
} key_stack = {0, 0, NULL};
+void
+basic_key_cleanup(void) {
+ /* this should be safe since push_repetition_stack sets all new
+ elements to NULL when resizing the stack */
+ for (size_t i = 0; i < repetition_stack.alloc; i++) {
+ free(repetition_stack.stack[i].key_text);
+ }
+ for (size_t i = 0; i < repetition_stack.tmp_alloc; i++) {
+ free(repetition_stack.tmp_stack[i].key_text);
+ }
+ free(repetition_stack.stack);
+ free(repetition_stack.tmp_stack);
+ free(key_stack.stack);
+}
+
/* No, this isn't actually a stack. So what? */
static struct repetition_stack_elem *push_repetition_stack(void);
static void finalize_repetition_stack(void);
@@ -146,6 +161,9 @@ push_repetition_stack(void) {
repetition_stack.tmp_stack,
new_alloc * sizeof(struct repetition_stack_elem)
);
+ for (size_t i = repetition_stack.tmp_alloc; i < new_alloc; i++) {
+ repetition_stack.tmp_stack[i].key_text = NULL;
+ }
repetition_stack.tmp_alloc = new_alloc;
}
e = &repetition_stack.tmp_stack[repetition_stack.tmp_len];
diff --git a/keys_basic.h b/keys_basic.h
@@ -1 +1,2 @@
+void basic_key_cleanup(void);
struct action basic_key_handler(ledit_buffer *buffer, XEvent *event, int lang_index);
diff --git a/ledit.c b/ledit.c
@@ -38,6 +38,7 @@
#include "undo.h"
#include "buffer.h"
#include "action.h"
+#include "search.h"
#include "keys.h"
#include "keys_basic.h"
@@ -230,14 +231,12 @@ setup(int argc, char *argv[]) {
static void
cleanup(void) {
- /* FIXME: cleanup everything else */
- /*
- ledit_cleanup_search();
- ledit_destroy_cache();
- ledit_destroy_undo_stack(buffer);
- ledit_destroy_buffer(buffer);
- */
+ /* FIXME: check for other things to clean up */
+ ledit_search_cleanup();
+ basic_key_cleanup();
+ ledit_buffer_destroy(buffer);
ledit_window_destroy(window);
+ ledit_theme_destroy(&common, theme);
XCloseDisplay(common.dpy);
}
diff --git a/search.c b/search.c
@@ -19,7 +19,6 @@
#include "search.h"
/* FIXME: make sure only whole utf8 chars are matched */
-/* FIXME: clean this up */
char *last_search = NULL;
enum {
FORWARD,
@@ -27,15 +26,15 @@ enum {
} last_dir = FORWARD;
void
-ledit_set_search_forward(char *pattern) {
- last_dir = FORWARD;
+ledit_search_cleanup(void) {
free(last_search);
- last_search = ledit_strdup(pattern);
}
void
-ledit_cleanup_search(void) {
+ledit_set_search_forward(char *pattern) {
+ last_dir = FORWARD;
free(last_search);
+ last_search = ledit_strdup(pattern);
}
void
diff --git a/search.h b/search.h
@@ -5,7 +5,7 @@ enum ledit_search_state {
SEARCH_NO_PATTERN
};
-void ledit_cleanup_search(void);
+void ledit_search_cleanup(void);
void ledit_set_search_forward(char *pattern);
void ledit_set_search_backward(char *pattern);
enum ledit_search_state ledit_search_next(ledit_buffer *buffer, int *line_ret, int *byte_ret);
diff --git a/txtbuf.c b/txtbuf.c
@@ -32,6 +32,8 @@ txtbuf_shrink(txtbuf *buf) {
void
txtbuf_destroy(txtbuf *buf) {
+ if (!buf)
+ return;
free(buf->text);
free(buf);
}
diff --git a/util.c b/util.c
@@ -1,3 +1,5 @@
+#include <stdlib.h>
+
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <pango/pangoxft.h>
@@ -39,3 +41,10 @@ ledit_draw_grow(ledit_window *window, ledit_draw *draw, int w, int h) {
XftDrawChange(draw->xftdraw, draw->pixmap);
}
}
+
+void
+ledit_draw_destroy(ledit_window *window, ledit_draw *draw) {
+ XFreePixmap(window->common->dpy, draw->pixmap);
+ XftDrawDestroy(draw->xftdraw);
+ free(draw);
+}
diff --git a/util.h b/util.h
@@ -6,3 +6,4 @@ typedef struct {
ledit_draw *ledit_draw_create(ledit_window *window, int w, int h);
void ledit_draw_grow(ledit_window *window, ledit_draw *draw, int w, int h);
+void ledit_draw_destroy(ledit_window *window, ledit_draw *draw);
diff --git a/window.c b/window.c
@@ -415,7 +415,27 @@ ledit_window_create(ledit_common *common, ledit_theme *theme) {
void
ledit_window_destroy(ledit_window *window) {
/* FIXME: cleanup everything else */
+ pango_font_description_free(window->font);
+ g_object_unref(window->fontmap);
+ g_object_unref(window->context);
+ /* FIXME: is gc, etc. destroyed automatically when destroying window? */
+ if (window->spotlist)
+ XFree(window->spotlist);
XDestroyWindow(window->common->dpy, window->xwin);
+ g_object_unref(window->bb->mode);
+ /*g_object_unref(window->bb->ruler);*/ /* FIXME: implement ruler */
+ g_object_unref(window->bb->line);
+ ledit_draw_destroy(window, window->bb->mode_draw);
+ ledit_draw_destroy(window, window->bb->line_draw);
+ free(window->bb->line_text);
+ free(window->bb);
+ free(window);
+}
+
+void
+ledit_window_cleanup(void) {
+ txtbuf_destroy(xsel.primary);
+ free(xsel.clipboard);
}
void
diff --git a/window.h b/window.h
@@ -42,6 +42,7 @@ typedef struct {
ledit_window *ledit_window_create(ledit_common *common, ledit_theme *theme);
void ledit_window_destroy(ledit_window *window);
+void ledit_window_cleanup(void);
/* FIXME: this is a bit confusing because there's a difference between editable
text shown and non-editable message shown */