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
118
119
120
121
122
123
124
125
126
|
#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, pastelen;
i = y1;
while( i < HEIGHT && i < y1 + cutbuf.num){
pastelen = strlen(cutbuf.l[i-y1].s);
curlen = strlen(screen.l[i].s);
memcpy(screen.l[i].s + x1, cutbuf.l[i-y1].s, pastelen);
if (curlen <= x1)
/* double-check this line below */
pad_line_to_length(screen.l[i].s + curlen, x1 - curlen);
if (curlen <= x1 + pastelen)
screen.l[i].s[x1 + pastelen] = '\0';
screen.l[i].lst = strlen(screen.l[i].s) - 1;
#ifdef DEBUG
fprintf(stderr, "%d.lst: %d\n", i, screen.l[i].lst);
#endif
i += 1;
modified = 1;
}
redraw();
}
|