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

📄 macro2.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;------------------------ End of DBCS 2/13/KK
 ENDIF                                  ;AN000;
	MOV     AL,DS:[SI-1]            ; last char to match
	call    PathChrCmp              ; did we end on a path char? (root)
	JZ      DoSplice                ; yes, no current dir here.
Pathline:                               ; 2/13/KK
	CMP     BYTE PTR ES:[DI],0      ; end at NUL?
	JZ      DoSplice
	INC     DI                      ; point to after current path char
	MOV     Curr_Dir_End,DI         ; point to correct spot ;smr;SS Override
;
; Splice the result.
;
DoSplice:
	Context DS                      ; back to DOSDATA
	MOV     SI,wfp_Start            ; point to beginning of string
	XOR     CX,CX
	TEST    fSplice,-1
	JZ      SkipSplice
	CALL    Splice                  ; replaces in place.
SkipSplice:
	ASSUME  DS:NOTHING
;
; The final thing is to assure ourselves that a FATREAD is done on the local
; device.
;
	Context DS
	LES     DI,ThisCDS              ; point to correct drive
	TEST    ES:[DI].curdir_flags,curdir_isnet
	JNZ     Done                    ; net, no fatread necessary (retnz)
	JCXZ    Done
	EnterCrit   critDisk
	invoke  FatRead_CDS
	LeaveCrit   critDisk
	MOV     AL,error_path_not_found ; Set up for possible bad path error
Done:   return                          ; any errors in carry flag.
EndProc TransPath

BREAK <Canonicalize - copy a path and remove . and .. entries>

;
;   Canonicalize - copy path removing . and .. entries.
;
;   Inputs:     DS:SI - point to ASCIZ string path
;               ES:DI - point to buffer
;               BX - backup limit (offset from ES) points to slash
;               BP - end of buffer
;   Outputs:    Carry Set - invalid path specification: too many .., bad
;                   syntax, etc.
;               Carry Clear -
;                   DS:DI - advanced to end of string
;                   ES:DI - advanced to end of canonicalized form after nul
;   Registers modified: AX CX DX (in addition to those above)

Procedure Canonicalize,NEAR
	ASSUME  CS:DOSCODE,SS:DOSDATA
;
; We copy all leading path separators.
;
	LODSB                           ;   while (PathChr (*s))
	call    PathChrCmp
 IFDEF  DBCS
	JNZ     CanonDec0               ; 2/19/KK
 ELSE
	JNZ     CanonDec
 ENDIF
	CMP     DI,BP                   ;       if (d > dlim)
	JAE     CanonBad                ;           goto error;
	STOSB
	JMP     Canonicalize            ;           *d++ = *s++;
 IFDEF  DBCS                            ;AN000;
CanonDec0:                              ;AN000; 2/19/KK
;       mov     cs:Temp_Var,di          ;AN000; 3/31/KK
 ENDIF                                  ;AN000;
CanonDec:
	DEC     SI
