From 18d8b06238c18db9243f0a01beccd445c4ed843a Mon Sep 17 00:00:00 2001 From: Slava Zanko Date: Sat, 26 Nov 2011 23:12:52 +0300 Subject: [PATCH] VFS: Added new function vfs_path_to_str_flags() Signed-off-by: Slava Zanko --- lib/vfs/path.c | 75 ++++++++++++++++++++++++++++----- lib/vfs/path.h | 6 ++- tests/lib/vfs/path_recode.c | 83 ++++++++++++++++++++++++++++++++++++- 3 files changed, 150 insertions(+), 14 deletions(-) diff --git a/lib/vfs/path.c b/lib/vfs/path.c index 40fc20281..56855468c 100644 --- a/lib/vfs/path.c +++ b/lib/vfs/path.c @@ -442,7 +442,7 @@ vfs_path_from_str_uri_parser (char *path) url_delimiter += strlen (VFS_PATH_URL_DELIMITER); sub = VFSDATA (element); - if (sub != NULL && sub->flags & VFS_S_REMOTE) + if (sub != NULL && (sub->flags & VFS_S_REMOTE) != 0) { slash_pointer = strchr (url_delimiter, PATH_SEP); if (slash_pointer == NULL) @@ -534,29 +534,65 @@ vfs_path_tokens_add_class_info (vfs_path_element_t * element, GString * ret_toke g_string_append (ret_tokens, element_tokens->str); } +/* --------------------------------------------------------------------------------------------- */ +/** + * Strip path to home dir. + * @param dir pointer to string contains full path + */ + +static char * +vfs_path_strip_home (const char *dir) +{ + const char *home_dir = mc_config_get_home_dir (); + + if (home_dir != NULL) + { + size_t len; + + len = strlen (home_dir); + + if (strncmp (dir, home_dir, len) == 0 && (dir[len] == PATH_SEP || dir[len] == '\0')) + return g_strdup_printf ("~%s", dir + len); + } + + return g_strdup (dir); +} + +/* --------------------------------------------------------------------------------------------- */ + /* --------------------------------------------------------------------------------------------- */ /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ /** - * Convert first elements_count elements from vfs_path_t to string representation. + * Convert first elements_count elements from vfs_path_t to string representation with flags. * * @param vpath pointer to vfs_path_t object * @param elements_count count of first elements for convert - * @param flags flags for parser + * @param flags flags for converter * * @return pointer to newly created string. */ #define vfs_append_from_path(appendfrom) \ { \ - if ((*appendfrom != PATH_SEP) && (*appendfrom != '\0') \ - && (buffer->str[buffer->len - 1] != PATH_SEP)) \ - g_string_append_c (buffer, PATH_SEP); \ - g_string_append (buffer, appendfrom); \ + if ((flags & VPF_STRIP_HOME) && element_index == 0 && (element->class->flags & VFSF_LOCAL) != 0) \ + { \ + char *stripped_home_str; \ + stripped_home_str = vfs_path_strip_home (appendfrom); \ + g_string_append (buffer, stripped_home_str); \ + g_free (stripped_home_str); \ + } \ + else \ + { \ + if ((*appendfrom != PATH_SEP) && (*appendfrom != '\0') \ + && (buffer->str[buffer->len - 1] != PATH_SEP)) \ + g_string_append_c (buffer, PATH_SEP); \ + g_string_append (buffer, appendfrom); \ + } \ } char * -vfs_path_to_str_elements_count (const vfs_path_t * vpath, int elements_count) +vfs_path_to_str_flags (const vfs_path_t * vpath, int elements_count, vfs_path_flag_t flags) { int element_index; GString *buffer; @@ -565,7 +601,7 @@ vfs_path_to_str_elements_count (const vfs_path_t * vpath, int elements_count) if (vpath == NULL) return NULL; - if (elements_count > vfs_path_elements_count (vpath)) + if (elements_count == 0 || elements_count > vfs_path_elements_count (vpath)) elements_count = vfs_path_elements_count (vpath); if (elements_count < 0) @@ -588,14 +624,15 @@ vfs_path_to_str_elements_count (const vfs_path_t * vpath, int elements_count) g_string_append (buffer, element->vfs_prefix); g_string_append (buffer, VFS_PATH_URL_DELIMITER); - url_str = vfs_path_build_url_params_str (element, TRUE); + url_str = vfs_path_build_url_params_str (element, !(flags & VPF_STRIP_PASSWORD)); + if (*url_str != '\0') g_string_append (buffer, url_str); g_free (url_str); } - if (vfs_path_element_need_cleanup_converter (element)) + if ((flags & VPF_RECODE) == 0 && vfs_path_element_need_cleanup_converter (element)) { if (buffer->str[buffer->len - 1] != PATH_SEP) g_string_append (buffer, PATH_SEP_STR); @@ -616,6 +653,22 @@ vfs_path_to_str_elements_count (const vfs_path_t * vpath, int elements_count) #undef vfs_append_from_path +/* --------------------------------------------------------------------------------------------- */ +/** + * Convert first elements_count elements from vfs_path_t to string representation. + * + * @param vpath pointer to vfs_path_t object + * @param elements_count count of first elements for convert + * + * @return pointer to newly created string. + */ + +char * +vfs_path_to_str_elements_count (const vfs_path_t * vpath, int elements_count) +{ + return vfs_path_to_str_flags (vpath, elements_count, VPF_NONE); +} + /* --------------------------------------------------------------------------------------------- */ /** * Convert vfs_path_t to string representation. diff --git a/lib/vfs/path.h b/lib/vfs/path.h index 2dc211b82..8aa3fcfce 100644 --- a/lib/vfs/path.h +++ b/lib/vfs/path.h @@ -11,7 +11,10 @@ typedef enum { VPF_NONE = 0, VPF_NO_CANON = 1 << 0, - VPF_USE_DEPRECATED_PARSER = 1 << 1 + VPF_USE_DEPRECATED_PARSER = 1 << 1, + VPF_RECODE = 1 << 2, + VPF_STRIP_HOME = 1 << 3, + VPF_STRIP_PASSWORD = 1 << 4 } vfs_path_flag_t; /*** structures declarations (and typedefs of structures)*****************************************/ @@ -55,6 +58,7 @@ int vfs_path_elements_count (const vfs_path_t * path); char *vfs_path_to_str (const vfs_path_t * path); char *vfs_path_to_str_elements_count (const vfs_path_t * path, int elements_count); +char *vfs_path_to_str_flags (const vfs_path_t * vpath, int elements_count, vfs_path_flag_t flags); vfs_path_t *vfs_path_from_str (const char *path_str); vfs_path_t *vfs_path_from_str_flags (const char *path_str, vfs_path_flag_t flags); vfs_path_t *vfs_path_build_filename (const char *first_element, ...); diff --git a/tests/lib/vfs/path_recode.c b/tests/lib/vfs/path_recode.c index b9aaf5b5d..661f52891 100644 --- a/tests/lib/vfs/path_recode.c +++ b/tests/lib/vfs/path_recode.c @@ -43,9 +43,14 @@ #include "src/vfs/local/local.c" +const char *mc_config_get_home_dir (void); + +const char * +mc_config_get_home_dir (void) +{ + return "/mock/home"; +} -struct vfs_s_subclass test_subclass1, test_subclass2, test_subclass3; -struct vfs_class vfs_test_ops1, vfs_test_ops2, vfs_test_ops3; static void setup (void) @@ -58,6 +63,7 @@ teardown (void) } /* --------------------------------------------------------------------------------------------- */ + #define path_recode_one_check(input, etalon1, etalon2) {\ vpath = vfs_path_from_str (input);\ element = vfs_path_get_by_index(vpath, -1);\ @@ -96,6 +102,8 @@ START_TEST (test_path_recode_base_utf8) } END_TEST +/* --------------------------------------------------------------------------------------------- */ + START_TEST (test_path_recode_base_koi8r) { vfs_path_t *vpath; @@ -125,6 +133,75 @@ START_TEST (test_path_recode_base_koi8r) END_TEST /* --------------------------------------------------------------------------------------------- */ +struct vfs_s_subclass test_subclass1; +struct vfs_class vfs_test_ops1; + +START_TEST(test_path_to_str_flags) +{ + + vfs_path_t *vpath; + char *str_path; + + str_init_strings ("UTF-8"); + + vfs_init (); + init_localfs (); + + vfs_setup_work_dir (); + mc_global.sysconfig_dir = (char *) TEST_SHARE_DIR; + mc_global.sysconfig_dir = (char *) TEST_SHARE_DIR; + load_codepages_list (); + + test_subclass1.flags = VFS_S_REMOTE; + vfs_s_init_class (&vfs_test_ops1, &test_subclass1); + vfs_test_ops1.name = "testfs1"; + vfs_test_ops1.flags = VFSF_NOLINKS; + vfs_test_ops1.prefix = "test1"; + vfs_register_class (&vfs_test_ops1); + + + vpath = vfs_path_from_str ("/test1://user:passwd@host.name/#enc:KOI8-R/тестовый/путь"); + str_path = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_PASSWORD); + fail_unless (strcmp ("/test1://user@host.name/#enc:KOI8-R/тестовый/путь", str_path) == 0, "\nstr=%s\n", str_path); + g_free (str_path); + + str_path = vfs_path_to_str_flags (vpath, 0, VPF_RECODE); + fail_unless (strcmp ("/test1://user:passwd@host.name//", str_path) == 0, "\nstr=%s\n", str_path); + g_free (str_path); + + str_path = vfs_path_to_str_flags (vpath, 0, VPF_RECODE | VPF_STRIP_PASSWORD); + fail_unless (strcmp ("/test1://user@host.name//", str_path) == 0, "\nstr=%s\n", str_path); + g_free (str_path); + + vfs_path_free (vpath); + + vpath = vfs_path_build_filename (mc_config_get_home_dir (), "test", "dir", NULL); + str_path = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_HOME); + fail_unless (strcmp ("~/test/dir", str_path) == 0, "\nstr=%s\n", str_path); + g_free (str_path); + vfs_path_free (vpath); + + vpath = vfs_path_build_filename (mc_config_get_home_dir (), "test1://user:passwd@host.name/#enc:KOI8-R/тестовый/путь", NULL); + str_path = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_HOME | VPF_STRIP_PASSWORD); + fail_unless (strcmp ("~/test1://user@host.name/#enc:KOI8-R/тестовый/путь", str_path) == 0, "\nstr=%s\n", str_path); + g_free (str_path); + str_path = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_HOME | VPF_RECODE); + fail_unless (strcmp ("~/test1://user:passwd@host.name//", str_path) == 0, "\nstr=%s\n", str_path); + g_free (str_path); + str_path = vfs_path_to_str_flags (vpath, 0, VPF_STRIP_HOME | VPF_RECODE | VPF_STRIP_PASSWORD); + fail_unless (strcmp ("~/test1://user@host.name//", str_path) == 0, "\nstr=%s\n", str_path); + g_free (str_path); + vfs_path_free (vpath); + + free_codepages_list (); + str_uninit_strings (); + vfs_shut (); + +} +END_TEST + +/* --------------------------------------------------------------------------------------------- */ + int main (void) @@ -140,10 +217,12 @@ main (void) /* Add new tests here: *************** */ tcase_add_test (tc_core, test_path_recode_base_utf8); tcase_add_test (tc_core, test_path_recode_base_koi8r); + tcase_add_test (tc_core, test_path_to_str_flags); /* *********************************** */ suite_add_tcase (s, tc_core); sr = srunner_create (s); + srunner_print (sr, CK_VERBOSE); srunner_set_log (sr, "path_recode.log"); srunner_run_all (sr, CK_NORMAL); number_failed = srunner_ntests_failed (sr);