112 lines
3.7 KiB
C
112 lines
3.7 KiB
C
/*****************************************************************************
|
|
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...EBfEnd<TmpSiz><IBFMIN>IBfEnd
|
|
* to: EbfBeg...GapBeg...<TmpSiz>GapEnd...EBfEnd<IBFMIN>IBfEnd
|
|
*/
|
|
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...GapBeg<GapSiz>GapEnd...EBfEnd...IBfEnd
|
|
* to: EbfBeg...GapBeg<length-GapSiz+EBFEXP>GapEnd...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;
|
|
}
|