;
; Main canonicalization loop.  We come here with DS:SI pointing to a textual
; component (no leading path separators) and ES:DI being the destination
; buffer.
;
CanonLoop:
;
; If we are at the end of the source string, then we need to check to see that
; a potential drive specifier is correctly terminated with a path sep char.
; Otherwise, do nothing
;
	XOR     AX,AX
	CMP     [SI],AL                 ;       if (*s == 0) {
	JNZ     DoComponent
 IFDEF  DBCS                            ;AN000;
	call    chk_last_colon          ;AN000; 2/18/KK
 ELSE                                   ;AN000;
	CMP     BYTE PTR ES:[DI-1],':'  ;           if (d[-1] == ':')
 ENDIF                                  ;AN000;
	JNZ     DoTerminate
	MOV     AL,'\'                  ;               *d++ = '\';
	STOSB
	MOV     AL,AH
DoTerminate:
	STOSB                           ;           *d++ = 0;
	CLC                             ;           return (0);
	return
 IFDEF  DBCS                            ;AN000;
;---------------- Start of DBCS 2/18/KK
chk_last_colon  proc                    ;AN000;
	push    si                      ;AN000;
	push    ax                      ;AN000;
	push    bx                      ;AN000;
	mov     si,[WFP_START]          ;AN000;;PTM. for cd ..  use beginning of buf;smr;SS Override
	cmp     si,di                   ;AN000;; no data stored ?
	jb      CLC02                   ;AN000;;PTM. for cd ..
	inc     si                      ;AN000;; make NZ flag
	JMP     SHORT CLC09             ;AN000;
CLC02:                                  ;AN000;
	mov     bx,di                   ;AN000;
	dec     bx                      ;AN000;
CLC_lop:                                ;AN000;
	cmp     si,bx                   ;AN000;
	jb      CLC00                   ;AN000;
	jne     CLC09                   ;AN000;
CLC01:                                  ;AN000;
	CMP     BYTE PTR ES:[DI-1],':'  ;AN000;;           if (d[-1] == ':')
	jmp     CLC09                   ;AN000;
CLC00:                                  ;AN000;
	mov     al,es:[si]              ;AN000;
	inc     si                      ;AN000;
	call    TestKanj                ;AN000;
	je      CLC_lop                 ;AN000;
	inc     si                      ;AN000;
	jmp     CLC_lop                 ;AN000;
CLC09:                                  ;AN000;
	pop     bx                      ;AN000;
	pop     ax                      ;AN000;
	pop     si                      ;AN000;
	ret                             ;AN000;
chk_last_colon  endp                    ;AN000;
;---------------- Endt of DBCS 2/18/KK
 ENDIF                                  ;AN000;

CanonBad:
	CALL    ScanPathChar            ; check for path chars in rest of string
	MOV     AL,error_path_not_found ; Set up for bad path error
	JZ      PathEnc                 ; path character encountered in string
	MOV     AL,error_file_not_found ; Set bad file error
PathEnc:
	STC
	return
;
; We have a textual component that we must copy.  We uppercase it and truncate
; it to 8.3
;
DoComponent:                            ;           }
	CALL    CopyComponent           ;       if (!CopyComponent (s, d))
	retc                            ;           return (-1);
;
; We special case the . and .. cases.  These will be backed up.
;
	CMP     WORD PTR ES:[DI],'.' + (0 SHL 8)
	JZ      Skip1
	CMP     WORD PTR ES:[DI],'..'
	JNZ     CanonNormal
	DEC     DI                      ;           d--;
Skip1:  CALL    SkipBack                ;           SkipBack ();
	MOV     AL,error_path_not_found ; Set up for possible bad path error
	retc
	JMP     short CanonPath         ;           }
;
; We have a normal path.  Advance destination pointer over it.
;
CanonNormal:                            ;       else
	ADD     DI,CX                   ;           d += ct;
;
; We have successfully copied a component.  We are now pointing at a path
; sep char or are pointing at a nul or are pointing at something else.
; If we point at something else, then we have an error.
;
CanonPath:
	CALL    PathSep
	JNZ     CanonBad                ; something else...
;
; Copy the first path char we see.
;
	LODSB                           ; get the char
	call    PathChrCmp              ; is it path char?
	JNZ     CanonDec                ; no, go test for nul
	CMP     DI,BP                   ; beyond buffer end?
	JAE     CanonBad                ; yep, error.
	STOSB                           ; copy the one byte
;
; Skip all remaining path chars
;
CanonPathLoop:
	LODSB                           ; get next byte
	call    PathChrCmp              ; path char again?
	JZ      CanonPathLoop           ; yep, grab another
	DEC     SI                      ; back up
	JMP     CanonLoop               ; go copy component
EndProc Canonicalize

BREAK <PathSep - determine if char is a path separator>

;
;   PathSep - look at DS:SI and see if char is / \ or NUL
;   Inputs:     DS:SI - point to a char
;   Outputs:    AL has char from DS:SI (/ => \)
;               Zero set if AL is / \ or NUL
;               Zero reset otherwise
;   Registers modified: AL

Procedure   PathSep,NEAR
	ASSUME  CS:DOSCODE,SS:DOSDATA
	MOV     AL,[SI]                 ; get the character
	entry   PathSepGotCh            ; already have character
	OR      AL,AL                   ; test for zero
	retz                            ; return if equal to zero (NUL)
	call    PathChrCmp              ; check for path character
	return                          ; and return HIS determination
EndProc PathSep

BREAK <SkipBack - move backwards to a path separator>

