rust/cargo-c: update to 0.10.7+cargo-0.84.0
[oi-userland.git] / components / x11 / libXaw4 / src / Xaw3_1AsciiSrc.c
blob6a9ad004754a7b22681c48431415b0d1bbefc63e
1 #if ( !defined(lint) && !defined(SABER) )
2 static char Xrcsid[] = "$XConsortium: AsciiSrc.c,v 1.28 90/01/10 14:25:21 kit Exp $";
3 #endif
5 /*
6 * Copyright 1989 Massachusetts Institute of Technology
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of M.I.T. not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. M.I.T. makes no representations about the
15 * suitability of this software for any purpose. It is provided "as is"
16 * without express or implied warranty.
18 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
20 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 * Author: Chris Peterson, MIT X Consortium.
27 * Much code taken from X11R3 String and Disk Sources.
31 * AsciiSrc.c - AsciiSrc object. (For use with the text widget).
35 #include <stdio.h>
36 #include <ctype.h>
37 #include <X11/IntrinsicP.h>
38 #include <X11/StringDefs.h>
40 #include <./Xaw3_1XawInit.h>
41 #include <./Xaw3_1AsciiSrcP.h>
42 #include <X11/Xmu/Misc.h>
43 #include <X11/Xmu/CharSet.h>
45 #ifdef ASCII_STRING
46 #include <./Xaw3_1AsciiText.h> /* for Widget Classes. */
47 #endif
48 #ifdef ASCII_DISK)
49 #include <./Xaw3_1AsciiText.h> /* for Widget Classes. */
50 #endif
51 /****************************************************************
53 * Full class record constant
55 ****************************************************************/
57 /* Private Data */
59 static int magic_value = MAGIC_VALUE;
61 #define offset(field) XtOffset(AsciiSrcObject, ascii_src.field)
63 static XtResource resources[] = {
64 {XtNstring, XtCString, XtRString, sizeof (char *),
65 offset(string), XtRString, NULL},
66 {XtNtype, XtCType, XtRAsciiType, sizeof (XawAsciiType),
67 offset(type), XtRImmediate, (XtPointer)XawAsciiString},
68 {XtNdataCompression, XtCDataCompression, XtRBoolean, sizeof (Boolean),
69 offset(data_compression), XtRImmediate, (XtPointer) TRUE},
70 {XtNpieceSize, XtCPieceSize, XtRInt, sizeof (XawTextPosition),
71 offset(piece_size), XtRImmediate, (XtPointer) BUFSIZ},
72 {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
73 offset(callback), XtRCallback, (XtPointer)NULL},
74 {XtNuseStringInPlace, XtCUseStringInPlace, XtRBoolean, sizeof (Boolean),
75 offset(use_string_in_place), XtRImmediate, (XtPointer) FALSE},
76 {XtNlength, XtCLength, XtRInt, sizeof (int),
77 offset(ascii_length), XtRInt, (XtPointer) &magic_value},
79 #ifdef ASCII_DISK
80 {XtNfile, XtCFile, XtRString, sizeof (String),
81 offset(filename), XtRString, NULL},
82 #endif /* ASCII_DISK */
85 static XawTextPosition Scan(), Search(), ReadText();
86 static int ReplaceText();
87 static Piece * FindPiece(), * AllocNewPiece();
88 static FILE * InitStringOrFile();
89 static void FreeAllPieces(), RemovePiece(), BreakPiece(), LoadPieces();
90 static void RemoveOldStringOrFile(), CvtStringToAsciiType();
91 static void ClassInitialize(), Initialize(), Destroy(), GetValuesHook();
92 static String MyStrncpy(), StorePiecesInString();
93 static Boolean SetValues(), WriteToFile();
94 extern char *tmpnam();
95 #ifndef SYSV
96 void bcopy();
97 #endif
98 extern int errno, sys_nerr;
99 extern char* sys_errlist[];
101 #define superclass (&textSrcClassRec)
102 AsciiSrcClassRec asciiSrcClassRec = {
104 /* core_class fields */
105 /* superclass */ (WidgetClass) superclass,
106 /* class_name */ "AsciiSrc",
107 /* widget_size */ sizeof(AsciiSrcRec),
108 /* class_initialize */ ClassInitialize,
109 /* class_part_initialize */ NULL,
110 /* class_inited */ FALSE,
111 /* initialize */ Initialize,
112 /* initialize_hook */ NULL,
113 /* realize */ NULL,
114 /* actions */ NULL,
115 /* num_actions */ 0,
116 /* resources */ resources,
117 /* num_resources */ XtNumber(resources),
118 /* xrm_class */ NULLQUARK,
119 /* compress_motion */ FALSE,
120 /* compress_exposure */ FALSE,
121 /* compress_enterleave */ FALSE,
122 /* visible_interest */ FALSE,
123 /* destroy */ Destroy,
124 /* resize */ NULL,
125 /* expose */ NULL,
126 /* set_values */ SetValues,
127 /* set_values_hook */ NULL,
128 /* set_values_almost */ NULL,
129 /* get_values_hook */ GetValuesHook,
130 /* accept_focus */ NULL,
131 /* version */ XtVersion,
132 /* callback_private */ NULL,
133 /* tm_table */ NULL,
134 /* query_geometry */ NULL,
135 /* display_accelerator */ NULL,
136 /* extension */ NULL
138 /* textSrc_class fields */
140 /* Read */ ReadText,
141 /* Replace */ ReplaceText,
142 /* Scan */ Scan,
143 /* Search */ Search,
144 /* SetSelection */ XtInheritSetSelection,
145 /* ConvertSelection */ XtInheritConvertSelection
147 /* asciiSrc_class fields */
149 /* Keep the compiler happy */ NULL
153 WidgetClass asciiSrcObjectClass = (WidgetClass)&asciiSrcClassRec;
155 /************************************************************
157 * Semi-Public Interfaces.
159 ************************************************************/
161 /* Function Name: ClassInitialize
162 * Description: Class Initialize routine, called only once.
163 * Arguments: none.
164 * Returns: none.
167 static void
168 ClassInitialize()
170 XawInitializeWidgetSet();
171 XtAddConverter( XtRString, XtRAsciiType, CvtStringToAsciiType,
172 NULL, (Cardinal) 0);
175 /* Function Name: Initialize
176 * Description: Initializes the simple menu widget
177 * Arguments: request - the widget requested by the argument list.
178 * new - the new widget with both resource and non
179 * resource values.
180 * Returns: none.
183 /* ARGSUSED */
184 static void
185 Initialize(request, new)
186 Widget request, new;
188 AsciiSrcObject src = (AsciiSrcObject) new;
189 FILE * file;
192 * Set correct flags (override resources) depending upon widget class.
195 #ifdef ASCII_DISK
196 if (XtIsSubclass(XtParent(new), asciiDiskWidgetClass)) {
197 src->ascii_src.type = XawAsciiFile;
198 src->ascii_src.string = src->ascii_src.filename;
200 #endif
202 #ifdef ASCII_STRING
203 if (XtIsSubclass(XtParent(new), asciiStringWidgetClass)) {
204 src->ascii_src.use_string_in_place = TRUE;
205 src->ascii_src.type = XawAsciiString;
207 #endif
209 src->ascii_src.changes = FALSE;
210 src->ascii_src.allocated_string = FALSE;
212 file = InitStringOrFile(src);
213 LoadPieces(src, file, NULL);
215 if (file != NULL) fclose(file);
217 if ( src->ascii_src.type == XawAsciiString )
218 src->ascii_src.string = NULL;
221 /* Function Name: ReadText
222 * Description: This function reads the source.
223 * Arguments: w - the AsciiSource widget.
224 * pos - position of the text to retreive.
225 * RETURNED text - text block that will contain returned text.
226 * length - maximum number of characters to read.
227 * Returns: The number of characters read into the buffer.
230 static XawTextPosition
231 ReadText(w, pos, text, length)
232 Widget w;
233 XawTextPosition pos;
234 XawTextBlock *text;
235 int length;
237 AsciiSrcObject src = (AsciiSrcObject) w;
238 XawTextPosition count, start;
239 Piece * piece = FindPiece(src, pos, &start);
241 text->firstPos = pos;
242 text->ptr = piece->text + (pos - start);
243 count = piece->used - (pos - start);
244 text->length = (length > count) ? count : length;
245 return(pos + text->length);
248 /* Function Name: ReplaceText.
249 * Description: Replaces a block of text with new text.
250 * Arguments: w - the AsciiSource widget.
251 * startPos, endPos - ends of text that will be removed.
252 * text - new text to be inserted into buffer at startPos.
253 * Returns: XawEditError or XawEditDone.
256 /*ARGSUSED*/
257 static int
258 ReplaceText (w, startPos, endPos, text)
259 Widget w;
260 XawTextPosition startPos, endPos;
261 XawTextBlock *text;
263 AsciiSrcObject src = (AsciiSrcObject) w;
264 Piece *start_piece, *end_piece, *temp_piece;
265 XawTextPosition start_first, end_first;
266 int length, firstPos;
269 * Editing a read only source is not allowed.
272 if (src->text_src.edit_mode == XawtextRead)
273 return(XawEditError);
275 start_piece = FindPiece(src, startPos, &start_first);
276 end_piece = FindPiece(src, endPos, &end_first);
278 src->ascii_src.changes = TRUE; /* We have changed the buffer. */
280 XtCallCallbacks(w, XtNcallback, NULL);
283 * Remove Old Stuff.
286 if (start_piece != end_piece) {
287 temp_piece = start_piece->next;
290 * If empty and not the only piece then remove it.
293 if ( ((start_piece->used = startPos - start_first) == 0) &&
294 !((start_piece->next == NULL) && (start_piece->prev == NULL)) )
295 RemovePiece(src, start_piece);
297 while (temp_piece != end_piece) {
298 temp_piece = temp_piece->next;
299 RemovePiece(src, temp_piece->prev);
301 end_piece->used -= endPos - end_first;
302 if (end_piece->used != 0)
303 MyStrncpy(end_piece->text, (end_piece->text + endPos - end_first),
304 (int) end_piece->used);
306 else { /* We are fully in one piece. */
307 if ( (start_piece->used -= endPos - startPos) == 0) {
308 if ( !((start_piece->next == NULL) && (start_piece->prev == NULL)) )
309 RemovePiece(src, start_piece);
311 else {
312 MyStrncpy(start_piece->text + (startPos - start_first),
313 start_piece->text + (endPos - start_first),
314 (int) (start_piece->used - (startPos - start_first)) );
315 if ( src->ascii_src.use_string_in_place &&
316 ((src->ascii_src.length - (endPos - startPos)) <
317 (src->ascii_src.piece_size - 1)) )
318 start_piece->text[src->ascii_src.length - (endPos - startPos)] = '\0';
322 src->ascii_src.length += -(endPos - startPos) + text->length;
324 if ( text->length != 0) {
327 * Put in the New Stuff.
330 start_piece = FindPiece(src, startPos, &start_first);
332 length = text->length;
333 firstPos = text->firstPos;
335 while (length > 0) {
336 char * ptr;
337 int fill;
339 if (src->ascii_src.use_string_in_place) {
340 if (start_piece->used == (src->ascii_src.piece_size - 1)) {
342 * If we are in ascii string emulation mode. Then the
343 * string is not allowed to grow.
345 start_piece->used = src->ascii_src.length =
346 src->ascii_src.piece_size - 1;
347 start_piece->text[src->ascii_src.length] = '\0';
348 return(XawEditError);
353 if (start_piece->used == src->ascii_src.piece_size) {
354 BreakPiece(src, start_piece);
355 start_piece = FindPiece(src, startPos, &start_first);
358 fill = Min((int)(src->ascii_src.piece_size - start_piece->used), length);
360 ptr = start_piece->text + (startPos - start_first);
361 MyStrncpy(ptr + fill, ptr,
362 (int) start_piece->used - (startPos - start_first));
363 strncpy(ptr, text->ptr + firstPos, fill);
365 startPos += fill;
366 firstPos += fill;
367 start_piece->used += fill;
368 length -= fill;
372 if (src->ascii_src.use_string_in_place)
373 start_piece->text[start_piece->used] = '\0';
375 return(XawEditDone);
378 /* Function Name: Scan
379 * Description: Scans the text source for the number and type
380 * of item specified.
381 * Arguments: w - the AsciiSource widget.
382 * position - the position to start scanning.
383 * type - type of thing to scan for.
384 * dir - direction to scan.
385 * count - which occurance if this thing to search for.
386 * include - whether or not to include the character found in
387 * the position that is returned.
388 * Returns: the position of the item found.
390 * Note: While there are only 'n' characters in the file there are n+1
391 * possible cursor positions (one before the first character and
392 * one after the last character.
395 static
396 XawTextPosition
397 Scan (w, position, type, dir, count, include)
398 Widget w;
399 XawTextPosition position;
400 XawTextScanType type;
401 XawTextScanDirection dir;
402 int count;
403 Boolean include;
405 AsciiSrcObject src = (AsciiSrcObject) w;
406 register int inc;
407 Piece * piece;
408 XawTextPosition first, first_eol_position;
409 register char * ptr;
411 if (type == XawstAll) { /* Optomize this common case. */
412 if (dir == XawsdRight)
413 return(src->ascii_src.length);
414 return(0); /* else. */
417 if (position > src->ascii_src.length)
418 position = src->ascii_src.length;
420 if ( dir == XawsdRight ) {
421 if (position == src->ascii_src.length)
423 * Scanning right from src->ascii_src.length???
425 return(src->ascii_src.length);
426 inc = 1;
428 else {
429 if (position == 0)
430 return(0); /* Scanning left from 0??? */
431 inc = -1;
432 position--;
435 piece = FindPiece(src, position, &first);
438 * If the buffer is empty then return 0.
441 if ( piece->used == 0 ) return(0);
443 ptr = (position - first) + piece->text;
445 switch (type) {
446 case XawstEOL:
447 case XawstParagraph:
448 case XawstWhiteSpace:
449 for ( ; count > 0 ; count-- ) {
450 Boolean non_space = FALSE, first_eol = TRUE;
451 while (TRUE) {
452 register unsigned char c = *ptr;
454 ptr += inc;
455 position += inc;
457 if (type == XawstWhiteSpace) {
458 if (isspace(c)) {
459 if (non_space)
460 break;
462 else
463 non_space = TRUE;
465 else if (type == XawstEOL) {
466 if (c == '\n') break;
468 else { /* XawstParagraph */
469 if (first_eol) {
470 if (c == '\n') {
471 first_eol_position = position;
472 first_eol = FALSE;
475 else
476 if ( c == '\n')
477 break;
478 else if ( !isspace(c) )
479 first_eol = TRUE;
483 if ( ptr < piece->text ) {
484 piece = piece->prev;
485 if (piece == NULL) /* Begining of text. */
486 return(0);
487 ptr = piece->text + piece->used - 1;
489 else if ( ptr >= (piece->text + piece->used) ) {
490 piece = piece->next;
491 if (piece == NULL) /* End of text. */
492 return(src->ascii_src.length);
493 ptr = piece->text;
497 if (!include) {
498 if ( type == XawstParagraph)
499 position = first_eol_position;
500 position -= inc;
502 break;
503 case XawstPositions:
504 position += count * inc;
505 break;
506 /* case XawstAll: ---- handled in special code above */
509 if ( dir == XawsdLeft )
510 position++;
512 if (position >= src->ascii_src.length)
513 return(src->ascii_src.length);
514 if (position < 0)
515 return(0);
517 return(position);
520 /* Function Name: Search
521 * Description: Searchs the text source for the text block passed
522 * Arguments: w - the AsciiSource Widget.
523 * position - the position to start scanning.
524 * dir - direction to scan.
525 * text - the text block to search for.
526 * Returns: the position of the item found.
529 static XawTextPosition
530 Search(w, position, dir, text)
531 Widget w;
532 XawTextPosition position;
533 XawTextScanDirection dir;
534 XawTextBlock * text;
536 AsciiSrcObject src = (AsciiSrcObject) w;
537 register int inc, count = 0;
538 register char * ptr;
539 Piece * piece;
540 char * buf;
541 XawTextPosition first;
543 if ( dir == XawsdRight )
544 inc = 1;
545 else {
546 inc = -1;
547 if (position == 0)
548 return(XawTextSearchError); /* scanning left from 0??? */
549 position--;
552 buf = XtMalloc(sizeof(unsigned char) * text->length);
553 strncpy(buf, (text->ptr + text->firstPos), text->length);
554 piece = FindPiece(src, position, &first);
555 ptr = (position - first) + piece->text;
557 while (TRUE) {
558 if (*ptr == ((dir == XawsdRight) ? *(buf + count)
559 : *(buf + text->length - count - 1)) ) {
560 if (count == (text->length - 1))
561 break;
562 else
563 count++;
565 else {
566 if (count != 0) {
567 position -=inc * count;
568 ptr -= inc * count;
570 count = 0;
573 ptr += inc;
574 position += inc;
576 while ( ptr < piece->text ) {
577 piece = piece->prev;
578 if (piece == NULL) { /* Begining of text. */
579 XtFree(buf);
580 return(XawTextSearchError);
582 ptr = piece->text + piece->used - 1;
585 while ( ptr >= (piece->text + piece->used) ) {
586 piece = piece->next;
587 if (piece == NULL) { /* End of text. */
588 XtFree(buf);
589 return(XawTextSearchError);
591 ptr = piece->text;
595 XtFree(buf);
596 if (dir == XawsdLeft)
597 return(position);
598 return(position - (text->length - 1));
601 /* Function Name: SetValues
602 * Description: Sets the values for the AsciiSource.
603 * Arguments: current - current state of the widget.
604 * request - what was requested.
605 * new - what the widget will become.
606 * Returns: True if redisplay is needed.
609 /* ARGSUSED */
610 static Boolean
611 SetValues(current, request, new)
612 Widget current, request, new;
614 AsciiSrcObject src = (AsciiSrcObject) new;
615 AsciiSrcObject old_src = (AsciiSrcObject) current;
616 Boolean total_reset = FALSE;
617 FILE * file;
619 if ( old_src->ascii_src.use_string_in_place !=
620 src->ascii_src.use_string_in_place ) {
621 XtAppWarning( XtWidgetToApplicationContext(new),
622 "AsciiSrc: The XtNuseStrinInPlace resources may not be changed.");
623 src->ascii_src.use_string_in_place =
624 old_src->ascii_src.use_string_in_place;
627 if ( (old_src->ascii_src.string != src->ascii_src.string) ||
628 (old_src->ascii_src.type != src->ascii_src.type) ) {
629 if (old_src->ascii_src.string == src->ascii_src.string) {
630 /* Fool it into not freeing the string */
631 src->ascii_src.allocated_string = FALSE;
632 RemoveOldStringOrFile(old_src); /* remove old info. */
633 src->ascii_src.allocated_string = TRUE;
635 else {
636 RemoveOldStringOrFile(old_src); /* remove old info. */
637 src->ascii_src.allocated_string = FALSE;
640 file = InitStringOrFile(src); /* Init new info. */
641 LoadPieces(src, file, NULL); /* load new info into internal buffers. */
642 if (file != NULL) fclose(file);
643 XawTextSetSource( XtParent(new), new, 0); /* Tell text widget
644 what happened. */
645 if ( src->ascii_src.type == XawAsciiString )
646 src->ascii_src.string = NULL;
648 total_reset = TRUE;
651 if ( old_src->ascii_src.ascii_length != src->ascii_src.ascii_length )
652 src->ascii_src.piece_size = src->ascii_src.ascii_length;
654 if ( !total_reset &&
655 (old_src->ascii_src.piece_size != src->ascii_src.piece_size) ) {
656 String string = StorePiecesInString(old_src);
657 FreeAllPieces(old_src);
658 LoadPieces(src, NULL, string);
659 XtFree(string);
662 return(FALSE);
665 /* Function Name: GetValuesHook
666 * Description: This is a get values hook routine that sets the
667 * values specific to the ascii source.
668 * Arguments: w - the AsciiSource Widget.
669 * args - the argument list.
670 * num_args - the number of args.
671 * Returns: none.
674 static void
675 GetValuesHook(w, args, num_args)
676 Widget w;
677 ArgList args;
678 Cardinal * num_args;
680 AsciiSrcObject src = (AsciiSrcObject) w;
681 register int i;
683 if (src->ascii_src.use_string_in_place)
684 return;
686 if (src->ascii_src.type == XawAsciiString) {
687 for (i = 0; i < *num_args ; i++ )
688 if (streq(args[i].name, XtNstring)) {
689 if (XawAsciiSave(w)) /* If save sucessful. */
690 *((char **) args[i].value) = src->ascii_src.string;
691 break;
696 /* Function Name: Destroy
697 * Description: Destroys an ascii source (frees all data)
698 * Arguments: src - the Ascii source Widget to free.
699 * Returns: none.
702 static void
703 Destroy (w)
704 Widget w;
706 RemoveOldStringOrFile((AsciiSrcObject) w);
709 /************************************************************
711 * Public routines
713 ************************************************************/
715 /* Function Name: XawAsciiSourceFreeString
716 * Description: Frees the string returned by a get values call
717 * on the string when the source is of type string.
718 * Arguments: w - the AsciiSrc widget.
719 * Returns: none.
722 void
723 XawAsciiSourceFreeString(w)
724 Widget w;
726 AsciiSrcObject src = (AsciiSrcObject) w;
728 if (src->ascii_src.allocated_string) {
729 src->ascii_src.allocated_string = FALSE;
730 XtFree(src->ascii_src.string);
734 /* Function Name: XawAsciiSave
735 * Description: Saves all the pieces into a file or string as required.
736 * Arguments: w - the asciiSrc Widget.
737 * Returns: TRUE if the save was successful.
740 Boolean
741 XawAsciiSave(w)
742 Widget w;
744 AsciiSrcObject src = (AsciiSrcObject) w;
747 * If using the string in place then there is no need to play games
748 * to get the internal info into a readable string.
751 if (src->ascii_src.use_string_in_place)
752 return(TRUE);
754 if (src->ascii_src.type == XawAsciiFile) {
755 char * string;
757 if (!src->ascii_src.changes) /* No changes to save. */
758 return(TRUE);
760 string = StorePiecesInString(src);
762 if (WriteToFile(src, string, src->ascii_src.string) == FALSE) {
763 XtFree(string);
764 return(FALSE);
766 XtFree(string);
768 else { /* This is a string widget. */
769 if (src->ascii_src.allocated_string == TRUE)
770 XtFree(src->ascii_src.string);
771 else
772 src->ascii_src.allocated_string = TRUE;
774 src->ascii_src.string = StorePiecesInString(src);
776 src->ascii_src.changes = FALSE;
777 return(TRUE);
780 /* Function Name: XawAsciiSaveAsFile
781 * Description: Save the current buffer as a file.
782 * Arguments: w - the AsciiSrc widget.
783 * name - name of the file to save this file into.
784 * Returns: True if the save was sucessful.
787 Boolean
788 XawAsciiSaveAsFile(w, name)
789 Widget w;
790 String name;
792 AsciiSrcObject src = (AsciiSrcObject) w;
793 String string;
794 Boolean ret;
796 string = StorePiecesInString(src);
798 ret = WriteToFile(src, string, name);
799 XtFree(string);
800 return(ret);
803 /* Function Name: XawAsciiSourceChanged
804 * Description: Returns true if the source has changed since last saved.
805 * Arguments: w - the ascii source widget.
806 * Returns: a Boolean (see description).
809 Boolean
810 XawAsciiSourceChanged(w)
811 Widget w;
813 return( ((AsciiSrcObject) w)->ascii_src.changes );
816 /************************************************************
818 * Private Functions.
820 ************************************************************/
822 static void
823 RemoveOldStringOrFile(src)
824 AsciiSrcObject src;
826 FreeAllPieces(src);
828 if (src->ascii_src.allocated_string)
829 XtFree(src->ascii_src.string);
832 /* Function Name: WriteToFile
833 * Description: Write the string specified to the begining of the file
834 * specified.
835 * Arguments: w - the widget. (for error messages only)
836 * string - string to write.
837 * name - the name of the file
838 * file - file to write it to.
839 * Returns: returns TRUE if sucessful, FALSE otherwise.
842 static Boolean
843 WriteToFile(src, string, name)
844 AsciiSrcObject src;
845 String string, name;
847 unsigned char buf[BUFSIZ];
848 int fd;
850 if ( ((fd = creat(name, 0666)) == -1 ) ||
851 (write(fd, string, sizeof(unsigned char) * strlen(string)) == -1) ) {
852 sprintf((char *)buf, "Error, while attempting to write to the file %s.", name);
853 XtAppWarning(XtWidgetToApplicationContext((Widget) src), (const char *)buf);
854 return(FALSE);
857 if ( close(fd) == -1 ) {
858 sprintf((char *)buf, "Error, while attempting to close the file %s.", name);
859 XtAppWarning(XtWidgetToApplicationContext((Widget) src), (const char *)buf);
860 return(FALSE);
862 return(TRUE);
865 /* Function Name: StorePiecesInString
866 * Description: store the pieces in memory into a standard ascii string.
867 * Arguments: data - the ascii pointer data.
868 * Returns: none.
871 static String
872 StorePiecesInString(src)
873 AsciiSrcObject src;
875 String string;
876 XawTextPosition first;
877 Piece * piece;
879 string = XtMalloc(sizeof(unsigned char) * src->ascii_src.length + 1);
881 for (first = 0, piece = src->ascii_src.first_piece ; piece != NULL;
882 first += piece->used, piece = piece->next)
883 strncpy(string + first, piece->text, piece->used);
885 string[src->ascii_src.length] = '\0'; /* NULL terminate this sucker. */
888 * This will refill all pieces to capacity.
891 if (src->ascii_src.data_compression) {
892 FreeAllPieces(src);
893 LoadPieces(src, NULL, string);
896 return(string);
899 /* Function Name: InitStringOrFile.
900 * Description: Initializes the string or file.
901 * Arguments: src - the AsciiSource.
902 * Returns: none - May exit though.
905 static FILE *
906 InitStringOrFile(src)
907 AsciiSrcObject src;
909 char * open_mode;
910 FILE * file;
912 if (src->ascii_src.type == XawAsciiString) {
913 if (src->ascii_src.string == NULL)
914 src->ascii_src.length = 0;
915 else
916 src->ascii_src.length = strlen(src->ascii_src.string);
918 if (src->ascii_src.use_string_in_place) {
919 if (src->ascii_src.ascii_length == MAGIC_VALUE)
920 src->ascii_src.piece_size = src->ascii_src.length;
921 else
922 src->ascii_src.piece_size = src->ascii_src.ascii_length + 1;
925 return(NULL);
929 * type is XawAsciiFile.
932 src->ascii_src.is_tempfile = FALSE;
934 switch (src->text_src.edit_mode) {
935 case XawtextRead:
936 if (src->ascii_src.string == NULL)
937 XtErrorMsg("NoFile", "asciiSourceCreate", "XawError",
938 "Creating a read only disk widget and no file specified.",
939 NULL, 0);
940 open_mode = "r";
941 break;
942 case XawtextAppend:
943 case XawtextEdit:
944 if (src->ascii_src.string == NULL) {
945 src->ascii_src.string = tmpnam (XtMalloc((unsigned)TMPSIZ));
946 src->ascii_src.is_tempfile = TRUE;
948 else {
949 if (!src->ascii_src.allocated_string) {
950 src->ascii_src.allocated_string = TRUE;
951 src->ascii_src.string = XtNewString(src->ascii_src.string);
953 open_mode = "r+";
956 break;
957 default:
958 XtErrorMsg("badMode", "asciiSourceCreate", "XawError",
959 "Bad editMode for ascii source; must be Read, Append or Edit.",
960 NULL, NULL);
963 if (!src->ascii_src.is_tempfile) {
964 if ((file = fopen(src->ascii_src.string, open_mode)) == 0) {
965 String params[2];
966 Cardinal num_params = 2;
968 params[0] = src->ascii_src.string;
969 if (errno <= sys_nerr)
970 params[1] = sys_errlist[errno];
971 else {
972 char msg[11];
973 sprintf(msg, "errno=%.4d", errno);
974 params[1] = msg;
976 XtErrorMsg("openError", "asciiSourceCreate", "XawError",
977 "Cannot open source file %s; %s", params, &num_params);
979 (void) fseek(file, 0L, 2);
980 src->ascii_src.length = ftell (file);
982 else {
983 src->ascii_src.length = 0;
984 return(NULL);
987 return(file);
990 static void
991 LoadPieces(src, file, string)
992 AsciiSrcObject src;
993 FILE * file;
994 char * string;
996 char *local_str, *ptr;
997 register Piece * piece = NULL;
998 XawTextPosition left;
1000 if (string == NULL) {
1001 if (src->ascii_src.type == XawAsciiFile) {
1002 local_str = XtMalloc((src->ascii_src.length + 1) *sizeof(unsigned char));
1003 if (src->ascii_src.length != 0) {
1004 fseek(file, 0L, 0);
1005 if ( fread(local_str, sizeof(unsigned char),
1006 src->ascii_src.length, file) != src->ascii_src.length )
1007 XtErrorMsg("readError", "asciiSourceCreate", "XawError",
1008 "fread returned error.", NULL, NULL);
1010 local_str[src->ascii_src.length] = '\0';
1012 else
1013 local_str = src->ascii_src.string;
1015 else
1016 local_str = string;
1019 * If we are using teh string in place then set the other fields as follows:
1021 * piece_size = length;
1022 * piece->used = src->ascii_src.length;
1025 if (src->ascii_src.use_string_in_place) {
1026 piece = AllocNewPiece(src, piece);
1027 piece->used = Min(src->ascii_src.length, src->ascii_src.piece_size);
1028 piece->text = src->ascii_src.string;
1029 return;
1032 ptr = local_str;
1033 left = src->ascii_src.length;
1035 do {
1036 piece = AllocNewPiece(src, piece);
1038 piece->text = XtMalloc(src->ascii_src.piece_size * sizeof(unsigned char));
1039 piece->used = Min(left, src->ascii_src.piece_size);
1040 if (piece->used != 0)
1041 strncpy(piece->text, ptr, piece->used);
1043 left -= piece->used;
1044 ptr += piece->used;
1045 } while (left > 0);
1047 if ( (src->ascii_src.type == XawAsciiFile) && (string == NULL) )
1048 XtFree(local_str);
1051 /* Function Name: AllocNewPiece
1052 * Description: Allocates a new piece of memory.
1053 * Arguments: src - The AsciiSrc Widget.
1054 * prev - the piece just before this one, or NULL.
1055 * Returns: the allocated piece.
1058 static Piece *
1059 AllocNewPiece(src, prev)
1060 AsciiSrcObject src;
1061 Piece * prev;
1063 Piece * piece = XtNew(Piece);
1065 if (prev == NULL) {
1066 src->ascii_src.first_piece = piece;
1067 piece->next = NULL;
1069 else {
1070 if (prev->next != NULL)
1071 (prev->next)->prev = piece;
1072 piece->next = prev->next;
1073 prev->next = piece;
1076 piece->prev = prev;
1078 return(piece);
1081 /* Function Name: FreeAllPieces
1082 * Description: Frees all the pieces
1083 * Arguments: src - The AsciiSrc Widget.
1084 * Returns: none.
1087 static void
1088 FreeAllPieces(src)
1089 AsciiSrcObject src;
1091 Piece * next, * first = src->ascii_src.first_piece;
1093 if (first->prev != NULL)
1094 printf("Programmer Botch in FreeAllPieces, there may be a memory leak.\n");
1096 for ( ; first != NULL ; first = next ) {
1097 next = first->next;
1098 RemovePiece(src, first);
1102 /* Function Name: RemovePiece
1103 * Description: Removes a piece from the list.
1104 * Arguments:
1105 * piece - the piece to remove.
1106 * Returns: none.
1109 static void
1110 RemovePiece(src, piece)
1111 AsciiSrcObject src;
1112 Piece * piece;
1114 if (piece->prev == NULL)
1115 src->ascii_src.first_piece = piece->next;
1116 else
1117 (piece->prev)->next = piece->next;
1119 if (piece->next != NULL)
1120 (piece->next)->prev = piece->prev;
1122 if (src->ascii_src.allocated_string)
1123 XtFree(piece->text);
1125 XtFree((char *)piece);
1128 /* Function Name: FindPiece
1129 * Description: Finds the piece containing the position indicated.
1130 * Arguments: src - The AsciiSrc Widget.
1131 * position - the position that we are searching for.
1132 * RETURNED first - the position of the first character in this piece.
1133 * Returns: piece - the piece that contains this position.
1136 static Piece *
1137 FindPiece(src, position, first)
1138 AsciiSrcObject src;
1139 XawTextPosition position, *first;
1141 Piece * old_piece, * piece = src->ascii_src.first_piece;
1142 XawTextPosition temp;
1144 for ( temp = 0 ; piece != NULL ; temp += piece->used, piece = piece->next ) {
1145 *first = temp;
1146 old_piece = piece;
1148 if ((temp + piece->used) > position)
1149 return(piece);
1151 return(old_piece); /* if we run off the end the return the last piece */
1154 /* Function Name: MyStrncpy
1155 * Description: Just like string copy, but slower and will always
1156 * work on overlapping strings.
1157 * Arguments: (same as strncpy) - s1, s2 - strings to copy (2->1).
1158 * n - the number of chars to copy.
1159 * Returns: s1.
1162 static String
1163 MyStrncpy(s1, s2, n)
1164 char * s1, * s2;
1165 int n;
1167 char * temp = XtMalloc(sizeof(unsigned char) * n);
1169 strncpy(temp, s2, n); /* Saber has a bug that causes it to generate*/
1170 strncpy(s1, temp, n); /* a bogus warning message here (CDP 6/32/89)*/
1171 XtFree(temp);
1172 return(s1);
1175 /* Function Name: BreakPiece
1176 * Description: Breaks a full piece into two new pieces.
1177 * Arguments: src - The AsciiSrc Widget.
1178 * piece - the piece to break.
1179 * Returns: none.
1182 #define HALF_PIECE (src->ascii_src.piece_size/2)
1184 static void
1185 BreakPiece(src, piece)
1186 AsciiSrcObject src;
1187 Piece * piece;
1189 Piece * new = AllocNewPiece(src, piece);
1191 new->text = XtMalloc(src->ascii_src.piece_size * sizeof(unsigned char));
1192 strncpy(new->text, piece->text + HALF_PIECE,
1193 src->ascii_src.piece_size - HALF_PIECE);
1194 piece->used = HALF_PIECE;
1195 new->used = src->ascii_src.piece_size - HALF_PIECE;
1198 /* ARGSUSED */
1199 static void
1200 CvtStringToAsciiType(args, num_args, fromVal, toVal)
1201 XrmValuePtr *args; /* unused */
1202 Cardinal *num_args; /* unused */
1203 XrmValuePtr fromVal;
1204 XrmValuePtr toVal;
1206 static XawAsciiType type;
1207 static XrmQuark XtQEstring;
1208 static XrmQuark XtQEfile;
1209 static int haveQuarks = FALSE;
1210 XrmQuark q;
1211 char lowerName[BUFSIZ];
1213 if (!haveQuarks) {
1214 XtQEstring = XrmStringToQuark(XtEstring);
1215 XtQEfile = XrmStringToQuark(XtEfile);
1216 haveQuarks = TRUE;
1219 XmuCopyISOLatin1Lowered(lowerName, (char *) fromVal->addr);
1220 q = XrmStringToQuark(lowerName);
1222 if (q == XtQEstring) type = XawAsciiString;
1223 if (q == XtQEfile) type = XawAsciiFile;
1225 (*toVal).size = sizeof(XawAsciiType);
1226 (*toVal).addr = (caddr_t) &type;
1227 return;
1230 #if (defined(ASCII_STRING) || defined(ASCII_DISK))
1231 # include <./Xaw3_1Cardinals.h>
1232 #endif
1234 #ifdef ASCII_STRING
1235 /************************************************************
1237 * Compatability functions.
1239 ************************************************************/
1241 /* Function Name: AsciiStringSourceCreate
1242 * Description: Creates a string source.
1243 * Arguments: parent - the widget that will own this source.
1244 * args, num_args - the argument list.
1245 * Returns: a pointer to the new text source.
1248 Widget
1249 XawStringSourceCreate(parent, args, num_args)
1250 Widget parent;
1251 ArgList args;
1252 Cardinal num_args;
1254 XawTextSource src;
1255 ArgList ascii_args;
1256 Arg temp[2];
1258 XtSetArg(temp[0], XtNtype, XawAsciiString);
1259 XtSetArg(temp[1], XtNuseStringInPlace, TRUE);
1260 ascii_args = XtMergeArgLists(temp, TWO, args, num_args);
1262 src = XtCreateWidget("genericAsciiString", asciiSrcObjectClass, parent,
1263 ascii_args, num_args + TWO);
1264 XtFree((char *)ascii_args);
1265 return(src);
1269 * This is hacked up to try to emulate old functionality, it
1270 * may not work, as I have not old code to test it on.
1272 * Chris D. Peterson 8/31/89.
1275 void
1276 XawTextSetLastPos (w, lastPos)
1277 Widget w;
1278 XawTextPosition lastPos;
1280 AsciiSrcObject src = (AsciiSrcObject) XawTextGetSource(w);
1282 src->ascii_src.piece_size = lastPos;
1284 #endif /* ASCII_STRING */
1286 #ifdef ASCII_DISK
1287 /* Function Name: AsciiDiskSourceCreate
1288 * Description: Creates a disk source.
1289 * Arguments: parent - the widget that will own this source.
1290 * args, num_args - the argument list.
1291 * Returns: a pointer to the new text source.
1294 Widget
1295 XawDiskSourceCreate(parent, args, num_args)
1296 Widget parent;
1297 ArgList args;
1298 Cardinal num_args;
1300 XawTextSource src;
1301 ArgList ascii_args;
1302 Arg temp[1];
1303 register int i;
1305 XtSetArg(temp[0], XtNtype, XawAsciiFile);
1307 for (i = 0; i < num_args; i++)
1308 if (streq(args[i].name, XtNfile) || streq(args[i].name, XtCFile))
1309 args[i].name = XtNstring;
1311 ascii_args = XtMergeArgLists(temp, ONE, args, num_args);
1312 src = XtCreateWidget("genericAsciiDisk", asciiSrcObjectClass, parent,
1313 ascii_args, num_args + ONE);
1314 XtFree((char *)ascii_args);
1315 return(src);
1317 #endif /* ASCII_DISK */