home *** CD-ROM | disk | FTP | other *** search
- ;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
-