Fixing ke
Back in February of 2020, I started writing my own text editor ke. It seemed to work on my mac, but would always crash on Linux. While I never figured out what the bug was, I kept using it on Darwin.
Well, Wally and I got to talking Thursday, pining for the good old days (Dissolved Girl, some vim and terminal windows and man pages and C code and IRC and MDCR and ...). Well, after the absolute dumpster fire work has been, I got a hair up my ass to throw on some Massive Attack (the trip-hop playlist in general) and fix it.
The patch (eliding a function move)?
diff --git a/main.c b/main.c
index 67acb57..ba0b6e5 100644
--- a/main.c
+++ b/main.c
@@ -152,7 +152,70 @@ struct editor_t {
int dirtyex;
char msg[80];
time_t msgtm;
-} editor;
+} editor = {
+ .cols = 0,
+ .rows = 0,
+ .curx = 0,
+ .cury = 0,
+ .mode = 0,
+ .nrows = 0,
+ .rowoffs = 0,
+ .coloffs = 0,
+ .row = NULL,
+ .filename = NULL,
+ .dirty = 0,
+ .dirtyex = 0,
+};
+
+
+/*
+ * reset_editor presumes that editor has been initialized.
+ */
+void
+reset_editor(void)
+{
+ for (int i = 0; i < editor.nrows; i++) {
+ erow_free(&editor.row[i]);
+ }
+ free(editor.row);
+
+ if (editor.filename != NULL) {
+ free(editor.filename);
+ editor.filename = NULL;
+ }
+
+ init_editor();
+}
void
@@ -503,6 +566,8 @@ open_file(const char *filename)
editor.filename = strdup(filename);
assert(editor.filename != NULL);
+ reset_editor();
+
editor.dirty = 0;
if ((fp = fopen(filename, "r")) == NULL) {
if (errno == ENOENT) {
@@ -1408,35 +1473,6 @@ loop(void)
}
int
main(int argc, char *argv[])
{
Two main things here:
- On initialization (and program start) the editor should be initialized. The struct value setting is probably unnecessary given =init_editor=, but sanity checks never killed anyone.
- On loading a file, make sure to clear out all the data appropriately.
This fixed the main double-free killer; I found this by using ASan. It also pointed out some other areas I was leaking memory and I cleaned all that up.
I also got =forward-word=, =backward-word=, =kill-word=, and =kill-backward-word= (or, =find_next_word=, =find_prev_word=, =delete_next_word=, and =delete_prev_word=) working.
Next up: yanking.
I ended up putting both cert (the tool from the previous post) and =ke= on Homebrew:
brew tap kisom/homebrew-tap brew install cert ke
Should make it easier to keep them up to date on the work machine.