Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Based on intlist.c by:
0004  * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
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 }