Introduction
Introduction Statistics Contact Development Disclaimer Help
lineset.c - gramscii - A simple editor for ASCII box-and-arrow charts
Log
Files
Refs
Tags
README
LICENSE
---
lineset.c (4125B)
---
1 #define _POSIX_C_SOURCE 200112L
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "gramscii.h"
7
8 /** extern declarations **/
9
10 extern lineset_t screen; /* what is visualised */
11 extern lineset_t cutbuf; /* cut/paste buffer */
12 extern lineset_t *undo; /* undo list */
13
14 extern int undo_sz;/* allocated size of undo list*/
15 extern int undo_cur;/* undo position */
16 extern int undo_lst;/* last valid undo position */
17
18 extern int WIDTH, HEIGHT;
19
20 extern char modified; /* set to 1 if screen modified since last save */
21
22 /****/
23
24 static int LONG_STEP;
25
26 /* line_t and lineset_t management */
27
28 void ensure_line_length(line_t *l, int len){
29 char *tmp;
30
31 if (l->sz < len + 1){
32 tmp = realloc(l->s, (len+1) * 2 * sizeof(char));
33 if (tmp == NULL){
34 fprintf(stderr, "Unable to allocate string\n");
35 cleanup(1);
36 }
37 l->s = tmp;
38 l->sz = (len + 1) * 2;
39 }
40 }
41
42
43 void alloc_line(line_t *l){
44 char *tmp;
45
46 l->sz = WIDTH+1;
47 tmp = malloc((l->sz) * sizeof(char));
48 if (tmp == NULL){
49 fprintf(stderr, "unable to allocate line\n");
50 cleanup(1);
51 }
52 l->s = tmp;
53 memset(l->s, BG, l->sz);
54 l->lst = -1;
55 l->s[0]='\0';
56 }
57
58 void ensure_num_lines(lineset_t *ls, int n){
59 line_t *tmp;
60
61 if (n > ls->sz){
62 if (ls->sz == 0)
63 ls->l=NULL;
64 tmp = realloc(ls->l, (n + LONG_STEP) * sizeof(line_t));
65 if (tmp == NULL){
66 fprintf(stderr, "Unable to allocate memory for m…
67 cleanup(1);
68 }
69 else {
70 ls->l = tmp;
71 while ( ls->sz < n + LONG_STEP){
72 alloc_line(&(ls->l[ls->sz]));
73 ls->sz ++;
74 }
75 }
76 }
77 }
78
79
80 void dump_lines(lineset_t ls, FILE *f){
81 int i;
82 for (i=0; i<ls.num ;i++){
83 fprintf(f, "%s\n", ls.l[i].s);
84 }
85 fflush(f);
86 }
87
88 void pad_line_to_length(char *s, int W){
89
90 int i;
91
92 for (i=strlen(s); i<W; i++){
93 s[i] = BG;
94 }
95 }
96
97 /* cut/yank/paste/undo management */
98
99 void yank_region(int x1, int y1, int x2, int y2){
100
101 int N, W, i;
102
103 N = y2 - y1 + 1;
104 W = x2 - x1 + 1;
105 ensure_num_lines(&cutbuf, N);
106
107 for (i=y1; i<=y2; i++){
108 ensure_line_length(&(cutbuf.l[i-y1]), W);
109 memcpy(cutbuf.l[i-y1].s, screen.l[i].s + x1, x2-x1+1);
110 if (strlen(cutbuf.l[i-y1].s) < W)
111 pad_line_to_length(cutbuf.l[i-y1].s, W);
112 cutbuf.l[i-y1].s[W] = '\0';
113 cutbuf.l[i-y1].n = i;
114 }
115 cutbuf.num = N;
116 #ifdef DEBUG
117 dump_lines(cutbuf, stderr);
118 #endif
119
120 }
121
122
123 void paste_region(int x1, int y1){
124 int i, curlen, pastelen;
125
126 i = y1;
127 while( i < HEIGHT && i < y1 + cutbuf.num){
128 pastelen = strlen(cutbuf.l[i-y1].s);
129 curlen = strlen(screen.l[i].s);
130 memcpy(screen.l[i].s + x1, cutbuf.l[i-y1].s, pastelen);
131 if (curlen <= x1)
132 /* double-check this line below */
133 pad_line_to_length(screen.l[i].s + curlen, x1 - …
134 if (curlen <= x1 + pastelen)
135 screen.l[i].s[x1 + pastelen] = '\0';
136
137 screen.l[i].lst = strlen(screen.l[i].s) - 1;
138 #ifdef DEBUG
139 fprintf(stderr, "%d.lst: %d\n", i, screen.l[i].lst);
140 #endif
141 i += 1;
142 modified = 1;
143 }
144 redraw();
145 }
146
147 void copy_lines_to_ring(int y1, int y2, int which){
148 int i, len, idx;
149 lineset_t *tmp;
150
151 if (y1 > y2){
152 y1 ^= y2;
153 y2 ^= y1;
154 y1 ^= y2;
155 }
156 if (undo_cur > undo_lst)
157 undo_cur = undo_lst;
158 if (which == PRV_STATE){ /* adding a new previous state */
159 undo_cur += 2;
160 idx = undo_cur;
161 }
162 else
163 idx = undo_cur + 1;
164 if (idx >= undo_sz - 1){
165 tmp = realloc(undo, (undo_sz + 10) * sizeof(lineset_t));
166 if (tmp == NULL){
167 fprintf(stderr, "Error allocating undo buffer");
168 cleanup(1);
169 }
170 undo = tmp;
171 for (i=0; i<10; i++){
172 undo[undo_sz + i].sz = 0;
173 undo[undo_sz + i].l = NULL;
174 undo[undo_sz + i].num = 0;
175 }
176 undo_sz += 10;
177 }
178 ensure_num_lines(&(undo[idx]), y2 - y1 + 1);
179 for(i=y1; i<=y2; i++){
180 len = strlen(screen.l[i].s);
181 ensure_line_length(&(undo[idx].l[i-y1]), len);
182 strcpy(undo[idx].l[i-y1].s, screen.l[i].s);
183 undo[idx].l[i-y1].n = i;
184 undo[idx].l[i-y1].lst = screen.l[i].lst;
185 }
186 undo[idx].num = y2 - y1 + 1;
187 if (which == PRV_STATE)
188 undo_lst = undo_cur;
189 #ifdef DEBUG
190 fprintf(stderr, "undo_ring: y1: %d y2: %d idx: %d\n", y1, y2, id…
191 for(i=0; i<undo[idx].num; i++){
192 fprintf(stderr, "UU: %d| %s\n", undo[idx].l[i].n, undo[i…
193 }
194 #endif
195 }
196
197 void invalidate_undo(){
198 if (undo_lst > undo_cur)
199 undo_lst = undo_cur;
200 }
You are viewing proxied material from bitreich.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.