Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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