home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-386-Vol-2of3.iso
/
b
/
bm_rm.zip
/
FEXPAND.ASM
next >
Wrap
Assembly Source File
|
1989-08-02
|
8KB
|
256 lines
;fexpand() - Convert a relative pathname to a fully qualified name.
;
;Syntax: int fexpand (char *relname, char *absname);
;
;relname = ASCIIZ relative pathname to expand
;absname = ASCIIZ absolute pathname with drive I.D. and full directory path
;
;Return value: 0 = no errors detected (does not necessarily mean path is OK)
; 3 = invalid directory path
; 15 = invalid drive I.D.
;
;Letters in the pathname will be capitalized, and any occurrances of '/' will
;be converted to '\'. If the drive I.D. is missing, the current default
;drive I.D. will be prepended. Occurrances of '.' and '..' will be expanded
;appropriately. Directory and file names will be truncated to 8 characters,
;file name extensions to 3 characters. The absolute pathname will not be
;allowed to exceed 80 characters, including the final zero byte.
;
;This function is similar to the undocumented DOS call INT 21H, AH = 60H,
;but it may be used with DOS 2.0 and up whereas the DOS call was only
;introduced with DOS 3.0.
;
;Copyright (C) 1989 Brian B. McGuinness
; 15 Kevin Road
; Scotch Plains, NJ 07076
;
;This function is free software; you can redistribute it and/or modify it under
;the terms of the GNU General Public License as published by the Free Software
;Foundation; either version 1, or (at your option) any later version.
;
;This function is distributed in the hope that it will be useful, but WITHOUT
;ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
;FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
;details.
;
;You should have received a copy of the GNU General Public License along with
;this function; if not, write to the Free Software Foundation, Inc., 675 Mass
;Ave, Cambridge, MA 02139, USA.
;
;Version 1.0 July, 1989 MASM 5.1
DOSSEG
.MODEL small,C
.DATA
outchars dw ? ;Number of chars in output string so far.
;While we are in the process of copying a directory name, file name, or file
;name extension from the relative pathname to the absolute pathname, trunc
;tells us how many more characters to copy before we start truncating.
trunc db ?
.CODE
fexpand proc uses bx cx ds es si di, relname:ptr, absname:ptr
;Set up pointers to input and output buffers.
if @DataSize
lds si,relname ;Far pointers
les di,absname
else
mov si,relname ;Near pointers
mov di,absname
push ds
pop es
endif
cld
or [si], byte ptr 0 ;If input string is empty, quit.
jnz @F
jmp eos
@@: mov trunc,8 ;Initial name will be directory or file name.
;If drive I.D. is given in the input string, copy it to the output string.
;Otherwise write the default drive I.D. to the output string.
cmp [si+1], byte ptr ':' ;Look for drive I.D.
jne @F
lodsw ;Found it: capitalize and copy it.
and al,223
stosw
jmp short start
@@: mov ah,19H ;Get default drive ID.
int 21H
add al,'A' ;Write it to the output string.
mov ah,':'
stosw
;If next character is not a path delimiter, we must insert the current default
;directory name here.
start: lodsb
call fexchar
cmp al,'\'
jne nodir
;Starting directory was specified.
stosb ;Save the '\'.
mov outchars,3 ;3 chars in output buffer so far.
jmp short rdloop
;Starting directory was not specified, so insert default directory into output.
nodir: dec si ;We'll re-read this char later.
mov al,'\' ;Store leading backslash.
stosb
mov bx,absname ;Get drive I.D. to find default path for.
mov dl,[bx]
sub dl,'@'
push si
mov si,di
mov ah,47H ;Get path in output buffer.
int 21H
pop si
jnc @F ;If we can't get it, the drive ID is invalid.
mov ax,0FH
jmp endstr
@@: mov di,absname ;Find the end of the output string.
mov outchars,0
xor al,al ;String ends with a zero byte.
mov cx,80
repne scasb
mov cx,di
sub cx,absname
mov outchars,cx
dec di
gotend: cmp [di-1], byte ptr '\' ;If appropriate, append '\' to directory path.
je rdloop
cmp [si], byte ptr 0
jne @f
jmp eos
@@: mov al,'\'
stosb
inc outchars
;-------------------------------------------------------------------------------
;Expand and copy the rest of the directory path.
rdloop: lodsb ;Get next character and normalize it.
call fexchar
or al,al ;Watch for end of string.
jnz @F
jmp eos
@@: cmp al,'\' ;Watch for path delimiters.
jne @F
mov trunc,9 ;New name, so reset truncation counter.
jmp short store
@@: cmp al,'.' ;Watch for '.' and '..' entries.
jne store
;If it isn't the first char, and it doesn't follow a colon or path delimiter,
;it prefixes a file name extension so reset the truncation counter and copy it.
cmp [di-1], byte ptr ':'
je @F
cmp [di-1], byte ptr '\'
je @F
mov trunc,4
jmp short store
@@: lodsb ;Get char following the dot.
call fexchar
or al,al ;Watch out for end of string.
jnz @F
cmp [di-2], byte ptr ':' ;'.',0: Remove slash at end of path.
je eos
dec di
jmp short eos
@@: cmp al,'\' ;For '\.\' omit the '.\' after the '\'.
je rdloop
cmp al,'.' ;Otherwise it must be '\..\' or '\..',0 or it's illegal.
jne direrr
lodsb
or al,al
jz @F
call fexchar
cmp al,'\'
jne direrr
@@: cmp [di-2], byte ptr ':' ;If we're at the root, '..' is invalid.
je direrr
mov cx,14
std
mov al,'\'
repne scasb
repne scasb
inc di ;Point to the backslash.
cld
@@: dec si ;Read the final '\' or '/' or 0 again and deal with it.
jmp short rdloop
store: cmp trunc,0 ;Check if we're truncating characters.
jz @F
dec trunc ;Decrement truncation counter.
cmp outchars,79 ;Check if we've exceeded the maximum legal path length.
ja direrr
inc outchars ;Increment output character count.
stosb ;Copy char to output string.
@@: jmp rdloop ;Go back for next char.
direrr: mov ax,3
jmp short endstr
;-------------------------------------------------------------------------------
;We've reached the end of [d:][path][\].
eos: cmp [di-1], byte ptr ':' ;If output ends in a colon, append '\'.
jne @F
mov al,'\'
stosb
@@: xor ax,ax ;Return a zero to indicate success.
endstr: push ax
xor al,al ;Terminate output string and exit.
stosb
pop ax
ret
fexpand endp
;-------------------------------------------------------------------------------
;fexchar() - Called by fexpand(): Normalize the character in AL.
;
;Convert '/' to '\' and capitalize letters.
fexchar proc
cmp al,'/' ;Normalize path delimiters.
jne @F
mov al,'\'
jmp short exit
@@: cmp al,'a' ;Is it a lower case letter?
jb exit
cmp al,'z'
ja exit
and al,223 ;Capitalize the letter.
exit:
ret
fexchar endp
end