diff options
Diffstat (limited to 'lineset.c')
-rw-r--r-- | lineset.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/lineset.c b/lineset.c new file mode 100644 index 0000000..faabb30 --- /dev/null +++ b/lineset.c @@ -0,0 +1,117 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "gramscii.h" + +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){ + fprintf(stderr, "Unable to allocate string\n"); + exit(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"); + exit(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"); + exit(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<ls.num ;i++){ + fprintf(f, "%d:%s\n", i, ls.l[i].s); + } + fflush(f); +} + +void pad_line_to_length(char *s, int W){ + + int i; + + for (i=strlen(s); i<W; i++){ + s[i] = BG; + } +} + +/* cut/yank/paste/undo management */ + +void yank_region(int x1, int y1, int x2, int y2){ + + int N, W, i; + + N = y2 - y1 + 1; + W = x2 - x1 + 1; + ensure_num_lines(&cutbuf, N); + + for (i=y1; i<=y2; i++){ + ensure_line_length(&(cutbuf.l[i-y1]), W); + memcpy(cutbuf.l[i-y1].s, screen.l[i].s + x1, x2-x1+1); + if (strlen(cutbuf.l[i-y1].s) < W) + pad_line_to_length(cutbuf.l[i-y1].s, W); + cutbuf.l[i-y1].s[W] = '\0'; + cutbuf.l[i-y1].n = i; + } + cutbuf.num = N; +#ifdef DEBUG + dump_lines(cutbuf, stderr); +#endif + +} + + +void paste_region(int x1, int y1){ + int i, curlen; + + i = y1; + while( i < HEIGHT && i < y1 + cutbuf.num){ + memcpy(screen.l[i].s + x1, cutbuf.l[i-y1].s, strlen(cutbuf.l[i-y1].s)); + curlen = strlen(screen.l[i].s); + if (curlen <= x1) + /* double-check this line below */ + pad_line_to_length(screen.l[i].s+curlen, x1 - curlen); + i += 1; + modified = 1; + } +} |