0001
0002
0003
0004
0005
0006
0007 #include <errno.h>
0008 #include <stdlib.h>
0009 #include <linux/compiler.h>
0010
0011 #include "intlist.h"
0012
0013 static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
0014 const void *entry)
0015 {
0016 unsigned long i = (unsigned long)entry;
0017 struct rb_node *rc = NULL;
0018 struct int_node *node = malloc(sizeof(*node));
0019
0020 if (node != NULL) {
0021 node->i = i;
0022 node->priv = NULL;
0023 rc = &node->rb_node;
0024 }
0025
0026 return rc;
0027 }
0028
0029 static void int_node__delete(struct int_node *ilist)
0030 {
0031 free(ilist);
0032 }
0033
0034 static void intlist__node_delete(struct rblist *rblist __maybe_unused,
0035 struct rb_node *rb_node)
0036 {
0037 struct int_node *node = container_of(rb_node, struct int_node, rb_node);
0038
0039 int_node__delete(node);
0040 }
0041
0042 static int intlist__node_cmp(struct rb_node *rb_node, const void *entry)
0043 {
0044 unsigned long i = (unsigned long)entry;
0045 struct int_node *node = container_of(rb_node, struct int_node, rb_node);
0046
0047 if (node->i > i)
0048 return 1;
0049 else if (node->i < i)
0050 return -1;
0051
0052 return 0;
0053 }
0054
0055 int intlist__add(struct intlist *ilist, unsigned long i)
0056 {
0057 return rblist__add_node(&ilist->rblist, (void *)i);
0058 }
0059
0060 void intlist__remove(struct intlist *ilist, struct int_node *node)
0061 {
0062 rblist__remove_node(&ilist->rblist, &node->rb_node);
0063 }
0064
0065 static struct int_node *__intlist__findnew(struct intlist *ilist,
0066 unsigned long i, bool create)
0067 {
0068 struct int_node *node = NULL;
0069 struct rb_node *rb_node;
0070
0071 if (ilist == NULL)
0072 return NULL;
0073
0074 if (create)
0075 rb_node = rblist__findnew(&ilist->rblist, (void *)i);
0076 else
0077 rb_node = rblist__find(&ilist->rblist, (void *)i);
0078
0079 if (rb_node)
0080 node = container_of(rb_node, struct int_node, rb_node);
0081
0082 return node;
0083 }
0084
0085 struct int_node *intlist__find(struct intlist *ilist, unsigned long i)
0086 {
0087 return __intlist__findnew(ilist, i, false);
0088 }
0089
0090 struct int_node *intlist__findnew(struct intlist *ilist, unsigned long i)
0091 {
0092 return __intlist__findnew(ilist, i, true);
0093 }
0094
0095 static int intlist__parse_list(struct intlist *ilist, const char *s)
0096 {
0097 char *sep;
0098 int err;
0099
0100 do {
0101 unsigned long value = strtol(s, &sep, 10);
0102 err = -EINVAL;
0103 if (*sep != ',' && *sep != '\0')
0104 break;
0105 err = intlist__add(ilist, value);
0106 if (err)
0107 break;
0108 s = sep + 1;
0109 } while (*sep != '\0');
0110
0111 return err;
0112 }
0113
0114 struct intlist *intlist__new(const char *slist)
0115 {
0116 struct intlist *ilist = malloc(sizeof(*ilist));
0117
0118 if (ilist != NULL) {
0119 rblist__init(&ilist->rblist);
0120 ilist->rblist.node_cmp = intlist__node_cmp;
0121 ilist->rblist.node_new = intlist__node_new;
0122 ilist->rblist.node_delete = intlist__node_delete;
0123
0124 if (slist && intlist__parse_list(ilist, slist))
0125 goto out_delete;
0126 }
0127
0128 return ilist;
0129 out_delete:
0130 intlist__delete(ilist);
0131 return NULL;
0132 }
0133
0134 void intlist__delete(struct intlist *ilist)
0135 {
0136 if (ilist != NULL)
0137 rblist__delete(&ilist->rblist);
0138 }
0139
0140 struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx)
0141 {
0142 struct int_node *node = NULL;
0143 struct rb_node *rb_node;
0144
0145 rb_node = rblist__entry(&ilist->rblist, idx);
0146 if (rb_node)
0147 node = container_of(rb_node, struct int_node, rb_node);
0148
0149 return node;
0150 }