sss

spreadsheets for plan9
git clone git://nsmpr.xyz/sss.git
Log | Files | Refs | README

commit 7bfc3db39946bae25edb0765683e33ad946d0c68
parent 786ac8de9fde2bce55e9a1bbafd5032c7cd03233
Author: glenda <glenda@9front.local>
Date:   Wed, 13 May 2020 08:59:21 +0000

initial commit take 2

Diffstat:
Acells.c | 167+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acells.h | 37+++++++++++++++++++++++++++++++++++++
Amkfile | 10++++++++++
Asss.c | 204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest_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)); +}