|
|
1.1 root 1: #ifndef lint
2: static char rcs_id[] = "$Header: tsource.c,v 1.10 87/09/11 08:18:42 toddb Exp $";
3: #endif lint
4: /*
5: * COPYRIGHT 1987
6: * DIGITAL EQUIPMENT CORPORATION
7: * MAYNARD, MASSACHUSETTS
8: * ALL RIGHTS RESERVED.
9: *
10: * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
11: * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
12: * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
13: * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
14: *
15: * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
16: * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
17: * SET FORTH ABOVE.
18: *
19: *
20: * Permission to use, copy, modify, and distribute this software and its
21: * documentation for any purpose and without fee is hereby granted, provided
22: * that the above copyright notice appear in all copies and that both that
23: * copyright notice and this permission notice appear in supporting documentation,
24: * and that the name of Digital Equipment Corporation not be used in advertising
25: * or publicity pertaining to distribution of the software without specific,
26: * written prior permission.
27: */
28:
29: /* File: tsource.c -- the code for a toc source */
30:
31: #include "xmh.h"
32: #include "tocintrnl.h"
33:
34: /* Private definitions. */
35:
36: #define BUFSIZE 512
37:
38: Msg MsgFromPosition(toc, position, dir)
39: Toc toc;
40: XtTextPosition position;
41: ScanDirection dir;
42: {
43: Msg msg;
44: int h, l, m;
45: if (dir == XtsdLeft) position--;
46: l = 0;
47: h = toc->nummsgs - 1;
48: while (l < h - 1) {
49: m = (l + h) / 2;
50: if (toc->msgs[m]->position > position)
51: h = m;
52: else
53: l = m;
54: }
55: msg = toc->msgs[h];
56: if (msg->position > position)
57: msg = toc->msgs[h = l];
58: while (!msg->visible)
59: msg = toc->msgs[h++];
60: if (position < msg->position || position > msg->position + msg->length)
61: Punt("Error in MsgFromPosition!");
62: return msg;
63: }
64:
65:
66: static XtTextPosition CoerceToLegalPosition(toc, position)
67: Toc toc;
68: XtTextPosition position;
69: {
70: return (position < 0) ? 0 :
71: ((position > toc->lastPos) ? toc->lastPos : position);
72: }
73:
74:
75: /* Semi-public definitions */
76:
77: static TSourceReadText(src, position, text, maxRead)
78: XtTextSource *src;
79: XtTextPosition position;
80: XtTextBlock *text;
81: int maxRead;
82: {
83: Toc toc = (Toc) src->data;
84: Msg msg;
85: int count;
86: text->firstPos = position;
87: if (position < toc->lastPos) {
88: msg = MsgFromPosition(toc, position, XtsdRight);
89: text->ptr = msg->buf + (position - msg->position);
90: count = msg->length - (position - msg->position);
91: text->length = (count < maxRead) ? count : maxRead;
92: position += text->length;
93: }
94: else {
95: text->length = 0;
96: text->ptr = "";
97: }
98: return position;
99: }
100:
101:
102: /* Right now, we can only replace a piece with another piece of the same size,
103: and it can't cross between lines. */
104:
105: static int TSourceReplaceText(src, startPos, endPos, text, delta)
106: XtTextSource *src;
107: XtTextPosition startPos, endPos;
108: XtTextBlock *text;
109: int *delta;
110: {
111: Toc toc = (Toc) src->data;
112: Msg msg;
113: int i;
114: *delta = text->length - (endPos - startPos);
115: if (*delta != 0)
116: return EDITERROR;
117: msg = MsgFromPosition(toc, startPos, XtsdRight);
118: for (i = 0; i < text->length; i++)
119: msg->buf[startPos - msg->position + i] = text->ptr[i];
120: return EDITDONE;
121: }
122:
123:
124: static XtTextPosition TSourceGetLastPos(src)
125: XtTextSource *src;
126: {
127: return ((Toc) src->data)->lastPos;
128: }
129:
130:
131: /*ARGSUSED*/ /* -- keeps lint from complaining. */
132: static TSourceSetLastPos(src)
133: XtTextSource *src;
134: {
135: }
136:
137:
138: #define Look(index, c)\
139: { \
140: if ((dir == XtsdLeft && index <= 0) || \
141: (dir == XtsdRight && index >= toc->lastPos)) \
142: c = 0; \
143: else { \
144: if (index + doff < msg->position || \
145: index + doff >= msg->position + msg->length) \
146: msg = MsgFromPosition(toc, index, dir); \
147: c = msg->buf[index + doff - msg->position]; \
148: } \
149: }
150:
151:
152:
153: static XtTextPosition TSourceScan(src, position, sType, dir, count, include)
154: XtTextSource *src;
155: XtTextPosition position;
156: ScanType sType;
157: ScanDirection dir;
158: int count, include;
159: {
160: Toc toc = (Toc) src->data;
161: XtTextPosition index;
162: Msg msg;
163: char c;
164: int ddir, doff, i, whiteSpace;
165: ddir = (dir == XtsdRight) ? 1 : -1;
166: doff = (dir == XtsdRight) ? 0 : -1;
167:
168: if (toc->lastPos == 0) return 0;
169: index = position;
170: if (index + doff < 0) return 0;
171: if (dir == XtsdRight && index >= toc->lastPos) return toc->lastPos;
172: msg = MsgFromPosition(toc, index, dir);
173: switch (sType) {
174: case XtstPositions:
175: if (!include && count > 0)
176: count--;
177: index = CoerceToLegalPosition(toc, index + count * ddir);
178: break;
179: case XtstWhiteSpace:
180: for (i = 0; i < count; i++) {
181: whiteSpace = -1;
182: while (index >= 0 && index <= toc->lastPos) {
183: Look(index, c);
184: if ((c == ' ') || (c == '\t') || (c == '\n')) {
185: if (whiteSpace < 0) whiteSpace = index;
186: } else if (whiteSpace >= 0)
187: break;
188: index += ddir;
189: }
190: }
191: if (!include) {
192: if (whiteSpace < 0 && dir == XtsdRight)
193: whiteSpace = toc->lastPos;
194: index = whiteSpace;
195: }
196: index = CoerceToLegalPosition(toc, index);
197: break;
198: case XtstEOL:
199: for (i = 0; i < count; i++) {
200: while (index >= 0 && index <= toc->lastPos) {
201: Look(index, c);
202: if (c == '\n')
203: break;
204: index += ddir;
205: }
206: if (i < count - 1)
207: index += ddir;
208: }
209: if (include)
210: index += ddir;
211: index = CoerceToLegalPosition(toc, index);
212: break;
213: case XtstFile:
214: if (dir == XtsdLeft)
215: index = 0;
216: else
217: index = toc->lastPos;
218: break;
219: }
220: return index;
221: }
222:
223:
224: /*ARGSUSED*/ /* -- keeps lint from complaining. */
225: static XtEditType TSourceGetEditType(src)
226: XtTextSource *src;
227: {
228: return XttextRead;
229: }
230:
231: /* Public definitions. */
232:
233: XtTextSource *TSourceCreate(toc)
234: Toc toc;
235: {
236: XtTextSource *src;
237: src = (XtTextSource *) XtMalloc(sizeof(XtTextSource));
238: src->read = TSourceReadText;
239: src->replace = TSourceReplaceText;
240: src->getLastPos = TSourceGetLastPos;
241: src->setLastPos = TSourceSetLastPos;
242: src->editType = TSourceGetEditType;
243: src->scan = TSourceScan;
244: src->data = (int *) toc;
245: return src;
246: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.