From: Joel Rosdahl Date: Sat, 28 Jul 2012 15:17:25 +0000 (+0200) Subject: Merge branch 'maint' X-Git-Tag: v3.2~124 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6595cf871eafaec254d1c8a61d5b926d2a822a50;p=thirdparty%2Fccache.git Merge branch 'maint' * 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 --- 6595cf871eafaec254d1c8a61d5b926d2a822a50 diff --cc ccache.c index 01a73829f,1f8ee64eb..b126e20c5 --- a/ccache.c +++ 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; } diff --cc test/test_util.c index 7a9fbcdb2,10478baa7..0ad51d2e4 --- a/test/test_util.c +++ b/test/test_util.c @@@ -41,117 -41,32 +41,145 @@@ TEST(dirname CHECK_STR_EQ_FREE2("dir1/dir2", dirname("dir1/dir2/")); } + TEST(common_dir_prefix_length) + { - 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")); ++ 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 cd47909a9,b48980006..b4efe0488 --- a/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] == '/') {