⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textmgr.c

📁 MS DOS 6.0 操作系统源码完整版,对于研制操作系统结构,构建个人的操作系统是非常有用的.
💻 C
📖 第 1 页 / 共 2 页
字号:
*		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 + -