Bug Summary

File:MultiSrc.c
Location:line 587, column 4
Description:Value stored to 'c' is never read

Annotated Source Code

1/*
2 * Copyright 1991 by OMRON Corporation
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name OMRON not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. OMRON makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
13 *
14 * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Authors: Chris Peterson MIT X Consortium
23 * Li Yuhong OMRON Corporation
24 * Frank Sheeran OMRON Corporation
25 *
26 * Much code taken from X11R3 String and Disk Sources.
27 */
28
29/*
30
31Copyright 1991, 1994, 1998 The Open Group
32
33Permission to use, copy, modify, distribute, and sell this software and its
34documentation for any purpose is hereby granted without fee, provided that
35the above copyright notice appear in all copies and that both that
36copyright notice and this permission notice appear in supporting
37documentation.
38
39The above copyright notice and this permission notice shall be included in
40all copies or substantial portions of the Software.
41
42THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
46AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
47CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48
49Except as contained in this notice, the name of The Open Group shall not be
50used in advertising or otherwise to promote the sale, use or other dealings
51in this Software without prior written authorization from The Open Group.
52
53*/
54
55#ifdef HAVE_CONFIG_H1
56#include <config.h>
57#endif
58#include <stdio.h>
59#include <stdlib.h>
60#include <ctype.h>
61#include <errno(*__error()).h>
62#include <X11/IntrinsicP.h>
63#include <X11/StringDefs.h>
64#include <X11/Xfuncs.h>
65#include <X11/Xos.h>
66#include <X11/Xmu/CharSet.h>
67#include <X11/Xmu/Misc.h>
68#include <X11/Xaw/XawInit.h>
69#include <X11/Xaw/MultiSrcP.h>
70#include <X11/Xaw/XawImP.h>
71#include "XawI18n.h"
72#include "Private.h"
73
74#include <sys/types.h>
75#include <sys/stat.h>
76#include <fcntl.h>
77
78#define MAGIC_VALUE((XawTextPosition)-1) ((XawTextPosition)-1)
79#define streq(a, b)(strcmp((a), (b)) == 0) (strcmp((a), (b)) == 0)
80
81
82/*
83 * Class Methods
84 */
85static XawTextPosition ReadText(Widget, XawTextPosition, XawTextBlock*, int);
86static int ReplaceText(Widget, XawTextPosition, XawTextPosition,
87 XawTextBlock*);
88static XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType,
89 XawTextScanDirection, int, Boolint);
90static XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection,
91 XawTextBlock*);
92static void XawMultiSrcClassInitialize(void);
93static void XawMultiSrcDestroy(Widget);
94static void XawMultiSrcInitialize(Widget, Widget, ArgList, Cardinal*);
95static Boolean XawMultiSrcSetValues(Widget, Widget, Widget,
96 ArgList, Cardinal*);
97static void XawMultiSrcGetValuesHook(Widget, ArgList, Cardinal*);
98
99/*
100 * Prototypes
101 */
102static MultiPiece *AllocNewPiece(MultiSrcObject, MultiPiece*);
103static void BreakPiece(MultiSrcObject, MultiPiece*);
104static Boolean CvtMultiTypeToString(Display*, XrmValuePtr, Cardinal*,
105 XrmValuePtr, XrmValuePtr, XtPointer*);
106static void CvtStringToMultiType(XrmValuePtr, Cardinal*,
107 XrmValuePtr, XrmValuePtr);
108static MultiPiece *FindPiece(MultiSrcObject, XawTextPosition,
109 XawTextPosition*);
110static void FreeAllPieces(MultiSrcObject);
111static FILE *InitStringOrFile(MultiSrcObject, Boolint);
112static void LoadPieces(MultiSrcObject, FILE*, char*);
113static void RemovePiece(MultiSrcObject, MultiPiece*);
114static void RemoveOldStringOrFile(MultiSrcObject, Boolint);
115static String StorePiecesInString(MultiSrcObject);
116static Boolint WriteToFile(String, String);
117static void GetDefaultPieceSize(Widget, int, XrmValue*);
118
119/*
120 * Initialization
121 */
122#define offset(field) XtOffsetOf(MultiSrcRec, multi_src.field)__builtin_offsetof(MultiSrcRec, multi_src.field)
123static XtResource resources[] = {
124 {
125 XtNstring((char*)&XtStrings[733]),
126 XtCString((char*)&XtStrings[1416]),
127 XtRString((char*)&XtStrings[1797]),
128 sizeof(XtPointer),
129 offset(string),
130 XtRPointer((char*)&XtStrings[1767]),
131 NULL((void*)0)
132 },
133 {
134 XtNtype"type",
135 XtCType"Type",
136 XtRMultiType"MultiType",
137 sizeof(XawAsciiType),
138 offset(type),
139 XtRImmediate((char*)&XtStrings[1695]),
140 (XtPointer)XawAsciiString
141 },
142 {
143 XtNdataCompression"dataCompression",
144 XtCDataCompression"DataCompression",
145 XtRBoolean((char*)&XtStrings[1561]),
146 sizeof(Boolean),
147 offset(data_compression),
148 XtRImmediate((char*)&XtStrings[1695]),
149 (XtPointer)False0
150 },
151 {
152 XtNpieceSize"pieceSize",
153 XtCPieceSize"PieceSize",
154 XtRInt((char*)&XtStrings[1718]),
155 sizeof(XawTextPosition),
156 offset(piece_size),
157 XtRCallProc((char*)&XtStrings[1578]),
158 (XtPointer)GetDefaultPieceSize
159 },
160#ifdef OLDXAW
161 {
162 XtNcallback((char*)&XtStrings[136]),
163 XtCCallback((char*)&XtStrings[952]),
164 XtRCallback((char*)&XtStrings[1569]),
165 sizeof(XtPointer),
166 offset(callback),
167 XtRCallback((char*)&XtStrings[1569]),
168 (XtPointer)NULL((void*)0)
169 },
170#endif
171 {
172 XtNuseStringInPlace"useStringInPlace",
173 XtCUseStringInPlace"UseStringInPlace",
174 XtRBoolean((char*)&XtStrings[1561]),
175 sizeof(Boolean),
176 offset(use_string_in_place),
177 XtRImmediate((char*)&XtStrings[1695]),
178 (XtPointer)False0
179 },
180 {
181 XtNlength((char*)&XtStrings[435]),
182 XtCLength((char*)&XtStrings[1157]),
183 XtRInt((char*)&XtStrings[1718]),
184 sizeof(int),
185 offset(multi_length),
186 XtRImmediate((char*)&XtStrings[1695]),
187 (XtPointer)MAGIC_VALUE((XawTextPosition)-1)
188 },
189};
190#undef offset
191
192#define superclass(&textSrcClassRec) (&textSrcClassRec)
193MultiSrcClassRec multiSrcClassRec = {
194 /* object */
195 {
196 (WidgetClass)superclass(&textSrcClassRec), /* superclass */
197 "MultiSrc", /* class_name */
198 sizeof(MultiSrcRec), /* widget_size */
199 XawMultiSrcClassInitialize, /* class_initialize */
200 NULL((void*)0), /* class_part_initialize */
201 False0, /* class_inited */
202 XawMultiSrcInitialize, /* initialize */
203 NULL((void*)0), /* initialize_hook */
204 NULL((void*)0), /* obj1 */
205 NULL((void*)0), /* obj2 */
206 0, /* obj3 */
207 resources, /* resources */
208 XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))), /* num_resources */
209 NULLQUARK((XrmQuark) 0), /* xrm_class */
210 False0, /* obj4 */
211 False0, /* obj5 */
212 False0, /* obj6 */
213 False0, /* obj7 */
214 XawMultiSrcDestroy, /* destroy */
215 NULL((void*)0), /* obj8 */
216 NULL((void*)0), /* obj9 */
217 XawMultiSrcSetValues, /* set_values */
218 NULL((void*)0), /* set_values_hook */
219 NULL((void*)0), /* obj10 */
220 XawMultiSrcGetValuesHook, /* get_values_hook */
221 NULL((void*)0), /* obj11 */
222 XtVersion(11 * 1000 + 6), /* version */
223 NULL((void*)0), /* callback_private */
224 NULL((void*)0), /* obj12 */
225 NULL((void*)0), /* obj13 */
226 NULL((void*)0), /* obj14 */
227 NULL((void*)0), /* extension */
228 },
229 /* text_src */
230 {
231 ReadText, /* Read */
232 ReplaceText, /* Replace */
233 Scan, /* Scan */
234 Search, /* Search */
235 XtInheritSetSelection((_XawSrcSetSelectionProc)_XtInherit), /* SetSelection */
236 XtInheritConvertSelection((_XawSrcConvertSelectionProc)_XtInherit), /* ConvertSelection */
237 },
238 /* multi_src */
239 {
240 NULL((void*)0), /* extension */
241 },
242};
243
244WidgetClass multiSrcObjectClass = (WidgetClass)&multiSrcClassRec;
245
246static XrmQuark Qstring, Qfile;
247
248/*
249 * Implementation
250 */
251static void
252XawMultiSrcClassInitialize(void)
253{
254 XawInitializeWidgetSet();
255 Qstring = XrmPermStringToQuark(XtEstring"string");
256 Qfile = XrmPermStringToQuark(XtEfile"file");
257 XtAddConverter(XtRString((char*)&XtStrings[1797]), XtRMultiType"MultiType", CvtStringToMultiType, NULL((void*)0), 0);
258 XtSetTypeConverter(XtRMultiType"MultiType", XtRString((char*)&XtStrings[1797]), CvtMultiTypeToString, NULL((void*)0), 0,
259 XtCacheNone0x001, NULL((void*)0));
260}
261
262/*
263 * Function:
264 * XawMultiSrcInitialize
265 *
266 * Parameters:
267 * request - widget requested by the argument list
268 * cnew - the new widget with both resource and non resource values
269 * args - (unused)
270 * num_args - (unused)
271 *
272 * Description:
273 * Initializes the multi src object
274 */
275/*ARGSUSED*/
276static void
277XawMultiSrcInitialize(Widget request, Widget cnew,
278 ArgList args, Cardinal *num_args)
279{
280 MultiSrcObject src = (MultiSrcObject)cnew;
281 FILE *file;
282
283 /*
284 * Set correct flags (override resources) depending upon widget class
285 */
286#ifdef OLDXAW
287 src->multi_src.changes = False0;
288#else
289 src->text_src.changed = False0;
290#endif
291 src->multi_src.allocated_string = False0;
292
293 if (src->multi_src.use_string_in_place && src->multi_src.string == NULL((void*)0))
294 src->multi_src.use_string_in_place = False0;
295
296 file = InitStringOrFile(src, src->multi_src.type == XawAsciiFile);
297 LoadPieces(src, file, NULL((void*)0));
298
299 if (file != NULL((void*)0))
300 fclose(file);
301 src->text_src.text_format = XawFmtWide;
302}
303
304/*
305 * Function:
306 * ReadText
307 *
308 * Parameters:
309 * w - MultiSource object
310 * pos - position of the text to retrieve
311 * text - text block that will contain returned text
312 * length - maximum number of characters to read
313 *
314 * Description:
315 * This function reads the source.
316 *
317 * Returns:
318 * The character position following the retrieved text.
319 */
320static XawTextPosition
321ReadText(Widget w, XawTextPosition pos, XawTextBlock *text, int length)
322{
323 MultiSrcObject src = (MultiSrcObject)w;
324 XawTextPosition count, start;
325 MultiPiece *piece = FindPiece(src, pos, &start);
326
327 text->format = XawFmtWide;
328 text->firstPos = pos;
329 text->ptr = (char *)(piece->text + (pos - start));
330 count = piece->used - (pos - start);
331 text->length = Max(0, (length > count) ? count : length)(((0) > ((length > count) ? count : length)) ? (0) : ((
length > count) ? count : length))
;
332
333 return (pos + text->length);
334}
335
336/*
337 * Function:
338 * ReplaceText
339 *
340 * Parameters:
341 * w - MultiSource object
342 * startPos - ends of text that will be removed
343 * endPos - ""
344 * text - new text to be inserted into buffer at startPos
345 *
346 * Description:
347 * Replaces a block of text with new text.
348 *
349 * Returns:
350 * XawEditDone on success, XawEditError otherwise
351 */
352/*ARGSUSED*/
353static int
354ReplaceText(Widget w, XawTextPosition startPos, XawTextPosition endPos,
355 XawTextBlock *u_text_p)
356{
357 MultiSrcObject src = (MultiSrcObject)w;
358 MultiPiece *start_piece, *end_piece, *temp_piece;
359 XawTextPosition start_first, end_first;
360 int length, firstPos;
361 wchar_t *wptr;
362 Boolint local_artificial_block = False0;
363 XawTextBlock text;
364
365 /* STEP 1: The user handed me a text block called `u_text' that may be
366 * in either FMTWIDE or FMT8BIT (ie MB.) Later code needs the block
367 * `text' to hold FMTWIDE. So, this copies `u_text' to `text', and if
368 * `u_text' was MB, I knock it up to WIDE
369 */
370 if (u_text_p->length == 0) /* if so, the block contents never ref'd */
371 text.length = 0;
372
373 else if (u_text_p->format == XawFmtWide) {
374 local_artificial_block = False0; /* don't have to free it ourselves */
375 text.firstPos = u_text_p->firstPos;
376 text.length = u_text_p->length;
377 text.ptr = u_text_p->ptr;
378 }
379 else {
380 /*
381 * WARNING! u_text->firstPos and length are in units of CHAR,
382 * not CHARACTERS!
383 */
384 local_artificial_block = True1; /* have to free it ourselves */
385 text.firstPos = 0;
386 text.length = u_text_p->length; /* _XawTextMBToWC converts this
387 * to wchar len
388 */
389
390 text.ptr = (char*)_XawTextMBToWC(XtDisplay(XtParent(w))(((((w)->core.parent))->core.screen)->display),
391 &u_text_p->ptr[u_text_p->firstPos],
392 &text.length);
393
394 /* I assert the following assignment is not needed - since Step 4
395 depends on length, it has no need of a terminating NULL. I think
396 the ASCII-version has the same needless NULL. */
397 /*((wchar_t*)text.ptr)[ text.length ] = NULL;*/
398 }
399
400 /* STEP 2: some initialization... */
401 if (src->text_src.edit_mode == XawtextRead)
402 return (XawEditError1);
403
404 start_piece = FindPiece(src, startPos, &start_first);
405 end_piece = FindPiece(src, endPos, &end_first);
406
407 /* STEP 3: remove the empty pieces... */
408 if (start_piece != end_piece) {
409 temp_piece = start_piece->next;
410
411 /* If empty and not the only piece then remove it */
412 if (((start_piece->used = startPos - start_first) == 0)
413 && !(start_piece->next == NULL((void*)0) && start_piece->prev == NULL((void*)0)))
414 RemovePiece(src, start_piece);
415
416 while (temp_piece != end_piece) {
417 temp_piece = temp_piece->next;
418 RemovePiece(src, temp_piece->prev);
419 }
420 end_piece->used -= endPos - end_first;
421 if (end_piece->used != 0)
422 memmove(end_piece->text, end_piece->text + endPos - end_first,__builtin___memmove_chk (end_piece->text, end_piece->text
+ endPos - end_first, end_piece->used * sizeof(wchar_t), __builtin_object_size
(end_piece->text, 0))
423 end_piece->used * sizeof(wchar_t))__builtin___memmove_chk (end_piece->text, end_piece->text
+ endPos - end_first, end_piece->used * sizeof(wchar_t), __builtin_object_size
(end_piece->text, 0))
;
424 }
425 else { /* We are fully in one piece */
426 if ((start_piece->used -= endPos - startPos) == 0) {
427 if (!(start_piece->next == NULL((void*)0) && start_piece->prev == NULL((void*)0)))
428 RemovePiece(src, start_piece);
429 }
430 else {
431 memmove(start_piece->text + (startPos - start_first),__builtin___memmove_chk (start_piece->text + (startPos - start_first
), start_piece->text + (endPos - start_first), (start_piece
->used - (startPos - start_first)) * sizeof(wchar_t), __builtin_object_size
(start_piece->text + (startPos - start_first), 0))
432 start_piece->text + (endPos - start_first),__builtin___memmove_chk (start_piece->text + (startPos - start_first
), start_piece->text + (endPos - start_first), (start_piece
->used - (startPos - start_first)) * sizeof(wchar_t), __builtin_object_size
(start_piece->text + (startPos - start_first), 0))
433 (start_piece->used - (startPos - start_first)) *__builtin___memmove_chk (start_piece->text + (startPos - start_first
), start_piece->text + (endPos - start_first), (start_piece
->used - (startPos - start_first)) * sizeof(wchar_t), __builtin_object_size
(start_piece->text + (startPos - start_first), 0))
434 sizeof(wchar_t))__builtin___memmove_chk (start_piece->text + (startPos - start_first
), start_piece->text + (endPos - start_first), (start_piece
->used - (startPos - start_first)) * sizeof(wchar_t), __builtin_object_size
(start_piece->text + (startPos - start_first), 0))
;
435 if (src->multi_src.use_string_in_place &&
436 ((src->multi_src.length - (endPos - startPos))
437 < src->multi_src.piece_size - 1))
438 start_piece->text[src->multi_src.length - (endPos - startPos)] =
439 (wchar_t)0;
440 }
441 }
442
443 src->multi_src.length += text.length -(endPos - startPos);
444
445 /* STEP 4: insert the new stuff */
446 if ( text.length != 0) {
447 start_piece = FindPiece(src, startPos, &start_first);
448 length = text.length;
449 firstPos = text.firstPos;
450
451 while (length > 0) {
452 wchar_t *ptr;
453 int fill;
454
455 if (src->multi_src.use_string_in_place) {
456 if (start_piece->used == src->multi_src.piece_size - 1) {
457
458 /*
459 * The string is used in place, then the string
460 * is not allowed to grow
461 */
462 start_piece->used = src->multi_src.length =
463 src->multi_src.piece_size - 1;
464
465 start_piece->text[src->multi_src.length] = (wchar_t)0;
466 return (XawEditError1);
467 }
468 }
469
470 if (start_piece->used == src->multi_src.piece_size) {
471 BreakPiece(src, start_piece);
472 start_piece = FindPiece(src, startPos, &start_first);
473 }
474
475 fill = Min((int)(src->multi_src.piece_size - start_piece->used), length)((((int)(src->multi_src.piece_size - start_piece->used)
) < (length)) ? ((int)(src->multi_src.piece_size - start_piece
->used)) : (length))
;
476
477 ptr = start_piece->text + (startPos - start_first);
478 memmove(ptr + fill, ptr, (start_piece->used -__builtin___memmove_chk (ptr + fill, ptr, (start_piece->used
- (startPos - start_first)) * sizeof(wchar_t), __builtin_object_size
(ptr + fill, 0))
479 (startPos - start_first)) * sizeof(wchar_t))__builtin___memmove_chk (ptr + fill, ptr, (start_piece->used
- (startPos - start_first)) * sizeof(wchar_t), __builtin_object_size
(ptr + fill, 0))
;
480 wptr =(wchar_t *)text.ptr;
481 (void)wcsncpy(ptr, wptr + firstPos, fill);
482
483 startPos += fill;
484 firstPos += fill;
485 start_piece->used += fill;
486 length -= fill;
487 }
488 }
489
490 if (local_artificial_block == True1)
491 /* In other words, text is not the u_text that the user handed me but
492 one I made myself. I only care, because I need to free the string */
493 XtFree(text.ptr);
494
495 if (src->multi_src.use_string_in_place)
496 start_piece->text[start_piece->used] = (wchar_t)0;
497
498#ifdef OLDXAW
499 src->multi_src.changes = True1;
500 XtCallCallbacks(w, XtNcallback((char*)&XtStrings[136]), NULL((void*)0));
501#endif
502
503 return (XawEditDone0);
504}
505
506/*
507 * Function:
508 * Scan
509 *
510 * Parameters:
511 * w - MultiSource widget
512 * position - position to start scanning
513 * type - type of thing to scan for
514 * dir - direction to scan
515 * count - which occurance if this thing to search for
516 * include - whether or not to include the character found in
517 * the position that is returned
518 *
519 * Description:
520 * Scans the text source for the number and type of item specified.
521 *
522 * Returns:
523 * The position of the item found
524 *
525 * Note:
526 * While there are only 'n' characters in the file there are n+1
527 * possible cursor positions (one before the first character and
528 * one after the last character
529 */
530static XawTextPosition
531Scan(Widget w, register XawTextPosition position, XawTextScanType type,
532 XawTextScanDirection dir, int count, Boolint include)
533{
534 MultiSrcObject src = (MultiSrcObject)w;
535 register char inc;
536 MultiPiece *piece;
537 XawTextPosition first, first_eol_position = position;
538 register wchar_t *ptr;
539 int cnt = count;
540
541 if (type == XawstAll) {
542 if (dir == XawsdRight)
543 return (src->multi_src.length);
544 return (0);
545 }
546
547 /* STEP 1: basic sanity checks */
548 if (position > src->multi_src.length)
549 position = src->multi_src.length;
550
551 if (dir == XawsdRight) {
552 if (position == src->multi_src.length)
553 return (src->multi_src.length);
554 inc = 1;
555 }
556 else {
557 if (position == 0)
558 return (0);
559 inc = -1;
560 position--;
561 }
562
563 piece = FindPiece(src, position, &first);
564
565 if (piece->used == 0)
566 return (0);
567
568 ptr = (position - first) + piece->text;
569
570 switch (type) {
571 case XawstEOL:
572 case XawstParagraph:
573 case XawstWhiteSpace:
574 case XawstAlphaNumeric:
575 for (; cnt > 0 ; cnt--) {
576 Boolint non_space = False0, first_eol = True1;
577
578 /*CONSTCOND*/
579 while (True1) {
580 register wchar_t c;
581
582 if (ptr < piece->text) {
583 piece = piece->prev;
584 if (piece == NULL((void*)0)) /* Begining of text */
585 return (0);
586 ptr = piece->text + piece->used - 1;
587 c = *ptr;
Value stored to 'c' is never read
588 }
589 else if (ptr >= piece->text + piece->used) {
590 piece = piece->next;
591 if (piece == NULL((void*)0)) /* End of text */
592 return (src->multi_src.length);
593 ptr = piece->text;
594 }
595
596 c = *ptr;
597 ptr += inc;
598 position += inc;
599
600 if (type == XawstAlphaNumeric) {
601 if (!iswalnum(c)) {
602 if (non_space)
603 break;
604 }
605 else
606 non_space = True1;
607 }
608 else if (type == XawstWhiteSpace) {
609 if (iswspace(c)(isascii(c) && isspace(toascii(c)))) {
610 if (non_space)
611 break;
612 }
613 else
614 non_space = True1;
615 }
616 else if (type == XawstEOL) {
617 if (c == _Xaw_atowc(XawLF0x0a))
618 break;
619 }
620 else { /* XawstParagraph */
621 if (first_eol) {
622 if (c == _Xaw_atowc(XawLF0x0a)) {
623 first_eol_position = position;
624 first_eol = False0;
625 }
626 }
627 else
628 if (c == _Xaw_atowc(XawLF0x0a))
629 break;
630 else if (!iswspace(c)(isascii(c) && isspace(toascii(c))))
631 first_eol = True1;
632 }
633 }
634 }
635 if (!include) {
636 if (type == XawstParagraph)
637 position = first_eol_position;
638 if (count)
639 position -= inc;
640 }
641 break;
642 case XawstPositions:
643 position += count * inc;
644 break;
645 default:
646 break;
647 }
648
649 if (dir == XawsdLeft)
650 position++;
651
652 if (position >= src->multi_src.length)
653 return (src->multi_src.length);
654 if (position < 0)
655 return (0);
656
657 return (position);
658}
659
660/*
661 * Function:
662 * Search
663 *
664 * Parameters:
665 * w - MultiSource objecy
666 * position - position to start scanning
667 * dir - direction to scan
668 * text - text block to search for
669 *
670 * Description:
671 * Searchs the text source for the text block passed.
672 *
673 * Returns:
674 * The position of the item found
675 */
676static XawTextPosition
677Search(Widget w, register XawTextPosition position, XawTextScanDirection dir,
678 XawTextBlock *text)
679{
680 MultiSrcObject src = (MultiSrcObject)w;
681 register int count = 0;
682 wchar_t *ptr;
683 wchar_t *wtarget;
684 int wtarget_len;
685 Display *d = XtDisplay(XtParent(w))(((((w)->core.parent))->core.screen)->display);
686 MultiPiece *piece;
687 wchar_t *buf;
688 XawTextPosition first;
689 register char inc;
690 int cnt;
691
692 /* STEP 1: First, a brief sanity check */
693 if (dir == XawsdRight)
694 inc = 1;
695 else {
696 inc = -1;
697 if (position == 0)
698 return (XawTextSearchError(-12345L));
699 position--;
700 }
701
702 /* STEP 2: Ensure I have a local wide string.. */
703
704 /* Since this widget stores 32bit chars, I check here to see if
705 I'm being passed a string claiming to be 8bit chars (ie, MB text.)
706 If that is the case, naturally I convert to 32bit format */
707
708 /*if the block was FMT8BIT, length will convert to REAL wchar count bellow */
709 wtarget_len = text->length;
710
711 if (text->format == XawFmtWide)
712 wtarget = &(((wchar_t*)text->ptr) [text->firstPos]);
713 else {
714 /* The following converts wtarget_len from byte len to wchar count */
715 wtarget = _XawTextMBToWC(d, &text->ptr[text->firstPos], &wtarget_len);
716 }
717
718 /* OK, I can now assert that wtarget holds wide characters, wtarget_len
719 holds an accurate count of those characters, and that firstPos has been
720 effectively factored out of the following computations */
721
722 /* STEP 3: SEARCH! */
723 buf = (wchar_t *)XtMalloc(sizeof(wchar_t) * wtarget_len);
724 (void)wcsncpy(buf, wtarget, wtarget_len);
725 piece = FindPiece(src, position, &first);
726 ptr = (position - first) + piece->text;
727
728 /*CONSTCOND*/
729 while (True1) {
730 if (*ptr == (dir == XawsdRight ? *(buf + count)
731 : *(buf + wtarget_len - count - 1))) {
732 if (count == text->length - 1)
733 break;
734 else
735 count++;
736 }
737 else {
738 if (count != 0) {
739 position -=inc * count;
740 ptr -= inc * count;
741 }
742 count = 0;
743 }
744
745 ptr += inc;
746 position += inc;
747
748 while (ptr < piece->text) {
749 cnt = piece->text - ptr;
750
751 piece = piece->prev;
752 if (piece == NULL((void*)0)) { /* Begining of text */
753 XtFree((char *)buf);
754 return (XawTextSearchError(-12345L));
755 }
756 ptr = piece->text + piece->used - cnt;
757 }
758
759 while (ptr >= piece->text + piece->used) {
760 cnt = ptr - (piece->text + piece->used);
761
762 piece = piece->next;
763 if (piece == NULL((void*)0)) { /* End of text */
764 XtFree((char *)buf);
765 return (XawTextSearchError(-12345L));
766 }
767 ptr = piece->text + cnt;
768 }
769 }
770
771 XtFree((char *)buf);
772 if (dir == XawsdLeft)
773 return(position);
774
775 return(position - (wtarget_len - 1));
776}
777
778/*
779 * Function:
780 * XawMultiSrcSetValues
781 *
782 * Parameters:
783 * current - current state of the widget
784 * request - what was requested
785 * cnew - what the widget will become
786 * args - representation of resources that have changed
787 * num_args - number of changed resources
788 *
789 * Description:
790 * Sets the values for the MultiSource.
791 *
792 * Returns:
793 * True if redisplay is needed
794 */
795static Boolean
796XawMultiSrcSetValues(Widget current, Widget request, Widget cnew,
797 ArgList args, Cardinal *num_args)
798{
799 MultiSrcObject src = (MultiSrcObject)cnew;
800 MultiSrcObject old_src = (MultiSrcObject)current;
801 XtAppContext app_con = XtWidgetToApplicationContext(cnew);
802 Boolint total_reset = False0, string_set = False0;
803 FILE *file;
804 unsigned int i;
805
806 if (old_src->multi_src.use_string_in_place
807 != src->multi_src.use_string_in_place) {
808 XtAppWarning(app_con,
809 "MultiSrc: The XtNuseStringInPlace resources "
810 "may not be changed.");
811 src->multi_src.use_string_in_place =
812 old_src->multi_src.use_string_in_place;
813 }
814
815 for (i = 0; i < *num_args ; i++)
816 if (streq(args[i].name, XtNstring)(strcmp((args[i].name), (((char*)&XtStrings[733]))) == 0)) {
817 string_set = True1;
818 break;
819 }
820
821 if (string_set || old_src->multi_src.type != src->multi_src.type) {
822 RemoveOldStringOrFile(old_src, string_set);
823 src->multi_src.allocated_string = old_src->multi_src.allocated_string;
824 file = InitStringOrFile(src, string_set);
825
826 LoadPieces(src, file, NULL((void*)0));
827 if (file != NULL((void*)0))
828 fclose(file);
829#ifndef OLDXAW
830 for (i = 0; i < src->text_src.num_text; i++)
831 /* Tell text widget what happened */
832 XawTextSetSource(src->text_src.text[i], cnew, 0);
833#else
834 XawTextSetSource(XtParent(cnew)((cnew)->core.parent), cnew, 0);
835#endif
836 total_reset = True1;
837 }
838
839 if (old_src->multi_src.multi_length != src->multi_src.multi_length)
840 src->multi_src.piece_size = src->multi_src.multi_length + 1;
841
842 if ( !total_reset && old_src->multi_src.piece_size
843 != src->multi_src.piece_size) {
844 String mb_string = StorePiecesInString(old_src);
845
846 if (mb_string != 0) {
847 FreeAllPieces(old_src);
848 LoadPieces(src, NULL((void*)0), mb_string);
849 XtFree(mb_string);
850 }
851 else {
852 /* If the buffer holds bad chars, don't touch it... */
853 XtAppWarningMsg(app_con,
854 "convertError", "multiSource", "XawError",
855 XtName(XtParent((Widget)old_src)(((Widget)old_src)->core.parent)), NULL((void*)0), NULL((void*)0));
856 XtAppWarningMsg(app_con,
857 "convertError", "multiSource", "XawError",
858 "Non-character code(s) in buffer.", NULL((void*)0), NULL((void*)0));
859 }
860 }
861
862 return (False0);
863}
864
865static void
866XawMultiSrcGetValuesHook(Widget w, ArgList args, Cardinal *num_args)
867{
868 MultiSrcObject src = (MultiSrcObject)w;
869 unsigned int i;
870
871 if (src->multi_src.type == XawAsciiString) {
872 for (i = 0; i < *num_args ; i++) {
873 if (streq(args[i].name, XtNstring)(strcmp((args[i].name), (((char*)&XtStrings[733]))) == 0)) {
874 if (src->multi_src.use_string_in_place)
875 *((char **)args[i].value) = (char *)
876 src->multi_src.first_piece->text;
877 else if (_XawMultiSave(w)) /* If save sucessful */
878 *((char **)args[i].value) = (char *)src->multi_src.string;
879 break;
880 }
881 }
882 }
883}
884
885static void
886XawMultiSrcDestroy(Widget w)
887{
888 RemoveOldStringOrFile((MultiSrcObject) w, True1);
889}
890
891/*
892 * Public routines
893 */
894/*
895 * Function:
896 * XawMultiSourceFreeString
897 *
898 * Parameters:
899 * w - MultiSrc widget
900 *
901 * Description:
902 * Frees the string returned by a get values call
903 * on the string when the source is of type string.
904 *
905 * Note:
906 * The public interface is XawAsciiSourceFreeString!
907 */
908void
909_XawMultiSourceFreeString(Widget w)
910{
911 MultiSrcObject src = (MultiSrcObject)w;
912
913 if (src->multi_src.allocated_string) {
914 XtFree((char *)src->multi_src.string);
915 src->multi_src.allocated_string = False0;
916 src->multi_src.string = NULL((void*)0);
917 }
918}
919
920/*
921 * Function:
922 * _XawMultiSave
923 *
924 * Parameters:
925 * w - multiSrc Widget
926 *
927 * Description:
928 * Saves all the pieces into a file or string as required.
929 *
930 * Returns:
931 * True if the save was successful
932 *
933 * Note:
934 * The public interface is XawAsciiSave(w)!
935 */
936Boolint
937_XawMultiSave(Widget w)
938{
939 MultiSrcObject src = (MultiSrcObject)w;
940 XtAppContext app_con = XtWidgetToApplicationContext(w);
941 char *mb_string;
942
943 /*
944 * If using the string in place then there is no need to play games
945 * to get the internal info into a readable string
946 */
947 if (src->multi_src.use_string_in_place)
948 return (True1);
949
950 if (src->multi_src.type == XawAsciiFile) {
951#ifdef OLDXAW
952 if (!src->multi_src.changes)
953#else
954 if (!src->text_src.changed) /* No changes to save */
955#endif
956 return (True1);
957
958 mb_string = StorePiecesInString(src);
959
960 if (mb_string != 0) {
961 if (WriteToFile(mb_string, (String)src->multi_src.string) == False0) {
962 XtFree(mb_string);
963 return (False0);
964 }
965 XtFree(mb_string);
966#ifndef OLDXAW
967 src->text_src.changed = False0;
968#else
969 src->multi_src.changes = False0;
970#endif
971 return (True1);
972 }
973 else {
974 /* If the buffer holds bad chars, don't touch it... */
975 XtAppWarningMsg(app_con,
976 "convertError", "multiSource", "XawError",
977 "Due to illegal characters, file not saved.",
978 NULL((void*)0), NULL((void*)0));
979 return (False0);
980 }
981 }
982 else {
983 /* THIS FUNCTIONALITY IS UNDOCUMENTED, probably UNNEEDED? The manual
984 says this routine's only function is to save files to
985 disk. -Sheeran */
986 mb_string = StorePiecesInString(src);
987
988 if (mb_string == 0) {
989 /* If the buffer holds bad chars, don't touch it... */
990 XtAppWarningMsg(app_con,
991 "convertError", "multiSource", "XawError",
992 XtName(XtParent((Widget)src)(((Widget)src)->core.parent)), NULL((void*)0), NULL((void*)0));
993 return (False0);
994 }
995
996 /* assert: mb_string holds good characters so the buffer is fine */
997 if (src->multi_src.allocated_string == True1)
998 XtFree((char *)src->multi_src.string);
999 else
1000 src->multi_src.allocated_string = True1;
1001
1002 src->multi_src.string = mb_string;
1003 }
1004#ifdef OLDXAW
1005 src->multi_src.changes = False0;
1006#else
1007 src->text_src.changed = False0;
1008#endif
1009
1010 return (True1);
1011}
1012
1013/*
1014 * Function:
1015 * XawMultiSaveAsFile
1016 *
1017 * Parameters:
1018 * w - MultiSrc widget
1019 * name - name of the file to save this file into
1020 *
1021 * Description:
1022 * Save the current buffer as a file.
1023 *
1024 * Returns:
1025 * True if the save was sucessful
1026 *
1027 * Note:
1028 * The public interface is XawAsciiSaveAsFile!
1029 */
1030Boolint
1031_XawMultiSaveAsFile(Widget w, _Xconstconst char* name)
1032{
1033 MultiSrcObject src = (MultiSrcObject)w;
1034 String mb_string;
1035 Boolint ret;
1036
1037 mb_string = StorePiecesInString(src);
1038
1039 if (mb_string != 0) {
1040 ret = WriteToFile(mb_string, (char *)name);
1041 XtFree(mb_string);
1042
1043 return (ret);
1044 }
1045
1046 /* otherwise there was a conversion error. So print widget name too */
1047 XtAppWarningMsg(XtWidgetToApplicationContext(w),
1048 "convertError", "multiSource", "XawError",
1049 XtName(XtParent(w)((w)->core.parent)), NULL((void*)0), NULL((void*)0));
1050
1051 return (False0);
1052}
1053
1054/*
1055 * Private Functions
1056 */
1057static void
1058RemoveOldStringOrFile(MultiSrcObject src, Boolint checkString)
1059{
1060 FreeAllPieces(src);
1061
1062 if (checkString && src->multi_src.allocated_string) {
1063 XtFree((char *)src->multi_src.string);
1064 src->multi_src.allocated_string = False0;
1065 src->multi_src.string = NULL((void*)0);
1066 }
1067}
1068
1069/*
1070 * Function:
1071 * WriteToFile
1072 *
1073 * Parameters:
1074 * string - string to write
1075 * name - name of the file
1076 *
1077 * Description:
1078 * Write the string specified to the begining of the file specified.
1079 *
1080 * Returns:
1081 * Returns True if sucessful, False otherwise
1082 */
1083static Boolint
1084WriteToFile(String string, String name)
1085{
1086 int fd;
1087 Boolint result = True1;
1088
1089 if ((fd = creat(name, 0666)) == -1)
1090 return (False0);
1091
1092 if (write(fd, string, strlen(string)) == -1)
1093 result = False0;
1094
1095 if (close(fd) == -1)
1096 return (False0);
1097
1098 return (result);
1099}
1100
1101
1102/*
1103 * Function:
1104 * StorePiecesInString
1105 *
1106 * Parameters:
1107 * src - the multiSrc object to gather data from
1108 *
1109 * Description:
1110 * Store the pieces in memory into a char string.
1111 *
1112 * Returns:
1113 * mb_string: Caller must free
1114 * (or)
1115 * NULL: conversion error
1116 */
1117static String
1118StorePiecesInString(MultiSrcObject src)
1119{
1120 wchar_t *wc_string;
1121 char *mb_string;
1122 int char_count = src->multi_src.length;
1123 XawTextPosition first;
1124 MultiPiece *piece;
1125
1126 /* I believe the char_count + 1 and the NULL termination are unneeded! FS */
1127 wc_string = (wchar_t*)XtMalloc((char_count + 1) * sizeof(wchar_t));
1128
1129 for (first = 0, piece = src->multi_src.first_piece ; piece != NULL((void*)0);
1130 first += piece->used, piece = piece->next)
1131 (void)wcsncpy(wc_string + first, piece->text, piece->used);
1132
1133 wc_string[char_count] = 0;
1134
1135 /* This will refill all pieces to capacity */
1136 if (src->multi_src.data_compression) {
1137 FreeAllPieces(src);
1138 LoadPieces(src, NULL((void*)0), (char *)wc_string);
1139 }
1140
1141 /* Lastly, convert it to a MB format and send it back */
1142 mb_string = _XawTextWCToMB(XtDisplayOfObject((Widget)src),
1143 wc_string, &char_count);
1144
1145 /* NOTE THAT mb_string MAY BE ZERO IF THE CONVERSION FAILED */
1146 XtFree((char*)wc_string);
1147
1148 return (mb_string);
1149}
1150
1151/*
1152 * Function:
1153 * InitStringOrFile
1154 *
1155 * Parameters:
1156 * src - MultiSource
1157 *
1158 * Description:
1159 * Initializes the string or file.
1160 */
1161static FILE *
1162InitStringOrFile(MultiSrcObject src, Boolint newString)
1163{
1164 mode_t open_mode = 0;
1165 const char *fdopen_mode = NULL((void*)0);
1166 int fd;
1167 FILE *file;
1168 Display *d = XtDisplayOfObject((Widget)src);
1169
1170 if (src->multi_src.type == XawAsciiString) {
1171 if (src->multi_src.string == NULL((void*)0))
1172 src->multi_src.length = 0;
1173
1174 else if (!src->multi_src.use_string_in_place) {
1175 int length;
1176 String temp = XtNewString((char *)src->multi_src.string)(((char *)src->multi_src.string) != ((void*)0) ? (__builtin___strcpy_chk
(XtMalloc((unsigned)strlen((char *)src->multi_src.string)
+ 1), (char *)src->multi_src.string, __builtin_object_size
(XtMalloc((unsigned)strlen((char *)src->multi_src.string)
+ 1), 2 > 1 ? 1 : 0))) : ((void*)0))
;
1177
1178 if (src->multi_src.allocated_string)
1179 XtFree((char *)src->multi_src.string);
1180 src->multi_src.allocated_string = True1;
1181 src->multi_src.string = temp;
1182
1183 length = strlen((char *)src->multi_src.string);
1184
1185 /* Wasteful, throwing away the WC string, but need side effect! */
1186 (void)_XawTextMBToWC(d, (char *)src->multi_src.string, &length);
1187 src->multi_src.length = (XawTextPosition)length;
1188 }
1189 else {
1190 src->multi_src.length = strlen((char *)src->multi_src.string);
1191 /* In case the length resource is incorrectly set */
1192 if (src->multi_src.length > src->multi_src.multi_length)
1193 src->multi_src.multi_length = src->multi_src.length;
1194
1195 if (src->multi_src.multi_length == MAGIC_VALUE((XawTextPosition)-1))
1196 src->multi_src.piece_size = src->multi_src.length;
1197 else
1198 src->multi_src.piece_size = src->multi_src.multi_length + 1;
1199 }
1200
1201 return (NULL((void*)0));
1202 }
1203
1204 /*
1205 * type is XawAsciiFile
1206 */
1207 src->multi_src.is_tempfile = False0;
1208
1209 switch (src->text_src.edit_mode) {
1210 case XawtextRead:
1211 if (src->multi_src.string == NULL((void*)0))
1212 XtErrorMsg("NoFile", "multiSourceCreate", "XawError",
1213 "Creating a read only disk widget and no file specified.",
1214 NULL((void*)0), 0);
1215 open_mode = O_RDONLY0x0000;
1216 fdopen_mode = "r";
1217 break;
1218 case XawtextAppend:
1219 case XawtextEdit:
1220 if (src->multi_src.string == NULL((void*)0)) {
1221 src->multi_src.string = "*multi-src*";
1222 src->multi_src.is_tempfile = True1;
1223 }
1224 else {
1225/* O_NOFOLLOW is a BSD & Linux extension */
1226#ifdef O_NOFOLLOW0x0100
1227 open_mode = O_RDWR0x0002 | O_NOFOLLOW0x0100;
1228#else
1229 open_mode = O_RDWR0x0002; /* unsafe; subject to race conditions */
1230#endif
1231 fdopen_mode = "r+";
1232 }
1233 break;
1234 default:
1235 XtErrorMsg("badMode", "multiSourceCreate", "XawError",
1236 "Bad editMode for multi source; must be "
1237 "Read, Append or Edit.", NULL((void*)0), NULL((void*)0));
1238 }
1239
1240 /* If is_tempfile, allocate a private copy of the text
1241 * Unlikely to be changed, just to set allocated_string */
1242 if (newString || src->multi_src.is_tempfile) {
1243 String temp = XtNewString((char *)src->multi_src.string)(((char *)src->multi_src.string) != ((void*)0) ? (__builtin___strcpy_chk
(XtMalloc((unsigned)strlen((char *)src->multi_src.string)
+ 1), (char *)src->multi_src.string, __builtin_object_size
(XtMalloc((unsigned)strlen((char *)src->multi_src.string)
+ 1), 2 > 1 ? 1 : 0))) : ((void*)0))
;
1244
1245 if (src->multi_src.allocated_string)
1246 XtFree((char *)src->multi_src.string);
1247 src->multi_src.string = temp;
1248 src->multi_src.allocated_string = True1;
1249 }
1250
1251 if (!src->multi_src.is_tempfile) {
1252 if ((fd = open((char *)src->multi_src.string, open_mode, 0666)) != -1) {
1253 if ((file = fdopen(fd, fdopen_mode)) != NULL((void*)0)) {
1254 (void)fseek(file, 0, SEEK_END2);
1255 src->multi_src.length = (XawTextPosition)ftell(file);
1256 return(file);
1257 }
1258 else
1259 close(fd);
1260 }
1261 {
1262 String params[2];
1263 Cardinal num_params = 2;
1264
1265 params[0] = (String)src->multi_src.string;
1266 params[1] = strerror(errno(*__error()));
1267 XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src),
1268 "openError", "multiSourceCreate", "XawWarning",
1269 "Cannot open file %s; %s", params, &num_params);
1270 }
1271 }
1272 src->multi_src.length = 0;
1273 return (NULL((void*)0));
1274}
1275
1276/* LoadPieces: This routine takes either the MB contents of open file
1277 `file' or the MB contents of string or the MB contents of
1278 src->multi_src.string and places them in Pieces in WC format.
1279
1280 CAUTION: You must have src->multi_src.length set to file length bytes
1281 when src->multi_src.type == XawAsciiFile. src->multi_src.length must be
1282 the length of the parameter string if string is non-NULL
1283*/
1284static void
1285LoadPieces(MultiSrcObject src, FILE *file, char *string)
1286{
1287 Display *d = XtDisplayOfObject((Widget)src);
1288 wchar_t* local_str, *ptr;
1289 MultiPiece* piece = NULL((void*)0);
1290 XawTextPosition left;
1291 int bytes = sizeof(wchar_t);
1292 char* temp_mb_holder = NULL((void*)0);
1293
1294 /*
1295 * This is tricky - the _XawTextMBtoWC converter uses its 3rd arg
1296 * in as MB length, out as WC length. We want local_length to be
1297 * WC count.
1298 */
1299 int local_length = src->multi_src.length;
1300
1301 if (string != NULL((void*)0)) {
1302 /*
1303 * ASSERT: IF our caller passed a non-null string, THEN
1304 * src->multi_src.length is currently string's * byte count,
1305 * AND string is in a MB format
1306 */
1307 local_str = _XawTextMBToWC(d, (char *)string, &local_length);
1308 src->multi_src.length = (XawTextPosition) local_length;
1309 }
1310 else if (src->multi_src.type != XawAsciiFile) {
1311 /*
1312 * here, we are not changing the contents, just reloading,
1313 * so don't change len...
1314 */
1315 local_length = src->multi_src.string ?
1316 strlen((char *)src->multi_src.string) : 0;
1317 local_str = _XawTextMBToWC(d, (char *)src->multi_src.string,
1318 &local_length);
1319 }
1320 else {
1321 if (src->multi_src.length != 0) {
1322 temp_mb_holder =
1323 XtMalloc((src->multi_src.length + 1) * sizeof(unsigned char));
1324 fseek(file, 0, SEEK_SET0);
1325 src->multi_src.length = fread(temp_mb_holder,
1326 sizeof(unsigned char),
1327 (size_t)src->multi_src.length, file);
1328 if (src->multi_src.length <= 0)
1329 XtAppErrorMsg(XtWidgetToApplicationContext ((Widget) src),
1330 "readError", "multiSource", "XawError",
1331 "fread returned error.", NULL((void*)0), NULL((void*)0));
1332 local_length = src->multi_src.length;
1333 local_str = _XawTextMBToWC(d, temp_mb_holder, &local_length);
1334 src->multi_src.length = local_length;
1335
1336 if (local_str == 0) {
1337 String params[2];
1338 Cardinal num_params;
1339 static char err_text[] =
1340 "<<< FILE CONTENTS NOT REPRESENTABLE IN THIS LOCALE >>>";
1341
1342 params[0] = XtName(XtParent((Widget)src)(((Widget)src)->core.parent));
1343 params[1] = src->multi_src.string;
1344 num_params = 2;
1345
1346 XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src),
1347 "readLocaleError", "multiSource", "XawError",
1348 "%s: The file `%s' contains characters "
1349 "not representable in this locale.",
1350 params, &num_params);
1351 src->multi_src.length = sizeof err_text;
1352 local_length = src->multi_src.length;
1353 local_str = _XawTextMBToWC(d, err_text, &local_length);
1354 src->multi_src.length = local_length;
1355 }
1356 }
1357 else
1358 /* ASSERT that since following while loop looks at local_length
1359 this isn't needed. Sheeran, Omron KK, 1993/07/15
1360 temp_mb_holder[src->multi_src.length] = '\0'; */
1361 local_str = (wchar_t*)temp_mb_holder;
1362 }
1363
1364 if (src->multi_src.use_string_in_place) {
1365 piece = AllocNewPiece(src, piece);
1366 piece->used = Min(src->multi_src.length, src->multi_src.piece_size)(((src->multi_src.length) < (src->multi_src.piece_size
)) ? (src->multi_src.length) : (src->multi_src.piece_size
))
;
1367 piece->text = (wchar_t*)src->multi_src.string;
1368 return;
1369 }
1370
1371 ptr = local_str;
1372 left = local_length;
1373
1374 do {
1375 piece = AllocNewPiece(src, piece);
1376
1377 piece->text = (wchar_t*)XtMalloc((unsigned)(src->multi_src.piece_size
1378 * bytes));
1379 piece->used = Min(left, src->multi_src.piece_size)(((left) < (src->multi_src.piece_size)) ? (left) : (src
->multi_src.piece_size))
;
1380 if (piece->used != 0)
1381 (void)wcsncpy(piece->text, ptr, piece->used);
1382
1383 left -= piece->used;
1384 ptr += piece->used;
1385 } while (left > 0);
1386
1387 if (temp_mb_holder)
1388 XtFree((char*)temp_mb_holder);
1389}
1390
1391/*
1392 * Function:
1393 * AllocNewPiece
1394 *
1395 * Parameters:
1396 * src - MultiSrc Widget
1397 * prev - the piece just before this one, or NULL
1398 *
1399 * Description:
1400 * Allocates a new piece of memory.
1401 *
1402 * Returns:
1403 * The allocated piece
1404 */
1405static MultiPiece *
1406AllocNewPiece(MultiSrcObject src, MultiPiece *prev)
1407{
1408 MultiPiece *piece = XtNew(MultiPiece)((MultiPiece *) XtMalloc((unsigned) sizeof(MultiPiece)));
1409
1410 if (prev == NULL((void*)0)) {
1411 src->multi_src.first_piece = piece;
1412 piece->next = NULL((void*)0);
1413 }
1414 else {
1415 if (prev->next != NULL((void*)0))
1416 (prev->next)->prev = piece;
1417 piece->next = prev->next;
1418 prev->next = piece;
1419 }
1420
1421 piece->prev = prev;
1422
1423 return (piece);
1424}
1425
1426/*
1427 * Function:
1428 * FreeAllPieces
1429 *
1430 * Parameters:
1431 * src - MultiSrc Widget
1432 *
1433 * Description:
1434 * Frees all the pieces
1435 */
1436static void
1437FreeAllPieces(MultiSrcObject src)
1438{
1439 MultiPiece *next, *first = src->multi_src.first_piece;
1440
1441#ifdef DEBUG
1442 if (first->prev != NULL((void*)0))
1443 printf("Xaw MultiSrc Object: possible memory leak in FreeAllPieces().\n");
1444#endif
1445
1446 for (; first != NULL((void*)0) ; first = next) {
1447 next = first->next;
1448 RemovePiece(src, first);
1449 }
1450}
1451
1452/*
1453 * Function:
1454 * RemovePiece
1455 *
1456 * Parameters:
1457 * piece - piece to remove
1458 *
1459 * Description:
1460 * Removes a piece from the list.
1461 */
1462static void
1463RemovePiece(MultiSrcObject src, MultiPiece *piece)
1464{
1465 if (piece->prev == NULL((void*)0))
1466 src->multi_src.first_piece = piece->next;
1467 else
1468 piece->prev->next = piece->next;
1469
1470 if (piece->next != NULL((void*)0))
1471 piece->next->prev = piece->prev;
1472
1473 if (!src->multi_src.use_string_in_place)
1474 XtFree((char *)piece->text);
1475
1476 XtFree((char *)piece);
1477}
1478
1479/*
1480 * Function:
1481 * FindPiece
1482 *
1483 * Parameters:
1484 * src - MultiSrc Widget
1485 * position - position that we are searching for
1486 * first - position of the first character in this piece (return)
1487 *
1488 * Description:
1489 * Finds the piece containing the position indicated.
1490 *
1491 * Returns:
1492 * Piece that contains this position
1493 */
1494static MultiPiece *
1495FindPiece(MultiSrcObject src, XawTextPosition position, XawTextPosition *first)
1496{
1497 MultiPiece *old_piece, *piece;
1498 XawTextPosition temp;
1499
1500 for (old_piece = NULL((void*)0), piece = src->multi_src.first_piece, temp = 0;
1501 piece; old_piece = piece, piece = piece->next)
1502 if ((temp += piece->used) > position) {
1503 *first = temp - piece->used;
1504 return (piece);
1505 }
1506
1507 *first = temp - (old_piece ? old_piece->used : 0);
1508
1509 return (old_piece); /* if we run off the end the return the last piece */
1510}
1511
1512/*
1513 * Function:
1514 * BreakPiece
1515 *
1516 * Parameters:
1517 * src - MultiSrc Widget
1518 * piece - piece to break
1519 *
1520 * Description:
1521 * Breaks a full piece into two new pieces.
1522 */
1523#define HALF_PIECE(src->multi_src.piece_size >> 1) (src->multi_src.piece_size >> 1)
1524static void
1525BreakPiece(MultiSrcObject src, MultiPiece *piece)
1526{
1527 MultiPiece *cnew = AllocNewPiece(src, piece);
1528
1529 cnew->text = (wchar_t *)
1530 XtMalloc(src->multi_src.piece_size * sizeof(wchar_t));
1531 (void)wcsncpy(cnew->text, piece->text + HALF_PIECE(src->multi_src.piece_size >> 1),
1532 src->multi_src.piece_size - HALF_PIECE(src->multi_src.piece_size >> 1));
1533 piece->used = HALF_PIECE(src->multi_src.piece_size >> 1);
1534 cnew->used = src->multi_src.piece_size - HALF_PIECE(src->multi_src.piece_size >> 1);
1535}
1536
1537/*ARGSUSED*/
1538static void
1539CvtStringToMultiType(XrmValuePtr args, Cardinal *num_args,
1540 XrmValuePtr fromVal, XrmValuePtr toVal)
1541{
1542 static XawAsciiType type = XawAsciiString;
1543 XrmQuark q;
1544 char name[7];
1545
1546 XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name));
1547 q = XrmStringToQuark(name);
1548
1549 if (q == Qstring)
1550 type = XawAsciiString;
1551 if (q == Qfile)
1552 type = XawAsciiFile;
1553 else {
1554 toVal->size = 0;
1555 toVal->addr = NULL((void*)0);
1556 XtStringConversionWarning((char *)fromVal->addr, XtRAsciiType"AsciiType");
1557 }
1558
1559 toVal->size = sizeof(XawAsciiType);
1560 toVal->addr = (XPointer)&type;
1561}
1562
1563/*ARGSUSED*/
1564static Boolean
1565CvtMultiTypeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args,
1566 XrmValuePtr fromVal, XrmValuePtr toVal,
1567 XtPointer *data)
1568{
1569 static String buffer;
1570 Cardinal size;
1571
1572 switch (*(XawAsciiType *)fromVal->addr) {
1573 case XawAsciiFile:
1574 buffer = XtEfile"file";
1575 break;
1576 case XawAsciiString:
1577 buffer = XtEstring"string";
1578 break;
1579 default:
1580 XawTypeToStringWarning(dpy, XtRAsciiType"AsciiType");
1581 toVal->addr = NULL((void*)0);
1582 toVal->size = 0;
1583 return (False0);
1584 }
1585
1586 size = strlen(buffer) + 1;
1587 if (toVal->addr != NULL((void*)0)) {
1588 if (toVal->size < size) {
1589 toVal->size = size;
1590 return (False0);
1591 }
1592 strcpy((char *)toVal->addr, buffer)__builtin___strcpy_chk ((char *)toVal->addr, buffer, __builtin_object_size
((char *)toVal->addr, 2 > 1 ? 1 : 0))
;
1593 }
1594 else
1595 toVal->addr = (XPointer)buffer;
1596 toVal->size = sizeof(String);
1597
1598 return (True1);
1599}
1600
1601/*ARGSUSED*/
1602static void
1603GetDefaultPieceSize(Widget w, int offset, XrmValue *value)
1604{
1605 static XPointer pagesize;
1606
1607 if (pagesize == 0) {
1608 pagesize = (XPointer)((long)_XawGetPageSize());
1609 if (pagesize < (XPointer)BUFSIZ1024)
1610 pagesize = (XPointer)BUFSIZ1024;
1611 }
1612
1613 value->addr = (XPointer)&pagesize;
1614}