1 /*****************************************************************************
2 
3 	InsStr()
4 
5 	This function is called to insert text into the edit buffer.  The
6 edit buffer is expanded to make room for the text if necessary.
7 
8 *****************************************************************************/
9 
10 #include "zport.h"		/* define portability identifiers */
11 #include "tecoc.h"		/* define general identifiers */
12 #include "defext.h"		/* define external global variables */
13 #include "deferr.h"		/* define identifiers for error messages */
14 
15 /*
16  * The edit buffer gap needs to be expanded. If there's room in the input
17  * buffer,  then we can shuffle memory to steal some room from the input
18  * buffer. If there's not room to steal from the input buffer,  we have to
19  * re-allocate the whole edit/input buffer and then adjust the pointers to
20  * reflect the movement.
21  */
22 
23 #if USE_PROTOTYPES
expand_gap(ptrdiff_t length)24 static DEFAULT expand_gap(ptrdiff_t length)
25 #else
26 static DEFAULT expand_gap(length)
27 ptrdiff_t length;			/* amount of gap room needed */
28 #endif
29 {
30     SIZE_T TmpSiz;
31     SIZE_T NewSiz;
32     charptr NewBeg;
33 
34     DBGFEN(3,"expand_gap",NULL);
35 
36 /*
37  * If the size of the input buffer exceeds IBFMIN, make it IBFMIN and
38  * add the leftover space to the edit buffer gap.
39  *
40  * from:  EbfBeg...GapBeg...GapEnd...EBfEnd<TmpSiz><IBFMIN>IBfEnd
41  * to:    EbfBeg...GapBeg...<TmpSiz>GapEnd...EBfEnd<IBFMIN>IBfEnd
42  */
43     TmpSiz = IBfEnd-EBfEnd;
44     if (TmpSiz > IBFMIN) {
45 	TmpSiz -= IBFMIN;
46 	MEMMOVE(GapEnd+1+TmpSiz, GapEnd+1, (SIZE_T)(EBfEnd-GapEnd));
47 	GapEnd += TmpSiz;
48 	EBfEnd += TmpSiz;
49     }
50 /*
51  * If there's still not enough room in the edit buffer gap, expand the gap
52  * by reallocating the edit buffer.  Since reallocating is expensive,  take
53  * this opportunity to expand it by EBFEXP bytes more than what we need.
54  *
55  * from:  EbfBeg...GapBeg<GapSiz>GapEnd...EBfEnd...IBfEnd
56  * to:    EbfBeg...GapBeg<length-GapSiz+EBFEXP>GapEnd...EBfEnd...IBfEnd
57  */
58     TmpSiz = GapEnd-GapBeg+1;
59     if (TmpSiz < length) {			    /* str length > GapSiz */
60 	TmpSiz = (length - TmpSiz) + EBFEXP;	    /* amt to expand EBf */
61 	NewSiz = (IBfEnd-EBfBeg+1) + TmpSiz;	    /* new size of EBf */
62 	NewBeg = (charptr)ZRaloc(EBfBeg, NewSiz);   /* reallocate EBf */
63 	if (NewBeg == NULL) {			    /* if failure */
64 	    ErrMsg(ERR_MEM);			    /* memory overflow */
65 	    DBGFEX(3,DbgFNm,"FAILURE, couldn't ZRaloc more gap room");
66 	    return FAILURE;
67 	}
68 /*
69  * Make sure all the pointers reference the new memory area.
70  */
71 	if (NewBeg != EBfBeg) {
72 	    GapBeg = NewBeg + (GapBeg - EBfBeg);
73 	    GapEnd = NewBeg + (GapEnd - EBfBeg);
74 	    EBfEnd = NewBeg + (EBfEnd - EBfBeg);
75 	    IBfEnd = NewBeg + (IBfEnd - EBfBeg);
76 	    EBfBeg = NewBeg;
77 	}
78 /*
79  * Now open up the gap by moving the second half of the edit buffer
80  * down the amount we expanded the edit buffer (TmpSiz), then update the
81  * pointers again.
82  */
83 	MEMMOVE(GapEnd+1+TmpSiz, GapEnd+1, (SIZE_T)(EBfEnd - GapEnd));
84 	GapEnd += TmpSiz;
85 	EBfEnd += TmpSiz;
86 	IBfEnd += TmpSiz;
87     }
88     DBGFEX(3,DbgFNm,NULL);
89 
90     return SUCCESS;
91 }
92 
93 
InsStr(string,length)94 DEFAULT InsStr(string, length)		/* insert string into edit buffer */
95 charptr string;
96 ptrdiff_t length;
97 {
98 #if DEBUGGING
99 	static char *DbgFNm = "InsStr";
100 	sprintf(DbgSBf,"length = %d", length);
101 	DbgFEn(3,DbgFNm,DbgSBf);
102 #endif
103 
104 	RefLen = -length;		/* ^S = -length of last string */
105 
106 /*
107  * Before trying to insert the text,  we have to be sure there's enough room
108  * in the edit buffer gap for the text.
109  */
110 	if ((GapEnd-GapBeg+1) < length) {
111 	    if (expand_gap(length) == FAILURE) {
112 		DBGFEX(3,DbgFNm,"FAILURE, expand_gap() failed");
113 		return FAILURE;
114 	    }
115 	}
116 /*
117  * Copy the new text into the edit buffer gap,  and adjust GapBeg to make the
118  * text part of the edit buffer.
119  */
120 	MEMMOVE(GapBeg, string, (SIZE_T)length);
121 	GapBeg += length;
122 
123 	DBGFEX(3,DbgFNm,"SUCCESS");
124 	return SUCCESS;
125 }
126