commit 9caf5c8ebc2dd02d4fd0574c6936ab6bf295337a
Author: thing1 <l.standen@posteo.com>
Date: Fri, 17 Oct 2025 21:13:19 +0100
init commit
Diffstat:
| A | .gitignore | | | 2 | ++ |
| A | Makefile | | | 19 | +++++++++++++++++++ |
| A | TODO.md | | | 3 | +++ |
| A | ed.c | | | 58 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | parse.c | | | 61 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | parse.h | | | 7 | +++++++ |
| A | types.c | | | 50 | ++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | types.h | | | 11 | +++++++++++ |
| A | util.c | | | 26 | ++++++++++++++++++++++++++ |
| A | util.h | | | 2 | ++ |
10 files changed, 239 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+*.o
+ed
diff --git a/Makefile b/Makefile
@@ -0,0 +1,19 @@
+CC=c89
+CFLAGS=-ggdb -pedantic -fsanitize=address -Wall -Wextra
+CPPFLAGS=-D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=200112L
+
+SRC = types.c util.c parse.c ed.c
+OBJ = ${SRC:.c=.o}
+
+.POSIX:
+all: ed
+
+.c.o:
+ ${CC} -c ${CFLAGS} ${CPPFLAGS} $<
+
+ed: ${OBJ}
+ ${CC} -o $@ ${OBJ} ${CFLAGS}
+
+clean:
+ rm -rf *.o ed
+
diff --git a/TODO.md b/TODO.md
@@ -0,0 +1,3 @@
+- add a shell, it should work by switching on the cmd
+- to read the input it should use get line
+
diff --git a/ed.c b/ed.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "types.h"
+#include "util.h"
+#include "parse.h"
+
+dl_list *
+convert_file(char *file) {
+ dl_list *current = NULL, *prev = NULL, *start;
+ char *line_end;
+ bool end = false;
+
+ while (!end) {
+ if ((line_end = strchr(file, '\n')))
+ *line_end = 0;
+ else {
+ *(line_end = strchr(file, 0)) = 0;
+ end = true;
+ }
+
+ if (!current) {
+ current = zmalloc(sizeof(dl_list));
+ start = current;
+ }
+
+ current->str = strdup(file);
+ current->next = zmalloc(sizeof(dl_list));
+ current->prev = prev;
+ prev = current;
+ current = current->next;
+
+ file = line_end + 1;
+ }
+
+ return start;
+}
+
+int
+main() {
+ FILE *f = fopen("ed.c", "r");
+ char *raw_file;
+ dl_list *file;
+
+ if (!f)
+ return 1;
+
+ raw_file = drain_file(f);
+
+ file = convert_file(raw_file);
+
+ fclose(f);
+ free(raw_file);
+ free_dl_list(file);
+ return 0;
+}
diff --git a/parse.c b/parse.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "types.h"
+#include "util.h"
+#include "parse.h"
+
+cmd *
+parse_err(const char *msg) {
+ fprintf(stderr, "cmd: %s\n", msg);
+
+ return NULL;
+}
+
+cmd *
+cmd_parse(char *str) {
+ cmd *c;
+ char *arg, *arg_end, prev;
+ bool end = false;
+
+ if (!(*str))
+ return parse_err("empty");
+
+ c = zmalloc(sizeof(cmd));
+ c->op = *(str++);
+ c->argc = 0;
+
+ if (*str == 0)
+ return c;
+
+
+ while (!end) {
+ if (*str != '/' && *str != 0)
+ return parse_err("expected argument or cmd end");
+ str++;
+
+ for (arg_end = str; *arg_end && *arg_end != '/' && prev != '\\'; prev = *(arg_end++));
+ if (!*arg_end)
+ end = true;
+ *arg_end = 0;
+ arg = strdup(str);
+ str = arg_end;
+
+ c->argc++;
+ c->args = realloc(c->args, c->argc * sizeof(char **));
+ c->args[c->argc - 1] = arg;
+ }
+
+ return c;
+}
+
+void
+cmd_free(cmd *c) {
+ int i;
+ for (i = 0; i < c->argc; i++)
+ free(c->args[i]);
+ free(c->args);
+ free(c);
+}
diff --git a/parse.h b/parse.h
@@ -0,0 +1,7 @@
+typedef struct cmd {
+ char op, **args;
+ int argc;
+} cmd;
+
+cmd *cmd_parse(char *);
+void cmd_free(cmd *);
diff --git a/types.c b/types.c
@@ -0,0 +1,50 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "types.h"
+#include "util.h"
+
+dl_list *
+new_dl_list(char *str) {
+ dl_list *new = zmalloc(sizeof(dl_list));
+ new->str = str;
+ return new;
+}
+
+dl_list *
+end_dl_list(dl_list *l) {
+ if (l->next)
+ return end_dl_list(l->next);
+ return l;
+}
+
+dl_list *
+start_dl_list(dl_list *l) {
+ if (l->prev)
+ return end_dl_list(l->prev);
+ return l;
+}
+
+
+
+void
+append_dl_list(dl_list *l1, dl_list *l2) {
+ dl_list *swp = l1->next, *end = end_dl_list(l2);
+ l1->next = l2;
+ end->next = swp;
+}
+
+dl_list *
+insert_dl_list(dl_list *l1, dl_list *l2) {
+ dl_list *swp = l1->prev, *end = end_dl_list(l2);
+ l1->prev = l2;
+ end->next = swp;
+ return start_dl_list(l2);
+}
+
+void
+free_dl_list(dl_list *l) {
+ if (l->next)
+ free_dl_list(l->next);
+ free(l->str);
+ free(l);
+}
diff --git a/types.h b/types.h
@@ -0,0 +1,11 @@
+typedef struct dl_list {
+ char *str;
+ struct dl_list *next, *prev;
+} dl_list;
+
+dl_list *new_dl_list(char *);
+dl_list *end_dl_list(dl_list *);
+dl_list *start_dl_list(dl_list *);
+void append_dl_list(dl_list *, dl_list *);
+dl_list *insert_dl_list(dl_list *, dl_list *);
+void free_dl_list(dl_list *);
diff --git a/util.c b/util.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *
+drain_file(FILE *f) {
+ char *contents;
+ int len;
+
+ fseek(f, 0, SEEK_END);
+ len = ftell(f);
+ rewind(f);
+
+ contents = malloc(len + 1);
+ contents[len] = 0;
+
+ fread(contents, 1, len, f);
+ return contents;
+}
+
+void *
+zmalloc(size_t size) {
+ void *ptr = malloc(size);
+ memset(ptr, 0, size);
+ return ptr;
+}
diff --git a/util.h b/util.h
@@ -0,0 +1,2 @@
+char *drain_file(FILE *);
+void *zmalloc(size_t);