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 >
Assembly Source File  |  1989-08-02  |  8KB  |  256 lines

  1. ;fexpand() - Convert a relative pathname to a fully qualified name.
  2. ;
  3. ;Syntax: int fexpand (char *relname, char *absname);
  4. ;
  5. ;relname = ASCIIZ relative pathname to expand
  6. ;absname = ASCIIZ absolute pathname with drive I.D. and full directory path
  7. ;
  8. ;Return value: 0 = no errors detected (does not necessarily mean path is OK)
  9. ;              3 = invalid directory path
  10. ;             15 = invalid drive I.D.
  11. ;
  12. ;Letters in the pathname will be capitalized, and any occurrances of '/' will 
  13. ;be converted to '\'.  If the drive I.D. is missing, the current default 
  14. ;drive I.D. will be prepended.  Occurrances of '.' and '..' will be expanded 
  15. ;appropriately.  Directory and file names will be truncated to 8 characters, 
  16. ;file name extensions to 3 characters.  The absolute pathname will not be 
  17. ;allowed to exceed 80 characters, including the final zero byte.
  18. ;
  19. ;This function is similar to the undocumented DOS call INT 21H, AH = 60H, 
  20. ;but it may be used with DOS 2.0 and up whereas the DOS call was only 
  21. ;introduced with DOS 3.0.
  22. ;
  23. ;Copyright (C) 1989 Brian B. McGuinness
  24. ;                   15 Kevin Road
  25. ;                   Scotch Plains, NJ 07076
  26. ;
  27. ;This function is free software; you can redistribute it and/or modify it under 
  28. ;the terms of the GNU General Public License as published by the Free Software 
  29. ;Foundation; either version 1, or (at your option) any later version.
  30. ;
  31. ;This function is distributed in the hope that it will be useful, but WITHOUT 
  32. ;ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  33. ;FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  34. ;details.
  35. ;
  36. ;You should have received a copy of the GNU General Public License along with 
  37. ;this function; if not, write to the Free Software Foundation, Inc., 675 Mass 
  38. ;Ave, Cambridge, MA 02139, USA.
  39. ;
  40. ;Version 1.0          July, 1989          MASM 5.1
  41.  
  42.         DOSSEG
  43.         .MODEL small,C
  44.         .DATA
  45.  
  46. outchars dw ?           ;Number of chars in output string so far.
  47.  
  48. ;While we are in the process of copying a directory name, file name, or file 
  49. ;name extension from the relative pathname to the absolute pathname, trunc 
  50. ;tells us how many more characters to copy before we start truncating.
  51.  
  52. trunc    db ?
  53.  
  54.         .CODE
  55.  
  56. fexpand proc uses bx cx ds es si di, relname:ptr, absname:ptr
  57.  
  58. ;Set up pointers to input and output buffers.
  59.  
  60. if @DataSize
  61.         lds si,relname          ;Far pointers
  62.         les di,absname
  63. else
  64.         mov si,relname          ;Near pointers
  65.         mov di,absname
  66.         push ds
  67.         pop es
  68. endif
  69.  
  70.         cld
  71.         or [si], byte ptr 0     ;If input string is empty, quit.
  72.         jnz @F
  73.         jmp eos
  74.  
  75. @@:     mov trunc,8             ;Initial name will be directory or file name.
  76.  
  77. ;If drive I.D. is given in the input string, copy it to the output string.
  78. ;Otherwise write the default drive I.D. to the output string.
  79.  
  80.         cmp [si+1], byte ptr ':' ;Look for drive I.D. 
  81.         jne @F
  82.         lodsw                    ;Found it: capitalize and copy it.
  83.         and al,223
  84.         stosw
  85.         jmp short start
  86.  
  87. @@:     mov ah,19H      ;Get default drive ID.
  88.         int 21H
  89.         add al,'A'      ;Write it to the output string.
  90.         mov ah,':'
  91.         stosw
  92.  
  93. ;If next character is not a path delimiter, we must insert the current default 
  94. ;directory name here.
  95.  
  96. start:  lodsb
  97.         call fexchar
  98.         cmp al,'\'
  99.         jne nodir
  100.  
  101. ;Starting directory was specified.
  102.  
  103.         stosb           ;Save the '\'.
  104.         mov outchars,3  ;3 chars in output buffer so far.
  105.         jmp short rdloop
  106.  
  107. ;Starting directory was not specified, so insert default directory into output.
  108.  
  109. nodir:  dec si          ;We'll re-read this char later.
  110.         mov al,'\'      ;Store leading backslash.
  111.         stosb
  112.  
  113.         mov bx,absname  ;Get drive I.D. to find default path for.
  114.         mov dl,[bx]
  115.         sub dl,'@'
  116.         push si
  117.         mov si,di
  118.         mov ah,47H      ;Get path in output buffer.
  119.         int 21H
  120.         pop si
  121.         jnc @F          ;If we can't get it, the drive ID is invalid.
  122.         mov ax,0FH
  123.         jmp endstr
  124.  
  125. @@:     mov di,absname  ;Find the end of the output string.
  126.         mov outchars,0
  127.         xor al,al       ;String ends with a zero byte.
  128.         mov cx,80
  129.         repne scasb
  130.         mov cx,di
  131.         sub cx,absname
  132.         mov outchars,cx
  133.         dec di
  134.  
  135. gotend: cmp [di-1], byte ptr '\'  ;If appropriate, append '\' to directory path.
  136.         je rdloop
  137.         cmp [si], byte ptr 0
  138.         jne @f
  139.         jmp eos
  140. @@:     mov al,'\'
  141.         stosb
  142.         inc outchars
  143.  
  144. ;-------------------------------------------------------------------------------
  145. ;Expand and copy the rest of the directory path.
  146.  
  147. rdloop: lodsb           ;Get next character and normalize it.
  148.         call fexchar
  149.  
  150.         or al,al        ;Watch for end of string.
  151.         jnz @F
  152.         jmp eos
  153.  
  154. @@:     cmp al,'\'      ;Watch for path delimiters.
  155.         jne @F
  156.         mov trunc,9     ;New name, so reset truncation counter.
  157.         jmp short store
  158.  
  159. @@:     cmp al,'.'      ;Watch for '.' and '..' entries.
  160.         jne store
  161.  
  162. ;If it isn't the first char, and it doesn't follow a colon or path delimiter, 
  163. ;it prefixes a file name extension so reset the truncation counter and copy it.
  164.  
  165.         cmp [di-1], byte ptr ':'
  166.         je @F
  167.         cmp [di-1], byte ptr '\'
  168.         je @F
  169.         mov trunc,4
  170.         jmp short store
  171.  
  172. @@:     lodsb           ;Get char following the dot.
  173.         call fexchar
  174.         or al,al        ;Watch out for end of string.
  175.         jnz @F
  176.         cmp [di-2], byte ptr ':'        ;'.',0: Remove slash at end of path.
  177.         je eos
  178.         dec di
  179.         jmp short eos
  180.  
  181. @@:     cmp al,'\'      ;For '\.\' omit the '.\' after the '\'.
  182.         je rdloop
  183.  
  184.         cmp al,'.'      ;Otherwise it must be '\..\' or '\..',0 or it's illegal.
  185.         jne direrr
  186.         lodsb
  187.         or al,al
  188.         jz @F
  189.         call fexchar
  190.         cmp al,'\'
  191.         jne direrr
  192.  
  193. @@:     cmp [di-2], byte ptr ':'  ;If we're at the root, '..' is invalid.
  194.         je direrr
  195.         mov cx,14
  196.         std
  197.         mov al,'\'
  198.         repne scasb
  199.         repne scasb
  200.         inc di          ;Point to the backslash.
  201.         cld
  202. @@:     dec si          ;Read the final '\' or '/' or 0 again and deal with it.
  203.         jmp short rdloop
  204.  
  205. store:  cmp trunc,0     ;Check if we're truncating characters.
  206.         jz @F
  207.         dec trunc       ;Decrement truncation counter.
  208.  
  209.         cmp outchars,79 ;Check if we've exceeded the maximum legal path length.
  210.         ja direrr
  211.         inc outchars    ;Increment output character count.
  212.  
  213.         stosb           ;Copy char to output string.
  214. @@:     jmp rdloop      ;Go back for next char.
  215.  
  216. direrr: mov ax,3
  217.         jmp short endstr
  218.  
  219. ;-------------------------------------------------------------------------------
  220. ;We've reached the end of [d:][path][\].
  221.  
  222. eos:    cmp [di-1], byte ptr ':'  ;If output ends in a colon, append '\'.
  223.         jne @F
  224.         mov al,'\'
  225.         stosb
  226. @@:     xor ax,ax       ;Return a zero to indicate success.
  227.  
  228. endstr: push ax
  229.         xor al,al       ;Terminate output string and exit.
  230.         stosb
  231.         pop ax
  232.         ret
  233.  
  234. fexpand endp
  235.  
  236. ;-------------------------------------------------------------------------------
  237. ;fexchar() - Called by fexpand(): Normalize the character in AL.
  238. ;
  239. ;Convert '/' to '\' and capitalize letters.
  240.  
  241. fexchar proc
  242.         cmp al,'/'      ;Normalize path delimiters.
  243.         jne @F
  244.         mov al,'\'
  245.         jmp short exit
  246.  
  247. @@:     cmp al,'a'      ;Is it a lower case letter?
  248.         jb exit
  249.         cmp al,'z'
  250.         ja exit
  251.         and al,223      ;Capitalize the letter.
  252. exit:
  253.         ret
  254. fexchar endp
  255.         end
  256.