#define _POSIX_C_SOURCE 200112L #include #include #include #include "gramscii.h" /** extern declarations **/ extern lineset_t screen; /* what is visualised */ extern lineset_t cutbuf; /* cut/paste buffer */ extern lineset_t *undo; /* undo list */ extern int undo_sz;/* allocated size of undo list*/ extern int undo_cur;/* undo position */ extern int undo_lst;/* last valid undo position */ extern int WIDTH, HEIGHT; extern char modified; /* set to 1 if screen modified since last save */ /****/ static int LONG_STEP; /* line_t and lineset_t management */ void ensure_line_length(line_t *l, int len){ char *tmp; if (l->sz < len + 1){ tmp = realloc(l->s, (len+1) * 2 * sizeof(char)); if (tmp == NULL){ fprintf(stderr, "Unable to allocate string\n"); cleanup(1); } l->s = tmp; l->sz = (len + 1) * 2; } } void alloc_line(line_t *l){ char *tmp; l->sz = WIDTH+1; tmp = malloc((l->sz) * sizeof(char)); if (tmp == NULL){ fprintf(stderr, "unable to allocate line\n"); cleanup(1); } l->s = tmp; memset(l->s, BG, l->sz); l->lst = -1; l->s[0]='\0'; } void ensure_num_lines(lineset_t *ls, int n){ line_t *tmp; if (n > ls->sz){ if (ls->sz == 0) ls->l=NULL; tmp = realloc(ls->l, (n + LONG_STEP) * sizeof(line_t)); if (tmp == NULL){ fprintf(stderr, "Unable to allocate memory for more lines"); cleanup(1); } else { ls->l = tmp; while ( ls->sz < n + LONG_STEP){ alloc_line(&(ls->l[ls->sz])); ls->sz ++; } } } } void dump_lines(lineset_t ls, FILE *f){ int i; for (i=0; i y2){ y1 ^= y2; y2 ^= y1; y1 ^= y2; } if (undo_cur > undo_lst) undo_cur = undo_lst; if (which == PRV_STATE){ /* adding a new previous state */ undo_cur += 2; idx = undo_cur; } else idx = undo_cur + 1; if (idx >= undo_sz - 1){ tmp = realloc(undo, (undo_sz + 10) * sizeof(lineset_t)); if (tmp == NULL){ fprintf(stderr, "Error allocating undo buffer"); cleanup(1); } undo = tmp; for (i=0; i<10; i++){ undo[undo_sz + i].sz = 0; undo[undo_sz + i].l = NULL; undo[undo_sz + i].num = 0; } undo_sz += 10; } ensure_num_lines(&(undo[idx]), y2 - y1 + 1); for(i=y1; i<=y2; i++){ len = strlen(screen.l[i].s); ensure_line_length(&(undo[idx].l[i-y1]), len); strcpy(undo[idx].l[i-y1].s, screen.l[i].s); undo[idx].l[i-y1].n = i; undo[idx].l[i-y1].lst = screen.l[i].lst; } undo[idx].num = y2 - y1 + 1; if (which == PRV_STATE) undo_lst = undo_cur; #ifdef DEBUG fprintf(stderr, "undo_ring: y1: %d y2: %d idx: %d\n", y1, y2, idx); for(i=0; i undo_cur) undo_lst = undo_cur; }