summaryrefslogtreecommitdiffstats
path: root/private/crt32/misc/getpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/crt32/misc/getpath.c')
-rw-r--r--private/crt32/misc/getpath.c174
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);
+}