;
;   SkipBack - look at ES:DI and backup until it points to a / \
;   Inputs:     ES:DI - point to a char
;               BX has current directory back up limit (point to a / \)
;   Outputs:    ES:DI backed up to point to a path char
;               AL has char from output ES:DI (path sep if carry clear)
;               Carry set if illegal backup
;               Carry Clear if ok
;   Registers modified: DI,AL

Procedure   SkipBack,NEAR
	ASSUME  CS:DOSCODE,SS:DOSDATA
 IFDEF  DBCS                   ;AN000;
;-------------------------- Start of DBCS 2/13/KK
	PUSH    DS              ;AN000;
	PUSH    SI              ;AN000;
	PUSH    CX              ;AN000;
	PUSH    ES              ;AN000;
	POP     DS              ;AN000;
	MOV     SI,BX           ;AN000;; DS:SI -> start of ES:DI string
	MOV     CX,DI           ;AN000;; Limit of forward scan is input DI
	MOV     AL,[SI]         ;AN000;
	call    PathChrCmp      ;AN000;
	JNZ     SkipBadP        ;AN000;; Backup limit MUST be path char
	CMP     DI,BX           ;AN000;
	JBE     SkipBadP        ;AN000;
	MOV     DI,BX           ;AN000;; Init backup point to backup limit
Skiplp:                         ;AN000;
	CMP     SI,CX           ;AN000;
	JAE     SkipOK          ;AN000;; Done, DI is correct backup point
	LODSB                   ;AN000;
	call    TestKanj        ;AN000;
	jz      Notkanjv        ;AN000;
	lodsb                   ;AN000;; Skip over second kanji byte
	JMP     Skiplp          ;AN000;
NotKanjv:                       ;AN000;
	call    PathChrCmp      ;AN000;
	JNZ     Skiplp          ;AN000;; New backup point
	MOV     DI,SI           ;AN000;; DI point to path sep
	DEC     DI              ;AN000;
	jmp     Skiplp          ;AN000;
SkipOK:                         ;AN000;
	MOV     AL,ES:[DI]      ;AN000;; Set output AL
	CLC                     ;AN000;; return (0);
	POP     CX              ;AN000;
	POP     SI              ;AN000;
	POP     DS              ;AN000;
	return                  ;AN000;
				;AN000;
SkipBadP:                       ;AN000;
	POP     CX              ;AN000;
	POP     SI              ;AN000;
	POP     DS              ;AN000;
;-------------------------- End of DBCS 2/13/KK
 ELSE                           ;AN000;
	CMP     DI,BX                   ;   while (TRUE) {
	JB      SkipBad                 ;       if (d < dlim)
	DEC     DI                      ;           goto err;
	MOV     AL,ES:[DI]              ;       if (pathchr (*--d))
	call    PathChrCmp              ;           break;
	JNZ     SkipBack                ;       }
	CLC                             ;   return (0);
	return                          ;
 ENDIF                                  ;AN000;
SkipBad:                                ;err:
	MOV     AL,error_path_not_found ; bad path error
	STC                             ;   return (-1);
	return                          ;
EndProc SkipBack

Break <CopyComponent - copy out a file path component>

;
;   CopyComponent - copy a file component from a path string (DS:SI) into ES:DI
;
;   Inputs:     DS:SI - source path
;               ES:DI - destination
;               ES:BP - end of buffer
;   Outputs:    Carry Set - too long
;               Carry Clear - DS:SI moved past component
;                   CX has length of destination
;   Registers modified: AX,CX,DX

Procedure   CopyComponent,NEAR
	ASSUME  CS:DOSCODE,SS:DOSDATA
CopyBP      EQU     WORD PTR [BP]
CopyD       EQU     DWORD PTR [BP+2]
CopyDoff    EQU     WORD PTR [BP+2]
CopyS       EQU     DWORD PTR [BP+6]
CopySoff    EQU     WORD PTR [BP+6]
CopyTemp    EQU     BYTE PTR [BP+10]
	SUB     SP,14                   ; room for temp buffer
	SAVE    <DS,SI,ES,DI,BP>
	MOV     BP,SP
	MOV     AH,'.'
	LODSB
	STOSB
	CMP     AL,AH                   ;   if ((*d++=*s++) == '.') {
	JNZ     NormalComp
	CALL    PathSep                 ;       if (!pathsep(*s))
	JZ      NulTerm
TryTwoDot:
	LODSB                           ;           if ((*d++=*s++) != '.'
	STOSB

⌨️ 快捷键说明

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