svn commit: r1932928 - subversion/trunk/subversion/svnbrowse

[email protected]
Newsgroups gmane.comp.version-control.subversion.svn
Message-ID <177574910466.1085490.18280720397151212831@svn03-he-fi>
Author: rinrab
Date: Thu Apr  9 15:38:24 2026
New Revision: 1932928

Log:
svnbrowse: Sort all nodes in the list.

* subversion/svnbrowse/model.c
  (includes): Add private/svn_sorts_private.h for svn_sort__array().
  (compare_cstrings_lexically, compare_node_kind,
   sort_item_comparison_func): New functions.
  (svn_browse__state_create): Sort the list.

Modified:
   subversion/trunk/subversion/svnbrowse/model.c

Modified: subversion/trunk/subversion/svnbrowse/model.c
==============================================================================
--- subversion/trunk/subversion/svnbrowse/model.c	Thu Apr  9 15:29:54 2026	(r1932927)
+++ subversion/trunk/subversion/svnbrowse/model.c	Thu Apr  9 15:38:24 2026	(r1932928)
@@ -31,9 +31,59 @@
 #include "svn_error.h"
 
 #include "private/svn_client_private.h"
+#include "private/svn_sorts_private.h"
 
 #include "svnbrowse.h"
 
+/* similar to svn_sort_compare_items_lexically() */
+static int
+compare_cstrings_lexically(const char *a, const char *b)
+{
+  int alen = strlen(a);
+  int blen = strlen(b);
+  int len, val;
+
+  /* Compare bytes of a's key and b's key up to the common length. */
+  len = (alen < blen) ? alen : blen;
+  val = memcmp(a, b, len);
+
+  if (val != 0)
+    return val;
+
+  /* They match up until one of them ends; whichever is longer is greater. */
+  return (alen < blen) ? -1 : (alen > blen) ? 1 : 0;
+}
+
+/* sort comparator that puts directories before files */
+int static
+compare_node_kind(svn_node_kind_t a, svn_node_kind_t b)
+{
+  /* RA API should never return other node kinds */
+  SVN_ERR_ASSERT_NO_RETURN(a == svn_node_file || a == svn_node_dir);
+  SVN_ERR_ASSERT_NO_RETURN(b == svn_node_file || b == svn_node_dir);
+
+  /* so now we can do this safely */
+  return b - a;
+}
+
+/*
+ * 1. we want directories to be before files (compare_node_kind)
+ * 2. the nodes are sorted lexically (compare_cstrings_lexically)
+ */
+int static
+sort_item_comparison_func(const void *left, const void *right)
+{
+  /* don't worry about that... */
+  const svn_browse__item_t *a = *(const svn_browse__item_t **)left;
+  const svn_browse__item_t *b = *(const svn_browse__item_t **)right;
+
+  int val = compare_node_kind(a->dirent->kind, b->dirent->kind);
+  if (val != 0)
+    return val;
+
+  return compare_cstrings_lexically(a->name, b->name);
+}
+
 svn_error_t *
 svn_browse__state_create(svn_browse__state_t **state_p,
                          svn_ra_session_t *session,
@@ -68,6 +118,12 @@ svn_browse__state_create(svn_browse__sta
       APR_ARRAY_PUSH(state->list, svn_browse__item_t *) = item;
     }
 
+  /* libsvn_client:list.c, on the other hand, uses svn_sort__hash before coping
+   * items into an array. I prefer this approach instead because it's more
+   * pipeline-ish, I think. Firstly the targets are processed, secondly sorting
+   * rules are applied. */
+  svn_sort__array(state->list, sort_item_comparison_func);
+
   *state_p = state;
   return SVN_NO_ERROR;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.