#include #include #include #include "buff.h" #include line_t *b_start = NULL; line_t *b_end = NULL; line_t *cur = NULL; int num = 0; int pos = 0; /* addr1 is the last address, while addr2 is the previous one */ int addr1, addr2; char *fname; const char* skip_blank(const char **c){ while (isblank(**c)) (*c)++; return *c; } int get_addr(const char **cmd){ int addr, n, got; char sign = 0, comma = 0, semic = 0; const char *c; addr1 = addr2 = -1; c = *cmd; while(*c){ c = skip_blank(&c); n = 0; got = 0; if (isdigit(*c)){ while (isdigit(*c)){ got = 1; n = n * 10 + *c - '0', c++; } if (got){ if (addr1 > -1 ) addr2 = addr1; addr1 = n; } } else { switch(*c){ case '.': if (addr1 > -1) addr2 = addr1; addr1 = pos; break; case '$': if (addr1 > -1) addr2 = addr1; addr1 = num; break; case ',': comma = 1; if (addr1 ==-1) addr2 = 1, addr1=num; else if (addr1 < addr2){ *cmd = c++; return -1; } break; case ';': semic = 1; if (addr1 == -1) addr2 = pos, addr1=num; else if (addr1 < addr2){ *cmd = c++; return -1; } break; default: goto check; } c++; } } check: *cmd = c; fprintf(stderr, " >>> get_addr: addr1: %d addr2: %d\n", addr1, addr2); if (addr1 > num || addr2 > num) return -2; if (addr1 == -1){ if (comma){ addr1 = num; addr2 = 1; return 2; } if (semic){ addr1 = num; addr2 = pos; return 2; } addr1 = addr2 = pos; return 0; } if (addr2 == -1){ if (comma || semic){ addr2 = addr1; return 2; } addr2 = pos; return 1; } return 2; } int get_fname(char **cmd){ static char b[4096]; int s, n; n = sscanf(*cmd, "%s", b); if (n <1 ) return 0; fprintf(stderr, " >>> read fname: %s\n", b); s = strlen(b); if (s){ fname = realloc(fname, (s+1) * sizeof(char)); memcpy(fname, b, s+1); return 1; } return -1; } void main_loop(){ char *cmd, *c; int ret; char p; cmd = malloc(256 * sizeof(char)); c = cmd; while(1){ p = 0; fgets(cmd, 255, stdin); ret = get_addr((const char **) &cmd); fprintf(stderr,">>> *** pos: %d ret: %d ***\n", pos, ret); if (ret) { fprintf(stderr, ">>> *** addr1: %d, addr2= %d***\n", addr1, addr2); } switch(cmd[0]){ case 'a': if (addr1 > -1) move_to_line(addr1, 0); append_lines(); break; case 'c': if (addr1 > -1) move_to_line(addr1,0); delete_lines(); addr1 = addr2 = pos; append_lines(); case 'd': if (ret == -1){ E; break; } if (ret == 2){ CHECKADDR; } if (ret == 1) addr2 = addr1; delete_lines(); break; case 'e': cmd++; skip_blank((const char**)&cmd); if (cmd[0] == '!') //read_command(); ; else if(get_fname(&cmd) >=0) read_file(); else{ perror(fname); E; } break; case 'f': if (ret > 0) E; else{ cmd += 1; if (get_fname(&cmd)>=0) printf("%s\n", fname); else{ perror(fname); E; } } break; case 'i': if (addr1 > -1) move_to_line(addr1, 0); insert_lines(); break; case 'n': p = 1; case 'p': if (ret == 2){ CHECKADDR; print_lines(p); } else if (ret == 1) move_to_line(addr2, 1); else if (ret == 0) print_cur_line(p); else if (ret == -1){ addr1 = num; addr2 = 1; move_to_line(addr2,0); print_lines(p); } else E; break; case '\n': if (addr1 > -1 && addr1 <=pos) move_to_line(addr1, 1); else if (addr2 <=pos) print_cur_line(p); else E; break; case 'q': goto cleanup; break; case 'w': cmd +=1; get_fname(&cmd); if (!fname) E; else{ if (write_lines()){ perror(fname); E; } } break; case '=': if (addr1 == -1) addr1 = num; print_lineno(); break; default: if (cmd[0]) fprintf(stderr, ">>> **** unknown command: '%c'****\n", cmd[0]); E; } } cleanup: free(c); return; } int main(int argc, char *argv[]){ FILE *fin; fname = NULL; if (argc > 1){ fname = malloc((strlen(argv[1])+1) * sizeof(char)); memcpy(fname, argv[1], strlen(argv[1]) + 1); if (!read_file()) fclose(fin); else{ perror(fname); } } main_loop(); addr1 = pos, addr2 = 1; delete_lines(); free(fname); }