Skip to content

Commit

Permalink
ref-filter: move ref_sorting flags to a bitfield
Browse files Browse the repository at this point in the history
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
76f9e56 (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 b4c8eb0 (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>
  • Loading branch information
avar authored and gitster committed Jan 7, 2021
1 parent d094748 commit 7c269a7
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 17 deletions.
2 changes: 1 addition & 1 deletion builtin/branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
*/
if (!sorting)
sorting = ref_default_sorting();
ref_sorting_icase_all(sorting, icase);
ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
print_ref_list(&filter, sorting, &format);
print_columns(&output, colopts, NULL);
string_list_clear(&output, 0);
Expand Down
2 changes: 1 addition & 1 deletion builtin/for-each-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)

if (!sorting)
sorting = ref_default_sorting();
ref_sorting_icase_all(sorting, icase);
ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
filter.ignore_case = icase;

filter.name_patterns = argv;
Expand Down
2 changes: 1 addition & 1 deletion builtin/tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
}
if (!sorting)
sorting = ref_default_sorting();
ref_sorting_icase_all(sorting, icase);
ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
filter.ignore_case = icase;
if (cmdmode == 'l') {
int ret;
Expand Down
24 changes: 15 additions & 9 deletions ref-filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -2362,11 +2362,12 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru
if (get_ref_atom_value(b, s->atom, &vb, &err))
die("%s", err.buf);
strbuf_release(&err);
if (s->version) {
if (s->sort_flags & REF_SORTING_VERSION) {
cmp = versioncmp(va->s, vb->s);
} else if (cmp_type == FIELD_STR) {
int (*cmp_fn)(const char *, const char *);
cmp_fn = s->ignore_case ? strcasecmp : strcmp;
cmp_fn = s->sort_flags & REF_SORTING_ICASE
? strcasecmp : strcmp;
cmp = cmp_fn(va->s, vb->s);
} else {
if (va->value < vb->value)
Expand All @@ -2377,7 +2378,7 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru
cmp = 1;
}

return (s->reverse) ? -cmp : cmp;
return (s->sort_flags & REF_SORTING_REVERSE) ? -cmp : cmp;
}

static int compare_refs(const void *a_, const void *b_, void *ref_sorting)
Expand All @@ -2392,15 +2393,20 @@ static int compare_refs(const void *a_, const void *b_, void *ref_sorting)
return cmp;
}
s = ref_sorting;
return s && s->ignore_case ?
return s && s->sort_flags & REF_SORTING_ICASE ?
strcasecmp(a->refname, b->refname) :
strcmp(a->refname, b->refname);
}

void ref_sorting_icase_all(struct ref_sorting *sorting, int flag)
void ref_sorting_set_sort_flags_all(struct ref_sorting *sorting,
unsigned int mask, int on)
{
for (; sorting; sorting = sorting->next)
sorting->ignore_case = !!flag;
for (; sorting; sorting = sorting->next) {
if (on)
sorting->sort_flags |= mask;
else
sorting->sort_flags &= ~mask;
}
}

void ref_array_sort(struct ref_sorting *sorting, struct ref_array *array)
Expand Down Expand Up @@ -2537,12 +2543,12 @@ void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg)
*sorting_tail = s;

if (*arg == '-') {
s->reverse = 1;
s->sort_flags |= REF_SORTING_REVERSE;
arg++;
}
if (skip_prefix(arg, "version:", &arg) ||
skip_prefix(arg, "v:", &arg))
s->version = 1;
s->sort_flags |= REF_SORTING_VERSION;
s->atom = parse_sorting_atom(arg);
}

Expand Down
12 changes: 7 additions & 5 deletions ref-filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ struct atom_value;
struct ref_sorting {
struct ref_sorting *next;
int atom; /* index into used_atom array (internal) */
unsigned reverse : 1,
ignore_case : 1,
version : 1;
enum {
REF_SORTING_REVERSE = 1<<0,
REF_SORTING_ICASE = 1<<1,
REF_SORTING_VERSION = 1<<2,
} sort_flags;
};

struct ref_array_item {
Expand Down Expand Up @@ -109,8 +111,8 @@ void ref_array_clear(struct ref_array *array);
int verify_ref_format(struct ref_format *format);
/* Sort the given ref_array as per the ref_sorting provided */
void ref_array_sort(struct ref_sorting *sort, struct ref_array *array);
/* Set the ignore_case flag for all elements of a sorting list */
void ref_sorting_icase_all(struct ref_sorting *sorting, int flag);
/* Set REF_SORTING_* sort_flags for all elements of a sorting list */
void ref_sorting_set_sort_flags_all(struct ref_sorting *sorting, unsigned int mask, int on);
/* Based on the given format and quote_style, fill the strbuf */
int format_ref_array_item(struct ref_array_item *info,
const struct ref_format *format,
Expand Down

0 comments on commit 7c269a7

Please sign in to comment.