Bug Summary

File:AsciiSrc.c
Location:line 1488, column 12
Description:Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

1/*
2
3Copyright 1989, 1994, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27/*
28 * AsciiSrc.c - AsciiSrc object. (For use with the text widget).
29 *
30 */
31
32#ifdef HAVE_CONFIG_H1
33#include <config.h>
34#endif
35#include <stdio.h>
36#include <stdlib.h>
37#include <ctype.h>
38#include <errno(*__errno_location ()).h>
39#include <X11/IntrinsicP.h>
40#include <X11/StringDefs.h>
41#include <X11/Xos.h>
42#include <X11/Xfuncs.h>
43#include <X11/Xmu/CharSet.h>
44#include <X11/Xmu/Misc.h>
45#include <X11/Xaw/XawInit.h>
46#include <X11/Xaw/AsciiSrcP.h>
47#include <X11/Xaw/MultiSrcP.h>
48#ifndef OLDXAW
49#include <X11/Xaw/TextSinkP.h>
50#include <X11/Xaw/AsciiSinkP.h>
51#endif
52#include "Private.h"
53
54#include <sys/types.h>
55#include <sys/stat.h>
56#include <fcntl.h>
57
58#if (defined(ASCII_STRING) || defined(ASCII_DISK))
59#include <X11/Xaw/AsciiText.h> /* for Widget Classes */
60#endif
61
62#ifdef X_NOT_POSIX
63#define Off_toff_t long
64#define Size_tsize_t unsigned int
65#else
66#define Off_toff_t off_t
67#define Size_tsize_t size_t
68#endif
69
70#define MAGIC_VALUE((XawTextPosition)-1) ((XawTextPosition)-1)
71#define streq(a, b)(strcmp((a), (b)) == 0) (strcmp((a), (b)) == 0)
72
73/*
74 * Class Methods
75 */
76static void XawAsciiSrcClassInitialize(void);
77static void XawAsciiSrcDestroy(Widget);
78static void XawAsciiSrcGetValuesHook(Widget, ArgList, Cardinal*);
79static void XawAsciiSrcInitialize(Widget, Widget, ArgList, Cardinal*);
80static Boolean XawAsciiSrcSetValues(Widget, Widget, Widget,
81 ArgList, Cardinal*);
82static XawTextPosition ReadText(Widget, XawTextPosition, XawTextBlock*, int);
83static int ReplaceText(Widget, XawTextPosition, XawTextPosition,
84 XawTextBlock*);
85static XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType,
86 XawTextScanDirection, int, Boolint);
87static XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection,
88 XawTextBlock*);
89
90/*
91 * Prototypes
92 */
93static Piece *AllocNewPiece(AsciiSrcObject, Piece*);
94static void BreakPiece(AsciiSrcObject, Piece*);
95static Boolean CvtAsciiTypeToString(Display*, XrmValuePtr, Cardinal*,
96 XrmValuePtr, XrmValuePtr, XtPointer*);
97static void CvtStringToAsciiType(XrmValuePtr, Cardinal*,
98 XrmValuePtr, XrmValuePtr);
99static Piece *FindPiece(AsciiSrcObject, XawTextPosition, XawTextPosition*);
100static void FreeAllPieces(AsciiSrcObject);
101static FILE *InitStringOrFile(AsciiSrcObject, Boolint);
102static void LoadPieces(AsciiSrcObject, FILE*, char*);
103static void RemoveOldStringOrFile(AsciiSrcObject, Boolint);
104static void RemovePiece(AsciiSrcObject, Piece*);
105static String StorePiecesInString(AsciiSrcObject);
106static Boolint WriteToFile(String, String, unsigned);
107static Boolint WritePiecesToFile(AsciiSrcObject, String);
108static void GetDefaultPieceSize(Widget, int, XrmValue*);
109
110/*
111 * More Prototypes
112 */
113#ifdef ASCII_DISK
114Widget XawAsciiDiskSourceCreate(Widget, ArgList, Cardinal);
115#endif
116#ifdef ASCII_STRING
117Widget XawStringSourceCreate(Widget, ArgList, Cardinal);
118void XawTextSetLastPos(Widget, XawTextPosition);
119#endif
120
121/*
122 * Initialization
123 */
124#define offset(field) XtOffsetOf(AsciiSrcRec, ascii_src.field)__builtin_offsetof(AsciiSrcRec, ascii_src.field)
125static XtResource resources[] = {
126 {
127 XtNstring((char*)&XtStrings[733]),
128 XtCString((char*)&XtStrings[1416]),
129 XtRString((char*)&XtStrings[1797]),
130 sizeof(char*),
131 offset(string),
132 XtRString((char*)&XtStrings[1797]),
133 NULL((void*)0)
134 },
135 {
136 XtNtype"type",
137 XtCType"Type",
138 XtRAsciiType"AsciiType",
139 sizeof(XawAsciiType),
140 offset(type),
141 XtRImmediate((char*)&XtStrings[1695]),
142 (XtPointer)XawAsciiString
143 },
144 {
145 XtNdataCompression"dataCompression",
146 XtCDataCompression"DataCompression",
147 XtRBoolean((char*)&XtStrings[1561]),
148 sizeof(Boolean),
149 offset(data_compression),
150 XtRImmediate((char*)&XtStrings[1695]),
151 (XtPointer)True1
152 },
153 {
154 XtNpieceSize"pieceSize",
155 XtCPieceSize"PieceSize",
156 XtRInt((char*)&XtStrings[1718]),
157 sizeof(XawTextPosition),
158 offset(piece_size),
159 XtRCallProc((char*)&XtStrings[1578]),
160 (XtPointer)GetDefaultPieceSize
161 },
162#ifdef OLDXAW
163 {
164 XtNcallback((char*)&XtStrings[136]),
165 XtCCallback((char*)&XtStrings[952]),
166 XtRCallback((char*)&XtStrings[1569]),
167 sizeof(XtPointer),
168 offset(callback),
169 XtRCallback((char*)&XtStrings[1569]),
170 (XtPointer)NULL((void*)0)
171 },
172#endif
173 {
174 XtNuseStringInPlace"useStringInPlace",
175 XtCUseStringInPlace"UseStringInPlace",
176 XtRBoolean((char*)&XtStrings[1561]),
177 sizeof(Boolean),
178 offset(use_string_in_place),
179 XtRImmediate((char*)&XtStrings[1695]),
180 (XtPointer)False0
181 },
182 {
183 XtNlength((char*)&XtStrings[435]),
184 XtCLength((char*)&XtStrings[1157]),
185 XtRInt((char*)&XtStrings[1718]),
186 sizeof(int),
187 offset(ascii_length),
188 XtRImmediate((char*)&XtStrings[1695]),
189 (XtPointer)MAGIC_VALUE((XawTextPosition)-1)
190 },
191#ifdef ASCII_DISK
192 {
193 XtNfile((char*)&XtStrings[194]),
194 XtCFile((char*)&XtStrings[1012]),
195 XtRString((char*)&XtStrings[1797]),
196 sizeof(String),
197 offset(filename),
198 XtRString((char*)&XtStrings[1797]),
199 NULL((void*)0)
200 },
201#endif /* ASCII_DISK */
202};
203#undef offset
204
205
206#define Superclass(&textSrcClassRec) (&textSrcClassRec)
207AsciiSrcClassRec asciiSrcClassRec = {
208 /* object */
209 {
210 (WidgetClass)Superclass(&textSrcClassRec), /* superclass */
211 "AsciiSrc", /* class_name */
212 sizeof(AsciiSrcRec), /* widget_size */
213 XawAsciiSrcClassInitialize, /* class_initialize */
214 NULL((void*)0), /* class_part_initialize */
215 False0, /* class_inited */
216 XawAsciiSrcInitialize, /* initialize */
217 NULL((void*)0), /* initialize_hook */
218 NULL((void*)0), /* realize */
219 NULL((void*)0), /* actions */
220 0, /* num_actions */
221 resources, /* resources */
222 XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))), /* num_resources */
223 NULLQUARK((XrmQuark) 0), /* xrm_class */
224 False0, /* compress_motion */
225 False0, /* compress_exposure */
226 False0, /* compress_enterleave */
227 False0, /* visible_interest */
228 XawAsciiSrcDestroy, /* destroy */
229 NULL((void*)0), /* resize */
230 NULL((void*)0), /* expose */
231 XawAsciiSrcSetValues, /* set_values */
232 NULL((void*)0), /* set_values_hook */
233 NULL((void*)0), /* set_values_almost */
234 XawAsciiSrcGetValuesHook, /* get_values_hook */
235 NULL((void*)0), /* accept_focus */
236 XtVersion(11 * 1000 + 6), /* version */
237 NULL((void*)0), /* callback_private */
238 NULL((void*)0), /* tm_table */
239 NULL((void*)0), /* query_geometry */
240 NULL((void*)0), /* display_accelerator */
241 NULL((void*)0), /* extension */
242 },
243 /* text_src */
244 {
245 ReadText, /* Read */
246 ReplaceText, /* Replace */
247 Scan, /* Scan */
248 Search, /* Search */
249 XtInheritSetSelection((_XawSrcSetSelectionProc)_XtInherit), /* SetSelection */
250 XtInheritConvertSelection((_XawSrcConvertSelectionProc)_XtInherit), /* ConvertSelection */
251 },
252 /* ascii_src */
253 {
254 NULL((void*)0), /* extension */
255 },
256};
257
258WidgetClass asciiSrcObjectClass = (WidgetClass)&asciiSrcClassRec;
259
260static XrmQuark Qstring, Qfile;
261
262/*
263 * Implementation
264 */
265/*
266 * Function:
267 * XawAsciiSrcClassInitialize()
268 *
269 * Description:
270 * Initializes the asciiSrcObjectClass and install the converters for
271 * AsciiType <-> String.
272 */
273static void
274XawAsciiSrcClassInitialize(void)
275{
276 XawInitializeWidgetSet();
277 Qstring = XrmPermStringToQuark(XtEstring"string");
278 Qfile = XrmPermStringToQuark(XtEfile"file");
279 XtAddConverter(XtRString((char*)&XtStrings[1797]), XtRAsciiType"AsciiType", CvtStringToAsciiType, NULL((void*)0), 0);
280 XtSetTypeConverter(XtRAsciiType"AsciiType", XtRString((char*)&XtStrings[1797]), CvtAsciiTypeToString,
281 NULL((void*)0), 0, XtCacheNone0x001, NULL((void*)0));
282}
283
284/*
285 * Function:
286 * XawAsciiSrcInitialize
287 *
288 * Parameters:
289 * request - widget requested by the argument list
290 * cnew - new widget with both resource and non resource values
291 * args - (unused)
292 * num_args - (unused)
293 *
294 * Description:
295 * Initializes the ascii src object.
296 */
297/*ARGSUSED*/
298static void
299XawAsciiSrcInitialize(Widget request, Widget cnew,
300 ArgList args, Cardinal *num_args)
301{
302 AsciiSrcObject src = (AsciiSrcObject)cnew;
303 FILE *file;
304
305 /*
306 * Set correct flags (override resources) depending upon widget class
307 */
308 src->text_src.text_format = XawFmt8Bit;
309
310#ifdef ASCII_DISK
311 if (XtIsSubclass(XtParent(cnew)((cnew)->core.parent), asciiDiskWidgetClass)) {
312 src->ascii_src.type = XawAsciiFile;
313 src->ascii_src.string = src->ascii_src.filename;
314 }
315#endif
316
317#ifdef ASCII_STRING
318 if (XtIsSubclass(XtParent(cnew)((cnew)->core.parent), asciiStringWidgetClass)) {
319 src->ascii_src.use_string_in_place = True1;
320 src->ascii_src.type = XawAsciiString;
321 }
322#endif
323
324#ifdef OLDXAW
325 src->ascii_src.changes = False0;
326#else
327 src->text_src.changed = False0;
328#endif
329 src->ascii_src.allocated_string = False0;
330
331 if (src->ascii_src.use_string_in_place && src->ascii_src.string == NULL((void*)0))
332 src->ascii_src.use_string_in_place = False0;
333
334 file = InitStringOrFile(src, src->ascii_src.type == XawAsciiFile);
335 LoadPieces(src, file, NULL((void*)0));
336
337 if (file != NULL((void*)0))
338 fclose(file);
339}
340
341/*
342 * Function:
343 * ReadText
344 *
345 * Parameters:
346 * w - AsciiSource widget
347 * pos - position of the text to retreive.
348 * text - text block that will contain returned text
349 * length - maximum number of characters to read
350 *
351 * Description:
352 * This function reads the source.
353 *
354 * Returns:
355 * The character position following the retrieved text.
356 */
357static XawTextPosition
358ReadText(Widget w, XawTextPosition pos, XawTextBlock *text, int length)
359{
360 AsciiSrcObject src = (AsciiSrcObject)w;
361 XawTextPosition count, start;
362 Piece *piece;
363#ifndef OLDXAW
364 XawTextAnchor *anchor;
365 XawTextEntity *entity;
366 XawTextPosition offset, end = pos + length;
367 Boolint state;
368
369 end = XawMin(end, src->ascii_src.length)((end) < (src->ascii_src.length) ? (end) : (src->ascii_src
.length))
;
370 while ((state = XawTextSourceAnchorAndEntity(w, pos, &anchor, &entity)) &&
371 (entity->flags & XAW_TENTF_HIDE0x0001))
372 pos = anchor->position + entity->offset + entity->length;
373 if (state == False0 ||
374 !(entity->flags & XAW_TENTF_REPLACE0x0004)) {
375 while (entity) {
376 offset = anchor->position + entity->offset;
377 if (offset >= end)
378 break;
379 if (offset > pos &&
380 (entity->flags & (XAW_TENTF_HIDE0x0001 | XAW_TENTF_REPLACE0x0004))) {
381 end = XawMin(end, offset)((end) < (offset) ? (end) : (offset));
382 break;
383 }
384 if ((entity = entity->next) == NULL((void*)0) &&
385 (anchor = XawTextSourceNextAnchor(w, anchor)) != NULL((void*)0))
386 entity = anchor->entities;
387 }
388 }
389 else if (state && (entity->flags & XAW_TENTF_REPLACE0x0004) && pos < end) {
390 XawTextBlock *block = (XawTextBlock*)entity->data;
391
392 offset = anchor->position + entity->offset;
393 end = XawMin(end, offset + block->length)((end) < (offset + block->length) ? (end) : (offset + block
->length))
;
394 if ((length = end - pos) < 0)
395 length = 0;
396 text->length = length;
397 text->format = XawFmt8Bit;
398 if (length == 0) {
399 text->firstPos = end = offset + entity->length;
400 text->ptr = "";
401 }
402 else {
403 text->firstPos = pos;
404 text->ptr = block->ptr + (pos - offset);
405 if (pos + length < offset + block->length)
406 end = pos + length; /* there is data left to be read */
407 else
408 end = offset + entity->length;
409 }
410
411 return (end);
412 }
413
414 if ((length = end - pos) < 0)
415 length = 0;
416#endif
417
418 piece = FindPiece(src, pos, &start);
419 text->firstPos = pos;
420 text->ptr = piece->text + (pos - start);
421 count = piece->used - (pos - start);
422 text->length = Max(0, (length > count) ? count : length)(((0) > ((length > count) ? count : length)) ? (0) : ((
length > count) ? count : length))
;
423 text->format = XawFmt8Bit;
424
425 return (pos + text->length);
426}
427
428/*
429 * Function:
430 * ReplaceText
431 *
432 * Parameters:
433 * w - AsciiSource object
434 * startPos - ends of text that will be replaced
435 * endPos - ""
436 * text - new text to be inserted into buffer at startPos
437 *
438 * Description:
439 * Replaces a block of text with new text.
440 *
441 * Returns:
442 * XawEditDone on success, XawEditError otherwise
443 */
444/*ARGSUSED*/
445static int
446ReplaceText(Widget w, XawTextPosition startPos, XawTextPosition endPos,
447 XawTextBlock *text)
448{
449 AsciiSrcObject src = (AsciiSrcObject)w;
450 Piece *start_piece, *end_piece, *temp_piece;
451 XawTextPosition start_first, end_first;
452 int length, firstPos;
453
454 /*
455 * Editing a read only source is not allowed
456 */
457 if (src->text_src.edit_mode == XawtextRead)
458 return (XawEditError1);
459
460 start_piece = FindPiece(src, startPos, &start_first);
461 end_piece = FindPiece(src, endPos, &end_first);
462
463#ifndef OLDXAW
464 /*
465 * This is a big hack, but I can't think about a clever way to know
466 * if the character being moved forward has a negative lbearing.
467 *
468 */
469 if (start_piece->used) {
470 int i;
471
472 for (i = 0; i < src->text_src.num_text; i++) {
473 int line;
474 TextWidget ctx = (TextWidget)src->text_src.text[i];
475
476 for (line = 0; line < ctx->text.lt.lines; line++)
477 if (startPos < ctx->text.lt.info[line + 1].position)
478 break;
479 if (i < ctx->text.lt.lines &&
480 startPos > ctx->text.lt.info[i].position) {
481 AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink;
482 XawTextAnchor *anchor;
483 XawTextEntity *entity;
484 XawTextProperty *property;
485 XFontStruct *font;
486
487 if (XawTextSourceAnchorAndEntity(w, startPos, &anchor, &entity) &&
488 (property = XawTextSinkGetProperty(ctx->text.sink,
489 entity->property)) != NULL((void*)0) &&
490 (property->mask & XAW_TPROP_FONT(1<<0)))
491 font = property->font;
492 else
493 font = sink->ascii_sink.font;
494
495 if (font->min_bounds.lbearing < 0) {
496 int lbearing = font->min_bounds.lbearing;
497 unsigned char c = *(unsigned char*)
498 (start_piece->text + (startPos - start_first));
499
500 if (c == '\t' || c == '\n')
501 c = ' ';
502 else if ((c & 0177) < XawSP0x20 || c == 0177) {
503 if (sink->ascii_sink.display_nonprinting)
504 c = c > 0177 ? '\\' : c + '^';
505 else
506 c = ' ';
507 }
508 if (font->per_char &&
509 (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
510 lbearing = font->per_char[c - font->min_char_or_byte2].lbearing;
511 if (lbearing < 0)
512 _XawTextNeedsUpdating(ctx, startPos - 1, startPos);
513 }
514 }
515 }
516 }
517
518
519#endif
520
521 /*
522 * Remove Old Stuff
523 */
524 if (start_piece != end_piece) {
525 temp_piece = start_piece->next;
526
527 /*
528 * If empty and not the only piece then remove it.
529 */
530 if (((start_piece->used = startPos - start_first) == 0)
531 && !(start_piece->next == NULL((void*)0) && start_piece->prev == NULL((void*)0)))
532 RemovePiece(src, start_piece);
533
534 while (temp_piece != end_piece) {
535 temp_piece = temp_piece->next;
536 RemovePiece(src, temp_piece->prev);
537 }
538
539 end_piece->used -= endPos - end_first;
540 if (end_piece->used != 0)
541 memmove(end_piece->text, end_piece->text + endPos - end_first,
542 (unsigned)end_piece->used);
543 }
544 else { /* We are fully in one piece */
545 if ((start_piece->used -= endPos - startPos) == 0) {
546 if (!(start_piece->next == NULL((void*)0) && start_piece->prev == NULL((void*)0)))
547 RemovePiece(src, start_piece);
548 }
549 else {
550 memmove(start_piece->text + (startPos - start_first),
551 start_piece->text + (endPos - start_first),
552 (unsigned)(start_piece->used - (startPos - start_first)));
553 if (src->ascii_src.use_string_in_place
554 && src->ascii_src.length - (endPos - startPos)
555 < src->ascii_src.piece_size - 1)
556 start_piece->text[src->ascii_src.length - (endPos - startPos)] =
557 '\0';
558 }
559 }
560
561 src->ascii_src.length += -(endPos - startPos) + text->length;
562
563 if ( text->length != 0) {
564 /*
565 * Put in the New Stuff
566 */
567 start_piece = FindPiece(src, startPos, &start_first);
568
569 length = text->length;
570 firstPos = text->firstPos;
571
572 while (length > 0) {
573 char *ptr;
574 int fill;
575
576 if (src->ascii_src.use_string_in_place) {
577 if (start_piece->used == src->ascii_src.piece_size - 1) {
578 /*
579 * If we are in ascii string emulation mode. Then the
580 * string is not allowed to grow
581 */
582 start_piece->used = src->ascii_src.length =
583 src->ascii_src.piece_size - 1;
584 start_piece->text[src->ascii_src.length] = '\0';
585 return (XawEditError1);
586 }
587 }
588
589 if (start_piece->used == src->ascii_src.piece_size) {
590 BreakPiece(src, start_piece);
591 start_piece = FindPiece(src, startPos, &start_first);
592 }
593
594 fill = Min((int)(src->ascii_src.piece_size - start_piece->used),((((int)(src->ascii_src.piece_size - start_piece->used)
) < (length)) ? ((int)(src->ascii_src.piece_size - start_piece
->used)) : (length))
595 length)((((int)(src->ascii_src.piece_size - start_piece->used)
) < (length)) ? ((int)(src->ascii_src.piece_size - start_piece
->used)) : (length))
;
596
597 ptr = start_piece->text + (startPos - start_first);
598 memmove(ptr + fill, ptr,
599 (unsigned)(start_piece->used - (startPos - start_first)));
600 memcpy(ptr, text->ptr + firstPos, (unsigned)fill);
601
602 startPos += fill;
603 firstPos += fill;
604 start_piece->used += fill;
605 length -= fill;
606 }
607 }
608
609 if (src->ascii_src.use_string_in_place)
610 start_piece->text[start_piece->used] = '\0';
611
612#ifdef OLDXAW
613 src->ascii_src.changes = True1;
614 XtCallCallbacks(w, XtNcallback((char*)&XtStrings[136]), NULL((void*)0));
615#endif
616
617 return (XawEditDone0);
618}
619
620/*
621 * Function:
622 * Scan
623 *
624 * Parameters:
625 * w - AsciiSource object
626 * position - position to start scanning
627 * type - type of thing to scan for
628 * dir - direction to scan
629 * count - which occurance if this thing to search for.
630 * include - whether or not to include the character found in
631 * the position that is returned
632 *
633 * Description:
634 * Scans the text source for the number and type of item specified.
635 *
636 * Returns:
637 * The position of the item found
638 *
639 * Note:
640 * While there are only 'n' characters in the file there are n+1
641 * possible cursor positions (one before the first character and
642 * one after the last character
643 */
644static XawTextPosition
645Scan(Widget w, register XawTextPosition position, XawTextScanType type,
646 XawTextScanDirection dir, int count, Boolint include)
647{
648 AsciiSrcObject src = (AsciiSrcObject)w;
649 Piece *piece;
650 XawTextPosition first, first_eol_position = 0;
651 register char *ptr, *lim;
652 register int cnt = count;
653 register unsigned char c;
654
655 if (dir == XawsdLeft) {
656 if (position <= 0)
657 return (0);
658 --position;
659 }
660 else if (position >= src->ascii_src.length)
661 return (src->ascii_src.length);
662
663 piece = FindPiece(src, position, &first);
664 if (piece->used == 0)
665 return (0);
666
667 ptr = (position - first) + piece->text;
668
669 if (dir == XawsdRight) {
670 lim = piece->text + piece->used;
671 switch (type) {
672 case XawstEOL:
673 case XawstParagraph:
674 case XawstWhiteSpace:
675 case XawstAlphaNumeric:
676 for (; cnt > 0; cnt--) {
677 Boolint non_space = False0, first_eol = True1;
678
679 /*CONSTCOND*/
680 while (True1) {
681 if (ptr >= lim) {
682 piece = piece->next;
683 if (piece == NULL((void*)0)) /* End of text */
684 return (src->ascii_src.length);
685 ptr = piece->text;
686 lim = piece->text + piece->used;
687 }
688
689 c = *ptr++;
690 ++position;
691
692 if (type == XawstEOL) {
693 if (c == '\n')
694 break;
695 }
696 else if (type == XawstAlphaNumeric) {
697 if (!isalnum(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISalnum
)
) {
698 if (non_space)
699 break;
700 }
701 else
702 non_space = True1;
703 }
704 else if (type == XawstWhiteSpace) {
705 if (isspace(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISspace
)
) {
706 if (non_space)
707 break;
708 }
709 else
710 non_space = True1;
711 }
712 else { /* XawstParagraph */
713 if (first_eol) {
714 if (c == '\n') {
715 first_eol_position = position;
716 first_eol = False0;
717 }
718 }
719 else if (c == '\n')
720 break;
721 else if (!isspace(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISspace
)
)
722 first_eol = True1;
723 }
724 }
725 }
726 break;
727 case XawstPositions:
728 position += count;
729 return (position < src->ascii_src.length ?
730 position : src->ascii_src.length);
731 case XawstAll:
732 return (src->ascii_src.length);
733 default:
734 break;
735 }
736 if (!include) {
737 if (type == XawstParagraph)
738 position = first_eol_position;
739 if (count)
740 --position;
741 }
742 }
743 else {
744 lim = piece->text;
745 switch (type) {
746 case XawstEOL:
747 case XawstParagraph:
748 case XawstWhiteSpace:
749 case XawstAlphaNumeric:
750 for (; cnt > 0; cnt--) {
751 Boolint non_space = False0, first_eol = True1;
752
753 /*CONSTCOND*/
754 while (True1) {
755 if (ptr < lim) {
756 piece = piece->prev;
757 if (piece == NULL((void*)0)) /* Begining of text */
758 return (0);
759 ptr = piece->text + piece->used - 1;
760 lim = piece->text;
761 }
762
763 c = *ptr--;
764 --position;
765
766 if (type == XawstEOL) {
767 if (c == '\n')
768 break;
769 }
770 else if (type == XawstAlphaNumeric) {
771 if (!isalnum(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISalnum
)
) {
772 if (non_space)
773 break;
774 }
775 else
776 non_space = True1;
777 }
778 else if (type == XawstWhiteSpace) {
779 if (isspace(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISspace
)
) {
780 if (non_space)
781 break;
782 }
783 else
784 non_space = True1;
785 }
786 else { /* XawstParagraph */
787 if (first_eol) {
788 if (c == '\n') {
789 first_eol_position = position;
790 first_eol = False0;
791 }
792 }
793 else if (c == '\n')
794 break;
795 else if (!isspace(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISspace
)
)
796 first_eol = True1;
797 }
798 }
799 }
800 break;
801 case XawstPositions:
802 position -= count - 1;
803 return (position > 0 ? position : 0);
804 case XawstAll:
805 return (0);
806 default:
807 break;
808 }
809 if (!include) {
810 if (type == XawstParagraph)
811 position = first_eol_position;
812 if (count)
813 ++position;
814 }
815 position++;
816 }
817
818 return (position);
819}
820
821/*
822 * Function:
823 * Search
824 *
825 * Parameters:
826 * w - AsciiSource object
827 * position - the position to start scanning
828 * dir - direction to scan
829 * text - text block to search for
830 *
831 * Description:
832 * Searchs the text source for the text block passed.
833 *
834 * Returns:
835 * The position of the item found
836 */
837static XawTextPosition
838Search(Widget w, register XawTextPosition position, XawTextScanDirection dir,
839 XawTextBlock *text)
840{
841 AsciiSrcObject src = (AsciiSrcObject)w;
842 register int count = 0;
843 register char *ptr, c;
844 char *str;
845 Piece *piece;
846 char *buf;
847 XawTextPosition first;
848 int cnt, case_sensitive;
849
850 if (dir == XawsdLeft) {
851 if (position == 0)
852 return (XawTextSearchError(-12345L));
853 position--;
854 }
855
856 buf = XtMalloc((unsigned)sizeof(unsigned char) * text->length);
857 memcpy(buf, text->ptr, (unsigned)text->length);
858 piece = FindPiece(src, position, &first);
859 ptr = (position - first) + piece->text;
860 case_sensitive = text->firstPos;
861
862 if (dir == XawsdRight) {
863 str = buf;
864 c = *str;
865 /*CONSTCOND*/
866 while (1) {
867 if (*ptr++ == c
868 || (case_sensitive && isalpha(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISalpha
)
&& isalpha(ptr[-1])((*__ctype_b_loc ())[(int) ((ptr[-1]))] & (unsigned short
int) _ISalpha)
869 && toupper(c) == toupper(ptr[-1]))) {
870 if (++count == text->length)
871 break;
872 c = *++str;
873 }
874 else if (count) {
875 ptr -= count;
876 str -= count;
877 position -= count;
878 count = 0;
879 c = *str;
880
881 if (ptr < piece->text) {
882 do {
883 cnt = piece->text - ptr;
884 piece = piece->prev;
885 if (piece == NULL((void*)0)) {
886 XtFree(buf);
887 return (XawTextSearchError(-12345L));
888 }
889 ptr = piece->text + piece->used - cnt;
890 } while (ptr < piece->text);
891 }
892 }
893 position++;
894 if (ptr >= (piece->text + piece->used)) {
895 do {
896 cnt = ptr - (piece->text + piece->used);
897 piece = piece->next;
898 if (piece == NULL((void*)0)) {
899 XtFree(buf);
900 return (XawTextSearchError(-12345L));
901 }
902 ptr = piece->text + cnt;
903 } while (ptr >= (piece->text + piece->used));
904 }
905 }
906
907 position -= text->length - 1;
908 }
909 else {
910 str = buf + text->length - 1;
911 c = *str;
912 /*CONSTCOND*/
913 while (1) {
914 if (*ptr-- == c
915 || (case_sensitive && isalpha(c)((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISalpha
)
&& isalpha(ptr[1])((*__ctype_b_loc ())[(int) ((ptr[1]))] & (unsigned short int
) _ISalpha)
916 && toupper(c) == toupper(ptr[1]))) {
917 if (++count == text->length)
918 break;
919 c = *--str;
920 }
921 else if (count) {
922 ptr += count;
923 str += count;
924 position += count;
925 count = 0;
926 c = *str;
927
928 if (ptr >= (piece->text + piece->used)) {
929 do {
930 cnt = ptr - (piece->text + piece->used);
931 piece = piece->next;
932 if (piece == NULL((void*)0)) {
933 XtFree(buf);
934 return (XawTextSearchError(-12345L));
935 }
936 ptr = piece->text + cnt;
937 } while (ptr >= (piece->text + piece->used));
938 }
939 }
940 position--;
941 if (ptr < piece->text) {
942 do {
943 cnt = piece->text - ptr;
944 piece = piece->prev;
945 if (piece == NULL((void*)0)) {
946 XtFree(buf);
947 return (XawTextSearchError(-12345L));
948 }
949 ptr = piece->text + piece->used - cnt;
950 } while (ptr < piece->text);
951 }
952 }
953 }
954
955 XtFree(buf);
956
957 return (position);
958}
959
960/*
961 * Function:
962 * XawAsciiSrcSetValues
963 *
964 * Parameters:
965 * current - current state of the widget
966 * request - what was requested
967 * cnew - what the widget will become
968 * args - representation of changed resources
969 * num_args - number of resources that have changed
970 *
971 * Description:
972 * Sets the values for the AsciiSource.
973 *
974 * Returns:
975 * True if redisplay is needed
976 */
977static Boolean
978XawAsciiSrcSetValues(Widget current, Widget request, Widget cnew,
979 ArgList args, Cardinal *num_args)
980{
981 AsciiSrcObject src = (AsciiSrcObject)cnew;
982 AsciiSrcObject old_src = (AsciiSrcObject)current;
983 Boolint total_reset = False0, string_set = False0;
984 FILE *file;
985 unsigned int i;
986
987 if (old_src->ascii_src.use_string_in_place
988 != src->ascii_src.use_string_in_place) {
989 XtAppWarning(XtWidgetToApplicationContext(cnew),
990 "AsciiSrc: The XtNuseStringInPlace resource may "
991 "not be changed.");
992 src->ascii_src.use_string_in_place =
993 old_src->ascii_src.use_string_in_place;
994 }
995
996 for (i = 0; i < *num_args ; i++)
997 if (streq(args[i].name, XtNstring)(strcmp((args[i].name), (((char*)&XtStrings[733]))) == 0)) {
998 string_set = True1;
999 break;
1000 }
1001
1002 if (string_set || (old_src->ascii_src.type != src->ascii_src.type)) {
1003 RemoveOldStringOrFile(old_src, string_set); /* remove old info */
1004 file = InitStringOrFile(src, string_set); /* Init new info */
1005 LoadPieces(src, file, NULL((void*)0)); /* load new info into internal buffers */
1006 if (file != NULL((void*)0))
1007 fclose(file);
1008#ifndef OLDXAW
1009 for (i = 0; i < src->text_src.num_text; i++)
1010 /* Tell text widget what happened */
1011 XawTextSetSource(src->text_src.text[i], cnew, 0);
1012#else
1013 XawTextSetSource(XtParent(cnew)((cnew)->core.parent), cnew, 0);
1014#endif
1015 total_reset = True1;
1016 }
1017
1018 if (old_src->ascii_src.ascii_length != src->ascii_src.ascii_length)
1019 src->ascii_src.piece_size = src->ascii_src.ascii_length + 1;
1020
1021 if (!total_reset &&
1022 old_src->ascii_src.piece_size != src->ascii_src.piece_size) {
1023 String string = StorePiecesInString(old_src);
1024
1025 FreeAllPieces(old_src);
1026 LoadPieces(src, NULL((void*)0), string);
1027 XtFree(string);
1028 }
1029
1030 return (False0);
1031}
1032
1033/*
1034 * Function:
1035 * XawAsciiSrcGetValuesHook
1036 *
1037 * Parameters:
1038 * w - AsciiSource Widget
1039 * args - argument list
1040 * num_args - number of args
1041 *
1042 * Description:
1043 * This is a get values hook routine that sets the
1044 * values specific to the ascii source.
1045 */
1046static void
1047XawAsciiSrcGetValuesHook(Widget w, ArgList args, Cardinal *num_args)
1048{
1049 AsciiSrcObject src = (AsciiSrcObject)w;
1050 unsigned int i;
1051
1052 if (src->ascii_src.type == XawAsciiString) {
1053 for (i = 0; i < *num_args ; i++)
1054 if (streq(args[i].name, XtNstring)(strcmp((args[i].name), (((char*)&XtStrings[733]))) == 0)) {
1055 if (src->ascii_src.use_string_in_place)
1056 *((char **)args[i].value) = src->ascii_src.first_piece->text;
1057 else if (XawAsciiSave(w)) /* If save sucessful */
1058 *((char **)args[i].value) = src->ascii_src.string;
1059 break;
1060 }
1061 }
1062 }
1063
1064/*
1065 * Function:
1066 * XawAsciiSrcDestroy
1067 *
1068 * Parameters:
1069 * src - Ascii source object to free
1070 *
1071 * Description:
1072 * Destroys an ascii source (frees all data)
1073 */
1074static void
1075XawAsciiSrcDestroy(Widget w)
1076{
1077 RemoveOldStringOrFile((AsciiSrcObject) w, True1);
1078}
1079
1080/*
1081 * Public routines
1082 */
1083/*
1084 * Function:
1085 * XawAsciiSourceFreeString
1086 *
1087 * Parameters:
1088 * w - AsciiSrc widget
1089 *
1090 * Description:
1091 * Frees the string returned by a get values call
1092 * on the string when the source is of type string.
1093 */
1094void
1095XawAsciiSourceFreeString(Widget w)
1096{
1097 AsciiSrcObject src = (AsciiSrcObject)w;
1098
1099 /* If the src is really a multi, call the multi routine */
1100 if (XtIsSubclass(w, multiSrcObjectClass)) {
1101 _XawMultiSourceFreeString(w);
1102 return;
1103 }
1104 else if (!XtIsSubclass(w, asciiSrcObjectClass)) {
1105 XtErrorMsg("bad argument", "asciiSource", "XawError",
1106 "XawAsciiSourceFreeString's parameter must be "
1107 "an asciiSrc or multiSrc.",
1108 NULL((void*)0), NULL((void*)0));
1109 }
1110
1111 if (src->ascii_src.allocated_string && src->ascii_src.type != XawAsciiFile) {
1112 src->ascii_src.allocated_string = False0;
1113 XtFree(src->ascii_src.string);
1114 src->ascii_src.string = NULL((void*)0);
1115 }
1116}
1117
1118/*
1119 * Function:
1120 * XawAsciiSave
1121 *
1122 * Parameters:
1123 * w - asciiSrc Widget
1124 *
1125 * Description:
1126 * Saves all the pieces into a file or string as required.
1127 *
1128 * Returns:
1129 * True if the save was successful
1130 */
1131Boolint
1132XawAsciiSave(Widget w)
1133{
1134 AsciiSrcObject src = (AsciiSrcObject)w;
1135
1136 /* If the src is really a multi, call the multi save */
1137 if (XtIsSubclass(w, multiSrcObjectClass ))
1138 return (_XawMultiSave(w));
1139
1140 else if (!XtIsSubclass(w, asciiSrcObjectClass))
1141 XtErrorMsg("bad argument", "asciiSource", "XawError",
1142 "XawAsciiSave's parameter must be an asciiSrc or multiSrc.",
1143 NULL((void*)0), NULL((void*)0));
1144
1145 /*
1146 * If using the string in place then there is no need to play games
1147 * to get the internal info into a readable string.
1148 */
1149 if (src->ascii_src.use_string_in_place)
1150 return (True1);
1151
1152 if (src->ascii_src.type == XawAsciiFile) {
1153#ifdef OLDXAW
1154 if (!src->ascii_src.changes)
1155#else
1156 if (!src->text_src.changed) /* No changes to save */
1157#endif
1158 return (True1);
1159
1160 if (WritePiecesToFile(src, src->ascii_src.string) == False0)
1161 return (False0);
1162 }
1163 else {
1164 if (src->ascii_src.allocated_string == True1)
1165 XtFree(src->ascii_src.string);
1166 else
1167 src->ascii_src.allocated_string = True1;
1168
1169 src->ascii_src.string = StorePiecesInString(src);
1170 }
1171#ifdef OLDXAW
1172 src->ascii_src.changes = False0;
1173#else
1174 src->text_src.changed = False0;
1175#endif
1176
1177 return (True1);
1178}
1179
1180/*
1181 * Function:
1182 * XawAsciiSaveAsFile
1183 *
1184 * Arguments:
1185 * w - AsciiSrc widget
1186 * name - name of the file to save this file into
1187 *
1188 * Description:
1189 * Save the current buffer as a file.
1190 *
1191 * Returns:
1192 * True if the save was sucessful
1193 */
1194Boolint
1195XawAsciiSaveAsFile(Widget w, _Xconstconst char *name)
1196{
1197 AsciiSrcObject src = (AsciiSrcObject)w;
1198 Boolint ret;
1199
1200 /* If the src is really a multi, call the multi save */
1201
1202 if (XtIsSubclass( w, multiSrcObjectClass))
1203 return (_XawMultiSaveAsFile(w, name));
1204
1205 else if (!XtIsSubclass(w, asciiSrcObjectClass))
1206 XtErrorMsg("bad argument", "asciiSource", "XawError",
1207 "XawAsciiSaveAsFile's 1st parameter must be an "
1208 "asciiSrc or multiSrc.",
1209 NULL((void*)0), NULL((void*)0));
1210
1211 if (src->ascii_src.type == XawAsciiFile)
1212 ret = WritePiecesToFile(src, (String)name);
1213 else {
1214 String string = StorePiecesInString(src);
1215
1216 ret = WriteToFile(string, (String)name, src->ascii_src.length);
1217 XtFree(string);
1218 }
1219
1220 return (ret);
1221}
1222
1223/*
1224 * Function:
1225 * XawAsciiSourceChanged
1226 *
1227 * Parameters:
1228 * w - ascii source widget
1229 *
1230 * Description:
1231 * Returns true if the source has changed since last saved.
1232 *
1233 * Returns:
1234 * A Boolean (see description).
1235 */
1236Boolint
1237XawAsciiSourceChanged(Widget w)
1238{
1239#ifdef OLDXAW
1240 if (XtIsSubclass(w, multiSrcObjectClass))
1241 return (((MultiSrcObject)w)->multi_src.changes);
1242
1243 if (XtIsSubclass(w, asciiSrcObjectClass))
1244 return (((AsciiSrcObject)w)->ascii_src.changes);
1245#else
1246 if (XtIsSubclass(w, textSrcObjectClass))
1247 return (((TextSrcObject)w)->textSrc.changed);
1248#endif
1249 XtErrorMsg("bad argument", "asciiSource", "XawError",
1250 "XawAsciiSourceChanged parameter must be an "
1251 "asciiSrc or multiSrc.",
1252 NULL((void*)0), NULL((void*)0));
1253
1254 return (True1);
1255}
1256
1257/*
1258 * Private Functions
1259 */
1260static void
1261RemoveOldStringOrFile(AsciiSrcObject src, Boolint checkString)
1262{
1263 FreeAllPieces(src);
1264
1265 if (checkString && src->ascii_src.allocated_string) {
1266 XtFree(src->ascii_src.string);
1267 src->ascii_src.allocated_string = False0;
1268 src->ascii_src.string = NULL((void*)0);
1269 }
1270}
1271
1272/*
1273 * Function:
1274 * WriteToFile
1275 *
1276 * Parameters:
1277 * string - string to write
1278 * name - the name of the file
1279 *
1280 * Description:
1281 * Write the string specified to the begining of the file specified.
1282 *
1283 * Returns:
1284 * returns True if sucessful, False otherwise
1285 */
1286static Boolint
1287WriteToFile(String string, String name, unsigned length)
1288{
1289 int fd;
1290
1291 if ((fd = creat(name, 0666)) == -1)
1292 return (False0);
1293
1294 if (write(fd, string, length) == -1) {
1295 close(fd);
1296 return (False0);
1297 }
1298
1299 if (close(fd) == -1)
1300 return (False0);
1301
1302 return (True1);
1303}
1304
1305/*
1306 * Function:
1307 * WritePiecesToFile
1308 *
1309 * Parameters:
1310 * src - ascii source object
1311 * name - name of the file
1312 *
1313 * Description:
1314 * Almost identical to WriteToFile, but only works for ascii src objects
1315 * of type XawAsciiFile. This function avoids allocating temporary memory,
1316 * what can be useful when editing very large files.
1317 *
1318 * Returns:
1319 * returns True if sucessful, False otherwise
1320 */
1321static Boolint
1322WritePiecesToFile(AsciiSrcObject src, String name)
1323{
1324 Piece *piece;
1325 int fd;
1326
1327 if (src->ascii_src.data_compression) {
1328 Piece *tmp;
1329
1330 piece = src->ascii_src.first_piece;
1331 while (piece) {
1332 int bytes = src->ascii_src.piece_size - piece->used;
1333
1334 if (bytes > 0 && (tmp = piece->next) != NULL((void*)0)) {
1335 bytes = XawMin(bytes, tmp->used)((bytes) < (tmp->used) ? (bytes) : (tmp->used));
1336 memcpy(piece->text + piece->used, tmp->text, bytes);
1337 memmove(tmp->text, tmp->text + bytes, tmp->used - bytes);
1338 piece->used += bytes;
1339 if ((tmp->used -= bytes) == 0) {
1340 RemovePiece(src, tmp);
1341 continue;
1342 }
1343 }
1344 piece = piece->next;
1345 }
1346 }
1347
1348 if ((fd = creat(name, 0666)) == -1)
1349 return (False0);
1350
1351 for (piece = src->ascii_src.first_piece; piece; piece = piece->next)
1352 if (write(fd, piece->text, piece->used) == -1) {
1353 close(fd);
1354 return (False0);
1355 }
1356
1357 if (close(fd) == -1)
1358 return (False0);
1359
1360 return (True1);
1361}
1362
1363/*
1364 * Function:
1365 * StorePiecesInString
1366 *
1367 * Parameters:
1368 * data - ascii pointer data
1369 *
1370 * Description:
1371 * Store the pieces in memory into a standard ascii string.
1372 */
1373static String
1374StorePiecesInString(AsciiSrcObject src)
1375{
1376 String string;
1377 XawTextPosition first;
1378 Piece *piece;
1379
1380 string = XtMalloc((unsigned)(src->ascii_src.length + 1));
1381
1382 for (first = 0, piece = src->ascii_src.first_piece ; piece != NULL((void*)0);
1383 first += piece->used, piece = piece->next)
1384 memcpy(string + first, piece->text, (unsigned)piece->used);
1385
1386 string[src->ascii_src.length] = '\0';
1387
1388 /*
1389 * This will refill all pieces to capacity
1390 */
1391 if (src->ascii_src.data_compression) {
1392 FreeAllPieces(src);
1393 LoadPieces(src, NULL((void*)0), string);
1394 }
1395
1396 return (string);
1397}
1398
1399/*
1400 * Function:
1401 * InitStringOrFile
1402 *
1403 * Parameters:
1404 * src - AsciiSource
1405 *
1406 * Description:
1407 * Initializes the string or file.
1408 */
1409static FILE *
1410InitStringOrFile(AsciiSrcObject src, Boolint newString)
1411{
1412 mode_t open_mode = 0;
1413 const char *fdopen_mode = NULL((void*)0);
1414 int fd;
1415 FILE *file;
1416
1417 if (src->ascii_src.type == XawAsciiString) {
1
Taking false branch
1418 if (src->ascii_src.string == NULL((void*)0))
1419 src->ascii_src.length = 0;
1420
1421 else if (!src->ascii_src.use_string_in_place) {
1422 src->ascii_src.string = XtNewString(src->ascii_src.string)((src->ascii_src.string) != ((void*)0) ? (strcpy(XtMalloc(
(unsigned)strlen(src->ascii_src.string) + 1), src->ascii_src
.string)) : ((void*)0))
;
1423 src->ascii_src.allocated_string = True1;
1424 src->ascii_src.length = strlen(src->ascii_src.string);
1425 }
1426
1427 if (src->ascii_src.use_string_in_place) {
1428 if (src->ascii_src.string != NULL((void*)0))
1429 src->ascii_src.length = strlen(src->ascii_src.string);
1430 /* In case the length resource is incorrectly set */
1431 if (src->ascii_src.length > src->ascii_src.ascii_length)
1432 src->ascii_src.ascii_length = src->ascii_src.length;
1433
1434 if (src->ascii_src.ascii_length == MAGIC_VALUE((XawTextPosition)-1))
1435 src->ascii_src.piece_size = src->ascii_src.length;
1436 else
1437 src->ascii_src.piece_size = src->ascii_src.ascii_length + 1;
1438 }
1439
1440 return (NULL((void*)0));
1441 }
1442
1443 /*
1444 * type is XawAsciiFile
1445 */
1446 src->ascii_src.is_tempfile = False0;
1447
1448 switch (src->text_src.edit_mode) {
2
Control jumps to 'case XawtextRead:' at line 1449
1449 case XawtextRead:
1450 if (src->ascii_src.string == NULL((void*)0))
3
Taking true branch
1451 XtErrorMsg("NoFile", "asciiSourceCreate", "XawError",
1452 "Creating a read only disk widget and no file specified.",
1453 NULL((void*)0), NULL((void*)0));
1454 open_mode = O_RDONLY00;
1455 fdopen_mode = "r";
1456 break;
4
Execution continues on line 1482
1457 case XawtextAppend:
1458 case XawtextEdit:
1459 if (src->ascii_src.string == NULL((void*)0)) {
1460 src->ascii_src.string = "*ascii-src*";
1461 src->ascii_src.is_tempfile = True1;
1462 }
1463 else {
1464/* O_NOFOLLOW is a FreeBSD & Linux extension */
1465#ifdef O_NOFOLLOW0100000
1466 open_mode = O_RDWR02 | O_NOFOLLOW0100000;
1467#else
1468 open_mode = O_RDWR02; /* unsafe; subject to race conditions */
1469#endif /* O_NOFOLLOW */
1470 fdopen_mode = "r+";
1471 }
1472 break;
1473 default:
1474 XtErrorMsg("badMode", "asciiSourceCreate", "XawError",
1475 "Bad editMode for ascii source; must be Read, "
1476 "Append or Edit.",
1477 NULL((void*)0), NULL((void*)0));
1478 }
1479
1480 /* If is_tempfile, allocate a private copy of the text
1481 * Unlikely to be changed, just to set allocated_string */
1482 if (newString || src->ascii_src.is_tempfile) {
5
Taking false branch
1483 src->ascii_src.string = XtNewString(src->ascii_src.string)((src->ascii_src.string) != ((void*)0) ? (strcpy(XtMalloc(
(unsigned)strlen(src->ascii_src.string) + 1), src->ascii_src
.string)) : ((void*)0))
;
1484 src->ascii_src.allocated_string = True1;
1485 }
1486
1487 if (!src->ascii_src.is_tempfile) {
6
Taking true branch
1488 if ((fd = open(src->ascii_src.string, open_mode, 0666)) != -1) {
7
Null pointer passed as an argument to a 'nonnull' parameter
1489 if ((file = fdopen(fd, fdopen_mode))) {
1490 (void)fseek(file, 0, SEEK_END2);
1491 src->ascii_src.length = (XawTextPosition)ftell(file);
1492 return (file);
1493 }
1494 }
1495 {
1496 String params[2];
1497 Cardinal num_params = 2;
1498
1499 params[0] = src->ascii_src.string;
1500 params[1] = strerror(errno(*__errno_location ()));
1501 XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src),
1502 "openError", "asciiSourceCreate", "XawWarning",
1503 "Cannot open file %s; %s", params, &num_params);
1504 }
1505 }
1506 src->ascii_src.length = 0;
1507 return (NULL((void*)0));
1508}
1509
1510static void
1511LoadPieces(AsciiSrcObject src, FILE *file, char *string)
1512{
1513 char *ptr;
1514 Piece *piece = NULL((void*)0);
1515 XawTextPosition left;
1516
1517 if (string == NULL((void*)0)) {
1518 if (src->ascii_src.type == XawAsciiFile) {
1519 if (src->ascii_src.length != 0) {
1520 int len;
1521
1522 left = 0;
1523 fseek(file, 0, 0);
1524 while (left < src->ascii_src.length) {
1525 ptr = XtMalloc((unsigned)src->ascii_src.piece_size);
1526 if ((len = fread(ptr, (Size_tsize_t)sizeof(unsigned char),
1527 (Size_tsize_t)src->ascii_src.piece_size, file)) < 0)
1528 XtErrorMsg("readError", "asciiSourceCreate", "XawError",
1529 "fread returned error.", NULL((void*)0), NULL((void*)0));
1530 piece = AllocNewPiece(src, piece);
1531 piece->text = ptr;
1532 piece->used = XawMin(len, src->ascii_src.piece_size)((len) < (src->ascii_src.piece_size) ? (len) : (src->
ascii_src.piece_size))
;
1533 left += piece->used;
1534 }
1535 }
1536 else {
1537 piece = AllocNewPiece(src, NULL((void*)0));
1538 piece->text = XtMalloc((unsigned)src->ascii_src.piece_size);
1539 piece->used = 0;
1540 }
1541 return;
1542 }
1543 else
1544 string = src->ascii_src.string;
1545 }
1546
1547 if (src->ascii_src.use_string_in_place) {
1548 piece = AllocNewPiece(src, piece);
1549 piece->used = XawMin(src->ascii_src.length, src->ascii_src.piece_size)((src->ascii_src.length) < (src->ascii_src.piece_size
) ? (src->ascii_src.length) : (src->ascii_src.piece_size
))
;
1550 piece->text = src->ascii_src.string;
1551 return;
1552 }
1553
1554 ptr = string;
1555 left = src->ascii_src.length;
1556 do {
1557 piece = AllocNewPiece(src, piece);
1558
1559 piece->text = XtMalloc((unsigned)src->ascii_src.piece_size);
1560 piece->used = XawMin(left, src->ascii_src.piece_size)((left) < (src->ascii_src.piece_size) ? (left) : (src->
ascii_src.piece_size))
;
1561 if (piece->used != 0)
1562 memcpy(piece->text, ptr, (unsigned)piece->used);
1563
1564 left -= piece->used;
1565 ptr += piece->used;
1566 } while (left > 0);
1567}
1568
1569/*
1570 * Function:
1571 * AllocNewPiece
1572 *
1573 * Parameters:
1574 * src - AsciiSrc Widget
1575 * prev - piece just before this one, or NULL
1576 *
1577 * Description:
1578 * Allocates a new piece of memory.
1579 *
1580 * Returns:
1581 * The allocated piece
1582 */
1583static Piece *
1584AllocNewPiece(AsciiSrcObject src, Piece *prev)
1585{
1586 Piece *piece = XtNew(Piece)((Piece *) XtMalloc((unsigned) sizeof(Piece)));
1587
1588 if (prev == NULL((void*)0)) {
1589 src->ascii_src.first_piece = piece;
1590 piece->next = NULL((void*)0);
1591 }
1592 else {
1593 if (prev->next != NULL((void*)0))
1594 (prev->next)->prev = piece;
1595 piece->next = prev->next;
1596 prev->next = piece;
1597 }
1598
1599 piece->prev = prev;
1600
1601 return (piece);
1602}
1603
1604/*
1605 * Function:
1606 * FreeAllPieces
1607 *
1608 * Parameters:
1609 * src - AsciiSrc Widget
1610 *
1611 * Description:
1612 * Frees all the pieces.
1613 */
1614static void
1615FreeAllPieces(AsciiSrcObject src)
1616{
1617 Piece *next, * first = src->ascii_src.first_piece;
1618
1619#ifdef DEBUG
1620 if (first->prev != NULL((void*)0))
1621 printf("Xaw AsciiSrc Object: possible memory leak in FreeAllPieces().\n");
1622#endif
1623
1624 for (; first != NULL((void*)0) ; first = next) {
1625 next = first->next;
1626 RemovePiece(src, first);
1627 }
1628}
1629
1630/*
1631 * Function:
1632 * RemovePiece
1633 *
1634 * Parameters:
1635 * piece - piece to remove
1636 *
1637 * Description:
1638 * Removes a piece from the list.
1639 */
1640static void
1641RemovePiece(AsciiSrcObject src, Piece *piece)
1642{
1643 if (piece->prev == NULL((void*)0))
1644 src->ascii_src.first_piece = piece->next;
1645 else
1646 piece->prev->next = piece->next;
1647
1648 if (piece->next != NULL((void*)0))
1649 piece->next->prev = piece->prev;
1650
1651 if (!src->ascii_src.use_string_in_place)
1652 XtFree(piece->text);
1653
1654 XtFree((char *)piece);
1655}
1656
1657/*
1658 * Function:
1659 * FindPiece
1660 *
1661 * Parameters:
1662 * src - AsciiSrc Widget
1663 * position - position that we are searching for
1664 * first - position of the first character in this piece (return)
1665 *
1666 * Description:
1667 * Finds the piece containing the position indicated.
1668 *
1669 * Returns:
1670 * the piece that contains this position
1671 */
1672static Piece *
1673FindPiece(AsciiSrcObject src, XawTextPosition position, XawTextPosition *first)
1674{
1675 Piece *old_piece, *piece;
1676 XawTextPosition temp;
1677
1678 for (old_piece = NULL((void*)0), piece = src->ascii_src.first_piece, temp = 0;
1679 piece; old_piece = piece, piece = piece->next)
1680 if ((temp += piece->used) > position) {
1681 *first = temp - piece->used;
1682 return (piece);
1683 }
1684
1685 *first = temp - (old_piece ? old_piece->used : 0);
1686
1687 return (old_piece); /* if we run off the end the return the last piece */
1688}
1689
1690/*
1691 * Function:
1692 * BreakPiece
1693 *
1694 * Parameters:
1695 * src - AsciiSrc Widget
1696 * piece - piece to break
1697 *
1698 * Description:
1699 * Breaks a full piece into two new pieces.
1700 */
1701#define HALF_PIECE(src->ascii_src.piece_size >> 1) (src->ascii_src.piece_size >> 1)
1702static void
1703BreakPiece(AsciiSrcObject src, Piece *piece)
1704{
1705 Piece *cnew = AllocNewPiece(src, piece);
1706
1707 cnew->text = XtMalloc((unsigned)src->ascii_src.piece_size);
1708 memcpy(cnew->text, piece->text + HALF_PIECE(src->ascii_src.piece_size >> 1),
1709 (unsigned)(src->ascii_src.piece_size - HALF_PIECE(src->ascii_src.piece_size >> 1)));
1710 piece->used = HALF_PIECE(src->ascii_src.piece_size >> 1);
1711 cnew->used = src->ascii_src.piece_size - HALF_PIECE(src->ascii_src.piece_size >> 1);
1712}
1713
1714/*ARGSUSED*/
1715static void
1716CvtStringToAsciiType(XrmValuePtr args, Cardinal *num_args,
1717 XrmValuePtr fromVal, XrmValuePtr toVal)
1718{
1719 static XawAsciiType type;
1720 XrmQuark q;
1721 char name[7];
1722
1723 XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name));
1724 q = XrmStringToQuark(name);
1725
1726 if (q == Qstring)
1727 type = XawAsciiString;
1728 else if (q == Qfile)
1729 type = XawAsciiFile;
1730 else {
1731 toVal->size = 0;
1732 toVal->addr = NULL((void*)0);
1733 XtStringConversionWarning((char *)fromVal->addr, XtRAsciiType"AsciiType");
1734 }
1735
1736 toVal->size = sizeof(XawAsciiType);
1737 toVal->addr = (XPointer)&type;
1738}
1739
1740/*ARGSUSED*/
1741static Boolean
1742CvtAsciiTypeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args,
1743 XrmValuePtr fromVal, XrmValuePtr toVal,
1744 XtPointer *data)
1745{
1746 static String buffer;
1747 Cardinal size;
1748
1749 switch (*(XawAsciiType *)fromVal->addr) {
1750 case XawAsciiFile:
1751 buffer = XtEfile"file";
1752 break;
1753 case XawAsciiString:
1754 buffer = XtEstring"string";
1755 break;
1756 default:
1757 XawTypeToStringWarning(dpy, XtRAsciiType"AsciiType");
1758 toVal->addr = NULL((void*)0);
1759 toVal->size = 0;
1760 return (False0);
1761 }
1762
1763 size = strlen(buffer) + 1;
1764 if (toVal->addr != NULL((void*)0)) {
1765 if (toVal->size < size) {
1766 toVal->size = size;
1767 return (False0);
1768 }
1769 strcpy((char *)toVal->addr, buffer);
1770 }
1771 else
1772 toVal->addr = (XPointer)buffer;
1773 toVal->size = sizeof(String);
1774
1775 return (True1);
1776}
1777
1778/*ARGSUSED*/
1779static void
1780GetDefaultPieceSize(Widget w, int offset, XrmValue *value)
1781{
1782 static XPointer pagesize;
1783
1784 if (pagesize == NULL((void*)0)) {
1785 pagesize = (XPointer)((long)_XawGetPageSize());
1786 if (pagesize < (XPointer)BUFSIZ8192)
1787 pagesize = (XPointer)BUFSIZ8192;
1788 }
1789
1790 value->addr = (XPointer)&pagesize;
1791}
1792
1793#if (defined(ASCII_STRING) || defined(ASCII_DISK))
1794# include <X11/Xaw/Cardinals.h>
1795#endif
1796
1797#ifdef ASCII_STRING
1798/*
1799 * Compatability functions.
1800 */
1801/*
1802 * Function:
1803 * AsciiStringSourceCreate
1804 *
1805 * Parameters:
1806 * parent - widget that will own this source
1807 * args - the argument list
1808 * num_args - ""
1809 *
1810 * Description:
1811 * Creates a string source.
1812 *
1813 * Returns:
1814 * A pointer to the new text source.
1815 */
1816Widget
1817XawStringSourceCreate(Widget parent, ArgList args, Cardinal num_args)
1818{
1819 XawTextSource src;
1820 ArgList ascii_args;
1821 Arg temp[2];
1822
1823 XtSetArg(temp[0], XtNtype, XawAsciiString)((void)( (temp[0]).name = ("type"), (temp[0]).value = (XtArgVal
)(XawAsciiString) ))
;
1824 XtSetArg(temp[1], XtNuseStringInPlace, True)((void)( (temp[1]).name = ("useStringInPlace"), (temp[1]).value
= (XtArgVal)(1) ))
;
1825 ascii_args = XtMergeArgLists(temp, TWO, args, num_args);
1826
1827 src = XtCreateWidget("genericAsciiString", asciiSrcObjectClass, parent,
1828 ascii_args, num_args + TWO);
1829 XtFree((char *)ascii_args);
1830
1831 return (src);
1832}
1833
1834/*
1835 * This is hacked up to try to emulate old functionality, it
1836 * may not work, as I have not old code to test it on.
1837 *
1838 * Chris D. Peterson 8/31/89.
1839 */
1840void
1841XawTextSetLastPos(Widget w, XawTextPosition lastPos)
1842{
1843 AsciiSrcObject src = (AsciiSrcObject)XawTextGetSource(w);
1844
1845 src->ascii_src.piece_size = lastPos;
1846}
1847#endif /* ASCII_STRING */
1848
1849#ifdef ASCII_DISK
1850/*
1851 * Function:
1852 * AsciiDiskSourceCreate
1853 *
1854 * Parameters:
1855 * parent - widget that will own this source
1856 * args - argument list
1857 * num_args - ""
1858 *
1859 * Description:
1860 * Creates a disk source.
1861 *
1862 * Returns:
1863 * A pointer to the new text source
1864 */
1865Widget
1866XawDiskSourceCreate(Widget parent, ArgList args, Cardinal num_args)
1867{
1868 XawTextSource src;
1869 ArgList ascii_args;
1870 Arg temp[1];
1871 int i;
1872
1873 XtSetArg(temp[0], XtNtype, XawAsciiFile)((void)( (temp[0]).name = ("type"), (temp[0]).value = (XtArgVal
)(XawAsciiFile) ))
;
1874 ascii_args = XtMergeArgLists(temp, ONE, args, num_args);
1875 num_args++;
1876
1877 for (i = 0; i < num_args; i++)
1878 if (streq(ascii_args[i].name, XtNfile)(strcmp((ascii_args[i].name), (((char*)&XtStrings[194])))
== 0)
1879 || streq(ascii_args[i].name, XtCFile)(strcmp((ascii_args[i].name), (((char*)&XtStrings[1012]))
) == 0)
)
1880 ascii_args[i].name = XtNstring((char*)&XtStrings[733]);
1881
1882 src = XtCreateWidget("genericAsciiDisk", asciiSrcObjectClass, parent,
1883 ascii_args, num_args);
1884 XtFree((char *)ascii_args);
1885
1886 return (src);
1887}
1888#endif /* ASCII_DISK */