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

📄 textmgr.c

📁 这是DOS系统的源代码,汇编写的,值得看看,对开发操作系统的人员有价值
💻 C
📖 第 1 页 / 共 2 页
字号:
/***	TXTMGR.C - Text manager for multi-line editing
*
* GLOBAL
*	LoadBuf			Load a file into a buffer
*	FreeBuf			Free a buffer
*	NewBuf			Create a new (blank) buffer
*
*	S_LinesInBuf		LinesInBuf() routine
*	S_CbGetLineBuf		CbGetLineBuf() routine
*	S_ReplaceLineBuf	ReplaceLineBuf() routine
*	S_InsertLineBuf 	InsertLineBuf() routine
*	S_InsertBufInBuf	InsertBufInBuf() routine
*	S_DeleteLinesBuf	DeleteLinesBuf() routine
*
* LOCAL
*	CbFindLineBuf		Find a specified line in a buffer
*	InsSpace		Insert space into a buffer
*	GrowBuf			Increase the size of a buffer
*
* DESCRIPTION
*
*	This module manages the program source and contains all functions
*	that operate directly on the source.
*
*	The source buffer is maintained in a single Global Heap Segment. It
*	may be larger than 64k. Because of this, linear addresses (32 bit) are
*	used. The linear addresses are converted to segmented addresses when
*	actually accessing the buffer.
*
*	The format of the source buffer is:
*
*		+-----------+-----//-----+-----------+-----//-----+
*		| WORD len0 | len0 BYTES | WORD len1 | len1 BYTES |
*		+-----------+-----//-----+-----------+-----//-----+
*
*				    +------+-----//-----+---------+
*				... | lenN | lenN BYTES | WORD -1 |
*				    +------+-----//-----+---------+
*
*/

/*------------------------- Include Files -------------------------*/

#include <version.h>
/* Next, include COW's interface headers */
#include <cw/version.h>
#include <cw/windows.h>
#include <cw/edityp.h>
#include <uiext.h>

#include <..\hd\edit.h>

#ifndef UIINT_H
#include <uiint.h>
#endif

#ifndef HEAP_H
#include <heap.h>
#endif

#ifndef QBIMSGS_H
#include <qbimsgs.h>
#endif

extern char	szNull[];
       char	*pszNull = szNull;

/*-------------------------- Local Macros --------------------------*/

/* Returns TRUE if the fhd is allocated, zero if it is un-allocated */

#define ALLOCEDFHD(fhd) (fhd.hData != 0)

/* Dereferences a fhd and returns a far pointer to the data	    */

#define MAKELONG(l, h)	((long)(((unsigned)(l)) | ((unsigned long)((unsigned)(h))) << 16))
#define DEREFFHD(fhd)	((char far *) MAKELONG(0, GETSEG(fhd.hData)))

/*----------------------- Forward References -----------------------*/

LOCAL	WORD	NEAR	PASCAL	CbFindLineBuf(PBUFINFO, DWORD, WORD, DWORD *);
LOCAL	DWORD	NEAR	PASCAL	InsSpace(PBUFINFO, WORD, DWORD);
LOCAL	BOOL	NEAR	PASCAL	GrowBuf(PBUFINFO, DWORD);

/*------------------- Global and Local Variables -------------------*/

/* The EDITMGR requires a number of routines to get its work done; it
** does a call back into the application (us) to update the text buffer.
** Such routines as InsertLineBuf(), DeleteLinesBuf(), etc. are among
** these required call-back routines.
*/

/* These are the buffers that acually manage the data and the information
** that is associated with the data
*/

LOCAL	BUFINFO rgbufinfo[CBUFINFO];

/*------------------ S_LinesInBuf() ------------------*/

/***	LinesInBuf - How many lines in VAP's buffer?
*
* SYNOPSIS
*		cln = LinesInBuf(idVap)
*
* ENTRY
*		idVap			ID of VAP which owns buffer
*
* RETURNS
*		Number of lines currently in buffer
*
* DESCRIPTION
*		Examines the .cln field in the BUFINFO structure to determine
*		the number of lines currently in the buffer.
*
* NOTES
*		Required by EDITMGR
*
*/

