Removes duplicate slashes from the path in canonicalize_path(). It
authorBruce Momjian <bruce@momjian.us>
Sun, 7 Nov 2004 02:12:17 +0000 (02:12 +0000)
committerBruce Momjian <bruce@momjian.us>
Sun, 7 Nov 2004 02:12:17 +0000 (02:12 +0000)
preserve double leading slashes on Win32.

e.g.    ////a////b => /a/b

src/port/path.c

index b384b5e329a9b0f0f27ec13e083f5024011c2d31..f03b9f4dea9236f5f4f4905751a0c9306605a9fc 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/port/path.c,v 1.44 2004/11/06 21:39:45 tgl Exp $
+ *   $PostgreSQL: pgsql/src/port/path.c,v 1.45 2004/11/07 02:12:17 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -203,21 +203,22 @@ join_path_components(char *ret_path,
  *     o  make Win32 path use Unix slashes
  *     o  remove trailing quote on Win32
  *     o  remove trailing slash
+ *     o  remove duplicate adjacent separators
  *     o  remove trailing '.'
  *     o  process trailing '..' ourselves
  */
 void
 canonicalize_path(char *path)
 {
-#ifdef WIN32
+   char       *p, *to_p;
+   bool        was_sep = false;
 
+#ifdef WIN32
    /*
     * The Windows command processor will accept suitably quoted paths
     * with forward slashes, but barfs badly with mixed forward and back
     * slashes.
     */
-   char       *p;
-
    for (p = path; *p; p++)
    {
        if (*p == '\\')
@@ -226,7 +227,7 @@ canonicalize_path(char *path)
 
    /*
     * In Win32, if you do: prog.exe "a b" "\c\d\" the system will pass
-    * \c\d" as argv[2].
+    * \c\d" as argv[2], so trim off trailing quote.
     */
    if (p > path && *(p - 1) == '"')
        *(p - 1) = '/';
@@ -239,6 +240,27 @@ canonicalize_path(char *path)
     */
    trim_trailing_separator(path);
 
+   /*
+    *  Remove duplicate adjacent separators
+    */
+   p = path;
+#ifdef WIN32
+   /* Don't remove leading double-slash on Win32 */
+   if (*p)
+       p++;
+#endif
+   to_p = p;
+   for (; *p; p++, to_p++)
+   {
+       /* Handle many adjacent slashes, like "/a///b" */
+       while (*p == '/' && was_sep)
+           p++;
+       if (to_p != p)
+           *to_p = *p;
+       was_sep = (*p == '/');
+   }
+   *to_p = '\0';
+
    /*
     * Remove any trailing uses of "." and process ".." ourselves
     */
@@ -247,9 +269,7 @@ canonicalize_path(char *path)
        int         len = strlen(path);
 
        if (len > 2 && strcmp(path + len - 2, "/.") == 0)
-       {
            trim_directory(path);
-       }
        else if (len > 3 && strcmp(path + len - 3, "/..") == 0)
        {
            trim_directory(path);