aboutsummaryrefslogtreecommitdiffstats
path: root/buffer.c
diff options
context:
space:
mode:
authornytpu <alex@nytpu.com>2021-05-26 00:06:13 -0600
committernytpu <alex@nytpu.com>2021-05-26 14:27:19 -0600
commit7134a8e0abb2900986efdf54a797da23a46a3fd7 (patch)
tree86c5798878b8a7b917557755351744f9c2031428 /buffer.c
parentchange from int to long to accomodate longer files (diff)
downloaded-7134a8e0abb2900986efdf54a797da23a46a3fd7.tar.bz2
ed-7134a8e0abb2900986efdf54a797da23a46a3fd7.zip
add buffer.c and buffer.h for opening files and dealing with inserting/deleting rows
Diffstat (limited to 'buffer.c')
-rw-r--r--buffer.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/buffer.c b/buffer.c
new file mode 100644
index 0000000..d0f38ae
--- /dev/null
+++ b/buffer.c
@@ -0,0 +1,86 @@
+/* Copyright (c) 2021 nytpu <alex@nytpu.com>
+ * SPDX-License-Identifier: GPL-3.0-only
+ * For more license details, see LICENSE or <https://www.gnu.org/licenses/gpl-3.0.html>.
+ */
+
+#include "buffer.h"
+#include "common.h"
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+struct Buffer B;
+
+int
+open_file(const char *fn)
+{
+ B.dirty = false;
+ free(B.filename); // no check as free(NULL) is valid
+ size_t fnlen = strlen(fn) + 1;
+ B.filename = malloc(fnlen);
+ memcpy(B.filename, fn, fnlen);
+
+ FILE *f = fopen(fn, "r");
+ if (!f) {
+ if (errno != ENOENT) {
+ die("Opening file");
+ }
+ return -1;
+ }
+
+ char *l = NULL;
+ size_t lcap = 0;
+ ssize_t llen;
+ while ((llen = getline(&l, &lcap, f)) != -1) {
+ while (llen > 0 && (l[llen-1] == '\n' || l[llen-1] == '\r')) {
+ --llen;
+ }
+ insert_row(B.numrows, l, llen);
+ }
+ free(l);
+ fclose(f);
+ return 0;
+}
+
+int
+print_rows(long from, long to)
+{
+ if (from < 0 || to > B.numrows) return -1;
+ for (; from != to; ++from) {
+ puts(B.rows[from].chars);
+ }
+ return 0;
+}
+
+void
+insert_row(long at, char *r, size_t len)
+{
+ if (at > B.numrows) return;
+ B.rows = realloc(B.rows, (B.numrows+1) * sizeof(struct Row));
+ if (at != B.numrows) {
+ memmove(&B.rows[at+1], &B.rows[at], (B.numrows-at) * sizeof(struct Row));
+ for (long i = at+1; i <= B.numrows; ++i) ++B.rows[i].idx;
+ }
+
+ B.rows[at].size = len;
+ B.rows[at].chars = malloc(len + 1);
+ memcpy(B.rows[at].chars, r, len);
+ B.rows[at].chars[len] = '\0';
+ ++B.numrows;
+ B.dirty = true;
+}
+
+void
+delete_row(long at)
+{
+ if (at >= B.numrows) return;
+ free(B.rows[at].chars);
+ memmove(&B.rows[at], &B.rows[at+1], (B.numrows-at-1) * sizeof(struct Row));
+ for (long i = at; i < B.numrows; ++i) --B.rows[i].idx;
+ --B.numrows;
+ B.dirty = true;
+}