diff options
Diffstat (limited to 'private/crt32/misc/getpath.c')
-rw-r--r-- | private/crt32/misc/getpath.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/private/crt32/misc/getpath.c b/private/crt32/misc/getpath.c new file mode 100644 index 000000000..96782f176 --- /dev/null +++ b/private/crt32/misc/getpath.c @@ -0,0 +1,174 @@ +/*** +*getpath.c - extract a pathname from an environment variable +* +* Copyright (c) 1989-1991, Microsoft Corporation. All rights reserved. +* +*Purpose: +* Extract pathnames from a string of semicolon delimited pathnames +* (generally the value of an environment variable such as PATH). +* +*Revision History: +* 08-25-89 GJF Module created (taken from SEARCHEN.C and revised) +* 03-14-90 GJF Replaced near with _CALLTYPE1 and added #include +* <cruntime.h> +* 07-25-90 SBM Replaced <stdio.h> by <stddef.h> +* 10-04-90 GJF New-style function declarator. +* 04-26-91 SRW Removed level 3 warnings +* 09-18-91 JCR Strip off leading semi-colons (bug fix) +* 09-25-91 JCR Changed ifdef "OS2" to "_HPFS_" and defined it +* +*******************************************************************************/ + +#include <cruntime.h> +#include <stddef.h> +#include <internal.h> + +/* support HPFS file system */ +#define _HPFS_ 1 + +/*** +*_getpath() - extract a pathname from a semicolon-delimited list of pathnames +* +*Purpose: +* To extract the next pathname from a semicolon-delimited list of +* pathnames (usually the value on an environment variable) and copy +* it to a caller-specified buffer. No check is done to see if the path +* is valid. The maximum number of characters copied to the buffer is +* maxlen - 1 (and then a '\0' is appended). +* +#ifdef _HPFS_ +* If we hit a quoted string, then allow any characters inside. +* For example, to put a semi-colon in a path, the user could have +* an environment variable that looks like: +* +* PATH=C:\BIN;"D:\CRT\TOOLS;B1";C:\BINP +#endif +* +* NOTE: Semi-colons in sequence are skipped over; pointers to 0-length +* pathnames are NOT returned (this includes leading semi-colons). +* +* NOTE: If this routine is made user-callable, the near attribute +* must be replaced by _LOAD_DS and the prototype moved from INTERNAL.H +* to STDLIB.H. The source files MISC\SEARCHEN.C and EXEC\SPAWNVPE.C +* will need to be recompiled, but should not require any changes. +* +*Entry: +* src - Pointer to a string of 0 or more path specificiations, +* delimited by semicolons (';'), and terminated by a null +* character +* dst - Pointer to the buffer where the next path specification is to +* be copied +* maxlen - Maximum number of characters to be copied, counting the +* terminating null character. Note that a value of 0 is treated +* as UINT_MAX + 1. +* +*Exit: +* If a pathname is successfully extracted and copied, a pointer to the +* first character of next pathname is returned (intervening semicolons +* are skipped over). If the pathname is too long, as much as possible +* is copied to the user-specified buffer and NULL is returned. +* +* Note that the no check is made of the validity of the copied pathname. +* +*Exceptions: +* +*******************************************************************************/ + +char * _CALLTYPE1 _getpath ( + register const char *src, + register char *dst, + unsigned maxlen + ) +{ + const char *save_src; + + /* + * strip off leading semi colons + */ + while ( *src == ';' ) + src++; + + /* + * Save original src pointer + */ + save_src = src; + + /* + * Decrement maxlen to allow for the terminating '\0' + */ + if ( --maxlen == 0 ) + goto appendnull; + + + /* + * Get the next path in src string + */ + while (*src && (*src != ';')) { + +#ifdef _HPFS_ + + /* + * Check for quote char + */ + if (*src != '"') { + + *dst++ = *src++; + + if ( --maxlen == 0 ) { + save_src = src; /* ensure NULL return */ + goto appendnull; + } + + } + else { + + /* + * Found a quote. Copy all chars until we hit the + * final quote or the end of the string. + */ + src++; /* skip over opening quote */ + + while (*src && (*src != '"')) { + + *dst++ = *src++; + + if ( --maxlen == 0 ) { + save_src = src; /* ensure NULL return */ + goto appendnull; + } + } + + if (*src) + src++; /* skip over closing quote */ + + } + +#else + + *dst++ = *src++; + + if ( --maxlen == 0 ) { + save_src = src; /* ensure NULL return */ + goto appendnull; + } + +#endif + + } + + /* + * If we copied something and stopped because of a ';', + * skip the ';' before returning + */ + while ( *src == ';' ) + src++; + + /* + * Store a terminating null + */ +appendnull: + + *dst = '\0'; + + return((save_src != src) ? (char *)src : NULL); +} |