chatchai_j icon

part2.c

chatchai_j | PRO | 04/18/22 11:48:08 AM UTC | 0 ⭐ | 918 👁️ | Never ⏰ | []
C |

4.17 KB

|

None

|

0 👍

/

0 👎

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
 
#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;
}
 

Comments