From: Pietro Cerutti Date: Tue, 17 Jan 2017 12:34:07 +0000 (+0000) Subject: Fix sorting when using '/' as a namespace separator X-Git-Tag: neomutt-20170128~29 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=015d94180ca4ad66c4e17fa7c41c2f1852be2422;p=neomutt Fix sorting when using '/' as a namespace separator Closes: #301 --- diff --git a/browser.c b/browser.c index 360a04323..fd18d9b59 100644 --- a/browser.c +++ b/browser.c @@ -103,9 +103,9 @@ static int browser_compare_subject (const void *a, const void *b) struct folder_file *pb = (struct folder_file *) b; /* inbox should be sorted ahead of its siblings */ - int same_path = mutt_same_path (pa->name, pb->name); - int r = (same_path && mutt_is_inbox (pa->name)) ? -1 : - (same_path && mutt_is_inbox (pb->name)) ? 1 : + int common_subpath = mutt_have_common_subpath (pa->name, pb->name); + int r = (common_subpath && mutt_is_inbox (pa->name)) ? -1 : + (common_subpath && mutt_is_inbox (pb->name)) ? 1 : mutt_strcoll (pa->name, pb->name); return ((BrowserSort & SORT_REVERSE) ? -r : r); diff --git a/lib.c b/lib.c index 86d12f615..85374e486 100644 --- a/lib.c +++ b/lib.c @@ -1113,7 +1113,20 @@ int mutt_is_inbox (const char *path) return ((plen >= 6) && (mutt_strcasecmp (path + plen - 6, "/inbox") == 0)); } -int mutt_same_path (const char *a, const char *b) +/** + * mutt_have_common_subpath - check whether two paths have a common subpath. + * @param a First path. + * @param b Second path. + * + * @return 1 if a and b have a common subpath, 0 otherwise + * + * This function checks whether two paths (where the path separator is assumed + * to be '/', have a common subpath. Examples: + * + * /foo/bar/baz and /foo/hey/you do have a common subpath (/foo/) + * /apple/banana and /apples/bananas do NOT have a common subpath + */ +int mutt_have_common_subpath(const char *a, const char *b) { const char *a_end = strrchr (a, '/'); const char *b_end = strrchr (b, '/'); @@ -1128,7 +1141,10 @@ int mutt_same_path (const char *a, const char *b) /* Compare the paths */ size_t a_len = a_end - a; - return ((a_len == (b_end - b)) && (mutt_strncasecmp (a, b, a_len) == 0)); + size_t b_len = b_end - b; + size_t min = MIN(a_len, b_len); + return (a[min] == '/') && (b[min] == '/') && + (mutt_strncasecmp(a, b, min) == 0); } char * strfcpy (char *dest, const char *src, size_t dlen) diff --git a/lib.h b/lib.h index 7328bbcac..bc2e373b2 100644 --- a/lib.h +++ b/lib.h @@ -227,7 +227,7 @@ void mutt_unlink (const char *); void safe_free (void *); void safe_realloc (void *, size_t); int mutt_is_inbox (const char *path); -int mutt_same_path (const char *a, const char *b); +int mutt_have_common_subpath (const char *a, const char *b); const char *mutt_strsysexit(int e); #endif diff --git a/sidebar.c b/sidebar.c index b455f3adf..4c0baed7f 100644 --- a/sidebar.c +++ b/sidebar.c @@ -321,9 +321,9 @@ static int cb_qsort_sbe (const void *a, const void *b) break; case SORT_PATH: { - int same_path = mutt_same_path (b1->path, b2->path); - result = (same_path && mutt_is_inbox (b1->path)) ? -1 : - (same_path && mutt_is_inbox (b2->path)) ? 1 : + int common_subpath = mutt_have_common_subpath (b1->path, b2->path); + result = (common_subpath && mutt_is_inbox (b1->path)) ? -1 : + (common_subpath && mutt_is_inbox (b2->path)) ? 1 : mutt_strcoll (b1->path, b2->path); break; }