ed

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 9caf5c8ebc2dd02d4fd0574c6936ab6bf295337a
Author: thing1 <l.standen@posteo.com>
Date:   Fri, 17 Oct 2025 21:13:19 +0100

init commit

Diffstat:
A.gitignore | 2++
AMakefile | 19+++++++++++++++++++
ATODO.md | 3+++
Aed.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aparse.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aparse.h | 7+++++++
Atypes.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Atypes.h | 11+++++++++++
Autil.c | 26++++++++++++++++++++++++++
Autil.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);