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