Changeset 03c4b23 in mainline


Ignore:
Timestamp:
2021-10-15T16:13:21Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Children:
9bed565
Parents:
fe5c7a1
Message:

Sort panel entries

Location:
uspace/app/nav
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/nav/panel.c

    rfe5c7a1 r03c4b23  
    4444#include <ui/paint.h>
    4545#include <ui/resource.h>
     46#include <qsort.h>
    4647#include "panel.h"
    4748#include "nav.h"
     
    484485        closedir(dir);
    485486
     487        rc = panel_sort(panel);
     488        if (rc != EOK)
     489                goto error;
     490
    486491        panel->cursor = panel_first(panel);
    487492        panel->cursor_idx = 0;
     
    492497        closedir(dir);
    493498        return rc;
     499}
     500
     501/** Sort panel entries.
     502 *
     503 * @param panel Panel
     504 * @return EOK on success, ENOMEM if out of memory
     505 */
     506errno_t panel_sort(panel_t *panel)
     507{
     508        panel_entry_t **emap;
     509        panel_entry_t *entry;
     510        size_t i;
     511
     512        /* Create an array to hold pointer to each entry */
     513        emap = calloc(panel->entries_cnt, sizeof(panel_entry_t *));
     514        if (emap == NULL)
     515                return ENOMEM;
     516
     517        /* Write entry pointers to array */
     518        entry = panel_first(panel);
     519        i = 0;
     520        while (entry != NULL) {
     521                assert(i < panel->entries_cnt);
     522                emap[i++] = entry;
     523                entry = panel_next(entry);
     524        }
     525
     526        /* Sort the array of pointers */
     527        qsort(emap, panel->entries_cnt, sizeof(panel_entry_t *),
     528            panel_entry_ptr_cmp);
     529
     530        /* Unlink entries from entry list */
     531        entry = panel_first(panel);
     532        while (entry != NULL) {
     533                list_remove(&entry->lentries);
     534                entry = panel_first(panel);
     535        }
     536
     537        /* Add entries back to entry list sorted */
     538        for (i = 0; i < panel->entries_cnt; i++)
     539                list_append(&emap[i]->lentries, &panel->entries);
     540
     541        free(emap);
     542        return EOK;
     543}
     544
     545/** Compare two panel entries indirectly referenced by pointers.
     546 *
     547 * @param pa Pointer to pointer to first entry
     548 * @param pb Pointer to pointer to second entry
     549 * @return <0, =0, >=0 if pa < b, pa == pb, pa > pb, resp.
     550 */
     551int panel_entry_ptr_cmp(const void *pa, const void *pb)
     552{
     553        panel_entry_t *a = *(panel_entry_t **)pa;
     554        panel_entry_t *b = *(panel_entry_t **)pb;
     555
     556        return str_cmp(a->name, b->name);
    494557}
    495558
  • uspace/app/nav/panel.h

    rfe5c7a1 r03c4b23  
    6262extern void panel_clear_entries(panel_t *);
    6363extern errno_t panel_read_dir(panel_t *, const char *);
     64extern errno_t panel_sort(panel_t *);
     65extern int panel_entry_ptr_cmp(const void *, const void *);
    6466extern panel_entry_t *panel_first(panel_t *);
    6567extern panel_entry_t *panel_last(panel_t *);
  • uspace/app/nav/test/panel.c

    rfe5c7a1 r03c4b23  
    446446}
    447447
     448/** panel_sort() sorts panel entries */
     449PCUT_TEST(sort)
     450{
     451        panel_t *panel;
     452        panel_entry_t *entry;
     453        errno_t rc;
     454
     455        rc = panel_create(NULL, true, &panel);
     456        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     457
     458        rc = panel_entry_append(panel, "b", 1);
     459        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     460
     461        rc = panel_entry_append(panel, "c", 3);
     462        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     463
     464        rc = panel_entry_append(panel, "a", 2);
     465        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     466
     467        rc = panel_sort(panel);
     468        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     469
     470        entry = panel_first(panel);
     471        PCUT_ASSERT_STR_EQUALS("a", entry->name);
     472        PCUT_ASSERT_INT_EQUALS(2, entry->size);
     473
     474        entry = panel_next(entry);
     475        PCUT_ASSERT_STR_EQUALS("b", entry->name);
     476        PCUT_ASSERT_INT_EQUALS(1, entry->size);
     477
     478        entry = panel_next(entry);
     479        PCUT_ASSERT_STR_EQUALS("c", entry->name);
     480        PCUT_ASSERT_INT_EQUALS(3, entry->size);
     481
     482        panel_destroy(panel);
     483}
     484
     485/** panel_entry_ptr_cmp compares two indirectly referenced entries */
     486PCUT_TEST(entry_ptr_cmp)
     487{
     488        panel_t *panel;
     489        panel_entry_t *a, *b;
     490        int rel;
     491        errno_t rc;
     492
     493        rc = panel_create(NULL, true, &panel);
     494        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     495
     496        rc = panel_entry_append(panel, "a", 2);
     497        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     498
     499        rc = panel_entry_append(panel, "b", 1);
     500        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     501
     502        a = panel_first(panel);
     503        PCUT_ASSERT_NOT_NULL(a);
     504        b = panel_next(a);
     505        PCUT_ASSERT_NOT_NULL(b);
     506
     507        /* a < b */
     508        rel = panel_entry_ptr_cmp(&a, &b);
     509        PCUT_ASSERT_TRUE(rel < 0);
     510
     511        /* b > a */
     512        rel = panel_entry_ptr_cmp(&b, &a);
     513        PCUT_ASSERT_TRUE(rel > 0);
     514
     515        /* a == a */
     516        rel = panel_entry_ptr_cmp(&a, &a);
     517        PCUT_ASSERT_INT_EQUALS(0, rel);
     518
     519        panel_destroy(panel);
     520}
     521
    448522/** panel_first() returns valid entry or @c NULL as appropriate */
    449523PCUT_TEST(first)
Note: See TracChangeset for help on using the changeset viewer.