📄 txtutil.asm
字号:
;**************************************************************
; 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 + -