intlist.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. #include <errno.h>
  8. #include <stdlib.h>
  9. #include <linux/compiler.h>
  10. #include "intlist.h"
  11. static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
  12. const void *entry)
  13. {
  14. int i = (int)((long)entry);
  15. struct rb_node *rc = NULL;
  16. struct int_node *node = malloc(sizeof(*node));
  17. if (node != NULL) {
  18. node->i = i;
  19. rc = &node->rb_node;
  20. }
  21. return rc;
  22. }
  23. static void int_node__delete(struct int_node *ilist)
  24. {
  25. free(ilist);
  26. }
  27. static void intlist__node_delete(struct rblist *rblist __maybe_unused,
  28. struct rb_node *rb_node)
  29. {
  30. struct int_node *node = container_of(rb_node, struct int_node, rb_node);
  31. int_node__delete(node);
  32. }
  33. static int intlist__node_cmp(struct rb_node *rb_node, const void *entry)
  34. {
  35. int i = (int)((long)entry);
  36. struct int_node *node = container_of(rb_node, struct int_node, rb_node);
  37. return node->i - i;
  38. }
  39. int intlist__add(struct intlist *ilist, int i)
  40. {
  41. return rblist__add_node(&ilist->rblist, (void *)((long)i));
  42. }
  43. void intlist__remove(struct intlist *ilist, struct int_node *node)
  44. {
  45. rblist__remove_node(&ilist->rblist, &node->rb_node);
  46. }
  47. struct int_node *intlist__find(struct intlist *ilist, int i)
  48. {
  49. struct int_node *node;
  50. struct rb_node *rb_node;
  51. if (ilist == NULL)
  52. return NULL;
  53. node = NULL;
  54. rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
  55. if (rb_node)
  56. node = container_of(rb_node, struct int_node, rb_node);
  57. return node;
  58. }
  59. static int intlist__parse_list(struct intlist *ilist, const char *s)
  60. {
  61. char *sep;
  62. int err;
  63. do {
  64. long value = strtol(s, &sep, 10);
  65. err = -EINVAL;
  66. if (*sep != ',' && *sep != '\0')
  67. break;
  68. err = intlist__add(ilist, value);
  69. if (err)
  70. break;
  71. s = sep + 1;
  72. } while (*sep != '\0');
  73. return err;
  74. }
  75. struct intlist *intlist__new(const char *slist)
  76. {
  77. struct intlist *ilist = malloc(sizeof(*ilist));
  78. if (ilist != NULL) {
  79. rblist__init(&ilist->rblist);
  80. ilist->rblist.node_cmp = intlist__node_cmp;
  81. ilist->rblist.node_new = intlist__node_new;
  82. ilist->rblist.node_delete = intlist__node_delete;
  83. if (slist && intlist__parse_list(ilist, slist))
  84. goto out_delete;
  85. }
  86. return ilist;
  87. out_delete:
  88. intlist__delete(ilist);
  89. return NULL;
  90. }
  91. void intlist__delete(struct intlist *ilist)
  92. {
  93. if (ilist != NULL)
  94. rblist__delete(&ilist->rblist);
  95. }
  96. struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx)
  97. {
  98. struct int_node *node = NULL;
  99. struct rb_node *rb_node;
  100. rb_node = rblist__entry(&ilist->rblist, idx);
  101. if (rb_node)
  102. node = container_of(rb_node, struct int_node, rb_node);
  103. return node;
  104. }