From 2017a15d6ca7f756dcf036499a02e15393609c83 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Tue, 27 Dec 2011 16:03:28 +0100 Subject: [PATCH] path: add git_path_fromurl() --- src/path.c | 35 +++++++++++++++++++++++++++ src/path.h | 1 + tests-clay/clay.h | 17 +++++++------ tests-clay/clay_main.c | 21 ++++++++-------- tests-clay/core/path.c | 55 ++++++++++++++++++++++++++++++++++++------ 5 files changed, 103 insertions(+), 26 deletions(-) diff --git a/src/path.c b/src/path.c index bd62a3e4d..53f0f3dc6 100644 --- a/src/path.c +++ b/src/path.c @@ -272,3 +272,38 @@ append: return error; } + +int git_path_fromurl(git_buf *local_path_out, const char *file_url) +{ + int error = GIT_SUCCESS, offset = 0, len; + + assert(local_path_out && file_url); + + if (git__prefixcmp(file_url, "file://") != 0) + return git__throw(GIT_EINVALIDPATH, "Parsing of '%s' failed. A file Uri is expected (ie. with 'file://' scheme).", file_url); + + offset += 7; + len = strlen(file_url); + + if (offset < len && file_url[offset] == '/') + offset++; + else if (offset < len && git__prefixcmp(file_url + offset, "localhost/") == 0) + offset += 10; + else + return git__throw(GIT_EINVALIDPATH, "Parsing of '%s' failed. A local file Uri is expected.", file_url); + + if (offset >= len || file_url[offset] == '/') + return git__throw(GIT_EINVALIDPATH, "Parsing of '%s' failed. Invalid file Uri format.", file_url); + +#ifndef _MSC_VER + offset--; /* A *nix absolute path starts with a forward slash */ +#endif + + git_buf_clear(local_path_out); + + error = git__percent_decode(local_path_out, file_url + offset); + if (error < GIT_SUCCESS) + return git__rethrow(error, "Parsing of '%s' failed.", file_url); + + return error; +} diff --git a/src/path.h b/src/path.h index 6397feedf..c308c5bd4 100644 --- a/src/path.h +++ b/src/path.h @@ -75,5 +75,6 @@ GIT_INLINE(void) git_path_mkposix(char *path) #endif extern int git__percent_decode(git_buf *decoded_out, const char *input); +extern int git_path_fromurl(git_buf *local_path_out, const char *file_url); #endif diff --git a/tests-clay/clay.h b/tests-clay/clay.h index b2b31bef7..8cbd8ddf8 100644 --- a/tests-clay/clay.h +++ b/tests-clay/clay.h @@ -109,14 +109,15 @@ extern void test_core_filebuf__5(void); extern void test_core_hex__fromhex(void); extern void test_core_oid__initialize(void); extern void test_core_oid__streq(void); -extern void test_core_path__0_dirname(void); -extern void test_core_path__1_basename(void); -extern void test_core_path__2_topdir(void); -extern void test_core_path__5_joins(void); -extern void test_core_path__6_long_joins(void); -extern void test_core_path__7_path_to_dir(void); -extern void test_core_path__8_self_join(void); -extern void test_core_path__9_percent_decode(void); +extern void test_core_path__00_dirname(void); +extern void test_core_path__01_basename(void); +extern void test_core_path__02_topdir(void); +extern void test_core_path__05_joins(void); +extern void test_core_path__06_long_joins(void); +extern void test_core_path__07_path_to_dir(void); +extern void test_core_path__08_self_join(void); +extern void test_core_path__09_percent_decode(void); +extern void test_core_path__10_fromurl(void); extern void test_core_rmdir__delete_recursive(void); extern void test_core_rmdir__fail_to_delete_non_empty_dir(void); extern void test_core_rmdir__initialize(void); diff --git a/tests-clay/clay_main.c b/tests-clay/clay_main.c index e6bb80440..ce2ffaff4 100644 --- a/tests-clay/clay_main.c +++ b/tests-clay/clay_main.c @@ -174,14 +174,15 @@ static const struct clay_func _clay_cb_core_oid[] = { {"streq", &test_core_oid__streq} }; static const struct clay_func _clay_cb_core_path[] = { - {"0_dirname", &test_core_path__0_dirname}, - {"1_basename", &test_core_path__1_basename}, - {"2_topdir", &test_core_path__2_topdir}, - {"5_joins", &test_core_path__5_joins}, - {"6_long_joins", &test_core_path__6_long_joins}, - {"7_path_to_dir", &test_core_path__7_path_to_dir}, - {"8_self_join", &test_core_path__8_self_join}, - {"9_percent_decode", &test_core_path__9_percent_decode} + {"00_dirname", &test_core_path__00_dirname}, + {"01_basename", &test_core_path__01_basename}, + {"02_topdir", &test_core_path__02_topdir}, + {"05_joins", &test_core_path__05_joins}, + {"06_long_joins", &test_core_path__06_long_joins}, + {"07_path_to_dir", &test_core_path__07_path_to_dir}, + {"08_self_join", &test_core_path__08_self_join}, + {"09_percent_decode", &test_core_path__09_percent_decode}, + {"10_fromurl", &test_core_path__10_fromurl} }; static const struct clay_func _clay_cb_core_rmdir[] = { {"delete_recursive", &test_core_rmdir__delete_recursive}, @@ -382,7 +383,7 @@ static const struct clay_suite _clay_suites[] = { "core::path", {NULL, NULL}, {NULL, NULL}, - _clay_cb_core_path, 8 + _clay_cb_core_path, 9 }, { "core::rmdir", @@ -549,7 +550,7 @@ static const struct clay_suite _clay_suites[] = { }; static size_t _clay_suite_count = 39; -static size_t _clay_callback_count = 124; +static size_t _clay_callback_count = 125; /* Core test functions */ static void diff --git a/tests-clay/core/path.c b/tests-clay/core/path.c index 8744247d2..bdebfb9c5 100644 --- a/tests-clay/core/path.c +++ b/tests-clay/core/path.c @@ -70,7 +70,7 @@ check_joinpath_n( /* get the dirname of a path */ -void test_core_path__0_dirname(void) +void test_core_path__00_dirname(void) { check_dirname(NULL, "."); check_dirname("", "."); @@ -90,7 +90,7 @@ void test_core_path__0_dirname(void) } /* get the base name of a path */ -void test_core_path__1_basename(void) +void test_core_path__01_basename(void) { check_basename(NULL, "."); check_basename("", "."); @@ -107,7 +107,7 @@ void test_core_path__1_basename(void) } /* get the latest component in a path */ -void test_core_path__2_topdir(void) +void test_core_path__02_topdir(void) { check_topdir(".git/", ".git/"); check_topdir("/.git/", ".git/"); @@ -124,7 +124,7 @@ void test_core_path__2_topdir(void) } /* properly join path components */ -void test_core_path__5_joins(void) +void test_core_path__05_joins(void) { check_joinpath("", "", ""); check_joinpath("", "a", "a"); @@ -159,7 +159,7 @@ void test_core_path__5_joins(void) } /* properly join path components for more than one path */ -void test_core_path__6_long_joins(void) +void test_core_path__06_long_joins(void) { check_joinpath_n("", "", "", "", ""); check_joinpath_n("", "a", "", "", "a/"); @@ -212,7 +212,7 @@ check_string_to_dir( } /* convert paths to dirs */ -void test_core_path__7_path_to_dir(void) +void test_core_path__07_path_to_dir(void) { check_path_to_dir("", ""); check_path_to_dir(".", "./"); @@ -240,7 +240,7 @@ void test_core_path__7_path_to_dir(void) } /* join path to itself */ -void test_core_path__8_self_join(void) +void test_core_path__08_self_join(void) { git_buf path = GIT_BUF_INIT; ssize_t asize = 0; @@ -284,7 +284,7 @@ static void check_percent_decoding(const char *expected_result, const char *inpu git_buf_free(&buf); } -void test_core_path__9_percent_decode(void) +void test_core_path__09_percent_decode(void) { check_percent_decoding("abcd", "abcd"); check_percent_decoding("a2%", "a2%"); @@ -297,3 +297,42 @@ void test_core_path__9_percent_decode(void) check_percent_decoding("a bc ", "a%20bc%20"); check_percent_decoding("Vicent Mart" "\355", "Vicent%20Mart%ED"); } + +static void check_fromurl(const char *expected_result, const char *input, int should_fail) +{ + git_buf buf = GIT_BUF_INIT; + + assert(should_fail || expected_result); + + if (!should_fail) { + cl_git_pass(git_path_fromurl(&buf, input)); + cl_assert_strequal(expected_result, git_buf_cstr(&buf)); + } else + cl_git_fail(git_path_fromurl(&buf, input)); + + git_buf_free(&buf); +} + +#ifdef _MSC_VER +#define ABS_PATH_MARKER "" +#else +#define ABS_PATH_MARKER "/" +#endif + +void test_core_path__10_fromurl(void) +{ + /* Failing cases */ + check_fromurl(NULL, "a", 1); + check_fromurl(NULL, "http:///c:/Temp%20folder/note.txt", 1); + check_fromurl(NULL, "file://c:/Temp%20folder/note.txt", 1); + check_fromurl(NULL, "file:////c:/Temp%20folder/note.txt", 1); + check_fromurl(NULL, "file:///", 1); + check_fromurl(NULL, "file:////", 1); + check_fromurl(NULL, "file://servername/c:/Temp%20folder/note.txt", 1); + + /* Passing cases */ + check_fromurl(ABS_PATH_MARKER "c:/Temp folder/note.txt", "file:///c:/Temp%20folder/note.txt", 0); + check_fromurl(ABS_PATH_MARKER "c:/Temp folder/note.txt", "file://localhost/c:/Temp%20folder/note.txt", 0); + check_fromurl(ABS_PATH_MARKER "c:/Temp+folder/note.txt", "file:///c:/Temp+folder/note.txt", 0); + check_fromurl(ABS_PATH_MARKER "a", "file:///a", 0); +}