TEACL is a fork of TECOC created for the purpose of describing diffs in a document being collaboratively edited
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

115 lines
4.0 KiB

/*****************************************************************************
RdLine()
This function reads a line from the current input file into the
edit buffer. The input is placed into the edit buffer by appending it
to the edit buffer and adjusting the EBfEnd pointer. IBfEnd points to the
last byte of allocated, unused memory at the end of the edit buffer.
*****************************************************************************/
#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 */
#include "dchars.h" /* define identifiers for characters */
/*
* The input buffer needs to be expanded. If there's room in the edit buffer
* gap, then we can shuffle memory to steal some room from the gap. If
* there's still not enough room in the input buffer we re-allocate the
* entire edit/input buffer and then adjust the pointers to reflect the
* reallcatin. If the reallocation fails, set EBfFul to TRUE.
*/
#if USE_PROTOTYPES
static void expand_ibf(BOOLEAN *EBfFul)
#else
static void expand_ibf(EBfFul)
BOOLEAN *EBfFul; /* indicates edit buffer full */
#endif
{
SIZE_T TmpSiz;
SIZE_T NewSiz;
charptr NewBeg;
DBGFEN(3,"expabd_ibf",NULL);
/*
* If the size of the edit buffer gap exceeds GAPMIN, make it GAPMIN and
* add the leftover space to the input buffer.
*
* from: EbfBeg...GapBeg<GAPMIN><slack>GapEnd...EBfEnd...IBfEnd
* to: EbfBeg...GapBeg<GAPMIN>GapEnd...EBfEnd...<slack>IBfEnd
*/
TmpSiz = GapEnd-GapBeg+1;
if (TmpSiz > GAPMIN) {
TmpSiz -= GAPMIN;
MEMMOVE(GapEnd+1-TmpSiz, GapEnd+1, (SIZE_T)(EBfEnd-GapEnd));
GapEnd -= TmpSiz;
EBfEnd -= TmpSiz;
}
/*
* If there's still not enough room in the input buffer, expand the input
* buffer by reallocating everything. Since reallocating is expensive,
* take this opportunity to expand it by IBFEXP bytes more than what we
* need.
*
* from: EbfBeg...GapBeg...GapEnd...EBfEnd<TmpSiz>IBfEnd
* to: EbfBeg...GapBeg...GapEnd...EBfEnd<IBFMIN+IBFEXP>IBfEnd
*/
TmpSiz = IBfEnd-EBfEnd;
if (TmpSiz < IBFMIN) {
NewSiz = (IBfEnd-EBfBeg+1) + (IBFMIN-TmpSiz) + IBFEXP;
#if DEBUGGING
sprintf(DbgSBf,"ZRaloc-ing EBf, NewSiz = %ld", NewSiz);
DbgFMs(3,DbgFNm,DbgSBf);
#endif
NewBeg = (charptr)ZRaloc(EBfBeg, NewSiz);
if (NewBeg == NULL) {
*EBfFul = TRUE; /* we're full: stop reading lines */
} else {
if (NewBeg != EBfBeg) { /* if ZRaloc moved us, adjust ptrs */
GapBeg = NewBeg + (GapBeg - EBfBeg);
GapEnd = NewBeg + (GapEnd - EBfBeg);
EBfEnd = NewBeg + (EBfEnd - EBfBeg);
EBfBeg = NewBeg;
}
IBfEnd = (NewBeg + NewSiz) - 1;
}
}
DBGFEX(3,DbgFNm,NULL);
}
DEFAULT RdLine(EBfFul) /* read a line */
BOOLEAN *EBfFul;
{
DEFAULT length;
DBGFEN(3,"RdLine",NULL);
FFPage = 0; /* clear the form-feed flag */
if (!IsOpnI[CurInp]) { /* if current input stream not open */
ErrMsg(ERR_NFI); /* NFI = "no file for input" */
DBGFEX(3,DbgFNm,"FAILURE, no file for input");
return FAILURE;
}
if (IsEofI[CurInp]) { /* if already at end-of-file */
DBGFEX(3,DbgFNm,"SUCCESS, already at eof");
return SUCCESS;
}
/*
* Before trying to read the next line from the input file, we have to be
* sure there's enough room for the record. IBFMIN is the minimum amount of
* room to provide when reading a record. If there's not IBFMIN bytes
* available, we have to get more room.
*/
if ((IBfEnd-EBfEnd) < IBFMIN) { /* if not enough room */
expand_ibf(EBfFul);
}
/*
* Read the line from the input file.
*/
if (*EBfFul == FALSE) {
if (ZRdLin(EBfEnd+1, IBfEnd-EBfEnd, CurInp, &length) == FAILURE) {
ErrMsg(ERR_URL); /* unable to read line */
DBGFEX(3,DbgFNm,"FAILURE, ZRdLin() failed");
return FAILURE;
}
if (!IsEofI[CurInp]) { /* if not end-of-file */
EBfEnd += length;
}
}
DBGFEX(3,DbgFNm,"SUCCESS, final");
return SUCCESS;
}