GLOBAL WORD FAR PASCAL
S_LinesInBuf(PBUFINFO pbufinfo)
{
	DbChkPBufInfo(pbufinfo);
	DbAssert(ALLOCEDFHD(pbufinfo->fhd));

	return(pbufinfo->cln - 1);
}


/*--------------------------- FreeBuf() ---------------------------*/

/***	FreeBuf - Free a buffer
*
* SYNOPSIS
*		FreeBuf(pbufinfo)
*
* ENTRY
*		pbufinfo		pointer to BUFINFO of buffer
*					to deallocate
*
* RETURNS
*		None
*
* DESCRIPTION
*		Release the memory associated with this buffer.
*
* NOTES
*/

GLOBAL VOID FAR PASCAL
FreeBuf(PBUFINFO pbufinfo)
{
	DbChkPBufInfo(pbufinfo);

	if (ALLOCEDFHD(pbufinfo->fhd))
	{
		FhdDealloc(&pbufinfo->fhd);
	}
}

/*------------------------ CbFindLineBuf() ------------------------*/

/***	CbFindLineBuf() - Find a line in a buffer
*
* SYNOPSIS
*		cb = CbFindLineBuf(pbufinfo, obBase, oln, pobLine)
*
* ENTRY
*		pbufinfo		Pointer to a BUFINFO structure
*		obBase		32-bit pointer to start of buffer
*		oln			Line number to find
*		pobLine		Pointer to DWORD (return value)
*
* RETURNS
*		Number of bytes in line found
*		Also returns 32-bit pointer to line found through pobLine
*
*		Note that the "pointer" points to the actual text, NOT the WORD
*		length preceding the text.
*
* DESCRIPTION
*		Basically a higher-level routine for CbFindLine(); most of
*		the work is done there.  Uses and updates the cache (.olnCache
*		and .obCache fields) from the BUFINFO structure.
*
*/

LOCAL WORD NEAR PASCAL
CbFindLineBuf(PBUFINFO pbufinfo, DWORD obBase, WORD oln, DWORD *pobLine)
{
	WORD		cb;
	WORD		olnCache;

	*pobLine = obBase;

	/* If the requested line is farther along in the file than the
	** line last cached, we can save a lot of time by skipping to
	** the cached (known) line.
	*/

	olnCache = pbufinfo->olnCache;
	pbufinfo->olnCache = oln;

	if (oln >= olnCache)
	{
		*pobLine += pbufinfo->obCache;
		oln -= olnCache;
	}

	/* Find the line in the buffer.  pobLine as passed in to CbFindLine()
	** "points to" the WORD length preceding some line; on exit, it will
	** "point to" the actual text of the line found.
	*/

	cb = CbFindLine(pobLine, oln);

	/* Update the cache information for this BUFINFO.
	*/

	pbufinfo->obCache = *pobLine - sizeof(WORD) - obBase;

	return(cb);
}

/*--------------------------- InsSpace() ---------------------------*/

/***	InsSpace - Insert space into a buffer
*
* SYNOPSIS
*		obNewSpace = InsSpace(pbufinfo, oln, cbAdd)
*
* ENTRY
*		pbufinfo		Pointer to a BUFINFO structure
*		oln			Line number within buffer
*		cbAdd			Number of bytes to add
*
* RETURNS
*		32-bit pointer to start of vacated region  (relative
*		to begining of memory block)
*
*		-OR-
*
*		0L if the buffer could not accomodate the additional space
*
* DESCRIPTION
*		This routine will make space in the source buffer for a line of text.
*		The space will be made BEFORE oln. The source is moved down from
*		oln to the end of source.
*
* NOTES
*/		

