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

  1. /***
  2. *searchenv.c - find a file using paths from an environment variable
  3. *
  4. *       Copyright (c) 1987-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       to search a set a directories specified by an environment variable
  8. *       for a specified file name.  If found the full path name is returned.
  9. *
  10. *******************************************************************************/
  11.  
  12. #include <cruntime.h>
  13. #include <direct.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <io.h>
  17. #include <internal.h>
  18. #include <tchar.h>
  19.  
  20. /***
  21. *_searchenv() - search for file along paths from environment variable
  22. *
  23. *Purpose:
  24. *       to search for a specified file in the directory(ies) specified by
  25. *       a given environment variable, and, if found, to return the full
  26. *       path name of the file.  The file is first looked for in the current
  27. *       working directory, prior to looking in the paths specified by env_var.
  28. *
  29. *Entry:
  30. *       fname - name of file to search for
  31. *       env_var - name of environment variable to use for paths
  32. *       path - pointer to storage for the constructed path name
  33. *
  34. *Exit:
  35. *       path - pointer to constructed path name, if the file is found, otherwise
  36. *              it points to the empty string.
  37. *
  38. *Exceptions:
  39. *
  40. *******************************************************************************/
  41.  
  42. void __cdecl _tsearchenv (
  43.         const _TSCHAR *fname,
  44.         const _TSCHAR *env_var,
  45.         _TSCHAR *path
  46.         )
  47. {
  48.         register _TSCHAR *p;
  49.         register int c;
  50.         _TSCHAR *env_p;
  51.         size_t len;
  52.         _TSCHAR pathbuf[_MAX_PATH + 4];
  53.  
  54.         if (_taccess(fname, 0) == 0) {
  55.  
  56. #if defined (_WIN32)
  57.             /* exists, convert it to a fully qualified pathname and
  58.                return */
  59.             if ( _tfullpath(path, fname, _MAX_PATH) == NULL )
  60.                 *path = _T('\0');
  61. #else  /* defined (_WIN32) */
  62.             /* exists in this directory - get cwd and concatenate file
  63.                name */
  64.             if (_tgetcwd(path, _MAX_PATH))
  65.             {
  66.                 _tcscat(path, fname);
  67.             }
  68. #endif  /* defined (_WIN32) */
  69.  
  70.             return;
  71.         }
  72.  
  73.         if ((env_p = _tgetenv(env_var)) == NULL) {
  74.             /* no such environment var. and not in cwd, so return empty
  75.                string */
  76.             *path = _T('\0');
  77.             return;
  78.         }
  79.  
  80. #ifdef _UNICODE
  81.         while ( (env_p = _wgetpath(env_p, pathbuf, _MAX_PATH)) && *pathbuf ) {
  82. #else  /* _UNICODE */
  83.         while ( (env_p = _getpath(env_p, pathbuf, _MAX_PATH)) && *pathbuf ) {
  84. #endif  /* _UNICODE */
  85.             /* path now holds nonempty pathname from env_p, concatenate
  86.                the file name and go */
  87.  
  88. #ifdef _WIN32
  89.             len = _tcslen(pathbuf);
  90.             p = pathbuf + len;
  91.             if ( ((c = *(p - 1)) != _T('/')) && (c != _T('\\')) &&
  92.                  (c != _T(':')) )
  93.             {
  94.                 /* add a trailing '\' */
  95.                 *p++ = _T('\\');
  96.                 len++;
  97.             }
  98.             /* p now points to character following trailing '/', '\'
  99.                or ':' */
  100.  
  101. #else  /* _WIN32 */
  102.             len = _tcslen(pathbuf);
  103.             if ( _tcsstr(pathbuf, _T(":")) == NULL )
  104.             {
  105.                  /* path contains single name as partial dir name
  106.                     prefix ':' to make it a partial path */
  107.                  memmove(pathbuf + 1, pathbuf, (++len) * sizeof(_TSCHAR));
  108.                  *pathbuf = _T(':');
  109.             }
  110.             p = pathbuf + len;
  111.             if ( (c = *(p - 1)) != _T(':') ) {
  112.                 /* add a trailing ':' */
  113.                 *p++ = _T(':');
  114.                 len++;
  115.             }
  116.             /* p now points to character following trailing ':' */
  117. #endif  /* _WIN32 */
  118.  
  119.             if ( (len + _tcslen(fname)) <= _MAX_PATH ) {
  120.                 _tcscpy(p, fname);
  121.                 if ( _taccess(pathbuf, 0) == 0 ) {
  122.                     /* found a match, copy the full pathname into the caller's
  123.                        buffer */
  124.                     _tcscpy(path, pathbuf);
  125.                     return;
  126.                 }
  127.             }
  128.         }
  129.         /* if we get here, we never found it, return empty string */
  130.         *path = _T('\0');
  131. }
  132.