Commit 2017a15d by nulltoken

path: add git_path_fromurl()

parent 459e2dcd
...@@ -272,3 +272,38 @@ append: ...@@ -272,3 +272,38 @@ append:
return error; 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;
}
...@@ -75,5 +75,6 @@ GIT_INLINE(void) git_path_mkposix(char *path) ...@@ -75,5 +75,6 @@ GIT_INLINE(void) git_path_mkposix(char *path)
#endif #endif
extern int git__percent_decode(git_buf *decoded_out, const char *input); 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 #endif
...@@ -109,14 +109,15 @@ extern void test_core_filebuf__5(void); ...@@ -109,14 +109,15 @@ extern void test_core_filebuf__5(void);
extern void test_core_hex__fromhex(void); extern void test_core_hex__fromhex(void);
extern void test_core_oid__initialize(void); extern void test_core_oid__initialize(void);
extern void test_core_oid__streq(void); extern void test_core_oid__streq(void);
extern void test_core_path__0_dirname(void); extern void test_core_path__00_dirname(void);
extern void test_core_path__1_basename(void); extern void test_core_path__01_basename(void);
extern void test_core_path__2_topdir(void); extern void test_core_path__02_topdir(void);
extern void test_core_path__5_joins(void); extern void test_core_path__05_joins(void);
extern void test_core_path__6_long_joins(void); extern void test_core_path__06_long_joins(void);
extern void test_core_path__7_path_to_dir(void); extern void test_core_path__07_path_to_dir(void);
extern void test_core_path__8_self_join(void); extern void test_core_path__08_self_join(void);
extern void test_core_path__9_percent_decode(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__delete_recursive(void);
extern void test_core_rmdir__fail_to_delete_non_empty_dir(void); extern void test_core_rmdir__fail_to_delete_non_empty_dir(void);
extern void test_core_rmdir__initialize(void); extern void test_core_rmdir__initialize(void);
......
...@@ -174,14 +174,15 @@ static const struct clay_func _clay_cb_core_oid[] = { ...@@ -174,14 +174,15 @@ static const struct clay_func _clay_cb_core_oid[] = {
{"streq", &test_core_oid__streq} {"streq", &test_core_oid__streq}
}; };
static const struct clay_func _clay_cb_core_path[] = { static const struct clay_func _clay_cb_core_path[] = {
{"0_dirname", &test_core_path__0_dirname}, {"00_dirname", &test_core_path__00_dirname},
{"1_basename", &test_core_path__1_basename}, {"01_basename", &test_core_path__01_basename},
{"2_topdir", &test_core_path__2_topdir}, {"02_topdir", &test_core_path__02_topdir},
{"5_joins", &test_core_path__5_joins}, {"05_joins", &test_core_path__05_joins},
{"6_long_joins", &test_core_path__6_long_joins}, {"06_long_joins", &test_core_path__06_long_joins},
{"7_path_to_dir", &test_core_path__7_path_to_dir}, {"07_path_to_dir", &test_core_path__07_path_to_dir},
{"8_self_join", &test_core_path__8_self_join}, {"08_self_join", &test_core_path__08_self_join},
{"9_percent_decode", &test_core_path__9_percent_decode} {"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[] = { static const struct clay_func _clay_cb_core_rmdir[] = {
{"delete_recursive", &test_core_rmdir__delete_recursive}, {"delete_recursive", &test_core_rmdir__delete_recursive},
...@@ -382,7 +383,7 @@ static const struct clay_suite _clay_suites[] = { ...@@ -382,7 +383,7 @@ static const struct clay_suite _clay_suites[] = {
"core::path", "core::path",
{NULL, NULL}, {NULL, NULL},
{NULL, NULL}, {NULL, NULL},
_clay_cb_core_path, 8 _clay_cb_core_path, 9
}, },
{ {
"core::rmdir", "core::rmdir",
...@@ -549,7 +550,7 @@ static const struct clay_suite _clay_suites[] = { ...@@ -549,7 +550,7 @@ static const struct clay_suite _clay_suites[] = {
}; };
static size_t _clay_suite_count = 39; static size_t _clay_suite_count = 39;
static size_t _clay_callback_count = 124; static size_t _clay_callback_count = 125;
/* Core test functions */ /* Core test functions */
static void static void
......
...@@ -70,7 +70,7 @@ check_joinpath_n( ...@@ -70,7 +70,7 @@ check_joinpath_n(
/* get the dirname of a path */ /* 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(NULL, ".");
check_dirname("", "."); check_dirname("", ".");
...@@ -90,7 +90,7 @@ void test_core_path__0_dirname(void) ...@@ -90,7 +90,7 @@ void test_core_path__0_dirname(void)
} }
/* get the base name of a path */ /* 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(NULL, ".");
check_basename("", "."); check_basename("", ".");
...@@ -107,7 +107,7 @@ void test_core_path__1_basename(void) ...@@ -107,7 +107,7 @@ void test_core_path__1_basename(void)
} }
/* get the latest component in a path */ /* 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/");
check_topdir("/.git/", ".git/"); check_topdir("/.git/", ".git/");
...@@ -124,7 +124,7 @@ void test_core_path__2_topdir(void) ...@@ -124,7 +124,7 @@ void test_core_path__2_topdir(void)
} }
/* properly join path components */ /* properly join path components */
void test_core_path__5_joins(void) void test_core_path__05_joins(void)
{ {
check_joinpath("", "", ""); check_joinpath("", "", "");
check_joinpath("", "a", "a"); check_joinpath("", "a", "a");
...@@ -159,7 +159,7 @@ void test_core_path__5_joins(void) ...@@ -159,7 +159,7 @@ void test_core_path__5_joins(void)
} }
/* properly join path components for more than one path */ /* 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("", "", "", "", "");
check_joinpath_n("", "a", "", "", "a/"); check_joinpath_n("", "a", "", "", "a/");
...@@ -212,7 +212,7 @@ check_string_to_dir( ...@@ -212,7 +212,7 @@ check_string_to_dir(
} }
/* convert paths to dirs */ /* 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("", "");
check_path_to_dir(".", "./"); check_path_to_dir(".", "./");
...@@ -240,7 +240,7 @@ void test_core_path__7_path_to_dir(void) ...@@ -240,7 +240,7 @@ void test_core_path__7_path_to_dir(void)
} }
/* join path to itself */ /* 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; git_buf path = GIT_BUF_INIT;
ssize_t asize = 0; ssize_t asize = 0;
...@@ -284,7 +284,7 @@ static void check_percent_decoding(const char *expected_result, const char *inpu ...@@ -284,7 +284,7 @@ static void check_percent_decoding(const char *expected_result, const char *inpu
git_buf_free(&buf); 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("abcd", "abcd");
check_percent_decoding("a2%", "a2%"); check_percent_decoding("a2%", "a2%");
...@@ -297,3 +297,42 @@ void test_core_path__9_percent_decode(void) ...@@ -297,3 +297,42 @@ void test_core_path__9_percent_decode(void)
check_percent_decoding("a bc ", "a%20bc%20"); check_percent_decoding("a bc ", "a%20bc%20");
check_percent_decoding("Vicent Mart" "\355", "Vicent%20Mart%ED"); 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment