📄 textmgr.c
字号:
* fSuccess = S_ReplaceLineBuf(idVap, oln, cb, pBuf)
*
* ENTRY
* idVap ID of VAP whose buffer this concerns
* oln Line to replace
* cb Size of replacement text
* pBuf Point to Pointer to replacement text
*
* RETURNS
* TRUE if successful; FALSE if not
*
* DESCRIPTION
* Replace the indicated line in the buffer. The double
* indirection on the buffer allows us to point to a
* movable heap entry and still cause heap movement.
*
* NOTES
* Required by EDITMGR
*/
GLOBAL BOOL NEAR PASCAL
S_ReplaceLineBuf(PBUFINFO pbufinfo, WORD oln, WORD cb, char **pBuf)
{
DbChkPBufInfo(pbufinfo);
DbAssert(ALLOCEDFHD(pbufinfo->fhd));
if (S_InsertLineBuf(pbufinfo, oln + 1, cb, pBuf, TRUE))
{
S_DeleteLinesBuf(pbufinfo, oln, 1);
}
return(TRUE);
}
/*--------------- S_InsertLineBuf() ---------------*/
/*** S_InsertLineBuf - Insert a line in a buffer
*
* SYNOPSIS
* fSuccess = S_InsertLineBuf(idVap, oln, cb, pBuf, fOverCommit)
*
* ENTRY
* pBuf Buffer to insert into
* oln Line to insert text (AFTER)
* cb Size of text to insert
* pBuf Pointer to pointer to Text to insert
* fOverCommit Check for too many lines or not.
*
* RETURNS
* TRUE if successful; FALSE if not
*
* DESCRIPTION
* First remove any trailing spaces from the line, then convert
* any leading spaces to tabs, if possible. Then call InsSpace()
* to insert space in the buffer, and copy the line to the vacated
* region.
*
* if fOverCommit is true, then we will not check for
* inserting too many lines into the buffer. This allows
* S_ReplaceLineBuf to work properly, as it adds a line
* then deletes a line. If we did not allow it too add more
* lines than the maximum, we would not be able to modify
* a full text table.
*
* The double indirection on the buffer allows us to point to a
* movable heap entry and still cause heap movement.
*
* NOTES
* Required by EDITMGR
*
*/
GLOBAL BOOL NEAR PASCAL
S_InsertLineBuf(PBUFINFO pbufinfo, WORD oln, WORD cb, char **pBuf, BOOL fOverCommit)
{
DWORD obLine;
char far *fpData;
WORD cbSave = cb;
DbChkPBufInfo(pbufinfo);
DbAssert(ALLOCEDFHD(pbufinfo->fhd));
if (pbufinfo->cln >= CLNMAX && !fOverCommit) {
SetUiErr(MSG_DocTooLarge);
return (FALSE);
}
/* Ignore first line of buffer - it contains the filename.
*/
oln++;
obLine = InsSpace(pbufinfo, oln, (DWORD)(cb + sizeof(WORD)));
if (obLine)
{
DbHeapMoveOff();
fpData = SegAddr(obLine + LinearAddr(DEREFFHD(pbufinfo->fhd)));
*(WORD far *)fpData = cb;
if (cb != 0)
{
fmemcpy(fpData+(long)sizeof(WORD), (char far *)*pBuf, cb);
}
pbufinfo->cln++;
DbHeapMoveOn();
}
return(obLine != 0L);
}
/*-------------- S_InsertBufInBuf() --------------*/
/*** S_InsertBufInBuf - Insert a buffer into another buffer
*
* SYNOPSIS
* S_InsertBufInBuf(idVapDst, oln, idVapSrc)
*
* ENTRY
* idVapDst ID of VAP whose buffer is to serve as destination
* oln Line number in destination buffer
* idVapSrc ID of VAP whose buffer is to serve as source
*
* RETURNS
* None
*
* DESCRIPTION
* Insert a buffer within another buffer
*
* NOTES
* Required by EDITMGR
*
*/
GLOBAL VOID NEAR PASCAL
S_InsertBufInBuf(PBUFINFO pbufinfoDst, WORD oln, PBUFINFO pbufinfoSrc)
{
DWORD cbAdd;
WORD cbBufName;
DWORD obDst;
DWORD obSrc;
DbChkPBufInfo(pbufinfoSrc);
DbAssert(ALLOCEDFHD(pbufinfoSrc->fhd));
DbChkPBufInfo(pbufinfoDst);
DbAssert(ALLOCEDFHD(pbufinfoDst->fhd));
if (pbufinfoSrc->cln + pbufinfoDst->cln >= CLNMAX) {
SetUiErr(MSG_DocTooLarge);
return;
}
/* Ignore first line of buffer - it contains the filename.
*/
oln++;
cbBufName = *(WORD far *) DEREFFHD(pbufinfoSrc->fhd) + sizeof(WORD);
cbAdd = pbufinfoSrc->obNext - cbBufName; /* - sizeof(WORD); */
obDst = InsSpace(pbufinfoDst, oln, cbAdd);
if (obDst)
{
DbHeapMoveOff();
obDst += LinearAddr(DEREFFHD(pbufinfoDst->fhd));
obSrc = LinearAddr(DEREFFHD(pbufinfoSrc->fhd)) + cbBufName;
BigMoveUp( obDst, obSrc, cbAdd );
pbufinfoDst->cln += pbufinfoSrc->cln - 1;
DbHeapMoveOn();
}
return; /* M00BUG */
}
/*-------------- S_DeleteLinesBuf() --------------*/
/*** S_DeleteLinesBuf - Delete a range of lines from a buffer
*
* SYNOPSIS
* S_DeleteLinesBuf(pbufinfo, oln, cln)
*
* ENTRY
* pbufinfo handle to buffer
* oln Starting line number
* cln Number of lines to delete
*
* RETURNS
* None
*
* DESCRIPTION
* Delete lines oln..oln+cln-1 from the indicated buffer
*
* NOTES
* Required by EDITMGR
*
*/
GLOBAL VOID NEAR PASCAL
S_DeleteLinesBuf(PBUFINFO pbufinfo, WORD oln, WORD cln)
{
DWORD obSrc, obDst;
DWORD obBase;
DWORD cbMove;
WORD clnMax;
DbChkPBufInfo(pbufinfo);
DbAssert(ALLOCEDFHD(pbufinfo->fhd));
/* Ignore first line of buffer - it contains the filename.
*/
oln++;
clnMax = pbufinfo->cln - oln;
if (cln >= clnMax)
cln = clnMax;
if (pbufinfo->cln == cln+1)
{
/* Special case:
**
** Deleting all the lines in the buffer.
** Insert a blank line so that there will be a blank
** line left in the buffer after deleting the lines.
*/
S_InsertLineBuf(pbufinfo, pbufinfo->cln, 0, &pszNull, TRUE);
}
DbHeapMoveOff();
obBase = LinearAddr(DEREFFHD(pbufinfo->fhd));
CbFindLineBuf(pbufinfo, obBase, oln, &obSrc);
obSrc -= sizeof(WORD);
CbFindLineBuf(pbufinfo, obBase, oln+cln, &obDst);
obDst -= sizeof(WORD);
cbMove = pbufinfo->obNext - (obDst - obBase) + 1;
BigMoveUp( obSrc, obDst, cbMove );
pbufinfo->obNext -= obDst - obSrc;
pbufinfo->cln -= cln;
pbufinfo->olnCache = 0xFFFF; /* Trash the cache */
DbHeapMoveOn();
}
/*---------------------------- NewBuf() ----------------------------*/
/*** NewBuf - Create a new (blank) buffer
*
* SYNOPSIS
* fSuccess = NewBuf(pbufinfo)
*
* ENTRY
* pbufinfo pointer to buffer info block which is to
* own new buffer
*
* RETURNS
* PBUFINFO for buffer if successful; FALSE (0) if not
*
* DESCRIPTION
* then adds a blank line to make sure the EDITMGR doesn't get
* confused.
*/
GLOBAL PBUFINFO FAR PASCAL
NewBuf()
{
PBUFINFO pbufinfo;
int iBufInfo;
pbufinfo = NULL;
/* locate a buffer that is not already in use */
for (iBufInfo = 0; (iBufInfo < CBUFINFO) && !pbufinfo; iBufInfo++)
if (!ALLOCEDFHD(rgbufinfo[iBufInfo].fhd))
pbufinfo = &rgbufinfo[iBufInfo];
DbAssert(pbufinfo != NULL);
if (!FhdAlloc(&pbufinfo->fhd, (DWORD)CBSRCBLK))
{
SetUiErrOm();
return(FALSE);
}
pbufinfo->cln = 0;
pbufinfo->cb = CBSRCBLK;
pbufinfo->obNext = 0;
pbufinfo->olnCache = 0xFFFF; /* No line cached yet... */
if (AppendLineBuf(pbufinfo, &pszNull))
{
FreeBuf(pbufinfo);
return (FALSE);
}
return (pbufinfo);
}
/*** AppendLineBuf - append a line to the end of a buffer
*
* SYNOPSIS
* fSuccess = AppendLineBuf(pbufinfo, pBuf)
*
* ENTRY:
* pbufinfo Pointer to buffer to update
* pBuf Indirect Pointer to the source line (tab expanded)
*
* EXIT:
* Returns 0 on success, -1 on failure
*
* NOTES:
* This routine can cause heap movement.
*
* This was written for speed, not size. If the added speed is not
* is not needed for ASCII load, then call S_InsertLineBuf to do all
* of the work.
*
* The reason that we take a char ** is so that we can take a pointer
* to a movable heap item. This allows us to handle it like an LMEM
* entry.
*/
GLOBAL WORD FAR PASCAL
AppendLineBuf(PBUFINFO pbufinfo, char **pBuf)
{
WORD cbBuf = CbSzUi(*pBuf);
DWORD cbNeeded = cbBuf + sizeof(WORD);
DWORD cbAvail = pbufinfo->cb - pbufinfo->obNext;
DWORD obLine;
WORD far *fpLineLen;
char far *fpLine;
DbChkPBufInfo(pbufinfo);
DbAssert(ALLOCEDFHD(pbufinfo->fhd));
if (pbufinfo->cln >= CLNMAX) {
SetUiErr(MSG_DocTooLarge);
return (UNDEFINED);
}
if (cbAvail < cbNeeded)
if (!GrowBuf(pbufinfo, cbNeeded - cbAvail))
return (UNDEFINED);
obLine = LinearAddr(DEREFFHD(pbufinfo->fhd)) + pbufinfo->obNext;
fpLineLen = (WORD far *)SegAddr(obLine);
fpLine = SegAddr(obLine + sizeof(WORD));
*fpLineLen = cbBuf;
fmemcpy(fpLine, (char far *)*pBuf, cbBuf);
pbufinfo->obNext += cbNeeded;
pbufinfo->cln ++;
return (0);
}
/*** CompressBufs - Compress Document buffers to minimum size
*
* SYNOPSIS
* CompressBufs()
*
* ENTRY:
* None.
*
* EXIT:
* None.
*
* NOTES:
* This routine can cause heap movement.
*
* We keep some slack in the document buffers to allow for fast
* insertion of text. However, if we are running out of memory
* (or just run out), we need to get rid of the slack. This routine
* will go through all allocated document buffers, removing any slack.
*/
GLOBAL VOID FAR PASCAL CompressBufs()
{
int i = 0;
for (i = 0; i < CBUFINFO; i++)
if (ALLOCEDFHD(rgbufinfo[i].fhd))
if (FhdRealloc(&rgbufinfo[i].fhd, rgbufinfo[i].obNext))
rgbufinfo[i].cb = rgbufinfo[i].obNext;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -