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

  1. /***
  2. *getpath.c - extract a pathname from an environment variable
  3. *
  4. *       Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Extract pathnames from a string of semicolon delimited pathnames
  8. *       (generally the value of an environment variable such as PATH).
  9. *
  10. *******************************************************************************/
  11.  
  12. #include <cruntime.h>
  13. #include <stddef.h>
  14. #include <internal.h>
  15. #include <tchar.h>
  16.  
  17. /* support HPFS file system */
  18. #define _HPFS_ 1
  19.  
  20. /***
  21. *_getpath() - extract a pathname from a semicolon-delimited list of pathnames
  22. *
  23. *Purpose:
  24. *       To extract the next pathname from a semicolon-delimited list of
  25. *       pathnames (usually the value on an environment variable) and copy
  26. *       it to a caller-specified buffer. No check is done to see if the path
  27. *       is valid. The maximum number of characters copied to the buffer is
  28. *       maxlen - 1 (and then a '\0' is appended).
  29. *
  30. *ifdef _HPFS_
  31. *       If we hit a quoted string, then allow any characters inside.
  32. *       For example, to put a semi-colon in a path, the user could have
  33. *       an environment variable that looks like:
  34. *
  35. *               PATH=C:\BIN;"D:\CRT\TOOLS;B1";C:\BINP
  36. *endif
  37. *
  38. *       NOTE: Semi-colons in sequence are skipped over; pointers to 0-length
  39. *       pathnames are NOT returned (this includes leading semi-colons).
  40. *
  41. *       NOTE: If this routine is made user-callable, the near attribute
  42. *       must be replaced by _LOAD_DS and the prototype moved from INTERNAL.H
  43. *       to STDLIB.H. The source files MISC\SEARCHEN.C and EXEC\SPAWNVPE.C
  44. *       will need to be recompiled, but should not require any changes.
  45. *
  46. *Entry:
  47. *       src    - Pointer to a string of 0 or more path specificiations,
  48. *                delimited by semicolons (';'), and terminated by a null
  49. *                character
  50. *       dst    - Pointer to the buffer where the next path specification is to
  51. *                be copied
  52. *       maxlen - Maximum number of characters to be copied, counting the
  53. *                terminating null character. Note that a value of 0 is treated
  54. *                as UINT_MAX + 1.
  55. *
  56. *Exit:
  57. *       If a pathname is successfully extracted and copied, a pointer to the
  58. *       first character of next pathname is returned (intervening semicolons
  59. *       are skipped over). If the pathname is too long, as much as possible
  60. *       is copied to the user-specified buffer and NULL is returned.
  61. *
  62. *       Note that the no check is made of the validity of the copied pathname.
  63. *
  64. *Exceptions:
  65. *
  66. *******************************************************************************/
  67.  
  68. #ifdef WPRFLAG
  69. wchar_t * __cdecl _wgetpath (
  70. #else  /* WPRFLAG */
  71. char * __cdecl _getpath (
  72. #endif  /* WPRFLAG */
  73.         register const _TSCHAR *src,
  74.         register _TSCHAR *dst,
  75.         unsigned maxlen
  76.         )
  77. {
  78.         const _TSCHAR *save_src;
  79.  
  80.         /*
  81.          * strip off leading semi colons
  82.          */
  83.         while ( *src == _T(';') )
  84.                 src++;
  85.  
  86.         /*
  87.          * Save original src pointer
  88.          */
  89.         save_src = src;
  90.  
  91.         /*
  92.          * Decrement maxlen to allow for the terminating _T('\0')
  93.          */
  94.         if ( --maxlen == 0 )
  95.                 goto appendnull;
  96.  
  97.  
  98.         /*
  99.          * Get the next path in src string
  100.          */
  101.         while (*src && (*src != _T(';'))) {
  102.  
  103. #if defined (_HPFS_) && defined (_WIN32)
  104.  
  105.                 /*
  106.                  * Check for quote char
  107.                  */
  108.                 if (*src != _T('"')) {
  109.  
  110.                         *dst++ = *src++;
  111.  
  112.                         if ( --maxlen == 0 ) {
  113.                                 save_src = src; /* ensure NULL return */
  114.                                 goto appendnull;
  115.                         }
  116.  
  117.                 }
  118.                 else {
  119.  
  120.                         /*
  121.                          * Found a quote.  Copy all chars until we hit the
  122.                          * final quote or the end of the string.
  123.                          */
  124.                         src++;                  /* skip over opening quote */
  125.  
  126.                         while (*src && (*src != _T('"'))) {
  127.  
  128.                                 *dst++ = *src++;
  129.  
  130.                                 if ( --maxlen == 0 ) {
  131.                                         save_src = src; /* ensure NULL return */
  132.                                         goto appendnull;
  133.                                 }
  134.                         }
  135.  
  136.                         if (*src)
  137.                                 src++;          /* skip over closing quote */
  138.  
  139.                 }
  140.  
  141. #else  /* defined (_HPFS_) && defined (_WIN32) */
  142.  
  143.                 *dst++ = *src++;
  144.  
  145.                 if ( --maxlen == 0 ) {
  146.                         save_src = src; /* ensure NULL return */
  147.                         goto appendnull;
  148.                 }
  149.  
  150. #endif  /* defined (_HPFS_) && defined (_WIN32) */
  151.  
  152.         }
  153.  
  154.         /*
  155.          * If we copied something and stopped because of a _T(';'),
  156.          * skip the _T(';') before returning
  157.          */
  158.         while ( *src == _T(';') )
  159.                 src++;
  160.  
  161.         /*
  162.          * Store a terminating null
  163.          */
  164. appendnull:
  165.  
  166.         *dst = _T('\0');
  167.  
  168.         return((save_src != src) ? (_TSCHAR *)src : NULL);
  169. }
  170.