From 59fb00ae07d9cfbfac3735f541149bed2c7625cb Mon Sep 17 00:00:00 2001 From: Brian Dessent Date: Sun, 9 Mar 2008 04:10:10 +0000 Subject: * Makefile.in: Add a 'check' target that builds and runs testsuite.exe from path-testsuite.o and testsuite.o. * path.cc: Include testsuite.h. (struct mnt): Change to a mnt_t typedef and don't define mount_table when TESTSUITE is defined. (find2): Don't include when TESTSUITE is defined to avoid warning. (get_cygdrive0): Ditto. (get_cygdrive): Ditto. (read_mounts): Provide empty implementation when TESTSUITE is defined. (vconcat): Use the isslash macro. (unconvert_slashes): New helper to convert to backslashses. (rel_vconcat): Handle relative paths more gracefully. (cygpath): Skip a leading "./" sequence. Avoid double-slashes. Normalize final output to backslashes and remove redundant path sequences. * testsuite.cc: New file implementing testsuite driver. * testsuite.h: New header implementing harness mount table and series of tests. --- winsup/utils/path.cc | 61 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 10 deletions(-) (limited to 'winsup/utils/path.cc') diff --git a/winsup/utils/path.cc b/winsup/utils/path.cc index 75590282c..569196344 100644 --- a/winsup/utils/path.cc +++ b/winsup/utils/path.cc @@ -1,6 +1,6 @@ /* path.cc - Copyright 2001, 2002, 2003, 2005, 2006, 2007 Red Hat, Inc. + Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2008 Red Hat, Inc. This file is part of Cygwin. @@ -22,6 +22,7 @@ details. */ #include "cygwin/include/cygwin/version.h" #include "cygwin/include/sys/mount.h" #include "cygwin/include/mntent.h" +#include "testsuite.h" /* Used when treating / and \ as equivalent. */ #define isslash(ch) \ @@ -227,16 +228,27 @@ readlink (HANDLE fh, char *path, int maxlen) return true; } -static struct mnt +typedef struct mnt { const char *native; char *posix; unsigned flags; int issys; - } mount_table[255]; + } mnt_t; + +#ifndef TESTSUITE +static mnt_t mount_table[255]; +#else +# define TESTSUITE_MOUNT_TABLE +# include "testsuite.h" +# undef TESTSUITE_MOUNT_TABLE +#endif struct mnt *root_here = NULL; +/* These functions aren't called when defined(TESTSUITE) which results + in a compiler warning. */ +#ifndef TESTSUITE static char * find2 (HKEY rkey, unsigned *flags, char *what) { @@ -288,10 +300,14 @@ get_cygdrive (HKEY key, mnt *m, int issystem) m->issys = issystem; return m + 1; } +#endif static void read_mounts () { +/* If TESTSUITE is defined, bypass this whole function as a harness + mount table will be provided. */ +#ifndef TESTSUITE DWORD posix_path_size; int res; struct mnt *m = mount_table; @@ -358,6 +374,7 @@ read_mounts () } RegCloseKey (key); } +#endif /* !defined(TESTSUITE) */ } /* Return non-zero if PATH1 is a prefix of PATH2. @@ -439,7 +456,7 @@ vconcat (const char *s, va_list v) *d++ = *++p; *d++ = *++p; } - else if (*p == '/' || *p == '\\') + else if (isslash (*p)) { if (p == rv && unc) *d++ = *p++; @@ -462,6 +479,13 @@ concat (const char *s, ...) return vconcat (s, v); } +static void +unconvert_slashes (char* name) +{ + while ((name = strchr (name, '/')) != NULL) + *name++ = '\\'; +} + static char * rel_vconcat (const char *s, va_list v) { @@ -487,13 +511,22 @@ rel_vconcat (const char *s, va_list v) match = m; } - if (match) - strcpy (path, match->posix); - - if (!isslash (strchr (path, '\0')[-1])) - strcat (path, "/"); + char *temppath; + if (!match) + // No prefix matched - best effort to return meaningful value. + temppath = concat (path, "/", s, NULL); + else if (strcmp (match->posix, "/") != 0) + // Matched on non-root. Copy matching prefix + remaining 'path'. + temppath = concat (match->posix, path + max_len, "/", s, NULL); + else if (path[max_len] == '\0') + // Matched on root and there's no remaining 'path'. + temppath = concat ("/", s, NULL); + else if (isslash (path[max_len])) + // Matched on root but remaining 'path' starts with a slash anyway. + temppath = concat (path + max_len, "/", s, NULL); + else + temppath = concat ("/", path + max_len, "/", s, NULL); - char *temppath = concat (path, s, NULL); char *res = vconcat (temppath, v); free (temppath); return res; @@ -510,6 +543,9 @@ cygpath (const char *s, ...) read_mounts (); va_start (v, s); char *path; + if (s[0] == '.' && isslash (s[1])) + s += 2; + if (s[0] == '/' || s[1] == ':') /* FIXME: too crude? */ path = vconcat (s, v); else @@ -538,10 +574,15 @@ cygpath (const char *s, ...) native = strdup (path); else if (max_len == (int) strlen (path)) native = strdup (match->native); + else if (isslash (path[max_len])) + native = concat (match->native, path + max_len, NULL); else native = concat (match->native, "\\", path + max_len, NULL); free (path); + unconvert_slashes (native); + for (char *s = strstr (native + 1, "\\.\\"); s && *s; s = strstr (s, "\\.\\")) + memmove (s + 1, s + 3, strlen (s + 3) + 1); return native; } -- cgit v1.2.3