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

📄 txtutil.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;**************************************************************
; TxtReEnter, TxtReEnterBol
; Purpose:
;	Convert a line of pcode to source, parse it to pcode
;	and replace old pcode with new pcode.  This is done
;	for each line in the ReParse list before execution.
;	It is also done for each $INCLUDE line for FILE/REINCLUDE menu.
; Entry:
;	ax = offset into current text table anywhere within source line
;	     (points to opBol opcode for TxtReEnterBol variant)
; Exit:
;	same as for TxtChange
; Alters:
;	ps.bdpSrc (parser's source buffer)
;
;**************************************************************
PUBLIC	TxtReEnter
TxtReEnter PROC NEAR
	DbChk	Otx,ax			;error if ax > txdCur.bdlText.cbLogical
	push	ax
	call	OtxBolOfOtx		;ax = otx for start of INCLUDE line
	;fall into TxtReEnterBol
TxtReEnter ENDP

TxtReEnterBol PROC NEAR
	DbChk	Otx,ax			;error if ax > txdCur.bdlText.cbLogical
	push	ax			;pass otx to start of line to TxtChange

	push	ax			;pass otx to ListLine
	PUSHI	ax,<DATAOFFSET ps.PS_bdpSrc>	;pass dst adr to ListLine
	call	ListLine
	inc	ax			;test for UNDEFINED
	je	TrOmErr			;brif out-of-memory
	dec	ax			;restore ax = cb

	;If this line was included, set cInclNest non-zero, so parser
	;will generate an opBolInclude instead of an opBol for this line
	
	mov	al,[fLsIncluded]
	mov	[cInclNest],al

					;otxStart pushed several lines above
	push	[otxListNextInc]	;pass offset beyond end of line
	sub	ax,ax			;clear fNoInsert flag
	push	ax			;We have txt to insert
	call	TxtChange
	mov	[cInclNest],0		;restore: we know we're not loading
					; an INCLUDE file
TrExit:
	ret
TxtReEnterBol ENDP

;Out-of-memory error
TrOmErr:
	mov	ax,ER_OM		;ax = std error code for out-of-memory
	mov	[txtErr.TXER_errCode],ax
	jmp	SHORT TrExit

;**************************************************************
; DoReParse
; Purpose:
;	Re-Parse the 1st line after a given point in the current
;	tables 'reparse' list.
; Entry:
;	ax = text offset to start looking for lines to reparse
;	bx = text offset to stop looking for lines to reparse
; Exit:
;	ax = same as for TxtChange
;	If line was reparsed without errors
;	   carry clear on exit
;	else
;	   carry set on exit
;	   if error occurred (i.e. didn't just reached end of reparse list)
;	      txtErr struct is filled in.
;
;**************************************************************
PUBLIC	DoReParse
DoReParse PROC NEAR
	push	si			;save caller's si
	mov	si,[txdCur.TXD_otxReParseLink] ;si = otxLink
	xchg	dx,ax			; dx = starting otx, ax = garbage
	GetSegTxtTblCur			;es = seg addr of current text tbl
DrNext:
	sub	ax,ax			;prepare to return 0 (no TxtChange err)
	cmp	si,bx
	jae	DrEOL			;brif end of reparse list
	cmp	si,dx			;compare with otxStart parm
	jae	DrAbove
	mov	si,es:[si]		;si points to next opReParse link
	jmp	SHORT DrNext		;brif below otxStart
DrEOL:
	DJMP	jmp SHORT DrEndOfList

;si = otxLink = text offset to next re-parse opcode's link field.
;List this line and re-parse it.
;
;NOTE: It is real tempting to just call OtxBolOfOtx to get the
; offset to the start of the reparse line.  This SIGNIFICANTLY
; slows down paste.  We are guaranteed that the only opcodes that
; we may see before an opReParse are opBol, opBolInclude, opBolLab, and
; opBreakPoint.  Therefore the following opcode sequences could be seen:
;			  opBol  [opBreakPoint]
;	     opBolInclude(depth) [opBreakPoint]
;    opBolLab(otxNextLink, oNam) [opBreakPoint]
;
; The following code assumes the following:
;    opBol = 0
;    depth for include files is [1-5].
;    oNam for opBolInclude > 5
;    oTxNextLink > opBolInclude
;

DrAbove:
	mov	bx,-6			;amount to backup past count and
					; opcode field for opReparse

	mov	ax,si			;pass otxLink in ax
	cmp	word ptr es:[si+bx],opBreakPoint ;is there a BP set at the start
					; of this line?
	jne	DrGotBol		;brif not, already at opBol
	dec	bx			;back up past opBreakPoint
	dec	bx			; to opBol

; Parser guarantees only opBol, opBolLab, or opBolInclude before an opReparse.

DrGotBol:
	mov	cx,es:[si+bx]		;cx = opcode
	and	cx,OPCODE_MASK		;upper bits = leading spaces
	.errnz	opBol
					;have a standard opBol?
	jcxz	DrReenter		;brif so, reenter line

; We must have a line starting with opBolInclude, or opBolLab
	DbAssertRel oNamFirst,a,INCLUDE_DEPTH_MAX,CP,<DoReParse: err2>
	dec	bx
	dec	bx			;back up over include depth/oNam
	mov	cx,es:[si+bx]		;cx = opcode
	and	cx,OPCODE_MASK		;upper bits = leading spaces

	DbAssertRel opBolInclude,be,5,CP,<DoReParse: err3>
	cmp	cx,opBolInclude 	;is this an opBolInclude?
	je	DrReenter		;brif so

; We must have a line starting with opBolLab
	dec	bx
	dec	bx			;back up over include otxNextLink

DrReenter:
	add	ax,bx			;back up to bol opcode

	call	TxtReEnterBol		;reparse line ax
	cmp	[txtErr.TXER_errCode],0 ;tell caller a line was successfully
					; reparsed
	je	DrExit			;brif no error (carry is clear)
DrEndOfList:
	stc				;return carry set (no reparse, or error)
DrExit:
	pop	si			;restore caller's si
	ret
DoReParse ENDP

;**************************************************************
; ReParseTbl
; Purpose:
;	Called by SystemScan via ForEachMrs.  Finds all lines
;	that contain opReParse, and re-parses them until current
;	module contains no opReParse opcodes.
;	Caller should reset FM_asChg bit in mrsCur.MRS_flags
;	after all text tables in this module have no opReParse opcodes.
; Exit:
;	Same as ScanTxtTbl
;
;**************************************************************
cProc	ReParseTbl,<PUBLIC,NEAR>,<si>
cBegin

RptLoop0:
	;change any pcode which results from insertion/deletion of
	;AS clauses (due to their affect on ids with .)
	
	mov	al,[mrsCur.MRS_flags]
	mov	si,ax			
	and	[mrsCur.MRS_flags],NOT FM_asChg

RptLoop1:
	test	si, FM_asChg		
	je	NoAsChg			;brif no 'x AS' clauses have been
					; inserted or deleted in module.
	call	PreScanAsChg		;Re-Parse every line in current
					; text table with AS <user type>
					; or any non-record var with a
					; period in its name.
NoAsChg:
	call	ReParseTxdCur		
	jz	RptExit			
	call	NextTextPrsInMrs	;activate next procedure in module
	inc	ax
	jne	RptLoop1		;brif not at end of proc list
	dec	ax			;ax = UNDEFINED (return TRUE)
	test	[mrsCur.MRS_flags],FM_asChg
	jne	RptLoop0		;brif ReParse loop made added any
					; X AS clauses.
RptExit:
cEnd


;**************************************************************
; ReParseTxdCur
; Purpose:
;	Finds all lines in txdCur that contain opReParse,
;	and re-parses them.
;
;	This code was split out of ReParseTbl in revision [32].
; Exit:
;	Same as ScanTxtTbl
;	NZ and AX != 0	- Ok
;	Z and AX == 0	- Fail
;
;**************************************************************
cProc ReParseTxdCur,<NEAR,PUBLIC>,<DI>
cBegin
	mov	di,[grs.GRS_oRsCur]	;remember current oRs

;Now re-parse every line in current text table with opReParse opcode
;
RptLoop2:
	cmp	di,[grs.GRS_oRsCur]	;did we change our Rs?
	je	RptSameRs		;brif not

;A call to TxtRenEnter caused us to change to a new Rs.  This can only
; happen in the extremely rare case where a SUB or FUNCTION definition
; is a reparse (e.g. could already have one with the same name), and
; it can now be reparsed successfully, which causes a new Rs to be
; created and activated (e.g. the user Deleted the duplicate SUB or
; function before trying to execute).  In this case, we reactivate
; the original Rs continue reparsing it to completion.	If we don't
; do this, we could try to scan a text table containing reparses.
;
	extrn	RsActivateIfNotFree:near
	mov	ax,di			;ax = oRs to activate.
	call	RsActivateIfNotFree	;reactivate previous oRs (in AX)
					; unless ParseLine just renamed

RptSameRs:
	mov	ax,[txdCur.TXD_otxReParseLink]
	inc	ax			;test for UNDEFINED
	je	RptDone			;brif done with ReParse lines
	dec	ax
	mov	bx,0FFFFh		;search until end of text table
	call	DoReParse		;parse next opReParse in this text tbl
	jnc	RptLoop2		;brif progress was made (i.e. a line
					; was re-parsed with no errors)
	;TxtReEnter encountered an error.  txtErr struct was set up by TxtChange
	sbb	ax,ax			;ax = -1

RptDone:
	inc	ax			;Return 0 for fail, 1 for Ok
cEnd



;--------------------------------------------------------------
;		INCLUDE file support functions
;--------------------------------------------------------------

;**************************************************************
; SetViewInclude
; Purpose:
;	Enable or disable the visibility of $INCLUDEd source lines
; Entry:
;	parm uchar fEnable = TRUE if lines are to be visible
;
;**************************************************************
cProc	SetViewInclude,<PUBLIC,FAR>
	parmB	fEnable
cBegin
	mov	al,[fEnable]
	mov	[fViewInclude],al
	call	TxtFlushCache
cEnd

;**************************************************************
; TblReInclude
; Purpose:
;	Called for each text table to re-invoke $INCLUDE directives
;	in this text table.
; Exit:
;	returns ax = 0 if fatal error occurred (like out-of-memory,
;	or File-not-found) else returns non-zero
;
;**************************************************************
cProc	TblReInclude,<PUBLIC,NEAR>
cBegin
	PUSHI	ax,0
	call	CmdViewInclude		;make $INCLUDEd lines invisible
	DbAssertRelB [fViewInclude],e,0,CP,<TblReInclude fViewInclude != 0>
	and	[mrsCur.MRS_flags2], NOT FM2_ReInclude 
	sub	ax,ax
TblLoop:
	push	ax			;pass otxCur
	PUSHI	ax,<CODEOFFSET tOpReInclude>
	call	TxtFindNextOp		;ax = otx to next op_Include ($INCLUDE)
					;		(or OpStInclude [01])
					;dl = [txtFindIndex]
	cmp	dl,RI_opEot
	je	TblDone			;brif done with this text table


	;NOTE: next 3 lines must remain contiguous
	push	ax			;pass otx to OtxNoInclude
	call	TxtReEnter		;re-evaluate it, ignoring all errors
	call	OtxNoInclude		;ax = offset to next opBol/opEot
					; which was not included
	cmp	[txtErr.TXER_errCode],ER_OM
	jne	TblLoop			;brif TxtReEnter was successful
	sub	ax,ax			;return 0 (out-of-memory return code)
	jmp	SHORT TblExit

TblDone:
	sub	ax,ax
	mov	[txtErr.TXER_errCode],ax ;any errors encountered are in the
					; form of opReParse
	dec	ax			;return TRUE (non-zero)
TblExit:
cEnd

;**************************************************************
; TxtReInclude
; Purpose:
;	Called when user tries to execute a program.  If no loaded
;	INCLUDE files have been modified since last saved, it just
;	returns.  Else, it re-invokes the $INCLUDE directives in all
;	loaded text tables.  Errors are not reported, but reparsed.
;	The user will see any errors when he attempts to execute.
; Entry:
;	none
; Exit:
;	grs.fDirect = FALSE
;	ax = txtErr.errCode = error code if any error occurred while loading
;
;**************************************************************
cProc	TxtReInclude,<PUBLIC,FAR>
cBegin
	mov	[txtErr.TXER_errCode],0
	test	[flagsTm],FTM_reInclude
	je	NoReInclude
	and	[flagsTm],NOT FTM_reInclude
	call	SystemDescanCP		;descan all tables to SS_PARSE
	mov	al,FE_PcodeMrs+FE_CallMrs+FE_PcodePrs+FE_SaveRs
	mov	bx,CPOFFSET TblReInclude
	call	ForEachCP
NoReInclude:
	mov	ax,[txtErr.TXER_errCode]
cEnd

;*********************************************************************
; TxtFLnIncluded
; Entry:
;	parm1 = ln
; Exit:
;	ax = 0 if line was from $INCLUDE file
;
;*********************************************************************
cProc	TxtFLnIncluded,<PUBLIC,FAR>
	parmW	ln
	localV	bdBuf,<size BD>
cBegin
	push	[ln]			;pass line # to OtxOfLn
	call	OtxOfLn			;ax = otx for line
	push	ax			;pass otx to ListLine
	lea	bx,bdBuf		;pass pbd to ListLine
	mov	[bx.BD_pb],DATAOFFSET bufStdMsg
	mov	[bx.BD_cbLogical],0
	push	bx			;can't use bdpSrc, because editor
					; may have dirty copy of a line in it.
	call	ListLine		;set fLsIncluded for current line
					; since cbLogical is < 80, ListLine will
					; not try to grow buffer (it assumes
					; it is static). We just need the
					; 1st pass of the lister to execute,
					; not Stage2, since fLsIncluded is
					; set up during Stage1.
	mov	al,[fLsIncluded]
	cbw				;ax = result
cEnd

;*********************************************************************
; ushort TxtViewIncl(lnIncl, fDoIt)
; Purpose:
;	Called when user selects View/Include while insertion point
;	is on a line that has $INCLUDE in it.  This function creates
;	a new mrs by that name, and loads the file into that mrs.
; Entry:
;	grs.oRsCur is loaded with active window's register set.
;	lnIncl = the current line number in the active list window.
;	fDoIt = TRUE if the file is to actually be loaded (FALSE
;	   if we're just checking to see if current line contains $INCLUDE)
; Exit:
;	If fDoIt was FALSE on entry
;          if the line contains no $INCLUDE opcode, the function returns
;	      0
;	   else
;             it returns non-zero
;	   if lnIncl came from an $INCLUDE file, fLsIncluded is set
;	      non-zero, else it is set to 0.
;	else
;	   exit conditions are the same as LoadFile
; Alters:
;	ps.bdpDst (parser's pcode result buffer)
;
;*********************************************************************
cProc	TxtViewIncl,<PUBLIC,FAR>,<si>
	parmW	lnIncl
	parmW	fDoIt
	localV	filenameInc,FILNAML64
	localV	sdFilenameInc,<SIZE SD>
	localV	bdBuf,<size BD>
cBegin
	lea	si,sdFilenameInc
	lea	ax,filenameInc
	mov	[si.SD_pb],ax
	sub	ax,ax
	mov	[si.SD_cb],ax
	mov	[bdBuf.BD_cbLogical],ax ;pass cbMax to ListLine
					; since it is < 80, ListLine will
					; not try to grow buffer (it assumes
					; it is static). We just need the
					; 1st pass of the lister to execute,
					; not Stage2, since psdLsIncl is
					; set up during Stage1.
	mov	[bdBuf.BD_pb],DATAOFFSET bufStdMsg

⌨️ 快捷键说明

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