linux/tools/perf/util/intlist.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Based on intlist.c by:
   4 * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
   5 */
   6
   7#include <errno.h>
   8#include <stdlib.h>
   9#include <linux/compiler.h>
  10
  11#include "intlist.h"
  12
  13static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
  14                                         const void *entry)
  15{
  16        int i = (int)((long)entry);
  17        struct rb_node *rc = NULL;
  18        struct int_node *node = malloc(sizeof(*node));
  19
  20        if (node != NULL) {
  21                node->i = i;
  22                node->priv = NULL;
  23                rc = &node->rb_node;
  24        }
  25
  26        return rc;
  27}
  28
  29static void int_node__delete(struct int_node *ilist)
  30{
  31        free(ilist);
  32}
  33
  34static void intlist__node_delete(struct rblist *rblist __maybe_unused,
  35                                 struct rb_node *rb_node)
  36{
  37        struct int_node *node = container_of(rb_node, struct int_node, rb_node);
  38
  39        int_node__delete(node);
  40}
  41
  42static int intlist__node_cmp(struct rb_node *rb_node, const void *entry)
  43{
  44        int i = (int)((long)entry);
  45        struct int_node *node = container_of(rb_node, struct int_node, rb_node);
  46
  47        return node->i - i;
  48}
  49
  50int intlist__add(struct intlist *ilist, int i)
  51{
  52        return rblist__add_node(&ilist->rblist, (void *)((long)i));
  53}
  54
  55void intlist__remove(struct intlist *ilist, struct int_node *node)
  56{
  57        rblist__remove_node(&ilist->rblist, &node->rb_node);
  58}
  59
  60static struct int_node *__intlist__findnew(struct intlist *ilist,
  61                                           int i, bool create)
  62{
  63        struct int_node *node = NULL;
  64        struct rb_node *rb_node;
  65
  66        if (ilist == NULL)
  67                return NULL;
  68
  69        if (create)
  70                rb_node = rblist__findnew(&ilist->rblist, (void *)((long)i));
  71        else
  72                rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
  73
  74        if (rb_node)
  75                node = container_of(rb_node, struct int_node, rb_node);
  76
  77        return node;
  78}
  79
  80struct int_node *intlist__find(struct intlist *ilist, int i)
  81{
  82        return __intlist__findnew(ilist, i, false);
  83}
  84
  85struct int_node *intlist__findnew(struct intlist *ilist, int i)
  86{
  87        return __intlist__findnew(ilist, i, true);
  88}
  89
  90static int intlist__parse_list(struct intlist *ilist, const char *s)
  91{
  92        char *sep;
  93        int err;
  94
  95        do {
  96                long value = strtol(s, &sep, 10);
  97                err = -EINVAL;
  98                if (*sep != ',' && *sep != '\0')
  99                        break;
 100                err = intlist__add(ilist, value);
 101                if (err)
 102                        break;
 103                s = sep + 1;
 104        } while (*sep != '\0');
 105
 106        return err;
 107}
 108
 109struct intlist *intlist__new(const char *slist)
 110{
 111        struct intlist *ilist = malloc(sizeof(*ilist));
 112
 113        if (ilist != NULL) {
 114                rblist__init(&ilist->rblist);
 115                ilist->rblist.node_cmp    = intlist__node_cmp;
 116                ilist->rblist.node_new    = intlist__node_new;
 117                ilist->rblist.node_delete = intlist__node_delete;
 118
 119                if (slist && intlist__parse_list(ilist, slist))
 120                        goto out_delete;
 121        }
 122
 123        return ilist;
 124out_delete:
 125        intlist__delete(ilist);
 126        return NULL;
 127}
 128
 129void intlist__delete(struct intlist *ilist)
 130{
 131        if (ilist != NULL)
 132                rblist__delete(&ilist->rblist);
 133}
 134
 135struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx)
 136{
 137        struct int_node *node = NULL;
 138        struct rb_node *rb_node;
 139
 140        rb_node = rblist__entry(&ilist->rblist, idx);
 141        if (rb_node)
 142                node = container_of(rb_node, struct int_node, rb_node);
 143
 144        return node;
 145}
 146