]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Merge branch 'maint'
authorJoel Rosdahl <joel@rosdahl.net>
Sat, 28 Jul 2012 15:17:25 +0000 (17:17 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Sat, 28 Jul 2012 15:17:25 +0000 (17:17 +0200)
* maint:
  Improve get_relative_path and add unit tests
  Canonicalize paths when computing path relative to base directory

Conflicts:
test/test_util.c
util.c

1  2 
ccache.c
test/test_util.c
util.c

diff --cc ccache.c
index 01a73829f4417e874f109e145fe13e5ded5ada89,1f8ee64eb557000ad0289379773575f04c635a07..b126e20c57ac17236e62c697734497f5dd129b18
+++ b/ccache.c
@@@ -426,9 -386,9 +426,9 @@@ ignore
  static char *
  make_relative_path(char *path)
  {
-       char *relpath;
+       char *relpath, *canon_path;
  
 -      if (!base_dir || !str_startswith(path, base_dir)) {
 +      if (str_eq(conf->base_dir, "") || !str_startswith(path, conf->base_dir)) {
                return path;
        }
  
index 7a9fbcdb2447fc199c9c66aa993f5dd4fe745a31,10478baa7d6eac753ec3574144c8a57ca159b7fc..0ad51d2e496c452c3b1bef8052685ff9405b4cff
@@@ -41,117 -41,32 +41,145 @@@ TEST(dirname
        CHECK_STR_EQ_FREE2("dir1/dir2", dirname("dir1/dir2/"));
  }
  
 -      CHECK_UNS_EQ(0, common_dir_prefix_length("", ""));
 -      CHECK_UNS_EQ(0, common_dir_prefix_length("/", "/"));
 -      CHECK_UNS_EQ(0, common_dir_prefix_length("/", "/b"));
 -      CHECK_UNS_EQ(0, common_dir_prefix_length("/a", "/b"));
 -      CHECK_UNS_EQ(2, common_dir_prefix_length("/a", "/a"));
 -      CHECK_UNS_EQ(2, common_dir_prefix_length("/a", "/a/b"));
 -      CHECK_UNS_EQ(2, common_dir_prefix_length("/a/b", "/a/c"));
 -      CHECK_UNS_EQ(4, common_dir_prefix_length("/a/b", "/a/b"));
+ TEST(common_dir_prefix_length)
+ {
++      CHECK_INT_EQ(0, common_dir_prefix_length("", ""));
++      CHECK_INT_EQ(0, common_dir_prefix_length("/", "/"));
++      CHECK_INT_EQ(0, common_dir_prefix_length("/", "/b"));
++      CHECK_INT_EQ(0, common_dir_prefix_length("/a", "/b"));
++      CHECK_INT_EQ(2, common_dir_prefix_length("/a", "/a"));
++      CHECK_INT_EQ(2, common_dir_prefix_length("/a", "/a/b"));
++      CHECK_INT_EQ(2, common_dir_prefix_length("/a/b", "/a/c"));
++      CHECK_INT_EQ(4, common_dir_prefix_length("/a/b", "/a/b"));
+ }
+ TEST(get_relative_path)
+ {
+       CHECK_STR_EQ_FREE2("a", get_relative_path("/doesn't matter", "a"));
+       CHECK_STR_EQ_FREE2("a/b", get_relative_path("/doesn't matter", "a/b"));
+       CHECK_STR_EQ_FREE2(".", get_relative_path("/a", "/a"));
+       CHECK_STR_EQ_FREE2("..", get_relative_path("/a/b", "/a"));
+       CHECK_STR_EQ_FREE2("b", get_relative_path("/a", "/a/b"));
+       CHECK_STR_EQ_FREE2("b/c", get_relative_path("/a", "/a/b/c"));
+       CHECK_STR_EQ_FREE2("../c", get_relative_path("/a/b", "/a/c"));
+       CHECK_STR_EQ_FREE2("../c/d", get_relative_path("/a/b", "/a/c/d"));
+       CHECK_STR_EQ_FREE2("../../c/d", get_relative_path("/a/b/c", "/a/c/d"));
+       CHECK_STR_EQ_FREE2("../..", get_relative_path("/a/b", "/"));
+       CHECK_STR_EQ_FREE2("../../c", get_relative_path("/a/b", "/c"));
+       CHECK_STR_EQ_FREE2("a/b", get_relative_path("/", "/a/b"));
+ }
 +TEST(format_hash_as_string)
 +{
 +      unsigned char hash[16] = {
 +              "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"};
 +
 +      CHECK_STR_EQ_FREE2("00000000000000000000000000000000",
 +                         format_hash_as_string(hash, -1));
 +      CHECK_STR_EQ_FREE2("00000000000000000000000000000000-0",
 +                         format_hash_as_string(hash, 0));
 +      hash[0] = 17;
 +      hash[15] = 42;
 +      CHECK_STR_EQ_FREE2("1100000000000000000000000000002a-12345",
 +                         format_hash_as_string(hash, 12345));
 +}
 +
 +TEST(subst_env_in_string)
 +{
 +      char *errmsg;
 +      const char *shell = getenv("SHELL");
 +
 +      errmsg = "";
 +      CHECK_STR_EQ_FREE2(shell,
 +                         subst_env_in_string("$SHELL", &errmsg));
 +      CHECK(!errmsg);
 +
 +      errmsg = "";
 +      CHECK_STR_EQ_FREE2("$",
 +                         subst_env_in_string("$", &errmsg));
 +      CHECK(!errmsg);
 +
 +      errmsg = "";
 +      CHECK_STR_EQ_FREE12(format("%s %s:%s", shell, shell, shell),
 +                          subst_env_in_string("$SHELL $SHELL:$SHELL", &errmsg));
 +      CHECK(!errmsg);
 +
 +      errmsg = "";
 +      CHECK_STR_EQ_FREE12(format("x%s", shell),
 +                          subst_env_in_string("x$SHELL", &errmsg));
 +      CHECK(!errmsg);
 +
 +      errmsg = "";
 +      CHECK_STR_EQ_FREE12(format("%sx", shell),
 +                          subst_env_in_string("${SHELL}x", &errmsg));
 +      CHECK(!errmsg);
 +
 +      CHECK(!subst_env_in_string("$surelydoesntexist", &errmsg));
 +      CHECK_STR_EQ_FREE2("environment variable \"surelydoesntexist\" not set",
 +                         errmsg);
 +
 +      CHECK(!subst_env_in_string("${SHELL", &errmsg));
 +      CHECK_STR_EQ_FREE2("syntax error: missing '}' after \"SHELL\"", errmsg);
 +}
 +
 +TEST(format_human_readable_size)
 +{
 +      CHECK_STR_EQ_FREE2("0.0 kB", format_human_readable_size(0));
 +      CHECK_STR_EQ_FREE2("0.0 kB", format_human_readable_size(49));
 +      CHECK_STR_EQ_FREE2("0.1 kB", format_human_readable_size(50));
 +      CHECK_STR_EQ_FREE2("42.0 kB", format_human_readable_size(42 * 1000));
 +      CHECK_STR_EQ_FREE2("1.0 MB", format_human_readable_size(1000 * 1000));
 +      CHECK_STR_EQ_FREE2("1.2 MB", format_human_readable_size(1234 * 1000));
 +      CHECK_STR_EQ_FREE2("438.5 MB",
 +                         format_human_readable_size(438.5 * 1000 * 1000));
 +      CHECK_STR_EQ_FREE2("1.0 GB",
 +                         format_human_readable_size(1000 * 1000 * 1000));
 +      CHECK_STR_EQ_FREE2("17.1 GB",
 +                         format_human_readable_size(17.11 * 1000 * 1000 * 1000));
 +}
 +
 +TEST(format_parsable_size_with_suffix)
 +{
 +      CHECK_STR_EQ_FREE2("0", format_parsable_size_with_suffix(0));
 +      CHECK_STR_EQ_FREE2("42.0k", format_parsable_size_with_suffix(42 * 1000));
 +      CHECK_STR_EQ_FREE2("1.0M", format_parsable_size_with_suffix(1000 * 1000));
 +      CHECK_STR_EQ_FREE2("1.2M", format_parsable_size_with_suffix(1234 * 1000));
 +      CHECK_STR_EQ_FREE2("438.5M",
 +                         format_parsable_size_with_suffix(438.5 * 1000 * 1000));
 +      CHECK_STR_EQ_FREE2("1.0G",
 +                         format_parsable_size_with_suffix(1000 * 1000 * 1000));
 +      CHECK_STR_EQ_FREE2(
 +              "17.1G",
 +              format_parsable_size_with_suffix(17.11 * 1000 * 1000 * 1000));
 +}
 +
 +TEST(parse_size_with_suffix)
 +{
 +      uint64_t size;
 +      size_t i;
 +      struct { const char *size; int64_t expected; } sizes[] = {
 +              {"0", 0},
 +              {"42", 42},
 +
 +              {"78k",       78 * 1000},
 +              {"78K",       78 * 1000},
 +              {"1.1 M",     1.1 * 1000 * 1000},
 +              {"438.55M",   438.55 * 1000 * 1000},
 +              {"1 G",       1 * 1000 * 1000 * 1000},
 +              {"2T",        (int64_t)2 * 1000 * 1000 * 1000 * 1000},
 +
 +              {"78 Ki",     78 * 1024},
 +              {"1.1Mi",     1.1 * 1024 * 1024},
 +              {"438.55 Mi", 438.55 * 1024 * 1024},
 +              {"1Gi",       1 * 1024 * 1024 * 1024},
 +              {"2 Ti",      (int64_t)2 * 1024 * 1024 * 1024 * 1024},
 +
 +      };
 +
 +      for (i = 0; i < sizeof(sizes) / sizeof(sizes[0]); ++i) {
 +              CHECKM(parse_size_with_suffix(sizes[i].size, &size), sizes[i].size);
 +              CHECK_INT_EQ(sizes[i].expected, size);
 +      }
 +}
 +
  TEST_SUITE_END
diff --cc util.c
index cd47909a9cd2e1458d957e805f407c5fd5084c44,b4898000642b6df777f8502d89846daa5a80c225..b4efe0488c1d94c0d5b9e2ffd72beae0cefe5cb3
--- 1/util.c
--- 2/util.c
+++ b/util.c
@@@ -1150,17 -1019,15 +1169,15 @@@ get_relative_path(const char *from, con
  
        result = x_strdup("");
        common_prefix_len = common_dir_prefix_length(from, to);
-       for (p = from + common_prefix_len; *p; p++) {
-               if (*p == '/') {
-                       reformat(&result, "../%s", result);
+       if (common_prefix_len > 0 || !str_eq(from, "/")) {
+               for (p = from + common_prefix_len; *p; p++) {
+                       if (*p == '/') {
 -                              x_asprintf2(&result, "../%s", result);
++                              reformat(&result, "../%s", result);
+                       }
                }
        }
        if (strlen(to) > common_prefix_len) {
-               p = to + common_prefix_len + 1;
-               while (*p == '/') {
-                       p++;
-               }
-               reformat(&result, "%s%s", result, p);
 -              x_asprintf2(&result, "%s%s", result, to + common_prefix_len + 1);
++              reformat(&result, "%s%s", result, to + common_prefix_len + 1);
        }
        i = strlen(result) - 1;
        while (i >= 0 && result[i] == '/') {