Corrected a long-standing error in which ending text with a literal
[xcircuit.git] / Xw / SourceStr.c
blob71c6bbc40aa9a6d237cea2e71da66034d52d7021
1 /*************************************<+>*************************************
2 *****************************************************************************
3 **
4 ** File: SourceStr.c
5 **
6 ** Project: X Widgets
7 **
8 ** Description: Code for TextEdit widget string source
9 **
10 *****************************************************************************
11 **
12 ** Copyright (c) 1988 by Hewlett-Packard Company
13 ** Copyright (c) 1987, 1988 by Digital Equipment Corporation, Maynard,
14 ** Massachusetts, and the Massachusetts Institute of Technology,
15 ** Cambridge, Massachusetts
16 **
17 ** Permission to use, copy, modify, and distribute this software
18 ** and its documentation for any purpose and without fee is hereby
19 ** granted, provided that the above copyright notice appear in all
20 ** copies and that both that copyright notice and this permission
21 ** notice appear in supporting documentation, and that the names of
22 ** Hewlett-Packard, Digital or M.I.T. not be used in advertising or
23 ** publicity pertaining to distribution of the software without
24 ** written prior permission.
25 **
26 ** DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27 ** ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
28 ** DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
29 ** ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
30 ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
31 ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
32 ** SOFTWARE.
33 **
34 *****************************************************************************
35 *************************************<+>*************************************/
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <X11/Xlib.h>
40 #include <X11/IntrinsicP.h>
41 #include <X11/StringDefs.h>
42 #include <Xw/Xw.h>
43 #include <Xw/XwP.h>
44 #include <Xw/TextEdit.h>
45 #include <Xw/TextEditP.h>
46 #include <Xw/SourceP.h>
48 /* Private StringSource Definitions */
50 #define MAGICVALUE -1
51 #define DEFAULTBUFFERSIZE 512
54 #define Increment(data, position, direction)\
56 if (direction == XwsdLeft) {\
57 if (position > 0) \
58 position -= 1;\
60 else {\
61 if (position < data->length)\
62 position += 1;\
66 static long magic_value = MAGICVALUE;
68 static XtResource stringResources[] = {
69 {XtNstring, XtCString, XtRString, sizeof (char *),
70 XtOffset(StringSourcePtr, initial_string), XtRString, NULL},
71 {XtNmaximumSize, XtCMaximumSize, XtRLong, sizeof (long),
72 XtOffset(StringSourcePtr, max_size), XtRLong, (caddr_t)&magic_value},
73 {XtNeditType, XtCEditType, XtREditMode, sizeof(XwEditType),
74 XtOffset(StringSourcePtr, editMode), XtRString, "edit"},
77 /*--------------------------------------------------------------------------+*/
78 static unsigned char Look(data, position, direction)
79 /*--------------------------------------------------------------------------+*/
80 StringSourcePtr data;
81 XwTextPosition position;
82 XwScanDirection direction;
84 /* Looking left at pos 0 or right at position data->length returns newline */
85 if (direction == XwsdLeft) {
86 if (position == 0)
87 return(0);
88 else
89 return(data->buffer[position-1]);
91 else {
92 if (position == data->length)
93 return(0);
94 else
95 return(data->buffer[position]);
99 /*--------------------------------------------------------------------------+*/
100 static int StringReadText (src, pos, text, maxRead)
101 /*--------------------------------------------------------------------------+*/
102 XwTextSource *src;
103 int pos;
104 XwTextBlock *text;
105 int maxRead;
107 int charsLeft;
108 StringSourcePtr data;
110 data = (StringSourcePtr) src->data;
111 text->firstPos = pos;
112 text->ptr = data->buffer + pos;
113 charsLeft = data->length - pos;
114 text->length = (maxRead > charsLeft) ? charsLeft : maxRead;
115 return pos + text->length;
118 /*--------------------------------------------------------------------------+*/
119 static XwEditResult StringReplaceText (src, startPos, endPos, text, delta)
120 /*--------------------------------------------------------------------------+*/
121 XwTextSource *src;
122 XwTextPosition startPos, endPos;
123 XwTextBlock *text;
124 int *delta;
126 StringSourcePtr data;
127 int i, length;
129 data = (StringSourcePtr) src->data;
130 switch (data->editMode) {
131 case XwtextAppend:
132 if (startPos != endPos || endPos!= data->length)
133 return (XweditPosError);
134 break;
135 case XwtextRead:
136 return (XweditError);
137 case XwtextEdit:
138 break;
139 default:
140 return (XweditError);
142 length = endPos - startPos;
143 *delta = text->length - length;
144 if ((data->length + *delta) > data->buffer_size) {
145 if (data->max_size_flag)
146 return (XweditError);
147 else {
148 while ((data->length + *delta) > data->buffer_size)
149 data->buffer_size += DEFAULTBUFFERSIZE;
150 data->buffer = (unsigned char *)
151 XtRealloc(data->buffer, data->buffer_size);
156 if (*delta < 0) /* insert shorter than delete, text getting
157 shorter */
158 for (i = startPos; i < data->length + *delta; ++i)
159 data->buffer[i] = data->buffer[i - *delta];
160 else
161 if (*delta > 0) { /* insert longer than delete, text getting
162 longer */
163 for (i = data->length; i > startPos-1; --i)
164 data->buffer[i + *delta] = data->buffer[i];
166 if (text->length != 0) /* do insert */
167 for (i = 0; i < text->length; ++i)
168 data->buffer[startPos + i] = text->ptr[i];
169 data->length = data->length + *delta;
170 data->buffer[data->length] = 0;
171 return (XweditDone);
174 /*--------------------------------------------------------------------------+*/
175 static StringSetLastPos (src, lastPos)
176 /*--------------------------------------------------------------------------+*/
177 XwTextSource *src;
178 XwTextPosition lastPos;
180 ((StringSourceData *) (src->data))->length = lastPos;
183 /*--------------------------------------------------------------------------+*/
184 static XwTextPosition StringGetLastPos (src)
185 /*--------------------------------------------------------------------------+*/
186 XwTextSource *src;
188 return( ((StringSourceData *) (src->data))->length );
191 /*--------------------------------------------------------------------------+*/
192 static XwTextPosition StringScan (src, pos, sType, dir, count, include)
193 /*--------------------------------------------------------------------------+*/
194 XwTextSource *src;
195 XwTextPosition pos;
196 XwScanType sType;
197 XwScanDirection dir;
198 int count;
199 Boolean include;
201 StringSourcePtr data;
202 XwTextPosition position;
203 int i, whiteSpace;
204 unsigned char c;
205 int ddir = (dir == XwsdRight) ? 1 : -1;
207 data = (StringSourcePtr) src->data;
208 position = pos;
209 switch (sType) {
210 case XwstPositions:
211 if (!include && count > 0)
212 count -= 1;
213 for (i = 0; i < count; i++) {
214 Increment(data, position, dir);
216 break;
217 case XwstWhiteSpace:
219 for (i = 0; i < count; i++) {
220 whiteSpace = -1;
221 while (position >= 0 && position <= data->length) {
222 c = Look(data, position, dir);
223 if ((c == ' ') || (c == '\t') || (c == '\n')){
224 if (whiteSpace < 0) whiteSpace = position;
225 } else if (whiteSpace >= 0)
226 break;
227 position += ddir;
230 if (!include) {
231 if(whiteSpace < 0 && dir == XwsdRight) whiteSpace = data->length;
232 position = whiteSpace;
234 break;
235 case XwstEOL:
236 for (i = 0; i < count; i++) {
237 while (position >= 0 && position <= data->length) {
238 if (Look(data, position, dir) == '\n')
239 break;
240 if(((dir == XwsdRight) && (position == data->length)) ||
241 (dir == XwsdLeft) && ((position == 0)))
242 break;
243 Increment(data, position, dir);
245 if (i + 1 != count)
246 Increment(data, position, dir);
248 if (include) {
249 /* later!!!check for last char in file # eol */
250 Increment(data, position, dir);
252 break;
253 case XwstLast:
254 if (dir == XwsdLeft)
255 position = 0;
256 else
257 position = data->length;
259 if (position < 0) position = 0;
260 if (position > data->length) position = data->length;
261 return(position);
264 /*--------------------------------------------------------------------------+*/
265 static XwEditType StringGetEditType(src)
266 /*--------------------------------------------------------------------------+*/
267 XwTextSource *src;
269 StringSourcePtr data;
270 data = (StringSourcePtr) src->data;
271 return(data->editMode);
274 /*--------------------------------------------------------------------------+*/
275 static Boolean XwStringSourceCheckData(src)
276 /*--------------------------------------------------------------------------+*/
277 XwTextSource *src;
278 { int initial_size = 0;
279 StringSourcePtr data = (StringSourcePtr)src->data;
281 data->max_size_flag = (data->max_size != MAGICVALUE);
283 if (data->initial_string == NULL) {
284 if (data->max_size_flag)
285 data->buffer_size = data->max_size;
286 else
287 data->buffer_size = DEFAULTBUFFERSIZE;
288 if (!data->buffer) data->length = 0;
290 else {
291 initial_size = XwStrlen(data->initial_string);
292 if (data->max_size_flag) {
293 if (data->max_size < initial_size) {
294 XtWarning("Initial string size larger than XtNmaximumSize");
295 data->max_size = initial_size;
297 data->buffer_size = data->max_size;
299 else {
300 data->buffer_size =
301 (initial_size < DEFAULTBUFFERSIZE) ? DEFAULTBUFFERSIZE :
302 ((initial_size / DEFAULTBUFFERSIZE) + 1) * DEFAULTBUFFERSIZE;
304 data->length = initial_size;
307 if (data->buffer && initial_size)
308 data->buffer =
309 (unsigned char *) XtRealloc(data->buffer, data->buffer_size);
310 else if (!data->buffer)
311 data->buffer = (unsigned char *) XtMalloc(data->buffer_size);
313 if (initial_size) {
314 strcpy(data->buffer, data->initial_string);
315 data->initial_string = NULL;
319 /***** Public routines *****/
321 /*--------------------------------------------------------------------------+*/
322 void XwStringSourceDestroy (src)
323 /*--------------------------------------------------------------------------+*/
324 XwTextSource *src;
326 XtFree((char *) src->data);
327 XtFree((char *) src);
330 /*--------------------------------------------------------------------------+*/
331 XwTextSource *XwStringSourceCreate (w, args, argCount)
332 /*--------------------------------------------------------------------------+*/
333 Widget w;
334 ArgList args;
335 int argCount;
337 XwTextSource *src;
338 StringSourcePtr data;
341 src = XtNew(XwTextSource);
342 src->read = StringReadText;
343 src->replace = StringReplaceText;
344 src->setLastPos = StringSetLastPos;
345 src->getLastPos = StringGetLastPos;
346 src->scan = StringScan;
347 src->editType = StringGetEditType;
348 src->resources = stringResources;
349 src->resource_num = XtNumber(stringResources);
350 src->check_data = XwStringSourceCheckData;
351 src->destroy = XwStringSourceDestroy;
352 data = XtNew(StringSourceData);
353 data->editMode = XwtextRead;
354 data->buffer = NULL;
355 data->initial_string = NULL;
356 data->length = 0;
357 data->buffer_size = 0;
358 data->max_size = 0;
359 data->max_size_flag = 0;
360 src->data = (int *)data;
362 /* Use the name given to the TextEdit widget this source will go with.
363 This could be a problem if we allow multiple views on one source */
365 XtGetSubresources (w, data, XtNstringSrc, "StringSrc",
366 stringResources, XtNumber(stringResources), args, argCount);
368 src->data = (int *) (data);
370 XwStringSourceCheckData(src);
372 return src;