commit fdaaa933fea81bf2e29ea586841a3ab6d74c7d28
parent 095ed2427f56c6876951af58fa745a308d13cd8b
Author: ssnf <ssnf@ssnf.xyz>
Date: Mon, 12 Jul 2021 09:03:40 +0000
added strings, files and window structures, and emalloc, erealloc and die functions
Diffstat:
M | Makefile | | | 2 | +- |
A | file.c | | | 47 | +++++++++++++++++++++++++++++++++++++++++++++++ |
M | posix.c | | | 25 | ++++++++++++++++++++----- |
M | sim.c | | | 92 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
M | sim.h | | | 49 | ++++++++++++++++++++++++++++++++++++++++++------- |
A | string.c | | | 84 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 257 insertions(+), 42 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
CC = c89
-CFLAGS = -Os -Wall -Wpedantic -Wno-deprecated-declarations
+CFLAGS = -Os -g -Wall -Wpedantic -Wno-deprecated-declarations -Wno-return-type
SRC = ${wildcard *.c}
OBJ = ${SRC:.c=.o}
diff --git a/file.c b/file.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sim.h"
+
+void
+file_close(File* f)
+{
+ str_close(f->s);
+ free(f->s);
+}
+
+void
+file_init(File* f)
+{
+ f->s = emalloc(sizeof(String));
+ str_init(f->s);
+ if (f->name)
+ file_load(f);
+ f->dot.p0 = f->dot.p1 = 0;
+}
+
+void
+file_load(File* f)
+{
+ FILE* disk;
+
+ if (!(disk = fopen(f->name, "r")))
+ return;
+ fseek(disk, 0, SEEK_END);
+ f->s->n = ftell(disk);
+ str_insure(f->s, f->s->n);
+ rewind(disk);
+ fread(f->s->s, f->s->n, 1, disk);
+ fclose(disk);
+}
+
+
+void
+file_save(File* f)
+{
+ FILE* disk;
+
+ disk = fopen(f->name, "w");
+ fwrite(f->s->s, f->s->n, 1, disk);
+ fclose(disk);
+}
diff --git a/posix.c b/posix.c
@@ -1,13 +1,24 @@
+#include <sys/ioctl.h>
#include <stdio.h>
#include <termios.h>
-void raw_init();
-void raw_end();
+#include "sim.h"
+
+void win_end();
+void win_init();
+void win_query();
static struct termios initial_state;
void
-raw_init()
+win_end()
+{
+ printf(ED CSI "H");
+ tcsetattr(0, TCSAFLUSH, &initial_state);
+}
+
+void
+win_init()
{
struct termios raw_state;
@@ -19,7 +30,11 @@ raw_init()
}
void
-raw_end()
+win_query(Window* w)
{
- tcsetattr(0, TCSAFLUSH, &initial_state);
+ struct winsize ws;
+
+ ioctl(0, TIOCGWINSZ, &ws);
+ w->wx = ws.ws_col;
+ w->wy = ws.ws_row;
}
diff --git a/sim.c b/sim.c
@@ -1,43 +1,77 @@
#include <stdio.h>
+#include <stdarg.h>
#include <stdlib.h>
+#include <string.h>
#include "sim.h"
-void file_open(char* name);
-
-char* file;
+File f;
+Window w;
void
-file_open(char* name)
+die(char* fmt, ...)
+{
+ va_list ap;
+
+ win_end();
+ f.name = "sim-crash.swap";
+ file_save(&f);
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ if (fmt[0] && fmt[strlen(fmt) - 1] == ':')
+ perror(NULL);
+ else
+ fputc('\n', stderr);
+ fprintf(stderr, "sim crashed. file saved to sim-crash.swap\n");
+ *fmt = *(char*)0;
+}
+
+void*
+emalloc(ulong n)
{
- FILE* f;
- ulong l;
-
- f = fopen(name, "r");
- fseek(f, 0, SEEK_END);
- l = ftell(f);
- fseek(f, 0, SEEK_SET);
- file = malloc(l);
- fread(file, l, 1, f);
- fclose(f);
+ void* p;
+
+ p = malloc(n);
+ if (!p)
+ die("malloc:");
+ memset(p, 0, n);
+ return p;
}
+void*
+erealloc(void *p, ulong n)
+{
+ p = realloc(p, n);
+ if (!p)
+ die("realloc:");
+ return p;
+}
int
-main()
+main(int argc, char* argv[])
{
- char a[16];
- uint i, j;
- ushort wx, wy;
-
- raw_init();
- file_open("sim.c");
- printf(CSRMAX DSR);
- for (i = 0; fread(a + i, 1, 1, stdin), a[i] != '\x1b'; ++i); /*buffer the input, or expect hell*/
- for (j = i; fread(a + j, 1, 1, stdin), a[j++] != 'R';);
- sscanf(a + i, "[%hu;%huR", &wy, &wx);
- printf(ED CSI "%hu;H", wy/2);
- puts(file);
- raw_end();
- return 0;
+ Address a;
+
+ win_init();
+ if (argv[1])
+ f.name = argv[1];
+ file_init(&f);
+ for (;;) {
+ win_query(&w);
+
+ switch (fgetc(stdin)) {
+ case 'q':
+ goto exit;
+ case 'h':
+ if (f.dot.p1)
+ f.dot.p0 = --f.dot.p1;
+ break;
+ case 'l':
+ if (f.dot.p1 < f.s->n)
+ f.dot.p0 = ++f.dot.p1;
+ }
+ }
+exit:
+ win_end();
}
diff --git a/sim.h b/sim.h
@@ -1,12 +1,47 @@
#define ED "\x1b[2J"
-#define DSR "\x1b[6n"
-#define CSRMAX "\x1b[999C\x1b[999B"
#define CSI "\x1b["
-typedef unsigned char uchar;
-typedef unsigned int uint;
+typedef long Posn;
+typedef unsigned char uchar;
+typedef unsigned int uint;
+typedef unsigned long ulong;
typedef unsigned short ushort;
-typedef unsigned long ulong;
+typedef struct Address Address;
+typedef struct File File;
+typedef struct String String;
+typedef struct Window Window;
-void raw_init();
-void raw_end();
+struct Address {
+ Posn p0, p1;
+};
+
+struct File {
+ String* s;
+ char* name;
+ Address dot;
+};
+
+struct String {
+ char* s;
+ ulong n; /*number of filled characters*/
+ ulong size;
+};
+
+struct Window {
+ ushort wx, wy;
+ ushort cx;
+};
+
+void die(char* fmt, ...);
+void* emalloc(ulong n);
+void* erealloc(void* p, ulong n);
+void file_init(File* f);
+void file_load(File* f);
+void file_save(File* f);
+void file_close(File* f);
+void str_init(String* s);
+void str_insure(String* s, ulong n);
+void str_close(String* s);
+void win_init();
+void win_end();
+void win_query(Window* w);
diff --git a/string.c b/string.c
@@ -0,0 +1,84 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "sim.h"
+
+#define MINSIZE 16
+#define MAXEMPTY 256
+
+void
+str_init(String* p)
+{
+ p->s = emalloc(MINSIZE * sizeof(*p->s));
+ p->n = 0;
+ p->size = MINSIZE;
+}
+
+void
+str_close(String* p)
+{
+ free(p->s);
+}
+
+void
+str_zero(String* p)
+{
+ if (p->size > MAXEMPTY) {
+ p->s = erealloc(p->s, MAXEMPTY * sizeof(*p->s));
+ p->size = MAXEMPTY;
+ }
+ p->n = 0;
+}
+
+void
+str_insure(String* p, ulong n)
+{
+ if (p->size < n) {
+ n += MAXEMPTY;
+ p->s = erealloc(p->s, n * sizeof(*p->s));
+ p->size = n;
+ return;
+ }
+ if (p->size - p->n > MAXEMPTY) {
+ p->size = p->n + MAXEMPTY;
+ p->s = erealloc(p->s, p->size * sizeof(*p->s));
+ }
+}
+
+void
+str_addc(String* p, int c)
+{
+ str_insure(p, p->n + 1);
+ p->s[p->n++] = c;
+}
+
+void
+strnadds(String* p, char* s, uint n)
+{
+ str_insure(p, p->n + n);
+ memmove(p->s + p->n, s, n);
+ p->n += n;
+}
+
+void
+str_delc(String* p)
+{
+ if (p->n)
+ p->s[p->n--] = 0;
+}
+
+void
+str_insert(String* p, String* q, Posn p0)
+{
+ str_insure(p, p->n + q->n);
+ memmove(p->s + p0 + q->n, p->s + p0, p->n - p0);
+ memmove(p->s + p0, q->s, q->n);
+ p->n += q->n;
+}
+
+void
+str_delete(String* p, Posn p1, Posn p2)
+{
+ memmove(p->s + p1, p->s + p2, p->n - p2);
+ p->n -= p2 - p1;
+}