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                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
  60struct int_node *intlist__find(struct intlist *ilist, int i)
  61{
  62        struct int_node *node;
  63        struct rb_node *rb_node;
  64
  65        if (ilist == NULL)
  66                return NULL;
  67
  68        node = NULL;
  69        rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
  70        if (rb_node)
  71                node = container_of(rb_node, struct int_node, rb_node);
  72
  73        return node;
  74}
  75
  76static int intlist__parse_list(struct intlist *ilist, const char *s)
  77{
  78        char *sep;
  79        int err;
  80
  81        do {
  82                long value = strtol(s, &sep, 10);
  83                err = -EINVAL;
  84                if (*sep != ',' && *sep != '\0')
  85                        break;
  86                err = intlist__add(ilist, value);
  87                if (err)
  88                        break;
  89                s = sep + 1;
  90        } while (*sep != '\0');
  91
  92        return err;
  93}
  94
  95struct intlist *intlist__new(const char *slist)
  96{
  97        struct intlist *ilist = malloc(sizeof(*ilist));
  98
  99        if (ilist != NULL) {
 100                rblist__init(&ilist->rblist);
 101                ilist->rblist.node_cmp    = intlist__node_cmp;
 102                ilist->rblist.node_new    = intlist__node_new;
 103                ilist->rblist.node_delete = intlist__node_delete;
 104
 105                if (slist && intlist__parse_list(ilist, slist))
 106                        goto out_delete;
 107        }
 108
 109        return ilist;
 110out_delete:
 111        intlist__delete(ilist);
 112        return NULL;
 113}
 114
 115void intlist__delete(struct intlist *ilist)
 116{
 117        if (ilist != NULL)
 118                rblist__delete(&ilist->rblist);
 119}
 120
 121struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx)
 122{
 123        struct int_node *node = NULL;
 124        struct rb_node *rb_node;
 125
 126        rb_node = rblist__entry(&ilist->rblist, idx);
 127        if (rb_node)
 128                node = container_of(rb_node, struct int_node, rb_node);
 129
 130        return node;
 131}
 132