You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1203 lines
28 KiB
1203 lines
28 KiB
PAGE 60,132
|
|
TITLE Edlcmd2 - PART2 procedures called from EDLIN
|
|
;/*
|
|
; * Microsoft Confidential
|
|
; * Copyright (C) Microsoft Corporation 1991
|
|
; * All Rights Reserved.
|
|
; */
|
|
|
|
|
|
;======================= START OF SPECIFICATIONS =========================
|
|
;
|
|
; MODULE NAME: EDLCMD2.SAL
|
|
;
|
|
; DESCRIPTIVE NAME: EDLIN ROUTINES
|
|
;
|
|
; FUNCTION: THIS MODULE PROVIDES ROUTINES NEEDED FOR EDLIN'S EXECUTION.
|
|
;
|
|
; ENTRY POINT: ANY CALLED ROUTINE
|
|
;
|
|
; EXIT NORMAL: NA
|
|
;
|
|
; EXIT ERROR : NA
|
|
;
|
|
; INTERNAL REFERENCES:
|
|
;
|
|
; EXTERNAL REFERENCES:
|
|
;
|
|
; ROUTINE: EDLCMD1 - ROUTINES MAY BE CALLED FROM EDLCMD1
|
|
; EDLMES - ROUTINES MAY BE CALLED FROM EDLMES
|
|
;
|
|
; NOTES: THIS MODULE IS TO BE PREPPED BY SALUT WITH THE "PR" OPTIONS.
|
|
; LINK EDLIN+EDLCMD1+EDLCMD2+EDLMES+EDLPARSE
|
|
;
|
|
;
|
|
; REVISION HISTORY:
|
|
;
|
|
; AN000 VERSION DOS 4.00 - REVISIONS MADE RELATE TO THE FOLLOWING:
|
|
;
|
|
; - IMPLEMENT SYSPARSE
|
|
; - IMPLEMENT MESSAGE RETRIEVER
|
|
; - IMPLEMENT DBCS ENABLING
|
|
; - ENHANCED VIDEO SUPPORT
|
|
; - EXTENDED OPENS
|
|
; - SCROLLING ERROR
|
|
;
|
|
; COPYRIGHT: "MS DOS EDLIN UTILITY"
|
|
; "VERSION 4.00 (C) COPYRIGHT 1988 Microsoft"
|
|
;
|
|
;======================= END OF SPECIFICATIONS ===========================
|
|
|
|
include edlequ.asm
|
|
include syscall.inc
|
|
|
|
CODE SEGMENT PUBLIC
|
|
CODE ENDS
|
|
|
|
CONST SEGMENT PUBLIC WORD
|
|
CONST ENDS
|
|
|
|
cstack segment stack
|
|
cstack ends
|
|
|
|
DATA SEGMENT PUBLIC WORD
|
|
DATA ENDS
|
|
|
|
|
|
DG GROUP CODE,CONST,cstack,DATA
|
|
|
|
CONST SEGMENT PUBLIC WORD
|
|
extrn msg_crlf:abs,msg_lf:abs,qmes_ptr:byte,ask_ptr:byte
|
|
extrn bak:byte,$$$file:byte,delflg:byte,loadmod:byte,txt1:byte
|
|
extrn txt2:byte,memful_ptr:word
|
|
|
|
extrn Del_Bak_Ptr:byte ;an000;dms;
|
|
extrn cont_ptr:byte ;an000;dms:6/10/87
|
|
|
|
CONST ENDS
|
|
|
|
DATA SEGMENT PUBLIC WORD
|
|
extrn ParamCt:WORD
|
|
extrn current:word,pointer:word,start:word,endtxt:word
|
|
extrn wrt_handle:word,editbuf:byte,ext_ptr:word,qflg:byte
|
|
extrn temp_path:byte,line_num:word,line_flag:byte
|
|
extrn line_num_buf_ptr:byte,arg_buf:byte,arg_buf_ptr:word
|
|
extrn olddat:byte,oldlen:word,newlen:word,param1:word,param2:word
|
|
extrn srchflg:byte,srchmod:byte,comline:word,lstfnd:word,numpos:word
|
|
extrn lstnum:word,last_mem:word,srchcnt:word,amnt_req:word
|
|
|
|
extrn lc_adj:byte ;an000;dms:6/10/87
|
|
extrn continue:byte ;an000;dms:6/10/87
|
|
extrn pg_count:byte ;an000;dms:6/10/87
|
|
extrn Disp_Len:byte ;an000;dms;
|
|
extrn Disp_Width:byte ;an000;dms;
|
|
extrn lc_flag:byte ;an000;dms:6/10/87
|
|
|
|
ifdef DBCS
|
|
extrn lbtbl:dword
|
|
endif
|
|
|
|
DATA ENDS
|
|
|
|
CODE SEGMENT PUBLIC
|
|
|
|
ASSUME CS:DG,DS:DG,SS:CStack,ES:DG
|
|
|
|
public findlin,shownum,loadbuf,crlf,lf,abortcom,unquote
|
|
public kill_bl,make_caps,display,dispone,make_cntrl
|
|
public query,quit,scanln,delbak,scaneof,memerr
|
|
public fndfirst,fndnext,replace
|
|
ifdef DBCS
|
|
public testkanj
|
|
endif
|
|
extrn std_printf:near,command:near,chkrange:near,ComErr:NEAR
|
|
extrn Xerror:near
|
|
extrn display_message:near
|
|
|
|
|
|
FINDLIN:
|
|
|
|
; Inputs
|
|
; BX = Line number to be located in buffer (0 means last line+1)
|
|
; Outputs:
|
|
; DX = Actual line found
|
|
; DI = Pointer to start of line DX
|
|
; Zero set if BX = DX (if specified line found)
|
|
; AL,CX destroyed. No other registers affected.
|
|
|
|
MOV DX,[CURRENT]
|
|
MOV DI,[POINTER]
|
|
CMP BX,DX ; fast find. Current = requested
|
|
retz
|
|
JA FINDIT ; start scanning at current?
|
|
OR BX,BX ; special case of EOF?
|
|
JZ FINDIT ; yes
|
|
MOV DX,1 ; set up for scan at beginning
|
|
MOV DI,OFFSET DG:START
|
|
CMP BX,DX ; at beginning?
|
|
retz
|
|
FINDIT:
|
|
MOV CX,[ENDTXT] ; count of bytes in buffer
|
|
SUB CX,DI ; for scan
|
|
SCANLN:
|
|
MOV AL,10 ; LF is what we look for.
|
|
OR AL,AL ; Clear zero flag for JCXZ
|
|
FINLIN:
|
|
JCXZ RET4 ; at end? Yes, no skip.
|
|
REPNE SCASB ; find EOL
|
|
INC DX ; increment count
|
|
CMP BX,DX ; find correct line?
|
|
JNZ FINLIN ; no, try again.
|
|
RET4: return
|
|
|
|
; Inputs:
|
|
; BX = Line number to be displayed
|
|
; Function:
|
|
; Displays line number on terminal in 8-character
|
|
; format, suppressing leading zeros.
|
|
; AX, CX, DX destroyed. No other registers affected.
|
|
|
|
SHOWNUM:
|
|
mov dx,offset dg:line_num_buf_ptr
|
|
mov line_num,bx
|
|
MOV line_flag,"*"
|
|
CMP BX,[CURRENT]
|
|
JZ STARLIN
|
|
MOV line_flag," "
|
|
STARLIN:
|
|
call std_printf
|
|
ret5: return
|
|
|
|
|
|
DISPONE:
|
|
MOV DI,1
|
|
|
|
DISPLAY:
|
|
|
|
; Inputs:
|
|
; BX = Line number
|
|
; SI = Pointer to text buffer
|
|
; DI = No. of lines
|
|
; Function:
|
|
; Ouputs specified no. of line to terminal, each
|
|
; with leading line number.
|
|
; Outputs:
|
|
; BX = Last line output.
|
|
; All registers destroyed.
|
|
|
|
MOV CX,[ENDTXT]
|
|
SUB CX,SI
|
|
retz ; no lines to display
|
|
;=========================================================================
|
|
; Initialize screen size and line counts for use by display.
|
|
;
|
|
; Date : 6/10/87
|
|
;=========================================================================
|
|
|
|
push ax ;an000;save affected regs
|
|
|
|
mov al,dg:disp_len ;an000;length of video display
|
|
mov pg_count,al ;an000;init. screen size ctr.
|
|
|
|
pop ax ;an000;restore affected regs
|
|
|
|
;=========================================================================
|
|
|
|
mov dx,di ;number of lines to print
|
|
;
|
|
; CX is the number of bytes in the buffer
|
|
; dx is the number of lines to be output
|
|
;
|
|
DISPLN:
|
|
SaveReg <CX,DX>
|
|
CALL SHOWNUM
|
|
RestoreReg <DX,CX>
|
|
mov di,offset dg:arg_buf
|
|
;
|
|
; Copy chars until CR/LF or end of line hit
|
|
;
|
|
OUTLN:
|
|
LODSB
|
|
CMP DI,254+offset dg:arg_buf ; are we at end of buffer?
|
|
JAE StoreDone ; Yes, do NOT store
|
|
CMP AL," "
|
|
JAE SEND
|
|
CMP AL,10
|
|
JZ SEND
|
|
CMP AL,13
|
|
JZ SEND
|
|
CMP AL,9
|
|
JZ SEND
|
|
MOV AH,"^"
|
|
OR AL,40h
|
|
XCHG AL,AH
|
|
STOSW
|
|
JMP short StoreDone
|
|
SEND:
|
|
stosb
|
|
StoreDone:
|
|
CMP AL,10 ; perform copy until LF is seen
|
|
LOOPNZ OUTLN
|
|
;
|
|
; Make sure buffer ends with CRLF
|
|
;
|
|
cmp byte ptr [di-1],10
|
|
jz Terminate
|
|
;
|
|
; No LF seen. See if CR
|
|
;
|
|
cmp byte ptr [di-1],CR
|
|
jz StoreLF
|
|
mov al,CR
|
|
stosb
|
|
StoreLF:
|
|
mov al,10
|
|
stosb
|
|
Terminate:
|
|
mov byte ptr [di],0
|
|
|
|
call EDLIN_DISP_COUNT ;an000;determine lines printed
|
|
; DMS:6/10/87
|
|
push dx
|
|
mov dx,offset dg:arg_buf_ptr
|
|
call std_printf
|
|
pop dx
|
|
JCXZ ret7
|
|
INC BX
|
|
|
|
call EDLIN_PG_COUNT ;an000;adjust screen line count
|
|
; DMS:6/10/87
|
|
cmp lc_flag,false ;an000;continue DISPLAY?
|
|
; DMS:6/10/87
|
|
JNZ DISPLN
|
|
DEC BX
|
|
ret7: return
|
|
|
|
FNDFIRST:
|
|
MOV DI,1+OFFSET DG:TXT1
|
|
mov byte ptr[olddat],1 ;replace with old value if none new
|
|
CALL GETTEXT
|
|
OR AL,AL ;Reset zero flag in case CX is zero
|
|
JCXZ RET7
|
|
cmp al,1ah ;terminated with a ^Z ?
|
|
jne sj8
|
|
mov byte ptr[olddat],0 ;do not replace with old value
|
|
sj8:
|
|
MOV [OLDLEN],CX
|
|
XOR CX,CX
|
|
CMP AL,0DH
|
|
JZ SETBUF
|
|
CMP BYTE PTR [SRCHFLG],0
|
|
JZ NXTBUF
|
|
SETBUF:
|
|
DEC SI
|
|
NXTBUF:
|
|
MOV [COMLINE],SI
|
|
MOV DI,1+OFFSET DG:TXT2
|
|
CALL GETTEXT
|
|
CMP BYTE PTR [SRCHFLG],0
|
|
JNZ NOTREPL
|
|
CMP AL,0DH
|
|
JNZ HAVCHR
|
|
DEC SI
|
|
HAVCHR:
|
|
MOV [COMLINE],SI
|
|
NOTREPL:
|
|
MOV [NEWLEN],CX
|
|
MOV BX,[PARAM1]
|
|
OR BX,BX
|
|
JNZ CALLER
|
|
cmp byte ptr[srchmod],0
|
|
jne sj9
|
|
mov bx,1 ;start from line number 1
|
|
jmp short sj9a
|
|
sj9:
|
|
MOV BX,[CURRENT]
|
|
INC BX ;Default search and replace to current+1
|
|
sj9a:
|
|
CALL CHKRANGE
|
|
CALLER:
|
|
CALL FINDLIN
|
|
MOV [LSTFND],DI
|
|
MOV [NUMPOS],DI
|
|
MOV [LSTNUM],DX
|
|
MOV BX,[PARAM2]
|
|
CMP BX,1
|
|
SBB BX,-1 ;Decrement everything except zero
|
|
CALL FINDLIN
|
|
MOV CX,DI
|
|
SUB CX,[LSTFND]
|
|
OR AL,-1
|
|
JCXZ aret
|
|
CMP CX,[OLDLEN]
|
|
jae sj10
|
|
aret: return
|
|
sj10:
|
|
MOV [SRCHCNT],CX
|
|
|
|
FNDNEXT:
|
|
|
|
; Inputs:
|
|
; [TXT1+1] has string to search for
|
|
; [OLDLEN] has length of the string
|
|
; [LSTFND] has starting position of search in text buffer
|
|
; [LSTNUM] has line number which has [LSTFND]
|
|
; [SRCHCNT] has length to be searched
|
|
; [NUMPOS] has beginning of line which has [LSTFND]
|
|
; Outputs:
|
|
; Zero flag set if match found
|
|
; [LSTFND],[LSTNUM],[SRCHCNT] updated for continuing the search
|
|
; [NUMPOS] has beginning of line in which match was made
|
|
|
|
MOV AL,[TXT1+1]
|
|
MOV CX,[SRCHCNT]
|
|
MOV DI,[LSTFND]
|
|
SCAN:
|
|
OR DI,DI ;Clear zero flag in case CX=0
|
|
REPNE SCASB ;look for first byte of string
|
|
|
|
retnz ;return if you don't find
|
|
ifdef DBCS
|
|
call kanji_check ;see if the found byte is on a character boundary
|
|
jnz scan
|
|
endif
|
|
MOV DX,CX
|
|
MOV BX,DI ;Save search position
|
|
MOV CX,[OLDLEN]
|
|
DEC CX
|
|
MOV SI,2 + OFFSET DG:TXT1
|
|
CMP AL,AL ;Set zero flag in case CX=0
|
|
REPE CMPSB
|
|
MOV CX,DX
|
|
MOV DI,BX
|
|
JNZ SCAN
|
|
MOV [SRCHCNT],CX
|
|
MOV CX,DI
|
|
MOV [LSTFND],DI
|
|
MOV DI,[NUMPOS]
|
|
SUB CX,DI
|
|
MOV AL,10
|
|
MOV DX,[LSTNUM]
|
|
;Determine line number of match
|
|
GETLIN:
|
|
INC DX
|
|
MOV BX,DI
|
|
REPNE SCASB
|
|
JZ GETLIN
|
|
DEC DX
|
|
MOV [LSTNUM],DX
|
|
MOV [NUMPOS],BX
|
|
XOR AL,AL
|
|
return
|
|
|
|
ifdef DBCS
|
|
|
|
;Kanji_check idea is to scan backwards to the first
|
|
; character which can't be a kanji or part of one
|
|
; (.lt. DB_SP_LO) then scan forward to see if the
|
|
; current byte is on character boundary
|
|
;
|
|
;Output ZR <==> we're on a character boundary
|
|
; NZ <==> we're not on character boundary i.e. No Match
|
|
kanji_check:
|
|
push ax ;save search character
|
|
push di
|
|
dec di ;point to the character we found
|
|
mov si,di ;start searching bakwards from there
|
|
std
|
|
srch_loop:
|
|
lodsb
|
|
cmp al,DB_SP_LO
|
|
jae srch_loop
|
|
inc si ;point to first non-kanji
|
|
cld ;forward search
|
|
kan_loop:
|
|
cmp si,di ;are we at current byte?
|
|
jae passed_char ;if we are, or are passed it, exit
|
|
call next_char ;otherwise advance si to next char
|
|
jmp short kan_loop ;and loop
|
|
passed_char:
|
|
pop di
|
|
pop ax
|
|
ret
|
|
|
|
;Next_char si points to a character boundary
|
|
; advance si to point to the beginning of the next char
|
|
;
|
|
;
|
|
next_char:
|
|
push ax
|
|
lodsb
|
|
call testkanj
|
|
jz not_kanj
|
|
inc si
|
|
not_kanj:
|
|
pop ax
|
|
ret
|
|
|
|
;--------------------------------------------------------------------;
|
|
; TESTKANJ ~ FIND OUT IS THE BYTE IS A KANJI PREFIX ;
|
|
; ;
|
|
; entry: AL byte to test ;
|
|
; ;
|
|
; exit: NZ if lead byte ortherwise ZR ;
|
|
; ;
|
|
; modifies: AX ;
|
|
; ;
|
|
;--------------------------------------------------------------------;
|
|
|
|
testkanj:
|
|
push ax
|
|
xchg ah,al ;put byte in ah
|
|
push ds
|
|
push si
|
|
lds si,cs:[lbtbl] ;get pointer to lead byte table
|
|
ktlop:
|
|
lodsb ;direction flag should be OK
|
|
or al,al ;are we at the end of table?
|
|
jz notlead ;brif so
|
|
cmp al,ah ;is START RANGE > CHARACTER?
|
|
ja notlead ;brif so, not a lead character (carry clear)
|
|
lodsb ;get second range byte
|
|
cmp ah,al ;is CHARACTER > END RANGE
|
|
ja ktlop ;brif so, not a lead character (check next range)
|
|
or al,al ;make NZ
|
|
notl_exit:
|
|
pop si
|
|
pop ds
|
|
pop ax
|
|
ret
|
|
notlead:
|
|
cmp al,al
|
|
jmp notl_exit
|
|
|
|
endif
|
|
|
|
GETTEXT:
|
|
|
|
; Inputs:
|
|
; SI points into command line buffer
|
|
; DI points to result buffer
|
|
; Function:
|
|
; Moves [SI] to [DI] until ctrl-Z (1AH) or
|
|
; RETURN (0DH) is found. Termination char not moved.
|
|
; Outputs:
|
|
; AL = Termination character
|
|
; CX = No of characters moved.
|
|
; SI points one past termination character
|
|
; DI points to next free location
|
|
|
|
XOR CX,CX
|
|
|
|
GETIT:
|
|
LODSB
|
|
;-----------------------------------------------------------------------
|
|
cmp al,quote_char ;a quote character?
|
|
jne sj101 ;no, skip....
|
|
lodsb ;yes, get quoted character
|
|
call make_cntrl
|
|
jmp short sj102
|
|
;-----------------------------------------------------------------------
|
|
sj101:
|
|
CMP AL,1AH
|
|
JZ DEFCHK
|
|
sj102:
|
|
CMP AL,0DH
|
|
JZ DEFCHK
|
|
STOSB
|
|
INC CX
|
|
JMP SHORT GETIT
|
|
|
|
DEFCHK:
|
|
OR CX,CX
|
|
JZ OLDTXT
|
|
PUSH DI
|
|
SUB DI,CX
|
|
MOV BYTE PTR [DI-1],cl
|
|
POP DI
|
|
return
|
|
|
|
OLDTXT:
|
|
cmp byte ptr[olddat],1 ;replace with old text?
|
|
je sj11 ;yes...
|
|
mov byte ptr[di-1],cl ;zero text buffer char count
|
|
return
|
|
|
|
sj11:
|
|
MOV CL,BYTE PTR [DI-1]
|
|
ADD DI,CX
|
|
return
|
|
|
|
REPLACE:
|
|
|
|
; Inputs:
|
|
; CX = Length of new text
|
|
; DX = Length of original text
|
|
; SI = Pointer to new text
|
|
; DI = Pointer to old text in buffer
|
|
; Function:
|
|
; New text replaces old text in buffer and buffer
|
|
; size is adjusted. CX or DX may be zero.
|
|
; CX, SI, DI all destroyed. No other registers affected.
|
|
|
|
CMP CX,DX
|
|
JZ COPYIN
|
|
PUSH SI
|
|
PUSH DI
|
|
PUSH CX
|
|
MOV SI,DI
|
|
ADD SI,DX
|
|
ADD DI,CX
|
|
MOV AX,[ENDTXT]
|
|
SUB AX,DX
|
|
ADD AX,CX
|
|
CMP AX,[LAST_MEM]
|
|
JAE MEMERR
|
|
XCHG AX,[ENDTXT]
|
|
MOV CX,AX
|
|
SUB CX,SI
|
|
CMP SI,DI
|
|
JA DOMOV
|
|
ADD SI,CX
|
|
ADD DI,CX
|
|
STD
|
|
DOMOV:
|
|
INC CX
|
|
|
|
REP MOVSB
|
|
CLD
|
|
POP CX
|
|
POP DI
|
|
POP SI
|
|
COPYIN:
|
|
REP MOVSB
|
|
return
|
|
|
|
MEMERR:
|
|
MOV DX,OFFSET DG:MEMFUL_ptr
|
|
call std_printf
|
|
JMP COMMAND
|
|
|
|
|
|
LOADBUF:
|
|
MOV DI,2 + OFFSET DG:EDITBUF
|
|
MOV CX,255
|
|
MOV DX,-1
|
|
LOADLP:
|
|
LODSB
|
|
STOSB
|
|
INC DX
|
|
CMP AL,13
|
|
LOOPNZ LOADLP
|
|
MOV [EDITBUF+1],DL
|
|
retz
|
|
TRUNCLP:
|
|
LODSB
|
|
INC DX
|
|
CMP AL,13
|
|
JNZ TRUNCLP
|
|
DEC DI
|
|
STOSB
|
|
return
|
|
|
|
SCANEOF:
|
|
cmp [loadmod],0
|
|
je sj52
|
|
|
|
;----- Load till physical end of file
|
|
|
|
cmp cx,word ptr[amnt_req]
|
|
jb sj51
|
|
xor al,al
|
|
inc al ;reset zero flag
|
|
return
|
|
sj51:
|
|
jcxz sj51b
|
|
push di ;get rid of any ^Z at the end of the file
|
|
add di,cx
|
|
dec di ;points to last char
|
|
cmp byte ptr [di],1ah
|
|
pop di
|
|
jne sj51b
|
|
dec cx
|
|
sj51b:
|
|
xor al,al ;set zero flag
|
|
call check_end ;check that we have a CRLF pair at the end
|
|
return
|
|
|
|
;----- Load till first ^Z is found
|
|
|
|
sj52:
|
|
PUSH DI
|
|
PUSH CX
|
|
MOV AL,1AH
|
|
or cx,cx
|
|
jz not_found ;skip with zero flag set
|
|
REPNE SCASB ;Scan for end of file mark
|
|
jnz not_found
|
|
LAHF ;Save flags momentarily
|
|
inc cx ;include the ^Z
|
|
SAHF ;Restore flags
|
|
not_found:
|
|
mov di,cx ;not found at the end
|
|
POP CX
|
|
LAHF ;Save flags momentarily
|
|
SUB CX,DI ;Reduce byte count if EOF found
|
|
SAHF ;Restore flags
|
|
POP DI
|
|
call check_end ;check that we have a CRLF pair at the end
|
|
|
|
return
|
|
|
|
|
|
;-----------------------------------------------------------------------
|
|
; If the end of file was found, then check that the last character
|
|
; in the file is a LF. If not put a CRLF pair in.
|
|
|
|
check_end:
|
|
jnz not_end ;end was not reached
|
|
pushf ;save return flag
|
|
push di ;save pointer to buffer
|
|
add di,cx ;points to one past end on text
|
|
dec di ;points to last character
|
|
cmp di,offset dg:start
|
|
je check_no
|
|
cmp byte ptr[di],0ah ;is a LF the last character?
|
|
je check_done ;yes, exit
|
|
check_no:
|
|
mov byte ptr[di+1],0dh ;no, put a CR
|
|
inc cx ;one more char in text
|
|
mov byte ptr[di+2],0ah ;put a LF
|
|
inc cx ;another character at the end
|
|
check_done:
|
|
pop di
|
|
popf
|
|
not_end:
|
|
return
|
|
|
|
CRLF:
|
|
push dx
|
|
mov ax,msg_crlf
|
|
call display_message
|
|
pop dx
|
|
return
|
|
LF:
|
|
mov ax,msg_lf
|
|
jmp display_message
|
|
|
|
ABORTCOM:
|
|
MOV AX,CS
|
|
MOV DS,AX
|
|
MOV ES,AX
|
|
MOV AX,cstack
|
|
MOV SS,AX
|
|
MOV SP,STACK
|
|
STI
|
|
CALL CRLF
|
|
JMP COMMAND
|
|
|
|
DELBAK:
|
|
;Delete old backup file (.BAK)
|
|
|
|
MOV BYTE PTR [DELFLG],1
|
|
MOV DI,[EXT_PTR]
|
|
MOV SI,OFFSET DG:BAK
|
|
MOVSW
|
|
MOVSW
|
|
MOVSB
|
|
MOV AH,UNLINK
|
|
MOV DX,OFFSET DG:TEMP_PATH
|
|
INT 21H
|
|
; $if c ;error ? ;an000; dms;
|
|
JNC $$IF1
|
|
cmp ax,Access_Denied ;file read only? ;an000; dms;
|
|
; $if e ;yes ;an000; dms;
|
|
JNE $$IF2
|
|
mov bx,[Wrt_Handle] ;close .$$$ file ;an000; dms;
|
|
mov ah,Close ;close function ;an000; dms;
|
|
int 21h ;close it ;an000; dms;
|
|
|
|
mov di,[Ext_Ptr] ;point to extension ;an000; dms;
|
|
mov si,offset dg:$$$File ;point to .$$$ extension;an000; dms;
|
|
movsw ;get .$$$ extension ;an000; dms;
|
|
movsw ; ;an000; dms;
|
|
movsb ; ;an000; dms;
|
|
mov dx,offset dg:Temp_Path ;point to .$$$ file ;an000; dms;
|
|
mov ah,Unlink ;delete it ;an000; dms;
|
|
int 21h ; ;an000; dms;
|
|
|
|
mov di,[Ext_Ptr] ;point to extension ;an000; dms;
|
|
mov si,offset dg:BAK ;point to .BAK extension;an000; dms;
|
|
movsw ;get .BAK extension ;an000; dms;
|
|
movsw ; ;an000; dms;
|
|
movsb ; ;an000; dms;
|
|
mov dx,offset dg:Del_Bak_Ptr;point to error message ;an000; dms;
|
|
jmp Xerror ;display message & exit ;an000; dms;
|
|
; $endif
|
|
$$IF2:
|
|
; $endif
|
|
$$IF1:
|
|
|
|
MOV DI,[EXT_PTR]
|
|
MOV SI,OFFSET DG:$$$FILE
|
|
MOVSW
|
|
MOVSW
|
|
MOVSB
|
|
return
|
|
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Will scan buffer given pointed to by SI and get rid of quote
|
|
;characters, compressing the line and adjusting the length at the
|
|
;begining of the line.
|
|
; Preserves al registers except flags and AX .
|
|
|
|
unquote:
|
|
push cx
|
|
push di
|
|
push si
|
|
mov di,si
|
|
mov cl,[si-1] ;length of buffer
|
|
xor ch,ch
|
|
mov al,quote_char
|
|
cld
|
|
unq_loop:
|
|
jcxz unq_done ;no more chars in the buffer, exit
|
|
repnz scasb ;search for quote character
|
|
jnz unq_done ;none found, exit
|
|
push cx ;save chars left in buffer
|
|
push di ;save pointer to quoted character
|
|
push ax ;save quote character
|
|
mov al,byte ptr[di] ;get quoted character
|
|
call make_cntrl
|
|
mov byte ptr[di],al
|
|
pop ax ;restore quote character
|
|
mov si,di
|
|
dec di ;points to the quote character
|
|
inc cx ;include the carriage return also
|
|
rep movsb ;compact line
|
|
pop di ;now points to after quoted character
|
|
pop cx
|
|
jcxz sj13 ;if quote char was last of line do not adjust
|
|
dec cx ;one less char left in the buffer
|
|
sj13: pop si
|
|
dec byte ptr[si-1] ;one less character in total buffer count also
|
|
push si
|
|
jmp short unq_loop
|
|
|
|
unq_done:
|
|
pop si
|
|
pop di
|
|
pop cx
|
|
return
|
|
|
|
|
|
;-----------------------------------------------------------------------;
|
|
; Convert the character in AL to the corresponding control
|
|
; character. AL has to be between @ and _ to be converted. That is,
|
|
; it has to be a capital letter. All other letters are left unchanged.
|
|
|
|
make_cntrl:
|
|
push ax
|
|
and ax,11100000b
|
|
cmp ax,01000000b
|
|
pop ax
|
|
jne sj14
|
|
and ax,00011111b
|
|
sj14:
|
|
return
|
|
|
|
|
|
;---- Kill spaces in buffer --------------------------------------------;
|
|
;=========================================================================
|
|
; kill_bl : Parses over spaces in a buffer.
|
|
;
|
|
; Date : 6/10/86
|
|
;=========================================================================
|
|
kill_bl:
|
|
|
|
push bx ;an000;save affected reg.
|
|
kill_bl_cont:
|
|
|
|
lodsb ;get rid of blanks
|
|
cmp al,9
|
|
je kill_bl_cont ;an000;it is a tab
|
|
|
|
cmp al,10
|
|
je kill_bl_cont ;an000;if LF
|
|
|
|
cmp al,' '
|
|
je kill_bl_cont ;an000;we have a space
|
|
|
|
ifdef DBCS ;an000;is this a kanji assembly
|
|
call testkanj ;an000;do we have a dbcs lead byte
|
|
; $if nz ;an000;yes, we have a lead byte
|
|
JZ $$IF5
|
|
cmp al,DB_SP_HI ;an000;is it DB_SP_HI
|
|
; $if z ;an000;it is DB_SP_HI
|
|
JNZ $$IF6
|
|
mov bl,ds:[si] ;an000;set up for compare
|
|
cmp bl,DB_SP_LO ;an000;is it DB_SP_LO
|
|
; $if z ;an000;we have an asian blank
|
|
JNZ $$IF7
|
|
lodsb ;an000;skip byte containing 81h
|
|
jmp kill_bl_cont
|
|
; $endif ;an000;
|
|
$$IF7:
|
|
; $endif ;an000;fall through no delim
|
|
$$IF6:
|
|
; found
|
|
; $endif ;an000;end test for dbcs lead byte
|
|
$$IF5:
|
|
endif ;an000;end conditional assembly
|
|
|
|
pop bx ;an000;restore affected reg.
|
|
return
|
|
|
|
;----- Capitalize the character in AL ----------------------------------;
|
|
; ;
|
|
; Input: ;
|
|
; ;
|
|
; AL contains a character to capitalize ;
|
|
; ;
|
|
; Output: ;
|
|
; ;
|
|
; AL contains a capitalized character ;
|
|
; ;
|
|
;-----------------------------------------------------------------------;
|
|
|
|
MAKE_CAPS:
|
|
CMP AL,"a"
|
|
JB CAPS1
|
|
CMP AL,"z"
|
|
ifdef DBCS
|
|
JA CAPS1 ; M003 MSKK TAR 476, kana chars
|
|
else
|
|
JG CAPS1
|
|
endif
|
|
AND AL,0DFH
|
|
CAPS1:
|
|
return
|
|
|
|
QUIT:
|
|
CMP ParamCt,1
|
|
JZ Quit1
|
|
CERR: JMP ComErr
|
|
Quit1: CMP Param1,0
|
|
JNZ CERR
|
|
MOV DX,OFFSET DG:QMES_ptr
|
|
call std_printf
|
|
|
|
IFDEF DBCS
|
|
CALL TESTKANJ
|
|
JZ ASCII
|
|
MOV AX, (STD_CON_INPUT_FLUSH SHL 8) + 0
|
|
INT 21H ; Eat the trailing byte.
|
|
JMP CRLF
|
|
ASCII:
|
|
ENDIF
|
|
;=========================================================================
|
|
; We are invoking the VAL_YN proc here. This will replace the
|
|
; method of Y/N validation used prior to DOS 4.00.
|
|
;
|
|
; Date : 6/10/87
|
|
;=========================================================================
|
|
|
|
call val_yn ;an000;pass Y/N byte in AL to macro
|
|
cmp ax,yes ;an000;did we return a Y
|
|
jz NoCRLF ;an000; dms; close the file
|
|
cmp ax,no ;an000; dms; return N?
|
|
; $if ne ;an000; dms; neither N or Y - reprompt
|
|
JE $$IF11
|
|
call crlf ; spit out crlf
|
|
jmp Quit1 ;an000; dms; reprompt
|
|
; $endif ;an000; dms;
|
|
$$IF11:
|
|
call crlf ; spit out CRLF
|
|
return ;an000; dms;
|
|
|
|
;=========================================================================
|
|
; End of Y/N validation check for qmes_ptr
|
|
;=========================================================================
|
|
|
|
NOCRLF:
|
|
MOV BX,[WRT_HANDLE]
|
|
MOV AH,CLOSE
|
|
INT 21H
|
|
MOV DX,OFFSET DG:TEMP_PATH
|
|
MOV AH,UNLINK
|
|
INT 21H
|
|
mov ah,exit
|
|
xor al,al
|
|
INT 21H
|
|
|
|
QUERY:
|
|
TEST BYTE PTR [QFLG],-1
|
|
retz
|
|
MOV DX,OFFSET DG:ASK_ptr
|
|
call std_printf
|
|
PUSH AX
|
|
CALL CRLF
|
|
POP AX
|
|
IFDEF DBCS
|
|
CALL TESTKANJ
|
|
JZ ASCII1
|
|
PUSH AX
|
|
MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
|
|
INT 21H ;Eat the trailing byte
|
|
XOR AX,AX
|
|
INC AX ; non zero flag
|
|
POP AX
|
|
return
|
|
ASCII1:
|
|
ENDIF
|
|
CMP AL,13 ;Carriage return means yes
|
|
retz
|
|
;=========================================================================
|
|
; We are invoking the VAL_YN proc here. This will replace the
|
|
; method of Y/N validation used prior to DOS 4.00.
|
|
; This invocation of val_yn will return ZR if Y is found, otherwise
|
|
; it will return NZ.
|
|
;
|
|
; Date : 6/10/87
|
|
;=========================================================================
|
|
|
|
call val_yn ;an000;pass Y/N byte in AL to macro
|
|
cmp ax,yes ;an000;did we return a Y
|
|
je Query_Exit ;an000; dms; exit Y/N validation
|
|
cmp ax,no ;an000; dms; N response?
|
|
jne Query ;an000; dms; no - reprompt user
|
|
cmp ax,yes ;an000; dms; must have N response - force
|
|
; NZ flag
|
|
Query_Exit:
|
|
|
|
|
|
;=========================================================================
|
|
; End of Y/N validation check for ask_ptr
|
|
;=========================================================================
|
|
|
|
return
|
|
|
|
;=========================================================================
|
|
; EDLIN_DISP_COUNT: This routine will determine the number of lines
|
|
; actually displayed to the screen. Lines displayed to
|
|
; the screen for one EDLIN line printed will be calculated
|
|
; by the following formula:
|
|
;
|
|
; LINES_PRINTED = (LINE_LEN + 10) / SCREEN_WIDTH
|
|
;
|
|
; LINES_PRINTED - Actual number of lines printed on screen
|
|
; for one EDLIN line. If LINES_PRINTED has
|
|
; a remainder, it will be rounded up.
|
|
;
|
|
; LINE_LEN - The length, in bytes, of the EDLIN line
|
|
; printed.
|
|
;
|
|
; SCREEN_WIDTH - The width in bytes of the current display.
|
|
;
|
|
; Inputs : DI - offset into buffer containing line printed
|
|
; DISP_WIDTH - width of current video output
|
|
;
|
|
; Outputs: LC_ADJ - factor to adjust line counter by
|
|
;
|
|
; Date : 6/10/87
|
|
;=========================================================================
|
|
|
|
EDLIN_DISP_COUNT proc near ;an000;lines printed
|
|
|
|
push dx ;an000;save affected regs
|
|
push di ;an000;
|
|
push ax ;an000;
|
|
push bx ;an000;
|
|
push cx ;an000;
|
|
|
|
mov bx,offset dg:arg_buf ;an000;arg_buf holds line
|
|
; printed
|
|
mov ax,di ;an000;where print line ends
|
|
sub ax,bx ;an000;diff = line's length
|
|
add ax,10 ;an000;adjust for leading blks
|
|
mov cl,dg:disp_width ;an000;set up for division
|
|
div cl ;an000;divide AX by the
|
|
; width of the console
|
|
cmp ah,0 ;an000;see if a remainder
|
|
; $if nz ;an000;if a remainder
|
|
JZ $$IF13
|
|
add al,1 ;an000;increment AL 1
|
|
; to round upward
|
|
; $endif ;an000;
|
|
$$IF13:
|
|
|
|
mov lc_adj,al ;an000;number of lines printed
|
|
; on console
|
|
pop cx ;an000;restore affected regs
|
|
pop bx ;an000;
|
|
pop ax ;an000;
|
|
pop di ;an000;
|
|
pop dx ;an000;
|
|
|
|
ret ;an000;return to caller
|
|
|
|
EDLIN_DISP_COUNT endp ;an000;end proc
|
|
|
|
;=========================================================================
|
|
; EDLIN_PG_COUNT : This routine determines whether or not we will continue
|
|
; displaying text lines based on the count of lines that
|
|
; can be output to the current video screen.
|
|
;
|
|
; Inputs : LC_ADJ - adjustment factor for number of lines printed
|
|
; PG_COUNT - number of lines remaining on current video
|
|
; display
|
|
; DX - holds the total number of lines to print
|
|
; CONTINUE - signals if the user wants to continue
|
|
; printing lines.
|
|
;
|
|
; Outputs: LC_FLAG - used to signal completion of print
|
|
;
|
|
; Date : 6/10/87
|
|
;=========================================================================
|
|
|
|
EDLIN_PG_COUNT proc near ;an000;track remaining lines
|
|
|
|
push ax ;an000;save affected regs
|
|
|
|
mov lc_flag,true ;an000;init. flag to signal
|
|
; continue printing
|
|
|
|
mov al,pg_count ;an000;set up for page adj.
|
|
cmp al,lc_adj ;an000;see if we are at end
|
|
; $if be ;an000
|
|
JNBE $$IF15
|
|
mov pg_count,0 ;an000;set pg_count to 0
|
|
; $else
|
|
JMP SHORT $$EN15
|
|
$$IF15:
|
|
sub al,lc_adj ;an000;adjust number of lines
|
|
mov pg_count,al ;an000;save remaining line ct.
|
|
; $endif ;an000;
|
|
$$EN15:
|
|
|
|
dec dx ;an000;decrease total number
|
|
; of lines to print by 1
|
|
; $if nz ;an000;more lines to print
|
|
JZ $$IF18
|
|
cmp pg_count,0 ;an000;have we printed screen
|
|
; $if be ;an000;we have printed screen
|
|
JNBE $$IF19
|
|
call EDLIN_PG_PROMPT ;an000;prompt the user to
|
|
; "Continue(Y/N)?"
|
|
cmp continue,true ;an000;did user say continue
|
|
; $if z ;an000;continue
|
|
JNZ $$IF20
|
|
mov al,dg:disp_len ;an000;begin init of screen
|
|
; dec al ;an000; length
|
|
mov pg_count,al ;an000;
|
|
; $else ;an000;do not continue
|
|
JMP SHORT $$EN20
|
|
$$IF20:
|
|
mov lc_flag,false ;an000;signal no more to print
|
|
; $endif ;an000;
|
|
$$EN20:
|
|
; $endif ;an000;
|
|
$$IF19:
|
|
; $else ;an000;total lines printed
|
|
JMP SHORT $$EN18
|
|
$$IF18:
|
|
mov lc_flag,false ;an000;signal no more to print
|
|
; $endif ;an000;
|
|
$$EN18:
|
|
|
|
pop ax ;an000;restore affected regs
|
|
|
|
ret ;an000;return to caller
|
|
|
|
EDLIN_PG_COUNT endp ;an000;end procedure
|
|
|
|
;=========================================================================
|
|
; EDLIN_PG_PROMPT : This routine prompts the user as to whether or not to
|
|
; continue printing lines to the video display, if lines
|
|
; are still present for printing.
|
|
;
|
|
; Inputs : none
|
|
;
|
|
; Outputs: CONTINUE - flag that signals other routines whether or
|
|
; not to continue printing.
|
|
;
|
|
; Date : 6/10/87
|
|
;=========================================================================
|
|
|
|
EDLIN_PG_PROMPT proc near ;an000;ask user to continue?
|
|
|
|
push dx ;an000;save affected regs.
|
|
push ax ;an000;
|
|
|
|
EPP_Reprompt:
|
|
|
|
mov dx,offset dg:cont_ptr ;an000;point to Continue msg.
|
|
call std_printf ;an000;invoke message ret.
|
|
|
|
push ax ;an000;save affected regs.
|
|
call crlf ;an000;send crlf
|
|
pop ax ;an000;restore affected regs.
|
|
|
|
call val_yn ;an000;Y/N validation
|
|
|
|
cmp ax,yes ;an000;did we have a Y
|
|
jz EPP_True_Exit ;an000;we had a Y
|
|
cmp ax,no ;an000;did we have a N
|
|
jz EPP_False_Exit ;an000;yes
|
|
jmp EPP_Reprompt ;an000;neither Y or N - reprompt
|
|
|
|
EPP_True_Exit:
|
|
|
|
mov Continue,True ;an000;flag Y found
|
|
jmp short EPP_Exit ;an000;exit routine
|
|
|
|
EPP_False_Exit:
|
|
|
|
mov Continue,False ;an000;flag N found
|
|
|
|
EPP_Exit:
|
|
|
|
pop ax ;an000;restore affected regs.
|
|
pop dx ;an000;
|
|
|
|
ret ;an000;return to caller
|
|
|
|
EDLIN_PG_PROMPT endp ;an000;end procedure
|
|
|
|
;=========================================================================
|
|
; val_yn: This proc validates a Y/N response entered by the user. The
|
|
; routine uses the new functionality of "GET EXTENDED COUNTRY
|
|
; INFORMATION" being implemented in DOS 4.00.
|
|
;
|
|
; Inputs : AL - character to be validated for Y/N response
|
|
;
|
|
; Outputs: AX - 00h = "N"o
|
|
; - 01h = "Y"es
|
|
;=========================================================================
|
|
|
|
val_yn proc near ;an000;validate Y/N response
|
|
|
|
push dx ;an000;save affected registers
|
|
push cx ;an000;
|
|
push bx ;an000;
|
|
|
|
mov dl,al ;an000;character to be checked for Y/N
|
|
mov ah,GetExtCntry ;an000;get extended country information
|
|
mov al,yn_chk ;an000;perform Y/N checking
|
|
mov cx,max_len ;an000;max. len. of Y/N char.
|
|
int 21h ;an000;invoke function
|
|
|
|
pop bx ;an000;restore affected registers
|
|
pop cx ;an000;
|
|
pop dx ;an000;
|
|
|
|
ret ;an000;return to caller
|
|
|
|
val_yn endp ;an000;end proc
|
|
|
|
|
|
|
|
code ends
|
|
end
|
|
|