sheets

a simple spread sheet software
Log | Files | Refs

sheets.c (5283B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <stdbool.h>
      4 #include <ctype.h>
      5 #include <string.h>
      6 #include <math.h>
      7 
      8 #include "expr.h"
      9 #include "sheets.h"
     10 
     11 #define ACCURACY 2
     12 
     13 #define arg1(s, n) if (strcmp(argv[i], s) == 0) {\
     14 	i++; \
     15 	if (i >= argc) {\
     16 		fprintf(stderr, "expected value after %s option\n", s);\
     17 		exit(1);\
     18 	}
     19 
     20 #define arg2(s, n) else if (strcmp(argv[i], s) == 0) {\
     21 	i++; \
     22 	if (i  >= argc) {\
     23 		fprintf(stderr, "expected value after %s option\n", s);\
     24 		exit(1);\
     25 	}
     26 
     27 
     28 void clearstdin() {
     29 	while (getc(stdin) != '\n') continue;
     30 }
     31 
     32 void freeSheet(sheet *s) {
     33 	for (int y = 0; y < s->height; y++) {
     34 		for (int x = 0; x < s->width; x++) 
     35 			freeExpr(s->cells[y][x]);
     36 		free(s->cells[y]);
     37 	}
     38 	free(s->cells);
     39 	free(s);
     40 }
     41 
     42 sheet *makeSheet(int x, int y) {
     43 	sheet *s = calloc(1, sizeof(sheet));
     44 	s->width = x;
     45 	s->height = y;
     46 
     47 	s->cells = calloc(1, sizeof(expr **) * y);
     48 	for (int i = 0; i < y; i++) {
     49 		s->cells[i] = calloc(1, sizeof(expr *) * x);
     50 		for (int j = 0; j < x; j++) 
     51 			s->cells[i][j] = makeNumber(0);
     52 	}
     53 	return s;
     54 }
     55 
     56 void export(sheet *s, FILE *f) {
     57 	fprintf(f, "%d %d\n", s->width, s->height);
     58 	for (int y = 0; y < s->height; y++) {
     59 		fprintf(f, "\n|");
     60 		for (int x = 0; x < s->width; x++) 
     61 			fprintf(f, "%s|", s->cells[y][x]->expr);
     62 	}	
     63 	fprintf(f, "\n");
     64 }
     65 
     66 sheet *import(FILE *f) {
     67 	int width, height;
     68 	sheet *s;
     69 
     70 	fscanf(f, "%d %d\n\n|", &width, &height);
     71 	s = makeSheet(width, height);
     72 
     73 	for (int y = 0; y < s->height; y++) {
     74 		for (int x = 0; x < s->width; x++) {
     75 			in = Pin;
     76 			char expr[256] = {0};
     77 			fscanf(f, "%[^|]s", expr); 
     78 			fscanf(f, "|");
     79 
     80 			memcpy(in, expr, 256);
     81 			s->cells[y][x] = parseExpr();
     82 			s->cells[y][x]->expr = strdup(expr);
     83 		}
     84 		fscanf(f, "\n|");
     85 	}
     86 	return s;
     87 }
     88 
     89 void inputln(char *s, int size, FILE *f) {
     90 	fflush(stdout);
     91 	fgets(s, size, f);
     92 	*strchr(s, '\n') = 0;
     93 }
     94 
     95 void printSheetContents(sheet *s, int X, int Y) {
     96 	int longest[s->width];
     97 	memset(longest, 0, sizeof(int) * s->width);
     98 	
     99 	for (int y = 0; y < s->height; y++) 
    100 		for (int x = 0; x < s->width; x++) 
    101 			if (strlen(s->cells[y][x]->expr) > longest[x])
    102 				longest[x] = strlen(s->cells[y][x]->expr);
    103 
    104 	for (int y = 0; y < s->height; y++) {
    105 		printf("\n|");
    106 		for (int x = 0; x < s->width; x++)
    107 			if (strcmp(s->cells[y][x]->expr, "0") == 0)
    108 				printf(" %*s |", longest[x], " ");
    109 			else if (X == x && Y == y)
    110 				printf("\e[1;34m %*s \e[0m|", longest[x], s->cells[y][x]->expr); 
    111 			else 
    112 				printf(" %*s |", longest[x], s->cells[y][x]->expr); 
    113 	}
    114 	printf("\n");
    115 }
    116 
    117 void shell(char *prompt, FILE *fin) {
    118 	sheet *s;
    119 	if (!fin) {
    120 invalid:
    121 		int x = -1;
    122 		int y = -1;
    123 		printf("What size sheet do you want 'x,y': ");
    124 		scanf("%d,%d", &x, &y);
    125 		clearstdin();
    126 		if (x == -1 || y == -1) {
    127 			printf("Please input a valid expression!\n");
    128 			goto invalid;
    129 		}
    130 		s = makeSheet(x, y);
    131 	} else s = import(fin);
    132 
    133 
    134 	struct expr *e;
    135 	int x = 0;
    136 	int y = 0;
    137 	FILE *f;
    138 	char fname[256];
    139 
    140 
    141 	for (;;) {
    142 		in = Pin;
    143 		printf("(%d, %d) %s", x, y, prompt);
    144 		memset(in, 0, 256);
    145 		inputln(in, 256, stdin);
    146 
    147 		switch (in[0]) {
    148 			case 'u': y--; break;
    149 			case 'd': y++; break;
    150 			case 'l': x--; break;
    151 			case 'r': x++; break;
    152 			case 'q': 
    153 				  freeSheet(s);
    154 				  printf("Exiting\n"); 
    155 				  exit(0);
    156 			case 'p': printf("(%d,%d) %s\n", x, y,s->cells[y][x]->expr); break;
    157 			case 'P': 
    158 				  printSheetContents(s, x, y);
    159 				  break;
    160 			case 'e': 
    161 				  for (int i = 0; i < s->height; i++) {
    162 					  printf("\n|");
    163 					  for (int j = 0; j < s->width; j++)
    164 						  if (j == x && i == y)
    165 							  printf("\e[1;34m %.*f \e[0m|", ACCURACY, evalExpr(s->cells[i][j], s)); 
    166 						  else 
    167 							  printf(" %.*f |", ACCURACY, evalExpr(s->cells[i][j], s)); 
    168 				  }
    169 				  printf("\n");
    170 				  break;
    171 			case 'i': 
    172 				  in = Pin;
    173 				  memset(in, 0, 256);
    174 				  inputln(in, 256, stdin);
    175 
    176 				  freeExpr(s->cells[y][x]);
    177 
    178 				  s->cells[y][x] = parseExpr();
    179 				  s->cells[y][x]->expr = strdup(Pin);
    180 
    181 				  break;
    182 			case 's': 
    183 				  printf("file to save to: ");
    184 				  inputln(fname, 256, stdin);
    185 				  f = fopen(fname, "w");
    186 				  export(s, f); 
    187 				  fclose(f);
    188 				  break;
    189 			case 'o': 
    190 				  printf("file to open: ");
    191 				  inputln(fname, 256, stdin);
    192 				  f = fopen(fname, "r");
    193 				  if (!f) 
    194 					  fprintf(stderr, "couldn't open file!\n");
    195 				  else {
    196 					  freeSheet(s);
    197 					  s = import(f);
    198 					  fclose(f);
    199 				  }
    200 				  break;
    201 			default:
    202 				  fprintf(stderr, "unknown cmd '%s'!\n", in);
    203 				  break;
    204 
    205 		}
    206 
    207 		if (x > s->width) {
    208 			fprintf(stderr, "error: x:%d is out of range (0 - %d)\n", x, s->width);
    209 			x = s->width;
    210 		}
    211 		if (x < 0) {
    212 			fprintf(stderr, "error: x:%d is out of range (0 - %d)\n", x, s->width);
    213 			x = 0;
    214 		}
    215 		if (y > s->height) {
    216 			fprintf(stderr, "error: y:%d is out of range (0 - %d)\n", y, s->height);
    217 			y = s->height;
    218 		}
    219 		if (y < 0) {
    220 			fprintf(stderr, "error: y:%d is out of range (0 - %d)\n", y, s->height);
    221 			y = 0;
    222 		}
    223 	}
    224 }
    225 			
    226 
    227 int main(int argc, char **argv) {
    228 	setbuf(stdout, NULL);
    229 
    230 	in = malloc(256);
    231 	Pin = in;
    232 
    233 	char *prompt = "> ";
    234 	FILE *input = NULL;
    235 
    236 	for (int i = 1; i < argc; i++) {
    237 		arg1("-p", true) 
    238 			prompt = argv[i];
    239 		}
    240 		else {
    241 			input = fopen(argv[i], "r");
    242 			if (!input) {
    243 				fprintf(stderr, "couldn't open file\n");
    244 				exit(0);
    245 			}
    246 		}
    247 	}
    248 
    249 	shell(prompt, input);
    250 	free(in);
    251 }
    252 
    253 
    254 
    255 
    256 
    257 
    258 
    259 
    260 
    261 
    262 
    263 
    264 
    265 
    266 
    267 
    268