LOCAL DWORD NEAR PASCAL
InsSpace(PBUFINFO pbufinfo, WORD oln, DWORD cbAdd)
{
	DWORD		obSrc;
	DWORD		obBase;
	DWORD		cbMove;


	/* If adding the requested number of bytes would grow the buffer
	** beyond its current maximum size, try to make the buffer larger.
	** If this fails, return 0L.
	*/

	if (pbufinfo->obNext + cbAdd + 1 > pbufinfo->cb)
	{
		if (!GrowBuf(pbufinfo, cbAdd))
			return(0L);
	}

	/* Lock the buffer down and find the offset (32-bit pointer) of
	** the indicated line.
	*/

	DbHeapMoveOff();

	obBase = LinearAddr(DEREFFHD(pbufinfo->fhd));

	if (oln < pbufinfo->cln)				/* If within range... */
	{
		CbFindLineBuf(pbufinfo, obBase, oln, &obSrc);
		obSrc -= sizeof(WORD);				/* Move back to WORD length */
		cbMove = pbufinfo->obNext - (obSrc - obBase) + 1;

		BigMoveDown(obSrc + cbAdd, obSrc, cbMove);
	}
	else											/* Add to end of file */
		obSrc = obBase + pbufinfo->obNext;

	pbufinfo->obNext += cbAdd;
	pbufinfo->olnCache = 0xFFFF;			/* Destroy cache information */

	DbHeapMoveOn();

	return(obSrc - obBase);
}

/*--------------------------- GrowBuf() ---------------------------*/

/***	GrowBuf - Increase the size of a buffer
*
* SYNOPSIS
*		fStatus = GrowBuf(pbufinfo, cbAdd)
*
* ENTRY
*		pbufinfo		Pointer to BUFINFO
*		cbAdd			Number of bytes to increase size by
*
* RETURNS
*		TRUE if buffer could be grown; FALSE if not
*
* DESCRIPTION
*		Call the SBMGR to reallocate the buffer, rounding the new size
*		to be an even multiple of CBSRCBLK.
*
* NOTES
*/

LOCAL BOOL NEAR PASCAL
GrowBuf(PBUFINFO pbufinfo, DWORD cbAdd)
{
	DWORD		cbNeeded;
	DWORD		cbRequested;

	cbRequested = cbNeeded = pbufinfo->cb + cbAdd + 1;


	cbRequested += CBSRCBLK - 1;
	cbRequested &= ~(CBSRCBLK - 1);

	// Try the alloc with the extra space
	if (FhdRealloc(&(pbufinfo->fhd), cbRequested))
	{
		pbufinfo->cb = cbRequested;
		return(TRUE);
	}

	// Ok, now try it with just the amount that we need
	if (FhdRealloc(&(pbufinfo->fhd), cbNeeded)) {
		pbufinfo->cb = cbNeeded;
		return(TRUE);
	}

	// Unable to get the needed amount of memory, fail
	SetUiErrOm();
	return(FALSE);
}

/*---------------- S_CbGetLineBuf() ----------------*/

/***	S_CbGetLineBuf - Fetch a line of text from a buffer
*
* SYNOPSIS
*		cb = S_CbGetLineBuf(idVap, oln, cbMax, pBuf)
*
* ENTRY
*		idVap			ID of VAP whose buffer this concerns
*		oln			Line number to fetch
*		cbMax			Maximum number of characters to place in buffer
*		pBuf			Buffer to place text in
*
* RETURNS
*		Number of characters placed in buffer (excluding terminating zero)
*
* DESCRIPTION
*		This routine gets the specified line of text even it is the current
*		line. This is used when the ld buffer has been modified and the line
*		needs to be refreshed.
*
* NOTES
*		Required by EDITMGR
*
*		M00SWAP NPCORE
*/

GLOBAL WORD FAR PASCAL
S_CbGetLineBuf(PBUFINFO pbufinfo, WORD oln, WORD cbMax, char *pBuf)
{
	REG2	WORD	cb;
	DWORD		obSrc;

	DbChkPBufInfo(pbufinfo);
	DbAssert(ALLOCEDFHD(pbufinfo->fhd));

	/* Ignore first line of buffer -- it contains the filename.
	*/

	oln++;

	if (oln < pbufinfo->cln)
	{
		DbHeapMoveOff();

		cb = CbFindLineBuf(pbufinfo, LinearAddr(DEREFFHD(pbufinfo->fhd)), oln, &obSrc);
		cb = min(cb, cbMax);
		fmemcpy((char far *)pBuf, SegAddr(obSrc), cb);

		DbHeapMoveOn();
	}
	else
		cb = 0;
	
	pBuf[cb] = '\0';
	
	return(cb);
}


/*-------------- S_ReplaceLineBuf() --------------*/

/***	S_ReplaceLineBuf - Replace a line in a buffer
*
* SYNOPSIS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -