summaryrefslogtreecommitdiff
path: root/lineset.c
blob: faabb30eb4eda6f849f6a72c90022ad6d2a13a91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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;
	}
}