Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 248 lines (222 sloc) 6.436 kB
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
1 /* mark.c */
2 /* Copyright 1995 by Steve Kirkendall */
3
4
5 #include "elvis.h"
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
6 #ifdef FEATURE_RCSID
7 char id_mark[] = "$Id: mark.c,v 2.18 2002/11/01 19:29:49 steve Exp $";
8 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
9
10
11 MARK namedmark[26];
12
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
13 /* Allocate a mark, pointing to a specific location in a specific buffer.
14 * As changes are make to the buffer, the mark's offset into that buffer
15 * will automatically be updated.
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
16 */
17 #ifndef DEBUG_ALLOC
18 MARK markalloc(buffer, offset)
19 BUFFER buffer; /* the buffer that the new mark will refer to */
20 long offset; /* position of the mark within buffer */
21 {
22 MARK newp;
23
24 newp = (MARK)safealloc(1, sizeof(MARKBUF));
25 #else
26 MARK _markalloc(file, line, buffer, offset)
27 char *file; /* source file where allocating */
28 int line; /* source line where allocating */
29 BUFFER buffer; /* the buffer that the new mark will refer to */
30 long offset; /* position of the mark within buffer */
31 {
32 MARK newp;
33
34 assert(buffer != NULL && offset >= 0 && offset <= o_bufchars(buffer));
35
36 newp = (MARK)_safealloc(file, line, False, 1, sizeof(MARKBUF));
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
37 /*fprintf(stderr, "markalloc(0x%lx, %ld) called from %s(%d), returning 0x%lx\n", (long)buffer, offset, file, line, (long)newp);*/
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
38 #endif
39 newp->buffer = buffer;
40 newp->offset = offset;
41 newp->next = bufmarks(buffer);
42 bufsetmarks(buffer, newp);
43 return newp;
44 }
45
46 /* Free a mark which was created by markalloc(). This also adjusts the
47 * namedmarks[] array, if necessary.
48 */
49 #ifndef DEBUG_ALLOC
50 void markfree(mark)
51 MARK mark; /* the mark to destroy */
52 {
53 #else
54 void _markfree(file, line, mark)
55 char *file;
56 int line;
57 MARK mark;
58 {
59 #endif
60 MARK lag;
61 int i;
62
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
63 #ifdef DEBUG_ALLOC
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
64 /*fprintf(stderr, "markfree(0x%lx) called from %s(%d)\n", (long)mark, file, line);*/
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
65 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
66 /* remove from buffer's list of marks */
67 if (mark == bufmarks(mark->buffer))
68 {
69 bufsetmarks(mark->buffer, mark->next);
70 }
71 else
72 {
73 for (lag = bufmarks(mark->buffer); lag->next != mark; lag = lag->next)
74 {
75 assert(lag->next);
76 }
77 lag->next = mark->next;
78 }
79
80 /* if in namedmarks, then unset the namedmarks variable */
81 for (i = 0; i < QTY(namedmark); i++)
82 {
83 if (namedmark[i] == mark)
84 {
85 namedmark[i] = NULL;
86 break;
87 }
88 }
89
90 /* free the mark's resources */
91 #ifndef DEBUG_ALLOC
92 safefree(mark);
93 #else
94 _safefree(file, line, mark);
95 #endif
96 }
97
98 /* Adjust the offset of every who's offset is greater than "from". If at "to"
99 * or later, add "delta" to it. Between "from" and "to", add some fraction
100 * of "delta" to it.
101 *
102 * This function is meant to be called only from bufreplace().
103 */
104 void markadjust(from, to, delta)
105 MARK from; /* old start of text */
106 MARK to; /* old end of text */
107 long delta; /* difference between old "to" and new "to" offsets */
108 {
109 MARK mark; /* used for scanning the buffer's mark list */
110 long dist; /* original distance between "from" and "to" */
111 long tooff; /* original offset of "to" */
112 long fromoff;/* original offset of "from" */
113
114 /* trivial case */
115 if (delta == 0)
116 {
117 return;
118 }
119
120 /* Compute some stuff that depends on the "to" mark. Note that we
121 * must do this before the loop, because during the loop we may adjust
122 * the value of the "to" mark itself!
123 */
124 tooff = to->offset;
125 fromoff = from->offset;
126 dist = tooff - fromoff;
127 assert(from->buffer == to->buffer && -delta <= dist && dist >= 0);
128
129 /* for every mark... */
130 for (mark = bufmarks(from->buffer); mark; mark = mark->next)
131 {
132 /* adjust, if affected by mod */
133 if (mark->offset > tooff)
134 {
135 mark->offset += delta;
136 }
137 else if (mark->offset > fromoff)
138 {
139 /* NOTE: At this point we know that dist!=0 because
140 * that could only happen if fromoff==tooff, and we
141 * can only get here if this mark's offset <= tooff
142 * but >fromoff. When tooff==fromoff, that is
143 * impossible!
144 */
145 mark->offset += delta * (mark->offset - from->offset) / dist;
146 }
147 }
148 }
149
150 /* Find the line number of a mark. This is defined as being the number of
151 * newlines preceding the mark, plus 1. Note that this is not necessarily
97d8998 @mbert Import Elvis 2.1_4 (written by Steve Kirkendall)
authored
152 * how the display mode defines lines.
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
153 */
154 long markline(mark)
155 MARK mark; /* mark to be converted */
156 {
97d8998 @mbert Import Elvis 2.1_4 (written by Steve Kirkendall)
authored
157 #if 1
158 static long lnum;
159 static MARKBUF prevmark;
160 static long prevchanges;
161
162 /* try to avoid calling lowoffset(), since that function is slow */
163 if (markbuffer(mark) == markbuffer(&prevmark)
164 && markoffset(mark) == markoffset(&prevmark)
165 && markbuffer(mark)->changes == prevchanges)
166 return lnum;
167
168 /* remember info so we can maybe optimize the next call */
169 prevmark = *mark;
170 prevchanges = markbuffer(mark)->changes;
171 #else
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
172 long lnum;
97d8998 @mbert Import Elvis 2.1_4 (written by Steve Kirkendall)
authored
173 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
174 (void)lowoffset(bufbufinfo(markbuffer(mark)), markoffset(mark), NULL, NULL, NULL, &lnum);
175 return lnum;
176 }
177
178 /* Adjust a mark so that it points to a specific line, and then return mark.
179 * If the requested line doesn't exist, return NULL.
180 */
181 MARK marksetline(mark, linenum)
182 MARK mark; /* the mark to be adjusted */
183 long linenum;/* the desired line number */
184 {
185 /* if bogus line number, return NULL */
186 if (linenum < 1 || linenum > o_buflines(markbuffer(mark)))
187 {
188 return NULL;
189 }
190
191 /* else change the mark's offset & return it */
192 mark->offset = lowline(bufbufinfo(markbuffer(mark)), linenum);
193 assert(mark->offset < o_bufchars(markbuffer(mark)));
194 return mark;
195 }
196
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
197 /* Change the buffer of a mark. This involves deleting the mark from the mark
198 * list of the old buffer, and then adding it to the list of the new buffer.
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
199 */
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
200 #ifdef DEBUG_MARK
201 void _marksetbuffer(file, line, mark, buffer)
202 char *file;
203 int line;
204 #else
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
205 void marksetbuffer(mark, buffer)
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
206 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
207 MARK mark; /* the mark to be moved */
208 BUFFER buffer; /* the new buffer that the mark should refer to */
209 {
210 MARK lag;
211
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
212 /* if no change, then do nothing */
213 if (markbuffer(mark) == buffer)
214 return;
215
9f1c6f0 @mbert Import Elvis 2.2_0 (written by Steve Kirkendall)
authored
216 #ifdef DEBUG_MARK
217 {
218 WINDOW win = NULL;
219 while (win = winofbuf(win, NULL))
220 if (win->windowid.value.number == 1
221 && win->cursor == mark)
222 fprintf(stderr, "%s:%d: was \"%s\", now \"%s\"\n",
223 file, line,
224 win->cursor->buffer->bufname.value.string,
225 buffer->bufname.value.string);
226 }
227 #endif
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
228 /* remove from old buffer's list of marks */
229 if (mark == bufmarks(mark->buffer))
230 {
231 bufsetmarks(mark->buffer, mark->next);
232 }
233 else
234 {
235 assert(bufmarks(mark->buffer));
236 for (lag = bufmarks(mark->buffer); lag->next != mark; lag = lag->next)
237 {
238 assert(lag->next->next);
239 }
240 lag->next = mark->next;
241 }
242
243 /* insert it into the new buffer's list */
244 mark->buffer = buffer;
245 mark->next = bufmarks(buffer);
246 bufsetmarks(buffer, mark);
247 }
Something went wrong with that request. Please try again.