commit 7bfc3db39946bae25edb0765683e33ad946d0c68
parent 786ac8de9fde2bce55e9a1bbafd5032c7cd03233
Author: glenda <glenda@9front.local>
Date: Wed, 13 May 2020 08:59:21 +0000
initial commit take 2
Diffstat:
A | cells.c | | | 167 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | cells.h | | | 37 | +++++++++++++++++++++++++++++++++++++ |
A | mkfile | | | 10 | ++++++++++ |
A | sss.c | | | 204 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | test_cells.c | | | 24 | ++++++++++++++++++++++++ |
5 files changed, 442 insertions(+), 0 deletions(-)
diff --git a/cells.c b/cells.c
@@ -0,0 +1,166 @@
+#include <u.h>
+#include <libc.h>
+
+#include "cells.h"
+
+/*** ADDRESS ***/
+
+Addr xy2addr(long x, long y)
+{
+ Addr a;
+ a.x = x;
+ a.y = y;
+ return a;
+}
+
+int
+addrcmp(Addr addr1, Addr addr2)
+{
+ if ((addr1.x != addr2.x) || (addr1.y != addr2.y)) return -1;
+ return 0;
+}
+
+/*** VALUES ***/
+
+Value
+mk_value(Addr addr, char *data)
+{
+ Value v;
+ v.addr = addr;
+ v.data = strdup(data);
+ return v;
+}
+
+void
+free_value(Value v)
+{
+ free(v.data);
+}
+
+/*** TABLE ***/
+
+void
+free_table(Table T)
+{
+ while (*T != nil) {
+ free_value(**T);
+ free(*T);
+ T++;
+ }
+}
+
+Table
+empty_table(void)
+{
+ Table T;
+ T = malloc(sizeof(Value*));
+ T[0] = nil;
+ return T;
+}
+
+Table
+copy_table(Table T)
+{
+ Table N;
+ long i, len;
+ N = empty_table();
+ for (len = 0; T[len] != nil; len++);
+ N = realloc(N, sizeof(Value*) * (len + 1));
+ for (i = 0; i < len; i++) {
+ N[i] = malloc(sizeof(Value));
+ *N[i] = mk_value(T[i]->addr, T[i]->data);
+ }
+ N[len] = nil;
+ return N;
+}
+
+Table
+eval_table(Table T)
+{
+ // TODO
+ Table N;
+ N = copy_table(T);
+ return N;
+}
+
+Table
+table_put(Table T, Value v)
+{
+ Table N;
+ long n;
+ N = copy_table(T);
+ for (n = 0; N[n] != nil; n++) {
+ if (addrcmp(N[n]->addr, v.addr) == 0) {
+ free_value(*N[n]);
+ *N[n] = v;
+ return N;
+ }
+ }
+ N = realloc(N, sizeof(Value*) * (n + 1));
+ N[n] = malloc(sizeof(Value));
+ *N[n] = v;
+ N[n+1] = nil;
+ return N;
+}
+
+Value
+table_get(Table T, Addr addr)
+{
+ Value **V, v;
+ v.addr = addr;
+ v.data = "";
+ for (V = T; *V != nil; V++) {
+ if (addrcmp((*V)->addr, addr) == 0) {
+ v.data = strdup((*V)->data);
+ break;
+ }
+ }
+ return v;
+}
+
+Table
+table_read(char *path)
+{
+ Table T, N;
+ char b, *buf;
+ long bufsize, col, row;
+ int fd;
+ T = empty_table();
+ bufsize = 0;
+ col = 0;
+ buf = nil;
+ row = 0;
+ fd = open(path, OREAD);
+ if (fd == 0) return nil;
+ while (read(fd, &b, 1) > 0) {
+ switch (b){
+ case '\t':
+ N = table_put(T, mk_value(xy2addr(row, col), buf));
+ free_table(T);
+ T = N;
+ bufsize = 0;
+ buf = realloc(buf, 0);
+ col++;
+ break;
+ case '\n':
+ N = table_put(T, mk_value(xy2addr(row, col), buf));
+ free_table(T);
+ T = N;
+ bufsize = 0;
+ buf = realloc(buf, 0);
+ row++;
+ col = 0;
+ break;
+ default:
+ buf = realloc(buf, bufsize+2);
+ buf[bufsize] = b;
+ buf[bufsize+1] = 0;
+ bufsize++;
+ }
+ }
+ N = table_put(T, mk_value(xy2addr(row, col), buf));
+ free_table(T);
+ T = N;
+ realloc(buf, 0);
+ return T;
+}
+\ No newline at end of file
diff --git a/cells.h b/cells.h
@@ -0,0 +1,36 @@
+/*** ADDRESS ***/
+typedef struct Addr Addr;
+
+struct Addr {
+ long x;
+ long y;
+};
+
+Addr xy2addr(long, long);
+int addrcmp(Addr, Addr);
+
+/*** VALUES ***/
+typedef struct Value Value;
+
+struct Value {
+ Addr addr;
+ char *data;
+};
+
+Value mk_value(Addr, char *data);
+void free_value(Value);
+
+/*** TABLE ***/
+typedef Value** Table;
+
+void free_table(Table);
+Table empty_table(void);
+Table copy_table(Table);
+Table eval_table(Table);
+Table table_put(Table, Value);
+Value table_get(Table, Addr);
+Table table_read(char*);
+
+// TODO:
+Table table_join(Table, Table);
+Table table_transform(Table, void (*func)(void**), void**);
+\ No newline at end of file
diff --git a/mkfile b/mkfile
@@ -0,0 +1,10 @@
+</$objtype/mkfile
+
+TARG=sss
+
+OFILES=\
+ sss.$O\
+ cells.$O\
+
+BIN=/$objtype/bin
+</sys/src/cmd/mkone
diff --git a/sss.c b/sss.c
@@ -0,0 +1,203 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <thread.h>
+#include <mouse.h>
+#include <cursor.h>
+#include <keyboard.h>
+
+#include "cells.h"
+
+typedef struct Hist Hist;
+
+struct Hist {
+ Table T;
+ Hist *prev;
+};
+
+Hist *hp;
+
+int defcwidth, defcheight;
+
+Image *Iborder, *Ibg, *Ifg, *Ibg2;
+
+void usage(void);
+void clear(void);
+void draw_columns(void);
+void draw_cells(void);
+void draw_cell(Image*, Rectangle, Image*, Image*, Image*, char*, int);
+void draw_rows(void);
+void colors(void);
+
+void
+threadmain(int argc, char **argv)
+{
+ Mousectl *mc;
+ Keyboardctl *kc;
+ Mouse mv;
+ Rune kv;
+ int rv[2];
+ ARGBEGIN{
+ default:
+ usage();
+ break;
+ }ARGEND;
+
+ if(initdraw(0, 0, "Super Spreadsheet 64!") < 0)
+ sysfatal("inidraw failed: %r");
+ if((mc = initmouse(0, screen)) == nil)
+ sysfatal("initmouse failed: %r");
+ if((kc = initkeyboard(0)) == nil)
+ sysfatal("initkeyboard failed: %r");
+ Alt alts[4] = {
+ {kc->c, &kv, CHANRCV},
+ {mc->c, &mv, CHANRCV},
+ {mc->resizec, rv, CHANRCV},
+ {0, 0, CHANEND},
+ };
+
+ colors();
+
+ defcheight = font->height + 4;
+ defcwidth = stringwidth(font, "01234567") + 4;
+
+ hp = malloc(sizeof(Hist));
+ if (argc == 1) hp->T = table_read(argv[0]);
+ else hp->T = empty_table();
+ if (hp->T == nil) exits("failed to create initial table");
+
+ clear();
+ draw_columns();
+ draw_rows();
+ draw_cells();
+ flushimage(display, 1);
+ for (;;) {
+ switch (alt(alts)) {
+ case 0: /* keyboard */
+ if (kv == 0x7f) threadexitsall(nil);
+ break;
+ case 1: /* mouse */
+ break;
+ case 2: /* resize */
+ if(getwindow(display, Refnone) < 0)
+ sysfatal("resize failed: %r");
+ clear();
+ draw_columns();
+ draw_rows();
+ draw_cells();
+ flushimage(display, 1);
+ break;
+ }
+ }
+}
+
+void
+colors(void)
+{
+ Ibg2 = allocimage(display, Rect(0,0,1,1), RGBA32, 1, 0xEEEEEEFF);
+ Ibg = display->white;
+ Iborder = display->black;
+ Ifg = display->black;
+}
+
+void
+usage(void)
+{
+ fprint(2, "usage: %s", argv0);
+ exits("usage");
+}
+void
+clear(void)
+{
+ draw(screen, screen->r, display->black, 0, ZP);
+}
+
+void
+draw_columns(void)
+{
+ Point pt;
+ Rectangle r;
+ long col;
+ char *colnum;
+ col = 0;
+ pt = addpt(Pt(defcwidth, 0), screen->r.min);
+ while (pt.x < screen->r.max.x - defcwidth + 1) {
+ r = rectaddpt(Rect(0, 0, defcwidth, defcheight), pt);
+ colnum = smprint("%ld", col);
+ draw_cell(screen, r, Ibg2, Iborder, Ifg, colnum, 0);
+ free(colnum);
+ pt.x += defcwidth;
+ col++;
+ }
+}
+
+void
+draw_rows(void)
+{
+ Point pt;
+ Rectangle r;
+ long row;
+ char *colnum;
+ row = 0;
+ pt = addpt(Pt(0, defcheight), screen->r.min);
+ while (pt.y < screen->r.max.y - defcheight + 1) {
+ r = rectaddpt(Rect(0, 0, defcwidth, defcheight), pt);
+ colnum = smprint("%ld", row);
+ draw_cell(screen, r, Ibg2, Iborder, Ifg, colnum, 0);
+ free(colnum);
+ pt.y += defcheight;
+ row++;
+ }
+}
+
+void
+draw_cell(Image *dst, Rectangle r, Image *bg, Image *brd, Image*fg, char *s, int align)
+{
+ Rectangle rl, rr, rt, rb;
+ int dx;
+ rl = r;
+ rr = r;
+ rt = r;
+ rb = r;
+ rl.max.x = rl.min.x + 1;
+ rr.min.x = rr.max.x - 1;
+ rt.max.y = rt.min.y + 1;
+ rb.min.y = rb.max.y - 1;
+ draw(dst, r, bg, 0, ZP);
+ draw(dst, rl, brd, 0, ZP);
+ draw(dst, rr, brd, 0, ZP);
+ draw(dst, rt, brd, 0, ZP);
+ draw(dst, rb, brd, 0, ZP);
+ dx = (r.max.x - r.min.x - stringwidth(font,s));
+ if (align == 0) dx = dx / 2;
+ if (align < 0) dx = 0;
+ string(dst, addpt(Pt(2 + dx, 2), r.min), fg, ZP, font, s);
+}
+
+
+void
+draw_cells(void)
+{
+ Point pt;
+ Rectangle r;
+ long col, row;
+ char *text;
+ Value v;
+ col = 0;
+ row = 0;
+ pt = addpt(Pt(defcwidth, defcheight), screen->r.min);
+ while (pt.y < screen->r.max.y - defcheight + 1){
+ r = rectaddpt(Rect(0,0,defcwidth, defcheight), pt);
+ v = table_get(hp->T, xy2addr(row, col));
+ text = v.data;
+ draw_cell(screen, r, Ibg, Iborder, Ifg, text, -1);
+ pt.x += defcwidth;
+ col++;
+ if (pt.x > screen->r.max.x - defcwidth + 1){
+ pt.x = screen->r.min.x + defcwidth;
+ pt.y += defcheight;
+ row++;
+ col = 0;
+ }
+ }
+}
+\ No newline at end of file
diff --git a/test_cells.c b/test_cells.c
@@ -0,0 +1,24 @@
+#include <u.h>
+#include <libc.h>
+
+#include "cells.h"
+
+#define ECHO(X) print("=> %s\n", "X"); X
+
+void
+main(void)
+{
+ Table T, TT, N;
+ Value v, r;
+ char *str = "hello";
+ ECHO(T = empty_table());
+ ECHO(v = mk_value(xy2addr(0, 0), str));
+ ECHO(TT = copy_table(T));
+ ECHO(N = table_put(T, v));
+ ECHO(r = table_get(N, xy2addr(0, 0)));
+ print("data = %s\n", r.data);
+ ECHO(free_table(TT));
+ ECHO(free_table(T));
+ ECHO(free_value(v));
+ ECHO(free_table(N));
+}