#include #include #include #include #include #include #include "expr.h" #include "sheets.h" #define ACCURACY 2 #define arg1(s, n) if (strcmp(argv[i], s) == 0) {\ i++; \ if (i >= argc) {\ fprintf(stderr, "expected value after %s option\n", s);\ exit(1);\ } #define arg2(s, n) else if (strcmp(argv[i], s) == 0) {\ i++; \ if (i >= argc) {\ fprintf(stderr, "expected value after %s option\n", s);\ exit(1);\ } void clearstdin() { while (getc(stdin) != '\n') continue; } void freeSheet(sheet *s) { for (int y = 0; y < s->height; y++) { for (int x = 0; x < s->width; x++) freeExpr(s->cells[y][x]); free(s->cells[y]); } free(s->cells); free(s); } sheet *makeSheet(int x, int y) { sheet *s = calloc(1, sizeof(sheet)); s->width = x; s->height = y; s->cells = calloc(1, sizeof(expr **) * y); for (int i = 0; i < y; i++) { s->cells[i] = calloc(1, sizeof(expr *) * x); for (int j = 0; j < x; j++) s->cells[i][j] = makeNumber(0); } return s; } void export(sheet *s, FILE *f) { fprintf(f, "%d %d\n", s->width, s->height); for (int y = 0; y < s->height; y++) { fprintf(f, "\n|"); for (int x = 0; x < s->width; x++) fprintf(f, "%s|", s->cells[y][x]->expr); } fprintf(f, "\n"); } sheet *import(FILE *f) { int width, height; sheet *s; fscanf(f, "%d %d\n\n|", &width, &height); s = makeSheet(width, height); for (int y = 0; y < s->height; y++) { for (int x = 0; x < s->width; x++) { in = Pin; char expr[256] = {0}; fscanf(f, "%[^|]s", expr); fscanf(f, "|"); memcpy(in, expr, 256); s->cells[y][x] = parseExpr(); s->cells[y][x]->expr = strdup(expr); } fscanf(f, "\n|"); } return s; } void inputln(char *s, int size, FILE *f) { fflush(stdout); fgets(s, size, f); *strchr(s, '\n') = 0; } void printSheetContents(sheet *s, int X, int Y) { int longest[s->width]; memset(longest, 0, sizeof(int) * s->width); for (int y = 0; y < s->height; y++) for (int x = 0; x < s->width; x++) if (strlen(s->cells[y][x]->expr) > longest[x]) longest[x] = strlen(s->cells[y][x]->expr); for (int y = 0; y < s->height; y++) { printf("\n|"); for (int x = 0; x < s->width; x++) if (strcmp(s->cells[y][x]->expr, "0") == 0) printf(" %*s |", longest[x], " "); else if (X == x && Y == y) printf("\e[1;34m %*s \e[0m|", longest[x], s->cells[y][x]->expr); else printf(" %*s |", longest[x], s->cells[y][x]->expr); } printf("\n"); } void shell(char *prompt, FILE *fin) { sheet *s; if (!fin) { invalid: int x = -1; int y = -1; printf("What size sheet do you want 'x,y': "); scanf("%d,%d", &x, &y); clearstdin(); if (x == -1 || y == -1) { printf("Please input a valid expression!\n"); goto invalid; } s = makeSheet(x, y); } else s = import(fin); struct expr *e; int x = 0; int y = 0; FILE *f; char fname[256]; for (;;) { in = Pin; printf("(%d, %d) %s", x, y, prompt); memset(in, 0, 256); inputln(in, 256, stdin); switch (in[0]) { case 'u': y--; break; case 'd': y++; break; case 'l': x--; break; case 'r': x++; break; case 'q': freeSheet(s); printf("Exiting\n"); exit(0); case 'p': printf("(%d,%d) %s\n", x, y,s->cells[y][x]->expr); break; case 'P': printSheetContents(s, x, y); break; case 'e': for (int i = 0; i < s->height; i++) { printf("\n|"); for (int j = 0; j < s->width; j++) if (j == x && i == y) printf("\e[1;34m %.*f \e[0m|", ACCURACY, evalExpr(s->cells[i][j], s)); else printf(" %.*f |", ACCURACY, evalExpr(s->cells[i][j], s)); } printf("\n"); break; case 'i': in = Pin; memset(in, 0, 256); inputln(in, 256, stdin); freeExpr(s->cells[y][x]); s->cells[y][x] = parseExpr(); s->cells[y][x]->expr = strdup(Pin); break; case 's': printf("file to save to: "); inputln(fname, 256, stdin); f = fopen(fname, "w"); export(s, f); fclose(f); break; case 'o': printf("file to open: "); inputln(fname, 256, stdin); f = fopen(fname, "r"); if (!f) fprintf(stderr, "couldn't open file!\n"); else { freeSheet(s); s = import(f); fclose(f); } break; default: fprintf(stderr, "unknown cmd '%s'!\n", in); break; } if (x > s->width) { fprintf(stderr, "error: x:%d is out of range (0 - %d)\n", x, s->width); x = s->width; } if (x < 0) { fprintf(stderr, "error: x:%d is out of range (0 - %d)\n", x, s->width); x = 0; } if (y > s->height) { fprintf(stderr, "error: y:%d is out of range (0 - %d)\n", y, s->height); y = s->height; } if (y < 0) { fprintf(stderr, "error: y:%d is out of range (0 - %d)\n", y, s->height); y = 0; } } } int main(int argc, char **argv) { setbuf(stdout, NULL); in = malloc(256); Pin = in; char *prompt = "> "; FILE *input = NULL; for (int i = 1; i < argc; i++) { arg1("-p", true) prompt = argv[i]; } else { input = fopen(argv[i], "r"); if (!input) { fprintf(stderr, "couldn't open file\n"); exit(0); } } } shell(prompt, input); free(in); }