]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: startup: sort the feature list in haproxy -vv
authorWilliam Lallemand <wlallemand@haproxy.com>
Thu, 12 Feb 2026 16:41:31 +0000 (17:41 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Thu, 12 Feb 2026 17:02:19 +0000 (18:02 +0100)
The feature list in haproxy -vv is partly generated from the Makefile
using the USE_* keywords, but it's also possible to add keywords in the
feature list using hap_register_feature(), which adds the keyword at the
end of list. When doing so, the list is not correctly sorted anymore.

This patch fixes the problem by splitting the string using an array of
ist and applying a qsort() on it.

src/haproxy.c

index 6c6360171cef0e42c7fd0fdff3e156ecacd81cac..c18f1ce5f2f20fffcb26c2556ad1f846649dfe55 100644 (file)
@@ -604,6 +604,48 @@ void display_version()
        }
 }
 
+/* compare a feature string, ignoring the first character (-/+)
+   used for qsort */
+static int feat_cmp(const void *a, const void *b)
+{
+       const struct ist *ia = a;
+       const struct ist *ib = b;
+
+       struct ist sa = istadv(*ia, 1);
+       struct ist sb = istadv(*ib, 1);
+
+       return istdiff(sa, sb);
+}
+
+/* split the feature list into an allocated sorted array of ist
+   the return ptr must be freed by the caller */
+static struct ist *split_feature_list()
+{
+       struct ist *out;
+       struct ist tmp = ist(build_features);
+
+       int n = 1; /* last element don't have a ' ' */
+       int i = 0;
+
+       for (i = 0; build_features[i] != '\0'; i++) {
+               if (build_features[i] == ' ')
+                       n++;
+       }
+       out = calloc(n + 1, sizeof(*out)); // last elem is NULL
+       if (!out)
+               goto end;
+
+       i = 0;
+       while (tmp.len)
+               out[i++] = istsplit(&tmp, ' ');
+
+       qsort(out, n, sizeof(struct ist), feat_cmp);
+
+end:
+
+       return out;
+}
+
 /* display_mode:
  * 0 = short version (e.g., "3.3.1")
  * 1 = full version (e.g., "3.3.1-dev5-1bb975-71")
@@ -643,14 +685,18 @@ void display_version_plain(int display_mode)
 static void display_build_opts()
 {
        const char **opt;
+       struct ist *feat_list = NULL, *tmp;
+
+       feat_list = split_feature_list();
 
-       printf("Build options : %s"
-              "\n\nFeature list : %s"
-              "\n\nDefault settings :"
+       printf("Build options : %s", build_opts_string);
+       printf("\n\nFeature list :");
+       for (tmp = feat_list;tmp->ptr;tmp++)
+               printf(" %.*s", (int)tmp->len, tmp->ptr);
+       printf("\n\nDefault settings :"
               "\n  bufsize = %d, maxrewrite = %d, maxpollevents = %d"
               "\n\n",
-              build_opts_string,
-              build_features, BUFSIZE, MAXREWRITE, MAX_POLL_EVENTS);
+              BUFSIZE, MAXREWRITE, MAX_POLL_EVENTS);
 
        for (opt = NULL; (opt = hap_get_next_build_opt(opt)); puts(*opt))
                ;
@@ -669,6 +715,7 @@ static void display_build_opts()
        putchar('\n');
        list_filters(stdout);
        putchar('\n');
+       ha_free(&feat_list);
 }
 
 /*