ref-filter: move ref_sorting flags to a bitfield

Change the reverse/ignore_case/version sort flags in the ref_sorting struct into a bitfield. Having three of them was already a bit unwieldy, but it would be even more so if another flag needed a function like ref_sorting_icase_all() introduced in 76f9e569adb (ref-filter: apply --ignore-case to all sorting keys, 2020-05-03). A follow-up change will introduce such a flag, so let's move this over to a bitfield. Instead of using the usual '#define' pattern I'm using the "enum" pattern from builtin/rebase.c's b4c8eb024af (builtin rebase: support --quiet, 2018-09-04). Perhaps there's a more idiomatic way of doing the "for each in list amend mask" pattern than this "mask/on" variable combo. This function doesn't allow us to e.g. do any arbitrary changes to the bitfield for multiple flags, but I think in this case that's fine. The common case is that we're calling this with a list of one. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed Jan 7, 2021 at 10:51 UTC 7c269a7b162027d0465d52203e778903a2ddbdbf
5 files changed +25 -17
builtin/branch.c
+1 -1
@@ -739,7 +739,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
739 */
740 if (!sorting)
741 sorting = ref_default_sorting();
742 - ref_sorting_icase_all(sorting, icase);
742 + ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
743 print_ref_list(&filter, sorting, &format);
744 print_columns(&output, colopts, NULL);
745 string_list_clear(&output, 0);
builtin/for-each-ref.c
+1 -1
@@ -70,7 +70,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
70
71 if (!sorting)
72 sorting = ref_default_sorting();
73 - ref_sorting_icase_all(sorting, icase);
73 + ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
74 filter.ignore_case = icase;
75
76 filter.name_patterns = argv;
builtin/tag.c
+1 -1
@@ -485,7 +485,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
485 }
486 if (!sorting)
487 sorting = ref_default_sorting();
488 - ref_sorting_icase_all(sorting, icase);
488 + ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
489 filter.ignore_case = icase;
490 if (cmdmode == 'l') {
491 int ret;
ref-filter.c
+15 -9
@@ -2362,11 +2362,12 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru
2362 if (get_ref_atom_value(b, s->atom, &vb, &err))
2363 die("%s", err.buf);
2364 strbuf_release(&err);
2365 - if (s->version) {
2365 + if (s->sort_flags & REF_SORTING_VERSION) {
2366 cmp = versioncmp(va->s, vb->s);
2367 } else if (cmp_type == FIELD_STR) {
2368 int (*cmp_fn)(const char *, const char *);
2369 - cmp_fn = s->ignore_case ? strcasecmp : strcmp;
2369 + cmp_fn = s->sort_flags & REF_SORTING_ICASE
2370 + ? strcasecmp : strcmp;
2371 cmp = cmp_fn(va->s, vb->s);
2372 } else {
2373 if (va->value < vb->value)
@@ -2377,7 +2378,7 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru
2378 cmp = 1;
2379 }
2380
2380 - return (s->reverse) ? -cmp : cmp;
2381 + return (s->sort_flags & REF_SORTING_REVERSE) ? -cmp : cmp;
2382 }
2383
2384 static int compare_refs(const void *a_, const void *b_, void *ref_sorting)
@@ -2392,15 +2393,20 @@ static int compare_refs(const void *a_, const void *b_, void *ref_sorting)
2393 return cmp;
2394 }
2395 s = ref_sorting;
2395 - return s && s->ignore_case ?
2396 + return s && s->sort_flags & REF_SORTING_ICASE ?
2397 strcasecmp(a->refname, b->refname) :
2398 strcmp(a->refname, b->refname);
2399 }
2400
2400 -void ref_sorting_icase_all(struct ref_sorting *sorting, int flag)
2401 +void ref_sorting_set_sort_flags_all(struct ref_sorting *sorting,
2402 + unsigned int mask, int on)
2403 {
2402 - for (; sorting; sorting = sorting->next)
2403 - sorting->ignore_case = !!flag;
2404 + for (; sorting; sorting = sorting->next) {
2405 + if (on)
2406 + sorting->sort_flags |= mask;
2407 + else
2408 + sorting->sort_flags &= ~mask;
2409 + }
2410 }
2411
2412 void ref_array_sort(struct ref_sorting *sorting, struct ref_array *array)
@@ -2537,12 +2543,12 @@ void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg)
2543 *sorting_tail = s;
2544
2545 if (*arg == '-') {
2540 - s->reverse = 1;
2546 + s->sort_flags |= REF_SORTING_REVERSE;
2547 arg++;
2548 }
2549 if (skip_prefix(arg, "version:", &arg) ||
2550 skip_prefix(arg, "v:", &arg))
2545 - s->version = 1;
2551 + s->sort_flags |= REF_SORTING_VERSION;
2552 s->atom = parse_sorting_atom(arg);
2553 }
2554
ref-filter.h
+7 -5
@@ -28,9 +28,11 @@ struct atom_value;
28 struct ref_sorting {
29 struct ref_sorting *next;
30 int atom; /* index into used_atom array (internal) */
31 - unsigned reverse : 1,
32 - ignore_case : 1,
33 - version : 1;
31 + enum {
32 + REF_SORTING_REVERSE = 1<<0,
33 + REF_SORTING_ICASE = 1<<1,
34 + REF_SORTING_VERSION = 1<<2,
35 + } sort_flags;
36 };
37
38 struct ref_array_item {
@@ -109,8 +111,8 @@ void ref_array_clear(struct ref_array *array);
111 int verify_ref_format(struct ref_format *format);
112 /* Sort the given ref_array as per the ref_sorting provided */
113 void ref_array_sort(struct ref_sorting *sort, struct ref_array *array);
112 -/* Set the ignore_case flag for all elements of a sorting list */
113 -void ref_sorting_icase_all(struct ref_sorting *sorting, int flag);
114 +/* Set REF_SORTING_* sort_flags for all elements of a sorting list */
115 +void ref_sorting_set_sort_flags_all(struct ref_sorting *sorting, unsigned int mask, int on);
116 /* Based on the given format and quote_style, fill the strbuf */
117 int format_ref_array_item(struct ref_array_item *info,
118 const struct ref_format *format,