#include #include #include #include #define BUFSZ 80 #define OP_QUIT 0 #define OP_ADD 1 #define OP_MUL 2 #define OP_DEL 3 #define OP_INS 4 #define RANGE_INVALID -1 #define RANGE_ALL 0 #define RANGE_ONE 1 #define RANGE_TWO 2 typedef struct Cell_t { int valid; int row,col; } cell; typedef struct Range_t { int Type; cell From; cell To; } range; int getOp(char *cmd) { if (strcmp(cmd,"QUIT")==0 || strcmp(cmd,"quit")==0) { return OP_QUIT; } if (strncmp(cmd,"ADD",3)==0 || strncmp(cmd,"add",3)==0) { return OP_ADD; } if (strncmp(cmd,"MUL",3)==0 || strncmp(cmd,"mul",3)==0) { return OP_MUL; } if (strncmp(cmd,"DEL",3)==0 || strncmp(cmd,"del",3)==0) { return OP_DEL; } if (strncmp(cmd,"INS",3)==0 || strncmp(cmd,"ins",3)==0) { return OP_INS; } return -1; } cell getCell(char *ptr) { cell c; char col = (char)*ptr; char row = (char)*(ptr+1); // fprintf(stderr, "DEBUG: cell[%s] = (%c,%c)\n", ptr, row, col); c.valid = 0; if ( (col >= 'A' && col <= 'E') && (row >= '1' && row <= '5') ) { c.valid = 1; c.row = row - '1'; c.col = col - 'A'; } return c; } range getRange(char *ptr) { range r; cell from, to; int l=strlen(ptr); // fprintf(stderr, "DEBUG: range '%s' l=%d\n", ptr, l); r.Type = RANGE_INVALID; if (l==3 && strcmp(ptr,"();")==0) { r.Type = RANGE_ALL; return r; } if (l==5 && *ptr == '(' && strcmp(ptr+3,");")==0) { from = getCell(ptr+1); if (from.valid == 1) { r.From = from; r.Type = RANGE_ONE; } return r; } if (l==8 && *ptr == '(' && *(ptr+3) == ':' && strcmp(ptr+6,");")==0) { r.Type = RANGE_TWO; from = getCell(ptr+1); to = getCell(ptr+4); if (from.valid == 1 && to.valid == 1) { int f_row = r.From.row; int t_row = r.To.row; int f_col = r.From.col; int t_col = r.To.col; if ( ((f_row == t_row) && (f_col < t_col)) || ((f_col == t_col) && (f_row < t_row)) ) { r.From = from; r.To = to; r.Type = RANGE_TWO; } } return r; } return r; } range getInsRange(char *ptr) { range r; cell from, to; int l=strlen(ptr); // fprintf(stderr, "DEBUG: range '%s' l=%d\n", ptr, l); r.Type = RANGE_INVALID; if (l==2 && strcmp(ptr,"()")==0) { r.Type = RANGE_ALL; return r; } if (l==4 && *ptr == '(' && strcmp(ptr+3,")")==0) { from = getCell(ptr+1); if (from.valid == 1) { r.From = from; r.Type = RANGE_ONE; } return r; } if (l==7 && *ptr == '(' && *(ptr+3) == ':' && strcmp(ptr+6,")")==0) { r.Type = RANGE_TWO; from = getCell(ptr+1); to = getCell(ptr+4); if (from.valid == 1 && to.valid == 1) { int f_row = r.From.row; int t_row = r.To.row; int f_col = r.From.col; int t_col = r.To.col; if ( ((f_row == t_row) && (f_col < t_col)) || ((f_col == t_col) && (f_row < t_row)) ) { r.From = from; r.To = to; r.Type = RANGE_TWO; } } return r; } return r; } void doOperation(int op, range r, double insval) { fprintf(stderr, "OP = %d\t", op); if (r.Type == RANGE_ALL) fprintf(stderr, "ALL"); else if (r.Type == RANGE_ONE) fprintf(stderr, "(%d,%d)", r.From.row, r.From.col); else if (r.Type == RANGE_TWO) fprintf(stderr, "(%d,%d)->(%d,%d)", r.From.row, r.From.col, r.To.row, r.To.col ); else fprintf(stderr, "[ERROR]"); if (op == OP_INS) { fprintf(stderr, " %1.2lf", insval); } fprintf(stderr, "\n"); } int readCmdLoop() { char buf[BUFSZ]; char cmd[BUFSZ], arg[BUFSZ], *ptr; int op, res; double insval; range r; while (1) { printf(">> "); if (fgets(buf, sizeof(buf), stdin)==NULL) { // if user press CTRL+D fprintf(stderr, "Good bye\n"); break; } // printf("[%s]\n", buf); res=sscanf(buf, "%s %s", cmd, arg); // printf("res=%d cmd='%s' arg='%s'\n", res, cmd, arg);S op = getOp(cmd); if (op==-1) { fprintf(stderr, "Invalid operation (%s)\n", cmd); continue; } if (op==OP_QUIT) { fprintf(stderr, "Good Bye\n"); break; } ptr = cmd+3; if (op == OP_INS) { r = getInsRange(ptr); sscanf(arg, "%lf", &insval); } else { r = getRange(ptr); } if (r.Type == RANGE_INVALID) { fprintf(stderr, "Wrong Range [%s]\n", ptr); continue; } doOperation(op, r, insval); } return 0; } int main(int argc, char **argv) { readCmdLoop(); return 0; }