/***************************************************************************** InsStr() This function is called to insert text into the edit buffer. The edit buffer is expanded to make room for the text if necessary. *****************************************************************************/ #include "zport.h" /* define portability identifiers */ #include "tecoc.h" /* define general identifiers */ #include "defext.h" /* define external global variables */ #include "deferr.h" /* define identifiers for error messages */ /* * The edit buffer gap needs to be expanded. If there's room in the input * buffer, then we can shuffle memory to steal some room from the input * buffer. If there's not room to steal from the input buffer, we have to * re-allocate the whole edit/input buffer and then adjust the pointers to * reflect the movement. */ #if USE_PROTOTYPES static DEFAULT expand_gap(ptrdiff_t length) #else static DEFAULT expand_gap(length) ptrdiff_t length; /* amount of gap room needed */ #endif { SIZE_T TmpSiz; SIZE_T NewSiz; charptr NewBeg; DBGFEN(3,"expand_gap",NULL); /* * If the size of the input buffer exceeds IBFMIN, make it IBFMIN and * add the leftover space to the edit buffer gap. * * from: EbfBeg...GapBeg...GapEnd...EBfEndIBfEnd * to: EbfBeg...GapBeg...GapEnd...EBfEndIBfEnd */ TmpSiz = IBfEnd-EBfEnd; if (TmpSiz > IBFMIN) { TmpSiz -= IBFMIN; MEMMOVE(GapEnd+1+TmpSiz, GapEnd+1, (SIZE_T)(EBfEnd-GapEnd)); GapEnd += TmpSiz; EBfEnd += TmpSiz; } /* * If there's still not enough room in the edit buffer gap, expand the gap * by reallocating the edit buffer. Since reallocating is expensive, take * this opportunity to expand it by EBFEXP bytes more than what we need. * * from: EbfBeg...GapBegGapEnd...EBfEnd...IBfEnd * to: EbfBeg...GapBegGapEnd...EBfEnd...IBfEnd */ TmpSiz = GapEnd-GapBeg+1; if (TmpSiz < length) { /* str length > GapSiz */ TmpSiz = (length - TmpSiz) + EBFEXP; /* amt to expand EBf */ NewSiz = (IBfEnd-EBfBeg+1) + TmpSiz; /* new size of EBf */ NewBeg = (charptr)ZRaloc(EBfBeg, NewSiz); /* reallocate EBf */ if (NewBeg == NULL) { /* if failure */ ErrMsg(ERR_MEM); /* memory overflow */ DBGFEX(3,DbgFNm,"FAILURE, couldn't ZRaloc more gap room"); return FAILURE; } /* * Make sure all the pointers reference the new memory area. */ if (NewBeg != EBfBeg) { GapBeg = NewBeg + (GapBeg - EBfBeg); GapEnd = NewBeg + (GapEnd - EBfBeg); EBfEnd = NewBeg + (EBfEnd - EBfBeg); IBfEnd = NewBeg + (IBfEnd - EBfBeg); EBfBeg = NewBeg; } /* * Now open up the gap by moving the second half of the edit buffer * down the amount we expanded the edit buffer (TmpSiz), then update the * pointers again. */ MEMMOVE(GapEnd+1+TmpSiz, GapEnd+1, (SIZE_T)(EBfEnd - GapEnd)); GapEnd += TmpSiz; EBfEnd += TmpSiz; IBfEnd += TmpSiz; } DBGFEX(3,DbgFNm,NULL); return SUCCESS; } DEFAULT InsStr(string, length) /* insert string into edit buffer */ charptr string; ptrdiff_t length; { #if DEBUGGING static char *DbgFNm = "InsStr"; sprintf(DbgSBf,"length = %d", length); DbgFEn(3,DbgFNm,DbgSBf); #endif RefLen = -length; /* ^S = -length of last string */ /* * Before trying to insert the text, we have to be sure there's enough room * in the edit buffer gap for the text. */ if ((GapEnd-GapBeg+1) < length) { if (expand_gap(length) == FAILURE) { DBGFEX(3,DbgFNm,"FAILURE, expand_gap() failed"); return FAILURE; } } /* * Copy the new text into the edit buffer gap, and adjust GapBeg to make the * text part of the edit buffer. */ MEMMOVE(GapBeg, string, (SIZE_T)length); GapBeg += length; DBGFEX(3,DbgFNm,"SUCCESS"); return SUCCESS; }