-/* $OpenBSD: map.c,v 1.18 2021/11/12 16:57:24 claudio Exp $ */
+/* $OpenBSD: map.c,v 1.19 2021/11/15 14:57:57 claudio Exp $ */
/*
* Copyright (c) 2020 Martin Pieuchot <mpi@openbsd.org>
struct bt_arg *mval;
};
-int mcmp(struct mentry *, struct mentry *);
+int mcmp(const struct mentry *, const struct mentry *);
struct mentry *mget(struct map *, const char *);
RB_GENERATE(map, mentry, mlink, mcmp);
int
-mcmp(struct mentry *me0, struct mentry *me1)
+mcmp(const struct mentry *me0, const struct mentry *me1)
{
return strncmp(me0->mkey, me1->mkey, KLEN - 1);
}
return map;
}
+static int
+map_cmp(const void *a, const void *b)
+{
+ const struct mentry *ma = *(const struct mentry **)a;
+ const struct mentry *mb = *(const struct mentry **)b;
+ long rv;
+
+ rv = bacmp(ma->mval, mb->mval);
+ if (rv != 0)
+ return (rv > 0 ? -1 : 1);
+ return mcmp(ma, mb);
+}
+
/* Print at most `top' entries of the map ordered by value. */
void
map_print(struct map *map, size_t top, const char *name)
{
- struct mentry *mep, *mcur;
- struct bt_arg *bhigh, *bprev;
- size_t i;
+ struct mentry **elms, *mep;
+ size_t i, count = 0;
if (map == NULL)
return;
- bprev = &g_maxba;
- for (i = 0; i < top; i++) {
- mcur = NULL;
- bhigh = &g_nullba;
- RB_FOREACH(mep, map, map) {
- if (bacmp(mep->mval, bhigh) >= 0 &&
- bacmp(mep->mval, bprev) < 0 &&
- mep->mval != bprev) {
- mcur = mep;
- bhigh = mcur->mval;
- }
- }
- if (mcur == NULL)
- break;
- printf("@%s[%s]: %s\n", name, mcur->mkey,
- ba2str(mcur->mval, NULL));
- bprev = mcur->mval;
+ RB_FOREACH(mep, map, map)
+ count++;
+
+ elms = calloc(count, sizeof(*elms));
+ if (elms == NULL)
+ err(1, NULL);
+
+ count = 0;
+ RB_FOREACH(mep, map, map)
+ elms[count++] = mep;
+
+ qsort(elms, count, sizeof(*elms), map_cmp);
+
+ for (i = 0; i < top && i < count; i++) {
+ mep = elms[i];
+ printf("@%s[%s]: %s\n", name, mep->mkey,
+ ba2str(mep->mval, NULL));
}
+
+ free(elms);
}
void