tFree memory properly on exit - ledit - Text editor (WIP) | |
git clone git://lumidify.org/ledit.git (fast, but not encrypted) | |
git clone https://lumidify.org/git/ledit.git (encrypted, but very slow) | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit bf406bf2c7ad5025890a061780823576b65a67d7 | |
parent 2e64aac7eba6791ed47514d37838b0d5d9d00cf1 | |
Author: lumidify <[email protected]> | |
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: | |
M buffer.c | 12 ++++++++++-- | |
M cache.c | 2 +- | |
M keys_basic.c | 18 ++++++++++++++++++ | |
M keys_basic.h | 1 + | |
M ledit.c | 13 ++++++------- | |
M search.c | 9 ++++----- | |
M search.h | 2 +- | |
M txtbuf.c | 2 ++ | |
M util.c | 9 +++++++++ | |
M util.h | 1 + | |
M window.c | 20 ++++++++++++++++++++ | |
M window.h | 1 + | |
12 files changed, 74 insertions(+), 16 deletions(-) | |
--- | |
diff --git a/buffer.c b/buffer.c | |
t@@ -52,7 +52,6 @@ ledit_buffer_set_mode(ledit_buffer *buffer, enum ledit_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 *wi… | |
if (basic_attrs == NULL) { | |
t@@ -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( | |
t@@ -231,6 +237,7 @@ ledit_buffer_set_line_selection(ledit_buffer *buffer, int … | |
pango_attr_list_insert(list, attr2); | |
#endif | |
pango_layout_set_attributes(l->layout, list); | |
+ pango_attr_list_unref(list); | |
l->dirty = 1; | |
} | |
t@@ -256,6 +263,7 @@ ledit_buffer_set_line_cursor_attrs(ledit_buffer *buffer, i… | |
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 | |
t@@ -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 | |
t@@ -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); | |
t@@ -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 | |
t@@ -1 +1,2 @@ | |
+void basic_key_cleanup(void); | |
struct action basic_key_handler(ledit_buffer *buffer, XEvent *event, int lang_… | |
diff --git a/ledit.c b/ledit.c | |
t@@ -38,6 +38,7 @@ | |
#include "undo.h" | |
#include "buffer.h" | |
#include "action.h" | |
+#include "search.h" | |
#include "keys.h" | |
#include "keys_basic.h" | |
t@@ -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 | |
t@@ -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, | |
t@@ -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 | |
t@@ -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,… | |
diff --git a/txtbuf.c b/txtbuf.c | |
t@@ -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 | |
t@@ -1,3 +1,5 @@ | |
+#include <stdlib.h> | |
+ | |
#include <X11/Xlib.h> | |
#include <X11/Xutil.h> | |
#include <pango/pangoxft.h> | |
t@@ -39,3 +41,10 @@ ledit_draw_grow(ledit_window *window, ledit_draw *draw, int… | |
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 | |
t@@ -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 | |
t@@ -415,7 +415,27 @@ ledit_window_create(ledit_common *common, ledit_theme *th… | |
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 | |
t@@ -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 */ |