88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/port/path.c,v 1.44 2004/11/06 21:39:45 tgl Exp $
11+ * $PostgreSQL: pgsql/src/port/path.c,v 1.45 2004/11/07 02:12:17 momjian Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -203,21 +203,22 @@ join_path_components(char *ret_path,
203203 *o make Win32 path use Unix slashes
204204 *o remove trailing quote on Win32
205205 *o remove trailing slash
206+ *o remove duplicate adjacent separators
206207 *o remove trailing '.'
207208 *o process trailing '..' ourselves
208209 */
209210void
210211canonicalize_path (char * path )
211212{
212- #ifdef WIN32
213+ char * p ,* to_p ;
214+ bool was_sep = false;
213215
216+ #ifdef WIN32
214217/*
215218 * The Windows command processor will accept suitably quoted paths
216219 * with forward slashes, but barfs badly with mixed forward and back
217220 * slashes.
218221 */
219- char * p ;
220-
221222for (p = path ;* p ;p ++ )
222223{
223224if (* p == '\\' )
@@ -226,7 +227,7 @@ canonicalize_path(char *path)
226227
227228/*
228229 * In Win32, if you do: prog.exe "a b" "\c\d\" the system will pass
229- * \c\d" as argv[2].
230+ * \c\d" as argv[2], so trim off trailing quote .
230231 */
231232if (p > path && * (p - 1 )== '"' )
232233* (p - 1 )= '/' ;
@@ -239,6 +240,27 @@ canonicalize_path(char *path)
239240 */
240241trim_trailing_separator (path );
241242
243+ /*
244+ *Remove duplicate adjacent separators
245+ */
246+ p = path ;
247+ #ifdef WIN32
248+ /* Don't remove leading double-slash on Win32 */
249+ if (* p )
250+ p ++ ;
251+ #endif
252+ to_p = p ;
253+ for (;* p ;p ++ ,to_p ++ )
254+ {
255+ /* Handle many adjacent slashes, like "/a///b" */
256+ while (* p == '/' && was_sep )
257+ p ++ ;
258+ if (to_p != p )
259+ * to_p = * p ;
260+ was_sep = (* p == '/' );
261+ }
262+ * to_p = '\0' ;
263+
242264/*
243265 * Remove any trailing uses of "." and process ".." ourselves
244266 */
@@ -247,9 +269,7 @@ canonicalize_path(char *path)
247269int len = strlen (path );
248270
249271if (len > 2 && strcmp (path + len - 2 ,"/." )== 0 )
250- {
251272trim_directory (path );
252- }
253273else if (len > 3 && strcmp (path + len - 3 ,"/.." )== 0 )
254274{
255275trim_directory (path );