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