home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / fullpath.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  7KB  |  294 lines

  1. /***
  2. *fullpath.c -
  3. *
  4. *       Copyright (c) 1987-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose: contains the function _fullpath which makes an absolute path out
  7. *       of a relative path. i.e.  ..\pop\..\main.c => c:\src\main.c if the
  8. *       current directory is c:\src\src
  9. *
  10. *******************************************************************************/
  11.  
  12. #ifndef _MAC
  13.  
  14. #include <cruntime.h>
  15. #include <stdio.h>
  16. #include <direct.h>
  17. #include <errno.h>
  18. #include <stdlib.h>
  19. #include <internal.h>
  20. #include <tchar.h>
  21. #include <windows.h>
  22.  
  23.  
  24. /***
  25. *_TSCHAR *_fullpath( _TSCHAR *buf, const _TSCHAR *path, maxlen );
  26. *
  27. *Purpose:
  28. *
  29. *       _fullpath - combines the current directory with path to form
  30. *       an absolute path. i.e. _fullpath takes care of .\ and ..\
  31. *       in the path.
  32. *
  33. *       The result is placed in buf. If the length of the result
  34. *       is greater than maxlen NULL is returned, otherwise
  35. *       the address of buf is returned.
  36. *
  37. *       If buf is NULL then a buffer is malloc'ed and maxlen is
  38. *       ignored. If there are no errors then the address of this
  39. *       buffer is returned.
  40. *
  41. *       If path specifies a drive, the curent directory of this
  42. *       drive is combined with path. If the drive is not valid
  43. *       and _fullpath needs the current directory of this drive
  44. *       then NULL is returned.  If the current directory of this
  45. *       non existant drive is not needed then a proper value is
  46. *       returned.
  47. *       For example:  path = "z:\\pop" does not need z:'s current
  48. *       directory but path = "z:pop" does.
  49. *
  50. *
  51. *
  52. *Entry:
  53. *       _TSCHAR *buf  - pointer to a buffer maintained by the user;
  54. *       _TSCHAR *path - path to "add" to the current directory
  55. *       int maxlen - length of the buffer pointed to by buf
  56. *
  57. *Exit:
  58. *       Returns pointer to the buffer containing the absolute path
  59. *       (same as buf if non-NULL; otherwise, malloc is
  60. *       used to allocate a buffer)
  61. *
  62. *Exceptions:
  63. *
  64. *******************************************************************************/
  65.  
  66.  
  67. _TSCHAR * __cdecl _tfullpath (
  68.         _TSCHAR *UserBuf,
  69.         const _TSCHAR *path,
  70.         size_t maxlen
  71.         )
  72. {
  73.         _TSCHAR *buf;
  74.         _TSCHAR *pfname;
  75.         unsigned long count;
  76.  
  77.  
  78.         if ( !path || !*path )  /* no work to do */
  79.             return( _tgetcwd( UserBuf, maxlen ) );
  80.  
  81.         /* allocate buffer if necessary */
  82.  
  83.         if ( !UserBuf )
  84.             if ( !(buf = malloc(_MAX_PATH * sizeof(_TSCHAR))) ) {
  85.                 errno = ENOMEM;
  86.                 return( NULL );
  87.             }
  88.             else
  89.                 maxlen = _MAX_PATH;
  90.         else
  91.             buf = UserBuf;
  92.  
  93.         count = GetFullPathName ( path,
  94.                                   maxlen,
  95.                                   buf,
  96.                                   &pfname );
  97.  
  98.         if ( count >= maxlen ) {
  99.             if ( !UserBuf )
  100.                 free(buf);
  101.             errno = ERANGE;
  102.             return( NULL );
  103.         }
  104.         else if ( count == 0 ) {
  105.             if ( !UserBuf )
  106.                 free(buf);
  107.             _dosmaperr( GetLastError() );
  108.             return( NULL );
  109.         }
  110.  
  111.         return( buf );
  112.  
  113. }
  114.  
  115. #else  /* _MAC */
  116.  
  117. #include <cruntime.h>
  118. #include <stdio.h>
  119. #include <direct.h>
  120. #include <errno.h>
  121. #include <stdlib.h>
  122. #include <string.h>
  123. #include <internal.h>
  124. #include <macos\osutils.h>
  125. #include <macos\files.h>
  126. #include <macos\errors.h>
  127. #ifdef _MBCS
  128. #include <mbdata.h>
  129. #include <mbctype.h>
  130. #include <mbstring.h>
  131. int __cdecl isdbcscode (const char *, const char *);
  132. #endif  /* _MBCS */
  133.  
  134.  
  135. /***
  136. *char *_fullpath( char *buf, const char *path, maxlen );
  137. *
  138. *Purpose:
  139. *
  140. *       _fullpath - combines the current directory with path to form
  141. *       an absolute path. i.e. _fullpath takes care of ::
  142. *       in the path.
  143. *
  144. *       The result is placed in buf. If the length of the result
  145. *       is greater than maxlen NULL is returned, otherwise
  146. *       the address of buf is returned.
  147. *
  148. *       If buf is NULL then a buffer is malloc'ed and maxlen is
  149. *       ignored. If there are no errors then the address of this
  150. *       buffer is returned.
  151. *
  152. *
  153. *Entry:
  154. *       char *buf  - pointer to a buffer maintained by the user;
  155. *       char *path - path to "add" to the current directory
  156. *       int maxlen - length of the buffer pointed to by buf
  157. *
  158. *Exit:
  159. *       Returns pointer to the buffer containing the absolute path
  160. *       (same as buf if non-NULL; otherwise, malloc is
  161. *       used to allocate a buffer)
  162. *
  163. *Exceptions:
  164. *
  165. *******************************************************************************/
  166.  
  167. char * __cdecl _fullpath (
  168.         char *UserBuf,
  169.         const char *path,
  170.         size_t maxlen
  171.         )
  172. {
  173.         char    *buf;
  174.         size_t   cbPath;
  175.  
  176.         if( !path || !*path )   /* no work to do */
  177.             return( _getcwd( UserBuf, maxlen ) );
  178.  
  179.         if (UserBuf && (strlen(path) > maxlen))
  180.             return NULL;
  181.  
  182.         /* allocate buffer if necessary */
  183.  
  184.         if( !UserBuf )
  185.         {
  186.             if( !(buf = malloc(_MAX_PATH)) )
  187.             {
  188.                  errno = ENOMEM;
  189.                  return( NULL );
  190.             }
  191.             else
  192.             {
  193.                 maxlen = _MAX_PATH;
  194.             }
  195.         }
  196.         else
  197.         {
  198.             buf = UserBuf;
  199.         }
  200.  
  201.         cbPath = strlen(path);
  202.         if (cbPath > maxlen)
  203.         {
  204.             if (!UserBuf)
  205.             {
  206.                 free(buf);
  207.             }
  208.             errno = ERANGE;
  209.             return NULL;
  210.         }
  211.  
  212.         maxlen = maxlen - cbPath;
  213.         if (*path == ':')
  214.         {
  215.             maxlen++;        //this ":" is not counted
  216.         }
  217.  
  218.         if ((*path == ':') ||
  219. #ifndef _MBCS
  220.             (strstr(path, ":") == NULL) )
  221. #else  /* _MBCS */
  222.             (_mbsstr(path, ":") == NULL) )
  223. #endif  /* _MBCS */
  224.         {
  225.             //partial path
  226.             if (_getcwd( buf, maxlen ) != NULL)
  227.             {
  228.                 if (*path == ':')
  229.                 {
  230.                     strcat(buf, path+1);
  231.                 }
  232.                 else
  233.                 {
  234.                     strcat(buf, path);
  235.                 }
  236.             }
  237.             else
  238.             {
  239.                 if (!UserBuf)
  240.                 {
  241.                     free(buf);
  242.                 }
  243.                 return( NULL);
  244.             }
  245.         }
  246.         else
  247.         {
  248.             //fullpath
  249.             strcpy(buf, path);
  250.         }
  251.  
  252.         return buf;
  253.  
  254. }
  255.  
  256.  
  257. #ifdef _MBCS
  258. /***
  259. *       int isdbcscode( char *path, char *buf );
  260. *
  261. *Purpose:
  262. *
  263. *       isdbcscode - Check DBCS Code
  264. *
  265. *Entry:
  266. *       char *path - full path
  267. *       char *buf  - pointer to a buffer maintained by the user;
  268. *
  269. *Exit:
  270. *       TRUE    : -1
  271. *       FALSE   : 0
  272. *
  273. *Exceptions:
  274. *
  275. *******************************************************************************/
  276.  
  277. int __cdecl __isdbcscode(const char *path, const char *buf)
  278. {
  279.         while(path <= buf && *path++) {
  280.             if(_ISLEADBYTE( *(path - 1) ) )
  281.                 if(path == buf)
  282.                     return(-1);
  283.                 else
  284.                     path++;
  285.         }
  286.  
  287.         return 0;
  288.  
  289. }
  290. #endif  /* _MBCS */
  291.  
  292. #endif  /* _MAC */
  293.  
  294.