From b603cde31c98b1241951e70e62ea0c3962dfe266 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net>
Date: Tue, 26 Aug 1997 19:39:18 -0700
Subject: [PATCH] combine_path() now handles relative paths

Rev: src/builtin_functions.c:1.40
Rev: src/testsuite.in:1.47
---
 src/builtin_functions.c | 36 +++++++++++++++++++++++++++---------
 src/testsuite.in        |  6 +++++-
 2 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 1869f904f0..8a751063be 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -4,7 +4,7 @@
 ||| See the files COPYING and DISCLAIMER for more information.
 \*/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.39 1997/08/26 23:24:45 grubba Exp $");
+RCSID("$Id: builtin_functions.c,v 1.40 1997/08/27 02:39:17 hubbe Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -410,6 +410,9 @@ static char *combine_path(char *cwd,char *file)
   }
 
   from=to=ret;
+
+  /* Skip all leading "./" */
+  while(from[0]=='.' && from[1]=='/') from+=2;
   
   while(( *to = *from ))
   {
@@ -423,22 +426,26 @@ static char *combine_path(char *cwd,char *file)
 	case '.':
 	  if(from[3] == '/' || from[3] == 0)
 	  {
+	    char *tmp=to;
+	    while(--tmp>=ret)
+	      if(*tmp == '/')
+		break;
+
+	    if(tmp[1]=='.' && tmp[2]=='.' && (tmp[3]=='/' || !tmp[3]))
+	      break;
+	    
 	    from+=3;
-	    if(to != ret)
+	    to=tmp;
+	    if(to<ret)
 	    {
-	      for(--to;*to!='/' && to>ret;to--);
+	      to++;
+	      if(*from) from++;
 	    }
-	    if(!*from && to==ret && *to=='/') to++;
 	    continue;
 	  }
 	  break;
 
 	case 0:
-	  if (to == ret) {
-	    /* Special case, so we don't get an empty string */
-	    to++;
-	  }
-	  /* FALL_THROUGH */
 	case '/':
 	  from+=2;
 	  continue;
@@ -448,6 +455,17 @@ static char *combine_path(char *cwd,char *file)
     from++;
     to++;
   }
+  if(!*ret)
+  {
+    if(*cwd=='/')
+    {
+      ret[0]='/';
+      ret[1]=0;
+    }else{
+      ret[0]='.';
+      ret[1]=0;
+    }
+  }
 
   if(my_cwd) free(my_cwd);
   return ret;
diff --git a/src/testsuite.in b/src/testsuite.in
index accd80eaed..ea44ae8821 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.46 1997/08/26 22:29:18 grubba Exp $"]])
+test_true([["$Id: testsuite.in,v 1.47 1997/08/27 02:39:18 hubbe Exp $"]])
 test_eq(1e1,10.0)
 test_eq(1E1,10.0)
 test_eq(1e+1,10.0)
@@ -1467,6 +1467,10 @@ test_eq([[combine_path("/","/foo//bar/gazonk/../..")]],"/foo")
 test_eq([[combine_path("/","/foo/bar/./gazonk/../../..")]],"/")
 test_eq([[combine_path("/","/foo/../bar//./gazonk/../..")]],"/")
 test_eq([[combine_path("/","/foo/././/bar/gazonk/../../../..")]],"/")
+test_eq([[combine_path("/","..")]],"/")
+test_eq([[combine_path("./","..")]],"..")
+test_eq([[combine_path("./.","..")]],"..")
+test_eq([[combine_path("./foobar/.","..")]],".")
 
 // - compile_file
 // FIXME: add tests for compile_file
-- 
GitLab